]> git.sesse.net Git - vlc/blob - src/libvlc.c
* A few additional MSVC build fixes.
[vlc] / src / libvlc.c
1 /*****************************************************************************
2  * libvlc.c: main libvlc source
3  *****************************************************************************
4  * Copyright (C) 1998-2002 VideoLAN
5  * $Id: libvlc.c,v 1.44 2002/11/09 17:44:08 sam 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 <errno.h>                                                 /* ENOMEM */
37 #include <stdio.h>                                              /* sprintf() */
38 #include <string.h>                                            /* strerror() */
39 #include <stdlib.h>                                                /* free() */
40
41 #include <vlc/vlc.h>
42
43 #ifndef WIN32
44 #   include <netinet/in.h>                            /* BSD: struct in_addr */
45 #endif
46
47 #ifdef HAVE_UNISTD_H
48 #   include <unistd.h>
49 #elif defined( _MSC_VER ) && defined( _WIN32 )
50 #   include <io.h>
51 #endif
52
53 #ifdef WIN32                       /* optind, getopt(), included in unistd.h */
54 #   include "extras/getopt.h"
55 #endif
56
57 #ifdef HAVE_LOCALE_H
58 #   include <locale.h>
59 #endif
60
61 #include "vlc_cpu.h"                                        /* CPU detection */
62 #include "os_specific.h"
63
64 #include "error.h"
65 #include "netutils.h"                                 /* network_ChannelJoin */
66
67 #include "stream_control.h"
68 #include "input_ext-intf.h"
69
70 #include "vlc_playlist.h"
71 #include "interface.h"
72
73 #include "audio_output.h"
74
75 #include "video.h"
76 #include "video_output.h"
77
78 #include "libvlc.h"
79
80 /*****************************************************************************
81  * The evil global variable. We handle it with care, don't worry.
82  *****************************************************************************/
83 static libvlc_t libvlc;
84 static vlc_t *  p_static_vlc;
85
86 /*****************************************************************************
87  * Local prototypes
88  *****************************************************************************/
89 static void SetLanguage   ( char const * );
90 static int  GetFilenames  ( vlc_t *, int, char *[] );
91 static void Usage         ( vlc_t *, char const *psz_module_name );
92 static void ListModules   ( vlc_t * );
93 static void Version       ( void );
94
95 #ifdef WIN32
96 static void ShowConsole   ( void );
97 #endif
98
99 /*****************************************************************************
100  * VLC_Version: return the libvlc version.
101  *****************************************************************************
102  * This function returns full version string (numeric version and codename).
103  *****************************************************************************/
104 char const * VLC_Version( void )
105 {
106     return VERSION_MESSAGE;
107 }
108
109 /*****************************************************************************
110  * VLC_Error: strerror() equivalent
111  *****************************************************************************
112  * This function returns full version string (numeric version and codename).
113  *****************************************************************************/
114 char const * VLC_Error( int i_err )
115 {
116     return vlc_error( i_err );
117 }
118
119 /*****************************************************************************
120  * VLC_Create: allocate a vlc_t structure, and initialize libvlc if needed.
121  *****************************************************************************
122  * This function allocates a vlc_t structure and returns a negative value
123  * in case of failure. Also, the thread system is initialized.
124  *****************************************************************************/
125 int VLC_Create( void )
126 {
127     int i_ret;
128     vlc_t * p_vlc = NULL;
129     vlc_value_t lockval;
130
131     /* vlc_threads_init *must* be the first internal call! No other call is
132      * allowed before the thread system has been initialized. */
133     i_ret = vlc_threads_init( &libvlc );
134     if( i_ret < 0 )
135     {
136         return i_ret;
137     }
138
139     /* Now that the thread system is initialized, we don't have much, but
140      * at least we have var_Create */
141     var_Create( &libvlc, "libvlc", VLC_VAR_MUTEX );
142     var_Get( &libvlc, "libvlc", &lockval );
143     vlc_mutex_lock( lockval.p_address );
144     if( !libvlc.b_ready )
145     {
146         char *psz_env;
147
148         /* Guess what CPU we have */
149         libvlc.i_cpu = CPUCapabilities();
150
151         /* Find verbosity from VLC_VERBOSE environment variable */
152         psz_env = getenv( "VLC_VERBOSE" );
153         libvlc.i_verbose = psz_env ? atoi( psz_env ) : -1;
154
155 #ifdef HAVE_ISATTY
156         libvlc.b_color = isatty( 2 ); /* 2 is for stderr */
157 #else
158         libvlc.b_color = VLC_FALSE;
159 #endif
160
161         /* Initialize message queue */
162         msg_Create( &libvlc );
163
164         /* Announce who we are */
165         msg_Dbg( &libvlc, COPYRIGHT_MESSAGE );
166         msg_Dbg( &libvlc, "libvlc was configured with %s", CONFIGURE_LINE );
167
168         /* Initialize the module bank and load the configuration of the
169          * main module. We need to do this at this stage to be able to display
170          * a short help if required by the user. (short help == main module
171          * options) */
172         module_InitBank( &libvlc );
173         module_LoadMain( &libvlc );
174
175         libvlc.b_ready = VLC_TRUE;
176     }
177     vlc_mutex_unlock( lockval.p_address );
178     var_Destroy( &libvlc, "libvlc" );
179
180     /* Allocate a vlc object */
181     p_vlc = vlc_object_create( &libvlc, VLC_OBJECT_VLC );
182     if( p_vlc == NULL )
183     {
184         return VLC_EGENERIC;
185     }
186
187     p_vlc->psz_object_name = "root";
188
189     /* Initialize mutexes */
190     vlc_mutex_init( p_vlc, &p_vlc->config_lock );
191
192     /* Store our newly allocated structure in the global list */
193     vlc_object_attach( p_vlc, &libvlc );
194
195     /* Store data for the non-reentrant API */
196     p_static_vlc = p_vlc;
197
198     return p_vlc->i_object_id;
199 }
200
201 /*****************************************************************************
202  * VLC_Init: initialize a vlc_t structure.
203  *****************************************************************************
204  * This function initializes a previously allocated vlc_t structure:
205  *  - CPU detection
206  *  - gettext initialization
207  *  - message queue, module bank and playlist initialization
208  *  - configuration and commandline parsing
209  *****************************************************************************/
210 int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
211 {
212     char         p_capabilities[200];
213     char *       p_tmp;
214     vlc_bool_t   b_exit;
215     vlc_t *      p_vlc;
216     module_t    *p_help_module;
217     playlist_t  *p_playlist;
218
219     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
220
221     if( !p_vlc )
222     {
223         return VLC_ENOOBJ;
224     }
225
226     /*
227      * Support for gettext
228      */
229     SetLanguage( "" );
230
231     /*
232      * System specific initialization code
233      */
234     system_Init( p_vlc, &i_argc, ppsz_argv );
235
236     /* Get the executable name (similar to the basename command) */
237     if( i_argc > 0 )
238     {
239         p_vlc->psz_object_name = p_tmp = ppsz_argv[ 0 ];
240         while( *p_tmp )
241         {
242             if( *p_tmp == '/' ) p_vlc->psz_object_name = ++p_tmp;
243             else ++p_tmp;
244         }
245     }
246     else
247     {
248         p_vlc->psz_object_name = "vlc";
249     }
250
251     /* Hack: insert the help module here */
252     p_help_module = vlc_object_create( p_vlc, VLC_OBJECT_MODULE );
253     if( p_help_module == NULL )
254     {
255         //module_EndBank( p_vlc );
256         return VLC_EGENERIC;
257     }
258     p_help_module->psz_object_name = "help";
259     config_Duplicate( p_help_module, p_help_config );
260     vlc_object_attach( p_help_module, libvlc.p_module_bank );
261     /* End hack */
262
263     if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
264     {
265         vlc_object_detach( p_help_module );
266         config_Free( p_help_module );
267         vlc_object_destroy( p_help_module );
268         //module_EndBank( p_vlc );
269         return VLC_EGENERIC;
270     }
271
272     b_exit = VLC_FALSE;
273
274     /* Check for short help option */
275     if( config_GetInt( p_vlc, "help" ) )
276     {
277         fprintf( stderr, _("Usage: %s [options] [items]...\n\n"),
278                          p_vlc->psz_object_name );
279         Usage( p_vlc, "main" );
280         Usage( p_vlc, "help" );
281         b_exit = VLC_TRUE;
282     }
283     /* Check for version option */
284     else if( config_GetInt( p_vlc, "version" ) )
285     {
286         Version();
287         b_exit = VLC_TRUE;
288     }
289
290     /* Hack: remove the help module here */
291     vlc_object_detach( p_help_module );
292     /* End hack */
293
294     if( b_exit )
295     {
296         config_Free( p_help_module );
297         vlc_object_destroy( p_help_module );
298         //module_EndBank( p_vlc );
299         return VLC_EEXIT;
300     }
301
302     /*
303      * Load the builtins and plugins into the module_bank.
304      * We have to do it before config_Load*() because this also gets the
305      * list of configuration options exported by each module and loads their
306      * default values.
307      */
308     module_LoadBuiltins( &libvlc );
309     module_LoadPlugins( &libvlc );
310     msg_Dbg( p_vlc, "module bank initialized, found %i modules",
311                     libvlc.p_module_bank->i_children );
312
313     /* Hack: insert the help module here */
314     vlc_object_attach( p_help_module, libvlc.p_module_bank );
315     /* End hack */
316
317     /* Check for help on modules */
318     if( (p_tmp = config_GetPsz( p_vlc, "module" )) )
319     {
320         Usage( p_vlc, p_tmp );
321         free( p_tmp );
322         b_exit = VLC_TRUE;
323     }
324     /* Check for long help option */
325     else if( config_GetInt( p_vlc, "longhelp" ) )
326     {
327         Usage( p_vlc, NULL );
328         b_exit = VLC_TRUE;
329     }
330     /* Check for module list option */
331     else if( config_GetInt( p_vlc, "list" ) )
332     {
333         ListModules( p_vlc );
334         b_exit = VLC_TRUE;
335     }
336
337     /* Hack: remove the help module here */
338     vlc_object_detach( p_help_module );
339     config_Free( p_help_module );
340     vlc_object_destroy( p_help_module );
341     /* End hack */
342
343     if( b_exit )
344     {
345         //module_EndBank( p_vlc );
346         return VLC_EEXIT;
347     }
348
349     /*
350      * Override default configuration with config file settings
351      */
352     p_vlc->psz_homedir = config_GetHomeDir();
353     config_LoadConfigFile( p_vlc, NULL );
354
355     /*
356      * Override configuration with command line settings
357      */
358     if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
359     {
360 #ifdef WIN32
361         ShowConsole();
362         /* Pause the console because it's destroyed when we exit */
363         fprintf( stderr, "The command line options couldn't be loaded, check "
364                  "that they are valid.\nPress the RETURN key to continue..." );
365         getchar();
366 #endif
367         //module_EndBank( p_vlc );
368         return VLC_EGENERIC;
369     }
370
371     /*
372      * System specific configuration
373      */
374     system_Configure( p_vlc );
375
376     /*
377      * Message queue options
378      */
379     if( config_GetInt( p_vlc, "quiet" ) )
380     {
381         libvlc.i_verbose = -1;
382     }
383     else
384     {
385         int i_tmp = config_GetInt( p_vlc, "verbose" );
386         if( i_tmp >= 0 )
387         {
388             libvlc.i_verbose = __MIN( i_tmp, 2 );
389         }
390     }
391     libvlc.b_color = libvlc.b_color || config_GetInt( p_vlc, "color" );
392
393     /*
394      * Output messages that may still be in the queue
395      */
396     msg_Flush( p_vlc );
397
398     /* p_vlc inititalization. FIXME ? */
399     p_vlc->i_desync = config_GetInt( p_vlc, "desync" ) * (mtime_t)1000;
400
401 #if defined( __i386__ )
402     if( !config_GetInt( p_vlc, "mmx" ) )
403         libvlc.i_cpu &= ~CPU_CAPABILITY_MMX;
404     if( !config_GetInt( p_vlc, "3dn" ) )
405         libvlc.i_cpu &= ~CPU_CAPABILITY_3DNOW;
406     if( !config_GetInt( p_vlc, "mmxext" ) )
407         libvlc.i_cpu &= ~CPU_CAPABILITY_MMXEXT;
408     if( !config_GetInt( p_vlc, "sse" ) )
409         libvlc.i_cpu &= ~CPU_CAPABILITY_SSE;
410 #endif
411 #if defined( __powerpc__ ) || defined( SYS_DARWIN )
412     if( !config_GetInt( p_vlc, "altivec" ) )
413         libvlc.i_cpu &= ~CPU_CAPABILITY_ALTIVEC;
414 #endif
415
416 #define PRINT_CAPABILITY( capability, string )                              \
417     if( libvlc.i_cpu & capability )                                         \
418     {                                                                       \
419         strncat( p_capabilities, string " ",                                \
420                  sizeof(p_capabilities) - strlen(p_capabilities) );         \
421         p_capabilities[sizeof(p_capabilities) - 1] = '\0';                  \
422     }
423
424     p_capabilities[0] = '\0';
425     PRINT_CAPABILITY( CPU_CAPABILITY_486, "486" );
426     PRINT_CAPABILITY( CPU_CAPABILITY_586, "586" );
427     PRINT_CAPABILITY( CPU_CAPABILITY_PPRO, "Pentium Pro" );
428     PRINT_CAPABILITY( CPU_CAPABILITY_MMX, "MMX" );
429     PRINT_CAPABILITY( CPU_CAPABILITY_3DNOW, "3DNow!" );
430     PRINT_CAPABILITY( CPU_CAPABILITY_MMXEXT, "MMXEXT" );
431     PRINT_CAPABILITY( CPU_CAPABILITY_SSE, "SSE" );
432     PRINT_CAPABILITY( CPU_CAPABILITY_ALTIVEC, "AltiVec" );
433     PRINT_CAPABILITY( CPU_CAPABILITY_FPU, "FPU" );
434     msg_Dbg( p_vlc, "CPU has capabilities %s", p_capabilities );
435
436     /*
437      * Choose the best memcpy module
438      */
439     p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy" );
440
441     if( p_vlc->pf_memcpy == NULL )
442     {
443         p_vlc->pf_memcpy = memcpy;
444     }
445
446     if( p_vlc->pf_memset == NULL )
447     {
448         p_vlc->pf_memset = memset;
449     }
450
451     /*
452      * Initialize shared resources and libraries
453      */
454     if( config_GetInt( p_vlc, "network-channel" )
455          && network_ChannelCreate( p_vlc ) )
456     {
457         /* On error during Channels initialization, switch off channels */
458         msg_Warn( p_vlc,
459                   "channels initialization failed, deactivating channels" );
460         config_PutInt( p_vlc, "network-channel", VLC_FALSE );
461     }
462
463     /*
464      * Initialize playlist and get commandline files
465      */
466     p_playlist = playlist_Create( p_vlc );
467     if( !p_playlist )
468     {
469         msg_Err( p_vlc, "playlist initialization failed" );
470         if( p_vlc->p_memcpy_module != NULL )
471         {
472             module_Unneed( p_vlc, p_vlc->p_memcpy_module );
473         }
474         //module_EndBank( p_vlc );
475         return VLC_EGENERIC;
476     }
477
478     /*
479      * Get input filenames given as commandline arguments
480      */
481     GetFilenames( p_vlc, i_argc, ppsz_argv );
482
483     return VLC_SUCCESS;
484 }
485
486 /*****************************************************************************
487  * VLC_AddIntf: add an interface
488  *****************************************************************************
489  * This function opens an interface plugin and runs it. If b_block is set
490  * to 0, VLC_AddIntf will return immediately and let the interface run in a
491  * separate thread. If b_block is set to 1, VLC_AddIntf will continue until
492  * user requests to quit.
493  *****************************************************************************/
494 int VLC_AddIntf( int i_object, char const *psz_module, vlc_bool_t b_block )
495 {
496     int i_err;
497     intf_thread_t *p_intf;
498     vlc_t *p_vlc;
499     char *psz_oldmodule = NULL;
500
501     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
502
503     if( !p_vlc )
504     {
505         return VLC_ENOOBJ;
506     }
507
508     if( psz_module )
509     {
510         psz_oldmodule = config_GetPsz( p_vlc, "intf" );
511         config_PutPsz( p_vlc, "intf", psz_module );
512     }
513
514     /* Try to create the interface */
515     p_intf = intf_Create( p_vlc );
516
517     if( psz_module )
518     {
519         config_PutPsz( p_vlc, "intf", psz_oldmodule );
520         if( psz_oldmodule )
521         {
522             free( psz_oldmodule );
523         }
524     }
525
526     if( p_intf == NULL )
527     {
528         msg_Err( p_vlc, "interface initialization failed" );
529         return VLC_EGENERIC;
530     }
531
532     /* Try to run the interface */
533     p_intf->b_block = b_block;
534     i_err = intf_RunThread( p_intf );
535     if( i_err )
536     {
537         vlc_object_detach( p_intf );
538         intf_Destroy( p_intf );
539         return i_err;
540     }
541
542     return VLC_SUCCESS;
543 }
544
545 /*****************************************************************************
546  * VLC_Destroy: stop playing and destroy everything.
547  *****************************************************************************
548  * This function requests the running threads to finish, waits for their
549  * termination, and destroys their structure.
550  *****************************************************************************/
551 int VLC_Destroy( int i_object )
552 {
553     vlc_t *p_vlc;
554
555     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
556
557     if( !p_vlc )
558     {
559         return VLC_ENOOBJ;
560     }
561
562     /*
563      * Go back into channel 0 which is the network
564      */
565     if( config_GetInt( p_vlc, "network-channel" ) && p_vlc->p_channel )
566     {
567         network_ChannelJoin( p_vlc, COMMON_CHANNEL );
568     }
569     
570     /*
571      * Free allocated memory
572      */
573     if( p_vlc->p_memcpy_module )
574     {
575         module_Unneed( p_vlc, p_vlc->p_memcpy_module );
576         p_vlc->p_memcpy_module = NULL;
577     }
578
579     if( p_vlc->psz_homedir )
580     {
581         free( p_vlc->psz_homedir );
582         p_vlc->psz_homedir = NULL;
583     }
584
585     /*
586      * XXX: Free module bank !
587      */
588     //module_EndBank( p_vlc );
589     
590     /*
591      * System specific cleaning code
592      */
593     system_End( p_vlc );
594     
595     /* Destroy mutexes */
596     vlc_mutex_destroy( &p_vlc->config_lock );
597
598     vlc_object_detach( p_vlc );
599
600     vlc_object_destroy( p_vlc );
601
602     /* Stop thread system: last one out please shut the door! */
603     vlc_threads_end( &libvlc );
604
605     return VLC_SUCCESS;
606 }
607
608 /*****************************************************************************
609  * VLC_Die: ask vlc to die.
610  *****************************************************************************
611  * This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
612  * task. It is your duty to call vlc_end and VLC_Destroy afterwards.
613  *****************************************************************************/
614 int VLC_Die( int i_object )
615 {
616     vlc_t *p_vlc;
617
618     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
619
620     if( !p_vlc )
621     {
622         return VLC_ENOOBJ;
623     }
624
625     p_vlc->b_die = VLC_TRUE;
626
627     return VLC_SUCCESS;
628 }
629
630 /*****************************************************************************
631  * VLC_AddTarget: adds a target for playing.
632  *****************************************************************************
633  * This function adds psz_target to the current playlist. If a playlist does
634  * not exist, it will create one.
635  *****************************************************************************/
636 int VLC_AddTarget( int i_object, char const *psz_target, int i_mode, int i_pos )
637 {
638     int i_err;
639     playlist_t *p_playlist;
640     vlc_t *p_vlc;
641
642     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
643
644     if( !p_vlc )
645     {
646         return VLC_ENOOBJ;
647     }
648
649     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
650
651     if( p_playlist == NULL )
652     {
653         msg_Dbg( p_vlc, "no playlist present, creating one" );
654         p_playlist = playlist_Create( p_vlc );
655
656         if( p_playlist == NULL )
657         {
658             return VLC_EGENERIC;
659         }
660
661         vlc_object_yield( p_playlist );
662     }
663
664     i_err = playlist_Add( p_playlist, psz_target, i_mode, i_pos );
665
666     vlc_object_release( p_playlist );
667
668     return i_err;
669 }
670
671 /*****************************************************************************
672  * VLC_Set: set a vlc variable
673  *****************************************************************************
674  *
675  *****************************************************************************/
676 int VLC_Set( int i_object, char const *psz_var, vlc_value_t value )
677 {
678     vlc_t *p_vlc;
679
680     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
681
682     if( !p_vlc )
683     {
684         return VLC_ENOOBJ;
685     }
686
687     /* FIXME: Temporary hack for Mozilla, if variable starts with conf:: then
688      * we handle it as a configuration variable. Don't tell Gildas :) -- sam */
689     if( !strncmp( psz_var, "conf::", 6 ) )
690     {
691         module_config_t *p_item;
692         char const *psz_newvar = psz_var + 6;
693
694         p_item = config_FindConfig( VLC_OBJECT(p_vlc), psz_newvar );
695
696         if( p_item )
697         {
698             switch( p_item->i_type )
699             {
700                 case CONFIG_ITEM_BOOL:
701                     config_PutInt( p_vlc, psz_newvar, value.b_bool );
702                     break;
703                 case CONFIG_ITEM_INTEGER:
704                     config_PutInt( p_vlc, psz_newvar, value.i_int );
705                     break;
706                 case CONFIG_ITEM_FLOAT:
707                     config_PutFloat( p_vlc, psz_newvar, value.f_float );
708                     break;
709                 default:
710                     config_PutPsz( p_vlc, psz_newvar, value.psz_string );
711                     break;
712             }
713             return VLC_SUCCESS;
714         }
715     }
716
717     return var_Set( p_vlc, psz_var, value );
718 }
719
720 /*****************************************************************************
721  * VLC_Get: get a vlc variable
722  *****************************************************************************
723  *
724  *****************************************************************************/
725 int VLC_Get( int i_object, char const *psz_var, vlc_value_t *p_value )
726 {
727     vlc_t *p_vlc;
728
729     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
730
731     if( !p_vlc )
732     {
733         return VLC_ENOOBJ;
734     }
735
736     return var_Get( p_vlc, psz_var, p_value );
737 }
738
739 /* FIXME: temporary hacks */
740
741 /*****************************************************************************
742  * VLC_Play: play
743  *****************************************************************************/
744 int VLC_Play( int i_object )
745 {
746     playlist_t * p_playlist;
747     vlc_t *p_vlc;
748
749     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
750
751     /* Check that the handle is valid */
752     if( !p_vlc )
753     {
754         return VLC_ENOOBJ;
755     }
756
757     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
758
759     if( !p_playlist )
760     {
761         return VLC_ENOOBJ;
762     }
763
764     vlc_mutex_lock( &p_playlist->object_lock );
765     if( p_playlist->i_size )
766     {
767         vlc_mutex_unlock( &p_playlist->object_lock );
768         playlist_Play( p_playlist );
769     }
770     else
771     {
772         vlc_mutex_unlock( &p_playlist->object_lock );
773     }
774
775     vlc_object_release( p_playlist );
776
777     return VLC_SUCCESS;
778 }
779
780 /*****************************************************************************
781  * VLC_Stop: stop
782  *****************************************************************************/
783 int VLC_Stop( int i_object )
784 {
785     intf_thread_t *   p_intf;
786     playlist_t    *   p_playlist;
787     vout_thread_t *   p_vout;
788     aout_instance_t * p_aout;
789     vlc_t *p_vlc;
790
791     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
792
793     /* Check that the handle is valid */
794     if( !p_vlc )
795     {
796         return VLC_ENOOBJ;
797     }
798
799     /*
800      * Ask the interfaces to stop and destroy them
801      */
802     msg_Dbg( p_vlc, "removing all interfaces" );
803     while( (p_intf = vlc_object_find( p_vlc, VLC_OBJECT_INTF, FIND_CHILD )) )
804     {
805         intf_StopThread( p_intf );
806         vlc_object_detach( p_intf );
807         vlc_object_release( p_intf );
808         intf_Destroy( p_intf );
809     }
810
811     /*
812      * Free playlists
813      */
814     msg_Dbg( p_vlc, "removing all playlists" );
815     while( (p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST,
816                                           FIND_CHILD )) )
817     {
818         vlc_object_detach( p_playlist );
819         vlc_object_release( p_playlist );
820         playlist_Destroy( p_playlist );
821     }
822
823     /*
824      * Free video outputs
825      */
826     msg_Dbg( p_vlc, "removing all video outputs" );
827     while( (p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD )) )
828     {
829         vlc_object_detach( p_vout );
830         vlc_object_release( p_vout );
831         vout_DestroyThread( p_vout );
832     }
833
834     /*
835      * Free audio outputs
836      */
837     msg_Dbg( p_vlc, "removing all audio outputs" );
838     while( (p_aout = vlc_object_find( p_vlc, VLC_OBJECT_AOUT, FIND_CHILD )) )
839     {
840         vlc_object_detach( (vlc_object_t *)p_aout );
841         vlc_object_release( (vlc_object_t *)p_aout );
842         aout_Delete( p_aout );
843     }
844
845     return VLC_SUCCESS;
846 }
847
848 /*****************************************************************************
849  * VLC_Pause: toggle pause
850  *****************************************************************************/
851 int VLC_Pause( int i_object )
852 {
853     input_thread_t *p_input;
854     vlc_t *p_vlc;
855
856     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
857
858     if( !p_vlc )
859     {
860         return VLC_ENOOBJ;
861     }
862
863     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
864
865     if( !p_input )
866     {
867         return VLC_ENOOBJ;
868     }
869
870     input_SetStatus( p_input, INPUT_STATUS_PAUSE );
871     vlc_object_release( p_input );
872
873     return VLC_SUCCESS;
874 }
875
876 /*****************************************************************************
877  * VLC_FullScreen: toggle fullscreen mode
878  *****************************************************************************/
879 int VLC_FullScreen( int i_object )
880 {
881     vout_thread_t *p_vout;
882     vlc_t *p_vlc;
883
884     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
885
886     if( !p_vlc )
887     {
888         return VLC_ENOOBJ;
889     }
890
891     p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD );
892
893     if( !p_vout )
894     {
895         return VLC_ENOOBJ;
896     }
897
898     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
899     vlc_object_release( p_vout );
900
901     return VLC_SUCCESS;
902 }
903
904 /* following functions are local */
905
906 /*****************************************************************************
907  * SetLanguage: set the interface language.
908  *****************************************************************************
909  * We set the LC_MESSAGES locale category for interface messages and buttons,
910  * as well as the LC_CTYPE category for string sorting and possible wide
911  * character support.
912  *****************************************************************************/
913 static void SetLanguage ( char const *psz_lang )
914 {
915 #if defined( ENABLE_NLS ) \
916      && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
917
918 #   if defined( HAVE_INCLUDED_GETTEXT ) && !defined( HAVE_LC_MESSAGES )
919     if( *psz_lang )
920     {
921         /* We set LC_ALL manually because it is the only way to set
922          * the language at runtime under eg. Windows. Beware that this
923          * makes the environment unconsistent when libvlc is unloaded and
924          * should probably be moved to a safer place like vlc.c. */
925         static char psz_lcall[20];
926         snprintf( psz_lcall, 19, "LC_ALL=%s", psz_lang );
927         psz_lcall[19] = '\0';
928         putenv( psz_lcall );
929     }
930 #   endif
931
932 #   if defined( HAVE_LC_MESSAGES )
933     setlocale( LC_MESSAGES, psz_lang );
934 #   endif
935     setlocale( LC_CTYPE, psz_lang );
936
937     /* Specify where to find the locales for current domain */
938     if( !bindtextdomain( PACKAGE, LOCALEDIR ) )
939     {
940         fprintf( stderr, "warning: no domain %s in directory %s\n",
941                  PACKAGE, LOCALEDIR );
942     }
943
944     /* Set the default domain */
945     textdomain( PACKAGE );
946 #endif
947 }
948
949 /*****************************************************************************
950  * GetFilenames: parse command line options which are not flags
951  *****************************************************************************
952  * Parse command line for input files.
953  *****************************************************************************/
954 static int GetFilenames( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
955 {
956     int i_opt;
957
958     /* We assume that the remaining parameters are filenames */
959     for( i_opt = i_argc - 1; i_opt > optind; i_opt-- )
960     {
961         /* TODO: write an internal function of this one, to avoid
962          *       unnecessary lookups. */
963         VLC_AddTarget( p_vlc->i_object_id, ppsz_argv[ i_opt ],
964                        PLAYLIST_INSERT, 0 );
965     }
966
967     /* If there is at least one target, play it */
968     if( i_argc > optind )
969     {
970         VLC_AddTarget( p_vlc->i_object_id, ppsz_argv[ optind ],
971                        PLAYLIST_INSERT | PLAYLIST_GO, 0 );
972     }
973
974     return VLC_SUCCESS;
975 }
976
977 /*****************************************************************************
978  * Usage: print program usage
979  *****************************************************************************
980  * Print a short inline help. Message interface is initialized at this stage.
981  *****************************************************************************/
982 static void Usage( vlc_t *p_this, char const *psz_module_name )
983 {
984 #define FORMAT_STRING "      --%s%s%s%s%s%s%s %s%s\n"
985     /* option name -------------'     | | | |  | |
986      * <bra --------------------------' | | |  | |
987      * option type or "" ---------------' | |  | |
988      * ket> ------------------------------' |  | |
989      * padding spaces ----------------------'  | |
990      * comment --------------------------------' |
991      * comment suffix ---------------------------'
992      *
993      * The purpose of having bra and ket is that we might i18n them as well.
994      */
995 #define LINE_START 8
996 #define PADDING_SPACES 25
997     vlc_list_t *p_list;
998     module_t **pp_parser;
999     module_config_t *p_item;
1000     char psz_spaces[PADDING_SPACES+LINE_START+1];
1001     char psz_format[sizeof(FORMAT_STRING)];
1002
1003     memset( psz_spaces, ' ', PADDING_SPACES+LINE_START );
1004     psz_spaces[PADDING_SPACES+LINE_START] = '\0';
1005
1006     strcpy( psz_format, FORMAT_STRING );
1007
1008 #ifdef WIN32
1009     ShowConsole();
1010 #endif
1011
1012     /* List all modules */
1013     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
1014
1015     /* Enumerate the config for each module */
1016     for( pp_parser = (module_t **)p_list->pp_objects ;
1017          *pp_parser ;
1018          pp_parser++ )
1019     {
1020         vlc_bool_t b_help_module;
1021
1022         if( psz_module_name && strcmp( psz_module_name,
1023                                        (*pp_parser)->psz_object_name ) )
1024         {
1025             continue;
1026         }
1027
1028         /* Ignore modules without config options */
1029         if( !(*pp_parser)->i_config_items )
1030         {
1031             continue;
1032         }
1033
1034         b_help_module = !strcmp( "help", (*pp_parser)->psz_object_name );
1035
1036         /* Print module options */
1037         for( p_item = (*pp_parser)->p_config;
1038              p_item->i_type != CONFIG_HINT_END;
1039              p_item++ )
1040         {
1041             char *psz_bra = NULL, *psz_type = NULL, *psz_ket = NULL;
1042             char *psz_suf = "", *psz_prefix = NULL;
1043             int i;
1044
1045             switch( p_item->i_type )
1046             {
1047             case CONFIG_HINT_CATEGORY:
1048             case CONFIG_HINT_USAGE:
1049                 fprintf( stderr, " %s\n", p_item->psz_text );
1050                 break;
1051
1052             case CONFIG_ITEM_STRING:
1053             case CONFIG_ITEM_FILE:
1054             case CONFIG_ITEM_MODULE: /* We could also have "=<" here */
1055                 if( !p_item->ppsz_list )
1056                 {
1057                     psz_bra = " <"; psz_type = _("string"); psz_ket = ">";
1058                     break;
1059                 }
1060                 else
1061                 {
1062                     psz_bra = " [";
1063                     psz_type = malloc( 1000 );
1064                     memset( psz_type, 0, 1000 );
1065                     for( i=0; p_item->ppsz_list[i]; i++ )
1066                     {
1067                         strcat( psz_type, p_item->ppsz_list[i] );
1068                         strcat( psz_type, "|" );
1069                     }
1070                     psz_type[ strlen( psz_type ) - 1 ] = '\0';
1071                     psz_ket = "]";
1072                     break;
1073                 }
1074             case CONFIG_ITEM_INTEGER:
1075                 psz_bra = " <"; psz_type = _("integer"); psz_ket = ">";
1076                 break;
1077             case CONFIG_ITEM_FLOAT:
1078                 psz_bra = " <"; psz_type = _("float"); psz_ket = ">";
1079                 break;
1080             case CONFIG_ITEM_BOOL:
1081                 psz_bra = ""; psz_type = ""; psz_ket = "";
1082                 if( !b_help_module )
1083                 {
1084                     psz_suf = p_item->i_value ? _(" (default enabled)") :
1085                                                 _(" (default disabled)");
1086                 }
1087                 break;
1088             }
1089
1090             /* Add short option if any */
1091             if( p_item->i_short )
1092             {
1093                 psz_format[2] = '-';
1094                 psz_format[3] = p_item->i_short;
1095                 psz_format[4] = ',';
1096             }
1097             else
1098             {
1099                 psz_format[2] = ' ';
1100                 psz_format[3] = ' ';
1101                 psz_format[4] = ' ';
1102             }
1103
1104             if( psz_type )
1105             {
1106                 i = PADDING_SPACES - strlen( p_item->psz_name )
1107                      - strlen( psz_bra ) - strlen( psz_type )
1108                      - strlen( psz_ket ) - 1;
1109                 if( p_item->i_type == CONFIG_ITEM_BOOL
1110                      && !b_help_module )
1111                 {
1112                     /* If option is of type --foo-bar, we print its counterpart
1113                      * as --no-foo-bar, but if it is of type --foobar (without
1114                      * dashes in the name) we print it as --nofoobar. Both
1115                      * values are of course valid, only the display changes. */
1116                     vlc_bool_t b_dash = VLC_FALSE;
1117                     psz_prefix = p_item->psz_name;
1118                     while( *psz_prefix )
1119                     {
1120                         if( *psz_prefix++ == '-' )
1121                         {
1122                             b_dash = VLC_TRUE;
1123                             break;
1124                         }
1125                     }
1126
1127                     if( b_dash )
1128                     {
1129                         psz_prefix = ", --no-";
1130                         i -= strlen( p_item->psz_name ) + strlen( ", --no-" );
1131                     }
1132                     else
1133                     {
1134                         psz_prefix = ", --no";
1135                         i -= strlen( p_item->psz_name ) + strlen( ", --no" );
1136                     }
1137                 }
1138
1139                 if( i < 0 )
1140                 {
1141                     i = 0;
1142                     psz_spaces[i] = '\n';
1143                 }
1144                 else
1145                 {
1146                     psz_spaces[i] = '\0';
1147                 }
1148
1149                 if( p_item->i_type == CONFIG_ITEM_BOOL &&
1150                     !b_help_module )
1151                 {
1152                     fprintf( stderr, psz_format, p_item->psz_name, psz_prefix,
1153                              p_item->psz_name, psz_bra, psz_type, psz_ket,
1154                              psz_spaces, p_item->psz_text, psz_suf );
1155                 }
1156                 else
1157                 {
1158                     fprintf( stderr, psz_format, p_item->psz_name, "", "",
1159                              psz_bra, psz_type, psz_ket, psz_spaces,
1160                              p_item->psz_text, psz_suf );
1161                 }
1162                 psz_spaces[i] = ' ';
1163                 if ( p_item->ppsz_list )
1164                 {
1165                     free( psz_type );
1166                 }
1167             }
1168         }
1169     }
1170
1171     /* Release the module list */
1172     vlc_list_release( p_list );
1173
1174 #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
1175         fprintf( stderr, _("\nPress the RETURN key to continue...\n") );
1176         getchar();
1177 #endif
1178 }
1179
1180 /*****************************************************************************
1181  * ListModules: list the available modules with their description
1182  *****************************************************************************
1183  * Print a list of all available modules (builtins and plugins) and a short
1184  * description for each one.
1185  *****************************************************************************/
1186 static void ListModules( vlc_t *p_this )
1187 {
1188     vlc_list_t *p_list;
1189     module_t **pp_parser;
1190     char psz_spaces[22];
1191
1192     memset( psz_spaces, ' ', 22 );
1193
1194 #ifdef WIN32
1195     ShowConsole();
1196 #endif
1197
1198     /* Usage */
1199     fprintf( stderr, _("Usage: %s [options] [items]...\n\n"),
1200                      p_this->p_vlc->psz_object_name );
1201
1202     fprintf( stderr, _("[module]              [description]\n") );
1203
1204     /* List all modules */
1205     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
1206
1207     /* Enumerate each module */
1208     for( pp_parser = (module_t **)p_list->pp_objects ;
1209          *pp_parser ;
1210          pp_parser++ )
1211     {
1212         int i;
1213
1214         /* Nasty hack, but right now I'm too tired to think about a nice
1215          * solution */
1216         i = 22 - strlen( (*pp_parser)->psz_object_name ) - 1;
1217         if( i < 0 ) i = 0;
1218         psz_spaces[i] = 0;
1219
1220         fprintf( stderr, "  %s%s %s\n", (*pp_parser)->psz_object_name,
1221                          psz_spaces, (*pp_parser)->psz_longname );
1222
1223         psz_spaces[i] = ' ';
1224     }
1225
1226     vlc_list_release( p_list );
1227
1228 #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
1229         fprintf( stderr, _("\nPress the RETURN key to continue...\n") );
1230         getchar();
1231 #endif
1232 }
1233
1234 /*****************************************************************************
1235  * Version: print complete program version
1236  *****************************************************************************
1237  * Print complete program version and build number.
1238  *****************************************************************************/
1239 static void Version( void )
1240 {
1241 #ifdef WIN32
1242     ShowConsole();
1243 #endif
1244
1245     fprintf( stderr, VERSION_MESSAGE "\n" );
1246     fprintf( stderr,
1247       _("This program comes with NO WARRANTY, to the extent permitted by "
1248         "law.\nYou may redistribute it under the terms of the GNU General "
1249         "Public License;\nsee the file named COPYING for details.\n"
1250         "Written by the VideoLAN team at Ecole Centrale, Paris.\n") );
1251
1252 #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
1253     fprintf( stderr, _("\nPress the RETURN key to continue...\n") );
1254     getchar();
1255 #endif
1256 }
1257
1258 /*****************************************************************************
1259  * ShowConsole: On Win32, create an output console for debug messages
1260  *****************************************************************************
1261  * This function is useful only on Win32.
1262  *****************************************************************************/
1263 #ifdef WIN32 /*  */
1264 static void ShowConsole( void )
1265 {
1266     AllocConsole();
1267     freopen( "CONOUT$", "w", stdout );
1268     freopen( "CONOUT$", "w", stderr );
1269     freopen( "CONIN$", "r", stdin );
1270     return;
1271 }
1272 #endif
1273