X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Flibvlc-common.c;h=2ed103ee61a8259ccf4f8e0990d16a38e4abb229;hb=f7115564ce2bf24dfe480a5b7fc0cf37b0d794a2;hp=bb70edf575de5974a541a2b19e2c4a177859d5c8;hpb=da7262d76793cf824d1b6aafc472eb84b01e5612;p=vlc diff --git a/src/libvlc-common.c b/src/libvlc-common.c index bb70edf575..2ed103ee61 100644 --- a/src/libvlc-common.c +++ b/src/libvlc-common.c @@ -40,8 +40,11 @@ * Preamble *****************************************************************************/ #include -#include -#include +#include "control/libvlc_internal.h" +#include + +#include "misc/modules.h" +#include "misc/configuration.h" #include /* ENOMEM */ #include /* sprintf() */ @@ -66,28 +69,39 @@ # include #endif +#ifdef HAVE_DBUS_3 +# include + +/* 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 # include #endif -#include "vlc_cpu.h" /* CPU detection */ -#include "os_specific.h" +#include "vlc_os_specific.h" -#include "vlc_error.h" +#include +#include -#include "vlc_playlist.h" -#include "vlc_interface.h" +#include +#include "audio_output/aout_internal.h" -#include "audio_output.h" +#include -#include "vlc_video.h" -#include "video_output.h" +#include +#include "stream_output/stream_output.h" -#include "stream_output.h" -#include "charset.h" +#include #include "libvlc.h" +#include "playlist/playlist_internal.h" + /***************************************************************************** * The evil global variable. We handle it with care, don't worry. *****************************************************************************/ @@ -119,6 +133,9 @@ static int VerboseCallback( vlc_object_t *, char const *, static void InitDeviceValues( libvlc_int_t * ); +/* Refs misc/cpu.c */ +uint32_t CPUCapabilities( void ); + /***************************************************************************** * vlc_current_object: return the current object. ***************************************************************************** @@ -213,6 +230,40 @@ libvlc_int_t * libvlc_InternalCreate( void ) 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( "" ) ); + if (!p_root ) return DBUS_HANDLER_RESULT_NEED_MEMORY; + sprintf( p_root, "" ); + + 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 * This function initializes a previously allocated libvlc instance: @@ -287,7 +338,8 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] ) } p_help_module->psz_object_name = "help"; p_help_module->psz_longname = N_("Help options"); - config_Duplicate( p_help_module, p_help_config ); + config_Duplicate( p_help_module, p_help_config, + sizeof (p_help_config) / sizeof (p_help_config[0]) ); vlc_object_attach( p_help_module, libvlc_global.p_module_bank ); /* End hack */ @@ -567,6 +619,166 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *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 */ @@ -676,7 +888,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] ) if( psz_modules && *psz_modules ) { /* Add service discovery modules */ - playlist_AddSDModules( p_playlist, psz_modules ); + playlist_ServicesDiscoveryAdd( p_playlist, psz_modules ); } if( psz_modules ) free( psz_modules ); @@ -902,6 +1114,7 @@ int libvlc_InternalDestroy( libvlc_int_t *p_libvlc, vlc_bool_t b_release ) /* Destroy mutexes */ vlc_mutex_destroy( &p_libvlc->config_lock ); + vlc_mutex_destroy( &p_libvlc->timer_lock ); if( b_release ) vlc_object_release( p_libvlc ); vlc_object_destroy( p_libvlc ); @@ -1139,8 +1352,6 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name ) # define OPTION_VALUE_SEP " " #endif vlc_list_t *p_list; - module_t *p_parser; - module_config_t *p_item; char psz_spaces_text[PADDING_SPACES+LINE_START+1]; char psz_spaces_longtext[LINE_START+3]; char psz_format[sizeof(FORMAT_STRING)]; @@ -1165,8 +1376,9 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name ) for( i_index = 0; i_index < p_list->i_count; i_index++ ) { vlc_bool_t b_help_module; - - p_parser = (module_t *)p_list->p_values[i_index].p_object ; + module_t *p_parser = (module_t *)p_list->p_values[i_index].p_object; + module_config_t *p_item, + *p_end = p_parser->p_config + p_parser->confsize; if( psz_module_name && strcmp( psz_module_name, p_parser->psz_object_name ) ) @@ -1184,13 +1396,12 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name ) if( !b_advanced ) { for( p_item = p_parser->p_config; - p_item->i_type != CONFIG_HINT_END; + p_item < p_end; p_item++ ) { if( (p_item->i_type & CONFIG_ITEM) && !p_item->b_advanced ) break; } - if( p_item->i_type == CONFIG_HINT_END ) continue; } /* Print name of module */ @@ -1201,7 +1412,7 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name ) /* Print module options */ for( p_item = p_parser->p_config; - p_item->i_type != CONFIG_HINT_END; + p_item < p_end; p_item++ ) { char *psz_text, *psz_spaces = psz_spaces_text; @@ -1282,7 +1493,7 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name ) psz_bra = ""; psz_type = ""; psz_ket = ""; if( !b_help_module ) { - psz_suf = p_item->i_value ? _(" (default enabled)") : + psz_suf = p_item->value.i ? _(" (default enabled)") : _(" (default disabled)"); } break; @@ -1667,6 +1878,7 @@ static void InitDeviceValues( libvlc_int_t *p_vlc ) #ifdef HAVE_HAL_1 libhal_ctx_shutdown( ctx, NULL ); + dbus_connection_unref( p_connection ); #else hal_shutdown( ctx ); #endif