+ input_item_t *p_input = p_event->p_obj;
+ playlist_t *p_playlist = (( playlist_item_t* ) user_data)->p_playlist;
+ input_item_node_t *p_new_root = p_event->u.input_item_subitem_tree_added.p_root;
+
+ PL_LOCK;
+
+ playlist_item_t *p_item =
+ playlist_ItemGetByInput( p_playlist, p_input );
+
+ assert( p_item != NULL );
+ playlist_item_t *p_parent = p_item->p_parent;
+ assert( p_parent != NULL );
+
+ bool b_current = get_current_status_item( p_playlist ) == p_item;
+ bool b_autostart = var_CreateGetBool( p_playlist, "playlist-autostart" );
+ bool b_stop = p_item->i_flags & PLAYLIST_SUBITEM_STOP_FLAG;
+ p_item->i_flags &= ~PLAYLIST_SUBITEM_STOP_FLAG;
+
+ int pos = 0;
+ for( int i = 0; i < p_parent->i_children; i++ )
+ {
+ if( p_parent->pp_children[i] == p_item )
+ {
+ pos = i;
+ break;
+ }
+ }
+
+ bool b_flat = false;
+ playlist_item_t *p_up = p_item;
+ while( p_up->p_parent )
+ {
+ if( p_up->p_parent == p_playlist->p_playing )
+ {
+ if( !pl_priv(p_playlist)->b_tree ) b_flat = true;
+ break;
+ }
+ p_up = p_up->p_parent;
+ }
+ if( b_flat )
+ {
+ playlist_DeleteItem( p_playlist, p_item, true );
+ p_item = playlist_InsertInputItemTree( p_playlist, p_parent,
+ p_new_root, pos, true );
+ }
+ else
+ p_item = playlist_InsertInputItemTree( p_playlist, p_item,
+ p_new_root, PLAYLIST_END, false );
+
+ if( !b_flat ) var_SetAddress( p_playlist, "leaf-to-parent", p_input );
+
+ if( b_current )
+ {
+ if( ( b_stop && !b_flat ) || !b_autostart )
+ {
+ PL_UNLOCK;
+ playlist_Stop( p_playlist );
+ return;
+ }
+ else
+ {
+ playlist_Control( p_playlist, PLAYLIST_VIEWPLAY,
+ pl_Locked, get_current_status_node( p_playlist ), p_item );
+ }
+ }
+
+ PL_UNLOCK;
+}
+/*****************************************************************************
+ * An input item's meta or duration has changed (Event Callback)
+ *****************************************************************************/
+static void input_item_changed( const vlc_event_t * p_event,
+ void * user_data )
+{
+ playlist_item_t *p_item = user_data;
+ VLC_UNUSED( p_event );
+ var_SetAddress( p_item->p_playlist, "item-change", p_item->p_input );
+}
+
+/*****************************************************************************
+ * Listen to vlc_InputItemAddSubItem event
+ *****************************************************************************/
+static void install_input_item_observer( playlist_item_t * p_item )
+{
+ vlc_event_manager_t * p_em = &p_item->p_input->event_manager;
+ vlc_event_attach( p_em, vlc_InputItemSubItemTreeAdded,
+ input_item_add_subitem_tree, p_item );
+ vlc_event_attach( p_em, vlc_InputItemDurationChanged,
+ input_item_changed, p_item );
+ vlc_event_attach( p_em, vlc_InputItemMetaChanged,
+ input_item_changed, p_item );
+ vlc_event_attach( p_em, vlc_InputItemNameChanged,
+ input_item_changed, p_item );
+ vlc_event_attach( p_em, vlc_InputItemInfoChanged,
+ input_item_changed, p_item );
+ vlc_event_attach( p_em, vlc_InputItemErrorWhenReadingChanged,
+ input_item_changed, p_item );