dbus: Implement fullscreen switching (MPRIS 2.2)
authorKevin Anthony <kevin.s.anthony@gmail.com>
Fri, 24 Feb 2012 19:19:28 +0000 (14:19 -0500)
committerMirsal Ennaime <mirsal@videolan.org>
Wed, 29 Feb 2012 19:54:36 +0000 (20:54 +0100)
 * Add the Fullscreen and CanSetFullscreen properties
   to the root interface implementation

 * Implement org.freedesktop.DBus.Properties.PropertiesChanged
   for properties of the root interface

Signed-off-by: Mirsal Ennaime <mirsal@videolan.org>
modules/control/dbus/dbus.c
modules/control/dbus/dbus_common.h
modules/control/dbus/dbus_introspect.h
modules/control/dbus/dbus_root.c
modules/control/dbus/dbus_root.h

index 96d720b..c450b11 100644 (file)
@@ -232,6 +232,7 @@ static int Open( vlc_object_t *p_this )
     var_AddCallback( p_playlist, "random", AllCallback, p_intf );
     var_AddCallback( p_playlist, "repeat", AllCallback, p_intf );
     var_AddCallback( p_playlist, "loop", AllCallback, p_intf );
+    var_AddCallback( p_playlist, "fullscreen", AllCallback, p_intf );
 
     dbus_connection_set_dispatch_status_function( p_conn,
                                                   dispatch_status_cb,
@@ -285,6 +286,7 @@ static void Close   ( vlc_object_t *p_this )
     var_DelCallback( p_playlist, "random", AllCallback, p_intf );
     var_DelCallback( p_playlist, "repeat", AllCallback, p_intf );
     var_DelCallback( p_playlist, "loop", AllCallback, p_intf );
+    var_DelCallback( p_playlist, "fullscreen", AllCallback, p_intf );
 
     if( p_sys->p_input )
     {
@@ -531,9 +533,10 @@ static void ProcessEvents( intf_thread_t *p_intf,
     playlist_t *p_playlist = p_intf->p_sys->p_playlist;
     bool        b_can_play = p_intf->p_sys->b_can_play;
 
-    vlc_dictionary_t player_properties, tracklist_properties;
+    vlc_dictionary_t player_properties, tracklist_properties, root_properties;
     vlc_dictionary_init( &player_properties,    0 );
     vlc_dictionary_init( &tracklist_properties, 0 );
+    vlc_dictionary_init( &root_properties,      0 );
 
     for( int i = 0; i < i_events; i++ )
     {
@@ -566,6 +569,9 @@ static void ProcessEvents( intf_thread_t *p_intf,
         case SIGNAL_RANDOM:
             vlc_dictionary_insert( &player_properties, "Shuffle", NULL );
             break;
+        case SIGNAL_FULLSCREEN:
+            vlc_dictionary_insert( &root_properties, "Fullscreen", NULL );
+            break;
         case SIGNAL_REPEAT:
         case SIGNAL_LOOP:
             vlc_dictionary_insert( &player_properties, "LoopStatus", NULL );
@@ -624,8 +630,12 @@ static void ProcessEvents( intf_thread_t *p_intf,
     if( vlc_dictionary_keys_count( &tracklist_properties ) )
         TrackListPropertiesChangedEmit( p_intf, &tracklist_properties );
 
+    if( vlc_dictionary_keys_count( &root_properties ) )
+        RootPropertiesChangedEmit( p_intf, &root_properties );
+
     vlc_dictionary_clear( &player_properties,    NULL, NULL );
     vlc_dictionary_clear( &tracklist_properties, NULL, NULL );
+    vlc_dictionary_clear( &root_properties,      NULL, NULL );
 }
 
 /**
@@ -1050,6 +1060,9 @@ static int AllCallback( vlc_object_t *p_this, const char *psz_var,
     else if( !strcmp( "random", psz_var ) )
         info->signal = SIGNAL_RANDOM;
 
+    else if( !strcmp( "fullscreen", psz_var ) )
+        info->signal = SIGNAL_FULLSCREEN;
+
     else if( !strcmp( "repeat", psz_var ) )
         info->signal = SIGNAL_REPEAT;
 
index c977138..30d6e2c 100644 (file)
@@ -121,7 +121,8 @@ enum
     SIGNAL_CAN_SEEK,
     SIGNAL_CAN_PAUSE,
     SIGNAL_VOLUME_CHANGE,
-    SIGNAL_VOLUME_MUTED
+    SIGNAL_VOLUME_MUTED,
+    SIGNAL_FULLSCREEN
 };
 
 enum
index 5056c9b..cc53e45 100644 (file)
@@ -63,6 +63,8 @@ static const char* psz_introspection_xml =
 "    <property name=\"SupportedUriSchemes\" type=\"as\" access=\"read\" />\n"
 "    <property name=\"HasTrackList\" type=\"b\" access=\"read\" />\n"
 "    <property name=\"CanQuit\" type=\"b\" access=\"read\" />\n"
+"    <property name=\"CanSetFullscreen\" type=\"b\" access=\"read\" />\n"
+"    <property name=\"Fullscreen\" type=\"b\" access=\"readwrite\" />\n"
 "    <property name=\"CanRaise\" type=\"b\" access=\"read\" />\n"
 "    <method name=\"Quit\" />\n"
 "    <method name=\"Raise\" />\n"
index 5de8af6..27d7685 100644 (file)
 
 #include <vlc_common.h>
 #include <vlc_interface.h>
+#include <vlc_input.h>
+#include <vlc_vout.h>
+#include <vlc_plugin.h>
+#include <vlc_playlist.h>
 
 #include <unistd.h>
 #include <limits.h>
@@ -94,6 +98,87 @@ DBUS_METHOD( Identity )
     REPLY_SEND;
 }
 
+static int
+MarshalCanSetFullscreen( intf_thread_t *p_intf, DBusMessageIter *container )
+{
+    const dbus_bool_t b_ret = (p_intf->p_sys->p_playlist) ? TRUE : FALSE;
+
+    dbus_message_iter_append_basic( container, DBUS_TYPE_BOOLEAN, &b_ret );
+    return VLC_SUCCESS;
+}
+
+DBUS_METHOD( CanSetFullscreen )
+{
+    REPLY_INIT;
+    OUT_ARGUMENTS;
+
+    DBusMessageIter v;
+    dbus_message_iter_open_container( &args, DBUS_TYPE_VARIANT, "b", &v );
+
+    MarshalCanSetFullscreen( p_this, &v );
+
+    if( !dbus_message_iter_close_container( &args, &v ) )
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+    REPLY_SEND;
+}
+
+static void
+MarshalFullscreen( intf_thread_t *p_intf, DBusMessageIter *container )
+{
+    dbus_bool_t b_fullscreen;
+
+    if ( p_intf->p_sys->p_playlist )
+        b_fullscreen = var_GetBool( p_intf->p_sys->p_playlist , "fullscreen" );
+    else
+        b_fullscreen = FALSE;
+
+    dbus_message_iter_append_basic( container,
+            DBUS_TYPE_BOOLEAN, &b_fullscreen );
+}
+
+DBUS_METHOD( FullscreenGet )
+{
+    REPLY_INIT;
+    OUT_ARGUMENTS;
+
+    DBusMessageIter v;
+
+    if( !dbus_message_iter_open_container( &args, DBUS_TYPE_VARIANT, "b", &v ) )
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+    MarshalFullscreen( p_this, &v );
+
+    if( !dbus_message_iter_close_container( &args, &v ) )
+        return DBUS_HANDLER_RESULT_NEED_MEMORY;
+
+    REPLY_SEND;
+}
+
+DBUS_METHOD( FullscreenSet )
+{
+    REPLY_INIT;
+    dbus_bool_t b_fullscreen;
+    input_thread_t *p_input = NULL;
+
+    if( VLC_SUCCESS != DemarshalSetPropertyValue( p_from, &b_fullscreen ) )
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+
+    if (INTF->p_sys->p_input)
+    {
+        p_input = (input_thread_t*) vlc_object_hold( INTF->p_sys->p_input );
+        vout_thread_t* p_vout = input_GetVout( p_input );
+        vlc_object_release( p_input );
+
+        if ( p_vout )
+            var_SetBool( p_vout, "fullscreen", ( b_fullscreen == TRUE ) );
+        if ( PL )
+            var_SetBool( PL , "fullscreen", ( b_fullscreen == TRUE ) );
+    }
+
+    REPLY_SEND;
+}
+
 static int
 MarshalCanQuit( intf_thread_t *p_intf, DBusMessageIter *container )
 {
@@ -343,10 +428,38 @@ DBUS_METHOD( GetProperty )
     PROPERTY_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "SupportedUriSchemes", SupportedUriSchemes )
     PROPERTY_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "HasTrackList",        HasTrackList )
     PROPERTY_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "CanQuit",             CanQuit )
+    PROPERTY_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "CanSetFullscreen",    CanSetFullscreen )
+    PROPERTY_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "Fullscreen",          FullscreenGet )
     PROPERTY_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "CanRaise",            CanRaise )
     PROPERTY_MAPPING_END
 }
 
+DBUS_METHOD( SetProperty )
+{
+    DBusError error;
+
+    char *psz_interface_name = NULL;
+    char *psz_property_name  = NULL;
+
+    dbus_error_init( &error );
+    dbus_message_get_args( p_from, &error,
+            DBUS_TYPE_STRING, &psz_interface_name,
+            DBUS_TYPE_STRING, &psz_property_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;
+    }
+
+    PROPERTY_MAPPING_BEGIN
+    PROPERTY_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "Fullscreen",    FullscreenSet )
+    PROPERTY_MAPPING_END
+}
+
 #undef PROPERTY_MAPPING_BEGIN
 #undef PROPERTY_GET_FUNC
 #undef PROPERTY_MAPPING_END
@@ -425,6 +538,7 @@ DBUS_METHOD( GetAllProperties )
     ADD_PROPERTY( SupportedUriSchemes, "as" );
     ADD_PROPERTY( HasTrackList,        "b"  );
     ADD_PROPERTY( CanQuit,             "b"  );
+    ADD_PROPERTY( CanSetFullscreen,    "b"  );
     ADD_PROPERTY( CanRaise,            "b"  );
 
     dbus_message_iter_close_container( &args, &dict );
@@ -444,6 +558,7 @@ handle_root ( DBusConnection *p_conn, DBusMessage *p_from, void *p_this )
 {
     METHOD_MAPPING_BEGIN
     METHOD_FUNC( DBUS_INTERFACE_PROPERTIES, "Get",          GetProperty );
+    METHOD_FUNC( DBUS_INTERFACE_PROPERTIES, "Set",          SetProperty );
     METHOD_FUNC( DBUS_INTERFACE_PROPERTIES, "GetAll",       GetAllProperties );
     METHOD_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "Quit",         Quit );
     METHOD_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "Raise",        Raise );
@@ -453,3 +568,75 @@ handle_root ( DBusConnection *p_conn, DBusMessage *p_from, void *p_this )
 #undef METHOD_MAPPING_BEGIN
 #undef METHOD_FUNC
 #undef METHOD_MAPPING_END
+/**
+ * PropertiesChangedSignal() synthetizes and sends the
+ * org.freedesktop.DBus.Properties.PropertiesChanged signal
+ */
+
+static DBusHandlerResult
+PropertiesChangedSignal( intf_thread_t    *p_intf,
+                         vlc_dictionary_t *p_changed_properties )
+{
+    DBusConnection  *p_conn = p_intf->p_sys->p_conn;
+    DBusMessageIter changed_properties, invalidated_properties, entry, variant;
+    const char *psz_interface_name = DBUS_MPRIS_ROOT_INTERFACE;
+    char **ppsz_properties = NULL;
+    int i_properties = 0;
+
+    SIGNAL_INIT( DBUS_INTERFACE_PROPERTIES,
+                 DBUS_MPRIS_OBJECT_PATH,
+                 "PropertiesChanged" );
+
+    OUT_ARGUMENTS;
+    ADD_STRING( &psz_interface_name );
+    dbus_message_iter_open_container( &args, DBUS_TYPE_ARRAY, "{sv}",
+                                      &changed_properties );
+
+    i_properties = vlc_dictionary_keys_count( p_changed_properties );
+    ppsz_properties = vlc_dictionary_all_keys( p_changed_properties );
+
+    for( int i = 0; i < i_properties; i++ )
+    {
+        dbus_message_iter_open_container( &changed_properties,
+                                          DBUS_TYPE_DICT_ENTRY, NULL,
+                                          &entry );
+
+        dbus_message_iter_append_basic( &entry, DBUS_TYPE_STRING,
+                                        &ppsz_properties[i] );
+
+        if( !strcmp( ppsz_properties[i], "Fullscreen" ) )
+        {
+            dbus_message_iter_open_container( &entry,
+                                              DBUS_TYPE_VARIANT, "b",
+                                              &variant );
+            MarshalFullscreen( p_intf, &variant );
+            dbus_message_iter_close_container( &entry, &variant );
+        }
+
+        dbus_message_iter_close_container( &changed_properties, &entry );
+        free( ppsz_properties[i] );
+    }
+
+    dbus_message_iter_close_container( &args, &changed_properties );
+
+    dbus_message_iter_open_container( &args, DBUS_TYPE_ARRAY, "s",
+                                      &invalidated_properties );
+
+    dbus_message_iter_close_container( &args, &invalidated_properties );
+    free( ppsz_properties );
+
+    SIGNAL_SEND;
+}
+
+/*****************************************************************************
+ * RootPropertiesChangedEmit: Emits the Seeked signal
+ *****************************************************************************/
+int RootPropertiesChangedEmit( intf_thread_t    *p_intf,
+                               vlc_dictionary_t *p_changed_properties )
+{
+    if( p_intf->p_sys->b_dead )
+        return VLC_SUCCESS;
+
+    PropertiesChangedSignal( p_intf, p_changed_properties );
+    return VLC_SUCCESS;
+}
index 38267ee..87f0e90 100644 (file)
@@ -36,5 +36,7 @@
 DBusHandlerResult handle_root ( DBusConnection *p_conn,
                                 DBusMessage *p_from,
                                 void *p_this );
+int RootPropertiesChangedEmit ( intf_thread_t *,
+                                vlc_dictionary_t * );
 
 #endif //dbus-root.h