Commit 245b9e9e authored by Kevin Anthony's avatar Kevin Anthony Committed by Mirsal Ennaime

dbus: Implement fullscreen switching (MPRIS 2.2)

 * 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: default avatarMirsal Ennaime <mirsal@videolan.org>
parent c5ba028a
...@@ -232,6 +232,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -232,6 +232,7 @@ static int Open( vlc_object_t *p_this )
var_AddCallback( p_playlist, "random", AllCallback, p_intf ); var_AddCallback( p_playlist, "random", AllCallback, p_intf );
var_AddCallback( p_playlist, "repeat", AllCallback, p_intf ); var_AddCallback( p_playlist, "repeat", AllCallback, p_intf );
var_AddCallback( p_playlist, "loop", 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, dbus_connection_set_dispatch_status_function( p_conn,
dispatch_status_cb, dispatch_status_cb,
...@@ -285,6 +286,7 @@ static void Close ( vlc_object_t *p_this ) ...@@ -285,6 +286,7 @@ static void Close ( vlc_object_t *p_this )
var_DelCallback( p_playlist, "random", AllCallback, p_intf ); var_DelCallback( p_playlist, "random", AllCallback, p_intf );
var_DelCallback( p_playlist, "repeat", AllCallback, p_intf ); var_DelCallback( p_playlist, "repeat", AllCallback, p_intf );
var_DelCallback( p_playlist, "loop", AllCallback, p_intf ); var_DelCallback( p_playlist, "loop", AllCallback, p_intf );
var_DelCallback( p_playlist, "fullscreen", AllCallback, p_intf );
if( p_sys->p_input ) if( p_sys->p_input )
{ {
...@@ -531,9 +533,10 @@ static void ProcessEvents( intf_thread_t *p_intf, ...@@ -531,9 +533,10 @@ static void ProcessEvents( intf_thread_t *p_intf,
playlist_t *p_playlist = p_intf->p_sys->p_playlist; playlist_t *p_playlist = p_intf->p_sys->p_playlist;
bool b_can_play = p_intf->p_sys->b_can_play; 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( &player_properties, 0 );
vlc_dictionary_init( &tracklist_properties, 0 ); vlc_dictionary_init( &tracklist_properties, 0 );
vlc_dictionary_init( &root_properties, 0 );
for( int i = 0; i < i_events; i++ ) for( int i = 0; i < i_events; i++ )
{ {
...@@ -566,6 +569,9 @@ static void ProcessEvents( intf_thread_t *p_intf, ...@@ -566,6 +569,9 @@ static void ProcessEvents( intf_thread_t *p_intf,
case SIGNAL_RANDOM: case SIGNAL_RANDOM:
vlc_dictionary_insert( &player_properties, "Shuffle", NULL ); vlc_dictionary_insert( &player_properties, "Shuffle", NULL );
break; break;
case SIGNAL_FULLSCREEN:
vlc_dictionary_insert( &root_properties, "Fullscreen", NULL );
break;
case SIGNAL_REPEAT: case SIGNAL_REPEAT:
case SIGNAL_LOOP: case SIGNAL_LOOP:
vlc_dictionary_insert( &player_properties, "LoopStatus", NULL ); vlc_dictionary_insert( &player_properties, "LoopStatus", NULL );
...@@ -624,8 +630,12 @@ static void ProcessEvents( intf_thread_t *p_intf, ...@@ -624,8 +630,12 @@ static void ProcessEvents( intf_thread_t *p_intf,
if( vlc_dictionary_keys_count( &tracklist_properties ) ) if( vlc_dictionary_keys_count( &tracklist_properties ) )
TrackListPropertiesChangedEmit( p_intf, &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( &player_properties, NULL, NULL );
vlc_dictionary_clear( &tracklist_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, ...@@ -1050,6 +1060,9 @@ static int AllCallback( vlc_object_t *p_this, const char *psz_var,
else if( !strcmp( "random", psz_var ) ) else if( !strcmp( "random", psz_var ) )
info->signal = SIGNAL_RANDOM; info->signal = SIGNAL_RANDOM;
else if( !strcmp( "fullscreen", psz_var ) )
info->signal = SIGNAL_FULLSCREEN;
else if( !strcmp( "repeat", psz_var ) ) else if( !strcmp( "repeat", psz_var ) )
info->signal = SIGNAL_REPEAT; info->signal = SIGNAL_REPEAT;
......
...@@ -121,7 +121,8 @@ enum ...@@ -121,7 +121,8 @@ enum
SIGNAL_CAN_SEEK, SIGNAL_CAN_SEEK,
SIGNAL_CAN_PAUSE, SIGNAL_CAN_PAUSE,
SIGNAL_VOLUME_CHANGE, SIGNAL_VOLUME_CHANGE,
SIGNAL_VOLUME_MUTED SIGNAL_VOLUME_MUTED,
SIGNAL_FULLSCREEN
}; };
enum enum
......
...@@ -63,6 +63,8 @@ static const char* psz_introspection_xml = ...@@ -63,6 +63,8 @@ static const char* psz_introspection_xml =
" <property name=\"SupportedUriSchemes\" type=\"as\" access=\"read\" />\n" " <property name=\"SupportedUriSchemes\" type=\"as\" access=\"read\" />\n"
" <property name=\"HasTrackList\" type=\"b\" access=\"read\" />\n" " <property name=\"HasTrackList\" type=\"b\" access=\"read\" />\n"
" <property name=\"CanQuit\" 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" " <property name=\"CanRaise\" type=\"b\" access=\"read\" />\n"
" <method name=\"Quit\" />\n" " <method name=\"Quit\" />\n"
" <method name=\"Raise\" />\n" " <method name=\"Raise\" />\n"
......
...@@ -30,6 +30,10 @@ ...@@ -30,6 +30,10 @@
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_interface.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 <unistd.h>
#include <limits.h> #include <limits.h>
...@@ -94,6 +98,87 @@ DBUS_METHOD( Identity ) ...@@ -94,6 +98,87 @@ DBUS_METHOD( Identity )
REPLY_SEND; 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 static int
MarshalCanQuit( intf_thread_t *p_intf, DBusMessageIter *container ) MarshalCanQuit( intf_thread_t *p_intf, DBusMessageIter *container )
{ {
...@@ -343,10 +428,38 @@ DBUS_METHOD( GetProperty ) ...@@ -343,10 +428,38 @@ DBUS_METHOD( GetProperty )
PROPERTY_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "SupportedUriSchemes", SupportedUriSchemes ) PROPERTY_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "SupportedUriSchemes", SupportedUriSchemes )
PROPERTY_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "HasTrackList", HasTrackList ) PROPERTY_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "HasTrackList", HasTrackList )
PROPERTY_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "CanQuit", CanQuit ) 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_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "CanRaise", CanRaise )
PROPERTY_MAPPING_END 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_MAPPING_BEGIN
#undef PROPERTY_GET_FUNC #undef PROPERTY_GET_FUNC
#undef PROPERTY_MAPPING_END #undef PROPERTY_MAPPING_END
...@@ -425,6 +538,7 @@ DBUS_METHOD( GetAllProperties ) ...@@ -425,6 +538,7 @@ DBUS_METHOD( GetAllProperties )
ADD_PROPERTY( SupportedUriSchemes, "as" ); ADD_PROPERTY( SupportedUriSchemes, "as" );
ADD_PROPERTY( HasTrackList, "b" ); ADD_PROPERTY( HasTrackList, "b" );
ADD_PROPERTY( CanQuit, "b" ); ADD_PROPERTY( CanQuit, "b" );
ADD_PROPERTY( CanSetFullscreen, "b" );
ADD_PROPERTY( CanRaise, "b" ); ADD_PROPERTY( CanRaise, "b" );
dbus_message_iter_close_container( &args, &dict ); dbus_message_iter_close_container( &args, &dict );
...@@ -444,6 +558,7 @@ handle_root ( DBusConnection *p_conn, DBusMessage *p_from, void *p_this ) ...@@ -444,6 +558,7 @@ handle_root ( DBusConnection *p_conn, DBusMessage *p_from, void *p_this )
{ {
METHOD_MAPPING_BEGIN METHOD_MAPPING_BEGIN
METHOD_FUNC( DBUS_INTERFACE_PROPERTIES, "Get", GetProperty ); 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 );
METHOD_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "Quit", Quit ); METHOD_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "Quit", Quit );
METHOD_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "Raise", Raise ); METHOD_FUNC( DBUS_MPRIS_ROOT_INTERFACE, "Raise", Raise );
...@@ -453,3 +568,75 @@ handle_root ( DBusConnection *p_conn, DBusMessage *p_from, void *p_this ) ...@@ -453,3 +568,75 @@ handle_root ( DBusConnection *p_conn, DBusMessage *p_from, void *p_this )
#undef METHOD_MAPPING_BEGIN #undef METHOD_MAPPING_BEGIN
#undef METHOD_FUNC #undef METHOD_FUNC
#undef METHOD_MAPPING_END #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;
}
...@@ -36,5 +36,7 @@ ...@@ -36,5 +36,7 @@
DBusHandlerResult handle_root ( DBusConnection *p_conn, DBusHandlerResult handle_root ( DBusConnection *p_conn,
DBusMessage *p_from, DBusMessage *p_from,
void *p_this ); void *p_this );
int RootPropertiesChangedEmit ( intf_thread_t *,
vlc_dictionary_t * );
#endif //dbus-root.h #endif //dbus-root.h
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment