]> git.sesse.net Git - vlc/blob - src/libvlc.c
Options as infos were bad in several ways: it broke PLAYLIST_GO, used
[vlc] / src / libvlc.c
1 /*****************************************************************************
2  * libvlc.c: main libvlc source
3  *****************************************************************************
4  * Copyright (C) 1998-2004 VideoLAN
5  * $Id: libvlc.c,v 1.115 2004/01/29 17:51:08 zorglub Exp $
6  *
7  * Authors: Vincent Seguin <seguin@via.ecp.fr>
8  *          Samuel Hocevar <sam@zoy.org>
9  *          Gildas Bazin <gbazin@netcourrier.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25
26 /*****************************************************************************
27  * Pretend we are a builtin module
28  *****************************************************************************/
29 #define MODULE_NAME main
30 #define MODULE_PATH main
31 #define __BUILTIN__
32
33 /*****************************************************************************
34  * Preamble
35  *****************************************************************************/
36 #include <vlc/vlc.h>
37
38 #ifdef HAVE_ERRNO_H
39 #   include <errno.h>                                              /* ENOMEM */
40 #endif
41 #include <stdio.h>                                              /* sprintf() */
42 #include <string.h>                                            /* strerror() */
43 #include <stdlib.h>                                                /* free() */
44
45 #ifndef WIN32
46 #   include <netinet/in.h>                            /* BSD: struct in_addr */
47 #endif
48
49 #ifdef HAVE_UNISTD_H
50 #   include <unistd.h>
51 #elif defined( WIN32 ) && !defined( UNDER_CE )
52 #   include <io.h>
53 #endif
54
55 #ifdef WIN32                       /* optind, getopt(), included in unistd.h */
56 #   include "extras/getopt.h"
57 #endif
58
59 #ifdef HAVE_LOCALE_H
60 #   include <locale.h>
61 #endif
62
63 #include "vlc_cpu.h"                                        /* CPU detection */
64 #include "os_specific.h"
65
66 #include "vlc_error.h"
67
68 #include "stream_control.h"
69 #include "input_ext-intf.h"
70
71 #include "vlc_playlist.h"
72 #include "vlc_interface.h"
73
74 #include "audio_output.h"
75
76 #include "vlc_video.h"
77 #include "video_output.h"
78
79 #include "libvlc.h"
80
81 /*****************************************************************************
82  * The evil global variable. We handle it with care, don't worry.
83  *****************************************************************************/
84 static libvlc_t   libvlc;
85 static libvlc_t * p_libvlc;
86 static vlc_t *    p_static_vlc;
87
88 /*****************************************************************************
89  * Local prototypes
90  *****************************************************************************/
91 static void SetLanguage   ( char const * );
92 static int  GetFilenames  ( vlc_t *, int, char *[] );
93 static void Usage         ( vlc_t *, char const *psz_module_name );
94 static void ListModules   ( vlc_t * );
95 static void Version       ( void );
96
97 #ifdef WIN32
98 static void ShowConsole   ( void );
99 #endif
100 static int  ConsoleWidth  ( void );
101
102 static int  VerboseCallback( vlc_object_t *, char const *,
103                              vlc_value_t, vlc_value_t, void * );
104
105 /*****************************************************************************
106  * vlc_current_object: return the current object.
107  *****************************************************************************
108  * If i_object is non-zero, return the corresponding object. Otherwise,
109  * return the statically allocated p_vlc object.
110  *****************************************************************************/
111 vlc_t * vlc_current_object( int i_object )
112 {
113     if( i_object )
114     {
115          return vlc_object_get( p_libvlc, i_object );
116     }
117
118     return p_static_vlc;
119 }
120
121 /*****************************************************************************
122  * VLC_Version: return the libvlc version.
123  *****************************************************************************
124  * This function returns full version string (numeric version and codename).
125  *****************************************************************************/
126 char const * VLC_Version( void )
127 {
128     return VERSION_MESSAGE;
129 }
130
131 /*****************************************************************************
132  * VLC_Error: strerror() equivalent
133  *****************************************************************************
134  * This function returns full version string (numeric version and codename).
135  *****************************************************************************/
136 char const * VLC_Error( int i_err )
137 {
138     return vlc_error( i_err );
139 }
140
141 /*****************************************************************************
142  * VLC_Create: allocate a vlc_t structure, and initialize libvlc if needed.
143  *****************************************************************************
144  * This function allocates a vlc_t structure and returns a negative value
145  * in case of failure. Also, the thread system is initialized.
146  *****************************************************************************/
147 int VLC_Create( void )
148 {
149     int i_ret;
150     vlc_t * p_vlc = NULL;
151     vlc_value_t lockval;
152
153     /* &libvlc never changes, so we can safely call this multiple times. */
154     p_libvlc = &libvlc;
155
156     /* vlc_threads_init *must* be the first internal call! No other call is
157      * allowed before the thread system has been initialized. */
158     i_ret = vlc_threads_init( p_libvlc );
159     if( i_ret < 0 )
160     {
161         return i_ret;
162     }
163
164     /* Now that the thread system is initialized, we don't have much, but
165      * at least we have var_Create */
166     var_Create( p_libvlc, "libvlc", VLC_VAR_MUTEX );
167     var_Get( p_libvlc, "libvlc", &lockval );
168     vlc_mutex_lock( lockval.p_address );
169     if( !libvlc.b_ready )
170     {
171         char *psz_env;
172
173         /* Guess what CPU we have */
174         libvlc.i_cpu = CPUCapabilities();
175
176         /* Find verbosity from VLC_VERBOSE environment variable */
177         psz_env = getenv( "VLC_VERBOSE" );
178         libvlc.i_verbose = psz_env ? atoi( psz_env ) : -1;
179
180 #if defined( HAVE_ISATTY ) && !defined( WIN32 )
181         libvlc.b_color = isatty( 2 ); /* 2 is for stderr */
182 #else
183         libvlc.b_color = VLC_FALSE;
184 #endif
185
186         /* Initialize message queue */
187         msg_Create( p_libvlc );
188
189         /* Announce who we are */
190         msg_Dbg( p_libvlc, COPYRIGHT_MESSAGE );
191         msg_Dbg( p_libvlc, "libvlc was configured with %s", CONFIGURE_LINE );
192
193         /* The module bank will be initialized later */
194         libvlc.p_module_bank = NULL;
195
196         libvlc.b_ready = VLC_TRUE;
197     }
198     vlc_mutex_unlock( lockval.p_address );
199     var_Destroy( p_libvlc, "libvlc" );
200
201     /* Allocate a vlc object */
202     p_vlc = vlc_object_create( p_libvlc, VLC_OBJECT_VLC );
203     if( p_vlc == NULL )
204     {
205         return VLC_EGENERIC;
206     }
207     vlc_thread_set_priority( p_vlc, VLC_THREAD_PRIORITY_LOW );
208
209     p_vlc->psz_object_name = "root";
210
211     /* Initialize mutexes */
212     vlc_mutex_init( p_vlc, &p_vlc->config_lock );
213 #ifdef SYS_DARWIN
214     vlc_mutex_init( p_vlc, &p_vlc->quicktime_lock );
215 #endif
216
217     /* Store our newly allocated structure in the global list */
218     vlc_object_attach( p_vlc, p_libvlc );
219
220     /* Store data for the non-reentrant API */
221     p_static_vlc = p_vlc;
222
223     return p_vlc->i_object_id;
224 }
225
226 /*****************************************************************************
227  * VLC_Init: initialize a vlc_t structure.
228  *****************************************************************************
229  * This function initializes a previously allocated vlc_t structure:
230  *  - CPU detection
231  *  - gettext initialization
232  *  - message queue, module bank and playlist initialization
233  *  - configuration and commandline parsing
234  *****************************************************************************/
235 int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
236 {
237     char         p_capabilities[200];
238     char *       p_tmp;
239     char *       psz_modules;
240     char *       psz_parser;
241     char *       psz_language;
242     vlc_bool_t   b_exit = VLC_FALSE;
243     vlc_t *      p_vlc = vlc_current_object( i_object );
244     module_t    *p_help_module;
245     playlist_t  *p_playlist;
246     vlc_value_t  lockval;
247
248     if( !p_vlc )
249     {
250         return VLC_ENOOBJ;
251     }
252
253     /*
254      * System specific initialization code
255      */
256     system_Init( p_vlc, &i_argc, ppsz_argv );
257
258     /* Get the executable name (similar to the basename command) */
259     if( i_argc > 0 )
260     {
261         p_vlc->psz_object_name = p_tmp = ppsz_argv[ 0 ];
262         while( *p_tmp )
263         {
264             if( *p_tmp == '/' ) p_vlc->psz_object_name = ++p_tmp;
265             else ++p_tmp;
266         }
267     }
268     else
269     {
270         p_vlc->psz_object_name = "vlc";
271     }
272
273     /*
274      * Support for gettext
275      */
276     SetLanguage( "" );
277
278     /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
279     msg_Dbg( p_vlc, "translation test: code is \"%s\"", _("C") );
280
281     /* Initialize the module bank and load the configuration of the
282      * main module. We need to do this at this stage to be able to display
283      * a short help if required by the user. (short help == main module
284      * options) */
285     var_Create( p_libvlc, "libvlc", VLC_VAR_MUTEX );
286     var_Get( p_libvlc, "libvlc", &lockval );
287     vlc_mutex_lock( lockval.p_address );
288     if( libvlc.p_module_bank == NULL )
289     {
290         module_InitBank( p_vlc );
291         module_LoadMain( p_vlc );
292     }
293     vlc_mutex_unlock( lockval.p_address );
294     var_Destroy( p_libvlc, "libvlc" );
295
296     /* Hack: insert the help module here */
297     p_help_module = vlc_object_create( p_vlc, VLC_OBJECT_MODULE );
298     if( p_help_module == NULL )
299     {
300         /*module_EndBank( p_vlc );*/
301         if( i_object ) vlc_object_release( p_vlc );
302         return VLC_EGENERIC;
303     }
304     p_help_module->psz_object_name = "help";
305     p_help_module->psz_longname = N_("Help options");
306     config_Duplicate( p_help_module, p_help_config );
307     vlc_object_attach( p_help_module, libvlc.p_module_bank );
308     /* End hack */
309
310     if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
311     {
312         vlc_object_detach( p_help_module );
313         config_Free( p_help_module );
314         vlc_object_destroy( p_help_module );
315         /*module_EndBank( p_vlc );*/
316         if( i_object ) vlc_object_release( p_vlc );
317         return VLC_EGENERIC;
318     }
319
320     /* Check for short help option */
321     if( config_GetInt( p_vlc, "help" ) )
322     {
323         fprintf( stdout, _("Usage: %s [options] [items]...\n"),
324                          p_vlc->psz_object_name );
325         Usage( p_vlc, "main" );
326         Usage( p_vlc, "help" );
327         b_exit = VLC_TRUE;
328     }
329     /* Check for version option */
330     else if( config_GetInt( p_vlc, "version" ) )
331     {
332         Version();
333         b_exit = VLC_TRUE;
334     }
335
336     /* Set the config file stuff */
337     p_vlc->psz_homedir = config_GetHomeDir();
338     p_vlc->psz_configfile = config_GetPsz( p_vlc, "config" );
339
340     /* Hack: remove the help module here */
341     vlc_object_detach( p_help_module );
342     /* End hack */
343
344     if( b_exit )
345     {
346         config_Free( p_help_module );
347         vlc_object_destroy( p_help_module );
348         /*module_EndBank( p_vlc );*/
349         if( i_object ) vlc_object_release( p_vlc );
350         return VLC_EEXIT;
351     }
352
353     /* Check for translation config option */
354 #if defined( ENABLE_NLS ) \
355      && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
356
357     /* This ain't really nice to have to reload the config here but it seems
358      * the only way to do it. */
359     config_LoadConfigFile( p_vlc, "main" );
360     config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
361
362     /* Check if the user specified a custom language */
363     psz_language = config_GetPsz( p_vlc, "language" );
364     if( psz_language && *psz_language && strcmp( psz_language, "auto" ) )
365     {
366         /* Reset the default domain */
367         SetLanguage( psz_language );
368
369         /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
370         msg_Dbg( p_vlc, "translation test: code is \"%s\"", _("C") );
371
372         textdomain( PACKAGE );
373
374 #if defined( SYS_BEOS ) || defined ( SYS_DARWIN ) || \
375     ( defined( WIN32 ) && !defined( HAVE_INCLUDED_GETTEXT ) )
376         /* BeOS only support UTF8 strings */
377         /* Mac OS X prefers UTF8 */
378         bind_textdomain_codeset( PACKAGE, "UTF-8" );
379 #endif
380
381         module_EndBank( p_vlc );
382         module_InitBank( p_vlc );
383         module_LoadMain( p_vlc );
384         config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
385     }
386     if( psz_language ) free( psz_language );
387 #endif
388
389     /*
390      * Load the builtins and plugins into the module_bank.
391      * We have to do it before config_Load*() because this also gets the
392      * list of configuration options exported by each module and loads their
393      * default values.
394      */
395     module_LoadBuiltins( p_vlc );
396     module_LoadPlugins( p_vlc );
397     if( p_vlc->b_die )
398     {
399         b_exit = VLC_TRUE;
400     }
401
402     msg_Dbg( p_vlc, "module bank initialized, found %i modules",
403                     libvlc.p_module_bank->i_children );
404
405     /* Hack: insert the help module here */
406     vlc_object_attach( p_help_module, libvlc.p_module_bank );
407     /* End hack */
408
409     /* Check for help on modules */
410     if( (p_tmp = config_GetPsz( p_vlc, "module" )) )
411     {
412         Usage( p_vlc, p_tmp );
413         free( p_tmp );
414         b_exit = VLC_TRUE;
415     }
416     /* Check for long help option */
417     else if( config_GetInt( p_vlc, "longhelp" ) )
418     {
419         Usage( p_vlc, NULL );
420         b_exit = VLC_TRUE;
421     }
422     /* Check for module list option */
423     else if( config_GetInt( p_vlc, "list" ) )
424     {
425         ListModules( p_vlc );
426         b_exit = VLC_TRUE;
427     }
428
429     /* Check for config file options */
430     if( config_GetInt( p_vlc, "reset-config" ) )
431     {
432         vlc_object_detach( p_help_module );
433         config_ResetAll( p_vlc );
434         config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
435         config_SaveConfigFile( p_vlc, NULL );
436         vlc_object_attach( p_help_module, libvlc.p_module_bank );
437     }
438     if( config_GetInt( p_vlc, "save-config" ) )
439     {
440         vlc_object_detach( p_help_module );
441         config_LoadConfigFile( p_vlc, NULL );
442         config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
443         config_SaveConfigFile( p_vlc, NULL );
444         vlc_object_attach( p_help_module, libvlc.p_module_bank );
445     }
446
447     /* Hack: remove the help module here */
448     vlc_object_detach( p_help_module );
449     /* End hack */
450
451     if( b_exit )
452     {
453         config_Free( p_help_module );
454         vlc_object_destroy( p_help_module );
455         /*module_EndBank( p_vlc );*/
456         if( i_object ) vlc_object_release( p_vlc );
457         return VLC_EEXIT;
458     }
459
460     /*
461      * Override default configuration with config file settings
462      */
463     config_LoadConfigFile( p_vlc, NULL );
464
465     /* Hack: insert the help module here */
466     vlc_object_attach( p_help_module, libvlc.p_module_bank );
467     /* End hack */
468
469     /*
470      * Override configuration with command line settings
471      */
472     if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
473     {
474 #ifdef WIN32
475         ShowConsole();
476         /* Pause the console because it's destroyed when we exit */
477         fprintf( stderr, "The command line options couldn't be loaded, check "
478                  "that they are valid.\nPress the RETURN key to continue..." );
479         getchar();
480 #endif
481         vlc_object_detach( p_help_module );
482         config_Free( p_help_module );
483         vlc_object_destroy( p_help_module );
484         /*module_EndBank( p_vlc );*/
485         if( i_object ) vlc_object_release( p_vlc );
486         return VLC_EGENERIC;
487     }
488
489     /* Hack: remove the help module here */
490     vlc_object_detach( p_help_module );
491     config_Free( p_help_module );
492     vlc_object_destroy( p_help_module );
493     /* End hack */
494
495     /*
496      * System specific configuration
497      */
498     system_Configure( p_vlc, &i_argc, ppsz_argv );
499
500     /*
501      * Message queue options
502      */
503
504     var_Create( p_vlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
505     if( config_GetInt( p_vlc, "quiet" ) )
506     {
507         vlc_value_t val;
508         val.i_int = -1;
509         var_Set( p_vlc, "verbose", val );
510     }
511     var_AddCallback( p_vlc, "verbose", VerboseCallback, NULL );
512     var_Change( p_vlc, "verbose", VLC_VAR_TRIGGER_CALLBACKS, NULL, NULL );
513
514     libvlc.b_color = libvlc.b_color && config_GetInt( p_vlc, "color" );
515
516     /*
517      * Output messages that may still be in the queue
518      */
519     msg_Flush( p_vlc );
520
521     /* p_vlc initialization. FIXME ? */
522
523 #if defined( __i386__ )
524     if( !config_GetInt( p_vlc, "mmx" ) )
525         libvlc.i_cpu &= ~CPU_CAPABILITY_MMX;
526     if( !config_GetInt( p_vlc, "3dn" ) )
527         libvlc.i_cpu &= ~CPU_CAPABILITY_3DNOW;
528     if( !config_GetInt( p_vlc, "mmxext" ) )
529         libvlc.i_cpu &= ~CPU_CAPABILITY_MMXEXT;
530     if( !config_GetInt( p_vlc, "sse" ) )
531         libvlc.i_cpu &= ~CPU_CAPABILITY_SSE;
532     if( !config_GetInt( p_vlc, "sse2" ) )
533         libvlc.i_cpu &= ~CPU_CAPABILITY_SSE2;
534 #endif
535 #if defined( __powerpc__ ) || defined( SYS_DARWIN )
536     if( !config_GetInt( p_vlc, "altivec" ) )
537         libvlc.i_cpu &= ~CPU_CAPABILITY_ALTIVEC;
538 #endif
539
540 #define PRINT_CAPABILITY( capability, string )                              \
541     if( libvlc.i_cpu & capability )                                         \
542     {                                                                       \
543         strncat( p_capabilities, string " ",                                \
544                  sizeof(p_capabilities) - strlen(p_capabilities) );         \
545         p_capabilities[sizeof(p_capabilities) - 1] = '\0';                  \
546     }
547
548     p_capabilities[0] = '\0';
549     PRINT_CAPABILITY( CPU_CAPABILITY_486, "486" );
550     PRINT_CAPABILITY( CPU_CAPABILITY_586, "586" );
551     PRINT_CAPABILITY( CPU_CAPABILITY_PPRO, "Pentium Pro" );
552     PRINT_CAPABILITY( CPU_CAPABILITY_MMX, "MMX" );
553     PRINT_CAPABILITY( CPU_CAPABILITY_3DNOW, "3DNow!" );
554     PRINT_CAPABILITY( CPU_CAPABILITY_MMXEXT, "MMXEXT" );
555     PRINT_CAPABILITY( CPU_CAPABILITY_SSE, "SSE" );
556     PRINT_CAPABILITY( CPU_CAPABILITY_SSE2, "SSE2" );
557     PRINT_CAPABILITY( CPU_CAPABILITY_ALTIVEC, "AltiVec" );
558     PRINT_CAPABILITY( CPU_CAPABILITY_FPU, "FPU" );
559     msg_Dbg( p_vlc, "CPU has capabilities %s", p_capabilities );
560
561     /*
562      * Choose the best memcpy module
563      */
564     p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy" );
565
566     if( p_vlc->pf_memcpy == NULL )
567     {
568         p_vlc->pf_memcpy = memcpy;
569     }
570
571     if( p_vlc->pf_memset == NULL )
572     {
573         p_vlc->pf_memset = memset;
574     }
575
576     /*
577      * Initialize hotkey handling
578      */
579     var_Create( p_vlc, "key-pressed", VLC_VAR_INTEGER );
580     p_vlc->p_hotkeys = malloc( sizeof(p_hotkeys) );
581     /* Do a copy (we don't need to modify the strings) */
582     memcpy( p_vlc->p_hotkeys, p_hotkeys, sizeof(p_hotkeys) );
583
584     /*
585      * Initialize playlist and get commandline files
586      */
587     p_playlist = playlist_Create( p_vlc );
588     if( !p_playlist )
589     {
590         msg_Err( p_vlc, "playlist initialization failed" );
591         if( p_vlc->p_memcpy_module != NULL )
592         {
593             module_Unneed( p_vlc, p_vlc->p_memcpy_module );
594         }
595         /*module_EndBank( p_vlc );*/
596         if( i_object ) vlc_object_release( p_vlc );
597         return VLC_EGENERIC;
598     }
599
600     /*
601      * Load background interfaces
602      */
603     psz_modules = config_GetPsz( p_vlc, "extraintf" );
604     psz_parser = psz_modules;
605     while ( psz_parser && *psz_parser )
606     {
607         char *psz_module, *psz_temp;
608         psz_module = psz_parser;
609         psz_parser = strchr( psz_module, ',' );
610         if ( psz_parser )
611         {
612             *psz_parser = '\0';
613             psz_parser++;
614         }
615         psz_temp = (char *)malloc( strlen(psz_module) + sizeof(",none") );
616         if( psz_temp )
617         {
618             sprintf( psz_temp, "%s,none", psz_module );
619             VLC_AddIntf( 0, psz_temp, VLC_FALSE );
620             free( psz_temp );
621         }
622     }
623     if ( psz_modules )
624     {
625         free( psz_modules );
626     }
627
628     /*
629      * Allways load the hotkeys interface if it exists
630      */
631     VLC_AddIntf( 0, "hotkeys,none", VLC_FALSE );
632
633     /*
634      * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin
635      */
636     var_Create( p_vlc, "drawable", VLC_VAR_INTEGER );
637     var_Create( p_vlc, "drawableredraw", VLC_VAR_INTEGER );
638     var_Create( p_vlc, "drawablet", VLC_VAR_INTEGER );
639     var_Create( p_vlc, "drawablel", VLC_VAR_INTEGER );
640     var_Create( p_vlc, "drawableb", VLC_VAR_INTEGER );
641     var_Create( p_vlc, "drawabler", VLC_VAR_INTEGER );
642     var_Create( p_vlc, "drawablex", VLC_VAR_INTEGER );
643     var_Create( p_vlc, "drawabley", VLC_VAR_INTEGER );
644     var_Create( p_vlc, "drawablew", VLC_VAR_INTEGER );
645     var_Create( p_vlc, "drawableh", VLC_VAR_INTEGER );
646     var_Create( p_vlc, "drawableportx", VLC_VAR_INTEGER );
647     var_Create( p_vlc, "drawableporty", VLC_VAR_INTEGER );
648
649     /*
650      * Get input filenames given as commandline arguments
651      */
652     GetFilenames( p_vlc, i_argc, ppsz_argv );
653
654     if( i_object ) vlc_object_release( p_vlc );
655     return VLC_SUCCESS;
656 }
657
658 /*****************************************************************************
659  * VLC_AddIntf: add an interface
660  *****************************************************************************
661  * This function opens an interface plugin and runs it. If b_block is set
662  * to 0, VLC_AddIntf will return immediately and let the interface run in a
663  * separate thread. If b_block is set to 1, VLC_AddIntf will continue until
664  * user requests to quit.
665  *****************************************************************************/
666 int VLC_AddIntf( int i_object, char const *psz_module, vlc_bool_t b_block )
667 {
668     int i_err;
669     intf_thread_t *p_intf;
670     vlc_t *p_vlc = vlc_current_object( i_object );
671
672     if( !p_vlc )
673     {
674         return VLC_ENOOBJ;
675     }
676
677     /* Try to create the interface */
678     p_intf = intf_Create( p_vlc, psz_module ? psz_module : "$intf" );
679
680     if( p_intf == NULL )
681     {
682         msg_Err( p_vlc, "interface \"%s\" initialization failed", psz_module );
683         if( i_object ) vlc_object_release( p_vlc );
684         return VLC_EGENERIC;
685     }
686
687     /* Try to run the interface */
688     p_intf->b_block = b_block;
689     i_err = intf_RunThread( p_intf );
690     if( i_err )
691     {
692         vlc_object_detach( p_intf );
693         intf_Destroy( p_intf );
694         if( i_object ) vlc_object_release( p_vlc );
695         return i_err;
696     }
697
698     if( i_object ) vlc_object_release( p_vlc );
699     return VLC_SUCCESS;
700 }
701
702 /*****************************************************************************
703  * VLC_Destroy: stop playing and destroy everything.
704  *****************************************************************************
705  * This function requests the running threads to finish, waits for their
706  * termination, and destroys their structure.
707  *****************************************************************************/
708 int VLC_Destroy( int i_object )
709 {
710     vlc_t *p_vlc = vlc_current_object( i_object );
711
712     if( !p_vlc )
713     {
714         return VLC_ENOOBJ;
715     }
716
717     /*
718      * Free allocated memory
719      */
720     if( p_vlc->p_memcpy_module )
721     {
722         module_Unneed( p_vlc, p_vlc->p_memcpy_module );
723         p_vlc->p_memcpy_module = NULL;
724     }
725
726     if( p_vlc->psz_homedir )
727     {
728         free( p_vlc->psz_homedir );
729         p_vlc->psz_homedir = NULL;
730     }
731
732     if( p_vlc->psz_configfile )
733     {
734         free( p_vlc->psz_configfile );
735         p_vlc->psz_configfile = NULL;
736     }
737
738     if( p_vlc->p_hotkeys )
739     {
740         free( p_vlc->p_hotkeys );
741         p_vlc->p_hotkeys = NULL;
742     }
743
744     /*
745      * XXX: Free module bank !
746      */
747     /*module_EndBank( p_vlc );*/
748
749     /*
750      * System specific cleaning code
751      */
752     system_End( p_vlc );
753
754     /* Destroy mutexes */
755     vlc_mutex_destroy( &p_vlc->config_lock );
756 #ifdef SYS_DARWIN
757     vlc_mutex_destroy( &p_vlc->quicktime_lock );
758 #endif
759
760     vlc_object_detach( p_vlc );
761
762     /* Release object before destroying it */
763     if( i_object ) vlc_object_release( p_vlc );
764
765     vlc_object_destroy( p_vlc );
766
767     /* Stop thread system: last one out please shut the door! */
768     vlc_threads_end( p_libvlc );
769
770     return VLC_SUCCESS;
771 }
772
773 /*****************************************************************************
774  * VLC_Die: ask vlc to die.
775  *****************************************************************************
776  * This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
777  * task. It is your duty to call VLC_End and VLC_Destroy afterwards.
778  *****************************************************************************/
779 int VLC_Die( int i_object )
780 {
781     vlc_t *p_vlc = vlc_current_object( i_object );
782
783     if( !p_vlc )
784     {
785         return VLC_ENOOBJ;
786     }
787
788     p_vlc->b_die = VLC_TRUE;
789
790     if( i_object ) vlc_object_release( p_vlc );
791     return VLC_SUCCESS;
792 }
793
794 /*****************************************************************************
795  * VLC_AddTarget: adds a target for playing.
796  *****************************************************************************
797  * This function adds psz_target to the current playlist. If a playlist does
798  * not exist, it will create one.
799  *****************************************************************************/
800 int VLC_AddTarget( int i_object, char const *psz_target,
801                    char const **ppsz_options, int i_options,
802                    int i_mode, int i_pos )
803 {
804     int i_err;
805     playlist_t *p_playlist;
806     vlc_t *p_vlc = vlc_current_object( i_object );
807
808     if( !p_vlc )
809     {
810         return VLC_ENOOBJ;
811     }
812
813     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
814
815     if( p_playlist == NULL )
816     {
817         msg_Dbg( p_vlc, "no playlist present, creating one" );
818         p_playlist = playlist_Create( p_vlc );
819
820         if( p_playlist == NULL )
821         {
822             if( i_object ) vlc_object_release( p_vlc );
823             return VLC_EGENERIC;
824         }
825
826         vlc_object_yield( p_playlist );
827     }
828
829     i_err = playlist_AddExt( p_playlist, psz_target, psz_target,
830                              i_mode, i_pos, -1, ppsz_options, i_options);
831
832     vlc_object_release( p_playlist );
833
834     if( i_object ) vlc_object_release( p_vlc );
835     return i_err;
836 }
837
838 /*****************************************************************************
839  * VLC_Set: set a vlc variable
840  *****************************************************************************
841  *
842  *****************************************************************************/
843 int VLC_Set( int i_object, char const *psz_var, vlc_value_t value )
844 {
845     vlc_t *p_vlc = vlc_current_object( i_object );
846     int i_ret;
847
848     if( !p_vlc )
849     {
850         return VLC_ENOOBJ;
851     }
852
853     /* FIXME: Temporary hack for Mozilla, if variable starts with conf:: then
854      * we handle it as a configuration variable. Don't tell Gildas :) -- sam */
855     if( !strncmp( psz_var, "conf::", 6 ) )
856     {
857         module_config_t *p_item;
858         char const *psz_newvar = psz_var + 6;
859
860         p_item = config_FindConfig( VLC_OBJECT(p_vlc), psz_newvar );
861
862         if( p_item )
863         {
864             switch( p_item->i_type )
865             {
866                 case CONFIG_ITEM_BOOL:
867                     config_PutInt( p_vlc, psz_newvar, value.b_bool );
868                     break;
869                 case CONFIG_ITEM_INTEGER:
870                     config_PutInt( p_vlc, psz_newvar, value.i_int );
871                     break;
872                 case CONFIG_ITEM_FLOAT:
873                     config_PutFloat( p_vlc, psz_newvar, value.f_float );
874                     break;
875                 default:
876                     config_PutPsz( p_vlc, psz_newvar, value.psz_string );
877                     break;
878             }
879             if( i_object ) vlc_object_release( p_vlc );
880             return VLC_SUCCESS;
881         }
882     }
883
884     i_ret = var_Set( p_vlc, psz_var, value );
885
886     if( i_object ) vlc_object_release( p_vlc );
887     return i_ret;
888 }
889
890 /*****************************************************************************
891  * VLC_Get: get a vlc variable
892  *****************************************************************************
893  *
894  *****************************************************************************/
895 int VLC_Get( int i_object, char const *psz_var, vlc_value_t *p_value )
896 {
897     vlc_t *p_vlc = vlc_current_object( i_object );
898     int i_ret;
899
900     if( !p_vlc )
901     {
902         return VLC_ENOOBJ;
903     }
904
905     i_ret = var_Get( p_vlc, psz_var, p_value );
906
907     if( i_object ) vlc_object_release( p_vlc );
908     return i_ret;
909 }
910
911 /* FIXME: temporary hacks */
912
913
914 /*****************************************************************************
915  * VLC_IsPlaying: Query for Playlist Status
916  *****************************************************************************/
917 vlc_bool_t VLC_IsPlaying( int i_object )
918 {
919
920     playlist_t * p_playlist;
921     vlc_bool_t   playing;
922
923     vlc_t *p_vlc = vlc_current_object( i_object );
924
925     /* Check that the handle is valid */
926     if( !p_vlc )
927     {
928         return VLC_ENOOBJ;
929     }
930
931     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
932
933     if( !p_playlist )
934     {
935         if( i_object ) vlc_object_release( p_vlc );
936         return VLC_ENOOBJ;
937     }
938
939     playing = playlist_IsPlaying( p_playlist );
940
941     vlc_object_release( p_playlist );
942
943     if( i_object ) vlc_object_release( p_vlc );
944
945     return playing;
946
947 }
948
949
950 /*****************************************************************************
951  * VLC_ClearPlaylist: Query for Playlist Status
952  *
953  * return: 0
954  *****************************************************************************/
955 int VLC_ClearPlaylist( int i_object )
956 {
957
958     playlist_t * p_playlist;
959     vlc_t *p_vlc = vlc_current_object( i_object );
960
961     /* Check that the handle is valid */
962     if( !p_vlc )
963     {
964         return VLC_ENOOBJ;
965     }
966
967     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
968
969     if( !p_playlist )
970     {
971         if( i_object ) vlc_object_release( p_vlc );
972         return VLC_ENOOBJ;
973     }
974
975     playlist_Clear(p_playlist);
976
977     vlc_object_release( p_playlist );
978
979     if( i_object ) vlc_object_release( p_vlc );
980     return 0;
981 }
982
983
984 /*****************************************************************************
985  * VLC_Play: play
986  *****************************************************************************/
987 int VLC_Play( int i_object )
988 {
989     playlist_t * p_playlist;
990     vlc_t *p_vlc = vlc_current_object( i_object );
991
992     /* Check that the handle is valid */
993     if( !p_vlc )
994     {
995         return VLC_ENOOBJ;
996     }
997
998     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
999
1000     if( !p_playlist )
1001     {
1002         if( i_object ) vlc_object_release( p_vlc );
1003         return VLC_ENOOBJ;
1004     }
1005
1006     vlc_mutex_lock( &p_playlist->object_lock );
1007     if( p_playlist->i_size )
1008     {
1009         vlc_mutex_unlock( &p_playlist->object_lock );
1010         playlist_Play( p_playlist );
1011     }
1012     else
1013     {
1014         vlc_mutex_unlock( &p_playlist->object_lock );
1015     }
1016
1017     vlc_object_release( p_playlist );
1018
1019     if( i_object ) vlc_object_release( p_vlc );
1020     return VLC_SUCCESS;
1021 }
1022
1023 /*****************************************************************************
1024  * VLC_Stop: stop
1025  *****************************************************************************/
1026 int VLC_Stop( int i_object )
1027 {
1028     intf_thread_t *   p_intf;
1029     playlist_t    *   p_playlist;
1030     vout_thread_t *   p_vout;
1031     aout_instance_t * p_aout;
1032     vlc_t *p_vlc = vlc_current_object( i_object );
1033
1034     /* Check that the handle is valid */
1035     if( !p_vlc )
1036     {
1037         return VLC_ENOOBJ;
1038     }
1039
1040     /*
1041      * Ask the interfaces to stop and destroy them
1042      */
1043     msg_Dbg( p_vlc, "removing all interfaces" );
1044
1045     while( (p_intf = vlc_object_find( p_vlc, VLC_OBJECT_INTF, FIND_CHILD )) )
1046     {
1047         intf_StopThread( p_intf );
1048         vlc_object_detach( p_intf );
1049         vlc_object_release( p_intf );
1050         intf_Destroy( p_intf );
1051     }
1052
1053     /*
1054      * Free playlists
1055      */
1056
1057     msg_Dbg( p_vlc, "removing all playlists" );
1058     while( (p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST,
1059                                           FIND_CHILD )) )
1060     {
1061         vlc_object_detach( p_playlist );
1062         vlc_object_release( p_playlist );
1063         playlist_Destroy( p_playlist );
1064     }
1065
1066     /*
1067      * Free video outputs
1068      */
1069     msg_Dbg( p_vlc, "removing all video outputs" );
1070     while( (p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD )) )
1071     {
1072         vlc_object_detach( p_vout );
1073         vlc_object_release( p_vout );
1074         vout_Destroy( p_vout );
1075     }
1076
1077     /*
1078      * Free audio outputs
1079      */
1080     msg_Dbg( p_vlc, "removing all audio outputs" );
1081     while( (p_aout = vlc_object_find( p_vlc, VLC_OBJECT_AOUT, FIND_CHILD )) )
1082     {
1083         vlc_object_detach( (vlc_object_t *)p_aout );
1084         vlc_object_release( (vlc_object_t *)p_aout );
1085         aout_Delete( p_aout );
1086     }
1087
1088     if( i_object ) vlc_object_release( p_vlc );
1089     return VLC_SUCCESS;
1090 }
1091
1092 /*****************************************************************************
1093  * VLC_Pause: toggle pause
1094  *****************************************************************************/
1095 int VLC_Pause( int i_object )
1096 {
1097     input_thread_t *p_input;
1098     vlc_t *p_vlc = vlc_current_object( i_object );
1099
1100     if( !p_vlc )
1101     {
1102         return VLC_ENOOBJ;
1103     }
1104
1105     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
1106
1107     if( !p_input )
1108     {
1109         if( i_object ) vlc_object_release( p_vlc );
1110         return VLC_ENOOBJ;
1111     }
1112
1113     input_SetStatus( p_input, INPUT_STATUS_PAUSE );
1114     vlc_object_release( p_input );
1115
1116     if( i_object ) vlc_object_release( p_vlc );
1117     return VLC_SUCCESS;
1118 }
1119
1120 /*****************************************************************************
1121  * VLC_FullScreen: toggle fullscreen mode
1122  *****************************************************************************/
1123 int VLC_FullScreen( int i_object )
1124 {
1125     vout_thread_t *p_vout;
1126     vlc_t *p_vlc = vlc_current_object( i_object );
1127
1128     if( !p_vlc )
1129     {
1130         return VLC_ENOOBJ;
1131     }
1132
1133     p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD );
1134
1135     if( !p_vout )
1136     {
1137         if( i_object ) vlc_object_release( p_vlc );
1138         return VLC_ENOOBJ;
1139     }
1140
1141     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
1142     vlc_object_release( p_vout );
1143
1144     if( i_object ) vlc_object_release( p_vlc );
1145     return VLC_SUCCESS;
1146 }
1147
1148 /* following functions are local */
1149
1150 /*****************************************************************************
1151  * SetLanguage: set the interface language.
1152  *****************************************************************************
1153  * We set the LC_MESSAGES locale category for interface messages and buttons,
1154  * as well as the LC_CTYPE category for string sorting and possible wide
1155  * character support.
1156  *****************************************************************************/
1157 static void SetLanguage ( char const *psz_lang )
1158 {
1159 #if defined( ENABLE_NLS ) \
1160      && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
1161
1162     char *          psz_path;
1163 #if defined( SYS_DARWIN ) || defined ( WIN32 ) || defined( SYS_BEOS )
1164     char            psz_tmp[1024];
1165 #endif
1166
1167     if( psz_lang && !*psz_lang )
1168     {
1169 #   if defined( HAVE_LC_MESSAGES )
1170         setlocale( LC_MESSAGES, psz_lang );
1171 #   endif
1172         setlocale( LC_CTYPE, psz_lang );
1173     }
1174     else if( psz_lang )
1175     {
1176 #ifdef SYS_DARWIN
1177         /* I need that under Darwin, please check it doesn't disturb
1178          * other platforms. --Meuuh */
1179         setenv( "LANG", psz_lang, 1 );
1180
1181 #elif defined( SYS_BEOS ) || defined( WIN32 )
1182         /* We set LC_ALL manually because it is the only way to set
1183          * the language at runtime under eg. Windows. Beware that this
1184          * makes the environment unconsistent when libvlc is unloaded and
1185          * should probably be moved to a safer place like vlc.c. */
1186         static char psz_lcall[20];
1187         snprintf( psz_lcall, 19, "LC_ALL=%s", psz_lang );
1188         psz_lcall[19] = '\0';
1189         putenv( psz_lcall );
1190 #endif
1191
1192         setlocale( LC_ALL, psz_lang );
1193     }
1194
1195     /* Specify where to find the locales for current domain */
1196 #if !defined( SYS_DARWIN ) && !defined( WIN32 ) && !defined( SYS_BEOS )
1197     psz_path = LOCALEDIR;
1198 #else
1199     snprintf( psz_tmp, sizeof(psz_tmp), "%s/%s", libvlc.psz_vlcpath,
1200               "locale" );
1201     psz_path = psz_tmp;
1202 #endif
1203     if( !bindtextdomain( PACKAGE, psz_path ) )
1204     {
1205         fprintf( stderr, "warning: no domain %s in directory %s\n",
1206                  PACKAGE, psz_path );
1207     }
1208
1209     /* Set the default domain */
1210     textdomain( PACKAGE );
1211
1212 #if defined( SYS_BEOS ) || defined ( SYS_DARWIN ) || \
1213     ( defined( WIN32 ) && !defined( HAVE_INCLUDED_GETTEXT ) )
1214     /* BeOS only support UTF8 strings */
1215     /* Mac OS X prefers UTF8 */
1216     bind_textdomain_codeset( PACKAGE, "UTF-8" );
1217 #endif
1218
1219 #endif
1220 }
1221
1222 /*****************************************************************************
1223  * GetFilenames: parse command line options which are not flags
1224  *****************************************************************************
1225  * Parse command line for input files as well as their associated options.
1226  * An option always follows its associated input and begins with a ":".
1227  *****************************************************************************/
1228 static int GetFilenames( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
1229 {
1230     int i_opt, i_options;
1231
1232     /* We assume that the remaining parameters are filenames
1233      * and their input options */
1234     for( i_opt = i_argc - 1; i_opt >= optind; i_opt-- )
1235     {
1236         i_options = 0;
1237
1238         /* Count the input options */
1239         while( *ppsz_argv[ i_opt ] == ':' && i_opt > optind )
1240         {
1241             i_options++;
1242             i_opt--;
1243         }
1244
1245         /* TODO: write an internal function of this one, to avoid
1246          *       unnecessary lookups. */
1247         VLC_AddTarget( p_vlc->i_object_id, ppsz_argv[ i_opt ],
1248                        (char const **)( i_options ? &ppsz_argv[i_opt + 1] :
1249                                         NULL ), i_options,
1250                        PLAYLIST_INSERT | (i_opt == optind ? PLAYLIST_GO : 0),
1251                        0 );
1252     }
1253
1254     return VLC_SUCCESS;
1255 }
1256
1257 /*****************************************************************************
1258  * Usage: print program usage
1259  *****************************************************************************
1260  * Print a short inline help. Message interface is initialized at this stage.
1261  *****************************************************************************/
1262 static void Usage( vlc_t *p_this, char const *psz_module_name )
1263 {
1264 #define FORMAT_STRING "  %s --%s%s%s%s%s%s%s "
1265     /* short option ------'    |     | | | |  | |
1266      * option name ------------'     | | | |  | |
1267      * <bra -------------------------' | | |  | |
1268      * option type or "" --------------' | |  | |
1269      * ket> -----------------------------' |  | |
1270      * padding spaces ---------------------'  | |
1271      * comment -------------------------------' |
1272      * comment suffix --------------------------'
1273      *
1274      * The purpose of having bra and ket is that we might i18n them as well.
1275      */
1276 #define LINE_START 8
1277 #define PADDING_SPACES 25
1278     vlc_list_t *p_list;
1279     module_t *p_parser;
1280     module_config_t *p_item;
1281     char psz_spaces[PADDING_SPACES+LINE_START+1];
1282     char psz_format[sizeof(FORMAT_STRING)];
1283     char psz_buffer[1000];
1284     char psz_short[4];
1285     int i_index;
1286     int i_width = ConsoleWidth() - (PADDING_SPACES+LINE_START+1);
1287     vlc_bool_t b_advanced = config_GetInt( p_this, "advanced" );
1288
1289     memset( psz_spaces, ' ', PADDING_SPACES+LINE_START );
1290     psz_spaces[PADDING_SPACES+LINE_START] = '\0';
1291
1292     strcpy( psz_format, FORMAT_STRING );
1293
1294 #ifdef WIN32
1295     ShowConsole();
1296 #endif
1297
1298     /* List all modules */
1299     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
1300
1301     /* Enumerate the config for each module */
1302     for( i_index = 0; i_index < p_list->i_count; i_index++ )
1303     {
1304         vlc_bool_t b_help_module;
1305
1306         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
1307
1308         if( psz_module_name && strcmp( psz_module_name,
1309                                        p_parser->psz_object_name ) )
1310         {
1311             continue;
1312         }
1313
1314         /* Ignore modules without config options */
1315         if( !p_parser->i_config_items )
1316         {
1317             continue;
1318         }
1319
1320         /* Ignore modules with only advanced config options if requested */
1321         if( !b_advanced )
1322         {
1323             for( p_item = p_parser->p_config;
1324                  p_item->i_type != CONFIG_HINT_END;
1325                  p_item++ )
1326             {
1327                 if( (p_item->i_type & CONFIG_ITEM) &&
1328                     !p_item->b_advanced ) break;
1329             }
1330             if( p_item->i_type == CONFIG_HINT_END ) continue;
1331         }
1332
1333         /* Print name of module */
1334         if( strcmp( "main", p_parser->psz_object_name ) )
1335         fprintf( stdout, "\n %s\n", p_parser->psz_longname );
1336
1337         b_help_module = !strcmp( "help", p_parser->psz_object_name );
1338
1339         /* Print module options */
1340         for( p_item = p_parser->p_config;
1341              p_item->i_type != CONFIG_HINT_END;
1342              p_item++ )
1343         {
1344             char *psz_text;
1345             char *psz_bra = NULL, *psz_type = NULL, *psz_ket = NULL;
1346             char *psz_suf = "", *psz_prefix = NULL;
1347             int i;
1348
1349             /* Skip advanced options if requested */
1350             if( p_item->b_advanced && !b_advanced )
1351             {
1352                 continue;
1353             }
1354
1355             switch( p_item->i_type )
1356             {
1357             case CONFIG_HINT_CATEGORY:
1358             case CONFIG_HINT_USAGE:
1359                 if( !strcmp( "main", p_parser->psz_object_name ) )
1360                 fprintf( stdout, "\n %s\n", p_item->psz_text );
1361                 break;
1362
1363             case CONFIG_ITEM_STRING:
1364             case CONFIG_ITEM_FILE:
1365             case CONFIG_ITEM_DIRECTORY:
1366             case CONFIG_ITEM_MODULE: /* We could also have "=<" here */
1367                 if( !p_item->ppsz_list )
1368                 {
1369                     psz_bra = " <"; psz_type = _("string"); psz_ket = ">";
1370                     break;
1371                 }
1372                 else
1373                 {
1374                     psz_bra = " {";
1375                     psz_type = psz_buffer;
1376                     psz_type[0] = '\0';
1377                     for( i = 0; p_item->ppsz_list[i]; i++ )
1378                     {
1379                         if( i ) strcat( psz_type, "," );
1380                         strcat( psz_type, p_item->ppsz_list[i] );
1381                     }
1382                     psz_ket = "}";
1383                     break;
1384                 }
1385             case CONFIG_ITEM_INTEGER:
1386             case CONFIG_ITEM_KEY: /* FIXME: do something a bit more clever */
1387                 psz_bra = " <"; psz_type = _("integer"); psz_ket = ">";
1388                 break;
1389             case CONFIG_ITEM_FLOAT:
1390                 psz_bra = " <"; psz_type = _("float"); psz_ket = ">";
1391                 break;
1392             case CONFIG_ITEM_BOOL:
1393                 psz_bra = ""; psz_type = ""; psz_ket = "";
1394                 if( !b_help_module )
1395                 {
1396                     psz_suf = p_item->i_value ? _(" (default enabled)") :
1397                                                 _(" (default disabled)");
1398                 }
1399                 break;
1400             }
1401
1402             if( !psz_type )
1403             {
1404                 continue;
1405             }
1406
1407             /* Add short option if any */
1408             if( p_item->i_short )
1409             {
1410                 sprintf( psz_short, "-%c,", p_item->i_short );
1411             }
1412             else
1413             {
1414                 strcpy( psz_short, "   " );
1415             }
1416
1417             i = PADDING_SPACES - strlen( p_item->psz_name )
1418                  - strlen( psz_bra ) - strlen( psz_type )
1419                  - strlen( psz_ket ) - 1;
1420
1421             if( p_item->i_type == CONFIG_ITEM_BOOL && !b_help_module )
1422             {
1423                 /* If option is of type --foo-bar, we print its counterpart
1424                  * as --no-foo-bar, but if it is of type --foobar (without
1425                  * dashes in the name) we print it as --nofoobar. Both
1426                  * values are of course valid, only the display changes. */
1427                 psz_prefix = strchr( p_item->psz_name, '-' ) ? ", --no-"
1428                                                              : ", --no";
1429                 i -= strlen( p_item->psz_name ) + strlen( psz_prefix );
1430             }
1431
1432             if( i < 0 )
1433             {
1434                 psz_spaces[0] = '\n';
1435                 i = 0;
1436             }
1437             else
1438             {
1439                 psz_spaces[i] = '\0';
1440             }
1441
1442             if( p_item->i_type == CONFIG_ITEM_BOOL && !b_help_module )
1443             {
1444                 fprintf( stdout, psz_format, psz_short, p_item->psz_name,
1445                          psz_prefix, p_item->psz_name, psz_bra, psz_type,
1446                          psz_ket, psz_spaces );
1447             }
1448             else
1449             {
1450                 fprintf( stdout, psz_format, psz_short, p_item->psz_name,
1451                          "", "", psz_bra, psz_type, psz_ket, psz_spaces );
1452             }
1453
1454             psz_spaces[i] = ' ';
1455
1456             /* We wrap the rest of the output */
1457             sprintf( psz_buffer, "%s%s", p_item->psz_text, psz_suf );
1458             psz_text = psz_buffer;
1459             while( *psz_text )
1460             {
1461                 char *psz_parser, *psz_word;
1462                 int i_end = strlen( psz_text );
1463
1464                 /* If the remaining text fits in a line, print it. */
1465                 if( i_end <= i_width )
1466                 {
1467                     fprintf( stdout, "%s\n", psz_text );
1468                     break;
1469                 }
1470
1471                 /* Otherwise, eat as many words as possible */
1472                 psz_parser = psz_text;
1473                 do
1474                 {
1475                     psz_word = psz_parser;
1476                     psz_parser = strchr( psz_word, ' ' );
1477                     /* If no space was found, we reached the end of the text
1478                      * block; otherwise, we skip the space we just found. */
1479                     psz_parser = psz_parser ? psz_parser + 1
1480                                             : psz_text + i_end;
1481
1482                 } while( psz_parser - psz_text <= i_width );
1483
1484                 /* We cut a word in one of these cases:
1485                  *  - it's the only word in the line and it's too long.
1486                  *  - we used less than 80% of the width and the word we are
1487                  *    going to wrap is longer than 40% of the width, and even
1488                  *    if the word would have fit in the next line. */
1489                 if( psz_word == psz_text
1490                      || ( psz_word - psz_text < 80 * i_width / 100
1491                            && psz_parser - psz_word > 40 * i_width / 100 ) )
1492                 {
1493                     char c = psz_text[i_width];
1494                     psz_text[i_width] = '\0';
1495                     fprintf( stdout, "%s\n%s", psz_text, psz_spaces );
1496                     psz_text += i_width;
1497                     psz_text[0] = c;
1498                 }
1499                 else
1500                 {
1501                     psz_word[-1] = '\0';
1502                     fprintf( stdout, "%s\n%s", psz_text, psz_spaces );
1503                     psz_text = psz_word;
1504                 }
1505             }
1506         }
1507     }
1508
1509     /* Release the module list */
1510     vlc_list_release( p_list );
1511
1512 #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
1513     fprintf( stdout, _("\nPress the RETURN key to continue...\n") );
1514     getchar();
1515 #endif
1516 }
1517
1518 /*****************************************************************************
1519  * ListModules: list the available modules with their description
1520  *****************************************************************************
1521  * Print a list of all available modules (builtins and plugins) and a short
1522  * description for each one.
1523  *****************************************************************************/
1524 static void ListModules( vlc_t *p_this )
1525 {
1526     vlc_list_t *p_list;
1527     module_t *p_parser;
1528     char psz_spaces[22];
1529     int i_index;
1530
1531     memset( psz_spaces, ' ', 22 );
1532
1533 #ifdef WIN32
1534     ShowConsole();
1535 #endif
1536
1537     /* Usage */
1538     fprintf( stdout, _("Usage: %s [options] [items]...\n\n"),
1539                      p_this->p_vlc->psz_object_name );
1540
1541     fprintf( stdout, _("[module]              [description]\n") );
1542
1543     /* List all modules */
1544     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
1545
1546     /* Enumerate each module */
1547     for( i_index = 0; i_index < p_list->i_count; i_index++ )
1548     {
1549         int i;
1550
1551         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
1552
1553         /* Nasty hack, but right now I'm too tired to think about a nice
1554          * solution */
1555         i = 22 - strlen( p_parser->psz_object_name ) - 1;
1556         if( i < 0 ) i = 0;
1557         psz_spaces[i] = 0;
1558
1559         fprintf( stdout, "  %s%s %s\n", p_parser->psz_object_name,
1560                          psz_spaces, p_parser->psz_longname );
1561
1562         psz_spaces[i] = ' ';
1563     }
1564
1565     vlc_list_release( p_list );
1566
1567 #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
1568     fprintf( stdout, _("\nPress the RETURN key to continue...\n") );
1569     getchar();
1570 #endif
1571 }
1572
1573 /*****************************************************************************
1574  * Version: print complete program version
1575  *****************************************************************************
1576  * Print complete program version and build number.
1577  *****************************************************************************/
1578 static void Version( void )
1579 {
1580 #ifdef WIN32
1581     ShowConsole();
1582 #endif
1583
1584     fprintf( stdout, VERSION_MESSAGE "\n" );
1585     fprintf( stdout,
1586       _("This program comes with NO WARRANTY, to the extent permitted by "
1587         "law.\nYou may redistribute it under the terms of the GNU General "
1588         "Public License;\nsee the file named COPYING for details.\n"
1589         "Written by the VideoLAN team; see the AUTHORS file.\n") );
1590
1591 #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
1592     fprintf( stdout, _("\nPress the RETURN key to continue...\n") );
1593     getchar();
1594 #endif
1595 }
1596
1597 /*****************************************************************************
1598  * ShowConsole: On Win32, create an output console for debug messages
1599  *****************************************************************************
1600  * This function is useful only on Win32.
1601  *****************************************************************************/
1602 #ifdef WIN32 /*  */
1603 static void ShowConsole( void )
1604 {
1605 #   ifndef UNDER_CE
1606     AllocConsole();
1607     freopen( "CONOUT$", "w", stdout );
1608     freopen( "CONOUT$", "w", stderr );
1609     freopen( "CONIN$", "r", stdin );
1610 #   endif
1611     return;
1612 }
1613 #endif
1614
1615 /*****************************************************************************
1616  * ConsoleWidth: Return the console width in characters
1617  *****************************************************************************
1618  * We use the stty shell command to get the console width; if this fails or
1619  * if the width is less than 80, we default to 80.
1620  *****************************************************************************/
1621 static int ConsoleWidth( void )
1622 {
1623     int i_width = 80;
1624
1625 #ifndef WIN32
1626     char buf[20], *psz_parser;
1627     FILE *file;
1628     int i_ret;
1629
1630     file = popen( "stty size 2>/dev/null", "r" );
1631     if( file )
1632     {
1633         i_ret = fread( buf, 1, 20, file );
1634         if( i_ret > 0 )
1635         {
1636             buf[19] = '\0';
1637             psz_parser = strchr( buf, ' ' );
1638             if( psz_parser )
1639             {
1640                 i_ret = atoi( psz_parser + 1 );
1641                 if( i_ret >= 80 )
1642                 {
1643                     i_width = i_ret;
1644                 }
1645             }
1646         }
1647
1648         pclose( file );
1649     }
1650 #endif
1651
1652     return i_width;
1653 }
1654
1655 static int VerboseCallback( vlc_object_t *p_this, const char *psz_variable,
1656                      vlc_value_t old_val, vlc_value_t new_val, void *param)
1657 {
1658     vlc_t *p_vlc = (vlc_t *)p_this;
1659
1660     if( new_val.i_int >= -1 )
1661     {
1662         p_vlc->p_libvlc->i_verbose = __MIN( new_val.i_int, 2 );
1663     }
1664     return VLC_SUCCESS;
1665 }