]> git.sesse.net Git - vlc/blob - src/interface/main.c
* Bug fixes and enhancements in the Gtk+/Gnome interfaces.
[vlc] / src / interface / main.c
1 /*****************************************************************************
2  * main.c: main vlc source
3  * Includes the main() function for vlc. Parses command line, start interface
4  * and spawn threads.
5  *****************************************************************************
6  * Copyright (C) 1998, 1999, 2000 VideoLAN
7  *
8  * Authors:
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  * 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include "defs.h"
29
30 #include <signal.h>                               /* SIGHUP, SIGINT, SIGKILL */
31 #include <stdio.h>                                              /* sprintf() */
32
33 #ifdef HAVE_GETOPT_H
34 #include <getopt.h>                                              /* getopt() */
35 #endif
36
37 #include <errno.h>                                                 /* ENOMEM */
38 #include <stdlib.h>                                  /* getenv(), strtol(),  */
39 #include <string.h>                                            /* strerror() */
40
41 #include "config.h"
42 #include "common.h"
43 #include "debug.h"
44 #include "threads.h"
45 #include "mtime.h"
46 #include "tests.h"                                              /* TestCPU() */
47 #include "modules.h"
48
49 #include "stream_control.h"
50 #include "input_ext-intf.h"
51
52 #include "intf_msg.h"
53 #include "intf_playlist.h"
54 #include "interface.h"
55
56 #include "audio_output.h"
57
58 #include "video.h"
59 #include "video_output.h"
60
61 #ifdef SYS_BEOS
62 #include "beos_specific.h"
63 #endif
64
65 #include "main.h"
66
67 /*****************************************************************************
68  * Command line options constants. If something is changed here, be sure that
69  * GetConfiguration and Usage are also changed.
70  *****************************************************************************/
71
72 /* Long options return values - note that values corresponding to short options
73  * chars, and in general any regular char, should be avoided */
74 #define OPT_NOAUDIO             150
75 #define OPT_STEREO              151
76 #define OPT_MONO                152
77
78 #define OPT_NOVIDEO             160
79 #define OPT_DISPLAY             161
80 #define OPT_WIDTH               162
81 #define OPT_HEIGHT              163
82 #define OPT_COLOR               164
83 #define OPT_FULLSCREEN          165
84 #define OPT_OVERLAY             166
85
86 #define OPT_VLANS               170
87 #define OPT_SERVER              171
88 #define OPT_PORT                172
89 #define OPT_BROADCAST           173
90
91 #define OPT_INPUT               180
92 #define OPT_MOTION              181
93 #define OPT_IDCT                182
94 #define OPT_YUV                 183
95
96 #define OPT_SYNCHRO             190
97 #define OPT_WARNING             191
98
99 /* Usage fashion */
100 #define USAGE                     0
101 #define SHORT_HELP                1
102 #define LONG_HELP                 2
103
104 /* Long options */
105 #ifdef HAVE_GETOPT_H
106 static const struct option longopts[] =
107 {
108     /*  name,               has_arg,    flag,   val */
109
110     /* General/common options */
111     {   "help",             0,          0,      'h' },
112     {   "longhelp",         0,          0,      'H' },
113     {   "version",          0,          0,      'v' },
114
115     /* Interface options */
116     {   "intf",             1,          0,      'I' },
117     {   "warning",          1,          0,      OPT_WARNING },
118
119     /* Audio options */
120     {   "noaudio",          0,          0,      OPT_NOAUDIO },
121     {   "aout",             1,          0,      'A' },
122     {   "stereo",           0,          0,      OPT_STEREO },
123     {   "mono",             0,          0,      OPT_MONO },
124
125     /* Video options */
126     {   "novideo",          0,          0,      OPT_NOVIDEO },
127     {   "vout",             1,          0,      'V' },
128     {   "display",          1,          0,      OPT_DISPLAY },
129     {   "width",            1,          0,      OPT_WIDTH },
130     {   "height",           1,          0,      OPT_HEIGHT },
131     {   "grayscale",        0,          0,      'g' },
132     {   "color",            0,          0,      OPT_COLOR },
133     {   "motion",           1,          0,      OPT_MOTION },
134     {   "idct",             1,          0,      OPT_IDCT },
135     {   "yuv",              1,          0,      OPT_YUV },
136     {   "fullscreen",       0,          0,      OPT_FULLSCREEN },
137     {   "overlay",          0,          0,      OPT_OVERLAY },
138
139     /* DVD options */
140     {   "dvdtitle",         1,          0,      't' },
141     {   "dvdchapter",       1,          0,      'T' },
142     {   "dvdaudio",         1,          0,      'a' },
143     {   "dvdchannel",       1,          0,      'c' },
144     {   "dvdsubtitle",      1,          0,      's' },
145     
146     /* Input options */
147     {   "input",            1,          0,      OPT_INPUT },
148     {   "vlans",            0,          0,      OPT_VLANS },
149     {   "server",           1,          0,      OPT_SERVER },
150     {   "port",             1,          0,      OPT_PORT },
151     {   "broadcast",        0,          0,      OPT_BROADCAST },
152
153     /* Synchro options */
154     {   "synchro",          1,          0,      OPT_SYNCHRO },
155     {   0,                  0,          0,      0 }
156 };
157
158 /* Short options */
159 static const char *psz_shortopts = "hHvgt:T:a:s:c:I:A:V:";
160 #endif
161
162
163 /*****************************************************************************
164  * Global variable program_data - this is the one and only, see main.h
165  *****************************************************************************/
166 main_t *p_main;
167
168 /*****************************************************************************
169  * Local prototypes
170  *****************************************************************************/
171 static void SetDefaultConfiguration ( void );
172 static int  GetConfiguration        ( int i_argc, char *ppsz_argv[],
173                                       char *ppsz_env[] );
174 static int  GetFilenames            ( int i_argc, char *ppsz_argv[] );
175 static void Usage                   ( int i_fashion );
176 static void Version                 ( void );
177
178 static void InitSignalHandler       ( void );
179 static void SimpleSignalHandler     ( int i_signal );
180 static void FatalSignalHandler      ( int i_signal );
181
182 /*****************************************************************************
183  * main: parse command line, start interface and spawn threads
184  *****************************************************************************
185  * Steps during program execution are:
186  *      -configuration parsing and messages interface initialization
187  *      -opening of audio output device and some global modules
188  *      -execution of interface, which exit on error or on user request
189  *      -closing of audio output device and some global modules
190  * On error, the spawned threads are canceled, and the open devices closed.
191  *****************************************************************************/
192 int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
193 {
194     main_t  main_data;                      /* root of all data - see main.h */
195
196     p_main = &main_data;                       /* set up the global variable */
197
198     /*
199      * System specific initialization code
200      */
201 #ifdef SYS_BEOS
202     beos_Create();
203 #endif
204
205     p_main->i_cpu_capabilities = CPUCapabilities();
206     
207     /*
208      * Test if our code is likely to run on this CPU 
209      */
210 #if defined( __pentium__ ) || defined( __pentiumpro__ )
211     if( ! TestCPU( CPU_CAPABILITY_586 ) )
212     {
213         fprintf( stderr, "error: this program needs a Pentium CPU,\n"
214                          "please try a version without Pentium support\n" );
215         return( 1 );
216     }
217 #endif
218
219 #ifdef HAVE_MMX
220     if( ! TestCPU( CPU_CAPABILITY_MMX ) )
221     {
222         fprintf( stderr, "error: this program needs MMX extensions,\n"
223                          "please try a version without MMX support\n" );
224         return( 1 );
225     }
226 #endif
227
228     /*
229      * Initialize messages interface
230      */
231     p_main->p_msg = intf_MsgCreate();
232     if( !p_main->p_msg )                         /* start messages interface */
233     {
234         fprintf( stderr, "error: can't initialize messages interface (%s)\n",
235                  strerror(errno) );
236         return( errno );
237     }
238
239     intf_MsgImm( COPYRIGHT_MESSAGE );
240
241     /*
242      * Read configuration
243      */
244     if( GetConfiguration( i_argc, ppsz_argv, ppsz_env ) )  /* parse cmd line */
245     {
246         intf_MsgDestroy();
247         return( errno );
248     }
249
250     p_main->i_warning_level = main_GetIntVariable( INTF_WARNING_VAR,
251                                                    INTF_WARNING_DEFAULT );
252
253     /*
254      * Initialize playlist and get commandline files
255      */
256     p_main->p_playlist = intf_PlaylistCreate( );
257     if( !p_main->p_playlist )
258     {
259         intf_ErrMsg( "playlist error: playlist initialization failed" );
260         intf_MsgDestroy();
261         return( errno );
262     }
263     intf_PlaylistInit( p_main->p_playlist );
264
265     /*
266      * Get input filenames given as commandline arguments
267      */
268     GetFilenames( i_argc, ppsz_argv );
269
270     /*
271      * Initialize module bank
272      */
273     p_main->p_bank = module_CreateBank( );
274     if( !p_main->p_bank )
275     {
276         intf_ErrMsg( "module error: module bank initialization failed" );
277         intf_PlaylistDestroy( p_main->p_playlist );
278         intf_MsgDestroy();
279         return( errno );
280     }
281     module_InitBank( p_main->p_bank );
282
283     /*
284      * Initialize shared resources and libraries
285      */
286     /* FIXME: no VLANs */
287 #if 0
288     if( p_main->b_vlans && input_VlanCreate() )
289     {
290         /* On error during vlans initialization, switch off vlans */
291         intf_Msg( "Virtual LANs initialization failed : "
292                   "vlans management is deactivated" );
293         p_main->b_vlans = 0;
294     }
295 #endif
296
297     /*
298      * Run interface
299      */
300     p_main->p_intf = intf_Create();
301     if( !p_main->p_intf )
302     {
303         intf_ErrMsg( "intf error: interface initialization failed" );
304         module_DestroyBank( p_main->p_bank );
305         intf_PlaylistDestroy( p_main->p_playlist );
306         intf_MsgDestroy();
307         return( errno );
308     }
309
310     /*
311      * Set signal handling policy for all threads
312      */
313     InitSignalHandler();
314
315     /*
316      * Open audio device and start aout thread
317      */
318     if( p_main->b_audio )
319     {
320         p_main->p_aout = aout_CreateThread( NULL );
321         if( p_main->p_aout == NULL )
322         {
323             /* On error during audio initialization, switch off audio */
324             intf_ErrMsg( "aout error: audio initialization failed,"
325                          " audio is deactivated" );
326             p_main->b_audio = 0;
327         }
328     }
329
330     /*
331      * Open video device and start vout thread
332      */
333     if( p_main->b_video )
334     {
335         p_main->p_vout = vout_CreateThread( NULL );
336         if( p_main->p_vout == NULL )
337         {
338             /* On error during video initialization, switch off video */
339             intf_ErrMsg( "vout error: video initialization failed,"
340                          " video is deactivated" );
341             p_main->b_video = 0;
342         }
343     }
344
345     /* Flush messages before entering the main loop */
346     intf_FlushMsg();
347
348     /*
349      * This is the main loop
350      */
351     p_main->p_intf->pf_run( p_main->p_intf );
352
353     intf_Destroy( p_main->p_intf );
354
355     /*
356      * Close video device
357      */
358     if( p_main->b_video )
359     {
360         vout_DestroyThread( p_main->p_vout, NULL );
361     }
362
363     /*
364      * Close audio device
365      */
366     if( p_main->b_audio )
367     {
368         aout_DestroyThread( p_main->p_aout, NULL );
369     }
370
371     /*
372      * Free shared resources and libraries
373      */
374     /* FIXME */
375 #if 0
376     if( p_main->b_vlans )
377     {
378         input_VlanDestroy();
379     }
380 #endif
381
382     /*
383      * Free module bank
384      */
385     module_DestroyBank( p_main->p_bank );
386
387     /*
388      * Free playlist
389      */
390     intf_PlaylistDestroy( p_main->p_playlist );
391
392 #ifdef SYS_BEOS
393     /*
394      * System specific cleaning code
395      */
396     beos_Destroy();
397 #endif
398
399     /*
400      * Terminate messages interface and program
401      */
402     intf_Msg( "intf: program terminated" );
403     intf_MsgDestroy();
404
405     return( 0 );
406 }
407
408 /*****************************************************************************
409  * main_GetIntVariable: get the int value of an environment variable
410  *****************************************************************************
411  * This function is used to read some default parameters in modules.
412  *****************************************************************************/
413 int main_GetIntVariable( char *psz_name, int i_default )
414 {
415     char *      psz_env;                                /* environment value */
416     char *      psz_end;                             /* end of parsing index */
417     long int    i_value;                                            /* value */
418
419     psz_env = getenv( psz_name );
420     if( psz_env )
421     {
422         i_value = strtol( psz_env, &psz_end, 0 );
423         if( (*psz_env != '\0') && (*psz_end == '\0') )
424         {
425             return( i_value );
426         }
427     }
428     return( i_default );
429 }
430
431 /*****************************************************************************
432  * main_GetPszVariable: get the string value of an environment variable
433  *****************************************************************************
434  * This function is used to read some default parameters in modules.
435  *****************************************************************************/
436 char * main_GetPszVariable( char *psz_name, char *psz_default )
437 {
438     char *psz_env;
439
440     psz_env = getenv( psz_name );
441     if( psz_env )
442     {
443         return( psz_env );
444     }
445     return( psz_default );
446 }
447
448 /*****************************************************************************
449  * main_PutPszVariable: set the string value of an environment variable
450  *****************************************************************************
451  * This function is used to set some default parameters in modules. The use of
452  * this function will cause some memory leak: since some systems use the pointer
453  * passed to putenv to store the environment string, it can't be freed.
454  *****************************************************************************/
455 void main_PutPszVariable( char *psz_name, char *psz_value )
456 {
457     char *psz_env;
458
459     psz_env = malloc( strlen(psz_name) + strlen(psz_value) + 2 );
460     if( psz_env == NULL )
461     {
462         intf_ErrMsg( "intf error: cannot create psz_env (%s)",
463                      strerror(ENOMEM) );
464     }
465     else
466     {
467         sprintf( psz_env, "%s=%s", psz_name, psz_value );
468         if( putenv( psz_env ) )
469         {
470             intf_ErrMsg( "intf error: cannot putenv (%s)", strerror(errno) );
471         }
472     }
473 }
474
475 /*****************************************************************************
476  * main_PutIntVariable: set the integer value of an environment variable
477  *****************************************************************************
478  * This function is used to set some default parameters in modules. The use of
479  * this function will cause some memory leak: since some systems use the pointer
480  * passed to putenv to store the environment string, it can't be freed.
481  *****************************************************************************/
482 void main_PutIntVariable( char *psz_name, int i_value )
483 {
484     char psz_value[ 256 ];                               /* buffer for value */
485
486     sprintf( psz_value, "%d", i_value );
487     main_PutPszVariable( psz_name, psz_value );
488 }
489
490 /* following functions are local */
491
492 /*****************************************************************************
493  * SetDefaultConfiguration: set default options
494  *****************************************************************************
495  * This function is called by GetConfiguration before command line is parsed.
496  * It sets all the default values required later by the program. At this stage,
497  * most structure are not yet allocated, so initialization must be done using
498  * environment.
499  *****************************************************************************/
500 static void SetDefaultConfiguration( void )
501 {
502     /*
503      * All features are activated by default except vlans
504      */
505     p_main->b_audio  = 1;
506     p_main->b_video  = 1;
507     p_main->b_vlans  = 0;
508 }
509
510 /*****************************************************************************
511  * GetConfiguration: parse command line
512  *****************************************************************************
513  * Parse command line and configuration file for configuration. If the inline
514  * help is requested, the function Usage() is called and the function returns
515  * -1 (causing main() to exit). The messages interface is initialized at this
516  * stage, but most structures are not allocated, so only environment should
517  * be used.
518  *****************************************************************************/
519 static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
520 {
521     int c;
522     char * p_pointer;
523
524     /* Set default configuration and copy arguments */
525     p_main->i_argc    = i_argc;
526     p_main->ppsz_argv = ppsz_argv;
527     p_main->ppsz_env  = ppsz_env;
528     SetDefaultConfiguration();
529
530     /* Get the executable name (similar to the basename command) */
531     p_main->psz_arg0 = p_pointer = ppsz_argv[ 0 ];
532     while( *p_pointer )
533     {
534         if( *p_pointer == '/' )
535         {
536             p_main->psz_arg0 = ++p_pointer;
537         }
538         else
539         {
540             ++p_pointer;
541         }
542     }
543
544     /* Parse command line options */
545 #ifdef HAVE_GETOPT_H
546     opterr = 0;
547     while( ( c = getopt_long( i_argc, ppsz_argv, psz_shortopts, longopts, 0 ) ) != EOF )
548     {
549         switch( c )
550         {
551         /* General/common options */
552         case 'h':                                              /* -h, --help */
553             Usage( SHORT_HELP );
554             return( -1 );
555             break;
556         case 'H':                                          /* -H, --longhelp */
557             Usage( LONG_HELP );
558             return( -1 );
559             break;
560         case 'v':                                           /* -v, --version */
561             Version();
562             return( -1 );
563             break;
564
565         /* Interface warning messages level */
566         case 'I':                                              /* -I, --intf */
567             main_PutPszVariable( INTF_METHOD_VAR, optarg );
568             break;
569         case OPT_WARNING:                                       /* --warning */
570             main_PutIntVariable( INTF_WARNING_VAR, atoi(optarg) );
571             break;
572
573         /* Audio options */
574         case OPT_NOAUDIO:                                       /* --noaudio */
575             p_main->b_audio = 0;
576             break;
577         case 'A':                                              /* -A, --aout */
578             main_PutPszVariable( AOUT_METHOD_VAR, optarg );
579             break;
580         case OPT_STEREO:                                         /* --stereo */
581             main_PutIntVariable( AOUT_STEREO_VAR, 1 );
582             break;
583         case OPT_MONO:                                             /* --mono */
584             main_PutIntVariable( AOUT_STEREO_VAR, 0 );
585             break;
586
587         /* Video options */
588         case OPT_NOVIDEO:                                       /* --novideo */
589             p_main->b_video = 0;
590             break;
591         case 'V':                                              /* -V, --vout */
592             main_PutPszVariable( VOUT_METHOD_VAR, optarg );
593             break;
594         case OPT_DISPLAY:                                       /* --display */
595             main_PutPszVariable( VOUT_DISPLAY_VAR, optarg );
596             break;
597         case OPT_WIDTH:                                           /* --width */
598             main_PutPszVariable( VOUT_WIDTH_VAR, optarg );
599             break;
600         case OPT_HEIGHT:                                         /* --height */
601             main_PutPszVariable( VOUT_HEIGHT_VAR, optarg );
602             break;
603         case 'g':                                         /* -g, --grayscale */
604             main_PutIntVariable( VOUT_GRAYSCALE_VAR, 1 );
605             break;
606         case OPT_COLOR:                                           /* --color */
607             main_PutIntVariable( VOUT_GRAYSCALE_VAR, 0 );
608             break;
609         case OPT_FULLSCREEN:                                 /* --fullscreen */
610             main_PutIntVariable( VOUT_FULLSCREEN_VAR, 1 );
611             break;
612         case OPT_OVERLAY:                                       /* --overlay */
613             main_PutIntVariable( VOUT_OVERLAY_VAR, 1 );
614             break;
615         case OPT_MOTION:                                         /* --motion */
616             main_PutPszVariable( MOTION_METHOD_VAR, optarg );
617             break;
618         case OPT_IDCT:                                             /* --idct */
619             main_PutPszVariable( IDCT_METHOD_VAR, optarg );
620             break;
621         case OPT_YUV:                                               /* --yuv */
622             main_PutPszVariable( YUV_METHOD_VAR, optarg );
623             break;
624
625         /* DVD options */
626         case 't':
627             main_PutIntVariable( INPUT_TITLE_VAR, atoi(optarg) );
628             break;
629         case 'T':
630             main_PutIntVariable( INPUT_CHAPTER_VAR, atoi(optarg) );
631             break;
632         case 'a':
633             if ( ! strcmp(optarg, "ac3") )
634                 main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_AC3 );
635             else if ( ! strcmp(optarg, "lpcm") )
636                 main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_LPCM );
637             else if ( ! strcmp(optarg, "mpeg") )
638                 main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_MPEG );
639             else
640                 main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_NOAUDIO );
641             break;
642         case 'c':
643             main_PutIntVariable( INPUT_CHANNEL_VAR, atoi(optarg) );
644             break;
645         case 's':
646             main_PutIntVariable( INPUT_SUBTITLE_VAR, atoi(optarg) );
647             break;
648
649         /* Input options */
650         case OPT_INPUT:                                           /* --input */
651             main_PutPszVariable( INPUT_METHOD_VAR, optarg );
652             break;
653         case OPT_VLANS:                                           /* --vlans */
654             p_main->b_vlans = 1;
655             break;
656         case OPT_SERVER:                                         /* --server */
657             main_PutPszVariable( INPUT_SERVER_VAR, optarg );
658             break;
659         case OPT_PORT:                                             /* --port */
660             main_PutPszVariable( INPUT_PORT_VAR, optarg );
661             break;
662         case OPT_BROADCAST:                                   /* --broadcast */
663             main_PutIntVariable( INPUT_BROADCAST_VAR, 1 );
664             break;
665
666         /* Synchro options */
667         case OPT_SYNCHRO:                                      
668             main_PutPszVariable( VPAR_SYNCHRO_VAR, optarg );
669             break;
670             
671         /* Internal error: unknown option */
672         case '?':
673         default:
674             intf_ErrMsg( "intf error: unknown option `%s'", ppsz_argv[optind - 1] );
675             Usage( USAGE );
676             return( EINVAL );
677             break;
678         }
679     }
680 #endif
681     return( 0 );
682 }
683
684 /*****************************************************************************
685  * GetFilenames: parse command line options which are not flags
686  *****************************************************************************
687  * Parse command line for input files.
688  *****************************************************************************/
689 static int GetFilenames( int i_argc, char *ppsz_argv[] )
690 {
691     int i_opt;
692
693     /* We assume that the remaining parameters are filenames */
694     for( i_opt = optind; i_opt < i_argc; i_opt++ )
695     {
696         intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END,
697                           ppsz_argv[ i_opt ] );
698     }
699
700     return( 0 );
701 }
702
703 /*****************************************************************************
704  * Usage: print program usage
705  *****************************************************************************
706  * Print a short inline help. Message interface is initialized at this stage.
707  *****************************************************************************/
708 static void Usage( int i_fashion )
709 {
710     /* Usage */
711     intf_MsgImm( "Usage: %s [options] [parameters] [file]...",
712                  p_main->psz_arg0 );
713
714     if( i_fashion == USAGE )
715     {
716         intf_MsgImm( "Try `%s --help' for more information.",
717                      p_main->psz_arg0 );
718         return;
719     }
720
721     /* Options */
722     intf_MsgImm( "\nOptions:"
723           "\n  -I, --intf <module>            \tinterface method"
724           "\n      --warning <level>          \tdisplay warning messages"
725           "\n"
726           "\n      --noaudio                  \tdisable audio"
727           "\n  -A, --aout <module>            \taudio output method"
728           "\n      --stereo, --mono           \tstereo/mono audio"
729           "\n"
730           "\n      --novideo                  \tdisable video"
731           "\n  -V, --vout <module>            \tvideo output method"
732           "\n      --display <display>        \tdisplay string"
733           "\n      --width <w>, --height <h>  \tdisplay dimensions"
734           "\n  -g, --grayscale                \tgrayscale output"
735           "\n      --fullscreen               \tfullscreen output"
736           "\n      --overlay                  \taccelerated display"
737           "\n      --color                    \tcolor output"
738           "\n      --motion <module>          \tmotion compensation method"
739           "\n      --idct <module>            \tIDCT method"
740           "\n      --yuv <module>             \tYUV method"
741           "\n      --synchro <type>           \tforce synchro algorithm"
742           "\n"
743           "\n  -t, --dvdtitle <num>           \tchoose DVD title"
744           "\n  -T, --dvdchapter <num>         \tchoose DVD chapter"
745           "\n  -a, --dvdaudio <type>          \tchoose DVD audio type"
746           "\n  -c, --dvdchannel <channel>     \tchoose DVD audio channel"
747           "\n  -s, --dvdsubtitle <channel>    \tchoose DVD subtitle channel"
748           "\n"
749           "\n      --input                    \tinput method"
750           "\n      --vlans                    \tenable vlans"
751           "\n      --server <host>            \tvideo server address"
752           "\n      --port <port>              \tvideo server port"
753           "\n      --broadcast                \tlisten to a broadcast"
754           "\n"
755           "\n  -h, --help                     \tprint help and exit"
756           "\n  -H, --longhelp                 \tprint long help and exit"
757           "\n  -v, --version                  \toutput version information and exit" );
758
759     if( i_fashion == SHORT_HELP )
760         return;
761
762     /* Interface parameters */
763     intf_MsgImm( "\nInterface parameters:"
764         "\n  " INTF_METHOD_VAR "=<method name>          \tinterface method"
765         "\n  " INTF_INIT_SCRIPT_VAR "=<filename>               \tinitialization script"
766         "\n  " INTF_CHANNELS_VAR "=<filename>            \tchannels list"
767         "\n  " INTF_WARNING_VAR "=<level>                \twarning level" );
768
769     /* Audio parameters */
770     intf_MsgImm( "\nAudio parameters:"
771         "\n  " AOUT_METHOD_VAR "=<method name>        \taudio method"
772         "\n  " AOUT_DSP_VAR "=<filename>              \tdsp device path"
773         "\n  " AOUT_STEREO_VAR "={1|0}                \tstereo or mono output"
774         "\n  " AOUT_RATE_VAR "=<rate>             \toutput rate" );
775
776     /* Video parameters */
777     intf_MsgImm( "\nVideo parameters:"
778         "\n  " VOUT_METHOD_VAR "=<method name>        \tdisplay method"
779         "\n  " VOUT_DISPLAY_VAR "=<display name>      \tdisplay used"
780         "\n  " VOUT_WIDTH_VAR "=<width>               \tdisplay width"
781         "\n  " VOUT_HEIGHT_VAR "=<height>             \tdislay height"
782         "\n  " VOUT_FB_DEV_VAR "=<filename>           \tframebuffer device path"
783         "\n  " VOUT_GRAYSCALE_VAR "={1|0}             \tgrayscale or color output"
784         "\n  " VOUT_FULLSCREEN_VAR "={1|0}            \tfullscreen"
785         "\n  " VOUT_OVERLAY_VAR "={1|0}               \toverlay"
786         "\n  " MOTION_METHOD_VAR "=<method name>      \tmotion compensation method"
787         "\n  " IDCT_METHOD_VAR "=<method name>        \tIDCT method"
788         "\n  " YUV_METHOD_VAR "=<method name>         \tYUV method"
789         "\n  " VPAR_SYNCHRO_VAR "={I|I+|IP|IP+|IPB}   \tsynchro algorithm" );
790
791     /* DVD parameters */
792     intf_MsgImm( "\nDVD parameters:"
793         "\n  " INPUT_DVD_DEVICE_VAR "=<device>           \tDVD device"
794         "\n  " INPUT_TITLE_VAR "=<title>             \ttitle number"
795         "\n  " INPUT_CHAPTER_VAR "=<chapter>         \tchapter number"
796         "\n  " INPUT_AUDIO_VAR "={ac3|lpcm|mpeg|off} \taudio type"
797         "\n  " INPUT_CHANNEL_VAR "=[0-15]            \taudio channel"
798         "\n  " INPUT_SUBTITLE_VAR "=[0-31]           \tsubtitle channel" );
799
800     /* Input parameters */
801     intf_MsgImm( "\nInput parameters:"
802         "\n  " INPUT_SERVER_VAR "=<hostname>          \tvideo server"
803         "\n  " INPUT_PORT_VAR "=<port>            \tvideo server port"
804         "\n  " INPUT_IFACE_VAR "=<interface>          \tnetwork interface"
805         "\n  " INPUT_BROADCAST_VAR "={1|0}            \tbroadcast mode"
806         "\n  " INPUT_VLAN_SERVER_VAR "=<hostname>     \tvlan server"
807         "\n  " INPUT_VLAN_PORT_VAR "=<port>           \tvlan server port" );
808
809 }
810
811 /*****************************************************************************
812  * Version: print complete program version
813  *****************************************************************************
814  * Print complete program version and build number.
815  *****************************************************************************/
816 static void Version( void )
817 {
818     intf_MsgImm( VERSION_MESSAGE
819         "This program comes with NO WARRANTY, to the extent permitted by law.\n"
820         "You may redistribute it under the terms of the GNU General Public License;\n"
821         "see the file named COPYING for details.\n"
822         "Written by the VideoLAN team at Ecole Centrale, Paris." );
823 }
824
825 /*****************************************************************************
826  * InitSignalHandler: system signal handler initialization
827  *****************************************************************************
828  * Set the signal handlers. SIGTERM is not intercepted, because we need at
829  * at least a method to kill the program when all other methods failed, and
830  * when we don't want to use SIGKILL.
831  *****************************************************************************/
832 static void InitSignalHandler( void )
833 {
834     /* Termination signals */
835     signal( SIGHUP,  FatalSignalHandler );
836     signal( SIGINT,  FatalSignalHandler );
837     signal( SIGQUIT, FatalSignalHandler );
838
839     /* Other signals */
840     signal( SIGALRM, SimpleSignalHandler );
841     signal( SIGPIPE, SimpleSignalHandler );
842 }
843
844
845 /*****************************************************************************
846  * SimpleSignalHandler: system signal handler
847  *****************************************************************************
848  * This function is called when a non fatal signal is received by the program.
849  *****************************************************************************/
850 static void SimpleSignalHandler( int i_signal )
851 {
852     /* Acknowledge the signal received */
853     intf_WarnMsg( 0, "intf: ignoring signal %d", i_signal );
854 }
855
856
857 /*****************************************************************************
858  * FatalSignalHandler: system signal handler
859  *****************************************************************************
860  * This function is called when a fatal signal is received by the program.
861  * It tries to end the program in a clean way.
862  *****************************************************************************/
863 static void FatalSignalHandler( int i_signal )
864 {
865     /* Once a signal has been trapped, the termination sequence will be
866      * armed and following signals will be ignored to avoid sending messages
867      * to an interface having been destroyed */
868     signal( SIGHUP,  SIG_IGN );
869     signal( SIGINT,  SIG_IGN );
870     signal( SIGQUIT, SIG_IGN );
871
872     /* Acknowledge the signal received */
873     intf_ErrMsgImm( "intf error: signal %d received, exiting", i_signal );
874
875     /* Try to terminate everything - this is done by requesting the end of the
876      * interface thread */
877     p_main->p_intf->b_die = 1;
878 }
879