Commit 0f7dd9f9 authored by Rafaël Carré's avatar Rafaël Carré

Reenables D-Bus one instance code, without needing to modify libvlc structs

Outputs an error and continue if D-Bus control isn't enabled on the first instance
Removes unneeded NewInstance signal
Closes #505
parent b12d3db7
...@@ -49,9 +49,6 @@ ...@@ -49,9 +49,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/types.h> /* getpid() */
#include <unistd.h> /* getpid() */
#include "dbus.h" #include "dbus.h"
#include <vlc/vlc.h> #include <vlc/vlc.h>
...@@ -307,15 +304,6 @@ DBUS_METHOD( TogglePause ) ...@@ -307,15 +304,6 @@ DBUS_METHOD( TogglePause )
REPLY_SEND; REPLY_SEND;
} }
DBUS_SIGNAL( NewInstance )
{ /* emits a signal with vlc pid */
SIGNAL_INIT( "NewInstance" );
OUT_ARGUMENTS;
dbus_uint32_t i_pid = (dbus_uint32_t) getpid();
ADD_UINT32( &i_pid );
SIGNAL_SEND;
}
DBUS_METHOD( AddMRL ) DBUS_METHOD( AddMRL )
{ /* add the string to the playlist, and play it if the boolean is true */ { /* add the string to the playlist, and play it if the boolean is true */
REPLY_INIT; REPLY_INIT;
...@@ -423,17 +411,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -423,17 +411,8 @@ static int Open( vlc_object_t *p_this )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/* we request the service org.videolan.vlc */ /* we unregister the object /, registered by libvlc */
dbus_bus_request_name( p_conn, VLC_DBUS_SERVICE, dbus_connection_unregister_object_path( p_conn, "/" );
DBUS_NAME_FLAG_REPLACE_EXISTING , &error );
if (dbus_error_is_set( &error ) )
{
msg_Err( p_this, "Error requesting %s service: %s\n", VLC_DBUS_SERVICE,
error.message );
dbus_error_free( &error );
free( p_sys );
return VLC_EGENERIC;
}
/* we register the object /org/videolan/vlc */ /* we register the object /org/videolan/vlc */
dbus_connection_register_object_path( p_conn, VLC_DBUS_OBJECT_PATH, dbus_connection_register_object_path( p_conn, VLC_DBUS_OBJECT_PATH,
...@@ -479,8 +458,6 @@ static void Close ( vlc_object_t *p_this ) ...@@ -479,8 +458,6 @@ static void Close ( vlc_object_t *p_this )
static void Run ( intf_thread_t *p_intf ) static void Run ( intf_thread_t *p_intf )
{ {
NewInstance( p_intf->p_sys->p_conn, NULL );
while( !p_intf->b_die ) while( !p_intf->b_die )
{ {
msleep( INTF_IDLE_SLEEP ); msleep( INTF_IDLE_SLEEP );
......
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
/* DBUS IDENTIFIERS */ /* 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_SERVICE "org.videolan.vlc"
#define VLC_DBUS_INTERFACE "org.videolan.vlc" #define VLC_DBUS_INTERFACE "org.videolan.vlc"
#define VLC_DBUS_OBJECT_PATH "/org/videolan/vlc" #define VLC_DBUS_OBJECT_PATH "/org/videolan/vlc"
...@@ -40,10 +43,9 @@ ...@@ -40,10 +43,9 @@
#define REPLY_INIT \ #define REPLY_INIT \
DBusMessage* p_msg = dbus_message_new_method_return( p_from ); \ DBusMessage* p_msg = dbus_message_new_method_return( p_from ); \
if( !p_msg ) return DBUS_HANDLER_RESULT_NEED_MEMORY; \ if( !p_msg ) return DBUS_HANDLER_RESULT_NEED_MEMORY; \
dbus_uint32_t i_serial = 0
#define REPLY_SEND \ #define REPLY_SEND \
if( !dbus_connection_send( p_conn, p_msg, &i_serial ) ) \ if( !dbus_connection_send( p_conn, p_msg, NULL ) ) \
return DBUS_HANDLER_RESULT_NEED_MEMORY; \ return DBUS_HANDLER_RESULT_NEED_MEMORY; \
dbus_connection_flush( p_conn ); \ dbus_connection_flush( p_conn ); \
dbus_message_unref( p_msg ); \ dbus_message_unref( p_msg ); \
...@@ -53,10 +55,9 @@ ...@@ -53,10 +55,9 @@
DBusMessage *p_msg = dbus_message_new_signal( VLC_DBUS_OBJECT_PATH, \ DBusMessage *p_msg = dbus_message_new_signal( VLC_DBUS_OBJECT_PATH, \
VLC_DBUS_INTERFACE, signal ); \ VLC_DBUS_INTERFACE, signal ); \
if( !p_msg ) return DBUS_HANDLER_RESULT_NEED_MEMORY; \ if( !p_msg ) return DBUS_HANDLER_RESULT_NEED_MEMORY; \
dbus_uint32_t i_serial = 0
#define SIGNAL_SEND \ #define SIGNAL_SEND \
if( !dbus_connection_send( p_conn, p_msg, &i_serial ) ) \ if( !dbus_connection_send( p_conn, p_msg, NULL ) ) \
return DBUS_HANDLER_RESULT_NEED_MEMORY; \ return DBUS_HANDLER_RESULT_NEED_MEMORY; \
dbus_message_unref( p_msg ); \ dbus_message_unref( p_msg ); \
dbus_connection_flush( p_conn ); \ dbus_connection_flush( p_conn ); \
......
...@@ -66,6 +66,16 @@ ...@@ -66,6 +66,16 @@
# include <locale.h> # include <locale.h>
#endif #endif
#ifdef HAVE_DBUS_3
# 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 #ifdef HAVE_HAL
# include <hal/libhal.h> # include <hal/libhal.h>
#endif #endif
...@@ -215,6 +225,40 @@ libvlc_int_t * libvlc_InternalCreate( void ) ...@@ -215,6 +225,40 @@ libvlc_int_t * libvlc_InternalCreate( void )
return p_libvlc; return p_libvlc;
} }
/*
* D-Bus callback needed in libvlc_InternalInit()
*/
#ifdef HAVE_DBUS_3
/* Handling of messages received on / object */
static DBusHandlerResult handle_root
( DBusConnection *p_conn, DBusMessage *p_from, void *p_data )
{
DBusMessage* p_msg = dbus_message_new_method_return( p_from );
if( !p_msg ) return DBUS_HANDLER_RESULT_NEED_MEMORY;
DBusMessageIter args;
dbus_message_iter_init_append( p_msg, &args );
char *p_root = malloc( strlen( "<node name='/'></node>" ) );
if (!p_root ) return DBUS_HANDLER_RESULT_NEED_MEMORY;
sprintf( p_root, "<node name='/'></node>" );
if( !dbus_message_iter_append_basic( &args, DBUS_TYPE_STRING, &p_root ) )
return DBUS_HANDLER_RESULT_NEED_MEMORY;
if( !dbus_connection_send( p_conn, p_msg, NULL ) )
return DBUS_HANDLER_RESULT_NEED_MEMORY;
dbus_connection_flush( p_conn );
dbus_message_unref( p_msg );
return DBUS_HANDLER_RESULT_HANDLED;
}
/* vtable passed to dbus_connection_register_object_path() */
static DBusObjectPathVTable vlc_dbus_root_vtable = {
NULL, handle_root, NULL, NULL, NULL, NULL
};
#endif
/** /**
* Initialize a libvlc instance * Initialize a libvlc instance
* This function initializes a previously allocated libvlc instance: * This function initializes a previously allocated libvlc instance:
...@@ -569,6 +613,166 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] ) ...@@ -569,6 +613,166 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] )
*/ */
system_Configure( p_libvlc, &i_argc, ppsz_argv ); system_Configure( p_libvlc, &i_argc, ppsz_argv );
/* FIXME: could be replaced by using Unix sockets */
#ifdef HAVE_DBUS_3
/* Initialise D-Bus interface, check for other instances */
DBusConnection *p_conn;
DBusError dbus_error;
int i_dbus_service;
dbus_threads_init_default();
dbus_error_init( &dbus_error );
/* connect to the session bus */
p_conn = dbus_bus_get( DBUS_BUS_SESSION, &dbus_error );
if( !p_conn )
{
msg_Err( p_libvlc, "Failed to connect to the D-Bus session daemon: %s",
dbus_error.message );
dbus_error_free( &dbus_error );
}
else
{
/* we request the service org.videolan.vlc */
i_dbus_service = dbus_bus_request_name( p_conn, VLC_DBUS_SERVICE, 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 );
dbus_error_free( &dbus_error );
}
else
{
if( i_dbus_service != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER )
{ /* the name is already registered by another instance of vlc */
if( config_GetInt( p_libvlc, "one-instance" ) )
{
/* check if /org/videolan/vlc exists
* 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 */
p_test_reply = dbus_connection_send_with_reply_and_block(
p_conn, p_test_msg, -1, &dbus_error );
dbus_message_unref( p_test_msg );
if( p_test_reply == NULL )
{
dbus_error_free( &dbus_error );
msg_Err( p_libvlc, "one instance mode has been "
"set but D-Bus control interface is not "
"enabled. Enable it and restart vlc, or "
"disable one instance mode." );
}
else
{
dbus_message_unref( p_test_reply );
msg_Warn( p_libvlc,
"Another vlc instance exists: will now exit");
int i_input;
DBusMessage* p_dbus_msg;
DBusMessageIter dbus_args;
DBusPendingCall* p_dbus_pending;
dbus_bool_t b_play;
for( i_input = optind;i_input < i_argc;i_input++ )
{
msg_Dbg( p_libvlc, "Give %s to other vlc\n",
ppsz_argv[i_input] );
p_dbus_msg = dbus_message_new_method_call(
VLC_DBUS_SERVICE, VLC_DBUS_OBJECT_PATH,
VLC_DBUS_INTERFACE, "AddMRL" );
if ( NULL == p_dbus_msg )
{
msg_Err( p_libvlc, "D-Bus problem" );
system_End( p_libvlc );
exit( 0 );
}
/* append MRLs */
dbus_message_iter_init_append( p_dbus_msg,
&dbus_args );
if ( !dbus_message_iter_append_basic( &dbus_args,
DBUS_TYPE_STRING,
&ppsz_argv[i_input] ) )
{
msg_Err( p_libvlc, "Out of memory" );
dbus_message_unref( p_dbus_msg );
system_End( p_libvlc );
exit( 0 );
}
b_play = TRUE;
if( config_GetInt( p_libvlc, "playlist-enqueue" ) )
b_play = FALSE;
if ( !dbus_message_iter_append_basic( &dbus_args,
DBUS_TYPE_BOOLEAN, &b_play ) )
{
msg_Err( p_libvlc, "Out of memory" );
dbus_message_unref( p_dbus_msg );
system_End( p_libvlc );
exit( 0 );
}
/* send message and get a handle for a reply */
if ( !dbus_connection_send_with_reply ( p_conn,
p_dbus_msg, &p_dbus_pending, -1 ) )
{
msg_Err( p_libvlc, "D-Bus problem" );
dbus_message_unref( p_dbus_msg );
system_End( p_libvlc );
exit( 0 );
}
if ( NULL == p_dbus_pending )
{
msg_Err( p_libvlc, "D-Bus problem" );
dbus_message_unref( p_dbus_msg );
system_End( p_libvlc );
exit( 0 );
}
dbus_connection_flush( p_conn );
dbus_message_unref( p_dbus_msg );
/* block until we receive a reply */
dbus_pending_call_block( p_dbus_pending );
dbus_pending_call_unref( p_dbus_pending );
} /* processes all command line MRLs */
/* bye bye */
system_End( p_libvlc );
exit( 0 );
}
} /* we're not in one-instance mode */
else
{
msg_Dbg( p_libvlc,
"%s is already registered on the session bus\n",
VLC_DBUS_SERVICE );
}
} /* the named is owned by something else */
else
{
/* register "/" object */
if( !dbus_connection_register_object_path( p_conn, "/",
&vlc_dbus_root_vtable, NULL ) )
{
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 );
}
} /* no error when requesting the name on the bus */
/* we unreference the connection when we've finished with it */
dbus_connection_unref( p_conn );
} /* ( p_conn != NULL ) */
#endif
/* /*
* Message queue options * Message queue options
*/ */
......
...@@ -1622,8 +1622,7 @@ vlc_module_begin(); ...@@ -1622,8 +1622,7 @@ vlc_module_begin();
change_need_restart(); change_need_restart();
#endif #endif
#if defined(HAVE_DBUS_3)
#if 0 //defined(HAVE_DBUS_3)
add_bool( "one-instance", 0, NULL, ONEINSTANCE_DBUS_TEXT, add_bool( "one-instance", 0, NULL, ONEINSTANCE_DBUS_TEXT,
ONEINSTANCE_DBUS_LONGTEXT, VLC_TRUE ); ONEINSTANCE_DBUS_LONGTEXT, VLC_TRUE );
add_bool( "playlist-enqueue", 0, NULL, PLAYLISTENQUEUE_TEXT, add_bool( "playlist-enqueue", 0, NULL, PLAYLISTENQUEUE_TEXT,
......
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