+static playlist_item_t *PlaylistGetRoot( intf_thread_t *p_intf )
+{
+ intf_sys_t *p_sys = p_intf->p_sys;
+ playlist_t *p_playlist = p_sys->p_playlist;
+
+ if( p_playlist == NULL )
+ {
+ return NULL;
+ }
+
+ switch( p_sys->i_current_view )
+ {
+ case VIEW_CATEGORY:
+ return p_playlist->p_root_category;
+ default:
+ return p_playlist->p_root_onelevel;
+ }
+}
+
+static void PlaylistRebuild( intf_thread_t *p_intf )
+{
+ intf_sys_t *p_sys = p_intf->p_sys;
+ playlist_t *p_playlist = p_sys->p_playlist;
+
+ if( p_playlist == NULL )
+ {
+ return;
+ }
+
+ vlc_mutex_lock( &p_playlist->object_lock );
+
+ /* First clear the old one */
+ PlaylistDestroy( p_intf );
+
+ /* Build the new one */
+ PlaylistAddNode( p_intf, PlaylistGetRoot( p_intf ), 0, "" );
+
+ p_sys->b_need_update = VLC_FALSE;
+
+ vlc_mutex_unlock( &p_playlist->object_lock );
+}
+
+static void PlaylistAddNode( intf_thread_t *p_intf, playlist_item_t *p_node,
+ int i, char *c )
+{
+ intf_sys_t *p_sys = p_intf->p_sys;
+ playlist_item_t *p_child;
+ char *psz_tmp;
+ int k;
+
+ psz_tmp = (char *)malloc( strlen( c ) + 4 );
+ if( psz_tmp == NULL ) return;
+ for( k = 0; k < p_node->i_children; k++ )
+ {
+ struct pl_item_t *p_pl_item;
+ char *buff;
+ int i_size;
+
+ p_child = p_node->pp_children[k];
+ i_size = strlen( c ) + strlen( p_child->p_input->psz_name ) + 4;
+ buff = (char *)malloc( sizeof( char ) * i_size );
+ p_pl_item = (struct pl_item_t *)malloc( sizeof( struct pl_item_t ) );
+ if( p_pl_item == NULL || buff == NULL ) return;
+
+ if( strlen( c ) )
+ {
+ sprintf( buff, "%s%c-%s", c, k == p_node->i_children - 1 ?
+ '`' : '|', p_child->p_input->psz_name );
+ }
+ else
+ {
+ sprintf( buff, " %s", p_child->p_input->psz_name );
+ }
+ p_pl_item->psz_display = strdup( buff );
+ p_pl_item->p_item = p_child;
+ INSERT_ELEM( p_sys->pp_plist, p_sys->i_plist_entries,
+ p_sys->i_plist_entries, p_pl_item );
+ free( buff );
+ i++;
+
+ if( p_child->i_children > 0 )
+ {
+ sprintf( psz_tmp, "%s%c ", c,
+ k == p_node->i_children - 1 ? ' ' : '|' );
+ PlaylistAddNode( p_intf, p_child, i,
+ strlen( c ) ? psz_tmp : " " );
+ }
+ }
+ free( psz_tmp );
+}
+
+static int PlaylistChanged( vlc_object_t *p_this, const char *psz_variable,
+ vlc_value_t oval, vlc_value_t nval, void *param )
+{
+ intf_thread_t *p_intf = (intf_thread_t *)param;
+ p_intf->p_sys->b_need_update = VLC_TRUE;
+ return VLC_SUCCESS;
+}
+
+/* Playlist suxx */
+static inline vlc_bool_t PlaylistIsPlaying( intf_thread_t *p_intf,
+ playlist_item_t *p_item )
+{
+ playlist_item_t *p_played_item = p_intf->p_sys->p_playlist->status.p_item;
+ return( p_item != NULL && p_played_item != NULL &&
+ p_item->p_input != NULL && p_played_item->p_input != NULL &&
+ p_item->p_input->i_id == p_played_item->p_input->i_id );
+}
+
+static void FindIndex( intf_thread_t *p_intf )
+{
+ intf_sys_t *p_sys = p_intf->p_sys;
+ int i;
+
+ if( p_sys->i_box_plidx < p_sys->i_plist_entries &&
+ p_sys->i_box_plidx >= 0 &&
+ PlaylistIsPlaying( p_intf,
+ p_sys->pp_plist[p_sys->i_box_plidx]->p_item ) )
+ {
+ return;
+ }
+
+ for( i = 0; i < p_sys->i_plist_entries; i++ )
+ {
+ if( PlaylistIsPlaying( p_intf, p_sys->pp_plist[i]->p_item ) )
+ {
+ p_sys->i_box_plidx = i;
+ break;
+ }
+ }
+}
+
+static void PlaylistDestroy( intf_thread_t *p_intf )
+{
+ intf_sys_t *p_sys = p_intf->p_sys;
+ int i;
+
+ for( i = 0; i < p_sys->i_plist_entries; i++ )
+ {
+ struct pl_item_t *p_pl_item = p_sys->pp_plist[i];
+ free( p_pl_item->psz_display );
+ REMOVE_ELEM( p_sys->pp_plist, p_sys->i_plist_entries, i );
+ free( p_pl_item );
+ }
+ p_sys->pp_plist = NULL;
+ p_sys->i_plist_entries = 0;
+}
+
+static void Eject( intf_thread_t *p_intf )