main.c 24.6 KB
Newer Older
1
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
2 3 4
 * main.c: main vlc source
 * Includes the main() function for vlc. Parses command line, start interface
 * and spawn threads.
5 6 7 8 9 10 11 12 13
 *****************************************************************************
 * Copyright (C) 1998, 1999, 2000 VideoLAN
 *
 * Authors:
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
14
 * 
15 16
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
19
 *
20 21 22
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
24

25
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
26
 * Preamble
27
 *****************************************************************************/
28 29
#include "defs.h"

30
#include <signal.h>                               /* SIGHUP, SIGINT, SIGKILL */
31
#include <getopt.h>                                              /* getopt() */
32 33 34 35 36
#include <stdio.h>                                              /* sprintf() */

#include <errno.h>                                                 /* ENOMEM */
#include <stdlib.h>                                  /* getenv(), strtol(),  */
#include <string.h>                                            /* strerror() */
Vincent Seguin's avatar
Vincent Seguin committed
37

Michel Kaempf's avatar
Michel Kaempf committed
38 39
#include "config.h"
#include "common.h"
40
#include "threads.h"
Michel Kaempf's avatar
Michel Kaempf committed
41
#include "mtime.h"
42
#include "plugins.h"
Michel Kaempf's avatar
Michel Kaempf committed
43
#include "input_vlan.h"
44

Vincent Seguin's avatar
Vincent Seguin committed
45
#include "intf_msg.h"
Michel Kaempf's avatar
Michel Kaempf committed
46
#include "interface.h"
47

Vincent Seguin's avatar
Vincent Seguin committed
48
#include "audio_output.h"
49

50 51 52 53
#ifdef SYS_BEOS
#include "beos_specific.h"
#endif

Vincent Seguin's avatar
Vincent Seguin committed
54
#include "main.h"
Michel Kaempf's avatar
Michel Kaempf committed
55

56
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
57 58
 * Command line options constants. If something is changed here, be sure that
 * GetConfiguration and Usage are also changed.
59
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
60 61 62 63

/* Long options return values - note that values corresponding to short options
 * chars, and in general any regular char, should be avoided */
#define OPT_NOAUDIO             150
64 65 66
#define OPT_AOUT                151
#define OPT_STEREO              152
#define OPT_MONO                153
Michel Kaempf's avatar
Michel Kaempf committed
67 68

#define OPT_NOVIDEO             160
69 70 71 72 73
#define OPT_VOUT                161
#define OPT_DISPLAY             162
#define OPT_WIDTH               163
#define OPT_HEIGHT              164
#define OPT_COLOR               165
Michel Kaempf's avatar
Michel Kaempf committed
74 75

#define OPT_NOVLANS             170
76 77
#define OPT_SERVER              171
#define OPT_PORT                172
78

79
/* Usage fashion */
80 81 82
#define USAGE                     0
#define SHORT_HELP                1
#define LONG_HELP                 2
83

Michel Kaempf's avatar
Michel Kaempf committed
84 85
/* Long options */
static const struct option longopts[] =
86 87
{
    /*  name,               has_arg,    flag,   val */
Michel Kaempf's avatar
Michel Kaempf committed
88 89

    /* General/common options */
90
    {   "help",             0,          0,      'h' },
91
    {   "longhelp",         0,          0,      'H' },
92
    {   "version",          0,          0,      'v' },
Michel Kaempf's avatar
Michel Kaempf committed
93 94

    /* Audio options */
95
    {   "noaudio",          0,          0,      OPT_NOAUDIO },
96
    {   "aout",             1,          0,      OPT_AOUT },
Michel Kaempf's avatar
Michel Kaempf committed
97
    {   "stereo",           0,          0,      OPT_STEREO },
98
    {   "mono",             0,          0,      OPT_MONO },
Michel Kaempf's avatar
Michel Kaempf committed
99 100

    /* Video options */
101
    {   "novideo",          0,          0,      OPT_NOVIDEO },
102
    {   "vout",             1,          0,      OPT_VOUT },
103
    {   "display",          1,          0,      OPT_DISPLAY },
104
    {   "width",            1,          0,      OPT_WIDTH },
105 106 107
    {   "height",           1,          0,      OPT_HEIGHT },
    {   "grayscale",        0,          0,      'g' },
    {   "color",            0,          0,      OPT_COLOR },
Michel Kaempf's avatar
Michel Kaempf committed
108

109
    /* Input options */
Michel Kaempf's avatar
Michel Kaempf committed
110
    {   "novlans",          0,          0,      OPT_NOVLANS },
111 112
    {   "server",           1,          0,      OPT_SERVER },
    {   "port",             1,          0,      OPT_PORT },
Michel Kaempf's avatar
Michel Kaempf committed
113 114 115 116 117

    {   0,                  0,          0,      0 }
};

/* Short options */
118
static const char *psz_shortopts = "hHvg";
Michel Kaempf's avatar
Michel Kaempf committed
119

120
/*****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
121
 * Global variable program_data - this is the one and only, see main.h
122
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
123
main_t *p_main;
Michel Kaempf's avatar
Michel Kaempf committed
124

125
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
126
 * Local prototypes
127
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
128 129
static void SetDefaultConfiguration ( void );
static int  GetConfiguration        ( int i_argc, char *ppsz_argv[], char *ppsz_env[] );
130
static void Usage                   ( int i_fashion );
Vincent Seguin's avatar
Vincent Seguin committed
131
static void Version                 ( void );
Vincent Seguin's avatar
Vincent Seguin committed
132

Michel Kaempf's avatar
Michel Kaempf committed
133 134
static void InitSignalHandler       ( void );
static void SignalHandler           ( int i_signal );
135
#ifdef HAVE_MMX
136
static int  TestMMX                 ( void );
137
#endif
Michel Kaempf's avatar
Michel Kaempf committed
138

139
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
140
 * main: parse command line, start interface and spawn threads
141
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
142 143
 * Steps during program execution are:
 *      -configuration parsing and messages interface initialization
Vincent Seguin's avatar
Vincent Seguin committed
144
 *      -openning of audio output device and some global modules
Michel Kaempf's avatar
Michel Kaempf committed
145
 *      -execution of interface, which exit on error or on user request
Vincent Seguin's avatar
Vincent Seguin committed
146
 *      -closing of audio output device and some global modules
147
 * On error, the spawned threads are cancelled, and the open devices closed.
148
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
149 150
int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
{
151 152
    main_t  main_data;                      /* root of all data - see main.h */
    p_main = &main_data;                       /* set up the global variable */
Vincent Seguin's avatar
Vincent Seguin committed
153

154 155 156 157 158 159 160
    /*
     * System specific initialization code
     */
#ifdef SYS_BEOS
    beos_Init();
#endif

Michel Kaempf's avatar
Michel Kaempf committed
161 162
    /*
     * Read configuration, initialize messages interface and set up program
163
     */
164 165 166 167
#ifdef HAVE_MMX
    if( !TestMMX() )
    {
        fprintf( stderr, "Sorry, this program needs an MMX processor. Please run the non-MMX version.\n" );
168
        return( 1 );
169 170
    }
#endif
Vincent Seguin's avatar
Vincent Seguin committed
171
    p_main->p_msg = intf_MsgCreate();
172
    if( !p_main->p_msg )                         /* start messages interface */
Michel Kaempf's avatar
Michel Kaempf committed
173
    {
174 175 176
        fprintf( stderr, "critical error: can't initialize messages interface (%s)\n",
                strerror(errno) );
        return( errno );
Michel Kaempf's avatar
Michel Kaempf committed
177
    }
178
    if( GetConfiguration( i_argc, ppsz_argv, ppsz_env ) )  /* parse cmd line */
Michel Kaempf's avatar
Michel Kaempf committed
179
    {
Vincent Seguin's avatar
Vincent Seguin committed
180
        intf_MsgDestroy();
181
        return( errno );
Michel Kaempf's avatar
Michel Kaempf committed
182
    }
183
    intf_MsgImm( COPYRIGHT_MESSAGE "\n" );          /* print welcome message */
Michel Kaempf's avatar
Michel Kaempf committed
184 185 186 187

    /*
     * Initialize shared resources and libraries
     */
Vincent Seguin's avatar
Vincent Seguin committed
188
    if( main_data.b_vlans && input_VlanCreate() )
Michel Kaempf's avatar
Michel Kaempf committed
189 190
    {
        /* On error during vlans initialization, switch of vlans */
191
        intf_Msg( "Virtual LANs initialization failed : vlans management is deactivated\n" );
Vincent Seguin's avatar
Vincent Seguin committed
192
        main_data.b_vlans = 0;
Michel Kaempf's avatar
Michel Kaempf committed
193
    }
194

Michel Kaempf's avatar
Michel Kaempf committed
195
    /*
Vincent Seguin's avatar
Vincent Seguin committed
196
     * Open audio device and start aout thread
Michel Kaempf's avatar
Michel Kaempf committed
197
     */
Vincent Seguin's avatar
Vincent Seguin committed
198 199 200
    if( main_data.b_audio )
    {
        main_data.p_aout = aout_CreateThread( NULL );
201 202 203
        if( main_data.p_aout == NULL )
        {
            /* On error during audio initialization, switch of audio */
204
            intf_Msg( "Audio initialization failed : audio is deactivated\n" );
Vincent Seguin's avatar
Vincent Seguin committed
205
            main_data.b_audio = 0;
206
        }
Michel Kaempf's avatar
Michel Kaempf committed
207
    }
208

Michel Kaempf's avatar
Michel Kaempf committed
209 210 211
    /*
     * Run interface
     */
Vincent Seguin's avatar
Vincent Seguin committed
212 213 214
    main_data.p_intf = intf_Create();
    if( main_data.p_intf != NULL )
    {
215
        InitSignalHandler();             /* prepare signals for interception */
216 217
        intf_Run( main_data.p_intf );
        intf_Destroy( main_data.p_intf );
Vincent Seguin's avatar
Vincent Seguin committed
218
    }
Michel Kaempf's avatar
Michel Kaempf committed
219

Michel Kaempf's avatar
Michel Kaempf committed
220
    /*
Michel Kaempf's avatar
Michel Kaempf committed
221 222
     * Close audio device
     */
Vincent Seguin's avatar
Vincent Seguin committed
223
    if( main_data.b_audio )
Michel Kaempf's avatar
Michel Kaempf committed
224
    {
Vincent Seguin's avatar
Vincent Seguin committed
225
        aout_DestroyThread( main_data.p_aout, NULL );
Michel Kaempf's avatar
Michel Kaempf committed
226
    }
Michel Kaempf's avatar
Michel Kaempf committed
227 228 229 230

    /*
     * Free shared resources and libraries
     */
Vincent Seguin's avatar
Vincent Seguin committed
231
    if( main_data.b_vlans )
232 233 234
    {
        input_VlanDestroy();
    }
Michel Kaempf's avatar
Michel Kaempf committed
235

236 237 238 239 240 241 242
    /*
     * System specific cleaning code
     */
#ifdef SYS_BEOS
    beos_Clean();
#endif

Michel Kaempf's avatar
Michel Kaempf committed
243 244 245
    /*
     * Terminate messages interface and program
     */
Vincent Seguin's avatar
Vincent Seguin committed
246 247
    intf_Msg( "Program terminated.\n" );
    intf_MsgDestroy();
Michel Kaempf's avatar
Michel Kaempf committed
248 249 250
    return( 0 );
}

251
/*****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
252
 * main_GetIntVariable: get the int value of an environment variable
253
 *****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
254
 * This function is used to read some default parameters in modules.
255
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
256 257
int main_GetIntVariable( char *psz_name, int i_default )
{
258 259 260
    char *      psz_env;                                /* environment value */
    char *      psz_end;                             /* end of parsing index */
    long int    i_value;                                            /* value */
Vincent Seguin's avatar
Vincent Seguin committed
261 262 263

    psz_env = getenv( psz_name );
    if( psz_env )
264
    {
265 266 267 268
        i_value = strtol( psz_env, &psz_end, 0 );
        if( (*psz_env != '\0') && (*psz_end == '\0') )
        {
            return( i_value );
269
        }
270
    }
Vincent Seguin's avatar
Vincent Seguin committed
271 272 273
    return( i_default );
}

274
/*****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
275
 * main_GetPszVariable: get the string value of an environment variable
276
 *****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
277
 * This function is used to read some default parameters in modules.
278
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
279 280 281 282 283 284 285
char * main_GetPszVariable( char *psz_name, char *psz_default )
{
    char *psz_env;

    psz_env = getenv( psz_name );
    if( psz_env )
    {
286
        return( psz_env );
Vincent Seguin's avatar
Vincent Seguin committed
287
    }
288
    return( psz_default );
Vincent Seguin's avatar
Vincent Seguin committed
289 290
}

291
/*****************************************************************************
292
 * main_PutPszVariable: set the string value of an environment variable
293
 *****************************************************************************
294 295 296
 * This function is used to set some default parameters in modules. The use of
 * this function will cause some memory leak: since some systems use the pointer
 * passed to putenv to store the environment string, it can't be freed.
297
 *****************************************************************************/
298 299 300 301 302 303 304
void main_PutPszVariable( char *psz_name, char *psz_value )
{
    char *psz_env;

    psz_env = malloc( strlen(psz_name) + strlen(psz_value) + 2 );
    if( psz_env == NULL )
    {
305
        intf_ErrMsg( "error: %s\n", strerror(ENOMEM) );
306 307 308 309 310 311
    }
    else
    {
        sprintf( psz_env, "%s=%s", psz_name, psz_value );
        if( putenv( psz_env ) )
        {
312
            intf_ErrMsg( "error: %s\n", strerror(errno) );
313
        }
314 315 316
    }
}

317
/*****************************************************************************
318
 * main_PutIntVariable: set the integer value of an environment variable
319
 *****************************************************************************
320 321 322
 * This function is used to set some default parameters in modules. The use of
 * this function will cause some memory leak: since some systems use the pointer
 * passed to putenv to store the environment string, it can't be freed.
323
 *****************************************************************************/
324 325
void main_PutIntVariable( char *psz_name, int i_value )
{
326
    char psz_value[ 256 ];                               /* buffer for value */
327

328
    sprintf( psz_value, "%d", i_value );
329
    main_PutPszVariable( psz_name, psz_value );
330 331
}

Michel Kaempf's avatar
Michel Kaempf committed
332 333
/* following functions are local */

334
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
335
 * SetDefaultConfiguration: set default options
336
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
337
 * This function is called by GetConfiguration before command line is parsed.
Vincent Seguin's avatar
Vincent Seguin committed
338 339 340
 * It sets all the default values required later by the program. At this stage,
 * most structure are not yet allocated, so initialization must be done using
 * environment.
341
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
342
static void SetDefaultConfiguration( void )
Michel Kaempf's avatar
Michel Kaempf committed
343 344
{
    /*
Vincent Seguin's avatar
Vincent Seguin committed
345
     * All features are activated by default
Michel Kaempf's avatar
Michel Kaempf committed
346
     */
Vincent Seguin's avatar
Vincent Seguin committed
347 348 349
    p_main->b_audio  = 1;
    p_main->b_video  = 1;
    p_main->b_vlans  = 1;
Michel Kaempf's avatar
Michel Kaempf committed
350 351
}

352
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
353
 * GetConfiguration: parse command line
354
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
355 356
 * Parse command line and configuration file for configuration. If the inline
 * help is requested, the function Usage() is called and the function returns
357
 * -1 (causing main() to exit). The messages interface is initialized at this
Vincent Seguin's avatar
Vincent Seguin committed
358 359
 * stage, but most structures are not allocated, so only environment should
 * be used.
360
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
361
static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
Michel Kaempf's avatar
Michel Kaempf committed
362
{
Vincent Seguin's avatar
Vincent Seguin committed
363
    int c, i_opt;
Michel Kaempf's avatar
Michel Kaempf committed
364 365

    /* Set default configuration and copy arguments */
Vincent Seguin's avatar
Vincent Seguin committed
366 367
    p_main->i_argc    = i_argc;
    p_main->ppsz_argv = ppsz_argv;
368
    p_main->ppsz_env  = ppsz_env;
Vincent Seguin's avatar
Vincent Seguin committed
369
    SetDefaultConfiguration();
Michel Kaempf's avatar
Michel Kaempf committed
370

Vincent Seguin's avatar
Vincent Seguin committed
371
    /* Parse command line options */
Michel Kaempf's avatar
Michel Kaempf committed
372 373 374 375 376
    opterr = 0;
    while( ( c = getopt_long( i_argc, ppsz_argv, psz_shortopts, longopts, 0 ) ) != EOF )
    {
        switch( c )
        {
377 378
        /* General/common options */
        case 'h':                                              /* -h, --help */
379 380 381
            Usage( SHORT_HELP );
            return( -1 );
            break;
382
        case 'H':                                          /* -H, --longhelp */
383
            Usage( LONG_HELP );
Michel Kaempf's avatar
Michel Kaempf committed
384 385
            return( -1 );
            break;
386
        case 'v':                                           /* -v, --version */
Vincent Seguin's avatar
Vincent Seguin committed
387 388
            Version();
            return( -1 );
389
            break;
Michel Kaempf's avatar
Michel Kaempf committed
390 391

        /* Audio options */
392
        case OPT_NOAUDIO:                                       /* --noaudio */
393
            p_main->b_audio = 0;
Michel Kaempf's avatar
Michel Kaempf committed
394
            break;
395 396 397
        case OPT_AOUT:                                             /* --aout */
            main_PutPszVariable( AOUT_METHOD_VAR, optarg );
            break;
398
        case OPT_STEREO:                                         /* --stereo */
399
            main_PutIntVariable( AOUT_STEREO_VAR, 1 );
Michel Kaempf's avatar
Michel Kaempf committed
400
            break;
401
        case OPT_MONO:                                             /* --mono */
402
            main_PutIntVariable( AOUT_STEREO_VAR, 0 );
Michel Kaempf's avatar
Michel Kaempf committed
403 404 405
            break;

        /* Video options */
406
        case OPT_NOVIDEO:                                       /* --novideo */
Vincent Seguin's avatar
Vincent Seguin committed
407
            p_main->b_video = 0;
408
            break;
409 410 411
        case OPT_VOUT:                                             /* --vout */
            main_PutPszVariable( VOUT_METHOD_VAR, optarg );
            break;
412
        case OPT_DISPLAY:                                       /* --display */
413
            main_PutPszVariable( VOUT_DISPLAY_VAR, optarg );
414 415
            break;
        case OPT_WIDTH:                                           /* --width */
416
            main_PutPszVariable( VOUT_WIDTH_VAR, optarg );
417 418 419 420 421 422
            break;
        case OPT_HEIGHT:                                         /* --height */
            main_PutPszVariable( VOUT_HEIGHT_VAR, optarg );
            break;

        case 'g':                                         /* -g, --grayscale */
423
            main_PutIntVariable( VOUT_GRAYSCALE_VAR, 1 );
424 425
            break;
        case OPT_COLOR:                                           /* --color */
426
            main_PutIntVariable( VOUT_GRAYSCALE_VAR, 0 );
427
            break;
Michel Kaempf's avatar
Michel Kaempf committed
428

429
        /* Input options */
430
        case OPT_NOVLANS:                                       /* --novlans */
Vincent Seguin's avatar
Vincent Seguin committed
431
            p_main->b_vlans = 0;
432 433
            break;
        case OPT_SERVER:                                         /* --server */
434
            main_PutPszVariable( INPUT_SERVER_VAR, optarg );
435 436
            break;
        case OPT_PORT:                                             /* --port */
437
            main_PutPszVariable( INPUT_PORT_VAR, optarg );
438
            break;
439

Michel Kaempf's avatar
Michel Kaempf committed
440
        /* Internal error: unknown option */
441
        case '?':
Michel Kaempf's avatar
Michel Kaempf committed
442
        default:
443 444
            intf_ErrMsg( "intf error: unknown option `%s'\n", ppsz_argv[optind - 1] );
            Usage( USAGE );
Michel Kaempf's avatar
Michel Kaempf committed
445 446 447 448 449
            return( EINVAL );
            break;
        }
    }

Vincent Seguin's avatar
Vincent Seguin committed
450 451 452
    /* Parse command line parameters - no check is made for these options */
    for( i_opt = optind; i_opt < i_argc; i_opt++ )
    {
453
        putenv( ppsz_argv[ i_opt ] );
Vincent Seguin's avatar
Vincent Seguin committed
454
    }
Michel Kaempf's avatar
Michel Kaempf committed
455 456 457
    return( 0 );
}

458
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
459
 * Usage: print program usage
460
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
461
 * Print a short inline help. Message interface is initialized at this stage.
462
 *****************************************************************************/
463
static void Usage( int i_fashion )
Michel Kaempf's avatar
Michel Kaempf committed
464
{
Vincent Seguin's avatar
Vincent Seguin committed
465
    /* Usage */
466 467 468 469 470 471 472 473 474
    intf_Msg( "Usage: vlc [options] [parameters]\n" );

    if( i_fashion == USAGE )
    {
        intf_Msg( "Try `vlc --help' for more information.\n" );
        return;
    }

    intf_MsgImm( COPYRIGHT_MESSAGE "\n" );
Vincent Seguin's avatar
Vincent Seguin committed
475 476

    /* Options */
477 478 479 480 481 482
    intf_Msg( "\n"
              "Options:\n"
              "      --noaudio                  \tdisable audio\n"
              "      --aout <plugin>            \taudio output method\n"
              "      --stereo, --mono           \tstereo/mono audio\n"
              "\n"
483
              "      --novideo                  \tdisable video\n"
484 485 486 487 488 489 490 491 492 493 494 495 496
              "      --vout <plugin>            \tvideo output method\n"
              "      --display <display>        \tdisplay string\n"
              "      --width <w>, --height <h>  \tdisplay dimensions\n"
              "  -g, --grayscale                \tgrayscale output\n"
              "      --color                    \tcolor output\n"
              "\n"
              "      --novlans                  \tdisable vlans\n"
              "      --server <host>            \tvideo server address\n"
              "      --port <port>              \tvideo server port\n"
              "\n"
              "  -h, --help                     \tprint help and exit\n"
              "  -H, --longhelp                 \tprint long help and exit\n"
              "  -v, --version                  \toutput version information and exit\n" );
Michel Kaempf's avatar
Michel Kaempf committed
497

498 499 500
    if( i_fashion == SHORT_HELP )
        return;

Vincent Seguin's avatar
Vincent Seguin committed
501
    /* Interface parameters */
502 503 504 505
    intf_Msg( "\n"
              "Interface parameters:\n"
              "  " INTF_INIT_SCRIPT_VAR "=<filename>             \tinitialization script\n"
              "  " INTF_CHANNELS_VAR "=<filename>            \tchannels list\n" );
Vincent Seguin's avatar
Vincent Seguin committed
506 507

    /* Audio parameters */
508 509 510 511 512 513
    intf_Msg( "\n"
              "Audio parameters:\n"
              "  " AOUT_METHOD_VAR "=<method name>        \taudio method\n"
              "  " AOUT_DSP_VAR "=<filename>              \tdsp device path\n"
              "  " AOUT_STEREO_VAR "={1|0}                \tstereo or mono output\n"
              "  " AOUT_RATE_VAR "=<rate>             \toutput rate\n" );
Vincent Seguin's avatar
Vincent Seguin committed
514 515

    /* Video parameters */
516 517 518 519 520 521 522 523
    intf_Msg( "\n"
              "Video parameters:\n"
              "  " VOUT_METHOD_VAR "=<method name>        \tdisplay method\n"
              "  " VOUT_DISPLAY_VAR "=<display name>      \tdisplay used\n"
              "  " VOUT_WIDTH_VAR "=<width>               \tdisplay width\n"
              "  " VOUT_HEIGHT_VAR "=<height>             \tdislay height\n"
              "  " VOUT_FB_DEV_VAR "=<filename>           \tframebuffer device path\n"
              "  " VOUT_GRAYSCALE_VAR "={1|0}             \tgrayscale or color output\n" );
Vincent Seguin's avatar
Vincent Seguin committed
524

525
    /* Input parameters */
526 527 528 529 530 531 532
    intf_Msg( "\n"
              "Input parameters:\n"
              "  " INPUT_SERVER_VAR "=<hostname>          \tvideo server\n"
              "  " INPUT_PORT_VAR "=<port>            \tvideo server port\n"
              "  " INPUT_IFACE_VAR "=<interface>          \tnetwork interface\n"
              "  " INPUT_VLAN_SERVER_VAR "=<hostname>     \tvlan server\n"
              "  " INPUT_VLAN_PORT_VAR "=<port>           \tvlan server port\n" );
Michel Kaempf's avatar
Michel Kaempf committed
533 534
}

535
/*****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
536
 * Version: print complete program version
537
 *****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
538
 * Print complete program version and build number.
539
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
540 541
static void Version( void )
{
542
    intf_Msg( VERSION_MESSAGE
543 544 545 546 547
              "This program comes with NO WARRANTY, to the extent permitted by law.\n"
              "You may redistribute it under the terms of the GNU General Public License;\n"
              "see the file named COPYING for details.\n"
              "Written by the VideoLAN team at Ecole Centrale, Paris.\n" );
	    
548
}
Vincent Seguin's avatar
Vincent Seguin committed
549

550
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
551
 * InitSignalHandler: system signal handler initialization
552
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
553
 * Set the signal handlers. SIGTERM is not intercepted, because we need at
554
 * at least a method to kill the program when all other methods failed, and
Michel Kaempf's avatar
Michel Kaempf committed
555
 * when we don't want to use SIGKILL.
556
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
557 558
static void InitSignalHandler( void )
{
Vincent Seguin's avatar
Vincent Seguin committed
559 560 561 562
    /* Termination signals */
    signal( SIGHUP,  SignalHandler );
    signal( SIGINT,  SignalHandler );
    signal( SIGQUIT, SignalHandler );
Michel Kaempf's avatar
Michel Kaempf committed
563 564
}

565
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
566
 * SignalHandler: system signal handler
567
 *****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
568 569
 * This function is called when a signal is received by the program. It tries to
 * end the program in a clean way.
570
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
571 572
static void SignalHandler( int i_signal )
{
573
    /* Once a signal has been trapped, the termination sequence will be armed and
Vincent Seguin's avatar
Vincent Seguin committed
574 575 576 577 578 579 580 581 582
     * following signals will be ignored to avoid sending messages to an interface
     * having been destroyed */
    signal( SIGHUP,  SIG_IGN );
    signal( SIGINT,  SIG_IGN );
    signal( SIGQUIT, SIG_IGN );

    /* Acknowledge the signal received */
    intf_ErrMsgImm("intf: signal %d received\n", i_signal );

583
    /* Try to terminate everything - this is done by requesting the end of the
Vincent Seguin's avatar
Vincent Seguin committed
584 585 586 587
     * interface thread */
    p_main->p_intf->b_die = 1;
}

588 589 590 591 592 593 594 595 596
#ifdef HAVE_MMX
/*****************************************************************************
 * TestMMX: tests if the processor has MMX support.
 *****************************************************************************
 * This function is called if HAVE_MMX is enabled, to check whether the
 * cpu really supports MMX.
 *****************************************************************************/
static int TestMMX( void )
{
597
/* FIXME: under beos, gcc does not support the foolowing inline assembly */ 
598 599 600
#ifdef SYS_BEOS
    return( 1 );
#else
601

602
    int i_reg, i_dummy = 0;
603 604 605 606 607 608 609 610 611 612 613 614

    /* test for a 386 cpu */
    asm volatile ( "pushfl
                    popl %%eax
                    movl %%eax, %%ecx
                    xorl $0x40000, %%eax
                    pushl %%eax
                    popfl
                    pushfl
                    popl %%eax
                    xorl %%ecx, %%eax
                    andl $0x40000, %%eax"
615
                 : "=a" ( i_reg ) );
616

617
    if( !i_reg )
618 619 620 621 622 623 624 625 626 627
        return( 0 );

    /* test for a 486 cpu */
    asm volatile ( "movl %%ecx, %%eax
                    xorl $0x200000, %%eax
                    pushl %%eax
                    popfl
                    pushfl
                    popl %%eax
                    xorl %%ecx, %%eax
628
                    pushl %%ecx
629 630
                    popfl
                    andl $0x200000, %%eax"
631
                 : "=a" ( i_reg ) );
632

633
    if( !i_reg )
634 635 636 637
        return( 0 );

    /* the cpu supports the CPUID instruction - get its level */
    asm volatile ( "cpuid"
638 639 640 641 642 643
                 : "=a" ( i_reg ),
                   "=b" ( i_dummy ),
                   "=c" ( i_dummy ),
                   "=d" ( i_dummy )
                 : "a"  ( 0 ),       /* level 0 */
                   "b"  ( i_dummy ) ); /* buggy compiler shouldn't complain */
644 645

    /* this shouldn't happen on a normal cpu */
646
    if( !i_reg )
647 648 649 650 651
        return( 0 );

    /* test for the MMX flag */
    asm volatile ( "cpuid
                    andl $0x00800000, %%edx" /* X86_FEATURE_MMX */
652 653 654 655 656 657 658 659
                 : "=a" ( i_dummy ),
                   "=b" ( i_dummy ),
                   "=c" ( i_dummy ),
                   "=d" ( i_reg )
                 : "a"  ( 1 ),       /* level 1 */
                   "b"  ( i_dummy ) ); /* buggy compiler shouldn't complain */

    if( !i_reg )
660 661 662
        return( 0 );

    return( 1 );
663

664
#endif
665 666
}
#endif