]> git.sesse.net Git - vlc/blob - src/interface/main.c
Resize sous X11, gestion du screen saver.
[vlc] / src / interface / main.c
1 /*******************************************************************************
2  * main.c: main vlc source
3  * (c)1998 VideoLAN
4  *******************************************************************************
5  * Includes the main() function for vlc. Parses command line, start interface
6  * and spawn threads.
7  *******************************************************************************/
8
9 /*******************************************************************************
10  * Preamble
11  *******************************************************************************/
12 #include <errno.h>
13 #include <getopt.h>
14 #include <signal.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include <sys/soundcard.h>                                   /* audio_output.h */
20
21 #include "config.h"
22 #include "common.h"
23 #include "mtime.h"
24 #include "vlc_thread.h"
25 #include "input_vlan.h"
26 #include "intf_msg.h"
27 #include "interface.h"
28 #include "audio_output.h"
29 #include "main.h"
30
31 /*******************************************************************************
32  * Command line options constants. If something is changed here, be sure that
33  * GetConfiguration and Usage are also changed.
34  *******************************************************************************/
35
36 /* Long options return values - note that values corresponding to short options
37  * chars, and in general any regular char, should be avoided */
38 #define OPT_NOAUDIO             150
39 #define OPT_STEREO              151
40 #define OPT_MONO                152
41
42 #define OPT_NOVIDEO             160
43 #define OPT_COLOR               161
44
45 #define OPT_NOVLANS             170
46  
47 /* Long options */
48 static const struct option longopts[] =
49 {   
50     /*  name,               has_arg,    flag,   val */     
51
52     /* General/common options */
53     {   "help",             0,          0,      'h' },          
54
55     /* Audio options */
56     {   "noaudio",          0,          0,      OPT_NOAUDIO },       
57     {   "stereo",           0,          0,      OPT_STEREO },
58     {   "mono",             0,          0,      OPT_MONO },      
59
60     /* Video options */
61     {   "novideo",          0,          0,      OPT_NOVIDEO },           
62     {   "grayscale",        0,          0,      'g' },    
63     {   "color",            0,          0,      OPT_COLOR },                
64
65     /* VLAN management options */
66     {   "novlans",          0,          0,      OPT_NOVLANS },
67
68     {   0,                  0,          0,      0 }
69 };
70
71 /* Short options */
72 static const char *psz_shortopts = "hg";
73
74 /*******************************************************************************
75  * Global variable program_data - this is the one and only, see main.h
76  *******************************************************************************/
77 main_t *p_main;
78
79 /*******************************************************************************
80  * Local prototypes
81  *******************************************************************************/
82 static void SetDefaultConfiguration ( void );
83 static int  GetConfiguration        ( int i_argc, char *ppsz_argv[], char *ppsz_env[] );
84 static void Usage                   ( void );
85
86 static void InitSignalHandler       ( void );
87 static void SignalHandler           ( int i_signal );
88
89 /*******************************************************************************
90  * main: parse command line, start interface and spawn threads
91  *******************************************************************************
92  * Steps during program execution are:
93  *      -configuration parsing and messages interface initialization
94  *      -openning of audio output device and some global modules
95  *      -execution of interface, which exit on error or on user request
96  *      -closing of audio output device and some global modules
97  * On error, the spawned threads are cancelled, and the openned devices closed.
98  *******************************************************************************/
99 int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
100 {
101     main_t  main_data;                        /* root of all data - see main.h */
102     p_main = &main_data;                         /* set up the global variable */   
103
104     /*
105      * Read configuration, initialize messages interface and set up program
106      */    
107     p_main->p_msg = intf_MsgCreate();
108     if( !p_main->p_msg )                           /* start messages interface */
109     {
110         fprintf(stderr, "critical error: can't initialize messages interface (%s)\n",
111                 strerror(errno));
112         return(errno);
113     }
114     if( GetConfiguration( i_argc, ppsz_argv, ppsz_env ) )/* parse command line */
115     {
116         intf_MsgDestroy();
117         return(errno);
118     }
119     intf_MsgImm( COPYRIGHT_MESSAGE "\n" );            /* print welcome message */
120
121     /*
122      * Initialize shared resources and libraries
123      */
124     if( main_data.b_vlans && input_VlanCreate() )
125     {
126         /* On error during vlans initialization, switch of vlans */
127         intf_Msg("Virtual LANs initialization failed : vlans management is desactivated\n");
128         main_data.b_vlans = 0;
129     }
130     
131     /*
132      * Open audio device and start aout thread
133      */
134     if( main_data.b_audio )
135     {
136         main_data.p_aout = aout_CreateThread( NULL );
137         if( main_data.p_aout == NULL )
138         {
139             /* On error during audio initialization, switch of audio */
140             intf_Msg("Audio initialization failed : audio is desactivated\n");
141             main_data.b_audio = 0;
142         }
143     }
144     
145     /*
146      * Run interface
147      */
148     main_data.p_intf = intf_Create();
149     if( main_data.p_intf != NULL )
150     {
151         InitSignalHandler();               /* prepare signals for interception */
152         intf_Run( main_data.p_intf );
153         intf_Destroy( main_data.p_intf );
154     }
155
156     /*
157      * Close audio device
158      */
159     if( main_data.b_audio )
160     {
161         aout_DestroyThread( main_data.p_aout, NULL );
162     }
163
164     /*
165      * Free shared resources and libraries
166      */
167     if( main_data.b_vlans )
168     {        
169         input_VlanDestroy();    
170     }    
171
172     /*
173      * Terminate messages interface and program
174      */
175     intf_Msg( "Program terminated.\n" );
176     intf_MsgDestroy();
177     return( 0 );
178 }
179
180 /*******************************************************************************
181  * main_GetIntVariable: get the int value of an environment variable
182  *******************************************************************************
183  * This function is used to read some default parameters in modules.
184  *******************************************************************************/
185 int main_GetIntVariable( char *psz_name, int i_default )
186 {
187     char *      psz_env;                                  /* environment value */
188     char *      psz_end;                               /* end of parsing index */
189     long int    i_value;                                              /* value */
190
191     psz_env = getenv( psz_name );
192     if( psz_env )
193     {        
194         i_value = strtol( psz_env, &psz_end, 0 );
195         if( (*psz_env != '\0') && (*psz_end == '\0') )
196         {
197             return( i_value );
198         }        
199     }   
200     return( i_default );
201 }
202
203 /*******************************************************************************
204  * main_GetPszVariable: get the string value of an environment variable
205  *******************************************************************************
206  * This function is used to read some default parameters in modules.
207  *******************************************************************************/
208 char * main_GetPszVariable( char *psz_name, char *psz_default )
209 {
210     char *psz_env;
211
212     psz_env = getenv( psz_name );
213     if( psz_env )
214     {
215         return( psz_env );
216     }
217     return( psz_default );    
218 }
219
220 /*******************************************************************************
221  * main_PutPszVariable: set the string value of an environment variable
222  *******************************************************************************
223  * This function is used to set some default parameters in modules. The use of
224  * this function will cause some memory leak: since some systems use the pointer
225  * passed to putenv to store the environment string, it can't be freed.
226  *******************************************************************************/
227 void main_PutPszVariable( char *psz_name, char *psz_value )
228 {
229     char *psz_env;
230
231     psz_env = malloc( strlen(psz_name) + strlen(psz_value) + 2 );
232     if( psz_env == NULL )
233     {
234         intf_ErrMsg("error: %s\n", strerror(ENOMEM));        
235     }
236     else
237     {
238         sprintf( psz_env, "%s=%s", psz_name, psz_value );
239         if( putenv( psz_env ) )
240         {
241             intf_ErrMsg("error: %s\n", strerror(errno));
242         }        
243     }
244 }
245
246 /*******************************************************************************
247  * main_PutIntVariable: set the integer value of an environment variable
248  *******************************************************************************
249  * This function is used to set some default parameters in modules. The use of
250  * this function will cause some memory leak: since some systems use the pointer
251  * passed to putenv to store the environment string, it can't be freed.
252  *******************************************************************************/
253 void main_PutIntVariable( char *psz_name, int i_value )
254 {
255     char psz_value[ 256 ];                                 /* buffer for value */    
256
257     sprintf(psz_value, "%d", i_value );        
258     main_PutPszVariable( psz_name, psz_value );    
259 }
260
261 /* following functions are local */
262
263 /*******************************************************************************
264  * SetDefaultConfiguration: set default options
265  *******************************************************************************
266  * This function is called by GetConfiguration before command line is parsed.
267  * It sets all the default values required later by the program. At this stage,
268  * most structure are not yet allocated, so initialization must be done using
269  * environment.
270  *******************************************************************************/
271 static void SetDefaultConfiguration( void )
272 {
273     /*
274      * All features are activated by default
275      */
276     p_main->b_audio  = 1;
277     p_main->b_video  = 1;
278     p_main->b_vlans  = 1;
279
280     /*
281      * Audio output thread configuration 
282      */
283
284     // ?? initialization using structures is no more available, use putenv/getenv
285     // instead.
286
287    
288
289     /*
290      * Video output thread configuration
291      */
292     //    p_data->vout_cfg.i_properties =         0;
293
294     /* VLAN management */
295     /*???    p_data->cfg.b_vlans =                   0;    
296     p_data->cfg.psz_input_vlan_server =     VLAN_DEFAULT_SERVER;
297     p_data->cfg.i_input_vlan_server_port =  VLAN_DEFAULT_SERVER_PORT;    
298     */
299 }
300
301 /*******************************************************************************
302  * GetConfiguration: parse command line
303  *******************************************************************************
304  * Parse command line and configuration file for configuration. If the inline
305  * help is requested, the function Usage() is called and the function returns
306  * -1 (causing main() to exit). The messages interface is initialized at this 
307  * stage, but most structures are not allocated, so only environment should
308  * be used.
309  *******************************************************************************/
310 static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
311 {
312     int c, i_opt;
313
314     /* Set default configuration and copy arguments */
315     p_main->i_argc    = i_argc;
316     p_main->ppsz_argv = ppsz_argv;
317     p_main->ppsz_env  = ppsz_env;    
318     SetDefaultConfiguration();
319
320     /* Parse command line options */
321     opterr = 0;
322     while( ( c = getopt_long( i_argc, ppsz_argv, psz_shortopts, longopts, 0 ) ) != EOF )
323     {
324         switch( c )
325         {
326         /* General/common options */   
327         case 'h':                                                /* -h, --help */
328             Usage();
329             return( -1 );
330             break;
331
332         /* Audio options */
333         case OPT_NOAUDIO:                                        /* --noaudio */
334             p_main->b_audio = 0;
335             break;
336         case OPT_STEREO:                                          /* --stereo */
337             main_PutIntVariable( AOUT_STEREO_VAR, 1 );
338             break;
339         case OPT_MONO:                                              /* --mono */
340             main_PutIntVariable( AOUT_STEREO_VAR, 0 );
341             break;
342
343         /* Video options */
344         case OPT_NOVIDEO:                                         /* --novideo */
345             p_main->b_video = 0;
346             break;       
347         case 'g':                                           /* -g, --grayscale */
348             main_PutIntVariable( VOUT_GRAYSCALE_VAR, 1 );
349             break;            
350         case OPT_COLOR:                                             /* --color */
351             main_PutIntVariable( VOUT_GRAYSCALE_VAR, 0 );
352             break;            
353
354         /* VLAN management options */
355         case OPT_NOVLANS:                                         /* --novlans */
356             p_main->b_vlans = 0;
357             break;      
358             
359         /* Internal error: unknown option */
360         case '?':                          
361         default:
362             intf_ErrMsg("intf error: unknown option '%s'\n", ppsz_argv[optind - 1]);
363             return( EINVAL );
364             break;
365         }
366     }
367
368     /* Parse command line parameters - no check is made for these options */
369     for( i_opt = optind; i_opt < i_argc; i_opt++ )
370     {
371         putenv( ppsz_argv[ i_opt ] );
372     }
373     return( 0 );
374 }
375
376 /*******************************************************************************
377  * Usage: print program usage
378  *******************************************************************************
379  * Print a short inline help. Message interface is initialized at this stage.
380  *******************************************************************************/
381 static void Usage( void )
382 {
383     intf_Msg(COPYRIGHT_MESSAGE);
384     /* Usage */
385     intf_Msg("usage: vlc [options...] [parameters]\n" \
386              "  parameters can be passed using environment variables\n" \
387              "  example: vlan_server=vlan-server.via.ecp.fr:1234\n" \
388              );
389
390     /* Options */
391     intf_Msg("Options:\n" \
392              "  -h, --help                      print usage\n" \
393              "  -g, --grayscale                 grayscale video\n" \
394              "  --noaudio                       disable audio\n" \
395              "  --stereo                        enable stereo\n" \
396              "  --mono                          disable stereo\n"
397              "  --novideo                       disable video\n" \
398              "  --color                         color video\n" \
399              "  --novlans                       disable vlans\n" \
400              );
401
402     /* Interface parameters */
403     intf_Msg("Interface parameters:\n" \
404              "  " INTF_INIT_SCRIPT_VAR "=<filename>             initialization script\n" \
405              );
406
407     /* Audio parameters */
408     intf_Msg("Audio parameters:\n" \
409              "  " AOUT_DSP_VAR "=<filename>              dsp device path\n" \
410              "  " AOUT_STEREO_VAR "={1|0}                stereo or mono output\n" \
411              "  " AOUT_RATE_VAR "=<rate>           output rate\n" \
412              );
413
414     /* Video parameters */
415     intf_Msg("Video parameters:\n" \
416              "  " VOUT_FB_DEV_VAR "=<filename>           framebuffer device path\n" \
417              "  " VOUT_GRAYSCALE_VAR "={1|0}             grayscale or color output\n" \
418              ); 
419
420     /* Vlan parameters */
421     intf_Msg("VLANs (Virtual Local Aera Networks) parameters:\n" \
422              "  vlan_server=<host>[:<port>]     VLANs server address and port\n" \
423              );
424 }
425
426 /*******************************************************************************
427  * InitSignalHandler: system signal handler initialization
428  *******************************************************************************
429  * Set the signal handlers. SIGTERM is not intercepted, because we need at
430  * at least a method to kill the program when all other methods failed, and 
431  * when we don't want to use SIGKILL.
432  *******************************************************************************/
433 static void InitSignalHandler( void )
434 {
435     /* Termination signals */
436     signal( SIGHUP,  SignalHandler );
437     signal( SIGINT,  SignalHandler );
438     signal( SIGQUIT, SignalHandler );
439 }
440
441 /*******************************************************************************
442  * SignalHandler: system signal handler
443  *******************************************************************************
444  * This function is called when a signal is received by the program. It tries to
445  * end the program in a clean way.
446  *******************************************************************************/
447 static void SignalHandler( int i_signal )
448 {
449     /* Once a signal has been trapped, the termination sequence will be armed and 
450      * following signals will be ignored to avoid sending messages to an interface
451      * having been destroyed */
452     signal( SIGHUP,  SIG_IGN );
453     signal( SIGINT,  SIG_IGN );
454     signal( SIGQUIT, SIG_IGN );
455
456     /* Acknowledge the signal received */
457     intf_ErrMsgImm("intf: signal %d received\n", i_signal );
458
459     /* Try to terminate everything - this is done by requesting the end of the 
460      * interface thread */
461     p_main->p_intf->b_die = 1;
462 }
463
464
465