X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finterface%2Fmain.c;h=99d4c867fa55ed35744c6e5fead319878018d302;hb=08999a39bccd9b1b199294933a54c50e94f4148f;hp=442955b40383024651abfbf317ad6edf41974312;hpb=d0c9b47957ec825d43aba1b27202bba5170c0d08;p=vlc diff --git a/src/interface/main.c b/src/interface/main.c index 442955b403..99d4c867fa 100644 --- a/src/interface/main.c +++ b/src/interface/main.c @@ -3,17 +3,18 @@ * Includes the main() function for vlc. Parses command line, start interface * and spawn threads. ***************************************************************************** - * Copyright (C) 1998, 1999, 2000 VideoLAN - * $Id: main.c,v 1.108 2001/07/18 14:21:00 massiot Exp $ + * Copyright (C) 1998-2001 VideoLAN + * $Id: main.c,v 1.187 2002/04/24 00:36:24 sam Exp $ * * Authors: Vincent Seguin * Samuel Hocevar + * Gildas Bazin * * 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 @@ -27,12 +28,12 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include "defs.h" - #include /* SIGHUP, SIGINT, SIGKILL */ #include /* sprintf() */ #include /* longjmp, setjmp */ +#include + #ifdef HAVE_GETOPT_LONG # ifdef HAVE_GETOPT_H # include /* getopt() */ @@ -49,31 +50,28 @@ #endif #ifndef WIN32 -#include /* BSD: struct in_addr */ +# include /* BSD: struct in_addr */ #endif #ifdef HAVE_UNISTD_H -#include +# include +#elif defined( _MSC_VER ) && defined( _WIN32 ) +# include +#endif + +#ifdef HAVE_LOCALE_H +# include #endif #include /* ENOMEM */ #include /* getenv(), strtol(), */ #include /* strerror() */ -#include /* open(), O_WRONLY */ -#include /* S_IREAD */ -#include "config.h" -#include "common.h" -#include "debug.h" -#include "threads.h" -#include "mtime.h" -#include "tests.h" /* TestCPU() */ -#include "modules.h" +#include "netutils.h" /* network_ChannelJoin */ #include "stream_control.h" #include "input_ext-intf.h" -#include "intf_msg.h" #include "intf_playlist.h" #include "interface.h" @@ -82,162 +80,383 @@ #include "video.h" #include "video_output.h" -#ifdef SYS_BEOS -# include "beos_specific.h" -#endif +#include "debug.h" -#ifdef SYS_DARWIN -# include "darwin_specific.h" +/***************************************************************************** + * Configuration options for the main program. Each module 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 */ + + +#define INTF_TEXT N_("interface module") +#define INTF_LONGTEXT N_( \ + "This option allows you to select the interface used by vlc.\nNote that " \ + "the default behavior is to automatically select the best method " \ + "available.") + +#define WARNING_TEXT N_("warning level (or use -v, -vv, etc...)") +#define WARNING_LONGTEXT N_( \ + "Increasing the warning level will allow you to see more debug messages " \ + "and can sometimes help you to troubleshoot a problem.") + +#define STATS_TEXT N_("output statistics") +#define STATS_LONGTEXT N_( \ + "Enabling the stats mode will flood your log console with various " \ + "statistics messages.") + +#define INTF_PATH_TEXT N_("interface default search path") +#define INTF_PATH_LONGTEXT N_( \ + "This option allows you to set the default path that the interface will " \ + "open when looking for a file.") + +#define AOUT_TEXT N_("audio output module") +#define AOUT_LONGTEXT N_( \ + "This option allows you to select the audio audio output method used by " \ + "vlc.\nNote that the default behavior is to automatically select the " \ + "best method available.") + +#define NOAUDIO_TEXT N_("disable audio") +#define NOAUDIO_LONGTEXT N_( \ + "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 N_("mono audio") +#define MONO_LONGTEXT N_("This will force a mono audio output") + +#define VOLUME_TEXT N_("audio output volume") +#define VOLUME_LONGTEXT N_( \ + "You can set the default audio output volume here, in a range from 0 to " \ + "1024.") + +#define FORMAT_TEXT N_("audio output format") +#define FORMAT_LONGTEXT N_( \ + "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 N_("audio output frequency (Hz)") +#define RATE_LONGTEXT N_( \ + "You can force the audio output frequency here.\nCommon values are " \ + "48000, 44100, 32000, 22050, 16000, 11025, 8000.") + +#define DESYNC_TEXT N_("compensate desynchronization of audio (in ms)") +#define DESYNC_LONGTEXT N_( \ + "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 N_("video output module") +#define VOUT_LONGTEXT N_( \ + "This option allows you to select the video output method used by vlc.\n" \ + "Note that the default behavior is to automatically select the best " \ + "method available.") + +#define NOVIDEO_TEXT N_("disable video") +#define NOVIDEO_LONGTEXT N_( \ + "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 N_("display identifier") +#define DISPLAY_LONGTEXT "" + +#define WIDTH_TEXT N_("video width") +#define WIDTH_LONGTEXT N_( \ + "You can enforce the video width here.\nNote that by default vlc will " \ + "adapt to the video characteristics.") + +#define HEIGHT_TEXT N_("video height") +#define HEIGHT_LONGTEXT N_( \ + "You can enforce the video height here.\nNote that by default vlc will " \ + "adapt to the video characteristics.") + +#define ZOOM_TEXT N_("zoom video") +#define ZOOM_LONGTEXT N_( \ + "You can zoom the video by the specified factor.") + +#define GRAYSCALE_TEXT N_("grayscale video output") +#define GRAYSCALE_LONGTEXT N_( \ + "Using this option, vlc will not decode the color information from the " \ + "video (this can also allow you to save some processing power).") + +#define FULLSCREEN_TEXT N_("fullscreen video output") +#define FULLSCREEN_LONGTEXT N_( \ + "If this option is enabled, vlc will always start a video in fullscreen " \ + "mode.") + +#define NOOVERLAY_TEXT N_("disable hardware acceleration for the video output") +#define NOOVERLAY_LONGTEXT N_( \ + "By default vlc will try to take advantage of the overlay capabilities " \ + "of you graphics card.") + +#define SPUMARGIN_TEXT N_("force SPU position") +#define SPUMARGIN_LONGTEXT "" + +#define FILTER_TEXT N_("video filter module") +#define FILTER_LONGTEXT "" + +#define SERVER_PORT_TEXT N_("server port") +#define SERVER_PORT_LONGTEXT "" + +#define NETCHANNEL_TEXT N_("enable network channel mode") +#define NETCHANNEL_LONGTEXT "" + +#define CHAN_SERV_TEXT N_("channel server address") +#define CHAN_SERV_LONGTEXT "" + +#define CHAN_PORT_TEXT N_("channel server port") +#define CHAN_PORT_LONGTEXT "" + +#define IFACE_TEXT N_("network interface") +#define IFACE_LONGTEXT "" + +#define INPUT_PROGRAM_TEXT N_("choose program (SID)") +#define INPUT_PROGRAM_LONGTEXT N_( \ + "Choose the program to select by giving its Service ID.") + +#define INPUT_AUDIO_TEXT N_("choose audio") +#define INPUT_AUDIO_LONGTEXT "" + +#define INPUT_CHAN_TEXT N_("choose channel") +#define INPUT_CHAN_LONGTEXT "" + +#define INPUT_SUBT_TEXT N_("choose subtitles") +#define INPUT_SUBT_LONGTEXT "" + +#define DVD_DEV_TEXT N_("DVD device") +#define DVD_DEV_LONGTEXT "" + +#define VCD_DEV_TEXT N_("VCD device") +#define VCD_DEV_LONGTEXT "" + +#define IPV6_TEXT N_("force IPv6") +#define IPV6_LONGTEXT "" + +#define IPV4_TEXT N_("force IPv4") +#define IPV4_LONGTEXT "" + +#define ADEC_MPEG_TEXT N_("choose MPEG audio decoder") +#define ADEC_MPEG_LONGTEXT "" + +#define ADEC_AC3_TEXT N_("choose AC3 audio decoder") +#define ADEC_AC3_LONGTEXT "" + +#define VDEC_SMP_TEXT N_("use additional processors") +#define VDEC_SMP_LONGTEXT "" + +#define VPAR_SYNCHRO_TEXT N_("force synchro algorithm {I|I+|IP|IP+|IPB}") +#define VPAR_SYNCHRO_LONGTEXT "" + +#define NOMMX_TEXT N_("disable CPU's MMX support") +#define NOMMX_LONGTEXT "" + +#define NO3DN_TEXT N_("disable CPU's 3D Now! support") +#define NO3DN_LONGTEXT "" + +#define NOMMXEXT_TEXT N_("disable CPU's MMX EXT support") +#define NOMMXEXT_LONGTEXT "" + +#define NOSSE_TEXT N_("disable CPU's SSE support") +#define NOSSE_LONGTEXT "" + +#define NOALTIVEC_TEXT N_("disable CPU's AltiVec support") +#define NOALTIVEC_LONGTEXT "" + +#define PLAYLIST_LAUNCH_TEXT N_("launch playlist on startup") +#define PLAYLIST_LAUNCH_LONGTEXT "" + +#define PLAYLIST_ENQUEUE_TEXT N_("enqueue playlist as default") +#define PLAYLIST_ENQUEUE_LONGTEXT "" + +#define PLAYLIST_LOOP_TEXT N_("loop playlist on end") +#define PLAYLIST_LOOP_LONGTEXT "" + +#define MEMCPY_TEXT N_("memory copy module") +#define MEMCPY_LONGTEXT "" + +#define FAST_PTHREAD_TEXT N_("fast pthread on NT/2K/XP (developpers only)") +#define FAST_PTHREAD_LONGTEXT N_( \ + "On Windows NT/2K/XP we use a slow but correct pthread implementation, " \ + "you can also use this faster implementation but you might experience " \ + "problems with it.") + +/* + * Quick usage guide for the configuration options: + * + * MODULE_CONFIG_START + * MODULE_CONFIG_STOP + * ADD_CATEGORY_HINT( N_(text), longtext ) + * ADD_SUBCATEGORY_HINT( N_(text), longtext ) + * ADD_STRING( option_name, value, p_callback, N_(text), N_(longtext) ) + * ADD_FILE( option_name, psz_value, p_callback, N_(text), N_(longtext) ) + * ADD_MODULE( option_name, psz_value, i_capability, p_callback, + * N_(text), N_(longtext) ) + * ADD_INTEGER( option_name, i_value, p_callback, N_(text), N_(longtext) ) + * ADD_BOOL( option_name, p_callback, N_(text), N_(longtext) ) + */ + +MODULE_CONFIG_START + +/* Interface options */ +ADD_CATEGORY_HINT( N_("Interface"), NULL) +ADD_MODULE_WITH_SHORT ( "intf", 'I', 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( N_("Audio"), NULL) +ADD_MODULE_WITH_SHORT ( "aout", 'A', 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 ) +ADD_INTEGER ( "audio-format", 0, NULL, FORMAT_TEXT, + FORMAT_LONGTEXT ) + +/* Video options */ +ADD_CATEGORY_HINT( N_("Video"), NULL ) +ADD_MODULE_WITH_SHORT ( "vout", 'V', MODULE_CAPABILITY_VOUT, NULL, NULL, VOUT_TEXT, VOUT_LONGTEXT ) +ADD_BOOL ( "novideo", NULL, NOVIDEO_TEXT, NOVIDEO_LONGTEXT ) +ADD_INTEGER ( "width", -1, NULL, WIDTH_TEXT, WIDTH_LONGTEXT ) +ADD_INTEGER ( "height", -1, NULL, HEIGHT_TEXT, HEIGHT_LONGTEXT ) +ADD_FLOAT ( "zoom", 1, NULL, ZOOM_TEXT, ZOOM_LONGTEXT ) +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_MODULE ( "filter", MODULE_CAPABILITY_VOUT, NULL, NULL, FILTER_TEXT, FILTER_LONGTEXT ) + +/* Input options */ +ADD_CATEGORY_HINT( N_("Input"), NULL ) +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 ( "program", 0, NULL, INPUT_PROGRAM_TEXT, INPUT_PROGRAM_LONGTEXT ) +ADD_INTEGER ( "audio-type", -1, NULL, INPUT_AUDIO_TEXT, INPUT_AUDIO_LONGTEXT ) +ADD_INTEGER ( "audio-channel", -1, NULL, INPUT_CHAN_TEXT, INPUT_CHAN_LONGTEXT ) +ADD_INTEGER ( "spu-channel", -1, NULL, INPUT_SUBT_TEXT, INPUT_SUBT_LONGTEXT ) + +ADD_STRING ( "dvd", "/dev/dvd", NULL, DVD_DEV_TEXT, DVD_DEV_LONGTEXT ) +ADD_STRING ( "vcd", "/dev/cdrom", NULL, VCD_DEV_TEXT, VCD_DEV_LONGTEXT ) + +ADD_BOOL_WITH_SHORT ( "ipv6", '6', NULL, IPV6_TEXT, IPV6_LONGTEXT ) +ADD_BOOL_WITH_SHORT ( "ipv4", '4', NULL, IPV4_TEXT, IPV4_LONGTEXT ) + +/* Decoder options */ +ADD_CATEGORY_HINT( N_("Decoders"), NULL ) +ADD_MODULE ( "mpeg-adec", MODULE_CAPABILITY_DECODER, NULL, NULL, ADEC_MPEG_TEXT, ADEC_MPEG_LONGTEXT ) +ADD_MODULE ( "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 ) + +/* CPU options */ +ADD_CATEGORY_HINT( N_("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 ) + +/* Playlist options */ +ADD_CATEGORY_HINT( N_("Playlist"), NULL ) +ADD_BOOL ( "launch-playlist", NULL, PLAYLIST_LAUNCH_TEXT, PLAYLIST_LAUNCH_LONGTEXT ) +ADD_BOOL ( "enqueue-playlist", NULL, PLAYLIST_ENQUEUE_TEXT, PLAYLIST_ENQUEUE_LONGTEXT ) +ADD_BOOL ( "loop-playlist", NULL, PLAYLIST_LOOP_TEXT, PLAYLIST_LOOP_LONGTEXT ) + +/* Misc options */ +ADD_CATEGORY_HINT( N_("Miscellaneous"), NULL ) +ADD_MODULE ( "memcpy", MODULE_CAPABILITY_MEMCPY, NULL, NULL, MEMCPY_TEXT, MEMCPY_LONGTEXT ) +ADD_MODULE ( "access", MODULE_CAPABILITY_ACCESS, NULL, NULL, "access module", "This is a legacy entry to let you configure access modules" ) +ADD_MODULE ( "demux", MODULE_CAPABILITY_DEMUX, NULL, NULL, "demux module", "This is a legacy entry to let you configure demux modules" ) + +#if defined(WIN32) +ADD_BOOL ( "fast_pthread", NULL, FAST_PTHREAD_TEXT, FAST_PTHREAD_LONGTEXT ) #endif -#include "netutils.h" /* network_ChannelJoin */ +MODULE_CONFIG_STOP -#include "main.h" +MODULE_INIT_START + SET_DESCRIPTION( N_("main program") ) + ADD_CAPABILITY( MAIN, 100/*whatever*/ ) +MODULE_INIT_STOP -/***************************************************************************** - * Command line options constants. If something is changed here, be sure that - * GetConfiguration and Usage are also changed. - *****************************************************************************/ +MODULE_ACTIVATE_START +MODULE_ACTIVATE_STOP -/* 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 -#define OPT_STEREO 151 -#define OPT_MONO 152 -#define OPT_SPDIF 153 - -#define OPT_NOVIDEO 160 -#define OPT_DISPLAY 161 -#define OPT_WIDTH 162 -#define OPT_HEIGHT 163 -#define OPT_COLOR 164 -#define OPT_FULLSCREEN 165 -#define OPT_OVERLAY 166 -#define OPT_SMP 167 - -#define OPT_CHANNELS 170 -#define OPT_SERVER 171 -#define OPT_PORT 172 -#define OPT_BROADCAST 173 - -#define OPT_INPUT 180 -#define OPT_MOTION 181 -#define OPT_IDCT 182 -#define OPT_YUV 183 -#define OPT_DOWNMIX 184 -#define OPT_IMDCT 185 - -#define OPT_SYNCHRO 190 -#define OPT_WARNING 191 -#define OPT_VERSION 192 -#define OPT_STDOUT 193 - -/* Usage fashion */ -#define USAGE 0 -#define SHORT_HELP 1 -#define LONG_HELP 2 - -/* Needed for x86 CPU capabilities detection */ -#define cpuid( a ) \ - asm volatile ( "cpuid" \ - : "=a" ( i_eax ), \ - "=b" ( i_ebx ), \ - "=c" ( i_ecx ), \ - "=d" ( i_edx ) \ - : "a" ( a ) \ - : "cc" ); +MODULE_DEACTIVATE_START +MODULE_DEACTIVATE_STOP -/* Long options */ -static const struct option longopts[] = +/* Hack for help options */ +static module_t help_module; +static module_config_t p_help_config[] = { - /* name, has_arg, flag, val */ - - /* General/common options */ - { "help", 0, 0, 'h' }, - { "longhelp", 0, 0, 'H' }, - { "version", 0, 0, OPT_VERSION }, - - /* Interface options */ - { "intf", 1, 0, 'I' }, - { "warning", 1, 0, OPT_WARNING }, - { "stdout", 1, 0, OPT_STDOUT }, - - /* Audio options */ - { "noaudio", 0, 0, OPT_NOAUDIO }, - { "aout", 1, 0, 'A' }, - { "stereo", 0, 0, OPT_STEREO }, - { "mono", 0, 0, OPT_MONO }, - { "spdif", 0, 0, OPT_SPDIF }, - { "downmix", 1, 0, OPT_DOWNMIX }, - { "imdct", 1, 0, OPT_IMDCT }, - - /* Video options */ - { "novideo", 0, 0, OPT_NOVIDEO }, - { "vout", 1, 0, 'V' }, - { "display", 1, 0, OPT_DISPLAY }, - { "width", 1, 0, OPT_WIDTH }, - { "height", 1, 0, OPT_HEIGHT }, - { "grayscale", 0, 0, 'g' }, - { "color", 0, 0, OPT_COLOR }, - { "motion", 1, 0, OPT_MOTION }, - { "idct", 1, 0, OPT_IDCT }, - { "yuv", 1, 0, OPT_YUV }, - { "fullscreen", 0, 0, OPT_FULLSCREEN }, - { "overlay", 0, 0, OPT_OVERLAY }, - { "smp", 1, 0, OPT_SMP }, - - /* DVD options */ - { "dvdtitle", 1, 0, 't' }, - { "dvdchapter", 1, 0, 'T' }, - { "dvdangle", 1, 0, 'u' }, - { "dvdaudio", 1, 0, 'a' }, - { "dvdchannel", 1, 0, 'c' }, - { "dvdsubtitle", 1, 0, 's' }, - - /* Input options */ - { "input", 1, 0, OPT_INPUT }, - { "server", 1, 0, OPT_SERVER }, - { "port", 1, 0, OPT_PORT }, - { "broadcast", 1, 0, OPT_BROADCAST }, - { "channels", 0, 0, OPT_CHANNELS }, - - /* Synchro options */ - { "synchro", 1, 0, OPT_SYNCHRO }, - { 0, 0, 0, 0 } + { MODULE_CONFIG_ITEM_BOOL, "help", 'h', N_("print help"), + NULL, NULL, 0, 0, NULL, NULL, 0 }, + { MODULE_CONFIG_ITEM_BOOL, "longhelp", 'H', N_("print detailed help"), + NULL, NULL, 0, 0, NULL, NULL, 0 }, + { MODULE_CONFIG_ITEM_BOOL, "list", 'l', N_("print a list of available " + "modules"), NULL, NULL, 0, 0, NULL, NULL, 0 }, + { MODULE_CONFIG_ITEM_STRING, "module", 'p', N_("print help on module " + ""), NULL, NULL, 0, 0, NULL, &help_module.config_lock, 0 }, + { MODULE_CONFIG_ITEM_BOOL, "version", '\0', + N_("print version information"), NULL, NULL, 0, 0, NULL, NULL, 0 }, + { MODULE_CONFIG_HINT_END, NULL, '\0', NULL, NULL, NULL, 0, 0, + NULL, NULL, 0 } }; -/* Short options */ -static const char *psz_shortopts = "hHvgt:T:u:a:s:c:I:A:V:"; +/***************************************************************************** + * End configuration. + *****************************************************************************/ /***************************************************************************** - * Global variable program_data - these are the only ones, see main.h and - * modules.h + * Global variables - these are the only ones, see main.h and modules.h *****************************************************************************/ main_t *p_main; +p_main_sys_t p_main_sys; module_bank_t *p_module_bank; +input_bank_t *p_input_bank; aout_bank_t *p_aout_bank; vout_bank_t *p_vout_bank; /***************************************************************************** * Local prototypes *****************************************************************************/ -static int GetConfiguration ( int *pi_argc, char *ppsz_argv[], - char *ppsz_env[] ); -static int GetFilenames ( int i_argc, char *ppsz_argv[] ); -static void Usage ( int i_fashion ); -static void Version ( void ); - -static void InitSignalHandler ( void ); -static void SimpleSignalHandler ( int i_signal ); -static void FatalSignalHandler ( int i_signal ); -static void InstructionSignalHandler( int i_signal ); -static int CPUCapabilities ( void ); - -static int RedirectSTDOUT ( void ); -static void ShowConsole ( void ); +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 static jmp_buf env; -static int i_illegal; +static int i_illegal; +static char *psz_capability; /***************************************************************************** * main: parse command line, start interface and spawn threads @@ -253,67 +472,260 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) { main_t main_data; /* root of all data - see main.h */ module_bank_t module_bank; + input_bank_t input_bank; aout_bank_t aout_bank; vout_bank_t vout_bank; + char *psz_module; + char *p_tmp; + struct module_config_s *p_item; p_main = &main_data; /* set up the global variables */ p_module_bank = &module_bank; + p_input_bank = &input_bank; p_aout_bank = &aout_bank; p_vout_bank = &vout_bank; + p_main->i_warning_level = 0; + + /* + * Support for gettext + */ +#if defined( ENABLE_NLS ) && defined ( HAVE_GETTEXT ) +# if defined( HAVE_LOCALE_H ) && defined( HAVE_LC_MESSAGES ) + if( !setlocale( LC_MESSAGES, "" ) ) + { + fprintf( stderr, "warning: unsupported locale settings\n" ); + } + + setlocale( LC_CTYPE, "" ); +# endif + + if( !bindtextdomain( PACKAGE, LOCALEDIR ) ) + { + fprintf( stderr, "warning: no domain %s in directory %s\n", + PACKAGE, LOCALEDIR ); + } + + textdomain( PACKAGE ); +#endif + /* * Initialize threads system */ - vlc_threads_init( ); + vlc_threads_init(); /* - * Test if our code is likely to run on this CPU + * Test if our code is likely to run on this CPU */ p_main->i_cpu_capabilities = CPUCapabilities(); - -#if defined( __pentium__ ) || defined( __pentiumpro__ ) - if( ! TestCPU( CPU_CAPABILITY_586 ) ) - { - fprintf( stderr, "error: this program needs a Pentium CPU,\n" - "please try a version without Pentium support\n" ); - return( 1 ); - } -#endif /* * System specific initialization code */ -#if defined( SYS_BEOS ) || defined( SYS_DARWIN ) +#if defined( SYS_BEOS ) || defined( SYS_DARWIN ) || defined( WIN32 ) system_Init( &i_argc, ppsz_argv, ppsz_env ); + +#elif defined( SYS_LINUX ) +# ifdef DEBUG + /* Activate malloc checking routines to detect heap corruptions. */ + putenv( "MALLOC_CHECK_=2" ); + putenv( "GNOME_DISABLE_CRASH_DIALOG=1" ); +# endif #endif /* * Initialize messages interface */ - p_main->p_msg = intf_MsgCreate(); - if( !p_main->p_msg ) /* start messages interface */ + intf_MsgCreate(); + + intf_Msg( COPYRIGHT_MESSAGE "\n" ); + + + /* Get the executable name (similar to the basename command) */ + if( i_argc > 0 ) + { + p_main->psz_arg0 = p_tmp = ppsz_argv[ 0 ]; + while( *p_tmp ) + { + if( *p_tmp == '/' ) p_main->psz_arg0 = ++p_tmp; + else ++p_tmp; + } + } + else + { + p_main->psz_arg0 = "vlc"; + } + + /* + * 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) + */ + module_InitBank(); + module_LoadMain(); + + /* Hack: insert the help module here */ + help_module.psz_name = "help"; + help_module.psz_longname = _( "help module" ); + help_module.i_config_items = + sizeof(p_help_config) / sizeof(module_config_t) - 1; + vlc_mutex_init( &help_module.config_lock ); + help_module.p_config = config_Duplicate( p_help_config ); + for( p_item = help_module.p_config; + p_item->i_type != MODULE_CONFIG_HINT_END; + p_item++ ) { - fprintf( stderr, "error: can't initialize messages interface (%s)\n", - strerror(errno) ); + p_item->p_lock = &help_module.config_lock; + } + help_module.next = p_module_bank->first; + p_module_bank->first = &help_module; + /* end hack */ + + if( config_LoadCmdLine( &i_argc, ppsz_argv, 1 ) ) + { + intf_MsgDestroy(); return( errno ); } - intf_MsgImm( COPYRIGHT_MESSAGE ); + /* Check for short help option */ + if( config_GetIntVariable( "help" ) ) + { + intf_Msg( _("Usage: %s [options] [parameters] [file]...\n"), + p_main->psz_arg0 ); + + Usage( "help" ); + Usage( "main" ); + return( -1 ); + } + + /* Check for version option */ + if( config_GetIntVariable( "version" ) ) + { + Version(); + return( -1 ); + } + + /* Hack: remove the help module here */ + p_module_bank->first = help_module.next; + /* end hack */ + + /* + * Load the builtins and plugins into the module_bank. + * We have to do it before config_Load*() because this also gets the + * list of configuration options exported by each module and loads their + * default values. + */ + module_LoadBuiltins(); + module_LoadPlugins(); + intf_WarnMsg( 2, "module: module bank initialized, found %i modules", + p_module_bank->i_count ); + + /* Hack: insert the help module here */ + help_module.next = p_module_bank->first; + p_module_bank->first = &help_module; + /* end hack */ + + /* Check for help on modules */ + if( (p_tmp = config_GetPszVariable( "module" )) ) + { + Usage( p_tmp ); + free( p_tmp ); + return( -1 ); + } + + /* Check for long help option */ + if( config_GetIntVariable( "longhelp" ) ) + { + Usage( NULL ); + return( -1 ); + } + + /* Check for module list option */ + if( config_GetIntVariable( "list" ) ) + { + ListModules(); + return( -1 ); + } + + /* Hack: remove the help module here */ + p_module_bank->first = help_module.next; + /* end hack */ + /* - * Read configuration + * Override default configuration with config file settings */ - if( GetConfiguration( &i_argc, ppsz_argv, ppsz_env ) ) /* parse cmd line */ + vlc_mutex_init( &p_main->config_lock ); + p_main->psz_homedir = config_GetHomeDir(); + config_LoadConfigFile( NULL ); + + /* + * Override configuration with command line settings + */ + if( config_LoadCmdLine( &i_argc, ppsz_argv, 0 ) ) { +#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 intf_MsgDestroy(); return( errno ); } + /* - * Redirect the standard output if required by the user, and on Win32 we - * also open a console to display the debug messages. + * System specific configuration */ - RedirectSTDOUT(); +#if defined( WIN32 ) + system_Configure(); +#endif + + /* p_main inititalization. FIXME ? */ + p_main->i_warning_level = config_GetIntVariable( "warning" ); + p_main->i_desync = config_GetIntVariable( "desync" ) * (mtime_t)1000; + 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" ) ) + p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_MMX; + if( config_GetIntVariable( "no3dn" ) ) + p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_3DNOW; + if( config_GetIntVariable( "nommxext" ) ) + p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_MMXEXT; + if( config_GetIntVariable( "nosse" ) ) + p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_SSE; + if( config_GetIntVariable( "noaltivec" ) ) + p_main->i_cpu_capabilities &= ~CPU_CAPABILITY_ALTIVEC; + + + 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" ); + PRINT_CAPABILITY( CPU_CAPABILITY_FPU, "FPU" ); + intf_StatMsg( "info: CPU has capabilities : %s", p_capabilities ); + } /* * Initialize playlist and get commandline files @@ -333,23 +745,41 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) GetFilenames( i_argc, ppsz_argv ); /* - * Initialize module, aout and vout banks + * Initialize input, aout and vout banks */ - module_InitBank(); + input_InitBank(); aout_InitBank(); vout_InitBank(); + /* + * Choose the best memcpy module + */ + psz_module = config_GetPszVariable( "memcpy" ); + p_main->p_memcpy_module = module_Need( MODULE_CAPABILITY_MEMCPY, + psz_module, NULL ); + if( psz_module ) free( psz_module ); + if( p_main->p_memcpy_module == NULL ) + { + intf_ErrMsg( "intf error: no suitable memcpy module, " + "using libc default" ); + p_main->pf_memcpy = memcpy; + } + else + { + p_main->pf_memcpy = p_main->p_memcpy_module->p_functions + ->memcpy.functions.memcpy.pf_memcpy; + } + /* * Initialize shared resources and libraries */ - if( main_GetIntVariable( INPUT_NETWORK_CHANNEL_VAR, - INPUT_NETWORK_CHANNEL_DEFAULT ) && + if( config_GetIntVariable( "network-channel" ) && network_ChannelCreate() ) { /* On error during Channels initialization, switch off channels */ - intf_Msg( "Channels initialization failed : " - "Channel management is deactivated" ); - main_PutIntVariable( INPUT_NETWORK_CHANNEL_VAR, 0 ); + intf_ErrMsg( "intf error: channels initialization failed, " + "deactivating channels" ); + config_PutIntVariable( "network-channel", 0 ); } /* @@ -380,29 +810,41 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) /* * Go back into channel 0 which is the network */ - if( main_GetIntVariable( INPUT_NETWORK_CHANNEL_VAR, - INPUT_NETWORK_CHANNEL_DEFAULT ) ) + if( config_GetIntVariable( "network-channel" ) && p_main->p_channel ) { network_ChannelJoin( COMMON_CHANNEL ); } } /* - * Free module, aout and vout banks + * Free input, aout and vout banks */ + input_EndBank(); vout_EndBank(); aout_EndBank(); - module_EndBank(); /* * Free playlist */ intf_PlaylistDestroy( p_main->p_playlist ); + /* + * Free memcpy module if it was allocated + */ + if( p_main->p_memcpy_module != NULL ) + { + module_Unneed( p_main->p_memcpy_module ); + } + + /* + * Free module bank + */ + module_EndBank(); + /* * System specific cleaning code */ -#if defined( SYS_BEOS ) || defined( SYS_DARWIN ) +#if defined( SYS_BEOS ) || defined( SYS_DARWIN ) || defined( WIN32 ) system_End(); #endif @@ -410,7 +852,7 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) /* * Terminate messages interface and program */ - intf_Msg( "intf: program terminated" ); + intf_WarnMsg( 1, "intf: program terminated" ); intf_MsgDestroy(); /* @@ -421,500 +863,215 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] ) return 0; } -/***************************************************************************** - * main_GetIntVariable: get the int value of an environment variable - ***************************************************************************** - * This function is used to read some default parameters in modules. - *****************************************************************************/ -int main_GetIntVariable( char *psz_name, int i_default ) -{ - char * psz_env; /* environment value */ - char * psz_end; /* end of parsing index */ - long int i_value; /* value */ - psz_env = getenv( psz_name ); - if( psz_env ) - { - i_value = strtol( psz_env, &psz_end, 0 ); - if( (*psz_env != '\0') && (*psz_end == '\0') ) - { - return( i_value ); - } - } - return( i_default ); -} +/* following functions are local */ /***************************************************************************** - * main_GetPszVariable: get the string value of an environment variable + * GetFilenames: parse command line options which are not flags ***************************************************************************** - * This function is used to read some default parameters in modules. + * Parse command line for input files. *****************************************************************************/ -char * main_GetPszVariable( char *psz_name, char *psz_default ) +static int GetFilenames( int i_argc, char *ppsz_argv[] ) { - char *psz_env; + int i_opt; - psz_env = getenv( psz_name ); - if( psz_env ) + /* We assume that the remaining parameters are filenames */ + for( i_opt = optind; i_opt < i_argc; i_opt++ ) { - return( psz_env ); + intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, + ppsz_argv[ i_opt ] ); } - return( psz_default ); -} -/***************************************************************************** - * main_PutPszVariable: set the string value of an environment variable - ***************************************************************************** - * 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. - *****************************************************************************/ -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 ) - { - intf_ErrMsg( "intf error: cannot create psz_env (%s)", - strerror(ENOMEM) ); - } - else - { - sprintf( psz_env, "%s=%s", psz_name, psz_value ); - if( putenv( psz_env ) ) - { - intf_ErrMsg( "intf error: cannot putenv (%s)", strerror(errno) ); - } - } + return( 0 ); } /***************************************************************************** - * main_PutIntVariable: set the integer value of an environment variable + * Usage: print program usage ***************************************************************************** - * 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. + * Print a short inline help. Message interface is initialized at this stage. *****************************************************************************/ -void main_PutIntVariable( char *psz_name, int i_value ) +static void Usage( const char *psz_module_name ) { - char psz_value[ 256 ]; /* buffer for value */ - - sprintf( psz_value, "%d", i_value ); - main_PutPszVariable( psz_name, psz_value ); -} +#define FORMAT_STRING " --%s%s%s%s%s %s" + /* option name ---------------' | | | | | + * ----------------------------' | | + * padding spaces --------------------' | + * comment ------------------------------' + * + * The purpose of having bra and ket is that we might i18n them as well. + */ +#define LINE_START 8 +#define PADDING_SPACES 25 + module_t *p_module; + module_config_t *p_item; + char psz_spaces[PADDING_SPACES+LINE_START+1]; + char psz_format[sizeof(FORMAT_STRING)]; -/* following functions are local */ + memset( psz_spaces, ' ', PADDING_SPACES+LINE_START ); + psz_spaces[PADDING_SPACES+LINE_START] = '\0'; -/***************************************************************************** - * GetConfiguration: parse command line - ***************************************************************************** - * Parse command line and configuration file for configuration. If the inline - * help is requested, the function Usage() is called and the function returns - * -1 (causing main() to exit). The messages interface is initialized at this - * stage, but most structures are not allocated, so only environment should - * be used. - *****************************************************************************/ -static int GetConfiguration( int *pi_argc, char *ppsz_argv[], char *ppsz_env[] ) -{ - int i_cmd; - char *p_tmp; + strcpy( psz_format, FORMAT_STRING ); - /* Set default configuration and copy arguments */ - p_main->i_argc = *pi_argc; - p_main->ppsz_argv = ppsz_argv; - p_main->ppsz_env = ppsz_env; +#ifdef WIN32 + ShowConsole(); +#endif - p_main->b_audio = 1; - p_main->b_video = 1; + /* Enumerate the config of each module */ + for( p_module = p_module_bank->first ; + p_module != NULL ; + p_module = p_module->next ) + { + if( psz_module_name && strcmp( psz_module_name, p_module->psz_name ) ) + continue; - p_main->i_warning_level = 0; + /* ignore modules without config options */ + if( !p_module->i_config_items ) continue; - p_main->p_channel = NULL; + /* print module name */ + intf_Msg( _("%s module options:\n"), p_module->psz_name ); - /* 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 + for( p_item = p_module->p_config; + p_item->i_type != MODULE_CONFIG_HINT_END; + p_item++ ) { - ++p_tmp; - } - } + char *psz_bra = NULL, *psz_type = NULL, *psz_ket = NULL; + int i; -#ifdef SYS_DARWIN - /* When vlc.app is run by double clicking in Mac OS X, the 2nd arg - * is the PSN - process serial number (a unique PID-ish thingie) - * still ok for real Darwin & when run from command line */ - if ( (*pi_argc > 1) && (strncmp( ppsz_argv[ 1 ] , "-psn" , 4 ) == 0) ) - /* for example -psn_0_9306113 */ - { - /* GDMF!... I can't do this or else the MacOSX window server will - * not pick up the PSN and not register the app and we crash... - * hence the following kludge otherwise we'll get confused w/ argv[1] - * being an input file name */ -#if 0 - ppsz_argv[ 1 ] = NULL; -#endif - *pi_argc = *pi_argc - 1; - pi_argc--; - return( 0 ); - } -#endif - - /* Parse command line options */ - opterr = 0; - while( ( i_cmd = getopt_long( *pi_argc, ppsz_argv, - psz_shortopts, longopts, 0 ) ) != EOF ) - { - switch( i_cmd ) - { - /* General/common options */ - case 'h': /* -h, --help */ - ShowConsole(); - RedirectSTDOUT(); - Usage( SHORT_HELP ); -#ifdef WIN32 /* Pause the console because it's destroyed when we exit */ - if( strcmp( "", main_GetPszVariable( INTF_STDOUT_VAR, - INTF_STDOUT_DEFAULT ) ) == 0 ) + if( p_item->i_short ) { - /* No stdout redirection has been asked for */ - intf_MsgImm( "\nPress the RETURN key to continue..." ); - getchar(); + psz_format[2] = '-'; + psz_format[3] = p_item->i_short; + psz_format[4] = ','; } -#endif - return( -1 ); - break; - case 'H': /* -H, --longhelp */ - ShowConsole(); - RedirectSTDOUT(); - Usage( LONG_HELP ); -#ifdef WIN32 /* Pause the console because it's destroyed when we exit */ - if( strcmp( "", main_GetPszVariable( INTF_STDOUT_VAR, - INTF_STDOUT_DEFAULT ) ) == 0 ) + else { - /* No stdout redirection has been asked for */ - intf_MsgImm( "\nPress the RETURN key to continue..." ); - getchar(); + psz_format[2] = ' '; + psz_format[3] = ' '; + psz_format[4] = ' '; } -#endif - return( -1 ); - break; - case OPT_VERSION: /* --version */ - ShowConsole(); - RedirectSTDOUT(); - Version(); -#ifdef WIN32 /* Pause the console because it's destroyed when we exit */ - if( strcmp( "", main_GetPszVariable( INTF_STDOUT_VAR, - INTF_STDOUT_DEFAULT ) ) == 0 ) + + switch( p_item->i_type ) { - /* No stdout redirection has been asked for */ - intf_MsgImm( "\nPress the RETURN key to continue..." ); - getchar(); + case MODULE_CONFIG_HINT_CATEGORY: + intf_Msg( " %s", p_item->psz_text ); + break; + + case MODULE_CONFIG_ITEM_STRING: + case MODULE_CONFIG_ITEM_FILE: + case MODULE_CONFIG_ITEM_MODULE: /* We could also have "=<" here */ + psz_bra = " <"; psz_type = _("string"); psz_ket = ">"; + break; + case MODULE_CONFIG_ITEM_INTEGER: + psz_bra = " <"; psz_type = _("integer"); psz_ket = ">"; + break; + case MODULE_CONFIG_ITEM_FLOAT: + psz_bra = " <"; psz_type = _("float"); psz_ket = ">"; + break; + case MODULE_CONFIG_ITEM_BOOL: + psz_bra = ""; psz_type = ""; psz_ket = ""; + break; } -#endif - return( -1 ); - break; - case 'v': /* -v, --verbose */ - p_main->i_warning_level++; - break; - - /* Interface warning messages level */ - case 'I': /* -I, --intf */ - main_PutPszVariable( INTF_METHOD_VAR, optarg ); - break; - case OPT_WARNING: /* --warning */ - intf_ErrMsg( "intf error: `--warning' is deprecated, use `-v'" ); - p_main->i_warning_level = atoi(optarg); - break; - - case OPT_STDOUT: /* --stdout */ - main_PutPszVariable( INTF_STDOUT_VAR, optarg ); - break; - - /* Audio options */ - case OPT_NOAUDIO: /* --noaudio */ - p_main->b_audio = 0; - break; - case 'A': /* -A, --aout */ - main_PutPszVariable( AOUT_METHOD_VAR, optarg ); - break; - case OPT_STEREO: /* --stereo */ - main_PutIntVariable( AOUT_STEREO_VAR, 1 ); - break; - case OPT_MONO: /* --mono */ - main_PutIntVariable( AOUT_STEREO_VAR, 0 ); - break; - case OPT_SPDIF: /* --spdif */ - main_PutIntVariable( AOUT_SPDIF_VAR, 1 ); - break; - case OPT_DOWNMIX: /* --downmix */ - main_PutPszVariable( DOWNMIX_METHOD_VAR, optarg ); - break; - case OPT_IMDCT: /* --imdct */ - main_PutPszVariable( IMDCT_METHOD_VAR, optarg ); - break; - - /* Video options */ - case OPT_NOVIDEO: /* --novideo */ - p_main->b_video = 0; - break; - case 'V': /* -V, --vout */ - main_PutPszVariable( VOUT_METHOD_VAR, optarg ); - break; - case OPT_DISPLAY: /* --display */ - main_PutPszVariable( VOUT_DISPLAY_VAR, optarg ); - break; - case OPT_WIDTH: /* --width */ - main_PutPszVariable( VOUT_WIDTH_VAR, optarg ); - break; - case OPT_HEIGHT: /* --height */ - main_PutPszVariable( VOUT_HEIGHT_VAR, optarg ); - break; - case 'g': /* -g, --grayscale */ - main_PutIntVariable( VOUT_GRAYSCALE_VAR, 1 ); - break; - case OPT_COLOR: /* --color */ - main_PutIntVariable( VOUT_GRAYSCALE_VAR, 0 ); - break; - case OPT_FULLSCREEN: /* --fullscreen */ - main_PutIntVariable( VOUT_FULLSCREEN_VAR, 1 ); - break; - case OPT_OVERLAY: /* --overlay */ - main_PutIntVariable( VOUT_OVERLAY_VAR, 1 ); - break; - case OPT_MOTION: /* --motion */ - main_PutPszVariable( MOTION_METHOD_VAR, optarg ); - break; - case OPT_IDCT: /* --idct */ - main_PutPszVariable( IDCT_METHOD_VAR, optarg ); - break; - case OPT_YUV: /* --yuv */ - main_PutPszVariable( YUV_METHOD_VAR, optarg ); - break; - case OPT_SMP: /* --smp */ - main_PutIntVariable( VDEC_SMP_VAR, atoi(optarg) ); - break; - - /* DVD options */ - case 't': - main_PutIntVariable( INPUT_TITLE_VAR, atoi(optarg) ); - break; - case 'T': - main_PutIntVariable( INPUT_CHAPTER_VAR, atoi(optarg) ); - break; - case 'u': - main_PutIntVariable( INPUT_ANGLE_VAR, atoi(optarg) ); - break; - case 'a': - if ( ! strcmp(optarg, "ac3") ) - main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_AC3 ); - else if ( ! strcmp(optarg, "lpcm") ) - main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_LPCM ); - else if ( ! strcmp(optarg, "mpeg") ) - main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_MPEG ); - else - main_PutIntVariable( INPUT_AUDIO_VAR, REQUESTED_NOAUDIO ); - break; - case 'c': - main_PutIntVariable( INPUT_CHANNEL_VAR, atoi(optarg) ); - break; - case 's': - main_PutIntVariable( INPUT_SUBTITLE_VAR, atoi(optarg) ); - break; - - /* Input options */ - case OPT_INPUT: /* --input */ - main_PutPszVariable( INPUT_METHOD_VAR, optarg ); - break; - case OPT_CHANNELS: /* --channels */ - main_PutIntVariable( INPUT_NETWORK_CHANNEL_VAR, 1 ); - break; - case OPT_SERVER: /* --server */ - main_PutPszVariable( INPUT_SERVER_VAR, optarg ); - break; - case OPT_PORT: /* --port */ - main_PutPszVariable( INPUT_PORT_VAR, optarg ); - break; - case OPT_BROADCAST: /* --broadcast */ - main_PutIntVariable( INPUT_BROADCAST_VAR, 1 ); - main_PutPszVariable( INPUT_BCAST_ADDR_VAR, optarg ); - break; - - /* Synchro options */ - case OPT_SYNCHRO: - main_PutPszVariable( VPAR_SYNCHRO_VAR, optarg ); - break; - - /* Internal error: unknown option */ - case '?': - default: - ShowConsole(); - RedirectSTDOUT(); - intf_ErrMsg( "intf error: unknown option `%s'", - ppsz_argv[optind - 1] ); - Usage( USAGE ); -#ifdef WIN32 /* Pause the console because it's destroyed when we exit */ - if( strcmp( "", main_GetPszVariable( INTF_STDOUT_VAR, - INTF_STDOUT_DEFAULT ) ) == 0 ) + + if( psz_type ) { - /* No stdout redirection has been asked for */ - intf_MsgImm( "\nPress the RETURN key to continue..." ); - getchar(); + i = PADDING_SPACES - strlen( p_item->psz_name ) + - strlen( psz_bra ) - strlen( psz_type ) + - strlen( psz_ket ) - 1; + if( i < 0 ) + { + i = 0; + psz_spaces[i] = '\n'; + } + else + { + psz_spaces[i] = '\0'; + } + + intf_Msg( psz_format, p_item->psz_name, psz_bra, psz_type, + psz_ket, psz_spaces, p_item->psz_text ); + psz_spaces[i] = ' '; } -#endif - return( EINVAL ); - break; } - } - if( p_main->i_warning_level < 0 ) - { - p_main->i_warning_level = 0; + /* 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 plain MPEG-1/2 files" + "\n [dvd:][device][@raw_device][@[title][,[chapter][,angle]]]" + "\n DVD device" + "\n [vcd:][device][@[title][,[chapter]]" + "\n VCD device" + "\n udpstream:[@[][:]]" + "\n UDP stream sent by VLS" + "\n vlc:loop loop execution of the " + "playlist" + "\n vlc:pause pause execution of " + "playlist items" + "\n vlc:quit quit VLC") ); + } + + intf_Msg( "" ); + } - return( 0 ); +#ifdef WIN32 /* Pause the console because it's destroyed when we exit */ + intf_Msg( _("\nPress the RETURN key to continue...") ); + getchar(); +#endif } /***************************************************************************** - * GetFilenames: parse command line options which are not flags + * ListModules: list the available modules with their description ***************************************************************************** - * Parse command line for input files. + * Print a list of all available modules (builtins and plugins) and a short + * description for each one. *****************************************************************************/ -static int GetFilenames( int i_argc, char *ppsz_argv[] ) +static void ListModules( void ) { - int i_opt; + module_t *p_module; + char psz_spaces[22]; - /* We assume that the remaining parameters are filenames */ - for( i_opt = optind; i_opt < i_argc; i_opt++ ) - { - intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, - ppsz_argv[ i_opt ] ); - } + memset( psz_spaces, ' ', 22 ); - return( 0 ); -} +#ifdef WIN32 + ShowConsole(); +#endif -/***************************************************************************** - * Usage: print program usage - ***************************************************************************** - * Print a short inline help. Message interface is initialized at this stage. - *****************************************************************************/ -static void Usage( int i_fashion ) -{ /* Usage */ - intf_MsgImm( "Usage: %s [options] [parameters] [file]...", - p_main->psz_arg0 ); + intf_Msg( _("Usage: %s [options] [parameters] [file]...\n"), + p_main->psz_arg0 ); + + intf_Msg( _("[module] [description]") ); - if( i_fashion == USAGE ) + /* Enumerate each module */ + for( p_module = p_module_bank->first ; + p_module != NULL ; + p_module = p_module->next ) { - intf_MsgImm( "Try `%s --help' for more information.", - p_main->psz_arg0 ); - return; - } + int i; + + /* Nasty hack, but right now I'm too tired to think about a nice + * solution */ + i = 22 - 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 ); - /* Options */ - intf_MsgImm( "\nOptions:" - "\n -I, --intf \tinterface method" - "\n -v, --verbose \tverbose mode (cumulative)" - "\n --stdout \tredirect console stdout" - "\n" - "\n --noaudio \tdisable audio" - "\n -A, --aout \taudio output method" - "\n --stereo, --mono \tstereo/mono audio" - "\n --spdif \tAC3 pass-through mode" - "\n --downmix \tAC3 downmix method" - "\n --imdct \tAC3 IMDCT method" - "\n" - "\n --novideo \tdisable video" - "\n -V, --vout \tvideo output method" - "\n --display \tdisplay string" - "\n --width , --height \tdisplay dimensions" - "\n -g, --grayscale \tgrayscale output" - "\n --fullscreen \tfullscreen output" - "\n --overlay \taccelerated display" - "\n --color \tcolor output" - "\n --motion \tmotion compensation method" - "\n --idct \tIDCT method" - "\n --yuv \tYUV method" - "\n --synchro \tforce synchro algorithm" - "\n --smp \tuse several processors" - "\n" - "\n -t, --dvdtitle \tchoose DVD title" - "\n -T, --dvdchapter \tchoose DVD chapter" - "\n -u, --dvdangle \tchoose DVD angle" - "\n -a, --dvdaudio \tchoose DVD audio type" - "\n -c, --dvdchannel \tchoose DVD audio channel" - "\n -s, --dvdsubtitle \tchoose DVD subtitle channel" - "\n" - "\n --input \tinput method" - "\n --channels \tenable channels" - "\n --server \tvideo server address" - "\n --port \tvideo server port" - "\n --broadcast \tlisten to a broadcast" - "\n" - "\n -h, --help \tprint help and exit" - "\n -H, --longhelp \tprint long help and exit" - "\n --version \toutput version information and exit" ); - - if( i_fashion == SHORT_HELP ) - return; - - /* Interface parameters */ - intf_MsgImm( "\nInterface parameters:" - "\n " INTF_METHOD_VAR "= \tinterface method" - "\n " INTF_INIT_SCRIPT_VAR "= \tinitialization script" - "\n " INTF_CHANNELS_VAR "= \tchannels list" - "\n " INTF_STDOUT_VAR "= \tredirect console stdout" ); - - /* Audio parameters */ - intf_MsgImm( "\nAudio parameters:" - "\n " AOUT_METHOD_VAR "= \taudio method" - "\n " AOUT_DSP_VAR "= \tdsp device path" - "\n " AOUT_STEREO_VAR "={1|0} \tstereo or mono output" - "\n " AOUT_SPDIF_VAR "={1|0} \tAC3 pass-through mode" - "\n " DOWNMIX_METHOD_VAR "= \tAC3 downmix method" - "\n " IMDCT_METHOD_VAR "= \tAC3 IMDCT method" - "\n " AOUT_RATE_VAR "= \toutput rate" ); - - /* Video parameters */ - intf_MsgImm( "\nVideo parameters:" - "\n " VOUT_METHOD_VAR "= \tdisplay method" - "\n " VOUT_DISPLAY_VAR "= \tdisplay used" - "\n " VOUT_WIDTH_VAR "= \tdisplay width" - "\n " VOUT_HEIGHT_VAR "= \tdislay height" - "\n " VOUT_FB_DEV_VAR "= \tframebuffer device path" - "\n " VOUT_GRAYSCALE_VAR "={1|0} \tgrayscale or color output" - "\n " VOUT_FULLSCREEN_VAR "={1|0} \tfullscreen" - "\n " VOUT_OVERLAY_VAR "={1|0} \toverlay" - "\n " MOTION_METHOD_VAR "= \tmotion compensation method" - "\n " IDCT_METHOD_VAR "= \tIDCT method" - "\n " YUV_METHOD_VAR "= \tYUV method" - "\n " VPAR_SYNCHRO_VAR "={I|I+|IP|IP+|IPB} \tsynchro algorithm" - "\n " VDEC_SMP_VAR "= \tuse several processors" ); - - /* DVD parameters */ - intf_MsgImm( "\nDVD parameters:" - "\n " INPUT_DVD_DEVICE_VAR "= \tDVD device" - "\n " INPUT_TITLE_VAR "= \ttitle number" - "\n " INPUT_CHAPTER_VAR "=<chapter> \tchapter number" - "\n " INPUT_ANGLE_VAR "=<angle> \tangle number" - "\n " INPUT_AUDIO_VAR "={ac3|lpcm|mpeg|off} \taudio type" - "\n " INPUT_CHANNEL_VAR "=[0-15] \taudio channel" - "\n " INPUT_SUBTITLE_VAR "=[0-31] \tsubtitle channel" ); - - /* Input parameters */ - intf_MsgImm( "\nInput 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_BCAST_ADDR_VAR "=<addr> \tbroadcast mode" - "\n " INPUT_CHANNEL_SERVER_VAR "=<hostname> \tchannel server" - "\n " INPUT_CHANNEL_PORT_VAR "=<port> \tchannel server port" ); + psz_spaces[i] = ' '; + + } +#ifdef WIN32 /* Pause the console because it's destroyed when we exit */ + intf_Msg( _("\nPress the RETURN key to continue...") ); + getchar(); +#endif } /***************************************************************************** @@ -924,11 +1081,21 @@ static void Usage( int i_fashion ) *****************************************************************************/ static void Version( void ) { - intf_MsgImm( VERSION_MESSAGE - "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." ); +#ifdef WIN32 + ShowConsole(); +#endif + + intf_Msg( VERSION_MESSAGE ); + intf_Msg( + _("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" + "Written by the VideoLAN team at Ecole Centrale, Paris.") ); + +#ifdef WIN32 /* Pause the console because it's destroyed when we exit */ + intf_Msg( _("\nPress the RETURN key to continue...") ); + getchar(); +#endif } /***************************************************************************** @@ -952,7 +1119,6 @@ static void InitSignalHandler( void ) #endif } - /***************************************************************************** * SimpleSignalHandler: system signal handler ***************************************************************************** @@ -964,7 +1130,6 @@ static void SimpleSignalHandler( int i_signal ) intf_WarnMsg( 0, "intf: ignoring signal %d", i_signal ); } - /***************************************************************************** * FatalSignalHandler: system signal handler ***************************************************************************** @@ -983,7 +1148,7 @@ static void FatalSignalHandler( int i_signal ) #endif /* Acknowledge the signal received */ - intf_ErrMsgImm( "intf error: signal %d received, exiting", i_signal ); + intf_ErrMsg( "intf error: signal %d received, exiting", i_signal ); /* Try to terminate everything - this is done by requesting the end of the * interface thread */ @@ -991,26 +1156,30 @@ static void FatalSignalHandler( int i_signal ) } /***************************************************************************** - * InstructionSignalHandler: system signal handler + * IllegalSignalHandler: system signal handler ***************************************************************************** - * This function is called when a illegal instruction signal is received by - * the program. - * We use this function to test OS and CPU_Capabilities + * This function is called when an illegal instruction signal is received by + * the program. We use this function to test OS and CPU capabilities *****************************************************************************/ -static void InstructionSignalHandler( int i_signal ) +static void IllegalSignalHandler( int i_signal ) { - /* 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 */ - /* Acknowledge the signal received */ - fprintf( stderr, "illegal instruction : optimization disabled\n" ); - i_illegal = 1; - + #ifdef HAVE_SIGRELSE sigrelse( i_signal ); #endif + +#if defined( __i386__ ) + fprintf( stderr, "warning: your CPU has %s instructions, but not your " + "operating system.\n", psz_capability ); + fprintf( stderr, " some optimizations will be disabled unless " + "you upgrade your OS\n" ); +# if defined( SYS_LINUX ) + fprintf( stderr, " (for instance Linux kernel 2.4.x or later)\n" ); +# endif +#endif + longjmp( env, 1 ); } @@ -1019,18 +1188,11 @@ static void InstructionSignalHandler( int i_signal ) ***************************************************************************** * This function is called to list extensions the CPU may have. *****************************************************************************/ -static int CPUCapabilities( void ) +static u32 CPUCapabilities( void ) { - volatile int i_capabilities = CPU_CAPABILITY_NONE; - -#if defined( SYS_BEOS ) - i_capabilities |= CPU_CAPABILITY_486 - | CPU_CAPABILITY_586 - | CPU_CAPABILITY_MMX; + volatile u32 i_capabilities = CPU_CAPABILITY_NONE; - return( i_capabilities ); - -#elif defined( SYS_DARWIN ) +#if defined( SYS_DARWIN ) struct host_basic_info hi; kern_return_t ret; host_name_port_t host; @@ -1038,6 +1200,8 @@ static int CPUCapabilities( void ) int i_size; char *psz_name, *psz_subname; + i_capabilities |= CPU_CAPABILITY_FPU; + /* Should 'never' fail? */ host = mach_host_self(); @@ -1046,14 +1210,14 @@ static int CPUCapabilities( void ) if( ret != KERN_SUCCESS ) { - intf_ErrMsg( "error: couldn't get CPU information" ); + fprintf( stderr, "error: couldn't get CPU information\n" ); return( i_capabilities ); } slot_name( hi.cpu_type, hi.cpu_subtype, &psz_name, &psz_subname ); /* FIXME: need better way to detect newer proccessors. * could do strncmp(a,b,5), but that's real ugly */ - if( strcmp(psz_name, "ppc7400") || strcmp(psz_name, "ppc7450") ) + if( !strcmp(psz_name, "ppc7400") || !strcmp(psz_name, "ppc7450") ) { i_capabilities |= CPU_CAPABILITY_ALTIVEC; } @@ -1064,25 +1228,47 @@ static int CPUCapabilities( void ) volatile unsigned int i_eax, i_ebx, i_ecx, i_edx; volatile boolean_t b_amd; - signal( SIGILL, InstructionSignalHandler ); - + /* Needed for x86 CPU capabilities detection */ +# define cpuid( a ) \ + asm volatile ( "pushl %%ebx\n\t" \ + "cpuid\n\t" \ + "movl %%ebx,%1\n\t" \ + "popl %%ebx\n\t" \ + : "=a" ( i_eax ), \ + "=r" ( i_ebx ), \ + "=c" ( i_ecx ), \ + "=d" ( i_edx ) \ + : "a" ( a ) \ + : "cc" ); + + i_capabilities |= CPU_CAPABILITY_FPU; + +# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) + signal( SIGILL, IllegalSignalHandler ); +# endif + /* test for a 486 CPU */ - asm volatile ( "pushfl\n\t" + asm volatile ( "pushl %%ebx\n\t" + "pushfl\n\t" "popl %%eax\n\t" "movl %%eax, %%ebx\n\t" "xorl $0x200000, %%eax\n\t" "pushl %%eax\n\t" "popfl\n\t" "pushfl\n\t" - "popl %%eax" + "popl %%eax\n\t" + "movl %%ebx,%1\n\t" + "popl %%ebx\n\t" : "=a" ( i_eax ), - "=b" ( i_ebx ) + "=r" ( i_ebx ) : : "cc" ); if( i_eax == i_ebx ) { - signal( SIGILL, NULL ); +# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) + signal( SIGILL, NULL ); +# endif return( i_capabilities ); } @@ -1093,7 +1279,9 @@ static int CPUCapabilities( void ) if( !i_eax ) { - signal( SIGILL, NULL ); +# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) + signal( SIGILL, NULL ); +# endif return( i_capabilities ); } @@ -1109,7 +1297,9 @@ static int CPUCapabilities( void ) if( ! (i_edx & 0x00800000) ) { - signal( SIGILL, NULL ); +# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) + signal( SIGILL, NULL ); +# endif return( i_capabilities ); } @@ -1119,7 +1309,9 @@ static int CPUCapabilities( void ) { i_capabilities |= CPU_CAPABILITY_MMXEXT; - /* We test if OS support the SSE instructions */ +# ifdef CAN_COMPILE_SSE + /* We test if OS supports the SSE instructions */ + psz_capability = "SSE"; i_illegal = 0; if( setjmp( env ) == 0 ) { @@ -1131,22 +1323,27 @@ static int CPUCapabilities( void ) { i_capabilities |= CPU_CAPABILITY_SSE; } +# endif } - + /* test for additional capabilities */ cpuid( 0x80000000 ); if( i_eax < 0x80000001 ) { - signal( SIGILL, NULL ); +# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) + signal( SIGILL, NULL ); +# endif return( i_capabilities ); } /* list these additional capabilities */ cpuid( 0x80000001 ); +# ifdef CAN_COMPILE_3DNOW if( i_edx & 0x80000000 ) { + psz_capability = "3D Now!"; i_illegal = 0; if( setjmp( env ) == 0 ) { @@ -1154,78 +1351,74 @@ static int CPUCapabilities( void ) __asm__ __volatile__ ( "pfadd %%mm0,%%mm0\n" "femms\n" : : ); } - if( i_illegal == 0 ) + if( i_illegal == 0 ) { i_capabilities |= CPU_CAPABILITY_3DNOW; } } +# endif if( b_amd && ( i_edx & 0x00400000 ) ) { i_capabilities |= CPU_CAPABILITY_MMXEXT; } - signal( SIGILL, NULL ); +# if defined( CAN_COMPILE_SSE ) || defined ( CAN_COMPILE_3DNOW ) + signal( SIGILL, NULL ); +# endif return( i_capabilities ); -#else - /* default behaviour */ - return( i_capabilities ); +#elif defined( __powerpc__ ) -#endif -} + i_capabilities |= CPU_CAPABILITY_FPU; -/***************************************************************************** - * RedirectSTDOUT: redirect stdout and stderr to a file - ***************************************************************************** - * This function will redirect stdout and stderr to a file if the user has - * specified so. - *****************************************************************************/ -static int RedirectSTDOUT( void ) -{ - int i_stdout_filedesc; - char *psz_stdout_filename; +# ifdef CAN_COMPILE_ALTIVEC + signal( SIGILL, IllegalSignalHandler ); - psz_stdout_filename = main_GetPszVariable( INTF_STDOUT_VAR, - INTF_STDOUT_DEFAULT ); - if( strcmp( "", psz_stdout_filename ) != 0 ) + psz_capability = "AltiVec"; + i_illegal = 0; + if( setjmp( env ) == 0 ) { - ShowConsole(); - i_stdout_filedesc = open( psz_stdout_filename, - O_CREAT | O_TRUNC | O_RDWR, - S_IREAD | S_IWRITE ); - if( dup2( i_stdout_filedesc, fileno(stdout) ) == -1 ) - intf_ErrMsg("Unable to redirect stdout!\n"); - if( dup2( i_stdout_filedesc, fileno(stderr) ) == -1 ) - intf_ErrMsg("Unable to redirect stderr!\n"); - close( i_stdout_filedesc ); + asm volatile ("mtspr 256, %0\n\t" + "vand %%v0, %%v0, %%v0" + : + : "r" (-1)); } - else - { - /* No stdout redirection has been asked so open a console */ - if( p_main->i_warning_level ) - { - ShowConsole(); - } + if( i_illegal == 0 ) + { + i_capabilities |= CPU_CAPABILITY_ALTIVEC; } - return 0; + signal( SIGILL, NULL ); +# endif + + return( i_capabilities ); + +#elif defined( __sparc__ ) + + i_capabilities |= CPU_CAPABILITY_FPU; + return( i_capabilities ); + +#else + /* default behaviour */ + return( i_capabilities ); + +#endif } /***************************************************************************** * ShowConsole: On Win32, create an output console for debug messages ***************************************************************************** - * This function is usefull only on Win32. + * This function is useful only on Win32. *****************************************************************************/ +#ifdef WIN32 /* */ static void ShowConsole( void ) { -#ifdef WIN32 /* */ AllocConsole(); freopen( "CONOUT$", "w", stdout ); freopen( "CONOUT$", "w", stderr ); freopen( "CONIN$", "r", stdin ); -#endif return; } - +#endif