]> git.sesse.net Git - vlc/blob - src/libvlc.c
Initialize language from vlcrc before any language-dependent stuff
[vlc] / src / libvlc.c
1 /*****************************************************************************
2  * libvlc.c: libvlc instances creation and deletion, interfaces handling
3  *****************************************************************************
4  * Copyright (C) 1998-2008 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Vincent Seguin <seguin@via.ecp.fr>
8  *          Samuel Hocevar <sam@zoy.org>
9  *          Gildas Bazin <gbazin@videolan.org>
10  *          Derk-Jan Hartman <hartman at videolan dot org>
11  *          RĂ©mi Denis-Courmont <rem # videolan : org>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26  *****************************************************************************/
27
28 /** \file
29  * This file contains functions to create and destroy libvlc instances
30  */
31
32 /*****************************************************************************
33  * Preamble
34  *****************************************************************************/
35 #ifdef HAVE_CONFIG_H
36 # include "config.h"
37 #endif
38
39 #include <vlc_common.h>
40 #include "control/libvlc_internal.h"
41 #include <vlc_input.h>
42
43 #include "modules/modules.h"
44 #include "config/configuration.h"
45
46 #include <stdio.h>                                              /* sprintf() */
47 #include <string.h>
48 #include <stdlib.h>                                                /* free() */
49
50 #ifndef WIN32
51 #   include <netinet/in.h>                            /* BSD: struct in_addr */
52 #endif
53
54 #ifdef HAVE_UNISTD_H
55 #   include <unistd.h>
56 #elif defined( WIN32 ) && !defined( UNDER_CE )
57 #   include <io.h>
58 #endif
59
60 #include "config/vlc_getopt.h"
61
62 #ifdef HAVE_LOCALE_H
63 #   include <locale.h>
64 #endif
65
66 #ifdef HAVE_DBUS
67 /* used for one-instance mode */
68 #   include <dbus/dbus.h>
69 #endif
70
71
72 #include <vlc_media_library.h>
73 #include <vlc_playlist.h>
74 #include <vlc_interface.h>
75
76 #include <vlc_aout.h>
77 #include "audio_output/aout_internal.h"
78
79 #include <vlc_charset.h>
80 #include <vlc_fs.h>
81 #include <vlc_cpu.h>
82 #include <vlc_url.h>
83 #include <vlc_atomic.h>
84 #include <vlc_modules.h>
85
86 #include "libvlc.h"
87
88 #include "playlist/playlist_internal.h"
89
90 #include <vlc_vlm.h>
91
92 #ifdef __APPLE__
93 # include <libkern/OSAtomic.h>
94 #endif
95
96 #include <assert.h>
97
98 /*****************************************************************************
99  * The evil global variables. We handle them with care, don't worry.
100  *****************************************************************************/
101
102 #ifndef WIN32
103 static bool b_daemon = false;
104 #endif
105
106 #undef vlc_gc_init
107 #undef vlc_hold
108 #undef vlc_release
109
110 /**
111  * Atomically set the reference count to 1.
112  * @param p_gc reference counted object
113  * @param pf_destruct destruction calback
114  * @return p_gc.
115  */
116 void *vlc_gc_init (gc_object_t *p_gc, void (*pf_destruct) (gc_object_t *))
117 {
118     /* There is no point in using the GC if there is no destructor... */
119     assert (pf_destruct);
120     p_gc->pf_destructor = pf_destruct;
121
122     vlc_atomic_set (&p_gc->refs, 1);
123     return p_gc;
124 }
125
126 /**
127  * Atomically increment the reference count.
128  * @param p_gc reference counted object
129  * @return p_gc.
130  */
131 void *vlc_hold (gc_object_t * p_gc)
132 {
133     uintptr_t refs;
134
135     assert( p_gc );
136     refs = vlc_atomic_inc (&p_gc->refs);
137     assert (refs != 1); /* there had to be a reference already */
138     return p_gc;
139 }
140
141 /**
142  * Atomically decrement the reference count and, if it reaches zero, destroy.
143  * @param p_gc reference counted object.
144  */
145 void vlc_release (gc_object_t *p_gc)
146 {
147     uintptr_t refs;
148
149     assert( p_gc );
150     refs = vlc_atomic_dec (&p_gc->refs);
151     assert (refs != (uintptr_t)(-1)); /* reference underflow?! */
152     if (refs == 0)
153         p_gc->pf_destructor (p_gc);
154 }
155
156 /*****************************************************************************
157  * Local prototypes
158  *****************************************************************************/
159 #if defined( ENABLE_NLS ) && (defined (__APPLE__) || defined (WIN32)) && \
160     ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
161 static void SetLanguage   ( char const * );
162 #endif
163 static void GetFilenames  ( libvlc_int_t *, unsigned, const char *const [] );
164 static void Help          ( libvlc_int_t *, char const *psz_help_name );
165 static void Usage         ( libvlc_int_t *, char const *psz_search );
166 static void ListModules   ( libvlc_int_t *, bool );
167 static void Version       ( void );
168
169 #ifdef WIN32
170 static void ShowConsole   ( bool );
171 static void PauseConsole  ( void );
172 #endif
173 static int  ConsoleWidth  ( void );
174
175 extern const char psz_vlc_changeset[];
176
177 /**
178  * Allocate a libvlc instance, initialize global data if needed
179  * It also initializes the threading system
180  */
181 libvlc_int_t * libvlc_InternalCreate( void )
182 {
183     libvlc_int_t *p_libvlc;
184     libvlc_priv_t *priv;
185     char *psz_env = NULL;
186
187     /* Now that the thread system is initialized, we don't have much, but
188      * at least we have variables */
189     /* Allocate a libvlc instance object */
190     p_libvlc = vlc_custom_create( (vlc_object_t *)NULL, sizeof (*priv),
191                                   "libvlc" );
192     if( p_libvlc == NULL )
193         return NULL;
194
195     priv = libvlc_priv (p_libvlc);
196     priv->p_playlist = NULL;
197     priv->p_ml = NULL;
198     priv->p_dialog_provider = NULL;
199     priv->p_vlm = NULL;
200
201     /* Find verbosity from VLC_VERBOSE environment variable */
202     psz_env = getenv( "VLC_VERBOSE" );
203     if( psz_env != NULL )
204         priv->i_verbose = atoi( psz_env );
205     else
206         priv->i_verbose = 3;
207 #if defined( HAVE_ISATTY ) && !defined( WIN32 )
208     priv->b_color = isatty( 2 ); /* 2 is for stderr */
209 #else
210     priv->b_color = false;
211 #endif
212
213     /* Initialize mutexes */
214     vlc_mutex_init( &priv->ml_lock );
215     vlc_mutex_init( &priv->timer_lock );
216     vlc_ExitInit( &priv->exit );
217
218     return p_libvlc;
219 }
220
221 /**
222  * Initialize a libvlc instance
223  * This function initializes a previously allocated libvlc instance:
224  *  - CPU detection
225  *  - gettext initialization
226  *  - message queue, module bank and playlist initialization
227  *  - configuration and commandline parsing
228  */
229 int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
230                          const char *ppsz_argv[] )
231 {
232     libvlc_priv_t *priv = libvlc_priv (p_libvlc);
233     char *       p_tmp = NULL;
234     char *       psz_modules = NULL;
235     char *       psz_parser = NULL;
236     char *       psz_control = NULL;
237     bool   b_exit = false;
238     int          i_ret = VLC_EEXIT;
239     playlist_t  *p_playlist = NULL;
240     char        *psz_val;
241
242     /* System specific initialization code */
243     system_Init();
244
245     /* Initialize the module bank and load the configuration of the
246      * main module. We need to do this at this stage to be able to display
247      * a short help if required by the user. (short help == main module
248      * options) */
249     module_InitBank ();
250
251     /* Get command line options that affect module loading. */
252     if( config_LoadCmdLine( p_libvlc, i_argc, ppsz_argv, NULL ) )
253     {
254         module_EndBank (false);
255         return VLC_EGENERIC;
256     }
257     priv->i_verbose = var_InheritInteger( p_libvlc, "verbose" );
258
259     /* Announce who we are (TODO: only first instance?) */
260     msg_Dbg( p_libvlc, "VLC media player - %s", VERSION_MESSAGE );
261     msg_Dbg( p_libvlc, "%s", COPYRIGHT_MESSAGE );
262     msg_Dbg( p_libvlc, "revision %s", psz_vlc_changeset );
263     msg_Dbg( p_libvlc, "configured with %s", CONFIGURE_LINE );
264
265     /* Load the builtins and plugins into the module_bank.
266      * We have to do it before config_Load*() because this also gets the
267      * list of configuration options exported by each module and loads their
268      * default values. */
269     size_t module_count = module_LoadPlugins (p_libvlc);
270
271     /*
272      * Override default configuration with config file settings
273      */
274     if( !var_InheritBool( p_libvlc, "ignore-config" ) )
275     {
276         if( var_InheritBool( p_libvlc, "reset-config" ) )
277             config_SaveConfigFile( p_libvlc ); /* Save default config */
278         else
279             config_LoadConfigFile( p_libvlc );
280     }
281
282     /*
283      * Override configuration with command line settings
284      */
285     int vlc_optind;
286     if( config_LoadCmdLine( p_libvlc, i_argc, ppsz_argv, &vlc_optind ) )
287     {
288 #ifdef WIN32
289         ShowConsole( false );
290         /* Pause the console because it's destroyed when we exit */
291         fprintf( stderr, "The command line options couldn't be loaded, check "
292                  "that they are valid.\n" );
293         PauseConsole();
294 #endif
295         module_EndBank (true);
296         return VLC_EGENERIC;
297     }
298     priv->i_verbose = var_InheritInteger( p_libvlc, "verbose" );
299
300     /*
301      * Support for gettext
302      */
303 #if defined( ENABLE_NLS ) \
304      && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
305 # if defined (WIN32) || defined (__APPLE__)
306     /* Check if the user specified a custom language */
307     char *lang = var_InheritString (p_libvlc, "language");
308     if (lang != NULL && strcmp (lang, "auto"))
309         SetLanguage (lang);
310     free (lang);
311 # endif
312     vlc_bindtextdomain (PACKAGE_NAME);
313 #endif
314     /*xgettext: Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
315     msg_Dbg( p_libvlc, "translation test: code is \"%s\"", _("C") );
316
317     /* Check for short help option */
318     if( var_InheritBool( p_libvlc, "help" ) )
319     {
320         Help( p_libvlc, "help" );
321         b_exit = true;
322         i_ret = VLC_EEXITSUCCESS;
323     }
324     /* Check for version option */
325     else if( var_InheritBool( p_libvlc, "version" ) )
326     {
327         Version();
328         b_exit = true;
329         i_ret = VLC_EEXITSUCCESS;
330     }
331
332     /* Check for daemon mode */
333 #if !defined( WIN32 ) && !defined( __SYMBIAN32__ )
334     if( var_InheritBool( p_libvlc, "daemon" ) )
335     {
336 #ifdef HAVE_DAEMON
337         char *psz_pidfile = NULL;
338
339         if( daemon( 1, 0) != 0 )
340         {
341             msg_Err( p_libvlc, "Unable to fork vlc to daemon mode" );
342             b_exit = true;
343         }
344         b_daemon = true;
345
346         /* lets check if we need to write the pidfile */
347         psz_pidfile = var_CreateGetNonEmptyString( p_libvlc, "pidfile" );
348         if( psz_pidfile != NULL )
349         {
350             FILE *pidfile;
351             pid_t i_pid = getpid ();
352             msg_Dbg( p_libvlc, "PID is %d, writing it to %s",
353                                i_pid, psz_pidfile );
354             pidfile = vlc_fopen( psz_pidfile,"w" );
355             if( pidfile != NULL )
356             {
357                 utf8_fprintf( pidfile, "%d", (int)i_pid );
358                 fclose( pidfile );
359             }
360             else
361             {
362                 msg_Err( p_libvlc, "cannot open pid file for writing: %s (%m)",
363                          psz_pidfile );
364             }
365         }
366         free( psz_pidfile );
367
368 #else
369         pid_t i_pid;
370
371         if( ( i_pid = fork() ) < 0 )
372         {
373             msg_Err( p_libvlc, "unable to fork vlc to daemon mode" );
374             b_exit = true;
375         }
376         else if( i_pid )
377         {
378             /* This is the parent, exit right now */
379             msg_Dbg( p_libvlc, "closing parent process" );
380             b_exit = true;
381             i_ret = VLC_EEXITSUCCESS;
382         }
383         else
384         {
385             /* We are the child */
386             msg_Dbg( p_libvlc, "daemon spawned" );
387             close( STDIN_FILENO );
388             close( STDOUT_FILENO );
389             close( STDERR_FILENO );
390
391             b_daemon = true;
392         }
393 #endif
394     }
395 #endif
396
397     if( b_exit )
398     {
399         module_EndBank (true);
400         return i_ret;
401     }
402
403     /* Check for help on modules */
404     if( (p_tmp = var_InheritString( p_libvlc, "module" )) )
405     {
406         Help( p_libvlc, p_tmp );
407         free( p_tmp );
408         b_exit = true;
409         i_ret = VLC_EEXITSUCCESS;
410     }
411     /* Check for full help option */
412     else if( var_InheritBool( p_libvlc, "full-help" ) )
413     {
414         var_Create( p_libvlc, "advanced", VLC_VAR_BOOL );
415         var_SetBool( p_libvlc, "advanced", true );
416         var_Create( p_libvlc, "help-verbose", VLC_VAR_BOOL );
417         var_SetBool( p_libvlc, "help-verbose", true );
418         Help( p_libvlc, "full-help" );
419         b_exit = true;
420         i_ret = VLC_EEXITSUCCESS;
421     }
422     /* Check for long help option */
423     else if( var_InheritBool( p_libvlc, "longhelp" ) )
424     {
425         Help( p_libvlc, "longhelp" );
426         b_exit = true;
427         i_ret = VLC_EEXITSUCCESS;
428     }
429     /* Check for module list option */
430     else if( var_InheritBool( p_libvlc, "list" ) )
431     {
432         ListModules( p_libvlc, false );
433         b_exit = true;
434         i_ret = VLC_EEXITSUCCESS;
435     }
436     else if( var_InheritBool( p_libvlc, "list-verbose" ) )
437     {
438         ListModules( p_libvlc, true );
439         b_exit = true;
440         i_ret = VLC_EEXITSUCCESS;
441     }
442
443     if( module_count <= 1 )
444     {
445         msg_Err( p_libvlc, "No plugins found! Check your VLC installation.");
446         b_exit = true;
447         i_ret = VLC_ENOITEM;
448     }
449
450     if( b_exit )
451     {
452         module_EndBank (true);
453         return i_ret;
454     }
455
456 /* FIXME: could be replaced by using Unix sockets */
457 #ifdef HAVE_DBUS
458     dbus_threads_init_default();
459
460     if( var_InheritBool( p_libvlc, "one-instance" )
461     || ( var_InheritBool( p_libvlc, "one-instance-when-started-from-file" )
462       && var_InheritBool( p_libvlc, "started-from-file" ) ) )
463     {
464         /* Initialise D-Bus interface, check for other instances */
465         DBusConnection  *p_conn = NULL;
466         DBusError       dbus_error;
467
468         dbus_error_init( &dbus_error );
469
470         /* connect to the session bus */
471         p_conn = dbus_bus_get( DBUS_BUS_SESSION, &dbus_error );
472         if( !p_conn )
473         {
474             msg_Err( p_libvlc, "Failed to connect to D-Bus session daemon: %s",
475                     dbus_error.message );
476             dbus_error_free( &dbus_error );
477         }
478         else
479         {
480             /* check if VLC is available on the bus
481              * if not: D-Bus control is not enabled on the other
482              * instance and we can't pass MRLs to it */
483             DBusMessage *p_test_msg   = NULL;
484             DBusMessage *p_test_reply = NULL;
485
486             p_test_msg =  dbus_message_new_method_call(
487                     "org.mpris.MediaPlayer2.vlc", "/org/mpris/MediaPlayer2",
488                     "org.freedesktop.DBus.Introspectable", "Introspect" );
489
490             /* block until a reply arrives */
491             p_test_reply = dbus_connection_send_with_reply_and_block(
492                     p_conn, p_test_msg, -1, &dbus_error );
493             dbus_message_unref( p_test_msg );
494             if( p_test_reply == NULL )
495             {
496                 dbus_error_free( &dbus_error );
497                 msg_Dbg( p_libvlc, "No Media Player is running. "
498                         "Continuing normally." );
499             }
500             else
501             {
502                 int i_input;
503                 DBusMessage* p_dbus_msg = NULL;
504                 DBusMessageIter dbus_args;
505                 DBusPendingCall* p_dbus_pending = NULL;
506                 dbus_bool_t b_play;
507
508                 dbus_message_unref( p_test_reply );
509                 msg_Warn( p_libvlc, "Another Media Player is running. Exiting");
510
511                 for( i_input = vlc_optind; i_input < i_argc;i_input++ )
512                 {
513                     /* Skip input options, we can't pass them through D-Bus */
514                     if( ppsz_argv[i_input][0] == ':' )
515                     {
516                         msg_Warn( p_libvlc, "Ignoring option %s",
517                                   ppsz_argv[i_input] );
518                         continue;
519                     }
520
521                     /* We need to resolve relative paths in this instance */
522                     char *psz_mrl = make_URI( ppsz_argv[i_input], NULL );
523                     const char *psz_after_track = "/";
524
525                     if( psz_mrl == NULL )
526                         continue;
527                     msg_Dbg( p_libvlc, "Adds %s to the running Media Player",
528                              psz_mrl );
529
530                     p_dbus_msg = dbus_message_new_method_call(
531                         "org.mpris.MediaPlayer2.vlc", "/org/mpris/MediaPlayer2",
532                         "org.mpris.MediaPlayer2.TrackList", "AddTrack" );
533
534                     if ( NULL == p_dbus_msg )
535                     {
536                         msg_Err( p_libvlc, "D-Bus problem" );
537                         free( psz_mrl );
538                         system_End( );
539                         exit( 1 );
540                     }
541
542                     /* append MRLs */
543                     dbus_message_iter_init_append( p_dbus_msg, &dbus_args );
544                     if ( !dbus_message_iter_append_basic( &dbus_args,
545                                 DBUS_TYPE_STRING, &psz_mrl ) )
546                     {
547                         dbus_message_unref( p_dbus_msg );
548                         free( psz_mrl );
549                         system_End( );
550                         exit( 1 );
551                     }
552                     free( psz_mrl );
553
554                     if( !dbus_message_iter_append_basic( &dbus_args,
555                                 DBUS_TYPE_OBJECT_PATH, &psz_after_track ) )
556                     {
557                         dbus_message_unref( p_dbus_msg );
558                         system_End( );
559                         exit( 1 );
560                     }
561
562                     b_play = TRUE;
563                     if( var_InheritBool( p_libvlc, "playlist-enqueue" ) )
564                         b_play = FALSE;
565
566                     if ( !dbus_message_iter_append_basic( &dbus_args,
567                                 DBUS_TYPE_BOOLEAN, &b_play ) )
568                     {
569                         dbus_message_unref( p_dbus_msg );
570                         system_End( );
571                         exit( 1 );
572                     }
573
574                     /* send message and get a handle for a reply */
575                     if ( !dbus_connection_send_with_reply ( p_conn,
576                                 p_dbus_msg, &p_dbus_pending, -1 ) )
577                     {
578                         msg_Err( p_libvlc, "D-Bus problem" );
579                         dbus_message_unref( p_dbus_msg );
580                         system_End( );
581                         exit( 1 );
582                     }
583
584                     if ( NULL == p_dbus_pending )
585                     {
586                         msg_Err( p_libvlc, "D-Bus problem" );
587                         dbus_message_unref( p_dbus_msg );
588                         system_End( );
589                         exit( 1 );
590                     }
591                     dbus_connection_flush( p_conn );
592                     dbus_message_unref( p_dbus_msg );
593                     /* block until we receive a reply */
594                     dbus_pending_call_block( p_dbus_pending );
595                     dbus_pending_call_unref( p_dbus_pending );
596                 } /* processes all command line MRLs */
597
598                 /* bye bye */
599                 system_End( );
600                 exit( 0 );
601             }
602         }
603         /* we unreference the connection when we've finished with it */
604         if( p_conn ) dbus_connection_unref( p_conn );
605     }
606 #endif
607
608     /*
609      * Message queue options
610      */
611     /* Last chance to set the verbosity. Once we start interfaces and other
612      * threads, verbosity becomes read-only. */
613     var_Create( p_libvlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
614     if( var_InheritBool( p_libvlc, "quiet" ) )
615     {
616         var_SetInteger( p_libvlc, "verbose", -1 );
617         priv->i_verbose = -1;
618     }
619     vlc_threads_setup( p_libvlc );
620
621     if( priv->b_color )
622         priv->b_color = var_InheritBool( p_libvlc, "color" );
623
624     vlc_CPU_dump( VLC_OBJECT(p_libvlc) );
625     /*
626      * Choose the best memcpy module
627      */
628     priv->p_memcpy_module = module_need( p_libvlc, "memcpy", "$memcpy", false );
629     /* Avoid being called "memcpy":*/
630     vlc_object_set_name( p_libvlc, "main" );
631
632     priv->b_stats = var_InheritBool( p_libvlc, "stats" );
633     priv->i_timers = 0;
634     priv->pp_timers = NULL;
635
636     /*
637      * Initialize hotkey handling
638      */
639     priv->actions = vlc_InitActions( p_libvlc );
640
641     /* Create a variable for showing the fullscreen interface */
642     var_Create( p_libvlc, "intf-show", VLC_VAR_BOOL );
643     var_SetBool( p_libvlc, "intf-show", true );
644
645     /* Create a variable for showing the right click menu */
646     var_Create( p_libvlc, "intf-popupmenu", VLC_VAR_BOOL );
647
648     /* variables for signalling creation of new files */
649     var_Create( p_libvlc, "snapshot-file", VLC_VAR_STRING );
650     var_Create( p_libvlc, "record-file", VLC_VAR_STRING );
651
652     /* some default internal settings */
653     var_Create( p_libvlc, "window", VLC_VAR_STRING );
654     var_Create( p_libvlc, "user-agent", VLC_VAR_STRING );
655     var_SetString( p_libvlc, "user-agent", "(LibVLC "VERSION")" );
656
657     /* Initialize playlist and get commandline files */
658     p_playlist = playlist_Create( VLC_OBJECT(p_libvlc) );
659     if( !p_playlist )
660     {
661         msg_Err( p_libvlc, "playlist initialization failed" );
662         if( priv->p_memcpy_module != NULL )
663         {
664             module_unneed( p_libvlc, priv->p_memcpy_module );
665         }
666         module_EndBank (true);
667         return VLC_EGENERIC;
668     }
669
670     /* System specific configuration */
671     system_Configure( p_libvlc, i_argc - vlc_optind, ppsz_argv + vlc_optind );
672
673 #if defined(MEDIA_LIBRARY)
674     /* Get the ML */
675     if( var_GetBool( p_libvlc, "load-media-library-on-startup" ) )
676     {
677         priv->p_ml = ml_Create( VLC_OBJECT( p_libvlc ), NULL );
678         if( !priv->p_ml )
679         {
680             msg_Err( p_libvlc, "ML initialization failed" );
681             return VLC_EGENERIC;
682         }
683     }
684     else
685     {
686         priv->p_ml = NULL;
687     }
688 #endif
689
690     /* Add service discovery modules */
691     psz_modules = var_InheritString( p_libvlc, "services-discovery" );
692     if( psz_modules )
693     {
694         char *p = psz_modules, *m;
695         while( ( m = strsep( &p, " :," ) ) != NULL )
696             playlist_ServicesDiscoveryAdd( p_playlist, m );
697         free( psz_modules );
698     }
699
700 #ifdef ENABLE_VLM
701     /* Initialize VLM if vlm-conf is specified */
702     psz_parser = var_CreateGetNonEmptyString( p_libvlc, "vlm-conf" );
703     if( psz_parser )
704     {
705         priv->p_vlm = vlm_New( p_libvlc );
706         if( !priv->p_vlm )
707             msg_Err( p_libvlc, "VLM initialization failed" );
708     }
709     free( psz_parser );
710 #endif
711
712     /*
713      * Load background interfaces
714      */
715     psz_modules = var_CreateGetNonEmptyString( p_libvlc, "extraintf" );
716     psz_control = var_CreateGetNonEmptyString( p_libvlc, "control" );
717
718     if( psz_modules && psz_control )
719     {
720         char* psz_tmp;
721         if( asprintf( &psz_tmp, "%s:%s", psz_modules, psz_control ) != -1 )
722         {
723             free( psz_modules );
724             psz_modules = psz_tmp;
725         }
726     }
727     else if( psz_control )
728     {
729         free( psz_modules );
730         psz_modules = strdup( psz_control );
731     }
732
733     psz_parser = psz_modules;
734     while ( psz_parser && *psz_parser )
735     {
736         char *psz_module, *psz_temp;
737         psz_module = psz_parser;
738         psz_parser = strchr( psz_module, ':' );
739         if ( psz_parser )
740         {
741             *psz_parser = '\0';
742             psz_parser++;
743         }
744         if( asprintf( &psz_temp, "%s,none", psz_module ) != -1)
745         {
746             intf_Create( p_libvlc, psz_temp );
747             free( psz_temp );
748         }
749     }
750     free( psz_modules );
751     free( psz_control );
752
753     /*
754      * Always load the hotkeys interface if it exists
755      */
756     intf_Create( p_libvlc, "hotkeys,none" );
757
758 #ifdef HAVE_DBUS
759     /* loads dbus control interface if in one-instance mode
760      * we do it only when playlist exists, because dbus module needs it */
761     if( var_InheritBool( p_libvlc, "one-instance" )
762      || ( var_InheritBool( p_libvlc, "one-instance-when-started-from-file" )
763        && var_InheritBool( p_libvlc, "started-from-file" ) ) )
764         intf_Create( p_libvlc, "dbus,none" );
765
766 # if !defined (HAVE_MAEMO)
767     /* Prevents the power management daemon from suspending the system
768      * when VLC is active */
769     if( var_InheritBool( p_libvlc, "inhibit" ) > 0 )
770         intf_Create( p_libvlc, "inhibit,none" );
771 # endif
772 #endif
773
774     if( var_InheritBool( p_libvlc, "file-logging" ) &&
775         !var_InheritBool( p_libvlc, "syslog" ) )
776     {
777         intf_Create( p_libvlc, "logger,none" );
778     }
779 #ifdef HAVE_SYSLOG_H
780     if( var_InheritBool( p_libvlc, "syslog" ) )
781     {
782         char *logmode = var_CreateGetNonEmptyString( p_libvlc, "logmode" );
783         var_SetString( p_libvlc, "logmode", "syslog" );
784         intf_Create( p_libvlc, "logger,none" );
785
786         if( logmode )
787         {
788             var_SetString( p_libvlc, "logmode", logmode );
789             free( logmode );
790         }
791         var_Destroy( p_libvlc, "logmode" );
792     }
793 #endif
794
795     if( var_InheritBool( p_libvlc, "network-synchronisation") )
796     {
797         intf_Create( p_libvlc, "netsync,none" );
798     }
799
800 #ifdef __APPLE__
801     var_Create( p_libvlc, "drawable-view-top", VLC_VAR_INTEGER );
802     var_Create( p_libvlc, "drawable-view-left", VLC_VAR_INTEGER );
803     var_Create( p_libvlc, "drawable-view-bottom", VLC_VAR_INTEGER );
804     var_Create( p_libvlc, "drawable-view-right", VLC_VAR_INTEGER );
805     var_Create( p_libvlc, "drawable-clip-top", VLC_VAR_INTEGER );
806     var_Create( p_libvlc, "drawable-clip-left", VLC_VAR_INTEGER );
807     var_Create( p_libvlc, "drawable-clip-bottom", VLC_VAR_INTEGER );
808     var_Create( p_libvlc, "drawable-clip-right", VLC_VAR_INTEGER );
809     var_Create( p_libvlc, "drawable-nsobject", VLC_VAR_ADDRESS );
810 #endif
811 #ifdef WIN32
812     var_Create( p_libvlc, "drawable-hwnd", VLC_VAR_INTEGER );
813 #endif
814
815     /*
816      * Get input filenames given as commandline arguments.
817      * We assume that the remaining parameters are filenames
818      * and their input options.
819      */
820     GetFilenames( p_libvlc, i_argc - vlc_optind, ppsz_argv + vlc_optind );
821
822     /*
823      * Get --open argument
824      */
825     psz_val = var_InheritString( p_libvlc, "open" );
826     if ( psz_val != NULL )
827     {
828         playlist_AddExt( p_playlist, psz_val, NULL, PLAYLIST_INSERT, 0,
829                          -1, 0, NULL, 0, true, pl_Unlocked );
830         free( psz_val );
831     }
832
833     return VLC_SUCCESS;
834 }
835
836 /**
837  * Cleanup a libvlc instance. The instance is not completely deallocated
838  * \param p_libvlc the instance to clean
839  */
840 void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
841 {
842     libvlc_priv_t *priv = libvlc_priv (p_libvlc);
843     playlist_t    *p_playlist = libvlc_priv (p_libvlc)->p_playlist;
844
845     /* Deactivate the playlist */
846     msg_Dbg( p_libvlc, "deactivating the playlist" );
847     pl_Deactivate( p_libvlc );
848
849     /* Remove all services discovery */
850     msg_Dbg( p_libvlc, "removing all services discovery tasks" );
851     playlist_ServicesDiscoveryKillAll( p_playlist );
852
853     /* Ask the interfaces to stop and destroy them */
854     msg_Dbg( p_libvlc, "removing all interfaces" );
855     libvlc_Quit( p_libvlc );
856     intf_DestroyAll( p_libvlc );
857
858 #ifdef ENABLE_VLM
859     /* Destroy VLM if created in libvlc_InternalInit */
860     if( priv->p_vlm )
861     {
862         vlm_Delete( priv->p_vlm );
863     }
864 #endif
865
866 #if defined(MEDIA_LIBRARY)
867     media_library_t* p_ml = priv->p_ml;
868     if( p_ml )
869     {
870         ml_Destroy( VLC_OBJECT( p_ml ) );
871         vlc_object_release( p_ml );
872         libvlc_priv(p_playlist->p_libvlc)->p_ml = NULL;
873     }
874 #endif
875
876     /* Free playlist now, all threads are gone */
877     playlist_Destroy( p_playlist );
878     stats_TimersDumpAll( p_libvlc );
879     stats_TimersCleanAll( p_libvlc );
880
881     msg_Dbg( p_libvlc, "removing stats" );
882
883 #ifndef WIN32
884     char* psz_pidfile = NULL;
885
886     if( b_daemon )
887     {
888         psz_pidfile = var_CreateGetNonEmptyString( p_libvlc, "pidfile" );
889         if( psz_pidfile != NULL )
890         {
891             msg_Dbg( p_libvlc, "removing pid file %s", psz_pidfile );
892             if( unlink( psz_pidfile ) == -1 )
893             {
894                 msg_Dbg( p_libvlc, "removing pid file %s: %m",
895                         psz_pidfile );
896             }
897         }
898         free( psz_pidfile );
899     }
900 #endif
901
902     if( priv->p_memcpy_module )
903     {
904         module_unneed( p_libvlc, priv->p_memcpy_module );
905         priv->p_memcpy_module = NULL;
906     }
907
908     /* Save the configuration */
909     if( !var_InheritBool( p_libvlc, "ignore-config" ) )
910         config_AutoSaveConfigFile( VLC_OBJECT(p_libvlc) );
911
912     /* Free module bank. It is refcounted, so we call this each time  */
913     module_EndBank (true);
914
915     vlc_DeinitActions( p_libvlc, priv->actions );
916 }
917
918 /**
919  * Destroy everything.
920  * This function requests the running threads to finish, waits for their
921  * termination, and destroys their structure.
922  * It stops the thread systems: no instance can run after this has run
923  * \param p_libvlc the instance to destroy
924  */
925 void libvlc_InternalDestroy( libvlc_int_t *p_libvlc )
926 {
927     libvlc_priv_t *priv = libvlc_priv( p_libvlc );
928
929     system_End( );
930
931     /* Destroy mutexes */
932     vlc_ExitDestroy( &priv->exit );
933     vlc_mutex_destroy( &priv->timer_lock );
934     vlc_mutex_destroy( &priv->ml_lock );
935
936 #ifndef NDEBUG /* Hack to dump leaked objects tree */
937     if( vlc_internals( p_libvlc )->i_refcount > 1 )
938         while( vlc_internals( p_libvlc )->i_refcount > 0 )
939             vlc_object_release( p_libvlc );
940 #endif
941
942     assert( vlc_internals( p_libvlc )->i_refcount == 1 );
943     vlc_object_release( p_libvlc );
944 }
945
946 /**
947  * Add an interface plugin and run it
948  */
949 int libvlc_InternalAddIntf( libvlc_int_t *p_libvlc, char const *psz_module )
950 {
951     if( !p_libvlc )
952         return VLC_EGENERIC;
953
954     if( !psz_module ) /* requesting the default interface */
955     {
956         char *psz_interface = var_CreateGetNonEmptyString( p_libvlc, "intf" );
957         if( !psz_interface ) /* "intf" has not been set */
958         {
959 #ifndef WIN32
960             if( b_daemon )
961                  /* Daemon mode hack.
962                   * We prefer the dummy interface if none is specified. */
963                 psz_module = "dummy";
964             else
965 #endif
966                 msg_Info( p_libvlc, "%s",
967                           _("Running vlc with the default interface. "
968                             "Use 'cvlc' to use vlc without interface.") );
969         }
970         free( psz_interface );
971         var_Destroy( p_libvlc, "intf" );
972     }
973
974     /* Try to create the interface */
975     int ret = intf_Create( p_libvlc, psz_module ? psz_module : "$intf" );
976     if( ret )
977         msg_Err( p_libvlc, "interface \"%s\" initialization failed",
978                  psz_module ? psz_module : "default" );
979     return ret;
980 }
981
982 #if defined( ENABLE_NLS ) && (defined (__APPLE__) || defined (WIN32)) && \
983     ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
984 /*****************************************************************************
985  * SetLanguage: set the interface language.
986  *****************************************************************************
987  * We set the LC_MESSAGES locale category for interface messages and buttons,
988  * as well as the LC_CTYPE category for string sorting and possible wide
989  * character support.
990  *****************************************************************************/
991 static void SetLanguage ( const char *psz_lang )
992 {
993 #ifdef __APPLE__
994     /* I need that under Darwin, please check it doesn't disturb
995      * other platforms. --Meuuh */
996     setenv( "LANG", psz_lang, 1 );
997
998 #else
999     /* We set LC_ALL manually because it is the only way to set
1000      * the language at runtime under eg. Windows. Beware that this
1001      * makes the environment unconsistent when libvlc is unloaded and
1002      * should probably be moved to a safer place like vlc.c. */
1003     setenv( "LC_ALL", psz_lang, 1 );
1004
1005 #endif
1006
1007     setlocale( LC_ALL, psz_lang );
1008 }
1009 #endif
1010
1011 /*****************************************************************************
1012  * GetFilenames: parse command line options which are not flags
1013  *****************************************************************************
1014  * Parse command line for input files as well as their associated options.
1015  * An option always follows its associated input and begins with a ":".
1016  *****************************************************************************/
1017 static void GetFilenames( libvlc_int_t *p_vlc, unsigned n,
1018                           const char *const args[] )
1019 {
1020     while( n > 0 )
1021     {
1022         /* Count the input options */
1023         unsigned i_options = 0;
1024
1025         while( args[--n][0] == ':' )
1026         {
1027             i_options++;
1028             if( n == 0 )
1029             {
1030                 msg_Warn( p_vlc, "options %s without item", args[n] );
1031                 return; /* syntax!? */
1032             }
1033         }
1034
1035         char *mrl = make_URI( args[n], NULL );
1036         if( !mrl )
1037             continue;
1038
1039         playlist_AddExt( pl_Get( p_vlc ), mrl, NULL, PLAYLIST_INSERT,
1040                 0, -1, i_options, ( i_options ? &args[n + 1] : NULL ),
1041                 VLC_INPUT_OPTION_TRUSTED, true, pl_Unlocked );
1042         free( mrl );
1043     }
1044 }
1045
1046 /*****************************************************************************
1047  * Help: print program help
1048  *****************************************************************************
1049  * Print a short inline help. Message interface is initialized at this stage.
1050  *****************************************************************************/
1051 static inline void print_help_on_full_help( void )
1052 {
1053     utf8_fprintf( stdout, "\n" );
1054     utf8_fprintf( stdout, "%s\n", _("To get exhaustive help, use '-H'.") );
1055 }
1056
1057 static const char vlc_usage[] = N_(
1058                             "Usage: %s [options] [stream] ..."
1059                             "\nYou can specify multiple streams on the commandline. They will be enqueued in the playlist."
1060                             "\nThe first item specified will be played first."
1061                             "\n"
1062                             "\nOptions-styles:"
1063                             "\n  --option  A global option that is set for the duration of the program."
1064                             "\n   -option  A single letter version of a global --option."
1065                             "\n   :option  An option that only applies to the stream directly before it"
1066                             "\n            and that overrides previous settings."
1067                             "\n"
1068                             "\nStream MRL syntax:"
1069                             "\n  [[access][/demux]://]URL[@[title][:chapter][-[title][:chapter]]] [:option=value ...]"
1070                             "\n"
1071                             "\n  Many of the global --options can also be used as MRL specific :options."
1072                             "\n  Multiple :option=value pairs can be specified."
1073                             "\n"
1074                             "\nURL syntax:"
1075                             "\n  [file://]filename              Plain media file"
1076                             "\n  http://ip:port/file            HTTP URL"
1077                             "\n  ftp://ip:port/file             FTP URL"
1078                             "\n  mms://ip:port/file             MMS URL"
1079                             "\n  screen://                      Screen capture"
1080                             "\n  [dvd://][device][@raw_device]  DVD device"
1081                             "\n  [vcd://][device]               VCD device"
1082                             "\n  [cdda://][device]              Audio CD device"
1083                             "\n  udp://[[<source address>]@[<bind address>][:<bind port>]]"
1084                             "\n                                 UDP stream sent by a streaming server"
1085                             "\n  vlc://pause:<seconds>          Special item to pause the playlist for a certain time"
1086                             "\n  vlc://quit                     Special item to quit VLC"
1087                             "\n");
1088
1089 static void Help( libvlc_int_t *p_this, char const *psz_help_name )
1090 {
1091 #ifdef WIN32
1092     ShowConsole( true );
1093 #endif
1094
1095     if( psz_help_name && !strcmp( psz_help_name, "help" ) )
1096     {
1097         utf8_fprintf( stdout, vlc_usage, "vlc" );
1098         Usage( p_this, "=help" );
1099         Usage( p_this, "=main" );
1100         print_help_on_full_help();
1101     }
1102     else if( psz_help_name && !strcmp( psz_help_name, "longhelp" ) )
1103     {
1104         utf8_fprintf( stdout, vlc_usage, "vlc" );
1105         Usage( p_this, NULL );
1106         print_help_on_full_help();
1107     }
1108     else if( psz_help_name && !strcmp( psz_help_name, "full-help" ) )
1109     {
1110         utf8_fprintf( stdout, vlc_usage, "vlc" );
1111         Usage( p_this, NULL );
1112     }
1113     else if( psz_help_name )
1114     {
1115         Usage( p_this, psz_help_name );
1116     }
1117
1118 #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
1119     PauseConsole();
1120 #endif
1121     fflush( stdout );
1122 }
1123
1124 /*****************************************************************************
1125  * Usage: print module usage
1126  *****************************************************************************
1127  * Print a short inline help. Message interface is initialized at this stage.
1128  *****************************************************************************/
1129 #   define COL(x)  "\033[" #x ";1m"
1130 #   define RED     COL(31)
1131 #   define GREEN   COL(32)
1132 #   define YELLOW  COL(33)
1133 #   define BLUE    COL(34)
1134 #   define MAGENTA COL(35)
1135 #   define CYAN    COL(36)
1136 #   define WHITE   COL(0)
1137 #   define GRAY    "\033[0m"
1138 static void
1139 print_help_section( const module_t *m, const module_config_t *p_item,
1140                     bool b_color, bool b_description )
1141 {
1142     if( !p_item ) return;
1143     if( b_color )
1144     {
1145         utf8_fprintf( stdout, RED"   %s:\n"GRAY,
1146                       module_gettext( m, p_item->psz_text ) );
1147         if( b_description && p_item->psz_longtext )
1148             utf8_fprintf( stdout, MAGENTA"   %s\n"GRAY,
1149                           module_gettext( m, p_item->psz_longtext ) );
1150     }
1151     else
1152     {
1153         utf8_fprintf( stdout, "   %s:\n",
1154                       module_gettext( m, p_item->psz_text ) );
1155         if( b_description && p_item->psz_longtext )
1156             utf8_fprintf( stdout, "   %s\n",
1157                           module_gettext(m, p_item->psz_longtext ) );
1158     }
1159 }
1160
1161 static void Usage( libvlc_int_t *p_this, char const *psz_search )
1162 {
1163 #define FORMAT_STRING "  %s --%s%s%s%s%s%s%s "
1164     /* short option ------'    | | | | | | |
1165      * option name ------------' | | | | | |
1166      * <bra ---------------------' | | | | |
1167      * option type or "" ----------' | | | |
1168      * ket> -------------------------' | | |
1169      * padding spaces -----------------' | |
1170      * comment --------------------------' |
1171      * comment suffix ---------------------'
1172      *
1173      * The purpose of having bra and ket is that we might i18n them as well.
1174      */
1175
1176 #define COLOR_FORMAT_STRING (WHITE"  %s --%s"YELLOW"%s%s%s%s%s%s "GRAY)
1177 #define COLOR_FORMAT_STRING_BOOL (WHITE"  %s --%s%s%s%s%s%s%s "GRAY)
1178
1179 #define LINE_START 8
1180 #define PADDING_SPACES 25
1181 #ifdef WIN32
1182 #   define OPTION_VALUE_SEP "="
1183 #else
1184 #   define OPTION_VALUE_SEP " "
1185 #endif
1186     char psz_spaces_text[PADDING_SPACES+LINE_START+1];
1187     char psz_spaces_longtext[LINE_START+3];
1188     char psz_format[sizeof(COLOR_FORMAT_STRING)];
1189     char psz_format_bool[sizeof(COLOR_FORMAT_STRING_BOOL)];
1190     char psz_buffer[10000];
1191     char psz_short[4];
1192     int i_width = ConsoleWidth() - (PADDING_SPACES+LINE_START+1);
1193     int i_width_description = i_width + PADDING_SPACES - 1;
1194     bool b_advanced    = var_InheritBool( p_this, "advanced" );
1195     bool b_description = var_InheritBool( p_this, "help-verbose" );
1196     bool b_description_hack;
1197     bool b_color       = var_InheritBool( p_this, "color" );
1198     bool b_has_advanced = false;
1199     bool b_found       = false;
1200     int  i_only_advanced = 0; /* Number of modules ignored because they
1201                                * only have advanced options */
1202     bool b_strict = psz_search && *psz_search == '=';
1203     if( b_strict ) psz_search++;
1204
1205     memset( psz_spaces_text, ' ', PADDING_SPACES+LINE_START );
1206     psz_spaces_text[PADDING_SPACES+LINE_START] = '\0';
1207     memset( psz_spaces_longtext, ' ', LINE_START+2 );
1208     psz_spaces_longtext[LINE_START+2] = '\0';
1209 #ifndef WIN32
1210     if( !isatty( 1 ) )
1211 #endif
1212         b_color = false; // don't put color control codes in a .txt file
1213
1214     if( b_color )
1215     {
1216         strcpy( psz_format, COLOR_FORMAT_STRING );
1217         strcpy( psz_format_bool, COLOR_FORMAT_STRING_BOOL );
1218     }
1219     else
1220     {
1221         strcpy( psz_format, FORMAT_STRING );
1222         strcpy( psz_format_bool, FORMAT_STRING );
1223     }
1224
1225     /* List all modules */
1226     module_t **list = module_list_get (NULL);
1227     if (!list)
1228         return;
1229
1230     /* Ugly hack to make sure that the help options always come first
1231      * (part 1) */
1232     if( !psz_search )
1233         Usage( p_this, "help" );
1234
1235     /* Enumerate the config for each module */
1236     for (size_t i = 0; list[i]; i++)
1237     {
1238         bool b_help_module;
1239         module_t *p_parser = list[i];
1240         module_config_t *p_item = NULL;
1241         module_config_t *p_section = NULL;
1242         module_config_t *p_end = p_parser->p_config + p_parser->confsize;
1243         const char *objname = module_get_object (p_parser);
1244
1245         if( psz_search &&
1246             ( b_strict ? strcmp( objname, psz_search )
1247                        : !strstr( objname, psz_search ) ) )
1248         {
1249             char *const *pp_shortcuts = p_parser->pp_shortcuts;
1250             unsigned i;
1251             for( i = 0; i < p_parser->i_shortcuts; i++ )
1252             {
1253                 if( b_strict ? !strcmp( psz_search, pp_shortcuts[i] )
1254                              : !!strstr( pp_shortcuts[i], psz_search ) )
1255                     break;
1256             }
1257             if( i == p_parser->i_shortcuts )
1258                 continue;
1259         }
1260
1261         /* Ignore modules without config options */
1262         if( !p_parser->i_config_items )
1263         {
1264             continue;
1265         }
1266
1267         b_help_module = !strcmp( "help", objname );
1268         /* Ugly hack to make sure that the help options always come first
1269          * (part 2) */
1270         if( !psz_search && b_help_module )
1271             continue;
1272
1273         /* Ignore modules with only advanced config options if requested */
1274         if( !b_advanced )
1275         {
1276             for( p_item = p_parser->p_config;
1277                  p_item < p_end;
1278                  p_item++ )
1279             {
1280                 if( CONFIG_ITEM(p_item->i_type) &&
1281                     !p_item->b_advanced && !p_item->b_removed ) break;
1282             }
1283
1284             if( p_item == p_end )
1285             {
1286                 i_only_advanced++;
1287                 continue;
1288             }
1289         }
1290
1291         b_found = true;
1292
1293         /* Print name of module */
1294         if( strcmp( "main", objname ) )
1295         {
1296             if( b_color )
1297                 utf8_fprintf( stdout, "\n " GREEN "%s" GRAY " (%s)\n",
1298                               module_gettext( p_parser, p_parser->psz_longname ),
1299                               objname );
1300             else
1301                 utf8_fprintf( stdout, "\n %s\n",
1302                               module_gettext(p_parser, p_parser->psz_longname ) );
1303         }
1304         if( p_parser->psz_help )
1305         {
1306             if( b_color )
1307                 utf8_fprintf( stdout, CYAN" %s\n"GRAY,
1308                               module_gettext( p_parser, p_parser->psz_help ) );
1309             else
1310                 utf8_fprintf( stdout, " %s\n",
1311                               module_gettext( p_parser, p_parser->psz_help ) );
1312         }
1313
1314         /* Print module options */
1315         for( p_item = p_parser->p_config;
1316              p_item < p_end;
1317              p_item++ )
1318         {
1319             char *psz_text, *psz_spaces = psz_spaces_text;
1320             const char *psz_bra = NULL, *psz_type = NULL, *psz_ket = NULL;
1321             const char *psz_suf = "", *psz_prefix = NULL;
1322             signed int i;
1323             size_t i_cur_width;
1324
1325             /* Skip removed options */
1326             if( p_item->b_removed )
1327             {
1328                 continue;
1329             }
1330             /* Skip advanced options if requested */
1331             if( p_item->b_advanced && !b_advanced )
1332             {
1333                 b_has_advanced = true;
1334                 continue;
1335             }
1336
1337             switch( CONFIG_CLASS(p_item->i_type) )
1338             {
1339             case 0: // hint class
1340                 switch( p_item->i_type )
1341                 {
1342                 case CONFIG_HINT_CATEGORY:
1343                 case CONFIG_HINT_USAGE:
1344                     if( !strcmp( "main", objname ) )
1345                     {
1346                         if( b_color )
1347                             utf8_fprintf( stdout, GREEN "\n %s\n" GRAY,
1348                                           module_gettext( p_parser, p_item->psz_text ) );
1349                         else
1350                             utf8_fprintf( stdout, "\n %s\n",
1351                                           module_gettext( p_parser, p_item->psz_text ) );
1352                     }
1353                     if( b_description && p_item->psz_longtext )
1354                     {
1355                         if( b_color )
1356                             utf8_fprintf( stdout, CYAN " %s\n" GRAY,
1357                                           module_gettext( p_parser, p_item->psz_longtext ) );
1358                         else
1359                             utf8_fprintf( stdout, " %s\n",
1360                                           module_gettext( p_parser, p_item->psz_longtext ) );
1361                 }
1362                 break;
1363
1364                 case CONFIG_HINT_SUBCATEGORY:
1365                     if( strcmp( "main", objname ) )
1366                         break;
1367                 case CONFIG_SECTION:
1368                     p_section = p_item;
1369                     break;
1370                 }
1371                 break;
1372
1373             case CONFIG_ITEM_STRING:
1374                 print_help_section( p_parser, p_section, b_color,
1375                                     b_description );
1376                 p_section = NULL;
1377                 psz_bra = OPTION_VALUE_SEP "<";
1378                 psz_type = _("string");
1379                 psz_ket = ">";
1380
1381                 if( p_item->ppsz_list )
1382                 {
1383                     psz_bra = OPTION_VALUE_SEP "{";
1384                     psz_type = psz_buffer;
1385                     psz_buffer[0] = '\0';
1386                     for( i = 0; p_item->ppsz_list[i]; i++ )
1387                     {
1388                         if( i ) strcat( psz_buffer, "," );
1389                         strcat( psz_buffer, p_item->ppsz_list[i] );
1390                     }
1391                     psz_ket = "}";
1392                 }
1393                 break;
1394             case CONFIG_ITEM_INTEGER:
1395                 print_help_section( p_parser, p_section, b_color,
1396                                     b_description );
1397                 p_section = NULL;
1398                 psz_bra = OPTION_VALUE_SEP "<";
1399                 psz_type = _("integer");
1400                 psz_ket = ">";
1401
1402                 if( p_item->min.i || p_item->max.i )
1403                 {
1404                     sprintf( psz_buffer, "%s [%"PRId64" .. %"PRId64"]",
1405                              psz_type, p_item->min.i, p_item->max.i );
1406                     psz_type = psz_buffer;
1407                 }
1408
1409                 if( p_item->i_list )
1410                 {
1411                     psz_bra = OPTION_VALUE_SEP "{";
1412                     psz_type = psz_buffer;
1413                     psz_buffer[0] = '\0';
1414                     for( i = 0; p_item->ppsz_list_text[i]; i++ )
1415                     {
1416                         if( i ) strcat( psz_buffer, ", " );
1417                         sprintf( psz_buffer + strlen(psz_buffer), "%i (%s)",
1418                                  p_item->pi_list[i],
1419                                  module_gettext( p_parser, p_item->ppsz_list_text[i] ) );
1420                     }
1421                     psz_ket = "}";
1422                 }
1423                 break;
1424             case CONFIG_ITEM_FLOAT:
1425                 print_help_section( p_parser, p_section, b_color,
1426                                     b_description );
1427                 p_section = NULL;
1428                 psz_bra = OPTION_VALUE_SEP "<";
1429                 psz_type = _("float");
1430                 psz_ket = ">";
1431                 if( p_item->min.f || p_item->max.f )
1432                 {
1433                     sprintf( psz_buffer, "%s [%f .. %f]", psz_type,
1434                              p_item->min.f, p_item->max.f );
1435                     psz_type = psz_buffer;
1436                 }
1437                 break;
1438             case CONFIG_ITEM_BOOL:
1439                 print_help_section( p_parser, p_section, b_color,
1440                                     b_description );
1441                 p_section = NULL;
1442                 psz_bra = ""; psz_type = ""; psz_ket = "";
1443                 if( !b_help_module )
1444                 {
1445                     psz_suf = p_item->value.i ? _(" (default enabled)") :
1446                                                 _(" (default disabled)");
1447                 }
1448                 break;
1449             }
1450
1451             if( !psz_type )
1452             {
1453                 continue;
1454             }
1455
1456             /* Add short option if any */
1457             if( p_item->i_short )
1458             {
1459                 sprintf( psz_short, "-%c,", p_item->i_short );
1460             }
1461             else
1462             {
1463                 strcpy( psz_short, "   " );
1464             }
1465
1466             i = PADDING_SPACES - strlen( p_item->psz_name )
1467                  - strlen( psz_bra ) - strlen( psz_type )
1468                  - strlen( psz_ket ) - 1;
1469
1470             if( CONFIG_CLASS(p_item->i_type) == CONFIG_ITEM_BOOL
1471              && !b_help_module )
1472             {
1473                 psz_prefix =  ", --no-";
1474                 i -= strlen( p_item->psz_name ) + strlen( psz_prefix );
1475             }
1476
1477             if( i < 0 )
1478             {
1479                 psz_spaces[0] = '\n';
1480                 i = 0;
1481             }
1482             else
1483             {
1484                 psz_spaces[i] = '\0';
1485             }
1486
1487             if( CONFIG_CLASS(p_item->i_type) == CONFIG_ITEM_BOOL
1488              && !b_help_module )
1489             {
1490                 utf8_fprintf( stdout, psz_format_bool, psz_short,
1491                               p_item->psz_name, psz_prefix, p_item->psz_name,
1492                               psz_bra, psz_type, psz_ket, psz_spaces );
1493             }
1494             else
1495             {
1496                 utf8_fprintf( stdout, psz_format, psz_short, p_item->psz_name,
1497                          "", "", psz_bra, psz_type, psz_ket, psz_spaces );
1498             }
1499
1500             psz_spaces[i] = ' ';
1501
1502             /* We wrap the rest of the output */
1503             sprintf( psz_buffer, "%s%s", module_gettext( p_parser, p_item->psz_text ),
1504                      psz_suf );
1505             b_description_hack = b_description;
1506
1507  description:
1508             psz_text = psz_buffer;
1509             i_cur_width = b_description && !b_description_hack
1510                           ? i_width_description
1511                           : i_width;
1512             if( !*psz_text ) strcpy(psz_text, " ");
1513             while( *psz_text )
1514             {
1515                 char *psz_parser, *psz_word;
1516                 size_t i_end = strlen( psz_text );
1517
1518                 /* If the remaining text fits in a line, print it. */
1519                 if( i_end <= i_cur_width )
1520                 {
1521                     if( b_color )
1522                     {
1523                         if( !b_description || b_description_hack )
1524                             utf8_fprintf( stdout, BLUE"%s\n"GRAY, psz_text );
1525                         else
1526                             utf8_fprintf( stdout, "%s\n", psz_text );
1527                     }
1528                     else
1529                     {
1530                         utf8_fprintf( stdout, "%s\n", psz_text );
1531                     }
1532                     break;
1533                 }
1534
1535                 /* Otherwise, eat as many words as possible */
1536                 psz_parser = psz_text;
1537                 do
1538                 {
1539                     psz_word = psz_parser;
1540                     psz_parser = strchr( psz_word, ' ' );
1541                     /* If no space was found, we reached the end of the text
1542                      * block; otherwise, we skip the space we just found. */
1543                     psz_parser = psz_parser ? psz_parser + 1
1544                                             : psz_text + i_end;
1545
1546                 } while( (size_t)(psz_parser - psz_text) <= i_cur_width );
1547
1548                 /* We cut a word in one of these cases:
1549                  *  - it's the only word in the line and it's too long.
1550                  *  - we used less than 80% of the width and the word we are
1551                  *    going to wrap is longer than 40% of the width, and even
1552                  *    if the word would have fit in the next line. */
1553                 if( psz_word == psz_text
1554              || ( (size_t)(psz_word - psz_text) < 80 * i_cur_width / 100
1555              && (size_t)(psz_parser - psz_word) > 40 * i_cur_width / 100 ) )
1556                 {
1557                     char c = psz_text[i_cur_width];
1558                     psz_text[i_cur_width] = '\0';
1559                     if( b_color )
1560                     {
1561                         if( !b_description || b_description_hack )
1562                             utf8_fprintf( stdout, BLUE"%s\n%s"GRAY,
1563                                           psz_text, psz_spaces );
1564                         else
1565                             utf8_fprintf( stdout, "%s\n%s",
1566                                           psz_text, psz_spaces );
1567                     }
1568                     else
1569                     {
1570                         utf8_fprintf( stdout, "%s\n%s", psz_text, psz_spaces );
1571                     }
1572                     psz_text += i_cur_width;
1573                     psz_text[0] = c;
1574                 }
1575                 else
1576                 {
1577                     psz_word[-1] = '\0';
1578                     if( b_color )
1579                     {
1580                         if( !b_description || b_description_hack )
1581                             utf8_fprintf( stdout, BLUE"%s\n%s"GRAY,
1582                                           psz_text, psz_spaces );
1583                         else
1584                             utf8_fprintf( stdout, "%s\n%s",
1585                                           psz_text, psz_spaces );
1586                     }
1587                     else
1588                     {
1589                         utf8_fprintf( stdout, "%s\n%s", psz_text, psz_spaces );
1590                     }
1591                     psz_text = psz_word;
1592                 }
1593             }
1594
1595             if( b_description_hack && p_item->psz_longtext )
1596             {
1597                 sprintf( psz_buffer, "%s%s",
1598                          module_gettext( p_parser, p_item->psz_longtext ),
1599                          psz_suf );
1600                 b_description_hack = false;
1601                 psz_spaces = psz_spaces_longtext;
1602                 utf8_fprintf( stdout, "%s", psz_spaces );
1603                 goto description;
1604             }
1605         }
1606     }
1607
1608     if( b_has_advanced )
1609     {
1610         if( b_color )
1611             utf8_fprintf( stdout, "\n" WHITE "%s" GRAY " %s\n", _( "Note:" ),
1612            _( "add --advanced to your command line to see advanced options."));
1613         else
1614             utf8_fprintf( stdout, "\n%s %s\n", _( "Note:" ),
1615            _( "add --advanced to your command line to see advanced options."));
1616     }
1617
1618     if( i_only_advanced > 0 )
1619     {
1620         if( b_color )
1621         {
1622             utf8_fprintf( stdout, "\n" WHITE "%s" GRAY " ", _( "Note:" ) );
1623             utf8_fprintf( stdout, _( "%d module(s) were not displayed because they only have advanced options.\n" ), i_only_advanced );
1624         }
1625         else
1626         {
1627             utf8_fprintf( stdout, "\n%s ", _( "Note:" ) );
1628             utf8_fprintf( stdout, _( "%d module(s) were not displayed because they only have advanced options.\n" ), i_only_advanced );
1629         }
1630     }
1631     else if( !b_found )
1632     {
1633         if( b_color )
1634             utf8_fprintf( stdout, "\n" WHITE "%s" GRAY "\n",
1635                        _( "No matching module found. Use --list or " \
1636                           "--list-verbose to list available modules." ) );
1637         else
1638             utf8_fprintf( stdout, "\n%s\n",
1639                        _( "No matching module found. Use --list or " \
1640                           "--list-verbose to list available modules." ) );
1641     }
1642
1643     /* Release the module list */
1644     module_list_free (list);
1645 }
1646
1647 /*****************************************************************************
1648  * ListModules: list the available modules with their description
1649  *****************************************************************************
1650  * Print a list of all available modules (builtins and plugins) and a short
1651  * description for each one.
1652  *****************************************************************************/
1653 static void ListModules( libvlc_int_t *p_this, bool b_verbose )
1654 {
1655     module_t *p_parser;
1656
1657     bool b_color = var_InheritBool( p_this, "color" );
1658
1659 #ifdef WIN32
1660     ShowConsole( true );
1661     b_color = false; // don't put color control codes in a .txt file
1662 #else
1663     if( !isatty( 1 ) )
1664         b_color = false;
1665 #endif
1666
1667     /* List all modules */
1668     module_t **list = module_list_get (NULL);
1669
1670     /* Enumerate each module */
1671     for (size_t j = 0; (p_parser = list[j]) != NULL; j++)
1672     {
1673         const char *objname = module_get_object (p_parser);
1674         if( b_color )
1675             utf8_fprintf( stdout, GREEN"  %-22s "WHITE"%s\n"GRAY, objname,
1676                           module_gettext( p_parser, p_parser->psz_longname ) );
1677         else
1678             utf8_fprintf( stdout, "  %-22s %s\n", objname,
1679                           module_gettext( p_parser, p_parser->psz_longname ) );
1680
1681         if( b_verbose )
1682         {
1683             char *const *pp_shortcuts = p_parser->pp_shortcuts;
1684             for( unsigned i = 0; i < p_parser->i_shortcuts; i++ )
1685             {
1686                 if( strcmp( pp_shortcuts[i], objname ) )
1687                 {
1688                     if( b_color )
1689                         utf8_fprintf( stdout, CYAN"   s %s\n"GRAY,
1690                                       pp_shortcuts[i] );
1691                     else
1692                         utf8_fprintf( stdout, "   s %s\n",
1693                                       pp_shortcuts[i] );
1694                 }
1695             }
1696             if( p_parser->psz_capability )
1697             {
1698                 if( b_color )
1699                     utf8_fprintf( stdout, MAGENTA"   c %s (%d)\n"GRAY,
1700                                   p_parser->psz_capability,
1701                                   p_parser->i_score );
1702                 else
1703                     utf8_fprintf( stdout, "   c %s (%d)\n",
1704                                   p_parser->psz_capability,
1705                                   p_parser->i_score );
1706             }
1707         }
1708     }
1709     module_list_free (list);
1710
1711 #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
1712     PauseConsole();
1713 #endif
1714 }
1715
1716 /*****************************************************************************
1717  * Version: print complete program version
1718  *****************************************************************************
1719  * Print complete program version and build number.
1720  *****************************************************************************/
1721 static void Version( void )
1722 {
1723 #ifdef WIN32
1724     ShowConsole( true );
1725 #endif
1726
1727     utf8_fprintf( stdout, _("VLC version %s (%s)\n"), VERSION_MESSAGE,
1728                   psz_vlc_changeset );
1729     utf8_fprintf( stdout, _("Compiled by %s on %s (%s)\n"),
1730              VLC_CompileBy(), VLC_CompileHost(), __DATE__" "__TIME__ );
1731     utf8_fprintf( stdout, _("Compiler: %s\n"), VLC_Compiler() );
1732     utf8_fprintf( stdout, "%s", LICENSE_MSG );
1733
1734 #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
1735     PauseConsole();
1736 #endif
1737 }
1738
1739 /*****************************************************************************
1740  * ShowConsole: On Win32, create an output console for debug messages
1741  *****************************************************************************
1742  * This function is useful only on Win32.
1743  *****************************************************************************/
1744 #ifdef WIN32 /*  */
1745 static void ShowConsole( bool b_dofile )
1746 {
1747 #   ifndef UNDER_CE
1748     FILE *f_help = NULL;
1749
1750     if( getenv( "PWD" ) ) return; /* Cygwin shell or Wine */
1751
1752     AllocConsole();
1753     /* Use the ANSI code page (e.g. Windows-1252) as expected by the LibVLC
1754      * Unicode/locale subsystem. By default, we have the obsolecent OEM code
1755      * page (e.g. CP437 or CP850). */
1756     SetConsoleOutputCP (GetACP ());
1757     SetConsoleTitle ("VLC media player version "PACKAGE_VERSION);
1758
1759     freopen( "CONOUT$", "w", stderr );
1760     freopen( "CONIN$", "r", stdin );
1761
1762     if( b_dofile && (f_help = fopen( "vlc-help.txt", "wt" )) )
1763     {
1764         fclose( f_help );
1765         freopen( "vlc-help.txt", "wt", stdout );
1766         utf8_fprintf( stderr, _("\nDumped content to vlc-help.txt file.\n") );
1767     }
1768     else freopen( "CONOUT$", "w", stdout );
1769
1770 #   endif
1771 }
1772 #endif
1773
1774 /*****************************************************************************
1775  * PauseConsole: On Win32, wait for a key press before closing the console
1776  *****************************************************************************
1777  * This function is useful only on Win32.
1778  *****************************************************************************/
1779 #ifdef WIN32 /*  */
1780 static void PauseConsole( void )
1781 {
1782 #   ifndef UNDER_CE
1783
1784     if( getenv( "PWD" ) ) return; /* Cygwin shell or Wine */
1785
1786     utf8_fprintf( stderr, _("\nPress the RETURN key to continue...\n") );
1787     getchar();
1788     fclose( stdout );
1789
1790 #   endif
1791 }
1792 #endif
1793
1794 /*****************************************************************************
1795  * ConsoleWidth: Return the console width in characters
1796  *****************************************************************************
1797  * We use the stty shell command to get the console width; if this fails or
1798  * if the width is less than 80, we default to 80.
1799  *****************************************************************************/
1800 static int ConsoleWidth( void )
1801 {
1802     unsigned i_width = 80;
1803
1804 #ifndef WIN32
1805     FILE *file = popen( "stty size 2>/dev/null", "r" );
1806     if (file != NULL)
1807     {
1808         if (fscanf (file, "%*u %u", &i_width) <= 0)
1809             i_width = 80;
1810         pclose( file );
1811     }
1812 #elif !defined (UNDER_CE)
1813     CONSOLE_SCREEN_BUFFER_INFO buf;
1814
1815     if (GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &buf))
1816         i_width = buf.dwSize.X;
1817 #endif
1818
1819     return i_width;
1820 }