main.c 44.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
 * Copyright (C) 1998-2001 VideoLAN
Johan Bilien's avatar
 
Johan Bilien committed
7
 * $Id: main.c,v 1.168 2002/03/25 02:06:24 jobi Exp $
8
 *
Sam Hocevar's avatar
 
Sam Hocevar committed
9 10
 * Authors: Vincent Seguin <seguin@via.ecp.fr>
 *          Samuel Hocevar <sam@zoy.org>
gbazin's avatar
 
gbazin committed
11
 *          Gildas Bazin <gbazin@netcourrier.com>
12 13 14 15 16
 *
 * 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.
17
 * 
18 19
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
22
 *
23 24 25
 * 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.
26
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
27

28
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
29
 * Preamble
30
 *****************************************************************************/
31 32
#include <signal.h>                               /* SIGHUP, SIGINT, SIGKILL */
#include <stdio.h>                                              /* sprintf() */
33
#include <setjmp.h>                                       /* longjmp, setjmp */
34

Sam Hocevar's avatar
 
Sam Hocevar committed
35 36
#include <videolan/vlc.h>

Sam Hocevar's avatar
 
Sam Hocevar committed
37 38 39 40 41 42
#ifdef HAVE_GETOPT_LONG
#   ifdef HAVE_GETOPT_H
#       include <getopt.h>                                       /* getopt() */
#   endif
#else
#   include "GNUgetopt/getopt.h"
Benoit Steiner's avatar
Benoit Steiner committed
43 44
#endif

Sam Hocevar's avatar
 
Sam Hocevar committed
45
#ifdef SYS_DARWIN
Sam Hocevar's avatar
 
Sam Hocevar committed
46 47
#   include <mach/mach.h>                               /* Altivec detection */
#   include <mach/mach_error.h>       /* some day the header files||compiler *
Sam Hocevar's avatar
 
Sam Hocevar committed
48
                                                       will define it for us */
Sam Hocevar's avatar
 
Sam Hocevar committed
49
#   include <mach/bootstrap.h>
Sam Hocevar's avatar
 
Sam Hocevar committed
50
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
51 52

#ifndef WIN32
Sam Hocevar's avatar
 
Sam Hocevar committed
53
#   include <netinet/in.h>                            /* BSD: struct in_addr */
Sam Hocevar's avatar
 
Sam Hocevar committed
54
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
55

Sam Hocevar's avatar
 
Sam Hocevar committed
56
#ifdef HAVE_UNISTD_H
Sam Hocevar's avatar
 
Sam Hocevar committed
57 58 59
#   include <unistd.h>
#elif defined( _MSC_VER ) && defined( _WIN32 )
#   include <io.h>
Sam Hocevar's avatar
 
Sam Hocevar committed
60 61
#endif

Sam Hocevar's avatar
 
Sam Hocevar committed
62 63 64 65
#ifdef HAVE_LOCALE_H
#    include <locale.h>
#endif

66 67 68
#include <errno.h>                                                 /* ENOMEM */
#include <stdlib.h>                                  /* getenv(), strtol(),  */
#include <string.h>                                            /* strerror() */
gbazin's avatar
 
gbazin committed
69 70
#include <fcntl.h>                                       /* open(), O_WRONLY */
#include <sys/stat.h>                                             /* S_IREAD */
Vincent Seguin's avatar
Vincent Seguin committed
71

Sam Hocevar's avatar
 
Sam Hocevar committed
72
#include "netutils.h"                                 /* network_ChannelJoin */
Sam Hocevar's avatar
 
Sam Hocevar committed
73

74 75
#include "stream_control.h"
#include "input_ext-intf.h"
76

Sam Hocevar's avatar
 
Sam Hocevar committed
77
#include "intf_playlist.h"
Michel Kaempf's avatar
Michel Kaempf committed
78
#include "interface.h"
79

Vincent Seguin's avatar
Vincent Seguin committed
80
#include "audio_output.h"
81

Sam Hocevar's avatar
 
Sam Hocevar committed
82 83 84
#include "video.h"
#include "video_output.h"

Sam Hocevar's avatar
 
Sam Hocevar committed
85
#include "debug.h"
Henri Fallon's avatar
 
Henri Fallon committed
86

87
/*****************************************************************************
gbazin's avatar
 
gbazin committed
88 89 90 91 92 93 94 95 96 97
 * Configuration options for the main program. Each plugin will also separatly
 * define its own configuration options.
 * Look into configuration.h if you need to know more about the following
 * macros.
 * 
 *****************************************************************************/
#define BUILTIN
#define MODULE_NAME main
#include "modules_inner.h"                        /* for configuration stuff */

gbazin's avatar
 
gbazin committed
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132

#define INTF_TEXT "interface method"
#define INTF_LONGTEXT "This option allows you to select the interface used by"\
                      " vlc.\nNote that the default behaviour is to" \
                      " automatically select the best method available"

#define WARNING_TEXT "warning level (or use -v, -vv, etc...)"
#define WARNING_LONGTEXT "Increasing the warning level will allow you to see" \
                         " more debug messages and can sometimes help you to" \
                         " troubleshoot a problem"

#define STATS_TEXT "output statistics"
#define STATS_LONGTEXT "Enabling the stats mode will flood your log console" \
                       " with various statistics messages"

#define INTF_PATH_TEXT "interface default search path"
#define INTF_PATH_LONGTEXT "This option allows you to set the default path" \
                           "that the interface will open when looking for a" \
                           " file"

#define AOUT_TEXT "audio output method"
#define AOUT_LONGTEXT "This option allows you to select the audio" \
                      " audio output method used by vlc.\nNote that the" \
                      " default behaviour is to automatically select the best"\
                      " method available"

#define NOAUDIO_TEXT "disable audio"
#define NOAUDIO_LONGTEXT "This will completely disable the audio output. The" \
                         " audio decoding stage shouldn't even be done, so it"\
                         " can allow you to save some processing power"

#define MONO_TEXT "mono audio"
#define MONO_LONGTEXT "This will force a mono audio output"

#define VOLUME_TEXT "audio output volume"
Stéphane Borel's avatar
 
Stéphane Borel committed
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
#define VOLUME_LONGTEXT "You can set the default audio output volume here," \
                        " in a range from 0 to 1024"

#define FORMAT_TEXT "audio output format"
#define FORMAT_LONGTEXT "You can force the audio output format here.\n" \
                        "0 -> 16 bits signed native endian (default)\n" \
                        "1 ->  8 bits unsigned\n"                       \
                        "2 -> 16 bits signed little endian\n"           \
                        "3 -> 16 bits signed big endian\n"              \
                        "4 ->  8 bits signed\n"                         \
                        "5 -> 16 bits unsigned little endian\n"         \
                        "6 -> 16 bits unsigned big endian\n"            \
                        "7 -> mpeg2 audio (unsupported)\n"              \
                        "8 -> ac3 pass-through"
                         
#define RATE_TEXT "audio output frequency (Hz)"
#define RATE_LONGTEXT "You can force the audio output frequency here.\n"    \
                      "Common values are 48000, 44100, 32000, 22050,"       \
                      " 16000, 11025, 8000"
gbazin's avatar
 
gbazin committed
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225

#define DESYNC_TEXT "Compensate desynchronization of audio (in ms)"
#define DESYNC_LONGTEXT "This option allows you to delay the audio output." \
                        "This can be handy if you notice a lag between the" \
                        " video and the audio"

#define VOUT_TEXT "video output method"
#define VOUT_LONGTEXT "This option allows you to select the video output" \
                      "method used by vlc.\nNote that the default behaviour" \
                      "is to automatically select the best method available"

#define NOVIDEO_TEXT "disable video"
#define NOVIDEO_LONGTEXT "This will completely disable the video output. The" \
                         "video decoding stage shouldn't even be done, so it" \
                         "can allow you to save some processing power"

#define DISPLAY_TEXT "display identifier"
#define DISPLAY_LONGTEXT NULL

#define WIDTH_TEXT "video width"
#define WIDTH_LONGTEXT "You can enforce the video width here.\nNote" \
                       "that by default vlc will adapt to the video properties"

#define HEIGHT_TEXT "video height"
#define HEIGHT_LONGTEXT NULL

#define GRAYSCALE_TEXT "grayscale video output"
#define GRAYSCALE_LONGTEXT NULL

#define FULLSCREEN_TEXT "fullscreen video output"
#define FULLSCREEN_LONGTEXT NULL

#define NOOVERLAY_TEXT "disable accelerated display"
#define NOOVERLAY_LONGTEXT NULL

#define SPUMARGIN_TEXT "force SPU position"
#define SPUMARGIN_LONGTEXT NULL

#define FILTER_TEXT "video filter module"
#define FILTER_LONGTEXT NULL

#define INPUT_TEXT "input method"
#define INPUT_LONGTEXT NULL

#define SERVER_PORT_TEXT "server port"
#define SERVER_PORT_LONGTEXT NULL

#define NETCHANNEL_TEXT "enable network channel mode"
#define NETCHANNEL_LONGTEXT NULL

#define CHAN_SERV_TEXT "channel server address"
#define CHAN_SERV_LONGTEXT NULL

#define CHAN_PORT_TEXT "channel server port"
#define CHAN_PORT_LONGTEXT NULL

#define IFACE_TEXT "network interface"
#define IFACE_LONGTEXT NULL

#define INPUT_AUDIO_TEXT "choose audio"
#define INPUT_AUDIO_LONGTEXT NULL

#define INPUT_CHAN_TEXT "choose channel"
#define INPUT_CHAN_LONGTEXT NULL

#define INPUT_SUBT_TEXT "choose subtitles"
#define INPUT_SUBT_LONGTEXT NULL

#define DVD_DEV_TEXT "DVD device"
#define DVD_DEV_LONGTEXT NULL

#define VCD_DEV_TEXT "VCD device"
#define VCD_DEV_LONGTEXT NULL

Johan Bilien's avatar
 
Johan Bilien committed
226 227 228 229 230 231 232 233 234
#define SAT_FREQ_TEXT "Satellite transponder frequency"
#define SAT_FREQ_LONGTEXT NULL

#define SAT_POL_TEXT "Satellite transponder polarization"
#define SAT_POL_LONGTEXT NULL

#define SAT_SRATE_TEXT "Satellite transponder symbol rate"
#define SAT_SRATE_LONGTEXT NULL
                       
gbazin's avatar
 
gbazin committed
235 236 237
#define IPV6_TEXT "force IPv6"
#define IPV6_LONGTEXT NULL

Sam Hocevar's avatar
 
Sam Hocevar committed
238
#define IPV4_TEXT "force IPv4"
gbazin's avatar
 
gbazin committed
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
#define IPV4_LONGTEXT NULL

#define ADEC_MPEG_TEXT "choose MPEG audio decoder"
#define ADEC_MPEG_LONGTEXT NULL

#define ADEC_AC3_TEXT "choose AC3 audio decoder"
#define ADEC_AC3_LONGTEXT NULL

#define VDEC_SMP_TEXT "use additional processors"
#define VDEC_SMP_LONGTEXT NULL

#define VPAR_SYNCHRO_TEXT "force synchro algorithm {I|I+|IP|IP+|IPB}"
#define VPAR_SYNCHRO_LONGTEXT NULL

#define NOMMX_TEXT "disable CPU's MMX support"
#define NOMMX_LONGTEXT NULL

#define NO3DN_TEXT "disable CPU's 3D Now! support"
#define NO3DN_LONGTEXT NULL

#define NOMMXEXT_TEXT "disable CPU's MMX EXT support"
#define NOMMXEXT_LONGTEXT NULL

#define NOSSE_TEXT "disable CPU's SSE support"
#define NOSSE_LONGTEXT NULL

#define NOALTIVEC_TEXT "disable CPU's AltiVec support"
#define NOALTIVEC_LONGTEXT NULL

#define PLAYLIST_LAUNCH_TEXT "launch playlist on startup"
#define PLAYLIST_LAUNCH_LONGTEXT NULL

#define PLAYLIST_ENQUEUE_TEXT "enqeue playlist as default"
#define PLAYLIST_ENQUEUE_LONGTEXT NULL

#define PLAYLIST_LOOP_TEXT "loop playlist on end"
#define PLAYLIST_LOOP_LONGTEXT NULL

#define MEMCPY_TEXT "memory copy method"
#define MEMCPY_LONGTEXT NULL

gbazin's avatar
 
gbazin committed
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
/* Quick usage guide
MODULE_CONFIG_START
MODULE_CONFIG_STOP
ADD_CATEGORY_HINT( text, longtext )
ADD_SUBCATEGORY_HINT( text, longtext )
ADD_STRING( option_name, value, p_callback, text, longtext )
ADD_FILE( option_name, psz_value, p_callback, text, longtext )
ADD_PLUGIN( option_name, psz_value, i_capability, p_callback, text, longtext )
ADD_INTEGER( option_name, i_value, p_callback, text, longtext )
ADD_BOOL( option_name, p_callback, text, longtext )
*/

MODULE_CONFIG_START

/* Interface options */
gbazin's avatar
 
gbazin committed
295 296 297 298 299 300 301 302 303 304 305 306 307 308
ADD_CATEGORY_HINT( "Interface", NULL)
ADD_PLUGIN  ( "intf", MODULE_CAPABILITY_INTF, NULL, NULL, INTF_TEXT, INTF_LONGTEXT )
ADD_INTEGER ( "warning", 0, NULL, WARNING_TEXT, WARNING_LONGTEXT )
ADD_BOOL    ( "stats", NULL, STATS_TEXT, STATS_LONGTEXT )
ADD_STRING  ( "search_path", NULL, NULL, INTF_PATH_TEXT, INTF_PATH_LONGTEXT )

/* Audio options */
ADD_CATEGORY_HINT( "Audio", NULL)
ADD_PLUGIN  ( "aout", MODULE_CAPABILITY_AOUT, NULL, NULL, AOUT_TEXT, AOUT_LONGTEXT )
ADD_BOOL    ( "noaudio", NULL, NOAUDIO_TEXT, NOAUDIO_LONGTEXT )
ADD_BOOL    ( "mono", NULL, MONO_TEXT, MONO_LONGTEXT )
ADD_INTEGER ( "volume", VOLUME_DEFAULT, NULL, VOLUME_TEXT, VOLUME_LONGTEXT )
ADD_INTEGER ( "rate", 44100, NULL, RATE_TEXT, RATE_LONGTEXT )
ADD_INTEGER ( "desync", 0, NULL, DESYNC_TEXT, DESYNC_LONGTEXT )
Stéphane Borel's avatar
 
Stéphane Borel committed
309 310
ADD_INTEGER ( "aout_format", 0, NULL, FORMAT_TEXT,
              FORMAT_LONGTEXT )
gbazin's avatar
 
gbazin committed
311 312

/* Video options */
gbazin's avatar
 
gbazin committed
313 314 315 316
ADD_CATEGORY_HINT( "Video", NULL )
ADD_PLUGIN  ( "vout", MODULE_CAPABILITY_VOUT, NULL, NULL, VOUT_TEXT, VOUT_LONGTEXT )
ADD_BOOL    ( "novideo", NULL, NOVIDEO_TEXT, NOVIDEO_LONGTEXT )
ADD_STRING  ( "display", NULL, NULL, DISPLAY_TEXT, DISPLAY_LONGTEXT )
gbazin's avatar
 
gbazin committed
317 318
ADD_INTEGER ( "width", -1, NULL, WIDTH_TEXT, WIDTH_LONGTEXT )
ADD_INTEGER ( "height", -1, NULL, HEIGHT_TEXT, HEIGHT_LONGTEXT )
gbazin's avatar
 
gbazin committed
319 320 321 322 323
ADD_BOOL    ( "grayscale", NULL, GRAYSCALE_TEXT, GRAYSCALE_LONGTEXT )
ADD_BOOL    ( "fullscreen", NULL, FULLSCREEN_TEXT, FULLSCREEN_LONGTEXT )
ADD_BOOL    ( "nooverlay", NULL, NOOVERLAY_TEXT, NOOVERLAY_LONGTEXT )
ADD_INTEGER ( "spumargin", -1, NULL, SPUMARGIN_TEXT, SPUMARGIN_LONGTEXT )
ADD_PLUGIN  ( "filter", MODULE_CAPABILITY_VOUT, NULL, NULL, FILTER_TEXT, FILTER_LONGTEXT )
gbazin's avatar
 
gbazin committed
324 325

/* Input options */
gbazin's avatar
 
gbazin committed
326 327 328 329 330 331 332 333 334
ADD_CATEGORY_HINT( "Input", NULL )
ADD_STRING  ( "input", NULL, NULL, INPUT_TEXT, INPUT_LONGTEXT )
ADD_INTEGER ( "server_port", 1234, NULL, SERVER_PORT_TEXT, SERVER_PORT_LONGTEXT )
ADD_BOOL    ( "network_channel", NULL, NETCHANNEL_TEXT, NETCHANNEL_LONGTEXT )
ADD_STRING  ( "channel_server", "localhost", NULL, CHAN_SERV_TEXT, CHAN_SERV_LONGTEXT )
ADD_INTEGER ( "channel_port", 6010, NULL, CHAN_PORT_TEXT, CHAN_PORT_LONGTEXT )
ADD_STRING  ( "iface", "eth0", NULL, IFACE_TEXT, IFACE_LONGTEXT )

ADD_INTEGER ( "input_audio", -1, NULL, INPUT_AUDIO_TEXT, INPUT_AUDIO_LONGTEXT )
Stéphane Borel's avatar
 
Stéphane Borel committed
335
ADD_INTEGER ( "input_channel", -1, NULL, INPUT_CHAN_TEXT, INPUT_CHAN_LONGTEXT )
gbazin's avatar
 
gbazin committed
336 337 338 339
ADD_INTEGER ( "input_subtitle", -1, NULL, INPUT_SUBT_TEXT, INPUT_SUBT_LONGTEXT )

ADD_STRING  ( "dvd_device", "/dev/dvd", NULL, DVD_DEV_TEXT, DVD_DEV_LONGTEXT )
ADD_STRING  ( "vcd_device", "/dev/cdrom", NULL, VCD_DEV_TEXT, VCD_DEV_LONGTEXT )
Johan Bilien's avatar
 
Johan Bilien committed
340 341 342 343 344 345 346
#ifdef HAVE_SATELLITE
ADD_INTEGER ( "sat_frequency", 12553, NULL, SAT_FREQ_TEXT, SAT_FREQ_LONGTEXT )
ADD_INTEGER ( "sat_polarization", 0, NULL, SAT_POL_TEXT, SAT_POL_LONGTEXT )
ADD_INTEGER ( "sat_symbol_rate", 27500, NULL, SAT_SRATE_TEXT, 
            SAT_SRATE_LONGTEXT )
#endif

gbazin's avatar
 
gbazin committed
347 348
ADD_BOOL    ( "ipv6", NULL, IPV6_TEXT, IPV6_LONGTEXT )
ADD_BOOL    ( "ipv4", NULL, IPV4_TEXT, IPV4_LONGTEXT )
gbazin's avatar
 
gbazin committed
349 350

/* Decoder options */
gbazin's avatar
 
gbazin committed
351 352 353 354 355
ADD_CATEGORY_HINT( "Decoders", NULL )
ADD_PLUGIN  ( "mpeg_adec", MODULE_CAPABILITY_DECODER, NULL, NULL, ADEC_MPEG_TEXT, ADEC_MPEG_LONGTEXT )
ADD_PLUGIN  ( "ac3_adec", MODULE_CAPABILITY_DECODER, NULL, NULL, ADEC_AC3_TEXT, ADEC_AC3_LONGTEXT )
ADD_INTEGER ( "vdec_smp", 0, NULL, VDEC_SMP_TEXT, VDEC_SMP_LONGTEXT )
ADD_STRING  ( "vpar_synchro", NULL, NULL, VPAR_SYNCHRO_TEXT, VPAR_SYNCHRO_LONGTEXT )
gbazin's avatar
 
gbazin committed
356 357

/* CPU options */
gbazin's avatar
 
gbazin committed
358 359 360 361 362 363
ADD_CATEGORY_HINT( "CPU", NULL )
ADD_BOOL    ( "nommx", NULL, NOMMX_TEXT, NOMMX_LONGTEXT )
ADD_BOOL    ( "no3dn", NULL, NO3DN_TEXT, NO3DN_LONGTEXT )
ADD_BOOL    ( "nommxext", NULL, NOMMXEXT_TEXT, NOMMXEXT_LONGTEXT )
ADD_BOOL    ( "nosse", NULL, NOSSE_TEXT, NOSSE_LONGTEXT )
ADD_BOOL    ( "noaltivec", NULL, NOALTIVEC_TEXT, NOALTIVEC_LONGTEXT )
gbazin's avatar
 
gbazin committed
364 365

/* Playlist options */
gbazin's avatar
 
gbazin committed
366 367 368 369
ADD_CATEGORY_HINT( "Playlist", NULL )
ADD_BOOL    ( "playlist_launch", NULL, PLAYLIST_LAUNCH_TEXT, PLAYLIST_LAUNCH_LONGTEXT )
ADD_BOOL    ( "playlist_enqueue", NULL, PLAYLIST_ENQUEUE_TEXT, PLAYLIST_ENQUEUE_LONGTEXT )
ADD_BOOL    ( "playlist_loop", NULL, PLAYLIST_LOOP_TEXT, PLAYLIST_LOOP_LONGTEXT )
gbazin's avatar
 
gbazin committed
370 371

/* Misc options */
gbazin's avatar
 
gbazin committed
372 373
ADD_CATEGORY_HINT( "Miscellaneous", NULL )
ADD_PLUGIN  ( "memcpy", MODULE_CAPABILITY_MEMCPY, NULL, NULL, MEMCPY_TEXT, MEMCPY_LONGTEXT )
gbazin's avatar
 
gbazin committed
374 375 376 377 378 379 380 381 382 383 384 385 386

MODULE_CONFIG_STOP

MODULE_INIT_START
    SET_DESCRIPTION( "Main program" )
    ADD_CAPABILITY( MAIN, 100/*whatever*/ )
MODULE_INIT_STOP

MODULE_ACTIVATE_START
MODULE_ACTIVATE_STOP

MODULE_DEACTIVATE_START
MODULE_DEACTIVATE_STOP
gbazin's avatar
 
gbazin committed
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403

/* Hack for help options */
static module_t help_module;
static module_config_t p_help_config[] = {
    { MODULE_CONFIG_ITEM_BOOL, "help", "print help (or use -h)",
      NULL, NULL, 0, NULL, NULL, 0 },
    { MODULE_CONFIG_ITEM_BOOL, "longhelp", "print detailed help (or use -H)",
      NULL, NULL, 0, NULL, NULL, 0 },
    { MODULE_CONFIG_ITEM_BOOL, "list", "print a list of available plugins "
      "(or use -l)", NULL, NULL, 0, NULL, NULL, 0 },
    { MODULE_CONFIG_ITEM_STRING, "plugin", "print help on plugin (or use -p)",
      NULL, NULL, 0, NULL, &help_module.config_lock, 0 },
    { MODULE_CONFIG_ITEM_BOOL, "version", "print version information",
      NULL, NULL, 0, NULL, NULL, 0 },
    { MODULE_CONFIG_HINT_END, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0 } };


gbazin's avatar
 
gbazin committed
404 405
/*****************************************************************************
 * End configuration.
406
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
407

408
/*****************************************************************************
Sam Hocevar's avatar
 
Sam Hocevar committed
409
 * Global variables - these are the only ones, see main.h and modules.h
410
 *****************************************************************************/
Sam Hocevar's avatar
 
Sam Hocevar committed
411 412
main_t        *p_main;
module_bank_t *p_module_bank;
Sam Hocevar's avatar
 
Sam Hocevar committed
413
input_bank_t  *p_input_bank;
Sam Hocevar's avatar
 
Sam Hocevar committed
414 415
aout_bank_t   *p_aout_bank;
vout_bank_t   *p_vout_bank;
Michel Kaempf's avatar
Michel Kaempf committed
416

417
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
418
 * Local prototypes
419
 *****************************************************************************/
gbazin's avatar
 
gbazin committed
420 421 422 423 424 425 426 427 428 429 430 431 432 433
static int  GetFilenames                ( int i_argc, char *ppsz_argv[] );
static void Usage                       ( const char *psz_module_name );
static void ListModules                 ( void );
static void Version                     ( void );

static void InitSignalHandler           ( void );
static void SimpleSignalHandler         ( int i_signal );
static void FatalSignalHandler          ( int i_signal );
static void IllegalSignalHandler        ( int i_signal );
static u32  CPUCapabilities             ( void );

#ifdef WIN32
static void ShowConsole                 ( void );
#endif
gbazin's avatar
 
gbazin committed
434

435
static jmp_buf env;
Sam Hocevar's avatar
 
Sam Hocevar committed
436 437
static int     i_illegal;
static char   *psz_capability;
Sam Hocevar's avatar
 
Sam Hocevar committed
438

439
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
440
 * main: parse command line, start interface and spawn threads
441
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
442 443
 * Steps during program execution are:
 *      -configuration parsing and messages interface initialization
444
 *      -opening of audio output device and some global modules
Michel Kaempf's avatar
Michel Kaempf committed
445
 *      -execution of interface, which exit on error or on user request
Vincent Seguin's avatar
Vincent Seguin committed
446
 *      -closing of audio output device and some global modules
447
 * On error, the spawned threads are canceled, and the open devices closed.
448
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
449 450
int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
{
Sam Hocevar's avatar
 
Sam Hocevar committed
451 452
    main_t        main_data;                /* root of all data - see main.h */
    module_bank_t module_bank;
Sam Hocevar's avatar
 
Sam Hocevar committed
453
    input_bank_t  input_bank;
Sam Hocevar's avatar
 
Sam Hocevar committed
454 455
    aout_bank_t   aout_bank;
    vout_bank_t   vout_bank;
gbazin's avatar
 
gbazin committed
456
    char *psz_plugin;
gbazin's avatar
 
gbazin committed
457
    char *p_tmp;
458

Sam Hocevar's avatar
 
Sam Hocevar committed
459 460
    p_main        = &main_data;               /* set up the global variables */
    p_module_bank = &module_bank;
Sam Hocevar's avatar
 
Sam Hocevar committed
461
    p_input_bank  = &input_bank;
Sam Hocevar's avatar
 
Sam Hocevar committed
462 463
    p_aout_bank   = &aout_bank;
    p_vout_bank   = &vout_bank;
Sam Hocevar's avatar
 
Sam Hocevar committed
464

gbazin's avatar
 
gbazin committed
465 466
    p_main->i_warning_level = 0;

Sam Hocevar's avatar
 
Sam Hocevar committed
467
#if defined( ENABLE_NLS ) && defined ( HAVE_GETTEXT )
Sam Hocevar's avatar
 
Sam Hocevar committed
468
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
469 470
     * Support for getext
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
471 472
#if defined( HAVE_LOCALE_H ) && defined( HAVE_LC_MESSAGES )
    if( !setlocale( LC_MESSAGES, "" ) )
Sam Hocevar's avatar
 
Sam Hocevar committed
473 474 475
    {
        fprintf( stderr, "warning: unsupported locale.\n" );
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
476
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
477

Sam Hocevar's avatar
 
Sam Hocevar committed
478
    if( !bindtextdomain( PACKAGE, LOCALEDIR ) )
Sam Hocevar's avatar
 
Sam Hocevar committed
479 480 481 482 483 484 485
    {
        fprintf( stderr, "warning: no domain %s in directory %s\n",
                 PACKAGE, LOCALEDIR );
    }

    textdomain( PACKAGE );
#endif
Sam Hocevar's avatar
 
Sam Hocevar committed
486

Sam Hocevar's avatar
 
Sam Hocevar committed
487
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
488
     * Initialize threads system
Sam Hocevar's avatar
 
Sam Hocevar committed
489
     */
gbazin's avatar
 
gbazin committed
490
    vlc_threads_init();
Sam Hocevar's avatar
 
Sam Hocevar committed
491

Sam Hocevar's avatar
 
Sam Hocevar committed
492
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
493
     * Test if our code is likely to run on this CPU
Sam Hocevar's avatar
 
Sam Hocevar committed
494 495
     */
    p_main->i_cpu_capabilities = CPUCapabilities();
Sam Hocevar's avatar
 
Sam Hocevar committed
496

Sam Hocevar's avatar
 
Sam Hocevar committed
497 498 499
    /*
     * System specific initialization code
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
500
#if defined( SYS_BEOS ) || defined( SYS_DARWIN ) || defined( WIN32 )
Sam Hocevar's avatar
 
Sam Hocevar committed
501
    system_Init( &i_argc, ppsz_argv, ppsz_env );
502 503 504 505

#elif defined( SYS_LINUX )
#   ifdef DEBUG
    /* Activate malloc checking routines to detect heap corruptions. */
gbazin's avatar
 
gbazin committed
506
    putenv( "MALLOC_CHECK_=2" );
Sam Hocevar's avatar
 
Sam Hocevar committed
507
    putenv( "GNOME_DISABLE_CRASH_DIALOG=1" );
508
#   endif
509
#endif
510 511 512 513

    /*
     * Initialize messages interface
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
514
    intf_MsgCreate();
515

Sam Hocevar's avatar
 
Sam Hocevar committed
516
    intf_Msg( COPYRIGHT_MESSAGE "\n" );
Sam Hocevar's avatar
 
Sam Hocevar committed
517

gbazin's avatar
 
gbazin committed
518 519 520 521 522 523 524 525 526

    /* Get the executable name (similar to the basename command) */
    p_main->psz_arg0 = p_tmp = ppsz_argv[ 0 ];
    while( *p_tmp )
    {
        if( *p_tmp == '/' ) p_main->psz_arg0 = ++p_tmp;
        else ++p_tmp;
    }

527
    /*
gbazin's avatar
 
gbazin committed
528 529 530
     * Initialize the module bank and and load the configuration of the main
     * module. We need to do this at this stage to be able to display a short
     * help if required by the user. (short help == main module options)
531
     */
gbazin's avatar
 
gbazin committed
532 533 534
    module_InitBank();
    module_LoadMain();

gbazin's avatar
 
gbazin committed
535 536 537 538 539 540 541 542 543 544 545
    /* Hack: insert the help module here */
    help_module.psz_name = "help";
    help_module.i_config_lines = sizeof(p_help_config) /
                                     sizeof(module_config_t);
    help_module.i_config_items = help_module.i_config_lines - 1;
    vlc_mutex_init( &help_module.config_lock );
    help_module.p_config = p_help_config;
    help_module.next = p_module_bank->first;
    p_module_bank->first = &help_module;
    /* end hack */

gbazin's avatar
 
gbazin committed
546
    if( config_LoadCmdLine( &i_argc, ppsz_argv, 1 ) )
Michel Kaempf's avatar
Michel Kaempf committed
547
    {
Vincent Seguin's avatar
Vincent Seguin committed
548
        intf_MsgDestroy();
549
        return( errno );
Michel Kaempf's avatar
Michel Kaempf committed
550
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
551

gbazin's avatar
 
gbazin committed
552 553 554
    /* Check for short help option */
    if( config_GetIntVariable( "help" ) )
    {
gbazin's avatar
 
gbazin committed
555 556 557 558
        intf_Msg( "Usage: %s [options] [parameters] [file]...\n",
                  p_main->psz_arg0 );

        Usage( "help" );
gbazin's avatar
 
gbazin committed
559 560 561 562 563 564 565 566 567 568 569
        Usage( "main" );
        return( -1 );
    }

    /* Check for version option */
    if( config_GetIntVariable( "version" ) )
    {
        Version();
        return( -1 );
    }

gbazin's avatar
 
gbazin committed
570 571 572 573
    /* Hack: remove the help module here */
    p_module_bank->first = help_module.next;
    /* end hack */

gbazin's avatar
 
gbazin committed
574
    /*
gbazin's avatar
 
gbazin committed
575
     * Load the builtins and plugins into the module_bank.
gbazin's avatar
 
gbazin committed
576
     * We have to do it before config_Load*() because this also gets the
gbazin's avatar
 
gbazin committed
577 578
     * list of configuration options exported by each plugin and loads their
     * default values.
gbazin's avatar
 
gbazin committed
579
     */
gbazin's avatar
 
gbazin committed
580 581 582 583 584
    module_LoadBuiltins();
    module_LoadPlugins();
    intf_WarnMsg( 2, "module: module bank initialized, found %i modules",
                  p_module_bank->i_count );

gbazin's avatar
 
gbazin committed
585 586 587 588 589
    /* Hack: insert the help module here */
    help_module.next = p_module_bank->first;
    p_module_bank->first = &help_module;
    /* end hack */

gbazin's avatar
 
gbazin committed
590
    /* Check for help on plugins */
gbazin's avatar
 
gbazin committed
591
    if( (p_tmp = config_GetPszVariable( "plugin" )) )
gbazin's avatar
 
gbazin committed
592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
    {
        Usage( p_tmp );
        free( p_tmp );
        return( -1 );
    }

    /* Check for long help option */
    if( config_GetIntVariable( "longhelp" ) )
    {
        Usage( NULL );
        return( -1 );
    }

    /* Check for plugin list option */
    if( config_GetIntVariable( "list" ) )
    {
        ListModules();
        return( -1 );
    }

gbazin's avatar
 
gbazin committed
612 613 614 615 616
    /* Hack: remove the help module here */
    p_module_bank->first = help_module.next;
    /* end hack */


gbazin's avatar
 
gbazin committed
617 618 619
    /*
     * Override default configuration with config file settings
     */
gbazin's avatar
 
gbazin committed
620
    vlc_mutex_init( &p_main->config_lock );
gbazin's avatar
 
gbazin committed
621
    p_main->psz_homedir = config_GetHomeDir();
gbazin's avatar
 
gbazin committed
622
    config_LoadConfigFile( NULL );
gbazin's avatar
 
gbazin committed
623 624 625 626

    /*
     * Override configuration with command line settings
     */
gbazin's avatar
 
gbazin committed
627
    if( config_LoadCmdLine( &i_argc, ppsz_argv, 0 ) )
gbazin's avatar
 
gbazin committed
628
    {
gbazin's avatar
 
gbazin committed
629 630 631 632 633 634 635
#ifdef WIN32
        ShowConsole();
        /* Pause the console because it's destroyed when we exit */
        intf_Msg( "The command line options couldn't be loaded, check that "
                  "they are valid.\nPress the RETURN key to continue..." );
        getchar();
#endif
gbazin's avatar
 
gbazin committed
636 637 638 639
        intf_MsgDestroy();
        return( errno );
    }

gbazin's avatar
 
gbazin committed
640

gbazin's avatar
 
gbazin committed
641
    /* p_main inititalization. FIXME ? */
gbazin's avatar
 
gbazin committed
642
    p_main->i_desync = (mtime_t)config_GetIntVariable( "desync" )
gbazin's avatar
 
gbazin committed
643
      * (mtime_t)1000;
gbazin's avatar
 
gbazin committed
644 645 646 647 648
    p_main->b_stats = config_GetIntVariable( "stats" );
    p_main->b_audio = !config_GetIntVariable( "noaudio" );
    p_main->b_stereo= !config_GetIntVariable( "mono" );
    p_main->b_video = !config_GetIntVariable( "novideo" );
    if( config_GetIntVariable( "nommx" ) )
gbazin's avatar
 
gbazin committed
649
        p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_MMX;
gbazin's avatar
 
gbazin committed
650
    if( config_GetIntVariable( "no3dn" ) )
gbazin's avatar
 
gbazin committed
651
        p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_3DNOW;
gbazin's avatar
 
gbazin committed
652
    if( config_GetIntVariable( "nommxext" ) )
gbazin's avatar
 
gbazin committed
653
        p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_MMXEXT;
gbazin's avatar
 
gbazin committed
654
    if( config_GetIntVariable( "nosse" ) )
gbazin's avatar
 
gbazin committed
655
        p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_SSE;
gbazin's avatar
 
gbazin committed
656
    if( config_GetIntVariable( "noaltivec" ) )
gbazin's avatar
 
gbazin committed
657 658 659
        p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_ALTIVEC;


660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
    if( p_main->b_stats )
    {
        char          p_capabilities[200];
        p_capabilities[0] = '\0';

#define PRINT_CAPABILITY( capability, string )                              \
        if( p_main->i_cpu_capabilities & capability )                       \
        {                                                                   \
            strncat( p_capabilities, string " ",                            \
                     sizeof(p_capabilities) - strlen(p_capabilities) );     \
            p_capabilities[sizeof(p_capabilities) - 1] = '\0';              \
        }

        PRINT_CAPABILITY( CPU_CAPABILITY_486, "486" );
        PRINT_CAPABILITY( CPU_CAPABILITY_586, "586" );
        PRINT_CAPABILITY( CPU_CAPABILITY_PPRO, "Pentium Pro" );
        PRINT_CAPABILITY( CPU_CAPABILITY_MMX, "MMX" );
        PRINT_CAPABILITY( CPU_CAPABILITY_3DNOW, "3DNow!" );
        PRINT_CAPABILITY( CPU_CAPABILITY_MMXEXT, "MMXEXT" );
        PRINT_CAPABILITY( CPU_CAPABILITY_SSE, "SSE" );
        PRINT_CAPABILITY( CPU_CAPABILITY_ALTIVEC, "Altivec" );
Sam Hocevar's avatar
 
Sam Hocevar committed
681
        PRINT_CAPABILITY( CPU_CAPABILITY_FPU, "FPU" );
Sam Hocevar's avatar
 
Sam Hocevar committed
682
        intf_StatMsg( "info: CPU has capabilities : %s", p_capabilities );
683 684
    }

685
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
686
     * Initialize playlist and get commandline files
687
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
688
    p_main->p_playlist = intf_PlaylistCreate();
Sam Hocevar's avatar
 
Sam Hocevar committed
689
    if( !p_main->p_playlist )
690
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
691
        intf_ErrMsg( "playlist error: playlist initialization failed" );
692 693
        intf_MsgDestroy();
        return( errno );
694
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
695
    intf_PlaylistInit( p_main->p_playlist );
696 697

    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
698
     * Get input filenames given as commandline arguments
699
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
700
    GetFilenames( i_argc, ppsz_argv );
Michel Kaempf's avatar
Michel Kaempf committed
701

Sam Hocevar's avatar
 
Sam Hocevar committed
702
    /*
gbazin's avatar
 
gbazin committed
703
     * Initialize input, aout and vout banks
Sam Hocevar's avatar
 
Sam Hocevar committed
704
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
705
    input_InitBank();
Sam Hocevar's avatar
 
Sam Hocevar committed
706 707
    aout_InitBank();
    vout_InitBank();
Sam Hocevar's avatar
 
Sam Hocevar committed
708

Sam Hocevar's avatar
 
Sam Hocevar committed
709 710 711
    /*
     * Choose the best memcpy module
     */
gbazin's avatar
 
gbazin committed
712
    psz_plugin = config_GetPszVariable( "memcpy" );
Sam Hocevar's avatar
 
Sam Hocevar committed
713
    p_main->p_memcpy_module = module_Need( MODULE_CAPABILITY_MEMCPY, NULL,
gbazin's avatar
 
gbazin committed
714 715
                                           psz_plugin );
    if( psz_plugin ) free( psz_plugin );
Sam Hocevar's avatar
 
Sam Hocevar committed
716
    if( p_main->p_memcpy_module == NULL )
Sam Hocevar's avatar
 
Sam Hocevar committed
717 718 719
    {
        intf_ErrMsg( "intf error: no suitable memcpy module, "
                     "using libc default" );
Sam Hocevar's avatar
 
Sam Hocevar committed
720 721 722 723 724 725
        p_main->pf_memcpy = memcpy;
    }
    else
    {
        p_main->pf_memcpy = p_main->p_memcpy_module->p_functions
                                  ->memcpy.functions.memcpy.pf_memcpy;
Sam Hocevar's avatar
 
Sam Hocevar committed
726
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
727

Michel Kaempf's avatar
Michel Kaempf committed
728 729 730
    /*
     * Initialize shared resources and libraries
     */
gbazin's avatar
 
gbazin committed
731
    if( config_GetIntVariable( "network_channel" ) &&
732
        network_ChannelCreate() )
Michel Kaempf's avatar
Michel Kaempf committed
733
    {
Henri Fallon's avatar
 
Henri Fallon committed
734
        /* On error during Channels initialization, switch off channels */
Sam Hocevar's avatar
 
Sam Hocevar committed
735 736
        intf_ErrMsg( "intf error: channels initialization failed, " 
                                 "deactivating channels" );
gbazin's avatar
 
gbazin committed
737
        config_PutIntVariable( "network_channel", 0 );
Michel Kaempf's avatar
Michel Kaempf committed
738
    }
739

Michel Kaempf's avatar
Michel Kaempf committed
740
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
741
     * Try to run the interface
Michel Kaempf's avatar
Michel Kaempf committed
742
     */
743
    p_main->p_intf = intf_Create();
Sam Hocevar's avatar
 
Sam Hocevar committed
744
    if( p_main->p_intf == NULL )
Sam Hocevar's avatar
 
Sam Hocevar committed
745 746 747
    {
        intf_ErrMsg( "intf error: interface initialization failed" );
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
748
    else
749
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
        /*
         * Set signal handling policy for all threads
         */
        InitSignalHandler();

        /*
         * This is the main loop
         */
        p_main->p_intf->pf_run( p_main->p_intf );

        /*
         * Finished, destroy the interface
         */
        intf_Destroy( p_main->p_intf );

        /*
         * Go back into channel 0 which is the network
         */
gbazin's avatar
 
gbazin committed
768
        if( config_GetIntVariable( "network_channel" ) )
Sam Hocevar's avatar
 
Sam Hocevar committed
769 770 771
        {
            network_ChannelJoin( COMMON_CHANNEL );
        }
772
    }
Michel Kaempf's avatar
Michel Kaempf committed
773

Sam Hocevar's avatar
 
Sam Hocevar committed
774
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
775
     * Free input, aout and vout banks
Sam Hocevar's avatar
 
Sam Hocevar committed
776
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
777
    input_EndBank();
Sam Hocevar's avatar
 
Sam Hocevar committed
778 779 780 781 782 783 784 785
    vout_EndBank();
    aout_EndBank();

    /*
     * Free playlist
     */
    intf_PlaylistDestroy( p_main->p_playlist );

Sam Hocevar's avatar
 
Sam Hocevar committed
786
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
787
     * Free memcpy module if it was allocated
Sam Hocevar's avatar
 
Sam Hocevar committed
788
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
789
    if( p_main->p_memcpy_module != NULL )
Sam Hocevar's avatar
 
Sam Hocevar committed
790
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
791
        module_Unneed( p_main->p_memcpy_module );
Sam Hocevar's avatar
 
Sam Hocevar committed
792
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
793

Sam Hocevar's avatar
 
Sam Hocevar committed
794
    /*
Sam Hocevar's avatar
 
Sam Hocevar committed
795
     * Free module bank
Sam Hocevar's avatar
 
Sam Hocevar committed
796
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
797
    module_EndBank();
798 799 800 801

    /*
     * System specific cleaning code
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
802
#if defined( SYS_BEOS ) || defined( SYS_DARWIN ) || defined( WIN32 )
Sam Hocevar's avatar
 
Sam Hocevar committed
803
    system_End();
804 805
#endif

Sam Hocevar's avatar
 
Sam Hocevar committed
806

Michel Kaempf's avatar
Michel Kaempf committed
807 808 809
    /*
     * Terminate messages interface and program
     */
Sam Hocevar's avatar
 
Sam Hocevar committed
810
    intf_WarnMsg( 1, "intf: program terminated" );
Vincent Seguin's avatar
Vincent Seguin committed
811
    intf_MsgDestroy();
812

Sam Hocevar's avatar
 
Sam Hocevar committed
813 814 815 816
    /*
     * Stop threads system
     */
    vlc_threads_end( );
Sam Hocevar's avatar
 
Sam Hocevar committed
817

Sam Hocevar's avatar
 
Sam Hocevar committed
818
    return 0;
Michel Kaempf's avatar
Michel Kaempf committed
819 820
}

Vincent Seguin's avatar
Vincent Seguin committed
821

gbazin's avatar
 
gbazin committed
822
/* following functions are local */
823

Sam Hocevar's avatar
 
Sam Hocevar committed
824 825 826 827 828 829 830 831
/*****************************************************************************
 * GetFilenames: parse command line options which are not flags
 *****************************************************************************
 * Parse command line for input files.
 *****************************************************************************/
static int GetFilenames( int i_argc, char *ppsz_argv[] )
{
    int i_opt;
Michel Kaempf's avatar
Michel Kaempf committed
832

Sam Hocevar's avatar
 
Sam Hocevar committed
833
    /* We assume that the remaining parameters are filenames */
Vincent Seguin's avatar
Vincent Seguin committed
834 835
    for( i_opt = optind; i_opt < i_argc; i_opt++ )
    {
Sam Hocevar's avatar
 
Sam Hocevar committed
836 837
        intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END,
                          ppsz_argv[ i_opt ] );
Vincent Seguin's avatar
Vincent Seguin committed
838
    }
Sam Hocevar's avatar
 
Sam Hocevar committed
839

Michel Kaempf's avatar
Michel Kaempf committed
840 841 842
    return( 0 );
}

843
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
844
 * Usage: print program usage
845
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
846
 * Print a short inline help. Message interface is initialized at this stage.
847
 *****************************************************************************/
gbazin's avatar
 
gbazin committed
848
static void Usage( const char *psz_module_name )
Michel Kaempf's avatar
Michel Kaempf committed
849
{
gbazin's avatar
 
gbazin committed
850 851 852 853 854 855 856 857 858 859 860 861 862 863
    int i;
    module_t *p_module;
    char psz_spaces[30];

    memset( psz_spaces, 32, 30 );

#ifdef WIN32
    ShowConsole();
#endif

    /* Enumerate the config of each module */
    for( p_module = p_module_bank->first ;
         p_module != NULL ;
         p_module = p_module->next )
864
    {
gbazin's avatar
 
gbazin committed
865 866 867 868

        if( psz_module_name && strcmp( psz_module_name, p_module->psz_name ) )
            continue;

gbazin's avatar
 
gbazin committed
869 870 871
        /* ignore plugins without config options */
        if( !p_module->i_config_items ) continue;

gbazin's avatar
 
gbazin committed
872
        /* print module name */
gbazin's avatar
 
gbazin committed
873
        intf_Msg( "%s options:\n", p_module->psz_name );
gbazin's avatar
 
gbazin committed
874

gbazin's avatar
 
gbazin committed
875
        for( i = 0; i < p_module->i_config_lines; i++ )
gbazin's avatar
 
gbazin committed
876 877 878 879 880
        {
            int j;

            switch( p_module->p_config[i].i_type )
            {
gbazin's avatar
 
gbazin committed
881
            case MODULE_CONFIG_HINT_CATEGORY:
gbazin's avatar
 
gbazin committed
882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910
                intf_Msg( " %s", p_module->p_config[i].psz_text );
                break;

            case MODULE_CONFIG_ITEM_STRING:
            case MODULE_CONFIG_ITEM_FILE:
            case MODULE_CONFIG_ITEM_PLUGIN:
                /* Nasty hack, but right now I'm too tired to think about
                 * a nice solution */
                j = 25 - strlen( p_module->p_config[i].psz_name )
                    - strlen(" <string>") - 1;
                if( j < 0 ) j = 0; psz_spaces[j] = 0;

                intf_Msg( "  --%s <string>%s %s",
                          p_module->p_config[i].psz_name, psz_spaces,
                          p_module->p_config[i].psz_text );
                psz_spaces[j] = 32;
                break;
            case MODULE_CONFIG_ITEM_INTEGER:
                /* Nasty hack, but right now I'm too tired to think about
                 * a nice solution */
                j = 25 - strlen( p_module->p_config[i].psz_name )
                    - strlen(" <integer>") - 1;
                if( j < 0 ) j = 0; psz_spaces[j] = 0;

                intf_Msg( "  --%s <integer>%s %s",
                          p_module->p_config[i].psz_name, psz_spaces,
                          p_module->p_config[i].psz_text );
                psz_spaces[j] = 32;
                break;
gbazin's avatar
 
gbazin committed
911
            case MODULE_CONFIG_ITEM_BOOL:
gbazin's avatar
 
gbazin committed
912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930
                /* Nasty hack, but right now I'm too tired to think about
                 * a nice solution */
                j = 25 - strlen( p_module->p_config[i].psz_name ) - 1;
                if( j < 0 ) j = 0; psz_spaces[j] = 0;

                intf_Msg( "  --%s%s %s",
                          p_module->p_config[i].psz_name, psz_spaces,
                          p_module->p_config[i].psz_text );
                psz_spaces[j] = 32;
                break;
            }
        }

        /* Yet another nasty hack.
         * Maybe we could use MODULE_CONFIG_ITEM_END to display tail messages
         * for each module?? */
        if( !strcmp( "main", p_module->psz_name ) )
            intf_Msg( "\nPlaylist items:"
                "\n  *.mpg, *.vob                   \tPlain MPEG-1/2 files"
gbazin's avatar
 
gbazin committed
931 932
                "\n  [dvd:][device][@raw_device][@[title][,[chapter][,angle]]]"
                "\n                                 \tDVD device"
gbazin's avatar
 
gbazin committed
933 934
                "\n  [vcd:][device][@[title][,[chapter]]"
                "\n                                 \tVCD device"
gbazin's avatar
 
gbazin committed
935 936 937 938 939 940 941 942 943 944 945
                "\n  udpstream:[<server>[:<server port>]][@[<bind address>]"
                      "[:<bind port>]]"
                "\n                                 \tUDP stream sent by VLS"
                "\n  vlc:loop                       \tLoop execution of the "
                      "playlist"
                "\n  vlc:pause                      \tPause execution of "
                      "playlist items"
                "\n  vlc:quit                       \tQuit VLC" );

        intf_Msg( "" );

946 947
    }

gbazin's avatar
 
gbazin committed
948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
#ifdef WIN32        /* Pause the console because it's destroyed when we exit */
        intf_Msg( "\nPress the RETURN key to continue..." );
        getchar();
#endif
}

/*****************************************************************************
 * ListModules: list the available modules with their description
 *****************************************************************************
 * Print a list of all available modules (builtins and plugins) and a short
 * description for each one.
 *****************************************************************************/
static void ListModules( void )
{
    module_t *p_module;
    char psz_spaces[20];

    memset( psz_spaces, 32, 20 );

#ifdef WIN32
    ShowConsole();
#endif

    /* Usage */
    intf_Msg( "Usage: %s [options] [parameters] [file]...\n",
              p_main->psz_arg0 );

    intf_Msg( "[plugin]              [description]" );

    /* Enumerate each module */
    for( p_module = p_module_bank->first ;
         p_module != NULL ;
         p_module = p_module->next )
    {
        int i;

        /* Nasty hack, but right now I'm too tired to think about a nice
         * solution */
        i = 20 - strlen( p_module->psz_name ) - 1;
        if( i < 0 ) i = 0;
        psz_spaces[i] = 0;

        intf_Msg( "  %s%s %s", p_module->psz_name, psz_spaces,
                  p_module->psz_longname );

        psz_spaces[i] = 32;

    }

#ifdef WIN32        /* Pause the console because it's destroyed when we exit */
        intf_Msg( "\nPress the RETURN key to continue..." );
        getchar();
#endif
Michel Kaempf's avatar
Michel Kaempf committed
1001 1002
}

1003
/*****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
1004
 * Version: print complete program version
1005
 *****************************************************************************
Vincent Seguin's avatar
Vincent Seguin committed
1006
 * Print complete program version and build number.
1007
 *****************************************************************************/
Vincent Seguin's avatar
Vincent Seguin committed
1008 1009
static void Version( void )
{
gbazin's avatar
 
gbazin committed
1010 1011 1012
#ifdef WIN32
    ShowConsole();
#endif
gbazin's avatar
 
gbazin committed
1013

Sam Hocevar's avatar
 
Sam Hocevar committed
1014
    intf_Msg( VERSION_MESSAGE
gbazin's avatar
 
gbazin committed
1015 1016 1017
        "This program comes with NO WARRANTY, to the extent permitted by "
        "law.\nYou may redistribute it under the terms of the GNU General "
        "Public License;\nsee the file named COPYING for details.\n"
Sam Hocevar's avatar
 
Sam Hocevar committed
1018
        "Written by the VideoLAN team at Ecole Centrale, Paris." );
gbazin's avatar
 
gbazin committed
1019

gbazin's avatar
 
gbazin committed
1020 1021 1022 1023
#ifdef WIN32        /* Pause the console because it's destroyed when we exit */
        intf_Msg( "\nPress the RETURN key to continue..." );
        getchar();
#endif
1024
}
Vincent Seguin's avatar
Vincent Seguin committed
1025

1026
/*****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
1027
 * InitSignalHandler: system signal handler initialization
1028
 *****************************************************************************
Michel Kaempf's avatar
Michel Kaempf committed
1029
 * Set the signal handlers. SIGTERM is not intercepted, because we need at
1030
 * at least a method to kill the program when all other methods failed, and
Michel Kaempf's avatar
Michel Kaempf committed
1031
 * when we don't want to use SIGKILL.
1032
 *****************************************************************************/
Michel Kaempf's avatar
Michel Kaempf committed
1033 1034
static void InitSignalHandler( void )
{
Vincent Seguin's avatar
Vincent Seguin committed
1035
    /* Termination signals */
Sam Hocevar's avatar
 
Sam Hocevar committed
1036
#ifndef WIN32
Benoit Steiner's avatar
 
Benoit Steiner committed
1037
    signal( SIGINT,  FatalSignalHandler );
Sam Hocevar's avatar
 
Sam Hocevar committed
1038
    signal( SIGHUP,  FatalSignalHandler );
Benoit Steiner's avatar
 
Benoit Steiner committed
1039 1040 1041 1042 1043
    signal( SIGQUIT, FatalSignalHandler );

    /* Other signals */
    signal( SIGALRM, SimpleSignalHandler );
    signal( SIGPIPE, SimpleSignalHandler );
Sam Hocevar's avatar
 
Sam Hocevar committed
1044
#endif
Benoit Steiner's avatar
 
Benoit Steiner committed
1045 1046 1047 1048 1049 1050 1051 1052 1053 1054
}

/*****************************************************************************
 * SimpleSignalHandler: system signal handler
 *****************************************************************************
 * This function is called when a non fatal signal is received by the program.
 *****************************************************************************/
static void SimpleSignalHandler( int i_signal )
{
    /* Acknowledge the signal received */
Sam Hocevar's avatar
 
Sam Hocevar committed
1055
    intf_WarnMsg( 0, "intf: ignoring signal %d", i_signal );
Michel Kaempf's avatar
Michel Kaempf committed
1056 1057
}

1058
/*****************************************************************************
Benoit Steiner's avatar
 
Benoit Steiner committed
1059
 * FatalSignalHandler: system signal handler
1060
 *****************************************************************************
Benoit Steiner's avatar
 
Benoit Steiner committed
1061 1062
 * This function is called when a fatal signal is received by the program.
 * It tries to end the program in a clean way.
1063
 *****************************************************************************/
Benoit Steiner's avatar
 
Benoit Steiner committed
1064
static void FatalSignalHandler( int i_signal )
Michel Kaempf's avatar
Michel Kaempf committed
1065
{
Sam Hocevar's avatar
 
Sam Hocevar committed
1066 1067 1068
    /* Once a signal has been trapped, the termination sequence will be
     * armed and following signals will be ignored to avoid sending messages
     * to an interface having been destroyed */
Sam Hocevar's avatar
 
Sam Hocevar committed
1069
#ifndef WIN32