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 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

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

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

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

/* 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
65 66 67
#define OPT_AOUT                151
#define OPT_STEREO              152
#define OPT_MONO                153
Michel Kaempf's avatar
Michel Kaempf committed
68 69

#define OPT_NOVIDEO             160
70 71 72 73 74
#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
75 76

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

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

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

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

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

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

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

    {   0,                  0,          0,      0 }
};

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

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

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

Michel Kaempf's avatar
Michel Kaempf committed
134 135
static void InitSignalHandler       ( void );
static void SignalHandler           ( int i_signal );
136
static int  TestMMX                 ( void );
Michel Kaempf's avatar
Michel Kaempf committed
137

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

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

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

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

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

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

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

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

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

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

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

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

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

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

290
/*****************************************************************************
291
 * main_PutPszVariable: set the string value of an environment variable
292
 *****************************************************************************
293 294 295
 * 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.
296
 *****************************************************************************/
297 298 299 300 301 302 303
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 )
    {
304
        intf_ErrMsg( "error: %s\n", strerror(ENOMEM) );
305 306 307 308 309 310
    }
    else
    {
        sprintf( psz_env, "%s=%s", psz_name, psz_value );
        if( putenv( psz_env ) )
        {
311
            intf_ErrMsg( "error: %s\n", strerror(errno) );
312
        }
313 314 315
    }
}

316
/*****************************************************************************
317
 * main_PutIntVariable: set the integer value of an environment variable
318
 *****************************************************************************
319 320 321
 * 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.
322
 *****************************************************************************/
323 324
void main_PutIntVariable( char *psz_name, int i_value )
{
325
    char psz_value[ 256 ];                               /* buffer for value */
326

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

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

333
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
334
 * SetDefaultConfiguration: set default options
335
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
336
 * This function is called by GetConfiguration before command line is parsed.
Vincent Seguin's avatar
Vincent Seguin committed
337 338 339
 * 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.
340
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
341
static void SetDefaultConfiguration( void )
Michel Kaempf's avatar
Michel Kaempf committed
342 343
{
    /*
Vincent Seguin's avatar
Vincent Seguin committed
344
     * All features are activated by default
Michel Kaempf's avatar
Michel Kaempf committed
345
     */
Vincent Seguin's avatar
Vincent Seguin committed
346 347 348
    p_main->b_audio  = 1;
    p_main->b_video  = 1;
    p_main->b_vlans  = 1;
Michel Kaempf's avatar
Michel Kaempf committed
349 350
}

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

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

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

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

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

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

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

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

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

457
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
458
 * Usage: print program usage
459
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
460
 * Print a short inline help. Message interface is initialized at this stage.
461
 *****************************************************************************/
462
static void Usage( int i_fashion )
Michel Kaempf's avatar
Michel Kaempf committed
463
{
Vincent Seguin's avatar
Vincent Seguin committed
464
    /* Usage */
465 466 467 468 469 470 471 472 473
    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
474 475

    /* Options */
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495
    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
496

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

Vincent Seguin's avatar
Vincent Seguin committed
500
    /* Interface parameters */
501 502 503 504
    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
505 506

    /* Audio parameters */
507 508 509 510 511 512
    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
513 514

    /* Video parameters */
515 516 517 518 519 520 521 522
    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
523

524
    /* Input parameters */
525 526 527 528 529 530 531
    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
532 533
}

534
/*****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
535
 * Version: print complete program version
536
 *****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
537
 * Print complete program version and build number.
538
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
539 540
static void Version( void )
{
541
    intf_Msg( VERSION_MESSAGE
542 543 544 545 546
              "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" );
	    
547
}
Vincent Seguin's avatar
Vincent Seguin committed
548

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

564
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
565
 * SignalHandler: system signal handler
566
 *****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
567 568
 * This function is called when a signal is received by the program. It tries to
 * end the program in a clean way.
569
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
570 571
static void SignalHandler( int i_signal )
{
572
    /* Once a signal has been trapped, the termination sequence will be armed and
Vincent Seguin's avatar
Vincent Seguin committed
573 574 575 576 577 578 579 580 581
     * 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 );

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

587 588 589 590 591 592 593 594 595
#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 )
{
596
/* FIXME: under beos, gcc does not support the foolowing inline assembly */ 
597 598 599
#ifdef SYS_BEOS
    return( 1 );
#else
600

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

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

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

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

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

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

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

    /* test for the MMX flag */
    asm volatile ( "cpuid
                    andl $0x00800000, %%edx" /* X86_FEATURE_MMX */
651 652 653 654 655 656 657 658
                 : "=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 )
659 660 661
        return( 0 );

    return( 1 );
662

663
#endif
664 665
}
#endif