Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

libvlc.c

00001 /*****************************************************************************
00002  * libvlc.c: main libvlc source
00003  *****************************************************************************
00004  * Copyright (C) 1998-2004 the VideoLAN team
00005  * $Id: libvlc.c 13433 2005-11-27 20:52:40Z zorglub $
00006  *
00007  * Authors: Vincent Seguin <[email protected]>
00008  *          Samuel Hocevar <[email protected]>
00009  *          Gildas Bazin <[email protected]>
00010  *          Derk-Jan Hartman <hartman at videolan dot org>
00011  *
00012  * This program is free software; you can redistribute it and/or modify
00013  * it under the terms of the GNU General Public License as published by
00014  * the Free Software Foundation; either version 2 of the License, or
00015  * (at your option) any later version.
00016  *
00017  * This program is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  * GNU General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU General Public License
00023  * along with this program; if not, write to the Free Software
00024  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00025  *****************************************************************************/
00026 
00027 /*****************************************************************************
00028  * Pretend we are a builtin module
00029  *****************************************************************************/
00030 #define MODULE_NAME main
00031 #define MODULE_PATH main
00032 #define __BUILTIN__
00033 
00034 /*****************************************************************************
00035  * Preamble
00036  *****************************************************************************/
00037 #include <vlc/vlc.h>
00038 #include <vlc/input.h>
00039 
00040 #include <errno.h>                                                 /* ENOMEM */
00041 #include <stdio.h>                                              /* sprintf() */
00042 #include <string.h>                                            /* strerror() */
00043 #include <stdlib.h>                                                /* free() */
00044 
00045 #ifndef WIN32
00046 #   include <netinet/in.h>                            /* BSD: struct in_addr */
00047 #endif
00048 
00049 #ifdef HAVE_UNISTD_H
00050 #   include <unistd.h>
00051 #elif defined( WIN32 ) && !defined( UNDER_CE )
00052 #   include <io.h>
00053 #endif
00054 
00055 #ifdef WIN32                       /* optind, getopt(), included in unistd.h */
00056 #   include "extras/getopt.h"
00057 #endif
00058 
00059 #ifdef HAVE_LOCALE_H
00060 #   include <locale.h>
00061 #endif
00062 
00063 #ifdef HAVE_HAL
00064 #   include <hal/libhal.h>
00065 #endif
00066 
00067 #include "vlc_cpu.h"                                        /* CPU detection */
00068 #include "os_specific.h"
00069 
00070 #include "vlc_error.h"
00071 
00072 #include "vlc_playlist.h"
00073 #include "vlc_interface.h"
00074 
00075 #include "audio_output.h"
00076 
00077 #include "vlc_video.h"
00078 #include "video_output.h"
00079 
00080 #include "stream_output.h"
00081 #include "charset.h"
00082 
00083 #include "libvlc.h"
00084 
00085 /*****************************************************************************
00086  * The evil global variable. We handle it with care, don't worry.
00087  *****************************************************************************/
00088 static libvlc_t   libvlc;
00089 static libvlc_t * p_libvlc;
00090 static vlc_t *    p_static_vlc;
00091 
00092 /*****************************************************************************
00093  * Local prototypes
00094  *****************************************************************************/
00095 static void LocaleInit( void );
00096 static void LocaleDeinit( void );
00097 static void SetLanguage   ( char const * );
00098 static int  GetFilenames  ( vlc_t *, int, char *[] );
00099 static void Help          ( vlc_t *, char const *psz_help_name );
00100 static void Usage         ( vlc_t *, char const *psz_module_name );
00101 static void ListModules   ( vlc_t * );
00102 static void Version       ( void );
00103 
00104 #ifdef WIN32
00105 static void ShowConsole   ( void );
00106 static void PauseConsole  ( void );
00107 #endif
00108 static int  ConsoleWidth  ( void );
00109 
00110 static int  VerboseCallback( vlc_object_t *, char const *,
00111                              vlc_value_t, vlc_value_t, void * );
00112 
00113 static void InitDeviceValues( vlc_t * );
00114 
00115 /*****************************************************************************
00116  * vlc_current_object: return the current object.
00117  *****************************************************************************
00118  * If i_object is non-zero, return the corresponding object. Otherwise,
00119  * return the statically allocated p_vlc object.
00120  *****************************************************************************/
00121 vlc_t * vlc_current_object( int i_object )
00122 {
00123     if( i_object )
00124     {
00125          return vlc_object_get( p_libvlc, i_object );
00126     }
00127 
00128     return p_static_vlc;
00129 }
00130 
00131 /*****************************************************************************
00132  * VLC_Version: return the libvlc version.
00133  *****************************************************************************
00134  * This function returns full version string (numeric version and codename).
00135  *****************************************************************************/
00136 char const * VLC_Version( void )
00137 {
00138     return VERSION_MESSAGE;
00139 }
00140 
00141 /*****************************************************************************
00142  * VLC_CompileBy, VLC_CompileHost, VLC_CompileDomain,
00143  * VLC_Compiler, VLC_Changeset
00144  *****************************************************************************/
00145 #define DECLARE_VLC_VERSION( func, var )                                    \
00146 char const * VLC_##func ( void )                                            \
00147 {                                                                           \
00148     return VLC_##var ;                                                      \
00149 }
00150 
00151 DECLARE_VLC_VERSION( CompileBy, COMPILE_BY );
00152 DECLARE_VLC_VERSION( CompileHost, COMPILE_HOST );
00153 DECLARE_VLC_VERSION( CompileDomain, COMPILE_DOMAIN );
00154 DECLARE_VLC_VERSION( Compiler, COMPILER );
00155 
00156 extern const char psz_vlc_changeset[];
00157 char const * VLC_Changeset( void )
00158 {
00159     return psz_vlc_changeset;
00160 }
00161 
00162 /*****************************************************************************
00163  * VLC_Error: strerror() equivalent
00164  *****************************************************************************
00165  * This function returns full version string (numeric version and codename).
00166  *****************************************************************************/
00167 char const * VLC_Error( int i_err )
00168 {
00169     return vlc_error( i_err );
00170 }
00171 
00172 /*****************************************************************************
00173  * VLC_Create: allocate a vlc_t structure, and initialize libvlc if needed.
00174  *****************************************************************************
00175  * This function allocates a vlc_t structure and returns a negative value
00176  * in case of failure. Also, the thread system is initialized.
00177  *****************************************************************************/
00178 int VLC_Create( void )
00179 {
00180     int i_ret;
00181     vlc_t * p_vlc = NULL;
00182     vlc_value_t lockval;
00183 
00184     /* &libvlc never changes, so we can safely call this multiple times. */
00185     p_libvlc = &libvlc;
00186 
00187     /* vlc_threads_init *must* be the first internal call! No other call is
00188      * allowed before the thread system has been initialized. */
00189     i_ret = vlc_threads_init( p_libvlc );
00190     if( i_ret < 0 )
00191     {
00192         return i_ret;
00193     }
00194 
00195     /* Now that the thread system is initialized, we don't have much, but
00196      * at least we have var_Create */
00197     var_Create( p_libvlc, "libvlc", VLC_VAR_MUTEX );
00198     var_Get( p_libvlc, "libvlc", &lockval );
00199     vlc_mutex_lock( lockval.p_address );
00200     if( !libvlc.b_ready )
00201     {
00202         char *psz_env;
00203 
00204         /* Guess what CPU we have */
00205         libvlc.i_cpu = CPUCapabilities();
00206 
00207         /* Find verbosity from VLC_VERBOSE environment variable */
00208         psz_env = getenv( "VLC_VERBOSE" );
00209         libvlc.i_verbose = psz_env ? atoi( psz_env ) : -1;
00210 
00211 #if defined( HAVE_ISATTY ) && !defined( WIN32 )
00212         libvlc.b_color = isatty( 2 ); /* 2 is for stderr */
00213 #else
00214         libvlc.b_color = VLC_FALSE;
00215 #endif
00216 
00217         /* Initialize message queue */
00218         msg_Create( p_libvlc );
00219 
00220         /* Announce who we are */
00221         msg_Dbg( p_libvlc, COPYRIGHT_MESSAGE );
00222         msg_Dbg( p_libvlc, "libvlc was configured with %s", CONFIGURE_LINE );
00223 
00224         /* The module bank will be initialized later */
00225         libvlc.p_module_bank = NULL;
00226 
00227         libvlc.b_ready = VLC_TRUE;
00228 
00229         /* UTF-8 convertor are initialized after the locale */
00230         libvlc.from_locale = libvlc.to_locale = (vlc_iconv_t)(-1);
00231     }
00232     vlc_mutex_unlock( lockval.p_address );
00233     var_Destroy( p_libvlc, "libvlc" );
00234 
00235     /* Allocate a vlc object */
00236     p_vlc = vlc_object_create( p_libvlc, VLC_OBJECT_VLC );
00237     if( p_vlc == NULL )
00238     {
00239         return VLC_EGENERIC;
00240     }
00241     p_vlc->thread_id = 0;
00242 
00243     p_vlc->psz_object_name = "root";
00244 
00245     /* Initialize mutexes */
00246     vlc_mutex_init( p_vlc, &p_vlc->config_lock );
00247 #ifdef SYS_DARWIN
00248     vlc_mutex_init( p_vlc, &p_vlc->quicktime_lock );
00249     vlc_thread_set_priority( p_vlc, VLC_THREAD_PRIORITY_LOW );
00250 #endif
00251 
00252     /* Store our newly allocated structure in the global list */
00253     vlc_object_attach( p_vlc, p_libvlc );
00254 
00255     /* Store data for the non-reentrant API */
00256     p_static_vlc = p_vlc;
00257 
00258     return p_vlc->i_object_id;
00259 }
00260 
00261 /*****************************************************************************
00262  * VLC_Init: initialize a vlc_t structure.
00263  *****************************************************************************
00264  * This function initializes a previously allocated vlc_t structure:
00265  *  - CPU detection
00266  *  - gettext initialization
00267  *  - message queue, module bank and playlist initialization
00268  *  - configuration and commandline parsing
00269  *****************************************************************************/
00270 int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
00271 {
00272     char         p_capabilities[200];
00273     char *       p_tmp;
00274     char *       psz_modules;
00275     char *       psz_parser;
00276     char *       psz_control;
00277     vlc_bool_t   b_exit = VLC_FALSE;
00278     vlc_t *      p_vlc = vlc_current_object( i_object );
00279     module_t    *p_help_module;
00280     playlist_t  *p_playlist;
00281     vlc_value_t  val;
00282 #if defined( ENABLE_NLS ) \
00283      && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
00284     char *       psz_language;
00285 #endif
00286 
00287     if( !p_vlc )
00288     {
00289         return VLC_ENOOBJ;
00290     }
00291 
00292     /*
00293      * System specific initialization code
00294      */
00295     system_Init( p_vlc, &i_argc, ppsz_argv );
00296 
00297     /* Get the executable name (similar to the basename command) */
00298     if( i_argc > 0 )
00299     {
00300         p_vlc->psz_object_name = p_tmp = ppsz_argv[ 0 ];
00301         while( *p_tmp )
00302         {
00303             if( *p_tmp == '/' ) p_vlc->psz_object_name = ++p_tmp;
00304             else ++p_tmp;
00305         }
00306     }
00307     else
00308     {
00309         p_vlc->psz_object_name = "vlc";
00310     }
00311 
00312     /*
00313      * Support for gettext
00314      */
00315     SetLanguage( "" );
00316 
00317     /*
00318      * Global iconv, must be done after setlocale()
00319      * so that vlc_current_charset() works.
00320      */
00321     LocaleInit();
00322 
00323     /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
00324     msg_Dbg( p_vlc, "translation test: code is \"%s\"", _("C") );
00325 
00326     /* Initialize the module bank and load the configuration of the
00327      * main module. We need to do this at this stage to be able to display
00328      * a short help if required by the user. (short help == main module
00329      * options) */
00330     module_InitBank( p_vlc );
00331 
00332     /* Hack: insert the help module here */
00333     p_help_module = vlc_object_create( p_vlc, VLC_OBJECT_MODULE );
00334     if( p_help_module == NULL )
00335     {
00336         module_EndBank( p_vlc );
00337         if( i_object ) vlc_object_release( p_vlc );
00338         return VLC_EGENERIC;
00339     }
00340     p_help_module->psz_object_name = "help";
00341     p_help_module->psz_longname = N_("Help options");
00342     config_Duplicate( p_help_module, p_help_config );
00343     vlc_object_attach( p_help_module, libvlc.p_module_bank );
00344     /* End hack */
00345 
00346     if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
00347     {
00348         vlc_object_detach( p_help_module );
00349         config_Free( p_help_module );
00350         vlc_object_destroy( p_help_module );
00351         module_EndBank( p_vlc );
00352         if( i_object ) vlc_object_release( p_vlc );
00353         return VLC_EGENERIC;
00354     }
00355 
00356     /* Check for short help option */
00357     if( config_GetInt( p_vlc, "help" ) )
00358     {
00359         Help( p_vlc, "help" );
00360         b_exit = VLC_TRUE;
00361     }
00362     /* Check for version option */
00363     else if( config_GetInt( p_vlc, "version" ) )
00364     {
00365         Version();
00366         b_exit = VLC_TRUE;
00367     }
00368 
00369     /* Set the config file stuff */
00370     p_vlc->psz_homedir = config_GetHomeDir();
00371     p_vlc->psz_userdir = config_GetUserDir();
00372     if( p_vlc->psz_userdir == NULL )
00373         p_vlc->psz_userdir = strdup(p_vlc->psz_homedir);
00374     p_vlc->psz_configfile = config_GetPsz( p_vlc, "config" );
00375     if( p_vlc->psz_configfile != NULL && p_vlc->psz_configfile[0] == '~'
00376          && p_vlc->psz_configfile[1] == '/' )
00377     {
00378         char *psz = malloc( strlen(p_vlc->psz_userdir)
00379                              + strlen(p_vlc->psz_configfile) );
00380         /* This is incomplete : we should also support the ~cmassiot/ syntax. */
00381         sprintf( psz, "%s/%s", p_vlc->psz_userdir,
00382                                p_vlc->psz_configfile + 2 );
00383         free( p_vlc->psz_configfile );
00384         p_vlc->psz_configfile = psz;
00385     }
00386 
00387     /* Check for plugins cache options */
00388     if( config_GetInt( p_vlc, "reset-plugins-cache" ) )
00389     {
00390         libvlc.p_module_bank->b_cache_delete = VLC_TRUE;
00391     }
00392 
00393     /* Hack: remove the help module here */
00394     vlc_object_detach( p_help_module );
00395     /* End hack */
00396 
00397     /* Will be re-done properly later on */
00398     p_vlc->p_libvlc->i_verbose = config_GetInt( p_vlc, "verbose" );
00399 
00400     /* Check for daemon mode */
00401 #ifndef WIN32
00402     if( config_GetInt( p_vlc, "daemon" ) )
00403     {
00404 #if HAVE_DAEMON
00405         if( daemon( 1, 0) != 0 )
00406         {
00407             msg_Err( p_vlc, "Unable to fork vlc to daemon mode" );
00408             b_exit = VLC_TRUE;
00409         }
00410 
00411         p_vlc->p_libvlc->b_daemon = VLC_TRUE;
00412 
00413 #else
00414         pid_t i_pid;
00415 
00416         if( ( i_pid = fork() ) < 0 )
00417         {
00418             msg_Err( p_vlc, "Unable to fork vlc to daemon mode" );
00419             b_exit = VLC_TRUE;
00420         }
00421         else if( i_pid )
00422         {
00423             /* This is the parent, exit right now */
00424             msg_Dbg( p_vlc, "closing parent process" );
00425             b_exit = VLC_TRUE;
00426         }
00427         else
00428         {
00429             /* We are the child */
00430             msg_Dbg( p_vlc, "daemon spawned" );
00431             close( STDIN_FILENO );
00432             close( STDOUT_FILENO );
00433             close( STDERR_FILENO );
00434 
00435             p_vlc->p_libvlc->b_daemon = VLC_TRUE;
00436         }
00437 #endif
00438     }
00439 #endif
00440 
00441     if( b_exit )
00442     {
00443         config_Free( p_help_module );
00444         vlc_object_destroy( p_help_module );
00445         module_EndBank( p_vlc );
00446         if( i_object ) vlc_object_release( p_vlc );
00447         return VLC_EEXIT;
00448     }
00449 
00450     /* Check for translation config option */
00451 #if defined( ENABLE_NLS ) \
00452      && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
00453 
00454     /* This ain't really nice to have to reload the config here but it seems
00455      * the only way to do it. */
00456     config_LoadConfigFile( p_vlc, "main" );
00457     config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
00458 
00459     /* Check if the user specified a custom language */
00460     psz_language = config_GetPsz( p_vlc, "language" );
00461     if( psz_language && *psz_language && strcmp( psz_language, "auto" ) )
00462     {
00463         vlc_bool_t b_cache_delete = libvlc.p_module_bank->b_cache_delete;
00464 
00465         /* Reset the default domain */
00466         SetLanguage( psz_language );
00467         LocaleDeinit();
00468         LocaleInit();
00469 
00470         /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
00471         msg_Dbg( p_vlc, "translation test: code is \"%s\"", _("C") );
00472 
00473         module_EndBank( p_vlc );
00474         module_InitBank( p_vlc );
00475         config_LoadConfigFile( p_vlc, "main" );
00476         config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
00477         libvlc.p_module_bank->b_cache_delete = b_cache_delete;
00478     }
00479     if( psz_language ) free( psz_language );
00480 #endif
00481 
00482     /*
00483      * Load the builtins and plugins into the module_bank.
00484      * We have to do it before config_Load*() because this also gets the
00485      * list of configuration options exported by each module and loads their
00486      * default values.
00487      */
00488     module_LoadBuiltins( p_vlc );
00489     module_LoadPlugins( p_vlc );
00490     if( p_vlc->b_die )
00491     {
00492         b_exit = VLC_TRUE;
00493     }
00494 
00495     msg_Dbg( p_vlc, "module bank initialized, found %i modules",
00496                     libvlc.p_module_bank->i_children );
00497 
00498     /* Hack: insert the help module here */
00499     vlc_object_attach( p_help_module, libvlc.p_module_bank );
00500     /* End hack */
00501 
00502     /* Check for help on modules */
00503     if( (p_tmp = config_GetPsz( p_vlc, "module" )) )
00504     {
00505         Help( p_vlc, p_tmp );
00506         free( p_tmp );
00507         b_exit = VLC_TRUE;
00508     }
00509     /* Check for long help option */
00510     else if( config_GetInt( p_vlc, "longhelp" ) )
00511     {
00512         Help( p_vlc, "longhelp" );
00513         b_exit = VLC_TRUE;
00514     }
00515     /* Check for module list option */
00516     else if( config_GetInt( p_vlc, "list" ) )
00517     {
00518         ListModules( p_vlc );
00519         b_exit = VLC_TRUE;
00520     }
00521 
00522     /* Check for config file options */
00523     if( config_GetInt( p_vlc, "reset-config" ) )
00524     {
00525         vlc_object_detach( p_help_module );
00526         config_ResetAll( p_vlc );
00527         config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
00528         config_SaveConfigFile( p_vlc, NULL );
00529         vlc_object_attach( p_help_module, libvlc.p_module_bank );
00530     }
00531     if( config_GetInt( p_vlc, "save-config" ) )
00532     {
00533         vlc_object_detach( p_help_module );
00534         config_LoadConfigFile( p_vlc, NULL );
00535         config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
00536         config_SaveConfigFile( p_vlc, NULL );
00537         vlc_object_attach( p_help_module, libvlc.p_module_bank );
00538     }
00539 
00540     /* Hack: remove the help module here */
00541     vlc_object_detach( p_help_module );
00542     /* End hack */
00543 
00544     if( b_exit )
00545     {
00546         config_Free( p_help_module );
00547         vlc_object_destroy( p_help_module );
00548         module_EndBank( p_vlc );
00549         if( i_object ) vlc_object_release( p_vlc );
00550         return VLC_EEXIT;
00551     }
00552 
00553     /*
00554      * Init device values
00555      */
00556     InitDeviceValues( p_vlc );
00557 
00558     /*
00559      * Override default configuration with config file settings
00560      */
00561     config_LoadConfigFile( p_vlc, NULL );
00562 
00563     /* Hack: insert the help module here */
00564     vlc_object_attach( p_help_module, libvlc.p_module_bank );
00565     /* End hack */
00566 
00567     /*
00568      * Override configuration with command line settings
00569      */
00570     if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
00571     {
00572 #ifdef WIN32
00573         ShowConsole();
00574         /* Pause the console because it's destroyed when we exit */
00575         fprintf( stderr, "The command line options couldn't be loaded, check "
00576                  "that they are valid.\n" );
00577         PauseConsole();
00578 #endif
00579         vlc_object_detach( p_help_module );
00580         config_Free( p_help_module );
00581         vlc_object_destroy( p_help_module );
00582         module_EndBank( p_vlc );
00583         if( i_object ) vlc_object_release( p_vlc );
00584         return VLC_EGENERIC;
00585     }
00586 
00587     /* Hack: remove the help module here */
00588     vlc_object_detach( p_help_module );
00589     config_Free( p_help_module );
00590     vlc_object_destroy( p_help_module );
00591     /* End hack */
00592 
00593     /*
00594      * System specific configuration
00595      */
00596     system_Configure( p_vlc, &i_argc, ppsz_argv );
00597 
00598     /*
00599      * Message queue options
00600      */
00601 
00602     var_Create( p_vlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
00603     if( config_GetInt( p_vlc, "quiet" ) )
00604     {
00605         val.i_int = -1;
00606         var_Set( p_vlc, "verbose", val );
00607     }
00608     var_AddCallback( p_vlc, "verbose", VerboseCallback, NULL );
00609     var_Change( p_vlc, "verbose", VLC_VAR_TRIGGER_CALLBACKS, NULL, NULL );
00610 
00611     libvlc.b_color = libvlc.b_color && config_GetInt( p_vlc, "color" );
00612 
00613     /*
00614      * Output messages that may still be in the queue
00615      */
00616     msg_Flush( p_vlc );
00617 
00618     /* p_vlc initialization. FIXME ? */
00619 
00620     if( !config_GetInt( p_vlc, "fpu" ) )
00621         libvlc.i_cpu &= ~CPU_CAPABILITY_FPU;
00622 
00623 #if defined( __i386__ ) || defined( __x86_64__ )
00624     if( !config_GetInt( p_vlc, "mmx" ) )
00625         libvlc.i_cpu &= ~CPU_CAPABILITY_MMX;
00626     if( !config_GetInt( p_vlc, "3dn" ) )
00627         libvlc.i_cpu &= ~CPU_CAPABILITY_3DNOW;
00628     if( !config_GetInt( p_vlc, "mmxext" ) )
00629         libvlc.i_cpu &= ~CPU_CAPABILITY_MMXEXT;
00630     if( !config_GetInt( p_vlc, "sse" ) )
00631         libvlc.i_cpu &= ~CPU_CAPABILITY_SSE;
00632     if( !config_GetInt( p_vlc, "sse2" ) )
00633         libvlc.i_cpu &= ~CPU_CAPABILITY_SSE2;
00634 #endif
00635 #if defined( __powerpc__ ) || defined( SYS_DARWIN )
00636     if( !config_GetInt( p_vlc, "altivec" ) )
00637         libvlc.i_cpu &= ~CPU_CAPABILITY_ALTIVEC;
00638 #endif
00639 
00640 #define PRINT_CAPABILITY( capability, string )                              \
00641     if( libvlc.i_cpu & capability )                                         \
00642     {                                                                       \
00643         strncat( p_capabilities, string " ",                                \
00644                  sizeof(p_capabilities) - strlen(p_capabilities) );         \
00645         p_capabilities[sizeof(p_capabilities) - 1] = '\0';                  \
00646     }
00647 
00648     p_capabilities[0] = '\0';
00649     PRINT_CAPABILITY( CPU_CAPABILITY_486, "486" );
00650     PRINT_CAPABILITY( CPU_CAPABILITY_586, "586" );
00651     PRINT_CAPABILITY( CPU_CAPABILITY_PPRO, "Pentium Pro" );
00652     PRINT_CAPABILITY( CPU_CAPABILITY_MMX, "MMX" );
00653     PRINT_CAPABILITY( CPU_CAPABILITY_3DNOW, "3DNow!" );
00654     PRINT_CAPABILITY( CPU_CAPABILITY_MMXEXT, "MMXEXT" );
00655     PRINT_CAPABILITY( CPU_CAPABILITY_SSE, "SSE" );
00656     PRINT_CAPABILITY( CPU_CAPABILITY_SSE2, "SSE2" );
00657     PRINT_CAPABILITY( CPU_CAPABILITY_ALTIVEC, "AltiVec" );
00658     PRINT_CAPABILITY( CPU_CAPABILITY_FPU, "FPU" );
00659     msg_Dbg( p_vlc, "CPU has capabilities %s", p_capabilities );
00660 
00661     /*
00662      * Choose the best memcpy module
00663      */
00664     p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy", 0 );
00665 
00666     if( p_vlc->pf_memcpy == NULL )
00667     {
00668         p_vlc->pf_memcpy = memcpy;
00669     }
00670 
00671     if( p_vlc->pf_memset == NULL )
00672     {
00673         p_vlc->pf_memset = memset;
00674     }
00675 
00676     /*
00677      * Initialize hotkey handling
00678      */
00679     var_Create( p_vlc, "key-pressed", VLC_VAR_INTEGER );
00680     p_vlc->p_hotkeys = malloc( sizeof(p_hotkeys) );
00681     /* Do a copy (we don't need to modify the strings) */
00682     memcpy( p_vlc->p_hotkeys, p_hotkeys, sizeof(p_hotkeys) );
00683 
00684     /*
00685      * Initialize playlist and get commandline files
00686      */
00687     p_playlist = playlist_Create( p_vlc );
00688     if( !p_playlist )
00689     {
00690         msg_Err( p_vlc, "playlist initialization failed" );
00691         if( p_vlc->p_memcpy_module != NULL )
00692         {
00693             module_Unneed( p_vlc, p_vlc->p_memcpy_module );
00694         }
00695         module_EndBank( p_vlc );
00696         if( i_object ) vlc_object_release( p_vlc );
00697         return VLC_EGENERIC;
00698     }
00699 
00700     psz_modules = config_GetPsz( p_playlist, "services-discovery" );
00701     if( psz_modules && *psz_modules )
00702     {
00703         /* Add service discovery modules */
00704         playlist_AddSDModules( p_playlist, psz_modules );
00705     }
00706     if( psz_modules ) free( psz_modules );
00707 
00708     /*
00709      * Load background interfaces
00710      */
00711     psz_modules = config_GetPsz( p_vlc, "extraintf" );
00712     psz_control = config_GetPsz( p_vlc, "control" );
00713 
00714     if( psz_modules && *psz_modules && psz_control && *psz_control )
00715     {
00716         psz_modules = (char *)realloc( psz_modules, strlen( psz_modules ) +
00717                                                     strlen( psz_control ) + 1 );
00718         sprintf( psz_modules, "%s:%s", psz_modules, psz_control );
00719     }
00720     else if( psz_control && *psz_control )
00721     {
00722         if( psz_modules ) free( psz_modules );
00723         psz_modules = strdup( psz_control );
00724     }
00725 
00726     psz_parser = psz_modules;
00727     while ( psz_parser && *psz_parser )
00728     {
00729         char *psz_module, *psz_temp;
00730         psz_module = psz_parser;
00731         psz_parser = strchr( psz_module, ':' );
00732         if ( psz_parser )
00733         {
00734             *psz_parser = '\0';
00735             psz_parser++;
00736         }
00737         psz_temp = (char *)malloc( strlen(psz_module) + sizeof(",none") );
00738         if( psz_temp )
00739         {
00740             sprintf( psz_temp, "%s,none", psz_module );
00741             VLC_AddIntf( 0, psz_temp, VLC_FALSE, VLC_FALSE );
00742             free( psz_temp );
00743         }
00744     }
00745     if ( psz_modules )
00746     {
00747         free( psz_modules );
00748     }
00749 
00750     /*
00751      * Always load the hotkeys interface if it exists
00752      */
00753     VLC_AddIntf( 0, "hotkeys,none", VLC_FALSE, VLC_FALSE );
00754 
00755     /*
00756      * If needed, load the Xscreensaver interface
00757      * Currently, only for X
00758      */
00759 #ifdef HAVE_X11_XLIB_H
00760     if( config_GetInt( p_vlc, "disable-screensaver" ) == 1 )
00761     {
00762         VLC_AddIntf( 0, "screensaver", VLC_FALSE, VLC_FALSE );
00763     }
00764 #endif
00765 
00766     /*
00767      * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin
00768      */
00769     var_Create( p_vlc, "drawable", VLC_VAR_INTEGER );
00770     var_Create( p_vlc, "drawableredraw", VLC_VAR_INTEGER );
00771     var_Create( p_vlc, "drawablet", VLC_VAR_INTEGER );
00772     var_Create( p_vlc, "drawablel", VLC_VAR_INTEGER );
00773     var_Create( p_vlc, "drawableb", VLC_VAR_INTEGER );
00774     var_Create( p_vlc, "drawabler", VLC_VAR_INTEGER );
00775     var_Create( p_vlc, "drawablex", VLC_VAR_INTEGER );
00776     var_Create( p_vlc, "drawabley", VLC_VAR_INTEGER );
00777     var_Create( p_vlc, "drawablew", VLC_VAR_INTEGER );
00778     var_Create( p_vlc, "drawableh", VLC_VAR_INTEGER );
00779     var_Create( p_vlc, "drawableportx", VLC_VAR_INTEGER );
00780     var_Create( p_vlc, "drawableporty", VLC_VAR_INTEGER );
00781 
00782     /* Create volume callback system. */
00783     var_Create( p_vlc, "volume-change", VLC_VAR_BOOL );
00784 
00785     /*
00786      * Get input filenames given as commandline arguments
00787      */
00788     GetFilenames( p_vlc, i_argc, ppsz_argv );
00789 
00790     /*
00791      * Get --open argument
00792      */
00793     var_Create( p_vlc, "open", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
00794     var_Get( p_vlc, "open", &val );
00795     if ( val.psz_string != NULL && *val.psz_string )
00796     {
00797         VLC_AddTarget( p_vlc->i_object_id, val.psz_string, NULL, 0,
00798                        PLAYLIST_INSERT, 0 );
00799     }
00800     if ( val.psz_string != NULL ) free( val.psz_string );
00801 
00802     if( i_object ) vlc_object_release( p_vlc );
00803     return VLC_SUCCESS;
00804 }
00805 
00806 /*****************************************************************************
00807  * VLC_AddIntf: add an interface
00808  *****************************************************************************
00809  * This function opens an interface plugin and runs it. If b_block is set
00810  * to 0, VLC_AddIntf will return immediately and let the interface run in a
00811  * separate thread. If b_block is set to 1, VLC_AddIntf will continue until
00812  * user requests to quit. If b_play is set to 1, VLC_AddIntf will start playing
00813  * the playlist when it is completely initialised.
00814  *****************************************************************************/
00815 int VLC_AddIntf( int i_object, char const *psz_module,
00816                  vlc_bool_t b_block, vlc_bool_t b_play )
00817 {
00818     int i_err;
00819     intf_thread_t *p_intf;
00820     vlc_t *p_vlc = vlc_current_object( i_object );
00821 
00822     if( !p_vlc )
00823     {
00824         return VLC_ENOOBJ;
00825     }
00826 
00827 #ifndef WIN32
00828     if( p_vlc->p_libvlc->b_daemon && b_block && !psz_module )
00829     {
00830         /* Daemon mode hack.
00831          * We prefer the dummy interface if none is specified. */
00832         char *psz_interface = config_GetPsz( p_vlc, "intf" );
00833         if( !psz_interface || !*psz_interface ) psz_module = "dummy";
00834         if( psz_interface ) free( psz_interface );
00835     }
00836 #endif
00837 
00838     /* Try to create the interface */
00839     p_intf = intf_Create( p_vlc, psz_module ? psz_module : "$intf" );
00840 
00841     if( p_intf == NULL )
00842     {
00843         msg_Err( p_vlc, "interface \"%s\" initialization failed", psz_module );
00844         if( i_object ) vlc_object_release( p_vlc );
00845         return VLC_EGENERIC;
00846     }
00847 
00848     /* Interface doesn't handle play on start so do it ourselves */
00849     if( !p_intf->b_play && b_play ) VLC_Play( i_object );
00850 
00851     /* Try to run the interface */
00852     p_intf->b_play = b_play;
00853     p_intf->b_block = b_block;
00854     i_err = intf_RunThread( p_intf );
00855     if( i_err )
00856     {
00857         vlc_object_detach( p_intf );
00858         intf_Destroy( p_intf );
00859         if( i_object ) vlc_object_release( p_vlc );
00860         return i_err;
00861     }
00862 
00863     if( i_object ) vlc_object_release( p_vlc );
00864     return VLC_SUCCESS;
00865 }
00866 
00867 /*****************************************************************************
00868  * VLC_Die: ask vlc to die.
00869  *****************************************************************************
00870  * This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
00871  * task. It is your duty to call VLC_CleanUp and VLC_Destroy afterwards.
00872  *****************************************************************************/
00873 int VLC_Die( int i_object )
00874 {
00875     vlc_t *p_vlc = vlc_current_object( i_object );
00876 
00877     if( !p_vlc )
00878     {
00879         return VLC_ENOOBJ;
00880     }
00881 
00882     p_vlc->b_die = VLC_TRUE;
00883 
00884     if( i_object ) vlc_object_release( p_vlc );
00885     return VLC_SUCCESS;
00886 }
00887 
00888 /*****************************************************************************
00889  * VLC_CleanUp: CleanUp all the intf, playlist, vout, aout
00890  *****************************************************************************/
00891 int VLC_CleanUp( int i_object )
00892 {
00893     intf_thread_t      * p_intf;
00894     playlist_t         * p_playlist;
00895     vout_thread_t      * p_vout;
00896     aout_instance_t    * p_aout;
00897     announce_handler_t * p_announce;
00898     vlc_t *p_vlc = vlc_current_object( i_object );
00899 
00900     /* Check that the handle is valid */
00901     if( !p_vlc )
00902     {
00903         return VLC_ENOOBJ;
00904     }
00905 
00906     /*
00907      * Ask the interfaces to stop and destroy them
00908      */
00909     msg_Dbg( p_vlc, "removing all interfaces" );
00910     while( (p_intf = vlc_object_find( p_vlc, VLC_OBJECT_INTF, FIND_CHILD )) )
00911     {
00912         intf_StopThread( p_intf );
00913         vlc_object_detach( p_intf );
00914         vlc_object_release( p_intf );
00915         intf_Destroy( p_intf );
00916     }
00917 
00918     /*
00919      * Free playlists
00920      */
00921     msg_Dbg( p_vlc, "removing all playlists" );
00922     while( (p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST,
00923                                           FIND_CHILD )) )
00924     {
00925         vlc_object_detach( p_playlist );
00926         vlc_object_release( p_playlist );
00927         playlist_Destroy( p_playlist );
00928     }
00929 
00930     /*
00931      * Free video outputs
00932      */
00933     msg_Dbg( p_vlc, "removing all video outputs" );
00934     while( (p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD )) )
00935     {
00936         vlc_object_detach( p_vout );
00937         vlc_object_release( p_vout );
00938         vout_Destroy( p_vout );
00939     }
00940 
00941     /*
00942      * Free audio outputs
00943      */
00944     msg_Dbg( p_vlc, "removing all audio outputs" );
00945     while( (p_aout = vlc_object_find( p_vlc, VLC_OBJECT_AOUT, FIND_CHILD )) )
00946     {
00947         vlc_object_detach( (vlc_object_t *)p_aout );
00948         vlc_object_release( (vlc_object_t *)p_aout );
00949         aout_Delete( p_aout );
00950     }
00951 
00952     /*
00953      * Free announce handler(s?)
00954      */
00955     msg_Dbg( p_vlc, "removing announce handler" );
00956     while( (p_announce = vlc_object_find( p_vlc, VLC_OBJECT_ANNOUNCE,
00957                                                  FIND_CHILD ) ) )
00958    {
00959         vlc_object_detach( p_announce );
00960         vlc_object_release( p_announce );
00961         announce_HandlerDestroy( p_announce );
00962    }
00963 
00964     if( i_object ) vlc_object_release( p_vlc );
00965     return VLC_SUCCESS;
00966 }
00967 
00968 /*****************************************************************************
00969  * VLC_Destroy: Destroy everything.
00970  *****************************************************************************
00971  * This function requests the running threads to finish, waits for their
00972  * termination, and destroys their structure.
00973  *****************************************************************************/
00974 int VLC_Destroy( int i_object )
00975 {
00976     vlc_t *p_vlc = vlc_current_object( i_object );
00977 
00978     if( !p_vlc )
00979     {
00980         return VLC_ENOOBJ;
00981     }
00982 
00983     /*
00984      * Free allocated memory
00985      */
00986     if( p_vlc->p_memcpy_module )
00987     {
00988         module_Unneed( p_vlc, p_vlc->p_memcpy_module );
00989         p_vlc->p_memcpy_module = NULL;
00990     }
00991 
00992     /*
00993      * Free module bank !
00994      */
00995     module_EndBank( p_vlc );
00996 
00997     if( p_vlc->psz_homedir )
00998     {
00999         free( p_vlc->psz_homedir );
01000         p_vlc->psz_homedir = NULL;
01001     }
01002 
01003     if( p_vlc->psz_userdir )
01004     {
01005         free( p_vlc->psz_userdir );
01006         p_vlc->psz_userdir = NULL;
01007     }
01008 
01009     if( p_vlc->psz_configfile )
01010     {
01011         free( p_vlc->psz_configfile );
01012         p_vlc->psz_configfile = NULL;
01013     }
01014 
01015     if( p_vlc->p_hotkeys )
01016     {
01017         free( p_vlc->p_hotkeys );
01018         p_vlc->p_hotkeys = NULL;
01019     }
01020 
01021     /*
01022      * System specific cleaning code
01023      */
01024     system_End( p_vlc );
01025 
01026     /*
01027      * Free message queue.
01028      * Nobody shall use msg_* afterward.
01029      */
01030     msg_Flush( p_vlc );
01031     msg_Destroy( p_libvlc );
01032 
01033     /* Destroy global iconv */
01034     LocaleDeinit();
01035 
01036     /* Destroy mutexes */
01037     vlc_mutex_destroy( &p_vlc->config_lock );
01038 
01039     vlc_object_detach( p_vlc );
01040 
01041     /* Release object before destroying it */
01042     if( i_object ) vlc_object_release( p_vlc );
01043 
01044     vlc_object_destroy( p_vlc );
01045 
01046     /* Stop thread system: last one out please shut the door! */
01047     vlc_threads_end( p_libvlc );
01048 
01049     return VLC_SUCCESS;
01050 }
01051 
01052 /*****************************************************************************
01053  * VLC_VariableSet: set a vlc variable
01054  *****************************************************************************/
01055 int VLC_VariableSet( int i_object, char const *psz_var, vlc_value_t value )
01056 {
01057     vlc_t *p_vlc = vlc_current_object( i_object );
01058     int i_ret;
01059 
01060     if( !p_vlc )
01061     {
01062         return VLC_ENOOBJ;
01063     }
01064 
01065     /* FIXME: Temporary hack for Mozilla, if variable starts with conf:: then
01066      * we handle it as a configuration variable. Don't tell Gildas :) -- sam */
01067     if( !strncmp( psz_var, "conf::", 6 ) )
01068     {
01069         module_config_t *p_item;
01070         char const *psz_newvar = psz_var + 6;
01071 
01072         p_item = config_FindConfig( VLC_OBJECT(p_vlc), psz_newvar );
01073 
01074         if( p_item )
01075         {
01076             switch( p_item->i_type )
01077             {
01078                 case CONFIG_ITEM_BOOL:
01079                     config_PutInt( p_vlc, psz_newvar, value.b_bool );
01080                     break;
01081                 case CONFIG_ITEM_INTEGER:
01082                     config_PutInt( p_vlc, psz_newvar, value.i_int );
01083                     break;
01084                 case CONFIG_ITEM_FLOAT:
01085                     config_PutFloat( p_vlc, psz_newvar, value.f_float );
01086                     break;
01087                 default:
01088                     config_PutPsz( p_vlc, psz_newvar, value.psz_string );
01089                     break;
01090             }
01091             if( i_object ) vlc_object_release( p_vlc );
01092             return VLC_SUCCESS;
01093         }
01094     }
01095 
01096     i_ret = var_Set( p_vlc, psz_var, value );
01097 
01098     if( i_object ) vlc_object_release( p_vlc );
01099     return i_ret;
01100 }
01101 
01102 /*****************************************************************************
01103  * VLC_VariableGet: get a vlc variable
01104  *****************************************************************************/
01105 int VLC_VariableGet( int i_object, char const *psz_var, vlc_value_t *p_value )
01106 {
01107     vlc_t *p_vlc = vlc_current_object( i_object );
01108     int i_ret;
01109 
01110     if( !p_vlc )
01111     {
01112         return VLC_ENOOBJ;
01113     }
01114 
01115     i_ret = var_Get( p_vlc , psz_var, p_value );
01116 
01117     if( i_object ) vlc_object_release( p_vlc );
01118     return i_ret;
01119 }
01120 
01121 /*****************************************************************************
01122  * VLC_VariableType: get a vlc variable type
01123  *****************************************************************************/
01124 int VLC_VariableType( int i_object, char const *psz_var, int *pi_type )
01125 {
01126     int i_type;
01127     vlc_t *p_vlc = vlc_current_object( i_object );
01128 
01129     if( !p_vlc )
01130     {
01131         return VLC_ENOOBJ;
01132     }
01133 
01134     /* FIXME: Temporary hack for Mozilla, if variable starts with conf:: then
01135      * we handle it as a configuration variable. Don't tell Gildas :) -- sam */
01136     if( !strncmp( psz_var, "conf::", 6 ) )
01137     {
01138         module_config_t *p_item;
01139         char const *psz_newvar = psz_var + 6;
01140 
01141         p_item = config_FindConfig( VLC_OBJECT(p_vlc), psz_newvar );
01142 
01143         if( p_item )
01144         {
01145             switch( p_item->i_type )
01146             {
01147                 case CONFIG_ITEM_BOOL:
01148                     i_type = VLC_VAR_BOOL;
01149                     break;
01150                 case CONFIG_ITEM_INTEGER:
01151                     i_type = VLC_VAR_INTEGER;
01152                     break;
01153                 case CONFIG_ITEM_FLOAT:
01154                     i_type = VLC_VAR_FLOAT;
01155                     break;
01156                 default:
01157                     i_type = VLC_VAR_STRING;
01158                     break;
01159             }
01160         }
01161         else
01162             i_type = 0;
01163     }
01164     else
01165         i_type = VLC_VAR_TYPE & var_Type( p_vlc , psz_var );
01166 
01167     if( i_object ) vlc_object_release( p_vlc );
01168 
01169     if( i_type > 0 )
01170     {
01171         *pi_type = i_type;
01172         return VLC_SUCCESS;
01173     }
01174     return VLC_ENOVAR;
01175 }
01176 
01177 /*****************************************************************************
01178  * VLC_AddTarget: adds a target for playing.
01179  *****************************************************************************
01180  * This function adds psz_target to the current playlist. If a playlist does
01181  * not exist, it will create one.
01182  *****************************************************************************/
01183 int VLC_AddTarget( int i_object, char const *psz_target,
01184                    char const **ppsz_options, int i_options,
01185                    int i_mode, int i_pos )
01186 {
01187     int i_err;
01188     playlist_t *p_playlist;
01189     vlc_t *p_vlc = vlc_current_object( i_object );
01190 
01191     if( !p_vlc )
01192     {
01193         return VLC_ENOOBJ;
01194     }
01195 
01196     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
01197 
01198     if( p_playlist == NULL )
01199     {
01200         msg_Dbg( p_vlc, "no playlist present, creating one" );
01201         p_playlist = playlist_Create( p_vlc );
01202 
01203         if( p_playlist == NULL )
01204         {
01205             if( i_object ) vlc_object_release( p_vlc );
01206             return VLC_EGENERIC;
01207         }
01208 
01209         vlc_object_yield( p_playlist );
01210     }
01211 
01212     i_err = playlist_AddExt( p_playlist, psz_target, psz_target,
01213                              i_mode, i_pos, -1, ppsz_options, i_options);
01214 
01215     vlc_object_release( p_playlist );
01216 
01217     if( i_object ) vlc_object_release( p_vlc );
01218     return i_err;
01219 }
01220 
01221 /*****************************************************************************
01222  * VLC_Play: play
01223  *****************************************************************************/
01224 int VLC_Play( int i_object )
01225 {
01226     playlist_t * p_playlist;
01227     vlc_t *p_vlc = vlc_current_object( i_object );
01228 
01229     /* Check that the handle is valid */
01230     if( !p_vlc )
01231     {
01232         return VLC_ENOOBJ;
01233     }
01234 
01235     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
01236 
01237     if( !p_playlist )
01238     {
01239         if( i_object ) vlc_object_release( p_vlc );
01240         return VLC_ENOOBJ;
01241     }
01242 
01243     playlist_Play( p_playlist );
01244     vlc_object_release( p_playlist );
01245 
01246     if( i_object ) vlc_object_release( p_vlc );
01247     return VLC_SUCCESS;
01248 }
01249 
01250 /*****************************************************************************
01251  * VLC_Pause: toggle pause
01252  *****************************************************************************/
01253 int VLC_Pause( int i_object )
01254 {
01255     playlist_t * p_playlist;
01256     vlc_t *p_vlc = vlc_current_object( i_object );
01257 
01258     /* Check that the handle is valid */
01259     if( !p_vlc )
01260     {
01261         return VLC_ENOOBJ;
01262     }
01263 
01264     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
01265 
01266     if( !p_playlist )
01267     {
01268         if( i_object ) vlc_object_release( p_vlc );
01269         return VLC_ENOOBJ;
01270     }
01271 
01272     playlist_Pause( p_playlist );
01273     vlc_object_release( p_playlist );
01274 
01275     if( i_object ) vlc_object_release( p_vlc );
01276     return VLC_SUCCESS;
01277 }
01278 
01279 /*****************************************************************************
01280  * VLC_Pause: toggle pause
01281  *****************************************************************************/
01282 int VLC_Stop( int i_object )
01283 {
01284     playlist_t * p_playlist;
01285     vlc_t *p_vlc = vlc_current_object( i_object );
01286 
01287     /* Check that the handle is valid */
01288     if( !p_vlc )
01289     {
01290         return VLC_ENOOBJ;
01291     }
01292 
01293     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
01294 
01295     if( !p_playlist )
01296     {
01297         if( i_object ) vlc_object_release( p_vlc );
01298         return VLC_ENOOBJ;
01299     }
01300 
01301     playlist_Stop( p_playlist );
01302     vlc_object_release( p_playlist );
01303 
01304     if( i_object ) vlc_object_release( p_vlc );
01305     return VLC_SUCCESS;
01306 }
01307 
01308 /*****************************************************************************
01309  * VLC_IsPlaying: Query for Playlist Status
01310  *****************************************************************************/
01311 
01312 vlc_bool_t VLC_IsPlaying( int i_object )
01313 {
01314     playlist_t * p_playlist;
01315     vlc_bool_t   b_playing;
01316 
01317     vlc_t *p_vlc = vlc_current_object( i_object );
01318 
01319     /* Check that the handle is valid */
01320     if( !p_vlc )
01321     {
01322         return VLC_ENOOBJ;
01323     }
01324 
01325     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
01326 
01327     if( !p_playlist )
01328     {
01329         if( i_object ) vlc_object_release( p_vlc );
01330         return VLC_ENOOBJ;
01331     }
01332 
01333     if( p_playlist->p_input )
01334     {
01335         vlc_value_t  val;
01336         var_Get( p_playlist->p_input, "state", &val );
01337         b_playing = ( val.i_int == PLAYING_S );
01338     }
01339     else
01340     {
01341         b_playing = playlist_IsPlaying( p_playlist );
01342     }
01343     vlc_object_release( p_playlist );
01344 
01345     if( i_object ) vlc_object_release( p_vlc );
01346     return b_playing;
01347 }
01348 
01358 float VLC_PositionGet( int i_object )
01359 {
01360     input_thread_t *p_input;
01361     vlc_value_t val;
01362     vlc_t *p_vlc = vlc_current_object( i_object );
01363 
01364     /* Check that the handle is valid */
01365     if( !p_vlc )
01366     {
01367         return VLC_ENOOBJ;
01368     }
01369 
01370     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
01371 
01372     if( !p_input )
01373     {
01374         if( i_object ) vlc_object_release( p_vlc );
01375         return VLC_ENOOBJ;
01376     }
01377 
01378     var_Get( p_input, "position", &val );
01379     vlc_object_release( p_input );
01380 
01381     if( i_object ) vlc_object_release( p_vlc );
01382     return val.f_float;
01383 }
01384 
01396 float VLC_PositionSet( int i_object, float i_position )
01397 {
01398     input_thread_t *p_input;
01399     vlc_value_t val;
01400     vlc_t *p_vlc = vlc_current_object( i_object );
01401 
01402     /* Check that the handle is valid */
01403     if( !p_vlc )
01404     {
01405         return VLC_ENOOBJ;
01406     }
01407 
01408     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
01409 
01410     if( !p_input )
01411     {
01412         if( i_object ) vlc_object_release( p_vlc );
01413         return VLC_ENOOBJ;
01414     }
01415 
01416     val.f_float = i_position;
01417     var_Set( p_input, "position", val );
01418     var_Get( p_input, "position", &val );
01419     vlc_object_release( p_input );
01420 
01421     if( i_object ) vlc_object_release( p_vlc );
01422     return val.f_float;
01423 }
01424 
01434 int VLC_TimeGet( int i_object )
01435 {
01436     input_thread_t *p_input;
01437     vlc_value_t val;
01438     vlc_t *p_vlc = vlc_current_object( i_object );
01439 
01440     /* Check that the handle is valid */
01441     if( !p_vlc )
01442     {
01443         return VLC_ENOOBJ;
01444     }
01445 
01446     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
01447 
01448     if( !p_input )
01449     {
01450         if( i_object ) vlc_object_release( p_vlc );
01451         return VLC_ENOOBJ;
01452     }
01453 
01454     var_Get( p_input, "time", &val );
01455     vlc_object_release( p_input );
01456 
01457     if( i_object ) vlc_object_release( p_vlc );
01458     return val.i_time  / 1000000;
01459 }
01460 
01474 int VLC_TimeSet( int i_object, int i_seconds, vlc_bool_t b_relative )
01475 {
01476     input_thread_t *p_input;
01477     vlc_value_t val;
01478     vlc_t *p_vlc = vlc_current_object( i_object );
01479 
01480     /* Check that the handle is valid */
01481     if( !p_vlc )
01482     {
01483         return VLC_ENOOBJ;
01484     }
01485 
01486     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
01487 
01488     if( !p_input )
01489     {
01490         if( i_object ) vlc_object_release( p_vlc );
01491         return VLC_ENOOBJ;
01492     }
01493 
01494     if( b_relative )
01495     {
01496         val.i_time = i_seconds;
01497         val.i_time = val.i_time * 1000000L;
01498         var_Set( p_input, "time-offset", val );
01499     }
01500     else
01501     {
01502         val.i_time = i_seconds;
01503         val.i_time = val.i_time * 1000000L;
01504         var_Set( p_input, "time", val );
01505     }
01506     vlc_object_release( p_input );
01507 
01508     if( i_object ) vlc_object_release( p_vlc );
01509     return VLC_SUCCESS;
01510 }
01511 
01521 int VLC_LengthGet( int i_object )
01522 {
01523     input_thread_t *p_input;
01524     vlc_value_t val;
01525     vlc_t *p_vlc = vlc_current_object( i_object );
01526 
01527     /* Check that the handle is valid */
01528     if( !p_vlc )
01529     {
01530         return VLC_ENOOBJ;
01531     }
01532 
01533     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
01534 
01535     if( !p_input )
01536     {
01537         if( i_object ) vlc_object_release( p_vlc );
01538         return VLC_ENOOBJ;
01539     }
01540 
01541     var_Get( p_input, "length", &val );
01542     vlc_object_release( p_input );
01543 
01544     if( i_object ) vlc_object_release( p_vlc );
01545     return val.i_time  / 1000000L;
01546 }
01547 
01557 float VLC_SpeedFaster( int i_object )
01558 {
01559     input_thread_t *p_input;
01560     vlc_value_t val;
01561     vlc_t *p_vlc = vlc_current_object( i_object );
01562 
01563     /* Check that the handle is valid */
01564     if( !p_vlc )
01565     {
01566         return VLC_ENOOBJ;
01567     }
01568 
01569     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
01570 
01571     if( !p_input )
01572     {
01573         if( i_object ) vlc_object_release( p_vlc );
01574         return VLC_ENOOBJ;
01575     }
01576 
01577     val.b_bool = VLC_TRUE;
01578     var_Set( p_input, "rate-faster", val );
01579     var_Get( p_input, "rate", &val );
01580     vlc_object_release( p_input );
01581 
01582     if( i_object ) vlc_object_release( p_vlc );
01583     return val.f_float / INPUT_RATE_DEFAULT;
01584 }
01585 
01595 float VLC_SpeedSlower( int i_object )
01596 {
01597     input_thread_t *p_input;
01598     vlc_value_t val;
01599     vlc_t *p_vlc = vlc_current_object( i_object );
01600 
01601     /* Check that the handle is valid */
01602     if( !p_vlc )
01603     {
01604         return VLC_ENOOBJ;
01605     }
01606 
01607     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
01608 
01609     if( !p_input )
01610     {
01611         if( i_object ) vlc_object_release( p_vlc );
01612         return VLC_ENOOBJ;
01613     }
01614 
01615     val.b_bool = VLC_TRUE;
01616     var_Set( p_input, "rate-slower", val );
01617     var_Get( p_input, "rate", &val );
01618     vlc_object_release( p_input );
01619 
01620     if( i_object ) vlc_object_release( p_vlc );
01621     return val.f_float / INPUT_RATE_DEFAULT;
01622 }
01623 
01633 int VLC_PlaylistIndex( int i_object )
01634 {
01635     int i_index;
01636     playlist_t * p_playlist;
01637     vlc_t *p_vlc = vlc_current_object( i_object );
01638 
01639     /* Check that the handle is valid */
01640     if( !p_vlc )
01641     {
01642         return VLC_ENOOBJ;
01643     }
01644 
01645     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
01646 
01647     if( !p_playlist )
01648     {
01649         if( i_object ) vlc_object_release( p_vlc );
01650         return VLC_ENOOBJ;
01651     }
01652 
01653     i_index = p_playlist->i_index;
01654     vlc_object_release( p_playlist );
01655 
01656     if( i_object ) vlc_object_release( p_vlc );
01657     return i_index;
01658 }
01659 
01666 int VLC_PlaylistNumberOfItems( int i_object )
01667 {
01668     int i_size;
01669     playlist_t * p_playlist;
01670     vlc_t *p_vlc = vlc_current_object( i_object );
01671 
01672     /* Check that the handle is valid */
01673     if( !p_vlc )
01674     {
01675         return VLC_ENOOBJ;
01676     }
01677 
01678     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
01679 
01680     if( !p_playlist )
01681     {
01682         if( i_object ) vlc_object_release( p_vlc );
01683         return VLC_ENOOBJ;
01684     }
01685 
01686     i_size = p_playlist->i_size;
01687     vlc_object_release( p_playlist );
01688 
01689     if( i_object ) vlc_object_release( p_vlc );
01690     return i_size;
01691 }
01692 
01701 int VLC_PlaylistNext( int i_object )
01702 {
01703     playlist_t * p_playlist;
01704     vlc_t *p_vlc = vlc_current_object( i_object );
01705 
01706     /* Check that the handle is valid */
01707     if( !p_vlc )
01708     {
01709         return VLC_ENOOBJ;
01710     }
01711 
01712     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
01713 
01714     if( !p_playlist )
01715     {
01716         if( i_object ) vlc_object_release( p_vlc );
01717         return VLC_ENOOBJ;
01718     }
01719 
01720     playlist_Next( p_playlist );
01721     vlc_object_release( p_playlist );
01722 
01723     if( i_object ) vlc_object_release( p_vlc );
01724     return VLC_SUCCESS;
01725 }
01726 
01735 int VLC_PlaylistPrev( int i_object )
01736 {
01737     playlist_t * p_playlist;
01738     vlc_t *p_vlc = vlc_current_object( i_object );
01739 
01740     /* Check that the handle is valid */
01741     if( !p_vlc )
01742     {
01743         return VLC_ENOOBJ;
01744     }
01745 
01746     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
01747 
01748     if( !p_playlist )
01749     {
01750         if( i_object ) vlc_object_release( p_vlc );
01751         return VLC_ENOOBJ;
01752     }
01753 
01754     playlist_Prev( p_playlist );
01755     vlc_object_release( p_playlist );
01756 
01757     if( i_object ) vlc_object_release( p_vlc );
01758     return VLC_SUCCESS;
01759 }
01760 
01761 
01762 /*****************************************************************************
01763  * VLC_PlaylistClear: Empty the playlist
01764  *****************************************************************************/
01765 int VLC_PlaylistClear( int i_object )
01766 {
01767     int i_err;
01768     playlist_t * p_playlist;
01769     vlc_t *p_vlc = vlc_current_object( i_object );
01770 
01771     /* Check that the handle is valid */
01772     if( !p_vlc )
01773     {
01774         return VLC_ENOOBJ;
01775     }
01776 
01777     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
01778 
01779     if( !p_playlist )
01780     {
01781         if( i_object ) vlc_object_release( p_vlc );
01782         return VLC_ENOOBJ;
01783     }
01784 
01785     i_err = playlist_Clear( p_playlist );
01786 
01787     vlc_object_release( p_playlist );
01788 
01789     if( i_object ) vlc_object_release( p_vlc );
01790     return i_err;
01791 }
01792 
01800 int VLC_VolumeSet( int i_object, int i_volume )
01801 {
01802     audio_volume_t i_vol = 0;
01803     vlc_t *p_vlc = vlc_current_object( i_object );
01804 
01805     /* Check that the handle is valid */
01806     if( !p_vlc )
01807     {
01808         return VLC_ENOOBJ;
01809     }
01810 
01811     if( i_volume >= 0 && i_volume <= 200 )
01812     {
01813         i_vol = i_volume * AOUT_VOLUME_MAX / 200;
01814         aout_VolumeSet( p_vlc, i_vol );
01815     }
01816 
01817     if( i_object ) vlc_object_release( p_vlc );
01818     return i_vol * 200 / AOUT_VOLUME_MAX;
01819 }
01820 
01829 int VLC_VolumeGet( int i_object )
01830 {
01831     audio_volume_t i_volume;
01832     vlc_t *p_vlc = vlc_current_object( i_object );
01833 
01834     /* Check that the handle is valid */
01835     if( !p_vlc )
01836     {
01837         return VLC_ENOOBJ;
01838     }
01839 
01840     aout_VolumeGet( p_vlc, &i_volume );
01841 
01842     if( i_object ) vlc_object_release( p_vlc );
01843     return i_volume*200/AOUT_VOLUME_MAX;
01844 }
01845 
01852 int VLC_VolumeMute( int i_object )
01853 {
01854     vlc_t *p_vlc = vlc_current_object( i_object );
01855 
01856     /* Check that the handle is valid */
01857     if( !p_vlc )
01858     {
01859         return VLC_ENOOBJ;
01860     }
01861 
01862     aout_VolumeMute( p_vlc, NULL );
01863 
01864     if( i_object ) vlc_object_release( p_vlc );
01865     return VLC_SUCCESS;
01866 }
01867 
01868 /*****************************************************************************
01869  * VLC_FullScreen: toggle fullscreen mode
01870  *****************************************************************************/
01871 int VLC_FullScreen( int i_object )
01872 {
01873     vout_thread_t *p_vout;
01874     vlc_t *p_vlc = vlc_current_object( i_object );
01875 
01876     if( !p_vlc )
01877     {
01878         return VLC_ENOOBJ;
01879     }
01880 
01881     p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD );
01882 
01883     if( !p_vout )
01884     {
01885         if( i_object ) vlc_object_release( p_vlc );
01886         return VLC_ENOOBJ;
01887     }
01888 
01889     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
01890     vlc_object_release( p_vout );
01891 
01892     if( i_object ) vlc_object_release( p_vlc );
01893     return VLC_SUCCESS;
01894 }
01895 
01896 /* following functions are local */
01897 
01898 static void LocaleInit( void )
01899 {
01900     char *psz_charset;
01901 
01902     if( !vlc_current_charset( &psz_charset ) )
01903     {
01904         char *psz_conv = psz_charset;
01905 
01906         /*
01907          * Still allow non-ASCII characters when the locale is not set.
01908          * Western Europeans are being favored for historical reasons.
01909          */
01910         psz_conv = strcmp( psz_charset, "ASCII" )
01911             ? psz_charset
01912             : "ISO-8859-15";
01913 
01914         vlc_mutex_init( p_libvlc, &libvlc.from_locale_lock );
01915         vlc_mutex_init( p_libvlc, &libvlc.to_locale_lock );
01916         libvlc.from_locale = vlc_iconv_open( "UTF-8", psz_charset );
01917         libvlc.to_locale = vlc_iconv_open( psz_charset, "UTF-8" );
01918         if( !libvlc.to_locale )
01919         {
01920             /* Not sure it is the right thing to do, but at least it
01921              doesn't make vlc crash with msvc ! */
01922             libvlc.to_locale = (vlc_iconv_t)(-1);
01923         }
01924     }
01925     else
01926         libvlc.from_locale = libvlc.to_locale = (vlc_iconv_t)(-1);
01927     free( psz_charset );
01928 }
01929 
01930 static void LocaleDeinit( void )
01931 {
01932     if( libvlc.to_locale != (vlc_iconv_t)(-1) )
01933     {
01934         vlc_mutex_destroy( &libvlc.from_locale_lock );
01935         vlc_mutex_destroy( &libvlc.to_locale_lock );
01936         vlc_iconv_close( libvlc.from_locale );
01937         vlc_iconv_close( libvlc.to_locale );
01938     }
01939 }
01940 
01941 /*****************************************************************************
01942  * SetLanguage: set the interface language.
01943  *****************************************************************************
01944  * We set the LC_MESSAGES locale category for interface messages and buttons,
01945  * as well as the LC_CTYPE category for string sorting and possible wide
01946  * character support.
01947  *****************************************************************************/
01948 static void SetLanguage ( char const *psz_lang )
01949 {
01950 #if defined( ENABLE_NLS ) \
01951      && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
01952 
01953     char *          psz_path;
01954 #if defined( SYS_DARWIN ) || defined ( WIN32 ) || defined( SYS_BEOS )
01955     char            psz_tmp[1024];
01956 #endif
01957 
01958     if( psz_lang && !*psz_lang )
01959     {
01960 #   if defined( HAVE_LC_MESSAGES )
01961         setlocale( LC_MESSAGES, psz_lang );
01962 #   endif
01963         setlocale( LC_CTYPE, psz_lang );
01964     }
01965     else if( psz_lang )
01966     {
01967 #ifdef SYS_DARWIN
01968         /* I need that under Darwin, please check it doesn't disturb
01969          * other platforms. --Meuuh */
01970         setenv( "LANG", psz_lang, 1 );
01971 
01972 #elif defined( SYS_BEOS ) || defined( WIN32 )
01973         /* We set LC_ALL manually because it is the only way to set
01974          * the language at runtime under eg. Windows. Beware that this
01975          * makes the environment unconsistent when libvlc is unloaded and
01976          * should probably be moved to a safer place like vlc.c. */
01977         static char psz_lcall[20];
01978         snprintf( psz_lcall, 19, "LC_ALL=%s", psz_lang );
01979         psz_lcall[19] = '\0';
01980         putenv( psz_lcall );
01981 #endif
01982 
01983         setlocale( LC_ALL, psz_lang );
01984         /* many code paths assume that float numbers are formatted according
01985          * to the US standard (ie. with dot as decimal point), so we keep
01986          * C for LC_NUMERIC. */
01987         setlocale(LC_NUMERIC, "C" );
01988     }
01989 
01990     /* Specify where to find the locales for current domain */
01991 #if !defined( SYS_DARWIN ) && !defined( WIN32 ) && !defined( SYS_BEOS )
01992     psz_path = LOCALEDIR;
01993 #else
01994     snprintf( psz_tmp, sizeof(psz_tmp), "%s/%s", libvlc.psz_vlcpath,
01995               "locale" );
01996     psz_path = psz_tmp;
01997 #endif
01998     if( !bindtextdomain( PACKAGE_NAME, psz_path ) )
01999     {
02000         fprintf( stderr, "warning: couldn't bind domain %s in directory %s\n",
02001                  PACKAGE_NAME, psz_path );
02002     }
02003 
02004     /* Set the default domain */
02005     textdomain( PACKAGE_NAME );
02006     bind_textdomain_codeset( PACKAGE_NAME, "UTF-8" );
02007 #endif
02008 }
02009 
02010 /*****************************************************************************
02011  * GetFilenames: parse command line options which are not flags
02012  *****************************************************************************
02013  * Parse command line for input files as well as their associated options.
02014  * An option always follows its associated input and begins with a ":".
02015  *****************************************************************************/
02016 static int GetFilenames( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
02017 {
02018     int i_opt, i_options;
02019 
02020     /* We assume that the remaining parameters are filenames
02021      * and their input options */
02022     for( i_opt = i_argc - 1; i_opt >= optind; i_opt-- )
02023     {
02024         const char *psz_target;
02025         i_options = 0;
02026 
02027         /* Count the input options */
02028         while( *ppsz_argv[ i_opt ] == ':' && i_opt > optind )
02029         {
02030             i_options++;
02031             i_opt--;
02032         }
02033 
02034         /* TODO: write an internal function of this one, to avoid
02035          *       unnecessary lookups. */
02036         /* FIXME: should we convert options to UTF-8 as well ?? */
02037         psz_target = FromLocale( ppsz_argv[ i_opt ] );
02038         VLC_AddTarget( p_vlc->i_object_id, psz_target,
02039                        (char const **)( i_options ? &ppsz_argv[i_opt + 1] :
02040                                         NULL ), i_options,
02041                        PLAYLIST_INSERT, 0 );
02042         LocaleFree( psz_target );
02043     }
02044 
02045     return VLC_SUCCESS;
02046 }
02047 
02048 /*****************************************************************************
02049  * Help: print program help
02050  *****************************************************************************
02051  * Print a short inline help. Message interface is initialized at this stage.
02052  *****************************************************************************/
02053 static void Help( vlc_t *p_this, char const *psz_help_name )
02054 {
02055 #ifdef WIN32
02056     ShowConsole();
02057 #endif
02058 
02059     if( psz_help_name && !strcmp( psz_help_name, "help" ) )
02060     {
02061         fprintf( stdout, VLC_USAGE, p_this->psz_object_name );
02062         Usage( p_this, "help" );
02063         Usage( p_this, "main" );
02064     }
02065     else if( psz_help_name && !strcmp( psz_help_name, "longhelp" ) )
02066     {
02067         fprintf( stdout, VLC_USAGE, p_this->psz_object_name );
02068         Usage( p_this, NULL );
02069     }
02070     else if( psz_help_name )
02071     {
02072         Usage( p_this, psz_help_name );
02073     }
02074 
02075 #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
02076     PauseConsole();
02077 #endif
02078 }
02079 
02080 /*****************************************************************************
02081  * Usage: print module usage
02082  *****************************************************************************
02083  * Print a short inline help. Message interface is initialized at this stage.
02084  *****************************************************************************/
02085 static void Usage( vlc_t *p_this, char const *psz_module_name )
02086 {
02087 #define FORMAT_STRING "  %s --%s%s%s%s%s%s%s "
02088     /* short option ------'    |     | | | |  | |
02089      * option name ------------'     | | | |  | |
02090      * <bra -------------------------' | | |  | |
02091      * option type or "" --------------' | |  | |
02092      * ket> -----------------------------' |  | |
02093      * padding spaces ---------------------'  | |
02094      * comment -------------------------------' |
02095      * comment suffix --------------------------'
02096      *
02097      * The purpose of having bra and ket is that we might i18n them as well.
02098      */
02099 #define LINE_START 8
02100 #define PADDING_SPACES 25
02101     vlc_list_t *p_list;
02102     module_t *p_parser;
02103     module_config_t *p_item;
02104     char psz_spaces_text[PADDING_SPACES+LINE_START+1];
02105     char psz_spaces_longtext[LINE_START+3];
02106     char psz_format[sizeof(FORMAT_STRING)];
02107     char psz_buffer[10000];
02108     char psz_short[4];
02109     int i_index;
02110     int i_width = ConsoleWidth() - (PADDING_SPACES+LINE_START+1);
02111     vlc_bool_t b_advanced = config_GetInt( p_this, "advanced" );
02112     vlc_bool_t b_description;
02113 
02114     memset( psz_spaces_text, ' ', PADDING_SPACES+LINE_START );
02115     psz_spaces_text[PADDING_SPACES+LINE_START] = '\0';
02116     memset( psz_spaces_longtext, ' ', LINE_START+2 );
02117     psz_spaces_longtext[LINE_START+2] = '\0';
02118 
02119     strcpy( psz_format, FORMAT_STRING );
02120 
02121     /* List all modules */
02122     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
02123 
02124     /* Enumerate the config for each module */
02125     for( i_index = 0; i_index < p_list->i_count; i_index++ )
02126     {
02127         vlc_bool_t b_help_module;
02128 
02129         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
02130 
02131         if( psz_module_name && strcmp( psz_module_name,
02132                                        p_parser->psz_object_name ) )
02133         {
02134             continue;
02135         }
02136 
02137         /* Ignore modules without config options */
02138         if( !p_parser->i_config_items )
02139         {
02140             continue;
02141         }
02142 
02143         /* Ignore modules with only advanced config options if requested */
02144         if( !b_advanced )
02145         {
02146             for( p_item = p_parser->p_config;
02147                  p_item->i_type != CONFIG_HINT_END;
02148                  p_item++ )
02149             {
02150                 if( (p_item->i_type & CONFIG_ITEM) &&
02151                     !p_item->b_advanced ) break;
02152             }
02153             if( p_item->i_type == CONFIG_HINT_END ) continue;
02154         }
02155 
02156         /* Print name of module */
02157         if( strcmp( "main", p_parser->psz_object_name ) )
02158         fprintf( stdout, "\n %s\n", p_parser->psz_longname );
02159 
02160         b_help_module = !strcmp( "help", p_parser->psz_object_name );
02161 
02162         /* Print module options */
02163         for( p_item = p_parser->p_config;
02164              p_item->i_type != CONFIG_HINT_END;
02165              p_item++ )
02166         {
02167             char *psz_text, *psz_spaces = psz_spaces_text;
02168             char *psz_bra = NULL, *psz_type = NULL, *psz_ket = NULL;
02169             char *psz_suf = "", *psz_prefix = NULL;
02170             signed int i;
02171 
02172             /* Skip deprecated options */
02173             if( p_item->psz_current )
02174             {
02175                 continue;
02176             }
02177             /* Skip advanced options if requested */
02178             if( p_item->b_advanced && !b_advanced )
02179             {
02180                 continue;
02181             }
02182 
02183             switch( p_item->i_type )
02184             {
02185             case CONFIG_HINT_CATEGORY:
02186             case CONFIG_HINT_USAGE:
02187                 if( !strcmp( "main", p_parser->psz_object_name ) )
02188                 fprintf( stdout, "\n %s\n", p_item->psz_text );
02189                 break;
02190 
02191             case CONFIG_ITEM_STRING:
02192             case CONFIG_ITEM_FILE:
02193             case CONFIG_ITEM_DIRECTORY:
02194             case CONFIG_ITEM_MODULE: /* We could also have "=<" here */
02195             case CONFIG_ITEM_MODULE_CAT:
02196             case CONFIG_ITEM_MODULE_LIST:
02197             case CONFIG_ITEM_MODULE_LIST_CAT:
02198                 psz_bra = " <"; psz_type = _("string"); psz_ket = ">";
02199 
02200                 if( p_item->ppsz_list )
02201                 {
02202                     psz_bra = " {";
02203                     psz_type = psz_buffer;
02204                     psz_type[0] = '\0';
02205                     for( i = 0; p_item->ppsz_list[i]; i++ )
02206                     {
02207                         if( i ) strcat( psz_type, "," );
02208                         strcat( psz_type, p_item->ppsz_list[i] );
02209                     }
02210                     psz_ket = "}";
02211                 }
02212                 break;
02213             case CONFIG_ITEM_INTEGER:
02214             case CONFIG_ITEM_KEY: /* FIXME: do something a bit more clever */
02215                 psz_bra = " <"; psz_type = _("integer"); psz_ket = ">";
02216 
02217                 if( p_item->i_list )
02218                 {
02219                     psz_bra = " {";
02220                     psz_type = psz_buffer;
02221                     psz_type[0] = '\0';
02222                     for( i = 0; p_item->ppsz_list_text[i]; i++ )
02223                     {
02224                         if( i ) strcat( psz_type, ", " );
02225                         sprintf( psz_type + strlen(psz_type), "%i (%s)",
02226                                  p_item->pi_list[i],
02227                                  p_item->ppsz_list_text[i] );
02228                     }
02229                     psz_ket = "}";
02230                 }
02231                 break;
02232             case CONFIG_ITEM_FLOAT:
02233                 psz_bra = " <"; psz_type = _("float"); psz_ket = ">";
02234                 break;
02235             case CONFIG_ITEM_BOOL:
02236                 psz_bra = ""; psz_type = ""; psz_ket = "";
02237                 if( !b_help_module )
02238                 {
02239                     psz_suf = p_item->i_value ? _(" (default enabled)") :
02240                                                 _(" (default disabled)");
02241                 }
02242                 break;
02243             }
02244 
02245             if( !psz_type )
02246             {
02247                 continue;
02248             }
02249 
02250             /* Add short option if any */
02251             if( p_item->i_short )
02252             {
02253                 sprintf( psz_short, "-%c,", p_item->i_short );
02254             }
02255             else
02256             {
02257                 strcpy( psz_short, "   " );
02258             }
02259 
02260             i = PADDING_SPACES - strlen( p_item->psz_name )
02261                  - strlen( psz_bra ) - strlen( psz_type )
02262                  - strlen( psz_ket ) - 1;
02263 
02264             if( p_item->i_type == CONFIG_ITEM_BOOL && !b_help_module )
02265             {
02266                 psz_prefix =  ", --no-";
02267                 i -= strlen( p_item->psz_name ) + strlen( psz_prefix );
02268             }
02269 
02270             if( i < 0 )
02271             {
02272                 psz_spaces[0] = '\n';
02273                 i = 0;
02274             }
02275             else
02276             {
02277                 psz_spaces[i] = '\0';
02278             }
02279 
02280             if( p_item->i_type == CONFIG_ITEM_BOOL && !b_help_module )
02281             {
02282                 fprintf( stdout, psz_format, psz_short, p_item->psz_name,
02283                          psz_prefix, p_item->psz_name, psz_bra, psz_type,
02284                          psz_ket, psz_spaces );
02285             }
02286             else
02287             {
02288                 fprintf( stdout, psz_format, psz_short, p_item->psz_name,
02289                          "", "", psz_bra, psz_type, psz_ket, psz_spaces );
02290             }
02291 
02292             psz_spaces[i] = ' ';
02293 
02294             /* We wrap the rest of the output */
02295             sprintf( psz_buffer, "%s%s", p_item->psz_text, psz_suf );
02296             b_description = config_GetInt( p_this, "help-verbose" );
02297 
02298  description:
02299             psz_text = psz_buffer;
02300             while( *psz_text )
02301             {
02302                 char *psz_parser, *psz_word;
02303                 size_t i_end = strlen( psz_text );
02304 
02305                 /* If the remaining text fits in a line, print it. */
02306                 if( i_end <= (size_t)i_width )
02307                 {
02308                     fprintf( stdout, "%s\n", psz_text );
02309                     break;
02310                 }
02311 
02312                 /* Otherwise, eat as many words as possible */
02313                 psz_parser = psz_text;
02314                 do
02315                 {
02316                     psz_word = psz_parser;
02317                     psz_parser = strchr( psz_word, ' ' );
02318                     /* If no space was found, we reached the end of the text
02319                      * block; otherwise, we skip the space we just found. */
02320                     psz_parser = psz_parser ? psz_parser + 1
02321                                             : psz_text + i_end;
02322 
02323                 } while( psz_parser - psz_text <= i_width );
02324 
02325                 /* We cut a word in one of these cases:
02326                  *  - it's the only word in the line and it's too long.
02327                  *  - we used less than 80% of the width and the word we are
02328                  *    going to wrap is longer than 40% of the width, and even
02329                  *    if the word would have fit in the next line. */
02330                 if( psz_word == psz_text
02331                      || ( psz_word - psz_text < 80 * i_width / 100
02332                            && psz_parser - psz_word > 40 * i_width / 100 ) )
02333                 {
02334                     char c = psz_text[i_width];
02335                     psz_text[i_width] = '\0';
02336                     fprintf( stdout, "%s\n%s", psz_text, psz_spaces );
02337                     psz_text += i_width;
02338                     psz_text[0] = c;
02339                 }
02340                 else
02341                 {
02342                     psz_word[-1] = '\0';
02343                     fprintf( stdout, "%s\n%s", psz_text, psz_spaces );
02344                     psz_text = psz_word;
02345                 }
02346             }
02347 
02348             if( b_description && p_item->psz_longtext )
02349             {
02350                 sprintf( psz_buffer, "%s%s", p_item->psz_longtext, psz_suf );
02351                 b_description = VLC_FALSE;
02352                 psz_spaces = psz_spaces_longtext;
02353                 fprintf( stdout, "%s", psz_spaces );
02354                 goto description;
02355             }
02356         }
02357     }
02358 
02359     /* Release the module list */
02360     vlc_list_release( p_list );
02361 }
02362 
02363 /*****************************************************************************
02364  * ListModules: list the available modules with their description
02365  *****************************************************************************
02366  * Print a list of all available modules (builtins and plugins) and a short
02367  * description for each one.
02368  *****************************************************************************/
02369 static void ListModules( vlc_t *p_this )
02370 {
02371     vlc_list_t *p_list;
02372     module_t *p_parser;
02373     char psz_spaces[22];
02374     int i_index;
02375 
02376     memset( psz_spaces, ' ', 22 );
02377 
02378 #ifdef WIN32
02379     ShowConsole();
02380 #endif
02381 
02382     /* List all modules */
02383     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
02384 
02385     /* Enumerate each module */
02386     for( i_index = 0; i_index < p_list->i_count; i_index++ )
02387     {
02388         int i;
02389 
02390         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
02391 
02392         /* Nasty hack, but right now I'm too tired to think about a nice
02393          * solution */
02394         i = 22 - strlen( p_parser->psz_object_name ) - 1;
02395         if( i < 0 ) i = 0;
02396         psz_spaces[i] = 0;
02397 
02398         fprintf( stdout, "  %s%s %s\n", p_parser->psz_object_name,
02399                          psz_spaces, p_parser->psz_longname );
02400 
02401         psz_spaces[i] = ' ';
02402     }
02403 
02404     vlc_list_release( p_list );
02405 
02406 #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
02407     PauseConsole();
02408 #endif
02409 }
02410 
02411 /*****************************************************************************
02412  * Version: print complete program version
02413  *****************************************************************************
02414  * Print complete program version and build number.
02415  *****************************************************************************/
02416 static void Version( void )
02417 {
02418 #ifdef WIN32
02419     ShowConsole();
02420 #endif
02421 
02422     fprintf( stdout, _("VLC version %s\n"), VLC_Version() );
02423     fprintf( stdout, _("Compiled by %s@%s.%s\n"),
02424              VLC_CompileBy(), VLC_CompileHost(), VLC_CompileDomain() );
02425     fprintf( stdout, _("Compiler: %s\n"), VLC_Compiler() );
02426     if( strcmp( VLC_Changeset(), "exported" ) )
02427         fprintf( stdout, _("Based upon svn changeset [%s]\n"),
02428                  VLC_Changeset() );
02429     fprintf( stdout,
02430       _("This program comes with NO WARRANTY, to the extent permitted by "
02431         "law.\nYou may redistribute it under the terms of the GNU General "
02432         "Public License;\nsee the file named COPYING for details.\n"
02433         "Written by the VideoLAN team; see the AUTHORS file.\n") );
02434 
02435 #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
02436     PauseConsole();
02437 #endif
02438 }
02439 
02440 /*****************************************************************************
02441  * ShowConsole: On Win32, create an output console for debug messages
02442  *****************************************************************************
02443  * This function is useful only on Win32.
02444  *****************************************************************************/
02445 #ifdef WIN32 /*  */
02446 static void ShowConsole( void )
02447 {
02448 #   ifndef UNDER_CE
02449     FILE *f_help;
02450 
02451     if( getenv( "PWD" ) && getenv( "PS1" ) ) return; /* cygwin shell */
02452 
02453     AllocConsole();
02454 
02455     freopen( "CONOUT$", "w", stderr );
02456     freopen( "CONIN$", "r", stdin );
02457 
02458     if( (f_help = fopen( "vlc-help.txt", "wt" )) )
02459     {
02460         fclose( f_help );
02461         freopen( "vlc-help.txt", "wt", stdout );
02462         fprintf( stderr, _("\nDumped content to vlc-help.txt file.\n") );
02463     }
02464 
02465     else freopen( "CONOUT$", "w", stdout );
02466 
02467 #   endif
02468 }
02469 #endif
02470 
02471 /*****************************************************************************
02472  * PauseConsole: On Win32, wait for a key press before closing the console
02473  *****************************************************************************
02474  * This function is useful only on Win32.
02475  *****************************************************************************/
02476 #ifdef WIN32 /*  */
02477 static void PauseConsole( void )
02478 {
02479 #   ifndef UNDER_CE
02480 
02481     if( getenv( "PWD" ) && getenv( "PS1" ) ) return; /* cygwin shell */
02482 
02483     fprintf( stderr, _("\nPress the RETURN key to continue...\n") );
02484     getchar();
02485     fclose( stdout );
02486 
02487 #   endif
02488 }
02489 #endif
02490 
02491 /*****************************************************************************
02492  * ConsoleWidth: Return the console width in characters
02493  *****************************************************************************
02494  * We use the stty shell command to get the console width; if this fails or
02495  * if the width is less than 80, we default to 80.
02496  *****************************************************************************/
02497 static int ConsoleWidth( void )
02498 {
02499     int i_width = 80;
02500 
02501 #ifndef WIN32
02502     char buf[20], *psz_parser;
02503     FILE *file;
02504     int i_ret;
02505 
02506     file = popen( "stty size 2>/dev/null", "r" );
02507     if( file )
02508     {
02509         i_ret = fread( buf, 1, 20, file );
02510         if( i_ret > 0 )
02511         {
02512             buf[19] = '\0';
02513             psz_parser = strchr( buf, ' ' );
02514             if( psz_parser )
02515             {
02516                 i_ret = atoi( psz_parser + 1 );
02517                 if( i_ret >= 80 )
02518                 {
02519                     i_width = i_ret;
02520                 }
02521             }
02522         }
02523 
02524         pclose( file );
02525     }
02526 #endif
02527 
02528     return i_width;
02529 }
02530 
02531 static int VerboseCallback( vlc_object_t *p_this, const char *psz_variable,
02532                      vlc_value_t old_val, vlc_value_t new_val, void *param)
02533 {
02534     vlc_t *p_vlc = (vlc_t *)p_this;
02535 
02536     if( new_val.i_int >= -1 )
02537     {
02538         p_vlc->p_libvlc->i_verbose = __MIN( new_val.i_int, 2 );
02539     }
02540     return VLC_SUCCESS;
02541 }
02542 
02543 /*****************************************************************************
02544  * InitDeviceValues: initialize device values
02545  *****************************************************************************
02546  * This function inits the dvd, vcd and cd-audio values
02547  *****************************************************************************/
02548 static void InitDeviceValues( vlc_t *p_vlc )
02549 {
02550 #ifdef HAVE_HAL
02551     LibHalContext * ctx;
02552     int i, i_devices;
02553     char **devices;
02554     char *block_dev;
02555     dbus_bool_t b_dvd;
02556     DBusConnection *p_connection;
02557     DBusError       error;
02558 
02559 #ifdef HAVE_HAL_1
02560     ctx =  libhal_ctx_new();
02561     if( !ctx ) return;
02562     dbus_error_init( &error );
02563     p_connection = dbus_bus_get ( DBUS_BUS_SYSTEM, &error );
02564     if( dbus_error_is_set( &error ) )
02565     {
02566         dbus_error_free( &error );
02567         return;
02568     }
02569     libhal_ctx_set_dbus_connection( ctx, p_connection );
02570     if( libhal_ctx_init( ctx, &error ) )
02571 #else
02572     if( ( ctx = hal_initialize( NULL, FALSE ) ) )
02573 #endif
02574     {
02575 #ifdef HAVE_HAL_1
02576         if( ( devices = libhal_get_all_devices( ctx, &i_devices, NULL ) ) )
02577 #else
02578         if( ( devices = hal_get_all_devices( ctx, &i_devices ) ) )
02579 #endif
02580         {
02581             for( i = 0; i < i_devices; i++ )
02582             {
02583 #ifdef HAVE_HAL_1
02584                 if( !libhal_device_property_exists( ctx, devices[i],
02585                                                 "storage.cdrom.dvd", NULL ) )
02586 #else
02587                 if( !hal_device_property_exists( ctx, devices[ i ],
02588                                                 "storage.cdrom.dvd" ) )
02589 #endif
02590                 {
02591                     continue;
02592                 }
02593 #ifdef HAVE_HAL_1
02594                 b_dvd = libhal_device_get_property_bool( ctx, devices[ i ],
02595                                                  "storage.cdrom.dvd", NULL  );
02596                 block_dev = libhal_device_get_property_string( ctx,
02597                                 devices[ i ], "block.device" , NULL );
02598 #else
02599                 b_dvd = hal_device_get_property_bool( ctx, devices[ i ],
02600                                                       "storage.cdrom.dvd" );
02601                 block_dev = hal_device_get_property_string( ctx, devices[ i ],
02602                                                             "block.device" );
02603 #endif
02604                 if( b_dvd )
02605                 {
02606                     config_PutPsz( p_vlc, "dvd", block_dev );
02607                 }
02608 
02609                 config_PutPsz( p_vlc, "vcd", block_dev );
02610                 config_PutPsz( p_vlc, "cd-audio", block_dev );
02611 #ifdef HAVE_HAL_1
02612                 libhal_free_string( block_dev );
02613 #else
02614                 hal_free_string( block_dev );
02615 #endif
02616             }
02617 #ifdef HAVE_HAL_1
02618             libhal_free_string_array( devices );
02619 #else
02620             hal_free_string_array( devices );
02621 #endif
02622         }
02623 
02624 #ifdef HAVE_HAL_1
02625         libhal_ctx_shutdown( ctx, NULL );
02626 #else
02627         hal_shutdown( ctx );
02628 #endif
02629     }
02630     else
02631     {
02632         msg_Warn( p_vlc, "Unable to get HAL device properties" );
02633     }
02634 #endif
02635 }
02636 
02637 /*****************************************************************************
02638  * FromLocale: converts a locale string to UTF-8
02639  *****************************************************************************/
02640 char *FromLocale( const char *locale )
02641 {
02642     if( locale == NULL )
02643         return NULL;
02644 
02645     if( libvlc.from_locale != (vlc_iconv_t)(-1) )
02646     {
02647         char *iptr = (char *)locale, *output, *optr;
02648         size_t inb, outb;
02649 
02650         /*
02651          * We are not allowed to modify the locale pointer, even if we cast it
02652          * to non-const.
02653          */
02654         inb = strlen( locale );
02655         outb = inb * 6 + 1;
02656 
02657         /* FIXME: I'm not sure about the value for the multiplication
02658          * (for western people, multiplication by 3 (Latin9) is sufficient) */
02659         optr = output = calloc( outb , 1);
02660 
02661         vlc_mutex_lock( &libvlc.from_locale_lock );
02662         vlc_iconv( libvlc.from_locale, NULL, NULL, NULL, NULL );
02663 
02664         while( vlc_iconv( libvlc.from_locale, &iptr, &inb, &optr, &outb )
02665                                                                == (size_t)-1 )
02666         {
02667             *optr = '?';
02668             optr++;
02669             iptr++;
02670             vlc_iconv( libvlc.from_locale, NULL, NULL, NULL, NULL );
02671         }
02672         vlc_mutex_unlock( &libvlc.from_locale_lock );
02673 
02674         return realloc( output, strlen( output ) + 1 );
02675     }
02676     return (char *)locale;
02677 }
02678 
02679 /*****************************************************************************
02680  * ToLocale: converts an UTF-8 string to locale
02681  *****************************************************************************/
02682 char *ToLocale( const char *utf8 )
02683 {
02684     if( utf8 == NULL )
02685         return NULL;
02686 
02687     if( libvlc.to_locale != (vlc_iconv_t)(-1) )
02688     {
02689         char *iptr = (char *)utf8, *output, *optr;
02690         size_t inb, outb;
02691 
02692         /*
02693          * We are not allowed to modify the locale pointer, even if we cast it
02694          * to non-const.
02695          */
02696         inb = strlen( utf8 );
02697         /* FIXME: I'm not sure about the value for the multiplication
02698          * (for western people, multiplication is not needed) */
02699         outb = inb * 2 + 1;
02700 
02701         optr = output = calloc( outb, 1 );
02702         vlc_mutex_lock( &libvlc.to_locale_lock );
02703         vlc_iconv( libvlc.to_locale, NULL, NULL, NULL, NULL );
02704 
02705         while( vlc_iconv( libvlc.to_locale, &iptr, &inb, &optr, &outb )
02706                                                                == (size_t)-1 )
02707         {
02708             *optr = '?'; /* should not happen, and yes, it sucks */
02709             optr++;
02710             iptr++;
02711             vlc_iconv( libvlc.to_locale, NULL, NULL, NULL, NULL );
02712         }
02713         vlc_mutex_unlock( &libvlc.to_locale_lock );
02714 
02715         return realloc( output, strlen( output ) + 1 );
02716     }
02717     return (char *)utf8;
02718 }
02719 
02720 void LocaleFree( const char *str )
02721 {
02722     if( ( str != NULL ) && ( libvlc.to_locale != (vlc_iconv_t)(-1) ) )
02723         free( (char *)str );
02724 }

Generated on Tue Dec 20 10:15:00 2005 for vlc-0.8.4a by  doxygen 1.4.2