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