#include "vlc_playlist.h"
#include "vlc_events.h"
#include <vlc_services_discovery.h>
+#include <vlc_probe.h>
#include "playlist_internal.h"
#include "../libvlc.h"
+typedef struct
+{
+ char *name;
+ char *longname;
+} vlc_sd_probe_t;
+
+int vlc_sd_probe_Add (vlc_probe_t *probe, const char *name,
+ const char *longname)
+{
+ vlc_sd_probe_t names = { strdup(name), strdup(longname) };
+
+ if (unlikely (names.name == NULL || names.longname == NULL
+ || vlc_probe_add (probe, &names, sizeof (names))))
+ {
+ free (names.name);
+ free (names.longname);
+ return VLC_ENOMEM;
+ }
+ return VLC_PROBE_CONTINUE;
+}
+
+#undef vlc_sd_GetNames
+
+/**
+ * Gets the list of available services discovery plugins.
+ */
+char **vlc_sd_GetNames (vlc_object_t *obj, char ***pppsz_longnames)
+{
+ size_t count;
+ vlc_sd_probe_t *tab = vlc_probe (obj, "services probe", &count);
+
+ if (count == 0)
+ {
+ free (tab);
+ return NULL;
+ }
+
+ char **names = malloc (sizeof(char *) * (count + 1));
+ char **longnames = malloc (sizeof(char *) * (count + 1));
+
+ if (unlikely (names == NULL || longnames == NULL))
+ abort();
+ for( size_t i = 0; i < count; i++ )
+ {
+ names[i] = tab[i].name;
+ longnames[i] = tab[i].longname;
+ }
+ free (tab);
+ names[count] = longnames[count] = NULL;
+ *pppsz_longnames = longnames;
+ return names;
+}
+
+
+struct vlc_sd_internal_t
+{
+ /* the playlist items for category and onelevel */
+ playlist_item_t *p_node;
+ services_discovery_t *p_sd; /**< Loaded service discovery modules */
+ char *psz_name;
+};
static void services_discovery_Destructor ( vlc_object_t *p_obj );
* That's how the playlist get's Service Discovery information
*/
-/**
- * Gets the list of available services discovery plugins.
- */
-char **vlc_sd_GetNames( char ***pppsz_longnames )
-{
- return module_GetModulesNamesForCapability( "services_discovery",
- pppsz_longnames );
-}
-
/***********************************************************************
* Create
***********************************************************************/
{
input_item_t * p_input = p_event->u.services_discovery_item_added.p_new_item;
const char * psz_cat = p_event->u.services_discovery_item_added.psz_category;
- playlist_item_t *p_new_item, * p_parent = user_data;
+ playlist_item_t * p_parent = user_data;
playlist_t * p_playlist = p_parent->p_playlist;
msg_Dbg( p_playlist, "Adding %s in %s",
PL_LOCK;
/* If p_parent is in root category (this is clearly a hack) and we have a cat */
- if( !EMPTY_STR(psz_cat) &&
- p_parent->p_parent == p_playlist->p_root_category )
+ if( !EMPTY_STR(psz_cat) )
{
/* */
playlist_item_t * p_cat;
p_parent = p_cat;
}
- p_new_item = playlist_NodeAddInput( p_playlist, p_input, p_parent,
- PLAYLIST_APPEND, PLAYLIST_END, pl_Locked );
- if( p_new_item )
- {
- p_new_item->i_flags &= ~PLAYLIST_SKIP_FLAG;
- p_new_item->i_flags &= ~PLAYLIST_SAVE_FLAG;
- }
+ playlist_NodeAddInput( p_playlist, p_input, p_parent,
+ PLAYLIST_APPEND, PLAYLIST_END,
+ pl_Locked );
PL_UNLOCK;
}
{
input_item_t * p_input = p_event->u.services_discovery_item_removed.p_item;
playlist_item_t * p_parent = user_data;
- playlist_item_t * p_pl_item;
-
- /* First make sure that if item is a node it will be deleted.
- * XXX: Why don't we have a function to ensure that in the playlist code ? */
- playlist_Lock( p_parent->p_playlist );
- p_pl_item = playlist_ItemFindFromInputAndRoot( p_parent->p_playlist,
- p_input, p_parent, false );
-
- if( p_pl_item && p_pl_item->i_children > -1 )
- playlist_NodeDelete( p_parent->p_playlist, p_pl_item, true, false );
- else
- /* Delete the non-node item normally */
- playlist_DeleteFromInputInParent( p_parent->p_playlist, p_input,
- p_parent, pl_Locked );
-
- playlist_Unlock( p_parent->p_playlist );
+ playlist_DeleteFromInput( p_parent->p_playlist, p_input, false );
}
int playlist_ServicesDiscoveryAdd( playlist_t *p_playlist, const char *psz_module )
if( !p_sd )
return VLC_ENOMEM;
- module_t *m = module_find_by_shortcut( psz_module );
+ char *psz_name = NULL;
+ config_ChainCreate( &psz_name, &p_sd->p_cfg, psz_module );
+
+ module_t *m = module_find_by_shortcut( psz_name );
if( !m )
{
- msg_Err( p_playlist, "No such module: %s", psz_module );
+ msg_Err( p_playlist, "No such module: %s", psz_name );
vlc_sd_Destroy( p_sd );
return VLC_EGENERIC;
}
/* Free in playlist_ServicesDiscoveryRemove */
- struct playlist_services_discovery_support_t * p_sds;
- p_sds = malloc( sizeof(struct playlist_services_discovery_support_t) );
+ vlc_sd_internal_t * p_sds = malloc( sizeof(*p_sds) );
if( !p_sds )
{
vlc_sd_Destroy( p_sd );
return VLC_ENOMEM;
}
- playlist_item_t * p_cat;
- playlist_item_t * p_one;
+ playlist_item_t *p_node;
PL_LOCK;
- playlist_NodesPairCreate( p_playlist, module_get_name( m, true ),
- &p_cat, &p_one, false );
+ p_node = playlist_NodeCreate( p_playlist, module_get_name( m, true ),
+ p_playlist->p_root, 0, NULL );
PL_UNLOCK;
module_release( m );
vlc_event_attach( services_discovery_EventManager( p_sd ),
vlc_ServicesDiscoveryItemAdded,
- playlist_sd_item_added, p_one );
-
- vlc_event_attach( services_discovery_EventManager( p_sd ),
- vlc_ServicesDiscoveryItemAdded,
- playlist_sd_item_added, p_cat );
+ playlist_sd_item_added, p_node );
vlc_event_attach( services_discovery_EventManager( p_sd ),
vlc_ServicesDiscoveryItemRemoved,
- playlist_sd_item_removed, p_one );
+ playlist_sd_item_removed, p_node );
- vlc_event_attach( services_discovery_EventManager( p_sd ),
- vlc_ServicesDiscoveryItemRemoved,
- playlist_sd_item_removed, p_cat );
-
- if( !vlc_sd_Start( p_sd, psz_module ) )
+ if( !vlc_sd_Start( p_sd, psz_name ) )
{
vlc_sd_Destroy( p_sd );
free( p_sds );
}
/* We want tree-view for service directory */
- p_one->p_input->b_prefers_tree = true;
+ p_node->p_input->b_prefers_tree = true;
p_sds->p_sd = p_sd;
- p_sds->p_one = p_one;
- p_sds->p_cat = p_cat;
+ p_sds->p_node = p_node;
p_sds->psz_name = strdup( psz_module );
PL_LOCK;
const char *psz_name )
{
playlist_private_t *priv = pl_priv( p_playlist );
- struct playlist_services_discovery_support_t * p_sds = NULL;
+ vlc_sd_internal_t * p_sds = NULL;
PL_LOCK;
for( int i = 0; i < priv->i_sds; i++ )
vlc_event_detach( services_discovery_EventManager( p_sd ),
vlc_ServicesDiscoveryItemAdded,
playlist_sd_item_added,
- p_sds->p_one );
-
- vlc_event_detach( services_discovery_EventManager( p_sd ),
- vlc_ServicesDiscoveryItemAdded,
- playlist_sd_item_added,
- p_sds->p_cat );
+ p_sds->p_node );
vlc_event_detach( services_discovery_EventManager( p_sd ),
vlc_ServicesDiscoveryItemRemoved,
playlist_sd_item_removed,
- p_sds->p_one );
-
- vlc_event_detach( services_discovery_EventManager( p_sd ),
- vlc_ServicesDiscoveryItemRemoved,
- playlist_sd_item_removed,
- p_sds->p_cat );
+ p_sds->p_node );
/* Remove the sd playlist node if it exists */
PL_LOCK;
- if( p_sds->p_cat != p_playlist->p_root_category &&
- p_sds->p_one != p_playlist->p_root_onelevel )
- {
- playlist_NodeDelete( p_playlist, p_sds->p_cat, true, false );
- playlist_NodeDelete( p_playlist, p_sds->p_one, true, false );
- }
+ playlist_NodeDelete( p_playlist, p_sds->p_node, true, false );
PL_UNLOCK;
vlc_sd_Destroy( p_sd );