D-Bus module now uses new specification
authorRafaël Carré <funman@videolan.org>
Wed, 6 Dec 2006 00:52:04 +0000 (00:52 +0000)
committerRafaël Carré <funman@videolan.org>
Wed, 6 Dec 2006 00:52:04 +0000 (00:52 +0000)
TODO: playlist management

extras/dbus-vlc.py
modules/control/dbus.c
modules/control/dbus.h
src/libvlc-common.c

index dab06d5..9b8c155 100755 (executable)
@@ -30,50 +30,53 @@ import os
 
 global position
 global timer
-global playing
+#global playing
 
 def itemchange_handler(item):
     gobject.timeout_add( 2000, timeset)
     l_item.set_text(item)
 
 bus = dbus.SessionBus()
-remote_object = bus.get_object("org.videolan.vlc", "/org/videolan/vlc")
-interface  = dbus.Interface(remote_object, "org.videolan.vlc")
+player_o = bus.get_object("org.freedesktop.MediaPlayer", "/Player")
+tracklist_o = bus.get_object("org.freedesktop.MediaPlayer", "/TrackList")
+
+tracklist  = dbus.Interface(tracklist_o, "org.freedesktop.MediaPlayer")
+player = dbus.Interface(player_o, "org.freedesktop.MediaPlayer")
 try:
-    remote_object.connect_to_signal("ItemChange", itemchange_handler, dbus_interface="org.videolan.vlc")
+    player_o.connect_to_signal("TrackChange", itemchange_handler, dbus_interface="org.freedesktop.MediaPlayer")
 except:
     True
 
-def AddMRL(widget):
+def AddTrack(widget):
     mrl = e_mrl.get_text()
     if mrl != None and mrl != "":
-        interface.AddMRL(mrl, True)
+        tracklist.AddTrack(mrl, True)
     else:
         mrl = bt_file.get_filename()
         if mrl != None and mrl != "":
-            interface.AddMRL("directory://" + mrl, True)
+            tracklist.AddTrack("directory://" + mrl, True)
 
 def Next(widget):
-    interface.Next(reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
+    player.Next(reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
     update(0)
 
 def Prev(widget):
-    interface.Prev(reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
+    player.Prev(reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
     update(0)
 
 def Stop(widget):
-    interface.Stop(reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
+    player.Stop(reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
     update(0)
 
 def update(widget):
-    itemchange_handler(str(interface.GetPlayingItem()))
-    vol.set_value(interface.VolumeGet())
+#    itemchange_handler(str(player.GetPlayingItem()))
+    vol.set_value(player.VolumeGet())
     GetPlayStatus(0)
 
 def GetPlayStatus(widget):
     global playing
-    status = str(interface.GetPlayStatus())
-    if status == "playing":
+    status = str(player.GetStatus())
+    if status == 0:
         img_bt_toggle.set_from_stock("gtk-media-pause", gtk.ICON_SIZE_SMALL_TOOLBAR)
         playing = True
     else:
@@ -81,26 +84,25 @@ def GetPlayStatus(widget):
         playing = False
 
 def Quit(widget):
-    interface.Quit(reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
+    player.Quit(reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
     l_item.set_text("")
 
-def TogglePause(widget):
-    if interface.TogglePause() == True:
-        img_bt_toggle.set_from_stock(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_SMALL_TOOLBAR)
-    else:
-        img_bt_toggle.set_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_SMALL_TOOLBAR)
+def Pause(widget):
+    player.Pause()
+#        img_bt_toggle.set_from_stock(gtk.STOCK_MEDIA_PAUSE, gtk.ICON_SIZE_SMALL_TOOLBAR)
+#        img_bt_toggle.set_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_SMALL_TOOLBAR)
     update(0)
 
 def volchange(widget, data):
-    interface.VolumeSet(vol.get_value_as_int(), reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
+    player.VolumeSet(vol.get_value_as_int(), reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
 
 def timechange(widget, x=None, y=None):
-    interface.PositionSet(time_s.get_value(), reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
+    player.PositionSet(time_s.get_value(), reply_handler=(lambda *args: None), error_handler=(lambda *args: None))
 
 def timeset():
-    global playing
-    time_s.set_value(interface.PositionGet())
-    return playing
+#    global playing
+    time_s.set_value(player.PositionGet())
+#    return playing
 
 def expander(widget):
     if exp.get_expanded() == False:
@@ -177,8 +179,8 @@ menu.attach_to_widget(eventbox,None)
 
 bt_close.connect('clicked',     destroy)
 bt_quit.connect('clicked',      Quit)
-bt_mrl.connect('clicked',       AddMRL)
-bt_toggle.connect('clicked',    TogglePause)
+bt_mrl.connect('clicked',       AddTrack)
+bt_toggle.connect('clicked',    Pause)
 bt_next.connect('clicked',      Next)
 bt_prev.connect('clicked',      Prev)
 bt_stop.connect('clicked',      Stop)
index 07139ef..50f0d18 100644 (file)
@@ -67,7 +67,7 @@ static void Close   ( vlc_object_t * );
 static void Run        ( intf_thread_t * );
 
 
-static int ItemChange( vlc_object_t *p_this, const char *psz_var,
+static int TrackChange( vlc_object_t *p_this, const char *psz_var,
                     vlc_value_t oldval, vlc_value_t newval, void *p_data );
 
 struct intf_sys_t
@@ -91,18 +91,12 @@ vlc_module_end();
 /*****************************************************************************
  * Methods
  *****************************************************************************/
-
-DBUS_METHOD( Nothing )
-{ /* do nothing */
-    REPLY_INIT;
-    REPLY_SEND;
-}
-
+#if 0
 DBUS_METHOD( PlaylistExport_XSPF )
-{ /* export playlist to an xspf file */
+{ /*export playlist to an xspf file */
 
   /* reads the filename to export to */
-  /* returns the status as uint16:
+  /* returns the status as int32:
    *    0 : success
    *    1 : error
    *    2 : playlist empty
@@ -114,7 +108,7 @@ DBUS_METHOD( PlaylistExport_XSPF )
     dbus_error_init( &error );
 
     char *psz_file;
-    dbus_uint16_t i_ret;
+    dbus_int32_t i_ret;
 
     dbus_message_get_args( p_from, &error,
             DBUS_TYPE_STRING, &psz_file,
@@ -145,9 +139,12 @@ DBUS_METHOD( PlaylistExport_XSPF )
 
     pl_Release( ((vlc_object_t*) p_this ) );
 
-    ADD_UINT16( &i_ret );
+    ADD_INT32( &i_ret );
     REPLY_SEND;
 }
+#endif
+
+/* Player */
 
 DBUS_METHOD( Quit )
 { /* exits vlc */
@@ -164,7 +161,7 @@ DBUS_METHOD( PositionGet )
     REPLY_INIT;
     OUT_ARGUMENTS;
     vlc_value_t position;
-    dbus_uint16_t i_pos;
+    dbus_int32_t i_pos;
 
     playlist_t *p_playlist = pl_Yield( ((vlc_object_t*) p_this) );
     input_thread_t *p_input = p_playlist->p_input;
@@ -176,7 +173,7 @@ DBUS_METHOD( PositionGet )
         var_Get( p_input, "position", &position );
         i_pos = position.f_float * 1000 ;
     }
-    ADD_UINT16( &i_pos );
+    ADD_INT32( &i_pos );
     pl_Release( ((vlc_object_t*) p_this) );
     REPLY_SEND;
 }
@@ -186,13 +183,13 @@ DBUS_METHOD( PositionSet )
 
     REPLY_INIT;
     vlc_value_t position;
-    dbus_uint16_t i_pos;
+    dbus_int32_t i_pos;
 
     DBusError error;
     dbus_error_init( &error );
 
     dbus_message_get_args( p_from, &error,
-            DBUS_TYPE_UINT16, &i_pos,
+            DBUS_TYPE_INT32, &i_pos,
             DBUS_TYPE_INVALID );
 
     if( dbus_error_is_set( &error ) )
@@ -218,11 +215,12 @@ DBUS_METHOD( VolumeGet )
 { /* returns volume in percentage */
     REPLY_INIT;
     OUT_ARGUMENTS;
-    dbus_uint16_t i_vol;
-    /* 2nd argument of aout_VolumeGet is uint16 */
+    dbus_int32_t i_dbus_vol;
+    audio_volume_t i_vol;
+    /* 2nd argument of aout_VolumeGet is int32 */
     aout_VolumeGet( (vlc_object_t*) p_this, &i_vol );
-    i_vol = ( 100 * i_vol ) / AOUT_VOLUME_MAX;
-    ADD_UINT16( &i_vol );
+    i_dbus_vol = ( 100 * i_vol ) / AOUT_VOLUME_MAX;
+    ADD_INT32( &i_dbus_vol );
     REPLY_SEND;
 }
 
@@ -233,10 +231,11 @@ DBUS_METHOD( VolumeSet )
     DBusError error;
     dbus_error_init( &error );
 
-    dbus_uint16_t i_vol;
+    dbus_int32_t i_dbus_vol;
+    audio_volume_t i_vol;
 
     dbus_message_get_args( p_from, &error,
-            DBUS_TYPE_UINT16, &i_vol,
+            DBUS_TYPE_INT32, &i_dbus_vol,
             DBUS_TYPE_INVALID );
 
     if( dbus_error_is_set( &error ) )
@@ -247,7 +246,8 @@ DBUS_METHOD( VolumeSet )
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     }
 
-    aout_VolumeSet( (vlc_object_t*) p_this, ( AOUT_VOLUME_MAX / 100 ) * i_vol );
+    i_vol = ( AOUT_VOLUME_MAX / 100 ) *i_dbus_vol;
+    aout_VolumeSet( (vlc_object_t*) p_this, i_vol );
 
     REPLY_SEND;
 }
@@ -279,84 +279,67 @@ DBUS_METHOD( Stop )
     REPLY_SEND;
 }
 
-DBUS_METHOD( GetPlayingItem )
-{ /* return the current item */
-    REPLY_INIT;
-    OUT_ARGUMENTS;
-    char psz_no_input = '\0';
-    char *p_psz_no_input = &psz_no_input;
-    playlist_t *p_playlist = pl_Yield( ((vlc_object_t*) p_this) );
-    input_thread_t *p_input = p_playlist->p_input;
-    ADD_STRING( ( p_input ) ? &input_GetItem(p_input)->psz_name :
-            &p_psz_no_input );
-    pl_Release( ((vlc_object_t*) p_this) );
-    REPLY_SEND;
-}
-
-DBUS_METHOD( GetPlayStatus )
-{ /* return a string */
+DBUS_METHOD( GetStatus )
+{ /* returns an int: 0=playing 1=paused 2=stopped */
     REPLY_INIT;
     OUT_ARGUMENTS;
 
-    char *psz_play;
+    dbus_int32_t i_status;
     vlc_value_t val;
+
     playlist_t *p_playlist = pl_Yield( (vlc_object_t*) p_this );
     input_thread_t *p_input = p_playlist->p_input;
 
-    if( !p_input )
-        psz_play = strdup( "stopped" );
-    else
+    i_status = 2;
+    if( p_input )
     {
         var_Get( p_input, "state", &val );
         if( val.i_int == PAUSE_S )
-            psz_play = strdup( "pause" );
+            i_status = 1;
         else if( val.i_int == PLAYING_S )
-            psz_play = strdup( "playing" );
-        else psz_play = strdup( "unknown" );
+            i_status = 0;
     }
 
     pl_Release( p_playlist );
 
-    ADD_STRING( &psz_play );
-    free( psz_play );
+    ADD_INT32( &i_status );
     REPLY_SEND;
 }
 
-DBUS_METHOD( TogglePause )
-{ /* return a bool: true if playing */
+DBUS_METHOD( Pause )
+{
     REPLY_INIT;
-    OUT_ARGUMENTS;
+    playlist_t *p_playlist = pl_Yield( (vlc_object_t*) p_this );
+    playlist_Pause( p_playlist );
+    pl_Release( p_playlist );
+    REPLY_SEND;
+}
 
-    vlc_value_t val;
+DBUS_METHOD( Play )
+{
+    REPLY_INIT;
     playlist_t *p_playlist = pl_Yield( (vlc_object_t*) p_this );
-    input_thread_t *p_input = p_playlist->p_input;
-    if( p_input != NULL )
-    {
-        var_Get( p_input, "state", &val );
-        if( val.i_int != PAUSE_S )
-        {
-            val.i_int = PAUSE_S;
-            playlist_Pause( p_playlist );
-        }
-        else
-        {
-            val.i_int = PLAYING_S;
-            playlist_Play( p_playlist );
-        }
-    }
-    else
-    {
-        val.i_int = PLAYING_S;
-        playlist_Play( p_playlist );
-    }
+    playlist_Play( p_playlist );
     pl_Release( p_playlist );
+    REPLY_SEND;
+}
 
-    dbus_bool_t pause = ( val.i_int == PLAYING_S ) ? TRUE : FALSE;
-    ADD_BOOL( &pause );
+/* Media Player information */
+
+DBUS_METHOD( Identity )
+{
+    REPLY_INIT;
+    OUT_ARGUMENTS;
+    char *psz_identity = malloc( strlen( PACKAGE ) + strlen( VERSION ) + 1 );
+    sprintf( psz_identity, "%s %s", PACKAGE, VERSION );
+    ADD_STRING( &psz_identity );
+    free( psz_identity );
     REPLY_SEND;
 }
 
-DBUS_METHOD( AddMRL )
+/* TrackList */
+
+DBUS_METHOD( AddTrack )
 { /* add the string to the playlist, and play it if the boolean is true */
     REPLY_INIT;
 
@@ -387,49 +370,165 @@ DBUS_METHOD( AddMRL )
     REPLY_SEND;
 }
 
+DBUS_METHOD( GetCurrentTrack )
+{ //TODO
+    REPLY_INIT;
+    OUT_ARGUMENTS;
+    dbus_int32_t i_position = 0;
+    //TODO get position of playing element
+    ADD_INT32( &i_position );
+    REPLY_SEND;
+}
+
+DBUS_METHOD( GetMetadata )
+{ //TODO reads int, returns a{sv}
+    REPLY_INIT;
+    OUT_ARGUMENTS;
+    DBusError error;
+    dbus_error_init( &error );
+
+    dbus_int32_t i_position;
+
+    dbus_message_get_args( p_from, &error,
+            DBUS_TYPE_INT32, &i_position,
+            DBUS_TYPE_INVALID );
+
+    if( dbus_error_is_set( &error ) )
+    {
+        msg_Err( (vlc_object_t*) p_this, "D-Bus message reading : %s\n",
+                error.message );
+        dbus_error_free( &error );
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+    }
+
+    //TODO return a{sv}
+
+    REPLY_SEND;
+}
+
+DBUS_METHOD( GetLength )
+{ //TODO
+    REPLY_INIT;
+    OUT_ARGUMENTS;
+    dbus_int32_t i_elements = 0;
+    //TODO: return number of elements in playlist
+    ADD_INT32( &i_elements );
+    REPLY_SEND;
+}
+
+DBUS_METHOD( DelTrack )
+{ //TODO
+    REPLY_INIT;
+
+    DBusError error;
+    dbus_error_init( &error );
+
+    dbus_int32_t i_position;
+
+    dbus_message_get_args( p_from, &error,
+            DBUS_TYPE_INT32, &i_position,
+            DBUS_TYPE_INVALID );
+
+    if( dbus_error_is_set( &error ) )
+    {
+        msg_Err( (vlc_object_t*) p_this, "D-Bus message reading : %s\n",
+                error.message );
+        dbus_error_free( &error );
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+    }
+
+    //TODO delete the element
+
+    REPLY_SEND;
+}
+
 /*****************************************************************************
  * Introspection method
  *****************************************************************************/
 
-DBUS_METHOD( handle_introspect )
+DBUS_METHOD( handle_introspect_root )
 { /* handles introspection of /org/videolan/vlc */
     REPLY_INIT;
     OUT_ARGUMENTS;
-    ADD_STRING( &psz_introspection_xml_data );
+    ADD_STRING( &psz_introspection_xml_data_root );
+    REPLY_SEND;
+}
+
+DBUS_METHOD( handle_introspect_player )
+{
+    REPLY_INIT;
+    OUT_ARGUMENTS;
+    ADD_STRING( &psz_introspection_xml_data_player );
+    REPLY_SEND;
+}
+
+DBUS_METHOD( handle_introspect_tracklist )
+{
+    REPLY_INIT;
+    OUT_ARGUMENTS;
+    ADD_STRING( &psz_introspection_xml_data_tracklist );
     REPLY_SEND;
 }
 
 /*****************************************************************************
- * handle_messages: answer to incoming messages
+ * handle_*: answer to incoming messages
  *****************************************************************************/
 
 #define METHOD_FUNC( method, function ) \
     else if( dbus_message_is_method_call( p_from, VLC_DBUS_INTERFACE, method ) )\
         return function( p_conn, p_from, p_this )
 
-DBUS_METHOD( handle_messages )
-{ /* the main handler, that call methods */
+DBUS_METHOD( handle_root )
+{
 
     if( dbus_message_is_method_call( p_from,
                 DBUS_INTERFACE_INTROSPECTABLE, "Introspect" ) )
-        return handle_introspect( p_conn, p_from, p_this );
+        return handle_introspect_root( p_conn, p_from, p_this );
+
+    /* here D-Bus method's names are associated to an handler */
+
+    METHOD_FUNC( "Identity",                Identity );
+
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+
+DBUS_METHOD( handle_player )
+{
+    if( dbus_message_is_method_call( p_from,
+                DBUS_INTERFACE_INTROSPECTABLE, "Introspect" ) )
+    return handle_introspect_player( p_conn, p_from, p_this );
 
     /* here D-Bus method's names are associated to an handler */
 
-    METHOD_FUNC( "GetPlayStatus",           GetPlayStatus );
-    METHOD_FUNC( "GetPlayingItem",          GetPlayingItem );
-    METHOD_FUNC( "AddMRL",                  AddMRL );
-    METHOD_FUNC( "TogglePause",             TogglePause );
-    METHOD_FUNC( "Nothing",                 Nothing );
     METHOD_FUNC( "Prev",                    Prev );
     METHOD_FUNC( "Next",                    Next );
     METHOD_FUNC( "Quit",                    Quit );
     METHOD_FUNC( "Stop",                    Stop );
+    METHOD_FUNC( "Play",                    Play );
+    METHOD_FUNC( "Pause",                   Pause );
     METHOD_FUNC( "VolumeSet",               VolumeSet );
     METHOD_FUNC( "VolumeGet",               VolumeGet );
     METHOD_FUNC( "PositionSet",             PositionSet );
     METHOD_FUNC( "PositionGet",             PositionGet );
-    METHOD_FUNC( "PlaylistExport_XSPF",     PlaylistExport_XSPF );
+    METHOD_FUNC( "GetStatus",               GetStatus );
+
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+DBUS_METHOD( handle_tracklist )
+{
+    if( dbus_message_is_method_call( p_from,
+                DBUS_INTERFACE_INTROSPECTABLE, "Introspect" ) )
+    return handle_introspect_tracklist( p_conn, p_from, p_this );
+
+    /* here D-Bus method's names are associated to an handler */
+
+    METHOD_FUNC( "GetMetadata",             GetMetadata );
+    METHOD_FUNC( "GetCurrentTrack",         GetCurrentTrack );
+    METHOD_FUNC( "GetLength",               GetLength );
+    METHOD_FUNC( "AddTrack",                AddTrack );
+    METHOD_FUNC( "DelTrack",                DelTrack );
 
     return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
@@ -464,18 +563,32 @@ static int Open( vlc_object_t *p_this )
         return VLC_EGENERIC;
     }
 
+    /* register a well-known name on the bus */
+    dbus_bus_request_name( p_conn, "org.freedesktop.MediaPlayer", 0, &error );
+    if( dbus_error_is_set( &error ) )
+    {
+        msg_Err( p_this, "Error requesting org.freedesktop.MediaPlayer service:"                " %s\n", error.message );
+        dbus_error_free( &error );
+        free( p_sys );
+        return VLC_EGENERIC;
+    }
+
     /* we unregister the object /, registered by libvlc */
     dbus_connection_unregister_object_path( p_conn, "/" );
 
-    /* we register the object /org/videolan/vlc */
-    dbus_connection_register_object_path( p_conn, VLC_DBUS_OBJECT_PATH,
-            &vlc_dbus_vtable, p_this );
+    /* we register the objects */
+    dbus_connection_register_object_path( p_conn, VLC_DBUS_ROOT_PATH,
+            &vlc_dbus_root_vtable, p_this );
+    dbus_connection_register_object_path( p_conn, VLC_DBUS_PLAYER_PATH,
+            &vlc_dbus_player_vtable, p_this );
+    dbus_connection_register_object_path( p_conn, VLC_DBUS_TRACKLIST_PATH,
+            &vlc_dbus_tracklist_vtable, p_this );
 
     dbus_connection_flush( p_conn );
 
     p_playlist = pl_Yield( p_intf );
     PL_LOCK;
-    var_AddCallback( p_playlist, "playlist-current", ItemChange, p_intf );
+    var_AddCallback( p_playlist, "playlist-current", TrackChange, p_intf );
     PL_UNLOCK;
     pl_Release( p_playlist );
 
@@ -496,7 +609,7 @@ static void Close   ( vlc_object_t *p_this )
     playlist_t      *p_playlist = pl_Yield( p_intf );;
 
     PL_LOCK;
-    var_DelCallback( p_playlist, "playlist-current", ItemChange, p_intf );
+    var_DelCallback( p_playlist, "playlist-current", TrackChange, p_intf );
     PL_UNLOCK;
     pl_Release( p_playlist );
 
@@ -519,12 +632,12 @@ static void Run          ( intf_thread_t *p_intf )
 }
 
 /*****************************************************************************
- * ItemChange: Playlist item change callback
+ * TrackChange: Playlist item change callback
  *****************************************************************************/
 
-DBUS_SIGNAL( ItemChangeSignal )
+DBUS_SIGNAL( TrackChangeSignal )
 { /* emit the name of the new item */
-    SIGNAL_INIT( "ItemChange" );
+    SIGNAL_INIT( "TrackChange" );
     OUT_ARGUMENTS;
 
     input_thread_t *p_input = (input_thread_t*) p_data;
@@ -533,7 +646,7 @@ DBUS_SIGNAL( ItemChangeSignal )
     SIGNAL_SEND;
 }
 
-static int ItemChange( vlc_object_t *p_this, const char *psz_var,
+static int TrackChange( vlc_object_t *p_this, const char *psz_var,
             vlc_value_t oldval, vlc_value_t newval, void *p_data )
 {
     intf_thread_t       *p_intf     = ( intf_thread_t* ) p_data;
@@ -557,7 +670,7 @@ static int ItemChange( vlc_object_t *p_this, const char *psz_var,
     PL_UNLOCK;
     pl_Release( p_playlist );
 
-    ItemChangeSignal( p_sys->p_conn, p_input );
+    TrackChangeSignal( p_sys->p_conn, p_input );
 
     vlc_object_release( p_input );
     return VLC_SUCCESS;
index e6890f6..a3d0d35 100644 (file)
 
 /* DBUS IDENTIFIERS */
 
-/* this is also defined in src/libvlc-common.c for one-instance mode */
-
 /* name registered on the session bus */
-#define VLC_DBUS_SERVICE        "org.videolan.vlc"
-#define VLC_DBUS_INTERFACE      "org.videolan.vlc"
-#define VLC_DBUS_OBJECT_PATH    "/org/videolan/vlc"
+#define VLC_DBUS_SERVICE        "org.freedesktop.MediaPlayer"
+#define VLC_DBUS_INTERFACE      "org.freedesktop.MediaPlayer"
+#define VLC_DBUS_ROOT_PATH      "/"
+#define VLC_DBUS_PLAYER_PATH    "/Player"
+#define VLC_DBUS_TRACKLIST_PATH "/TrackList"
 
 /* MACROS */
 
@@ -52,7 +52,7 @@
     return DBUS_HANDLER_RESULT_HANDLED
 
 #define SIGNAL_INIT( signal ) \
-    DBusMessage *p_msg = dbus_message_new_signal( VLC_DBUS_OBJECT_PATH, \
+    DBusMessage *p_msg = dbus_message_new_signal( VLC_DBUS_PLAYER_PATH, \
         VLC_DBUS_INTERFACE, signal ); \
     if( !p_msg ) return DBUS_HANDLER_RESULT_NEED_MEMORY; \
 
 
 #define ADD_STRING( s ) DBUS_ADD( DBUS_TYPE_STRING, s )
 #define ADD_BOOL( b ) DBUS_ADD( DBUS_TYPE_BOOLEAN, b )
-#define ADD_UINT32( i ) DBUS_ADD( DBUS_TYPE_UINT32, i )
-#define ADD_UINT16( i ) DBUS_ADD( DBUS_TYPE_UINT16, i )
+#define ADD_INT32( i ) DBUS_ADD( DBUS_TYPE_INT32, i )
 #define ADD_BYTE( b ) DBUS_ADD( DBUS_TYPE_BYTE, b )
 
 /* XML data to answer org.freedesktop.DBus.Introspectable.Introspect requests */
 
-const char* psz_introspection_xml_data =
+const char* psz_introspection_xml_data_root =
 "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
 "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
 "<node>"
@@ -88,21 +87,26 @@ const char* psz_introspection_xml_data =
 "      <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
 "    </method>\n"
 "  </interface>\n"
-"  <interface name=\"org.videolan.vlc\">\n"
-"    <method name=\"GetPlayStatus\">\n"
-"      <arg type=\"s\" direction=\"out\" />\n"
-"    </method>\n"
-"    <method name=\"GetPlayingItem\">\n"
+"  <interface name=\"org.freedesktop.MediaPlayer\">\n"
+"    <method name=\"Identity\">\n"
 "      <arg type=\"s\" direction=\"out\" />\n"
 "    </method>\n"
-"    <method name=\"TogglePause\">\n"
-"      <arg type=\"b\" direction=\"out\" />\n"
-"    </method>\n"
-"    <method name=\"AddMRL\">\n"
-"      <arg type=\"s\" direction=\"in\" />\n"
-"      <arg type=\"b\" direction=\"in\" />\n"
+"  </interface>\n"
+"</node>\n"
+;
+
+const char* psz_introspection_xml_data_player =
+"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
+"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
+"<node>"
+"  <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
+"    <method name=\"Introspect\">\n"
+"      <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
 "    </method>\n"
-"    <method name=\"Nothing\">\n"
+"  </interface>\n"
+"  <interface name=\"org.videolan.vlc\">\n"
+"    <method name=\"GetStatus\">\n"
+"      <arg type=\"i\" direction=\"out\" />\n"
 "    </method>\n"
 "    <method name=\"Quit\">\n"
 "    </method>\n"
@@ -112,36 +116,78 @@ const char* psz_introspection_xml_data =
 "    </method>\n"
 "    <method name=\"Stop\">\n"
 "    </method>\n"
+"    <method name=\"Play\">\n"
+"    </method>\n"
+"    <method name=\"Pause\">\n"
+"    </method>\n"
 "    <method name=\"VolumeSet\">\n"
-"      <arg type=\"q\" direction=\"in\" />\n"
+"      <arg type=\"i\" direction=\"in\" />\n"
 "    </method>\n"
 "    <method name=\"VolumeGet\">\n"
-"      <arg type=\"q\" direction=\"out\" />\n"
+"      <arg type=\"i\" direction=\"out\" />\n"
 "    </method>\n"
 "    <method name=\"PositionSet\">\n"
-"      <arg type=\"q\" direction=\"in\" />\n"
+"      <arg type=\"i\" direction=\"in\" />\n"
 "    </method>\n"
 "    <method name=\"PositionGet\">\n"
-"      <arg type=\"q\" direction=\"out\" />\n"
+"      <arg type=\"i\" direction=\"out\" />\n"
 "    </method>\n"
-"    <method name=\"PlaylistExport_XSPF\">\n"
+"  </interface>\n"
+"</node>\n"
+;
+
+const char* psz_introspection_xml_data_tracklist =
+"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
+"\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
+"<node>"
+"  <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
+"    <method name=\"Introspect\">\n"
+"      <arg name=\"data\" direction=\"out\" type=\"s\"/>\n"
+"    </method>\n"
+"  </interface>\n"
+"  <interface name=\"org.videolan.vlc\">\n"
+"    <method name=\"AddTrack\">\n"
 "      <arg type=\"s\" direction=\"in\" />\n"
-"      <arg type=\"q\" direction=\"out\" />\n"
+"      <arg type=\"b\" direction=\"in\" />\n"
+"    </method>\n"
+"    <method name=\"DelTrack\">\n"
+"      <arg type=\"i\" direction=\"in\" />\n"
+"    </method>\n"
+"    <method name=\"GetMetadata\">\n"
+"      <arg type=\"i\" direction=\"in\" />\n"
+"      <arg type=\"a{sv}\" direction=\"out\" />\n"
+"    </method>\n"
+"    <method name=\"GetCurrentTrack\">\n"
+"      <arg type=\"i\" direction=\"out\" />\n"
+"    </method>\n"
+"    <method name=\"GetLength\">\n"
+"      <arg type=\"i\" direction=\"out\" />\n"
 "    </method>\n"
 "  </interface>\n"
 "</node>\n"
 ;
 
-/* Handling of messages received onn VLC_DBUS_OBJECT_PATH */
-DBUS_METHOD( handle_messages ); /* handler function */
-
-/* vtable passed to dbus_connection_register_object_path() */
-static DBusObjectPathVTable vlc_dbus_vtable = {
-        NULL, /* Called when vtable is unregistered or its connection is freed*/
-        handle_messages, /* handler function */
-        NULL,
-        NULL,
-        NULL,
-        NULL
+#define VLC_DBUS_ROOT_PATH      "/"
+#define VLC_DBUS_PLAYER_PATH    "/Player"
+#define VLC_DBUS_TRACKLIST_PATH "/TrackList"
+
+/* Handle  messages reception */
+DBUS_METHOD( handle_root );
+DBUS_METHOD( handle_player );
+DBUS_METHOD( handle_tracklist );
+
+static DBusObjectPathVTable vlc_dbus_root_vtable = {
+        NULL, handle_root, /* handler function */
+        NULL, NULL, NULL, NULL
+};
+
+static DBusObjectPathVTable vlc_dbus_player_vtable = {
+        NULL, handle_player, /* handler function */
+        NULL, NULL, NULL, NULL
+};
+
+static DBusObjectPathVTable vlc_dbus_tracklist_vtable = {
+        NULL, handle_tracklist, /* handler function */
+        NULL, NULL, NULL, NULL
 };
 
index 85e04a5..a9ee400 100644 (file)
 #endif
 
 #ifdef HAVE_DBUS_3
+/* used for one-instance mode */
 #   include <dbus/dbus.h>
-
-/* this is also defined in modules/control/dbus.h */
-/* names registered on the session bus */
-#define VLC_DBUS_SERVICE        "org.videolan.vlc"
-#define VLC_DBUS_INTERFACE      "org.videolan.vlc"
-#define VLC_DBUS_OBJECT_PATH    "/org/videolan/vlc"
 #endif
 
 #ifdef HAVE_HAL
@@ -632,12 +627,12 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] )
     else
     {
         /* we request the service org.videolan.vlc */
-        i_dbus_service = dbus_bus_request_name( p_conn, VLC_DBUS_SERVICE, 0, 
+        i_dbus_service = dbus_bus_request_name( p_conn, "org.videolan.vlc", 0, 
                 &dbus_error );
         if( dbus_error_is_set( &dbus_error ) )
         { 
-            msg_Err( p_libvlc, "Error requesting %s service: %s\n",
-                    VLC_DBUS_SERVICE, dbus_error.message );
+            msg_Err( p_libvlc, "Error requesting org.videolan.vlc service: "
+                    "%s\n", dbus_error.message );
             dbus_error_free( &dbus_error );
         }
         else
@@ -646,14 +641,14 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] )
             { /* the name is already registered by another instance of vlc */
                 if( config_GetInt( p_libvlc, "one-instance" ) )
                 {
-                    /* check if /org/videolan/vlc exists
+                    /* check if a Media Player is available
                      * if not: D-Bus control is not enabled on the other
                      * instance and we can't pass MRLs to it */
                     DBusMessage *p_test_msg, *p_test_reply;
                     p_test_msg =  dbus_message_new_method_call(
-                            VLC_DBUS_SERVICE, VLC_DBUS_OBJECT_PATH,
-                            VLC_DBUS_INTERFACE, "Nothing" );
-                    /* block unti a reply arrives */
+                            "org.freedesktop.MediaPlayer", "/",
+                            "org.freedesktop.MediaPlayer", "Identity" );
+                    /* block until a reply arrives */
                     p_test_reply = dbus_connection_send_with_reply_and_block(
                             p_conn, p_test_msg, -1, &dbus_error );
                     dbus_message_unref( p_test_msg );
@@ -683,8 +678,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] )
                                     ppsz_argv[i_input] );
 
                             p_dbus_msg = dbus_message_new_method_call(
-                                    VLC_DBUS_SERVICE, VLC_DBUS_OBJECT_PATH,
-                                    VLC_DBUS_INTERFACE, "AddMRL" );
+                                    "org.freedesktop.MediaPlayer", "/TrackList",
+                                    "org.freedesktop.MediaPlayer", "AddTrack" );
 
                             if ( NULL == p_dbus_msg )
                             {
@@ -748,9 +743,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] )
                 } /* we're not in one-instance mode */
                 else
                 {
-                    msg_Dbg( p_libvlc, 
-                            "%s is already registered on the session bus\n",
-                            VLC_DBUS_SERVICE );
+                    msg_Dbg( p_libvlc, "org.videolan.vlc is already registered "
+                            "on the session bus\n" );
                 }
             } /* the named is owned by something else */
             else
@@ -762,8 +756,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] )
                     msg_Err( p_libvlc, "Out of memory" );
                 }
                 msg_Dbg( p_libvlc, 
-                        "We are the primary owner of %s on the session bus",
-                        VLC_DBUS_SERVICE );
+                        "We are the primary owner of org.videolan.vlc on the "
+                        " session bus" );
             }
         } /* no error when requesting the name on the bus */
         /* we unreference the connection when we've finished with it */