/* FIXME: It is not called on tracklist reordering */ static int TrackListChangeEmit( intf_thread_t *p_intf, int signal, int i_node ) { // "playlist-item-append" if( signal == SIGNAL_PLAYLIST_ITEM_APPEND ) { /* don't signal when items are added/removed in p_category */ playlist_t *p_playlist = pl_Hold( p_intf ); PL_LOCK; playlist_item_t *p_item = playlist_ItemGetById( p_playlist, i_node ); assert( p_item ); while( p_item->p_parent ) p_item = p_item->p_parent; if( p_item == p_playlist->p_root_category ) { PL_UNLOCK; pl_Release( p_intf ); return VLC_SUCCESS; } PL_UNLOCK; pl_Release( p_intf ); } if( p_intf->p_sys->b_dead ) return VLC_SUCCESS; UpdateCaps( p_intf ); TrackListChangeSignal( p_intf->p_sys->p_conn, p_intf ); return VLC_SUCCESS; }
/***************************************************************************** * StateChange: callback on input "state" *****************************************************************************/ static int StateChange( intf_thread_t *p_intf ) { intf_sys_t *p_sys = p_intf->p_sys; playlist_t *p_playlist = p_sys->p_playlist; input_thread_t *p_input; input_item_t *p_item; if( p_intf->p_sys->b_dead ) return VLC_SUCCESS; UpdateCaps( p_intf ); if( !p_sys->b_meta_read && p_sys->i_playing_state == 0) { p_input = playlist_CurrentInput( p_playlist ); if( p_input ) { p_item = input_GetItem( p_input ); if( p_item ) { p_sys->b_meta_read = true; TrackChangeEmit( p_intf, p_item ); } vlc_object_release( p_input ); } } StatusChangeEmit( p_intf ); return VLC_SUCCESS; }
/***************************************************************************** * StatusChangeEmit: Emits the StatusChange signal *****************************************************************************/ static int StatusChangeEmit( intf_thread_t * p_intf ) { if( p_intf->p_sys->b_dead ) return VLC_SUCCESS; UpdateCaps( p_intf ); StatusChangeSignal( p_intf->p_sys->p_conn, p_intf ); return VLC_SUCCESS; }
/***************************************************************************** * TrackChangeEmit: Emits the TrackChange signal *****************************************************************************/ int TrackChangeEmit( intf_thread_t * p_intf, input_item_t* p_item ) { if( p_intf->p_sys->b_dead ) return VLC_SUCCESS; UpdateCaps( p_intf ); TrackChangeSignal( p_intf->p_sys->p_conn, p_item ); return VLC_SUCCESS; }
//static int StateChange( vlc_object_t *p_this, const char* psz_var, // vlc_value_t oldval, vlc_value_t newval, void *p_data ) static int StateChange( intf_thread_t *p_intf, int i_input_state ) { intf_sys_t *p_sys = p_intf->p_sys; playlist_t *p_playlist; input_thread_t *p_input; input_item_t *p_item; if( p_intf->p_sys->b_dead ) return VLC_SUCCESS; UpdateCaps( p_intf ); if( !p_sys->b_meta_read && i_input_state == PLAYING_S ) { p_playlist = pl_Hold( p_intf ); p_input = playlist_CurrentInput( p_playlist ); if( p_input ) { p_item = input_GetItem( p_input ); if( p_item ) { p_sys->b_meta_read = true; TrackChangeSignal( p_sys->p_conn, p_item ); } vlc_object_release( p_input ); } pl_Release( p_intf ); } if( i_input_state == PLAYING_S || i_input_state == PAUSE_S || i_input_state == END_S ) { StatusChangeSignal( p_sys->p_conn, p_intf ); } return VLC_SUCCESS; }
static int Open( vlc_object_t *p_this ) { /* initialisation of the connection */ intf_thread_t *p_intf = (intf_thread_t*)p_this; intf_sys_t *p_sys = malloc( sizeof( intf_sys_t ) ); playlist_t *p_playlist; DBusConnection *p_conn; DBusError error; if( !p_sys ) return VLC_ENOMEM; p_sys->b_meta_read = false; p_sys->i_caps = CAPS_NONE; p_sys->b_dead = false; dbus_error_init( &error ); /* connect to the session bus */ p_conn = dbus_bus_get( DBUS_BUS_SESSION, &error ); if( !p_conn ) { msg_Err( p_this, "Failed to connect to the D-Bus session daemon: %s", error.message ); dbus_error_free( &error ); free( p_sys ); return VLC_EGENERIC; } /* register a well-known name on the bus */ dbus_bus_request_name( p_conn, VLC_MPRIS_DBUS_SERVICE, 0, &error ); if( dbus_error_is_set( &error ) ) { msg_Err( p_this, "Error requesting service " VLC_MPRIS_DBUS_SERVICE ": %s", error.message ); dbus_error_free( &error ); free( p_sys ); return VLC_EGENERIC; } /* we register the objects */ dbus_connection_register_object_path( p_conn, MPRIS_DBUS_ROOT_PATH, &vlc_dbus_root_vtable, p_this ); dbus_connection_register_object_path( p_conn, MPRIS_DBUS_PLAYER_PATH, &vlc_dbus_player_vtable, p_this ); dbus_connection_register_object_path( p_conn, MPRIS_DBUS_TRACKLIST_PATH, &vlc_dbus_tracklist_vtable, p_this ); dbus_connection_flush( p_conn ); p_intf->pf_run = Run; p_intf->p_sys = p_sys; p_sys->p_conn = p_conn; p_sys->p_events = vlc_array_new(); vlc_mutex_init( &p_sys->lock ); p_playlist = pl_Hold( p_intf ); PL_LOCK; var_AddCallback( p_playlist, "item-current", AllCallback, p_intf ); var_AddCallback( p_playlist, "intf-change", AllCallback, p_intf ); var_AddCallback( p_playlist, "playlist-item-append", AllCallback, p_intf ); var_AddCallback( p_playlist, "playlist-item-deleted", AllCallback, p_intf ); var_AddCallback( p_playlist, "random", AllCallback, p_intf ); var_AddCallback( p_playlist, "repeat", AllCallback, p_intf ); var_AddCallback( p_playlist, "loop", AllCallback, p_intf ); PL_UNLOCK; pl_Release( p_intf ); UpdateCaps( p_intf ); return VLC_SUCCESS; }
static int Open( vlc_object_t *p_this ) { /* initialisation of the connection */ intf_thread_t *p_intf = (intf_thread_t*)p_this; intf_sys_t *p_sys = malloc( sizeof( intf_sys_t ) ); playlist_t *p_playlist; DBusConnection *p_conn; DBusError error; char *psz_service_name = NULL; if( !p_sys || !dbus_threads_init_default()) return VLC_ENOMEM; p_sys->b_meta_read = false; p_sys->i_caps = CAPS_NONE; p_sys->b_dead = false; p_sys->p_input = NULL; p_sys->i_playing_state = -1; if( vlc_pipe( p_sys->p_pipe_fds ) ) { free( p_sys ); msg_Err( p_intf, "Could not create pipe" ); return VLC_EGENERIC; } p_sys->b_unique = var_CreateGetBool( p_intf, "dbus-unique-service-id" ); if( p_sys->b_unique ) { if( asprintf( &psz_service_name, "%s-%d", DBUS_MPRIS_BUS_NAME, getpid() ) < 0 ) { free( p_sys ); return VLC_ENOMEM; } } else { psz_service_name = strdup(DBUS_MPRIS_BUS_NAME); } dbus_error_init( &error ); /* connect privately to the session bus * the connection will not be shared with other vlc modules which use dbus, * thus avoiding a whole class of concurrency issues */ p_conn = dbus_bus_get_private( DBUS_BUS_SESSION, &error ); if( !p_conn ) { msg_Err( p_this, "Failed to connect to the D-Bus session daemon: %s", error.message ); dbus_error_free( &error ); free( psz_service_name ); free( p_sys ); return VLC_EGENERIC; } dbus_connection_set_exit_on_disconnect( p_conn, FALSE ); /* register a well-known name on the bus */ dbus_bus_request_name( p_conn, psz_service_name, 0, &error ); if( dbus_error_is_set( &error ) ) { msg_Err( p_this, "Error requesting service %s: %s", psz_service_name, error.message ); dbus_error_free( &error ); free( psz_service_name ); free( p_sys ); return VLC_EGENERIC; } msg_Info( p_intf, "listening on dbus as: %s", psz_service_name ); free( psz_service_name ); /* we register the objects */ dbus_connection_register_object_path( p_conn, DBUS_MPRIS_ROOT_PATH, &dbus_mpris_root_vtable, p_this ); dbus_connection_register_object_path( p_conn, DBUS_MPRIS_PLAYER_PATH, &dbus_mpris_player_vtable, p_this ); dbus_connection_register_object_path( p_conn, DBUS_MPRIS_TRACKLIST_PATH, &dbus_mpris_tracklist_vtable, p_this ); dbus_connection_flush( p_conn ); p_intf->pf_run = Run; p_intf->p_sys = p_sys; p_sys->p_conn = p_conn; p_sys->p_events = vlc_array_new(); p_sys->p_timeouts = vlc_array_new(); p_sys->p_watches = vlc_array_new(); vlc_mutex_init( &p_sys->lock ); p_playlist = pl_Get( p_intf ); p_sys->p_playlist = p_playlist; var_AddCallback( p_playlist, "item-current", AllCallback, p_intf ); var_AddCallback( p_playlist, "intf-change", AllCallback, p_intf ); var_AddCallback( p_playlist, "playlist-item-append", AllCallback, p_intf ); var_AddCallback( p_playlist, "playlist-item-deleted", AllCallback, p_intf ); var_AddCallback( p_playlist, "random", AllCallback, p_intf ); var_AddCallback( p_playlist, "repeat", AllCallback, p_intf ); var_AddCallback( p_playlist, "loop", AllCallback, p_intf ); dbus_connection_set_dispatch_status_function( p_conn, dispatch_status_cb, p_intf, NULL ); if( !dbus_connection_set_timeout_functions( p_conn, add_timeout, remove_timeout, timeout_toggled, p_intf, NULL ) ) { dbus_connection_unref( p_conn ); free( psz_service_name ); free( p_sys ); return VLC_ENOMEM; } if( !dbus_connection_set_watch_functions( p_conn, add_watch, remove_watch, watch_toggled, p_intf, NULL ) ) { dbus_connection_unref( p_conn ); free( psz_service_name ); free( p_sys ); return VLC_ENOMEM; } /* dbus_connection_set_wakeup_main_function( p_conn, wakeup_main_loop, p_intf, NULL); */ UpdateCaps( p_intf ); return VLC_SUCCESS; }
static int Open( vlc_object_t *p_this ) { /* initialisation of the connection */ intf_thread_t *p_intf = (intf_thread_t*)p_this; intf_sys_t *p_sys = malloc( sizeof( intf_sys_t ) ); playlist_t *p_playlist; DBusConnection *p_conn; DBusError error; char *psz_service_name = NULL; if( !p_sys ) return VLC_ENOMEM; p_sys->b_meta_read = false; p_sys->i_caps = CAPS_NONE; p_sys->b_dead = false; p_sys->p_input = NULL; p_sys->i_playing_state = -1; p_sys->b_unique = var_CreateGetBool( p_intf, "dbus-unique-service-id" ); if( p_sys->b_unique ) { if( asprintf( &psz_service_name, "%s-%d", DBUS_MPRIS_BUS_NAME, getpid() ) < 0 ) { free( p_sys ); return VLC_ENOMEM; } } else { psz_service_name = strdup(DBUS_MPRIS_BUS_NAME); } dbus_error_init( &error ); /* connect to the session bus */ p_conn = dbus_bus_get( DBUS_BUS_SESSION, &error ); if( !p_conn ) { msg_Err( p_this, "Failed to connect to the D-Bus session daemon: %s", error.message ); dbus_error_free( &error ); free( p_sys ); return VLC_EGENERIC; } /* register a well-known name on the bus */ dbus_bus_request_name( p_conn, psz_service_name, 0, &error ); if( dbus_error_is_set( &error ) ) { msg_Err( p_this, "Error requesting service %s: %s", psz_service_name, error.message ); dbus_error_free( &error ); free( psz_service_name ); free( p_sys ); return VLC_EGENERIC; } msg_Info( p_intf, "listening on dbus as: %s", psz_service_name ); free( psz_service_name ); /* we register the objects */ dbus_connection_register_object_path( p_conn, DBUS_MPRIS_ROOT_PATH, &dbus_mpris_root_vtable, p_this ); dbus_connection_register_object_path( p_conn, DBUS_MPRIS_PLAYER_PATH, &dbus_mpris_player_vtable, p_this ); dbus_connection_register_object_path( p_conn, DBUS_MPRIS_TRACKLIST_PATH, &dbus_mpris_tracklist_vtable, p_this ); dbus_connection_flush( p_conn ); p_intf->pf_run = Run; p_intf->p_sys = p_sys; p_sys->p_conn = p_conn; p_sys->p_events = vlc_array_new(); vlc_mutex_init( &p_sys->lock ); p_playlist = pl_Get( p_intf ); p_sys->p_playlist = p_playlist; var_AddCallback( p_playlist, "item-current", AllCallback, p_intf ); var_AddCallback( p_playlist, "intf-change", AllCallback, p_intf ); var_AddCallback( p_playlist, "playlist-item-append", AllCallback, p_intf ); var_AddCallback( p_playlist, "playlist-item-deleted", AllCallback, p_intf ); var_AddCallback( p_playlist, "random", AllCallback, p_intf ); var_AddCallback( p_playlist, "repeat", AllCallback, p_intf ); var_AddCallback( p_playlist, "loop", AllCallback, p_intf ); UpdateCaps( p_intf ); return VLC_SUCCESS; }