1 /*****************************************************************************
2 * libvlc.c: main libvlc source
3 *****************************************************************************
4 * Copyright (C) 1998-2002 VideoLAN
5 * $Id: libvlc.c,v 1.33 2002/09/29 18:19:53 sam Exp $
7 * Authors: Vincent Seguin <seguin@via.ecp.fr>
8 * Samuel Hocevar <sam@zoy.org>
9 * Gildas Bazin <gbazin@netcourrier.com>
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.
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.
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 *****************************************************************************/
26 /*****************************************************************************
27 * Pretend we are a builtin module
28 *****************************************************************************/
29 #define MODULE_NAME main
30 #define MODULE_PATH main
33 /*****************************************************************************
35 *****************************************************************************/
36 #include <errno.h> /* ENOMEM */
37 #include <stdio.h> /* sprintf() */
38 #include <string.h> /* strerror() */
39 #include <stdlib.h> /* free() */
44 # include <netinet/in.h> /* BSD: struct in_addr */
49 #elif defined( _MSC_VER ) && defined( _WIN32 )
53 #ifdef WIN32 /* optind, getopt(), included in unistd.h */
54 # include "extras/GNUgetopt/getopt.h"
61 #include "vlc_cpu.h" /* CPU detection */
62 #include "os_specific.h"
64 #include "netutils.h" /* network_ChannelJoin */
66 #include "stream_control.h"
67 #include "input_ext-intf.h"
69 #include "vlc_playlist.h"
70 #include "interface.h"
72 #include "audio_output.h"
75 #include "video_output.h"
79 /*****************************************************************************
80 * The evil global variables. We handle them with care, don't worry.
81 *****************************************************************************/
83 /* This global lock is used for critical sections - don't abuse it! */
84 static vlc_mutex_t global_lock;
87 /* A list of all the currently allocated vlc objects */
88 static int volatile i_vlc = 0;
89 static vlc_t ** volatile pp_vlc = NULL;
91 /*****************************************************************************
93 *****************************************************************************/
94 static int GetFilenames ( vlc_t *, int, char *[] );
95 static void Usage ( vlc_t *, const char *psz_module_name );
96 static void ListModules ( vlc_t * );
97 static void Version ( void );
100 static void ShowConsole ( void );
103 /*****************************************************************************
104 * vlc_create: allocate a vlc_t structure, and initialize libvlc if needed.
105 *****************************************************************************
106 * This function allocates a vlc_t structure and returns NULL in case of
107 * failure. Also, the thread system is initialized.
108 *****************************************************************************/
109 vlc_error_t vlc_create( void )
112 vlc_bool_t b_failed = VLC_FALSE;
114 /* This gives us a rather good protection against concurrent calls, but
115 * an additional check will be necessary for complete thread safety. */
121 p_vlc = vlc_create_r();
128 /* We have created an object, which ensures us that p_global_lock has
129 * been properly initialized. We can now atomically check that we are
130 * the only p_vlc object. */
131 vlc_mutex_lock( p_vlc->p_global_lock );
136 vlc_mutex_unlock( p_vlc->p_global_lock );
138 /* There can be only one */
141 vlc_destroy_r( p_vlc );
148 vlc_t * vlc_create_r( void )
150 static int i_instance = 0;
151 vlc_t * p_vlc = NULL;
153 /* Allocate the main structure */
154 p_vlc = vlc_object_create( p_vlc, VLC_OBJECT_ROOT );
160 p_vlc->psz_object_name = "root";
162 p_vlc->p_global_lock = &global_lock;
163 p_vlc->pp_global_data = &p_global_data;
165 p_vlc->b_verbose = VLC_FALSE;
166 p_vlc->b_quiet = VLC_FALSE; /* FIXME: delay message queue output! */
168 /* Initialize the threads system */
169 vlc_threads_init( p_vlc );
171 /* Initialize mutexes */
172 vlc_mutex_init( p_vlc, &p_vlc->config_lock );
173 vlc_mutex_init( p_vlc, &p_vlc->structure_lock );
175 /* Store our newly allocated structure in the global list */
176 vlc_mutex_lock( p_vlc->p_global_lock );
177 pp_vlc = realloc( pp_vlc, (i_vlc+1) * sizeof( vlc_t * ) );
178 pp_vlc[ i_vlc ] = p_vlc;
180 p_vlc->i_instance = i_instance;
182 vlc_mutex_unlock( p_vlc->p_global_lock );
184 /* Update the handle status */
185 p_vlc->i_status = VLC_STATUS_CREATED;
190 /*****************************************************************************
191 * vlc_init: initialize a vlc_t structure.
192 *****************************************************************************
193 * This function initializes a previously allocated vlc_t structure:
195 * - gettext initialization
196 * - message queue, module bank and playlist initialization
197 * - configuration and commandline parsing
198 *****************************************************************************/
199 vlc_error_t vlc_init( int i_argc, char *ppsz_argv[] )
201 return vlc_init_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL, i_argc, ppsz_argv );
204 vlc_error_t vlc_init_r( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
206 char p_capabilities[200];
209 module_t *p_help_module;
210 playlist_t *p_playlist;
212 /* Check that the handle is valid */
213 if( !p_vlc || p_vlc->i_status != VLC_STATUS_CREATED )
215 fprintf( stderr, "error: invalid status (!CREATED)\n" );
219 /* Guess what CPU we have */
220 p_vlc->i_cpu = CPUCapabilities( p_vlc );
223 * Support for gettext
225 #if defined( ENABLE_NLS ) && defined ( HAVE_GETTEXT )
226 # if defined( HAVE_LOCALE_H ) && defined( HAVE_LC_MESSAGES )
227 if( !setlocale( LC_MESSAGES, "" ) )
229 fprintf( stderr, "warning: unsupported locale settings\n" );
232 setlocale( LC_CTYPE, "" );
235 if( !bindtextdomain( PACKAGE, LOCALEDIR ) )
237 fprintf( stderr, "warning: no domain %s in directory %s\n",
238 PACKAGE, LOCALEDIR );
241 textdomain( PACKAGE );
245 * Initialize message queue
250 * System specific initialization code
252 system_Init( p_vlc, &i_argc, ppsz_argv );
254 /* Get the executable name (similar to the basename command) */
257 p_vlc->psz_object_name = p_tmp = ppsz_argv[ 0 ];
260 if( *p_tmp == '/' ) p_vlc->psz_object_name = ++p_tmp;
266 p_vlc->psz_object_name = "vlc";
269 /* Announce who we are */
270 msg_Dbg( p_vlc, COPYRIGHT_MESSAGE );
271 msg_Dbg( p_vlc, "libvlc was configured with %s", CONFIGURE_LINE );
274 * Initialize the module bank and and load the configuration of the main
275 * module. We need to do this at this stage to be able to display a short
276 * help if required by the user. (short help == main module options)
278 module_InitBank( p_vlc );
279 module_LoadMain( p_vlc );
281 /* Hack: insert the help module here */
282 p_help_module = vlc_object_create( p_vlc, VLC_OBJECT_MODULE );
283 if( p_help_module == NULL )
285 module_EndBank( p_vlc );
286 msg_Destroy( p_vlc );
289 p_help_module->psz_object_name = "help";
290 config_Duplicate( p_help_module, p_help_config );
291 vlc_object_attach( p_help_module, p_vlc->p_module_bank );
294 if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
296 vlc_object_detach( p_help_module );
297 config_Free( p_help_module );
298 vlc_object_destroy( p_help_module );
299 module_EndBank( p_vlc );
300 msg_Destroy( p_vlc );
306 /* Check for short help option */
307 if( config_GetInt( p_vlc, "help" ) )
309 fprintf( stderr, _("Usage: %s [options] [items]...\n\n"),
310 p_vlc->psz_object_name );
311 Usage( p_vlc, "main" );
312 Usage( p_vlc, "help" );
315 /* Check for version option */
316 else if( config_GetInt( p_vlc, "version" ) )
322 /* Hack: remove the help module here */
323 vlc_object_detach( p_help_module );
328 config_Free( p_help_module );
329 vlc_object_destroy( p_help_module );
330 module_EndBank( p_vlc );
331 msg_Destroy( p_vlc );
336 * Load the builtins and plugins into the module_bank.
337 * We have to do it before config_Load*() because this also gets the
338 * list of configuration options exported by each module and loads their
341 module_LoadBuiltins( p_vlc );
342 module_LoadPlugins( p_vlc );
343 msg_Dbg( p_vlc, "module bank initialized, found %i modules",
344 p_vlc->p_module_bank->i_children );
346 /* Hack: insert the help module here */
347 vlc_object_attach( p_help_module, p_vlc->p_module_bank );
350 /* Check for help on modules */
351 if( (p_tmp = config_GetPsz( p_vlc, "module" )) )
353 Usage( p_vlc, p_tmp );
357 /* Check for long help option */
358 else if( config_GetInt( p_vlc, "longhelp" ) )
360 Usage( p_vlc, NULL );
363 /* Check for module list option */
364 else if( config_GetInt( p_vlc, "list" ) )
366 ListModules( p_vlc );
370 /* Hack: remove the help module here */
371 vlc_object_detach( p_help_module );
372 config_Free( p_help_module );
373 vlc_object_destroy( p_help_module );
378 module_EndBank( p_vlc );
379 msg_Destroy( p_vlc );
384 * Override default configuration with config file settings
386 p_vlc->psz_homedir = config_GetHomeDir();
387 config_LoadConfigFile( p_vlc, NULL );
390 * Override configuration with command line settings
392 if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
396 /* Pause the console because it's destroyed when we exit */
397 fprintf( stderr, "The command line options couldn't be loaded, check "
398 "that they are valid.\nPress the RETURN key to continue..." );
401 module_EndBank( p_vlc );
402 msg_Destroy( p_vlc );
407 * System specific configuration
409 system_Configure( p_vlc );
412 * Output messages that may still be in the queue
414 p_vlc->b_verbose = config_GetInt( p_vlc, "verbose" );
415 p_vlc->b_quiet = config_GetInt( p_vlc, "quiet" );
416 p_vlc->b_color = config_GetInt( p_vlc, "color" );
419 /* p_vlc inititalization. FIXME ? */
420 p_vlc->i_desync = config_GetInt( p_vlc, "desync" ) * (mtime_t)1000;
421 #if defined( __i386__ )
422 if( !config_GetInt( p_vlc, "mmx" ) )
423 p_vlc->i_cpu &= ~CPU_CAPABILITY_MMX;
424 if( !config_GetInt( p_vlc, "3dn" ) )
425 p_vlc->i_cpu &= ~CPU_CAPABILITY_3DNOW;
426 if( !config_GetInt( p_vlc, "mmxext" ) )
427 p_vlc->i_cpu &= ~CPU_CAPABILITY_MMXEXT;
428 if( !config_GetInt( p_vlc, "sse" ) )
429 p_vlc->i_cpu &= ~CPU_CAPABILITY_SSE;
431 #if defined( __powerpc__ ) || defined( SYS_DARWIN )
432 if( !config_GetInt( p_vlc, "altivec" ) )
433 p_vlc->i_cpu &= ~CPU_CAPABILITY_ALTIVEC;
436 #define PRINT_CAPABILITY( capability, string ) \
437 if( p_vlc->i_cpu & capability ) \
439 strncat( p_capabilities, string " ", \
440 sizeof(p_capabilities) - strlen(p_capabilities) ); \
441 p_capabilities[sizeof(p_capabilities) - 1] = '\0'; \
444 p_capabilities[0] = '\0';
445 PRINT_CAPABILITY( CPU_CAPABILITY_486, "486" );
446 PRINT_CAPABILITY( CPU_CAPABILITY_586, "586" );
447 PRINT_CAPABILITY( CPU_CAPABILITY_PPRO, "Pentium Pro" );
448 PRINT_CAPABILITY( CPU_CAPABILITY_MMX, "MMX" );
449 PRINT_CAPABILITY( CPU_CAPABILITY_3DNOW, "3DNow!" );
450 PRINT_CAPABILITY( CPU_CAPABILITY_MMXEXT, "MMXEXT" );
451 PRINT_CAPABILITY( CPU_CAPABILITY_SSE, "SSE" );
452 PRINT_CAPABILITY( CPU_CAPABILITY_ALTIVEC, "AltiVec" );
453 PRINT_CAPABILITY( CPU_CAPABILITY_FPU, "FPU" );
454 msg_Dbg( p_vlc, "CPU has capabilities %s", p_capabilities );
457 * Choose the best memcpy module
459 p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy" );
461 if( p_vlc->pf_memcpy == NULL )
463 p_vlc->pf_memcpy = memcpy;
466 if( p_vlc->pf_memset == NULL )
468 p_vlc->pf_memset = memset;
472 * Initialize shared resources and libraries
474 if( config_GetInt( p_vlc, "network-channel" )
475 && network_ChannelCreate( p_vlc ) )
477 /* On error during Channels initialization, switch off channels */
479 "channels initialization failed, deactivating channels" );
480 config_PutInt( p_vlc, "network-channel", VLC_FALSE );
484 * Initialize playlist and get commandline files
486 p_playlist = playlist_Create( p_vlc );
489 msg_Err( p_vlc, "playlist initialization failed" );
490 if( p_vlc->p_memcpy_module != NULL )
492 module_Unneed( p_vlc, p_vlc->p_memcpy_module );
494 module_EndBank( p_vlc );
495 msg_Destroy( p_vlc );
499 /* Update the handle status */
500 p_vlc->i_status = VLC_STATUS_STOPPED;
503 * Get input filenames given as commandline arguments
505 GetFilenames( p_vlc, i_argc, ppsz_argv );
510 /*****************************************************************************
511 * vlc_add_intf: add an interface
512 *****************************************************************************
513 * This function opens an interface plugin and runs it. If b_block is set
514 * to 0, vlc_add_intf will return immediately and let the interface run in a
515 * separate thread. If b_block is set to 1, vlc_add_intf will continue until
516 * user requests to quit.
517 *****************************************************************************/
518 vlc_error_t vlc_add_intf( const char *psz_module, vlc_bool_t b_block )
520 return vlc_add_intf_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL,
521 psz_module, b_block );
524 vlc_error_t vlc_add_intf_r( vlc_t *p_vlc, const char *psz_module,
528 intf_thread_t *p_intf;
529 char *psz_oldmodule = NULL;
531 /* Check that the handle is valid */
532 if( !p_vlc || p_vlc->i_status != VLC_STATUS_RUNNING )
534 fprintf( stderr, "error: invalid status (!RUNNING)\n" );
540 psz_oldmodule = config_GetPsz( p_vlc, "intf" );
541 config_PutPsz( p_vlc, "intf", psz_module );
544 /* Try to create the interface */
545 p_intf = intf_Create( p_vlc );
549 config_PutPsz( p_vlc, "intf", psz_oldmodule );
552 free( psz_oldmodule );
558 msg_Err( p_vlc, "interface initialization failed" );
562 /* Try to run the interface */
563 p_intf->b_block = b_block;
564 err = intf_RunThread( p_intf );
567 vlc_object_detach( p_intf );
568 intf_Destroy( p_intf );
575 /*****************************************************************************
576 * vlc_destroy: stop playing and destroy everything.
577 *****************************************************************************
578 * This function requests the running threads to finish, waits for their
579 * termination, and destroys their structure.
580 *****************************************************************************/
581 vlc_error_t vlc_destroy( void )
583 return vlc_destroy_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
586 vlc_error_t vlc_destroy_r( vlc_t *p_vlc )
590 /* Check that the handle is valid */
591 if( !p_vlc || (p_vlc->i_status != VLC_STATUS_STOPPED
592 && p_vlc->i_status != VLC_STATUS_CREATED) )
594 fprintf( stderr, "error: invalid status "
595 "(!STOPPED&&!CREATED)\n" );
599 if( p_vlc->i_status == VLC_STATUS_STOPPED )
602 * Go back into channel 0 which is the network
604 if( config_GetInt( p_vlc, "network-channel" ) && p_vlc->p_channel )
606 network_ChannelJoin( p_vlc, COMMON_CHANNEL );
610 * Free allocated memory
612 if( p_vlc->p_memcpy_module != NULL )
614 module_Unneed( p_vlc, p_vlc->p_memcpy_module );
617 free( p_vlc->psz_homedir );
622 module_EndBank( p_vlc );
625 * System specific cleaning code
630 * Terminate messages interface and program
632 msg_Destroy( p_vlc );
634 /* Update the handle status */
635 p_vlc->i_status = VLC_STATUS_CREATED;
638 /* Update the handle status, just in case */
639 p_vlc->i_status = VLC_STATUS_NONE;
641 /* Remove our structure from the global list */
642 vlc_mutex_lock( p_vlc->p_global_lock );
643 for( i_index = 0 ; i_index < i_vlc ; i_index++ )
645 if( pp_vlc[ i_index ] == p_vlc )
651 if( i_index == i_vlc )
653 fprintf( stderr, "error: trying to unregister %p which is not in "
654 "the list\n", (void *)p_vlc );
655 vlc_mutex_unlock( p_vlc->p_global_lock );
656 vlc_object_destroy( p_vlc );
660 for( i_index++ ; i_index < i_vlc ; i_index++ )
662 pp_vlc[ i_index - 1 ] = pp_vlc[ i_index ];
668 pp_vlc = realloc( pp_vlc, i_vlc * sizeof( vlc_t * ) );
675 vlc_mutex_unlock( p_vlc->p_global_lock );
677 /* Stop thread system: last one out please shut the door! */
678 vlc_threads_end( p_vlc );
680 /* Destroy mutexes */
681 vlc_mutex_destroy( &p_vlc->structure_lock );
682 vlc_mutex_destroy( &p_vlc->config_lock );
684 vlc_object_destroy( p_vlc );
689 /*****************************************************************************
690 * vlc_die: ask vlc to die.
691 *****************************************************************************
692 * This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
693 * task. It is your duty to call vlc_end and vlc_destroy afterwards.
694 *****************************************************************************/
695 vlc_error_t vlc_die( void )
697 return vlc_die_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
700 vlc_error_t vlc_die_r( vlc_t *p_vlc )
704 fprintf( stderr, "error: invalid status (!EXIST)\n" );
708 p_vlc->b_die = VLC_TRUE;
713 /*****************************************************************************
714 * vlc_status: return the current vlc status.
715 *****************************************************************************
716 * This function returns the current value of p_vlc->i_status.
717 *****************************************************************************/
718 vlc_status_t vlc_status( void )
720 return vlc_status_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
723 vlc_status_t vlc_status_r( vlc_t *p_vlc )
727 return VLC_STATUS_NONE;
730 return p_vlc->i_status;
733 /*****************************************************************************
734 * vlc_add_target: adds a target for playing.
735 *****************************************************************************
736 * This function adds psz_target to the current playlist. If a playlist does
737 * not exist, it will create one.
738 *****************************************************************************/
739 vlc_error_t vlc_add_target( const char *psz_target, int i_mode, int i_pos )
741 return vlc_add_target_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL,
742 psz_target, i_mode, i_pos );
745 vlc_error_t vlc_add_target_r( vlc_t *p_vlc, const char *psz_target,
746 int i_mode, int i_pos )
749 playlist_t *p_playlist;
751 if( !p_vlc || ( p_vlc->i_status != VLC_STATUS_STOPPED
752 && p_vlc->i_status != VLC_STATUS_RUNNING ) )
754 fprintf( stderr, "error: invalid status (!STOPPED&&!RUNNING)\n" );
758 p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
760 if( p_playlist == NULL )
762 msg_Dbg( p_vlc, "no playlist present, creating one" );
763 p_playlist = playlist_Create( p_vlc );
765 if( p_playlist == NULL )
770 vlc_object_yield( p_playlist );
773 err = playlist_Add( p_playlist, psz_target, i_mode, i_pos );
775 vlc_object_release( p_playlist );
780 /*****************************************************************************
781 * vlc_set: set a vlc variable
782 *****************************************************************************
784 *****************************************************************************/
785 vlc_error_t vlc_set( const char *psz_var, const char *psz_val )
787 return vlc_set_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL, psz_var, psz_val );
790 vlc_error_t vlc_set_r( vlc_t *p_vlc, const char *psz_var, const char *psz_val )
792 module_config_t *p_config;
796 fprintf( stderr, "error: invalid status\n" );
800 p_config = config_FindConfig( VLC_OBJECT(p_vlc), psz_var );
804 msg_Err( p_vlc, "option %s does not exist", psz_var );
808 vlc_mutex_lock( p_config->p_lock );
810 switch( p_config->i_type )
812 case CONFIG_ITEM_BOOL:
813 if( psz_val && *psz_val )
815 if( !strcmp( psz_val, "off" ) || !strcmp( psz_val, "no" ) )
817 p_config->i_value = VLC_FALSE;
821 p_config->i_value = atoi( psz_val );
826 p_config->i_value = VLC_TRUE;
829 case CONFIG_ITEM_INTEGER:
830 if( psz_val && *psz_val )
832 p_config->i_value = atoi( psz_val );
836 p_config->i_value = 0;
839 case CONFIG_ITEM_FLOAT:
840 if( psz_val && *psz_val )
842 p_config->f_value = (float)atof( psz_val );
846 p_config->f_value = 0.0;
849 case CONFIG_ITEM_STRING:
850 case CONFIG_ITEM_FILE:
851 case CONFIG_ITEM_MODULE:
853 if( p_config->psz_value )
855 free( p_config->psz_value );
860 p_config->psz_value = strdup( psz_val );
864 p_config->psz_value = NULL;
869 if( p_config->pf_callback )
871 vlc_mutex_unlock( p_config->p_lock );
872 p_config->pf_callback( VLC_OBJECT(p_vlc) );
876 vlc_mutex_unlock( p_config->p_lock );
882 /* XXX: temporary hacks */
884 /*****************************************************************************
886 *****************************************************************************/
887 vlc_error_t vlc_play( )
889 return vlc_play_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
892 vlc_error_t vlc_play_r( vlc_t *p_vlc )
894 playlist_t * p_playlist;
896 /* Check that the handle is valid */
897 if( !p_vlc || p_vlc->i_status != VLC_STATUS_STOPPED )
899 fprintf( stderr, "error: invalid status (!STOPPED)\n" );
903 /* Update the handle status */
904 p_vlc->i_status = VLC_STATUS_RUNNING;
906 p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
913 vlc_mutex_lock( &p_playlist->object_lock );
914 if( p_playlist->i_size )
916 vlc_mutex_unlock( &p_playlist->object_lock );
917 playlist_Play( p_playlist );
921 vlc_mutex_unlock( &p_playlist->object_lock );
924 vlc_object_release( p_playlist );
929 /*****************************************************************************
931 *****************************************************************************/
932 vlc_error_t vlc_stop( )
934 return vlc_stop_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
937 vlc_error_t vlc_stop_r( vlc_t *p_vlc )
939 intf_thread_t * p_intf;
940 playlist_t * p_playlist;
941 vout_thread_t * p_vout;
942 aout_instance_t * p_aout;
944 /* Check that the handle is valid */
945 if( !p_vlc || ( p_vlc->i_status != VLC_STATUS_STOPPED
946 && p_vlc->i_status != VLC_STATUS_RUNNING ) )
948 fprintf( stderr, "error: invalid status (!STOPPED&&!RUNNING)\n" );
953 * Ask the interfaces to stop and destroy them
955 msg_Dbg( p_vlc, "removing all interfaces" );
956 while( (p_intf = vlc_object_find( p_vlc, VLC_OBJECT_INTF, FIND_CHILD )) )
958 intf_StopThread( p_intf );
959 vlc_object_detach( p_intf );
960 vlc_object_release( p_intf );
961 intf_Destroy( p_intf );
967 msg_Dbg( p_vlc, "removing all playlists" );
968 while( (p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST,
971 vlc_object_detach( p_playlist );
972 vlc_object_release( p_playlist );
973 playlist_Destroy( p_playlist );
979 msg_Dbg( p_vlc, "removing all video outputs" );
980 while( (p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD )) )
982 vlc_object_detach( p_vout );
983 vlc_object_release( p_vout );
984 vout_DestroyThread( p_vout );
990 msg_Dbg( p_vlc, "removing all audio outputs" );
991 while( (p_aout = vlc_object_find( p_vlc, VLC_OBJECT_AOUT, FIND_CHILD )) )
993 vlc_object_detach( (vlc_object_t *)p_aout );
994 vlc_object_release( (vlc_object_t *)p_aout );
995 aout_Delete( p_aout );
998 /* Update the handle status */
999 p_vlc->i_status = VLC_STATUS_STOPPED;
1004 /*****************************************************************************
1005 * vlc_pause: toggle pause
1006 *****************************************************************************/
1007 vlc_error_t vlc_pause( )
1009 return vlc_pause_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
1012 vlc_error_t vlc_pause_r( vlc_t *p_vlc )
1014 input_thread_t *p_input;
1016 p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
1023 input_SetStatus( p_input, INPUT_STATUS_PAUSE );
1024 vlc_object_release( p_input );
1029 /*****************************************************************************
1030 * vlc_fullscreen: toggle fullscreen mode
1031 *****************************************************************************/
1032 vlc_error_t vlc_fullscreen( )
1034 return vlc_fullscreen_r( ( i_vlc == 1 ) ? pp_vlc[0] : NULL );
1037 vlc_error_t vlc_fullscreen_r( vlc_t *p_vlc )
1039 vout_thread_t *p_vout;
1041 p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD );
1048 p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
1049 vlc_object_release( p_vout );
1054 /* following functions are local */
1056 /*****************************************************************************
1057 * GetFilenames: parse command line options which are not flags
1058 *****************************************************************************
1059 * Parse command line for input files.
1060 *****************************************************************************/
1061 static int GetFilenames( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
1065 /* We assume that the remaining parameters are filenames */
1066 for( i_opt = optind; i_opt < i_argc; i_opt++ )
1068 vlc_add_target_r( p_vlc, ppsz_argv[ i_opt ],
1069 PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
1075 /*****************************************************************************
1076 * Usage: print program usage
1077 *****************************************************************************
1078 * Print a short inline help. Message interface is initialized at this stage.
1079 *****************************************************************************/
1080 static void Usage( vlc_t *p_this, const char *psz_module_name )
1082 #define FORMAT_STRING " --%s%s%s%s%s%s%s %s%s\n"
1083 /* option name -------------' | | | | | |
1084 * <bra --------------------------' | | | | |
1085 * option type or "" ---------------' | | | |
1086 * ket> ------------------------------' | | |
1087 * padding spaces ----------------------' | |
1088 * comment --------------------------------' |
1089 * comment suffix ---------------------------'
1091 * The purpose of having bra and ket is that we might i18n them as well.
1093 #define LINE_START 8
1094 #define PADDING_SPACES 25
1096 module_t **pp_parser;
1097 module_config_t *p_item;
1098 char psz_spaces[PADDING_SPACES+LINE_START+1];
1099 char psz_format[sizeof(FORMAT_STRING)];
1101 memset( psz_spaces, ' ', PADDING_SPACES+LINE_START );
1102 psz_spaces[PADDING_SPACES+LINE_START] = '\0';
1104 strcpy( psz_format, FORMAT_STRING );
1110 /* List all modules */
1111 p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
1113 /* Enumerate the config for each module */
1114 for( pp_parser = (module_t **)p_list->pp_objects ;
1118 vlc_bool_t b_help_module;
1120 if( psz_module_name && strcmp( psz_module_name,
1121 (*pp_parser)->psz_object_name ) )
1126 /* Ignore modules without config options */
1127 if( !(*pp_parser)->i_config_items )
1132 b_help_module = !strcmp( "help", (*pp_parser)->psz_object_name );
1134 /* Print module options */
1135 for( p_item = (*pp_parser)->p_config;
1136 p_item->i_type != CONFIG_HINT_END;
1139 char *psz_bra = NULL, *psz_type = NULL, *psz_ket = NULL;
1140 char *psz_suf = "", *psz_prefix = NULL;
1143 switch( p_item->i_type )
1145 case CONFIG_HINT_CATEGORY:
1146 case CONFIG_HINT_USAGE:
1147 fprintf( stderr, " %s\n", p_item->psz_text );
1150 case CONFIG_ITEM_STRING:
1151 case CONFIG_ITEM_FILE:
1152 case CONFIG_ITEM_MODULE: /* We could also have "=<" here */
1153 if( !p_item->ppsz_list )
1155 psz_bra = " <"; psz_type = _("string"); psz_ket = ">";
1161 psz_type = malloc( 1000 );
1162 memset( psz_type, 0, 1000 );
1163 for( i=0; p_item->ppsz_list[i]; i++ )
1165 strcat( psz_type, p_item->ppsz_list[i] );
1166 strcat( psz_type, "|" );
1168 psz_type[ strlen( psz_type ) - 1 ] = '\0';
1172 case CONFIG_ITEM_INTEGER:
1173 psz_bra = " <"; psz_type = _("integer"); psz_ket = ">";
1175 case CONFIG_ITEM_FLOAT:
1176 psz_bra = " <"; psz_type = _("float"); psz_ket = ">";
1178 case CONFIG_ITEM_BOOL:
1179 psz_bra = ""; psz_type = ""; psz_ket = "";
1180 if( !b_help_module )
1182 psz_suf = p_item->i_value ? _(" (default enabled)") :
1183 _(" (default disabled)");
1188 /* Add short option if any */
1189 if( p_item->i_short )
1191 psz_format[2] = '-';
1192 psz_format[3] = p_item->i_short;
1193 psz_format[4] = ',';
1197 psz_format[2] = ' ';
1198 psz_format[3] = ' ';
1199 psz_format[4] = ' ';
1204 i = PADDING_SPACES - strlen( p_item->psz_name )
1205 - strlen( psz_bra ) - strlen( psz_type )
1206 - strlen( psz_ket ) - 1;
1207 if( p_item->i_type == CONFIG_ITEM_BOOL
1210 /* If option is of type --foo-bar, we print its counterpart
1211 * as --no-foo-bar, but if it is of type --foobar (without
1212 * dashes in the name) we print it as --nofoobar. Both
1213 * values are of course valid, only the display changes. */
1214 vlc_bool_t b_dash = VLC_FALSE;
1215 psz_prefix = p_item->psz_name;
1216 while( *psz_prefix )
1218 if( *psz_prefix++ == '-' )
1227 psz_prefix = ", --no-";
1228 i -= strlen( p_item->psz_name ) + strlen( ", --no-" );
1232 psz_prefix = ", --no";
1233 i -= strlen( p_item->psz_name ) + strlen( ", --no" );
1240 psz_spaces[i] = '\n';
1244 psz_spaces[i] = '\0';
1247 if( p_item->i_type == CONFIG_ITEM_BOOL &&
1250 fprintf( stderr, psz_format, p_item->psz_name, psz_prefix,
1251 p_item->psz_name, psz_bra, psz_type, psz_ket,
1252 psz_spaces, p_item->psz_text, psz_suf );
1256 fprintf( stderr, psz_format, p_item->psz_name, "", "",
1257 psz_bra, psz_type, psz_ket, psz_spaces,
1258 p_item->psz_text, psz_suf );
1260 psz_spaces[i] = ' ';
1261 if ( p_item->ppsz_list )
1269 /* Release the module list */
1270 vlc_list_release( p_list );
1272 #ifdef WIN32 /* Pause the console because it's destroyed when we exit */
1273 fprintf( stderr, _("\nPress the RETURN key to continue...\n") );
1278 /*****************************************************************************
1279 * ListModules: list the available modules with their description
1280 *****************************************************************************
1281 * Print a list of all available modules (builtins and plugins) and a short
1282 * description for each one.
1283 *****************************************************************************/
1284 static void ListModules( vlc_t *p_this )
1287 module_t **pp_parser;
1288 char psz_spaces[22];
1290 memset( psz_spaces, ' ', 22 );
1297 fprintf( stderr, _("Usage: %s [options] [items]...\n\n"),
1298 p_this->p_vlc->psz_object_name );
1300 fprintf( stderr, _("[module] [description]\n") );
1302 /* List all modules */
1303 p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
1305 /* Enumerate each module */
1306 for( pp_parser = (module_t **)p_list->pp_objects ;
1312 /* Nasty hack, but right now I'm too tired to think about a nice
1314 i = 22 - strlen( (*pp_parser)->psz_object_name ) - 1;
1318 fprintf( stderr, " %s%s %s\n", (*pp_parser)->psz_object_name,
1319 psz_spaces, (*pp_parser)->psz_longname );
1321 psz_spaces[i] = ' ';
1324 vlc_list_release( p_list );
1326 #ifdef WIN32 /* Pause the console because it's destroyed when we exit */
1327 fprintf( stderr, _("\nPress the RETURN key to continue...\n") );
1332 /*****************************************************************************
1333 * Version: print complete program version
1334 *****************************************************************************
1335 * Print complete program version and build number.
1336 *****************************************************************************/
1337 static void Version( void )
1343 fprintf( stderr, VERSION_MESSAGE "\n" );
1345 _("This program comes with NO WARRANTY, to the extent permitted by "
1346 "law.\nYou may redistribute it under the terms of the GNU General "
1347 "Public License;\nsee the file named COPYING for details.\n"
1348 "Written by the VideoLAN team at Ecole Centrale, Paris.\n") );
1350 #ifdef WIN32 /* Pause the console because it's destroyed when we exit */
1351 fprintf( stderr, _("\nPress the RETURN key to continue...\n") );
1356 /*****************************************************************************
1357 * ShowConsole: On Win32, create an output console for debug messages
1358 *****************************************************************************
1359 * This function is useful only on Win32.
1360 *****************************************************************************/
1362 static void ShowConsole( void )
1365 freopen( "CONOUT$", "w", stdout );
1366 freopen( "CONOUT$", "w", stderr );
1367 freopen( "CONIN$", "r", stdin );