]> git.sesse.net Git - vlc/blobdiff - src/libvlc-common.c
Attempt to fix C++ compilation
[vlc] / src / libvlc-common.c
index 01c235b44dca83fb4847df25b1a8a8ffed874400..9116c48fbd7e512a208b95e08f95c8056284c0a6 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * libvlc-common.c: libvlc instances creation and deletion
+ * libvlc-common.c: libvlc instances creation and deletion, interfaces handling
  *****************************************************************************
  * Copyright (C) 1998-2006 the VideoLAN team
  * $Id$
 #   include <locale.h>
 #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
 #   include <hal/libhal.h>
 #endif
 
 #include "libvlc.h"
 
+#include "playlist/playlist_internal.h"
+
 /*****************************************************************************
  * The evil global variable. We handle it with care, don't worry.
  *****************************************************************************/
 static libvlc_global_data_t   libvlc_global;
 static libvlc_global_data_t * p_libvlc_global;
 static libvlc_int_t *    p_static_vlc;
+static volatile unsigned int i_instances = 0;
 
 /*****************************************************************************
  * Local prototypes
@@ -144,6 +157,7 @@ libvlc_int_t * libvlc_InternalCreate( void )
     int i_ret;
     libvlc_int_t * p_libvlc = NULL;
     vlc_value_t lockval;
+    char *psz_env;
 
     /* &libvlc_global never changes,
      * so we can safely call this multiple times. */
@@ -159,32 +173,14 @@ libvlc_int_t * libvlc_InternalCreate( void )
     var_Create( p_libvlc_global, "libvlc", VLC_VAR_MUTEX );
     var_Get( p_libvlc_global, "libvlc", &lockval );
     vlc_mutex_lock( lockval.p_address );
+
+    i_instances++;
+
     if( !libvlc_global.b_ready )
     {
-        char *psz_env;
-
         /* Guess what CPU we have */
         libvlc_global.i_cpu = CPUCapabilities();
-
-        /* Find verbosity from VLC_VERBOSE environment variable */
-        psz_env = getenv( "VLC_VERBOSE" );
-        libvlc_global.i_verbose = psz_env ? atoi( psz_env ) : -1;
-
-#if defined( HAVE_ISATTY ) && !defined( WIN32 )
-        libvlc_global.b_color = isatty( 2 ); /* 2 is for stderr */
-#else
-        libvlc_global.b_color = VLC_FALSE;
-#endif
-
-        /* Initialize message queue */
-        msg_Create( p_libvlc_global );
-
-        /* Announce who we are */
-        msg_Dbg( p_libvlc_global, COPYRIGHT_MESSAGE );
-        msg_Dbg( p_libvlc_global, "libvlc was configured with %s",
-                                CONFIGURE_LINE );
-
-        /* The module bank will be initialized later */
+       /* The module bank will be initialized later */
         libvlc_global.p_module_bank = NULL;
 
         libvlc_global.b_ready = VLC_TRUE;
@@ -194,27 +190,75 @@ libvlc_int_t * libvlc_InternalCreate( void )
 
     /* Allocate a libvlc instance object */
     p_libvlc = vlc_object_create( p_libvlc_global, VLC_OBJECT_LIBVLC );
-    if( p_libvlc == NULL ) return NULL;
+    if( p_libvlc == NULL ) { i_instances--; return NULL; }
     p_libvlc->thread_id = 0;
     p_libvlc->p_playlist = NULL;
     p_libvlc->psz_object_name = "libvlc";
 
+    /* Initialize message queue */
+    msg_Create( p_libvlc );
+    /* Announce who we are - Do it only for first instance ? */
+    msg_Dbg( p_libvlc, COPYRIGHT_MESSAGE );
+    msg_Dbg( p_libvlc, "libvlc was configured with %s", CONFIGURE_LINE );
+
+    /* Find verbosity from VLC_VERBOSE environment variable */
+    psz_env = getenv( "VLC_VERBOSE" );
+    p_libvlc->i_verbose = psz_env ? atoi( psz_env ) : -1;
+
+#if defined( HAVE_ISATTY ) && !defined( WIN32 )
+    p_libvlc->b_color = isatty( 2 ); /* 2 is for stderr */
+#else
+    p_libvlc->b_color = VLC_FALSE;
+#endif
+
     /* Initialize mutexes */
     vlc_mutex_init( p_libvlc, &p_libvlc->config_lock );
 #ifdef __APPLE__
     vlc_mutex_init( p_libvlc, &p_libvlc->quicktime_lock );
     vlc_thread_set_priority( p_libvlc, VLC_THREAD_PRIORITY_LOW );
 #endif
-
-    /* Store our newly allocated structure in the global list */
-    vlc_object_attach( p_libvlc, p_libvlc_global );
-
+    /* Fake attachment */
+    p_libvlc->b_attached = VLC_TRUE;
     /* Store data for the non-reentrant API */
     p_static_vlc = 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
  * This function initializes a previously allocated libvlc instance:
@@ -289,7 +333,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 */
 
@@ -346,7 +391,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] )
     /* End hack */
 
     /* Will be re-done properly later on */
-    p_libvlc->p_libvlc_global->i_verbose = config_GetInt( p_libvlc, "verbose" );
+    p_libvlc->i_verbose = config_GetInt( p_libvlc, "verbose" );
 
     /* Check for daemon mode */
 #ifndef WIN32
@@ -569,6 +614,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
      */
@@ -582,8 +787,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] )
     var_AddCallback( p_libvlc, "verbose", VerboseCallback, NULL );
     var_Change( p_libvlc, "verbose", VLC_VAR_TRIGGER_CALLBACKS, NULL, NULL );
 
-    libvlc_global.b_color = libvlc_global.b_color && 
-                                config_GetInt( p_libvlc, "color" );
+    p_libvlc->b_color = p_libvlc->b_color && config_GetInt( p_libvlc, "color" );
 
     /*
      * Output messages that may still be in the queue
@@ -679,7 +883,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 );
 
@@ -748,7 +952,7 @@ int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc, char *ppsz_argv[] )
 #ifdef HAVE_SYSLOG_H
     if( config_GetInt( p_libvlc, "syslog" ) == 1 )
     {
-        char *psz_logmode = "logmode=syslog";
+        const char *psz_logmode = "logmode=syslog";
         libvlc_InternalAddIntf( 0, "logger,none", VLC_FALSE, VLC_FALSE,
                                 1, &psz_logmode );
     }
@@ -868,14 +1072,15 @@ int libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
  */
 int libvlc_InternalDestroy( libvlc_int_t *p_libvlc, vlc_bool_t b_release )
 {
-    /* Free allocated memory */
+    vlc_value_t lockval;
+
     if( p_libvlc->p_memcpy_module )
     {
         module_Unneed( p_libvlc, p_libvlc->p_memcpy_module );
         p_libvlc->p_memcpy_module = NULL;
     }
 
-    /* Free module bank !  */
+    /* Free module bank. It is refcounted, so we call this each time  */
     module_EndBank( p_libvlc );
 
     FREENULL( p_libvlc->psz_homedir );
@@ -883,27 +1088,34 @@ int libvlc_InternalDestroy( libvlc_int_t *p_libvlc, vlc_bool_t b_release )
     FREENULL( p_libvlc->psz_configfile );
     FREENULL( p_libvlc->p_hotkeys );
 
-    /* System specific cleaning code */
-    system_End( p_libvlc );
+    var_Create( p_libvlc_global, "libvlc", VLC_VAR_MUTEX );
+    var_Get( p_libvlc_global, "libvlc", &lockval );
+    vlc_mutex_lock( lockval.p_address );
+    i_instances--;
 
-    /*
-     * Free message queue.
-     * Nobody shall use msg_* afterward.
-     */
-    msg_Flush( p_libvlc );
-    msg_Destroy( p_libvlc_global );
+    if( i_instances == 0 )
+    {
+        /* System specific cleaning code */
+        system_End( p_libvlc );
+
+       /* Destroy global iconv */
+        LocaleDeinit();
+    }
+    vlc_mutex_unlock( lockval.p_address );
+    var_Destroy( p_libvlc_global, "libvlc" );
 
-    /* Destroy global iconv */
-    LocaleDeinit();
+    msg_Flush( p_libvlc );
+    msg_Destroy( p_libvlc );
 
     /* Destroy mutexes */
     vlc_mutex_destroy( &p_libvlc->config_lock );
 
-    vlc_object_detach( p_libvlc );
     if( b_release ) vlc_object_release( p_libvlc );
     vlc_object_destroy( p_libvlc );
 
-    /* Stop thread system: last one out please shut the door! */
+    /* Stop thread system: last one out please shut the door!
+     * The number of initializations of the thread system is counted, we 
+     * can call this each time */
     vlc_threads_end( p_libvlc_global );
 
     return VLC_SUCCESS;
@@ -915,7 +1127,7 @@ int libvlc_InternalDestroy( libvlc_int_t *p_libvlc, vlc_bool_t b_release )
 int libvlc_InternalAddIntf( libvlc_int_t *p_libvlc,
                             char const *psz_module,
                             vlc_bool_t b_block, vlc_bool_t b_play,
-                            int i_options, char **ppsz_options )
+                            int i_options, const char *const *ppsz_options )
 {
     int i_err;
     intf_thread_t *p_intf;
@@ -972,7 +1184,7 @@ static void SetLanguage ( char const *psz_lang )
 #if defined( ENABLE_NLS ) \
      && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
 
-    char *          psz_path;
+    const char *          psz_path;
 #if defined( __APPLE__ ) || defined ( WIN32 ) || defined( SYS_BEOS )
     char            psz_tmp[1024];
 #endif
@@ -1051,12 +1263,25 @@ static int GetFilenames( libvlc_int_t *p_vlc, int i_argc, char *ppsz_argv[] )
         /* TODO: write an internal function of this one, to avoid
          *       unnecessary lookups. */
         /* FIXME: should we convert options to UTF-8 as well ?? */
-        psz_target = FromLocale( ppsz_argv[ i_opt ] );
-        VLC_AddTarget( p_vlc->i_object_id, psz_target,
+
+#ifdef WIN32
+        if( GetVersion() < 0x80000000 )
+        {
+            VLC_AddTarget( p_vlc->i_object_id, ppsz_argv[i_opt],
+                       (char const **)( i_options ? &ppsz_argv[i_opt + 1] :
+                                        NULL ), i_options,
+                       PLAYLIST_INSERT, 0 );
+        }
+        else
+#endif
+        {
+            psz_target = FromLocale( ppsz_argv[ i_opt ] );
+            VLC_AddTarget( p_vlc->i_object_id, psz_target,
                        (char const **)( i_options ? &ppsz_argv[i_opt + 1] :
                                         NULL ), i_options,
                        PLAYLIST_INSERT, 0 );
-        LocaleFree( psz_target );
+            LocaleFree( psz_target );
+        }
     }
 
     return VLC_SUCCESS;
@@ -1102,22 +1327,26 @@ static void Help( libvlc_int_t *p_this, char const *psz_help_name )
 static void Usage( libvlc_int_t *p_this, char const *psz_module_name )
 {
 #define FORMAT_STRING "  %s --%s%s%s%s%s%s%s "
-    /* short option ------'    |     | | | |  | |
-     * option name ------------'     | | | |  | |
-     * <bra -------------------------' | | |  | |
-     * option type or "" --------------' | |  | |
-     * ket> -----------------------------' |  | |
-     * padding spaces ---------------------'  | |
-     * comment -------------------------------' |
-     * comment suffix --------------------------'
+    /* short option ------'    | | | | | | |
+     * option name ------------' | | | | | |
+     * <bra ---------------------' | | | | |
+     * option type or "" ----------' | | | |
+     * ket> -------------------------' | | |
+     * padding spaces -----------------' | |
+     * comment --------------------------' |
+     * comment suffix ---------------------'
      *
      * The purpose of having bra and ket is that we might i18n them as well.
      */
 #define LINE_START 8
 #define PADDING_SPACES 25
+#ifdef WIN32
+#   define OPTION_VALUE_SEP "="
+#else
+#   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)];
@@ -1142,8 +1371,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 ) )
@@ -1161,13 +1391,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 */
@@ -1178,12 +1407,12 @@ 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;
-            char *psz_bra = NULL, *psz_type = NULL, *psz_ket = NULL;
-            char *psz_suf = "", *psz_prefix = NULL;
+            const char *psz_bra = NULL, *psz_type = NULL, *psz_ket = NULL;
+            const char *psz_suf = "", *psz_prefix = NULL;
             signed int i;
 
             /* Skip deprecated options */
@@ -1212,34 +1441,38 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name )
             case CONFIG_ITEM_MODULE_CAT:
             case CONFIG_ITEM_MODULE_LIST:
             case CONFIG_ITEM_MODULE_LIST_CAT:
-                psz_bra = " <"; psz_type = _("string"); psz_ket = ">";
+                psz_bra = OPTION_VALUE_SEP "<";
+                psz_type = _("string");
+                psz_ket = ">";
 
                 if( p_item->ppsz_list )
                 {
-                    psz_bra = {";
+                    psz_bra = OPTION_VALUE_SEP "{";
                     psz_type = psz_buffer;
-                    psz_type[0] = '\0';
+                    psz_buffer[0] = '\0';
                     for( i = 0; p_item->ppsz_list[i]; i++ )
                     {
-                        if( i ) strcat( psz_type, "," );
-                        strcat( psz_type, p_item->ppsz_list[i] );
+                        if( i ) strcat( psz_buffer, "," );
+                        strcat( psz_buffer, p_item->ppsz_list[i] );
                     }
                     psz_ket = "}";
                 }
                 break;
             case CONFIG_ITEM_INTEGER:
             case CONFIG_ITEM_KEY: /* FIXME: do something a bit more clever */
-                psz_bra = " <"; psz_type = _("integer"); psz_ket = ">";
+                psz_bra = OPTION_VALUE_SEP "<";
+                psz_type = _("integer");
+                psz_ket = ">";
 
                 if( p_item->i_list )
                 {
-                    psz_bra = {";
+                    psz_bra = OPTION_VALUE_SEP "{";
                     psz_type = psz_buffer;
-                    psz_type[0] = '\0';
+                    psz_buffer[0] = '\0';
                     for( i = 0; p_item->ppsz_list_text[i]; i++ )
                     {
-                        if( i ) strcat( psz_type, ", " );
-                        sprintf( psz_type + strlen(psz_type), "%i (%s)",
+                        if( i ) strcat( psz_buffer, ", " );
+                        sprintf( psz_buffer + strlen(psz_buffer), "%i (%s)",
                                  p_item->pi_list[i],
                                  p_item->ppsz_list_text[i] );
                     }
@@ -1247,13 +1480,15 @@ static void Usage( libvlc_int_t *p_this, char const *psz_module_name )
                 }
                 break;
             case CONFIG_ITEM_FLOAT:
-                psz_bra = " <"; psz_type = _("float"); psz_ket = ">";
+                psz_bra = OPTION_VALUE_SEP "<";
+                psz_type = _("float");
+                psz_ket = ">";
                 break;
             case CONFIG_ITEM_BOOL:
                 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;
@@ -1546,11 +1781,11 @@ static int ConsoleWidth( void )
 static int VerboseCallback( vlc_object_t *p_this, const char *psz_variable,
                      vlc_value_t old_val, vlc_value_t new_val, void *param)
 {
-    libvlc_int_t *p_vlc = (libvlc_int_t *)p_this;
+    libvlc_int_t *p_libvlc = (libvlc_int_t *)p_this;
 
     if( new_val.i_int >= -1 )
     {
-        p_vlc->p_libvlc_global->i_verbose = __MIN( new_val.i_int, 2 );
+        p_libvlc->i_verbose = __MIN( new_val.i_int, 2 );
     }
     return VLC_SUCCESS;
 }
@@ -1638,6 +1873,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