[vlc-devel] [PATCH 2/5] Implement Properties.GetAll on all MPRIS2 interfaces

Alex Merry dev at randomguy3.me.uk
Sun Jan 27 22:25:11 CET 2013


It was previously only implemented on the org.mpris.MediaPlayer2
interface, and even there it was not complete (Fullscreen was missing).

This also adds it to the introspection XML.
---
 modules/control/dbus/dbus.c            |  37 ++++++
 modules/control/dbus/dbus_common.h     |   7 ++
 modules/control/dbus/dbus_introspect.h |   6 +
 modules/control/dbus/dbus_player.c     | 213 +++++++++++++++++++++++----------
 modules/control/dbus/dbus_root.c       |  42 +------
 modules/control/dbus/dbus_tracklist.c  | 109 +++++++++++++----
 6 files changed, 295 insertions(+), 119 deletions(-)

diff --git a/modules/control/dbus/dbus.c b/modules/control/dbus/dbus.c
index a52bb74..898f40b 100644
--- a/modules/control/dbus/dbus.c
+++ b/modules/control/dbus/dbus.c
@@ -1,6 +1,7 @@
 /*****************************************************************************
  * dbus.c : D-Bus control interface
  *****************************************************************************
+ * Copyright © 2013      Alex Merry
  * Copyright © 2006-2008 Rafaël Carré
  * Copyright © 2007-2012 Mirsal Ennaime
  * Copyright © 2009-2012 The VideoLAN team
@@ -8,6 +9,7 @@
  *
  * Authors:    Rafaël Carré <funman at videolanorg>
  *             Mirsal Ennaime <mirsal at mirsal fr>
+ *             Alex Merry <dev at randomguy3 me uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -1210,6 +1212,41 @@ int GetInputMeta( input_item_t* p_input,
     return VLC_SUCCESS;
 }
 
+int AddProperty( intf_thread_t *p_intf,
+                 DBusMessageIter *p_container,
+                 const char* psz_property_name,
+                 const char* psz_signature,
+                 int (*pf_marshaller) (intf_thread_t*, DBusMessageIter*) )
+{
+    DBusMessageIter entry, v;
+
+    if( !dbus_message_iter_open_container( p_container,
+                                           DBUS_TYPE_DICT_ENTRY, NULL,
+                                           &entry ) )
+        return VLC_ENOMEM;
+
+    if( !dbus_message_iter_append_basic( &entry,
+                                         DBUS_TYPE_STRING,
+                                         &psz_property_name ) )
+        return VLC_ENOMEM;
+
+    if( !dbus_message_iter_open_container( &entry,
+                                           DBUS_TYPE_VARIANT, psz_signature,
+                                           &v ) )
+        return VLC_ENOMEM;
+
+    if( VLC_SUCCESS != pf_marshaller( p_intf, &v ) )
+        return VLC_ENOMEM;
+
+    if( !dbus_message_iter_close_container( &entry, &v) )
+        return VLC_ENOMEM;
+
+    if( !dbus_message_iter_close_container( p_container, &entry ) )
+        return VLC_ENOMEM;
+
+    return VLC_SUCCESS;
+}
+
 #undef ADD_META
 #undef ADD_VLC_META_STRING
 
diff --git a/modules/control/dbus/dbus_common.h b/modules/control/dbus/dbus_common.h
index 2e1c5b9..b37ba26 100644
--- a/modules/control/dbus/dbus_common.h
+++ b/modules/control/dbus/dbus_common.h
@@ -1,6 +1,7 @@
 /*****************************************************************************
  * dbus_common.h : Common header for D-Bus control modules
  *****************************************************************************
+ * Copyright © 2013      Alex Merry
  * Copyright © 2006-2008 Rafaël Carré
  * Copyright © 2007-2010 Mirsal Ennaime
  * Copyright © 2009-2010 The VideoLAN team
@@ -8,6 +9,7 @@
  *
  * Authors:    Mirsal Ennaime <mirsal dot ennaime at gmailcom>
  *             Rafaël Carré <funman at videolanorg>
+ *             Alex Merry <dev at randomguy3 me uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -138,5 +140,10 @@ enum
 
 int DemarshalSetPropertyValue( DBusMessage *p_msg, void *p_arg );
 int GetInputMeta  ( input_item_t* p_input, DBusMessageIter *args );
+int AddProperty ( intf_thread_t *p_intf,
+                  DBusMessageIter *p_container,
+                  const char* psz_property_name,
+                  const char* psz_signature,
+                  int (*pf_marshaller) (intf_thread_t*, DBusMessageIter*) );
 
 #endif //dbus-common.h
diff --git a/modules/control/dbus/dbus_introspect.h b/modules/control/dbus/dbus_introspect.h
index 31f4c9b..0d68c4d 100644
--- a/modules/control/dbus/dbus_introspect.h
+++ b/modules/control/dbus/dbus_introspect.h
@@ -1,6 +1,7 @@
 /*****************************************************************************
  * dbus_introspect.h : dbus control module (mpris v2.1) - introspection data
  *****************************************************************************
+ * Copyright © 2013      Alex Merry
  * Copyright © 2006-2011 Rafaël Carré
  * Copyright © 2007-2011 Mirsal Ennaime
  * Copyright © 2009-2011 The VideoLAN team
@@ -8,6 +9,7 @@
  *
  * Authors:    Mirsal Ennaime <mirsal at mirsal fr>
  *             Rafaël Carré <funman at videolanorg>
+ *             Alex Merry <dev at randomguy3 me uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -50,6 +52,10 @@ static const char* psz_introspection_xml =
 "      <arg direction=\"in\" type=\"s\"/>\n"
 "      <arg direction=\"in\" type=\"v\"/>\n"
 "    </method>\n"
+"    <method name=\"GetAll\">\n"
+"      <arg direction=\"in\" type=\"s\"/>\n"
+"      <arg direction=\"out\" type=\"a{sv}\"/>\n"
+"    </method>\n"
 "    <signal name=\"PropertiesChanged\">\n"
 "      <arg type=\"s\"/>\n"
 "      <arg type=\"a{sv}\"/>\n"
diff --git a/modules/control/dbus/dbus_player.c b/modules/control/dbus/dbus_player.c
index b3ee33e..3aa8ef1 100644
--- a/modules/control/dbus/dbus_player.c
+++ b/modules/control/dbus/dbus_player.c
@@ -1,6 +1,7 @@
 /*****************************************************************************
  * dbus_player.c : dbus control module (mpris v1.0) - /Player object
  *****************************************************************************
+ * Copyright © 2013      Alex Merry
  * Copyright © 2006-2011 Rafaël Carré
  * Copyright © 2007-2011 Mirsal Ennaime
  * Copyright © 2009-2011 The VideoLAN team
@@ -8,6 +9,7 @@
  *
  * Authors:    Mirsal Ennaime <mirsal at mirsal fr>
  *             Rafaël Carré <funman at videolanorg>
+ *             Alex Merry <dev at randomguy3 me uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -37,19 +39,14 @@
 #include "dbus_player.h"
 #include "dbus_common.h"
 
-static void MarshalLoopStatus ( intf_thread_t *, DBusMessageIter * );
+static int MarshalLoopStatus ( intf_thread_t *, DBusMessageIter * );
 
-DBUS_METHOD( Position )
-{ /* returns position in microseconds */
-    REPLY_INIT;
-    OUT_ARGUMENTS;
-    DBusMessageIter v;
+static int
+MarshalPosition( intf_thread_t *p_intf, DBusMessageIter *container )
+{
     dbus_int64_t i_pos;
-
-    if( !dbus_message_iter_open_container( &args, DBUS_TYPE_VARIANT, "x", &v ) )
-        return DBUS_HANDLER_RESULT_NEED_MEMORY;
-
-    input_thread_t *p_input = playlist_CurrentInput( PL );
+    input_thread_t *p_input;
+    p_input = playlist_CurrentInput( p_intf->p_sys->p_playlist );
 
     if( !p_input )
         i_pos = 0;
@@ -60,9 +57,22 @@ DBUS_METHOD( Position )
         vlc_object_release( p_input );
     }
 
-    if( !dbus_message_iter_append_basic( &v, DBUS_TYPE_INT64, &i_pos ) )
+    dbus_message_iter_append_basic( container, DBUS_TYPE_INT64, &i_pos );
+
+    return VLC_SUCCESS;
+}
+
+DBUS_METHOD( Position )
+{ /* returns position in microseconds */
+    REPLY_INIT;
+    OUT_ARGUMENTS;
+    DBusMessageIter v;
+
+    if( !dbus_message_iter_open_container( &args, DBUS_TYPE_VARIANT, "x", &v ) )
         return DBUS_HANDLER_RESULT_NEED_MEMORY;
 
+    MarshalPosition( p_this, &v );
+
     if( !dbus_message_iter_close_container( &args, &v ) )
         return DBUS_HANDLER_RESULT_NEED_MEMORY;
 
@@ -163,7 +173,7 @@ DBUS_METHOD( Seek )
     REPLY_SEND;
 }
 
-static void
+static int
 MarshalVolume( intf_thread_t *p_intf, DBusMessageIter *container )
 {
     float f_vol = playlist_VolumeGet( p_intf->p_sys->p_playlist );
@@ -172,6 +182,7 @@ MarshalVolume( intf_thread_t *p_intf, DBusMessageIter *container )
 
     double d_vol = f_vol;
     dbus_message_iter_append_basic( container, DBUS_TYPE_DOUBLE, &d_vol );
+    return VLC_SUCCESS;
 }
 
 DBUS_METHOD( VolumeGet )
@@ -300,7 +311,7 @@ DBUS_METHOD( OpenUri )
     REPLY_SEND;
 }
 
-static void
+static int
 MarshalCanPlay( intf_thread_t *p_intf, DBusMessageIter *container )
 {
     playlist_t *p_playlist = p_intf->p_sys->p_playlist;
@@ -310,6 +321,7 @@ MarshalCanPlay( intf_thread_t *p_intf, DBusMessageIter *container )
     PL_UNLOCK;
 
     dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN, &b_can_play );
+    return VLC_SUCCESS;
 }
 
 DBUS_METHOD( CanPlay )
@@ -330,7 +342,7 @@ DBUS_METHOD( CanPlay )
     REPLY_SEND;
 }
 
-static void
+static int
 MarshalCanPause( intf_thread_t *p_intf, DBusMessageIter *container )
 {
     dbus_bool_t b_can_pause = FALSE;
@@ -345,6 +357,7 @@ MarshalCanPause( intf_thread_t *p_intf, DBusMessageIter *container )
 
     dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN,
                                     &b_can_pause );
+    return VLC_SUCCESS;
 }
 
 DBUS_METHOD( CanPause )
@@ -365,23 +378,29 @@ DBUS_METHOD( CanPause )
     REPLY_SEND;
 }
 
-DBUS_METHOD( CanControl )
+static int
+MarshalCanControl( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    VLC_UNUSED( p_this );
+    VLC_UNUSED( p_intf );
+    dbus_bool_t b_can_control = TRUE;
+
+    dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN,
+                                    &b_can_control );
+    return VLC_SUCCESS;
+}
 
+DBUS_METHOD( CanControl )
+{
     REPLY_INIT;
     OUT_ARGUMENTS;
 
     DBusMessageIter v;
-    dbus_bool_t b_can_control = TRUE;
 
     if( !dbus_message_iter_open_container( &args, DBUS_TYPE_VARIANT,
                                            "b", &v ) )
         return DBUS_HANDLER_RESULT_NEED_MEMORY;
 
-    if( !dbus_message_iter_append_basic( &v, DBUS_TYPE_BOOLEAN,
-                                         &b_can_control ) )
-        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+    MarshalCanControl( p_this, &v );
 
     if( !dbus_message_iter_close_container( &args, &v ) )
         return DBUS_HANDLER_RESULT_NEED_MEMORY;
@@ -389,7 +408,7 @@ DBUS_METHOD( CanControl )
     REPLY_SEND;
 }
 
-static void
+static int
 MarshalCanSeek( intf_thread_t *p_intf, DBusMessageIter *container )
 {
     dbus_bool_t b_can_seek = FALSE;
@@ -403,6 +422,7 @@ MarshalCanSeek( intf_thread_t *p_intf, DBusMessageIter *container )
     }
 
     dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN, &b_can_seek );
+    return VLC_SUCCESS;
 }
 
 DBUS_METHOD( CanSeek )
@@ -423,11 +443,12 @@ DBUS_METHOD( CanSeek )
     REPLY_SEND;
 }
 
-static void
+static int
 MarshalShuffle( intf_thread_t *p_intf, DBusMessageIter *container )
 {
     dbus_bool_t b_shuffle = var_GetBool( p_intf->p_sys->p_playlist, "random" );
     dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN, &b_shuffle );
+    return VLC_SUCCESS;
 }
 
 DBUS_METHOD( ShuffleGet )
@@ -461,7 +482,7 @@ DBUS_METHOD( ShuffleSet )
     REPLY_SEND;
 }
 
-static void
+static int
 MarshalPlaybackStatus( intf_thread_t *p_intf, DBusMessageIter *container )
 {
     input_thread_t *p_input;
@@ -489,6 +510,7 @@ MarshalPlaybackStatus( intf_thread_t *p_intf, DBusMessageIter *container )
 
     dbus_message_iter_append_basic( container, DBUS_TYPE_STRING,
                                     &psz_playback_status );
+    return VLC_SUCCESS;
 }
 
 DBUS_METHOD( PlaybackStatus )
@@ -509,7 +531,7 @@ DBUS_METHOD( PlaybackStatus )
     REPLY_SEND;
 }
 
-static void
+static int
 MarshalRate( intf_thread_t *p_intf, DBusMessageIter *container )
 {
     double d_rate;
@@ -523,6 +545,7 @@ MarshalRate( intf_thread_t *p_intf, DBusMessageIter *container )
         d_rate = 0.;
 
     dbus_message_iter_append_basic( container, DBUS_TYPE_DOUBLE, &d_rate );
+    return VLC_SUCCESS;
 }
 
 DBUS_METHOD( RateGet )
@@ -564,21 +587,27 @@ DBUS_METHOD( RateSet )
     REPLY_SEND;
 }
 
-DBUS_METHOD( MinimumRate )
+static int
+MarshalMinimumRate( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    VLC_UNUSED( p_this );
+    VLC_UNUSED( p_intf );
+    double d_min_rate = (double) INPUT_RATE_MIN / INPUT_RATE_DEFAULT;
 
+    dbus_message_iter_append_basic( container, DBUS_TYPE_DOUBLE, &d_min_rate );
+    return VLC_SUCCESS;
+}
+
+DBUS_METHOD( MinimumRate )
+{
     REPLY_INIT;
     OUT_ARGUMENTS;
 
     DBusMessageIter v;
-    double d_min_rate = (double) INPUT_RATE_MIN / INPUT_RATE_DEFAULT;
 
     if( !dbus_message_iter_open_container( &args, DBUS_TYPE_VARIANT, "d", &v ) )
         return DBUS_HANDLER_RESULT_NEED_MEMORY;
 
-    if( !dbus_message_iter_append_basic( &v, DBUS_TYPE_DOUBLE, &d_min_rate ) )
-        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+    MarshalMinimumRate( p_this, &v );
 
     if( !dbus_message_iter_close_container( &args, &v ) )
         return DBUS_HANDLER_RESULT_NEED_MEMORY;
@@ -586,21 +615,27 @@ DBUS_METHOD( MinimumRate )
     REPLY_SEND;
 }
 
-DBUS_METHOD( MaximumRate )
+static int
+MarshalMaximumRate( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    VLC_UNUSED( p_this );
+    VLC_UNUSED( p_intf );
+    double d_max_rate = (double) INPUT_RATE_MAX / INPUT_RATE_DEFAULT;
 
+    dbus_message_iter_append_basic( container, DBUS_TYPE_DOUBLE, &d_max_rate );
+    return VLC_SUCCESS;
+}
+
+DBUS_METHOD( MaximumRate )
+{
     REPLY_INIT;
     OUT_ARGUMENTS;
 
     DBusMessageIter v;
-    double d_max_rate = (double) INPUT_RATE_MAX / INPUT_RATE_DEFAULT;
 
     if( !dbus_message_iter_open_container( &args, DBUS_TYPE_VARIANT, "d", &v ) )
         return DBUS_HANDLER_RESULT_NEED_MEMORY;
 
-    if( !dbus_message_iter_append_basic( &v, DBUS_TYPE_DOUBLE, &d_max_rate ) )
-        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+    MarshalMaximumRate( p_this, &v );
 
     if( !dbus_message_iter_close_container( &args, &v ) )
         return DBUS_HANDLER_RESULT_NEED_MEMORY;
@@ -608,7 +643,7 @@ DBUS_METHOD( MaximumRate )
     REPLY_SEND;
 }
 
-static void
+static int
 MarshalLoopStatus( intf_thread_t *p_intf, DBusMessageIter *container )
 {
     const char *psz_loop_status;
@@ -624,6 +659,7 @@ MarshalLoopStatus( intf_thread_t *p_intf, DBusMessageIter *container )
 
     dbus_message_iter_append_basic( container, DBUS_TYPE_STRING,
                                     &psz_loop_status );
+    return VLC_SUCCESS;
 }
 
 DBUS_METHOD( LoopStatusGet )
@@ -673,30 +709,41 @@ DBUS_METHOD( LoopStatusSet )
     REPLY_SEND;
 }
 
-DBUS_METHOD( Metadata )
+static int
+MarshalMetadata( intf_thread_t *p_intf, DBusMessageIter *container )
 {
-    REPLY_INIT;
-    OUT_ARGUMENTS;
-
-    DBusMessageIter v, a;
-    playlist_t *p_playlist = PL;
-
-    if( !dbus_message_iter_open_container( &args, DBUS_TYPE_VARIANT,
-                                           "a{sv}", &v ) )
-        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+    DBusMessageIter a;
+    playlist_t *p_playlist = p_intf->p_sys->p_playlist;
 
     PL_LOCK;
     playlist_item_t* p_item =  playlist_CurrentPlayingItem( p_playlist );
 
     if( p_item )
-        GetInputMeta( p_item->p_input, &v );
+        GetInputMeta( p_item->p_input, container );
 
     PL_UNLOCK;
 
-    if( ( !p_item &&
-        ( !dbus_message_iter_open_container( &v, DBUS_TYPE_ARRAY, "{sv}", &a ) ||
-          !dbus_message_iter_close_container( &v, &a ) ) ) ||
+    if( !p_item &&
+        ( !dbus_message_iter_open_container( container, DBUS_TYPE_ARRAY, "{sv}", &a ) ||
+          !dbus_message_iter_close_container( container, &a ) ) ) {
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+    }
 
+    return VLC_SUCCESS;
+}
+
+DBUS_METHOD( Metadata )
+{
+    REPLY_INIT;
+    OUT_ARGUMENTS;
+
+    DBusMessageIter v;
+
+    if( !dbus_message_iter_open_container( &args, DBUS_TYPE_VARIANT,
+                                           "a{sv}", &v ) )
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+    if( MarshalMetadata( p_this, &v ) != VLC_SUCCESS ||
         !dbus_message_iter_close_container( &args, &v ) ) {
         return DBUS_HANDLER_RESULT_NEED_MEMORY;
     }
@@ -810,6 +857,58 @@ DBUS_METHOD( SetProperty )
 #undef PROPERTY_GET_FUNC
 #undef PROPERTY_MAPPING_END
 
+#define ADD_PROPERTY( prop, signature ) \
+    if( VLC_SUCCESS != AddProperty( (intf_thread_t*) p_this, \
+                &dict, #prop, signature, Marshal##prop ) ) \
+        return VLC_ENOMEM;
+
+DBUS_METHOD( GetAllProperties )
+{
+    REPLY_INIT;
+    OUT_ARGUMENTS;
+
+    DBusError error;
+    DBusMessageIter dict;
+
+    char *const psz_interface_name = NULL;
+
+    dbus_error_init( &error );
+    dbus_message_get_args( p_from, &error,
+            DBUS_TYPE_STRING, &psz_interface_name,
+            DBUS_TYPE_INVALID );
+
+    if( dbus_error_is_set( &error ) )
+    {
+        msg_Err( (vlc_object_t*) p_this, "D-Bus message reading : %s",
+                                         error.message );
+        dbus_error_free( &error );
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+    }
+
+    msg_Dbg( (vlc_object_t*) p_this, "Getting All properties" );
+
+    dbus_message_iter_open_container( &args, DBUS_TYPE_ARRAY, "{sv}", &dict );
+
+    ADD_PROPERTY ( Metadata,       "a{sv}" );
+    ADD_PROPERTY ( Position,       "x"     );
+    ADD_PROPERTY ( PlaybackStatus, "s"     );
+    ADD_PROPERTY ( LoopStatus,     "s"     );
+    ADD_PROPERTY ( Shuffle,        "b"     );
+    ADD_PROPERTY ( Volume,         "d"     );
+    ADD_PROPERTY ( Rate,           "d"     );
+    ADD_PROPERTY ( MinimumRate,    "d"     );
+    ADD_PROPERTY ( MaximumRate,    "d"     );
+    ADD_PROPERTY ( CanControl,     "b"     );
+    ADD_PROPERTY ( CanPlay,        "b"     );
+    ADD_PROPERTY ( CanPause,       "b"     );
+    ADD_PROPERTY ( CanSeek,        "b"     );
+
+    dbus_message_iter_close_container( &args, &dict );
+    REPLY_SEND;
+}
+
+#undef ADD_PROPERTY
+
 #define METHOD_FUNC( interface, method, function ) \
     else if( dbus_message_is_method_call( p_from, interface, method ) )\
         return function( p_conn, p_from, p_this )
@@ -820,7 +919,7 @@ handle_player ( DBusConnection *p_conn, DBusMessage *p_from, void *p_this )
     if(0);
     METHOD_FUNC( DBUS_INTERFACE_PROPERTIES,   "Get",        GetProperty );
     METHOD_FUNC( DBUS_INTERFACE_PROPERTIES,   "Set",        SetProperty );
-/*  METHOD_FUNC( DBUS_INTERFACE_PROPERTIES,   "GetAll",     GetAllProperties );*/
+    METHOD_FUNC( DBUS_INTERFACE_PROPERTIES,   "GetAll",     GetAllProperties );
 
     /* here D-Bus method names are associated to an handler */
 
@@ -888,20 +987,10 @@ PropertiesChangedSignal( intf_thread_t    *p_intf,
 
         if( !strcmp( ppsz_properties[i], "Metadata" ) )
         {
-            playlist_t *p_playlist = p_intf->p_sys->p_playlist;
-
             dbus_message_iter_open_container( &entry,
                                               DBUS_TYPE_VARIANT, "a{sv}",
                                               &variant );
-
-            PL_LOCK;
-            playlist_item_t* p_item =  playlist_CurrentPlayingItem( p_playlist );
-
-            if( p_item )
-                GetInputMeta( p_item->p_input, &variant );
-
-            PL_UNLOCK;
-
+            MarshalMetadata( p_intf, &variant );
             dbus_message_iter_close_container( &entry, &variant );
         }
         else if( !strcmp( ppsz_properties[i], "PlaybackStatus" ) )
diff --git a/modules/control/dbus/dbus_root.c b/modules/control/dbus/dbus_root.c
index 1b6b962..515cb8e 100644
--- a/modules/control/dbus/dbus_root.c
+++ b/modules/control/dbus/dbus_root.c
@@ -1,6 +1,7 @@
 /*****************************************************************************
  * dbus_root.c : dbus control module (mpris v1.0) - root object
  *****************************************************************************
+ * Copyright © 2013      Alex Merry
  * Copyright © 2006-2008 Rafaël Carré
  * Copyright © 2007-2011 Mirsal Ennaime
  * Copyright © 2009-2011 The VideoLAN team
@@ -8,6 +9,7 @@
  *
  * Authors:    Mirsal Ennaime <mirsal at mirsal fr>
  *             Rafaël Carré <funman at videolanorg>
+ *             Alex Merry <dev at randomguy3 me uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -137,7 +139,7 @@ DBUS_METHOD( CanSetFullscreen )
     REPLY_SEND;
 }
 
-static void
+static int
 MarshalFullscreen( intf_thread_t *p_intf, DBusMessageIter *container )
 {
     dbus_bool_t b_fullscreen;
@@ -149,6 +151,7 @@ MarshalFullscreen( intf_thread_t *p_intf, DBusMessageIter *container )
 
     dbus_message_iter_append_basic( container,
             DBUS_TYPE_BOOLEAN, &b_fullscreen );
+    return VLC_SUCCESS;
 }
 
 DBUS_METHOD( FullscreenGet )
@@ -478,42 +481,6 @@ DBUS_METHOD( SetProperty )
 #undef PROPERTY_GET_FUNC
 #undef PROPERTY_MAPPING_END
 
-static int
-AddProperty( intf_thread_t *p_intf,
-             DBusMessageIter *p_container,
-             const char* psz_property_name,
-             const char* psz_signature,
-             int (*pf_marshaller) (intf_thread_t*, DBusMessageIter*) )
-{
-    DBusMessageIter entry, v;
-
-    if( !dbus_message_iter_open_container( p_container,
-                                           DBUS_TYPE_DICT_ENTRY, NULL,
-                                           &entry ) )
-        return VLC_ENOMEM;
-
-    if( !dbus_message_iter_append_basic( &entry,
-                                         DBUS_TYPE_STRING,
-                                         &psz_property_name ) )
-        return VLC_ENOMEM;
-
-    if( !dbus_message_iter_open_container( &entry,
-                                           DBUS_TYPE_VARIANT, psz_signature,
-                                           &v ) )
-        return VLC_ENOMEM;
-
-    if( VLC_SUCCESS != pf_marshaller( p_intf, &v ) )
-        return VLC_ENOMEM;
-
-    if( !dbus_message_iter_close_container( &entry, &v) )
-        return VLC_ENOMEM;
-
-    if( !dbus_message_iter_close_container( p_container, &entry ) )
-        return VLC_ENOMEM;
-
-    return VLC_SUCCESS;
-}
-
 #define ADD_PROPERTY( prop, signature ) \
     if( VLC_SUCCESS != AddProperty( (intf_thread_t*) p_this, \
                 &dict, #prop, signature, Marshal##prop ) ) \
@@ -553,6 +520,7 @@ DBUS_METHOD( GetAllProperties )
     ADD_PROPERTY( HasTrackList,        "b"  );
     ADD_PROPERTY( CanQuit,             "b"  );
     ADD_PROPERTY( CanSetFullscreen,    "b"  );
+    ADD_PROPERTY( Fullscreen,          "b"  );
     ADD_PROPERTY( CanRaise,            "b"  );
 
     dbus_message_iter_close_container( &args, &dict );
diff --git a/modules/control/dbus/dbus_tracklist.c b/modules/control/dbus/dbus_tracklist.c
index 1081343..f09c721 100644
--- a/modules/control/dbus/dbus_tracklist.c
+++ b/modules/control/dbus/dbus_tracklist.c
@@ -1,6 +1,7 @@
 /*****************************************************************************
  * dbus_tracklist.c : dbus control module (mpris v2.1) - TrackList interface
  *****************************************************************************
+ * Copyright © 2013      Alex Merry
  * Copyright © 2006-2011 Rafaël Carré
  * Copyright © 2007-2011 Mirsal Ennaime
  * Copyright © 2009-2011 The VideoLAN team
@@ -8,6 +9,7 @@
  *
  * Authors:    Mirsal Ennaime <mirsal at mirsal fr>
  *             Rafaël Carré <funman at videolanorg>
+ *             Alex Merry <dev at randomguy3 me uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -286,20 +288,16 @@ DBUS_METHOD( RemoveTrack )
     REPLY_SEND;
 }
 
-DBUS_METHOD( Tracks )
-{ /* Tracks property */
-    VLC_UNUSED( p_this );
-
-    REPLY_INIT;
-    OUT_ARGUMENTS;
-
-    DBusMessageIter tracks, v;
-    char *psz_track_id = NULL;
-    playlist_t   *p_playlist   = PL;
+static int
+MarshalTracks( intf_thread_t *p_intf, DBusMessageIter *container )
+{
+    DBusMessageIter tracks;
+    char         *psz_track_id = NULL;
+    playlist_t   *p_playlist   = p_intf->p_sys->p_playlist;
     input_item_t *p_input      = NULL;
 
-    dbus_message_iter_open_container( &args, DBUS_TYPE_VARIANT, "ao", &v );
-    dbus_message_iter_open_container( &v,    DBUS_TYPE_ARRAY, "o", &tracks );
+    dbus_message_iter_open_container( container, DBUS_TYPE_ARRAY, "o",
+                                      &tracks );
 
     PL_LOCK;
 
@@ -315,8 +313,7 @@ DBUS_METHOD( Tracks )
                                              &psz_track_id ) )
         {
             PL_UNLOCK;
-            dbus_message_iter_abandon_container( &v, &tracks );
-            dbus_message_iter_abandon_container( &args, &v );
+            dbus_message_iter_abandon_container( container, &tracks );
             return DBUS_HANDLER_RESULT_NEED_MEMORY;
         }
 
@@ -325,27 +322,57 @@ DBUS_METHOD( Tracks )
 
     PL_UNLOCK;
 
-    if( !dbus_message_iter_close_container( &v, &tracks ) ||
-        !dbus_message_iter_close_container( &args, &v ) )
+    if( !dbus_message_iter_close_container( container, &tracks ) )
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+    return VLC_SUCCESS;
+}
+
+DBUS_METHOD( Tracks )
+{ /* Tracks property */
+    REPLY_INIT;
+    OUT_ARGUMENTS;
+
+    DBusMessageIter v;
+
+    dbus_message_iter_open_container( &args, DBUS_TYPE_VARIANT, "ao", &v );
+
+    if( MarshalTracks( p_this, &v ) != VLC_SUCCESS ) {
+        dbus_message_iter_abandon_container( &args, &v );
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+    }
+
+    if( !dbus_message_iter_close_container( &args, &v ) )
         return DBUS_HANDLER_RESULT_NEED_MEMORY;
 
     REPLY_SEND;
 }
 
+static int
+MarshalCanEditTracks( intf_thread_t *p_intf, DBusMessageIter *container )
+{
+    VLC_UNUSED( p_intf );
+    const dbus_bool_t b_ret = TRUE;
+
+    if( !dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN, &b_ret ) )
+    {
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+    }
+
+    return VLC_SUCCESS;
+}
+
 DBUS_METHOD( CanEditTracks )
 { /* CanEditTracks property */
-    VLC_UNUSED( p_this );
     REPLY_INIT;
     OUT_ARGUMENTS;
 
     DBusMessageIter v;
-    const dbus_bool_t b_ret = TRUE;
 
     if( !dbus_message_iter_open_container( &args, DBUS_TYPE_VARIANT, "b", &v ) )
         return DBUS_HANDLER_RESULT_NEED_MEMORY;
 
-    if( !dbus_message_iter_append_basic( &v, DBUS_TYPE_BOOLEAN, &b_ret ) )
-    {
+    if( MarshalCanEditTracks( p_this, &v ) != VLC_SUCCESS ) {
         dbus_message_iter_abandon_container( &args, &v );
         return DBUS_HANDLER_RESULT_NEED_MEMORY;
     }
@@ -401,6 +428,47 @@ DBUS_METHOD( GetProperty )
 #undef PROPERTY_GET_FUNC
 #undef PROPERTY_MAPPING_END
 
+#define ADD_PROPERTY( prop, signature ) \
+    if( VLC_SUCCESS != AddProperty( (intf_thread_t*) p_this, \
+                &dict, #prop, signature, Marshal##prop ) ) \
+        return VLC_ENOMEM;
+
+DBUS_METHOD( GetAllProperties )
+{
+    REPLY_INIT;
+    OUT_ARGUMENTS;
+
+    DBusError error;
+    DBusMessageIter dict;
+
+    char *const psz_interface_name = NULL;
+
+    dbus_error_init( &error );
+    dbus_message_get_args( p_from, &error,
+            DBUS_TYPE_STRING, &psz_interface_name,
+            DBUS_TYPE_INVALID );
+
+    if( dbus_error_is_set( &error ) )
+    {
+        msg_Err( (vlc_object_t*) p_this, "D-Bus message reading : %s",
+                                         error.message );
+        dbus_error_free( &error );
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+    }
+
+    msg_Dbg( (vlc_object_t*) p_this, "Getting All properties" );
+
+    dbus_message_iter_open_container( &args, DBUS_TYPE_ARRAY, "{sv}", &dict );
+
+    ADD_PROPERTY ( Tracks,        "ao" )
+    ADD_PROPERTY ( CanEditTracks, "b"  )
+
+    dbus_message_iter_close_container( &args, &dict );
+    REPLY_SEND;
+}
+
+#undef ADD_PROPERTY
+
 #define METHOD_FUNC( interface, method, function ) \
     else if( dbus_message_is_method_call( p_from, interface, method ) )\
         return function( p_conn, p_from, p_this )
@@ -411,6 +479,7 @@ handle_tracklist ( DBusConnection *p_conn, DBusMessage *p_from, void *p_this )
     if(0);
 
     METHOD_FUNC( DBUS_INTERFACE_PROPERTIES, "Get",    GetProperty );
+    METHOD_FUNC( DBUS_INTERFACE_PROPERTIES, "GetAll", GetAllProperties );
 
     /* here D-Bus method names are associated to an handler */
 
-- 
1.8.1.1




More information about the vlc-devel mailing list