]> git.sesse.net Git - vlc/commitdiff
Merge back branch 0.8.6-playlist-vlm to trunk.
authorClément Stenac <zorglub@videolan.org>
Sun, 14 May 2006 18:29:00 +0000 (18:29 +0000)
committerClément Stenac <zorglub@videolan.org>
Sun, 14 May 2006 18:29:00 +0000 (18:29 +0000)
What is currently broken:
 * Some playlist demuxers (shout, dvb and pls)
 * DAAP
 * BeOS playlist
 * GPE playlist, I suppose

What has some trouble:
 * Meta handling in several demuxers (most notably TS)
 * Skins2 playlist (doesn't refresh correctly)
 * OS X playlist (see bigben's latest commits)

104 files changed:
configure.ac
include/vlc/vlc.h
include/vlc_common.h
include/vlc_config.h
include/vlc_input.h
include/vlc_messages.h
include/vlc_meta.h
include/vlc_objects.h
include/vlc_playlist.h
include/vlc_symbols.h
modules/access/cdda.c
modules/access/cdda/cdda.c
modules/access/directory.c
modules/access/dvdnav.c
modules/access/http.c
modules/access/mms/mmsh.c
modules/codec/cmml/intf.c
modules/control/hotkeys.c
modules/control/http/http.h
modules/control/http/macro.c
modules/control/http/mvar.c
modules/control/http/rpn.c
modules/control/http/util.c
modules/control/rc.c
modules/demux/asf/asf.c
modules/demux/avi/avi.c
modules/demux/flac.c
modules/demux/m3u.c
modules/demux/mkv.cpp
modules/demux/mp4/mp4.c
modules/demux/mpeg/mpga.c
modules/demux/playlist/b4s.c
modules/demux/playlist/dvb.c
modules/demux/playlist/m3u.c
modules/demux/playlist/old.c
modules/demux/playlist/playlist.c
modules/demux/playlist/playlist.h
modules/demux/playlist/pls.c
modules/demux/playlist/podcast.c
modules/demux/playlist/shoutcast.c
modules/demux/playlist/xspf.c
modules/demux/sgimb.c
modules/demux/ts.c
modules/demux/util/id3tag.c
modules/gui/macosx/applescript.m
modules/gui/macosx/intf.m
modules/gui/macosx/playlist.h
modules/gui/macosx/playlist.m
modules/gui/macosx/playlistinfo.m
modules/gui/macosx/wizard.m
modules/gui/skins2/Modules.am
modules/gui/skins2/commands/cmd_add_item.cpp
modules/gui/skins2/commands/cmd_playlist.cpp
modules/gui/skins2/commands/cmd_playtree.cpp
modules/gui/skins2/commands/cmd_vars.cpp
modules/gui/skins2/parser/interpreter.cpp
modules/gui/skins2/parser/skin_parser.cpp
modules/gui/skins2/src/skin_main.cpp
modules/gui/skins2/src/vlcproc.cpp
modules/gui/skins2/src/vlcproc.hpp
modules/gui/skins2/vars/playlist.cpp [deleted file]
modules/gui/skins2/vars/playlist.hpp [deleted file]
modules/gui/skins2/vars/playtree.cpp
modules/gui/wxwidgets/dialogs.cpp
modules/gui/wxwidgets/dialogs/infopanels.cpp
modules/gui/wxwidgets/dialogs/iteminfo.cpp
modules/gui/wxwidgets/dialogs/open.cpp
modules/gui/wxwidgets/dialogs/playlist.cpp
modules/gui/wxwidgets/dialogs/playlist.hpp
modules/gui/wxwidgets/dialogs/wizard.cpp
modules/gui/wxwidgets/input_manager.cpp
modules/gui/wxwidgets/interface.cpp
modules/gui/wxwidgets/playlist_manager.cpp
modules/misc/growl.c
modules/misc/msn.c
modules/misc/playlist/m3u.c
modules/misc/playlist/old.c
modules/misc/playlist/xspf.c
modules/mux/mp4.c
modules/services_discovery/daap.c
modules/services_discovery/hal.c
modules/services_discovery/podcast.c
modules/services_discovery/sap.c
modules/visualization/xosd.c
src/Makefile.am
src/control/mediacontrol_core.c
src/control/playlist.c
src/input/es_out.c
src/input/input.c
src/input/item.c [new file with mode: 0644]
src/libvlc.c
src/playlist/control.c [new file with mode: 0644]
src/playlist/engine.c [new file with mode: 0644]
src/playlist/item-ext.c [deleted file]
src/playlist/item.c
src/playlist/loadsave.c
src/playlist/playlist.c [deleted file]
src/playlist/search.c [new file with mode: 0644]
src/playlist/sort.c
src/playlist/thread.c [new file with mode: 0644]
src/playlist/tree.c [new file with mode: 0644]
src/playlist/view.c [deleted file]
test/NativeGcTest.py [new file with mode: 0644]
test/native/gc.c [new file with mode: 0644]

index abbc0c5de302723189c197b8a11b3a6732202482..5086009ddb30cd6515f65adf73273b5f5af3b1e9 100644 (file)
@@ -1121,7 +1121,7 @@ VLC_ADD_PLUGINS([deinterlace invert adjust transform distort motionblur rv32])
 VLC_ADD_PLUGINS([fixed32tos16 s16tofixed32 u8tofixed32])
 VLC_ADD_PLUGINS([trivial_resampler ugly_resampler])
 VLC_ADD_PLUGINS([trivial_channel_mixer trivial_mixer])
-VLC_ADD_PLUGINS([playlist export sgimb m3u nsc xtag])
+VLC_ADD_PLUGINS([playlist export sgimb nsc xtag])
 VLC_ADD_PLUGINS([i420_rgb rawvideo blend scale image logo magnify])
 VLC_ADD_PLUGINS([wav araw subtitle vobsub adpcm a52sys dtssys au ty voc xa nuv])
 VLC_ADD_PLUGINS([access_directory access_file access_udp access_tcp])
index a6afd1d4b91120ba2424a4f71f8133abc764e602..f85164b0d61b9dc673426d7626cfd01c74e62eb5 100644 (file)
@@ -138,11 +138,9 @@ struct vlc_list_t
 
 /* Used by VLC_AddTarget() */
 #define PLAYLIST_INSERT          0x0001
-#define PLAYLIST_REPLACE         0x0002
-#define PLAYLIST_APPEND          0x0004
-#define PLAYLIST_GO              0x0008
-#define PLAYLIST_CHECK_INSERT    0x0010
-#define PLAYLIST_PREPARSE        0x0020
+#define PLAYLIST_APPEND          0x0002
+#define PLAYLIST_GO              0x0004
+#define PLAYLIST_PREPARSE        0x0008
 
 #define PLAYLIST_END           -666
 
index 75bafe91ae12f5bef73bbd560e757bd6a4fc08e8..7c8dbb259d7db70a4728ce8f5753274b57570324 100644 (file)
@@ -24,6 +24,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
+
 /**
  * \file
  * This file is a collection of common definitions and types
@@ -203,6 +204,7 @@ typedef struct vlc_t vlc_t;
 typedef struct variable_t variable_t;
 typedef struct date_t date_t;
 typedef struct hashtable_entry_t hashtable_entry_t;
+typedef struct gc_object_t gc_object_t ;
 
 /* Messages */
 typedef struct msg_bank_t msg_bank_t;
@@ -525,6 +527,44 @@ typedef int ( * vlc_callback_t ) ( vlc_object_t *,      /* variable's object */
 #define VLC_OBJECT( x ) \
     ((vlc_object_t *)(x))+0*(x)->be_sure_to_add_VLC_COMMON_MEMBERS_to_struct
 
+#define VLC_GC_MEMBERS                                                       \
+/** \name VLC_GC_MEMBERS                                                     \
+ * these members are common to all objects that wish to be garbage-collected \
+ */                                                                          \
+/**@{*/                                                                      \
+    int i_gc_refcount;                                                       \
+    void (*pf_destructor) ( gc_object_t * );                                 \
+    void *p_destructor_arg;                                                  \
+/**@}*/
+
+struct gc_object_t
+{
+            VLC_GC_MEMBERS
+};
+
+static inline void __vlc_gc_incref( gc_object_t * p_gc )
+{
+    p_gc->i_gc_refcount ++;
+};
+
+static inline void __vlc_gc_decref( gc_object_t *p_gc )
+{
+    p_gc->i_gc_refcount -- ;
+
+    if( p_gc->i_gc_refcount == 0 )
+    {
+        p_gc->pf_destructor( p_gc );
+        /* Do not use the p_gc pointer from now on ! */
+     }
+}
+
+#define vlc_gc_incref( a ) __vlc_gc_incref( (gc_object_t *)a )
+#define vlc_gc_decref( a ) __vlc_gc_decref( (gc_object_t *)a )
+#define vlc_gc_init( a,b,c ) {  ((gc_object_t *)a)->i_gc_refcount = 0; \
+                              ((gc_object_t *)a)->pf_destructor = b; \
+                              ((gc_object_t *)a)->p_destructor_arg = c; }
+
+
 /*****************************************************************************
  * Macros and inline functions
  *****************************************************************************/
index 966b1517bd43081f40710d0d7874b5bde6782f85..5c17718f3ba50104ea2dfbd8b6b3ac0e183345f8 100644 (file)
  * Input thread configuration
  *****************************************************************************/
 
+#define DEFAULT_INPUT_ACTIVITY 1
+#define DIRECTORY_ACTIVITY 100
+#define TRANSCODE_ACTIVITY 10
+
 /* Used in ErrorThread */
 #define INPUT_IDLE_SLEEP                ((mtime_t)(0.100*CLOCK_FREQ))
 
index fed26101c7e4612318ce0384515e3682cdc1ef02..9b9dc6a4312c13c76f776dc44746f03c5570f333 100644 (file)
 #ifndef _VLC__INPUT_H
 #define _VLC__INPUT_H 1
 
+#include <vlc_playlist.h>
+#include <vlc_meta.h>
+
+struct vlc_meta_t;
+
 /*****************************************************************************
  * input_item_t: Describes an input and is used to spawn input_thread_t objects
  *****************************************************************************/
@@ -44,29 +49,32 @@ struct info_category_t
 
 struct input_item_t
 {
+    VLC_GC_MEMBERS
+    int        i_id;                 /**< Identifier of the item */
+
     char       *psz_name;            /**< text describing this item */
     char       *psz_uri;             /**< mrl of this item */
+    vlc_bool_t  b_fixed_name;        /**< Can the interface change the name ?*/
 
     int        i_options;            /**< Number of input options */
     char       **ppsz_options;       /**< Array of input options */
 
-    mtime_t    i_duration;           /**< A hint about the duration of this
-                                      * item, in milliseconds*/
+    mtime_t    i_duration;           /**< Duration in milliseconds*/
 
-    int        i_id;                 /**< Identifier of the item */
     uint8_t    i_type;               /**< Type (file, disc, ...) */
 
     int        i_categories;         /**< Number of info categories */
     info_category_t **pp_categories; /**< Pointer to the first info category */
 
     int         i_es;                /**< Number of es format descriptions */
-    es_format_t **es;                /**< Pointer to an array of es formats */
-
-    vlc_bool_t  b_fixed_name;        /**< Can the interface change the name ?*/
+    es_format_t **es;                /**< Es formats */
 
     input_stats_t *p_stats;          /**< Statistics */
+    int           i_nb_played;       /**< Number of times played */
+
+    vlc_meta_t *p_meta;
 
-    vlc_mutex_t lock;                /**< Item cannot be changed without this lock */
+    vlc_mutex_t lock;                /**< Lock for the item */
 };
 
 #define ITEM_TYPE_UNKNOWN       0
@@ -83,18 +91,19 @@ struct input_item_t
 static inline void vlc_input_item_Init( vlc_object_t *p_o, input_item_t *p_i )
 {
     memset( p_i, 0, sizeof(input_item_t) );
-    p_i->i_options  = 0;
-    p_i->i_es = 0;
-    p_i->i_categories = 0 ;
     p_i->psz_name = 0;
     p_i->psz_uri = 0;
+    p_i->i_es = 0;
+    p_i->es = 0;
+    p_i->i_options  = 0;
     p_i->ppsz_options = 0;
+    p_i->i_categories = 0 ;
     p_i->pp_categories = 0;
-    p_i->es = 0;
     p_i->i_type = ITEM_TYPE_UNKNOWN;
     p_i->b_fixed_name = VLC_TRUE;
 
     p_i->p_stats = (input_stats_t*) malloc( sizeof( input_stats_t ) );
+    p_i->p_meta = NULL;
     vlc_mutex_init( p_o, &p_i->p_stats->lock );
 
     vlc_mutex_init( p_o, &p_i->lock );
@@ -115,6 +124,8 @@ static inline void vlc_input_item_CopyOptions( input_item_t *p_parent,
     }
 }
 
+VLC_EXPORT( void, vlc_input_item_AddOption, ( input_item_t *p_input, const char *psz_option ) );
+
 static inline void vlc_input_item_Clean( input_item_t *p_i )
 {
     if( p_i->psz_name ) free( p_i->psz_name );
@@ -123,6 +134,8 @@ static inline void vlc_input_item_Clean( input_item_t *p_i )
     p_i->psz_name = 0;
     p_i->psz_uri = 0;
 
+    if( p_i->p_meta ) vlc_meta_Delete( p_i->p_meta );
+
     while( p_i->i_options )
     {
         p_i->i_options--;
@@ -168,6 +181,14 @@ static inline void vlc_input_item_Clean( input_item_t *p_i )
 VLC_EXPORT( char *, vlc_input_item_GetInfo, ( input_item_t *p_i, const char *psz_cat,const char *psz_name ) );
 VLC_EXPORT(int, vlc_input_item_AddInfo, ( input_item_t *p_i, const char *psz_cat, const char *psz_name, const char *psz_format, ... ) );
 
+#define input_ItemNew( a,b,c ) input_ItemNewExt( a, b, c, 0, NULL, -1 )
+#define input_ItemNewExt(a,b,c,d,e,f) __input_ItemNewExt( VLC_OBJECT(a),b,c,d,e,f)
+VLC_EXPORT( input_item_t *, __input_ItemNewExt, (vlc_object_t *, const char *, const char*, int, const char **, int)  );
+VLC_EXPORT( input_item_t *, input_ItemNewWithType, ( vlc_object_t *, const char *, const char *e, int, const char **, int, int ) );
+
+VLC_EXPORT( input_item_t *, input_ItemGetById, (playlist_t *, int ) );
+
+
 /*****************************************************************************
  * Seek point: (generalisation of chapters)
  *****************************************************************************/
index f3b46a075a7cde069f431746d3d8821640e4381d..578f4cb1ec1552ff3182542579e5b6ea24dc0fa1 100644 (file)
@@ -301,9 +301,8 @@ static inline int __stats_GetInteger( vlc_object_t *p_obj, int i_id,
 static inline int __stats_GetFloat( vlc_object_t *p_obj, int i_id,
                                     unsigned int i_counter, float *value )
 {
-    int i_ret;
     vlc_value_t val;val.f_float = 0.0;
-    i_ret = __stats_Get( p_obj, i_id, i_counter, &val );
+    int i_ret = __stats_Get( p_obj, i_id, i_counter, &val );
     *value = val.f_float;
     return i_ret;
 }
index 5041fbfb92458eddc317f780b139afef71d6f938..2b427be97e295b94421057e2f9d9f6b36a388bf6 100644 (file)
 #define VLC_META_NOW_PLAYING        N_("Now Playing")
 #define VLC_META_PUBLISHER          N_("Publisher")
 
-#define VLC_META_CDDB_ARTIST        N_("CDDB Artist")
-#define VLC_META_CDDB_CATEGORY      N_("CDDB Category")
-#define VLC_META_CDDB_DISCID        N_("CDDB Disc ID")
-#define VLC_META_CDDB_EXT_DATA      N_("CDDB Extended Data")
-#define VLC_META_CDDB_GENRE         N_("CDDB Genre")
-#define VLC_META_CDDB_YEAR          N_("CDDB Year")
-#define VLC_META_CDDB_TITLE         N_("CDDB Title")
-
-#define VLC_META_CDTEXT_ARRANGER    N_("CD-Text Arranger")
-#define VLC_META_CDTEXT_COMPOSER    N_("CD-Text Composer")
-#define VLC_META_CDTEXT_DISCID      N_("CD-Text Disc ID")
-#define VLC_META_CDTEXT_GENRE       N_("CD-Text Genre")
-#define VLC_META_CDTEXT_MESSAGE     N_("CD-Text Message")
-#define VLC_META_CDTEXT_SONGWRITER  N_("CD-Text Songwriter")
-#define VLC_META_CDTEXT_PERFORMER   N_("CD-Text Performer")
-#define VLC_META_CDTEXT_TITLE       N_("CD-Text Title")
-
-#define VLC_META_ISO_APPLICATION_ID N_("ISO-9660 Application ID")
-#define VLC_META_ISO_PREPARER       N_("ISO-9660 Preparer")
-#define VLC_META_ISO_PUBLISHER      N_("ISO-9660 Publisher")
-#define VLC_META_ISO_VOLUME         N_("ISO-9660 Volume")
-#define VLC_META_ISO_VOLUMESET      N_("ISO-9660 Volume Set")
-
 #define VLC_META_CODEC_NAME         N_("Codec Name")
 #define VLC_META_CODEC_DESCRIPTION  N_("Codec Description")
 
 struct vlc_meta_t
 {
-    /* meta name/value pairs */
-    int     i_meta;
-    char    **name;
-    char    **value;
-
+    char *psz_title;
+    char *psz_author;
+    char *psz_artist;
+    char *psz_genre;
+    char *psz_copyright;
+    char *psz_album;
+    char *psz_tracknum;
+    char *psz_description;
+    char *psz_rating;
+    char *psz_date;
+    char *psz_setting;
+    char *psz_url;
+    char *psz_language;
+    char *psz_nowplaying;
+    char *psz_publisher;
+#if 0
     /* track meta information */
     int         i_track;
     vlc_meta_t  **track;
+#endif
 };
 
+#define vlc_meta_Set( meta,var,val ) { \
+    if( meta->psz_##var ) free( meta->psz_##var ); \
+    meta->psz_##var = strdup( val ); }
+
+#define vlc_meta_SetTitle( meta, b ) vlc_meta_Set( meta, title, b );
+#define vlc_meta_SetArtist( meta, b ) vlc_meta_Set( meta, artist, b );
+#define vlc_meta_SetAuthor( meta, b ) vlc_meta_Set( meta, author, b );
+#define vlc_meta_SetGenre( meta, b ) vlc_meta_Set( meta, genre, b );
+#define vlc_meta_SetCopyright( meta, b ) vlc_meta_Set( meta, copyright, b );
+#define vlc_meta_SetAlbum( meta, b ) vlc_meta_Set( meta, album, b );
+#define vlc_meta_SetTracknum( meta, b ) vlc_meta_Set( meta, tracknum, b );
+#define vlc_meta_SetDescription( meta, b ) vlc_meta_Set( meta, description, b );
+#define vlc_meta_SetRating( meta, b ) vlc_meta_Set( meta, rating, b );
+#define vlc_meta_SetDate( meta, b ) vlc_meta_Set( meta, date, b );
+#define vlc_meta_SetSetting( meta, b ) vlc_meta_Set( meta, setting, b );
+#define vlc_meta_SetURL( meta, b ) vlc_meta_Set( meta, url, b );
+#define vlc_meta_SetLanguage( meta, b ) vlc_meta_Set( meta, language, b );
+#define vlc_meta_SetNowPlaying( meta, b ) vlc_meta_Set( meta, nowplaying, b );
+#define vlc_meta_SetPublisher( meta, b ) vlc_meta_Set( meta, publisher, b );
+
 static inline vlc_meta_t *vlc_meta_New( void )
 {
     vlc_meta_t *m = (vlc_meta_t*)malloc( sizeof( vlc_meta_t ) );
-
-    m->i_meta = 0;
-    m->name   = NULL;
-    m->value  = NULL;
-
-    m->i_track= 0;
-    m->track  = NULL;
-
+    if( !m ) return NULL;
+    m->psz_title = NULL;
+    m->psz_author = NULL;
+    m->psz_artist = NULL;
+    m->psz_genre = NULL;
+    m->psz_copyright = NULL;
+    m->psz_album = NULL;
+    m->psz_tracknum = NULL;
+    m->psz_description = NULL;
+    m->psz_rating = NULL;
+    m->psz_date = NULL;
+    m->psz_setting = NULL;
+    m->psz_url = NULL;
+    m->psz_language = NULL;
+    m->psz_nowplaying = NULL;
+    m->psz_publisher = NULL;
     return m;
 }
 
 static inline void vlc_meta_Delete( vlc_meta_t *m )
 {
-    int i;
-    for( i = 0; i < m->i_meta; i++ )
-    {
-        free( m->name[i] );
-        free( m->value[i] );
-    }
-    if( m->name ) free( m->name );
-    if( m->value ) free( m->value );
+    free( m->psz_title );
+    free( m->psz_author );
+    free( m->psz_artist );
+    free( m->psz_genre );
+    free( m->psz_copyright );
+    free( m->psz_album );
+    free( m->psz_tracknum );
+    free( m->psz_description );
+    free( m->psz_rating );
+    free( m->psz_date );
+    free( m->psz_setting );
+    free( m->psz_url );
+    free( m->psz_language );
+    free( m->psz_nowplaying );
+    free( m->psz_publisher );
 
-    for( i = 0; i < m->i_track; i++ )
-    {
-        vlc_meta_Delete( m->track[i] );
-    }
-    if( m->track ) free( m->track );
     free( m );
 }
 
-static inline void vlc_meta_Add( vlc_meta_t *m,
-                                 const char *name, const char *value )
-{
-    m->name  = (char**)realloc( m->name, sizeof(char*) * ( m->i_meta + 1 ) );
-    m->name[m->i_meta] = strdup( name );
-
-    m->value = (char**)realloc( m->value, sizeof(char*) * ( m->i_meta + 1 ) );
-    m->value[m->i_meta] = strdup( value );
-
-    m->i_meta++;
-}
-
-static inline vlc_meta_t *vlc_meta_Duplicate( vlc_meta_t *src )
-{
-    vlc_meta_t *dst = vlc_meta_New();
-    int i;
-    for( i = 0; i < src->i_meta; i++ )
-    {
-        vlc_meta_Add( dst, src->name[i], src->value[i] );
-    }
-    for( i = 0; i < src->i_track; i++ )
-    {
-        vlc_meta_t *tk = vlc_meta_Duplicate( src->track[i] );
-
-        dst->track = (vlc_meta_t**)realloc( dst->track, sizeof( vlc_meta_t* ) * (dst->i_track+1) );
-        dst->track[dst->i_track++] = tk;
-    }
-    return dst;
-}
-
 static inline void vlc_meta_Merge( vlc_meta_t *dst, vlc_meta_t *src )
 {
-    int i, j;
-    for( i = 0; i < src->i_meta; i++ )
-    {
-        /* Check if dst contains the entry */
-        for( j = 0; j < dst->i_meta; j++ )
-        {
-            if( !strcmp( src->name[i], dst->name[j] ) ) break;
-        }
-        if( j < dst->i_meta )
-        {
-            if( dst->value[j] ) free( dst->value[j] );
-            dst->value[j] = strdup( src->value[i] );
-        }
-        else vlc_meta_Add( dst, src->name[i], src->value[i] );
-    }
-}
-
-static inline char *vlc_meta_GetValue( vlc_meta_t *m, const char *name )
-{
-    int i;
-
-    for( i = 0; i < m->i_meta; i++ )
-    {
-        if( !strcmp( m->name[i], name ) )
-        {
-            char *value = NULL;
-            if( m->value[i] ) value = strdup( m->value[i] );
-            return value;
-        }
+    if( !dst || !src ) return;
+#define COPY_FIELD( a ) \
+    if( src->psz_ ## a ) { \
+        if( dst->psz_ ## a ) free( dst->psz_## a ); \
+        dst->psz_##a = strdup( src->psz_##a ); \
     }
-    return NULL;
+    COPY_FIELD( title );
+    COPY_FIELD( author );
+    COPY_FIELD( artist );
+    COPY_FIELD( genre );
+    COPY_FIELD( copyright );
+    COPY_FIELD( album );
+    COPY_FIELD( tracknum );
+    COPY_FIELD( description );
+    COPY_FIELD( rating );
+    COPY_FIELD( date );
+    COPY_FIELD( setting );
+    COPY_FIELD( url );
+    COPY_FIELD( language );
+    COPY_FIELD( nowplaying );
+    COPY_FIELD( publisher );
 }
+    /** \todo Track meta */
 
 #endif
index 009b9f5488653c67e59a4acb77aafa4f96fd1357..6f8af171419095bfa2f132b4da2767ad01de8adf 100644 (file)
@@ -23,7 +23,7 @@
 
 /**
  * \file
- * This file defines the vlc_object_t structure and object types
+ * This file defines the vlc_object_t structure and object types.
  */
 
 /**
@@ -100,6 +100,7 @@ VLC_EXPORT( void, __vlc_object_release, ( vlc_object_t * ) );
 VLC_EXPORT( vlc_list_t *, __vlc_list_find, ( vlc_object_t *, int, int ) );
 VLC_EXPORT( void, vlc_list_release, ( vlc_list_t * ) );
 VLC_EXPORT( vlc_t *, vlc_current_object, ( int ) );
+
 /*}@*/
 
 #define vlc_object_create(a,b) \
@@ -129,4 +130,3 @@ VLC_EXPORT( vlc_t *, vlc_current_object, ( int ) );
 
 #define vlc_list_find(a,b,c) \
     __vlc_list_find( VLC_OBJECT(a),b,c)
-
index bb458706aaeb15ba657c5d11c39ca4ff1541e744..d701fbd474963197a9cbbff6099eb8968d94d36c 100644 (file)
@@ -21,6 +21,9 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
+#ifndef _VLC_PLAYLIST_H_
+#define _VLC_PLAYLIST_H_
+
 /**
  *  \file
  *  This file contain structures and function prototypes related
@@ -40,12 +43,7 @@ struct playlist_export_t
 {
     char *psz_filename;
     FILE *p_file;
-};
-
-struct item_parent_t
-{
-    int i_view;
-    playlist_item_t *p_parent;
+    playlist_item_t *p_root;
 };
 
 /**
@@ -54,70 +52,31 @@ struct item_parent_t
  */
 struct playlist_item_t
 {
-    input_item_t           input;       /**< input item descriptor */
+    input_item_t           *p_input;    /**< input item descriptor */
 
     /* Tree specific fields */
     int                    i_children;  /**< Number of children
                                              -1 if not a node */
     playlist_item_t      **pp_children; /**< Children nodes/items */
-    int                    i_parents;   /**< Number of parents */
-    struct item_parent_t **pp_parents;  /**< Parents */
-    int                    i_serial;    /**< Has this node been updated ? */
-
-    uint8_t                i_flags;     /**< Flags */
-
+    playlist_item_t       *p_parent;    /**< Item parent */
 
-    int        i_nb_played;       /**< How many times was this item played ? */
+    int                    i_id;        /**< Playlist item specific id */
 
-    /* LEGACY FIELDS */
-    vlc_bool_t b_autodeletion;    /**< Indicates whther this item is to
-                                   * be deleted after playback. True mean
-                                   * that this item is to be deleted
-                                   * after playback, false otherwise */
-    vlc_bool_t b_enabled;         /**< Indicates whether this item is to be
-                                   * played or skipped */
-    /* END LEGACY FIELDS */
+    uint8_t                i_flags;     /**< Flags */
 };
 
-#define PLAYLIST_SAVE_FLAG      0x01     /**< Must it be saved */
-#define PLAYLIST_SKIP_FLAG      0x02     /**< Must playlist skip after it ? */
-#define PLAYLIST_ENA_FLAG       0x04     /**< Is it enabled ? */
-#define PLAYLIST_DEL_FLAG       0x08     /**< Autodelete ? */
+#define PLAYLIST_SAVE_FLAG      0x01    /**< Must it be saved */
+#define PLAYLIST_SKIP_FLAG      0x02    /**< Must playlist skip after it ? */
+#define PLAYLIST_DBL_FLAG       0x04    /**< Is it disabled ? */
 #define PLAYLIST_RO_FLAG        0x10    /**< Write-enabled ? */
 #define PLAYLIST_REMOVE_FLAG    0x20    /**< Remove this item at the end */
-
-/**
- * playlist view
- * \see playlist_t
-*/
-struct playlist_view_t
-{
-    char            *   psz_name;        /**< View name */
-    int                 i_id;            /**< Identifier for the view */
-    playlist_item_t *   p_root;          /**< Root node */
-};
-
-
-/**
- * predefined views
- *
- */
-#define VIEW_CATEGORY 1
-#define VIEW_SIMPLE   2
-#define VIEW_ALL      3
-#define VIEW_FIRST_SORTED  4
-#define VIEW_S_AUTHOR 4
-#define VIEW_S_GENRE 5
-#define VIEW_S_ALBUM  6
-
-#define VIEW_LAST_SORTED  10
-
-#define VIEW_FIRST_CUSTOM 100
+#define PLAYLIST_EXPANDED_FLAG  0x40    /**< Expanded node */
 
 /**
  * Playlist status
  */
-typedef enum { PLAYLIST_STOPPED,PLAYLIST_RUNNING,PLAYLIST_PAUSED } playlist_status_t;
+typedef enum
+{ PLAYLIST_STOPPED,PLAYLIST_RUNNING,PLAYLIST_PAUSED } playlist_status_t;
 
 
 struct services_discovery_t
@@ -136,7 +95,7 @@ struct playlist_preparse_t
     VLC_COMMON_MEMBERS
     vlc_mutex_t     lock;
     int             i_waiting;
-    int            *pi_waiting;
+    input_item_t  **pp_waiting;
 };
 
 
@@ -151,7 +110,6 @@ struct playlist_t
    These members are uniq to playlist_t
 */
 /*@{*/
-    int                   i_index;  /**< current index into the playlist */
     int                   i_enabled; /**< How many items are enabled ? */
 
     int                   i_size;   /**< total size of the list */
@@ -160,65 +118,59 @@ struct playlist_t
     int                   i_all_size; /**< size of list of items and nodes */
     playlist_item_t **    pp_all_items; /**< array of pointers to the
                                          * playlist items and nodes */
+    int                   i_last_playlist_id; /**< Last id to an item */
 
-    int                   i_views; /**< Number of views */
-    playlist_view_t **    pp_views; /**< array of pointers to the
-                                     * playlist views */
+    int                   i_input_items;
+    input_item_t **    pp_input_items;
 
-    input_thread_t *      p_input;  /**< the input thread ascosiated
-                                     * with the current item */
+    int                  i_last_input_id ;
 
-    mtime_t               request_date; /**< Used for profiling */
+    input_thread_t *      p_input;  /**< the input thread associated
+                                     * with the current item */
 
-    int                   i_last_id; /**< Last id to an item */
     int                   i_sort; /**< Last sorting applied to the playlist */
     int                   i_order; /**< Last ordering applied to the playlist */
 
-    playlist_item_t *    p_general; /**< Keep a pointer on the "general"
-                                        category */
+    playlist_item_t *     p_root_category;
+    playlist_item_t *     p_root_onelevel;
+
+    playlist_item_t *     p_local_category; /** < "Playlist" in CATEGORY view */
+    playlist_item_t *     p_ml_category; /** < "Library" in CATEGORY view */
+    playlist_item_t *     p_local_onelevel; /** < "Playlist" in ONELEVEL view */
+    playlist_item_t *     p_ml_onelevel; /** < "Library" in ONELEVEL iew */
 
     services_discovery_t **pp_sds;
     int                   i_sds;
 
-    vlc_bool_t          b_go_next; /*< Go further than the parent node ? */
-
     struct {
-        /* Current status */
+        /* Current status. These fields are readonly, only the playlist
+         * main loop can touch it*/
         playlist_status_t   i_status;  /**< Current status of playlist */
-
-        /* R/O fields, don't touch if you aren't the playlist thread */
-        /* Use a request */
         playlist_item_t *   p_item; /**< Currently playing/active item */
-        playlist_item_t *   p_node;   /**< Current node to play from */
-        int                 i_view;    /**< Current view */
+        playlist_item_t *   p_node; /**< Current node to play from */
     } status;
 
     struct {
-        /* Request */
-        /* Playlist thread uses this info to calculate the next position */
-        int                 i_view;   /**< requested view id */
+        /* Request. Use this to give orders to the playlist main loop  */
+        int                 i_status; /**< requested playlist status */
         playlist_item_t *   p_node;   /**< requested node to play from */
         playlist_item_t *   p_item;   /**< requested item to play in the node */
 
         int                 i_skip;   /**< Number of items to skip */
-        int                 i_goto;   /**< Direct index to go to (non-view)*/
 
-        vlc_bool_t          b_request; /**< Set to true by the requester
-                                            The playlist sets it back to false
-                                            when processing the request */
-        vlc_mutex_t         lock;      /**< Lock to protect request */
+        vlc_bool_t          b_request;/**< Set to true by the requester
+                                           The playlist sets it back to false
+                                           when processing the request */
+        vlc_mutex_t         lock;     /**< Lock to protect request */
     } request;
 
-    playlist_preparse_t     *p_preparse;
+    playlist_preparse_t     *p_preparse; /**< Preparser object */
 
     vlc_mutex_t gc_lock;         /**< Lock to protect the garbage collection */
 
-    // The following members are about user interaction
-    // The playlist manages the user interaction to avoid creating another
-    // thread
-    interaction_t *p_interaction;
-
-    global_stats_t *p_stats;
+    // Playlist-unrelated fields
+    interaction_t *p_interaction;       /**< Interaction manager */
+    global_stats_t *p_stats;            /**< Global statistics */
 
     /*@}*/
 };
@@ -249,10 +201,27 @@ struct playlist_add_t
  * Prototypes
  *****************************************************************************/
 
+/* Global thread */
+#define playlist_ThreadCreate(a) __playlist_ThreadCreate(VLC_OBJECT(a))
+playlist_t *__playlist_ThreadCreate   ( vlc_object_t * );
+int           playlist_ThreadDestroy  ( playlist_t * );
+
+/* Helpers */
+#define PL_LOCK vlc_mutex_lock( &p_playlist->object_lock );
+#define PL_UNLOCK vlc_mutex_unlock( &p_playlist->object_lock );
+
 /* Creation/Deletion */
-#define playlist_Create(a) __playlist_Create(VLC_OBJECT(a))
-playlist_t * __playlist_Create   ( vlc_object_t * );
-int            playlist_Destroy  ( playlist_t * );
+playlist_t *playlist_Create   ( vlc_object_t * );
+void        playlist_Destroy  ( playlist_t * );
+
+/* Engine */
+void playlist_MainLoop( playlist_t * );
+void playlist_LastLoop( playlist_t * );
+void playlist_PreparseLoop( playlist_preparse_t * );
+
+/* Control */
+playlist_item_t * playlist_NextItem  ( playlist_t * );
+int playlist_PlayItem  ( playlist_t *, playlist_item_t * );
 
 /* Playlist control */
 #define playlist_Play(p) playlist_LockControl(p,PLAYLIST_PLAY )
@@ -261,13 +230,12 @@ int            playlist_Destroy  ( playlist_t * );
 #define playlist_Next(p) playlist_LockControl(p,PLAYLIST_SKIP, 1)
 #define playlist_Prev(p) playlist_LockControl(p,PLAYLIST_SKIP, -1)
 #define playlist_Skip(p,i) playlist_LockControl(p,PLAYLIST_SKIP, i)
-#define playlist_Goto(p,i) playlist_LockControl(p,PLAYLIST_GOTO, i)
 
 VLC_EXPORT( int, playlist_Control, ( playlist_t *, int, ...  ) );
 VLC_EXPORT( int, playlist_LockControl, ( playlist_t *, int, ...  ) );
 
-VLC_EXPORT( int,  playlist_Clear, ( playlist_t * ) );
-VLC_EXPORT( int,  playlist_LockClear, ( playlist_t * ) );
+VLC_EXPORT( void,  playlist_Clear, ( playlist_t * ) );
+VLC_EXPORT( void,  playlist_LockClear, ( playlist_t * ) );
 
 VLC_EXPORT( int, playlist_PreparseEnqueue, (playlist_t *, input_item_t *) );
 VLC_EXPORT( int, playlist_PreparseEnqueueItem, (playlist_t *, playlist_item_t *) );
@@ -281,80 +249,99 @@ VLC_EXPORT( vlc_bool_t, playlist_IsServicesDiscoveryLoaded, ( playlist_t *,const
 
 
 /* Item management functions (act on items) */
-#define playlist_AddItem(p,pi,i1,i2) playlist_ItemAdd(p,pi,i1,i2)
 #define playlist_ItemNew( a , b, c ) __playlist_ItemNew(VLC_OBJECT(a) , b , c )
 #define playlist_ItemCopy( a, b ) __playlist_ItemCopy(VLC_OBJECT(a), b )
 VLC_EXPORT( playlist_item_t* , __playlist_ItemNew, ( vlc_object_t *,const char *,const char * ) );
 VLC_EXPORT( playlist_item_t* , __playlist_ItemCopy, ( vlc_object_t *,playlist_item_t* ) );
-VLC_EXPORT( playlist_item_t* , playlist_ItemNewWithType, ( vlc_object_t *,const char *,const char *, int ) );
+VLC_EXPORT( playlist_item_t* , playlist_ItemNewWithType, ( vlc_object_t *,const char *,const char *, int , const char **, int, int) );
+#define playlist_ItemNewFromInput(a,b) __playlist_ItemNewFromInput(VLC_OBJECT(a),b)
+VLC_EXPORT( playlist_item_t *, __playlist_ItemNewFromInput, ( vlc_object_t *p_obj,input_item_t *p_input ) );
+
+
 VLC_EXPORT( int, playlist_ItemDelete, ( playlist_item_t * ) );
-VLC_EXPORT( int, playlist_ItemAddParent, ( playlist_item_t *, int,playlist_item_t *) );
-VLC_EXPORT( int, playlist_CopyParents, ( playlist_item_t *,playlist_item_t *) );
+
 /* Item informations accessors */
 VLC_EXPORT( int, playlist_ItemSetName, (playlist_item_t *,  char * ) );
 VLC_EXPORT( int, playlist_ItemSetDuration, (playlist_item_t *, mtime_t ) );
 
+VLC_EXPORT( void, playlist_ItemAddOption, (playlist_item_t *, const char *) );
 
-/* View management functions */
-VLC_EXPORT( int, playlist_ViewInsert, (playlist_t *, int, char * ) );
-VLC_EXPORT( int, playlist_ViewDelete, (playlist_t *,playlist_view_t* ) );
-VLC_EXPORT( playlist_view_t *, playlist_ViewFind, (playlist_t *, int ) );
-VLC_EXPORT( int, playlist_ViewUpdate, (playlist_t *, int ) );
-VLC_EXPORT( int, playlist_ViewDump, (playlist_t *, playlist_view_t * ) );
-VLC_EXPORT( int, playlist_ViewEmpty, (playlist_t *, int, vlc_bool_t ) );
+VLC_EXPORT(void, playlist_NodeDump, ( playlist_t *p_playlist, playlist_item_t *p_item, int i_level ) );
+
+/** Counts the items of a view */
+VLC_EXPORT( int, playlist_NodeChildrenCount, (playlist_t *,playlist_item_t* ) );
 
 /* Node management */
-VLC_EXPORT( playlist_item_t *, playlist_NodeCreate, ( playlist_t *,int,char *, playlist_item_t * p_parent ) );
-VLC_EXPORT( int, playlist_NodeAppend, (playlist_t *,int,playlist_item_t*,playlist_item_t *) );
-VLC_EXPORT( int, playlist_NodeInsert, (playlist_t *,int,playlist_item_t*,playlist_item_t *, int) );
+VLC_EXPORT( playlist_item_t *, playlist_NodeCreate, ( playlist_t *, char *, playlist_item_t * p_parent ) );
+VLC_EXPORT( int, playlist_NodeAppend, (playlist_t *,playlist_item_t*,playlist_item_t *) );
+VLC_EXPORT( int, playlist_NodeInsert, (playlist_t *,playlist_item_t*,playlist_item_t *, int) );
 VLC_EXPORT( int, playlist_NodeRemoveItem, (playlist_t *,playlist_item_t*,playlist_item_t *) );
-VLC_EXPORT( int, playlist_NodeRemoveParent, (playlist_t *,playlist_item_t*,playlist_item_t *) );
-VLC_EXPORT( int, playlist_NodeChildrenCount, (playlist_t *,playlist_item_t* ) );
 VLC_EXPORT( playlist_item_t *, playlist_ChildSearchName, (playlist_item_t*, const char* ) );
 VLC_EXPORT( int, playlist_NodeDelete, ( playlist_t *, playlist_item_t *, vlc_bool_t , vlc_bool_t ) );
 VLC_EXPORT( int, playlist_NodeEmpty, ( playlist_t *, playlist_item_t *, vlc_bool_t ) );
 
-/* Tree walking */
-playlist_item_t *playlist_FindNextFromParent( playlist_t *p_playlist,
-                int i_view,
-                playlist_item_t *p_root,
-                playlist_item_t *p_node,
-                playlist_item_t *p_item );
-playlist_item_t *playlist_FindPrevFromParent( playlist_t *p_playlist,
-                int i_view,
-                playlist_item_t *p_root,
-                playlist_item_t *p_node,
-                playlist_item_t *p_item );
+/* Tree walking - These functions are only for playlist, not plugins */
+playlist_item_t *playlist_GetNextLeaf( playlist_t *p_playlist,
+                                       playlist_item_t *p_root,
+                                       playlist_item_t *p_item );
+playlist_item_t *playlist_GetNextEnabledLeaf( playlist_t *p_playlist,
+                                              playlist_item_t *p_root,
+                                              playlist_item_t *p_item );
+playlist_item_t *playlist_GetPrevLeaf( playlist_t *p_playlist,
+                                       playlist_item_t *p_root,
+                                       playlist_item_t *p_item );
+playlist_item_t *playlist_GetLastLeaf( playlist_t *p_playlist,
+                                       playlist_item_t *p_root );
 
 
 /* Simple add/remove functions */
-/* These functions add the item to the "simple" view (+all & category )*/
-VLC_EXPORT( int,  playlist_Add,    ( playlist_t *, const char *, const char *, int, int ) );
-VLC_EXPORT( int,  playlist_AddExt, ( playlist_t *, const char *, const char *, int, int, mtime_t, const char **,int ) );
-VLC_EXPORT( int,  playlist_ItemAdd, ( playlist_t *, playlist_item_t *, int, int ) );
-VLC_EXPORT(int, playlist_NodeAddItem, ( playlist_t *, playlist_item_t *,int,playlist_item_t *,int , int ) );
+VLC_EXPORT( int,  playlist_PlaylistAdd,    ( playlist_t *, const char *, const char *, int, int ) );
+VLC_EXPORT( int,  playlist_PlaylistAddExt, ( playlist_t *, const char *, const char *, int, int, mtime_t, const char **,int ) );
+VLC_EXPORT( int, playlist_PlaylistAddInput, ( playlist_t *, input_item_t *,int , int ) );
+VLC_EXPORT( playlist_item_t *, playlist_NodeAddInput, ( playlist_t *, input_item_t *,playlist_item_t *,int , int ) );
+VLC_EXPORT( void, playlist_NodeAddItem, ( playlist_t *, playlist_item_t *, playlist_item_t *,int , int ) );
+VLC_EXPORT( int, playlist_BothAddInput, ( playlist_t *, input_item_t *,playlist_item_t *,int , int ) );
+VLC_EXPORT( void, playlist_AddWhereverNeeded, (playlist_t* , input_item_t*, playlist_item_t*,playlist_item_t*,vlc_bool_t, int ) );
+
+void playlist_SendAddNotify( playlist_t *p_playlist, int i_item_id, int i_node_id );
 
 /* Misc item operations (act on item+playlist) */
-VLC_EXPORT( int,  playlist_Delete, ( playlist_t *, int ) );
+VLC_EXPORT( int,  playlist_DeleteAllFromInput, ( playlist_t *, int ) );
+VLC_EXPORT( int,  playlist_DeleteFromInput, ( playlist_t *, int, playlist_item_t *, vlc_bool_t ) );
+VLC_EXPORT( int,  playlist_DeleteFromItemId, ( playlist_t *, int ) );
 VLC_EXPORT( int,  playlist_LockDelete, ( playlist_t *, int ) );
-VLC_EXPORT( int,  playlist_Disable, ( playlist_t *, playlist_item_t * ) );
-VLC_EXPORT( int,  playlist_Enable, ( playlist_t *, playlist_item_t * ) );
-VLC_EXPORT( int, playlist_ItemToNode, (playlist_t *,playlist_item_t *) );
-VLC_EXPORT( int, playlist_LockItemToNode, (playlist_t *,playlist_item_t *) );
-VLC_EXPORT( int, playlist_Replace, (playlist_t *,playlist_item_t *, input_item_t*) );
-VLC_EXPORT( int, playlist_LockReplace, (playlist_t *,playlist_item_t *, input_item_t*) );
+VLC_EXPORT( int,  playlist_LockDeleteAllFromInput, ( playlist_t *, int ) );
+VLC_EXPORT( playlist_item_t*, playlist_ItemToNode, (playlist_t *,playlist_item_t *) );
+VLC_EXPORT( playlist_item_t*, playlist_LockItemToNode, (playlist_t *,playlist_item_t *) );
 
+playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist,
+                                   int i_input_id, playlist_item_t *p_root );
 
 /* Item search functions */
 VLC_EXPORT( playlist_item_t *, playlist_ItemGetById, (playlist_t *, int) );
-VLC_EXPORT( playlist_item_t *, playlist_LockItemGetById, (playlist_t *, int) );
-VLC_EXPORT( playlist_item_t *, playlist_ItemGetByPos, (playlist_t *, int) );
-VLC_EXPORT( playlist_item_t *, playlist_LockItemGetByPos, (playlist_t *, int) );
 VLC_EXPORT( playlist_item_t *, playlist_ItemGetByInput, (playlist_t *,input_item_t * ) );
-VLC_EXPORT( playlist_item_t *, playlist_LockItemGetByInput, (playlist_t *,input_item_t * ) );
-VLC_EXPORT( int, playlist_GetPositionById, (playlist_t *,int ) );
 
-VLC_EXPORT( int, playlist_ItemAddOption, (playlist_item_t *, const char *) );
+static inline playlist_item_t *playlist_LockItemGetById( playlist_t *p_playlist,
+                                                         int i_id)
+{
+    playlist_item_t *p_ret;
+    vlc_mutex_lock( &p_playlist->object_lock );
+    p_ret = playlist_ItemGetById( p_playlist, i_id );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+    return p_ret;
+}
+
+static inline playlist_item_t *playlist_LockItemGetByInput(
+                                playlist_t *p_playlist, input_item_t *p_item )
+{
+    playlist_item_t *p_ret;
+    vlc_mutex_lock( &p_playlist->object_lock );
+    p_ret = playlist_ItemGetByInput( p_playlist, p_item );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+    return p_ret;
+}
+
+VLC_EXPORT( int, playlist_LiveSearchUpdate, (playlist_t *, playlist_item_t *, const char *) );
 
 /* Playlist sorting */
 #define playlist_SortID(p, i) playlist_Sort( p, SORT_ID, i)
@@ -362,56 +349,41 @@ VLC_EXPORT( int, playlist_ItemAddOption, (playlist_item_t *, const char *) );
 #define playlist_SortAuthor(p, i) playlist_Sort( p, SORT_AUTHOR, i)
 #define playlist_SortAlbum(p, i) playlist_Sort( p, SORT_ALBUM, i)
 #define playlist_SortGroup(p, i) playlist_Sort( p, SORT_GROUP, i)
-VLC_EXPORT( int,  playlist_Sort, ( playlist_t *, int, int) );
-VLC_EXPORT( int,  playlist_Move, ( playlist_t *, int, int ) );
-VLC_EXPORT( int,  playlist_TreeMove, ( playlist_t *, playlist_item_t *, playlist_item_t *, int, int ) );
-VLC_EXPORT( int,  playlist_NodeGroup, ( playlist_t *, int,playlist_item_t *,playlist_item_t **,int, int, int ) );
+VLC_EXPORT( int,  playlist_TreeMove, ( playlist_t *, playlist_item_t *, playlist_item_t *, int ) );
+VLC_EXPORT( int,  playlist_NodeGroup, ( playlist_t *, playlist_item_t *,playlist_item_t **,int, int, int ) );
 VLC_EXPORT( int,  playlist_NodeSort, ( playlist_t *, playlist_item_t *,int, int ) );
 VLC_EXPORT( int,  playlist_RecursiveNodeSort, ( playlist_t *, playlist_item_t *,int, int ) );
 
 /* Load/Save */
 VLC_EXPORT( int,  playlist_Import, ( playlist_t *, const char * ) );
-VLC_EXPORT( int,  playlist_Export, ( playlist_t *, const char *, const char * ) );
+VLC_EXPORT( int,  playlist_Export, ( playlist_t *, const char *, playlist_item_t *, const char * ) );
 
 /***********************************************************************
  * Inline functions
  ***********************************************************************/
 
-
-/**
- *  tell if a playlist is currently playing.
- *  \param p_playlist the playlist to check
- *  \return true if playlist is playing, false otherwise
- */
+/** Tell if the playlist is currently running */
 static inline vlc_bool_t playlist_IsPlaying( playlist_t * p_playlist )
 {
     vlc_bool_t b_playing;
-
     vlc_mutex_lock( &p_playlist->object_lock );
     b_playing = p_playlist->status.i_status == PLAYLIST_RUNNING;
     vlc_mutex_unlock( &p_playlist->object_lock );
-
     return( b_playing );
 }
 
-/**
- *  tell if a playlist is currently empty
- *  \param p_playlist the playlist to check
- *  \return true if the playlist is empty, false otherwise
- */
+/** Tell if the playlist is empty */
 static inline vlc_bool_t playlist_IsEmpty( playlist_t * p_playlist )
 {
     vlc_bool_t b_empty;
-
     vlc_mutex_lock( &p_playlist->object_lock );
     b_empty = p_playlist->i_size == 0;
     vlc_mutex_unlock( &p_playlist->object_lock );
-
     return( b_empty );
 }
 
-
-
 /**
  * @}
  */
+
+#endif
index 5bff63cbcc0e710f3a0844668c81c48873639731..52622d837d7653a707c44bfbbe85c98ebf0335fb 100644 (file)
@@ -258,8 +258,8 @@ struct module_symbols_t
     void (*vlc_list_release_inner) (vlc_list_t *);
     int (*playlist_Control_inner) (playlist_t *, int, ...);
     int (*playlist_LockControl_inner) (playlist_t *, int, ...);
-    int (*playlist_Clear_inner) (playlist_t *);
-    int (*playlist_LockClear_inner) (playlist_t *);
+    void (*playlist_Clear_inner) (playlist_t *);
+    void (*playlist_LockClear_inner) (playlist_t *);
     int (*playlist_PreparseEnqueue_inner) (playlist_t *, input_item_t *);
     int (*playlist_ServicesDiscoveryAdd_inner) (playlist_t *, const char *);
     int (*playlist_ServicesDiscoveryRemove_inner) (playlist_t *, const char *);
@@ -267,53 +267,53 @@ struct module_symbols_t
     vlc_bool_t (*playlist_IsServicesDiscoveryLoaded_inner) (playlist_t *,const char *);
     playlist_item_t* (*__playlist_ItemNew_inner) (vlc_object_t *,const char *,const char *);
     playlist_item_t* (*__playlist_ItemCopy_inner) (vlc_object_t *,playlist_item_t*);
-    playlist_item_t* (*playlist_ItemNewWithType_inner) (vlc_object_t *,const char *,const char *, int);
+    playlist_item_t* (*playlist_ItemNewWithType_inner) (vlc_object_t *,const char *,const char *, int , const char **, int, int);
     int (*playlist_ItemDelete_inner) (playlist_item_t *);
-    int (*playlist_ItemAddParent_inner) (playlist_item_t *, int,playlist_item_t *);
-    int (*playlist_CopyParents_inner) (playlist_item_t *,playlist_item_t *);
+    void *playlist_ItemAddParent_deprecated;
+    void *playlist_CopyParents_deprecated;
     int (*playlist_ItemSetName_inner) (playlist_item_t *,  char *);
     int (*playlist_ItemSetDuration_inner) (playlist_item_t *, mtime_t);
-    int (*playlist_ViewInsert_inner) (playlist_t *, int, char *);
-    int (*playlist_ViewDelete_inner) (playlist_t *,playlist_view_t*);
-    playlist_view_t * (*playlist_ViewFind_inner) (playlist_t *, int);
-    int (*playlist_ViewUpdate_inner) (playlist_t *, int);
-    int (*playlist_ViewDump_inner) (playlist_t *, playlist_view_t *);
-    int (*playlist_ViewEmpty_inner) (playlist_t *, int, vlc_bool_t);
-    playlist_item_t * (*playlist_NodeCreate_inner) (playlist_t *,int,char *, playlist_item_t * p_parent);
-    int (*playlist_NodeAppend_inner) (playlist_t *,int,playlist_item_t*,playlist_item_t *);
-    int (*playlist_NodeInsert_inner) (playlist_t *,int,playlist_item_t*,playlist_item_t *, int);
+    void *playlist_ViewInsert_deprecated;
+    void *playlist_ViewDelete_deprecated;
+    void *playlist_ViewFind_deprecated;
+    void *playlist_ViewUpdate_deprecated;
+    void *playlist_ViewDump_deprecated;
+    void *playlist_ViewEmpty_deprecated;
+    playlist_item_t * (*playlist_NodeCreate_inner) (playlist_t *, char *, playlist_item_t * p_parent);
+    int (*playlist_NodeAppend_inner) (playlist_t *,playlist_item_t*,playlist_item_t *);
+    int (*playlist_NodeInsert_inner) (playlist_t *,playlist_item_t*,playlist_item_t *, int);
     int (*playlist_NodeRemoveItem_inner) (playlist_t *,playlist_item_t*,playlist_item_t *);
     int (*playlist_NodeChildrenCount_inner) (playlist_t *,playlist_item_t*);
     playlist_item_t * (*playlist_ChildSearchName_inner) (playlist_item_t*, const char*);
     int (*playlist_NodeDelete_inner) (playlist_t *, playlist_item_t *, vlc_bool_t , vlc_bool_t);
     int (*playlist_NodeEmpty_inner) (playlist_t *, playlist_item_t *, vlc_bool_t);
-    int (*playlist_Add_inner) (playlist_t *, const char *, const char *, int, int);
-    int (*playlist_AddExt_inner) (playlist_t *, const char *, const char *, int, int, mtime_t, const char **,int);
-    int (*playlist_ItemAdd_inner) (playlist_t *, playlist_item_t *, int, int);
-    int (*playlist_NodeAddItem_inner) (playlist_t *, playlist_item_t *,int,playlist_item_t *,int , int);
-    int (*playlist_Delete_inner) (playlist_t *, int);
+    void *playlist_Add_deprecated;
+    void *playlist_AddExt_deprecated;
+    void *playlist_ItemAdd_deprecated;
+    void (*playlist_NodeAddItem_inner) (playlist_t *, playlist_item_t *, playlist_item_t *,int , int);
+    void *playlist_Delete_deprecated;
     int (*playlist_LockDelete_inner) (playlist_t *, int);
-    int (*playlist_Disable_inner) (playlist_t *, playlist_item_t *);
-    int (*playlist_Enable_inner) (playlist_t *, playlist_item_t *);
-    int (*playlist_ItemToNode_inner) (playlist_t *,playlist_item_t *);
-    int (*playlist_LockItemToNode_inner) (playlist_t *,playlist_item_t *);
-    int (*playlist_Replace_inner) (playlist_t *,playlist_item_t *, input_item_t*);
-    int (*playlist_LockReplace_inner) (playlist_t *,playlist_item_t *, input_item_t*);
+    void *playlist_Disable_deprecated;
+    void *playlist_Enable_deprecated;
+    playlist_item_t* (*playlist_ItemToNode_inner) (playlist_t *,playlist_item_t *);
+    playlist_item_t* (*playlist_LockItemToNode_inner) (playlist_t *,playlist_item_t *);
+    void *playlist_Replace_deprecated;
+    void *playlist_LockReplace_deprecated;
     playlist_item_t * (*playlist_ItemGetById_inner) (playlist_t *, int);
-    playlist_item_t * (*playlist_LockItemGetById_inner) (playlist_t *, int);
-    playlist_item_t * (*playlist_ItemGetByPos_inner) (playlist_t *, int);
-    playlist_item_t * (*playlist_LockItemGetByPos_inner) (playlist_t *, int);
+    void *playlist_LockItemGetById_deprecated;
+    void *playlist_ItemGetByPos_deprecated;
+    void *playlist_LockItemGetByPos_deprecated;
     playlist_item_t * (*playlist_ItemGetByInput_inner) (playlist_t *,input_item_t *);
-    playlist_item_t * (*playlist_LockItemGetByInput_inner) (playlist_t *,input_item_t *);
-    int (*playlist_GetPositionById_inner) (playlist_t *,int);
-    int (*playlist_ItemAddOption_inner) (playlist_item_t *, const char *);
-    int (*playlist_Sort_inner) (playlist_t *, int, int);
-    int (*playlist_Move_inner) (playlist_t *, int, int);
-    int (*playlist_NodeGroup_inner) (playlist_t *, int,playlist_item_t *,playlist_item_t **,int, int, int);
+    void *playlist_LockItemGetByInput_deprecated;
+    void *playlist_GetPositionById_deprecated;
+    void (*playlist_ItemAddOption_inner) (playlist_item_t *, const char *);
+    void *playlist_Sort_deprecated;
+    void *playlist_Move_deprecated;
+    int (*playlist_NodeGroup_inner) (playlist_t *, playlist_item_t *,playlist_item_t **,int, int, int);
     int (*playlist_NodeSort_inner) (playlist_t *, playlist_item_t *,int, int);
     int (*playlist_RecursiveNodeSort_inner) (playlist_t *, playlist_item_t *,int, int);
     int (*playlist_Import_inner) (playlist_t *, const char *);
-    int (*playlist_Export_inner) (playlist_t *, const char *, const char *);
+    int (*playlist_Export_inner) (playlist_t *, const char *, playlist_item_t *, const char *);
     spu_t * (*__spu_Create_inner) (vlc_object_t *);
     int (*spu_Init_inner) (spu_t *);
     void (*spu_Destroy_inner) (spu_t *);
@@ -379,7 +379,7 @@ struct module_symbols_t
     void (*net_ListenClose_inner) (int *fd);
     void (*DigestMD5_inner) (struct md5_s *, uint32_t *);
     int (*ACL_Check_inner) (vlc_acl_t *p_acl, const char *psz_ip);
-    int (*playlist_NodeRemoveParent_inner) (playlist_t *,playlist_item_t*,playlist_item_t *);
+    void *playlist_NodeRemoveParent_deprecated;
     vlc_acl_t * (*__ACL_Duplicate_inner) (vlc_object_t *p_this, const vlc_acl_t *p_acl);
     vlc_acl_t * (*__ACL_Create_inner) (vlc_object_t *p_this, vlc_bool_t b_allow);
     int (*ACL_LoadFile_inner) (vlc_acl_t *p_acl, const char *path);
@@ -475,7 +475,7 @@ struct module_symbols_t
     char * (*FromLocaleDup_inner) (const char *);
     int (*utf8_mkdir_inner) (const char *filename);
     vlm_media_t* (*vlm_MediaSearch_inner) (vlm_t *, const char *);
-    int (*playlist_TreeMove_inner) (playlist_t *, playlist_item_t *, playlist_item_t *, int, int);
+    int (*playlist_TreeMove_inner) (playlist_t *, playlist_item_t *, playlist_item_t *, int);
     const char * (*config_GetDataDir_inner) (const vlc_object_t *);
     double (*us_atof_inner) (const char *);
     double (*us_strtod_inner) (const char *, char **);
@@ -492,6 +492,26 @@ struct module_symbols_t
     void (*decode_URI_inner) (char *psz);
     char * (*encode_URI_component_inner) (const char *psz);
     size_t (*vlc_strlcpy_inner) (char *, const char *, size_t);
+    void *playlist_ItemNewFromInput_deprecated;
+    input_item_t * (*__input_ItemNewExt_inner) (vlc_object_t *, const char *, const char*, int, const char **, int);
+    input_item_t * (*input_ItemNewWithType_inner) (vlc_object_t *, const char *, const char *e, int, const char **, int, int);
+    playlist_item_t * (*playlist_NodeAddInput_inner) (playlist_t *, input_item_t *,playlist_item_t *,int , int);
+    int (*playlist_PlaylistAdd_inner) (playlist_t *, const char *, const char *, int, int);
+    int (*playlist_PlaylistAddExt_inner) (playlist_t *, const char *, const char *, int, int, mtime_t, const char **,int);
+    int (*playlist_PlaylistAddInput_inner) (playlist_t *, input_item_t *,int , int);
+    int (*playlist_BothAddInput_inner) (playlist_t *, input_item_t *,playlist_item_t *,int , int);
+    playlist_item_t * (*__playlist_ItemNewFromInput_inner) (vlc_object_t *p_obj,input_item_t *p_input);
+    input_item_t * (*input_ItemGetById_inner) (playlist_t *, int);
+    int (*playlist_LiveSearchUpdate_inner) (playlist_t *, playlist_item_t *, const char *);
+    void (*vlc_input_item_AddOption_inner) (input_item_t *p_input, const char *psz_option);
+    int (*playlist_DeleteFromInput_inner) (playlist_t *, int, playlist_item_t *, vlc_bool_t);
+    int (*playlist_DeleteAllFromInput_inner) (playlist_t *, int);
+    int (*playlist_LockDeleteAllFromInput_inner) (playlist_t *, int);
+    void (*playlist_AddWhereverNeeded_inner) (playlist_t* , input_item_t*, playlist_item_t*,playlist_item_t*,vlc_bool_t, int);
+    int (*playlist_DeleteFromItemId_inner) (playlist_t *, int);
+    void (*playlist_NodeDump_inner) (playlist_t *p_playlist, playlist_item_t *p_item, int i_level);
+    int (*__intf_UserOkayCancel_inner) (vlc_object_t*, const char*, const char*);
+    int (*__intf_UserStringInput_inner) (vlc_object_t*, const char*, const char*, char **);
 };
 # if defined (__PLUGIN__)
 #  define aout_FiltersCreatePipeline (p_symbols)->aout_FiltersCreatePipeline_inner
@@ -743,16 +763,8 @@ struct module_symbols_t
 #  define __playlist_ItemCopy (p_symbols)->__playlist_ItemCopy_inner
 #  define playlist_ItemNewWithType (p_symbols)->playlist_ItemNewWithType_inner
 #  define playlist_ItemDelete (p_symbols)->playlist_ItemDelete_inner
-#  define playlist_ItemAddParent (p_symbols)->playlist_ItemAddParent_inner
-#  define playlist_CopyParents (p_symbols)->playlist_CopyParents_inner
 #  define playlist_ItemSetName (p_symbols)->playlist_ItemSetName_inner
 #  define playlist_ItemSetDuration (p_symbols)->playlist_ItemSetDuration_inner
-#  define playlist_ViewInsert (p_symbols)->playlist_ViewInsert_inner
-#  define playlist_ViewDelete (p_symbols)->playlist_ViewDelete_inner
-#  define playlist_ViewFind (p_symbols)->playlist_ViewFind_inner
-#  define playlist_ViewUpdate (p_symbols)->playlist_ViewUpdate_inner
-#  define playlist_ViewDump (p_symbols)->playlist_ViewDump_inner
-#  define playlist_ViewEmpty (p_symbols)->playlist_ViewEmpty_inner
 #  define playlist_NodeCreate (p_symbols)->playlist_NodeCreate_inner
 #  define playlist_NodeAppend (p_symbols)->playlist_NodeAppend_inner
 #  define playlist_NodeInsert (p_symbols)->playlist_NodeInsert_inner
@@ -761,28 +773,13 @@ struct module_symbols_t
 #  define playlist_ChildSearchName (p_symbols)->playlist_ChildSearchName_inner
 #  define playlist_NodeDelete (p_symbols)->playlist_NodeDelete_inner
 #  define playlist_NodeEmpty (p_symbols)->playlist_NodeEmpty_inner
-#  define playlist_Add (p_symbols)->playlist_Add_inner
-#  define playlist_AddExt (p_symbols)->playlist_AddExt_inner
-#  define playlist_ItemAdd (p_symbols)->playlist_ItemAdd_inner
 #  define playlist_NodeAddItem (p_symbols)->playlist_NodeAddItem_inner
-#  define playlist_Delete (p_symbols)->playlist_Delete_inner
 #  define playlist_LockDelete (p_symbols)->playlist_LockDelete_inner
-#  define playlist_Disable (p_symbols)->playlist_Disable_inner
-#  define playlist_Enable (p_symbols)->playlist_Enable_inner
 #  define playlist_ItemToNode (p_symbols)->playlist_ItemToNode_inner
 #  define playlist_LockItemToNode (p_symbols)->playlist_LockItemToNode_inner
-#  define playlist_Replace (p_symbols)->playlist_Replace_inner
-#  define playlist_LockReplace (p_symbols)->playlist_LockReplace_inner
 #  define playlist_ItemGetById (p_symbols)->playlist_ItemGetById_inner
-#  define playlist_LockItemGetById (p_symbols)->playlist_LockItemGetById_inner
-#  define playlist_ItemGetByPos (p_symbols)->playlist_ItemGetByPos_inner
-#  define playlist_LockItemGetByPos (p_symbols)->playlist_LockItemGetByPos_inner
 #  define playlist_ItemGetByInput (p_symbols)->playlist_ItemGetByInput_inner
-#  define playlist_LockItemGetByInput (p_symbols)->playlist_LockItemGetByInput_inner
-#  define playlist_GetPositionById (p_symbols)->playlist_GetPositionById_inner
 #  define playlist_ItemAddOption (p_symbols)->playlist_ItemAddOption_inner
-#  define playlist_Sort (p_symbols)->playlist_Sort_inner
-#  define playlist_Move (p_symbols)->playlist_Move_inner
 #  define playlist_NodeGroup (p_symbols)->playlist_NodeGroup_inner
 #  define playlist_NodeSort (p_symbols)->playlist_NodeSort_inner
 #  define playlist_RecursiveNodeSort (p_symbols)->playlist_RecursiveNodeSort_inner
@@ -853,7 +850,6 @@ struct module_symbols_t
 #  define net_ListenClose (p_symbols)->net_ListenClose_inner
 #  define DigestMD5 (p_symbols)->DigestMD5_inner
 #  define ACL_Check (p_symbols)->ACL_Check_inner
-#  define playlist_NodeRemoveParent (p_symbols)->playlist_NodeRemoveParent_inner
 #  define __ACL_Duplicate (p_symbols)->__ACL_Duplicate_inner
 #  define __ACL_Create (p_symbols)->__ACL_Create_inner
 #  define ACL_LoadFile (p_symbols)->ACL_LoadFile_inner
@@ -964,6 +960,25 @@ struct module_symbols_t
 #  define decode_URI (p_symbols)->decode_URI_inner
 #  define encode_URI_component (p_symbols)->encode_URI_component_inner
 #  define vlc_strlcpy (p_symbols)->vlc_strlcpy_inner
+#  define __input_ItemNewExt (p_symbols)->__input_ItemNewExt_inner
+#  define input_ItemNewWithType (p_symbols)->input_ItemNewWithType_inner
+#  define playlist_NodeAddInput (p_symbols)->playlist_NodeAddInput_inner
+#  define playlist_PlaylistAdd (p_symbols)->playlist_PlaylistAdd_inner
+#  define playlist_PlaylistAddExt (p_symbols)->playlist_PlaylistAddExt_inner
+#  define playlist_PlaylistAddInput (p_symbols)->playlist_PlaylistAddInput_inner
+#  define playlist_BothAddInput (p_symbols)->playlist_BothAddInput_inner
+#  define __playlist_ItemNewFromInput (p_symbols)->__playlist_ItemNewFromInput_inner
+#  define input_ItemGetById (p_symbols)->input_ItemGetById_inner
+#  define playlist_LiveSearchUpdate (p_symbols)->playlist_LiveSearchUpdate_inner
+#  define vlc_input_item_AddOption (p_symbols)->vlc_input_item_AddOption_inner
+#  define playlist_DeleteFromInput (p_symbols)->playlist_DeleteFromInput_inner
+#  define playlist_DeleteAllFromInput (p_symbols)->playlist_DeleteAllFromInput_inner
+#  define playlist_LockDeleteAllFromInput (p_symbols)->playlist_LockDeleteAllFromInput_inner
+#  define playlist_AddWhereverNeeded (p_symbols)->playlist_AddWhereverNeeded_inner
+#  define playlist_DeleteFromItemId (p_symbols)->playlist_DeleteFromItemId_inner
+#  define playlist_NodeDump (p_symbols)->playlist_NodeDump_inner
+#  define __intf_UserOkayCancel (p_symbols)->__intf_UserOkayCancel_inner
+#  define __intf_UserStringInput (p_symbols)->__intf_UserStringInput_inner
 # elif defined (HAVE_DYNAMIC_PLUGINS) && !defined (__BUILTIN__)
 /******************************************************************
  * STORE_SYMBOLS: store VLC APIs into p_symbols for plugin access.
@@ -1218,16 +1233,8 @@ struct module_symbols_t
     ((p_symbols)->__playlist_ItemCopy_inner) = __playlist_ItemCopy; \
     ((p_symbols)->playlist_ItemNewWithType_inner) = playlist_ItemNewWithType; \
     ((p_symbols)->playlist_ItemDelete_inner) = playlist_ItemDelete; \
-    ((p_symbols)->playlist_ItemAddParent_inner) = playlist_ItemAddParent; \
-    ((p_symbols)->playlist_CopyParents_inner) = playlist_CopyParents; \
     ((p_symbols)->playlist_ItemSetName_inner) = playlist_ItemSetName; \
     ((p_symbols)->playlist_ItemSetDuration_inner) = playlist_ItemSetDuration; \
-    ((p_symbols)->playlist_ViewInsert_inner) = playlist_ViewInsert; \
-    ((p_symbols)->playlist_ViewDelete_inner) = playlist_ViewDelete; \
-    ((p_symbols)->playlist_ViewFind_inner) = playlist_ViewFind; \
-    ((p_symbols)->playlist_ViewUpdate_inner) = playlist_ViewUpdate; \
-    ((p_symbols)->playlist_ViewDump_inner) = playlist_ViewDump; \
-    ((p_symbols)->playlist_ViewEmpty_inner) = playlist_ViewEmpty; \
     ((p_symbols)->playlist_NodeCreate_inner) = playlist_NodeCreate; \
     ((p_symbols)->playlist_NodeAppend_inner) = playlist_NodeAppend; \
     ((p_symbols)->playlist_NodeInsert_inner) = playlist_NodeInsert; \
@@ -1236,28 +1243,13 @@ struct module_symbols_t
     ((p_symbols)->playlist_ChildSearchName_inner) = playlist_ChildSearchName; \
     ((p_symbols)->playlist_NodeDelete_inner) = playlist_NodeDelete; \
     ((p_symbols)->playlist_NodeEmpty_inner) = playlist_NodeEmpty; \
-    ((p_symbols)->playlist_Add_inner) = playlist_Add; \
-    ((p_symbols)->playlist_AddExt_inner) = playlist_AddExt; \
-    ((p_symbols)->playlist_ItemAdd_inner) = playlist_ItemAdd; \
     ((p_symbols)->playlist_NodeAddItem_inner) = playlist_NodeAddItem; \
-    ((p_symbols)->playlist_Delete_inner) = playlist_Delete; \
     ((p_symbols)->playlist_LockDelete_inner) = playlist_LockDelete; \
-    ((p_symbols)->playlist_Disable_inner) = playlist_Disable; \
-    ((p_symbols)->playlist_Enable_inner) = playlist_Enable; \
     ((p_symbols)->playlist_ItemToNode_inner) = playlist_ItemToNode; \
     ((p_symbols)->playlist_LockItemToNode_inner) = playlist_LockItemToNode; \
-    ((p_symbols)->playlist_Replace_inner) = playlist_Replace; \
-    ((p_symbols)->playlist_LockReplace_inner) = playlist_LockReplace; \
     ((p_symbols)->playlist_ItemGetById_inner) = playlist_ItemGetById; \
-    ((p_symbols)->playlist_LockItemGetById_inner) = playlist_LockItemGetById; \
-    ((p_symbols)->playlist_ItemGetByPos_inner) = playlist_ItemGetByPos; \
-    ((p_symbols)->playlist_LockItemGetByPos_inner) = playlist_LockItemGetByPos; \
     ((p_symbols)->playlist_ItemGetByInput_inner) = playlist_ItemGetByInput; \
-    ((p_symbols)->playlist_LockItemGetByInput_inner) = playlist_LockItemGetByInput; \
-    ((p_symbols)->playlist_GetPositionById_inner) = playlist_GetPositionById; \
     ((p_symbols)->playlist_ItemAddOption_inner) = playlist_ItemAddOption; \
-    ((p_symbols)->playlist_Sort_inner) = playlist_Sort; \
-    ((p_symbols)->playlist_Move_inner) = playlist_Move; \
     ((p_symbols)->playlist_NodeGroup_inner) = playlist_NodeGroup; \
     ((p_symbols)->playlist_NodeSort_inner) = playlist_NodeSort; \
     ((p_symbols)->playlist_RecursiveNodeSort_inner) = playlist_RecursiveNodeSort; \
@@ -1328,7 +1320,6 @@ struct module_symbols_t
     ((p_symbols)->net_ListenClose_inner) = net_ListenClose; \
     ((p_symbols)->DigestMD5_inner) = DigestMD5; \
     ((p_symbols)->ACL_Check_inner) = ACL_Check; \
-    ((p_symbols)->playlist_NodeRemoveParent_inner) = playlist_NodeRemoveParent; \
     ((p_symbols)->__ACL_Duplicate_inner) = __ACL_Duplicate; \
     ((p_symbols)->__ACL_Create_inner) = __ACL_Create; \
     ((p_symbols)->ACL_LoadFile_inner) = ACL_LoadFile; \
@@ -1439,9 +1430,53 @@ struct module_symbols_t
     ((p_symbols)->decode_URI_inner) = decode_URI; \
     ((p_symbols)->encode_URI_component_inner) = encode_URI_component; \
     ((p_symbols)->vlc_strlcpy_inner) = vlc_strlcpy; \
+    ((p_symbols)->__input_ItemNewExt_inner) = __input_ItemNewExt; \
+    ((p_symbols)->input_ItemNewWithType_inner) = input_ItemNewWithType; \
+    ((p_symbols)->playlist_NodeAddInput_inner) = playlist_NodeAddInput; \
+    ((p_symbols)->playlist_PlaylistAdd_inner) = playlist_PlaylistAdd; \
+    ((p_symbols)->playlist_PlaylistAddExt_inner) = playlist_PlaylistAddExt; \
+    ((p_symbols)->playlist_PlaylistAddInput_inner) = playlist_PlaylistAddInput; \
+    ((p_symbols)->playlist_BothAddInput_inner) = playlist_BothAddInput; \
+    ((p_symbols)->__playlist_ItemNewFromInput_inner) = __playlist_ItemNewFromInput; \
+    ((p_symbols)->input_ItemGetById_inner) = input_ItemGetById; \
+    ((p_symbols)->playlist_LiveSearchUpdate_inner) = playlist_LiveSearchUpdate; \
+    ((p_symbols)->vlc_input_item_AddOption_inner) = vlc_input_item_AddOption; \
+    ((p_symbols)->playlist_DeleteFromInput_inner) = playlist_DeleteFromInput; \
+    ((p_symbols)->playlist_DeleteAllFromInput_inner) = playlist_DeleteAllFromInput; \
+    ((p_symbols)->playlist_LockDeleteAllFromInput_inner) = playlist_LockDeleteAllFromInput; \
+    ((p_symbols)->playlist_AddWhereverNeeded_inner) = playlist_AddWhereverNeeded; \
+    ((p_symbols)->playlist_DeleteFromItemId_inner) = playlist_DeleteFromItemId; \
+    ((p_symbols)->playlist_NodeDump_inner) = playlist_NodeDump; \
+    ((p_symbols)->__intf_UserOkayCancel_inner) = __intf_UserOkayCancel; \
+    ((p_symbols)->__intf_UserStringInput_inner) = __intf_UserStringInput; \
     (p_symbols)->net_ConvertIPv4_deprecated = NULL; \
+    (p_symbols)->playlist_ItemAddParent_deprecated = NULL; \
+    (p_symbols)->playlist_CopyParents_deprecated = NULL; \
+    (p_symbols)->playlist_ViewInsert_deprecated = NULL; \
+    (p_symbols)->playlist_ViewDelete_deprecated = NULL; \
+    (p_symbols)->playlist_ViewFind_deprecated = NULL; \
+    (p_symbols)->playlist_ViewUpdate_deprecated = NULL; \
+    (p_symbols)->playlist_ViewDump_deprecated = NULL; \
+    (p_symbols)->playlist_ViewEmpty_deprecated = NULL; \
+    (p_symbols)->playlist_Add_deprecated = NULL; \
+    (p_symbols)->playlist_AddExt_deprecated = NULL; \
+    (p_symbols)->playlist_ItemAdd_deprecated = NULL; \
+    (p_symbols)->playlist_Delete_deprecated = NULL; \
+    (p_symbols)->playlist_Disable_deprecated = NULL; \
+    (p_symbols)->playlist_Enable_deprecated = NULL; \
+    (p_symbols)->playlist_Replace_deprecated = NULL; \
+    (p_symbols)->playlist_LockReplace_deprecated = NULL; \
+    (p_symbols)->playlist_LockItemGetById_deprecated = NULL; \
+    (p_symbols)->playlist_ItemGetByPos_deprecated = NULL; \
+    (p_symbols)->playlist_LockItemGetByPos_deprecated = NULL; \
+    (p_symbols)->playlist_LockItemGetByInput_deprecated = NULL; \
+    (p_symbols)->playlist_GetPositionById_deprecated = NULL; \
+    (p_symbols)->playlist_Sort_deprecated = NULL; \
+    (p_symbols)->playlist_Move_deprecated = NULL; \
+    (p_symbols)->playlist_NodeRemoveParent_deprecated = NULL; \
     (p_symbols)->__stats_CounterGet_deprecated = NULL; \
     (p_symbols)->__stats_TimerDumpAll_deprecated = NULL; \
+    (p_symbols)->playlist_ItemNewFromInput_deprecated = NULL; \
 
 # endif /* __PLUGIN__ */
 #endif /* __VLC_SYMBOLS_H */
index 5b3dbf1bcc0daa45b84b34c99f1782eba288dcc3..db9860737b0c5eb665460fe5cc41972170706956 100644 (file)
@@ -216,7 +216,7 @@ static int Open( vlc_object_t *p_this )
         if( !p_playlist ) return VLC_EGENERIC;
 
         /* Let's check if we need to play */
-        if( &p_playlist->status.p_item->input ==
+        if( p_playlist->status.p_item->p_input ==
              ((input_thread_t *)p_access->p_parent)->input.p_item )
         {
             p_item = p_playlist->status.p_item;
@@ -290,8 +290,7 @@ static int Open( vlc_object_t *p_this )
     if( b_play )
     {
         playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
-                          p_playlist->status.i_view, p_playlist->status.p_item,
-                          NULL );
+                          p_playlist->status.p_item, NULL );
     }
 
     if( p_playlist ) vlc_object_release( p_playlist );
@@ -445,7 +444,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
     input_title_t ***ppp_title;
     int i;
     char         *psz_title;
-    vlc_meta_t  **pp_meta;
+    vlc_meta_t  *p_meta;
 
     switch( i_query )
     {
@@ -511,9 +510,8 @@ static int Control( access_t *p_access, int i_query, va_list args )
              psz_title = malloc( strlen( _("Audio CD - Track ") ) + 5 );
              snprintf( psz_title, 100, _("Audio CD - Track %i" ),
                                         p_access->info.i_title+1 );
-             pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
-             *pp_meta = vlc_meta_New();
-             vlc_meta_Add( *pp_meta, _(VLC_META_TITLE), psz_title );
+             p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
+             vlc_meta_SetTitle( p_meta, psz_title );
              free( psz_title );
              break;
 
@@ -534,7 +532,7 @@ static int GetTracks( access_t *p_access, vlc_bool_t b_separate,
 {
     access_sys_t *p_sys = p_access->p_sys;
     int i;
-    playlist_item_t *p_item;
+    input_item_t *p_input_item;
     char *psz_name;
     p_sys->i_titles = ioctl_GetTracksMap( VLC_OBJECT(p_access),
                                           p_sys->vcddev, &p_sys->p_sectors );
@@ -560,7 +558,7 @@ static int GetTracks( access_t *p_access, vlc_bool_t b_separate,
         playlist_ItemSetName( p_parent, psz_name );
         vlc_mutex_unlock( &p_playlist->object_lock );
         var_SetInteger( p_playlist, "item-change",
-                        p_parent->input.i_id );
+                        p_parent->p_input->i_id );
         free( psz_name );
 
 #ifdef HAVE_LIBCDDB
@@ -575,7 +573,7 @@ static int GetTracks( access_t *p_access, vlc_bool_t b_separate,
                 playlist_ItemSetName( p_parent, psz_name );
                 vlc_mutex_unlock( &p_playlist->object_lock );
                 var_SetInteger( p_playlist, "item-change",
-                                p_parent->input.i_id );
+                                p_parent->p_input->i_id );
                 free( psz_name );
             }
         }
@@ -615,9 +613,10 @@ static int GetTracks( access_t *p_access, vlc_bool_t b_separate,
             sprintf( psz_name, _("Audio CD - Track %i"), (i+1) );
 
             /* Create playlist items */
-            p_item = playlist_ItemNewWithType( VLC_OBJECT( p_playlist ),
-                                 psz_uri, psz_name, ITEM_TYPE_DISC );
-            playlist_ItemAddOption( p_item, psz_opt );
+            p_input_item = input_ItemNewWithType( VLC_OBJECT( p_playlist ),
+                                psz_uri, psz_name, 0, NULL, -1,
+                                ITEM_TYPE_DISC );
+            vlc_input_item_AddOption( p_input_item, psz_opt );
 #ifdef HAVE_LIBCDDB
             /* If we have CDDB info, change the name */
             if( p_sys->p_disc )
@@ -628,28 +627,27 @@ static int GetTracks( access_t *p_access, vlc_bool_t b_separate,
                 {
                     if( cddb_track_get_title( t )  != NULL )
                     {
-                        vlc_input_item_AddInfo( &p_item->input,
+                        vlc_input_item_AddInfo( p_input_item,
                                             _(VLC_META_INFO_CAT),
                                             _(VLC_META_TITLE),
                                             cddb_track_get_title( t ) );
-                        if( p_item->input.psz_name )
-                            free( p_item->input.psz_name );
-                        asprintf( &p_item->input.psz_name, "%s",
+                        if( p_input_item->psz_name )
+                            free( p_input_item->psz_name );
+                        asprintf( &p_input_item->psz_name, "%s",
                                   cddb_track_get_title( t ) );
                     }
                     psz_result = cddb_track_get_artist( t );
                     if( psz_result )
                     {
-                        vlc_input_item_AddInfo( &p_item->input,
+                        vlc_input_item_AddInfo( p_input_item,
                                             _(VLC_META_INFO_CAT),
                                             _(VLC_META_ARTIST), psz_result );
                     }
                 }
             }
 #endif
-            playlist_NodeAddItem( p_playlist, p_item,
-                                  p_parent->pp_parents[0]->i_view,
-                                  p_parent, PLAYLIST_APPEND, PLAYLIST_END );
+            playlist_BothAddInput( p_playlist, p_input_item, p_parent,
+                                   PLAYLIST_APPEND, PLAYLIST_END );
             free( psz_uri ); free( psz_opt ); free( psz_name );
         }
     }
index a8903509943b854fb0a2eec870b6f749cff25abd..227f76cf8c64598100869eed6c614dd52cc30f63 100644 (file)
@@ -40,7 +40,7 @@
 #if LIBCDIO_VERSION_NUM >= 72
 static char *psz_paranoia_list[] = { "none", "overlap", "full" };
 static char *psz_paranoia_list_text[] = { N_("none"), N_("overlap"),
-                                         N_("full") };
+                                          N_("full") };
 #endif
 
 #define DEBUG_LONGTEXT N_( \
index 5d273207ca982b5401dd70a7e60f89360172ee6f..4ebb1a0bfc1a698ac81d15daf444003a799eebb7 100644 (file)
@@ -124,7 +124,7 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args );
 
 
 static int ReadDir( playlist_t *, const char *psz_name, int i_mode,
-                    playlist_item_t * );
+                    playlist_item_t *, playlist_item_t * );
 
 /*****************************************************************************
  * Open: open the directory
@@ -198,9 +198,9 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len)
 {
     char *psz_name = NULL;
     char *psz;
-    int  i_mode, i_pos;
+    int  i_mode, i_activity;
 
-    playlist_item_t *p_item;
+    playlist_item_t *p_item, *p_root_category;
     vlc_bool_t b_play = VLC_FALSE;
 
     playlist_t *p_playlist =
@@ -212,54 +212,41 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len)
         msg_Err( p_access, "can't find playlist" );
         goto end;
     }
-    else
-    {
-        char *ptr;
 
-        psz_name = ToLocale( p_access->psz_path );
-        ptr = strdup( psz_name );
-        LocaleFree( psz_name );
-        if( ptr == NULL )
-            goto end;
+    char *ptr;
+    psz_name = ToLocale( p_access->psz_path );
+    ptr = strdup( psz_name );
+    LocaleFree( psz_name );
+    if( ptr == NULL )
+        goto end;
 
-        psz_name = ptr;
+    psz_name = ptr;
 
-        /* Remove the ending '/' char */
-        ptr += strlen( ptr );
-        if( ( ptr > psz_name ) )
+    /* Remove the ending '/' char */
+    ptr += strlen( ptr );
+    if( ( ptr > psz_name ) )
+    {
+        switch( *--ptr )
         {
-            switch( *--ptr )
-            {
-                case '/':
-                case '\\':
-                    *ptr = '\0';
-            }
+            case '/':
+            case '\\':
+                *ptr = '\0';
         }
     }
 
-    /* Initialize structure */
+    /* Handle mode */
     psz = var_CreateGetString( p_access, "recursive" );
     if( *psz == '\0' || !strncmp( psz, "none" , 4 )  )
-    {
         i_mode = MODE_NONE;
-    }
     else if( !strncmp( psz, "collapse", 8 )  )
-    {
         i_mode = MODE_COLLAPSE;
-    }
     else
-    {
         i_mode = MODE_EXPAND;
-    }
     free( psz );
 
-    /* Make sure we are deleted when we are done */
-    /* The playlist position we will use for the add */
-    i_pos = p_playlist->i_index + 1;
-
     msg_Dbg( p_access, "opening directory `%s'", p_access->psz_path );
 
-    if( &p_playlist->status.p_item->input ==
+    if( p_playlist->status.p_item->p_input ==
         ((input_thread_t *)p_access->p_parent)->input.p_item )
     {
         p_item = p_playlist->status.p_item;
@@ -279,19 +266,29 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len)
         }
         b_play = VLC_FALSE;
     }
+    p_item->p_input->i_type = ITEM_TYPE_DIRECTORY;
 
-    p_item->input.i_type = ITEM_TYPE_DIRECTORY;
-    if( ReadDir( p_playlist, psz_name , i_mode, p_item ) != VLC_SUCCESS )
-    {
-    }
+    p_root_category = playlist_LockItemToNode( p_playlist, p_item );
+
+    i_activity = var_GetInteger( p_playlist, "activity" );
+    var_SetInteger( p_playlist, "activity", i_activity +
+                    DIRECTORY_ACTIVITY );
+
+    ReadDir( p_playlist, psz_name , i_mode, p_item, p_root_category );
+
+    i_activity = var_GetInteger( p_playlist, "activity" );
+    var_SetInteger( p_playlist, "activity", i_activity -
+                    DIRECTORY_ACTIVITY );
 end:
 
     /* Begin to read the directory */
     if( b_play )
     {
-        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
-                          p_playlist->status.i_view,
+#if 0
+       /// \bug we can start playing an already deleted item. Fix ?*/
+       playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, 1242,
                           p_playlist->status.p_item, NULL );
+#endif
     }
     if( psz_name ) free( psz_name );
     vlc_object_release( p_playlist );
@@ -387,7 +384,8 @@ static int Filter( const struct dirent *foo )
  * ReadDir: read a directory and add its content to the list
  *****************************************************************************/
 static int ReadDir( playlist_t *p_playlist, const char *psz_name,
-                    int i_mode, playlist_item_t *p_parent )
+                    int i_mode, playlist_item_t *p_parent,
+                    playlist_item_t *p_parent_category )
 {
     struct dirent   **pp_dir_content;
     int             i_dir_content, i;
@@ -424,12 +422,6 @@ static int ReadDir( playlist_t *p_playlist, const char *psz_name,
         }
     }
 
-    /* Change the item to a node */
-    if( p_parent->i_children == -1 )
-    {
-        playlist_LockItemToNode( p_playlist,p_parent );
-    }
-
     /* get the first directory entry */
     i_dir_content = scandir( psz_name, &pp_dir_content, Filter, alphasort );
     if( i_dir_content == -1 )
@@ -498,16 +490,22 @@ static int ReadDir( playlist_t *p_playlist, const char *psz_name,
                                                 p_playlist, psz_tmp );
                     LocaleFree( psz_tmp );
 
-                    p_node = playlist_NodeCreate( p_playlist,
-                                       p_parent->pp_parents[0]->i_view,
-                                       psz_newname, p_parent );
-
-                    playlist_CopyParents(  p_parent, p_node );
-
-                    p_node->input.i_type = ITEM_TYPE_DIRECTORY;
+                    if( p_parent_category )
+                    {
+                        p_node = playlist_NodeCreate( p_playlist, psz_newname,
+                                                      p_parent_category );
+                    }
+                    else
+                    {
+                        p_node = playlist_NodeCreate( p_playlist, psz_newname,
+                                                      p_parent_category );
+                    }
 
+                    /* If we had the parent in category, the it is now node.
+                     * Else, we still don't have  */
                     if( ReadDir( p_playlist, psz_uri , MODE_EXPAND,
-                                 p_node ) != VLC_SUCCESS )
+                                 p_node, p_parent_category ? p_node : NULL )
+                          != VLC_SUCCESS )
                     {
                         return VLC_EGENERIC;
                     }
@@ -518,7 +516,7 @@ static int ReadDir( playlist_t *p_playlist, const char *psz_name,
             }
             else
             {
-                playlist_item_t *p_item;
+                input_item_t *p_input;
                 char *psz_tmp1, *psz_tmp2, *psz_loc;
 
                 if( i_extensions > 0 )
@@ -551,15 +549,13 @@ static int ReadDir( playlist_t *p_playlist, const char *psz_name,
                                                     psz_loc );
                 LocaleFree( psz_loc );
 
-                p_item = playlist_ItemNewWithType( VLC_OBJECT(p_playlist),
-                        psz_tmp1, psz_tmp2, ITEM_TYPE_VFILE );
-                playlist_NodeAddItem( p_playlist,p_item,
-                                      p_parent->pp_parents[0]->i_view,
-                                      p_parent,
-                                      PLAYLIST_APPEND | PLAYLIST_PREPARSE,
-                                      PLAYLIST_END );
+                p_input = input_ItemNewWithType( VLC_OBJECT(p_playlist),
+                                                 psz_tmp1, psz_tmp2, 0, NULL,
+                                                 -1, ITEM_TYPE_VFILE );
 
-                playlist_CopyParents( p_parent, p_item );
+                playlist_AddWhereverNeeded( p_playlist, p_input, p_parent,
+                                            p_parent_category, VLC_FALSE,
+                                            PLAYLIST_APPEND|PLAYLIST_PREPARSE);
             }
         }
         free( psz_uri );
index 387b32762ebf3d3066bd73f1c7412f0885697370..f362e3eecf0b7760494ea717edc0a31fb4149f39 100644 (file)
@@ -543,10 +543,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             dvdnav_get_title_string(p_sys->dvdnav, &title_name);
             if( (NULL != title_name) && ('\0' != title_name[0]) )
             {
-                vlc_meta_t **pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
-                vlc_meta_t *meta;
-                *pp_meta = meta = vlc_meta_New();
-                vlc_meta_Add( meta, VLC_META_TITLE, title_name );
+                vlc_meta_t *p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
+                vlc_meta_SetTitle( p_meta, title_name );
                 return VLC_SUCCESS;
             }
             return VLC_EGENERIC;
index 2905d59c03216b00d58dd336d990af807a87c572..2bc605250eaa1f5db7611ceec61f4b5a6e2cba71 100644 (file)
@@ -337,9 +337,9 @@ connect:
             goto error;
         }
 
-        /* Change the uri */
+        /* Change the URI */
         vlc_mutex_lock( &p_playlist->object_lock );
-        p_input_item = &p_playlist->status.p_item->input;
+        p_input_item = p_playlist->status.p_item->p_input;
         vlc_mutex_lock( &p_input_item->lock );
         free( p_input_item->psz_uri );
         free( p_access->psz_path );
@@ -696,7 +696,7 @@ static int Control( access_t *p_access, int i_query, va_list args )
     vlc_bool_t   *pb_bool;
     int          *pi_int;
     int64_t      *pi_64;
-    vlc_meta_t **pp_meta;
+    vlc_meta_t   *p_meta;
 
     switch( i_query )
     {
@@ -736,18 +736,14 @@ static int Control( access_t *p_access, int i_query, va_list args )
             break;
 
         case ACCESS_GET_META:
-            pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
-            *pp_meta = vlc_meta_New();
+            p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
 
             if( p_sys->psz_icy_name )
-                vlc_meta_Add( *pp_meta, VLC_META_TITLE,
-                              p_sys->psz_icy_name );
+                vlc_meta_SetTitle( p_meta, p_sys->psz_icy_name );
             if( p_sys->psz_icy_genre )
-                vlc_meta_Add( *pp_meta, VLC_META_GENRE,
-                              p_sys->psz_icy_genre );
+                vlc_meta_SetGenre( p_meta, p_sys->psz_icy_genre );
             if( p_sys->psz_icy_title )
-                vlc_meta_Add( *pp_meta, VLC_META_NOW_PLAYING,
-                              p_sys->psz_icy_title );
+                vlc_meta_SetNowPlaying( p_meta, p_sys->psz_icy_title );
             break;
 
         case ACCESS_GET_TITLE_INFO:
index 4d32bd1f88d01e0b157b8a4dd5de4f5c5ce51379..6786972d0dc2af6d863c36bc5edf218c4cb212f8 100644 (file)
@@ -118,10 +118,9 @@ int E_(MMSHOpen)( access_t *p_access )
             free( psz_location );
             return VLC_EGENERIC;
         }
-        p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;
-        playlist_Add( p_playlist, psz_location, psz_location,
-                      PLAYLIST_INSERT | PLAYLIST_GO,
-                      p_playlist->i_index + 1 );
+        /** \bug we do not autodelete here */
+        playlist_PlaylistAdd( p_playlist, psz_location, psz_location,
+                              PLAYLIST_INSERT | PLAYLIST_GO, PLAYLIST_END );
         vlc_object_release( p_playlist );
 
         free( psz_location );
index b8a71fd1241d9841d824b9a87ead944df15ae247..7c633b594a8a894c953a61b3d1651a7be1ba9c18 100644 (file)
@@ -13,7 +13,7 @@
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -192,7 +192,7 @@ static void RunIntf( intf_thread_t *p_intf )
     /* Main loop */
     while( !p_intf->b_die )
     {
-        
+
         /* find a video output if we currently don't have one */
         if( p_vout == NULL )
         {
@@ -412,7 +412,7 @@ static int KeyEvent( vlc_object_t *p_this, char const *psz_var,
     vlc_mutex_lock( &p_intf->change_lock );
 
     p_intf->p_sys->b_key_pressed = VLC_TRUE;
-    
+
     vlc_mutex_unlock( &p_intf->change_lock );
 
     return VLC_SUCCESS;
@@ -451,7 +451,7 @@ static void FollowAnchor ( intf_thread_t *p_intf )
         mtime_t i_seconds;
         vlc_value_t time;
 
-        p_playlist = (playlist_t *) vlc_object_find( p_intf, 
+        p_playlist = (playlist_t *) vlc_object_find( p_intf,
                 VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
         if ( !p_playlist )
         {
@@ -460,13 +460,13 @@ static void FollowAnchor ( intf_thread_t *p_intf )
         }
 
         /* Get new URL */
-        p_current_item = p_playlist->pp_items[p_playlist->i_index];
+        p_current_item = p_playlist->status.p_item;
 #ifdef CMML_INTF_DEBUG
         msg_Dbg( p_intf, "Current playlist item URL is \"%s\"",
                 p_current_item->input.psz_uri );
 #endif
 
-        psz_uri_to_load = XURL_Concat( p_current_item->input.psz_uri,
+        psz_uri_to_load = XURL_Concat( p_current_item->p_input->psz_uri,
                                        psz_url );
 
 #ifdef CMML_INTF_DEBUG
@@ -550,7 +550,7 @@ char *GetTimedURLFromPlaylistItem( intf_thread_t *p_intf,
     char *psz_return_value = NULL;
     char *psz_seconds = NULL;
     int i_seconds;
-    
+
     psz_url = XURL_GetWithoutFragment( p_current_item->input->psz_uri );
 
     /* Get current time as a string */
@@ -577,7 +577,7 @@ char *GetTimedURLFromPlaylistItem( intf_thread_t *p_intf,
     p = GetTimedURIFragmentForTime; /* unused */
     p = GetCurrentTimeInSeconds;    /* unused */
 
-    return strdup( p_current_item->input.psz_uri );
+    return strdup( p_current_item->p_input->psz_uri );
 #endif
 }
 
@@ -653,7 +653,7 @@ void GoBack( intf_thread_t *p_intf )
 #endif
 
     /* Find the playlist */
-    p_playlist = (playlist_t *) vlc_object_find( p_intf, 
+    p_playlist = (playlist_t *) vlc_object_find( p_intf,
             VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
     if ( !p_playlist )
     {
@@ -686,7 +686,7 @@ void GoBack( intf_thread_t *p_intf )
         return;
     }
 
-    p_current_item = p_playlist->pp_items[p_playlist->i_index];
+    p_current_item = p_playlist->status.p_item;
 
     /* Save the currently-playing media in a new history item */
     psz_timed_url = GetTimedURLFromPlaylistItem( p_intf, p_current_item );
@@ -731,7 +731,7 @@ void GoForward( intf_thread_t *p_intf )
 #endif
 
     /* Find the playlist */
-    p_playlist = (playlist_t *) vlc_object_find( p_intf, 
+    p_playlist = (playlist_t *) vlc_object_find( p_intf,
             VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
     if ( !p_playlist )
     {
@@ -774,8 +774,8 @@ void GoForward( intf_thread_t *p_intf )
         vlc_object_release( p_playlist );
         return;
     }
-    p_current_item = p_playlist->pp_items[p_playlist->i_index];
-    p_new_history_item->psz_uri = GetTimedURLFromPlaylistItem( p_intf, 
+    p_current_item = p_playlist->status.p_item;
+    p_new_history_item->psz_uri = GetTimedURLFromPlaylistItem( p_intf,
             p_current_item );
     p_new_history_item->psz_name = p_new_history_item->psz_uri;
 
@@ -796,9 +796,8 @@ void GoForward( intf_thread_t *p_intf )
 static void ReplacePlaylistItem( playlist_t *p_playlist, char *psz_uri )
 {
     playlist_Stop( p_playlist );
-    (void) playlist_Add( p_playlist, psz_uri, psz_uri,
-                         PLAYLIST_REPLACE, p_playlist->i_index );
-    playlist_Goto( p_playlist, p_playlist->i_index );
+    (void) playlist_PlaylistAdd( p_playlist, psz_uri, psz_uri,
+                         PLAYLIST_INSERT /* FIXME: used to be PLAYLIST_REPLACE */, PLAYLIST_END|PLAYLIST_GO /* FIXME: p_playlist->status.i_index */ );
 }
 
 /****************************************************************************
index faee64c5a76752b23ba1654f4f7641031efda7d6..9b1c321d958e8faa4ca9ff52b6080244741b361f 100644 (file)
@@ -900,7 +900,7 @@ static int ActionKeyCB( vlc_object_t *p_this, char const *psz_var,
 static void PlayBookmark( intf_thread_t *p_intf, int i_num )
 {
     vlc_value_t val;
-    int i_position;
+    int i;
     char psz_bookmark_name[11];
     playlist_t *p_playlist =
         vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
@@ -912,12 +912,13 @@ static void PlayBookmark( intf_thread_t *p_intf, int i_num )
     if( p_playlist )
     {
         char *psz_bookmark = strdup( val.psz_string );
-        for( i_position = 0; i_position < p_playlist->i_size; i_position++)
+        for( i = 0; i < p_playlist->pp_all_items; i++)
         {
             if( !strcmp( psz_bookmark,
-                         p_playlist->pp_items[i_position]->input.psz_uri ) )
+                         p_playlist->pp_items[i]->p_input->psz_uri ) )
             {
-                playlist_Goto( p_playlist, i_position );
+                playlist_LockControl( p_playlist, PLAYLIST_ITEMPLAY,
+                                      p_playlist->pp_items[i] );
                 break;
             }
         }
@@ -938,9 +939,9 @@ static void SetBookmark( intf_thread_t *p_intf, int i_num )
         if( p_playlist->status.p_item )
         {
             config_PutPsz( p_intf, psz_bookmark_name,
-                           p_playlist->status.p_item->input.psz_uri);
+                           p_playlist->status.p_item->p_input->psz_uri);
             msg_Info( p_intf, "setting playlist bookmark %i to %s", i_num,
-                           p_playlist->status.p_item->input.psz_uri);
+                           p_playlist->status.p_item->p_input->psz_uri);
             config_SaveConfigFile( p_intf, "hotkeys" );
         }
         vlc_object_release( p_playlist );
index b08f558b9dfec79682f52d6d644e186b5136463b..4d274c742908cd5ea4ae9368416bd5a41c05213b 100644 (file)
@@ -130,7 +130,7 @@ char *E_(ExtractURIValue)( char *psz_uri, const char *psz_name,
 int E_(TestURIParam)( char *psz_uri, const char *psz_name );
 
 /** This function parses a MRL */
-playlist_item_t *E_(MRLParse)( intf_thread_t *, char *psz, char *psz_name );
+input_item_t *E_(MRLParse)( intf_thread_t *, char *psz, char *psz_name );
 
 /** Return the first word from a string (works in-place) */
 char *E_(FirstWord)( char *psz, char *new );
index 60c5454248d60e518859e406abe7653cc9bf0daf..34795bb65ccbec37b09245a661f96941ab730eeb 100644 (file)
@@ -303,7 +303,7 @@ void E_(MacroDo)( httpd_file_sys_t *p_args,
                 {
                     char mrl[1024], psz_name[1024], tmp[1024];
                     char *p, *str;
-                    playlist_item_t *p_item;
+                    input_item_t *p_input;
 
                     E_(ExtractURIValue)( p_request, "mrl", tmp, 1024 );
                     decode_URI( tmp );
@@ -327,16 +327,16 @@ void E_(MacroDo)( httpd_file_sys_t *p_args,
                     }
                     *p = '\0';
 
-                    p_item = E_(MRLParse)( p_intf, mrl, psz_name );
+                    p_input = E_(MRLParse)( p_intf, mrl, psz_name );
 
-                    if( !p_item || !p_item->input.psz_uri ||
-                        !*p_item->input.psz_uri )
+                    if( !p_input || p_input->psz_uri ||
+                        !*p_input->psz_uri )
                     {
                         msg_Dbg( p_intf, "invalid requested mrl: %s", mrl );
                     }
                     else
                     {
-                        playlist_AddItem( p_sys->p_playlist, p_item,
+                        playlist_PlaylistAddInput( p_sys->p_playlist, p_input,
                                           PLAYLIST_APPEND, PLAYLIST_END );
                         msg_Dbg( p_intf, "requested mrl add: %s", mrl );
                     }
@@ -401,11 +401,13 @@ void E_(MacroDo)( httpd_file_sys_t *p_args,
                         for( j = 0 ; j < i_nb_items ; j++ )
                         {
                             if( p_items[j] ==
-                                p_sys->p_playlist->pp_items[i]->input.i_id ) break;
+                                p_sys->p_playlist->pp_items[i]->p_input->i_id )
+                                break;
                         }
                         if( j == i_nb_items )
                         {
-                            playlist_LockDelete( p_sys->p_playlist, p_sys->p_playlist->pp_items[i]->input.i_id );
+                            playlist_LockDelete( p_sys->p_playlist,
+                            p_sys->p_playlist->pp_items[i]->p_input->i_id );
                             msg_Dbg( p_intf, "requested playlist delete: %d",
                                      i );
                         }
@@ -439,7 +441,8 @@ void E_(MacroDo)( httpd_file_sys_t *p_args,
                     if( !strcmp( type , "title" ) )
                     {
                         playlist_RecursiveNodeSort( p_sys->p_playlist, /*playlist_ItemGetById( p_sys->p_playlist, i_item ),*/
-                                                    p_sys->p_playlist->pp_views[0]->p_root,
+                                                    /* Ugly hack,but not worse than before ... */
+                                                    p_sys->p_playlist->p_root_onelevel,
                                                     SORT_TITLE_NODES_FIRST,
                                                     ( i_order == 0 ) ? ORDER_NORMAL : ORDER_REVERSE );
                         msg_Dbg( p_intf, "requested playlist sort by title (%d)" , i_order );
@@ -447,7 +450,7 @@ void E_(MacroDo)( httpd_file_sys_t *p_args,
                     else if( !strcmp( type , "author" ) )
                     {
                         playlist_RecursiveNodeSort( p_sys->p_playlist, /*playlist_ItemGetById( p_sys->p_playlist, i_item ),*/
-                                                    p_sys->p_playlist->pp_views[0]->p_root,
+                                                    p_sys->p_playlist->p_root_onelevel,
                                                     SORT_AUTHOR,
                                                     ( i_order == 0 ) ? ORDER_NORMAL : ORDER_REVERSE );
                         msg_Dbg( p_intf, "requested playlist sort by author (%d)" , i_order );
@@ -455,7 +458,7 @@ void E_(MacroDo)( httpd_file_sys_t *p_args,
                     else if( !strcmp( type , "shuffle" ) )
                     {
                         playlist_RecursiveNodeSort( p_sys->p_playlist, /*playlist_ItemGetById( p_sys->p_playlist, i_item ),*/
-                                                    p_sys->p_playlist->pp_views[0]->p_root,
+                                                    p_sys->p_playlist->p_root_onelevel,
                                                     SORT_RANDOM,
                                                     ( i_order == 0 ) ? ORDER_NORMAL : ORDER_REVERSE );
                         msg_Dbg( p_intf, "requested playlist shuffle");
@@ -473,6 +476,8 @@ void E_(MacroDo)( httpd_file_sys_t *p_args,
                     E_(ExtractURIValue)( p_request, "psz_newpos", psz_newpos, 6 );
                     i_pos = atoi( psz_pos );
                     i_newpos = atoi( psz_newpos );
+                    /* FIXME FIXME TODO TODO XXX XXX
+                    ( duplicate from rpn.c )
                     if ( i_pos < i_newpos )
                     {
                         playlist_Move( p_sys->p_playlist, i_pos, i_newpos + 1 );
@@ -482,6 +487,7 @@ void E_(MacroDo)( httpd_file_sys_t *p_args,
                         playlist_Move( p_sys->p_playlist, i_pos, i_newpos );
                     }
                     msg_Dbg( p_intf, "requested move playlist item %d to %d", i_pos, i_newpos);
+                    FIXME FIXME TODO TODO XXX XXX */
                     break;
                 }
 
index e3d262bc0ed513d1b2d85a7a20c6324ba5e03973..bbad22de3ea693d01fb1244fd7de6464615057a4 100644 (file)
@@ -279,19 +279,10 @@ mvar_t *E_(mvar_IntegerSetNew)( const char *name, const char *arg )
 mvar_t *E_(mvar_PlaylistSetNew)( intf_thread_t *p_intf, char *name,
                                  playlist_t *p_pl )
 {
-    playlist_view_t *p_view;
     mvar_t *s = E_(mvar_New)( name, "set" );
-
-
     vlc_mutex_lock( &p_pl->object_lock );
-
-    p_view = playlist_ViewFind( p_pl, VIEW_CATEGORY ); /* FIXME */
-
-    if( p_view != NULL )
-        E_(PlaylistListNode)( p_intf, p_pl, p_view->p_root, name, s, 0 );
-
+    E_(PlaylistListNode)( p_intf, p_pl, p_pl->p_root_category , name, s, 0 );
     vlc_mutex_unlock( &p_pl->object_lock );
-
     return s;
 }
 
index 09b072f89d75f769fed8d4adad79d2fc357fb9d5..14c15167fbda3f1522d3beb834717b15877b72e8 100644 (file)
@@ -830,7 +830,7 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t  *vars,
             char *psz_name = E_(SSPop)( st );
             char *mrl = E_(SSPop)( st );
             char *tmp;
-            playlist_item_t *p_item;
+            input_item_t *p_input;
             int i_id;
 
             tmp = E_(ToUTF8)( p_intf, psz_name );
@@ -842,22 +842,21 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t  *vars,
 
             if( !*psz_name )
             {
-                p_item = E_(MRLParse)( p_intf, mrl, mrl );
+                p_input = E_(MRLParse)( p_intf, mrl, mrl );
             }
             else
             {
-                p_item = E_(MRLParse)( p_intf, mrl, psz_name );
+                p_input = E_(MRLParse)( p_intf, mrl, psz_name );
             }
 
-            if( p_item == NULL || p_item->input.psz_uri == NULL ||
-                 !*p_item->input.psz_uri )
+            if( !p_input || !p_input->psz_uri || !*p_input->psz_uri )
             {
                 i_id = VLC_EGENERIC;
                 msg_Dbg( p_intf, "invalid requested mrl: %s", mrl );
             }
             else
             {
-                i_id = playlist_AddItem( p_sys->p_playlist, p_item,
+                i_id = playlist_PlaylistAddInput( p_sys->p_playlist, p_input,
                                          PLAYLIST_APPEND, PLAYLIST_END );
                 msg_Dbg( p_intf, "requested mrl add: %s", mrl );
             }
@@ -879,8 +878,10 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t  *vars,
         }
         else if( !strcmp( s, "playlist_move" ) )
         {
-            int i_newpos = E_(SSPopN)( st, vars );
-            int i_pos = E_(SSPopN)( st, vars );
+            /*int i_newpos =*/ E_(SSPopN)( st, vars );
+            /*int i_pos =*/ E_(SSPopN)( st, vars );
+            /* FIXME FIXME TODO TODO XXX XXX
+            do not release before fixing this
             if ( i_pos < i_newpos )
             {
                 playlist_Move( p_sys->p_playlist, i_pos, i_newpos + 1 );
@@ -891,6 +892,8 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t  *vars,
             }
             msg_Dbg( p_intf, "requested to move playlist item %d to %d",
                      i_pos, i_newpos);
+               FIXME FIXME TODO TODO XXX XXX */
+            msg_Err( p_intf, "moving using indexes is obsolete. We need to update this function" );
         }
         else if( !strcmp( s, "playlist_sort" ) )
         {
@@ -898,11 +901,15 @@ void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t  *vars,
             int i_sort = E_(SSPopN)( st, vars );
             i_order = i_order % 2;
             i_sort = i_sort % 9;
+            /* FIXME FIXME TODO TODO XXX XXX
+            do not release before fixing this
             playlist_RecursiveNodeSort(  p_sys->p_playlist,
                                          p_sys->p_playlist->p_general,
                                          i_sort, i_order );
             msg_Dbg( p_intf, "requested sort playlist by : %d in order : %d",
                      i_sort, i_order );
+               FIXME FIXME TODO TODO XXX XXX */
+            msg_Err( p_intf, "this needs to be fixed to use the new playlist framework" );
         }
         else if( !strcmp( s, "services_discovery_add" ) )
         {
index ae29a2caa3a0f21b0bb1afc3002b3e84e2c4fbd3..6f2a32f9f4e27c136345c0e80aae7682539021f6 100644 (file)
@@ -428,14 +428,14 @@ void E_(PlaylistListNode)( intf_thread_t *p_intf, playlist_t *p_pl,
             sprintf( value, "%d", ( p_pl->status.p_item == p_node )? 1 : 0 );
             E_(mvar_AppendNewVar)( itm, "current", value );
 
-            sprintf( value, "%d", p_node->input.i_id );
+            sprintf( value, "%d", p_node->p_input->i_id );
             E_(mvar_AppendNewVar)( itm, "index", value );
 
-            psz = E_(FromUTF8)( p_intf, p_node->input.psz_name );
+            psz = E_(FromUTF8)( p_intf, p_node->p_input->psz_name );
             E_(mvar_AppendNewVar)( itm, "name", psz );
             free( psz );
 
-            psz = E_(FromUTF8)( p_intf, p_node->input.psz_uri );
+            psz = E_(FromUTF8)( p_intf, p_node->p_input->psz_uri );
             E_(mvar_AppendNewVar)( itm, "uri", psz );
             free( psz );
 
@@ -454,7 +454,7 @@ void E_(PlaylistListNode)( intf_thread_t *p_intf, playlist_t *p_pl,
                 E_(mvar_AppendNewVar)( itm, "ro", "rw" );
             }
 
-            sprintf( value, "%ld", (long)p_node->input.i_duration );
+            sprintf( value, "%ld", (long)p_node->p_input->i_duration );
             E_(mvar_AppendNewVar)( itm, "duration", value );
 
             E_(mvar_AppendVar)( s, itm );
@@ -466,7 +466,7 @@ void E_(PlaylistListNode)( intf_thread_t *p_intf, playlist_t *p_pl,
             int i_child;
             mvar_t *itm = E_(mvar_New)( name, "set" );
 
-            psz = E_(FromUTF8)( p_intf, p_node->input.psz_name );
+            psz = E_(FromUTF8)( p_intf, p_node->p_input->psz_name );
             E_(mvar_AppendNewVar)( itm, "name", psz );
             E_(mvar_AppendNewVar)( itm, "uri", psz );
             free( psz );
@@ -474,7 +474,7 @@ void E_(PlaylistListNode)( intf_thread_t *p_intf, playlist_t *p_pl,
             sprintf( value, "Node" );
             E_(mvar_AppendNewVar)( itm, "type", value );
 
-            sprintf( value, "%d", p_node->input.i_id );
+            sprintf( value, "%d", p_node->p_input->i_id );
             E_(mvar_AppendNewVar)( itm, "index", value );
 
             sprintf( value, "%d", p_node->i_children);
@@ -864,13 +864,13 @@ static char *FirstOption( char *psz, char *new )
         return NULL;
 }
 
-playlist_item_t *E_(MRLParse)( intf_thread_t *p_intf, char *_psz,
-                               char *psz_name )
+input_item_t *E_(MRLParse)( intf_thread_t *p_intf, char *_psz,
+                                   char *psz_name )
 {
     char *psz = strdup( _psz );
     char *s_mrl = psz;
     char *s_temp;
-    playlist_item_t * p_item = NULL;
+    input_item_t * p_input = NULL;
 
     /* extract the mrl */
     s_temp = FirstOption( s_mrl, s_mrl );
@@ -879,7 +879,7 @@ playlist_item_t *E_(MRLParse)( intf_thread_t *p_intf, char *_psz,
         s_temp = s_mrl + strlen( s_mrl );
     }
 
-    p_item = playlist_ItemNew( p_intf, s_mrl, psz_name );
+    p_input = input_ItemNew( p_intf, s_mrl, psz_name );
     s_mrl = s_temp;
 
     /* now we can take care of the options */
@@ -892,13 +892,12 @@ playlist_item_t *E_(MRLParse)( intf_thread_t *p_intf, char *_psz,
         {
             s_temp = s_mrl + strlen( s_mrl );
         }
-        playlist_ItemAddOption( p_item, s_mrl );
+        vlc_input_item_AddOption( p_input, s_mrl );
         s_mrl = s_temp;
     }
 
     free( psz );
-
-    return p_item;
+    return p_input;
 }
 
 /**********************************************************************
index 05c104b1829b6586a02e3e8b483ca2d5e1473cb7..897b8e24404bcbc46d93a65a0be4e704612efef4 100644 (file)
@@ -201,7 +201,6 @@ vlc_module_end();
 static int Activate( vlc_object_t *p_this )
 {
     intf_thread_t *p_intf = (intf_thread_t*)p_this;
-    playlist_t *p_playlist;
     char *psz_host, *psz_unix_path;
     int  *pi_socket = NULL;
 
@@ -321,17 +320,6 @@ static int Activate( vlc_object_t *p_this )
     CONSOLE_INTRO_MSG;
 #endif
 
-    /* Force "no-view" mode */
-    p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
-                                                 FIND_ANYWHERE );
-    if( p_playlist )
-    {
-        vlc_mutex_lock( &p_playlist->object_lock );
-        p_playlist->status.i_view = -1;
-        vlc_mutex_unlock( &p_playlist->object_lock );
-        vlc_object_release( p_playlist );
-    }
-
     msg_rc( _("Remote control interface initialized. Type `help' for help.") );
     return VLC_SUCCESS;
 }
@@ -1234,6 +1222,7 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
                                            FIND_ANYWHERE );
     if( !p_playlist )
     {
+        msg_Err( p_this, "no playlist" );
         return VLC_ENOOBJ;
     }
 
@@ -1241,7 +1230,8 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
     {
         vlc_value_t val;
         var_Get( p_playlist->p_input, "state", &val );
-        if( ( val.i_int == PAUSE_S ) || ( val.i_int == PLAYLIST_PAUSED ) )        {
+        if( ( val.i_int == PAUSE_S ) || ( val.i_int == PLAYLIST_PAUSED ) )
+        {
             msg_rc( _("Type 'menu select' or 'pause' to continue.") );
             vlc_object_release( p_playlist );
             return VLC_EGENERIC;
@@ -1259,29 +1249,12 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
     }
     else if( !strcmp( psz_cmd, "play" ) )
     {
-        if( p_playlist->p_input )
-        {
-            vlc_value_t val;
-
-            var_Get( p_playlist->p_input, "rate", &val );
-            if( val.i_int != INPUT_RATE_DEFAULT )
-            {
-                val.i_int = INPUT_RATE_DEFAULT;
-                var_Set( p_playlist->p_input, "rate", val );
-            }
-            else
-            {
-                playlist_Play( p_playlist );
-            }
-        }
+        msg_Warn( p_playlist, "play" );
+        playlist_Play( p_playlist );
     }
     else if (!strcmp( psz_cmd, "goto" ) )
     {
-        if( strlen( newval.psz_string ) > 0)
-        {
-            val.i_int = atoi( newval.psz_string );
-            playlist_Goto( p_playlist, val.i_int);
-        }
+        msg_Err( p_playlist, "goto is deprecated" );
     }
     else if( !strcmp( psz_cmd, "stop" ) )
     {
@@ -1302,26 +1275,16 @@ static int Playlist( vlc_object_t *p_this, char const *psz_cmd,
         if( p_item )
         {
             msg_rc( "Trying to add %s to playlist.", newval.psz_string );
-            playlist_AddItem( p_playlist, p_item,
-                              PLAYLIST_GO|PLAYLIST_APPEND, PLAYLIST_END );
+//            playlist_AddItem( p_playlist, p_item,
+//                              PLAYLIST_GO|PLAYLIST_APPEND, PLAYLIST_END );
         }
     }
     else if( !strcmp( psz_cmd, "playlist" ) )
     {
         int i;
-
-        for ( i = 0; i < p_playlist->i_size; i++ )
-        {
-            msg_rc( "|%s%s   %s|%s|", i == p_playlist->i_index ? "*" : " ",
-                    p_playlist->pp_items[i]->input.psz_name,
-                    p_playlist->pp_items[i]->input.psz_uri,
-                    p_playlist->pp_items[i]->i_parents > 0 ?
-                    p_playlist->pp_items[i]->pp_parents[0]->p_parent->input.psz_name : "" );
-        }
-        if ( i == 0 )
-        {
-            msg_rc( "| no entries" );
-        }
+        playlist_view_t *p_view;
+        playlist_NodeDump( p_playlist, p_playlist->p_root_category, 0 );
+        playlist_NodeDump( p_playlist, p_playlist->p_root_onelevel, 0 );
     }
     else if( !strcmp( psz_cmd, "status" ) )
     {
index c315a0486f90c0f9db6e063c917040f9be6f13c2..79c00d95201200576d89b5a05a8fa2cf7788932e 100644 (file)
@@ -219,7 +219,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
     demux_sys_t *p_sys = p_demux->p_sys;
     int64_t     *pi64;
     int         i;
-    vlc_meta_t **pp_meta;
+    vlc_meta_t *p_meta;
 
     switch( i_query )
     {
@@ -232,8 +232,8 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             return VLC_SUCCESS;
 
         case DEMUX_GET_META:
-            pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
-            *pp_meta = vlc_meta_Duplicate( p_sys->meta );
+            p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
+            vlc_meta_Merge( p_meta, p_sys->meta );
             return VLC_SUCCESS;
 
         case DEMUX_SET_POSITION:
@@ -812,25 +812,27 @@ static int DemuxInit( demux_t *p_demux )
     {
         if( p_cd->psz_title && *p_cd->psz_title )
         {
-            vlc_meta_Add( p_sys->meta, VLC_META_TITLE, p_cd->psz_title );
+            vlc_meta_SetTitle( p_sys->meta, p_cd->psz_title );
         }
         if( p_cd->psz_author && *p_cd->psz_author )
         {
-             vlc_meta_Add( p_sys->meta, VLC_META_AUTHOR, p_cd->psz_author );
+             vlc_meta_SetAuthor( p_sys->meta, p_cd->psz_author );
         }
         if( p_cd->psz_copyright && *p_cd->psz_copyright )
         {
-            vlc_meta_Add( p_sys->meta, VLC_META_COPYRIGHT, p_cd->psz_copyright );
+            vlc_meta_SetCopyright( p_sys->meta, p_cd->psz_copyright );
         }
         if( p_cd->psz_description && *p_cd->psz_description )
         {
-            vlc_meta_Add( p_sys->meta, VLC_META_DESCRIPTION, p_cd->psz_description );
+            vlc_meta_SetDescription( p_sys->meta, p_cd->psz_description );
         }
         if( p_cd->psz_rating && *p_cd->psz_rating )
         {
-            vlc_meta_Add( p_sys->meta, VLC_META_RATING, p_cd->psz_rating );
+            vlc_meta_SetRating( p_sys->meta, p_cd->psz_rating );
         }
     }
+    fprintf( stderr, "*********** Unhandled child meta\n" );
+#if 0
     for( i_stream = 0, i = 0; i < 128; i++ )
     {
         asf_object_codec_list_t *p_cl = ASF_FindObject( p_sys->p_root->p_hdr,
@@ -859,6 +861,7 @@ static int DemuxInit( demux_t *p_demux )
             i_stream++;
         }
     }
+#endif
 
     es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
     return VLC_SUCCESS;
index 98088fb49077b2c2f0085c3d876a5bf95a5c0695..73040eaacb220040d3355c16b0fd74c444b33eaa 100644 (file)
@@ -327,7 +327,7 @@ static int Open( vlc_object_t * p_this )
                  p_avih->i_flags&AVIF_MUSTUSEINDEX?" MUST_USE_INDEX":"",
                  p_avih->i_flags&AVIF_ISINTERLEAVED?" IS_INTERLEAVED":"",
                  p_avih->i_flags&AVIF_TRUSTCKTYPE?" TRUST_CKTYPE":"" );
-        vlc_meta_Add( p_sys->meta, VLC_META_SETTING, buffer );
+        vlc_meta_SetSetting( p_sys->meta, buffer );
     }
 
     /* now read info on each stream and create ES */
@@ -1308,7 +1308,7 @@ static int    Control( demux_t *p_demux, int i_query, va_list args )
     int i;
     double   f, *pf;
     int64_t i64, *pi64;
-    vlc_meta_t **pp_meta;
+    vlc_meta_t *p_meta;
 
     switch( i_query )
     {
@@ -1369,8 +1369,8 @@ static int    Control( demux_t *p_demux, int i_query, va_list args )
             }
             return VLC_SUCCESS;
         case DEMUX_GET_META:
-            pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
-            *pp_meta = vlc_meta_Duplicate( p_sys->meta );
+            p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
+            vlc_meta_Merge( p_meta,  p_sys->meta );
             return VLC_SUCCESS;
 
         default:
index c007694168563785b69ef5a48334b98af1548823..64f302f9c57c8402ecf71cc6669b7068cdb4e7e9 100644 (file)
@@ -91,7 +91,7 @@ static int Open( vlc_object_t * p_this )
     p_demux->p_sys      = p_sys = malloc( sizeof( demux_sys_t ) );
     es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 'f', 'l', 'a', 'c' ) );
     p_sys->b_start = VLC_TRUE;
-    p_sys->p_meta = 0;
+    p_sys->p_meta = NULL;
 
     /* We need to read and store the STREAMINFO metadata */
     i_peek = stream_Peek( p_demux->s, &p_peek, 8 );
@@ -231,10 +231,9 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
     if( i_query == DEMUX_SET_TIME ) return VLC_EGENERIC;
     else if( i_query == DEMUX_GET_META )
     {
-        vlc_meta_t **pp_meta = (vlc_meta_t **)va_arg( args, vlc_meta_t** );
+        vlc_meta_t *p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t* );
         if( p_demux->p_sys->p_meta )
-            *pp_meta = vlc_meta_Duplicate( p_demux->p_sys->p_meta );
-        else *pp_meta = NULL;
+            vlc_meta_Merge( p_meta, p_demux->p_sys->p_meta );
         return VLC_SUCCESS;
     }
     else return demux2_vaControlHelper( p_demux->s, 0, -1,
index 161136aacaa2919403ebccf6d912896e440d2721..a60812785b05180969dbcb2478c6032e387b01d6 100644 (file)
@@ -68,10 +68,8 @@ vlc_module_begin();
     set_description( _("Playlist metademux") );
     set_capability( "demux2", 5 );
     set_callbacks( Activate, Deactivate );
-    add_shortcut( "m3u" );
     add_shortcut( "asx" );
     add_shortcut( "html" );
-    add_shortcut( "pls" );
     add_shortcut( "b4s" );
 vlc_module_end();
 
@@ -91,10 +89,7 @@ static int Activate( vlc_object_t * p_this )
     /* Check for m3u/asx file extension or if the demux has been forced */
     psz_ext = strrchr ( p_demux->psz_path, '.' );
 
-    if( ( psz_ext && !strcasecmp( psz_ext, ".m3u") ) ||
-        /* a .ram file can contain a single rtsp link */
-        ( psz_ext && !strcasecmp( psz_ext, ".ram") ) ||
-        ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "m3u") ) )
+    if(( psz_ext && !strcasecmp( psz_ext, ".ram") ) )
     {
         i_type = TYPE_M3U;
     }
@@ -108,11 +103,6 @@ static int Activate( vlc_object_t * p_this )
     {
         i_type = TYPE_HTML;
     }
-    else if( ( psz_ext && !strcasecmp( psz_ext, ".pls") ) ||
-             ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "pls") ) )
-    {
-        i_type = TYPE_PLS;
-    }
     else if( ( psz_ext && !strcasecmp( psz_ext, ".b4s") ) ||
              ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "b4s") ) )
     {
index cfaebc1c1a54b7794692f569c537a603dc01dc69..a86f299174a3f5a212657a9055058bbff6895d46 100644 (file)
@@ -1592,13 +1592,13 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
     int         i_skp;
     size_t      i_idx;
 
-    vlc_meta_t **pp_meta;
+    vlc_meta_t *p_meta;
 
     switch( i_query )
     {
         case DEMUX_GET_META:
-            pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
-            *pp_meta = vlc_meta_Duplicate( p_sys->meta );
+            p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
+            vlc_meta_Merge( p_meta, p_sys->meta );
             return VLC_SUCCESS;
 
         case DEMUX_GET_LENGTH:
@@ -4917,54 +4917,30 @@ void matroska_segment_c::InformationCreate( )
 
     if( psz_title )
     {
-        vlc_meta_Add( sys.meta, VLC_META_TITLE, psz_title );
+        vlc_meta_SetTitle( sys.meta, psz_title );
     }
     if( psz_date_utc )
     {
-        vlc_meta_Add( sys.meta, VLC_META_DATE, psz_date_utc );
+        vlc_meta_SetDate( sys.meta, psz_date_utc );
     }
     if( psz_segment_filename )
     {
-        vlc_meta_Add( sys.meta, _("Segment filename"), psz_segment_filename );
+        fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
     }
     if( psz_muxing_application )
     {
-        vlc_meta_Add( sys.meta, _("Muxing application"), psz_muxing_application );
+        fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
     }
     if( psz_writing_application )
     {
-        vlc_meta_Add( sys.meta, _("Writing application"), psz_writing_application );
+        fprintf( stderr, "***** WARNING: Unhandled meta - Use custom\n" );
     }
 
     for( i_track = 0; i_track < tracks.size(); i_track++ )
     {
-        mkv_track_t *tk = tracks[i_track];
-        vlc_meta_t *mtk = vlc_meta_New();
-
-        sys.meta->track = (vlc_meta_t**)realloc( sys.meta->track,
-                                                    sizeof( vlc_meta_t * ) * ( sys.meta->i_track + 1 ) );
-        sys.meta->track[sys.meta->i_track++] = mtk;
-
-        if( tk->fmt.psz_description )
-        {
-            vlc_meta_Add( sys.meta, VLC_META_DESCRIPTION, tk->fmt.psz_description );
-        }
-        if( tk->psz_codec_name )
-        {
-            vlc_meta_Add( sys.meta, VLC_META_CODEC_NAME, tk->psz_codec_name );
-        }
-        if( tk->psz_codec_settings )
-        {
-            vlc_meta_Add( sys.meta, VLC_META_SETTING, tk->psz_codec_settings );
-        }
-        if( tk->psz_codec_info_url )
-        {
-            vlc_meta_Add( sys.meta, VLC_META_CODEC_DESCRIPTION, tk->psz_codec_info_url );
-        }
-        if( tk->psz_codec_download_url )
-        {
-            vlc_meta_Add( sys.meta, VLC_META_URL, tk->psz_codec_download_url );
-        }
+//        mkv_track_t *tk = tracks[i_track];
+//        vlc_meta_t *mtk = vlc_meta_New();
+        fprintf( stderr, "***** WARNING: Unhandled child meta\n");
     }
 
     if( i_tags_position >= 0 )
index 884aad8bd3db88b67371a310c3c32884c98e9494..586bcfdc3beaf556538e8c15a6f6fe569fe9db68 100644 (file)
@@ -387,6 +387,8 @@ static int Open( vlc_object_t * p_this )
                         !strncmp( psz_ref, "rtsp://", 7 ) )
                     {
                         msg_Dbg( p_demux, "adding ref = `%s'", psz_ref );
+                        msg_Err( p_demux, "REF is broken (fix playlist") ;
+#if 0
                         if( p_item )
                         {
                             playlist_item_t *p_child =
@@ -402,6 +404,7 @@ static int Open( vlc_object_t * p_this )
                                 b_play = VLC_TRUE;
                             }
                         }
+#endif
                     }
                     else
                     {
@@ -422,6 +425,8 @@ static int Open( vlc_object_t * p_this )
                         }
                         strcat( psz_absolute, psz_ref );
                         msg_Dbg( p_demux, "adding ref = `%s'", psz_absolute );
+                        msg_Err( p_demux, "Ref broken (fix playlist" );
+#if 0
                         if( p_item )
                         {
                             playlist_item_t *p_child =
@@ -438,6 +443,7 @@ static int Open( vlc_object_t * p_this )
                                 b_play = VLC_TRUE;
                             }
                         }
+#endif
                     }
                 }
                 else
@@ -449,7 +455,6 @@ static int Open( vlc_object_t * p_this )
             if( b_play == VLC_TRUE )
             {
                  playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
-                                   p_playlist->status.i_view,
                                    p_playlist->status.p_item, NULL );
             }
             vlc_object_release( p_playlist );
@@ -799,15 +804,13 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
 
         case DEMUX_GET_META:
         {
-            vlc_meta_t **pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );
-            vlc_meta_t *meta;
+            vlc_meta_t *p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t*);
             MP4_Box_t  *p_udta   = MP4_BoxGet( p_sys->p_root, "/moov/udta" );
             MP4_Box_t  *p_0xa9xxx;
             if( p_udta == NULL )
             {
                 return VLC_EGENERIC;
             }
-            *pp_meta = meta = vlc_meta_New();
             for( p_0xa9xxx = p_udta->p_first; p_0xa9xxx != NULL;
                  p_0xa9xxx = p_0xa9xxx->p_next )
             {
@@ -824,25 +827,25 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                 switch( p_0xa9xxx->i_type )
                 {
                 case FOURCC_0xa9nam: /* Full name */
-                    vlc_meta_Add( meta, VLC_META_TITLE, psz_utf );
+                    vlc_meta_SetArtist( p_meta, psz_utf );
                     break;
                 case FOURCC_0xa9aut:
-                    vlc_meta_Add( meta, VLC_META_AUTHOR, psz_utf );
+                    vlc_meta_SetAuthor( p_meta, psz_utf );
                     break;
                 case FOURCC_0xa9ART:
-                    vlc_meta_Add( meta, VLC_META_ARTIST, psz_utf );
+                    vlc_meta_SetArtist( p_meta, psz_utf );
                     break;
                 case FOURCC_0xa9cpy:
-                    vlc_meta_Add( meta, VLC_META_COPYRIGHT, psz_utf );
+                    vlc_meta_SetCopyright( p_meta, psz_utf );
                     break;
                 case FOURCC_0xa9day: /* Creation Date */
-                    vlc_meta_Add( meta, VLC_META_DATE, psz_utf );
+                    vlc_meta_SetDate( p_meta, psz_utf );
                     break;
                 case FOURCC_0xa9des: /* Description */
-                    vlc_meta_Add( meta, VLC_META_DESCRIPTION, psz_utf );
+                    vlc_meta_SetDescription( p_meta, psz_utf );
                     break;
                 case FOURCC_0xa9gen: /* Genre */
-                    vlc_meta_Add( meta, VLC_META_GENRE, psz_utf );
+                    vlc_meta_SetGenre( p_meta, psz_utf );
                     break;
 
                 case FOURCC_0xa9swr:
index 4d14fc74cee875a622f3a8a22e24de3ee1caf296..e1e3951d6c0a223ea87a94b8781ceb3b0ee6d045 100644 (file)
@@ -371,15 +371,14 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
 {
     demux_sys_t *p_sys  = p_demux->p_sys;
     int64_t *pi64;
-    vlc_meta_t **pp_meta;
+    vlc_meta_t *p_meta;
     int i_ret;
 
     switch( i_query )
     {
         case DEMUX_GET_META:
-            pp_meta = (vlc_meta_t **)va_arg( args, vlc_meta_t** );
-            if( p_sys->meta ) *pp_meta = vlc_meta_Duplicate( p_sys->meta );
-            else *pp_meta = NULL;
+            p_meta = (vlc_meta_t *)va_arg( args, vlc_meta_t* );
+            vlc_meta_Merge( p_meta, p_sys->meta );
             return VLC_SUCCESS;
 
         case DEMUX_GET_TIME:
index da134dafa0f200bf51dc34beecb1dada2b81b3a7..272490d4f49111ed99977e5814b3a8b6898a7b35 100644 (file)
 struct demux_sys_t
 {
     char *psz_prefix;
-    playlist_t *p_playlist;
     xml_t *p_xml;
     xml_reader_t *p_xml_reader;
-    int b_shout;
 };
 
 /*****************************************************************************
@@ -51,9 +49,6 @@ static int Demux( demux_t *p_demux);
 static int Control( demux_t *p_demux, int i_query, va_list args );
 static char *GetNextToken(char *psz_cur_string);
 static int IsWhitespace( char *psz_string );
-static void ShoutcastAdd( playlist_t *p_playlist, playlist_item_t* p_genre,
-                          playlist_item_t *p_bitrate, playlist_item_t *p_item,
-                          char *psz_genre, char *psz_bitrate );
 
 /*****************************************************************************
  * Import_B4S: main import function
@@ -68,8 +63,7 @@ int E_(Import_B4S)( vlc_object_t *p_this )
     psz_ext = strrchr ( p_demux->psz_path, '.' );
 
     if( ( psz_ext && !strcasecmp( psz_ext, ".b4s") ) ||
-        ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "b4s-open") ) ||
-        ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "shout-b4s") ) )
+        ( p_demux->psz_demux && !strcmp(p_demux->psz_demux, "b4s-open") ) )
     {
         ;
     }
@@ -87,10 +81,7 @@ int E_(Import_B4S)( vlc_object_t *p_this )
         msg_Err( p_demux, "out of memory" );
         return VLC_ENOMEM;
     }
-    p_sys->b_shout = p_demux->psz_demux &&
-        !strcmp(p_demux->psz_demux, "shout-b4s");
     p_sys->psz_prefix = E_(FindPrefix)( p_demux );
-    p_sys->p_playlist = NULL;
     p_sys->p_xml = NULL;
     p_sys->p_xml_reader = NULL;
 
@@ -106,7 +97,6 @@ void E_(Close_B4S)( vlc_object_t *p_this )
     demux_sys_t *p_sys = p_demux->p_sys;
 
     if( p_sys->psz_prefix ) free( p_sys->psz_prefix );
-    if( p_sys->p_playlist ) vlc_object_release( p_sys->p_playlist );
     if( p_sys->p_xml_reader ) xml_ReaderDelete( p_sys->p_xml, p_sys->p_xml_reader );
     if( p_sys->p_xml ) xml_Delete( p_sys->p_xml );
     free( p_sys );
@@ -115,44 +105,19 @@ void E_(Close_B4S)( vlc_object_t *p_this )
 static int Demux( demux_t *p_demux )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
-    playlist_t *p_playlist;
-    playlist_item_t *p_item, *p_current;
+    playlist_item_t *p_item;
     playlist_item_t *p_bitrate = NULL, *p_genre = NULL;
 
-    vlc_bool_t b_play;
-    int i_ret;
+    int i_ret, i_parent_id;
 
     xml_t *p_xml;
     xml_reader_t *p_xml_reader;
     char *psz_elname = NULL;
-    int i_type, b_shoutcast;
+    int i_type;
     char *psz_mrl = NULL, *psz_name = NULL, *psz_genre = NULL;
     char *psz_now = NULL, *psz_listeners = NULL, *psz_bitrate = NULL;
 
-
-    b_shoutcast = p_sys->b_shout;
-
-    p_playlist = (playlist_t *) vlc_object_find( p_demux, VLC_OBJECT_PLAYLIST,
-                                                 FIND_ANYWHERE );
-    if( !p_playlist )
-    {
-        msg_Err( p_demux, "can't find playlist" );
-        return -1;
-    }
-    p_sys->p_playlist = p_playlist;
-
-    b_play = E_(FindItem)( p_demux, p_playlist, &p_current );
-
-    playlist_ItemToNode( p_playlist, p_current );
-    p_current->input.i_type = ITEM_TYPE_PLAYLIST;
-    if( b_shoutcast )
-    {
-        p_genre = playlist_NodeCreate( p_playlist, p_current->pp_parents[0]->i_view, "Genre", p_current );
-        playlist_CopyParents( p_current, p_genre );
-
-        p_bitrate = playlist_NodeCreate( p_playlist, p_current->pp_parents[0]->i_view, "Bitrate", p_current );
-        playlist_CopyParents( p_current, p_bitrate );
-    }
+    INIT_PLAYLIST_STUFF;
 
     p_xml = p_sys->p_xml = xml_Create( p_demux );
     if( !p_xml ) return -1;
@@ -170,6 +135,7 @@ static int Demux( demux_t *p_demux )
     if( xml_ReaderRead( p_xml_reader ) != 1 )
     {
         msg_Err( p_demux, "invalid file (no root node)" );
+        vlc_object_release( p_playlist );
         return -1;
     }
 
@@ -180,6 +146,7 @@ static int Demux( demux_t *p_demux )
         msg_Err( p_demux, "invalid root node %i, %s",
                  xml_ReaderNodeType( p_xml_reader ), psz_elname );
         if( psz_elname ) free( psz_elname );
+        vlc_object_release( p_playlist );
         return -1;
     }
     free( psz_elname );
@@ -317,82 +284,20 @@ static int Demux( demux_t *p_demux )
                 if( !psz_elname ) return -1;
                 if( !strcmp( psz_elname, "entry" ) )
                 {
-                    p_item = playlist_ItemNew( p_playlist, psz_mrl, psz_name );
+                    p_input = input_ItemNewExt( p_playlist, psz_mrl, psz_name,
+                                                0, NULL, -1 );
                     if( psz_now )
-                    {
-                        vlc_input_item_AddInfo( &(p_item->input),
-                                                _(VLC_META_INFO_CAT),
-                                                _( VLC_META_NOW_PLAYING ),
-                                                "%s",
-                                                psz_now );
-                    }
+                        vlc_meta_SetNowPlaying( p_input->p_meta, psz_now );
                     if( psz_genre )
-                    {
-                        vlc_input_item_AddInfo( &p_item->input,
-                                                _(VLC_META_INFO_CAT),
-                                                _( VLC_META_GENRE ),
-                                                "%s",
-                                                psz_genre );
-                    }
+                        vlc_meta_SetGenre( p_input->p_meta, psz_genre );
                     if( psz_listeners )
-                    {
-                        vlc_input_item_AddInfo( &p_item->input,
-                                                _(VLC_META_INFO_CAT),
-                                                _( "Listeners" ),
-                                                "%s",
-                                                psz_listeners );
-                    }
+                        msg_Err( p_playlist, "Unsupported meta listeners" );
                     if( psz_bitrate )
-                    {
-                        vlc_input_item_AddInfo( &p_item->input,
-                                                _(VLC_META_INFO_CAT),
-                                                _( "Bitrate" ),
-                                                "%s",
-                                                psz_bitrate );
-                    }
-                    playlist_NodeAddItem( p_playlist, p_item,
-                                          p_current->pp_parents[0]->i_view,
-                                          p_current, PLAYLIST_APPEND,
-                                          PLAYLIST_END );
-
-                    /* We need to declare the parents of the node as the
-                     *                  * same of the parent's ones */
-                    playlist_CopyParents( p_current, p_item );
-
-                    vlc_input_item_CopyOptions( &p_current->input,
-                                                &p_item->input );
-                    if( b_shoutcast )
-                    {
-                        char *psz_genreToken;
-                        char *psz_otherToken;
-                        int i = 0;
-
-                        psz_genreToken = psz_genre;
-
-                        /* split up the combined genre string form
-                        shoutcast and add the individual genres */
-                        while ( psz_genreToken &&
-                          ( psz_otherToken = GetNextToken(psz_genreToken )))
-                        {
-                            if( strlen(psz_genreToken)>2 )
-                            /* We dont want genres below 2 letters,
-                            this gets rid of alot of junk*/
-                            {
-                                /* lowercase everything */
-                                for( i=0; psz_genreToken[i]!=0; i++ )
-                                    psz_genreToken[i] =
-                                        tolower(psz_genreToken[i]);
-                /* Make first letter uppercase, purely cosmetical */
-                                psz_genreToken[0] =
-                                    toupper( psz_genreToken[0] );
-                                ShoutcastAdd( p_playlist, p_genre,
-                                              p_bitrate, p_item,
-                                              psz_genreToken, psz_bitrate );
-
-                                psz_genreToken = psz_otherToken;
-                            }
-                        }
-                    }
+                        msg_Err( p_playlist, "Unsupported meta bitrate" );
+
+                    playlist_AddWhereverNeeded( p_playlist, p_input, p_current,
+                         p_item_in_category, (i_parent_id > 0 ) ? VLC_TRUE:
+                                                 VLC_FALSE, PLAYLIST_APPEND );
 
 #define FREE(a) if( a ) free( a ); a = NULL;
                     FREE( psz_name );
@@ -415,25 +320,8 @@ static int Demux( demux_t *p_demux )
     {
         msg_Warn( p_demux, "error while parsing data" );
     }
-    if( b_shoutcast )
-    {
-        vlc_mutex_lock( &p_playlist->object_lock );
-        playlist_NodeSort( p_playlist, p_bitrate, SORT_TITLE_NUMERIC, ORDER_NORMAL );
-        vlc_mutex_unlock( &p_playlist->object_lock );
-    }
 
-    /* Go back and play the playlist */
-    if( b_play && p_playlist->status.p_item &&
-        p_playlist->status.p_item->i_children > 0 )
-    {
-        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
-                          p_playlist->status.i_view,
-                          p_playlist->status.p_item,
-                          p_playlist->status.p_item->pp_children[0] );
-    }
-    
-    vlc_object_release( p_playlist );
-    p_sys->p_playlist = NULL;
+    HANDLE_PLAY_AND_RELEASE;
     return VLC_SUCCESS;
 }
 
@@ -476,38 +364,3 @@ static int IsWhitespace( char *psz_string )
     }
     return VLC_TRUE;
 }
-
-static void ShoutcastAdd( playlist_t *p_playlist, playlist_item_t* p_genre,
-                          playlist_item_t *p_bitrate, playlist_item_t *p_item,
-                          char *psz_genre, char *psz_bitrate )
-{
-    playlist_item_t *p_parent;
-    if( psz_bitrate )
-    {
-        playlist_item_t *p_copy = playlist_ItemCopy(p_playlist,p_item);
-        p_parent = playlist_ChildSearchName( p_bitrate, psz_bitrate );
-        if( !p_parent )
-        {
-            p_parent = playlist_NodeCreate( p_playlist, p_genre->pp_parents[0]->i_view, psz_bitrate,
-                                            p_bitrate );
-            playlist_CopyParents( p_bitrate, p_parent );
-        }
-        playlist_NodeAddItem( p_playlist, p_copy, p_parent->pp_parents[0]->i_view, p_parent, PLAYLIST_APPEND, PLAYLIST_END  );
-        playlist_CopyParents( p_parent, p_copy );
-
-    }
-
-    if( psz_genre )
-    {
-        playlist_item_t *p_copy = playlist_ItemCopy(p_playlist,p_item);
-        p_parent = playlist_ChildSearchName( p_genre, psz_genre );
-        if( !p_parent )
-        {
-            p_parent = playlist_NodeCreate( p_playlist, p_genre->pp_parents[0]->i_view, psz_genre,
-                                            p_genre );
-            playlist_CopyParents( p_genre, p_parent );
-        }
-        playlist_NodeAddItem( p_playlist, p_copy, p_parent->pp_parents[0]->i_view, p_parent, PLAYLIST_APPEND, PLAYLIST_END );
-        playlist_CopyParents( p_parent, p_copy );
-    }
-}
index 8ad82ec1603242b1468d09699ce782241e7bacd5..e7e6b010fee7b54bb2f0a0dd8a05be2c15e92e4f 100644 (file)
@@ -100,6 +100,7 @@ void E_(Close_DVB)( vlc_object_t *p_this )
  *****************************************************************************/
 static int Demux( demux_t *p_demux )
 {
+#if 0
     playlist_t *p_playlist;
     char       *psz_line;
     playlist_item_t *p_current;
@@ -116,7 +117,7 @@ static int Demux( demux_t *p_demux )
     b_play = E_(FindItem)( p_demux, p_playlist, &p_current );
 
     playlist_ItemToNode( p_playlist, p_current );
-    p_current->input.i_type = ITEM_TYPE_PLAYLIST;
+    p_current->p_input->i_type = ITEM_TYPE_PLAYLIST;
 
     while( (psz_line = stream_ReadLine( p_demux->s )) )
     {
@@ -166,6 +167,7 @@ static int Demux( demux_t *p_demux )
 
     vlc_object_release( p_playlist );
     return VLC_SUCCESS;
+#endif
 }
 
 static struct
index 6fadf92bbdaaac45505e859bafadb4847a2b1830..931ad9b062c0bf8fc0891dadef6c16f7c3b6f7f5 100644 (file)
@@ -107,34 +107,16 @@ void E_(Close_M3U)( vlc_object_t *p_this )
 
 static int Demux( demux_t *p_demux )
 {
-    playlist_t *p_playlist;
     char       *psz_line;
-
     char       *psz_name = NULL;
     char       *psz_artist = NULL;
     int        i_parsed_duration = 0;
     mtime_t    i_duration = -1;
-    char       **ppsz_options = NULL;
-    int        i_options = 0, i;
-
-    playlist_item_t *p_item, *p_current;
-
-    vlc_bool_t b_play;
-
+    const char**ppsz_options = NULL;
+    int        i_options = 0, i, i_parent_id;
     vlc_bool_t b_cleanup = VLC_FALSE;
 
-    p_playlist = (playlist_t *) vlc_object_find( p_demux, VLC_OBJECT_PLAYLIST,
-                                                 FIND_ANYWHERE );
-    if( !p_playlist )
-    {
-        msg_Err( p_demux, "can't find playlist" );
-        return -1;
-    }
-
-    b_play = E_(FindItem)( p_demux, p_playlist, &p_current );
-
-    playlist_ItemToNode( p_playlist, p_current );
-    p_current->input.i_type = ITEM_TYPE_PLAYLIST;
+    INIT_PLAYLIST_STUFF;
 
     psz_line = stream_ReadLine( p_demux->s );
     while( psz_line )
@@ -172,7 +154,7 @@ static int Demux( demux_t *p_demux )
                                    sizeof("EXTVLCOPT:") -1 ) )
             {
                 /* VLC Option */
-                char *psz_option;
+                const char *psz_option;
                 psz_parse += sizeof("EXTVLCOPT:") -1;
                 if( !*psz_parse ) goto error;
 
@@ -199,28 +181,18 @@ static int Demux( demux_t *p_demux )
             EnsureUTF8( psz_name );
             EnsureUTF8( psz_mrl );
 
-            p_item = playlist_ItemNew( p_playlist, psz_mrl, psz_name );
             for( i = 0; i< i_options; i++ )
-            {
-                EnsureUTF8( ppsz_options[i] );
-                playlist_ItemAddOption( p_item, ppsz_options[i] );
-            }
-            p_item->input.i_duration = i_duration;
+                EnsureUTF8( (char*)ppsz_options[i] );
+
+            p_input = input_ItemNewExt( p_playlist, psz_mrl, psz_name,
+                                        i_options, ppsz_options, i_duration );
             if ( psz_artist && *psz_artist )
-                vlc_input_item_AddInfo( &p_item->input, _(VLC_META_INFO_CAT),
+                vlc_input_item_AddInfo( p_input, _(VLC_META_INFO_CAT),
                                         _(VLC_META_ARTIST), "%s", psz_artist );
-            playlist_NodeAddItem( p_playlist, p_item,
-                                  p_current->pp_parents[0]->i_view,
-                                  p_current, PLAYLIST_APPEND,
-                                  PLAYLIST_END );
-
-            /* We need to declare the parents of the node as the
-             *                  * same of the parent's ones */
-            playlist_CopyParents( p_current, p_item );
-
-            vlc_input_item_CopyOptions( &p_current->input,
-                                        &p_item->input );
-
+            fprintf( stderr, "Adding %s\n", p_input->psz_uri );
+            playlist_AddWhereverNeeded( p_playlist, p_input, p_current,
+                 p_item_in_category, (i_parent_id > 0 )? VLC_TRUE : VLC_FALSE,
+                 PLAYLIST_APPEND );
             free( psz_mrl );
         }
 
@@ -234,7 +206,7 @@ static int Demux( demux_t *p_demux )
         if( b_cleanup )
         {
             /* Cleanup state */
-            while( i_options-- ) free( ppsz_options[i_options] );
+            while( i_options-- ) free( (char*)ppsz_options[i_options] );
             if( ppsz_options ) free( ppsz_options );
             ppsz_options = NULL; i_options = 0;
             if( psz_name ) free( psz_name );
@@ -247,18 +219,7 @@ static int Demux( demux_t *p_demux )
             b_cleanup = VLC_FALSE;
         }
     }
-
-    /* Go back and play the playlist */
-    if( b_play && p_playlist->status.p_item &&
-        p_playlist->status.p_item->i_children > 0 )
-    {
-        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
-                          p_playlist->status.i_view,
-                          p_playlist->status.p_item,
-                          p_playlist->status.p_item->pp_children[0] );
-    }
-
-    vlc_object_release( p_playlist );
+    HANDLE_PLAY_AND_RELEASE;
     return VLC_SUCCESS;
 }
 
@@ -267,7 +228,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
     return VLC_EGENERIC;
 }
 
-static void parseEXTINF(char *psz_string, char **ppsz_artist, 
+static void parseEXTINF(char *psz_string, char **ppsz_artist,
                         char **ppsz_name, int *pi_duration)
 {
     char *end = NULL;
@@ -306,7 +267,7 @@ static void parseEXTINF(char *psz_string, char **ppsz_artist,
         *ppsz_artist = psz_string;
         *ppsz_name = psz_item + 3;          /* points directly after ' - ' */
         return;
-    } 
+    }
 
     /* reaching this point means: 0.8.1- with artist or something without artist */
     if ( *psz_string == ',' )
@@ -315,7 +276,7 @@ static void parseEXTINF(char *psz_string, char **ppsz_artist,
         psz_string++;
         *ppsz_name = psz_string;
         return;
-    } 
+    }
 
     psz_item = psz_string;
     psz_string = strchr( psz_string, ',' );
index 38323a329df6078f2207519c9c9543c4e6fe8f81..62da1368b52a71082c558f3e2ae4649d7eb9d143 100644 (file)
@@ -75,7 +75,6 @@ static int Demux( demux_t *p_demux)
         return VLC_EGENERIC;
     }
 
-    p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;
     while( ( psz_line = stream_ReadLine( p_demux->s) ) != NULL )
     {
         char *psz_unicode;
@@ -95,8 +94,8 @@ static int Demux( demux_t *p_demux)
         }
 
         psz_unicode = FromLocale( psz_line );
-        playlist_Add( p_playlist, psz_unicode, psz_unicode, PLAYLIST_APPEND,
-                      PLAYLIST_END );
+//        playlist_Add( p_playlist, psz_unicode, psz_unicode, PLAYLIST_APPEND,
+//                      PLAYLIST_END );
 
         free( psz_line );
         LocaleFree( psz_line );
index d7459443238befce93bcb422725a1d3e9207e2fb..23f5ca6e4d483c987777aa13f954f9430d03d944 100644 (file)
@@ -50,6 +50,8 @@ vlc_module_begin();
     add_bool( "playlist-autostart", 1, NULL,
               AUTOSTART_TEXT, AUTOSTART_LONGTEXT, VLC_FALSE );
 
+    add_integer( "parent-item", 0, NULL, NULL, NULL, VLC_TRUE );
+
     set_shortname( _("Playlist") );
     set_description( _("Playlist") );
     add_shortcut( "old-open" );
@@ -153,13 +155,37 @@ char *E_(ProcessMRL)( char *psz_mrl, char *psz_prefix )
     return psz_mrl;
 }
 
+void E_(AddToPlaylist)( demux_t *p_demux, playlist_t *p_playlist,
+                        input_item_t *p_input,
+                        playlist_item_t *p_item, int i_parent_id )
+{
+    // Only add to parent if specific parent requested or not current
+    // playlist item
+   if( i_parent_id > 0 || ! (
+         p_playlist->status.p_item &&
+         p_playlist->status.p_item->p_input ==
+              ((input_thread_t *)p_demux->p_parent)->input.p_item ) )
+   {
+       playlist_NodeAddInput( p_playlist, p_input, p_item,
+                              PLAYLIST_APPEND, PLAYLIST_END );
+   }
+   // Else, add to both
+   else
+   {
+       playlist_BothAddInput( p_playlist, p_input, p_item,
+                              PLAYLIST_APPEND, PLAYLIST_END );
+   }
+   vlc_input_item_CopyOptions( p_item->p_input, p_input );
+}
+
+
 vlc_bool_t E_(FindItem)( demux_t *p_demux, playlist_t *p_playlist,
                      playlist_item_t **pp_item )
 {
      vlc_bool_t b_play = var_CreateGetBool( p_demux, "playlist-autostart" );
 
      if( b_play && p_playlist->status.p_item &&
-             &p_playlist->status.p_item->input ==
+             p_playlist->status.p_item->p_input ==
                 ((input_thread_t *)p_demux->p_parent)->input.p_item )
      {
          msg_Dbg( p_playlist, "starting playlist playback" );
index 542f2347de1ef2df1b8bc81e53b7f9bc488cfdfd..a669849e6df83823d90e9dfd1a05704d7e47b6d2 100644 (file)
@@ -26,6 +26,8 @@ char *E_(FindPrefix)( demux_t * );
 
 vlc_bool_t E_(FindItem)( demux_t *, playlist_t *, playlist_item_t **);
 
+void E_(AddToPlaylist)( demux_t *, playlist_t*,input_item_t*,playlist_item_t*,int );
+
 int E_(Import_Old) ( vlc_object_t * );
 
 int E_(Import_Native) ( vlc_object_t * );
@@ -50,3 +52,38 @@ int E_(xspf_import_Activate) ( vlc_object_t * );
 
 int E_(Import_Shoutcast) ( vlc_object_t * );
 void E_(Close_Shoutcast) ( vlc_object_t * );
+
+#define INIT_PLAYLIST_STUFF \
+    vlc_bool_t b_play; \
+    playlist_item_t *p_current, *p_item_in_category = NULL; \
+    input_item_t *p_input; \
+    playlist_t *p_playlist = (playlist_t *) vlc_object_find( p_demux, \
+                                        VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); \
+    if( !p_playlist ) \
+    { \
+        msg_Err( p_demux, "can't find playlist" ); \
+        return VLC_EGENERIC; \
+    } \
+    i_parent_id = var_CreateGetInteger( p_demux, "parent-item" ); \
+    if( i_parent_id > 0 ) \
+    { \
+        b_play = VLC_FALSE;     \
+        p_current = playlist_ItemGetById( p_playlist, i_parent_id );    \
+    } \
+    else \
+    { \
+        b_play = E_(FindItem)( p_demux, p_playlist, &p_current ); \
+        p_item_in_category = playlist_ItemToNode( p_playlist, p_current ); \
+        p_current->p_input->i_type = ITEM_TYPE_PLAYLIST;        \
+    }
+
+#define HANDLE_PLAY_AND_RELEASE \
+    /* Go back and play the playlist */ \
+    if( b_play && p_playlist->status.p_item && \
+                  p_playlist->status.p_item->i_children > 0 ) \
+    { \
+        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, 1242, \
+                          p_playlist->status.p_item, NULL ); \
+    } \
+    vlc_object_release( p_playlist );
+
index 3341890cc1baef440d74ed28a6e13dcfd69b15b8..e924f50df163d6fd70c898375e2204b12c11b3b3 100644 (file)
@@ -99,6 +99,7 @@ void E_(Close_PLS)( vlc_object_t *p_this )
 
 static int Demux( demux_t *p_demux )
 {
+#if 0
     mtime_t        i_duration = -1;
     char          *psz_name = NULL;
     char          *psz_line;
@@ -282,6 +283,7 @@ static int Demux( demux_t *p_demux )
     }
     vlc_object_release( p_playlist );
     return VLC_SUCCESS;
+#endif
 }
 
 static int Control( demux_t *p_demux, int i_query, va_list args )
index 8122d967ded59f210d6e1766e9d06ccedd3270bd..25f9846eb835b7fc5bfb327040a3fbb13154139d 100644 (file)
@@ -106,13 +106,10 @@ void E_(Close_podcast)( vlc_object_t *p_this )
 static int Demux( demux_t *p_demux )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
-    playlist_t *p_playlist;
-    playlist_item_t *p_item, *p_current;
 
-    vlc_bool_t b_play;
     vlc_bool_t b_item = VLC_FALSE;
     vlc_bool_t b_image = VLC_FALSE;
-    int i_ret;
+    int i_ret, i_parent_id;
 
     xml_t *p_xml;
     xml_reader_t *p_xml_reader;
@@ -130,19 +127,7 @@ static int Demux( demux_t *p_demux )
     char *psz_item_summary = NULL;
     int i_type;
 
-    p_playlist = (playlist_t *) vlc_object_find( p_demux, VLC_OBJECT_PLAYLIST,
-                                                 FIND_ANYWHERE );
-    if( !p_playlist )
-    {
-        msg_Err( p_demux, "can't find playlist" );
-        return -1;
-    }
-    p_sys->p_playlist = p_playlist;
-
-    b_play = E_(FindItem)( p_demux, p_playlist, &p_current );
-
-    playlist_ItemToNode( p_playlist, p_current );
-    p_current->input.i_type = ITEM_TYPE_PLAYLIST;
+    INIT_PLAYLIST_STUFF;
 
     p_xml = p_sys->p_xml = xml_Create( p_demux );
     if( !p_xml ) return -1;
@@ -285,7 +270,7 @@ static int Demux( demux_t *p_demux )
                 else if( b_item == VLC_FALSE && b_image == VLC_FALSE
                          && !strcmp( psz_elname, "link" ) )
                 {
-                    vlc_input_item_AddInfo( &(p_current->input),
+                    vlc_input_item_AddInfo( p_current->p_input,
                                             _( "Podcast Info" ),
                                             _( "Podcast Link" ),
                                             "%s",
@@ -294,7 +279,7 @@ static int Demux( demux_t *p_demux )
                 else if( b_item == VLC_FALSE && b_image == VLC_FALSE
                          && !strcmp( psz_elname, "copyright" ) )
                 {
-                    vlc_input_item_AddInfo( &(p_current->input),
+                    vlc_input_item_AddInfo( p_current->p_input,
                                             _( "Podcast Info" ),
                                             _( "Podcast Copyright" ),
                                             "%s",
@@ -303,7 +288,7 @@ static int Demux( demux_t *p_demux )
                 else if( b_item == VLC_FALSE && b_image == VLC_FALSE
                          && !strcmp( psz_elname, "itunes:category" ) )
                 {
-                    vlc_input_item_AddInfo( &(p_current->input),
+                    vlc_input_item_AddInfo( p_current->p_input,
                                             _( "Podcast Info" ),
                                             _( "Podcast Category" ),
                                             "%s",
@@ -312,7 +297,7 @@ static int Demux( demux_t *p_demux )
                 else if( b_item == VLC_FALSE && b_image == VLC_FALSE
                          && !strcmp( psz_elname, "itunes:keywords" ) )
                 {
-                    vlc_input_item_AddInfo( &(p_current->input),
+                    vlc_input_item_AddInfo( p_current->p_input,
                                             _( "Podcast Info" ),
                                             _( "Podcast Keywords" ),
                                             "%s",
@@ -321,7 +306,7 @@ static int Demux( demux_t *p_demux )
                 else if( b_item == VLC_FALSE && b_image == VLC_FALSE
                          && !strcmp( psz_elname, "itunes:subtitle" ) )
                 {
-                    vlc_input_item_AddInfo( &(p_current->input),
+                    vlc_input_item_AddInfo( p_current->p_input,
                                             _( "Podcast Info" ),
                                             _( "Podcast Subtitle" ),
                                             "%s",
@@ -331,7 +316,7 @@ static int Demux( demux_t *p_demux )
                          && ( !strcmp( psz_elname, "itunes:summary" )
                             ||!strcmp( psz_elname, "description" ) ) )
                 { /* <description> isn't standard iTunes podcast stuff */
-                    vlc_input_item_AddInfo( &(p_current->input),
+                    vlc_input_item_AddInfo( p_current->p_input,
                                             _( "Podcast Info" ),
                                             _( "Podcast Summary" ),
                                             "%s",
@@ -354,21 +339,12 @@ static int Demux( demux_t *p_demux )
                 if( !psz_elname ) return -1;
                 if( !strcmp( psz_elname, "item" ) )
                 {
-                    p_item = playlist_ItemNew( p_playlist, psz_item_mrl,
-                                               psz_item_name );
-                    if( p_item == NULL ) break;
-                    playlist_NodeAddItem( p_playlist, p_item,
-                                          p_current->pp_parents[0]->i_view,
-                                          p_current, PLAYLIST_APPEND,
-                                          PLAYLIST_END );
-
-                    /* We need to declare the parents of the node as the
-                     *                  * same of the parent's ones */
-                    playlist_CopyParents( p_current, p_item );
-
+                    p_input = input_ItemNewExt( p_playlist, psz_item_mrl,
+                                                psz_item_name, 0, NULL, -1 );
+                    if( p_input == NULL ) break;
                     if( psz_item_date )
                     {
-                        vlc_input_item_AddInfo( &p_item->input,
+                        vlc_input_item_AddInfo( p_input,
                                                 _( "Podcast Info" ),
                                                 _( "Podcast Publication Date" ),
                                                 "%s",
@@ -376,7 +352,7 @@ static int Demux( demux_t *p_demux )
                     }
                     if( psz_item_author )
                     {
-                        vlc_input_item_AddInfo( &p_item->input,
+                        vlc_input_item_AddInfo( p_input,
                                                 _( "Podcast Info" ),
                                                 _( "Podcast Author" ),
                                                 "%s",
@@ -384,7 +360,7 @@ static int Demux( demux_t *p_demux )
                     }
                     if( psz_item_category )
                     {
-                        vlc_input_item_AddInfo( &p_item->input,
+                        vlc_input_item_AddInfo( p_input,
                                                 _( "Podcast Info" ),
                                                 _( "Podcast Subcategory" ),
                                                 "%s",
@@ -392,7 +368,7 @@ static int Demux( demux_t *p_demux )
                     }
                     if( psz_item_duration )
                     {
-                        vlc_input_item_AddInfo( &p_item->input,
+                        vlc_input_item_AddInfo( p_input,
                                                 _( "Podcast Info" ),
                                                 _( "Podcast Duration" ),
                                                 "%s",
@@ -400,7 +376,7 @@ static int Demux( demux_t *p_demux )
                     }
                     if( psz_item_keywords )
                     {
-                        vlc_input_item_AddInfo( &p_item->input,
+                        vlc_input_item_AddInfo( p_input,
                                                 _( "Podcast Info" ),
                                                 _( "Podcast Keywords" ),
                                                 "%s",
@@ -408,7 +384,7 @@ static int Demux( demux_t *p_demux )
                     }
                     if( psz_item_subtitle )
                     {
-                        vlc_input_item_AddInfo( &p_item->input,
+                        vlc_input_item_AddInfo( p_input,
                                                 _( "Podcast Info" ),
                                                 _( "Podcast Subtitle" ),
                                                 "%s",
@@ -416,7 +392,7 @@ static int Demux( demux_t *p_demux )
                     }
                     if( psz_item_summary )
                     {
-                        vlc_input_item_AddInfo( &p_item->input,
+                        vlc_input_item_AddInfo( p_input,
                                                 _( "Podcast Info" ),
                                                 _( "Podcast Summary" ),
                                                 "%s",
@@ -424,7 +400,7 @@ static int Demux( demux_t *p_demux )
                     }
                     if( psz_item_size )
                     {
-                        vlc_input_item_AddInfo( &p_item->input,
+                        vlc_input_item_AddInfo( p_input,
                                                 _( "Podcast Info" ),
                                                 _( "Podcast Size" ),
                                                 "%s bytes",
@@ -432,13 +408,17 @@ static int Demux( demux_t *p_demux )
                     }
                     if( psz_item_type )
                     {
-                        vlc_input_item_AddInfo( &p_item->input,
+                        vlc_input_item_AddInfo( p_input,
                                                 _( "Podcast Info" ),
                                                 _( "Podcast Type" ),
                                                 "%s",
                                                 psz_item_type );
                     }
 
+                    fprintf( stderr, "Adding WHEREVER\n");
+                    playlist_AddWhereverNeeded( p_playlist, p_input, p_current,
+                          p_item_in_category, (i_parent_id > 0 ) ? VLC_TRUE:
+                                                VLC_FALSE, PLAYLIST_APPEND );
 #define FREE(a) if( a ) free( a ); a = NULL;
                     FREE( psz_item_name );
                     FREE( psz_item_mrl );
@@ -472,18 +452,7 @@ static int Demux( demux_t *p_demux )
         msg_Warn( p_demux, "error while parsing data" );
     }
 
-    /* Go back and play the playlist */
-    if( b_play && p_playlist->status.p_item &&
-        p_playlist->status.p_item->i_children > 0 )
-    {
-        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
-                          p_playlist->status.i_view,
-                          p_playlist->status.p_item,
-                          p_playlist->status.p_item->pp_children[0] );
-    }
-
-    vlc_object_release( p_playlist );
-    p_sys->p_playlist = NULL;
+    HANDLE_PLAY_AND_RELEASE;
     return VLC_SUCCESS;
 }
 
index 14330329a81b1cc1036f12fb6e756ab7fee769a1..438b6b0f08126a8a3592094bb42a6234cffd456a 100644 (file)
@@ -119,6 +119,7 @@ void E_(Close_Shoutcast)( vlc_object_t *p_this )
 
 static int Demux( demux_t *p_demux )
 {
+#if 0
     demux_sys_t *p_sys = p_demux->p_sys;
     playlist_t *p_playlist;
 
@@ -196,6 +197,7 @@ static int Demux( demux_t *p_demux )
 
     vlc_object_release( p_playlist );
     p_sys->p_playlist = NULL;
+#endif
     return VLC_SUCCESS;
 }
 
@@ -211,6 +213,7 @@ static int Demux( demux_t *p_demux )
  **/
 static int DemuxGenre( demux_t *p_demux )
 {
+#if 0
     demux_sys_t *p_sys = p_demux->p_sys;
     char *psz_name = NULL; /* genre name */
     char *psz_eltname = NULL; /* tag name */
@@ -303,6 +306,7 @@ static int DemuxGenre( demux_t *p_demux )
                 break;
         }
     }
+#endif
     return 0;
 }
 
@@ -333,6 +337,7 @@ static int DemuxGenre( demux_t *p_demux )
  **/
 static int DemuxStation( demux_t *p_demux )
 {
+#if 0
     demux_sys_t *p_sys = p_demux->p_sys;
 
     char *psz_base = NULL; /* */
@@ -552,6 +557,7 @@ static int DemuxStation( demux_t *p_demux )
                 break;
         }
     }
+#endif
     return 0;
 }
 #undef FREE
index 34ae342a83379538e6e12e9ef5e091aa0a066a04..2b6c321ba4c26731ce2df0c9796f60f7ce22884b 100644 (file)
@@ -61,6 +61,7 @@ int E_(xspf_import_Activate)( vlc_object_t *p_this )
  */
 int xspf_import_Demux( demux_t *p_demux )
 {
+#if 0
     playlist_t *p_playlist = NULL;
     playlist_item_t *p_current = NULL;
 
@@ -144,6 +145,7 @@ int xspf_import_Demux( demux_t *p_demux )
         xml_Delete( p_xml );
 
     return i_ret;
+#endif
 }
 
 /** \brief dummy function for demux callback interface */
@@ -151,7 +153,7 @@ int xspf_import_Control( demux_t *p_demux, int i_query, va_list args )
 {
     return VLC_EGENERIC;
 }
-
+#if 0
 /**
  * \brief parse the root node of a XSPF playlist
  * \param p_demux demuxer instance
@@ -680,3 +682,4 @@ static vlc_bool_t insert_new_item( playlist_t *p_pl, playlist_item_t *p_cur,
 
     return VLC_TRUE;
 }
+#endif
index 509ca1d9a9c169fefeb3f8ad3db1a32fb5174b11..08e5736277de81c86902b08c021306e1c4bc931f 100644 (file)
@@ -404,6 +404,8 @@ static int Demux ( demux_t *p_demux )
         free( temp );
     }
 
+    msg_Err( p_playlist, "SGIMB playlist handling is broken" );
+#if 0
     p_child = playlist_ItemNew( p_playlist, p_sys->psz_uri,
                       p_sys->psz_name ? p_sys->psz_name : p_sys->psz_uri );
 
@@ -442,7 +444,7 @@ static int Demux ( demux_t *p_demux )
     playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
                            p_playlist->status.i_view,
                            p_playlist->status.p_item, NULL );
-
+#endif
     vlc_object_release( p_playlist );
     return VLC_SUCCESS;
 }
index c6e23b3af5c98cc847a246c07838f41b7fedae1c..3ae74b38db80be5500af33f5eacc3e43296bf118 100644 (file)
@@ -74,6 +74,7 @@
  *  - ...
  */
 
+#define vlc_meta_Add(a,b,c) fprintf(stderr, "FIXME: TS demuxer meta is broken\n" )
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
index a7169392b138e00ccfdc40933dd217d34c4233f2..0de160ce9cf6af58a223a0a688c8d8533736e9ad 100644 (file)
@@ -76,6 +76,8 @@ static void ParseID3Tag( demux_t *p_demux, uint8_t *p_data, int i_size )
 
         while( i_strings > 0 )
         {
+            vlc_meta_t *p_meta = (vlc_meta_t *)(p_demux->p_private);
+
             char *psz_temp = id3_ucs4_utf8duplicate(
                 id3_field_getstrings( &p_frame->fields[1], --i_strings ) );
 
@@ -87,51 +89,41 @@ static void ParseID3Tag( demux_t *p_demux, uint8_t *p_data, int i_size )
                 if( psz_temp != psz_endptr &&
                     i_genre >= 0 && i_genre < NUM_GENRES )
                 {
-                    vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
-                                  VLC_META_GENRE, ppsz_genres[atoi(psz_temp)]);
+                    vlc_meta_SetGenre( p_meta, ppsz_genres[atoi(psz_temp)]);
                 }
                 else
                 {
                     /* Unknown genre */
-                    vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
-                                  VLC_META_GENRE, psz_temp );
+                    vlc_meta_SetGenre( p_meta,psz_temp );
                 }
             }
             else if( !strcmp(p_frame->id, ID3_FRAME_TITLE ) )
             {
-                vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
-                              VLC_META_TITLE, psz_temp );
+                vlc_meta_SetTitle( p_meta, psz_temp );
             }
             else if( !strcmp(p_frame->id, ID3_FRAME_ARTIST ) )
             {
-                vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
-                              VLC_META_ARTIST, psz_temp );
+                vlc_meta_SetArtist( p_meta, psz_temp );
             }
             else if( !strcmp(p_frame->id, ID3_FRAME_YEAR ) )
             {
-                vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
-                              VLC_META_DATE, psz_temp );
+                vlc_meta_SetDate( p_meta, psz_temp );
             }
             else if( !strcmp(p_frame->id, ID3_FRAME_COMMENT ) )
             {
-                vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
-                              VLC_META_DESCRIPTION, psz_temp );
+                vlc_meta_SetDescription( p_meta, psz_temp );
             }
             else if( strstr( (char*)p_frame->description, "Copyright" ) )
             {
-                vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
-                              VLC_META_COPYRIGHT, psz_temp );
+                vlc_meta_SetCopyright( p_meta, psz_temp );
             }
             else if( strstr( (char*)p_frame->description, "Publisher" ) )
             {
-                vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
-                              VLC_META_PUBLISHER, psz_temp );
+                vlc_meta_SetPublisher( p_meta, psz_temp );
             }
             else
             {
-                /* Unknown meta info */
-                vlc_meta_Add( (vlc_meta_t *)p_demux->p_private,
-                              (char *)p_frame->description, psz_temp );
+                msg_Err(p_demux, "Fixme: unhandled meta" );
             }
             free( psz_temp );
         }
index a6d059e25beb98dc388a2e982cabd328f868a260..203a268978deb4908268d9109ebdbe18a9e3cdcf 100644 (file)
         if ( o_urlString )
         {
             NSURL * o_url;
-    
-            playlist_Add( p_playlist, [o_urlString fileSystemRepresentation],
-                          [[[NSFileManager defaultManager] displayNameAtPath: o_urlString] UTF8String],
-                          PLAYLIST_INSERT, PLAYLIST_END );
+            input_item_t *p_input;
+
+            p_input = input_ItemNew( p_playlist,
+                                    [o_urlString fileSystemRepresentation],
+                                    [[[NSFileManager defaultManager]
+                                    displayNameAtPath: o_urlString] UTF8String] );
+            playlist_PlaylistAddInput( p_playlist, p_input, PLAYLIST_INSERT,
+                                                                PLAYLIST_END );
+
 
             o_url = [NSURL fileURLWithPath: o_urlString];
             if( o_url != nil )
-            { 
+            {
                 [[NSDocumentController sharedDocumentController]
-                    noteNewRecentDocumentURL: o_url]; 
+                    noteNewRecentDocumentURL: o_url];
             }
         }
         vlc_object_release( p_playlist );
index 2065392f39d4bf887e615d87f432aec41aadc678..9f539997e1f9f4e745ca63b3d8ede513a8d05114 100644 (file)
@@ -943,7 +943,6 @@ static VLCMain *_o_sharedMainInstance = nil;
         return;
     }
 
-#define p_input p_intf->p_sys->p_input
     if( p_intf->p_sys->b_input_update )
     {
         /* Called when new input is opened */
@@ -965,17 +964,17 @@ static VLCMain *_o_sharedMainInstance = nil;
 
         vlc_object_release( p_playlist );
 
-        if( ( b_input = ( p_input != NULL ) ) )
+        if( ( b_input = ( p_intf->p_sys->p_input != NULL ) ) )
         {
-            vlc_object_yield( p_input );
+            vlc_object_yield( p_intf->p_sys->p_input );
             /* seekable streams */
-            b_seekable = var_GetBool( p_input, "seekable" );
+            b_seekable = var_GetBool( p_intf->p_sys->p_input, "seekable" );
 
             /* check wether slow/fast motion is possible*/
-            b_control = p_input->input.b_can_pace_control;
+            b_control = p_intf->p_sys->p_input->input.b_can_pace_control;
 
             /* chapters & titles */
-            //b_chapters = p_input->stream.i_area_nb > 1;
+            //b_chapters = p_intf->p_sys->p_input->stream.i_area_nb > 1;
             vlc_object_release( p_input );
         }
 
@@ -1039,13 +1038,13 @@ static VLCMain *_o_sharedMainInstance = nil;
                 return;
             }
             o_temp = [NSString stringWithUTF8String:
-                p_playlist->status.p_item->input.psz_name];
+                p_playlist->status.p_item->p_input->psz_name];
             if( o_temp == NULL )
                 o_temp = [NSString stringWithCString:
-                    p_playlist->status.p_item->input.psz_name];
+                    p_playlist->status.p_item->p_input->psz_name];
             [self setScrollField: o_temp stopAfter:-1];
 
-            p_vout = vlc_object_find( p_input, VLC_OBJECT_VOUT,
+            p_vout = vlc_object_find( p_intf->p_sys->p_input, VLC_OBJECT_VOUT,
                                                     FIND_PARENT );
             if( p_vout != NULL )
             {
@@ -1069,7 +1068,7 @@ static VLCMain *_o_sharedMainInstance = nil;
             p_intf->p_sys->b_current_title_update = FALSE;
         }
 
-        if( p_input && [o_timeslider isEnabled] )
+        if( p_intf->p_sys->p_input && [o_timeslider isEnabled] )
         {
             /* Update the slider */
             vlc_value_t time;
@@ -1078,11 +1077,11 @@ static VLCMain *_o_sharedMainInstance = nil;
             vlc_value_t pos;
             float f_updated;
 
-            var_Get( p_input, "position", &pos );
+            var_Get( p_intf->p_sys->p_input, "position", &pos );
             f_updated = 10000. * pos.f_float;
             [o_timeslider setFloatValue: f_updated];
 
-            var_Get( p_input, "time", &time );
+            var_Get( p_intf->p_sys->p_input, "time", &time );
             i_seconds = time.i_time / 1000000;
 
             o_time = [NSString stringWithFormat: @"%d:%02d:%02d",
@@ -1108,7 +1107,7 @@ static VLCMain *_o_sharedMainInstance = nil;
         }
 
         /* Manage Playing status */
-        var_Get( p_input, "state", &val );
+        var_Get( p_intf->p_sys->p_input, "state", &val );
         if( p_intf->p_sys->i_play_status != val.i_int )
         {
             p_intf->p_sys->i_play_status = val.i_int;
@@ -1125,7 +1124,6 @@ static VLCMain *_o_sharedMainInstance = nil;
         [self setSubmenusEnabled: FALSE];
     }
 
-#undef p_input
 
     [self updateMessageArray];
 
@@ -1225,8 +1223,7 @@ static VLCMain *_o_sharedMainInstance = nil;
 - (void)resetScrollField
 {
     i_end_scroll = -1;
-#define p_input p_intf->p_sys->p_input
-    if( p_input && !p_input->b_die )
+    if( p_intf->p_sys->p_input && !p_intf->p_sys->p_input->b_die )
     {
         NSString *o_temp;
         playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
@@ -1236,15 +1233,14 @@ static VLCMain *_o_sharedMainInstance = nil;
             return;
         }
         o_temp = [NSString stringWithUTF8String:
-                  p_playlist->status.p_item->input.psz_name];
+                  p_playlist->status.p_item->p_input->psz_name];
         if( o_temp == NULL )
             o_temp = [NSString stringWithCString:
-                    p_playlist->status.p_item->input.psz_name];
+                    p_playlist->status.p_item->p_input->psz_name];
         [self setScrollField: o_temp stopAfter:-1];
         vlc_object_release( p_playlist );
         return;
     }
-#undef p_input
     [self setScrollField: _NS("VLC media player") stopAfter:-1];
 }
 
index 67ecdf3cc8705f71cb436bdc42671317613d6161..18ef164fcaf6d53c88ee1835a34111aff696ba10 100644 (file)
@@ -42,7 +42,6 @@
     IBOutlet id o_outline_view;
 
     NSMutableDictionary *o_outline_dict;
-    int i_current_view;
 }
 
 - (void)initStrings;
 - (IBAction)addNode:(id)sender;
 
 - (void)appendArray:(NSArray*)o_array atPos:(int)i_position enqueue:(BOOL)b_enqueue;
-- (void)appendNodeArray:(NSArray*)o_array inNode:(playlist_item_t *)p_node atPos:(int)i_position inView:(int)i_view enqueue:(BOOL)b_enqueue;
+- (void)appendNodeArray:(NSArray*)o_array inNode:(playlist_item_t *)p_node atPos:(int)i_position enqueue:(BOOL)b_enqueue;
 
 
 @end
index 406ff1620bd6a0efa5b25283cc527f3fd83fff5d..07d8edc31978ad4d7332ffe07188ca53acbe08e8 100644 (file)
 {
     playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
                                           FIND_ANYWHERE );
-    i_current_view = VIEW_CATEGORY;
-    playlist_ViewUpdate( p_playlist, i_current_view );
-
     [o_outline_view setTarget: self];
     [o_outline_view setDelegate: self];
     [o_outline_view setDataSource: self];
     if( item == nil )
     {
         /* root object */
-        playlist_view_t *p_view;
-        p_view = playlist_ViewFind( p_playlist, i_current_view );
-        if( p_view && p_view->p_root )
+        if( p_playlist->p_root_category )
         {
-            i_return = p_view->p_root->i_children;
-
-            if( i_current_view == VIEW_CATEGORY )
-            {
-                i_return--; /* remove the GENERAL item from the list */
-                i_return += p_playlist->p_general->i_children; /* add the items of the general node */
-            }
+            i_return = p_playlist->p_root_category->i_children;
         }
     }
     else
             i_return = p_item->i_children;
     }
     vlc_object_release( p_playlist );
-    
+
     if( i_return <= 0 )
         i_return = 0;
-    
+
     return i_return;
 }
 
     if( item == nil )
     {
         /* root object */
-        playlist_view_t *p_view;
-        p_view = playlist_ViewFind( p_playlist, i_current_view );
-        if( p_view && p_view->p_root ) p_return = p_view->p_root->pp_children[index];
-
-        if( i_current_view == VIEW_CATEGORY )
+        if( p_playlist->p_root_category )
         {
-            if( p_playlist->p_general->i_children && index >= 0 && index < p_playlist->p_general->i_children )
-            {
-                p_return = p_playlist->p_general->pp_children[index];
-            }
-            else if( p_view && p_view->p_root && index >= 0 && index - p_playlist->p_general->i_children < p_view->p_root->i_children )
-            {
-                p_return = p_view->p_root->pp_children[index - p_playlist->p_general->i_children + 1];
-            }
+            p_return = p_playlist->p_root_category->pp_children[index];
         }
     }
     else
         if( p_item && index < p_item->i_children && index >= 0 )
             p_return = p_item->pp_children[index];
     }
-    
 
     vlc_object_release( p_playlist );
 
     if( item == nil )
     {
         /* root object */
-        playlist_view_t *p_view;
-        p_view = playlist_ViewFind( p_playlist, i_current_view );
-        if( p_view && p_view->p_root ) i_return = p_view->p_root->i_children;
-
-        if( i_current_view == VIEW_CATEGORY )
+        if( p_playlist->p_root_category )
         {
-            i_return--;
-            i_return += p_playlist->p_general->i_children;
+            i_return = p_playlist->p_root_category->i_children;
         }
     }
     else
     if( [[o_tc identifier] isEqualToString:@"1"] )
     {
         o_value = [NSString stringWithUTF8String:
-            p_item->input.psz_name];
+            p_item->p_input->psz_name];
         if( o_value == NULL )
             o_value = [NSString stringWithCString:
-                p_item->input.psz_name];
+                p_item->p_input->psz_name];
     }
     else if( [[o_tc identifier] isEqualToString:@"2"] )
     {
         char *psz_temp;
-        psz_temp = vlc_input_item_GetInfo( &p_item->input ,_("Meta-information"),_("Artist") );
+        psz_temp = vlc_input_item_GetInfo( p_item->p_input ,_("Meta-information"),_("Artist") );
 
         if( psz_temp == NULL )
             o_value = @"";
     else if( [[o_tc identifier] isEqualToString:@"3"] )
     {
         char psz_duration[MSTRTIME_MAX_SIZE];
-        mtime_t dur = p_item->input.i_duration;
+        mtime_t dur = p_item->p_input->i_duration;
         if( dur != -1 )
         {
             secstotimestr( psz_duration, dur/1000000 );
@@ -577,19 +549,6 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     vlc_object_release( p_playlist );
 }
 
-- (playlist_item_t *)parentOfItem:(playlist_item_t *)p_item
-{
-    int i;
-    for( i = 0 ; i < p_item->i_parents; i++ )
-    {
-        if( p_item->pp_parents[i]->i_view == i_current_view )
-        {
-            return p_item->pp_parents[i]->p_parent;
-        }
-    }
-    return NULL;
-}
-
 - (void)updateRowSelection
 {
     int i_row;
@@ -611,11 +570,10 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     }
 
     p_temp_item = p_item;
-    while( p_temp_item->i_parents > 0 )
+    while( p_temp_item->p_parent )
     {
         [o_array insertObject: [NSValue valueWithPointer: p_temp_item] atIndex: 0];
-
-        p_temp_item = [self parentOfItem: p_temp_item];
+        p_temp_item = p_temp_item->p_parent;
         /*for (i = 0 ; i < p_temp_item->i_parents ; i++)
         {
             if( p_temp_item->pp_parents[i]->i_view == i_current_view )
@@ -626,13 +584,16 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         }*/
     }
 
-    for (j = 0 ; j < [o_array count] - 1 ; j++)
+    for( j = 0; j < [o_array count] - 1; j++ )
     {
         id o_item;
         if( ( o_item = [o_outline_dict objectForKey:
                             [NSString stringWithFormat: @"%p",
                             [[o_array objectAtIndex:j] pointerValue]]] ) != nil )
+        {
+            msg_Err( p_playlist, "o_item: %p", o_item );
             [o_outline_view expandItem: o_item];
+        }
 
     }
 
@@ -700,33 +661,15 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
             }
         }
 
-        while( p_temp_item->i_parents > 0 )
+        while( p_temp_item )
         {
-            p_temp_item = [self parentOfItem: p_temp_item];
+            p_temp_item = p_temp_item->p_parent;
             if( p_temp_item == p_node )
             {
                  vlc_mutex_unlock( &p_playlist->object_lock );
                  vlc_object_release( p_playlist );
                  return YES;
             }
-
-/*            for( i = 0; i < p_temp_item->i_parents ; i++ )
-            {
-                if( p_temp_item->pp_parents[i]->i_view == i_current_view )
-                {
-                    if( p_temp_item->pp_parents[i]->p_parent == p_node )
-                    {
-                        vlc_mutex_unlock( &p_playlist->object_lock );
-                        vlc_object_release( p_playlist );
-                        return YES;
-                    }
-                    else
-                    {
-                        p_temp_item = p_temp_item->pp_parents[i]->p_parent;
-                        break;
-                    }
-                }
-            }*/
         }
         vlc_mutex_unlock( &p_playlist->object_lock );
     }
@@ -816,7 +759,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
             {
                 o_real_filename = o_filename;
             }
-            playlist_Export( p_playlist, [o_real_filename fileSystemRepresentation], "export-m3u" );
+            playlist_Export( p_playlist, [o_real_filename fileSystemRepresentation], p_playlist->p_local_category, "export-m3u" );
         }
     }
     vlc_object_release( p_playlist );
@@ -840,15 +783,8 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         {
             if( p_item->i_children == -1 )
             {
-                p_node = [self parentOfItem: p_item];
+                p_node = p_item->p_parent;
 
-/*                for( i = 0 ; i < p_item->i_parents ; i++ )
-                {
-                    if( p_item->pp_parents[i]->i_view == i_current_view )
-                    {
-                        p_node = p_item->pp_parents[i]->p_parent;
-                    }
-                }*/
             }
             else
             {
@@ -862,7 +798,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
                     p_item = NULL;
                 }
             }
-            playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, i_current_view, p_node, p_item );
+            playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, 0, p_node, p_item );
         }
         vlc_object_release( p_playlist );
     }
@@ -898,7 +834,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
             {
                 if( p_item->i_children == -1 )
                 {
-                    playlist_PreparseEnqueue( p_playlist, &p_item->input );
+                    playlist_PreparseEnqueue( p_playlist, p_item->p_input );
                 }
                 else
                 {
@@ -925,8 +861,6 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     [o_mi setState: playlist_IsServicesDiscoveryLoaded( p_playlist,
                                           [o_string cString] ) ? YES : NO];
 
-    i_current_view = VIEW_CATEGORY;
-    playlist_ViewUpdate( p_playlist, i_current_view );
     vlc_object_release( p_playlist );
     [self playlistUpdated];
     return;
@@ -983,14 +917,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         }
         else
         {
-            if( p_playlist->status.i_status != PLAYLIST_STOPPED &&
-                p_playlist->status.p_item == [[o_outline_view itemAtRow: i_row] pointerValue] )
-            {
-                playlist_Stop( p_playlist );
-            }
-            vlc_mutex_lock( &p_playlist->object_lock );
-            playlist_Delete( p_playlist, p_item->input.i_id );
-            vlc_mutex_unlock( &p_playlist->object_lock );
+            playlist_LockDelete( p_playlist, p_item->i_id );
         }
     }
     [self playlistUpdated];
@@ -1026,8 +953,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     else
     /*If no item is selected, sort the whole playlist*/
     {
-        playlist_view_t * p_view = playlist_ViewFind( p_playlist, i_current_view );
-        p_item = p_view->p_root;
+        p_item = p_playlist->p_root_category;
     }
 
     if( p_item->i_children > -1 ) // the item is a node
@@ -1038,25 +964,16 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     }
     else
     {
-        int i;
-
-        for( i = 0 ; i < p_item->i_parents ; i++ )
-        {
-            if( p_item->pp_parents[i]->i_view == i_current_view )
-            {
-                vlc_mutex_lock( &p_playlist->object_lock );
-                playlist_RecursiveNodeSort( p_playlist,
-                        p_item->pp_parents[i]->p_parent, i_mode, ORDER_NORMAL );
-                vlc_mutex_unlock( &p_playlist->object_lock );
-                break;
-            }
-        }
+        vlc_mutex_lock( &p_playlist->object_lock );
+        playlist_RecursiveNodeSort( p_playlist,
+                p_item->p_parent, i_mode, ORDER_NORMAL );
+        vlc_mutex_unlock( &p_playlist->object_lock );
     }
     vlc_object_release( p_playlist );
     [self playlistUpdated];
 }
 
-- (playlist_item_t *)createItem:(NSDictionary *)o_one_item
+- (input_item_t *)createItem:(NSDictionary *)o_one_item
 {
     intf_thread_t * p_intf = VLCIntf;
     playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
@@ -1066,7 +983,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     {
         return NULL;
     }
-    playlist_item_t *p_item;
+    input_item_t *p_input;
     int i;
     BOOL b_rem = FALSE, b_dir = FALSE;
     NSString *o_uri, *o_name;
@@ -1124,15 +1041,15 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         o_uri = o_temp;
     }
 
-    p_item = playlist_ItemNew( p_intf, [o_uri fileSystemRepresentation], [o_name UTF8String] );
-    if( !p_item )
+    p_input = input_ItemNew( p_playlist, [o_uri fileSystemRepresentation], [o_name UTF8String] );
+    if( !p_input )
        return NULL;
 
     if( o_options )
     {
         for( i = 0; i < (int)[o_options count]; i++ )
         {
-            playlist_ItemAddOption( p_item, strdup( [[o_options objectAtIndex:i] UTF8String] ) );
+            vlc_input_item_AddOption( p_input, strdup( [[o_options objectAtIndex:i] UTF8String] ) );
         }
     }
 
@@ -1145,7 +1062,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     }
 
     vlc_object_release( p_playlist );
-    return p_item;
+    return p_input;
 }
 
 - (void)appendArray:(NSArray*)o_array atPos:(int)i_position enqueue:(BOOL)b_enqueue
@@ -1160,29 +1077,39 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
 
     for( i_item = 0; i_item < (int)[o_array count]; i_item++ )
     {
-        playlist_item_t *p_item;
+        input_item_t *p_input;
         NSDictionary *o_one_item;
 
         /* Get the item */
         o_one_item = [o_array objectAtIndex: i_item];
-        p_item = [self createItem: o_one_item];
-        if( !p_item )
+        p_input = [self createItem: o_one_item];
+        if( !p_input )
         {
             continue;
         }
 
         /* Add the item */
-        playlist_AddItem( p_playlist, p_item, PLAYLIST_INSERT, i_position == -1 ? PLAYLIST_END : i_position + i_item );
+        playlist_PlaylistAddInput( p_playlist, p_input, PLAYLIST_INSERT,
+                        i_position == -1 ? PLAYLIST_END : i_position + i_item );
 
         if( i_item == 0 && !b_enqueue )
         {
+            playlist_item_t *p_item;
+            p_item = playlist_ItemGetByInput( p_playlist, p_input );
             playlist_Control( p_playlist, PLAYLIST_ITEMPLAY, p_item );
         }
+        else
+        {
+            playlist_item_t *p_item;
+            p_item = playlist_ItemGetByInput( p_playlist, p_input );
+            playlist_Control( p_playlist, PLAYLIST_PREPARSE, p_item );
+        }
     }
+    [self playlistUpdated];
     vlc_object_release( p_playlist );
 }
 
-- (void)appendNodeArray:(NSArray*)o_array inNode:(playlist_item_t *)p_node atPos:(int)i_position inView:(int)i_view enqueue:(BOOL)b_enqueue
+- (void)appendNodeArray:(NSArray*)o_array inNode:(playlist_item_t *)p_node atPos:(int)i_position enqueue:(BOOL)b_enqueue
 {
     int i_item;
     playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
@@ -1194,27 +1121,39 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
 
     for( i_item = 0; i_item < (int)[o_array count]; i_item++ )
     {
-        playlist_item_t *p_item;
+        input_item_t *p_input;
         NSDictionary *o_one_item;
 
         /* Get the item */
         o_one_item = [o_array objectAtIndex: i_item];
-        p_item = [self createItem: o_one_item];
-        if( !p_item )
+        p_input = [self createItem: o_one_item];
+        if( !p_input )
         {
             continue;
         }
 
         /* Add the item */
-        playlist_NodeAddItem( p_playlist, p_item, i_view, p_node, PLAYLIST_INSERT, i_position + i_item );
+       playlist_NodeAddInput( p_playlist, p_input, p_node,
+                                      PLAYLIST_INSERT,
+                                      i_position == -1 ?
+                                      PLAYLIST_END : i_position + i_item );
+
 
         if( i_item == 0 && !b_enqueue )
         {
+            playlist_item_t *p_item;
+            p_item = playlist_ItemGetByInput( p_playlist, p_input );
             playlist_Control( p_playlist, PLAYLIST_ITEMPLAY, p_item );
         }
+        else
+        {
+            playlist_item_t *p_item;
+            p_item = playlist_ItemGetByInput( p_playlist, p_input );
+            playlist_Control( p_playlist, PLAYLIST_PREPARSE, p_item );
+        }
     }
+    [self playlistUpdated];
     vlc_object_release( p_playlist );
-
 }
 
 - (IBAction)handlePopUp:(id)sender
@@ -1288,8 +1227,8 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
 
         vlc_mutex_lock( &p_playlist->object_lock );
         o_current_name = [NSString stringWithUTF8String:
-            p_item->pp_children[i_current]->input.psz_name];
-        psz_temp = vlc_input_item_GetInfo( &p_item->input ,
+            p_item->pp_children[i_current]->p_input->psz_name];
+        psz_temp = vlc_input_item_GetInfo( p_item->p_input ,
                    _("Meta-information"),_("Artist") );
         o_current_author = [NSString stringWithUTF8String: psz_temp];
         free( psz_temp);
@@ -1339,7 +1278,6 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
 {
     playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST,
                                                        FIND_ANYWHERE );
-    playlist_view_t * p_view;
     id o_result;
 
     unsigned int i;
@@ -1349,65 +1287,53 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
 
     if( p_playlist == NULL )
         return;
-    p_view = playlist_ViewFind( p_playlist, i_current_view );
 
-    if( p_view )
-    {
         /*First, only search after the selected item:*
          *(b_selected_item_met = NO)                 */
-        o_result = [self subSearchItem:p_view->p_root];
-        if( o_result == NULL )
-        {
-            /* If the first search failed, search again from the beginning */
-            o_result = [self subSearchItem:p_view->p_root];
-        }
-        if( o_result != NULL )
-        {
-            int i_start;
-            if( [[o_result objectAtIndex: 0] pointerValue] ==
-                                                    p_playlist->p_general )
-            i_start = 1;
-            else
-            i_start = 0;
+    o_result = [self subSearchItem:p_playlist->p_root_category];
+    if( o_result == NULL )
+    {
+        /* If the first search failed, search again from the beginning */
+        o_result = [self subSearchItem:p_playlist->p_root_category];
+    }
+    if( o_result != NULL )
+    {
+        int i_start;
+        if( [[o_result objectAtIndex: 0] pointerValue] ==
+                                                    p_playlist->p_local_category )
+        i_start = 1;
+        else
+        i_start = 0;
 
-            for( i = i_start ; i < [o_result count] - 1 ; i++ )
-            {
-                [o_outline_view expandItem: [o_outline_dict objectForKey:
-                            [NSString stringWithFormat: @"%p",
-                            [[o_result objectAtIndex: i] pointerValue]]]];
-            }
-            i_row = [o_outline_view rowForItem: [o_outline_dict objectForKey:
-                            [NSString stringWithFormat: @"%p",
-                            [[o_result objectAtIndex: [o_result count] - 1 ]
-                            pointerValue]]]];
-        }
-        if( i_row > -1 )
+        for( i = i_start ; i < [o_result count] - 1 ; i++ )
         {
-            [o_outline_view selectRow:i_row byExtendingSelection: NO];
-            [o_outline_view scrollRowToVisible: i_row];
+            [o_outline_view expandItem: [o_outline_dict objectForKey:
+                        [NSString stringWithFormat: @"%p",
+                        [[o_result objectAtIndex: i] pointerValue]]]];
         }
+        i_row = [o_outline_view rowForItem: [o_outline_dict objectForKey:
+                        [NSString stringWithFormat: @"%p",
+                        [[o_result objectAtIndex: [o_result count] - 1 ]
+                        pointerValue]]]];
+    }
+    if( i_row > -1 )
+    {
+        [o_outline_view selectRow:i_row byExtendingSelection: NO];
+        [o_outline_view scrollRowToVisible: i_row];
     }
     vlc_object_release( p_playlist );
 }
 
 - (IBAction)recursiveExpandNode:(id)sender
 {
-    int i;
     id o_item = [o_outline_view itemAtRow: [o_outline_view selectedRow]];
     playlist_item_t *p_item = (playlist_item_t *)[o_item pointerValue];
 
     if( ![[o_outline_view dataSource] outlineView: o_outline_view
                                                     isItemExpandable: o_item] )
     {
-        for( i = 0 ; i < p_item->i_parents ; i++ )
-        {
-            if( p_item->pp_parents[i]->i_view == i_current_view )
-            {
-                o_item = [o_outline_dict objectForKey: [NSString
-                    stringWithFormat: @"%p", p_item->pp_parents[i]->p_parent]];
-                break;
-            }
-        }
+        o_item = [o_outline_dict objectForKey: [NSString
+                   stringWithFormat: @"%p", p_item->p_parent]];
     }
 
     /* We need to collapse the node first, since OSX refuses to recursively
@@ -1445,7 +1371,6 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
 {
     int i_mode = 0, i_type;
     intf_thread_t *p_intf = VLCIntf;
-    playlist_view_t *p_view;
 
     playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                        FIND_ANYWHERE );
@@ -1462,8 +1387,6 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         return;
     }
 
-    p_view = playlist_ViewFind( p_playlist, i_current_view );
-
     if( o_tc_sortColumn == o_tc )
     {
         b_isSortDescending = !b_isSortDescending;
@@ -1492,7 +1415,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     }
 
     vlc_mutex_lock( &p_playlist->object_lock );
-    playlist_RecursiveNodeSort( p_playlist, p_view->p_root, i_mode, i_type );
+    playlist_RecursiveNodeSort( p_playlist, p_playlist->p_root_category, i_mode, i_type );
     vlc_mutex_unlock( &p_playlist->object_lock );
 
     vlc_object_release( p_playlist );
@@ -1552,15 +1475,14 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         return;
     }
 
-    playlist_item_t * p_item = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, 
-        _("Empty Folder"), p_playlist->p_general );
+    playlist_item_t * p_item = playlist_NodeCreate( p_playlist,
+                                _("Empty Folder"), p_playlist->p_local_category );
 
     if(! p_item )
         msg_Warn( VLCIntf, "node creation failed" );
-    
-    playlist_ViewUpdate( p_playlist, VIEW_CATEGORY );
-    
+
     vlc_object_release( p_playlist );
+    [self playlistUpdated];
 }
 
 @end
@@ -1621,7 +1543,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         /* Refuse to move items that are not in the General Node
            (Service Discovery) */
         if( ![self isItem: [o_item pointerValue] inNode:
-                        p_playlist->p_general checkItemExistence: NO])
+                        p_playlist->p_local_category checkItemExistence: NO])
         {
             vlc_object_release(p_playlist);
             return NO;
@@ -1671,7 +1593,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
     /* We refuse to drop an item in anything else than a child of the General
        Node. We still accept items that would be root nodes of the outlineview
        however, to allow drop in an empty playlist. */
-    if( !([self isItem: [item pointerValue] inNode: p_playlist->p_general
+    if( !([self isItem: [item pointerValue] inNode: p_playlist->p_local_category
                                     checkItemExistence: NO] || item == nil) )
     {
         vlc_object_release( p_playlist );
@@ -1726,7 +1648,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         /* If the item is to be dropped as root item of the outline, make it a
            child of the General node.
            Else, choose the proposed parent as parent. */
-        if( item == nil ) p_new_parent = p_playlist->p_general;
+        if( item == nil ) p_new_parent = p_playlist->p_local_category;
         else p_new_parent = [item pointerValue];
 
         /* Make sure the proposed parent is a node.
@@ -1743,7 +1665,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
             int i_old_index = 0;
 
             p_item = [[o_all_items objectAtIndex:i] pointerValue];
-            p_old_parent = [self parentOfItem: p_item];
+            p_old_parent = p_item->p_parent;
             if( !p_old_parent )
             continue;
             /* We may need the old index later */
@@ -1763,8 +1685,6 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
             vlc_mutex_lock( &p_playlist->object_lock );
             // Acually detach the item from the old position
             if( playlist_NodeRemoveItem( p_playlist, p_item, p_old_parent ) ==
-                VLC_SUCCESS  &&
-                playlist_NodeRemoveParent( p_playlist, p_item, p_old_parent ) ==
                 VLC_SUCCESS )
             {
                 int i_new_index;
@@ -1783,8 +1703,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
                     i_new_index = index + i - i_removed_from_node;
                 }
                 // Reattach the item to the new position
-                playlist_NodeInsert( p_playlist, i_current_view, p_item,
-                                                    p_new_parent, i_new_index );
+                playlist_NodeInsert( p_playlist, p_item, p_new_parent, i_new_index );
             }
             vlc_mutex_unlock( &p_playlist->object_lock );
         }
@@ -1839,7 +1758,7 @@ belongs to an Apple hidden private API, and then can "disapear" at any time*/
         else
         {
             [self appendNodeArray: o_array inNode: p_node
-                atPos: index inView: i_current_view enqueue: YES];
+                atPos: index enqueue: YES];
         }
         vlc_object_release( p_playlist );
         return YES;
index a52a0d130aa42e61811f3b285c439955b5719e91..8869e8d9382ca9bb5e1865e9a15f6d5477d34114 100644 (file)
     if(! [self isItemInPlaylist: p_item] ) return;
 
     char *psz_temp;
-    vlc_mutex_lock( &p_item->input.lock );
+    vlc_mutex_lock( &p_item->p_input->lock );
 
     /* fill uri / title / author info */
-    if( p_item->input.psz_uri )
+    if( p_item->p_input->psz_uri )
     {
         [o_uri_txt setStringValue:
-            ([NSString stringWithUTF8String:p_item->input.psz_uri] == nil ) ?
-            [NSString stringWithCString:p_item->input.psz_uri] :
-            [NSString stringWithUTF8String:p_item->input.psz_uri]];
+            ([NSString stringWithUTF8String:p_item->p_input->psz_uri] == nil ) ?
+            [NSString stringWithCString:p_item->p_input->psz_uri] :
+            [NSString stringWithUTF8String:p_item->p_input->psz_uri]];
     }
 
-    if( p_item->input.psz_name )
+    if( p_item->p_input->psz_name )
     {
         [o_title_txt setStringValue:
-            ([NSString stringWithUTF8String:p_item->input.psz_name] == nil ) ?
-            [NSString stringWithCString:p_item->input.psz_name] :
-            [NSString stringWithUTF8String:p_item->input.psz_name]];
+            ([NSString stringWithUTF8String:p_item->p_input->psz_name] == nil ) ?
+            [NSString stringWithCString:p_item->p_input->psz_name] :
+            [NSString stringWithUTF8String:p_item->p_input->psz_name]];
     }
-    vlc_mutex_unlock( &p_item->input.lock );
+    vlc_mutex_unlock( &p_item->p_input->lock );
 
-    psz_temp = vlc_input_item_GetInfo( &p_item->input, _("Meta-information"), _("Artist") );
+    psz_temp = vlc_input_item_GetInfo( p_item->p_input, _("Meta-information"), _("Artist") );
 
     if( psz_temp )
     {
 
 - (void)setMeta: (char *)meta forLabel: (id)theItem
 {
-    char *psz_meta = vlc_input_item_GetInfo( &p_item->input, \
+    char *psz_meta = vlc_input_item_GetInfo( p_item->p_input, \
         _(VLC_META_INFO_CAT), _(meta) );
     if( psz_meta != NULL && *psz_meta)
         [theItem setStringValue: [NSString stringWithUTF8String: psz_meta]];
     {
         /* we can only do that if there's a valid input around */
 
-        vlc_mutex_lock( &p_item->input.p_stats->lock );
+        vlc_mutex_lock( &p_item->p_input->p_stats->lock );
 
         /* input */
         [o_read_bytes_txt setStringValue: [NSString stringWithFormat: \
-            @"%8.0f kB", (float)(p_item->input.p_stats->i_read_bytes)/1000]];
+            @"%8.0f kB", (float)(p_item->p_input->p_stats->i_read_bytes)/1000]];
         [o_input_bitrate_txt setStringValue: [NSString stringWithFormat: \
-            @"%6.0f kb/s", (float)(p_item->input.p_stats->f_input_bitrate)*8000]];
+            @"%6.0f kb/s", (float)(p_item->p_input->p_stats->f_input_bitrate)*8000]];
         [o_demux_bytes_txt setStringValue: [NSString stringWithFormat: \
-            @"%8.0f kB", (float)(p_item->input.p_stats->i_demux_read_bytes)/1000]];
+            @"%8.0f kB", (float)(p_item->p_input->p_stats->i_demux_read_bytes)/1000]];
         [o_demux_bitrate_txt setStringValue: [NSString stringWithFormat: \
-            @"%6.0f kb/s", (float)(p_item->input.p_stats->f_demux_bitrate)*8000]];
+            @"%6.0f kb/s", (float)(p_item->p_input->p_stats->f_demux_bitrate)*8000]];
 
         /* Video */
         [o_video_decoded_txt setStringValue: [NSString stringWithFormat: @"%5i", \
-            p_item->input.p_stats->i_decoded_video]];
+            p_item->p_input->p_stats->i_decoded_video]];
         [o_displayed_txt setStringValue: [NSString stringWithFormat: @"%5i", \
-            p_item->input.p_stats->i_displayed_pictures]];
+            p_item->p_input->p_stats->i_displayed_pictures]];
         [o_lost_frames_txt setStringValue: [NSString stringWithFormat: @"%5i", \
-            p_item->input.p_stats->i_lost_pictures]];
+            p_item->p_input->p_stats->i_lost_pictures]];
 
         /* Sout */
         [o_sent_packets_txt setStringValue: [NSString stringWithFormat: @"%5i", \
-            p_item->input.p_stats->i_sent_packets]];
+            p_item->p_input->p_stats->i_sent_packets]];
         [o_sent_bytes_txt setStringValue: [NSString stringWithFormat: @"%8.0f kB", \
-            (float)(p_item->input.p_stats->i_sent_bytes)/1000]];
+            (float)(p_item->p_input->p_stats->i_sent_bytes)/1000]];
         [o_sent_bitrate_txt setStringValue: [NSString stringWithFormat: \
-            @"%6.0f kb/s", (float)(p_item->input.p_stats->f_send_bitrate*8)*1000]];
+            @"%6.0f kb/s", (float)(p_item->p_input->p_stats->f_send_bitrate*8)*1000]];
 
         /* Audio */
         [o_audio_decoded_txt setStringValue: [NSString stringWithFormat: @"%5i", \
-            p_item->input.p_stats->i_decoded_audio]];
+            p_item->p_input->p_stats->i_decoded_audio]];
         [o_played_abuffers_txt setStringValue: [NSString stringWithFormat: @"%5i", \
-            p_item->input.p_stats->i_played_abuffers]];
+            p_item->p_input->p_stats->i_played_abuffers]];
         [o_lost_abuffers_txt setStringValue: [NSString stringWithFormat: @"%5i", \
-            p_item->input.p_stats->i_lost_abuffers]];
+            p_item->p_input->p_stats->i_lost_abuffers]];
 
-        vlc_mutex_unlock( &p_item->input.p_stats->lock );
+        vlc_mutex_unlock( &p_item->p_input->p_stats->lock );
     }
 }
 
 
     if( [self isItemInPlaylist: p_item] )
     {
-        vlc_mutex_lock( &p_item->input.lock );
+        vlc_mutex_lock( &p_item->p_input->lock );
 
-        p_item->input.psz_uri = strdup( [[o_uri_txt stringValue] UTF8String] );
-        p_item->input.psz_name = strdup( [[o_title_txt stringValue] UTF8String] );
-        vlc_mutex_unlock( &p_item->input.lock );
-        vlc_input_item_AddInfo( &p_item->input, _("Meta-information"), _("Artist"), [[o_author_txt stringValue] UTF8String]);
+        p_item->p_input->psz_uri = strdup( [[o_uri_txt stringValue] UTF8String] );
+        p_item->p_input->psz_name = strdup( [[o_title_txt stringValue] UTF8String] );
+        vlc_mutex_unlock( &p_item->p_input->lock );
+        vlc_input_item_AddInfo( p_item->p_input, _("Meta-information"), _("Artist"), [[o_author_txt stringValue] UTF8String]);
         
         val.b_bool = VLC_TRUE;
         var_Set( p_playlist, "intf-change", val );
@@ -461,37 +461,37 @@ static VLCInfoTreeItem *o_root_item = nil;
         {
             if( self == o_root_item )
             {
-                vlc_mutex_lock( &p_item->input.lock );
+                vlc_mutex_lock( &p_item->p_input->lock );
                 o_children = [[NSMutableArray alloc] initWithCapacity:
-                                                p_item->input.i_categories];
-                for (i = 0 ; i < p_item->input.i_categories ; i++)
+                                                p_item->p_input->i_categories];
+                for (i = 0 ; i < p_item->p_input->i_categories ; i++)
                 {
                     [o_children addObject:[[VLCInfoTreeItem alloc]
                         initWithName: [NSString stringWithUTF8String:
-                            p_item->input.pp_categories[i]->psz_name]
+                            p_item->p_input->pp_categories[i]->psz_name]
                         value: @""
                         ID: i
                         parent: self]];
                 }
-                vlc_mutex_unlock( &p_item->input.lock );
+                vlc_mutex_unlock( &p_item->p_input->lock );
             }
             else if( o_parent == o_root_item )
             {
-                vlc_mutex_lock( &p_item->input.lock );
+                vlc_mutex_lock( &p_item->p_input->lock );
                 o_children = [[NSMutableArray alloc] initWithCapacity:
-                    p_item->input.pp_categories[i_object_id]->i_infos];
+                    p_item->p_input->pp_categories[i_object_id]->i_infos];
 
-                for (i = 0 ; i < p_item->input.pp_categories[i_object_id]->i_infos ; i++)
+                for (i = 0 ; i < p_item->p_input->pp_categories[i_object_id]->i_infos ; i++)
                 {
                     [o_children addObject:[[VLCInfoTreeItem alloc]
                     initWithName: [NSString stringWithUTF8String:
-                            p_item->input.pp_categories[i_object_id]->pp_infos[i]->psz_name]
+                            p_item->p_input->pp_categories[i_object_id]->pp_infos[i]->psz_name]
                         value: [NSString stringWithUTF8String:
-                            p_item->input.pp_categories[i_object_id]->pp_infos[i]->psz_value]
+                            p_item->p_input->pp_categories[i_object_id]->pp_infos[i]->psz_value]
                         ID: i
                         parent: self]];
                 }
-                vlc_mutex_unlock( &p_item->input.lock );
+                vlc_mutex_unlock( &p_item->p_input->lock );
             }
             else
             {
index 8ef0f75225415027b09148ea24b91d7faef5eb3b..388c02f33c754f26af612bded51077cd1c8f7656 100644 (file)
@@ -583,7 +583,7 @@ static VLCWizard *_o_sharedInstance = nil;
                 NSMutableArray * tempArray = [[NSMutableArray alloc] init];
                 while( x != y )
                 {
-                    playlist_item_t *p_item = 
+                    playlist_item_t *p_item =
                         [[o_t2_tbl_plst itemAtRow: 
                             [[o_t2_tbl_plst selectedRowIndexes] 
                             indexGreaterThanOrEqualToIndex: x]] pointerValue];
@@ -591,7 +591,7 @@ static VLCWizard *_o_sharedInstance = nil;
                     if( p_item->i_children <= 0 )
                     {
                         [tempArray addObject: [NSString stringWithUTF8String:
-                        p_item->input.psz_uri]];
+                        p_item->p_input->psz_uri]];
                         stop = NO;
                     }
                     else
@@ -1289,17 +1289,17 @@ static VLCWizard *_o_sharedInstance = nil;
                 NSString *tempString = [NSString stringWithFormat: \
                     @"%@ (%i/%i)", _NS("Streaming/Transcoding Wizard"), \
                     ( x + 1 ), y];
-                playlist_item_t *p_item = playlist_ItemNew( p_playlist, \
+                input_item_t *p_input = input_ItemNew( p_playlist, \
                     [[[o_userSelections objectForKey:@"pathToStrm"] \
                     objectAtIndex:x] UTF8String], \
                     [tempString UTF8String] );
-                playlist_ItemAddOption( p_item, [[[o_userSelections \
+                vlc_input_item_AddOption( p_input, [[[o_userSelections \
                     objectForKey:@"opts"] objectAtIndex: x] UTF8String]);
 
                 if(! [[o_userSelections objectForKey:@"partExtractFrom"] \
                     isEqualToString:@""] )
                 {
-                    playlist_ItemAddOption( p_item, [[NSString \
+                    vlc_input_item_AddOption( p_input, [[NSString \
                         stringWithFormat: @"start-time=%@", [o_userSelections \
                         objectForKey: @"partExtractFrom"]] UTF8String] );
                 }
@@ -1307,26 +1307,27 @@ static VLCWizard *_o_sharedInstance = nil;
                 if(! [[o_userSelections objectForKey:@"partExtractTo"] \
                     isEqualToString:@""] )
                 {
-                    playlist_ItemAddOption( p_item, [[NSString \
+                    vlc_input_item_AddOption( p_input, [[NSString \
                         stringWithFormat: @"stop-time=%@", [o_userSelections \
                         objectForKey: @"partExtractTo"]] UTF8String] );
                 }
 
-                playlist_ItemAddOption( p_item, [[NSString stringWithFormat: \
+                vlc_input_item_AddOption( p_input, [[NSString stringWithFormat: \
                     @"ttl=%@", [o_userSelections objectForKey:@"ttl"]] \
                     UTF8String] );
 
-                playlist_AddItem( p_playlist, p_item, PLAYLIST_STOP, PLAYLIST_END );
-                
+                playlist_PlaylistAddInput( p_playlist, p_input, PLAYLIST_STOP, PLAYLIST_END );
+
                 if( x == 0 )
-                    /* play the first item and add the others afterwards */ 
+                {
+                    /* play the first item and add the others afterwards */
+                    playlist_item_t *p_item = playlist_ItemGetByInput( p_playlist, p_input );
                     playlist_Control( p_playlist, PLAYLIST_ITEMPLAY, p_item );
+                }
 
                 x += 1;
             }
 
-            playlist_ViewUpdate( p_playlist, VIEW_CATEGORY );
-
             vlc_object_release(p_playlist);
         } else {
             msg_Err( p_intf, "unable to find playlist" );
index b72118cf497ae8a122f45423ae81a0f31da87016..1951eec9a042d86dec500c339de7dbd88a7b5171 100644 (file)
@@ -176,8 +176,6 @@ SOURCES_skins2 = \
        \
        vars/equalizer.cpp \
        vars/equalizer.hpp \
-       vars/playlist.cpp \
-       vars/playlist.hpp \
        vars/playtree.cpp \
        vars/playtree.hpp \
        vars/time.cpp \
index 9bf80b6744e40cee7bc4c98588fb351cb8d48ff3..771ec13c913dea5f16c145468f851b2e2e83b1be 100644 (file)
@@ -37,13 +37,13 @@ void CmdAddItem::execute()
     if( m_playNow )
     {
         // Enqueue and play the item
-        playlist_Add( pPlaylist, m_name.c_str(),m_name.c_str(),
-                      PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
+        playlist_PlaylistAdd( pPlaylist, m_name.c_str(),m_name.c_str(),
+                              PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
     }
     else
     {
         // Enqueue the item only
-        playlist_Add( pPlaylist, m_name.c_str(), m_name.c_str(),
-                      PLAYLIST_APPEND, PLAYLIST_END );
+        playlist_PlaylistAdd( pPlaylist, m_name.c_str(), m_name.c_str(),
+                              PLAYLIST_APPEND, PLAYLIST_END );
     }
 }
index 617dc564b4a173a86f51e9adec17128eb8de271c..a598ba89fad1b9ccbadae405cbeb63b364304efb 100644 (file)
@@ -33,18 +33,6 @@ void CmdPlaylistDel::execute()
 }
 
 
-void CmdPlaylistSort::execute()
-{
-    // XXX add the mode and type
-    playlist_t *pPlaylist = getIntf()->p_sys->p_playlist;
-    if( pPlaylist != NULL )
-    {
-        playlist_Sort( pPlaylist, SORT_TITLE, ORDER_NORMAL );
-    }
-
-}
-
-
 void CmdPlaylistNext::execute()
 {
     playlist_t *pPlaylist = getIntf()->p_sys->p_playlist;
@@ -118,7 +106,8 @@ void CmdPlaylistSave::execute()
     {
         // FIXME: when the PLS export will be working, we'll need to remove
         // this hardcoding...
-        playlist_Export( pPlaylist, m_file.c_str(), "export-m3u" );
+        msg_Err( getIntf(), "need to fix playlist save" );
+//        playlist_Export( pPlaylist, m_file.c_str(), "export-m3u" );
     }
 }
 
index e40da6351988c0fe87f09bbc9da4b2a731de9d41..68aac7d977b1852244428114039f67d53064767f 100644 (file)
@@ -33,10 +33,11 @@ void CmdPlaytreeDel::execute()
 void CmdPlaytreeSort::execute()
 {
     /// \todo Choose sort method/order - Need more commands
+    /// \todo Choose the correct view
     playlist_t *p_playlist = getIntf()->p_sys->p_playlist;
     vlc_mutex_lock( &p_playlist->object_lock );
-    playlist_view_t* p_view = playlist_ViewFind( p_playlist, p_playlist->status.i_view );
-    playlist_RecursiveNodeSort( p_playlist, p_view->p_root , SORT_TITLE, ORDER_NORMAL );
+    playlist_RecursiveNodeSort( p_playlist, p_playlist->p_root_onelevel,
+                                SORT_TITLE, ORDER_NORMAL );
     vlc_mutex_unlock( &p_playlist->object_lock );
 
     // Ask for rebuild
index ce08f358131fc6bb7befe0f9981c6b421ff5bfa8..59c5848567995ab56d75174a209815512b0c211a 100644 (file)
 #include "../src/vlcproc.hpp"
 #include "../utils/var_text.hpp"
 #include "../vars/equalizer.hpp"
-#include "../vars/playlist.hpp"
 #include "../vars/playtree.hpp"
 
 
-void CmdNotifyPlaylist::execute()
-{
-    // Notify the playlist variable
-    Playlist &rVar = VlcProc::instance( getIntf() )->getPlaylistVar();
-    rVar.onChange();
-}
-
 void CmdPlaytreeChanged::execute()
 {
     // Notify  the playtree variable
@@ -43,7 +35,6 @@ void CmdPlaytreeChanged::execute()
     rVar.onChange();
 }
 
-
 void CmdPlaytreeUpdate::execute()
 {
     // Notify  the playtree variable
@@ -53,9 +44,8 @@ void CmdPlaytreeUpdate::execute()
 
 bool CmdPlaytreeUpdate::checkRemove( CmdGeneric *pQueuedCommand ) const
 {
-
+    // We don't use RTTI - Use C-style cast
     CmdPlaytreeUpdate *pUpdateCommand = (CmdPlaytreeUpdate *)(pQueuedCommand);
-    //CmdPlaytreeUpdate *pUpdateCommand = dynamic_cast<CmdPlaytreeUpdate *>(pQueuedCommand);
     if( m_id == pUpdateCommand->m_id )
     {
         return true;
index b09e910e675174bba9ee37fa0f05c5a1cccaea10..2ba41f6139b22242b5e005c0807af8a4414b6afb 100644 (file)
@@ -76,12 +76,8 @@ Interpreter::Interpreter( intf_thread_t *pIntf ): SkinObject( pIntf )
     REGISTER_CMD( "playlist.load()", CmdDlgPlaylistLoad )
     REGISTER_CMD( "playlist.save()", CmdDlgPlaylistSave )
     REGISTER_CMD( "playlist.add()", CmdDlgAdd )
-    VarList &rVar = VlcProc::instance( getIntf() )->getPlaylistVar();
-    m_commandMap["playlist.del()"] =
-        CmdGenericPtr( new CmdPlaylistDel( getIntf(), rVar ) );
     REGISTER_CMD( "playlist.next()", CmdPlaylistNext )
     REGISTER_CMD( "playlist.previous()", CmdPlaylistPrevious )
-    REGISTER_CMD( "playlist.sort()", CmdPlaylistSort )
     m_commandMap["playlist.setRandom(true)"] =
         CmdGenericPtr( new CmdPlaylistRandom( getIntf(), true ) );
     m_commandMap["playlist.setRandom(false)"] =
index f3ea0c2f748ae811101d2b58512143d8778cbe22..09a6dc71fc73e79868e3acd70338dd93d9dc970f 100644 (file)
@@ -291,12 +291,12 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
         m_pData->m_listLayout.push_back( layout );
         m_curLayer = 0;
     }
-
     else if( rName == "Playlist" )
     {
         RequireDefault( "id" );
         RequireDefault( "font" );
         CheckDefault( "visible", "true" );
+        CheckDefault( "flat", "true" ); // Only difference here
         CheckDefault( "x", "0" );
         CheckDefault( "y", "0" );
         CheckDefault( "width", "0" );
@@ -304,26 +304,33 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
         CheckDefault( "lefttop", "lefttop" );
         CheckDefault( "rightbottom", "lefttop" );
         CheckDefault( "bgimage", "none" );
+        CheckDefault( "itemimage", "none" );
+        CheckDefault( "openimage", "none" );
+        CheckDefault( "closedimage", "none" );
         CheckDefault( "fgcolor", "#000000" );
         CheckDefault( "playcolor", "#FF0000" );
         CheckDefault( "bgcolor1", "#FFFFFF" );
         CheckDefault( "bgcolor2", "#FFFFFF" );
         CheckDefault( "selcolor", "#0000FF" );
         CheckDefault( "help", "" );
-
-        m_curListId = uniqueId( attr["id"] );
-        const BuilderData::List listData( m_curListId, atoi( attr["x"] ) +
+        m_curTreeId = uniqueId( attr["id"] );
+        const BuilderData::Tree treeData( m_curTreeId, atoi( attr["x"] ) +
                 m_xOffset, atoi( attr["y"] ) + m_yOffset, attr["visible"],
+                attr["flat"],
                 atoi( attr["width"]), atoi( attr["height"] ),
-                attr["lefttop"], attr["rightbottom"], attr["font"],
-                "playlist", attr["bgimage"], attr["fgcolor"],
-                attr["playcolor"], attr["bgcolor1"], attr["bgcolor2"],
+                attr["lefttop"], attr["rightbottom"],
+                attr["font"], "playtree",
+                attr["bgimage"], attr["itemimage"],
+                attr["openimage"], attr["closedimage"],
+                attr["fgcolor"],
+                attr["playcolor"],
+                attr["bgcolor1"],
+                attr["bgcolor2"],
                 attr["selcolor"], attr["help"],
                 m_curLayer, m_curWindowId, m_curLayoutId );
         m_curLayer++;
-        m_pData->m_listList.push_back( listData );
+        m_pData->m_listTree.push_back( treeData );
     }
-
     else if( rName == "Playtree" )
     {
         RequireDefault( "id" );
@@ -412,12 +419,7 @@ void SkinParser::handleBeginElement( const string &rName, AttrList_t &attr )
         CheckDefault( "help", "" );
 
         string newValue = attr["value"];
-        if( m_curListId != "" )
-        {
-            // Slider associated to a list
-            newValue = "playlist.slider";
-        }
-        else if( m_curTreeId != "" )
+        if( m_curTreeId != "" )
         {
             // Slider associated to a tree
             newValue = "playtree.slider";
@@ -560,11 +562,7 @@ void SkinParser::handleEndElement( const string &rName )
         m_xOffsetList.pop_back();
         m_yOffsetList.pop_back();
     }
-    else if( rName == "Playlist" )
-    {
-        m_curListId = "";
-    }
-    else if( rName == "Playtree" )
+    else if( rName == "Playtree" || rName == "Playlist" )
     {
         m_curTreeId = "";
     }
index 503966114f0fe25bda9e0e40cf7ba58573409341..dccee59743b059b90bc74ec20cbb8a76f1a766e2 100644 (file)
@@ -308,8 +308,8 @@ static int DemuxOpen( vlc_object_t *p_this )
             if( p_playlist != NULL )
             {
                 // Make sure the item is deleted afterwards
-                p_playlist->pp_items[p_playlist->i_index]->b_autodeletion =
-                    VLC_TRUE;
+                /// \bug does not always work
+                p_playlist->status.p_item->i_flags |= PLAYLIST_REMOVE_FLAG;
                 vlc_object_release( p_playlist );
             }
 
index ec112348fd68d8e57c867ecd72d158bcf7a33c8a..dcd36ed537c19b9739e4270fc9794505ed7dfbdb 100644 (file)
@@ -79,11 +79,6 @@ VlcProc::VlcProc( intf_thread_t *pIntf ): SkinObject( pIntf ),
 #define REGISTER_VAR( var, type, name ) \
     var = VariablePtr( new type( getIntf() ) ); \
     pVarManager->registerVar( var, name );
-
-    /* Playlist variables */
-    REGISTER_VAR( m_cPlaylist, Playlist, "playlist" )
-    pVarManager->registerVar( getPlaylistVar().getPositionVarPtr(),
-                              "playlist.slider" );
     REGISTER_VAR( m_cVarRandom, VarBoolImpl, "playlist.isRandom" )
     REGISTER_VAR( m_cVarLoop, VarBoolImpl, "playlist.isLoop" )
     REGISTER_VAR( m_cVarRepeat, VarBoolImpl, "playlist.isRepeat" )
@@ -415,14 +410,11 @@ int VlcProc::onIntfChange( vlc_object_t *pObj, const char *pVariable,
     playlist_t *p_playlist = (playlist_t*)pObj;
     pThis->updateStreamName(p_playlist);
 
-    // Create a playlist notify command (for old style playlist)
-    CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
     // Create a playtree notify command (for new style playtree)
     CmdPlaytreeChanged *pCmdTree = new CmdPlaytreeChanged( pThis->getIntf() );
 
     // Push the command in the asynchronous command queue
     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
-    pQueue->push( CmdGenericPtr( pCmd ) );
     pQueue->push( CmdGenericPtr( pCmdTree ) );
 
     return VLC_SUCCESS;
@@ -460,16 +452,12 @@ int VlcProc::onItemChange( vlc_object_t *pObj, const char *pVariable,
     playlist_t *p_playlist = (playlist_t*)pObj;
     pThis->updateStreamName(p_playlist);
 
-    // Create a playlist notify command
-    // TODO: selective update
-    CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
     // Create a playtree notify command
     CmdPlaytreeUpdate *pCmdTree = new CmdPlaytreeUpdate( pThis->getIntf(),
                                                          newVal.i_int );
 
     // Push the command in the asynchronous command queue
     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
-    pQueue->push( CmdGenericPtr( pCmd ) );
     pQueue->push( CmdGenericPtr( pCmdTree ), true );
 
     return VLC_SUCCESS;
@@ -491,12 +479,8 @@ int VlcProc::onItemAppend( vlc_object_t *pObj, const char *pVariable,
                                                              p_add );
     ptrTree = CmdGenericPtr( pCmdTree );
 
-    // Create a playlist notify command (for old style playlist)
-    CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
-
     // Push the command in the asynchronous command queue
     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
-    pQueue->push( CmdGenericPtr( pCmd ) );
     pQueue->push( ptrTree , false );
 
     return VLC_SUCCESS;
@@ -515,20 +499,14 @@ int VlcProc::onItemDelete( vlc_object_t *pObj, const char *pVariable,
                                                          i_id);
     ptrTree = CmdGenericPtr( pCmdTree );
 
-    // Create a playlist notify command (for old style playlist)
-    CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
-
     // Push the command in the asynchronous command queue
     AsyncQueue *pQueue = AsyncQueue::instance( pThis->getIntf() );
-    pQueue->push( CmdGenericPtr( pCmd ) );
     pQueue->push( ptrTree , false );
 
     return VLC_SUCCESS;
 }
 
 
-
-
 int VlcProc::onPlaylistChange( vlc_object_t *pObj, const char *pVariable,
                                vlc_value_t oldVal, vlc_value_t newVal,
                                void *pParam )
@@ -541,10 +519,6 @@ int VlcProc::onPlaylistChange( vlc_object_t *pObj, const char *pVariable,
     playlist_t *p_playlist = (playlist_t*)pObj;
     pThis->updateStreamName(p_playlist);
 
-    // Create a playlist notify command (old style playlist)
-    // TODO: selective update
-    CmdNotifyPlaylist *pCmd = new CmdNotifyPlaylist( pThis->getIntf() );
-    pQueue->push( CmdGenericPtr( pCmd ) );
     // Create two playtree notify commands: one for old item, one for new
     CmdPlaytreeUpdate *pCmdTree = new CmdPlaytreeUpdate( pThis->getIntf(),
                                                          oldVal.i_int );
index 9f0ecea61ee14e4739c5b6fc8618290d8cd6f395..6008089a9b226ffdf2e8e03de8acaf00b2249d63 100644 (file)
@@ -28,7 +28,6 @@
 #include <set>
 
 #include "../vars/equalizer.hpp"
-#include "../vars/playlist.hpp"
 #include "../vars/playtree.hpp"
 #include "../vars/time.hpp"
 #include "../vars/volume.hpp"
@@ -52,9 +51,6 @@ class VlcProc: public SkinObject
         /// Delete the instance of VlcProc
         static void destroy( intf_thread_t *pIntf );
 
-        /// Getter for the playlist variable
-        Playlist &getPlaylistVar() { return *((Playlist*)m_cPlaylist.get()); }
-
         /// Getter for the playtree variable
         Playtree &getPlaytreeVar() { return *((Playtree*)m_cPlaytree.get()); }
 
@@ -104,9 +100,7 @@ class VlcProc: public SkinObject
     private:
         /// Timer to call manage() regularly (via doManage())
         OSTimer *m_pTimer;
-        /// Playlist variable
-        VariablePtr m_cPlaylist;
-        /// Playtree variable FIXME
+        /// Playtree variable
         VariablePtr m_cPlaytree;
         VariablePtr m_cVarRandom;
         VariablePtr m_cVarLoop;
diff --git a/modules/gui/skins2/vars/playlist.cpp b/modules/gui/skins2/vars/playlist.cpp
deleted file mode 100644 (file)
index 80d77d7..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*****************************************************************************
- * playlist.cpp
- *****************************************************************************
- * Copyright (C) 2003 the VideoLAN team
- * $Id$
- *
- * Authors: Cyril Deguet     <asmax@via.ecp.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#include <vlc/vlc.h>
-
-#include "playlist.hpp"
-#include "../utils/ustring.hpp"
-
-Playlist::Playlist( intf_thread_t *pIntf ): VarList( pIntf )
-{
-    // Get the playlist VLC object
-    m_pPlaylist = pIntf->p_sys->p_playlist;
-
-    buildList();
-}
-
-
-Playlist::~Playlist()
-{
-}
-
-
-void Playlist::delSelected()
-{
-    // Remove the items from the VLC playlist
-    int index = 0;
-    ConstIterator it;
-    for( it = begin(); it != end(); it++ )
-    {
-        if( (*it).m_selected )
-        {
-            playlist_item_t *p_item = playlist_LockItemGetByPos( m_pPlaylist,
-                                                                 index );
-            playlist_LockDelete( m_pPlaylist, p_item->input.i_id );
-        }
-        else
-        {
-            index++;
-        }
-    }
-
-    notify();
-}
-
-
-void Playlist::action( Elem_t *pItem )
-{
-    // Find the index of the item
-    int index = 0;
-    ConstIterator it;
-    for( it = begin(); it != end(); it++ )
-    {
-        if( &*it == pItem ) break;
-        index++;
-    }
-    // Item found ?
-    if( index < size() )
-    {
-        playlist_Goto( m_pPlaylist, index );
-    }
-}
-
-
-void Playlist::onChange()
-{
-    buildList();
-    notify();
-}
-
-
-void Playlist::buildList()
-{
-    clear();
-
-    vlc_mutex_lock( &m_pPlaylist->object_lock );
-    for( int i = 0; i < m_pPlaylist->i_size; i++ )
-    {
-        // Get the name of the playlist item
-        UString *pName =
-            new UString( getIntf(), m_pPlaylist->pp_items[i]->input.psz_name );
-        // Is it the played stream ?
-        bool playing = (i == m_pPlaylist->i_index );
-        // Add the item in the list
-        m_list.push_back( Elem_t( UStringPtr( pName ), false, playing ) );
-    }
-    vlc_mutex_unlock( &m_pPlaylist->object_lock );
-}
-
diff --git a/modules/gui/skins2/vars/playlist.hpp b/modules/gui/skins2/vars/playlist.hpp
deleted file mode 100644 (file)
index 693f1c9..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*****************************************************************************
- * playlist.hpp
- *****************************************************************************
- * Copyright (C) 2003 the VideoLAN team
- * $Id$
- *
- * Authors: Cyril Deguet     <asmax@via.ecp.fr>
- *          Olivier Teulière <ipkiss@via.ecp.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-
-#ifndef PLAYLIST_HPP
-#define PLAYLIST_HPP
-
-#include "../utils/var_list.hpp"
-
-/// Variable for VLC playlist
-class Playlist: public VarList
-{
-    public:
-        Playlist( intf_thread_t *pIntf );
-        virtual ~Playlist();
-
-        /// Remove the selected elements from the list
-        virtual void delSelected();
-
-        /// Execute the action associated to this item
-        virtual void action( Elem_t *pItem );
-
-        /// Function called to notify playlist changes
-        void onChange();
-
-    private:
-        /// VLC playlist object
-        playlist_t *m_pPlaylist;
-
-        /// Build the list from the VLC playlist
-        void buildList();
-};
-
-
-#endif
index 944a2e7c04af530ca595f8b3367f5a6a1fb78698..bf12c7538a58a4963a2334451e28654e4074abb7 100644 (file)
@@ -80,8 +80,8 @@ void Playtree::delSelected()
             playlist_item_t *p_item = (playlist_item_t *)(it->m_pData);
             if( p_item->i_children == -1 )
             {
-                playlist_Delete( getIntf()->p_sys->p_playlist,
-                                     p_item->input.i_id );
+                playlist_DeleteFromItemId( getIntf()->p_sys->p_playlist,
+                                           p_item->i_id );
                 it2 = getNextVisibleItem( it ) ;
                 it->parent()->removeChild( it );
                 it = it2;
@@ -107,21 +107,21 @@ void Playtree::action( VarTree *pItem )
 {
     vlc_mutex_lock( &m_pPlaylist->object_lock );
     VarTree::Iterator it;
-    if( pItem->size() )
+
+    playlist_item_t *p_item = (playlist_item_t *)pItem->m_pData;
+    playlist_item_t *p_parent = p_item;
+    while( p_parent )
+    {
+        if( p_parent == m_pPlaylist->p_root_category )
+            break;
+        p_parent = p_parent->p_parent;
+    }
+
+    if( p_parent )
     {
-        it = pItem->begin();
-        while( it->size() ) it = it->begin();
+        playlist_Control( m_pPlaylist, PLAYLIST_VIEWPLAY, 1242,
+                          p_parent, p_item );
     }
-    playlist_Control( m_pPlaylist,
-                      PLAYLIST_VIEWPLAY,
-                      m_pPlaylist->status.i_view,
-                      pItem->size()
-                          ? (playlist_item_t *)pItem->m_pData
-                          : (playlist_item_t *)pItem->parent()->m_pData,
-                      pItem->size()
-                          ? (playlist_item_t *)it->m_pData
-                          : (playlist_item_t *)pItem->m_pData
-                    );
     vlc_mutex_unlock( &m_pPlaylist->object_lock );
 }
 
@@ -142,7 +142,7 @@ void Playtree::onUpdateItem( int id )
     {
         // Update the item
         playlist_item_t* pNode = (playlist_item_t*)(it->m_pData);
-        UString *pName = new UString( getIntf(), pNode->input.psz_name );
+        UString *pName = new UString( getIntf(), pNode->p_input->psz_name );
         it->m_cString = UStringPtr( pName );
         it->m_playing = m_pPlaylist->status.p_item == pNode;
         if( it->m_playing ) descr.b_active_item = true;
@@ -185,7 +185,8 @@ void Playtree::onAppend( playlist_add_t *p_add )
             playlist_item_t *p_item = playlist_ItemGetById(
                                         m_pPlaylist, p_add->i_item );
             if( !p_item ) return;
-            UString *pName = new UString( getIntf(), p_item->input.psz_name );
+            UString *pName = new UString( getIntf(),
+                                          p_item->p_input->psz_name );
             node->add( p_add->i_item, UStringPtr( pName ),
                       false,false, false, p_item->i_flags & PLAYLIST_RO_FLAG,
                       p_item );
@@ -204,8 +205,8 @@ void Playtree::buildNode( playlist_item_t *pNode, VarTree &rTree )
     for( int i = 0; i < pNode->i_children; i++ )
     {
         UString *pName = new UString( getIntf(),
-                                      pNode->pp_children[i]->input.psz_name );
-        rTree.add( pNode->pp_children[i]->input.i_id, UStringPtr( pName ),
+                                   pNode->pp_children[i]->p_input->psz_name );
+        rTree.add( pNode->pp_children[i]->p_input->i_id, UStringPtr( pName ),
                      false,
                      m_pPlaylist->status.p_item == pNode->pp_children[i],
                      false, pNode->pp_children[i]->i_flags & PLAYLIST_RO_FLAG,
@@ -224,17 +225,16 @@ void Playtree::buildTree()
 
     i_items_to_append = 0;
 
-    playlist_view_t *p_view;
-    p_view = playlist_ViewFind( m_pPlaylist, VIEW_CATEGORY );
-    /// \todo let the user chose the view
-
     clear();
 
+    /* TODO: Let user choose view - Stick with category ATM */
+
     /* Set the root's name */
-    UString *pName = new UString( getIntf(), p_view->p_root->input.psz_name );
+    UString *pName = new UString( getIntf(),
+                             m_pPlaylist->p_root_category->p_input->psz_name );
     m_cString = UStringPtr( pName );
 
-    buildNode( p_view->p_root, *this );
+    buildNode( m_pPlaylist->p_root_category, *this );
 
     vlc_mutex_unlock( &m_pPlaylist->object_lock );
 //  What is it ?
index 3f8aaa96ec24006ab7f7296a1c20e66484f1c1fa..b9f9e04915439bde8167f58cfcc15203047ec9aa 100644 (file)
@@ -440,12 +440,12 @@ void DialogsProvider::OnOpenFileSimple( wxCommandEvent& event )
         {
             char *psz_utf8 = wxFromLocale( paths[i] );
             if( event.GetInt() )
-                playlist_Add( p_playlist, psz_utf8, psz_utf8,
+                playlist_PlaylistAdd( p_playlist, psz_utf8, psz_utf8,
                               PLAYLIST_APPEND | (i ? 0 : PLAYLIST_GO) |
                               (i ? PLAYLIST_PREPARSE : 0 ),
                               PLAYLIST_END );
             else
-                playlist_Add( p_playlist, psz_utf8, psz_utf8,
+                playlist_PlaylistAdd( p_playlist, psz_utf8, psz_utf8,
                               PLAYLIST_APPEND | PLAYLIST_PREPARSE , PLAYLIST_END );
             wxLocaleFree( psz_utf8 );
         }
@@ -471,7 +471,7 @@ void DialogsProvider::OnOpenDirectory( wxCommandEvent& event )
     {
         wxString path = p_dir_dialog->GetPath();
         char *psz_utf8 = wxFromLocale( path );
-        playlist_Add( p_playlist, psz_utf8, psz_utf8,
+        playlist_PlaylistAdd( p_playlist, psz_utf8, psz_utf8,
                       PLAYLIST_APPEND | (event.GetInt() ? PLAYLIST_GO : 0),
                       PLAYLIST_END );
         wxLocaleFree( psz_utf8 );
index 16be914a81797e2ca04ab8adc0dde5b8f2a28590..7260265d773f385494b6d7567e677d7271b49388 100644 (file)
@@ -98,6 +98,7 @@ MetaDataPanel::MetaDataPanel( intf_thread_t *_p_intf,
     ADD_META( VLC_META_LANGUAGE, language_text );
     ADD_META( VLC_META_NOW_PLAYING, nowplaying_text );
     ADD_META( VLC_META_PUBLISHER, publisher_text );
+    ADD_META( VLC_META_SETTING, setting_text );
 
     meta_sizer->Layout();
 
@@ -120,8 +121,7 @@ void MetaDataPanel::Update( input_item_t *p_item )
     name_text->SetValue( wxU( p_item->psz_name ) );
 
 #define UPDATE_META( meta, widget ) {                                       \
-    char *psz_meta = vlc_input_item_GetInfo( p_item, _(VLC_META_INFO_CAT),  \
-                                            _(meta) );                      \
+    char *psz_meta = p_item->p_meta->psz_##meta;                            \
     if( psz_meta != NULL && *psz_meta)                                      \
     {                                                                       \
         widget->SetLabel( wxU( psz_meta ) );                                \
@@ -129,17 +129,18 @@ void MetaDataPanel::Update( input_item_t *p_item )
     else { widget->SetLabel( wxU( "-" ) ); }                                \
     }
 
-    UPDATE_META( VLC_META_ARTIST, artist_text );
-    UPDATE_META( VLC_META_GENRE, genre_text );
-    UPDATE_META( VLC_META_COPYRIGHT, copyright_text );
-    UPDATE_META( VLC_META_COLLECTION, collection_text );
-    UPDATE_META( VLC_META_SEQ_NUM, seqnum_text );
-    UPDATE_META( VLC_META_DESCRIPTION, description_text );
-    UPDATE_META( VLC_META_RATING, rating_text );
-    UPDATE_META( VLC_META_DATE, date_text );
-    UPDATE_META( VLC_META_LANGUAGE, language_text );
-    UPDATE_META( VLC_META_NOW_PLAYING, nowplaying_text );
-    UPDATE_META( VLC_META_PUBLISHER, publisher_text );
+    UPDATE_META( artist, artist_text );
+    UPDATE_META( genre, genre_text );
+    UPDATE_META( copyright, copyright_text );
+    UPDATE_META( album, collection_text );
+    UPDATE_META( tracknum, seqnum_text );
+    UPDATE_META( description, description_text );
+    UPDATE_META( rating, rating_text );
+    UPDATE_META( date, date_text );
+    UPDATE_META( language, language_text );
+    UPDATE_META( nowplaying, nowplaying_text );
+    UPDATE_META( publisher, publisher_text );
+    UPDATE_META( setting, setting_text );
 
 #undef UPDATE_META
 }
index 7a92df04500e111bbeafe70d2ef0910abd11484c..01cc2eaae1e67e9150d9c041646b0374315fe4db 100644 (file)
@@ -70,7 +70,7 @@ ItemInfoDialog::ItemInfoDialog( intf_thread_t *_p_intf,
 
     /* Create the standard info panel */
     info_panel = new MetaDataPanel(p_intf, panel, true );
-    info_panel->Update( &(p_item->input) );
+    info_panel->Update( p_item->p_input );
     /* Separation */
     wxStaticLine *static_line = new wxStaticLine( panel, wxID_OK );
 
@@ -107,10 +107,10 @@ ItemInfoDialog::~ItemInfoDialog()
  *****************************************************************************/
 void ItemInfoDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
 {
-    vlc_mutex_lock( &p_item->input.lock );
-    p_item->input.psz_name = info_panel->GetName();
-    p_item->input.psz_uri = info_panel->GetURI();
-    vlc_mutex_unlock( &p_item->input.lock );
+    vlc_mutex_lock( &p_item->p_input->lock );
+    p_item->p_input->psz_name = info_panel->GetName();
+    p_item->p_input->psz_uri = info_panel->GetURI();
+    vlc_mutex_unlock( &p_item->p_input->lock );
     EndModal( wxID_OK );
 }
 
index d6a48cccefbc4c4274d64037484c5447a2856262..d8c9a17ab2145f5e5f832f2d592189ed0d50f98c 100644 (file)
@@ -1165,11 +1165,11 @@ void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
     for( int i = 0; i < (int)mrl.GetCount(); i++ )
     {
         vlc_bool_t b_start = !i && i_open_arg;
-        playlist_item_t *p_item;
+        input_item_t *p_input;
         char *psz_utf8;
 
         psz_utf8 = wxFromLocale( mrl[i] );
-        p_item = playlist_ItemNew( p_intf, psz_utf8, psz_utf8 );
+        p_input = input_ItemNew( p_intf, psz_utf8, psz_utf8 );
         wxLocaleFree( psz_utf8 );
 
         /* Insert options */
@@ -1177,7 +1177,7 @@ void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
                ((const char *)mrl[i + 1].mb_str())[0] == ':' )
         {
             psz_utf8 = wxFromLocale( mrl[i + 1] );
-            playlist_ItemAddOption( p_item, psz_utf8 );
+            vlc_input_item_AddOption( p_input, psz_utf8 );
             wxLocaleFree( psz_utf8 );
             i++;
         }
@@ -1188,7 +1188,7 @@ void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
             for( int j = 0; j < (int)subsfile_mrl.GetCount(); j++ )
             {
                 psz_utf8 = wxFromLocale( subsfile_mrl[j] );
-                playlist_ItemAddOption( p_item, psz_utf8 );
+                vlc_input_item_AddOption( p_input, psz_utf8 );
                 wxLocaleFree( psz_utf8 );
             }
         }
@@ -1199,24 +1199,24 @@ void OpenDialog::OnOk( wxCommandEvent& WXUNUSED(event) )
             for( int j = 0; j < (int)sout_mrl.GetCount(); j++ )
             {
                 psz_utf8 = wxFromLocale( sout_mrl[j] );
-                playlist_ItemAddOption( p_item, psz_utf8 );
+                vlc_input_item_AddOption( p_input, psz_utf8 );
                 wxLocaleFree( psz_utf8 );
             }
         }
 
-
         if( b_start )
         {
-            playlist_AddItem( p_playlist, p_item,
-                              PLAYLIST_APPEND,
-                              PLAYLIST_END );
-            playlist_Control( p_playlist, PLAYLIST_ITEMPLAY, p_item );
+            playlist_PlaylistAddInput( p_playlist, p_input, PLAYLIST_APPEND,
+                                       PLAYLIST_END );
+            msg_Err( p_playlist, "Item start not implemented" );
+            // FIXME: Play only within the playlist node
+            //playlist_Control( p_playlist, PLAYLIST_ITEMPLAY, p_item );
         }
         else
         {
-            playlist_AddItem( p_playlist, p_item,
-                              PLAYLIST_APPEND|PLAYLIST_PREPARSE,
-                              PLAYLIST_END );
+            playlist_PlaylistAddInput( p_playlist, p_input,
+                                       PLAYLIST_APPEND|PLAYLIST_PREPARSE,
+                                       PLAYLIST_END );
         }
     }
 
index a1162bde2b5d7dbd376a64f28efe3853514bd47d..8802d70b320a6bdeb6cc9800c3bedc3916cde76e 100644 (file)
@@ -102,6 +102,7 @@ enum
     Search_Event,
 
     /* controls */
+    Source_Event,
     TreeCtrl_Event,
 
     Browse_Event,  /* For export playlist */
@@ -114,6 +115,7 @@ enum
     MenuDummy_Event = wxID_HIGHEST + 999,
 
     FirstView_Event = wxID_HIGHEST + 1000,
+    CategoryView_Event, OneLevelView_Event,
     LastView_Event = wxID_HIGHEST + 1100,
 
     FirstSD_Event = wxID_HIGHEST + 2000,
@@ -156,6 +158,8 @@ BEGIN_EVENT_TABLE(Playlist, wxFrame)
     EVT_MENU( PopupInfo_Event, Playlist::OnPopupInfo)
     EVT_MENU( PopupAddNode_Event, Playlist::OnPopupAddNode)
 
+    /* Source selector */
+    EVT_LIST_ITEM_SELECTED( Source_Event, Playlist::OnSourceSelected )
     /* Tree control events */
     EVT_TREE_ITEM_ACTIVATED( TreeCtrl_Event, Playlist::OnActivateItem )
     EVT_TREE_KEY_DOWN( -1, Playlist::OnKeyDown )
@@ -187,9 +191,11 @@ class PlaylistItem : public wxTreeItemData
 public:
     PlaylistItem( playlist_item_t *p_item ) : wxTreeItemData()
     {
-        i_id = p_item->input.i_id;
+        i_id = p_item->i_id;
+        i_input_id = p_item->p_input->i_id;
     }
 protected:
+    int i_input_id;
     int i_id;
 friend class Playlist;
 friend class PlaylistFileDropTarget;
@@ -220,8 +226,9 @@ Playlist::Playlist( intf_thread_t *_p_intf, wxWindow *p_parent ):
     p_view_menu = NULL;
     p_sd_menu = SDMenu();
 
-    i_current_view = VIEW_CATEGORY;
-    b_changed_view = VLC_FALSE;
+//    i_current_view = VIEW_ONELEVEL;
+    p_current_viewroot = p_playlist->p_root_onelevel;
+    p_current_treeroot = p_playlist->p_local_onelevel;
 
     i_title_sorted = 0;
     i_group_sorted = 0;
@@ -331,6 +338,11 @@ Playlist::Playlist( intf_thread_t *_p_intf, wxWindow *p_parent ):
     search_button->SetDefault();
     toolbar->Realize();
 
+    /* Create teh source selector */
+    source_sel = new wxListCtrl( playlist_panel, Source_Event,
+                                wxDefaultPosition, wxDefaultSize,
+                                wxLC_AUTOARRANGE|wxLC_SINGLE_SEL );
+
     /* Create the tree */
     treectrl = new wxTreeCtrl( playlist_panel, TreeCtrl_Event,
                                wxDefaultPosition, wxDefaultSize,
@@ -362,7 +374,8 @@ Playlist::Playlist( intf_thread_t *_p_intf, wxWindow *p_parent ):
     font.SetPointSize(9);
     treectrl->SetFont( font );
 
-    wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
+    wxBoxSizer *panel_sizer = new wxBoxSizer( wxHORIZONTAL );
+    panel_sizer->Add( source_sel, 0, wxALL | wxEXPAND, 5 );
     panel_sizer->Add( treectrl, 1, wxEXPAND | wxALL, 5 );
     panel_sizer->Layout();
 
@@ -380,9 +393,7 @@ Playlist::Playlist( intf_thread_t *_p_intf, wxWindow *p_parent ):
 #endif
 
     i_saved_id = -1;
-
-
-    /* We want to be noticed of playlist changes */
+    i_saved_input_id = -1;
 
     /* Some global changes happened -> Rebuild all */
     var_AddCallback( p_playlist, "intf-change", PlaylistChanged, this );
@@ -443,7 +454,7 @@ void Playlist::UpdateNode( playlist_item_t *p_node, wxTreeItemId node )
             child = treectrl->GetNextChild( node, cookie );
         }
     }
-    treectrl->SetItemImage( node, p_node->input.i_type );
+    treectrl->SetItemImage( node, p_node->p_input->i_type );
 
 }
 
@@ -451,9 +462,9 @@ void Playlist::UpdateNode( playlist_item_t *p_node, wxTreeItemId node )
 void Playlist::CreateNode( playlist_item_t *p_node, wxTreeItemId parent )
 {
     wxTreeItemId node =
-        treectrl->AppendItem( parent, wxL2U( p_node->input.psz_name ),
+        treectrl->AppendItem( parent, wxL2U( p_node->p_input->psz_name ),
                               -1,-1, new PlaylistItem( p_node ) );
-    treectrl->SetItemImage( node, p_node->input.i_type );
+    treectrl->SetItemImage( node, p_node->p_input->i_type );
 
     UpdateNodeChildren( p_node, node );
 }
@@ -462,18 +473,20 @@ void Playlist::CreateNode( playlist_item_t *p_node, wxTreeItemId parent )
 void Playlist::UpdateNodeChildren( playlist_item_t *p_node,
                                    wxTreeItemId node )
 {
-
     for( int i = 0; i< p_node->i_children ; i++ )
     {
         /* Append the item */
         if( p_node->pp_children[i]->i_children == -1 )
         {
-            wxTreeItemId item =
-                treectrl->AppendItem( node,
-                    wxL2U( p_node->pp_children[i]->input.psz_name ), -1,-1,
+            if( !(p_node->pp_children[i]->i_flags & PLAYLIST_DBL_FLAG) )
+            {
+                wxTreeItemId item =
+                    treectrl->AppendItem( node,
+                    wxL2U( p_node->pp_children[i]->p_input->psz_name ), -1,-1,
                            new PlaylistItem( p_node->pp_children[i]) );
 
-            UpdateTreeItem( item );
+                UpdateTreeItem( item );
+            }
         }
         else
         {
@@ -485,12 +498,12 @@ void Playlist::UpdateNodeChildren( playlist_item_t *p_node,
 /* Update an item in the tree */
 void Playlist::UpdateTreeItem( wxTreeItemId item )
 {
+    LockPlaylist( p_intf->p_sys, p_playlist );
     if( ! item.IsOk() ) return;
 
     wxTreeItemData *p_data = treectrl->GetItemData( item );
     if( !p_data ) return;
 
-    LockPlaylist( p_intf->p_sys, p_playlist );
     playlist_item_t *p_item = playlist_ItemGetById( p_playlist,
                                           ((PlaylistItem *)p_data)->i_id );
     if( !p_item )
@@ -501,16 +514,19 @@ void Playlist::UpdateTreeItem( wxTreeItemId item )
 
     wxString msg;
     wxString duration = wxU( "" );
-    char *psz_author = vlc_input_item_GetInfo( &p_item->input,
-                                               _(VLC_META_INFO_CAT), _(VLC_META_ARTIST) );
-    if( !psz_author )
+
+    char *psz_author;
+    if( p_item->p_input->p_meta )
     {
-        UnlockPlaylist( p_intf->p_sys, p_playlist );
-        return;
+        psz_author= p_item->p_input->p_meta->psz_artist ?
+                        strdup( p_item->p_input->p_meta->psz_artist ) :
+                        strdup("");
     }
+    else
+        psz_author = strdup( "" );
 
     char psz_duration[MSTRTIME_MAX_SIZE];
-    mtime_t dur = p_item->input.i_duration;
+    mtime_t dur = p_item->p_input->i_duration;
 
     if( dur != -1 )
     {
@@ -519,18 +535,18 @@ void Playlist::UpdateTreeItem( wxTreeItemId item )
                          wxU( " )" ) );
     }
 
-    if( !strcmp( psz_author, "" ) || p_item->input.b_fixed_name == VLC_TRUE )
+    if( !strcmp( psz_author, "" ) || p_item->p_input->b_fixed_name == VLC_TRUE )
     {
-        msg = wxString( wxU( p_item->input.psz_name ) ) + duration;
+        msg = wxString( wxU( p_item->p_input->psz_name ) ) + duration;
     }
     else
     {
         msg = wxString(wxU( psz_author )) + wxT(" - ") +
-              wxString(wxU(p_item->input.psz_name)) + duration;
+              wxString(wxU(p_item->p_input->psz_name)) + duration;
     }
     free( psz_author );
     treectrl->SetItemText( item , msg );
-    treectrl->SetItemImage( item, p_item->input.i_type );
+    treectrl->SetItemImage( item, p_item->p_input->i_type );
 
     if( p_playlist->status.p_item == p_item )
     {
@@ -562,21 +578,20 @@ void Playlist::AppendItem( wxCommandEvent& event )
     /* No need to do anything if the playlist is going to be rebuilt */
     if( b_need_update ) return;
 
-    if( p_add->i_view != i_current_view ) goto update;
-
     node = FindItem( treectrl->GetRootItem(), p_add->i_node );
     if( !node.IsOk() ) goto update;
 
     p_item = playlist_ItemGetById( p_playlist, p_add->i_item );
     if( !p_item ) goto update;
+    if( (p_item->i_flags & PLAYLIST_DBL_FLAG ) ) goto update;
 
     item = FindItem( treectrl->GetRootItem(), p_add->i_item );
     if( item.IsOk() ) goto update;
 
     item = treectrl->AppendItem( node,
-                                 wxL2U( p_item->input.psz_name ), -1,-1,
+                                 wxL2U( p_item->p_input->psz_name ), -1,-1,
                                  new PlaylistItem( p_item ) );
-    treectrl->SetItemImage( item, p_item->input.i_type );
+    treectrl->SetItemImage( item, p_item->p_input->i_type );
 
     if( item.IsOk() && p_item->i_children == -1 )
     {
@@ -585,26 +600,8 @@ void Playlist::AppendItem( wxCommandEvent& event )
 
 update:
     int i_count = CountItems( treectrl->GetRootItem());
-    if( i_count != p_playlist->i_size )
-    {
-        statusbar->SetStatusText( wxString::Format( wxU(_(
-                                  "%i items in playlist (%i not shown)")),
-                                  p_playlist->i_size,
-                                  p_playlist->i_size - i_count ) );
-        if( !b_changed_view )
-        {
-            i_current_view = VIEW_CATEGORY;
-            b_changed_view = VLC_TRUE;
-            b_need_update = VLC_TRUE;
-        }
-    }
-    else
-    {
-        statusbar->SetStatusText( wxString::Format( wxU(_(
-                                  "%i items in playlist")),
-                                  p_playlist->i_size ), 0 );
-    }
-
+    statusbar->SetStatusText( wxString::Format( wxU(_(
+                                  "%i items in playlist" ) ), i_count ) );
     return;
 }
 
@@ -612,9 +609,7 @@ update:
 void Playlist::UpdateItem( int i )
 {
     if( i < 0 ) return; /* Sanity check */
-
-    wxTreeItemId item = FindItem( treectrl->GetRootItem(), i );
-
+    wxTreeItemId item = FindItemByInput( treectrl->GetRootItem(), i );
     if( item.IsOk() )
     {
         UpdateTreeItem( item );
@@ -626,6 +621,11 @@ void Playlist::RemoveItem( int i )
     if( i <= 0 ) return; /* Sanity check */
     if( i == i_saved_id ) i_saved_id = -1;
 
+    /* Hack: always invalidate input item cache */
+    i_saved_input_id = -1;
+
+    /// \todo Check if it is in the source selector */
+
     wxTreeItemId item = FindItem( treectrl->GetRootItem(), i );
 
     if( item.IsOk() )
@@ -641,6 +641,16 @@ void Playlist::RemoveItem( int i )
 
 /* Find a wxItem from a playlist id */
 wxTreeItemId Playlist::FindItem( wxTreeItemId root, int i_id )
+{
+    return FindItemInner( root, i_id, false );
+}
+
+wxTreeItemId Playlist::FindItemByInput( wxTreeItemId root, int i_input_id )
+{
+    return FindItemInner( root, i_input_id, true );
+}
+
+wxTreeItemId Playlist::FindItemInner( wxTreeItemId root, int i_id, bool b_byinput )
 {
     wxTreeItemIdValue cookie;
     PlaylistItem *p_wxcurrent;
@@ -652,51 +662,70 @@ wxTreeItemId Playlist::FindItem( wxTreeItemId root, int i_id )
 
     if( i_id < 0 )
     {
-        wxTreeItemId dummy;
-        return dummy;
+        wxTreeItemId dummy; dummy.Unset(); return dummy;
     }
-    if( i_saved_id == i_id )
-    {
+    if( b_byinput && i_saved_input_id == i_id )
+        return saved_input_tree_item;
+    if( !b_byinput && i_saved_id == i_id)
         return saved_tree_item;
-    }
 
     if( !p_wxcurrent )
     {
-        wxTreeItemId dummy;
-        return dummy;
+        wxTreeItemId dummy; dummy.Unset(); return dummy;
     }
 
-    if( p_wxcurrent->i_id == i_id )
+    if( !b_byinput && p_wxcurrent->i_id == i_id  )
     {
         i_saved_id = i_id;
         saved_tree_item = root;
         return root;
     }
+    if( b_byinput && p_wxcurrent->i_input_id == i_id )
+    {
+        i_saved_input_id = i_id;
+        saved_input_tree_item = root;
+        return root;
+    }
 
     while( item.IsOk() )
     {
         p_wxcurrent = (PlaylistItem *)treectrl->GetItemData( item );
-        if( p_wxcurrent->i_id == i_id )
+        if( !b_byinput && p_wxcurrent->i_id == i_id )
         {
             i_saved_id = i_id;
             saved_tree_item = item;
             return item;
         }
+        else if( b_byinput && p_wxcurrent->i_input_id == i_id )
+        {
+            i_saved_input_id = i_id;
+            saved_input_tree_item = item;
+            return item;
+        }
         if( treectrl->ItemHasChildren( item ) )
         {
-            wxTreeItemId search = FindItem( item, i_id );
+            wxTreeItemId search = FindItemInner( item, i_id, b_byinput );
             if( search.IsOk() )
             {
-                i_saved_id = i_id;
-                saved_tree_item = search;
-                return search;
+                if( !b_byinput )
+                {
+                    i_saved_id = i_id;
+                    saved_tree_item = search;
+                    return search;
+                }
+                else
+                {
+                    i_saved_input_id = i_id;
+                    saved_input_tree_item = search;
+                    return search;
+
+                }
             }
         }
         item = treectrl->GetNextChild( root, cookie );
     }
     /* Not found */
-    wxTreeItemId dummy;
-    return dummy;
+    wxTreeItemId dummy; dummy.Unset(); return dummy;
 }
 
 int Playlist::CountItems( wxTreeItemId root )
@@ -759,7 +788,7 @@ wxTreeItemId Playlist::FindItemByName( wxTreeItemId root, wxString search_string
         item = treectrl->GetNextChild( root, cookie);
     }
     /* Not found */
-    wxTreeItemId dummy;
+    wxTreeItemId dummy; dummy.Unset();
     return dummy;
 }
 
@@ -768,8 +797,6 @@ wxTreeItemId Playlist::FindItemByName( wxTreeItemId root, wxString search_string
  **********************************************************************/
 void Playlist::Rebuild( vlc_bool_t b_root )
 {
-    playlist_view_t *p_view;
-
     i_items_to_append = 0;
 
     /* We can remove the callbacks before locking, anyway, we won't
@@ -785,39 +812,36 @@ void Playlist::Rebuild( vlc_bool_t b_root )
         /* ...and rebuild it */
         LockPlaylist( p_intf->p_sys, p_playlist );
     }
+    /* Invalidate cache */
     i_saved_id = -1;
+    i_saved_input_id = -1;
 
-    p_view = playlist_ViewFind( p_playlist, i_current_view ); /* FIXME */
+    /* Rebuild the list */
+    source_sel->ClearAll();
+    for( int i = 0 ; i< p_current_viewroot->i_children ; i++ )
+    {
+        source_sel->InsertItem( i,
+               wxL2U( p_current_viewroot->pp_children[i]->p_input->psz_name) );
+        source_sel->SetItemData( i,
+                        p_current_viewroot->pp_children[i]->i_id );
+        if( p_current_viewroot->pp_children[i] == p_current_treeroot )
+            source_sel->Select( i );
+    }
 
     /* HACK we should really get new*/
     treectrl->DeleteAllItems();
     treectrl->AddRoot( wxU(_("root" )), -1, -1,
-                         new PlaylistItem( p_view->p_root) );
+                         new PlaylistItem( p_current_treeroot ) );
 
     wxTreeItemId root = treectrl->GetRootItem();
-    UpdateNode( p_view->p_root, root );
+    //UpdateNode( p_current_treeroot, root );
+    //CreateNode( p_current_treeroot, root );
+    UpdateNodeChildren( p_current_treeroot, root );
 
     int i_count = CountItems( treectrl->GetRootItem() );
 
-    if( i_count < p_playlist->i_size && !b_changed_view )
-    {
-        i_current_view = VIEW_CATEGORY;
-        b_changed_view = VLC_TRUE;
-        Rebuild( VLC_FALSE );
-    }
-    else if( i_count != p_playlist->i_size )
-    {
-        statusbar->SetStatusText( wxString::Format( wxU(_(
-                                  "%i items in playlist (%i not shown)")),
-                                  p_playlist->i_size,
-                                  p_playlist->i_size - i_count ) );
-    }
-    else
-    {
-        statusbar->SetStatusText( wxString::Format( wxU(_(
-                                  "%i items in playlist")),
-                                  p_playlist->i_size ), 0 );
-    }
+    statusbar->SetStatusText( wxString::Format( wxU(_(
+                              "%i items in playlist")), i_count ), 0 );
 
     if( b_root )
     {
@@ -832,8 +856,6 @@ void Playlist::Rebuild( vlc_bool_t b_root )
     }
 }
 
-
-
 void Playlist::ShowPlaylist( bool show )
 {
     if( show ) Rebuild( VLC_TRUE );
@@ -876,16 +898,16 @@ void Playlist::DeleteTreeItem( wxTreeItemId item )
        return;
    }
 
-   if( p_item->i_children == -1 ) DeleteItem( p_item->input.i_id );
+   if( p_item->i_children == -1 ) DeleteItem( p_item->i_id );
    else DeleteNode( p_item );
 
-   RemoveItem( p_item->input.i_id );
+   RemoveItem( p_item->i_id );
    UnlockPlaylist( p_intf->p_sys, p_playlist );
 }
 
 void Playlist::DeleteItem( int item_id )
 {
-    playlist_Delete( p_playlist, item_id );
+    playlist_DeleteFromItemId( p_playlist, item_id );
 }
 
 void Playlist::DeleteNode( playlist_item_t *p_item )
@@ -937,8 +959,10 @@ void Playlist::OnSave( wxCommandEvent& WXUNUSED(event) )
     {
         if( dialog.GetPath().mb_str() )
         {
-            playlist_Export( p_playlist, dialog.GetPath().mb_str(),
-                             formats[dialog.GetFilterIndex()].psz_module );
+              abort();
+//            playlist_Export( p_playlist, dialog.GetPath().mb_str(),
+//                             /* ROOT */
+//                             formats[dialog.GetFilterIndex()].psz_module );
         }
     }
 
@@ -1010,28 +1034,16 @@ void Playlist::OnSort( wxCommandEvent& event )
 void Playlist::OnSearch( wxCommandEvent& WXUNUSED(event) )
 {
     wxString search_string = search_text->GetValue();
+    PlaylistItem *p_wxroot;
+    p_wxroot = (PlaylistItem *)treectrl->GetItemData( treectrl->GetRootItem() );
+    playlist_item_t *p_root = playlist_ItemGetById( p_playlist, p_wxroot->i_id );
 
-    vlc_bool_t pb_found = VLC_FALSE;
-
-    wxTreeItemId found =
-     FindItemByName( treectrl->GetRootItem(), search_string,
-                     search_current, &pb_found );
-
-    if( !found.IsOk() )
-    {
-        wxTreeItemId dummy;
-        search_current = dummy;
-        found =  FindItemByName( treectrl->GetRootItem(), search_string,
-                                 search_current, &pb_found );
-    }
+    if( !p_root ) abort();
+    char *psz_name = wxFromLocale( search_string );
+    playlist_LiveSearchUpdate( p_playlist, p_root, psz_name );
+    Rebuild( VLC_TRUE );
 
-    if( found.IsOk() )
-    {
-        search_current = found;
-        treectrl->EnsureVisible( found );
-        treectrl->UnselectAll();
-        treectrl->SelectItem( found, true );
-    }
+    wxLocaleFree( psz_name );
 }
 
 /**********************************************************************
@@ -1088,46 +1100,33 @@ void Playlist::OnRepeat( wxCommandEvent& event )
  ********************************************************************/
 void Playlist::OnActivateItem( wxTreeEvent& event )
 {
-    playlist_item_t *p_item,*p_node,*p_item2,*p_node2;
+    playlist_item_t *p_item, *p_parent;
 
     PlaylistItem *p_wxitem = (PlaylistItem *)treectrl->GetItemData(
                                                             event.GetItem() );
-    wxTreeItemId parent = treectrl->GetItemParent( event.GetItem() );
-
-    PlaylistItem *p_wxparent = (PlaylistItem *)treectrl->GetItemData( parent );
 
     LockPlaylist( p_intf->p_sys, p_playlist );
 
-    if( !( p_wxitem && p_wxparent ) )
+    if( !( p_wxitem ) )
     {
         UnlockPlaylist( p_intf->p_sys, p_playlist );
         return;
     }
+    p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id );
 
-    p_item2 = playlist_ItemGetById(p_playlist, p_wxitem->i_id);
-    p_node2 = playlist_ItemGetById(p_playlist, p_wxparent->i_id);
-    if( p_item2 && p_item2->i_children == -1 )
+    p_parent = p_item;
+    while( p_parent )
     {
-        p_node = p_node2;
-        p_item = p_item2;
+        if( p_parent == p_current_treeroot )
+            break;
+        p_parent = p_parent->p_parent;
     }
-    else
+
+    if( p_parent )
     {
-        p_node = p_item2;
-        p_item = NULL;
-/*        if( p_node && p_node->i_children > 0 &&
-            p_node->pp_children[0]->i_children == -1)
-        {
-            p_item = p_node->pp_children[0];
-        }
-        else
-        {
-            p_item = NULL;
-        }*/
+        playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, 1242,
+                          p_parent, p_item );
     }
-
-    playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, i_current_view,
-                      p_node, p_item );
     UnlockPlaylist( p_intf->p_sys, p_playlist );
 }
 
@@ -1157,11 +1156,6 @@ void Playlist::OnKeyDown( wxTreeEvent& event )
     }
 }
 
-void Playlist::OnEnDis( wxCommandEvent& event )
-{
-    msg_Warn( p_intf, "not implemented" );
-}
-
 void Playlist::OnDragItemBegin( wxTreeEvent& event )
 {
     event.Allow();
@@ -1227,14 +1221,12 @@ void Playlist::OnDragItemEnd( wxTreeEvent& event )
         {
             if( p_destitem2->pp_children[i] == p_destitem ) break;
         }
-        playlist_TreeMove( p_playlist, p_drageditem, p_destitem2,
-                           i, i_current_view );
+        playlist_TreeMove( p_playlist, p_drageditem, p_destitem2, i );
     }
     else
     /* this is a node */
     {
-        playlist_TreeMove( p_playlist, p_drageditem, p_destitem,
-                           0, i_current_view );
+        playlist_TreeMove( p_playlist, p_drageditem, p_destitem, 0 );
     }
 
     UnlockPlaylist( p_intf->p_sys, p_playlist );
@@ -1265,7 +1257,8 @@ bool PlaylistFileDropTarget::OnDropFiles( wxCoord x, wxCoord y,
     {
         /* We were droped below the last item so we append to the
          * general node */
-        p_dest = p->p_playlist->p_general;
+        msg_Err( p->p_playlist, "USE OF P_GENERAL" );
+        p_dest = p->p_playlist->p_local_category;
         i_pos = PLAYLIST_END;
     }
     else
@@ -1308,10 +1301,10 @@ bool PlaylistFileDropTarget::OnDropFiles( wxCoord x, wxCoord y,
     for( size_t i = 0; i < filenames.GetCount(); i++ )
     {
         const char *psz_utf8 = wxDnDFromLocale( filenames[i] );
-        playlist_item_t *p_item =
-            playlist_ItemNew( p->p_playlist, psz_utf8, psz_utf8 );
-        playlist_NodeAddItem( p->p_playlist, p_item, p->i_current_view,
-                              p_dest, PLAYLIST_PREPARSE, i_pos );
+        input_item_t *p_input = input_ItemNew( p->p_playlist,
+                                              psz_utf8, psz_utf8 );
+        playlist_NodeAddInput( p->p_playlist, p_input,
+                               p_dest, PLAYLIST_PREPARSE, i_pos );
         wxDnDLocaleFree( psz_utf8 );
     }
 
@@ -1350,30 +1343,37 @@ void Playlist::OnMenuEvent( wxCommandEvent& event )
     }
     else if( event.GetId() < LastView_Event )
     {
-
-        int i_new_view = event.GetId() - FirstView_Event;
-
-        playlist_view_t *p_view = playlist_ViewFind( p_playlist, i_new_view );
-
-        if( p_view != NULL )
+        if( event.GetId() == CategoryView_Event )
         {
-            b_changed_view = VLC_TRUE;
-            i_current_view = i_new_view;
-            playlist_ViewUpdate( p_playlist, i_new_view );
-            Rebuild( VLC_TRUE );
-            return;
+            p_current_viewroot = p_playlist->p_root_category;
+            if( p_current_treeroot == p_playlist->p_local_category ||
+                p_current_treeroot == p_playlist->p_local_onelevel )
+            {
+                p_current_treeroot = p_playlist->p_local_category;
+            }
+            else if( p_current_treeroot == p_playlist->p_ml_category ||
+                     p_current_treeroot == p_playlist->p_ml_onelevel )
+            {
+                p_current_treeroot = p_playlist->p_ml_category;
+            }
         }
-        else if( i_new_view >= VIEW_FIRST_SORTED &&
-                 i_new_view <= VIEW_LAST_SORTED )
+        else if( event.GetId() == OneLevelView_Event )
         {
-            b_changed_view = VLC_TRUE;
-            playlist_ViewInsert( p_playlist, i_new_view, "View" );
-            playlist_ViewUpdate( p_playlist, i_new_view );
-
-            i_current_view = i_new_view;
-
-            Rebuild( VLC_TRUE );
+            p_current_viewroot = p_playlist->p_root_onelevel;
+            if( p_current_treeroot == p_playlist->p_local_category ||
+                p_current_treeroot == p_playlist->p_local_onelevel )
+            {
+                p_current_treeroot = p_playlist->p_local_onelevel;
+            }
+            else if( p_current_treeroot == p_playlist->p_ml_category ||
+                     p_current_treeroot == p_playlist->p_ml_onelevel )
+            {
+                p_current_treeroot = p_playlist->p_ml_onelevel;
+            }
         }
+        wxCommandEvent event;
+        OnSearch( event );
+        return;
     }
     else if( event.GetId() >= FirstSD_Event && event.GetId() < LastSD_Event )
     {
@@ -1410,14 +1410,8 @@ wxMenu * Playlist::ViewMenu()
         }
     }
 
-    /* FIXME : have a list of "should have" views */
-    p_view_menu->Append( FirstView_Event + VIEW_CATEGORY,
-                           wxU(_("Normal") ) );
-    p_view_menu->Append( FirstView_Event + VIEW_S_AUTHOR,
-                           wxU(_("Sorted by Artist") ) );
-    p_view_menu->Append( FirstView_Event + VIEW_S_ALBUM,
-                           wxU(_("Sorted by Album") ) );
-
+    p_view_menu->Append( CategoryView_Event, wxU(_("Normal") ) );
+    p_view_menu->Append( OneLevelView_Event, wxU(_("One level") ) );
     return p_view_menu;
 }
 
@@ -1515,6 +1509,12 @@ void Playlist::OnPopup( wxContextMenuEvent& event )
 void Playlist::OnPopupPlay( wxCommandEvent& event )
 {
     playlist_item_t *p_popup_item, *p_popup_parent;
+
+    
+    
+    abort();
+
+
     LockPlaylist( p_intf->p_sys, p_playlist );
     p_popup_item = playlist_ItemGetById( p_playlist, i_popup_item );
     p_popup_parent = playlist_ItemGetById( p_playlist, i_popup_parent );
@@ -1526,13 +1526,13 @@ void Playlist::OnPopupPlay( wxCommandEvent& event )
                 p_popup_item->i_children > 0 )
             {
                 playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
-                                  i_current_view, p_popup_item,
+                                  1242, p_popup_item,
                                   p_popup_item->pp_children[0] );
             }
             else
             {
-                playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
-                                  i_current_view, p_popup_item, NULL );
+                playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, 1242,
+                                  p_popup_item, NULL );
             }
         }
         else
@@ -1540,8 +1540,7 @@ void Playlist::OnPopupPlay( wxCommandEvent& event )
             if( event.GetId() == PopupPlay_Event )
             {
                 playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
-                                  i_current_view, p_popup_parent,
-                                  p_popup_item );
+                                  1242, p_popup_parent, p_popup_item );
             }
         }
     }
@@ -1563,7 +1562,7 @@ void Playlist::Preparse()
     {
         if( p_popup_item->i_children == -1 )
         {
-            playlist_PreparseEnqueue( p_playlist, &p_popup_item->input );
+            playlist_PreparseEnqueue( p_playlist, p_popup_item->p_input );
         }
         else
         {
@@ -1573,8 +1572,8 @@ void Playlist::Preparse()
             {
                 wxMenuEvent dummy;
                 i_wx_popup_item = FindItem( treectrl->GetRootItem(),
-                                         p_parent->pp_children[i]->input.i_id );
-                i_popup_item = p_parent->pp_children[i]->input.i_id;
+                                         p_parent->pp_children[i]->i_id );
+                i_popup_item = p_parent->pp_children[i]->i_id;
                 Preparse();
             }
         }
@@ -1602,7 +1601,7 @@ void Playlist::OnPopupSort( wxCommandEvent& event )
                                     SORT_TITLE_NODES_FIRST, ORDER_NORMAL );
 
         treectrl->DeleteChildren( i_wx_popup_item );
-        i_saved_id = -1;
+        i_saved_id = -1; i_saved_input_id = -1;
         UpdateNodeChildren( p_item, i_wx_popup_item );
 
     }
@@ -1642,7 +1641,7 @@ void Playlist::OnPopupAddNode( wxCommandEvent& event )
 
     p_item = playlist_ItemGetById( p_playlist, p_wxitem->i_id );
 
-    playlist_NodeCreate( p_playlist, i_current_view, psz_name, p_item );
+    playlist_NodeCreate( p_playlist, psz_name, p_item );
 
     UnlockPlaylist( p_intf->p_sys, p_playlist );
     Rebuild( VLC_TRUE );
@@ -1650,6 +1649,17 @@ void Playlist::OnPopupAddNode( wxCommandEvent& event )
     wxLocaleFree( psz_name );
 }
 
+void Playlist::OnSourceSelected( wxListEvent &event )
+{
+   int i_id = event.GetData();
+
+   if( p_current_treeroot && i_id != p_current_treeroot->i_id )
+   {
+       playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id );
+       if( p_item ) p_current_treeroot = p_item;
+       Rebuild( VLC_TRUE );
+   }
+}
 
 /*****************************************************************************
  * Custom events management
@@ -1659,12 +1669,16 @@ void Playlist::OnPlaylistEvent( wxCommandEvent& event )
     switch( event.GetId() )
     {
         case UpdateItem_Event:
+            fprintf( stderr,"Update input item id %i\n", event.GetInt() );
             UpdateItem( event.GetInt() );
             break;
         case AppendItem_Event:
+            fprintf( stderr,"Append item id %i\n",
+                         ((playlist_add_t*)event.GetClientData())->i_item );
             AppendItem( event );
             break;
         case RemoveItem_Event:
+            fprintf( stderr,"Remove item id %i\n", event.GetInt() );
             RemoveItem( event.GetInt() );
             break;
     }
index 0c5461b67951f72470ca0fbf0ca39ad18451b878..ce2cd0fe6b58499a744050c93da14ed701e28006 100644 (file)
@@ -90,8 +90,6 @@ private:
     wxButton *search_button;
     wxTreeItemId search_current;
 
-    void OnEnDis( wxCommandEvent& event );
-
     /* Sort */
     int i_sort_mode;
     void OnSort( wxCommandEvent& event );
@@ -136,6 +134,9 @@ private:
     void OnPopupEna( wxCommandEvent& event );
     void OnPopupInfo( wxCommandEvent& event );
     void OnPopupAddNode( wxCommandEvent& event );
+
+    /* List */
+    void OnSourceSelected( wxListEvent &event );
 protected:
     void Rebuild( vlc_bool_t );
 private:
@@ -151,11 +152,15 @@ private:
     /* Search (internal) */
     int CountItems( wxTreeItemId);
     wxTreeItemId FindItem( wxTreeItemId, int );
+    wxTreeItemId FindItemByInput( wxTreeItemId, int );
+    wxTreeItemId FindItemInner( wxTreeItemId, int , bool );
     wxTreeItemId FindItemByName( wxTreeItemId, wxString,
                                  wxTreeItemId, vlc_bool_t *);
 
     wxTreeItemId saved_tree_item;
+    wxTreeItemId saved_input_tree_item;
     int i_saved_id;
+    int i_saved_input_id;
 
 protected:
     playlist_t *p_playlist;
@@ -179,7 +184,10 @@ private:
 protected:
     intf_thread_t *p_intf;
     wxTreeCtrl *treectrl;
+    wxListView *source_sel;
     int i_current_view;
+    playlist_item_t *p_current_treeroot;
+    playlist_item_t *p_current_viewroot;
 
 friend class PlaylistFileDropTarget;
 };
index 666d43250b5632fb371066c9679b9a1a9792b4f5..800915a583cb46678b43b72b76d58a91f7a47f21 100644 (file)
@@ -591,6 +591,7 @@ wizInputPage::wizInputPage( wxWizard *parent, wxWizardPage *prev, intf_thread_t
             listview->InsertColumn( 1, wxU(_("URI")) );
             listview->SetColumnWidth( 0, 250 );
             listview->SetColumnWidth( 1, 100 );
+#if 0
             for( int i=0 ; i < p_playlist->i_size ; i++ )
             {
                 wxString filename = wxL2U( p_playlist->pp_items[i]->input.
@@ -602,6 +603,7 @@ wizInputPage::wizInputPage( wxWizard *parent, wxWizardPage *prev, intf_thread_t
                                   (long)p_playlist->pp_items[i]->input.i_id );
             }
             listview->Select( p_playlist->i_index , TRUE);
+#endif
             mainSizer->Add( listview, 1, wxALL|wxEXPAND, 5 );
 
             listview->Hide();
@@ -727,7 +729,7 @@ void wizInputPage::OnWizardPageChanging(wxWizardEvent& event)
         i = listview->GetNextItem( i , wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
         if( i != -1 )
         {
-            long data = listview->GetItemData( i );            
+            long data = listview->GetItemData( i );
             playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_intf,
                                       VLC_OBJECT_PLAYLIST, FIND_ANYWHERE);
             if( p_playlist )
@@ -736,7 +738,7 @@ void wizInputPage::OnWizardPageChanging(wxWizardEvent& event)
                                                    p_playlist, (int)data );
                 if( p_item )
                 {
-                    p_parent->SetMrl( (const char*)p_item->input.psz_uri );
+                    p_parent->SetMrl( (const char*)p_item->p_input->psz_uri );
                 }
                 else
                     event.Veto();
@@ -1631,27 +1633,28 @@ void WizardDialog::Run()
                             VLC_OBJECT_PLAYLIST, FIND_ANYWHERE);
         if( p_playlist )
         {
-            playlist_item_t *p_item = playlist_ItemNew( p_playlist, mrl,
-                                                        ITEM_NAME );
-            playlist_ItemAddOption( p_item, psz_opt);
+            input_item_t *p_input = input_ItemNew( p_playlist, mrl,
+                                                   ITEM_NAME );
+            vlc_input_item_AddOption( p_input, psz_opt );
             if( i_from != 0)
             {
                 char psz_from[20];
                 snprintf( psz_from, 20, "start-time=%i", i_from);
-                playlist_ItemAddOption( p_item, psz_from);
+                vlc_input_item_AddOption( p_input, psz_from );
             }
             if( i_to != 0)
             {
                 char psz_to[20];
                 snprintf( psz_to, 20, "stop-time=%i", i_to);
-                playlist_ItemAddOption( p_item, psz_to);
+                vlc_input_item_AddOption( p_input, psz_to );
             }
 
             char psz_ttl[20];
             snprintf( psz_ttl, 20, "ttl=%i",i_ttl );
-            playlist_ItemAddOption( p_item, psz_ttl );
+            vlc_input_item_AddOption( p_input, psz_ttl );
 
-            playlist_AddItem( p_playlist, p_item, PLAYLIST_GO, PLAYLIST_END );
+            playlist_PlaylistAddInput( p_playlist, p_input,
+                                       PLAYLIST_GO, PLAYLIST_END );
             vlc_object_release(p_playlist);
         }
         else
index 210d90cd9a85351d72fc76b2cb18cf021cac8318..ed3021002e26b0a9ca50fbf4033e06ba7ea3042b 100644 (file)
@@ -144,8 +144,9 @@ void InputManager::UpdateInput()
 
 void InputManager::UpdateNowPlaying()
 {
-    char *psz_now_playing = vlc_input_item_GetInfo( p_input->input.p_item,
-                _(VLC_META_INFO_CAT), _(VLC_META_NOW_PLAYING) );
+    char *psz_now_playing = p_input->input.p_item->p_meta->psz_nowplaying ?
+                    strdup( p_input->input.p_item->p_meta->psz_nowplaying ):
+                    strdup( "" );
     if( psz_now_playing && *psz_now_playing )
     {
         p_main_intf->statusbar->SetStatusText(
index 52f8666b582b019b34f6e148a70e9741263db110..fe8fb736ff46ced9844b6de4998cd2857dc960cd 100644 (file)
@@ -1287,7 +1287,7 @@ bool DragAndDrop::OnDropFiles( wxCoord, wxCoord,
     {
         char *psz_utf8 = wxDnDFromLocale( filenames[i] );
 
-        playlist_Add( p_playlist, psz_utf8, psz_utf8,
+        playlist_PlaylistAdd( p_playlist, psz_utf8, psz_utf8,
                       PLAYLIST_APPEND | ((i | b_enqueue) ? 0 : PLAYLIST_GO),
                       PLAYLIST_END );
 
index c7b1ea0264edf10d334e591bd0321f04941d4cdb..6c1191ca0b53f5028720f30f1d9b906f56d564ef 100644 (file)
@@ -87,7 +87,7 @@ END_EVENT_TABLE()
 class PlaylistItem : public wxTreeItemData
 {
 public:
-    PlaylistItem( playlist_item_t *p_item ) : i_id(p_item->input.i_id) {}
+    PlaylistItem( playlist_item_t *p_item ) : i_id(p_item->p_input->i_id) {}
     int i_id;
 };
 
@@ -220,9 +220,9 @@ static int PlaylistNext( vlc_object_t *p_this, const char *psz_variable,
 void PlaylistManager::CreateNode( playlist_item_t *p_node, wxTreeItemId parent)
 {
     wxTreeItemId node =
-        treectrl->AppendItem( parent, wxL2U( p_node->input.psz_name ), -1, -1,
+        treectrl->AppendItem( parent, wxL2U( p_node->p_input->psz_name ), -1, -1,
                               new PlaylistItem( p_node ) );
-    treectrl->SetItemImage( node, p_node->input.i_type );
+    treectrl->SetItemImage( node, p_node->p_input->i_type );
 
     UpdateNodeChildren( p_node, node );
 }
@@ -246,7 +246,7 @@ void PlaylistManager::UpdateNode( playlist_item_t *p_node, wxTreeItemId node )
         }
     }
 
-    treectrl->SetItemImage( node, p_node->input.i_type );
+    treectrl->SetItemImage( node, p_node->p_input->i_type );
 
 }
 
@@ -260,7 +260,7 @@ void PlaylistManager::UpdateNodeChildren( playlist_item_t *p_node,
         {
             wxTreeItemId item =
                 treectrl->AppendItem( node,
-                    wxL2U( p_node->pp_children[i]->input.psz_name ), -1,-1,
+                    wxL2U( p_node->pp_children[i]->p_input->psz_name ), -1,-1,
                            new PlaylistItem( p_node->pp_children[i]) );
 
             UpdateTreeItem( item );
@@ -290,9 +290,9 @@ void PlaylistManager::UpdateTreeItem( wxTreeItemId item )
 
     wxString msg;
     wxString duration = wxU( "" );
-    char *psz_author =
-        vlc_input_item_GetInfo( &p_item->input,
-                                _(VLC_META_INFO_CAT), _(VLC_META_ARTIST) );
+    char *psz_author = p_item->p_input->p_meta->psz_artist ? 
+                        strdup( p_item->p_input->p_meta->psz_artist ) :
+                        strdup( "" );
     if( !psz_author )
     {
         UnlockPlaylist( p_intf->p_sys, p_playlist );
@@ -300,7 +300,7 @@ void PlaylistManager::UpdateTreeItem( wxTreeItemId item )
     }
 
     char psz_duration[MSTRTIME_MAX_SIZE];
-    mtime_t dur = p_item->input.i_duration;
+    mtime_t dur = p_item->p_input->i_duration;
 
     if( dur != -1 )
     {
@@ -309,18 +309,18 @@ void PlaylistManager::UpdateTreeItem( wxTreeItemId item )
                          wxU( " )" ) );
     }
 
-    if( !strcmp( psz_author, "" ) || p_item->input.b_fixed_name == VLC_TRUE )
+    if( !strcmp( psz_author, "" ) || p_item->p_input->b_fixed_name == VLC_TRUE )
     {
-        msg = wxString( wxU( p_item->input.psz_name ) ) + duration;
+        msg = wxString( wxU( p_item->p_input->psz_name ) ) + duration;
     }
     else
     {
         msg = wxString(wxU( psz_author )) + wxT(" - ") +
-                    wxString(wxU(p_item->input.psz_name)) + duration;
+                    wxString(wxU(p_item->p_input->psz_name)) + duration;
     }
     free( psz_author );
     treectrl->SetItemText( item , msg );
-    treectrl->SetItemImage( item, p_item->input.i_type );
+    treectrl->SetItemImage( item, p_item->p_input->i_type );
 
     if( p_playlist->status.p_item == p_item )
     {
@@ -360,9 +360,9 @@ void PlaylistManager::AppendItem( wxCommandEvent& event )
     item = FindItem( treectrl->GetRootItem(), p_add->i_item );
     if( item.IsOk() ) goto update;
 
-    item = treectrl->AppendItem( node, wxL2U( p_item->input.psz_name ), -1,-1,
+    item = treectrl->AppendItem( node, wxL2U( p_item->p_input->psz_name ), -1,-1,
                                  new PlaylistItem( p_item ) );
-    treectrl->SetItemImage( item, p_item->input.i_type );
+    treectrl->SetItemImage( item, p_item->p_input->i_type );
 
     if( item.IsOk() && p_item->i_children == -1 ) UpdateTreeItem( item );
 
@@ -415,19 +415,15 @@ void PlaylistManager::Update()
  **********************************************************************/
 void PlaylistManager::Rebuild( vlc_bool_t b_root )
 {
-    playlist_view_t *p_view;
-
     i_items_to_append = 0;
     i_cached_item_id = -1;
 
-    p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY );
-
     treectrl->DeleteAllItems();
     treectrl->AddRoot( wxU(_("root" )), -1, -1,
-                       new PlaylistItem( p_view->p_root ) );
+                       new PlaylistItem( p_playlist->p_root_category ) );
 
     wxTreeItemId root = treectrl->GetRootItem();
-    UpdateNode( p_view->p_root, root );
+    UpdateNode( p_playlist->p_root_category, root );
 }
 
 /**********************************************************************
@@ -506,9 +502,7 @@ void PlaylistManager::OnActivateItem( wxTreeEvent& event )
         p_node = p_item;
         p_item = NULL;
     }
-
-    playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, VIEW_CATEGORY,
-                      p_node, p_item );
+    playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, p_node, p_item );
     UnlockPlaylist( p_intf->p_sys, p_playlist );
 }
 
index db1d450a4c5b3f7ff84d4546802cba62acd6d3a9..162175d0a44ef4e92216fb8ebc0831725ad5abdf 100644 (file)
@@ -162,12 +162,12 @@ static int ItemChange( vlc_object_t *p_this, const char *psz_var,
     }
 
     /* Playing something ... */
-    psz_artist = vlc_input_item_GetInfo( p_input->input.p_item,
-                                         _("Meta-information"),
-                                         _(VLC_META_ARTIST) );
-    psz_album = vlc_input_item_GetInfo( p_input->input.p_item,
-                                         _("Meta-information"),
-                                         _("Album/movie/show title" ) );
+    psz_artist = p_input->input.p_item->p_meta->psz_artist ?
+                  strdup( p_input->input.p_item->p_meta->psz_artist ) :
+                  strdup( "" );
+    psz_album = p_input->input.p_item->p_meta->psz_album ?
+                  strdup( p_input->input.p_item->p_meta->psz_album ) :
+                  strdup( "" );
     psz_title = strdup( p_input->input.p_item->psz_name );
     if( psz_title == NULL ) psz_title = strdup( N_("(no title)") );
     if( psz_artist == NULL ) psz_artist = strdup( N_("(no artist)") );
index 6150c7f901387dcba94c5893f7fb25e8d1b37f0b..9d4423964b4cf0533e41b3ff4f74fbd71e58a8e5 100644 (file)
@@ -192,12 +192,12 @@ static int ItemChange( vlc_object_t *p_this, const char *psz_var,
     }
 
     /* Playing something ... */
-    psz_artist = vlc_input_item_GetInfo( p_input->input.p_item,
-                                         _(VLC_META_INFO_CAT),
-                                         _(VLC_META_ARTIST) );
-    psz_album = vlc_input_item_GetInfo( p_input->input.p_item,
-                                         _(VLC_META_INFO_CAT),
-                                         _(VLC_META_COLLECTION) );
+    psz_artist = p_input->input.p_item->p_meta->psz_artist ?
+                  strdup( p_input->input.p_item->p_meta->psz_artist ) :
+                  strdup( "" );
+    psz_album = p_input->input.p_item->p_meta->psz_album ?
+                  strdup( p_input->input.p_item->p_meta->psz_album ) :
+                  strdup( "" );
     psz_title = strdup( p_input->input.p_item->psz_name );
     if( psz_title == NULL ) psz_title = strdup( N_("(no title)") );
     if( psz_artist == NULL ) psz_artist = strdup( N_("(no artist)") );
index bcf37e8d1950896e5e7a13c8b269b140c10645b2..01f4dcfe327c6b7090fdd20ef27826539ff941ce 100644 (file)
@@ -52,51 +52,50 @@ int Export_M3U( vlc_object_t *p_this )
     fprintf( p_export->p_file, "#EXTM3U\n" );
 
     /* Go through the playlist and add items */
-    for( i = 0; i< p_playlist->i_size ; i++)
+    for( i = 0; i< p_export->p_root->i_children ; i++)
     {
-        if( (p_playlist->pp_items[i]->i_flags & PLAYLIST_SAVE_FLAG) == 0 )
-        {
+        playlist_item_t *p_current = p_export->p_root->pp_children[i];
+        if( p_current->i_flags & PLAYLIST_SAVE_FLAG )
             continue;
-        }
 
         /* General info */
-        if( p_playlist->pp_items[i]->input.psz_name &&
-             strcmp( p_playlist->pp_items[i]->input.psz_name,
-                    p_playlist->pp_items[i]->input.psz_uri ) )
+        if( p_current->p_input->psz_name &&
+             strcmp( p_current->p_input->psz_uri,
+                     p_current->p_input->psz_name ) )
         {
-            char *psz_artist =
-                vlc_input_item_GetInfo( &p_playlist->pp_items[i]->input,
-                                        _(VLC_META_INFO_CAT), _(VLC_META_ARTIST) );
+            char *psz_artist = p_current->p_input->p_meta->psz_artist ?
+                               strdup( p_current->p_input->p_meta->psz_artist ):
+                               strdup( "" );
             if( psz_artist && *psz_artist )
             {
                 /* write EXTINF with artist */
                 fprintf( p_export->p_file, "#EXTINF:%i,%s - %s\n",
-                         (int)(p_playlist->pp_items[i]->input.i_duration/1000000),
-                         psz_artist,
-                         p_playlist->pp_items[i]->input.psz_name );
+                          (int)( p_current->p_input->i_duration/1000000 ),
+                          psz_artist,
+                          p_current->p_input->psz_name);
             }
             else
             {
                 /* write EXTINF without artist */
                 fprintf( p_export->p_file, "#EXTINF:%i,%s\n",
-                       (int)(p_playlist->pp_items[i]->input.i_duration/1000000),
-                         p_playlist->pp_items[i]->input.psz_name );
+                         (int)( p_current->p_input->i_duration/1000000 ),
+                          p_current->p_input->psz_name);
             }
             if( psz_artist )
                 free( psz_artist );
         }
 
         /* VLC specific options */
-        for( j = 0; j < p_playlist->pp_items[i]->input.i_options; j++ )
+        for( j = 0; j < p_current->p_input->i_options; j++ )
         {
             fprintf( p_export->p_file, "#EXTVLCOPT:%s\n",
-                     p_playlist->pp_items[i]->input.ppsz_options[j][0] == ':' ?
-                     p_playlist->pp_items[i]->input.ppsz_options[j] + 1 :
-                     p_playlist->pp_items[i]->input.ppsz_options[j] );
+                     p_current->p_input->ppsz_options[j][0] == ':' ?
+                     p_current->p_input->ppsz_options[j] + 1 :
+                     p_current->p_input->ppsz_options[j] );
         }
 
         fprintf( p_export->p_file, "%s\n",
-                 p_playlist->pp_items[i]->input.psz_uri );
+                 p_current->p_input->psz_uri );
     }
     return VLC_SUCCESS;
 }
index 5fd3793901b879343f160fc39bc4e5072e70c797..ea79b199ad80b1acacfcce17a94d1f1e040ac906 100644 (file)
@@ -53,11 +53,12 @@ int Export_Old( vlc_object_t *p_this )
     /* Write header */
     fprintf( p_export->p_file , PLAYLIST_FILE_HEADER "\n" );
 
-    for ( i = 0 ; i < p_playlist->i_size ; i++ )
+    for ( i = 0 ; i < p_export->p_root->i_children ; i++ )
     {
         char *psz_uri;
 
-        psz_uri = ToLocale( p_playlist->pp_items[i]->input.psz_uri );
+        psz_uri =
+             ToLocale( p_export->p_root->pp_children[i]->p_input->psz_name );
         fprintf( p_export->p_file , "%s\n" , psz_uri );
         LocaleFree( psz_uri );
     }
index 59ab4b93e114ccc6de5ecb646c016ecc5f627bd6..9366518237c1ce5e951e99f5623d2512a64f444d 100644 (file)
@@ -55,56 +55,51 @@ int E_(xspf_export_playlist)( vlc_object_t *p_this )
 #define p_item p_playlist->status.p_item
     if ( p_item )
     {
-        for (i = 0; i < p_item->i_parents; i++ )
+        if ( p_item->p_parent->p_input->i_type == ITEM_TYPE_PLAYLIST )
         {
-            if ( p_item->pp_parents[i]->p_parent->input.i_type
-                 == ITEM_TYPE_PLAYLIST )
-            {
-                /* set the current node and its children */
-                p_node   = p_item->pp_parents[i]->p_parent;
-                pp_items = p_node->pp_children;
-                i_size   = p_node->i_children;
+            /* set the current node and its children */
+            p_node   = p_item->p_parent;
+            pp_items = p_node->pp_children;
+            i_size   = p_node->i_children;
 #undef p_item
 
-                /* save name of the playlist node */
-                psz_temp = convert_xml_special_chars( p_node->input.psz_name );
-                if ( *psz_temp )
-                    fprintf(  p_export->p_file, "\t<title>%s</title>\n",
-                              psz_temp );
-                free( psz_temp );
-
-                /* save the creator of the playlist node */
-                psz = vlc_input_item_GetInfo( &p_node->input,
-                                              _(VLC_META_INFO_CAT),
-                                              _(VLC_META_ARTIST) );
-                if ( psz && !*psz )
-                {
-                    free ( psz );
-                    psz = NULL;
-                }
-
-                if ( !psz )
-                    psz = vlc_input_item_GetInfo( &p_node->input,
-                                                  _(VLC_META_INFO_CAT),
-                                                  _(VLC_META_AUTHOR) );
-
-                psz_temp = convert_xml_special_chars( psz );
-
-                if ( psz ) free( psz );
-                if ( *psz_temp )
-                    fprintf(  p_export->p_file, "\t<creator>%s</creator>\n",
-                              psz_temp );
-                free( psz_temp );
-
-                /* save location of the playlist node */
-                psz = assertUTF8URI( p_export->psz_filename );
-                if ( psz && *psz )
-                {
-                    fprintf( p_export->p_file, "\t<location>%s</location>\n",
-                             psz );
-                    free( psz );
-                }
-                break;
+            /* save name of the playlist node */
+            psz_temp = convert_xml_special_chars( p_node->p_input->psz_name );
+            if ( *psz_temp )
+                fprintf(  p_export->p_file, "\t<title>%s</title>\n",
+                          psz_temp );
+            free( psz_temp );
+
+            /* save the creator of the playlist node */
+            psz = p_node->p_input->p_meta->psz_artist ? 
+                        strdup( p_node->p_input->p_meta->psz_artist ):
+                        strdup( "" );
+            if ( psz && !*psz )
+            {
+                free ( psz );
+                psz = NULL;
+            }
+
+            if ( !psz )
+               psz = p_node->p_input->p_meta->psz_author ? 
+                            strdup( p_node->p_input->p_meta->psz_author ):
+                            strdup( "" );
+
+            psz_temp = convert_xml_special_chars( psz );
+
+            if ( psz ) free( psz );
+            if ( *psz_temp )
+                fprintf(  p_export->p_file, "\t<creator>%s</creator>\n",
+                          psz_temp );
+            free( psz_temp );
+
+            /* save location of the playlist node */
+            psz = assertUTF8URI( p_export->psz_filename );
+            if ( psz && *psz )
+            {
+                fprintf( p_export->p_file, "\t<location>%s</location>\n",
+                         psz );
+                free( psz );
             }
         }
     }
@@ -161,37 +156,37 @@ static void xspf_export_item( playlist_item_t *p_item, FILE *p_file )
     fprintf( p_file, "\t\t<track>\n" );
 
     /* -> the location */
-    if ( p_item->input.psz_uri && *p_item->input.psz_uri )
+    if ( p_item->p_input->psz_uri && *p_item->p_input->psz_uri )
     {
-        psz = assertUTF8URI( p_item->input.psz_uri );
+        psz = assertUTF8URI( p_item->p_input->psz_uri );
         fprintf( p_file, "\t\t\t<location>%s</location>\n", psz );
         free( psz );
     }
 
     /* -> the name/title (only if different from uri)*/
-    if ( p_item->input.psz_name &&
-         p_item->input.psz_uri &&
-         strcmp( p_item->input.psz_uri, p_item->input.psz_name ) )
+    if ( p_item->p_input->psz_name &&
+         p_item->p_input->psz_uri &&
+         strcmp( p_item->p_input->psz_uri, p_item->p_input->psz_name ) )
     {
-        psz_temp = convert_xml_special_chars( p_item->input.psz_name );
+        psz_temp = convert_xml_special_chars( p_item->p_input->psz_name );
         if ( *psz_temp )
             fprintf( p_file, "\t\t\t<title>%s</title>\n", psz_temp );
         free( psz_temp );
     }
 
     /* -> the artist/creator */
-    psz = vlc_input_item_GetInfo( &p_item->input,
-                                  _(VLC_META_INFO_CAT),
-                                  _(VLC_META_ARTIST) );
+    psz = p_item->p_input->p_meta->psz_artist ? 
+                        strdup( p_item->p_input->p_meta->psz_artist ):
+                        strdup( "" );
     if ( psz && !*psz )
     {
         free ( psz );
         psz = NULL;
     }
     if ( !psz )
-        psz = vlc_input_item_GetInfo( &p_item->input,
-                                      _(VLC_META_INFO_CAT),
-                                      _(VLC_META_AUTHOR) );
+        psz = p_item->p_input->p_meta->psz_author ? 
+                        strdup( p_item->p_input->p_meta->psz_author ):
+                        strdup( "" );
     psz_temp = convert_xml_special_chars( psz );
     if ( psz ) free( psz );
     if ( *psz_temp )
@@ -199,9 +194,9 @@ static void xspf_export_item( playlist_item_t *p_item, FILE *p_file )
     free( psz_temp );
 
     /* -> the album */
-    psz = vlc_input_item_GetInfo( &p_item->input,
-                                  _(VLC_META_INFO_CAT),
-                                  _(VLC_META_COLLECTION) );
+    psz = p_item->p_input->p_meta->psz_album ?
+                        strdup( p_item->p_input->p_meta->psz_album ):
+                        strdup( "" );
     psz_temp = convert_xml_special_chars( psz );
     if ( psz ) free( psz );
     if ( *psz_temp )
@@ -209,9 +204,9 @@ static void xspf_export_item( playlist_item_t *p_item, FILE *p_file )
     free( psz_temp );
 
     /* -> the track number */
-    psz = vlc_input_item_GetInfo( &p_item->input,
-                                  _(VLC_META_INFO_CAT),
-                                  _(VLC_META_SEQ_NUM) );
+    psz = p_item->p_input->p_meta->psz_tracknum ?
+                        strdup( p_item->p_input->p_meta->psz_tracknum ):
+                        strdup( "" );
     if ( psz )
     {
         if ( *psz )
@@ -220,10 +215,10 @@ static void xspf_export_item( playlist_item_t *p_item, FILE *p_file )
     }
 
     /* -> the duration */
-    if ( p_item->input.i_duration > 0 )
+    if ( p_item->p_input->i_duration > 0 )
     {
         fprintf( p_file, "\t\t\t<duration>%ld</duration>\n",
-                 (long)(p_item->input.i_duration / 1000) );
+                 (long)(p_item->p_input->i_duration / 1000) );
     }
 
     fprintf( p_file, "\t\t</track>\n" );
index 59a436716f6f3c96aad95e1716efffedd57a5d6e..6120257fd3eddc34c3caa0da756310688a5f3985 100644 (file)
@@ -1031,38 +1031,28 @@ static bo_t *GetUdtaTag( sout_mux_t *p_mux )
     /* Misc atoms */
     if( p_meta )
     {
-        int i;
-        for( i = 0; i < p_meta->i_meta; i++ )
-        {
-            bo_t *box = NULL;
-
-            if( !strcmp( p_meta->name[i], VLC_META_TITLE ) )
-                box = box_new( "\251nam" );
-            else if( !strcmp( p_meta->name[i], VLC_META_AUTHOR ) )
-                box = box_new( "\251aut" );
-            else if( !strcmp( p_meta->name[i], VLC_META_ARTIST ) )
-                box = box_new( "\251ART" );
-            else if( !strcmp( p_meta->name[i], VLC_META_GENRE ) )
-                box = box_new( "\251gen" );
-            else if( !strcmp( p_meta->name[i], VLC_META_COPYRIGHT ) )
-                box = box_new( "\251cpy" );
-            else if( !strcmp( p_meta->name[i], VLC_META_DESCRIPTION ) )
-                box = box_new( "\251des" );
-            else if( !strcmp( p_meta->name[i], VLC_META_DATE ) )
-                box = box_new( "\251day" );
-            else if( !strcmp( p_meta->name[i], VLC_META_URL ) )
-                box = box_new( "\251url" );
-
-            if( box )
-            {
-                bo_add_16be( box, strlen( p_meta->value[i] ) );
-                bo_add_16be( box, 0 );
-                bo_add_mem( box, strlen( p_meta->value[i] ),
-                            (uint8_t*)(p_meta->value[i]) );
-                box_fix( box );
-                box_gather( udta, box );
-            }
-        }
+#define ADD_META_BOX( type, box_string ) { \
+        bo_t *box = NULL;  \
+        if( p_meta->psz_##type ) box = box_new( "\251" box_string ); \
+        if( box ) \
+        { \
+            bo_add_16be( box, strlen( p_meta->psz_##type ) ); \
+            bo_add_16be( box, 0 ); \
+            bo_add_mem( box, strlen( p_meta->psz_##type ), \
+                        (uint8_t*)(p_meta->psz_##type ) ); \
+            box_fix( box ); \
+            box_gather( udta, box ); \
+        } }
+
+        ADD_META_BOX( title, "nam" );
+        ADD_META_BOX( author, "aut" );
+        ADD_META_BOX( artist, "ART" );
+        ADD_META_BOX( genre, "gen" );
+        ADD_META_BOX( copyright, "cpy" );
+        ADD_META_BOX( description, "des" );
+        ADD_META_BOX( date, "day" );
+        ADD_META_BOX( url, "url" );
+#undef ADD_META_BOX
     }
 
     box_fix( udta );
index 9790fb85d742994b7f5d3d8c26f610d37250fa32..5051b0d8f1e012c9a5587c50d52098b4ddd6b96a 100644 (file)
@@ -181,8 +181,10 @@ static int Open( vlc_object_t *p_this )
         msg_Warn( p_sd, "unable to find playlist, cancelling DAAP" );
         return VLC_EGENERIC;
     }
+    msg_Err( p_sd, "DAAP IS BROKEN !! Fix it if you want it !" );
+    return VLC_EGENERIC;
 
-    p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY );
+#if 0
     p_sys->p_node = playlist_NodeCreate( p_playlist, VIEW_CATEGORY,
                                          _("DAAP shares"), p_view->p_root );
     p_sys->p_node->i_flags |= PLAYLIST_RO_FLAG;
@@ -192,10 +194,12 @@ static int Open( vlc_object_t *p_this )
     vlc_object_release( p_playlist );
 
     return VLC_SUCCESS;
+#endif
 }
 
 static int OpenAccess( vlc_object_t *p_this )
 {
+#if 0
     access_t     *p_access = (access_t*)p_this;
     access_sys_t *p_sys;
     vlc_value_t val;
@@ -294,7 +298,7 @@ static int OpenAccess( vlc_object_t *p_this )
 
     if( i_ret != 0 )
         return VLC_EGENERIC;
-
+#endif
     return VLC_SUCCESS;
 }
 
@@ -303,6 +307,7 @@ static int OpenAccess( vlc_object_t *p_this )
  *****************************************************************************/
 static void Close( vlc_object_t *p_this )
 {
+#if 0
     services_discovery_t *p_sd = ( services_discovery_t* )p_this;
     services_discovery_sys_t    *p_sys  = p_sd->p_sys;
 
@@ -326,6 +331,7 @@ static void Close( vlc_object_t *p_this )
     }
 
     free( p_sys );
+#endif
 }
 
 static void CloseAccess( vlc_object_t *p_this )
@@ -522,6 +528,7 @@ static int EnumerateCallback( DAAP_SClient *p_client,
 
 static void ProcessHost( services_discovery_t *p_sd, dhost_t *p_host )
 {
+#if 0
     int i_dbsize, i_db, i, i_songsize, i_ret;
     int i_size = DAAP_ClientHost_GetSharename( p_host->p_host, NULL, 0 );
 
@@ -617,6 +624,7 @@ static void ProcessHost( services_discovery_t *p_sd, dhost_t *p_host )
     DAAP_ClientHost_AsyncWaitUpdate( p_host->p_host );
 
     vlc_object_release( p_playlist );
+#endif
 }
 
 static void FreeHost( services_discovery_t *p_sd, dhost_t *p_host )
index b336c0cebd02d13d1df78996b6f3620a4ed8424d..a344a7adb9e25e6681f68f3d36fe58a333fa69d0 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * sap.c :  SAP interface module
+ * hal.c :  HAL interface module
  *****************************************************************************
  * Copyright (C) 2004 the VideoLAN team
  * $Id$
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
-/*****************************************************************************
- * Includes
- *****************************************************************************/
-#include <stdlib.h>                                      /* malloc(), free() */
-
 #include <vlc/vlc.h>
 #include <vlc/intf.h>
 
 
 #include <hal/libhal.h>
 
-/************************************************************************
- * Macros and definitions
- ************************************************************************/
-
 #define MAX_LINE_LENGTH 256
 
-
 /*****************************************************************************
- * Module descriptor
+ * Local prototypes
  *****************************************************************************/
+struct services_discovery_sys_t
+{
+    LibHalContext *p_ctx;
+    playlist_item_t *p_node_cat;
+    playlist_item_t *p_node_one;
+};
+static void AddItem( services_discovery_t *p_sd, input_item_t * p_input );
+static void Run    ( services_discovery_t *p_intf );
 
-/* Callbacks */
-    static int  Open ( vlc_object_t * );
-    static void Close( vlc_object_t * );
+static int  Open ( vlc_object_t * );
+static void Close( vlc_object_t * );
 
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
 vlc_module_begin();
     set_description( _("HAL devices detection") );
     set_category( CAT_PLAYLIST );
@@ -70,26 +70,6 @@ vlc_module_begin();
 vlc_module_end();
 
 
-/*****************************************************************************
- * Local structures
- *****************************************************************************/
-
-struct services_discovery_sys_t
-{
-    LibHalContext *p_ctx;
-
-    /* playlist node */
-    playlist_item_t *p_node;
-
-};
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-
-/* Main functions */
-    static void Run    ( services_discovery_t *p_intf );
-
 /*****************************************************************************
  * Open: initialize and create stuff
  *****************************************************************************/
@@ -101,7 +81,6 @@ static int Open( vlc_object_t *p_this )
 
     vlc_value_t         val;
     playlist_t          *p_playlist;
-    playlist_view_t     *p_view;
 
     DBusError           dbus_error;
     DBusConnection      *p_connection;
@@ -148,11 +127,13 @@ static int Open( vlc_object_t *p_this )
         return VLC_EGENERIC;
     }
 
-    p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY );
-    p_sys->p_node = playlist_NodeCreate( p_playlist, VIEW_CATEGORY,
-                                         _("Devices"), p_view->p_root );
+    p_sys->p_node_cat = playlist_NodeCreate( p_playlist, _("Devices"),
+                                         p_playlist->p_root_category );
+    p_sys->p_node_cat->i_flags |= PLAYLIST_RO_FLAG;
+    p_sys->p_node_one = playlist_NodeCreate( p_playlist, _("Devices"),
+                                         p_playlist->p_root_onelevel );
+    p_sys->p_node_one->i_flags |= PLAYLIST_RO_FLAG;
 
-    p_sys->p_node->i_flags |= PLAYLIST_RO_FLAG;
     val.b_bool = VLC_TRUE;
     var_Set( p_playlist, "intf-change", val );
 
@@ -172,7 +153,8 @@ static void Close( vlc_object_t *p_this )
                                  VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
     if( p_playlist )
     {
-        playlist_NodeDelete( p_playlist, p_sys->p_node, VLC_TRUE, VLC_TRUE );
+        playlist_NodeDelete( p_playlist, p_sys->p_node_cat, VLC_TRUE,VLC_TRUE );
+        playlist_NodeDelete( p_playlist, p_sys->p_node_one, VLC_TRUE,VLC_TRUE );
         vlc_object_release( p_playlist );
     }
     free( p_sys );
@@ -183,9 +165,7 @@ static void AddDvd( services_discovery_t *p_sd, char *psz_device )
     char *psz_name;
     char *psz_uri;
     char *psz_blockdevice;
-    services_discovery_sys_t    *p_sys  = p_sd->p_sys;
-    playlist_t          *p_playlist;
-    playlist_item_t     *p_item;
+    input_item_t        *p_input;
 #ifdef HAVE_HAL_1
     psz_name = libhal_device_get_property_string( p_sd->p_sys->p_ctx,
                                         psz_device, "volume.label", NULL );
@@ -199,29 +179,36 @@ static void AddDvd( services_discovery_t *p_sd, char *psz_device )
 #endif
     asprintf( &psz_uri, "dvd://%s", psz_blockdevice );
     /* Create the playlist item here */
-    p_item = playlist_ItemNew( p_sd, psz_uri,
-                               psz_name );
+    p_input = input_ItemNew( p_sd, psz_uri, psz_name );
     free( psz_uri );
 #ifdef HAVE_HAL_1
     libhal_free_string( psz_device );
 #else
     hal_free_string( psz_device );
 #endif
-    if( !p_item )
+    if( !p_input )
     {
         return;
     }
-    p_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
-    p_playlist = (playlist_t *)vlc_object_find( p_sd, VLC_OBJECT_PLAYLIST,
-                                                FIND_ANYWHERE );
+    AddItem( p_sd, p_input );
+}
+
+static void AddItem( services_discovery_t *p_sd, input_item_t * p_input )
+{
+    playlist_item_t *p_item;
+    playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_sd,
+                                        VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
     if( !p_playlist )
     {
         msg_Err( p_sd, "playlist not found" );
         return;
     }
-
-    playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY, p_sys->p_node,
-                          PLAYLIST_APPEND, PLAYLIST_END );
+    p_item = playlist_NodeAddInput( p_playlist, p_input,p_sd->p_sys->p_node_cat,
+                                    PLAYLIST_APPEND, PLAYLIST_END );
+    p_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
+    p_item = playlist_NodeAddInput( p_playlist, p_input,p_sd->p_sys->p_node_one,
+                                    PLAYLIST_APPEND, PLAYLIST_END );
+    p_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
 
     vlc_object_release( p_playlist );
 }
@@ -231,9 +218,7 @@ static void AddCdda( services_discovery_t *p_sd, char *psz_device )
     char *psz_name = "Audio CD";
     char *psz_uri;
     char *psz_blockdevice;
-    services_discovery_sys_t    *p_sys  = p_sd->p_sys;
-    playlist_t          *p_playlist;
-    playlist_item_t     *p_item;
+    input_item_t     *p_input;
 #ifdef HAVE_HAL_1
     psz_blockdevice = libhal_device_get_property_string( p_sd->p_sys->p_ctx,
                                             psz_device, "block.device", NULL );
@@ -243,32 +228,16 @@ static void AddCdda( services_discovery_t *p_sd, char *psz_device )
 #endif
     asprintf( &psz_uri, "cdda://%s", psz_blockdevice );
     /* Create the playlist item here */
-    p_item = playlist_ItemNew( p_sd, psz_uri,
-                               psz_name );
+    p_input = input_ItemNew( p_sd, psz_uri, psz_name );
     free( psz_uri );
 #ifdef HAVE_HAL_1
     libhal_free_string( psz_device );
 #else
     hal_free_string( psz_device );
 #endif
-    if( !p_item )
-    {
-        return;
-    }
-    p_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
-    p_playlist = (playlist_t *)vlc_object_find( p_sd, VLC_OBJECT_PLAYLIST,
-                                                FIND_ANYWHERE );
-    if( !p_playlist )
-    {
-        msg_Err( p_sd, "playlist not found" );
+    if( !p_input )
         return;
-    }
-
-    playlist_NodeAddItem( p_playlist, p_item, VIEW_CATEGORY, p_sys->p_node,
-                          PLAYLIST_APPEND, PLAYLIST_END );
-
-    vlc_object_release( p_playlist );
-
+    AddItem( p_sd, p_input );
 }
 
 static void ParseDevice( services_discovery_t *p_sd, char *psz_device )
index 9b8d263d662bd8fbaae8c3d6fff314cbb930f202..a0498bcfd013d1470af838a154b6e74d96a36afc 100644 (file)
@@ -80,7 +80,8 @@ vlc_module_end();
 struct services_discovery_sys_t
 {
     /* playlist node */
-    playlist_item_t *p_node;
+    playlist_item_t *p_node_cat;
+    playlist_item_t *p_node_one;
     input_thread_t **pp_input;
 
     char **ppsz_urls;
@@ -150,29 +151,32 @@ static int Open( vlc_object_t *p_this )
         return VLC_EGENERIC;
     }
 
-    p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY );
-    p_sys->p_node = playlist_NodeCreate( p_playlist, VIEW_CATEGORY,
-                                         _("Podcast"), p_view->p_root );
+    p_sys->p_node_cat = playlist_NodeCreate( p_playlist, _("Podcast"),
+                                         p_playlist->p_root_category );
+    p_sys->p_node_one = playlist_NodeCreate( p_playlist, _("Podcast"),
+                                         p_playlist->p_root_onelevel );
+    p_sys->p_node_one->p_input->i_id = p_sys->p_node_cat->p_input->i_id;
+
+    p_sys->p_node_one->i_flags |= PLAYLIST_RO_FLAG;
+    p_sys->p_node_cat->i_flags |= PLAYLIST_RO_FLAG;
+    p_sys->p_node_one->i_flags |= PLAYLIST_SKIP_FLAG;
+    p_sys->p_node_cat->i_flags |= PLAYLIST_SKIP_FLAG;
     p_sys->pp_input = malloc( p_sys->i_urls * sizeof( input_thread_t * ) );
     for( i = 0; i < p_sys->i_urls; i++ )
     {
+        input_item_t *p_input;
         asprintf( &psz_buf, "%s", p_sys->ppsz_urls[i] );
-        p_item = playlist_ItemNew( p_playlist, psz_buf,
-                                         p_sys->ppsz_urls[i] );
+        p_input = input_ItemNewExt( p_playlist, psz_buf,
+                                    p_sys->ppsz_urls[i], 0, NULL, -1 );
+        vlc_input_item_AddOption( p_input, "demux=podcast" );
+        p_item = playlist_NodeAddInput( p_playlist, p_input, p_sys->p_node_cat,
+                                        PLAYLIST_APPEND, PLAYLIST_END );
+        p_item = playlist_NodeAddInput( p_playlist, p_input, p_sys->p_node_one,
+                                        PLAYLIST_APPEND, PLAYLIST_END );
         free( psz_buf );
-        playlist_ItemAddOption( p_item, "demux=podcast" );
-        playlist_NodeAddItem( p_playlist, p_item,
-                              p_sys->p_node->pp_parents[0]->i_view,
-                              p_sys->p_node, PLAYLIST_APPEND,
-                              PLAYLIST_END );
-
-        /* We need to declare the parents of the node as the same of the
-         * parent's ones */
-        playlist_CopyParents( p_sys->p_node, p_item );
-        p_sys->pp_input[i] = input_CreateThread( p_playlist, &p_item->input );
+        p_sys->pp_input[i] = input_CreateThread( p_playlist, p_input );
     }
 
-    p_sys->p_node->i_flags |= PLAYLIST_RO_FLAG;
     val.b_bool = VLC_TRUE;
     var_Set( p_playlist, "intf-change", val );
 
@@ -205,7 +209,8 @@ static void Close( vlc_object_t *p_this )
     free( p_sd->p_sys->pp_input );
     if( p_playlist )
     {
-        playlist_NodeDelete( p_playlist, p_sys->p_node, VLC_TRUE, VLC_TRUE );
+        playlist_NodeDelete( p_playlist, p_sys->p_node_cat, VLC_TRUE, VLC_TRUE );
+        playlist_NodeDelete( p_playlist, p_sys->p_node_one, VLC_TRUE, VLC_TRUE );
         vlc_object_release( p_playlist );
     }
     for( i = 0; i < p_sys->i_urls; i++ ) free( p_sys->ppsz_urls[i] );
index 612e42479c1249950a535ce0792963b35858c42f..9fd77d1fcd4a5849478460ec834d5453c8386bbc 100644 (file)
@@ -210,8 +210,9 @@ struct sap_announce_t
     /* SAP annnounces must only contain one SDP */
     sdp_t       *p_sdp;
 
-    int i_item_id;
-//    playlist_item_t *p_item;
+    int i_input_id;
+    int i_item_id_cat;
+    int i_item_id_one;
 };
 
 struct services_discovery_sys_t
@@ -221,7 +222,8 @@ struct services_discovery_sys_t
     int *pi_fd;
 
     /* playlist node */
-    playlist_item_t *p_node;
+    playlist_item_t *p_node_cat;
+    playlist_item_t *p_node_one;
     playlist_t *p_playlist;
 
     /* Table of announces */
@@ -316,12 +318,18 @@ static int Open( vlc_object_t *p_this )
         msg_Warn( p_sd, "unable to find playlist, cancelling SAP listening");
         return VLC_EGENERIC;
     }
+    p_sys->p_node_cat = playlist_NodeCreate( p_sys->p_playlist,
+                               _("SAP sessions"),
+                               p_sys->p_playlist->p_root_category );
+    p_sys->p_node_cat->i_flags |= PLAYLIST_RO_FLAG;
+    p_sys->p_node_cat->i_flags |= PLAYLIST_SKIP_FLAG;
+
+    p_sys->p_node_one = playlist_NodeCreate( p_sys->p_playlist,
+                               _("SAP sessions"),
+                               p_sys->p_playlist->p_root_onelevel );
+    p_sys->p_node_one->i_flags |= PLAYLIST_RO_FLAG;
+    p_sys->p_node_one->i_flags |= PLAYLIST_SKIP_FLAG;
 
-    p_view = playlist_ViewFind( p_sys->p_playlist, VIEW_CATEGORY );
-    p_sys->p_node = playlist_NodeCreate( p_sys->p_playlist, VIEW_CATEGORY,
-                                         _("Session Announcements (SAP)"), p_view->p_root );
-    p_sys->p_node->i_flags |= PLAYLIST_RO_FLAG;
-    p_sys->p_node->i_flags &= ~PLAYLIST_SKIP_FLAG;
     val.b_bool = VLC_TRUE;
     var_Set( p_sys->p_playlist, "intf-change", val );
 
@@ -458,7 +466,9 @@ static void Close( vlc_object_t *p_this )
 
     if( p_sys->p_playlist )
     {
-        playlist_NodeDelete( p_sys->p_playlist, p_sys->p_node, VLC_TRUE,
+        playlist_NodeDelete( p_sys->p_playlist, p_sys->p_node_cat, VLC_TRUE,
+                             VLC_TRUE );
+        playlist_NodeDelete( p_sys->p_playlist, p_sys->p_node_one, VLC_TRUE,
                              VLC_TRUE );
         vlc_object_release( p_sys->p_playlist );
     }
@@ -544,8 +554,8 @@ static void Run( services_discovery_t *p_sd )
                 p_announce = p_sd->p_sys->pp_announces[i];
 
                 /* Remove the playlist item */
-                playlist_LockDelete( p_sd->p_sys->p_playlist,
-                                     p_announce->i_item_id );
+                playlist_LockDeleteAllFromInput( p_sd->p_sys->p_playlist,
+                                                 p_announce->i_input_id );
 
                 /* Remove the sap_announce from the array */
                 REMOVE_ELEM( p_sd->p_sys->pp_announces,
@@ -584,10 +594,9 @@ static int Demux( demux_t *p_demux )
     p_playlist = (playlist_t *)vlc_object_find( p_demux, VLC_OBJECT_PLAYLIST,
                                                FIND_ANYWHERE );
 
-    p_playlist->status.p_item->i_flags |= PLAYLIST_DEL_FLAG;
-
-    playlist_Add( p_playlist, p_sdp->psz_uri, p_sdp->psz_sessionname,
-                 PLAYLIST_APPEND, PLAYLIST_END );
+    /* TODO FIXME !! Add at the correct place */
+    playlist_PlaylistAdd( p_playlist, p_sdp->psz_uri, p_sdp->psz_sessionname,
+                          PLAYLIST_APPEND, PLAYLIST_END );
 
     vlc_object_release( p_playlist );
     if( p_sdp ) FreeSDP( p_sdp );
@@ -786,6 +795,7 @@ static int ParseSAP( services_discovery_t *p_sd, uint8_t *p_buffer, int i_read )
 sap_announce_t *CreateAnnounce( services_discovery_t *p_sd, uint16_t i_hash,
                                 sdp_t *p_sdp )
 {
+    input_item_t *p_input;
     playlist_item_t     *p_item, *p_child;
     char *psz_value;
     sap_announce_t *p_sap = (sap_announce_t *)malloc(
@@ -800,66 +810,67 @@ sap_announce_t *CreateAnnounce( services_discovery_t *p_sd, uint16_t i_hash,
     p_sap->i_last = mdate();
     p_sap->i_hash = i_hash;
     p_sap->p_sdp = p_sdp;
-    p_sap->i_item_id = -1;
 
     /* Create the actual playlist item here */
-    p_item = playlist_ItemNew( p_sd, p_sap->p_sdp->psz_uri, p_sdp->psz_sessionname );
-
-    if( !p_item )
+    p_input = input_ItemNewWithType( VLC_OBJECT(p_sd),
+                                     p_sap->p_sdp->psz_uri,
+                                     p_sdp->psz_sessionname,
+                                     0, NULL, -1, ITEM_TYPE_NET );
+    p_sap->i_input_id = p_input->i_id;
+    if( !p_input )
     {
         free( p_sap );
         return NULL;
     }
 
     if( p_sys->b_timeshift )
-        playlist_ItemAddOption( p_item, ":access-filter=timeshift" );
+        vlc_input_item_AddOption( p_input, ":access-filter=timeshift" );
 
     psz_value = GetAttribute( p_sap->p_sdp, "tool" );
     if( psz_value != NULL )
     {
-        vlc_input_item_AddInfo( &p_item->input, _("Session"),
-                                _("Tool"), psz_value );
+        vlc_input_item_AddInfo( p_input, _("Session"),_("Tool"), psz_value );
     }
     if( strcmp( p_sdp->psz_username, "-" ) )
     {
-        vlc_input_item_AddInfo( &p_item->input, _("Session"),
+        vlc_input_item_AddInfo( p_input, _("Session"),
                                 _("User"), p_sdp->psz_username );
     }
 
+    /* Handle group */
     psz_value = GetAttribute( p_sap->p_sdp, "x-plgroup" );
-
     if( psz_value == NULL )
-    {
         psz_value = GetAttribute( p_sap->p_sdp, "plgroup" );
-    }
 
-    /* Find or Create the group playlist non-playable item */
     if( psz_value != NULL )
     {
         EnsureUTF8( psz_value );
 
-        p_child = playlist_ChildSearchName( p_sys->p_node, psz_value );
+        p_child = playlist_ChildSearchName( p_sys->p_node_cat, psz_value );
 
         if( p_child == NULL )
         {
-            p_child = playlist_NodeCreate( p_sys->p_playlist,
-                                           VIEW_CATEGORY, psz_value,
-                                           p_sys->p_node );
+            p_child = playlist_NodeCreate( p_sys->p_playlist, psz_value,
+                                           p_sys->p_node_cat );
             p_child->i_flags &= ~PLAYLIST_SKIP_FLAG;
         }
     }
     else
     {
-        p_child = p_sys->p_node;
+        p_child = p_sys->p_node_cat;
     }
 
+    p_item = playlist_NodeAddInput( p_sys->p_playlist, p_input, p_child,
+                                    PLAYLIST_APPEND, PLAYLIST_END );
     p_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
     p_item->i_flags &= ~PLAYLIST_SAVE_FLAG;
+    p_sap->i_item_id_cat = p_item->i_id;
 
-    playlist_NodeAddItem( p_sys->p_playlist, p_item, VIEW_CATEGORY, p_child,
-                          PLAYLIST_APPEND, PLAYLIST_END );
-
-    p_sap->i_item_id = p_item->input.i_id;
+    p_item = playlist_NodeAddInput( p_sys->p_playlist, p_input,
+                        p_sys->p_node_one, PLAYLIST_APPEND, PLAYLIST_END );
+    p_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
+    p_item->i_flags &= ~PLAYLIST_SAVE_FLAG;
+    p_sap->i_item_id_one = p_item->i_id;
 
     TAB_APPEND( p_sys->i_announces, p_sys->pp_announces, p_sap );
 
@@ -1286,15 +1297,6 @@ static int Decompress( unsigned char *psz_src, unsigned char **_dst, int i_len )
         printf( "inflateInit() failed. Result: %d\n", i_result );
         return( -1 );
     }
-#if 0
-    p_playlist->pp_items[p_playlist->i_index]->b_autodeletion = VLC_TRUE;
-    i_position = p_playlist->i_index;
-
-    /* Gather the complete sdp file */
-    for( ;; )
-    {
-        int i_read = stream_Read( p_demux->s, &p_sdp[i_sdp], i_sdp_max - i_sdp - 1 );
-#endif
     d_stream.next_in = (Bytef *)psz_src;
     d_stream.avail_in = i_len;
     n = 0;
@@ -1360,9 +1362,10 @@ static int RemoveAnnounce( services_discovery_t *p_sd,
 
     if( p_announce->p_sdp ) FreeSDP( p_announce->p_sdp );
 
-    if( p_announce->i_item_id > -1 )
+    if( p_announce->i_input_id > -1 )
     {
-        playlist_LockDelete( p_sd->p_sys->p_playlist, p_announce->i_item_id );
+        playlist_LockDeleteAllFromInput(
+                        p_sd->p_sys->p_playlist, p_announce->i_input_id );
     }
 
     for( i = 0; i< p_sd->p_sys->i_announces; i++)
index 0d805e54330b1a273f6d34ce8cafe982f5cdf95f..44661ecf368be640f79f59db2a4bf85bed42b727 100644 (file)
@@ -204,7 +204,6 @@ static void Close( vlc_object_t *p_this )
  *****************************************************************************/
 static void Run( intf_thread_t *p_intf )
 {
-    int i_size,i_index;
     playlist_t *p_playlist;
     playlist_item_t *p_item = NULL;
     input_item_t item;
@@ -223,7 +222,7 @@ static void Run( intf_thread_t *p_intf )
                 continue;
             }
 
-            if( p_playlist->i_size < 0 || p_playlist->i_index < 0 )
+            if( p_playlist->i_size < 0  )
             {
                 vlc_object_release( p_playlist );
                 continue;
@@ -245,18 +244,13 @@ static void Run( intf_thread_t *p_intf )
             }
             else
             {
-    //           vlc_mutex_lock(&p_playlist->object_lock );
                  p_item = p_playlist->status.p_item;
                 item = p_item->input;
                 if( !p_item )
                 {
                     vlc_object_release( p_playlist );
-     //            vlc_mutex_unlock(&p_playlist->object_lock );
                     continue;
                 }
-                i_size = p_playlist->i_size;
-                i_index = p_playlist->i_index+1;
-    //            vlc_mutex_unlock(&p_playlist->object_lock );
 
                 vlc_object_release( p_playlist );
 
@@ -274,8 +268,8 @@ static void Run( intf_thread_t *p_intf )
                 psz_display = (char *)malloc( sizeof(char )*
                                           (strlen( item.psz_name ) +
                                           MSTRTIME_MAX_SIZE + 2+6 + 10 +10 ));
-                sprintf( psz_display," %i/%i - %s %s",
-                         i_index,i_size, item.psz_name, psz_duration);
+                sprintf( psz_display,"%s %s",
+                         item.psz_name, psz_duration);
             }
 
             /* Display */
index d82a2510560dd058713fe7ee37ba3673a23f9d8b..8bfaa552ed4ceb7498aa14e68ae0a1c001aac70e 100644 (file)
@@ -256,13 +256,16 @@ SOURCES_libvlc_common = \
        interface/interface.c \
        interface/intf_eject.c \
        interface/interaction.c \
-       playlist/playlist.c \
+       playlist/thread.c \
+       playlist/control.c \
+       playlist/engine.c \
        playlist/sort.c \
        playlist/loadsave.c \
-       playlist/view.c \
+       playlist/tree.c \
        playlist/item.c \
-       playlist/item-ext.c \
+       playlist/search.c \
        playlist/services_discovery.c \
+       input/item.c \
        input/access.c \
        input/clock.c \
        input/control.c \
index d7eaf7701b5b837040b8124b05dfd626429c9c26..3886e0fcedd0539de67e436ef55faa6a40b46f82 100644 (file)
@@ -192,25 +192,17 @@ mediacontrol_start( mediacontrol_Instance *self,
     vlc_mutex_lock( &p_playlist->object_lock );
     if( p_playlist->i_size )
     {
-        int i_index;
         int i_from;
         char *psz_from = NULL;
 
         psz_from = ( char * )malloc( 20 * sizeof( char ) );
-        if( psz_from )
+        if( psz_from && p_playlist->status.p_item )
         {
             i_from = mediacontrol_position2microsecond( p_playlist->p_input, a_position ) / 1000000;
 
-            i_index = p_playlist->i_index;
-            if( i_index < 0 )
-            {
-                /* We know that there is at least 1 element, since i_size != 0 */
-                i_index = 0;
-            }
-
             /* Set start time */
             snprintf( psz_from, 20, "start-time=%i", i_from );
-            playlist_ItemAddOption( p_playlist->pp_items[i_index], psz_from );
+            playlist_ItemAddOption( p_playlist->status.p_item, psz_from );
             free( psz_from );
         }
 
@@ -345,7 +337,7 @@ mediacontrol_playlist_get_list( mediacontrol_Instance *self,
 
     for( i_index = 0 ; i_index < i_playlist_size ; i_index++ )
     {
-        retval->data[i_index] = strdup( p_playlist->pp_items[i_index]->input.psz_uri );
+        retval->data[i_index] = strdup( p_playlist->pp_items[i_index]->p_input->psz_uri );
     }
     vlc_mutex_unlock( &p_playlist->object_lock );
 
index 871c3cfa59bd73913c1359a3ffa06e9a4fd5b797..408f64eca177319da7c11d8fe16959db6fcf4917 100644 (file)
@@ -39,35 +39,15 @@ void libvlc_playlist_play( libvlc_instance_t *p_instance, int i_id,
     }
     if( i_id > 0 )
     {
-        /* Always use the current view when using libvlc */
-        playlist_view_t *p_view;
-        playlist_item_t *p_item;
-
-        if( p_instance->p_playlist->status.i_view == -1 )
-        {
-            playlist_Control( p_instance->p_playlist, PLAYLIST_GOTO,
-                              i_id );
-        }
-        p_view = playlist_ViewFind( p_instance->p_playlist,
-                                    p_instance->p_playlist->status.i_view );
-        if( !p_view )
-        {
-             libvlc_exception_raise( p_exception,
-                                     "Unable to find current playlist view ");
-             return;
-        }
-
-        p_item = playlist_ItemGetById( p_instance->p_playlist, i_id );
+        playlist_item_t *p_item = playlist_ItemGetById( p_instance->p_playlist, i_id );
 
         if( !p_item )
         {
             libvlc_exception_raise( p_exception, "Unable to find item " );
             return;
         }
-
         playlist_Control( p_instance->p_playlist, PLAYLIST_VIEWPLAY,
-                          p_instance->p_playlist->status.i_view,
-                          p_view->p_root, p_item );
+                          p_instance->p_playlist->status.p_node, p_item );
     }
     else
     {
index 862705c51e6b477a823afa8cded5c355cb7b5185..f59ca7b80e73281f73b9a8a4dc9a26b315701312 100644 (file)
@@ -573,19 +573,8 @@ static void EsOutProgramMeta( es_out_t *out, int i_group, vlc_meta_t *p_meta )
     msg_Dbg( p_input, "EsOutProgramMeta: number=%d", i_group );
     sprintf( psz_cat, "%s %d", _("Program"), i_group );
 
-    for( i = 0; i < p_meta->i_meta; i++ )
-    {
-        msg_Dbg( p_input, "  - %s = %s", p_meta->name[i], p_meta->value[i] );
-
-        input_Control( p_input, INPUT_ADD_INFO, psz_cat,
-                      _(p_meta->name[i]), "%s", p_meta->value[i] );
-        if( !strcasecmp( p_meta->name[i], "Name" ) )
-            psz_name = p_meta->value[i];
-        else if( !strcasecmp( p_meta->name[i], "Provider" ) )
-            psz_provider = p_meta->value[i];
-        else if( !strcasecmp( p_meta->name[i], VLC_META_NOW_PLAYING ) )
-            psz_now_playing = p_meta->value[i];
-    }
+//    if( p_meta->psz_provider) psz_provider = p_meta->psz_provider;
+    if( p_meta->psz_nowplaying ) psz_now_playing = p_meta->psz_nowplaying;
 
     if( !psz_name && !psz_now_playing )
     {
index ca3c51c0dcbce4ac0a0159cce8a973341d7e70b5..2bbe51ca1e988d847451875d39fe566a4a08eed6 100644 (file)
@@ -57,7 +57,6 @@ static inline int ControlPopNoLock( input_thread_t *, int *, vlc_value_t * );
 static void       ControlReduce( input_thread_t * );
 static vlc_bool_t Control( input_thread_t *, int, vlc_value_t );
 
-
 static int  UpdateFromAccess( input_thread_t * );
 static int  UpdateFromDemux( input_thread_t * );
 static int  UpdateMeta( input_thread_t *, vlc_bool_t );
@@ -76,7 +75,7 @@ static void InputSourceClean( input_thread_t *, input_source_t * );
 static void SlaveDemux( input_thread_t *p_input );
 static void SlaveSeek( input_thread_t *p_input );
 
-static vlc_meta_t *InputMetaUser( input_thread_t *p_input );
+static void InputMetaUser( input_thread_t *p_input );
 
 /*****************************************************************************
  * This function creates a new input, and returns a pointer
@@ -150,6 +149,7 @@ static input_thread_t *Create( vlc_object_t *p_parent, input_item_t *p_item,
     p_input->input.b_eof = VLC_FALSE;
     p_input->input.i_cr_average = 0;
 
+    p_input->input.p_item->p_meta = vlc_meta_New();
     stats_ReinitInputStats( p_item->p_stats );
 
     /* No slave */
@@ -335,9 +335,6 @@ int __input_Preparse( vlc_object_t *p_parent, input_item_t *p_item )
     /* Unload all modules */
     if( p_input->p_es_out ) input_EsOutDelete( p_input->p_es_out );
 
-    /* Delete meta */
-    if( p_input->p_meta ) vlc_meta_Delete( p_input->p_meta );
-
     vlc_object_detach( p_input );
     vlc_object_destroy( p_input );
 
@@ -667,7 +664,7 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick )
     char *psz_subtitle;
     vlc_value_t val;
     double f_fps;
-    vlc_meta_t *p_meta, *p_meta_tmp;
+    vlc_meta_t *p_meta;
     int i_es_out_mode;
     int i, i_delay;
 
@@ -1017,79 +1014,32 @@ static int Init( input_thread_t * p_input, vlc_bool_t b_quick )
         }
     }
 
+    p_meta = p_input->input.p_item->p_meta;
     /* Get meta data from users */
-    p_meta_tmp = InputMetaUser( p_input );
-
+    InputMetaUser( p_input );
     /* Get meta data from master input */
-    if( demux2_Control( p_input->input.p_demux, DEMUX_GET_META, &p_meta ) )
-        p_meta = NULL;
-
-    /* Merge them */
-    if( p_meta == NULL )
-    {
-        p_meta = p_meta_tmp;
-    }
-    else if( p_meta_tmp )
-    {
-        vlc_meta_Merge( p_meta, p_meta_tmp );
-        vlc_meta_Delete( p_meta_tmp );
-    }
+    demux2_Control( p_input->input.p_demux, DEMUX_GET_META, p_meta );
 
     /* Access_file does not give any meta, and there are no slave */
     if( !b_quick )
     {
-        if( !p_input->input.p_access ||
+        if( p_input->input.p_access )
             access2_Control( p_input->input.p_access, ACCESS_GET_META,
-                             &p_meta_tmp))
-            p_meta_tmp = NULL;
-
-        if( p_meta == NULL )
-        {
-            p_meta = p_meta_tmp;
-        }
-        else if( p_meta_tmp )
-        {
-            vlc_meta_Merge( p_meta, p_meta_tmp );
-            vlc_meta_Delete( p_meta_tmp );
-        }
+                             p_meta );
 
         /* Get meta data from slave input */
         for( i = 0; i < p_input->i_slave; i++ )
         {
-            vlc_meta_t *p_meta_slave;
-
-            if( !demux2_Control( p_input->slave[i]->p_demux,
-                                 DEMUX_GET_META, &p_meta_slave ) )
+            demux2_Control( p_input->slave[i]->p_demux,
+                            DEMUX_GET_META, p_meta );
+            if( p_input->slave[i]->p_access )
             {
-                if( p_meta == NULL )
-                {
-                    p_meta = p_meta_slave;
-                }
-                else if( p_meta_slave )
-                {
-                    vlc_meta_Merge( p_meta, p_meta_slave );
-                    vlc_meta_Delete( p_meta_slave );
-                }
-            }
-
-            if( p_input->slave[i]->p_access &&
-                !access2_Control( p_input->slave[i]->p_access,
-                                  ACCESS_GET_META, &p_meta_slave ) )
-            {
-                if( p_meta == NULL )
-                {
-                    p_meta = p_meta_slave;
-                }
-                else if( p_meta_slave )
-                {
-                    vlc_meta_Merge( p_meta, p_meta_slave );
-                    vlc_meta_Delete( p_meta_slave );
-                }
+                access2_Control( p_input->slave[i]->p_access,
+                                 ACCESS_GET_META, p_meta );
             }
         }
     }
 
-    p_input->p_meta = p_meta;
     UpdateMeta( p_input, b_quick );
 
     if( !b_quick )
@@ -1195,10 +1145,6 @@ static void End( input_thread_t * p_input )
             vlc_object_release( p_pl );
     }
 
-    /* Delete meta */
-    if( p_input->p_meta )
-        vlc_meta_Delete( p_input->p_meta );
-
     /* Tell we're dead */
     p_input->b_dead = VLC_TRUE;
 }
@@ -1669,8 +1615,7 @@ static vlc_bool_t Control( input_thread_t *p_input, int i_type,
                 if( !InputSourceInit( p_input, slave, val.psz_string, NULL,
                                       VLC_FALSE ) )
                 {
-                    vlc_meta_t *p_meta_new = NULL;
-                    vlc_meta_t *p_meta;
+                    vlc_meta_t *p_meta = p_input->input.p_item->p_meta;
                     int64_t i_time;
 
                     /* Add the slave */
@@ -1695,38 +1640,11 @@ static vlc_bool_t Control( input_thread_t *p_input, int i_type,
                         break;
                     }
 
-
                     /* Get meta (access and demux) */
-                    if( access2_Control( slave->p_access,
-                                          ACCESS_GET_META, &p_meta_new ) )
-                        p_meta_new = NULL;
-                    if( !demux2_Control( slave->p_demux,
-                                         DEMUX_GET_META, &p_meta ) )
-                    {
-                        if( p_meta_new )
-                        {
-                            vlc_meta_Merge( p_meta_new, p_meta );
-                            vlc_meta_Delete( p_meta );
-                        }
-                        else
-                        {
-                            p_meta_new = p_meta;
-                        }
-                    }
-                    /* Update meta */
-                    if( p_meta_new )
-                    {
-                        if( p_input->p_meta )
-                        {
-                            vlc_meta_Merge( p_input->p_meta, p_meta_new );
-                            vlc_meta_Delete( p_meta_new );
-                        }
-                        else
-                        {
-                            p_input->p_meta = p_meta_new;
-                        }
-                        UpdateMeta( p_input, VLC_FALSE );
-                    }
+                    access2_Control( slave->p_access, ACCESS_GET_META,
+                                     p_meta );
+                    demux2_Control( slave->p_demux, DEMUX_GET_META, p_meta );
+                    UpdateMeta( p_input, VLC_FALSE );
 
                     TAB_APPEND( p_input->i_slave, p_input->slave, slave );
                 }
@@ -1825,28 +1743,15 @@ static int UpdateFromAccess( input_thread_t *p_input )
     {
         v.i_int = p_access->info.i_seekpoint;
         var_Change( p_input, "chapter", VLC_VAR_SETVALUE, &v, NULL);
-
         p_access->info.i_update &= ~INPUT_UPDATE_SEEKPOINT;
     }
     if( p_access->info.i_update & INPUT_UPDATE_META )
     {
         /* TODO maybe multi - access ? */
-        vlc_meta_t *p_meta;
-        if( !access2_Control( p_input->input.p_access,ACCESS_GET_META,&p_meta))
-        {
-            if( p_input->p_meta )
-            {
-                vlc_meta_Merge( p_input->p_meta, p_meta );
-                vlc_meta_Delete( p_meta );
-            }
-            else
-            {
-                p_input->p_meta = p_meta;
-            }
-
-            UpdateMeta( p_input, VLC_FALSE );
-            var_SetBool( p_input, "item-change", p_input->input.p_item->i_id );
-        }
+        vlc_meta_t *p_meta = p_input->input.p_item->p_meta;
+        access2_Control( p_input->input.p_access,ACCESS_GET_META, p_meta );
+        UpdateMeta( p_input, VLC_FALSE );
+        var_SetBool( p_input, "item-change", p_input->input.p_item->i_id );
         p_access->info.i_update &= ~INPUT_UPDATE_META;
     }
 
@@ -1884,58 +1789,14 @@ static int UpdateFromAccess( input_thread_t *p_input )
  *****************************************************************************/
 static int  UpdateMeta( input_thread_t *p_input, vlc_bool_t b_quick )
 {
-    vlc_meta_t *p_meta = p_input->p_meta;
-    int i;
-
-    if( !p_meta || p_meta->i_meta == 0 )
+    vlc_meta_t *p_meta = p_input->input.p_item->p_meta;
+    if( !p_meta )
         return VLC_SUCCESS;
 
-    if( !b_quick ) msg_Dbg( p_input, "meta information:" );
-    for( i = 0; i < p_meta->i_meta; i++ )
-    {
-        if( !b_quick )
-            msg_Dbg( p_input, "  - '%s' = '%s'",
-                     _(p_meta->name[i]), p_meta->value[i] );
-
-        if( !strcmp(p_meta->name[i], _(VLC_META_TITLE)) && p_meta->value[i] &&
-            !p_input->input.p_item->b_fixed_name )
-            input_Control( p_input, INPUT_SET_NAME, p_meta->value[i] );
-
-        if( !strcmp( p_meta->name[i], _(VLC_META_AUTHOR) ) )
-            input_Control( p_input, INPUT_ADD_INFO, _("General"),
-                           _(VLC_META_AUTHOR), p_meta->value[i] );
-
-        input_Control( p_input, INPUT_ADD_INFO, _(VLC_META_INFO_CAT),
-                      _(p_meta->name[i]), "%s", p_meta->value[i] );
-    }
-
-    for( i = 0; i < p_meta->i_track; i++ )
-    {
-        vlc_meta_t *tk = p_meta->track[i];
-        int j;
-
-        if( tk->i_meta > 0 )
-        {
-            char *psz_cat = malloc( strlen(_("Stream")) + 10 );
+    if( p_meta->psz_title && !p_input->input.p_item->b_fixed_name )
+        input_Control( p_input, INPUT_SET_NAME, p_meta->psz_title );
 
-            msg_Dbg( p_input, "  - track[%d]:", i );
-
-            sprintf( psz_cat, "%s %d", _("Stream"), i );
-            for( j = 0; j < tk->i_meta; j++ )
-            {
-                msg_Dbg( p_input, "     - '%s' = '%s'", _(tk->name[j]),
-                         tk->value[j] );
-
-                input_Control( p_input, INPUT_ADD_INFO, psz_cat,
-                               _(tk->name[j]), "%s", tk->value[j] );
-            }
-        }
-    }
-
-    if( p_input->p_sout && p_input->p_sout->p_meta == NULL )
-    {
-        p_input->p_sout->p_meta = vlc_meta_Duplicate( p_meta );
-    }
+    /** \todo handle sout meta */
 
     return VLC_SUCCESS;
 }
@@ -2355,32 +2216,31 @@ static void SlaveSeek( input_thread_t *p_input )
 /*****************************************************************************
  * InputMetaUser:
  *****************************************************************************/
-static vlc_meta_t *InputMetaUser( input_thread_t *p_input )
+static void InputMetaUser( input_thread_t *p_input )
 {
-    vlc_meta_t *p_meta;
+    vlc_meta_t *p_meta = p_input->input.p_item->p_meta;
     vlc_value_t val;
 
-    if( ( p_meta = vlc_meta_New() ) == NULL )
-        return NULL;
+    if( !p_meta ) return;
 
     /* Get meta information from user */
-#define GET_META( c, s ) \
+#define GET_META( field, s ) \
     var_Get( p_input, (s), &val );  \
-    if( *val.psz_string )       \
-        vlc_meta_Add( p_meta, _(c), val.psz_string ); \
+    if( *val.psz_string ) { \
+        if( p_meta->psz_ ## field ) free ( p_meta->psz_ ## field ); \
+        p_meta->psz_ ## field = strdup( val.psz_string ); \
+    } \
     free( val.psz_string )
 
-    GET_META( VLC_META_TITLE, "meta-title" );
-    GET_META( VLC_META_AUTHOR, "meta-author" );
-    GET_META( VLC_META_ARTIST, "meta-artist" );
-    GET_META( VLC_META_GENRE, "meta-genre" );
-    GET_META( VLC_META_COPYRIGHT, "meta-copyright" );
-    GET_META( VLC_META_DESCRIPTION, "meta-description" );
-    GET_META( VLC_META_DATE, "meta-date" );
-    GET_META( VLC_META_URL, "meta-url" );
+    GET_META( title, "meta-title" );
+    GET_META( author, "meta-author" );
+    GET_META( artist, "meta-artist" );
+    GET_META( genre, "meta-genre" );
+    GET_META( copyright, "meta-copyright" );
+    GET_META( description, "meta-description" );
+    GET_META( date, "meta-date" );
+    GET_META( url, "meta-url" );
 #undef GET_META
-
-    return p_meta;
 }
 
 /*****************************************************************************
@@ -2546,114 +2406,3 @@ static void MRLSections( input_thread_t *p_input, char *psz_source,
              psz_source, *pi_title_start, *pi_chapter_start,
              *pi_title_end, *pi_chapter_end );
 }
-
-
-/***********************************************************************
- * Info management functions
- ***********************************************************************/
-/**
- * Get a info item from a given category in a given input item.
- *
- * \param p_i The input item to get info from
- * \param psz_cat String representing the category for the info
- * \param psz_name String representing the name of the desired info
- * \return A pointer to the string with the given info if found, or an
- *         empty string otherwise. The caller should free the returned
- *         pointer.
- */
-char *vlc_input_item_GetInfo( input_item_t *p_i,
-                              const char *psz_cat,
-                              const char *psz_name )
-{
-    int i,j;
-
-    vlc_mutex_lock( &p_i->lock );
-
-    for( i = 0 ; i< p_i->i_categories  ; i++ )
-    {
-        info_category_t *p_cat = p_i->pp_categories[i];
-
-        if( !psz_cat || strcmp( p_cat->psz_name, psz_cat ) )
-            continue;
-
-        for( j = 0; j < p_cat->i_infos ; j++ )
-        {
-            if( !strcmp( p_cat->pp_infos[j]->psz_name, psz_name ) )
-            {
-                char *psz_ret = strdup( p_cat->pp_infos[j]->psz_value );
-                vlc_mutex_unlock( &p_i->lock );
-                return psz_ret;
-            }
-        }
-    }
-    vlc_mutex_unlock( &p_i->lock );
-    return strdup( "" );
-}
-
-int vlc_input_item_AddInfo( input_item_t *p_i,
-                            const char *psz_cat,
-                            const char *psz_name,
-                            const char *psz_format, ... )
-{
-    va_list args;
-    int i;
-    info_t *p_info = NULL;
-    info_category_t *p_cat = NULL ;
-
-    vlc_mutex_lock( &p_i->lock );
-
-    for( i = 0 ; i < p_i->i_categories ; i ++ )
-    {
-        if( !strcmp( p_i->pp_categories[i]->psz_name, psz_cat ) )
-        {
-            p_cat = p_i->pp_categories[i];
-            break;
-        }
-    }
-    if( !p_cat )
-    {
-        if( !(p_cat = (info_category_t *)malloc( sizeof(info_category_t) )) )
-        {
-            vlc_mutex_unlock( &p_i->lock );
-            return VLC_EGENERIC;
-        }
-        p_cat->psz_name = strdup( psz_cat );
-        p_cat->i_infos = 0;
-        p_cat->pp_infos = 0;
-        INSERT_ELEM( p_i->pp_categories, p_i->i_categories, p_i->i_categories,
-                     p_cat );
-    }
-
-    for( i = 0; i< p_cat->i_infos; i++ )
-    {
-        if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
-        {
-            p_info = p_cat->pp_infos[i];
-            break;
-        }
-    }
-
-    if( !p_info )
-    {
-        if( ( p_info = (info_t *)malloc( sizeof( info_t ) ) ) == NULL )
-        {
-            vlc_mutex_unlock( &p_i->lock );
-            return VLC_EGENERIC;
-        }
-        INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, p_cat->i_infos, p_info );
-        p_info->psz_name = strdup( psz_name );
-    }
-    else
-    {
-        if( p_info->psz_value ) free( p_info->psz_value );
-    }
-
-    va_start( args, psz_format );
-    vasprintf( &p_info->psz_value, psz_format, args);
-    va_end( args );
-
-    vlc_mutex_unlock( &p_i->lock );
-
-    return VLC_SUCCESS;
-}
-
diff --git a/src/input/item.c b/src/input/item.c
new file mode 100644 (file)
index 0000000..9f893b7
--- /dev/null
@@ -0,0 +1,313 @@
+/*****************************************************************************
+ * item.c: input_item management
+ *****************************************************************************
+ * Copyright (C) 1998-2004 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include <vlc/vlc.h>
+#include <vlc/input.h>
+#include "vlc_playlist.h"
+#include "vlc_interface.h"
+
+static void GuessType( input_item_t *p_item );
+
+/**
+ * Get a info item from a given category in a given input item.
+ *
+ * \param p_i The input item to get info from
+ * \param psz_cat String representing the category for the info
+ * \param psz_name String representing the name of the desired info
+ * \return A pointer to the string with the given info if found, or an
+ *         empty string otherwise. The caller should free the returned
+ *         pointer.
+ */
+char *vlc_input_item_GetInfo( input_item_t *p_i,
+                              const char *psz_cat,
+                              const char *psz_name )
+{
+    int i,j;
+
+    vlc_mutex_lock( &p_i->lock );
+
+    for( i = 0 ; i< p_i->i_categories  ; i++ )
+    {
+        info_category_t *p_cat = p_i->pp_categories[i];
+
+        if( !psz_cat || strcmp( p_cat->psz_name, psz_cat ) )
+            continue;
+
+        for( j = 0; j < p_cat->i_infos ; j++ )
+        {
+            if( !strcmp( p_cat->pp_infos[j]->psz_name, psz_name ) )
+            {
+                char *psz_ret = strdup( p_cat->pp_infos[j]->psz_value );
+                vlc_mutex_unlock( &p_i->lock );
+                return psz_ret;
+            }
+        }
+    }
+    vlc_mutex_unlock( &p_i->lock );
+    return strdup( "" );
+}
+
+static void vlc_input_item_Destroy ( gc_object_t *p_this )
+{
+    vlc_object_t *p_obj = (vlc_object_t *)p_this->p_destructor_arg;
+    int i, i_top, i_bottom;
+    input_item_t *p_input = (input_item_t *) p_this;
+
+    playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_obj,
+                                          VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+
+    fprintf( stderr, "Destroying item %s\n", p_input->psz_name );
+
+
+    vlc_input_item_Clean( p_input );
+
+    if( p_playlist )
+    {
+        i_bottom = 0; i_top = p_playlist->i_input_items - 1;
+        i = i_top / 2;
+        while( p_playlist->pp_input_items[i]->i_id != p_input->i_id &&
+               i_top > i_bottom )
+        {
+            if( p_playlist->pp_input_items[i]->i_id < p_input->i_id )
+                i_bottom = i + 1;
+            else
+                i_top = i -1;
+
+            i = i_bottom + ( i_top - i_bottom ) / 2;
+
+        }
+        if( p_playlist->pp_input_items[i]->i_id == p_input->i_id )
+        {
+            REMOVE_ELEM( p_playlist->pp_input_items,
+                         p_playlist->i_input_items, i );
+        }
+        vlc_object_release( p_playlist );
+    }
+    free( p_input );
+}
+
+int vlc_input_item_AddInfo( input_item_t *p_i,
+                            const char *psz_cat,
+                            const char *psz_name,
+                            const char *psz_format, ... )
+{
+    va_list args;
+    int i;
+    info_t *p_info = NULL;
+    info_category_t *p_cat = NULL ;
+
+    vlc_mutex_lock( &p_i->lock );
+
+    for( i = 0 ; i < p_i->i_categories ; i ++ )
+    {
+        if( !strcmp( p_i->pp_categories[i]->psz_name, psz_cat ) )
+        {
+            p_cat = p_i->pp_categories[i];
+            break;
+        }
+    }
+    if( !p_cat )
+    {
+        if( !(p_cat = (info_category_t *)malloc( sizeof(info_category_t) )) )
+        {
+            vlc_mutex_unlock( &p_i->lock );
+            return VLC_EGENERIC;
+        }
+        p_cat->psz_name = strdup( psz_cat );
+        p_cat->i_infos = 0;
+        p_cat->pp_infos = 0;
+        INSERT_ELEM( p_i->pp_categories, p_i->i_categories, p_i->i_categories,
+                     p_cat );
+    }
+
+    for( i = 0; i< p_cat->i_infos; i++ )
+    {
+        if( !strcmp( p_cat->pp_infos[i]->psz_name, psz_name ) )
+        {
+            p_info = p_cat->pp_infos[i];
+            break;
+        }
+    }
+
+    if( !p_info )
+    {
+        if( ( p_info = (info_t *)malloc( sizeof( info_t ) ) ) == NULL )
+        {
+            vlc_mutex_unlock( &p_i->lock );
+            return VLC_EGENERIC;
+        }
+        INSERT_ELEM( p_cat->pp_infos, p_cat->i_infos, p_cat->i_infos, p_info );
+        p_info->psz_name = strdup( psz_name );
+    }
+    else
+    {
+        if( p_info->psz_value ) free( p_info->psz_value );
+    }
+
+    va_start( args, psz_format );
+    vasprintf( &p_info->psz_value, psz_format, args);
+    va_end( args );
+
+    vlc_mutex_unlock( &p_i->lock );
+
+    return VLC_SUCCESS;
+}
+
+void vlc_input_item_AddOption( input_item_t *p_input,
+                              const char *psz_option )
+{
+    if( !psz_option ) return;
+    vlc_mutex_lock( &p_input->lock );
+    INSERT_ELEM( p_input->ppsz_options, p_input->i_options,
+                 p_input->i_options, strdup( psz_option ) );
+    vlc_mutex_unlock( &p_input->lock );
+};
+
+
+input_item_t *input_ItemGetById( playlist_t *p_playlist, int i_id )
+{
+    int i, i_top, i_bottom;
+    i_bottom = 0; i_top = p_playlist->i_input_items -1;
+    i = i_top  /2 ;
+    while( p_playlist->pp_input_items[i]->i_id != i_id &&
+           i_top > i_bottom )
+    {
+        if( p_playlist->pp_input_items[i]->i_id < i_id )
+            i_bottom = i + 1;
+        else
+            i_top = i - 1;
+        i = i_bottom + ( i_top - i_bottom ) / 2;
+    }
+    if( p_playlist->pp_input_items[i]->i_id == i_id )
+    {
+        return p_playlist->pp_input_items[i];
+    }
+    return NULL;
+}
+
+input_item_t *__input_ItemNewExt( vlc_object_t *p_obj, const char *psz_uri,
+                                  const char *psz_name, int i_options,
+                                  const char **ppsz_options, int i_duration )
+{
+    return input_ItemNewWithType( p_obj, psz_uri, psz_name,
+                                  i_options, ppsz_options,
+                                  i_duration, ITEM_TYPE_UNKNOWN );
+}
+
+
+input_item_t *input_ItemNewWithType( vlc_object_t *p_obj, const char *psz_uri,
+                                const char *psz_name, int i_options,
+                                const char **ppsz_options, int i_duration,
+                                int i_type )
+{
+    /* FIXME DON'T SEARCH PLAYLIST */
+    /* FIXME SHOULD LOCK */
+    input_item_t *p_input = (input_item_t *)malloc( sizeof( input_item_t ) );
+    playlist_t *p_playlist = (playlist_t *) vlc_object_find( p_obj,
+                                VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+
+    vlc_input_item_Init( p_obj, p_input );
+    vlc_gc_init( p_input, vlc_input_item_Destroy, (void *)p_obj );
+
+    p_input->i_id = ++p_playlist->i_last_input_id;
+
+    INSERT_ELEM( p_playlist->pp_input_items, p_playlist->i_input_items,
+                 p_playlist->i_input_items, p_input );
+    vlc_object_release( p_playlist );
+
+    p_input->b_fixed_name = VLC_FALSE;
+
+    if( psz_uri )
+        p_input->psz_uri = strdup( psz_uri );
+    else
+        p_input->psz_uri = NULL;
+
+    if( psz_name != NULL )
+        p_input->psz_name = strdup( psz_name );
+    else
+        p_input->psz_name = strdup ( p_input->psz_uri );
+
+    p_input->i_type = i_type;
+
+    if( p_input->i_type == ITEM_TYPE_UNKNOWN )
+        GuessType( p_input );
+
+    p_input->i_duration = i_duration;
+    p_input->ppsz_options = NULL;
+
+    for( p_input->i_options = 0; p_input->i_options < i_options;
+         p_input->i_options++ )
+    {
+        if( !p_input->i_options )
+        {
+            p_input->ppsz_options = malloc( i_options * sizeof(char *) );
+            if( !p_input->ppsz_options ) break;
+        }
+        p_input->ppsz_options[p_input->i_options] =
+                    strdup( ppsz_options[p_input->i_options] );
+    }
+    return p_input;
+}
+
+/* Guess the type of the item using the beginning of the mrl */
+static void GuessType( input_item_t *p_item)
+{
+    int i;
+    static struct { char *psz_search; int i_type; }  types_array[] =
+    {
+        { "http", ITEM_TYPE_NET },
+        { "dvd", ITEM_TYPE_DISC },
+        { "cdda", ITEM_TYPE_CDDA },
+        { "mms", ITEM_TYPE_NET },
+        { "rtsp", ITEM_TYPE_NET },
+        { "udp", ITEM_TYPE_NET },
+        { "rtp", ITEM_TYPE_NET },
+        { "vcd", ITEM_TYPE_DISC },
+        { "v4l", ITEM_TYPE_CARD },
+        { "dshow", ITEM_TYPE_CARD },
+        { "pvr", ITEM_TYPE_CARD },
+        { "dvb", ITEM_TYPE_CARD },
+        { "qpsk", ITEM_TYPE_CARD },
+        { "sdp", ITEM_TYPE_NET },
+        { NULL, 0 }
+    };
+
+#if 0 /* Unused */
+    static struct { char *psz_search; int i_type; } exts_array[] =
+    {
+        { "mp3", ITEM_TYPE_AFILE },
+        { NULL, 0 }
+    };
+#endif
+
+    for( i = 0; types_array[i].psz_search != NULL; i++ )
+    {
+        if( !strncmp( p_item->psz_uri, types_array[i].psz_search,
+                      strlen( types_array[i].psz_search ) ) )
+        {
+            p_item->i_type = types_array[i].i_type;
+            return;
+        }
+    }
+    p_item->i_type = ITEM_TYPE_VFILE;
+}
index d1b5b77c76a04875020c9c2de9c5cee53be05c98..2b33b381fbf354b38f34b889344c4c26893dc9ac 100644 (file)
@@ -697,7 +697,7 @@ int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
     /*
      * Initialize playlist and get commandline files
      */
-    p_playlist = playlist_Create( p_vlc );
+    p_playlist = playlist_ThreadCreate( p_vlc );
     if( !p_playlist )
     {
         msg_Err( p_vlc, "playlist initialization failed" );
@@ -915,7 +915,7 @@ int VLC_CleanUp( int i_object )
     {
         vlc_object_detach( p_playlist );
         vlc_object_release( p_playlist );
-        playlist_Destroy( p_playlist );
+        playlist_ThreadDestroy( p_playlist );
     }
 
     /*
@@ -1198,7 +1198,7 @@ int VLC_AddTarget( int i_object, char const *psz_target,
     if( p_playlist == NULL )
     {
         msg_Dbg( p_vlc, "no playlist present, creating one" );
-        p_playlist = playlist_Create( p_vlc );
+        p_playlist = playlist_ThreadCreate( p_vlc );
 
         if( p_playlist == NULL )
         {
@@ -1209,7 +1209,7 @@ int VLC_AddTarget( int i_object, char const *psz_target,
         vlc_object_yield( p_playlist );
     }
 
-    i_err = playlist_AddExt( p_playlist, psz_target, psz_target,
+    i_err = playlist_PlaylistAddExt( p_playlist, psz_target, psz_target,
                              i_mode, i_pos, -1, ppsz_options, i_options);
 
     vlc_object_release( p_playlist );
@@ -1631,29 +1631,8 @@ float VLC_SpeedSlower( int i_object )
  */
 int VLC_PlaylistIndex( int i_object )
 {
-    int i_index;
-    playlist_t * p_playlist;
-    vlc_t *p_vlc = vlc_current_object( i_object );
-
-    /* Check that the handle is valid */
-    if( !p_vlc )
-    {
-        return VLC_ENOOBJ;
-    }
-
-    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
-
-    if( !p_playlist )
-    {
-        if( i_object ) vlc_object_release( p_vlc );
-        return VLC_ENOOBJ;
-    }
-
-    i_index = p_playlist->i_index;
-    vlc_object_release( p_playlist );
-
-    if( i_object ) vlc_object_release( p_vlc );
-    return i_index;
+    printf( "This function is deprecated and should not be used anymore" );
+    return -1;
 }
 
 /**
@@ -1763,7 +1742,6 @@ int VLC_PlaylistPrev( int i_object )
  *****************************************************************************/
 int VLC_PlaylistClear( int i_object )
 {
-    int i_err;
     playlist_t * p_playlist;
     vlc_t *p_vlc = vlc_current_object( i_object );
 
@@ -1781,12 +1759,12 @@ int VLC_PlaylistClear( int i_object )
         return VLC_ENOOBJ;
     }
 
-    i_err = playlist_Clear( p_playlist );
+    playlist_Clear( p_playlist );
 
     vlc_object_release( p_playlist );
 
     if( i_object ) vlc_object_release( p_vlc );
-    return i_err;
+    return VLC_SUCCESS;
 }
 
 /**
diff --git a/src/playlist/control.c b/src/playlist/control.c
new file mode 100644 (file)
index 0000000..5ac0ee6
--- /dev/null
@@ -0,0 +1,455 @@
+/*****************************************************************************
+ * control.c : Hanle control of the playlist & running through it
+ *****************************************************************************
+ * Copyright (C) 1999-2004 the VideoLAN team
+ * $Id: /local/vlc/0.8.6-playlist-vlm/src/playlist/playlist.c 13741 2006-03-21T19:29:39.792444Z zorglub  $
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *          Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/input.h>
+#include "vlc_playlist.h"
+
+#define PLAYLIST_DEBUG 1
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+int PlaylistVAControl( playlist_t * p_playlist, int i_query, va_list args );
+
+void PreparseEnqueueItemSub( playlist_t *, playlist_item_t * );
+
+playlist_item_t *playlist_RecursiveFindLast(playlist_t *p_playlist,
+                                            playlist_item_t *p_node );
+
+/*****************************************************************************
+ * Playlist control
+ *****************************************************************************/
+
+/**
+ * Do a playlist action. Should be entered without playlist lock
+ * \see playlist_Control
+ */
+int playlist_LockControl( playlist_t * p_playlist, int i_query, ... )
+{
+    va_list args;
+    int i_result;
+    va_start( args, i_query );
+    vlc_mutex_lock( &p_playlist->object_lock );
+    i_result = PlaylistVAControl( p_playlist, i_query, args );
+    va_end( args );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+    return i_result;
+}
+
+/**
+ * Do a playlist action.
+ * If there is something in the playlist then you can do playlist actions.
+ * Should be entered with playlist lock. See include/vlc_playlist.h for
+ * possible queries
+ *
+ * \param p_playlist the playlist to do the command on
+ * \param i_query the command to do
+ * \param variable number of arguments
+ * \return VLC_SUCCESS or an error
+ */
+int playlist_Control( playlist_t * p_playlist, int i_query, ... )
+{
+    va_list args;
+    int i_result;
+    va_start( args, i_query );
+    i_result = PlaylistVAControl( p_playlist, i_query, args );
+    va_end( args );
+
+    return i_result;
+}
+
+int PlaylistVAControl( playlist_t * p_playlist, int i_query, va_list args )
+{
+    int i_view;
+    playlist_item_t *p_item, *p_node;
+    vlc_value_t val;
+
+    if( p_playlist->i_size <= 0 )
+    {
+        return VLC_EGENERIC;
+    }
+
+    switch( i_query )
+    {
+    case PLAYLIST_STOP:
+        p_playlist->request.i_status = PLAYLIST_STOPPED;
+        p_playlist->request.b_request = VLC_TRUE;
+        p_playlist->request.p_item = NULL;
+        break;
+
+    case PLAYLIST_ITEMPLAY:
+        p_item = (playlist_item_t *)va_arg( args, playlist_item_t * );
+        if ( p_item == NULL || p_item->p_input->psz_uri == NULL )
+            return VLC_EGENERIC;
+        p_playlist->request.i_status = PLAYLIST_RUNNING;
+        p_playlist->request.i_skip = 0;
+        p_playlist->request.b_request = VLC_TRUE;
+        p_playlist->request.p_item = p_item;
+        p_playlist->request.p_node = p_playlist->status.p_node;
+        break;
+
+    case PLAYLIST_VIEWPLAY:
+        i_view = (int) va_arg( args, playlist_item_t *);
+        p_node = (playlist_item_t *)va_arg( args, playlist_item_t * );
+        p_item = (playlist_item_t *)va_arg( args, playlist_item_t * );
+        if ( p_node == NULL )
+        {
+            p_playlist->status.i_status = PLAYLIST_STOPPED;
+            p_playlist->request.b_request = VLC_TRUE;
+            msg_Err( p_playlist, "null node" );
+            return VLC_SUCCESS;
+        }
+        p_playlist->request.i_status = PLAYLIST_RUNNING;
+        p_playlist->request.i_skip = 0;
+        p_playlist->request.b_request = VLC_TRUE;
+        p_playlist->request.p_node = p_node;
+        p_playlist->request.p_item = p_item;
+        break;
+
+    case PLAYLIST_PLAY:
+        p_playlist->request.i_status = PLAYLIST_RUNNING;
+        p_playlist->request.b_request = VLC_TRUE;
+
+        if( p_playlist->p_input )
+        {
+            val.i_int = PLAYING_S;
+            var_Set( p_playlist->p_input, "state", val );
+            break;
+        }
+        p_playlist->request.p_node = p_playlist->status.p_node;
+        p_playlist->request.p_item = p_playlist->status.p_item;
+        p_playlist->request.i_skip = 0;
+        break;
+
+    case PLAYLIST_AUTOPLAY:
+        p_playlist->status.i_status = PLAYLIST_RUNNING;
+        p_playlist->status.p_node = p_playlist->p_local_category;
+        p_playlist->request.b_request = VLC_FALSE;
+        break;
+
+    case PLAYLIST_PAUSE:
+        val.i_int = 0;
+        if( p_playlist->p_input )
+            var_Get( p_playlist->p_input, "state", &val );
+
+        if( val.i_int == PAUSE_S )
+        {
+            p_playlist->status.i_status = PLAYLIST_RUNNING;
+            if( p_playlist->p_input )
+            {
+                val.i_int = PLAYING_S;
+                var_Set( p_playlist->p_input, "state", val );
+            }
+        }
+        else
+        {
+            p_playlist->status.i_status = PLAYLIST_PAUSED;
+            if( p_playlist->p_input )
+            {
+                val.i_int = PAUSE_S;
+                var_Set( p_playlist->p_input, "state", val );
+            }
+        }
+        break;
+
+    case PLAYLIST_SKIP:
+        p_playlist->request.p_node = p_playlist->status.p_node;
+        p_playlist->request.p_item = p_playlist->status.p_item;
+        p_playlist->request.i_skip = (int) va_arg( args, int );
+        p_playlist->request.b_request = VLC_TRUE;
+        break;
+
+    default:
+        msg_Err( p_playlist, "unknown playlist query" );
+        return VLC_EBADVAR;
+        break;
+    }
+
+    return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Preparse control
+ *****************************************************************************/
+/** Enqueue an item for preparsing */
+int playlist_PreparseEnqueue( playlist_t *p_playlist,
+                              input_item_t *p_item )
+{
+    vlc_mutex_lock( &p_playlist->p_preparse->object_lock );
+    vlc_gc_incref( p_item );
+    INSERT_ELEM( p_playlist->p_preparse->pp_waiting,
+                 p_playlist->p_preparse->i_waiting,
+                 p_playlist->p_preparse->i_waiting,
+                 p_item );
+    vlc_mutex_unlock( &p_playlist->p_preparse->object_lock );
+    return VLC_SUCCESS;
+}
+
+/** Enqueue a playlist item or a node for peparsing.
+ *  This function should be entered without playlist and preparser locks */
+int playlist_PreparseEnqueueItem( playlist_t *p_playlist,
+                                  playlist_item_t *p_item )
+{
+    vlc_mutex_lock( &p_playlist->object_lock );
+    vlc_mutex_lock( &p_playlist->p_preparse->object_lock );
+    PreparseEnqueueItemSub( p_playlist, p_item );
+    vlc_mutex_unlock( &p_playlist->p_preparse->object_lock );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+    return VLC_SUCCESS;
+}
+
+void PreparseEnqueueItemSub( playlist_t *p_playlist,
+                             playlist_item_t *p_item )
+{
+    int i;
+    if( p_item->i_children == -1 )
+    {
+        vlc_gc_incref( p_item );
+        INSERT_ELEM( p_playlist->p_preparse->pp_waiting,
+                     p_playlist->p_preparse->i_waiting,
+                     p_playlist->p_preparse->i_waiting,
+                     p_item->p_input );
+    }
+    else
+    {
+        for( i = 0; i < p_item->i_children; i++)
+        {
+            PreparseEnqueueItemSub( p_playlist,
+                                             p_item->pp_children[i] );
+        }
+    }
+}
+
+/*****************************************************************************
+ * Playback logic
+ *****************************************************************************/
+
+/** This function calculates the next playlist item, depending
+ *  on the playlist course mode (forward, backward, random, view,...). */
+playlist_item_t * playlist_NextItem( playlist_t *p_playlist )
+{
+    playlist_item_t *p_new = NULL;
+    int i_skip,i;
+
+    vlc_bool_t b_loop = var_GetBool( p_playlist, "loop" );
+    vlc_bool_t b_random = var_GetBool( p_playlist, "random" );
+    vlc_bool_t b_repeat = var_GetBool( p_playlist, "repeat" );
+    vlc_bool_t b_playstop = var_GetBool( p_playlist, "play-and-stop" );
+
+    /* Handle quickly a few special cases */
+
+    /* No items to play */
+    if( p_playlist->i_size == 0 )
+    {
+        msg_Info( p_playlist, "playlist is empty" );
+        return NULL;
+    }
+
+    /* Repeat and play/stop */
+    if( !p_playlist->request.b_request && b_repeat == VLC_TRUE &&
+         p_playlist->status.p_item )
+    {
+        msg_Dbg( p_playlist,"repeating item" );
+        return p_playlist->status.p_item;
+    }
+    if( !p_playlist->request.b_request && b_playstop == VLC_TRUE )
+    {
+        msg_Dbg( p_playlist,"stopping (play and stop)");
+        return NULL;
+    }
+
+    if( !p_playlist->request.b_request && p_playlist->status.p_item &&
+         p_playlist->status.p_item->i_flags & PLAYLIST_SKIP_FLAG )
+    {
+        msg_Dbg( p_playlist, "blocking item, stopping") ;
+        return NULL;
+    }
+
+    /* Random case. This is an exception: if request, but request is skip +- 1
+     * we don't go to next item but select a new random one. */
+    if( b_random )
+        msg_Err( p_playlist, "random unsupported" );
+#if 0
+            &&
+        ( !p_playlist->request.b_request ||
+        ( p_playlist->request.b_request && ( p_playlist->request.p_item == NULL ||
+          p_playlist->request.i_skip == 1 || p_playlist->request.i_skip == -1 ) ) ) )
+    {
+        /* how many items to choose from ? */
+        i_count = 0;
+        for ( i = 0; i < p_playlist->i_size; i++ )
+        {
+            if ( p_playlist->pp_items[i]->p_input->i_nb_played == 0 )
+                i_count++;
+        }
+        /* Nothing left? */
+        if ( i_count == 0 )
+        {
+            /* Don't loop? Exit! */
+            if( !b_loop )
+                return NULL;
+            /* Otherwise reset the counter */
+            for ( i = 0; i < p_playlist->i_size; i++ )
+            {
+                p_playlist->pp_items[i]->p_input->i_nb_played = 0;
+            }
+            i_count = p_playlist->i_size;
+        }
+        srand( (unsigned int)mdate() );
+        i = rand() % i_count + 1 ;
+        /* loop thru the list and count down the unplayed items to the selected one */
+        for ( i_new = 0; i_new < p_playlist->i_size && i > 0; i_new++ )
+        {
+            if ( p_playlist->pp_items[i_new]->p_input->i_nb_played == 0 )
+                i--;
+        }
+        i_new--;
+
+        p_playlist->request.i_skip = 0;
+        p_playlist->request.b_request = VLC_FALSE;
+        return p_playlist->pp_items[i_new];
+    }
+#endif
+
+    /* Start the real work */
+    if( p_playlist->request.b_request )
+    {
+#ifdef PLAYLIST_DEBUG
+        msg_Dbg( p_playlist,"processing request" );
+#endif
+        p_new = p_playlist->request.p_item;
+        i_skip = p_playlist->request.i_skip;
+
+        p_playlist->status.p_node = p_playlist->request.p_node;
+
+        /* If we are asked for a node, take its first item */
+        if( i_skip == 0 &&
+              ( p_new == NULL || p_new->i_children != -1 ) )
+        {
+            i_skip++;
+        }
+
+        if( i_skip > 0 )
+        {
+            for( i = i_skip; i > 0 ; i-- )
+            {
+                p_new = playlist_GetNextEnabledLeaf( p_playlist,
+                                                     p_playlist->request.p_node,
+                                                     p_new );
+                if( p_new == NULL )
+                {
+#ifdef PLAYLIST_DEBUG
+                    msg_Dbg( p_playlist, "looping - restarting at beginning "
+                                         "of node" );
+#endif
+                    p_new = playlist_GetNextLeaf( p_playlist,
+                                                  p_playlist->request.p_node,
+                                                  NULL );
+                    if( p_new == NULL ) break;
+                }
+            }
+        }
+        else if( i_skip < 0 )
+        {
+            for( i = i_skip; i < 0 ; i++ )
+            {
+                p_new = playlist_GetPrevLeaf( p_playlist,
+                                              p_playlist->request.p_node,
+                                              p_new );
+                if( p_new == NULL )
+                {
+#ifdef PLAYLIST_DEBUG
+                    msg_Dbg( p_playlist, "looping - restarting at end "
+                                         "of node" );
+#endif
+                    /** \bug This is needed because GetPrevLeaf does not loop
+                      * by itself */
+                    p_new = playlist_GetLastLeaf( p_playlist,
+                                                 p_playlist->request.p_node );
+                }
+                if( p_new == NULL ) break;
+            }
+        }
+        /* Clear the request */
+        p_playlist->request.b_request = VLC_FALSE;
+    }
+    /* "Automatic" item change ( next ) */
+    else
+    {
+#ifdef PLAYLIST_DEBUG
+        msg_Dbg( p_playlist,"changing item without a request" );
+#endif
+        /* Cant go to next from current item */
+        if( p_playlist->status.p_item &&
+            p_playlist->status.p_item->i_flags & PLAYLIST_SKIP_FLAG )
+            return NULL;
+
+        p_new = playlist_GetNextLeaf( p_playlist,
+                                      p_playlist->status.p_node,
+                                      p_playlist->status.p_item );
+        if( p_new == NULL && b_loop )
+        {
+#ifdef PLAYLIST_DEBUG
+            msg_Dbg( p_playlist, "looping" );
+#endif
+            p_new = playlist_GetNextLeaf( p_playlist,
+                                          p_playlist->status.p_node,
+                                          NULL );
+        }
+        /* The new item can't be autoselected  */
+        if( p_new != NULL && p_new->i_flags & PLAYLIST_SKIP_FLAG )
+            return NULL;
+    }
+    if( p_new == NULL )
+    {
+        msg_Dbg( p_playlist, "did not find something to play" );
+    }
+    return p_new;
+}
+
+/** Start the input for an item */
+int playlist_PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
+{
+    vlc_value_t val;
+    int i_activity = var_GetInteger( p_playlist, "activity") ;
+
+    msg_Dbg( p_playlist, "creating new input thread" );
+
+    p_item->p_input->i_nb_played++;
+    p_playlist->status.p_item = p_item;
+
+    p_playlist->status.i_status = PLAYLIST_RUNNING;
+
+    var_SetInteger( p_playlist, "activity", i_activity +
+                    DEFAULT_INPUT_ACTIVITY );
+    p_playlist->p_input = input_CreateThread( p_playlist, p_item->p_input );
+
+    val.i_int = p_item->p_input->i_id;
+    /* unlock the playlist to set the var...mmm */
+    vlc_mutex_unlock( &p_playlist->object_lock);
+    var_Set( p_playlist, "playlist-current", val);
+    vlc_mutex_lock( &p_playlist->object_lock);
+
+    return VLC_SUCCESS;
+}
diff --git a/src/playlist/engine.c b/src/playlist/engine.c
new file mode 100644 (file)
index 0000000..2d81f6f
--- /dev/null
@@ -0,0 +1,485 @@
+/*****************************************************************************
+ * engine.c : Run the playlist and handle its control
+ *****************************************************************************
+ * Copyright (C) 1999-2004 the VideoLAN team
+ * $Id: /local/vlc/0.8.6-playlist-vlm/src/playlist/playlist.c 13741 2006-03-21T19:29:39.792444Z zorglub  $
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *          Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/vout.h>
+#include <vlc/sout.h>
+#include <vlc/input.h>
+#include "vlc_playlist.h"
+#include "vlc_interaction.h"
+
+#undef PLAYLIST_DEBUG
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static void VariablesInit( playlist_t *p_playlist );
+
+/**
+ * Create playlist
+ *
+ * Create a playlist structure.
+ * \param p_parent the vlc object that is to be the parent of this playlist
+ * \return a pointer to the created playlist, or NULL on error
+ */
+playlist_t * playlist_Create( vlc_object_t *p_parent )
+{
+    playlist_t *p_playlist;
+
+    /* Allocate structure */
+    p_playlist = vlc_object_create( p_parent, VLC_OBJECT_PLAYLIST );
+    if( !p_playlist )
+    {
+        msg_Err( p_parent, "out of memory" );
+        return NULL;
+    }
+
+    VariablesInit( p_playlist );
+
+    /* Initialise data structures */
+    vlc_mutex_init( p_playlist, &p_playlist->gc_lock );
+    p_playlist->i_last_playlist_id = 0;
+    p_playlist->i_last_input_id = 0;
+    p_playlist->p_input = NULL;
+
+    p_playlist->i_size = 0;
+    p_playlist->pp_items = NULL;
+    p_playlist->i_all_size = 0;
+    p_playlist->pp_all_items = NULL;
+
+    p_playlist->i_input_items = 0;
+    p_playlist->pp_input_items = NULL;
+
+    p_playlist->p_root_category = playlist_NodeCreate( p_playlist, NULL, NULL);
+    p_playlist->p_root_onelevel = playlist_NodeCreate( p_playlist, NULL, NULL);
+
+    /* Create playlist and media library */
+    p_playlist->p_local_category = playlist_NodeCreate( p_playlist,
+                                 _( "Playlist" ),p_playlist->p_root_category );
+    p_playlist->p_ml_category =   playlist_NodeCreate( p_playlist,
+                           _( "Media Library" ), p_playlist->p_root_category );
+    p_playlist->p_local_onelevel =  playlist_NodeCreate( p_playlist,
+                                _( "Playlist" ), p_playlist->p_root_onelevel );
+    p_playlist->p_ml_onelevel =  playlist_NodeCreate( p_playlist,
+                           _( "Media Library" ), p_playlist->p_root_onelevel );
+
+    /* This is a hack to find it later. Quite ugly, but I haven't found a
+     * better way */
+    p_playlist->p_local_onelevel->p_input->i_id =
+        p_playlist->p_local_category->p_input->i_id;
+    p_playlist->p_ml_onelevel->p_input->i_id =
+        p_playlist->p_ml_category->p_input->i_id;
+
+    /* Initial status */
+    p_playlist->status.p_item = NULL;
+    p_playlist->status.p_node = p_playlist->p_root_onelevel;
+    p_playlist->request.b_request = VLC_FALSE;
+    p_playlist->status.i_status = PLAYLIST_STOPPED;
+
+    p_playlist->i_sort = SORT_ID;
+    p_playlist->i_order = ORDER_NORMAL;
+
+    vlc_object_attach( p_playlist, p_parent );
+    return p_playlist;
+}
+
+void playlist_Destroy( playlist_t *p_playlist )
+{
+    while( p_playlist->i_sds )
+    {
+        playlist_ServicesDiscoveryRemove( p_playlist,
+                                          p_playlist->pp_sds[0]->psz_module );
+    }
+    vlc_thread_join( p_playlist->p_preparse );
+    vlc_thread_join( p_playlist );
+
+    vlc_object_detach( p_playlist->p_preparse );
+
+    var_Destroy( p_playlist, "intf-change" );
+    var_Destroy( p_playlist, "item-change" );
+    var_Destroy( p_playlist, "playlist-current" );
+    var_Destroy( p_playlist, "intf-popmenu" );
+    var_Destroy( p_playlist, "intf-show" );
+    var_Destroy( p_playlist, "play-and-stop" );
+    var_Destroy( p_playlist, "random" );
+    var_Destroy( p_playlist, "repeat" );
+    var_Destroy( p_playlist, "loop" );
+    var_Destroy( p_playlist, "activity" );
+
+    playlist_LockClear( p_playlist );
+
+    if( p_playlist->p_stats )
+        free( p_playlist->p_stats );
+
+    vlc_mutex_destroy( &p_playlist->gc_lock );
+    vlc_object_destroy( p_playlist->p_preparse );
+    vlc_object_destroy( p_playlist );
+
+}
+/* Destroy remaining objects */
+static mtime_t ObjectGarbageCollector( playlist_t *p_playlist, int i_type,
+                                       mtime_t destroy_date )
+{
+    vlc_object_t *p_obj;
+
+    if( destroy_date > mdate() ) return destroy_date;
+
+    if( destroy_date == 0 )
+    {
+        /* give a little time */
+        return mdate() + I64C(1000000);
+    }
+    else
+    {
+        vlc_mutex_lock( &p_playlist->gc_lock );
+        while( ( p_obj = vlc_object_find( p_playlist, i_type, FIND_CHILD ) ) )
+        {
+            if( p_obj->p_parent != (vlc_object_t*)p_playlist )
+            {
+                /* only first child (ie unused) */
+                vlc_object_release( p_obj );
+                break;
+            }
+            if( i_type == VLC_OBJECT_VOUT )
+            {
+                msg_Dbg( p_playlist, "garbage collector destroying 1 vout" );
+                vlc_object_detach( p_obj );
+                vlc_object_release( p_obj );
+                vout_Destroy( (vout_thread_t *)p_obj );
+            }
+            else if( i_type == VLC_OBJECT_SOUT )
+            {
+                vlc_object_release( p_obj );
+                sout_DeleteInstance( (sout_instance_t*)p_obj );
+            }
+        }
+        vlc_mutex_unlock( &p_playlist->gc_lock );
+        return 0;
+    }
+}
+
+/** Main loop for the playlist */
+void playlist_MainLoop( playlist_t *p_playlist )
+{
+    playlist_item_t *p_item = NULL;
+
+    mtime_t    i_vout_destroyed_date = 0;
+    mtime_t    i_sout_destroyed_date = 0;
+
+    PL_LOCK
+
+    /* First, check if we have something to do */
+    /* FIXME : this can be called several times */
+    if( p_playlist->request.b_request )
+    {
+#ifdef PLAYLIST_DEBUG
+        msg_Dbg(p_playlist, "incoming request - stopping current input" );
+#endif
+        /* Stop the existing input */
+        if( p_playlist->p_input )
+        {
+            input_StopThread( p_playlist->p_input );
+        }
+    }
+
+    /* If there is an input, check that it doesn't need to die. */
+    if( p_playlist->p_input )
+    {
+        /* This input is dead. Remove it ! */
+        if( p_playlist->p_input->b_dead )
+        {
+            int i_activity;
+            input_thread_t *p_input;
+
+            p_input = p_playlist->p_input;
+            p_playlist->p_input = NULL;
+
+            /* Release the playlist lock, because we may get stuck
+             * in input_DestroyThread() for some time. */
+            PL_UNLOCK
+
+            /* Destroy input */
+            input_DestroyThread( p_input );
+
+            /* Unlink current input
+             * (_after_ input_DestroyThread for vout garbage collector) */
+            vlc_object_detach( p_input );
+
+            /* Destroy object */
+            vlc_object_destroy( p_input );
+
+            i_vout_destroyed_date = 0;
+            i_sout_destroyed_date = 0;
+
+            if( p_playlist->status.p_item->i_flags
+                & PLAYLIST_REMOVE_FLAG )
+            {
+                 playlist_ItemDelete( p_playlist->status.p_item );
+                 p_playlist->status.p_item = NULL;
+            }
+
+            i_activity= var_GetInteger( p_playlist, "activity") ;
+            var_SetInteger( p_playlist, "activity", i_activity -
+                            DEFAULT_INPUT_ACTIVITY );
+
+            return;
+        }
+        /* This input is dying, let it do */
+        else if( p_playlist->p_input->b_die )
+        {
+            ;
+        }
+        /* This input has finished, ask it to die ! */
+        else if( p_playlist->p_input->b_error
+                  || p_playlist->p_input->b_eof )
+        {
+            input_StopThread( p_playlist->p_input );
+            /* Select the next playlist item */
+            PL_UNLOCK
+            return;
+        }
+        else if( p_playlist->p_input->i_state != INIT_S )
+        {
+            PL_UNLOCK
+            i_vout_destroyed_date =
+                ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT,
+                                        i_vout_destroyed_date );
+            i_sout_destroyed_date =
+                ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT,
+                                        i_sout_destroyed_date );
+            PL_LOCK
+        }
+    }
+    else
+    {
+        /* No input. Several cases
+         *  - No request, running status -> start new item
+         *  - No request, stopped status -> collect garbage
+         *  - Request, running requested -> start new item
+         *  - Request, stopped requested -> collect garbage
+         */
+         if( (!p_playlist->request.b_request &&
+              p_playlist->status.i_status != PLAYLIST_STOPPED) ||
+              ( p_playlist->request.b_request &&
+                p_playlist->request.i_status != PLAYLIST_STOPPED ) )
+         {
+             msg_Dbg( p_playlist, "Starting new item" );
+             stats_TimerStart( p_playlist, "Playlist walk",
+                                  STATS_TIMER_PLAYLIST_WALK );
+             p_item = playlist_NextItem( p_playlist );
+             stats_TimerStop( p_playlist, STATS_TIMER_PLAYLIST_WALK );
+
+             if( p_item == NULL )
+             {
+                msg_Dbg( p_playlist, "nothing to play" );
+                p_playlist->status.i_status = PLAYLIST_STOPPED;
+                PL_UNLOCK
+                return;
+             }
+             playlist_PlayItem( p_playlist, p_item );
+         }
+         else
+         {
+             if( p_item && p_playlist->status.p_item &&
+                 p_playlist->status.p_item->i_flags & PLAYLIST_REMOVE_FLAG )
+             {
+                 playlist_ItemDelete( p_item );
+                 p_playlist->status.p_item = NULL;
+             }
+
+             /* Collect garbage */
+             PL_UNLOCK
+             i_sout_destroyed_date =
+             ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT, mdate() );
+             i_vout_destroyed_date =
+             ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT, mdate() );
+             PL_LOCK
+         }
+    }
+    PL_UNLOCK
+}
+
+/** Playlist dying last loop */
+void playlist_LastLoop( playlist_t *p_playlist )
+{
+    vlc_object_t *p_obj;
+
+    /* If there is an input, kill it */
+    while( 1 )
+    {
+        PL_LOCK
+
+        if( p_playlist->p_input == NULL )
+        {
+            PL_UNLOCK
+            break;
+        }
+
+        if( p_playlist->p_input->b_dead )
+        {
+            input_thread_t *p_input;
+
+            /* Unlink current input */
+            p_input = p_playlist->p_input;
+            p_playlist->p_input = NULL;
+            PL_UNLOCK
+
+            /* Destroy input */
+            input_DestroyThread( p_input );
+            /* Unlink current input (_after_ input_DestroyThread for vout
+             * garbage collector)*/
+            vlc_object_detach( p_input );
+
+            /* Destroy object */
+            vlc_object_destroy( p_input );
+            continue;
+        }
+        else if( p_playlist->p_input->b_die )
+        {
+            /* This input is dying, leave it alone */
+            ;
+        }
+        else if( p_playlist->p_input->b_error || p_playlist->p_input->b_eof )
+        {
+            input_StopThread( p_playlist->p_input );
+            PL_UNLOCK
+            continue;
+        }
+        else
+        {
+            p_playlist->p_input->b_eof = 1;
+        }
+
+        PL_UNLOCK
+
+        msleep( INTF_IDLE_SLEEP );
+    }
+
+    /* close all remaining sout */
+    while( ( p_obj = vlc_object_find( p_playlist,
+                                      VLC_OBJECT_SOUT, FIND_CHILD ) ) )
+    {
+        vlc_object_release( p_obj );
+        sout_DeleteInstance( (sout_instance_t*)p_obj );
+    }
+
+    /* close all remaining vout */
+    while( ( p_obj = vlc_object_find( p_playlist,
+                                      VLC_OBJECT_VOUT, FIND_CHILD ) ) )
+    {
+        vlc_object_detach( p_obj );
+        vlc_object_release( p_obj );
+        vout_Destroy( (vout_thread_t *)p_obj );
+    }
+}
+
+/** Main loop for preparser queue */
+void playlist_PreparseLoop( playlist_preparse_t *p_obj )
+{
+    playlist_t *p_playlist = (playlist_t *)p_obj->p_parent;
+    int i_activity;
+
+    vlc_mutex_lock( &p_obj->object_lock );
+
+    if( p_obj->i_waiting > 0 )
+    {
+        input_item_t *p_current = p_playlist->p_preparse->pp_waiting[0];
+        REMOVE_ELEM( p_obj->pp_waiting, p_obj->i_waiting, 0 );
+        vlc_mutex_unlock( &p_obj->object_lock );
+        vlc_mutex_lock( &p_playlist->object_lock );
+        if( p_current )
+        {
+            vlc_bool_t b_preparsed = VLC_FALSE;
+            if( strncmp( p_current->psz_uri, "http:", 5 ) &&
+                strncmp( p_current->psz_uri, "rtsp:", 5 ) &&
+                strncmp( p_current->psz_uri, "udp:", 4 ) &&
+                strncmp( p_current->psz_uri, "mms:", 4 ) &&
+                strncmp( p_current->psz_uri, "cdda:", 4 ) &&
+                strncmp( p_current->psz_uri, "dvd:", 4 ) &&
+                strncmp( p_current->psz_uri, "v4l:", 4 ) &&
+                strncmp( p_current->psz_uri, "dshow:", 6 ) )
+            {
+                b_preparsed = VLC_TRUE;
+                stats_TimerStart( p_playlist, "Preparse run",
+                                  STATS_TIMER_PREPARSE );
+                input_Preparse( p_playlist, p_current );
+                stats_TimerStop( p_playlist, STATS_TIMER_PREPARSE );
+            }
+            vlc_mutex_unlock( &p_playlist->object_lock );
+            if( b_preparsed )
+            {
+                var_SetInteger( p_playlist, "item-change",
+                                p_current->i_id );
+            }
+            vlc_gc_decref( p_current );
+        }
+        else
+        {
+            vlc_mutex_unlock( &p_playlist->object_lock );
+        }
+        vlc_mutex_lock( &p_obj->object_lock );
+        i_activity=  var_GetInteger( p_playlist, "activity" );
+        if( i_activity < 0 ) i_activity = 0;
+        msleep( (i_activity+1) * 1000 );
+    }
+
+    vlc_mutex_unlock( &p_obj->object_lock );
+}
+
+static void VariablesInit( playlist_t *p_playlist )
+{
+    vlc_value_t val;
+    /* These variables control updates */
+    var_Create( p_playlist, "intf-change", VLC_VAR_BOOL );
+    val.b_bool = VLC_TRUE;
+    var_Set( p_playlist, "intf-change", val );
+
+    var_Create( p_playlist, "item-change", VLC_VAR_INTEGER );
+    val.i_int = -1;
+    var_Set( p_playlist, "item-change", val );
+
+    var_Create( p_playlist, "item-deleted", VLC_VAR_INTEGER );
+    val.i_int = -1;
+    var_Set( p_playlist, "item-deleted", val );
+
+    var_Create( p_playlist, "item-append", VLC_VAR_ADDRESS );
+
+    var_Create( p_playlist, "playlist-current", VLC_VAR_INTEGER );
+    val.i_int = -1;
+    var_Set( p_playlist, "playlist-current", val );
+
+    var_Create( p_playlist, "intf-popupmenu", VLC_VAR_BOOL );
+
+    var_Create( p_playlist, "intf-show", VLC_VAR_BOOL );
+    val.b_bool = VLC_TRUE;
+    var_Set( p_playlist, "intf-show", val );
+
+    var_Create( p_playlist, "activity", VLC_VAR_INTEGER );
+    var_SetInteger( p_playlist, "activity", 0 );
+
+    /* Variables to control playback */
+    var_CreateGetBool( p_playlist, "play-and-stop" );
+    var_CreateGetBool( p_playlist, "random" );
+    var_CreateGetBool( p_playlist, "repeat" );
+    var_CreateGetBool( p_playlist, "loop" );
+}
diff --git a/src/playlist/item-ext.c b/src/playlist/item-ext.c
deleted file mode 100644 (file)
index 6b6830a..0000000
+++ /dev/null
@@ -1,931 +0,0 @@
-/*****************************************************************************
- * item-ext.c : Playlist item management functions (act on the playlist)
- *****************************************************************************
- * Copyright (C) 1999-2004 the VideoLAN team
- * $Id$
- *
- * Authors: Samuel Hocevar <sam@zoy.org>
- *          Clément Stenac <zorglub@videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#include <stdlib.h>                                      /* free(), strtol() */
-#include <stdio.h>                                              /* sprintf() */
-#include <string.h>                                            /* strerror() */
-
-#include <vlc/vlc.h>
-#include <vlc/input.h>
-
-#include "vlc_playlist.h"
-
-/***************************************************************************
- * Item creation/addition functions
- ***************************************************************************/
-
-/**
- * Add a MRL into the playlist, duration and options given
- *
- * \param p_playlist the playlist to add into
- * \param psz_uri the mrl to add to the playlist
- * \param psz_name a text giving a name or description of this item
- * \param i_mode the mode used when adding
- * \param i_pos the position in the playlist where to add. If this is
- *        PLAYLIST_END the item will be added at the end of the playlist
- *        regardless of it's size
- * \param i_duration length of the item in milliseconds.
- * \param ppsz_options an array of options
- * \param i_options the number of options
- * \return The id of the playlist item
-*/
-int playlist_AddExt( playlist_t *p_playlist, const char * psz_uri,
-                     const char *psz_name, int i_mode, int i_pos,
-                     mtime_t i_duration, const char **ppsz_options,
-                     int i_options )
-{
-    playlist_item_t *p_item;
-    p_item = playlist_ItemNew( p_playlist , psz_uri, psz_name );
-
-    if( p_item == NULL )
-    {
-        msg_Err( p_playlist, "unable to add item to playlist" );
-        return -1;
-    }
-
-    p_item->input.i_duration = i_duration;
-    p_item->input.i_options = i_options;
-    p_item->input.ppsz_options = NULL;
-
-    for( p_item->input.i_options = 0; p_item->input.i_options < i_options;
-         p_item->input.i_options++ )
-    {
-        if( !p_item->input.i_options )
-        {
-            p_item->input.ppsz_options = malloc( i_options * sizeof(char *) );
-            if( !p_item->input.ppsz_options ) break;
-        }
-
-        p_item->input.ppsz_options[p_item->input.i_options] =
-            strdup( ppsz_options[p_item->input.i_options] );
-    }
-
-    return playlist_AddItem( p_playlist, p_item, i_mode, i_pos );
-}
-
-/**
- * Add a MRL into the playlist.
- *
- * \param p_playlist the playlist to add into
- * \param psz_uri the mrl to add to the playlist
- * \param psz_name a text giving a name or description of this item
- * \param i_mode the mode used when adding
- * \param i_pos the position in the playlist where to add. If this is
- *        PLAYLIST_END the item will be added at the end of the playlist
- *        regardless of it's size
- * \return The id of the playlist item
-*/
-int playlist_Add( playlist_t *p_playlist, const char *psz_uri,
-                  const char *psz_name, int i_mode, int i_pos )
-{
-    return playlist_AddExt( p_playlist, psz_uri, psz_name, i_mode, i_pos,
-                            -1, NULL, 0 );
-}
-
-/**
- * Add a playlist item into a playlist
- *
- * \param p_playlist the playlist to insert into
- * \param p_item the playlist item to insert
- * \param i_mode the mode used when adding
- * \param i_pos the possition in the playlist where to add. If this is
- *        PLAYLIST_END the item will be added at the end of the playlist
- *        regardless of it's size
- * \return The id of the playlist item
- */
-int playlist_AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
-                      int i_mode, int i_pos)
-{
-    vlc_value_t val;
-    vlc_bool_t b_end = VLC_FALSE;
-    playlist_view_t *p_view = NULL;
-
-    playlist_add_t *p_add = (playlist_add_t *)malloc(sizeof( playlist_add_t));
-
-    vlc_mutex_lock( &p_playlist->object_lock );
-
-    /*
-     * CHECK_INSERT : checks if the item is already enqued before
-     * enqueing it
-     */
-
-    /* That should not change */
-    if ( i_mode & PLAYLIST_CHECK_INSERT )
-    {
-         int j;
-
-        if ( p_playlist->pp_items )
-        {
-            for ( j = 0; j < p_playlist->i_size; j++ )
-            {
-                if ( !strcmp( p_playlist->pp_items[j]->input.psz_uri,
-                               p_item->input.psz_uri ) )
-                {
-                    playlist_ItemDelete( p_item );
-                    vlc_mutex_unlock( &p_playlist->object_lock );
-                    return -1;
-                }
-             }
-         }
-         i_mode &= ~PLAYLIST_CHECK_INSERT;
-         i_mode |= PLAYLIST_APPEND;
-    }
-
-    msg_Dbg( p_playlist, "adding playlist item `%s' ( %s )",
-             p_item->input.psz_name, p_item->input.psz_uri );
-
-    p_item->input.i_id = ++p_playlist->i_last_id;
-
-    /* Do a few boundary checks and allocate space for the item */
-    if( i_pos == PLAYLIST_END )
-    {
-        b_end = VLC_TRUE;
-        if( i_mode & PLAYLIST_INSERT )
-        {
-            i_mode &= ~PLAYLIST_INSERT;
-            i_mode |= PLAYLIST_APPEND;
-        }
-
-        i_pos = p_playlist->i_size - 1;
-    }
-
-    if( !(i_mode & PLAYLIST_REPLACE)
-         || i_pos < 0 || i_pos >= p_playlist->i_size )
-    {
-        /* Additional boundary checks */
-        if( i_mode & PLAYLIST_APPEND )
-        {
-            i_pos++;
-        }
-
-        if( i_pos < 0 )
-        {
-            i_pos = 0;
-        }
-        else if( i_pos > p_playlist->i_size )
-        {
-            i_pos = p_playlist->i_size;
-        }
-
-        INSERT_ELEM( p_playlist->pp_items, p_playlist->i_size, i_pos, p_item );
-        INSERT_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size,
-                     p_playlist->i_all_size, p_item );
-        p_playlist->i_enabled ++;
-
-        /* We update the ALL view directly */
-        playlist_ViewUpdate( p_playlist, VIEW_ALL );
-
-        /* Add the item to the General category */
-        if( b_end == VLC_TRUE )
-        {
-            playlist_NodeAppend( p_playlist, VIEW_CATEGORY, p_item,
-                                 p_playlist->p_general );
-            p_add->i_item = p_item->input.i_id;
-            p_add->i_node = p_playlist->p_general->input.i_id;
-            p_add->i_view = VIEW_CATEGORY;
-            val.p_address = p_add;
-            var_Set( p_playlist, "item-append", val );
-        }
-        else
-        {
-            playlist_NodeInsert( p_playlist, VIEW_CATEGORY, p_item,
-                                 p_playlist->p_general, i_pos );
-        }
-
-
-        p_view = playlist_ViewFind( p_playlist, VIEW_ALL );
-        playlist_ItemAddParent( p_item, VIEW_ALL, p_view->p_root );
-
-        /* FIXME : Update sorted views */
-
-        if( p_playlist->i_index >= i_pos )
-        {
-            p_playlist->i_index++;
-        }
-    }
-    else
-    {
-        msg_Err( p_playlist, "Insert mode not implemented" );
-    }
-
-    if( (i_mode & PLAYLIST_GO ) && p_view )
-    {
-        p_playlist->request.b_request = VLC_TRUE;
-        /* FIXME ... */
-        p_playlist->request.i_view = VIEW_CATEGORY;
-        p_playlist->request.p_node = p_view->p_root;
-        p_playlist->request.p_item = p_item;
-
-        if( p_playlist->p_input )
-        {
-            input_StopThread( p_playlist->p_input );
-        }
-        p_playlist->status.i_status = PLAYLIST_RUNNING;
-    }
-
-    if( i_mode & PLAYLIST_PREPARSE &&
-        var_CreateGetBool( p_playlist, "auto-preparse" ) )
-    {
-        playlist_PreparseEnqueue( p_playlist, &p_item->input );
-    }
-
-    vlc_mutex_unlock( &p_playlist->object_lock );
-
-    if( b_end == VLC_FALSE )
-    {
-        val.b_bool = VLC_TRUE;
-        var_Set( p_playlist, "intf-change", val );
-    }
-
-    free( p_add );
-
-    return p_item->input.i_id;
-}
-
-
-/**
- * Add a playlist item to a given node (in the category view )
- *
- * \param p_playlist the playlist to insert into
- * \param p_item the playlist item to insert
- * \param i_view the view for which to add or TODO: ALL_VIEWS
- * \param p_parent the parent node
- * \param i_mode the mode used when adding
- * \param i_pos the possition in the node where to add. If this is
- *        PLAYLIST_END the item will be added at the end of the node
- ** \return The id of the playlist item
- */
-int playlist_NodeAddItem( playlist_t *p_playlist, playlist_item_t *p_item,
-                          int i_view,playlist_item_t *p_parent,
-                          int i_mode, int i_pos)
-{
-    vlc_value_t val;
-    int i_position;
-    playlist_view_t *p_view;
-
-    playlist_add_t *p_add = (playlist_add_t *)malloc(sizeof( playlist_add_t));
-
-    vlc_mutex_lock( &p_playlist->object_lock );
-
-    if ( i_pos == PLAYLIST_END ) i_pos = -1;
-
-    /* Sanity checks */
-    if( !p_parent || p_parent->i_children == -1 )
-    {
-        msg_Err( p_playlist, "invalid node" );
-    }
-
-    /*
-     * CHECK_INSERT : checks if the item is already enqued before
-     * enqueing it
-     */
-    if ( i_mode & PLAYLIST_CHECK_INSERT )
-    {
-         int j;
-
-        if ( p_playlist->pp_items )
-        {
-            for ( j = 0; j < p_playlist->i_size; j++ )
-            {
-                if ( !strcmp( p_playlist->pp_items[j]->input.psz_uri,
-                              p_item->input.psz_uri ) )
-                {
-                    playlist_ItemDelete( p_item );
-                    vlc_mutex_unlock( &p_playlist->object_lock );
-                    free( p_add );
-                    return -1;
-                }
-            }
-        }
-        i_mode &= ~PLAYLIST_CHECK_INSERT;
-        i_mode |= PLAYLIST_APPEND;
-    }
-
-    msg_Dbg( p_playlist, "adding playlist item `%s' ( %s )",
-             p_item->input.psz_name, p_item->input.psz_uri );
-
-    p_item->input.i_id = ++p_playlist->i_last_id;
-
-    /* First, add the item at the right position in the item bank */
-    /* WHY THAT ? */
-     //i_position = p_playlist->i_index == -1 ? 0 : p_playlist->i_index;
-    i_position = p_playlist->i_size ;
-
-    INSERT_ELEM( p_playlist->pp_items,
-                 p_playlist->i_size,
-                 i_position,
-                 p_item );
-    INSERT_ELEM( p_playlist->pp_all_items,
-                 p_playlist->i_all_size,
-                 p_playlist->i_all_size,
-                 p_item );
-    p_playlist->i_enabled ++;
-
-    /* TODO: Handle modes */
-    playlist_NodeInsert( p_playlist, i_view, p_item, p_parent, i_pos );
-
-    p_add->i_item = p_item->input.i_id;
-    p_add->i_node = p_parent->input.i_id;
-    p_add->i_view = i_view;
-    val.p_address = p_add;
-    var_Set( p_playlist, "item-append", val );
-
-    /* We update the ALL view directly */
-    p_view = playlist_ViewFind( p_playlist, VIEW_ALL );
-    playlist_ItemAddParent( p_item, VIEW_ALL, p_view->p_root );
-    playlist_ViewUpdate( p_playlist, VIEW_ALL );
-
-    /* TODO : Update sorted views*/
-
-    if( i_mode & PLAYLIST_GO )
-    {
-        p_playlist->request.b_request = VLC_TRUE;
-        p_playlist->request.i_view = VIEW_CATEGORY;
-        p_playlist->request.p_node = p_parent;
-        p_playlist->request.p_item = p_item;
-        if( p_playlist->p_input )
-        {
-            input_StopThread( p_playlist->p_input );
-        }
-        p_playlist->status.i_status = PLAYLIST_RUNNING;
-    }
-    if( i_mode & PLAYLIST_PREPARSE &&
-        var_CreateGetBool( p_playlist, "auto-preparse" ) )
-    {
-        playlist_PreparseEnqueue( p_playlist, &p_item->input );
-    }
-
-    vlc_mutex_unlock( &p_playlist->object_lock );
-
-    val.b_bool = VLC_TRUE;
-//    var_Set( p_playlist, "intf-change", val );
-//
-    free( p_add );
-
-    return p_item->input.i_id;
-}
-
-/***************************************************************************
- * Item search functions
- ***************************************************************************/
-
-/**
- * Search the position of an item by its id
- * This function must be entered with the playlist lock
- *
- * \param p_playlist the playlist
- * \param i_id the id to find
- * \return the position, or VLC_EGENERIC on failure
- */
-int playlist_GetPositionById( playlist_t * p_playlist , int i_id )
-{
-    int i;
-    for( i =  0 ; i < p_playlist->i_size ; i++ )
-    {
-        if( p_playlist->pp_items[i]->input.i_id == i_id )
-        {
-            return i;
-        }
-    }
-    return VLC_EGENERIC;
-}
-
-
-/**
- * Search an item by its position
- * This function must be entered with the playlist lock
- *
- * \param p_playlist the playlist
- * \param i_pos the position of the item to find
- * \return the item, or NULL on failure
- */
-playlist_item_t * playlist_ItemGetByPos( playlist_t * p_playlist , int i_pos )
-{
-    if( i_pos >= 0 && i_pos < p_playlist->i_size)
-    {
-        return p_playlist->pp_items[i_pos];
-    }
-    else if( p_playlist->i_size > 0)
-    {
-        return p_playlist->pp_items[p_playlist->i_index];
-    }
-    else
-    {
-        return NULL;
-    }
-}
-
-playlist_item_t *playlist_LockItemGetByPos( playlist_t *p_playlist, int i_pos )
-{
-    playlist_item_t *p_ret;
-    vlc_mutex_lock( &p_playlist->object_lock );
-    p_ret = playlist_ItemGetByPos( p_playlist, i_pos );
-    vlc_mutex_unlock( &p_playlist->object_lock );
-    return p_ret;
-}
-
-/**
- * Search an item by its id
- *
- * \param p_playlist the playlist
- * \param i_id the id to find
- * \return the item, or NULL on failure
- */
-playlist_item_t * playlist_ItemGetById( playlist_t * p_playlist , int i_id )
-{
-    int i, i_top, i_bottom;
-    i_bottom = 0; i_top = p_playlist->i_all_size - 1;
-    i = i_top / 2;
-    while( p_playlist->pp_all_items[i]->input.i_id != i_id &&
-           i_top > i_bottom )
-    {
-        if( p_playlist->pp_all_items[i]->input.i_id < i_id )
-        {
-            i_bottom = i + 1;
-        }
-        else
-        {
-            i_top = i - 1;
-        }
-        i = i_bottom + ( i_top - i_bottom ) / 2;
-    }
-    if( p_playlist->pp_all_items[i]->input.i_id == i_id )
-    {
-        return p_playlist->pp_all_items[i];
-    }
-    return NULL;
-}
-
-playlist_item_t *playlist_LockItemGetById( playlist_t *p_playlist, int i_id)
-{
-    playlist_item_t *p_ret;
-    vlc_mutex_lock( &p_playlist->object_lock );
-    p_ret = playlist_ItemGetById( p_playlist, i_id );
-    vlc_mutex_unlock( &p_playlist->object_lock );
-    return p_ret;
-}
-
-/**
- * Search an item by its input_item_t
- *
- * \param p_playlist the playlist
- * \param p_item the input_item_t to find
- * \return the item, or NULL on failure
- */
-playlist_item_t * playlist_ItemGetByInput( playlist_t * p_playlist ,
-                                           input_item_t *p_item )
-{
-    int i;
-    if( &p_playlist->status.p_item->input == p_item )
-    {
-        return p_playlist->status.p_item;
-    }
-
-    for( i =  0 ; i < p_playlist->i_size ; i++ )
-    {
-        if( &p_playlist->pp_items[i]->input == p_item )
-        {
-            return p_playlist->pp_items[i];
-        }
-    }
-    return NULL;
-}
-
-playlist_item_t *playlist_LockItemGetByInput( playlist_t *p_playlist,
-                                               input_item_t *p_item )
-{
-    playlist_item_t *p_ret;
-    vlc_mutex_lock( &p_playlist->object_lock );
-    p_ret = playlist_ItemGetByInput( p_playlist, p_item );
-    vlc_mutex_unlock( &p_playlist->object_lock );
-    return p_ret;
-}
-
-
-/***********************************************************************
- * Misc functions
- ***********************************************************************/
-
-/**
- * Transform an item to a node
- *
- * This function must be entered without the playlist lock
- *
- * \param p_playlist the playlist object
- * \param p_item the item to transform
- * \return nothing
- */
-int playlist_ItemToNode( playlist_t *p_playlist,playlist_item_t *p_item )
-{
-    int i = 0;
-    if( p_item->i_children == -1 )
-    {
-        p_item->i_children = 0;
-    }
-
-    /* Remove it from the array of available items */
-    for( i = 0 ; i < p_playlist->i_size ; i++ )
-    {
-        if( p_item == p_playlist->pp_items[i] )
-        {
-            REMOVE_ELEM( p_playlist->pp_items, p_playlist->i_size, i );
-        }
-    }
-    var_SetInteger( p_playlist, "item-change", p_item->input.i_id );
-
-    return VLC_SUCCESS;
-}
-
-int playlist_LockItemToNode( playlist_t *p_playlist, playlist_item_t *p_item )
-{
-    int i_ret;
-    vlc_mutex_lock( &p_playlist->object_lock );
-    i_ret = playlist_ItemToNode( p_playlist, p_item );
-    vlc_mutex_unlock( &p_playlist->object_lock );
-    return i_ret;
-}
-
-/**
- * Replaces an item with another one
- * This function must be entered without the playlist lock
- *
- * \see playlist_Replace
- */
-int playlist_LockReplace( playlist_t *p_playlist,
-                             playlist_item_t *p_olditem,
-                             input_item_t *p_new )
-{
-    int i_ret;
-    vlc_mutex_lock( &p_playlist->object_lock );
-    i_ret = playlist_Replace( p_playlist, p_olditem, p_new );
-    vlc_mutex_unlock( &p_playlist->object_lock );
-    return i_ret;
-}
-
-/**
- * Replaces an item with another one
- * This function must be entered with the playlist lock:
- *
- * \param p_playlist the playlist
- * \param p_olditem the item to replace
- * \param p_new the new input_item
- * \return VLC_SUCCESS or an error
- */
-int playlist_Replace( playlist_t *p_playlist, playlist_item_t *p_olditem,
-                       input_item_t *p_new )
-{
-    int i;
-    int j;
-
-    if( p_olditem->i_children != -1 )
-    {
-        msg_Err( p_playlist, "playlist_Replace can only be used on leafs");
-        return VLC_EGENERIC;
-    }
-
-    p_olditem->i_nb_played = 0;
-    memcpy( &p_olditem->input, p_new, sizeof( input_item_t ) );
-
-    p_olditem->i_nb_played = 0;
-
-    for( i = 0 ; i< p_olditem->i_parents ; i++ )
-    {
-        playlist_item_t *p_parent = p_olditem->pp_parents[i]->p_parent;
-
-        for( j = 0 ; j< p_parent->i_children ; i++ )
-        {
-            if( p_parent->pp_children[j] == p_olditem )
-            {
-                p_parent->i_serial++;
-            }
-        }
-    }
-    return VLC_SUCCESS;
-}
-
-/**
- * Deletes an item from a playlist.
- *
- * This function must be entered without the playlist lock
- *
- * \param p_playlist the playlist to remove from.
- * \param i_id the identifier of the item to delete
- * \return returns VLC_SUCCESS or an error
- */
-int playlist_Delete( playlist_t * p_playlist, int i_id )
-{
-    int i, i_top, i_bottom;
-    int i_pos;
-    vlc_bool_t b_flag = VLC_FALSE;
-
-    playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id );
-
-    if( p_item == NULL )
-    {
-        return VLC_EGENERIC;
-    }
-    if( p_item->i_children > -1 )
-    {
-        return playlist_NodeDelete( p_playlist, p_item, VLC_TRUE, VLC_FALSE );
-    }
-
-    var_SetInteger( p_playlist, "item-deleted", i_id );
-
-    i_bottom = 0; i_top = p_playlist->i_all_size - 1;
-    i = i_top / 2;
-    while( p_playlist->pp_all_items[i]->input.i_id != i_id &&
-           i_top > i_bottom )
-    {
-        if( p_playlist->pp_all_items[i]->input.i_id < i_id )
-        {
-            i_bottom = i + 1;
-        }
-        else
-        {
-            i_top = i - 1;
-        }
-        i = i_bottom + ( i_top - i_bottom ) / 2;
-    }
-    if( p_playlist->pp_all_items[i]->input.i_id == i_id )
-    {
-        REMOVE_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size, i );
-    }
-
-    /* Check if it is the current item */
-    if( p_playlist->status.p_item == p_item )
-    {
-        /* Hack we don't call playlist_Control for lock reasons */
-        p_playlist->status.i_status = PLAYLIST_STOPPED;
-        p_playlist->request.b_request = VLC_TRUE;
-        p_playlist->request.p_item = NULL;
-        msg_Info( p_playlist, "stopping playback" );
-        b_flag = VLC_TRUE;
-    }
-
-    /* Get position and update index if needed */
-    i_pos = playlist_GetPositionById( p_playlist, i_id );
-
-    if( i_pos >= 0 && i_pos <= p_playlist->i_index )
-    {
-        p_playlist->i_index--;
-    }
-
-    msg_Dbg( p_playlist, "deleting playlist item `%s'",
-                          p_item->input.psz_name );
-
-    /* Remove the item from all its parent nodes */
-    for ( i= 0 ; i < p_item->i_parents ; i++ )
-    {
-        playlist_NodeRemoveItem( p_playlist, p_item,
-                                 p_item->pp_parents[i]->p_parent );
-        if( p_item->pp_parents[i]->i_view == VIEW_ALL )
-        {
-            p_playlist->i_size--;
-        }
-    }
-
-    /* TODO : Update views */
-
-    if( b_flag == VLC_FALSE )
-        playlist_ItemDelete( p_item );
-    else
-        p_item->i_flags |= PLAYLIST_REMOVE_FLAG;
-
-    return VLC_SUCCESS;
-}
-
-int playlist_LockDelete( playlist_t * p_playlist, int i_id )
-{
-    int i_ret;
-    vlc_mutex_lock( &p_playlist->object_lock );
-    i_ret = playlist_Delete( p_playlist, i_id );
-    vlc_mutex_unlock( &p_playlist->object_lock );
-    return i_ret;
-}
-
-/**
- * Clear all playlist items
- *
- * \param p_playlist the playlist to be cleared.
- * \return returns 0
- */
-int playlist_Clear( playlist_t * p_playlist )
-{
-    int i;
-    for( i = p_playlist->i_size; i > 0 ; i-- )
-    {
-        playlist_Delete( p_playlist, p_playlist->pp_items[0]->input.i_id );
-    }
-    for( i = 0 ; i< p_playlist->i_views; i++ )
-    {
-        playlist_ViewEmpty( p_playlist, i, VLC_TRUE );
-    }
-    return VLC_SUCCESS;
-}
-
-int playlist_LockClear( playlist_t *p_playlist )
-{
-    int i_ret;
-    vlc_mutex_lock( &p_playlist->object_lock );
-    i_ret = playlist_Clear( p_playlist );
-    vlc_mutex_unlock( &p_playlist->object_lock );
-    return i_ret;
-}
-
-
-/**
- * Disables a playlist item
- *
- * \param p_playlist the playlist to disable from.
- * \param i_pos the position of the item to disable
- * \return returns 0
- */
-int playlist_Disable( playlist_t * p_playlist, playlist_item_t *p_item )
-{
-    if( !p_item ) return VLC_EGENERIC;
-
-    msg_Dbg( p_playlist, "disabling playlist item `%s'",
-                   p_item->input.psz_name );
-
-    if( p_item->i_flags & PLAYLIST_ENA_FLAG )
-    {
-        p_playlist->i_enabled--;
-    }
-    p_item->i_flags &= ~PLAYLIST_ENA_FLAG;
-
-    var_SetInteger( p_playlist, "item-change", p_item->input.i_id );
-    return VLC_SUCCESS;
-}
-
-/**
- * Enables a playlist item
- *
- * \param p_playlist the playlist to enable from.
- * \param i_pos the position of the item to enable
- * \return returns 0
- */
-int playlist_Enable( playlist_t * p_playlist, playlist_item_t *p_item )
-{
-    if( !p_item ) return VLC_EGENERIC;
-
-    msg_Dbg( p_playlist, "enabling playlist item `%s'",
-                   p_item->input.psz_name );
-
-    if( p_item->i_flags & ~PLAYLIST_ENA_FLAG )
-    {
-        p_playlist->i_enabled++;
-    }
-    p_item->i_flags |= PLAYLIST_ENA_FLAG;
-
-    var_SetInteger( p_playlist, "item-change", p_item->input.i_id );
-    return VLC_SUCCESS;
-}
-
-/**
- * Move an item in a playlist
- *
- * This function must be entered without the playlist lock
- *
- * Move the item in the playlist with position i_pos before the current item
- * at position i_newpos.
- * \param p_playlist the playlist to move items in
- * \param i_pos the position of the item to move
- * \param i_newpos the position of the item that will be behind the moved item
- *        after the move
- * \return returns VLC_SUCCESS
- */
-int playlist_Move( playlist_t * p_playlist, int i_pos, int i_newpos )
-{
-    vlc_value_t val;
-    vlc_mutex_lock( &p_playlist->object_lock );
-
-    /* take into account that our own row disappears. */
-    if( i_pos < i_newpos ) i_newpos--;
-
-    if( i_pos >= 0 && i_newpos >=0 && i_pos <= p_playlist->i_size &&
-        i_newpos <= p_playlist->i_size )
-    {
-        playlist_item_t * temp;
-
-        msg_Dbg( p_playlist, "moving playlist item `%s' (%i -> %i)",
-                 p_playlist->pp_items[i_pos]->input.psz_name, i_pos, i_newpos);
-
-        if( i_pos == p_playlist->i_index )
-        {
-            p_playlist->i_index = i_newpos;
-        }
-        else if( i_pos > p_playlist->i_index &&
-                 i_newpos <= p_playlist->i_index )
-        {
-            p_playlist->i_index++;
-        }
-        else if( i_pos < p_playlist->i_index &&
-                 i_newpos >= p_playlist->i_index )
-        {
-            p_playlist->i_index--;
-        }
-
-        if ( i_pos < i_newpos )
-        {
-            temp = p_playlist->pp_items[i_pos];
-            while ( i_pos < i_newpos )
-            {
-                p_playlist->pp_items[i_pos] = p_playlist->pp_items[i_pos+1];
-                i_pos++;
-            }
-            p_playlist->pp_items[i_newpos] = temp;
-        }
-        else if ( i_pos > i_newpos )
-        {
-            temp = p_playlist->pp_items[i_pos];
-            while ( i_pos > i_newpos )
-            {
-                p_playlist->pp_items[i_pos] = p_playlist->pp_items[i_pos-1];
-                i_pos--;
-            }
-            p_playlist->pp_items[i_newpos] = temp;
-        }
-    }
-
-    vlc_mutex_unlock( &p_playlist->object_lock );
-
-    val.b_bool = VLC_TRUE;
-    var_Set( p_playlist, "intf-change", val );
-
-    return VLC_SUCCESS;
-}
-
-/**
- * Moves an item
- *
- * This function must be entered with the playlist lock
- *
- * \param p_playlist the playlist
- * \param p_item the item to move
- * \param p_node the new parent of the item
- * \param i_newpos the new position under this new parent
- * \param i_view the view in which the move must be done or ALL_VIEWS
- * \return VLC_SUCCESS or an error
- */
-int playlist_TreeMove( playlist_t * p_playlist, playlist_item_t *p_item,
-                       playlist_item_t *p_node, int i_newpos, int i_view )
-{
-    int i;
-    playlist_item_t *p_detach = NULL;
-    struct item_parent_t *p_parent;
-
-    if( p_node->i_children == -1 ) return VLC_EGENERIC;
-
-    /* Detach from the parent */
-    for( i = 0 ; i< p_item->i_parents; i++ )
-    {
-        if( p_item->pp_parents[i]->i_view == i_view )
-        {
-            int j;
-            p_detach = p_item->pp_parents[i]->p_parent;
-            for( j = 0; j < p_detach->i_children; j++ )
-            {
-                if( p_detach->pp_children[j] == p_item ) break;
-            }
-            REMOVE_ELEM( p_detach->pp_children, p_detach->i_children, j );
-            p_detach->i_serial++;
-            free( p_item->pp_parents[i] );
-            REMOVE_ELEM( p_item->pp_parents, p_item->i_parents, i );
-            i--;
-        }
-    }
-
-    /* Attach to new parent */
-    INSERT_ELEM( p_node->pp_children, p_node->i_children, i_newpos, p_item );
-
-    p_parent = malloc( sizeof( struct item_parent_t ) );
-    p_parent->p_parent = p_node;
-    p_parent->i_view = i_view;
-
-    INSERT_ELEM( p_item->pp_parents, p_item->i_parents, p_item->i_parents,
-                 p_parent );
-    p_node->i_serial++;
-    p_item->i_serial++;
-
-    return VLC_SUCCESS;
-}
index f58cac634f9e46d346e6f881481c6ea0a2864c5f..f9fb51589a849f2ce61f2b854edc9eb42908692c 100644 (file)
@@ -1,10 +1,11 @@
 /*****************************************************************************
- * item.c : Playlist item functions
+ * item.c : Playlist item creation/deletion/add/removal functions
  *****************************************************************************
  * Copyright (C) 1999-2004 the VideoLAN team
  * $Id$
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
+ *          Clément Stenac <zorglub@videolan.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
-#include <stdlib.h>                                      /* free(), strtol() */
-#include <stdio.h>                                              /* sprintf() */
-#include <string.h>                                            /* strerror() */
-
 #include <vlc/vlc.h>
 #include <vlc/input.h>
 
-#include "vlc_input.h"
 #include "vlc_playlist.h"
 
-static void GuessType( input_item_t *p_item);
+void AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
+              playlist_item_t *p_node, int i_pos );
+void GoAndPreparse( playlist_t *p_playlist, int i_mode,
+                    playlist_item_t *p_item );
+void ChangeToNode( playlist_t *p_playlist, playlist_item_t *p_item );
+int DeleteInner( playlist_t * p_playlist, playlist_item_t *p_item,
+                          vlc_bool_t b_stop );
 
+/*****************************************************************************
+ * Playlist item creation
+ *****************************************************************************/
 /**
  * Create a new item, without adding it to the playlist
  *
@@ -40,63 +45,56 @@ static void GuessType( input_item_t *p_item);
  * \param psz_name a text giving a name or description of the item
  * \return the new item or NULL on failure
  */
-
 playlist_item_t * __playlist_ItemNew( vlc_object_t *p_obj,
                                       const char *psz_uri,
                                       const char *psz_name )
 {
     return playlist_ItemNewWithType( p_obj, psz_uri,
-                                     psz_name, ITEM_TYPE_UNKNOWN );
+                                     psz_name, 0, NULL, -1,
+                                     ITEM_TYPE_UNKNOWN );
 }
 
 playlist_item_t * playlist_ItemNewWithType( vlc_object_t *p_obj,
                                             const char *psz_uri,
                                             const char *psz_name,
+                                            int i_options,
+                                            const char **ppsz_options,
+                                            int i_duration,
                                             int i_type )
 {
-    playlist_item_t * p_item;
-
-    if( psz_uri == NULL) return NULL;
+    if( psz_uri == NULL ) return NULL;
+    input_item_t *p_input = input_ItemNewWithType( p_obj, psz_uri,
+                                        psz_name, i_options, ppsz_options,
+                                        i_duration, i_type );
+    return playlist_ItemNewFromInput( p_obj, p_input );
+}
 
+playlist_item_t *__playlist_ItemNewFromInput( vlc_object_t *p_obj,
+                                            input_item_t *p_input )
+{
+    /** FIXME !!!!! don't find playlist each time */
+    playlist_t *p_playlist = (playlist_t *)vlc_object_find( p_obj, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
+    playlist_item_t * p_item;
     p_item = malloc( sizeof( playlist_item_t ) );
     if( p_item == NULL ) return NULL;
 
-    memset( p_item, 0, sizeof( playlist_item_t ) );
-
-    vlc_input_item_Init( p_obj, &p_item->input );
-    p_item->input.b_fixed_name = VLC_FALSE;
-
-    p_item->input.psz_uri = strdup( psz_uri );
-
-    if( psz_name != NULL ) p_item->input.psz_name = strdup( psz_name );
-    else p_item->input.psz_name = strdup ( psz_uri );
-
-    p_item->input.i_type = i_type;
+    p_item->p_input = p_input;
+    vlc_gc_incref( p_item->p_input );
 
-    p_item->b_enabled = VLC_TRUE;
-    p_item->i_nb_played = 0;
+    p_item->i_id = ++p_playlist->i_last_playlist_id;
 
+    p_item->p_parent = NULL;
     p_item->i_children = -1;
     p_item->pp_children = NULL;
-
     p_item->i_flags = 0;
-    p_item->i_flags |= PLAYLIST_SKIP_FLAG;
-    p_item->i_flags |= PLAYLIST_SAVE_FLAG;
-
-    p_item->input.i_duration = -1;
-    p_item->input.ppsz_options = NULL;
-    p_item->input.i_options = 0;
-
-    vlc_mutex_init( p_obj, &p_item->input.lock );
 
-    if( p_item->input.i_type == ITEM_TYPE_UNKNOWN )
-        GuessType( &p_item->input );
+    vlc_object_release( p_playlist );
 
     return p_item;
 }
 
 /**
- * Copy a playlist item
+ * Copy a playlist item - FIXME: Rewrite FIXME
  *
  * Creates a new item with name, mrl and meta infor like the
  * source. Does not copy children for node type items.
@@ -110,24 +108,24 @@ playlist_item_t *__playlist_ItemCopy( vlc_object_t *p_obj,
 {
     playlist_item_t *p_res;
     int i;
-    vlc_mutex_lock( &p_item->input.lock );
+    vlc_mutex_lock( &p_item->p_input->lock );
 
     p_res = malloc( sizeof( playlist_item_t ) );
     if( p_res == NULL )
     {
-        vlc_mutex_unlock( &p_item->input.lock );
+        vlc_mutex_unlock( &p_item->p_input->lock );
         return NULL;
     }
 
     *p_res = *p_item;
-    vlc_mutex_init( p_obj, &p_res->input.lock );
+    vlc_mutex_init( p_obj, &p_res->p_input->lock );
 
-    if( p_item->input.i_options )
-        p_res->input.ppsz_options =
-            malloc( p_item->input.i_options * sizeof(char*) );
-    for( i = 0; i < p_item->input.i_options; i++ )
+    if( p_item->p_input->i_options )
+        p_res->p_input->ppsz_options =
+            malloc( p_item->p_input->i_options * sizeof(char*) );
+    for( i = 0; i < p_item->p_input->i_options; i++ )
     {
-        p_res->input.ppsz_options[i] = strdup( p_item->input.ppsz_options[i] );
+        p_res->p_input->ppsz_options[i] = strdup( p_item->p_input->ppsz_options[i] );
     }
 
     if( p_item->i_children != -1 )
@@ -136,228 +134,479 @@ playlist_item_t *__playlist_ItemCopy( vlc_object_t *p_obj,
         p_res->i_children = -1;
         p_res->pp_children = NULL;
     }
-    p_res->i_parents = 0;
-    p_res->pp_parents = NULL;
-    
-    if( p_item->input.psz_name )
-        p_res->input.psz_name = strdup( p_item->input.psz_name );
-    if( p_item->input.psz_uri )
-        p_res->input.psz_uri = strdup( p_item->input.psz_uri );
-    
-    if( p_item->input.i_es )
+    p_res->p_parent = NULL;
+
+    if( p_item->p_input->psz_name )
+        p_res->p_input->psz_name = strdup( p_item->p_input->psz_name );
+    if( p_item->p_input->psz_uri )
+        p_res->p_input->psz_uri = strdup( p_item->p_input->psz_uri );
+
+    if( p_item->p_input->i_es )
     {
-        p_res->input.es =
-            (es_format_t**)malloc( p_item->input.i_es * sizeof(es_format_t*));
-        for( i = 0; i < p_item->input.i_es; i++ )
+        p_res->p_input->es =
+            (es_format_t**)malloc( p_item->p_input->i_es * sizeof(es_format_t*));
+        for( i = 0; i < p_item->p_input->i_es; i++ )
         {
-            p_res->input.es[ i ] = (es_format_t*)malloc(sizeof(es_format_t*));
-            es_format_Copy( p_res->input.es[ i ],
-                         p_item->input.es[ i ] );
+            p_res->p_input->es[ i ] = (es_format_t*)malloc(sizeof(es_format_t*));
+            es_format_Copy( p_res->p_input->es[ i ],
+                         p_item->p_input->es[ i ] );
         }
     }
-    if( p_item->input.i_categories )
+    if( p_item->p_input->i_categories )
     {
-        p_res->input.pp_categories = NULL;
-        p_res->input.i_categories = 0;
-        for( i = 0; i < p_item->input.i_categories; i++ )
+        p_res->p_input->pp_categories = NULL;
+        p_res->p_input->i_categories = 0;
+        for( i = 0; i < p_item->p_input->i_categories; i++ )
         {
             info_category_t *p_incat;
-            p_incat = p_item->input.pp_categories[i];
+            p_incat = p_item->p_input->pp_categories[i];
             if( p_incat->i_infos )
             {
                 int j;
                 for( j = 0; j < p_incat->i_infos; j++ )
                 {
-                    vlc_input_item_AddInfo( &p_res->input, p_incat->psz_name,
+                    vlc_input_item_AddInfo( p_res->p_input, p_incat->psz_name,
                                             p_incat->pp_infos[j]->psz_name,
-                                            "%s", /* to be safe */
+                                            "%s",
                                             p_incat->pp_infos[j]->psz_value );
                 }
             }
         }
     }
 
-    vlc_mutex_unlock( &p_item->input.lock );
+    vlc_mutex_unlock( &p_item->p_input->lock );
     return p_res;
 }
 
+/***************************************************************************
+ * Playlist item destruction
+ ***************************************************************************/
+
+/** Delete a playlist item and detach its input item */
+int playlist_ItemDelete( playlist_item_t *p_item )
+{
+    vlc_gc_decref( p_item->p_input );
+    free( p_item );
+    return VLC_SUCCESS;
+}
+
+/** Remove an input item from ONELEVEL and CATEGORY */
+int playlist_DeleteAllFromInput( playlist_t *p_playlist, int i_input_id )
+{
+    playlist_DeleteFromInput( p_playlist, i_input_id,
+                              p_playlist->p_root_category, VLC_TRUE );
+    playlist_DeleteFromInput( p_playlist, i_input_id,
+                              p_playlist->p_root_onelevel, VLC_TRUE );
+    return VLC_SUCCESS;
+}
+
+/** Remove an input item from ONELEVEL and CATEGORY.
+ * This function must be entered without the playlist lock */
+int playlist_LockDeleteAllFromInput( playlist_t * p_playlist, int i_id )
+{
+    int i_ret;
+    vlc_mutex_lock( &p_playlist->object_lock );
+    i_ret = playlist_DeleteAllFromInput( p_playlist, i_id );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+    return i_ret;
+}
+
+/** Remove an input item when it appears from a root playlist item */
+int playlist_DeleteFromInput( playlist_t *p_playlist, int i_input_id,
+                              playlist_item_t *p_root, vlc_bool_t b_do_stop )
+{
+    int i;
+    for( i = 0 ; i< p_root->i_children ; i++ )
+    {
+        if( p_root->pp_children[i]->i_children == -1 &&
+            p_root->pp_children[i]->p_input->i_id == i_input_id )
+        {
+            DeleteInner( p_playlist, p_root->pp_children[i], b_do_stop );
+        }
+        else if( p_root->pp_children[i]->i_children >= 0 )
+        {
+            return playlist_DeleteFromInput( p_playlist, i_input_id,
+                                        p_root->pp_children[i], b_do_stop );
+        }
+    }
+}
+
+/** Remove a playlist item from the playlist, given its id */
+int playlist_DeleteFromItemId( playlist_t *p_playlist, int i_id )
+{
+    playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_id );
+    if( !p_item ) return VLC_EGENERIC;
+    return DeleteInner( p_playlist, p_item, VLC_TRUE );
+}
+
+/** Remove a playlist item from the playlist, given its id
+ * This function should be entered without the playlist lock */
+int playlist_LockDelete( playlist_t * p_playlist, int i_id )
+{
+    int i_ret;
+    vlc_mutex_lock( &p_playlist->object_lock );
+    i_ret = playlist_DeleteFromItemId( p_playlist, i_id );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+    return i_ret;
+}
+
+/** Clear the playlist */
+void playlist_Clear( playlist_t * p_playlist )
+{
+    playlist_NodeEmpty( p_playlist, p_playlist->p_root_category, VLC_TRUE );
+    playlist_NodeEmpty( p_playlist, p_playlist->p_root_onelevel, VLC_TRUE );
+}
+/** Clear the playlist. This function must be entered without the lock */
+void playlist_LockClear( playlist_t *p_playlist )
+{
+    vlc_mutex_lock( &p_playlist->object_lock );
+    playlist_Clear( p_playlist );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+}
+
+/***************************************************************************
+ * Playlist item addition
+ ***************************************************************************/
+
 /**
- * Deletes a playlist item
+ * Add a MRL into the playlist.
  *
- * \param p_item the item to delete
- * \return nothing
+ * \param p_playlist the playlist to add into
+ * \param psz_uri the mrl to add to the playlist
+ * \param psz_name a text giving a name or description of this item
+ * \param i_mode the mode used when adding
+ * \param i_pos the position in the playlist where to add. If this is
+ *        PLAYLIST_END the item will be added at the end of the playlist
+ *        regardless of it's size
+ * \return The id of the playlist item
  */
-int playlist_ItemDelete( playlist_item_t *p_item )
+int playlist_PlaylistAdd( playlist_t *p_playlist, const char *psz_uri,
+                          const char *psz_name, int i_mode, int i_pos )
 {
-    vlc_mutex_lock( &p_item->input.lock );
+    return playlist_PlaylistAddExt( p_playlist, psz_uri, psz_name,
+                                    i_mode, i_pos, -1, NULL, 0 );
+}
 
-    if( p_item->input.psz_name ) free( p_item->input.psz_name );
-    if( p_item->input.psz_uri ) free( p_item->input.psz_uri );
+/**
+ * Add a MRL into the playlist, duration and options given
+ *
+ * \param p_playlist the playlist to add into
+ * \param psz_uri the mrl to add to the playlist
+ * \param psz_name a text giving a name or description of this item
+ * \param i_mode the mode used when adding
+ * \param i_pos the position in the playlist where to add. If this is
+ *        PLAYLIST_END the item will be added at the end of the playlist
+ *        regardless of it's size
+ * \param i_duration length of the item in milliseconds.
+ * \param ppsz_options an array of options
+ * \param i_options the number of options
+ * \return The id of the playlist item
+*/
+int playlist_PlaylistAddExt( playlist_t *p_playlist, const char * psz_uri,
+                             const char *psz_name, int i_mode, int i_pos,
+                             mtime_t i_duration, const char **ppsz_options,
+                             int i_options )
+{
+    input_item_t *p_input = input_ItemNewExt( p_playlist, psz_uri, psz_name,
+                                              i_options, ppsz_options,
+                                              i_duration );
 
-    /* Free the info categories */
-    if( p_item->input.i_categories > 0 )
-    {
-        int i, j;
+    return playlist_PlaylistAddInput( p_playlist, p_input, i_mode, i_pos );
+}
 
-        for( i = 0; i < p_item->input.i_categories; i++ )
-        {
-            info_category_t *p_category = p_item->input.pp_categories[i];
+/** Add an input item to the playlist node */
+int playlist_PlaylistAddInput( playlist_t* p_playlist, input_item_t *p_input,
+                               int i_mode, int i_pos )
+{
+    playlist_item_t *p_item;
+    p_input->i_id = ++p_playlist->i_last_input_id;
 
-            for( j = 0; j < p_category->i_infos; j++)
-            {
-                if( p_category->pp_infos[j]->psz_name )
-                {
-                    free( p_category->pp_infos[j]->psz_name);
-                }
-                if( p_category->pp_infos[j]->psz_value )
-                {
-                    free( p_category->pp_infos[j]->psz_value );
-                }
-                free( p_category->pp_infos[j] );
-            }
+    msg_Dbg( p_playlist, "adding playlist item `%s' ( %s )",
+             p_input->psz_name, p_input->psz_uri );
 
-            if( p_category->i_infos ) free( p_category->pp_infos );
-            if( p_category->psz_name ) free( p_category->psz_name );
-            free( p_category );
-        }
+    vlc_mutex_lock( &p_playlist->object_lock );
 
-        free( p_item->input.pp_categories );
-    }
+    /* Add to ONELEVEL */
+    p_item = playlist_ItemNewFromInput( p_playlist, p_input );
+    if( p_item == NULL ) return VLC_EGENERIC;
+    AddItem( p_playlist, p_item,p_playlist->p_local_onelevel, i_pos );
+
+    /* Add to CATEGORY */
+    p_item = playlist_ItemNewFromInput( p_playlist, p_input );
+    if( p_item == NULL ) return VLC_EGENERIC;
+    AddItem( p_playlist, p_item, p_playlist->p_local_category, i_pos );
+
+    GoAndPreparse( p_playlist, i_mode, p_item );
 
-    for( ; p_item->input.i_options > 0; p_item->input.i_options-- )
+    vlc_mutex_unlock( &p_playlist->object_lock );
+    return VLC_SUCCESS;
+}
+
+/** Add an input item to p_direct_parent in the category tree, and to the
+ *  matching top category in onelevel **/
+int playlist_BothAddInput( playlist_t *p_playlist,
+                           input_item_t *p_input,
+                           playlist_item_t *p_direct_parent,
+                           int i_mode, int i_pos )
+{
+    playlist_item_t *p_item, *p_up;
+    int i_top;
+    vlc_mutex_lock( & p_playlist->object_lock );
+
+    /* Add to category */
+    p_item = playlist_ItemNewFromInput( p_playlist, p_input );
+    if( p_item == NULL ) return VLC_EGENERIC;
+    fprintf( stderr, "Adding to CATEGORY\n");
+    AddItem( p_playlist, p_item, p_direct_parent, i_pos );
+
+    /* Add to onelevel */
+    p_item = playlist_ItemNewFromInput( p_playlist, p_input );
+    if( p_item == NULL ) return VLC_EGENERIC;
+    fprintf( stderr, "Adding to ONE\n");
+
+    p_up = p_direct_parent;
+    while( p_up->p_parent != p_playlist->p_root_category )
     {
-        free( p_item->input.ppsz_options[p_item->input.i_options - 1] );
-        if( p_item->input.i_options == 1 ) free( p_item->input.ppsz_options );
+        p_up = p_up->p_parent;
     }
-
-    for( ; p_item->i_parents > 0 ; )
+    for( i_top = 0 ; i_top < p_playlist->p_root_onelevel->i_children; i_top++ )
     {
-        struct item_parent_t *p_parent =  p_item->pp_parents[0];
-        REMOVE_ELEM( p_item->pp_parents, p_item->i_parents, 0 );
-        free( p_parent );
+        if( p_playlist->p_root_onelevel->pp_children[i_top]->p_input->i_id == p_up->p_input->i_id )
+        {
+            AddItem( p_playlist, p_item,
+                     p_playlist->p_root_onelevel->pp_children[i_top], i_pos );
+            break;
+        }
     }
+    GoAndPreparse( p_playlist, i_mode, p_item );
 
-    vlc_mutex_unlock( &p_item->input.lock );
-    vlc_mutex_destroy( &p_item->input.lock );
-
-    free( p_item );
-
+    vlc_mutex_unlock( &p_playlist->object_lock );
     return VLC_SUCCESS;
 }
 
 /**
- *  Add a option to one item ( no need for p_playlist )
- *
- * \param p_item the item on which we want the info
- * \param psz_option the option
- * \return 0 on success
+ * Add an item where it should be added, when adding from a node
+ * (ex: directory access, playlist demuxers, services discovery, ... )
+ * \param p_playlist the playlist
+ * \param p_input the input to add
+ * \param p_parent the direct node
+ * \param p_item_in_category the item within category root (as returned by playlist_ItemToNode)
+ * \param b_forced_parent Are we forced to add only to p_parent ?
  */
-int playlist_ItemAddOption( playlist_item_t *p_item, const char *psz_option )
+void playlist_AddWhereverNeeded( playlist_t *p_playlist, input_item_t *p_input,
+                                 playlist_item_t *p_parent,
+                                 playlist_item_t *p_item_in_category,
+                                 vlc_bool_t b_forced_parent, int i_mode )
+{
+    /* If we have forced a parent :
+     *   - Just add the input to the forced parent (which should be p_parent)
+     * Else
+     *    - If we have item in category, add to it, and to onelevel (bothadd)
+     *    - If we don't, just add to p_parent
+     */
+    if( b_forced_parent == VLC_TRUE || !p_item_in_category  )
+    {
+        playlist_NodeAddInput( p_playlist, p_input, p_parent, i_mode,
+                               PLAYLIST_END );
+    }
+    else
+    {
+        playlist_BothAddInput( p_playlist, p_input, p_item_in_category,
+                               i_mode, PLAYLIST_END );
+    }
+}
+
+
+/** Add an input item to a given node */
+playlist_item_t * playlist_NodeAddInput( playlist_t *p_playlist,
+                                         input_item_t *p_input,
+                                         playlist_item_t *p_parent,
+                                         int i_mode, int i_pos )
 {
-    if( !psz_option ) return VLC_EGENERIC;
+    playlist_item_t *p_item;
+
+    /* Sanity checks */
+    if( !p_parent || p_parent->i_children == -1 )
+    {
+        msg_Err( p_playlist, "invalid node" );
+    }
 
-    vlc_mutex_lock( &p_item->input.lock );
-    INSERT_ELEM( p_item->input.ppsz_options, p_item->input.i_options,
-                 p_item->input.i_options, strdup( psz_option ) );
-    vlc_mutex_unlock( &p_item->input.lock );
+    vlc_mutex_lock( &p_playlist->object_lock );
 
-    return VLC_SUCCESS;
+    p_item = playlist_ItemNewFromInput( p_playlist, p_input );
+    if( p_item == NULL ) return NULL;
+    AddItem( p_playlist, p_item, p_parent, i_pos );
+
+    vlc_mutex_unlock( &p_playlist->object_lock );
+
+    return p_item;
 }
 
-/**
- * Add a parent to an item
- *
- * \param p_item the item
- * \param i_view the view in which the parent is
- * \param p_parent the parent to add
- * \return nothing
- */
-int playlist_ItemAddParent( playlist_item_t *p_item, int i_view,
-                            playlist_item_t *p_parent )
+/** Add a playlist item to a given node */
+void playlist_NodeAddItem( playlist_t *p_playlist, playlist_item_t *p_item,
+                           playlist_item_t *p_parent, int i_mode, int i_pos )
 {
-   vlc_bool_t b_found = VLC_FALSE;
-   int i;
-
-   for( i= 0; i< p_item->i_parents ; i++ )
-   {
-       if( p_item->pp_parents[i]->i_view == i_view )
-
-       {
-           b_found = VLC_TRUE;
-           break;
-       }
-   }
-   if( b_found == VLC_FALSE )
-   {
-
-       struct item_parent_t *p_ip = (struct item_parent_t *)
-               malloc(sizeof(struct item_parent_t) );
-       p_ip->i_view = i_view;
-       p_ip->p_parent = p_parent;
-
-       INSERT_ELEM( p_item->pp_parents,
-                    p_item->i_parents, p_item->i_parents,
-                    p_ip );
-   }
-   return VLC_SUCCESS;
+    vlc_mutex_lock( &p_playlist->object_lock );
+    AddItem( p_playlist, p_item, p_parent, i_pos );
+    vlc_mutex_unlock( &p_playlist->object_lock );
 }
 
+/*****************************************************************************
+ * Playlist item misc operations
+ *****************************************************************************/
+
 /**
- * Copy all parents from parent to child
+ * Transform an item to a node. Return the node in the category tree, or NULL
+ * if not found there
+ * This function must be entered without the playlist lock
  */
-int playlist_CopyParents( playlist_item_t *p_parent,
-                           playlist_item_t *p_child )
+playlist_item_t *playlist_ItemToNode( playlist_t *p_playlist,
+                                      playlist_item_t *p_item )
 {
-    int i=0;
-    for( i= 0 ; i< p_parent->i_parents; i ++ )
+    /* What we do
+     * Find the input in CATEGORY.
+     *  - If we find it
+     *    - change it to node
+     *    - we'll return it at the end
+     *    - Delete the input from ONELEVEL
+     *  - If we don't find it, just change to node (we are probably in VLM)
+     *    and return NULL
+     *
+     * If we were in ONELEVEL, we thus retrieve the node in CATEGORY (will be
+     * useful for later BothAddInput )
+     */
+
+    /** \todo First look if we don't already have it */
+    playlist_item_t *p_item_in_category = playlist_ItemFindFromInputAndRoot(
+                                            p_playlist, p_item->p_input->i_id,
+                                            p_playlist->p_root_category );
+
+    if( p_item_in_category )
     {
-        playlist_ItemAddParent( p_child,
-                                p_parent->pp_parents[i]->i_view,
-                                p_parent );
+        ChangeToNode( p_playlist, p_item_in_category );
+        playlist_DeleteFromInput( p_playlist, p_item->p_input->i_id,
+                                  p_playlist->p_root_onelevel, VLC_FALSE );
+        var_SetInteger( p_playlist, "item-change", p_item->p_input->i_id );
+        return p_item_in_category;
+    }
+    else
+    {
+        ChangeToNode( p_playlist, p_item );
+        return NULL;
     }
-    return VLC_SUCCESS;
 }
 
+/** Transform an item to a node
+ *  This function must be entered without the playlist lock
+ *  \see playlist_ItemToNode
+ */
+playlist_item_t * playlist_LockItemToNode( playlist_t *p_playlist,
+                                           playlist_item_t *p_item )
+{
+    playlist_item_t *p_ret;
+    vlc_mutex_lock( &p_playlist->object_lock );
+    p_ret = playlist_ItemToNode( p_playlist, p_item );
+    vlc_mutex_unlock( &p_playlist->object_lock );
+    return p_ret;
+}
 
-/**********************************************************************
- * playlist_item_t structure accessors
- * These functions give access to the fields of the playlist_item_t
- * structure
- **********************************************************************/
+/** Find an item within a root, given its input id.
+ * \return the first found item, or NULL if not found
+ */
+playlist_item_t *playlist_ItemFindFromInputAndRoot( playlist_t *p_playlist,
+                                                    int i_input_id,
+                                                    playlist_item_t *p_root )
+{
+    int i;
+    for( i = 0 ; i< p_root->i_children ; i++ )
+    {
+        if( p_root->pp_children[i]->i_children == -1 &&
+            p_root->pp_children[i]->p_input->i_id == i_input_id )
+        {
+            return p_root->pp_children[i];
+        }
+        else if( p_root->pp_children[i]->i_children >= 0 )
+        {
+            playlist_item_t *p_search =
+                 playlist_ItemFindFromInputAndRoot( p_playlist, i_input_id,
+                                                    p_root->pp_children[i] );
+            if( p_search ) return p_search;
+        }
+    }
+    return NULL;
+}
 
 
 /**
- * Set the name of a playlist item
+ * Moves an item
+ *
+ * This function must be entered with the playlist lock
  *
- * \param p_item the item
- * \param psz_name the new name
- * \return VLC_SUCCESS on success, VLC_EGENERIC on failure
+ * \param p_playlist the playlist
+ * \param p_item the item to move
+ * \param p_node the new parent of the item
+ * \param i_newpos the new position under this new parent
+ * \return VLC_SUCCESS or an error
  */
+int playlist_TreeMove( playlist_t * p_playlist, playlist_item_t *p_item,
+                       playlist_item_t *p_node, int i_newpos )
+{
+    int j;
+    playlist_item_t *p_detach = NULL;
+
+    if( p_node->i_children == -1 ) return VLC_EGENERIC;
+
+    p_detach = p_item->p_parent;
+    for( j = 0; j < p_detach->i_children; j++ )
+    {
+         if( p_detach->pp_children[j] == p_item ) break;
+    }
+    REMOVE_ELEM( p_detach->pp_children, p_detach->i_children, j );
+
+    /* Attach to new parent */
+    INSERT_ELEM( p_node->pp_children, p_node->i_children, i_newpos, p_item );
+
+    return VLC_SUCCESS;
+}
+
+/** Send a notification that an item has been added to a node */
+void playlist_SendAddNotify( playlist_t *p_playlist, int i_item_id,
+                             int i_node_id )
+{
+    vlc_value_t val;
+    playlist_add_t *p_add = (playlist_add_t *)malloc(sizeof( playlist_add_t));
+    p_add->i_item = i_item_id;
+    p_add->i_node = i_node_id;
+    val.p_address = p_add;
+    var_Set( p_playlist, "item-append", val );
+    free( p_add );
+}
+
+/*****************************************************************************
+ * Playlist item accessors
+ *****************************************************************************/
+
+/** Set the name of a playlist item */
 int playlist_ItemSetName( playlist_item_t *p_item, char *psz_name )
 {
     if( psz_name && p_item )
     {
-        if( p_item->input.psz_name ) free( p_item->input.psz_name );
-        p_item->input.psz_name = strdup( psz_name );
+        if( p_item->p_input->psz_name ) free( p_item->p_input->psz_name );
+        p_item->p_input->psz_name = strdup( psz_name );
         return VLC_SUCCESS;
     }
     return VLC_EGENERIC;
 }
 
-/**
- * Set the duration of a playlist item
- * This function must be entered with the item lock
- *
- * \param p_item the item
- * \param i_duration the new duration
- * \return VLC_SUCCESS on success, VLC_EGENERIC on failure
+/** Set the duration of a playlist item
+ * \param i_duration the new duration in microseconds
  */
 int playlist_ItemSetDuration( playlist_item_t *p_item, mtime_t i_duration )
 {
     char psz_buffer[MSTRTIME_MAX_SIZE];
     if( p_item )
     {
-        p_item->input.i_duration = i_duration;
+        p_item->p_input->i_duration = i_duration;
         if( i_duration != -1 )
         {
             secstotimestr( psz_buffer, (int)(i_duration/1000000) );
@@ -366,7 +615,7 @@ int playlist_ItemSetDuration( playlist_item_t *p_item, mtime_t i_duration )
         {
             memcpy( psz_buffer, "--:--:--", sizeof("--:--:--") );
         }
-        vlc_input_item_AddInfo( &p_item->input, _("General") , _("Duration"),
+        vlc_input_item_AddInfo( p_item->p_input, _("General") , _("Duration"),
                                 "%s", psz_buffer );
 
         return VLC_SUCCESS;
@@ -374,46 +623,152 @@ int playlist_ItemSetDuration( playlist_item_t *p_item, mtime_t i_duration )
     return VLC_EGENERIC;
 }
 
-/*
- * Guess the type of the item using the beginning of the mrl */
-static void GuessType( input_item_t *p_item)
+/** Add an option to a playlist item */
+void playlist_ItemAddOption( playlist_item_t *p_item,
+                             const char *psz_option)
 {
-    int i;
-    static struct { char *psz_search; int i_type; }  types_array[] =
+    vlc_input_item_AddOption( p_item->p_input, psz_option );
+}
+
+/***************************************************************************
+ * The following functions are local
+ ***************************************************************************/
+
+/* Enqueue an item for preparsing, and play it, if needed */
+void GoAndPreparse( playlist_t *p_playlist, int i_mode,
+                    playlist_item_t *p_item )
+{
+#if 0
+    if( (i_mode & PLAYLIST_GO ) && p_view )
     {
-        { "http", ITEM_TYPE_NET },
-        { "dvd", ITEM_TYPE_DISC },
-        { "cdda", ITEM_TYPE_CDDA },
-        { "mms", ITEM_TYPE_NET },
-        { "rtsp", ITEM_TYPE_NET },
-        { "udp", ITEM_TYPE_NET },
-        { "rtp", ITEM_TYPE_NET },
-        { "vcd", ITEM_TYPE_DISC },
-        { "v4l", ITEM_TYPE_CARD },
-        { "dshow", ITEM_TYPE_CARD },
-        { "pvr", ITEM_TYPE_CARD },
-        { "dvb", ITEM_TYPE_CARD },
-        { "qpsk", ITEM_TYPE_CARD },
-        { "sdp", ITEM_TYPE_NET },
-        { NULL, 0 }
-    };
-
-#if 0 /* Unused */
-    static struct { char *psz_search; int i_type; } exts_array[] =
+        p_playlist->request.b_request = VLC_TRUE;
+        /* FIXME ... */
+        p_playlist->request.i_view = VIEW_CATEGORY;
+        p_playlist->request.p_node = p_view->p_root;
+        p_playlist->request.p_item = p_item;
+
+        if( p_playlist->p_input )
+        {
+            input_StopThread( p_playlist->p_input );
+        }
+        p_playlist->status.i_status = PLAYLIST_RUNNING;
+    }
+#endif
+    if( i_mode & PLAYLIST_PREPARSE &&
+        var_CreateGetBool( p_playlist, "auto-preparse" ) )
     {
-        { "mp3", ITEM_TYPE_AFILE },
-        { NULL, 0 }
-    };
+        playlist_PreparseEnqueue( p_playlist, p_item->p_input );
+    }
+}
+
+/* Add the playlist item to the requested node and fire a notification */
+void AddItem( playlist_t *p_playlist, playlist_item_t *p_item,
+              playlist_item_t *p_node, int i_pos )
+{
+    INSERT_ELEM( p_playlist->pp_items, p_playlist->i_size,
+                 p_playlist->i_size, p_item );
+#if 0
+    fprintf( stderr, "Adding input %s (id %i) - playlist item id %i "
+                     "to node %s (id %i)\n",
+                     p_item->p_input->psz_name, p_item->p_input->i_id,
+                     p_item->i_id, p_node->p_input->psz_name,
+                     p_node->i_id );
 #endif
+    INSERT_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size,
+                 p_playlist->i_all_size, p_item );
+    p_playlist->i_enabled ++;
+
+    if( i_pos == PLAYLIST_END )
+    {
+        playlist_NodeAppend( p_playlist, p_item, p_node );
+    }
+    else
+    {
+        playlist_NodeInsert( p_playlist, p_item, p_node, i_pos );
+    }
+
+    playlist_SendAddNotify( p_playlist, p_item->i_id, p_node->i_id );
+}
+
+/* Actually convert an item to a node */
+void ChangeToNode( playlist_t *p_playlist, playlist_item_t *p_item )
+{
+    int i;
+    if( p_item->i_children == -1 )
+        p_item->i_children = 0;
+
+    /* Remove it from the array of available items */
+    for( i = 0 ; i < p_playlist->i_size ; i++ )
+    {
+        if( p_item == p_playlist->pp_items[i] )
+        {
+            REMOVE_ELEM( p_playlist->pp_items, p_playlist->i_size, i );
+        }
+    }
+}
+
+/* Do the actual removal */
+int DeleteInner( playlist_t * p_playlist, playlist_item_t *p_item,
+                vlc_bool_t b_stop )
+{
+    int i, i_top, i_bottom;
+    int i_id = p_item->i_id;
+    vlc_bool_t b_flag = VLC_FALSE;
+
+    //fprintf( stderr, "Deleting item %i - %s\n", i_id,
+    //                                            p_item->p_input->psz_name );
+
+    if( p_item->i_children > -1 )
+    {
+        return playlist_NodeDelete( p_playlist, p_item, VLC_TRUE, VLC_FALSE );
+    }
+    var_SetInteger( p_playlist, "item-deleted", i_id );
+
+    /* Remove the item from the bank */
+    i_bottom = 0; i_top = p_playlist->i_all_size - 1;
+    i = i_top / 2;
+    while( p_playlist->pp_all_items[i]->i_id != i_id &&
+           i_top > i_bottom )
+    {
+        if( p_playlist->pp_all_items[i]->i_id < i_id )
+        {
+            i_bottom = i + 1;
+        }
+        else
+        {
+            i_top = i - 1;
+        }
+        i = i_bottom + ( i_top - i_bottom ) / 2;
+    }
+    if( p_playlist->pp_all_items[i]->i_id == i_id )
+    {
+        REMOVE_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size, i );
+    }
 
-    for( i = 0; types_array[i].psz_search != NULL; i++ )
+    /* Check if it is the current item */
+    if( p_playlist->status.p_item == p_item )
     {
-        if( !strncmp( p_item->psz_uri, types_array[i].psz_search,
-                      strlen( types_array[i].psz_search ) ) )
+        /* Hack we don't call playlist_Control for lock reasons */
+        if( b_stop )
         {
-            p_item->i_type = types_array[i].i_type;
-            return;
+            p_playlist->status.i_status = PLAYLIST_STOPPED;
+            p_playlist->request.b_request = VLC_TRUE;
+            p_playlist->request.p_item = NULL;
+            msg_Info( p_playlist, "stopping playback" );
         }
+        b_flag = VLC_TRUE;
     }
-    p_item->i_type = ITEM_TYPE_VFILE;
+
+    msg_Dbg( p_playlist, "deleting playlist item `%s'",
+                          p_item->p_input->psz_name );
+
+    /* Remove the item from its parent */
+    playlist_NodeRemoveItem( p_playlist, p_item, p_item->p_parent );
+
+    if( b_flag == VLC_FALSE )
+        playlist_ItemDelete( p_item );
+    else
+        p_item->i_flags |= PLAYLIST_REMOVE_FLAG;
+
+    return VLC_SUCCESS;
 }
index 2fae7bdf8ab19c240e0c13402e7d8b6ab1e69c2a..3d02454e7dbc1408693148dcaae6daee2112ddd3 100644 (file)
@@ -57,12 +57,11 @@ int playlist_Import( playlist_t * p_playlist, const char *psz_filename )
     psz_uri = (char *)malloc(sizeof(char)*strlen(psz_filename) + 17 );
     sprintf( psz_uri, "file/playlist://%s", psz_filename);
 
-    i_id = playlist_Add( p_playlist, psz_uri, psz_uri,
+    i_id = playlist_PlaylistAdd( p_playlist, psz_uri, psz_uri,
                   PLAYLIST_INSERT  , PLAYLIST_END);
 
     vlc_mutex_lock( &p_playlist->object_lock );
     p_item = playlist_ItemGetById( p_playlist, i_id );
-    p_item->b_autodeletion = VLC_TRUE;
     vlc_mutex_unlock( &p_playlist->object_lock );
 
     playlist_Play(p_playlist);
@@ -91,12 +90,11 @@ int playlist_Load( playlist_t * p_playlist, const char *psz_filename )
     psz_uri = (char *)malloc(sizeof(char)*strlen(psz_filename) + 17 );
     sprintf( psz_uri, "file/playlist://%s", psz_filename);
 
-    i_id = playlist_Add( p_playlist, psz_uri, psz_uri,
+    i_id = playlist_PlaylistAdd( p_playlist, psz_uri, psz_uri,
                   PLAYLIST_INSERT  , PLAYLIST_END);
 
     vlc_mutex_lock( &p_playlist->object_lock );
     p_item = playlist_ItemGetById( p_playlist, i_id );
-    p_item->b_autodeletion = VLC_TRUE;
     vlc_mutex_unlock( &p_playlist->object_lock );
 
     playlist_Play(p_playlist);
@@ -105,26 +103,30 @@ int playlist_Load( playlist_t * p_playlist, const char *psz_filename )
 }
 
 /**
- * Export a playlist to a certain type of playlistfile
+ * Export a node of the playlist to a certain type of playlistfile
  *
  * \param p_playlist the playlist to export
  * \param psz_filename the location where the exported file will be saved
+ * \param p_export_root the root node to export
  * \param psz_type the type of playlist file to create.
  * \return VLC_SUCCESS on success
  */
 int playlist_Export( playlist_t * p_playlist, const char *psz_filename ,
-                     const char *psz_type)
+                     playlist_item_t *p_export_root,const char *psz_type )
 {
     module_t *p_module;
     playlist_export_t *p_export;
 
-    msg_Info( p_playlist, "saving playlist to file %s", psz_filename );
+    if( p_export_root == NULL ) return VLC_EGENERIC;
+
+    msg_Info( p_playlist, "saving %s to file %s",
+                    p_export_root->p_input->psz_name, psz_filename );
 
     /* Prepare the playlist_export_t structure */
     p_export = (playlist_export_t *)malloc( sizeof(playlist_export_t) );
     if( !p_export)
     {
-        msg_Err( p_playlist, "out of memory");
+        msg_Err( p_playlist, "out of memory" );
         return VLC_ENOMEM;
     }
     p_export->psz_filename = NULL;
@@ -138,9 +140,11 @@ int playlist_Export( playlist_t * p_playlist, const char *psz_filename ,
         return VLC_EGENERIC;
     }
 
-    p_playlist->p_private = (void *)p_export;
+    p_export->p_root = p_export_root;
+
     /* Lock the playlist */
     vlc_mutex_lock( &p_playlist->object_lock );
+    p_playlist->p_private = (void *)p_export;
 
     /* And call the module ! All work is done now */
     p_module = module_Need( p_playlist, "playlist export", psz_type, VLC_TRUE);
diff --git a/src/playlist/playlist.c b/src/playlist/playlist.c
deleted file mode 100644 (file)
index c3195f4..0000000
+++ /dev/null
@@ -1,1239 +0,0 @@
-/*****************************************************************************
- * playlist.c : Playlist management functions
- *****************************************************************************
- * Copyright (C) 1999-2004 the VideoLAN team
- * $Id$
- *
- * Authors: Samuel Hocevar <sam@zoy.org>
- *          Clément Stenac <zorglub@videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#include <stdlib.h>                                      /* free(), strtol() */
-#include <stdio.h>                                              /* sprintf() */
-#include <string.h>                                            /* strerror() */
-
-#include <vlc/vlc.h>
-#include <vlc/vout.h>
-#include <vlc/sout.h>
-#include <vlc/input.h>
-
-#include "vlc_playlist.h"
-
-#include "vlc_interaction.h"
-
-#define TITLE_CATEGORY N_( "By category" )
-#define TITLE_SIMPLE   N_( "Manually added" )
-#define TITLE_ALL      N_( "All items, unsorted" )
-
-#undef PLAYLIST_PROFILE
-#undef PLAYLIST_DEBUG
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static void RunThread ( playlist_t * );
-static void RunPreparse( playlist_preparse_t * );
-static playlist_item_t * NextItem  ( playlist_t * );
-static int PlayItem  ( playlist_t *, playlist_item_t * );
-
-int playlist_vaControl( playlist_t * p_playlist, int i_query, va_list args );
-
-void playlist_PreparseEnqueueItemSub( playlist_t *, playlist_item_t * );
-
-playlist_item_t *playlist_RecursiveFindLast(playlist_t *p_playlist,
-                                            playlist_item_t *p_node );
-
-/*****************************************************************************
- * Helper Function for NextItem
- *****************************************************************************/
-
-playlist_item_t *playlist_RecursiveFindLast(playlist_t *p_playlist,
-                                            playlist_item_t *p_node )
-{
-    int i;
-    playlist_item_t *p_item;
-    for ( i = p_node->i_children - 1; i >= 0; i-- )
-    {
-        if( p_node->pp_children[i]->i_children == -1 )
-            return p_node->pp_children[i];
-        else if(p_node->pp_children[i]->i_children > 0)
-        {
-             p_item = playlist_RecursiveFindLast( p_playlist,
-                                        p_node->pp_children[i] );
-            if ( p_item != NULL )
-                return p_item;
-        }
-        else if( i == 0 )
-            return NULL;
-    }
-    return NULL;
-}
-
-
-/**
- * Create playlist
- *
- * Create a playlist structure.
- * \param p_parent the vlc object that is to be the parent of this playlist
- * \return a pointer to the created playlist, or NULL on error
- */
-playlist_t * __playlist_Create ( vlc_object_t *p_parent )
-{
-    playlist_t *p_playlist;
-    playlist_view_t *p_view;
-    vlc_value_t     val;
-
-    /* Allocate structure */
-    p_playlist = vlc_object_create( p_parent, VLC_OBJECT_PLAYLIST );
-    if( !p_playlist )
-    {
-        msg_Err( p_parent, "out of memory" );
-        return NULL;
-    }
-
-    /* These variables control updates */
-    var_Create( p_playlist, "intf-change", VLC_VAR_BOOL );
-    val.b_bool = VLC_TRUE;
-    var_Set( p_playlist, "intf-change", val );
-
-    var_Create( p_playlist, "item-change", VLC_VAR_INTEGER );
-    val.i_int = -1;
-    var_Set( p_playlist, "item-change", val );
-
-    var_Create( p_playlist, "item-deleted", VLC_VAR_INTEGER );
-    val.i_int = -1;
-    var_Set( p_playlist, "item-deleted", val );
-
-    var_Create( p_playlist, "item-append", VLC_VAR_ADDRESS );
-
-    var_Create( p_playlist, "playlist-current", VLC_VAR_INTEGER );
-    val.i_int = -1;
-    var_Set( p_playlist, "playlist-current", val );
-
-    var_Create( p_playlist, "intf-popupmenu", VLC_VAR_BOOL );
-
-    var_Create( p_playlist, "intf-show", VLC_VAR_BOOL );
-    val.b_bool = VLC_TRUE;
-    var_Set( p_playlist, "intf-show", val );
-
-
-    /* Variables to control playback */
-    var_CreateGetBool( p_playlist, "play-and-stop" );
-    var_CreateGetBool( p_playlist, "random" );
-    var_CreateGetBool( p_playlist, "repeat" );
-    var_CreateGetBool( p_playlist, "loop" );
-
-    /* Initialise data structures */
-    vlc_mutex_init( p_playlist, &p_playlist->gc_lock );
-    p_playlist->i_last_id = 0;
-    p_playlist->b_go_next = VLC_TRUE;
-    p_playlist->p_input = NULL;
-
-    p_playlist->request_date = 0;
-
-    p_playlist->i_views = 0;
-    p_playlist->pp_views = NULL;
-
-    p_playlist->i_index = -1;
-    p_playlist->i_size = 0;
-    p_playlist->pp_items = NULL;
-    p_playlist->i_all_size = 0;
-    p_playlist->pp_all_items = 0;
-
-    playlist_ViewInsert( p_playlist, VIEW_CATEGORY, TITLE_CATEGORY );
-    playlist_ViewInsert( p_playlist, VIEW_ALL, TITLE_ALL );
-
-    p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY );
-
-    p_playlist->p_general =
-        playlist_NodeCreate( p_playlist, VIEW_CATEGORY,
-                             _( "General" ), p_view->p_root );
-    p_playlist->p_general->i_flags |= PLAYLIST_RO_FLAG;
-
-    /* Set startup status
-     * We set to simple view on startup for interfaces that don't do
-     * anything */
-    p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY );
-    p_playlist->status.i_view = VIEW_CATEGORY;
-    p_playlist->status.p_item = NULL;
-    p_playlist->status.p_node = p_view->p_root;
-    p_playlist->request.b_request = VLC_FALSE;
-    p_playlist->status.i_status = PLAYLIST_STOPPED;
-
-    p_playlist->i_sort = SORT_ID;
-    p_playlist->i_order = ORDER_NORMAL;
-
-    p_playlist->p_stats = (global_stats_t *)malloc( sizeof( global_stats_t ) );
-    vlc_mutex_init( p_playlist, &p_playlist->p_stats->lock );
-
-    /* Finally, launch the thread ! */
-    if( vlc_thread_create( p_playlist, "playlist", RunThread,
-                           VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
-    {
-        msg_Err( p_playlist, "cannot spawn playlist thread" );
-        vlc_object_destroy( p_playlist );
-        return NULL;
-    }
-
-    /* Preparsing stuff */
-    p_playlist->p_preparse = vlc_object_create( p_playlist,
-                                                sizeof( playlist_preparse_t ) );
-    if( !p_playlist->p_preparse )
-    {
-        msg_Err( p_playlist, "unable to create preparser" );
-        vlc_object_destroy( p_playlist );
-        return NULL;
-    }
-
-    // Preparse
-    p_playlist->p_preparse->i_waiting = 0;
-    p_playlist->p_preparse->pi_waiting = NULL;
-
-    // Interaction
-    p_playlist->p_interaction = NULL;
-
-    vlc_object_attach( p_playlist->p_preparse, p_playlist );
-    if( vlc_thread_create( p_playlist->p_preparse, "preparser",
-                           RunPreparse, VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
-    {
-        msg_Err( p_playlist, "cannot spawn preparse thread" );
-        vlc_object_detach( p_playlist->p_preparse );
-        vlc_object_destroy( p_playlist->p_preparse );
-        return NULL;
-    }
-
-    /* The object has been initialized, now attach it */
-    vlc_object_attach( p_playlist, p_parent );
-
-    return p_playlist;
-}
-
-/**
- * Destroy the playlist.
- *
- * Delete all items in the playlist and free the playlist structure.
- * \param p_playlist the playlist structure to destroy
- * \return VLC_SUCCESS or an error
- */
-int playlist_Destroy( playlist_t * p_playlist )
-{
-    int i;
-    p_playlist->b_die = 1;
-
-    while( p_playlist->i_sds )
-    {
-        playlist_ServicesDiscoveryRemove( p_playlist,
-                                          p_playlist->pp_sds[0]->psz_module );
-    }
-
-    if( p_playlist->p_interaction )
-    {
-        intf_InteractionDestroy( p_playlist->p_interaction );
-    }
-
-    vlc_thread_join( p_playlist->p_preparse );
-    vlc_thread_join( p_playlist );
-
-    vlc_object_detach( p_playlist->p_preparse );
-
-    var_Destroy( p_playlist, "intf-change" );
-    var_Destroy( p_playlist, "item-change" );
-    var_Destroy( p_playlist, "playlist-current" );
-    var_Destroy( p_playlist, "intf-popmenu" );
-    var_Destroy( p_playlist, "intf-show" );
-    var_Destroy( p_playlist, "play-and-stop" );
-    var_Destroy( p_playlist, "random" );
-    var_Destroy( p_playlist, "repeat" );
-    var_Destroy( p_playlist, "loop" );
-
-    playlist_Clear( p_playlist );
-
-    for( i = p_playlist->i_views - 1; i >= 0 ; i-- )
-    {
-        playlist_view_t *p_view = p_playlist->pp_views[i];
-        if( p_view->psz_name )
-            free( p_view->psz_name );
-        playlist_ItemDelete( p_view->p_root );
-        REMOVE_ELEM( p_playlist->pp_views, p_playlist->i_views, i );
-        free( p_view );
-    }
-
-    if( p_playlist->p_stats )
-        free( p_playlist->p_stats );
-
-    vlc_mutex_destroy( &p_playlist->gc_lock );
-    vlc_object_destroy( p_playlist->p_preparse );
-    vlc_object_destroy( p_playlist );
-
-    return VLC_SUCCESS;
-}
-
-
-/**
- * Do a playlist action.
- *
- * If there is something in the playlist then you can do playlist actions.
- *
- * Playlist lock must not be taken when calling this function
- *
- * \param p_playlist the playlist to do the command on
- * \param i_query the command to do
- * \param variable number of arguments
- * \return VLC_SUCCESS or an error
- */
-int playlist_LockControl( playlist_t * p_playlist, int i_query, ... )
-{
-    va_list args;
-    int i_result;
-    va_start( args, i_query );
-    vlc_mutex_lock( &p_playlist->object_lock );
-    i_result = playlist_vaControl( p_playlist, i_query, args );
-    va_end( args );
-    vlc_mutex_unlock( &p_playlist->object_lock );
-    return i_result;
-}
-
-/**
- * Do a playlist action.
- *
- * If there is something in the playlist then you can do playlist actions.
- *
- * Playlist lock must be taken when calling this function
- *
- * \param p_playlist the playlist to do the command on
- * \param i_query the command to do
- * \param variable number of arguments
- * \return VLC_SUCCESS or an error
- */
-int playlist_Control( playlist_t * p_playlist, int i_query, ... )
-{
-    va_list args;
-    int i_result;
-    va_start( args, i_query );
-    i_result = playlist_vaControl( p_playlist, i_query, args );
-    va_end( args );
-
-    return i_result;
-}
-
-int playlist_vaControl( playlist_t * p_playlist, int i_query, va_list args )
-{
-    playlist_view_t *p_view;
-    playlist_item_t *p_item, *p_node;
-    int i_view;
-    vlc_value_t val;
-
-#ifdef PLAYLIST_PROFILE
-    p_playlist->request_date = mdate();
-#endif
-
-    if( p_playlist->i_size <= 0 )
-    {
-        return VLC_EGENERIC;
-    }
-
-    switch( i_query )
-    {
-    case PLAYLIST_STOP:
-        p_playlist->status.i_status = PLAYLIST_STOPPED;
-        p_playlist->request.b_request = VLC_TRUE;
-        p_playlist->request.p_item = NULL;
-        break;
-
-    case PLAYLIST_ITEMPLAY:
-        p_item = (playlist_item_t *)va_arg( args, playlist_item_t * );
-        if ( p_item == NULL || p_item->input.psz_uri == NULL )
-            return VLC_EGENERIC;
-        p_playlist->status.i_status = PLAYLIST_RUNNING;
-        p_playlist->request.i_skip = 0;
-        p_playlist->request.b_request = VLC_TRUE;
-        p_playlist->request.p_item = p_item;
-        p_playlist->request.i_view = p_playlist->status.i_view;
-        p_view = playlist_ViewFind( p_playlist, p_playlist->status.i_view );
-        if( p_view )
-        {
-            p_playlist->request.p_node = p_view->p_root;
-        }
-        else
-        {
-            p_playlist->request.p_node = NULL;
-        }
-        break;
-
-    case PLAYLIST_VIEWPLAY:
-        i_view = (int)va_arg( args,int );
-        p_node = (playlist_item_t *)va_arg( args, playlist_item_t * );
-        p_item = (playlist_item_t *)va_arg( args, playlist_item_t * );
-        if ( p_node == NULL ) //|| (p_item != NULL && p_item->input.psz_uri
-                                //                         == NULL ))
-        {
-            p_playlist->status.i_status = PLAYLIST_STOPPED;
-            p_playlist->request.b_request = VLC_TRUE;
-            return VLC_SUCCESS;
-        }
-        p_playlist->status.i_status = PLAYLIST_RUNNING;
-        p_playlist->request.i_skip = 0;
-        p_playlist->request.b_request = VLC_TRUE;
-        p_playlist->request.i_view = i_view;
-        p_playlist->request.p_node = p_node;
-        p_playlist->request.p_item = p_item;
-
-        /* Don't go further if the node doesn't want to */
-        if( ! p_playlist->request.p_node->i_flags & PLAYLIST_SKIP_FLAG )
-        {
-            p_playlist->b_go_next = VLC_FALSE;
-        }
-        else
-        {
-            p_playlist->b_go_next = VLC_TRUE;
-        }
-        break;
-
-    case PLAYLIST_PLAY:
-        p_playlist->status.i_status = PLAYLIST_RUNNING;
-
-        if( p_playlist->p_input )
-        {
-            val.i_int = PLAYING_S;
-            var_Set( p_playlist->p_input, "state", val );
-            break;
-        }
-
-        /* FIXME : needed ? */
-        p_playlist->request.b_request = VLC_TRUE;
-        p_playlist->request.i_view = p_playlist->status.i_view;
-        p_playlist->request.p_node = p_playlist->status.p_node;
-        p_playlist->request.p_item = p_playlist->status.p_item;
-        p_playlist->request.i_skip = 0;
-        p_playlist->request.i_goto = -1;
-        break;
-
-    case PLAYLIST_AUTOPLAY:
-        p_playlist->status.i_status = PLAYLIST_RUNNING;
-        p_playlist->status.p_node = p_playlist->p_general;
-
-        p_playlist->request.b_request = VLC_FALSE;
-        break;
-
-    case PLAYLIST_PAUSE:
-        val.i_int = 0;
-        if( p_playlist->p_input )
-            var_Get( p_playlist->p_input, "state", &val );
-
-        if( val.i_int == PAUSE_S )
-        {
-            p_playlist->status.i_status = PLAYLIST_RUNNING;
-            if( p_playlist->p_input )
-            {
-                val.i_int = PLAYING_S;
-                var_Set( p_playlist->p_input, "state", val );
-            }
-        }
-        else
-        {
-            p_playlist->status.i_status = PLAYLIST_PAUSED;
-            if( p_playlist->p_input )
-            {
-                val.i_int = PAUSE_S;
-                var_Set( p_playlist->p_input, "state", val );
-            }
-        }
-        break;
-
-    case PLAYLIST_SKIP:
-        p_playlist->request.i_view = p_playlist->status.i_view;
-        if( p_playlist->status.i_view > -1 )
-        {
-            p_playlist->request.p_node = p_playlist->status.p_node;
-            p_playlist->request.p_item = p_playlist->status.p_item;
-        }
-        else
-        {
-            p_playlist->request.p_node = NULL;
-            p_playlist->request.p_item = NULL;
-        }
-        p_playlist->request.i_skip = (int) va_arg( args, int );
-        p_playlist->request.b_request = VLC_TRUE;
-        break;
-
-    case PLAYLIST_GOTO:
-        p_playlist->status.i_status = PLAYLIST_RUNNING;
-        p_playlist->request.p_node = NULL;
-        p_playlist->request.p_item = NULL;
-        p_playlist->request.i_view = -1;
-        p_playlist->request.i_goto = (int) va_arg( args, int );
-        p_playlist->request.b_request = VLC_TRUE;
-        break;
-
-    default:
-        msg_Err( p_playlist, "unknown playlist query" );
-        return VLC_EBADVAR;
-        break;
-    }
-
-    return VLC_SUCCESS;
-}
-
-int playlist_PreparseEnqueue( playlist_t *p_playlist,
-                              input_item_t *p_item )
-{
-    vlc_mutex_lock( &p_playlist->p_preparse->object_lock );
-    INSERT_ELEM( p_playlist->p_preparse->pi_waiting,
-                 p_playlist->p_preparse->i_waiting,
-                 p_playlist->p_preparse->i_waiting,
-                 p_item->i_id );
-    vlc_mutex_unlock( &p_playlist->p_preparse->object_lock );
-    return VLC_SUCCESS;
-}
-
-/* Should only be called if playlist and preparser are locked */
-void playlist_PreparseEnqueueItemSub( playlist_t *p_playlist,
-                                     playlist_item_t *p_item )
-{
-    int i;
-    if( p_item->i_children == -1 )
-    {
-        INSERT_ELEM( p_playlist->p_preparse->pi_waiting,
-                     p_playlist->p_preparse->i_waiting,
-                     p_playlist->p_preparse->i_waiting,
-                     (p_item->input.i_id) );
-    }
-    else
-    {
-        for( i = 0; i < p_item->i_children; i++)
-        {
-            playlist_PreparseEnqueueItemSub( p_playlist,
-                                             p_item->pp_children[i] );
-        }
-    }
-}
-
-int playlist_PreparseEnqueueItem( playlist_t *p_playlist,
-                                  playlist_item_t *p_item )
-{
-    vlc_mutex_lock( &p_playlist->object_lock );
-    vlc_mutex_lock( &p_playlist->p_preparse->object_lock );
-    playlist_PreparseEnqueueItemSub( p_playlist, p_item );
-    vlc_mutex_unlock( &p_playlist->p_preparse->object_lock );
-    vlc_mutex_unlock( &p_playlist->object_lock );
-    return VLC_SUCCESS;
-}
-
-
-/* Destroy remaining objects */
-static mtime_t ObjectGarbageCollector( playlist_t *p_playlist, int i_type,
-                                       mtime_t destroy_date )
-{
-    vlc_object_t *p_obj;
-
-    if( destroy_date > mdate() ) return destroy_date;
-
-    if( destroy_date == 0 )
-    {
-        /* give a little time */
-        return mdate() + I64C(1000000);
-    }
-    else
-    {
-        vlc_mutex_lock( &p_playlist->gc_lock );
-        while( ( p_obj = vlc_object_find( p_playlist, i_type, FIND_CHILD ) ) )
-        {
-            if( p_obj->p_parent != (vlc_object_t*)p_playlist )
-            {
-                /* only first child (ie unused) */
-                vlc_object_release( p_obj );
-                break;
-            }
-            if( i_type == VLC_OBJECT_VOUT )
-            {
-                msg_Dbg( p_playlist, "garbage collector destroys 1 vout" );
-                vlc_object_detach( p_obj );
-                vlc_object_release( p_obj );
-                vout_Destroy( (vout_thread_t *)p_obj );
-            }
-            else if( i_type == VLC_OBJECT_SOUT )
-            {
-                vlc_object_release( p_obj );
-                sout_DeleteInstance( (sout_instance_t*)p_obj );
-            }
-        }
-        vlc_mutex_unlock( &p_playlist->gc_lock );
-        return 0;
-    }
-}
-
-/*****************************************************************************
- * RunThread: main playlist thread
- *****************************************************************************/
-static void RunThread ( playlist_t *p_playlist )
-{
-    vlc_object_t *p_obj;
-    playlist_item_t *p_item = NULL;
-
-    mtime_t    i_vout_destroyed_date = 0;
-    mtime_t    i_sout_destroyed_date = 0;
-
-    int i_loops = 0;
-
-    playlist_item_t *p_autodelete_item = NULL;
-
-    /* Tell above that we're ready */
-    vlc_thread_ready( p_playlist );
-
-    while( !p_playlist->b_die )
-    {
-        i_loops++;
-        if( p_playlist->p_interaction )
-        {
-            stats_TimerStart( p_playlist, "Interaction thread",
-                              STATS_TIMER_INTERACTION );
-            intf_InteractionManage( p_playlist );
-            stats_TimerStop( p_playlist, STATS_TIMER_INTERACTION );
-        }
-
-        if( i_loops %5 == 0 && p_playlist->p_stats )
-        {
-            stats_ComputeGlobalStats( p_playlist, p_playlist->p_stats );
-        }
-
-        vlc_mutex_lock( &p_playlist->object_lock );
-
-        /* First, check if we have something to do */
-        /* FIXME : this can be called several times */
-        if( p_playlist->request.b_request )
-        {
-#ifdef PLAYLIST_PROFILE
-            msg_Dbg(p_playlist, "beginning processing of request, "
-                         I64Fi" us ", mdate() - p_playlist->request_date );
-#endif
-            /* Stop the existing input */
-            if( p_playlist->p_input )
-            {
-                input_StopThread( p_playlist->p_input );
-            }
-            /* The code below will start the next input for us */
-            if( p_playlist->status.i_status == PLAYLIST_STOPPED )
-            {
-                p_playlist->request.b_request = VLC_FALSE;
-            }
-        }
-
-        /* If there is an input, check that it doesn't need to die. */
-        if( p_playlist->p_input )
-        {
-            if( i_loops % 5 == 0 )
-            {
-                stats_ComputeInputStats( p_playlist->p_input,
-                                  p_playlist->p_input->input.p_item->p_stats );
-//                stats_DumpInputStats(
-//                            p_playlist->p_input->input.p_item->p_stats );
-            }
-
-            /* This input is dead. Remove it ! */
-            if( p_playlist->p_input->b_dead )
-            {
-                input_thread_t *p_input;
-
-                p_input = p_playlist->p_input;
-                p_playlist->p_input = NULL;
-
-                /* Release the playlist lock, because we may get stuck
-                 * in input_DestroyThread() for some time. */
-                vlc_mutex_unlock( &p_playlist->object_lock );
-
-                /* Destroy input */
-                input_DestroyThread( p_input );
-
-                /* Unlink current input
-                 * (_after_ input_DestroyThread for vout garbage collector) */
-                vlc_object_detach( p_input );
-
-                /* Destroy object */
-                vlc_object_destroy( p_input );
-
-                i_vout_destroyed_date = 0;
-                i_sout_destroyed_date = 0;
-
-                if( p_playlist->status.p_item->i_flags
-                    & PLAYLIST_REMOVE_FLAG )
-                {
-                     playlist_ItemDelete( p_item );
-                     p_playlist->status.p_item = NULL;
-                }
-
-                continue;
-            }
-            /* This input is dying, let it do */
-            else if( p_playlist->p_input->b_die )
-            {
-                ;
-            }
-            /* This input has finished, ask it to die ! */
-            else if( p_playlist->p_input->b_error
-                      || p_playlist->p_input->b_eof )
-            {
-                /* TODO FIXME XXX TODO FIXME XXX */
-                /* Check for autodeletion */
-
-                if( p_playlist->status.p_item->i_flags & PLAYLIST_DEL_FLAG )
-                {
-                    p_autodelete_item = p_playlist->status.p_item;
-                }
-                input_StopThread( p_playlist->p_input );
-                /* Select the next playlist item */
-                vlc_mutex_unlock( &p_playlist->object_lock );
-                continue;
-            }
-            else if( p_playlist->p_input->i_state != INIT_S )
-            {
-                vlc_mutex_unlock( &p_playlist->object_lock );
-                i_vout_destroyed_date =
-                    ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT,
-                                            i_vout_destroyed_date );
-                i_sout_destroyed_date =
-                    ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT,
-                                            i_sout_destroyed_date );
-                vlc_mutex_lock( &p_playlist->object_lock );
-            }
-        }
-        else if( p_playlist->status.i_status != PLAYLIST_STOPPED )
-        {
-            /* Start another input.
-             * Get the next item to play */
-            stats_TimerStart( p_playlist, "Playlist walk",
-                              STATS_TIMER_PLAYLIST_WALK );
-            p_item = NextItem( p_playlist );
-            stats_TimerStop( p_playlist, STATS_TIMER_PLAYLIST_WALK );
-
-            /* We must stop */
-            if( p_item == NULL )
-            {
-                if( p_autodelete_item )
-                {
-                    playlist_Delete( p_playlist,
-                                     p_autodelete_item->input.i_id );
-                    p_autodelete_item = NULL;
-                }
-                p_playlist->status.i_status = PLAYLIST_STOPPED;
-                vlc_mutex_unlock( &p_playlist->object_lock );
-                continue;
-            }
-
-            PlayItem( p_playlist, p_item );
-
-            if( p_autodelete_item )
-            {
-                playlist_Delete( p_playlist, p_autodelete_item->input.i_id );
-                p_autodelete_item = NULL;
-            }
-        }
-        else if( p_playlist->status.i_status == PLAYLIST_STOPPED )
-        {
-            if( p_item && p_playlist->status.p_item &&
-                p_playlist->status.p_item->i_flags & PLAYLIST_REMOVE_FLAG )
-            {
-                 playlist_ItemDelete( p_item );
-                 p_playlist->status.p_item = NULL;
-            }
-
-            /* Collect garbage */
-            vlc_mutex_unlock( &p_playlist->object_lock );
-            i_sout_destroyed_date =
-                ObjectGarbageCollector( p_playlist, VLC_OBJECT_SOUT, mdate() );
-            i_vout_destroyed_date =
-                ObjectGarbageCollector( p_playlist, VLC_OBJECT_VOUT, mdate() );
-            vlc_mutex_lock( &p_playlist->object_lock );
-        }
-        vlc_mutex_unlock( &p_playlist->object_lock );
-
-        msleep( INTF_IDLE_SLEEP / 2 );
-
-        /* Stop sleeping earlier if we have work */
-        /* TODO : statistics about this */
-        if ( p_playlist->request.b_request &&
-                        p_playlist->status.i_status == PLAYLIST_RUNNING )
-        {
-            continue;
-        }
-
-        msleep( INTF_IDLE_SLEEP / 2 );
-    }
-
-    /* Playlist dying */
-
-    /* If there is an input, kill it */
-    while( 1 )
-    {
-        vlc_mutex_lock( &p_playlist->object_lock );
-
-        if( p_playlist->p_input == NULL )
-        {
-            vlc_mutex_unlock( &p_playlist->object_lock );
-            break;
-        }
-
-        if( p_playlist->p_input->b_dead )
-        {
-            input_thread_t *p_input;
-
-            /* Unlink current input */
-            p_input = p_playlist->p_input;
-            p_playlist->p_input = NULL;
-            vlc_mutex_unlock( &p_playlist->object_lock );
-
-            /* Destroy input */
-            input_DestroyThread( p_input );
-            /* Unlink current input (_after_ input_DestroyThread for vout
-             * garbage collector)*/
-            vlc_object_detach( p_input );
-
-            /* Destroy object */
-            vlc_object_destroy( p_input );
-            continue;
-        }
-        else if( p_playlist->p_input->b_die )
-        {
-            /* This input is dying, leave it alone */
-            ;
-        }
-        else if( p_playlist->p_input->b_error || p_playlist->p_input->b_eof )
-        {
-            input_StopThread( p_playlist->p_input );
-            vlc_mutex_unlock( &p_playlist->object_lock );
-            continue;
-        }
-        else
-        {
-            p_playlist->p_input->b_eof = 1;
-        }
-
-        vlc_mutex_unlock( &p_playlist->object_lock );
-
-        msleep( INTF_IDLE_SLEEP );
-    }
-
-    /* close all remaining sout */
-    while( ( p_obj = vlc_object_find( p_playlist,
-                                      VLC_OBJECT_SOUT, FIND_CHILD ) ) )
-    {
-        vlc_object_release( p_obj );
-        sout_DeleteInstance( (sout_instance_t*)p_obj );
-    }
-
-    /* close all remaining vout */
-    while( ( p_obj = vlc_object_find( p_playlist,
-                                      VLC_OBJECT_VOUT, FIND_CHILD ) ) )
-    {
-        vlc_object_detach( p_obj );
-        vlc_object_release( p_obj );
-        vout_Destroy( (vout_thread_t *)p_obj );
-    }
-}
-
-/* Queue for items to preparse */
-static void RunPreparse ( playlist_preparse_t *p_obj )
-{
-    playlist_t *p_playlist = (playlist_t *)p_obj->p_parent;
-    vlc_bool_t b_sleep;
-
-    /* Tell above that we're ready */
-    vlc_thread_ready( p_obj );
-
-    while( !p_playlist->b_die )
-    {
-        vlc_mutex_lock( &p_obj->object_lock );
-
-        if( p_obj->i_waiting > 0 )
-        {
-            int i_current_id = p_obj->pi_waiting[0];
-            playlist_item_t *p_current;
-            REMOVE_ELEM( p_obj->pi_waiting, p_obj->i_waiting, 0 );
-            vlc_mutex_unlock( &p_obj->object_lock );
-            vlc_mutex_lock( &p_playlist->object_lock );
-
-            p_current = playlist_ItemGetById( p_playlist, i_current_id );
-            if( p_current )
-            {
-                vlc_bool_t b_preparsed = VLC_FALSE;
-                if( strncmp( p_current->input.psz_uri, "http:", 5 ) &&
-                    strncmp( p_current->input.psz_uri, "rtsp:", 5 ) &&
-                    strncmp( p_current->input.psz_uri, "udp:", 4 ) &&
-                    strncmp( p_current->input.psz_uri, "mms:", 4 ) &&
-                    strncmp( p_current->input.psz_uri, "cdda:", 4 ) &&
-                    strncmp( p_current->input.psz_uri, "dvd:", 4 ) &&
-                    strncmp( p_current->input.psz_uri, "v4l:", 4 ) &&
-                    strncmp( p_current->input.psz_uri, "dshow:", 6 ) )
-                {
-                    b_preparsed = VLC_TRUE;
-                    stats_TimerStart( p_playlist, "Preparse run",
-                                      STATS_TIMER_PREPARSE );
-                    input_Preparse( p_playlist, &p_current->input );
-                    stats_TimerStop( p_playlist, STATS_TIMER_PREPARSE );
-                }
-                vlc_mutex_unlock( &p_playlist->object_lock );
-                if( b_preparsed )
-                {
-                    var_SetInteger( p_playlist, "item-change",
-                                    p_current->input.i_id );
-                }
-            }
-            else
-                vlc_mutex_unlock( &p_playlist->object_lock );
-            vlc_mutex_lock( &p_obj->object_lock );
-        }
-        b_sleep = ( p_obj->i_waiting == 0 );
-
-        vlc_mutex_unlock( &p_obj->object_lock );
-
-        if( p_obj->i_waiting == 0 )
-        {
-            msleep( INTF_IDLE_SLEEP );
-        }
-    }
-}
-
-/*****************************************************************************
- * NextItem
- *****************************************************************************
- * This function calculates the next playlist item, depending
- * on the playlist course mode (forward, backward, random, view,...).
- *****************************************************************************/
-static playlist_item_t * NextItem( playlist_t *p_playlist )
-{
-    playlist_item_t *p_new = NULL;
-    int i_skip,i_goto,i, i_new, i_count ;
-    playlist_view_t *p_view;
-
-    vlc_bool_t b_loop = var_GetBool( p_playlist, "loop" );
-    vlc_bool_t b_random = var_GetBool( p_playlist, "random" );
-    vlc_bool_t b_repeat = var_GetBool( p_playlist, "repeat" );
-    vlc_bool_t b_playstop = var_GetBool( p_playlist, "play-and-stop" );
-
-#ifdef PLAYLIST_PROFILE
-    /* Calculate time needed */
-    int64_t start = mdate();
-#endif
-    /* Handle quickly a few special cases */
-
-    /* No items to play */
-    if( p_playlist->i_size == 0 )
-    {
-        msg_Info( p_playlist, "playlist is empty" );
-        return NULL;
-    }
-    /* Nothing requested */
-    if( !p_playlist->request.b_request && p_playlist->status.p_item == NULL )
-    {
-        msg_Dbg( p_playlist,"nothing requested, starting" );
-    }
-
-    /* Repeat and play/stop */
-    if( !p_playlist->request.b_request && b_repeat == VLC_TRUE &&
-         p_playlist->status.p_item )
-    {
-        msg_Dbg( p_playlist,"repeating item" );
-        return p_playlist->status.p_item;
-    }
-
-    if( !p_playlist->request.b_request && b_playstop == VLC_TRUE )
-    {
-        msg_Dbg( p_playlist,"stopping (play and stop)");
-        return NULL;
-    }
-
-    if( !p_playlist->request.b_request && p_playlist->status.p_item &&
-        !( p_playlist->status.p_item->i_flags & PLAYLIST_SKIP_FLAG ) )
-    {
-        msg_Dbg( p_playlist, "no-skip mode, stopping") ;
-        return NULL;
-    }
-
-    /* TODO: improve this (only use current node) */
-    /* TODO: use the "shuffled view" internally ? */
-    /* Random case. This is an exception: if request, but request is skip +- 1
-     * we don't go to next item but select a new random one. */
-    if( b_random &&
-        ( !p_playlist->request.b_request ||
-        ( p_playlist->request.b_request && ( p_playlist->request.p_item == NULL ||
-          p_playlist->request.i_skip == 1 || p_playlist->request.i_skip == -1 ) ) ) )
-    {
-        /* how many items to choose from ? */
-        i_count = 0;
-        for ( i = 0; i < p_playlist->i_size; i++ )
-        {
-            if ( p_playlist->pp_items[i]->i_nb_played == 0 )
-                i_count++;
-        }
-        /* Nothing left? */
-        if ( i_count == 0 )
-        {
-            /* Don't loop? Exit! */
-            if( !b_loop )
-                return NULL;
-            /* Otherwise reset the counter */
-            for ( i = 0; i < p_playlist->i_size; i++ )
-            {
-                p_playlist->pp_items[i]->i_nb_played = 0;
-            }
-            i_count = p_playlist->i_size;
-        }
-        srand( (unsigned int)mdate() );
-        i = rand() % i_count + 1 ;
-        /* loop thru the list and count down the unplayed items to the selected one */
-        for ( i_new = 0; i_new < p_playlist->i_size && i > 0; i_new++ )
-        {
-            if ( p_playlist->pp_items[i_new]->i_nb_played == 0 )
-                i--;
-        }
-        i_new--;
-
-        p_playlist->request.i_skip = 0;
-        p_playlist->request.b_request = VLC_FALSE;
-        return p_playlist->pp_items[i_new];
-    }
-
-    /* Start the real work */
-    if( p_playlist->request.b_request )
-    {
-#ifdef PLAYLIST_DEBUG
-        msg_Dbg( p_playlist,"processing request" );
-#endif
-        /* We are not playing from a view */
-        if( p_playlist->request.i_view == -1  )
-        {
-#ifdef PLAYLIST_DEBUG
-            msg_Dbg( p_playlist, "non-view mode request");
-#endif
-            /* Directly select the item, just like now */
-            p_new = p_playlist->request.p_item;
-            i_skip = p_playlist->request.i_skip;
-            i_goto = p_playlist->request.i_goto;
-
-            if( p_playlist->i_index < 0 ) p_playlist->i_index = 0;
-            if ( p_new == NULL )
-                p_new = p_playlist->pp_items[p_playlist->i_index];
-
-            if( i_goto >= 0  && i_goto < p_playlist->i_size )
-            {
-                p_playlist->i_index = i_goto;
-                p_new = p_playlist->pp_items[p_playlist->i_index];
-                p_playlist->request.i_goto = -1;
-            }
-
-            if( i_skip != 0 )
-            {
-                if( p_playlist->i_index + i_skip < p_playlist->i_size &&
-                    p_playlist->i_index + i_skip >=  0 )
-                {
-                    p_playlist->i_index += i_skip;
-                    p_new = p_playlist->pp_items[p_playlist->i_index];
-                }
-                p_playlist->request.i_skip = 0;
-            }
-            if( !( p_new->i_flags & PLAYLIST_SKIP_FLAG ) )
-            {
-                return NULL;
-            }
-        }
-        else
-        {
-#ifdef PLAYLIST_DEBUG
-            msg_Dbg( p_playlist, "view mode request" );
-#endif
-            p_new = p_playlist->request.p_item;
-            i_skip = p_playlist->request.i_skip;
-
-            /* If we are asked for a node, take its first item */
-            if( p_playlist->request.p_item == NULL && i_skip == 0 )
-            {
-                i_skip++;
-            }
-
-            p_view = playlist_ViewFind( p_playlist,p_playlist->request.i_view );
-            p_playlist->status.p_node = p_playlist->request.p_node;
-            p_playlist->status.i_view = p_playlist->request.i_view;
-            if( !p_view )
-            {
-                msg_Err( p_playlist, "p_view is NULL and should not! (requested view is %i", p_playlist->request.i_view );
-            }
-            else if( i_skip > 0 )
-            {
-                for( i = i_skip; i > 0 ; i-- )
-                {
-                    p_new = playlist_FindNextFromParent( p_playlist,
-                                    p_playlist->request.i_view,
-                                    p_view->p_root,
-                                    p_playlist->request.p_node,
-                                    p_new );
-                    if( p_new == NULL )
-                    {
-#ifdef PLAYLIST_DEBUG
-                        msg_Dbg( p_playlist, "looping" );
-#endif
-                        p_new = playlist_FindNextFromParent( p_playlist,
-                                  p_playlist->request.i_view,
-                                  p_view->p_root,
-                                  p_view->p_root,
-                                  NULL );
-                        if( p_new == NULL ) break;
-                    }
-                }
-            }
-            else if( i_skip < 0 )
-            {
-                for( i = i_skip; i < 0 ; i++ )
-                {
-                    p_new = playlist_FindPrevFromParent( p_playlist,
-                                    p_playlist->request.i_view,
-                                    p_view->p_root,
-                                    p_playlist->request.p_node,
-                                    p_new );
-                    if( p_new == NULL )
-                    {
-                    /* We reach the beginning of the playlist.
-                       Go back to the last item. */
-                        p_new = playlist_RecursiveFindLast( p_playlist,
-                                                            p_view->p_root );
-                    }
-                    if( p_new == NULL ) break;
-                }
-
-            }
-        }
-        /* Clear the request */
-        p_playlist->request.b_request = VLC_FALSE;
-    }
-    /* "Automatic" item change ( next ) */
-    else
-    {
-        p_playlist->request_date = 0;
-
-        if( p_playlist->status.i_view == -1 )
-        {
-#ifdef PLAYLIST_DEBUG
-        msg_Dbg( p_playlist, "no request - old mode" );
-#endif
-            if( p_playlist->i_index + 1 < p_playlist->i_size )
-            {
-                p_playlist->i_index++;
-                p_new = p_playlist->pp_items[p_playlist->i_index];
-                if( !( p_new->i_flags & PLAYLIST_SKIP_FLAG ) )
-                {
-                    return NULL;
-                }
-            }
-            else
-            {
-                if( b_loop && p_playlist->i_size > 0)
-                {
-                    p_playlist->i_index = 0;
-                    p_new = p_playlist->pp_items[0];
-                }
-                else
-                    p_new = NULL;
-            }
-        }
-        /* We are playing with a view */
-        else
-        {
-#ifdef PLAYLIST_DEBUG
-            msg_Dbg( p_playlist,"no request - from a view" );
-#endif
-            playlist_view_t *p_view =
-                    playlist_ViewFind( p_playlist,
-                                   p_playlist->status.i_view );
-            if( !p_view )
-            {
-                msg_Err( p_playlist, "p_view is NULL and should not! (FIXME)" );
-            }
-            else
-            {
-                p_new = playlist_FindNextFromParent( p_playlist,
-                            p_playlist->status.i_view,
-                            p_view->p_root,
-                            p_playlist->status.p_node,
-                            p_playlist->status.p_item );
-                if( p_new == NULL && b_loop )
-                {
-#ifdef PLAYLIST_DEBUG
-                    msg_Dbg( p_playlist, "looping" );
-#endif
-                    p_new = playlist_FindNextFromParent( p_playlist,
-                                   p_playlist->status.i_view,
-                                   p_view->p_root,
-                                   p_view->p_root,
-                                   NULL );
-                }
-                if( p_new != NULL && !(p_new->i_flags & PLAYLIST_SKIP_FLAG) )
-                    return NULL;
-            }
-        }
-    }
-
-    /* Reset index */
-    if( p_playlist->i_index >= 0 && p_new != NULL &&
-            p_playlist->pp_items[p_playlist->i_index] != p_new )
-    {
-        p_playlist->i_index = playlist_GetPositionById( p_playlist,
-                                                        p_new->input.i_id );
-    }
-
-#ifdef PLAYLIST_PROFILE
-    msg_Dbg(p_playlist,"next item found in "I64Fi " us", mdate()-start );
-#endif
-
-    if( p_new == NULL )
-    {
-        msg_Info( p_playlist, "nothing to play" );
-    }
-
-    return p_new;
-}
-
-/*****************************************************************************
- * PlayItem: start the input thread for an item
- ****************************************************************************/
-static int PlayItem( playlist_t *p_playlist, playlist_item_t *p_item )
-{
-    vlc_value_t val;
-
-    msg_Dbg( p_playlist, "creating new input thread" );
-
-    p_item->i_nb_played++;
-    p_playlist->status.p_item = p_item;
-
-    p_playlist->i_index = playlist_GetPositionById( p_playlist,
-                                                    p_item->input.i_id );
-
-#ifdef PLAYLIST_PROFILE
-    if( p_playlist->request_date != 0 )
-    {
-        msg_Dbg( p_playlist, "request processed after "I64Fi " us",
-                  mdate() - p_playlist->request_date );
-    }
-#endif
-
-    p_playlist->p_input = input_CreateThread( p_playlist, &p_item->input );
-
-    val.i_int = p_item->input.i_id;
-    /* unlock the playlist to set the var...mmm */
-    vlc_mutex_unlock( &p_playlist->object_lock);
-    var_Set( p_playlist, "playlist-current", val);
-    vlc_mutex_lock( &p_playlist->object_lock);
-
-    return VLC_SUCCESS;
-
-}
diff --git a/src/playlist/search.c b/src/playlist/search.c
new file mode 100644 (file)
index 0000000..29c0779
--- /dev/null
@@ -0,0 +1,109 @@
+/*****************************************************************************
+ * search.c : Search functions
+ *****************************************************************************
+ * Copyright (C) 1999-2004 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/input.h>
+
+#include "vlc_playlist.h"
+
+/***************************************************************************
+ * Item search functions
+ ***************************************************************************/
+
+/**
+ * Search a playlist item by its playlist_item id
+ *
+ * \param p_playlist the playlist
+ * \param i_id the id to find
+ * \return the item or NULL on failure
+ */
+playlist_item_t * playlist_ItemGetById( playlist_t * p_playlist , int i_id )
+{
+    int i, i_top, i_bottom;
+    i_bottom = 0; i_top = p_playlist->i_all_size - 1;
+    i = i_top / 2;
+    while( p_playlist->pp_all_items[i]->i_id != i_id &&
+           i_top > i_bottom )
+    {
+        if( p_playlist->pp_all_items[i]->i_id < i_id )
+            i_bottom = i + 1;
+        else
+            i_top = i - 1;
+        i = i_bottom + ( i_top - i_bottom ) / 2;
+    }
+    if( p_playlist->pp_all_items[i]->i_id == i_id )
+    {
+        return p_playlist->pp_all_items[i];
+    }
+    return NULL;
+}
+
+/**
+ * Search an item by its input_item_t
+ *
+ * \param p_playlist the playlist
+ * \param p_item the input_item_t to find
+ * \return the item, or NULL on failure
+ */
+playlist_item_t * playlist_ItemGetByInput( playlist_t * p_playlist ,
+                                           input_item_t *p_item )
+{
+    int i;
+    if( p_playlist->status.p_item && p_playlist->status.p_item->p_input == p_item )
+    {
+        return p_playlist->status.p_item;
+    }
+
+    for( i =  0 ; i < p_playlist->i_all_size; i++ )
+    {
+msg_Err( p_playlist, "%p, %p", p_item, p_playlist->pp_all_items[i]->p_input );
+        if( p_playlist->pp_all_items[i]->p_input == p_item )
+        {
+            return p_playlist->pp_all_items[i];
+        }
+    }
+    return NULL;
+}
+
+/***************************************************************************
+ * Live search handling
+ ***************************************************************************/
+
+int playlist_LiveSearchUpdate( playlist_t *p_playlist, playlist_item_t *p_root,
+                               const char *psz_string )
+{
+   int i;
+   for( i = 0 ; i< p_root->i_children ; i ++ )
+   {
+        playlist_item_t *p_item = p_root->pp_children[i];
+        if( p_item->i_children > -1 )
+        {
+            playlist_LiveSearchUpdate( p_playlist, p_item, psz_string );
+        }
+        /* Todo: Filter on all fields */
+        if( strcasestr( p_item->p_input->psz_name, psz_string ) )
+            p_item->i_flags &= ~PLAYLIST_DBL_FLAG;
+        else
+            p_item->i_flags |= PLAYLIST_DBL_FLAG;
+   }
+   return VLC_SUCCESS;
+}
index b530d93fc8070eb11c2c7864a6b0d5b1ba36b82a..6d6e25f85bfcc29f10b8bd3e3a0f91ec6ff3c1ed 100644 (file)
@@ -36,49 +36,6 @@ int playlist_ItemArraySort( playlist_t *p_playlist, int i_items,
                 playlist_item_t **pp_items, int i_mode,
                 int i_type );
 
-
-/**
- * Sort the playlist.
- * \param p_playlist the playlist
- * \param i_mode: SORT_ID, SORT_TITLE, SORT_AUTHOR, SORT_ALBUM, SORT_RANDOM
- * \param i_type: ORDER_NORMAL or ORDER_REVERSE (reversed order)
- * \return VLC_SUCCESS on success
- */
-int playlist_Sort( playlist_t * p_playlist , int i_mode, int i_type )
-{
-    int  i_id = -1;
-    vlc_value_t val;
-    val.b_bool = VLC_TRUE;
-
-    vlc_mutex_lock( &p_playlist->object_lock );
-
-    p_playlist->i_sort = i_mode;
-    p_playlist->i_order = i_type;
-
-    if( p_playlist->i_index >= 0 )
-    {
-        i_id = p_playlist->pp_items[p_playlist->i_index]->input.i_id;
-    }
-
-    playlist_ItemArraySort( p_playlist, p_playlist->i_size,
-                    p_playlist->pp_items, i_mode, i_type );
-
-    if( i_id != -1 )
-    {
-        p_playlist->i_index = playlist_GetPositionById( p_playlist, i_id );
-    }
-
-    /* ensure we are in no-view mode */
-    p_playlist->status.i_view = -1;
-
-    vlc_mutex_unlock( &p_playlist->object_lock );
-
-    /* Notify the interfaces */
-    var_Set( p_playlist, "intf-change", val );
-
-    return VLC_SUCCESS;
-}
-
 /**
  * Sort a node.
  *
@@ -97,8 +54,6 @@ int playlist_NodeSort( playlist_t * p_playlist , playlist_item_t *p_node,
     playlist_ItemArraySort( p_playlist,p_node->i_children,
                             p_node->pp_children, i_mode, i_type );
 
-    p_node->i_serial++;
-
     return VLC_SUCCESS;
 }
 
@@ -170,27 +125,23 @@ int playlist_ItemArraySort( playlist_t *p_playlist, int i_items,
 
             if( i_mode == SORT_TITLE )
             {
-                i_test = strcasecmp( pp_items[i]->input.psz_name,
-                                         pp_items[i_small]->input.psz_name );
+                i_test = strcasecmp( pp_items[i]->p_input->psz_name,
+                                         pp_items[i_small]->p_input->psz_name );
             }
             else if( i_mode == SORT_TITLE_NUMERIC )
             {
-                i_test = atoi( pp_items[i]->input.psz_name ) -
-                         atoi( pp_items[i_small]->input.psz_name );
+                i_test = atoi( pp_items[i]->p_input->psz_name ) -
+                         atoi( pp_items[i_small]->p_input->psz_name );
             }
             else if( i_mode == SORT_DURATION )
             {
-                i_test = pp_items[i]->input.i_duration -
-                             pp_items[i_small]->input.i_duration;
+                i_test = pp_items[i]->p_input->i_duration -
+                             pp_items[i_small]->p_input->i_duration;
             }
             else if( i_mode == SORT_AUTHOR )
             {
-                char *psz_a = vlc_input_item_GetInfo(
-                                 &pp_items[i]->input,
-                                 _(VLC_META_INFO_CAT), _(VLC_META_ARTIST) );
-                char *psz_b = vlc_input_item_GetInfo(
-                                 &pp_items[i_small]->input,
-                                 _(VLC_META_INFO_CAT), _(VLC_META_ARTIST) );
+                char *psz_a = pp_items[i]->p_input->p_meta->psz_artist;
+                char *psz_b = pp_items[i_small]->p_input->p_meta->psz_artist;
                 if( pp_items[i]->i_children == -1 &&
                     pp_items[i_small]->i_children >= 0 )
                 {
@@ -205,8 +156,8 @@ int playlist_ItemArraySort( playlist_t *p_playlist, int i_items,
                 else if( pp_items[i]->i_children >= 0 &&
                          pp_items[i_small]->i_children >= 0 )
                 {
-                    i_test = strcasecmp( pp_items[i]->input.psz_name,
-                                         pp_items[i_small]->input.psz_name );
+                    i_test = strcasecmp( pp_items[i]->p_input->psz_name,
+                                         pp_items[i_small]->p_input->psz_name );
                 }
                 else if( psz_a == NULL && psz_b != NULL )
                 {
@@ -218,8 +169,8 @@ int playlist_ItemArraySort( playlist_t *p_playlist, int i_items,
                 }
                 else if( psz_a == NULL && psz_b == NULL )
                 {
-                    i_test = strcasecmp( pp_items[i]->input.psz_name,
-                                         pp_items[i_small]->input.psz_name );
+                    i_test = strcasecmp( pp_items[i]->p_input->psz_name,
+                                         pp_items[i_small]->p_input->psz_name );
                 }
                 else
                 {
@@ -227,13 +178,9 @@ int playlist_ItemArraySort( playlist_t *p_playlist, int i_items,
                 }
             }
             else if( i_mode == SORT_ALBUM )
-           {
-                char *psz_a = vlc_input_item_GetInfo(
-                                 &pp_items[i]->input,
-                                 _(VLC_META_INFO_CAT), _(VLC_META_COLLECTION) );
-                char *psz_b = vlc_input_item_GetInfo(
-                                 &pp_items[i_small]->input,
-                                 _(VLC_META_INFO_CAT), _(VLC_META_COLLECTION) );
+            {
+                char *psz_a =  pp_items[i]->p_input->p_meta->psz_album;
+                char *psz_b =  pp_items[i_small]->p_input->p_meta->psz_album;
                 if( pp_items[i]->i_children == -1 &&
                     pp_items[i_small]->i_children >= 0 )
                 {
@@ -248,8 +195,8 @@ int playlist_ItemArraySort( playlist_t *p_playlist, int i_items,
                 else if( pp_items[i]->i_children >= 0 &&
                          pp_items[i_small]->i_children >= 0 )
                 {
-                    i_test = strcasecmp( pp_items[i]->input.psz_name,
-                                         pp_items[i_small]->input.psz_name );
+                    i_test = strcasecmp( pp_items[i]->p_input->psz_name,
+                                         pp_items[i_small]->p_input->psz_name );
                 }
                 else if( psz_a == NULL && psz_b != NULL )
                 {
@@ -261,14 +208,14 @@ int playlist_ItemArraySort( playlist_t *p_playlist, int i_items,
                 }
                 else if( psz_a == NULL && psz_b == NULL )
                 {
-                    i_test = strcasecmp( pp_items[i]->input.psz_name,
-                                         pp_items[i_small]->input.psz_name );
+                    i_test = strcasecmp( pp_items[i]->p_input->psz_name,
+                                         pp_items[i_small]->p_input->psz_name );
                 }
                 else
                 {
                     i_test = strcmp( psz_b, psz_a );
                 }
-           }
+            }
             else if( i_mode == SORT_TITLE_NODES_FIRST )
             {
                 /* Alphabetic sort, all nodes first */
@@ -285,8 +232,8 @@ int playlist_ItemArraySort( playlist_t *p_playlist, int i_items,
                 }
                 else
                 {
-                    i_test = strcasecmp( pp_items[i]->input.psz_name,
-                                         pp_items[i_small]->input.psz_name );
+                    i_test = strcasecmp( pp_items[i]->p_input->psz_name,
+                                         pp_items[i_small]->p_input->psz_name );
                 }
             }
 
@@ -304,8 +251,7 @@ int playlist_ItemArraySort( playlist_t *p_playlist, int i_items,
 }
 
 
-int playlist_NodeGroup( playlist_t * p_playlist , int i_view,
-                        playlist_item_t *p_root,
+int playlist_NodeGroup( playlist_t * p_playlist , playlist_item_t *p_root,
                         playlist_item_t **pp_items,int i_item,
                         int i_mode, int i_type )
 {
@@ -320,22 +266,19 @@ int playlist_NodeGroup( playlist_t * p_playlist , int i_view,
         if( psz_search ) free( psz_search );
         if( i_mode == SORT_TITLE )
         {
-            psz_search = strdup( pp_items[i]->input.psz_name );
+            psz_search = strdup( pp_items[i]->p_input->psz_name );
         }
         else if ( i_mode == SORT_AUTHOR )
         {
-            psz_search = vlc_input_item_GetInfo( &pp_items[i]->input,
-                            _(VLC_META_INFO_CAT), _(VLC_META_ARTIST) );
+            psz_search = pp_items[i]->p_input->p_meta->psz_artist;
         }
         else if ( i_mode == SORT_ALBUM )
         {
-            psz_search = vlc_input_item_GetInfo( &pp_items[i]->input,
-                            _(VLC_META_INFO_CAT), _(VLC_META_COLLECTION) );
+            psz_search = pp_items[i]->p_input->p_meta->psz_album;
         }
         else if ( i_mode == SORT_GENRE )
         {
-            psz_search = vlc_input_item_GetInfo( &pp_items[i]->input,
-                            _(VLC_META_INFO_CAT), _(VLC_META_GENRE) );
+            psz_search = pp_items[i]->p_input->p_meta->psz_genre;
         }
 
         if( psz_search && !strcmp( psz_search, "" ) )
@@ -347,21 +290,18 @@ int playlist_NodeGroup( playlist_t * p_playlist , int i_view,
         b_found = VLC_FALSE;
         for( j = 0 ; j< i_nodes; j++ )
         {
-           if( !strcasecmp( psz_search, pp_nodes[j]->input.psz_name ) )
+           if( !strcasecmp( psz_search, pp_nodes[j]->p_input->psz_name ) )
            {
-                playlist_NodeAppend( p_playlist, i_view,
-                                     pp_items[i], pp_nodes[j] );
+                playlist_NodeAppend( p_playlist, pp_items[i], pp_nodes[j] );
                 b_found = VLC_TRUE;
                 break;
            }
         }
         if( !b_found )
         {
-            p_node = playlist_NodeCreate( p_playlist, i_view,psz_search,
-                                          NULL );
+            p_node = playlist_NodeCreate( p_playlist, psz_search, NULL );
             INSERT_ELEM( pp_nodes, i_nodes, i_nodes, p_node );
-            playlist_NodeAppend( p_playlist, i_view,
-                                 pp_items[i],p_node );
+            playlist_NodeAppend( p_playlist, pp_items[i],p_node );
         }
     }
 
@@ -375,8 +315,7 @@ int playlist_NodeGroup( playlist_t * p_playlist , int i_view,
         playlist_ItemArraySort( p_playlist, pp_nodes[i]->i_children,
                                 pp_nodes[i]->pp_children, SORT_TITLE, i_type );
 
-        playlist_NodeAppend( p_playlist, i_view,
-                             pp_nodes[i], p_root );
+        playlist_NodeAppend( p_playlist, pp_nodes[i], p_root );
     }
     return VLC_SUCCESS;
 }
diff --git a/src/playlist/thread.c b/src/playlist/thread.c
new file mode 100644 (file)
index 0000000..9e36aca
--- /dev/null
@@ -0,0 +1,241 @@
+/*****************************************************************************
+ * playlist.c : Playlist management functions
+ *****************************************************************************
+ * Copyright (C) 1999-2004 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Samuel Hocevar <sam@zoy.org>
+ *          Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc_input.h>
+#include "vlc_playlist.h"
+#include "vlc_interaction.h"
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static void RunControlThread ( playlist_t * );
+static void RunPreparse( playlist_preparse_t * );
+
+static playlist_t * CreatePlaylist( vlc_object_t *p_parent );
+static void HandlePlaylist( playlist_t * );
+static void EndPlaylist( playlist_t * );
+static void DestroyPlaylist( playlist_t * );
+
+static void HandleStats( playlist_t *, int );
+
+static void HandleInteraction( playlist_t * );
+static void DestroyInteraction( playlist_t * );
+
+/*****************************************************************************
+ * Main functions for the global thread
+ *****************************************************************************/
+
+/**
+ * Create the main playlist thread
+ * Additionally to the playlist, this thread controls :
+ *    - Interaction
+ *    - Statistics
+ *    - VLM
+ * \param p_parent
+ * \return an object with a started thread
+ */
+playlist_t * __playlist_ThreadCreate( vlc_object_t *p_parent )
+{
+    playlist_t *p_playlist;
+    p_playlist = CreatePlaylist( p_parent );
+
+    if( !p_playlist ) return NULL;
+
+    // Stats
+    p_playlist->p_stats = (global_stats_t *)malloc( sizeof( global_stats_t ) );
+    vlc_mutex_init( p_playlist, &p_playlist->p_stats->lock );
+
+    // Interaction
+    p_playlist->p_interaction = NULL;
+
+    // Preparse
+    p_playlist->p_preparse = vlc_object_create( p_playlist,
+                                  sizeof( playlist_preparse_t ) );
+    if( !p_playlist->p_preparse )
+    {
+        msg_Err( p_playlist, "unable to create preparser" );
+        vlc_object_destroy( p_playlist );
+        return NULL;
+    }
+    p_playlist->p_preparse->i_waiting = 0;
+    p_playlist->p_preparse->pp_waiting = NULL;
+
+    vlc_object_attach( p_playlist->p_preparse, p_playlist );
+    if( vlc_thread_create( p_playlist->p_preparse, "preparser",
+                           RunPreparse, VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
+    {
+        msg_Err( p_playlist, "cannot spawn preparse thread" );
+        vlc_object_detach( p_playlist->p_preparse );
+        vlc_object_destroy( p_playlist->p_preparse );
+        return NULL;
+    }
+
+    // Start the thread
+    if( vlc_thread_create( p_playlist, "playlist", RunControlThread,
+                           VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) )
+    {
+        msg_Err( p_playlist, "cannot spawn playlist thread" );
+        vlc_object_destroy( p_playlist );
+        return NULL;
+    }
+
+    /* The object has been initialized, now attach it */
+    vlc_object_attach( p_playlist, p_parent );
+
+    return p_playlist;
+}
+
+/**
+ * Destroy the playlist global thread.
+ *
+ * Deinits all things controlled by the playlist global thread
+ * \param p_playlist the playlist thread to destroy
+ * \return VLC_SUCCESS or an error
+ */
+int playlist_ThreadDestroy( playlist_t * p_playlist )
+{
+    p_playlist->b_die = 1;
+
+    DestroyInteraction( p_playlist );
+    DestroyPlaylist( p_playlist );
+
+    return VLC_SUCCESS;
+}
+
+/**
+ * Run the main control thread itself
+ */
+static void RunControlThread ( playlist_t *p_playlist )
+{
+   int i_loops = 0;
+
+   /* Tell above that we're ready */
+   vlc_thread_ready( p_playlist );
+
+    while( !p_playlist->b_die )
+    {
+        i_loops++;
+
+        HandleInteraction( p_playlist );
+        HandleStats( p_playlist, i_loops );
+
+        HandlePlaylist( p_playlist );
+
+        msleep( INTF_IDLE_SLEEP / 2 );
+
+        /* Stop sleeping earlier if we have work */
+        /* TODO : statistics about this */
+        if ( p_playlist->request.b_request &&
+                        p_playlist->status.i_status == PLAYLIST_RUNNING )
+        {
+            continue;
+        }
+
+        msleep( INTF_IDLE_SLEEP / 2 );
+    }
+
+    EndPlaylist( p_playlist );
+}
+
+
+/*****************************************************************************
+ * Playlist-specific functions
+ *****************************************************************************/
+static playlist_t * CreatePlaylist( vlc_object_t *p_parent )
+{
+    return playlist_Create( p_parent );
+}
+
+static void DestroyPlaylist( playlist_t *p_playlist )
+{
+    playlist_Destroy( p_playlist );
+}
+
+static void HandlePlaylist( playlist_t *p_playlist )
+{
+    playlist_MainLoop( p_playlist );
+}
+
+static void EndPlaylist( playlist_t *p_playlist )
+{
+    playlist_LastLoop( p_playlist );
+}
+
+/*****************************************************************************
+ * Preparse-specific functions
+ *****************************************************************************/
+static void RunPreparse ( playlist_preparse_t *p_obj )
+{
+    /* Tell above that we're ready */
+    vlc_thread_ready( p_obj );
+    playlist_t *p_playlist = (playlist_t *)p_obj->p_parent;
+
+    while( !p_playlist->b_die )
+    {
+        playlist_PreparseLoop(  p_obj );
+        if( p_obj->i_waiting == 0 )
+        {
+            msleep( INTF_IDLE_SLEEP );
+        }
+    }
+}
+
+/*****************************************************************************
+ * Interaction functions
+ *****************************************************************************/
+static void DestroyInteraction( playlist_t *p_playlist )
+{
+    if( p_playlist->p_interaction )
+    {
+        intf_InteractionDestroy( p_playlist->p_interaction );
+    }
+}
+
+static void HandleInteraction( playlist_t *p_playlist )
+{
+    if( p_playlist->p_interaction )
+    {
+        stats_TimerStart( p_playlist, "Interaction thread",
+                          STATS_TIMER_INTERACTION );
+        intf_InteractionManage( p_playlist );
+        stats_TimerStop( p_playlist, STATS_TIMER_INTERACTION );
+    }
+}
+
+
+/*****************************************************************************
+ * Stats functions
+ *****************************************************************************/
+static void HandleStats( playlist_t *p_playlist, int i_loops )
+{
+    if( i_loops %5 == 0 && p_playlist->p_stats )
+    {
+        stats_ComputeGlobalStats( p_playlist, p_playlist->p_stats );
+        if( p_playlist->p_input )
+        {
+            stats_ComputeInputStats( p_playlist->p_input,
+                                p_playlist->p_input->input.p_item->p_stats );
+        }
+    }
+}
diff --git a/src/playlist/tree.c b/src/playlist/tree.c
new file mode 100644 (file)
index 0000000..c151dc1
--- /dev/null
@@ -0,0 +1,673 @@
+/*****************************************************************************
+ * tree.c : Playlist tree walking functions
+ *****************************************************************************
+ * Copyright (C) 1999-2004 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Clément Stenac <zorglub@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#include <vlc/vlc.h>
+#include <vlc/input.h>
+#include "vlc_playlist.h"
+
+#define PLAYLIST_DEBUG 1
+
+/************************************************************************
+ * Local prototypes
+ ************************************************************************/
+playlist_item_t *GetNextUncle( playlist_t *p_playlist, playlist_item_t *p_item,
+                               playlist_item_t *p_root );
+playlist_item_t *GetPrevUncle( playlist_t *p_playlist, playlist_item_t *p_item,
+                               playlist_item_t *p_root );
+
+playlist_item_t *GetNextItem( playlist_t *p_playlist,
+                              playlist_item_t *p_root,
+                              playlist_item_t *p_item );
+playlist_item_t *GetPrevItem( playlist_t *p_playlist,
+                              playlist_item_t *p_item,
+                              playlist_item_t *p_root );
+
+/**
+ * Create a playlist node
+ *
+ * \param p_playlist the playlist
+ * \paam psz_name the name of the node
+ * \param p_parent the parent node to attach to or NULL if no attach
+ * \return the new node
+ */
+playlist_item_t * playlist_NodeCreate( playlist_t *p_playlist, char *psz_name,
+                                       playlist_item_t *p_parent )
+{
+    input_item_t *p_input;
+    playlist_item_t *p_item;
+
+    if( !psz_name ) psz_name = strdup( _("Undefined") );
+    p_input = input_ItemNewWithType( VLC_OBJECT(p_playlist), NULL, psz_name,
+                                     0, NULL, -1, ITEM_TYPE_NODE );
+    p_input->i_id = ++p_playlist->i_last_input_id;
+    p_item = playlist_ItemNewFromInput( VLC_OBJECT(p_playlist), p_input );
+    p_item->i_children = 0;
+
+    if( p_item == NULL )
+    {
+        return NULL;
+    }
+    INSERT_ELEM( p_playlist->pp_all_items,
+                 p_playlist->i_all_size,
+                 p_playlist->i_all_size,
+                 p_item );
+
+    if( p_parent != NULL )
+    {
+        playlist_NodeAppend( p_playlist, p_item, p_parent );
+    }
+
+    playlist_SendAddNotify( p_playlist, p_item->i_id,
+                            p_parent ? p_parent->i_id : -1 );
+    return p_item;
+}
+
+/**
+ * Remove all the children of a node
+ *
+ * This function must be entered with the playlist lock
+ *
+ * \param p_playlist the playlist
+ * \param p_root the node
+ * \param b_delete_items do we have to delete the children items ?
+ * \return VLC_SUCCESS or an error
+ */
+int playlist_NodeEmpty( playlist_t *p_playlist, playlist_item_t *p_root,
+                        vlc_bool_t b_delete_items )
+{
+    int i;
+    if( p_root->i_children == -1 )
+    {
+        return VLC_EGENERIC;
+    }
+
+    /* Delete the children */
+    for( i =  p_root->i_children-1 ; i >= 0 ;i-- )
+    {
+        if( p_root->pp_children[i]->i_children > -1 )
+        {
+            playlist_NodeDelete( p_playlist, p_root->pp_children[i],
+                                 b_delete_items , VLC_FALSE );
+        }
+        else if( b_delete_items )
+        {
+            /* Delete the item here */
+            playlist_DeleteFromItemId( p_playlist,
+                                       p_root->pp_children[i]->i_id );
+        }
+    }
+    return VLC_SUCCESS;
+}
+
+/**
+ * Remove all the children of a node and removes the node
+ *
+ * \param p_playlist the playlist
+ * \param p_root the node
+ * \param b_delete_items do we have to delete the children items ?
+ * \return VLC_SUCCESS or an error
+ */
+int playlist_NodeDelete( playlist_t *p_playlist, playlist_item_t *p_root,
+                         vlc_bool_t b_delete_items, vlc_bool_t b_force )
+{
+    int i, i_top, i_bottom;
+    if( p_root->i_children == -1 )
+    {
+        return VLC_EGENERIC;
+    }
+
+    /* Delete the children */
+    for( i =  p_root->i_children - 1 ; i >= 0; i-- )
+    {
+        if( p_root->pp_children[i]->i_children > -1 )
+        {
+            playlist_NodeDelete( p_playlist, p_root->pp_children[i],
+                                 b_delete_items , b_force );
+        }
+        else if( b_delete_items )
+        {
+            playlist_DeleteFromItemId( p_playlist,
+                                       p_root->pp_children[i]->i_id );
+        }
+    }
+    /* Delete the node */
+    if( p_root->i_flags & PLAYLIST_RO_FLAG && !b_force )
+    {
+    }
+    else
+    {
+        var_SetInteger( p_playlist, "item-deleted", p_root->p_input->i_id );
+
+        i_bottom = 0; i_top = p_playlist->i_all_size - 1;
+        i = i_top / 2;
+        while( p_playlist->pp_all_items[i]->p_input->i_id !=
+                  p_root->p_input->i_id &&   i_top > i_bottom )
+        {
+            if( p_playlist->pp_all_items[i]->p_input->i_id <
+                               p_root->p_input->i_id )
+            {
+                i_bottom = i + 1;
+            }
+            else
+            {
+                i_top = i - 1;
+            }
+            i = i_bottom + ( i_top - i_bottom ) / 2;
+        }
+        if( p_playlist->pp_all_items[i]->p_input->i_id ==
+            p_root->p_input->i_id )
+        {
+            REMOVE_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size, i );
+        }
+        playlist_ItemDelete( p_root );
+    }
+    return VLC_SUCCESS;
+}
+
+
+/**
+ * Adds an item to the children of a node
+ *
+ * \param p_playlist the playlist
+ * \param p_item the item to append
+ * \param p_parent the parent node
+ * \return VLC_SUCCESS or an error
+ */
+int playlist_NodeAppend( playlist_t *p_playlist,
+                         playlist_item_t *p_item,
+                         playlist_item_t *p_parent )
+{
+    return playlist_NodeInsert( p_playlist, p_item, p_parent, -1 );
+}
+
+int playlist_NodeInsert( playlist_t *p_playlist,
+                         playlist_item_t *p_item,
+                         playlist_item_t *p_parent,
+                         int i_position )
+{
+   if( !p_parent || p_parent->i_children == -1 )
+   {
+        msg_Err( p_playlist, "invalid node" );
+        return VLC_EGENERIC;
+   }
+   if( i_position == -1 ) i_position = p_parent->i_children ;
+
+   INSERT_ELEM( p_parent->pp_children,
+                p_parent->i_children,
+                i_position,
+                p_item );
+
+   p_item->p_parent = p_parent;
+
+   return VLC_SUCCESS;
+}
+
+/**
+ * Deletes an item from the children of a node
+ *
+ * \param p_playlist the playlist
+ * \param p_item the item to remove
+ * \param p_parent the parent node
+ * \return VLC_SUCCESS or an error
+ */
+int playlist_NodeRemoveItem( playlist_t *p_playlist,
+                        playlist_item_t *p_item,
+                        playlist_item_t *p_parent )
+{
+   int i;
+   for( i= 0; i< p_parent->i_children ; i++ )
+   {
+       if( p_parent->pp_children[i] == p_item )
+       {
+           REMOVE_ELEM( p_parent->pp_children, p_parent->i_children, i );
+       }
+   }
+
+   return VLC_SUCCESS;
+}
+
+
+/**
+ * Count the children of a node
+ *
+ * \param p_playlist the playlist
+ * \param p_node the node
+ * \return the number of children
+ */
+int playlist_NodeChildrenCount( playlist_t *p_playlist, playlist_item_t*p_node)
+{
+    int i;
+    int i_nb = 0;
+    if( p_node->i_children == -1 )
+        return 0;
+
+    for( i=0 ; i< p_node->i_children;i++ )
+    {
+        if( p_node->pp_children[i]->i_children == -1 )
+            i_nb++;
+        else
+            i_nb += playlist_NodeChildrenCount( p_playlist,
+                                                p_node->pp_children[i] );
+    }
+    return i_nb;
+}
+
+/**
+ * Search a child of a node by its name
+ *
+ * \param p_node the node
+ * \param psz_search the name of the child to search
+ * \return the child item or NULL if not found or error
+ */
+playlist_item_t *playlist_ChildSearchName( playlist_item_t *p_node,
+                                           const char *psz_search )
+{
+    int i;
+
+    if( p_node->i_children < 0 )
+    {
+         return NULL;
+    }
+    for( i = 0 ; i< p_node->i_children; i++ )
+    {
+        if( !strcmp( p_node->pp_children[i]->p_input->psz_name, psz_search ) )
+        {
+            return p_node->pp_children[i];
+        }
+    }
+    return NULL;
+}
+
+/**********************************************************************
+ * Tree walking functions
+ **********************************************************************/
+
+playlist_item_t *playlist_GetLastLeaf(playlist_t *p_playlist,
+                                      playlist_item_t *p_root )
+{
+    int i;
+    playlist_item_t *p_item;
+    for ( i = p_root->i_children - 1; i >= 0; i-- )
+    {
+        if( p_root->pp_children[i]->i_children == -1 )
+            return p_root->pp_children[i];
+        else if( p_root->pp_children[i]->i_children > 0)
+        {
+             p_item = playlist_GetLastLeaf( p_playlist,
+                                            p_root->pp_children[i] );
+            if ( p_item != NULL )
+                return p_item;
+        }
+        else if( i == 0 )
+            return NULL;
+    }
+    return NULL;
+}
+
+/**
+ * Finds the next item to play
+ *
+ * \param p_playlist the playlist
+ * \param p_root the root node
+ * \param p_item the previous item  (NULL if none )
+ * \return the next item to play, or NULL if none found
+ */
+playlist_item_t *playlist_GetNextLeaf( playlist_t *p_playlist,
+                                       playlist_item_t *p_root,
+                                       playlist_item_t *p_item )
+{
+    playlist_item_t *p_next;
+
+#ifdef PLAYLIST_DEBUG
+    if( p_item != NULL )
+        msg_Dbg( p_playlist, "finding next of %s within %s",
+                        p_item->p_input->psz_name,  p_root->p_input->psz_name );
+    else
+        msg_Dbg( p_playlist, "finding something to play within %s",
+                         p_root->p_input->psz_name );
+#endif
+
+    if( !p_root  || p_root->i_children == -1 )
+    {
+        msg_Err( p_playlist,"invalid arguments for GetNextLeaf" );
+        return NULL;
+    }
+
+    /* Now, walk the tree until we find a suitable next item */
+    p_next = p_item;
+    do
+    {
+        p_next = GetNextItem( p_playlist, p_root, p_next );
+    } while ( p_next && p_next != p_root && p_next->i_children != -1 );
+
+#ifdef PLAYLIST_DEBUG
+    if( p_next == NULL )
+        msg_Dbg( p_playlist, "At end of node" );
+#endif
+    return p_next;
+}
+
+playlist_item_t *playlist_GetNextEnabledLeaf( playlist_t *p_playlist,
+                                              playlist_item_t *p_root,
+                                              playlist_item_t *p_item )
+{
+    playlist_item_t *p_next;
+
+#ifdef PLAYLIST_DEBUG
+    if( p_item != NULL )
+        msg_Dbg( p_playlist, "finding next of %s within %s",
+                        p_item->p_input->psz_name,  p_root->p_input->psz_name );
+    else
+        msg_Dbg( p_playlist, "finding something to play within %s",
+                         p_root->p_input->psz_name );
+#endif
+
+    if( !p_root  || p_root->i_children == -1 )
+    {
+        msg_Err( p_playlist,"invalid arguments for GetNextEnabledLeaf" );
+        return NULL;
+    }
+
+    /* Now, walk the tree until we find a suitable next item */
+    p_next = p_item;
+    do
+    {
+        p_next = GetNextItem( p_playlist, p_root, p_next );
+    } while ( p_next && p_next != p_root &&
+              !( p_next->i_children == -1 &&
+              !(p_next->i_flags & PLAYLIST_DBL_FLAG) ) );
+
+#ifdef PLAYLIST_DEBUG
+    if( p_next == NULL )
+        msg_Dbg( p_playlist, "At end of node" );
+#endif
+    return p_next;
+}
+
+/**
+ * Finds the previous item to play
+ *
+ * \param p_playlist the playlist
+ * \param p_root the root node
+ * \param p_item the previous item  (NULL if none )
+ * \return the next item to play, or NULL if none found
+ */
+playlist_item_t *playlist_GetPrevLeaf( playlist_t *p_playlist,
+                                       playlist_item_t *p_root,
+                                       playlist_item_t *p_item )
+{
+    playlist_item_t *p_prev;
+
+#ifdef PLAYLIST_DEBUG
+    if( p_item != NULL )
+        msg_Dbg( p_playlist, "finding previous of %s within %s",
+                        p_item->p_input->psz_name,  p_root->p_input->psz_name );
+    else
+        msg_Dbg( p_playlist, "finding previous to play within %s",
+                         p_root->p_input->psz_name );
+#endif
+
+    if( !p_root || p_root->i_children == -1 )
+    {
+        msg_Err( p_playlist,"invalid arguments for GetPrevLeaf" );
+        return NULL;
+    }
+
+    /* Now, walk the tree until we find a suitable previous item */
+    p_prev = p_item;
+    do
+    {
+        p_prev = GetPrevItem( p_playlist, p_root, p_prev );
+    } while ( p_prev && p_prev != p_root && p_prev->i_children != -1 );
+
+#ifdef PLAYLIST_DEBUG
+    if( p_prev == NULL )
+        msg_Dbg( p_playlist, "At beginning of node" );
+#endif
+    return p_prev;
+}
+
+/************************************************************************
+ * Following functions are local
+ ***********************************************************************/
+
+/**
+ * Get the next item in the tree
+ * If p_item is NULL, return the first child of root
+ **/
+playlist_item_t *GetNextItem( playlist_t *p_playlist,
+                              playlist_item_t *p_root,
+                              playlist_item_t *p_item )
+{
+    playlist_item_t *p_parent;
+    int i;
+
+    /* Node with children, get the first one */
+    if( p_item && p_item->i_children > 0 )
+        return p_item->pp_children[0];
+
+    if( p_item != NULL )
+        p_parent = p_item->p_parent;
+    else
+        p_parent = p_root;
+
+    for( i= 0 ; i < p_parent->i_children ; i++ )
+    {
+        if( p_item == NULL || p_parent->pp_children[i] == p_item )
+        {
+            if( p_item == NULL )
+                i = -1;
+
+            if( i+1 >= p_parent->i_children )
+            {
+                /* Was already the last sibling. Look for uncles */
+#ifdef PLAYLIST_DEBUG
+                msg_Dbg( p_playlist, "Current item is the last of the node,"
+                                     "looking for uncle from %s",
+                                     p_parent->p_input->psz_name );
+#endif
+                if( p_parent == p_root )
+                {
+#ifdef PLAYLIST_DEBUG
+                    msg_Dbg( p_playlist, "Already at root" );
+                    return NULL;
+#endif
+                }
+                return GetNextUncle( p_playlist, p_item, p_root );
+            }
+            else
+            {
+                return  p_parent->pp_children[i+1];
+            }
+        }
+    }
+    msg_Err( p_playlist, "I should not be here" );
+    return NULL;
+}
+
+playlist_item_t *GetNextUncle( playlist_t *p_playlist, playlist_item_t *p_item,
+                               playlist_item_t *p_root )
+{
+    playlist_item_t *p_parent = p_item->p_parent;
+    playlist_item_t *p_grandparent;
+    vlc_bool_t b_found = VLC_FALSE;
+
+    if( p_parent != NULL )
+    {
+        p_grandparent = p_parent->p_parent;
+        while( 1 )
+        {
+            int i;
+            for( i = 0 ; i< p_grandparent->i_children ; i++ )
+            {
+                if( p_parent == p_grandparent->pp_children[i] )
+                {
+#ifdef PLAYLIST_DEBUG
+                    msg_Dbg( p_playlist, "parent %s found as child %i of "
+                                    "grandparent %s",
+                                    p_parent->p_input->psz_name, i,
+                                    p_grandparent->p_input->psz_name );
+#endif
+                    b_found = VLC_TRUE;
+                    break;
+                }
+            }
+            if( b_found && i + 1 < p_grandparent->i_children )
+            {
+                    return p_grandparent->pp_children[i+1];
+            }
+            /* Not found at root */
+            if( p_grandparent == p_root )
+            {
+                return NULL;
+            }
+            else
+            {
+                p_parent = p_grandparent;
+                p_grandparent = p_parent->p_parent;
+            }
+        }
+    }
+    /* We reached root */
+    return NULL;
+}
+
+playlist_item_t *GetPrevUncle( playlist_t *p_playlist, playlist_item_t *p_item,
+                               playlist_item_t *p_root )
+{
+    playlist_item_t *p_parent = p_item->p_parent;
+    playlist_item_t *p_grandparent;
+    vlc_bool_t b_found = VLC_FALSE;
+
+    if( p_parent != NULL )
+    {
+        p_grandparent = p_parent->p_parent;
+        while( 1 )
+        {
+            int i;
+            for( i = p_grandparent->i_children -1 ; i >= 0; i-- )
+            {
+                if( p_parent == p_grandparent->pp_children[i] )
+                {
+                    b_found = VLC_TRUE;
+                    break;
+                }
+            }
+            if( b_found && i - 1 > 0 )
+            {
+                return p_grandparent->pp_children[i-1];
+            }
+            /* Not found at root */
+            if( p_grandparent == p_root )
+            {
+                return NULL;
+            }
+            else
+            {
+                p_parent = p_grandparent;
+                p_grandparent = p_parent->p_parent;
+            }
+        }
+    }
+    /* We reached root */
+    return NULL;
+}
+
+
+/* Recursively search the tree for previous item */
+playlist_item_t *GetPrevItem( playlist_t *p_playlist,
+                              playlist_item_t *p_root,
+                              playlist_item_t *p_item )
+{
+    playlist_item_t *p_parent;
+    int i;
+
+    /* Node with children, get the last one */
+    if( p_item && p_item->i_children > 0 )
+        return p_item->pp_children[p_item->i_children - 1];
+
+    /* Last child of its parent ? */
+    if( p_item != NULL )
+        p_parent = p_item->p_parent;
+    else
+    {
+        msg_Err( p_playlist, "Get the last one" );
+        abort();
+    };
+
+    for( i = p_parent->i_children -1 ; i >= 0 ;  i-- )
+    {
+        if( p_parent->pp_children[i] == p_item )
+        {
+            if( i-1 < 0 )
+            {
+                /* Was already the first sibling. Look for uncles */
+#ifdef PLAYLIST_DEBUG
+                msg_Dbg( p_playlist, "Current item is the first of the node,"
+                                     "looking for uncle from %s",
+                                     p_parent->p_input->psz_name );
+#endif
+                return GetPrevUncle( p_playlist, p_item, p_root );
+            }
+            else
+            {
+                return p_parent->pp_children[i-1];
+            }
+        }
+    }
+    msg_Err( p_playlist, "I should not be here" );
+    return NULL;
+}
+
+/* Dump the contents of a node */
+void playlist_NodeDump( playlist_t *p_playlist, playlist_item_t *p_item,
+                        int i_level )
+{
+    char str[512];
+    int i;
+
+    if( i_level == 1 )
+    {
+        msg_Dbg( p_playlist, "%s (%i)",
+                        p_item->p_input->psz_name, p_item->i_children );
+    }
+
+    if( p_item->i_children == -1 )
+    {
+        return;
+    }
+
+    for( i = 0; i< p_item->i_children; i++ )
+    {
+        memset( str, 32, 512 );
+        sprintf( str + 2 * i_level , "%s (%i)",
+                                p_item->pp_children[i]->p_input->psz_name,
+                                p_item->pp_children[i]->i_children );
+        msg_Dbg( p_playlist, "%s",str );
+        if( p_item->pp_children[i]->i_children >= 0 )
+        {
+            playlist_NodeDump( p_playlist, p_item->pp_children[i],
+                              i_level + 1 );
+        }
+    }
+    return;
+}
diff --git a/src/playlist/view.c b/src/playlist/view.c
deleted file mode 100644 (file)
index d052062..0000000
+++ /dev/null
@@ -1,1036 +0,0 @@
-/*****************************************************************************
- * view.c : Playlist views functions
- *****************************************************************************
- * Copyright (C) 1999-2004 the VideoLAN team
- * $Id$
- *
- * Authors: Clément Stenac <zorglub@videolan.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
- *****************************************************************************/
-#include <stdlib.h>                                      /* free(), strtol() */
-#include <stdio.h>                                              /* sprintf() */
-#include <string.h>                                            /* strerror() */
-
-#include <vlc/vlc.h>
-#include <vlc/input.h>
-
-#include "vlc_playlist.h"
-
-#undef PLAYLIST_DEBUG
-
-/************************************************************************
- * Local prototypes
- ************************************************************************/
-
-/* TODO: inline */
-playlist_item_t *playlist_FindDirectParent( playlist_t *p_playlist,
-                                        playlist_item_t *, int );
-
-playlist_item_t *playlist_RecursiveFindNext( playlist_t *p_playlist,
-                int i_view,
-                playlist_item_t *p_root,
-                playlist_item_t *p_item,
-                playlist_item_t *p_parent );
-
-playlist_item_t *playlist_RecursiveFindPrev( playlist_t *p_playlist,
-                int i_view,
-                playlist_item_t *p_root,
-                playlist_item_t *p_item,
-                playlist_item_t *p_parent );
-
-void playlist_NodeDump( playlist_t *p_playlist, playlist_item_t *p_item,
-                        int i_level );
-
-/**********************************************************************
- * Exported View management functions
- **********************************************************************/
-
-/**
- * Create a new view
- *
- * \param p_playlist a playlist object
- * \param i_id the view identifier
- * \return the new view or NULL on failure
- */
-playlist_view_t * playlist_ViewCreate( playlist_t *p_playlist, int i_id,
-                                       char *psz_name )
-{
-    playlist_view_t * p_view;
-
-    p_view = malloc( sizeof( playlist_view_t ) );
-
-    memset( p_view, 0, sizeof( playlist_view_t ) );
-
-    p_view->p_root = playlist_NodeCreate( p_playlist, i_id, NULL, NULL );
-    p_view->i_id = i_id;
-    p_view->psz_name = psz_name ? strdup( psz_name ) : strdup(_("Undefined") );
-
-    return p_view;
-}
-
-/**
- * Creates a new view and add it to the list
- *
- * This function must be entered without the playlist lock
- *
- * \param p_playlist a playlist object
- * \param i_id the view identifier
- * \return VLC_SUCCESS or an error
- */
-int playlist_ViewInsert( playlist_t *p_playlist, int i_id, char *psz_name )
-{
-    playlist_view_t *p_view =
-        playlist_ViewCreate( p_playlist, i_id , psz_name );
-    if( !p_view )
-    {
-        msg_Err( p_playlist, "Creation failed" );
-        return VLC_EGENERIC;
-    }
-
-    vlc_mutex_lock( &p_playlist->object_lock );
-
-    INSERT_ELEM( p_playlist->pp_views, p_playlist->i_views,
-                 p_playlist->i_views, p_view );
-
-    vlc_mutex_unlock( &p_playlist->object_lock );
-    return VLC_SUCCESS;
-}
-
-
-/**
- * Deletes a view
- *
- * This function must be entered wit the playlist lock
- *
- * \param p_view the view to delete
- * \return nothing
- */
-int playlist_ViewDelete( playlist_t *p_playlist,playlist_view_t *p_view )
-{
-    playlist_NodeDelete( p_playlist, p_view->p_root, VLC_TRUE, VLC_TRUE );
-    REMOVE_ELEM( p_playlist->pp_views, p_playlist->i_views, 0 );
-    return VLC_SUCCESS;
-}
-
-
-/**
- * Dumps the content of a view
- *
- * \param p_playlist the playlist
- * \param p_view the view to dump
- * \return nothing
- */
-int playlist_ViewDump( playlist_t *p_playlist, playlist_view_t *p_view )
-{
-#ifdef PLAYLIST_DEBUG
-    msg_Dbg( p_playlist, "dumping view %i",p_view->i_id );
-    playlist_NodeDump( p_playlist,p_view->p_root, 1 );
-#endif
-    return VLC_SUCCESS;
-}
-
-/**
- * Counts the items of a view
- *
- * \param p_playlist the playlist
- * \param p_view the view to count
- * \return the number of items
- */
-int playlist_ViewItemCount( playlist_t *p_playlist,
-                            playlist_view_t *p_view )
-{
-    return playlist_NodeChildrenCount( p_playlist, p_view->p_root );
-}
-
-
-/**
- * Updates a view. Only make sense for "sorted" and "ALL" views
- *
- * \param p_playlist the playlist
- * \param i_view the view to update
- * \return nothing
- */
-int playlist_ViewUpdate( playlist_t *p_playlist, int i_view)
-{
-    playlist_view_t *p_view = playlist_ViewFind( p_playlist, i_view );
-
-    if( p_view == NULL )
-    {
-        return VLC_EGENERIC;
-    }
-
-    if( i_view == VIEW_ALL )
-    {
-        p_view->p_root->i_children = p_playlist->i_size;
-        p_view->p_root->pp_children = p_playlist->pp_items;
-    }
-
-    /* Handle update of sorted views here */
-    if( i_view >= VIEW_FIRST_SORTED )
-    {
-        int i_sort_type;
-        playlist_ViewEmpty( p_playlist, i_view, VLC_FALSE );
-
-        switch( i_view )
-        {
-            case VIEW_S_AUTHOR: i_sort_type = SORT_AUTHOR;break;
-            case VIEW_S_ALBUM: i_sort_type = SORT_ALBUM;break;
-            case VIEW_S_GENRE: i_sort_type = SORT_GENRE;break;
-            default: i_sort_type = SORT_AUTHOR;
-        }
-        playlist_NodeGroup( p_playlist, i_view, p_view->p_root,
-                            p_playlist->pp_items,p_playlist->i_size,
-                            i_sort_type, ORDER_NORMAL );
-    }
-
-
-    return VLC_SUCCESS;
-}
-
-
-/**
- * Find a view
- *
- * \param p_playlist the playlist
- * \param i_id the id to find
- * \return the found view or NULL if not found
- */
-playlist_view_t *playlist_ViewFind( playlist_t *p_playlist, int i_id )
-{
-    int i;
-    for( i=0 ; i< p_playlist->i_views ; i++ )
-    {
-        if( p_playlist->pp_views[i]->i_id == i_id )
-        {
-            return p_playlist->pp_views[i];
-        }
-    }
-    return NULL;
-}
-
-
-int playlist_ViewEmpty( playlist_t *p_playlist, int i_view,
-                        vlc_bool_t b_delete_items )
-{
-    playlist_view_t *p_view = playlist_ViewFind( p_playlist, i_view );
-
-    if( p_view == NULL )
-    {
-        return VLC_EGENERIC;
-    }
-
-    return playlist_NodeEmpty( p_playlist, p_view->p_root, b_delete_items );
-}
-
-/**********************************************************************
- * Exported Nodes management functions
- **********************************************************************/
-
-
-
-/**
- * Create a playlist node
- *
- * \param p_playlist the playlist
- * \paam psz_name the name of the node
- * \param p_parent the parent node to attach to or NULL if no attach
- * \return the new node
- */
-playlist_item_t * playlist_NodeCreate( playlist_t *p_playlist, int i_view,
-                                       char *psz_name,
-                                       playlist_item_t *p_parent )
-{
-    /* Create the item */
-    playlist_item_t *p_item = (playlist_item_t *)malloc(
-                                        sizeof( playlist_item_t ) );
-    vlc_value_t val;
-    playlist_add_t *p_add;
-
-    if( p_item == NULL )
-    {
-        return NULL;
-    }
-    p_add = (playlist_add_t*)malloc( sizeof(playlist_add_t) );
-    if( p_add == NULL )
-    {
-        free( p_item );
-        return NULL;
-    }
-    vlc_input_item_Init( VLC_OBJECT(p_playlist), &p_item->input );
-
-    if( psz_name != NULL )
-    {
-        p_item->input.psz_name = strdup( psz_name );
-    }
-    else
-    {
-        p_item->input.psz_name = strdup( _("Undefined") );
-    }
-
-    p_item->input.psz_uri = NULL;
-
-    p_item->b_enabled = VLC_TRUE;
-    p_item->i_nb_played = 0;
-
-    p_item->i_flags = 0;
-
-    p_item->i_children = 0;
-    p_item->pp_children = NULL;
-
-    p_item->input.i_duration = -1;
-    p_item->input.ppsz_options = NULL;
-    p_item->input.i_options = 0;
-    p_item->input.i_categories = 0;
-    p_item->input.pp_categories = NULL;
-    p_item->input.i_id = ++p_playlist->i_last_id;
-
-    p_item->input.i_type = ITEM_TYPE_NODE;
-
-    p_item->pp_parents = NULL;
-    p_item->i_parents = 0;
-    p_item->i_serial = 0;
-
-    p_item->i_flags |= PLAYLIST_SKIP_FLAG; /* Default behaviour */
-
-    vlc_mutex_init( p_playlist, &p_item->input.lock );
-
-    INSERT_ELEM( p_playlist->pp_all_items,
-                 p_playlist->i_all_size,
-                 p_playlist->i_all_size,
-                 p_item );
-
-    if( p_parent != NULL )
-    {
-        playlist_NodeAppend( p_playlist, i_view, p_item, p_parent );
-    }
-
-    p_add->i_node = p_parent ? p_parent->input.i_id : -1;
-    p_add->i_item = p_item->input.i_id;
-    p_add->i_view = i_view;
-    val.p_address = p_add;
-    var_Set( p_playlist, "item-append", val);
-
-    free( p_add );
-
-    return p_item;
-}
-
-/**
- * Remove all the children of a node
- *
- * This function must be entered with the playlist lock
- *
- * \param p_playlist the playlist
- * \param p_root the node
- * \param b_delete_items do we have to delete the children items ?
- * \return VLC_SUCCESS or an error
- */
-int playlist_NodeEmpty( playlist_t *p_playlist, playlist_item_t *p_root,
-                        vlc_bool_t b_delete_items )
-{
-    int i;
-    if( p_root->i_children == -1 )
-    {
-        return VLC_EGENERIC;
-    }
-
-    /* Delete the children */
-    for( i =  p_root->i_children-1 ; i >= 0 ;i-- )
-    {
-        if( p_root->pp_children[i]->i_children > -1 )
-        {
-            playlist_NodeDelete( p_playlist, p_root->pp_children[i],
-                                 b_delete_items , VLC_FALSE );
-        }
-        else if( b_delete_items )
-        {
-            /* Delete the item here */
-            playlist_Delete( p_playlist, p_root->pp_children[i]->input.i_id );
-        }
-    }
-    return VLC_SUCCESS;
-}
-
-/**
- * Remove all the children of a node and removes the node
- *
- * \param p_playlist the playlist
- * \param p_root the node
- * \param b_delete_items do we have to delete the children items ?
- * \return VLC_SUCCESS or an error
- */
-int playlist_NodeDelete( playlist_t *p_playlist, playlist_item_t *p_root,
-                         vlc_bool_t b_delete_items, vlc_bool_t b_force )
-{
-    int i, i_top, i_bottom;
-    if( p_root->i_children == -1 )
-    {
-        return VLC_EGENERIC;
-    }
-
-    /* Delete the children */
-    for( i =  p_root->i_children - 1 ; i >= 0; i-- )
-    {
-        if( p_root->pp_children[i]->i_children > -1 )
-        {
-            playlist_NodeDelete( p_playlist, p_root->pp_children[i],
-                                b_delete_items , b_force );
-        }
-        else if( b_delete_items )
-        {
-            /* Delete the item here */
-            playlist_Delete( p_playlist, p_root->pp_children[i]->input.i_id );
-        }
-    }
-    /* Delete the node */
-    if( p_root->i_flags & PLAYLIST_RO_FLAG && !b_force )
-    {
-    }
-    else
-    {
-        for( i = 0 ; i< p_root->i_parents; i++ )
-        {
-            playlist_NodeRemoveItem( p_playlist, p_root,
-                                     p_root->pp_parents[i]->p_parent );
-        }
-        var_SetInteger( p_playlist, "item-deleted", p_root->input.i_id );
-
-        i_bottom = 0; i_top = p_playlist->i_all_size - 1;
-        i = i_top / 2;
-        while( p_playlist->pp_all_items[i]->input.i_id != p_root->input.i_id &&
-               i_top > i_bottom )
-        {
-            if( p_playlist->pp_all_items[i]->input.i_id < p_root->input.i_id )
-            {
-                i_bottom = i + 1;
-            }
-            else
-            {
-                i_top = i - 1;
-            }
-            i = i_bottom + ( i_top - i_bottom ) / 2;
-        }
-        if( p_playlist->pp_all_items[i]->input.i_id == p_root->input.i_id )
-        {
-            REMOVE_ELEM( p_playlist->pp_all_items, p_playlist->i_all_size, i );
-        }
-        playlist_ItemDelete( p_root );
-    }
-    return VLC_SUCCESS;
-}
-
-
-/**
- * Adds an item to the childs of a node
- *
- * \param p_playlist the playlist
- * \param i_view the view of the node ( needed for parent search )
- * \param p_item the item to append
- * \param p_parent the parent node
- * \return VLC_SUCCESS or an error
- */
-int playlist_NodeAppend( playlist_t *p_playlist,
-                         int i_view,
-                         playlist_item_t *p_item,
-                         playlist_item_t *p_parent )
-{
-    return playlist_NodeInsert( p_playlist, i_view, p_item, p_parent, -1 );
-}
-
-int playlist_NodeInsert( playlist_t *p_playlist,
-                         int i_view,
-                         playlist_item_t *p_item,
-                         playlist_item_t *p_parent,
-                         int i_position )
-{
-   int i;
-   vlc_bool_t b_found = VLC_FALSE;
-   if( !p_parent || p_parent->i_children == -1 )
-   {
-        msg_Err( p_playlist, "invalid node" );
-        return VLC_EGENERIC;
-   }
-
-   if( i_position == -1 ) i_position = p_parent->i_children ;
-
-   INSERT_ELEM( p_parent->pp_children,
-                p_parent->i_children,
-                i_position,
-                p_item );
-
-   /* Add the parent to the array */
-   for( i= 0; i< p_item->i_parents ; i++ )
-   {
-       if( p_item->pp_parents[i]->i_view == i_view )
-       {
-           b_found = VLC_TRUE;
-           break;
-       }
-   }
-   if( b_found == VLC_FALSE )
-   {
-        struct item_parent_t *p_ip = (struct item_parent_t *)
-                                     malloc(sizeof(struct item_parent_t) );
-        p_ip->i_view = i_view;
-        p_ip->p_parent = p_parent;
-
-        INSERT_ELEM( p_item->pp_parents,
-                     p_item->i_parents, p_item->i_parents,
-                     p_ip );
-   }
-
-   /* Let the interface know this has been updated */
-   p_parent->i_serial++;
-   return VLC_SUCCESS;
-}
-
-/**
- * Deletes a parent from the parent list of a node
- *
- * \param p_playlist the playlist
- * \param p_item the item to remove
- * \param p_parent the parent node
- * \return VLC_SUCCESS or an error
- */
-int playlist_NodeRemoveParent( playlist_t *p_playlist,
-                        playlist_item_t *p_item,
-                        playlist_item_t *p_parent )
-{
-   int i;
-   if( !p_parent || p_parent->i_children == -1 )
-   {
-        msg_Err( p_playlist, "invalid node" );
-   }
-
-   for( i = 0; i < p_item->i_parents; i++ )
-   {
-       if( p_item->pp_parents[i]->p_parent == p_parent )
-       {
-           if( p_item->pp_parents[i] )
-           {
-               free( p_item->pp_parents[i] );
-           }
-           REMOVE_ELEM( p_item->pp_parents, p_item->i_parents, i );
-       }
-   }
-   p_item->i_serial++;
-   return VLC_SUCCESS;
-}
-
-/**
- * Deletes an item from the children of a node
- *
- * \param p_playlist the playlist
- * \param p_item the item to remove
- * \param p_parent the parent node
- * \return VLC_SUCCESS or an error
- */
-int playlist_NodeRemoveItem( playlist_t *p_playlist,
-                        playlist_item_t *p_item,
-                        playlist_item_t *p_parent )
-{
-   int i;
-   for( i= 0; i< p_parent->i_children ; i++ )
-   {
-       if( p_parent->pp_children[i] == p_item )
-       {
-           REMOVE_ELEM( p_parent->pp_children, p_parent->i_children, i );
-       }
-   }
-
-   /* Let the interface know this has been updated */
-   p_parent->i_serial++;
-
-   return VLC_SUCCESS;
-}
-
-
-/**
- * Count the children of a node
- *
- * \param p_playlist the playlist
- * \param p_node the node
- * \return the number of children
- */
-int playlist_NodeChildrenCount( playlist_t *p_playlist, playlist_item_t*p_node)
-{
-    int i;
-    int i_nb = 0;
-    if( p_node->i_children == -1 )
-    {
-        return 0;
-    }
-
-    for( i=0 ; i< p_node->i_children;i++ )
-    {
-        if( p_node->pp_children[i]->i_children == -1 )
-        {
-            i_nb++;
-        }
-        else
-        {
-            i_nb += playlist_NodeChildrenCount( p_playlist, 
-                                                p_node->pp_children[i] );
-        }
-    }
-    return i_nb;
-}
-
-/**
- * Search a child of a node by its name
- *
- * \param p_node the node
- * \param psz_search the name of the child to search
- * \return the child item or NULL if not found or error
- */
-playlist_item_t *playlist_ChildSearchName( playlist_item_t *p_node,
-                                           const char *psz_search )
-{
-    int i;
-
-    if( p_node->i_children < 0 )
-    {
-         return NULL;
-    }
-    for( i = 0 ; i< p_node->i_children; i++ )
-    {
-        if( !strcmp( p_node->pp_children[i]->input.psz_name, psz_search ) )
-        {
-            return p_node->pp_children[i];
-        }
-    }
-    return NULL;
-}
-
-
-/**********************************************************************
- * Tree functions
- **********************************************************************/
-
-/**
- * Finds the next item to play
- *
- * \param p_playlist the playlist
- * \param i_view the view
- * \param p_root the root node
- * \param p_node the node we are playing from
- * \param p_item the item we were playing (NULL if none )
- * \return the next item to play, or NULL if none found
- */
-playlist_item_t *playlist_FindNextFromParent( playlist_t *p_playlist,
-                                        int i_view, /* FIXME: useless */
-                                        playlist_item_t *p_root,
-                                        playlist_item_t *p_node,
-                                        playlist_item_t *p_item )
-{
-    playlist_item_t *p_search, *p_next;
-
-#ifdef PLAYLIST_DEBUG
-    if( p_item != NULL )
-    {
-        msg_Dbg( p_playlist, "finding next of %s within %s - root %s",
-                        p_item->input.psz_name, p_node->input.psz_name,
-                        p_root->input.psz_name );
-    }
-    else
-    {
-        msg_Dbg( p_playlist, "finding something to play within %s -root %s",
-                            p_node->input.psz_name, p_root->input.psz_name );
-
-    }
-#endif
-
-    if( !p_node  || p_node->i_children == -1 )
-    {
-        msg_Err( p_playlist,"invalid arguments for FindNextFromParent" );
-        return NULL;
-    }
-
-    /* Find the parent node of the item */
-    if( p_item != NULL )
-    {
-        p_search = playlist_FindDirectParent( p_playlist, p_item, i_view );
-        if( p_search == NULL )
-        {
-            msg_Err( p_playlist, "parent node not found" );
-            return NULL;
-        }
-    }
-    else
-    {
-        p_search = p_node;
-    }
-
-    /* Now, go up the tree until we find a suitable next item */
-    p_next = playlist_RecursiveFindNext( p_playlist,i_view,
-                                         p_node, p_item, p_search );
-
-    /* Not found, do we go past p_node ? */
-    if( p_next == NULL )
-    {
-        if( p_playlist->b_go_next )
-        {
-#ifdef PLAYLIST_DEBUG
-            msg_Dbg( p_playlist, "moving on to next node: search from %s",
-                            p_root->input.psz_name );
-#endif
-            p_next = playlist_RecursiveFindNext( p_playlist, i_view,
-                                p_root, p_item, p_search );
-            if( p_next == NULL )
-            {
-                return NULL;
-            }
-            /* OK, we could continue, so set our current node to the root */
-            p_playlist->status.p_node = p_root;
-        }
-        else
-        {
-#ifdef PLAYLIST_DEBUG
-            msg_Dbg( p_playlist, "not moving on to next node: you loose" );
-#endif
-            return NULL;
-        }
-    }
-    return p_next;
-}
-
-/**
- * Finds the previous item to play
- *
- * \param p_playlist the playlist
- * \param i_view the view
- * \param p_root the root node
- * \param p_node the node we are playing from
- * \param p_item the item we were playing (NULL if none )
- * \return the next item to play, or NULL if none found
- */
-playlist_item_t *playlist_FindPrevFromParent( playlist_t *p_playlist,
-                                        int i_view,
-                                        playlist_item_t *p_root,
-                                        playlist_item_t *p_node,
-                                        playlist_item_t *p_item )
-{
-    playlist_item_t *p_search, *p_next;
-
-#ifdef PLAYLIST_DEBUG
-    if( p_item != NULL )
-    {
-        msg_Dbg( p_playlist, "finding prev of %s within %s",
-                        p_item->input.psz_name, p_node->input.psz_name );
-    }
-    else
-    {
-        msg_Dbg( p_playlist, "finding prev from %s",p_node->input.psz_name );
-    }
-#endif
-
-    if( !p_node  || p_node->i_children == -1 )
-    {
-        msg_Err( p_playlist,"Invalid arguments for FindPrevFromParent" );
-        return NULL;
-    }
-
-    /* Find the parent node of the item */
-    if( p_item != NULL )
-    {
-        p_search = playlist_FindDirectParent( p_playlist, p_item, i_view );
-        if( p_search == NULL )
-        {
-            msg_Err( p_playlist, "parent node not found" );
-            return NULL;
-        }
-    }
-    else
-    {
-        p_search = p_node;
-    }
-
-    /* Now, go up the tree until we find a suitable next item */
-    p_next = playlist_RecursiveFindPrev( p_playlist,i_view,
-                                         p_node, p_item, p_search );
-
-    if( p_next == NULL )
-    {
-        if( p_playlist->b_go_next )
-        {
-            p_next = playlist_RecursiveFindPrev( p_playlist, i_view,
-                                p_root, p_item, p_search );
-            if( p_next == NULL )
-            {
-                return NULL;
-            }
-            /* OK, we could continue, so set our current node to the root */
-            p_playlist->status.p_node = p_root;
-        }
-        else
-        {
-            return NULL;
-        }
-    }
-    return p_next;
-}
-
-/************************************************************************
- * Following functions are local
- ***********************************************************************/
-
-
-/* Recursively search the tree for next item */
-playlist_item_t *playlist_RecursiveFindNext( playlist_t *p_playlist,
-                int i_view,
-                playlist_item_t *p_root,
-                playlist_item_t *p_item,
-                playlist_item_t *p_parent )
-{
-    int i;
-    playlist_item_t *p_parent_parent;
-
-    for( i= 0 ; i < p_parent->i_children ; i++ )
-    {
-        if( p_parent->pp_children[i] == p_item || p_item == NULL )
-        {
-            if( p_item == NULL )
-            {
-                i = -1;
-            }
-#ifdef PLAYLIST_DEBUG
-            msg_Dbg( p_playlist,"current item found, child %i of %s",
-                                i , p_parent->input.psz_name );
-#endif
-            /* We found our item */
-            if( i+1 >= p_parent->i_children )
-            {
-                /* Too far... */
-#ifdef PLAYLIST_DEBUG
-                msg_Dbg( p_playlist, "going up the tree, at parent of %s",
-                                p_parent->input.psz_name );
-#endif
-                if( p_parent == p_root )
-                {
-#ifdef PLAYLIST_DEBUG
-                    msg_Dbg( p_playlist, "at root item (%s)",
-                                         p_root->input.psz_name );
-#endif
-                    /* Hmm, seems it's the end for you, guy ! */
-                    return NULL;
-                }
-
-                /* Go up one level */
-                p_parent_parent = playlist_FindDirectParent( p_playlist,
-                                                             p_parent, i_view );
-                if( p_parent_parent == NULL )
-                {
-                    msg_Warn( p_playlist, "unable to find parent!");
-                    return NULL;
-                }
-                return playlist_RecursiveFindNext( p_playlist, i_view,p_root,
-                                                   p_parent, p_parent_parent );
-            }
-            else
-            {
-                if( p_parent->pp_children[i+1]->i_children == -1 )
-                {
-                    /* Cool, we have found a real item to play */
-#ifdef PLAYLIST_DEBUG
-                    msg_Dbg( p_playlist, "playing child %i of %s",
-                                     i+1 , p_parent->input.psz_name );
-#endif
-                    return p_parent->pp_children[i+1];
-                }
-                else if( p_parent->pp_children[i+1]->i_children > 0 )
-                {
-                    /* Select the first child of this node */
-#ifdef PLAYLIST_DEBUG
-                    msg_Dbg( p_playlist, "%s is a node with children, "
-                                 "playing the first",
-                                  p_parent->pp_children[i+1]->input.psz_name);
-#endif
-                    if( p_parent->pp_children[i+1]->pp_children[0]
-                                    ->i_children >= 0 )
-                    {
-                        /* first child is a node ! */
-                        return playlist_RecursiveFindNext( p_playlist, i_view,
-                                   p_root, NULL ,
-                                   p_parent->pp_children[i+1]->pp_children[0]);
-                    }
-                    return p_parent->pp_children[i+1]->pp_children[0];
-                }
-                else
-                {
-                    /* This node has no child... We must continue */
-#ifdef PLAYLIST_DEBUG
-                    msg_Dbg( p_playlist, "%s is a node with no children",
-                                 p_parent->pp_children[i+1]->input.psz_name);
-#endif
-                    p_item = p_parent->pp_children[i+1];
-                }
-            }
-        }
-    }
-    /* Just in case :) */
-    return NULL;
-}
-
-/* Recursively search the tree for previous item */
-playlist_item_t *playlist_RecursiveFindPrev( playlist_t *p_playlist,
-                int i_view,
-                playlist_item_t *p_root,
-                playlist_item_t *p_item,
-                playlist_item_t *p_parent )
-{
-    int i;
-    playlist_item_t *p_parent_parent;
-
-    for( i= p_parent->i_children - 1 ; i >= 0 ; i-- )
-    {
-        if( p_parent->pp_children[i] == p_item || p_item == NULL )
-        {
-            if( p_item == NULL )
-            {
-                i = -1;
-            }
-#ifdef PLAYLIST_DEBUG
-            msg_Dbg( p_playlist,"current item found, child %i of %s",
-                             i , p_parent->input.psz_name );
-#endif
-            /* We found our item */
-            if( i < 1 )
-            {
-                /* Too far... */
-#ifdef PLAYLIST_DEBUG
-                msg_Dbg( p_playlist, "going up the tree, at parent of %s",
-                                     p_parent->input.psz_name );
-#endif
-                if( p_parent == p_root )
-                {
-#ifdef PLAYLIST_DEBUG
-                    msg_Dbg( p_playlist, "at root item (%s)",
-                                         p_root->input.psz_name );
-#endif
-                    /* Hmm, seems it's the end for you, guy ! */
-                    return NULL;
-                }
-                /* Go up one level */
-                p_parent_parent = playlist_FindDirectParent( p_playlist,
-                                            p_parent, i_view );
-                if( p_parent_parent == NULL )
-                {
-#ifdef PLAYLIST_DEBUG
-                    msg_Dbg( p_playlist, "mmmh, couldn't find parent" );
-#endif
-                    return NULL;
-                }
-                return playlist_RecursiveFindPrev( p_playlist, i_view,p_root,
-                                            p_parent, p_parent_parent );
-            }
-            else
-            {
-                if( p_parent->pp_children[i-1]->i_children == -1 )
-                {
-                    /* Cool, we have found a real item to play */
-#ifdef PLAYLIST_DEBUG
-                    msg_Dbg( p_playlist, "playing child %i of %s",
-                                     i-1, p_parent->input.psz_name );
-#endif
-                    return p_parent->pp_children[i-1];
-                }
-                else if( p_parent->pp_children[i-1]->i_children > 0 )
-                {
-                    /* Select the last child of this node */
-#ifdef PLAYLIST_DEBUG
-                    msg_Dbg( p_playlist, "%s is a node with children,"
-                                   " playing the last",
-                                   p_parent->pp_children[i-1]->input.psz_name);
-#endif
-                    if( p_parent->pp_children[i-1]->pp_children[p_parent->
-                            pp_children[i-1]->i_children-1]->i_children >= 0 )
-                    {
-                        /* Last child is a node */
-                        return playlist_RecursiveFindPrev( p_playlist, i_view,
-                                    p_root,NULL,
-                                    p_parent->pp_children[i-1]->pp_children[
-                                    p_parent->pp_children[i-1]->i_children-1]);
-                    }
-                    return p_parent->pp_children[i-1]->pp_children[
-                                 p_parent->pp_children[i-1]->i_children-1];
-                }
-                else
-                {
-                    /* This node has no child... We must continue */
-#ifdef PLAYLIST_DEBUG
-                    msg_Dbg( p_playlist, "%s is a node with no children",
-                                p_parent->pp_children[i-1]->input.psz_name);
-#endif
-                    p_item = p_parent->pp_children[i-1];
-                }
-            }
-        }
-    }
-    return NULL;
-}
-
-/* This function returns the parent of an item in a view */
-playlist_item_t *playlist_FindDirectParent( playlist_t *p_playlist,
-                                         playlist_item_t *p_item,
-                                         int i_view )
-{
-        int i = 0;
-        for( i= 0; i< p_item->i_parents ; i++ )
-        {
-            if( p_item->pp_parents[i]->i_view == i_view )
-            {
-                return p_item->pp_parents[i]->p_parent;
-            }
-        }
-        return NULL;
-}
-
-
-#ifdef PLAYLIST_DEBUG
-/* This function dumps a node : to be used only for debug*/
-void playlist_NodeDump( playlist_t *p_playlist, playlist_item_t *p_item,
-                        int i_level )
-{
-    char str[512];
-    int i;
-
-    if( i_level == 1 )
-    {
-        msg_Dbg( p_playlist, "%s (%i)",
-                        p_item->input.psz_name, p_item->i_children );
-    }
-
-    if( p_item->i_children == -1 )
-    {
-        return;
-    }
-
-    for( i = 0; i< p_item->i_children; i++ )
-    {
-        memset( str, 32, 512 );
-        sprintf( str + 2 * i_level , "%s (%i)",
-                                p_item->pp_children[i]->input.psz_name,
-                                p_item->pp_children[i]->i_children );
-        msg_Dbg( p_playlist, "%s",str );
-        if( p_item->pp_children[i]->i_children >= 0 )
-        {
-            playlist_NodeDump( p_playlist, p_item->pp_children[i],
-                              i_level + 1 );
-        }
-    }
-    return;
-}
-#endif
diff --git a/test/NativeGcTest.py b/test/NativeGcTest.py
new file mode 100644 (file)
index 0000000..396d813
--- /dev/null
@@ -0,0 +1,8 @@
+import unittest
+
+import native_gc_test
+
+class NativeGcTestCase( unittest.TestCase ):
+    def testGc( self ):
+        """[GC] Test GC"""
+        native_gc_test.gc_test()
diff --git a/test/native/gc.c b/test/native/gc.c
new file mode 100644 (file)
index 0000000..eaa5ff2
--- /dev/null
@@ -0,0 +1,45 @@
+#include "../pyunit.h"
+#include <vlc/vlc.h>
+
+#include <vlc_common.h>
+
+struct mygc
+{
+    VLC_GC_MEMBERS;
+    int i;
+};
+
+typedef struct mygc mygc;
+
+static void mygc_destructor( gc_object_t *p_gc )
+{
+    free( p_gc );
+    p_gc = NULL;
+};
+
+static PyObject *gc_test( PyObject *self, PyObject *args )
+{
+     mygc *gc = (mygc *)malloc( sizeof( mygc ) );
+
+     vlc_gc_init( gc, mygc_destructor );
+     gc->i_gc_refcount = 0;
+
+     vlc_gc_incref( gc );
+     ASSERT( gc->i_gc_refcount == 1, "Refcount should be 1" );
+     vlc_gc_incref( gc );
+     ASSERT( gc->i_gc_refcount == 2, "Refcount should be 2" );
+     gc->i++;
+     vlc_gc_decref( gc );
+     ASSERT( gc->i_gc_refcount == 1, "Refcount should be 1" );
+     vlc_gc_decref( gc );
+     
+     Py_INCREF( Py_None );
+     return Py_None;
+};
+
+static PyMethodDef native_gc_test_methods[] = {
+   DEF_METHOD( gc_test, "Test GC" )
+   { NULL, NULL, 0, NULL }
+};
+
+DECLARE_MODULE( native_gc_test )