main.c 24.4 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 14 15 16 17 18 19 20 21 22 23
 *****************************************************************************
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * 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-1307, USA.
24
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
25

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

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

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

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

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

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

Vincent Seguin's avatar
Vincent Seguin committed
51
#include "main.h"
Michel Kaempf's avatar
Michel Kaempf committed
52

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

/* 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
61 62 63
#define OPT_AOUT                151
#define OPT_STEREO              152
#define OPT_MONO                153
Michel Kaempf's avatar
Michel Kaempf committed
64 65

#define OPT_NOVIDEO             160
66 67 68 69 70
#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
71 72

#define OPT_NOVLANS             170
73 74
#define OPT_SERVER              171
#define OPT_PORT                172
75

76
/* Usage fashion */
77 78 79
#define USAGE                     0
#define SHORT_HELP                1
#define LONG_HELP                 2
80

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

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

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

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

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

    {   0,                  0,          0,      0 }
};

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

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

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

Michel Kaempf's avatar
Michel Kaempf committed
130 131
static void InitSignalHandler       ( void );
static void SignalHandler           ( int i_signal );
132
static int  TestMMX                 ( void );
Michel Kaempf's avatar
Michel Kaempf committed
133

134
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
135
 * main: parse command line, start interface and spawn threads
136
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
137 138
 * Steps during program execution are:
 *      -configuration parsing and messages interface initialization
Vincent Seguin's avatar
Vincent Seguin committed
139
 *      -openning of audio output device and some global modules
Michel Kaempf's avatar
Michel Kaempf committed
140
 *      -execution of interface, which exit on error or on user request
Vincent Seguin's avatar
Vincent Seguin committed
141
 *      -closing of audio output device and some global modules
142
 * On error, the spawned threads are cancelled, and the open devices closed.
143
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
144 145
int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
{
146 147
    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
148

Michel Kaempf's avatar
Michel Kaempf committed
149 150
    /*
     * Read configuration, initialize messages interface and set up program
151
     */
152 153 154 155
#ifdef HAVE_MMX
    if( !TestMMX() )
    {
        fprintf( stderr, "Sorry, this program needs an MMX processor. Please run the non-MMX version.\n" );
156
        return( 1 );
157 158
    }
#endif
Vincent Seguin's avatar
Vincent Seguin committed
159
    p_main->p_msg = intf_MsgCreate();
160
    if( !p_main->p_msg )                         /* start messages interface */
Michel Kaempf's avatar
Michel Kaempf committed
161
    {
162 163 164
        fprintf( stderr, "critical error: can't initialize messages interface (%s)\n",
                strerror(errno) );
        return( errno );
Michel Kaempf's avatar
Michel Kaempf committed
165
    }
166
    if( GetConfiguration( i_argc, ppsz_argv, ppsz_env ) )  /* parse cmd line */
Michel Kaempf's avatar
Michel Kaempf committed
167
    {
Vincent Seguin's avatar
Vincent Seguin committed
168
        intf_MsgDestroy();
169
        return( errno );
Michel Kaempf's avatar
Michel Kaempf committed
170
    }
171
    intf_MsgImm( COPYRIGHT_MESSAGE "\n" );          /* print welcome message */
Michel Kaempf's avatar
Michel Kaempf committed
172 173 174 175

    /*
     * Initialize shared resources and libraries
     */
Vincent Seguin's avatar
Vincent Seguin committed
176
    if( main_data.b_vlans && input_VlanCreate() )
Michel Kaempf's avatar
Michel Kaempf committed
177 178
    {
        /* On error during vlans initialization, switch of vlans */
179
        intf_Msg( "Virtual LANs initialization failed : vlans management is deactivated\n" );
Vincent Seguin's avatar
Vincent Seguin committed
180
        main_data.b_vlans = 0;
Michel Kaempf's avatar
Michel Kaempf committed
181
    }
182

Michel Kaempf's avatar
Michel Kaempf committed
183
    /*
Vincent Seguin's avatar
Vincent Seguin committed
184
     * Open audio device and start aout thread
Michel Kaempf's avatar
Michel Kaempf committed
185
     */
Vincent Seguin's avatar
Vincent Seguin committed
186 187 188
    if( main_data.b_audio )
    {
        main_data.p_aout = aout_CreateThread( NULL );
189 190 191
        if( main_data.p_aout == NULL )
        {
            /* On error during audio initialization, switch of audio */
192
            intf_Msg( "Audio initialization failed : audio is deactivated\n" );
Vincent Seguin's avatar
Vincent Seguin committed
193
            main_data.b_audio = 0;
194
        }
Michel Kaempf's avatar
Michel Kaempf committed
195
    }
196

Michel Kaempf's avatar
Michel Kaempf committed
197 198 199
    /*
     * Run interface
     */
Vincent Seguin's avatar
Vincent Seguin committed
200 201 202
    main_data.p_intf = intf_Create();
    if( main_data.p_intf != NULL )
    {
203
        InitSignalHandler();             /* prepare signals for interception */
204 205
        intf_Run( main_data.p_intf );
        intf_Destroy( main_data.p_intf );
Vincent Seguin's avatar
Vincent Seguin committed
206
    }
Michel Kaempf's avatar
Michel Kaempf committed
207

Michel Kaempf's avatar
Michel Kaempf committed
208
    /*
Michel Kaempf's avatar
Michel Kaempf committed
209 210
     * Close audio device
     */
Vincent Seguin's avatar
Vincent Seguin committed
211
    if( main_data.b_audio )
Michel Kaempf's avatar
Michel Kaempf committed
212
    {
Vincent Seguin's avatar
Vincent Seguin committed
213
        aout_DestroyThread( main_data.p_aout, NULL );
Michel Kaempf's avatar
Michel Kaempf committed
214
    }
Michel Kaempf's avatar
Michel Kaempf committed
215 216 217 218

    /*
     * Free shared resources and libraries
     */
Vincent Seguin's avatar
Vincent Seguin committed
219
    if( main_data.b_vlans )
220 221 222
    {
        input_VlanDestroy();
    }
Michel Kaempf's avatar
Michel Kaempf committed
223 224 225 226

    /*
     * Terminate messages interface and program
     */
Vincent Seguin's avatar
Vincent Seguin committed
227 228
    intf_Msg( "Program terminated.\n" );
    intf_MsgDestroy();
Michel Kaempf's avatar
Michel Kaempf committed
229 230 231
    return( 0 );
}

232
/*****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
233
 * main_GetIntVariable: get the int value of an environment variable
234
 *****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
235
 * This function is used to read some default parameters in modules.
236
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
237 238
int main_GetIntVariable( char *psz_name, int i_default )
{
239 240 241
    char *      psz_env;                                /* environment value */
    char *      psz_end;                             /* end of parsing index */
    long int    i_value;                                            /* value */
Vincent Seguin's avatar
Vincent Seguin committed
242 243 244

    psz_env = getenv( psz_name );
    if( psz_env )
245
    {
246 247 248 249
        i_value = strtol( psz_env, &psz_end, 0 );
        if( (*psz_env != '\0') && (*psz_end == '\0') )
        {
            return( i_value );
250
        }
251
    }
Vincent Seguin's avatar
Vincent Seguin committed
252 253 254
    return( i_default );
}

255
/*****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
256
 * main_GetPszVariable: get the string value of an environment variable
257
 *****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
258
 * This function is used to read some default parameters in modules.
259
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
260 261 262 263 264 265 266
char * main_GetPszVariable( char *psz_name, char *psz_default )
{
    char *psz_env;

    psz_env = getenv( psz_name );
    if( psz_env )
    {
267
        return( psz_env );
Vincent Seguin's avatar
Vincent Seguin committed
268
    }
269
    return( psz_default );
Vincent Seguin's avatar
Vincent Seguin committed
270 271
}

272
/*****************************************************************************
273
 * main_PutPszVariable: set the string value of an environment variable
274
 *****************************************************************************
275 276 277
 * 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.
278
 *****************************************************************************/
279 280 281 282 283 284 285
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 )
    {
286
        intf_ErrMsg( "error: %s\n", strerror(ENOMEM) );
287 288 289 290 291 292
    }
    else
    {
        sprintf( psz_env, "%s=%s", psz_name, psz_value );
        if( putenv( psz_env ) )
        {
293
            intf_ErrMsg( "error: %s\n", strerror(errno) );
294
        }
295 296 297
    }
}

298
/*****************************************************************************
299
 * main_PutIntVariable: set the integer value of an environment variable
300
 *****************************************************************************
301 302 303
 * 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.
304
 *****************************************************************************/
305 306
void main_PutIntVariable( char *psz_name, int i_value )
{
307
    char psz_value[ 256 ];                               /* buffer for value */
308

309
    sprintf( psz_value, "%d", i_value );
310
    main_PutPszVariable( psz_name, psz_value );
311 312
}

Michel Kaempf's avatar
Michel Kaempf committed
313 314
/* following functions are local */

315
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
316
 * SetDefaultConfiguration: set default options
317
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
318
 * This function is called by GetConfiguration before command line is parsed.
Vincent Seguin's avatar
Vincent Seguin committed
319 320 321
 * 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.
322
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
323
static void SetDefaultConfiguration( void )
Michel Kaempf's avatar
Michel Kaempf committed
324 325
{
    /*
Vincent Seguin's avatar
Vincent Seguin committed
326
     * All features are activated by default
Michel Kaempf's avatar
Michel Kaempf committed
327
     */
Vincent Seguin's avatar
Vincent Seguin committed
328 329 330
    p_main->b_audio  = 1;
    p_main->b_video  = 1;
    p_main->b_vlans  = 1;
Michel Kaempf's avatar
Michel Kaempf committed
331 332
}

333
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
334
 * GetConfiguration: parse command line
335
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
336 337
 * Parse command line and configuration file for configuration. If the inline
 * help is requested, the function Usage() is called and the function returns
338
 * -1 (causing main() to exit). The messages interface is initialized at this
Vincent Seguin's avatar
Vincent Seguin committed
339 340
 * stage, but most structures are not allocated, so only environment should
 * be used.
341
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
342
static int GetConfiguration( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
Michel Kaempf's avatar
Michel Kaempf committed
343
{
Vincent Seguin's avatar
Vincent Seguin committed
344
    int c, i_opt;
Michel Kaempf's avatar
Michel Kaempf committed
345 346

    /* Set default configuration and copy arguments */
Vincent Seguin's avatar
Vincent Seguin committed
347 348
    p_main->i_argc    = i_argc;
    p_main->ppsz_argv = ppsz_argv;
349
    p_main->ppsz_env  = ppsz_env;
Vincent Seguin's avatar
Vincent Seguin committed
350
    SetDefaultConfiguration();
Michel Kaempf's avatar
Michel Kaempf committed
351

Vincent Seguin's avatar
Vincent Seguin committed
352
    /* Parse command line options */
Michel Kaempf's avatar
Michel Kaempf committed
353 354 355 356 357
    opterr = 0;
    while( ( c = getopt_long( i_argc, ppsz_argv, psz_shortopts, longopts, 0 ) ) != EOF )
    {
        switch( c )
        {
358 359
        /* General/common options */
        case 'h':                                              /* -h, --help */
360 361 362
            Usage( SHORT_HELP );
            return( -1 );
            break;
363
        case 'H':                                          /* -H, --longhelp */
364
            Usage( LONG_HELP );
Michel Kaempf's avatar
Michel Kaempf committed
365 366
            return( -1 );
            break;
367
        case 'v':                                           /* -v, --version */
Vincent Seguin's avatar
Vincent Seguin committed
368 369
            Version();
            return( -1 );
370
            break;
Michel Kaempf's avatar
Michel Kaempf committed
371 372

        /* Audio options */
373
        case OPT_NOAUDIO:                                       /* --noaudio */
374
            p_main->b_audio = 0;
Michel Kaempf's avatar
Michel Kaempf committed
375
            break;
376 377 378
        case OPT_AOUT:                                             /* --aout */
            main_PutPszVariable( AOUT_METHOD_VAR, optarg );
            break;
379
        case OPT_STEREO:                                         /* --stereo */
380
            main_PutIntVariable( AOUT_STEREO_VAR, 1 );
Michel Kaempf's avatar
Michel Kaempf committed
381
            break;
382
        case OPT_MONO:                                             /* --mono */
383
            main_PutIntVariable( AOUT_STEREO_VAR, 0 );
Michel Kaempf's avatar
Michel Kaempf committed
384 385 386
            break;

        /* Video options */
387
        case OPT_NOVIDEO:                                       /* --novideo */
Vincent Seguin's avatar
Vincent Seguin committed
388
            p_main->b_video = 0;
389
            break;
390 391 392
        case OPT_VOUT:                                             /* --vout */
            main_PutPszVariable( VOUT_METHOD_VAR, optarg );
            break;
393
        case OPT_DISPLAY:                                       /* --display */
394
            main_PutPszVariable( VOUT_DISPLAY_VAR, optarg );
395 396
            break;
        case OPT_WIDTH:                                           /* --width */
397
            main_PutPszVariable( VOUT_WIDTH_VAR, optarg );
398 399 400 401 402 403
            break;
        case OPT_HEIGHT:                                         /* --height */
            main_PutPszVariable( VOUT_HEIGHT_VAR, optarg );
            break;

        case 'g':                                         /* -g, --grayscale */
404
            main_PutIntVariable( VOUT_GRAYSCALE_VAR, 1 );
405 406
            break;
        case OPT_COLOR:                                           /* --color */
407
            main_PutIntVariable( VOUT_GRAYSCALE_VAR, 0 );
408
            break;
Michel Kaempf's avatar
Michel Kaempf committed
409

410
        /* Input options */
411
        case OPT_NOVLANS:                                       /* --novlans */
Vincent Seguin's avatar
Vincent Seguin committed
412
            p_main->b_vlans = 0;
413 414
            break;
        case OPT_SERVER:                                         /* --server */
415
            main_PutPszVariable( INPUT_SERVER_VAR, optarg );
416 417
            break;
        case OPT_PORT:                                             /* --port */
418
            main_PutPszVariable( INPUT_PORT_VAR, optarg );
419
            break;
420

Michel Kaempf's avatar
Michel Kaempf committed
421
        /* Internal error: unknown option */
422
        case '?':
Michel Kaempf's avatar
Michel Kaempf committed
423
        default:
424 425
            intf_ErrMsg( "intf error: unknown option `%s'\n", ppsz_argv[optind - 1] );
            Usage( USAGE );
Michel Kaempf's avatar
Michel Kaempf committed
426 427 428 429 430
            return( EINVAL );
            break;
        }
    }

Vincent Seguin's avatar
Vincent Seguin committed
431 432 433
    /* Parse command line parameters - no check is made for these options */
    for( i_opt = optind; i_opt < i_argc; i_opt++ )
    {
434
        putenv( ppsz_argv[ i_opt ] );
Vincent Seguin's avatar
Vincent Seguin committed
435
    }
Michel Kaempf's avatar
Michel Kaempf committed
436 437 438
    return( 0 );
}

439
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
440
 * Usage: print program usage
441
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
442
 * Print a short inline help. Message interface is initialized at this stage.
443
 *****************************************************************************/
444
static void Usage( int i_fashion )
Michel Kaempf's avatar
Michel Kaempf committed
445
{
Vincent Seguin's avatar
Vincent Seguin committed
446
    /* Usage */
447 448 449 450 451 452 453 454 455
    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
456 457

    /* Options */
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
    intf_Msg( "\n"
              "Options:\n"
              "      --noaudio                  \tdisable audio\n"
              "      --aout <plugin>            \taudio output method\n"
              "      --stereo, --mono           \tstereo/mono audio\n"
              "\n"
              "      --novideo                  \tdisable audio\n"
              "      --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
478

479 480 481
    if( i_fashion == SHORT_HELP )
        return;

Vincent Seguin's avatar
Vincent Seguin committed
482
    /* Interface parameters */
483 484 485 486
    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
487 488

    /* Audio parameters */
489 490 491 492 493 494
    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
495 496

    /* Video parameters */
497 498 499 500 501 502 503 504
    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
505

506
    /* Input parameters */
507 508 509 510 511 512 513
    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
514 515
}

516
/*****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
517
 * Version: print complete program version
518
 *****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
519
 * Print complete program version and build number.
520
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
521 522
static void Version( void )
{
523
    intf_Msg( VERSION_MESSAGE
524 525 526 527 528
              "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" );
	    
529
}
Vincent Seguin's avatar
Vincent Seguin committed
530

531
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
532
 * InitSignalHandler: system signal handler initialization
533
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
534
 * Set the signal handlers. SIGTERM is not intercepted, because we need at
535
 * at least a method to kill the program when all other methods failed, and
Michel Kaempf's avatar
Michel Kaempf committed
536
 * when we don't want to use SIGKILL.
537
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
538 539
static void InitSignalHandler( void )
{
Vincent Seguin's avatar
Vincent Seguin committed
540 541 542 543
    /* Termination signals */
    signal( SIGHUP,  SignalHandler );
    signal( SIGINT,  SignalHandler );
    signal( SIGQUIT, SignalHandler );
Michel Kaempf's avatar
Michel Kaempf committed
544 545
}

546
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
547
 * SignalHandler: system signal handler
548
 *****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
549 550
 * This function is called when a signal is received by the program. It tries to
 * end the program in a clean way.
551
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
552 553
static void SignalHandler( int i_signal )
{
554
    /* Once a signal has been trapped, the termination sequence will be armed and
Vincent Seguin's avatar
Vincent Seguin committed
555 556 557 558 559 560 561 562 563
     * 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 );

564
    /* Try to terminate everything - this is done by requesting the end of the
Vincent Seguin's avatar
Vincent Seguin committed
565 566 567 568
     * interface thread */
    p_main->p_intf->b_die = 1;
}

569 570 571 572 573 574 575 576 577
#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 )
{
578
/* FIXME: under beos, gcc does not support the foolowing inline assembly */ 
579 580 581
#ifdef SYS_BEOS
    return( 1 );
#else
582

583
    int i_reg, i_dummy = 0;
584 585 586 587 588 589 590 591 592 593 594 595

    /* 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"
596
                 : "=a" ( i_reg ) );
597

598
    if( !i_reg )
599 600 601 602 603 604 605 606 607 608
        return( 0 );

    /* test for a 486 cpu */
    asm volatile ( "movl %%ecx, %%eax
                    xorl $0x200000, %%eax
                    pushl %%eax
                    popfl
                    pushfl
                    popl %%eax
                    xorl %%ecx, %%eax
609
                    pushl %%ecx
610 611
                    popfl
                    andl $0x200000, %%eax"
612
                 : "=a" ( i_reg ) );
613

614
    if( !i_reg )
615 616 617 618
        return( 0 );

    /* the cpu supports the CPUID instruction - get its level */
    asm volatile ( "cpuid"
619 620 621 622 623 624
                 : "=a" ( i_reg ),
                   "=b" ( i_dummy ),
                   "=c" ( i_dummy ),
                   "=d" ( i_dummy )
                 : "a"  ( 0 ),       /* level 0 */
                   "b"  ( i_dummy ) ); /* buggy compiler shouldn't complain */
625 626

    /* this shouldn't happen on a normal cpu */
627
    if( !i_reg )
628 629 630 631 632
        return( 0 );

    /* test for the MMX flag */
    asm volatile ( "cpuid
                    andl $0x00800000, %%edx" /* X86_FEATURE_MMX */
633 634 635 636 637 638 639 640
                 : "=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 )
641 642 643
        return( 0 );

    return( 1 );
644

645
#endif
646 647
}
#endif