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