libvlc.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:66k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * libvlc.c: main libvlc source
  3.  *****************************************************************************
  4.  * Copyright (C) 1998-2004 VideoLAN
  5.  * $Id: libvlc.c 9056 2004-10-24 21:07:58Z gbazin $
  6.  *
  7.  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  8.  *          Samuel Hocevar <sam@zoy.org>
  9.  *          Gildas Bazin <gbazin@videolan.org>
  10.  *          Derk-Jan Hartman <hartman at videolan dot org>
  11.  *
  12.  * This program is free software; you can redistribute it and/or modify
  13.  * it under the terms of the GNU General Public License as published by
  14.  * the Free Software Foundation; either version 2 of the License, or
  15.  * (at your option) any later version.
  16.  *
  17.  * This program is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  * GNU General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU General Public License
  23.  * along with this program; if not, write to the Free Software
  24.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  25.  *****************************************************************************/
  26. /*****************************************************************************
  27.  * Pretend we are a builtin module
  28.  *****************************************************************************/
  29. #define MODULE_NAME main
  30. #define MODULE_PATH main
  31. #define __BUILTIN__
  32. /*****************************************************************************
  33.  * Preamble
  34.  *****************************************************************************/
  35. #include <vlc/vlc.h>
  36. #include <vlc/input.h>
  37. #include <errno.h>                                                 /* ENOMEM */
  38. #include <stdio.h>                                              /* sprintf() */
  39. #include <string.h>                                            /* strerror() */
  40. #include <stdlib.h>                                                /* free() */
  41. #ifndef WIN32
  42. #   include <netinet/in.h>                            /* BSD: struct in_addr */
  43. #endif
  44. #ifdef HAVE_UNISTD_H
  45. #   include <unistd.h>
  46. #elif defined( WIN32 ) && !defined( UNDER_CE )
  47. #   include <io.h>
  48. #endif
  49. #ifdef WIN32                       /* optind, getopt(), included in unistd.h */
  50. #   include "extras/getopt.h"
  51. #endif
  52. #ifdef HAVE_LOCALE_H
  53. #   include <locale.h>
  54. #endif
  55. #ifdef HAVE_HAL
  56. #   include <hal/libhal.h>
  57. #endif
  58. #include "vlc_cpu.h"                                        /* CPU detection */
  59. #include "os_specific.h"
  60. #include "vlc_error.h"
  61. #include "vlc_playlist.h"
  62. #include "vlc_interface.h"
  63. #include "audio_output.h"
  64. #include "vlc_video.h"
  65. #include "video_output.h"
  66. #include "stream_output.h"
  67. #include "libvlc.h"
  68. /*****************************************************************************
  69.  * The evil global variable. We handle it with care, don't worry.
  70.  *****************************************************************************/
  71. static libvlc_t   libvlc;
  72. static libvlc_t * p_libvlc;
  73. static vlc_t *    p_static_vlc;
  74. /*****************************************************************************
  75.  * Local prototypes
  76.  *****************************************************************************/
  77. static void SetLanguage   ( char const * );
  78. static int  GetFilenames  ( vlc_t *, int, char *[] );
  79. static void Usage         ( vlc_t *, char const *psz_module_name );
  80. static void ListModules   ( vlc_t * );
  81. static void Version       ( void );
  82. #ifdef WIN32
  83. static void ShowConsole   ( void );
  84. static void PauseConsole  ( void );
  85. #endif
  86. static int  ConsoleWidth  ( void );
  87. static int  VerboseCallback( vlc_object_t *, char const *,
  88.                              vlc_value_t, vlc_value_t, void * );
  89. static void InitDeviceValues( vlc_t * );
  90. /*****************************************************************************
  91.  * vlc_current_object: return the current object.
  92.  *****************************************************************************
  93.  * If i_object is non-zero, return the corresponding object. Otherwise,
  94.  * return the statically allocated p_vlc object.
  95.  *****************************************************************************/
  96. vlc_t * vlc_current_object( int i_object )
  97. {
  98.     if( i_object )
  99.     {
  100.          return vlc_object_get( p_libvlc, i_object );
  101.     }
  102.     return p_static_vlc;
  103. }
  104. /*****************************************************************************
  105.  * VLC_Version: return the libvlc version.
  106.  *****************************************************************************
  107.  * This function returns full version string (numeric version and codename).
  108.  *****************************************************************************/
  109. char const * VLC_Version( void )
  110. {
  111.     return VERSION_MESSAGE;
  112. }
  113. /*****************************************************************************
  114.  * VLC_Error: strerror() equivalent
  115.  *****************************************************************************
  116.  * This function returns full version string (numeric version and codename).
  117.  *****************************************************************************/
  118. char const * VLC_Error( int i_err )
  119. {
  120.     return vlc_error( i_err );
  121. }
  122. /*****************************************************************************
  123.  * VLC_Create: allocate a vlc_t structure, and initialize libvlc if needed.
  124.  *****************************************************************************
  125.  * This function allocates a vlc_t structure and returns a negative value
  126.  * in case of failure. Also, the thread system is initialized.
  127.  *****************************************************************************/
  128. int VLC_Create( void )
  129. {
  130.     int i_ret;
  131.     vlc_t * p_vlc = NULL;
  132.     vlc_value_t lockval;
  133.     /* &libvlc never changes, so we can safely call this multiple times. */
  134.     p_libvlc = &libvlc;
  135.     /* vlc_threads_init *must* be the first internal call! No other call is
  136.      * allowed before the thread system has been initialized. */
  137.     i_ret = vlc_threads_init( p_libvlc );
  138.     if( i_ret < 0 )
  139.     {
  140.         return i_ret;
  141.     }
  142.     /* Now that the thread system is initialized, we don't have much, but
  143.      * at least we have var_Create */
  144.     var_Create( p_libvlc, "libvlc", VLC_VAR_MUTEX );
  145.     var_Get( p_libvlc, "libvlc", &lockval );
  146.     vlc_mutex_lock( lockval.p_address );
  147.     if( !libvlc.b_ready )
  148.     {
  149.         char *psz_env;
  150.         /* Guess what CPU we have */
  151.         libvlc.i_cpu = CPUCapabilities();
  152.         /* Find verbosity from VLC_VERBOSE environment variable */
  153.         psz_env = getenv( "VLC_VERBOSE" );
  154.         libvlc.i_verbose = psz_env ? atoi( psz_env ) : -1;
  155. #if defined( HAVE_ISATTY ) && !defined( WIN32 )
  156.         libvlc.b_color = isatty( 2 ); /* 2 is for stderr */
  157. #else
  158.         libvlc.b_color = VLC_FALSE;
  159. #endif
  160.         /* Initialize message queue */
  161.         msg_Create( p_libvlc );
  162.         /* Announce who we are */
  163.         msg_Dbg( p_libvlc, COPYRIGHT_MESSAGE );
  164.         msg_Dbg( p_libvlc, "libvlc was configured with %s", CONFIGURE_LINE );
  165.         /* The module bank will be initialized later */
  166.         libvlc.p_module_bank = NULL;
  167.         libvlc.b_ready = VLC_TRUE;
  168.     }
  169.     vlc_mutex_unlock( lockval.p_address );
  170.     var_Destroy( p_libvlc, "libvlc" );
  171.     /* Allocate a vlc object */
  172.     p_vlc = vlc_object_create( p_libvlc, VLC_OBJECT_VLC );
  173.     if( p_vlc == NULL )
  174.     {
  175.         return VLC_EGENERIC;
  176.     }
  177.     p_vlc->thread_id = 0;
  178.     p_vlc->psz_object_name = "root";
  179.     /* Initialize mutexes */
  180.     vlc_mutex_init( p_vlc, &p_vlc->config_lock );
  181. #ifdef SYS_DARWIN
  182.     vlc_mutex_init( p_vlc, &p_vlc->quicktime_lock );
  183.     vlc_thread_set_priority( p_vlc, VLC_THREAD_PRIORITY_LOW );
  184. #endif
  185.     /* Store our newly allocated structure in the global list */
  186.     vlc_object_attach( p_vlc, p_libvlc );
  187.     /* Store data for the non-reentrant API */
  188.     p_static_vlc = p_vlc;
  189.     return p_vlc->i_object_id;
  190. }
  191. /*****************************************************************************
  192.  * VLC_Init: initialize a vlc_t structure.
  193.  *****************************************************************************
  194.  * This function initializes a previously allocated vlc_t structure:
  195.  *  - CPU detection
  196.  *  - gettext initialization
  197.  *  - message queue, module bank and playlist initialization
  198.  *  - configuration and commandline parsing
  199.  *****************************************************************************/
  200. int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
  201. {
  202.     char         p_capabilities[200];
  203.     char *       p_tmp;
  204.     char *       psz_modules;
  205.     char *       psz_parser;
  206.     char *       psz_language;
  207.     vlc_bool_t   b_exit = VLC_FALSE;
  208.     vlc_t *      p_vlc = vlc_current_object( i_object );
  209.     module_t    *p_help_module;
  210.     playlist_t  *p_playlist;
  211.     if( !p_vlc )
  212.     {
  213.         return VLC_ENOOBJ;
  214.     }
  215.     /*
  216.      * System specific initialization code
  217.      */
  218.     system_Init( p_vlc, &i_argc, ppsz_argv );
  219.     /* Get the executable name (similar to the basename command) */
  220.     if( i_argc > 0 )
  221.     {
  222.         p_vlc->psz_object_name = p_tmp = ppsz_argv[ 0 ];
  223.         while( *p_tmp )
  224.         {
  225.             if( *p_tmp == '/' ) p_vlc->psz_object_name = ++p_tmp;
  226.             else ++p_tmp;
  227.         }
  228.     }
  229.     else
  230.     {
  231.         p_vlc->psz_object_name = "vlc";
  232.     }
  233.     /*
  234.      * Support for gettext
  235.      */
  236.     SetLanguage( "" );
  237.     /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
  238.     msg_Dbg( p_vlc, "translation test: code is "%s"", _("C") );
  239.     /* Initialize the module bank and load the configuration of the
  240.      * main module. We need to do this at this stage to be able to display
  241.      * a short help if required by the user. (short help == main module
  242.      * options) */
  243.     module_InitBank( p_vlc );
  244.     /* Hack: insert the help module here */
  245.     p_help_module = vlc_object_create( p_vlc, VLC_OBJECT_MODULE );
  246.     if( p_help_module == NULL )
  247.     {
  248.         module_EndBank( p_vlc );
  249.         if( i_object ) vlc_object_release( p_vlc );
  250.         return VLC_EGENERIC;
  251.     }
  252.     p_help_module->psz_object_name = "help";
  253.     p_help_module->psz_longname = N_("Help options");
  254.     config_Duplicate( p_help_module, p_help_config );
  255.     vlc_object_attach( p_help_module, libvlc.p_module_bank );
  256.     /* End hack */
  257.     if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
  258.     {
  259.         vlc_object_detach( p_help_module );
  260.         config_Free( p_help_module );
  261.         vlc_object_destroy( p_help_module );
  262.         module_EndBank( p_vlc );
  263.         if( i_object ) vlc_object_release( p_vlc );
  264.         return VLC_EGENERIC;
  265.     }
  266.     /* Check for short help option */
  267.     if( config_GetInt( p_vlc, "help" ) )
  268.     {
  269.         fprintf( stdout, _("Usage: %s [options] [items]...n"),
  270.                          p_vlc->psz_object_name );
  271.         Usage( p_vlc, "main" );
  272.         Usage( p_vlc, "help" );
  273.         b_exit = VLC_TRUE;
  274.     }
  275.     /* Check for version option */
  276.     else if( config_GetInt( p_vlc, "version" ) )
  277.     {
  278.         Version();
  279.         b_exit = VLC_TRUE;
  280.     }
  281.     /* Set the config file stuff */
  282.     p_vlc->psz_homedir = config_GetHomeDir();
  283.     p_vlc->psz_configfile = config_GetPsz( p_vlc, "config" );
  284.     /* Check for plugins cache options */
  285.     if( config_GetInt( p_vlc, "reset-plugins-cache" ) )
  286.     {
  287.         libvlc.p_module_bank->b_cache_delete = VLC_TRUE;
  288.     }
  289.     /* Hack: remove the help module here */
  290.     vlc_object_detach( p_help_module );
  291.     /* End hack */
  292.     /* Will be re-done properly later on */
  293.     p_vlc->p_libvlc->i_verbose = config_GetInt( p_vlc, "verbose" );
  294.     /* Check for daemon mode */
  295. #ifndef WIN32
  296.     if( config_GetInt( p_vlc, "daemon" ) )
  297.     {
  298. #if HAVE_DAEMON
  299.         if( daemon( 0, 0) != 0 )
  300.         {
  301.             msg_Err( p_vlc, "Unable to fork vlc to daemon mode" );
  302.             b_exit = VLC_TRUE;
  303.         }
  304.         p_vlc->p_libvlc->b_daemon = VLC_TRUE;
  305. #else
  306.         pid_t i_pid;
  307.         if( ( i_pid = fork() ) < 0 )
  308.         {
  309.             msg_Err( p_vlc, "Unable to fork vlc to daemon mode" );
  310.             b_exit = VLC_TRUE;
  311.         }
  312.         else if( i_pid )
  313.         {
  314.             /* This is the parent, exit right now */
  315.             msg_Dbg( p_vlc, "closing parent process" );
  316.             b_exit = VLC_TRUE;
  317.         }
  318.         else
  319.         {
  320.             /* We are the child */
  321.             msg_Dbg( p_vlc, "daemon spawned" );
  322.             close( STDIN_FILENO );
  323.             close( STDOUT_FILENO );
  324.             close( STDERR_FILENO );
  325.             p_vlc->p_libvlc->b_daemon = VLC_TRUE;
  326.         }
  327. #endif
  328.     }
  329. #endif
  330.     if( b_exit )
  331.     {
  332.         config_Free( p_help_module );
  333.         vlc_object_destroy( p_help_module );
  334.         module_EndBank( p_vlc );
  335.         if( i_object ) vlc_object_release( p_vlc );
  336.         return VLC_EEXIT;
  337.     }
  338.     /* Check for translation config option */
  339. #if defined( ENABLE_NLS ) 
  340.      && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
  341.     /* This ain't really nice to have to reload the config here but it seems
  342.      * the only way to do it. */
  343.     config_LoadConfigFile( p_vlc, "main" );
  344.     config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
  345.     /* Check if the user specified a custom language */
  346.     psz_language = config_GetPsz( p_vlc, "language" );
  347.     if( psz_language && *psz_language && strcmp( psz_language, "auto" ) )
  348.     {
  349.         vlc_bool_t b_cache_delete = libvlc.p_module_bank->b_cache_delete;
  350.         /* Reset the default domain */
  351.         SetLanguage( psz_language );
  352.         /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
  353.         msg_Dbg( p_vlc, "translation test: code is "%s"", _("C") );
  354.         textdomain( PACKAGE_NAME );
  355. #if defined( ENABLE_UTF8 )
  356.         bind_textdomain_codeset( PACKAGE_NAME, "UTF-8" );
  357. #endif
  358.         module_EndBank( p_vlc );
  359.         module_InitBank( p_vlc );
  360.         config_LoadConfigFile( p_vlc, "main" );
  361.         config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
  362.         libvlc.p_module_bank->b_cache_delete = b_cache_delete;
  363.     }
  364.     if( psz_language ) free( psz_language );
  365. #endif
  366.     /*
  367.      * Load the builtins and plugins into the module_bank.
  368.      * We have to do it before config_Load*() because this also gets the
  369.      * list of configuration options exported by each module and loads their
  370.      * default values.
  371.      */
  372.     module_LoadBuiltins( p_vlc );
  373.     module_LoadPlugins( p_vlc );
  374.     if( p_vlc->b_die )
  375.     {
  376.         b_exit = VLC_TRUE;
  377.     }
  378.     msg_Dbg( p_vlc, "module bank initialized, found %i modules",
  379.                     libvlc.p_module_bank->i_children );
  380.     /* Hack: insert the help module here */
  381.     vlc_object_attach( p_help_module, libvlc.p_module_bank );
  382.     /* End hack */
  383.     /* Check for help on modules */
  384.     if( (p_tmp = config_GetPsz( p_vlc, "module" )) )
  385.     {
  386.         Usage( p_vlc, p_tmp );
  387.         free( p_tmp );
  388.         b_exit = VLC_TRUE;
  389.     }
  390.     /* Check for long help option */
  391.     else if( config_GetInt( p_vlc, "longhelp" ) )
  392.     {
  393.         Usage( p_vlc, NULL );
  394.         b_exit = VLC_TRUE;
  395.     }
  396.     /* Check for module list option */
  397.     else if( config_GetInt( p_vlc, "list" ) )
  398.     {
  399.         ListModules( p_vlc );
  400.         b_exit = VLC_TRUE;
  401.     }
  402.     /* Check for config file options */
  403.     if( config_GetInt( p_vlc, "reset-config" ) )
  404.     {
  405.         vlc_object_detach( p_help_module );
  406.         config_ResetAll( p_vlc );
  407.         config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
  408.         config_SaveConfigFile( p_vlc, NULL );
  409.         vlc_object_attach( p_help_module, libvlc.p_module_bank );
  410.     }
  411.     if( config_GetInt( p_vlc, "save-config" ) )
  412.     {
  413.         vlc_object_detach( p_help_module );
  414.         config_LoadConfigFile( p_vlc, NULL );
  415.         config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
  416.         config_SaveConfigFile( p_vlc, NULL );
  417.         vlc_object_attach( p_help_module, libvlc.p_module_bank );
  418.     }
  419.     /* Hack: remove the help module here */
  420.     vlc_object_detach( p_help_module );
  421.     /* End hack */
  422.     if( b_exit )
  423.     {
  424.         config_Free( p_help_module );
  425.         vlc_object_destroy( p_help_module );
  426.         module_EndBank( p_vlc );
  427.         if( i_object ) vlc_object_release( p_vlc );
  428.         return VLC_EEXIT;
  429.     }
  430.     /*
  431.      * Init device values
  432.      */
  433.     InitDeviceValues( p_vlc );
  434.     /*
  435.      * Override default configuration with config file settings
  436.      */
  437.     config_LoadConfigFile( p_vlc, NULL );
  438.     /* Hack: insert the help module here */
  439.     vlc_object_attach( p_help_module, libvlc.p_module_bank );
  440.     /* End hack */
  441.     /*
  442.      * Override configuration with command line settings
  443.      */
  444.     if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
  445.     {
  446. #ifdef WIN32
  447.         ShowConsole();
  448.         /* Pause the console because it's destroyed when we exit */
  449.         fprintf( stderr, "The command line options couldn't be loaded, check "
  450.                  "that they are valid.n" );
  451.         PauseConsole();
  452. #endif
  453.         vlc_object_detach( p_help_module );
  454.         config_Free( p_help_module );
  455.         vlc_object_destroy( p_help_module );
  456.         module_EndBank( p_vlc );
  457.         if( i_object ) vlc_object_release( p_vlc );
  458.         return VLC_EGENERIC;
  459.     }
  460.     /* Hack: remove the help module here */
  461.     vlc_object_detach( p_help_module );
  462.     config_Free( p_help_module );
  463.     vlc_object_destroy( p_help_module );
  464.     /* End hack */
  465.     /*
  466.      * System specific configuration
  467.      */
  468.     system_Configure( p_vlc, &i_argc, ppsz_argv );
  469.     /*
  470.      * Message queue options
  471.      */
  472.     var_Create( p_vlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
  473.     if( config_GetInt( p_vlc, "quiet" ) )
  474.     {
  475.         vlc_value_t val;
  476.         val.i_int = -1;
  477.         var_Set( p_vlc, "verbose", val );
  478.     }
  479.     var_AddCallback( p_vlc, "verbose", VerboseCallback, NULL );
  480.     var_Change( p_vlc, "verbose", VLC_VAR_TRIGGER_CALLBACKS, NULL, NULL );
  481.     libvlc.b_color = libvlc.b_color && config_GetInt( p_vlc, "color" );
  482.     /*
  483.      * Output messages that may still be in the queue
  484.      */
  485.     msg_Flush( p_vlc );
  486.     /* p_vlc initialization. FIXME ? */
  487. #if defined( __i386__ )
  488.     if( !config_GetInt( p_vlc, "mmx" ) )
  489.         libvlc.i_cpu &= ~CPU_CAPABILITY_MMX;
  490.     if( !config_GetInt( p_vlc, "3dn" ) )
  491.         libvlc.i_cpu &= ~CPU_CAPABILITY_3DNOW;
  492.     if( !config_GetInt( p_vlc, "mmxext" ) )
  493.         libvlc.i_cpu &= ~CPU_CAPABILITY_MMXEXT;
  494.     if( !config_GetInt( p_vlc, "sse" ) )
  495.         libvlc.i_cpu &= ~CPU_CAPABILITY_SSE;
  496.     if( !config_GetInt( p_vlc, "sse2" ) )
  497.         libvlc.i_cpu &= ~CPU_CAPABILITY_SSE2;
  498. #endif
  499. #if defined( __powerpc__ ) || defined( SYS_DARWIN )
  500.     if( !config_GetInt( p_vlc, "altivec" ) )
  501.         libvlc.i_cpu &= ~CPU_CAPABILITY_ALTIVEC;
  502. #endif
  503. #define PRINT_CAPABILITY( capability, string )                              
  504.     if( libvlc.i_cpu & capability )                                         
  505.     {                                                                       
  506.         strncat( p_capabilities, string " ",                                
  507.                  sizeof(p_capabilities) - strlen(p_capabilities) );         
  508.         p_capabilities[sizeof(p_capabilities) - 1] = '';                  
  509.     }
  510.     p_capabilities[0] = '';
  511.     PRINT_CAPABILITY( CPU_CAPABILITY_486, "486" );
  512.     PRINT_CAPABILITY( CPU_CAPABILITY_586, "586" );
  513.     PRINT_CAPABILITY( CPU_CAPABILITY_PPRO, "Pentium Pro" );
  514.     PRINT_CAPABILITY( CPU_CAPABILITY_MMX, "MMX" );
  515.     PRINT_CAPABILITY( CPU_CAPABILITY_3DNOW, "3DNow!" );
  516.     PRINT_CAPABILITY( CPU_CAPABILITY_MMXEXT, "MMXEXT" );
  517.     PRINT_CAPABILITY( CPU_CAPABILITY_SSE, "SSE" );
  518.     PRINT_CAPABILITY( CPU_CAPABILITY_SSE2, "SSE2" );
  519.     PRINT_CAPABILITY( CPU_CAPABILITY_ALTIVEC, "AltiVec" );
  520.     PRINT_CAPABILITY( CPU_CAPABILITY_FPU, "FPU" );
  521.     msg_Dbg( p_vlc, "CPU has capabilities %s", p_capabilities );
  522.     /*
  523.      * Choose the best memcpy module
  524.      */
  525.     p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy", 0 );
  526.     if( p_vlc->pf_memcpy == NULL )
  527.     {
  528.         p_vlc->pf_memcpy = memcpy;
  529.     }
  530.     if( p_vlc->pf_memset == NULL )
  531.     {
  532.         p_vlc->pf_memset = memset;
  533.     }
  534.     /*
  535.      * Initialize hotkey handling
  536.      */
  537.     var_Create( p_vlc, "key-pressed", VLC_VAR_INTEGER );
  538.     p_vlc->p_hotkeys = malloc( sizeof(p_hotkeys) );
  539.     /* Do a copy (we don't need to modify the strings) */
  540.     memcpy( p_vlc->p_hotkeys, p_hotkeys, sizeof(p_hotkeys) );
  541.     /*
  542.      * Initialize playlist and get commandline files
  543.      */
  544.     p_playlist = playlist_Create( p_vlc );
  545.     if( !p_playlist )
  546.     {
  547.         msg_Err( p_vlc, "playlist initialization failed" );
  548.         if( p_vlc->p_memcpy_module != NULL )
  549.         {
  550.             module_Unneed( p_vlc, p_vlc->p_memcpy_module );
  551.         }
  552.         module_EndBank( p_vlc );
  553.         if( i_object ) vlc_object_release( p_vlc );
  554.         return VLC_EGENERIC;
  555.     }
  556.     /*
  557.      * Load background interfaces
  558.      */
  559.     psz_modules = config_GetPsz( p_vlc, "extraintf" );
  560.     psz_parser = psz_modules;
  561.     while ( psz_parser && *psz_parser )
  562.     {
  563.         char *psz_module, *psz_temp;
  564.         psz_module = psz_parser;
  565.         psz_parser = strchr( psz_module, ',' );
  566.         if ( psz_parser )
  567.         {
  568.             *psz_parser = '';
  569.             psz_parser++;
  570.         }
  571.         psz_temp = (char *)malloc( strlen(psz_module) + sizeof(",none") );
  572.         if( psz_temp )
  573.         {
  574.             sprintf( psz_temp, "%s,none", psz_module );
  575.             VLC_AddIntf( 0, psz_temp, VLC_FALSE, VLC_FALSE );
  576.             free( psz_temp );
  577.         }
  578.     }
  579.     if ( psz_modules )
  580.     {
  581.         free( psz_modules );
  582.     }
  583.     /*
  584.      * Allways load the hotkeys interface if it exists
  585.      */
  586.     VLC_AddIntf( 0, "hotkeys,none", VLC_FALSE, VLC_FALSE );
  587.     /*
  588.      * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin
  589.      */
  590.     var_Create( p_vlc, "drawable", VLC_VAR_INTEGER );
  591.     var_Create( p_vlc, "drawableredraw", VLC_VAR_INTEGER );
  592.     var_Create( p_vlc, "drawablet", VLC_VAR_INTEGER );
  593.     var_Create( p_vlc, "drawablel", VLC_VAR_INTEGER );
  594.     var_Create( p_vlc, "drawableb", VLC_VAR_INTEGER );
  595.     var_Create( p_vlc, "drawabler", VLC_VAR_INTEGER );
  596.     var_Create( p_vlc, "drawablex", VLC_VAR_INTEGER );
  597.     var_Create( p_vlc, "drawabley", VLC_VAR_INTEGER );
  598.     var_Create( p_vlc, "drawablew", VLC_VAR_INTEGER );
  599.     var_Create( p_vlc, "drawableh", VLC_VAR_INTEGER );
  600.     var_Create( p_vlc, "drawableportx", VLC_VAR_INTEGER );
  601.     var_Create( p_vlc, "drawableporty", VLC_VAR_INTEGER );
  602.     /*
  603.      * Get input filenames given as commandline arguments
  604.      */
  605.     GetFilenames( p_vlc, i_argc, ppsz_argv );
  606.     if( i_object ) vlc_object_release( p_vlc );
  607.     return VLC_SUCCESS;
  608. }
  609. /*****************************************************************************
  610.  * VLC_AddIntf: add an interface
  611.  *****************************************************************************
  612.  * This function opens an interface plugin and runs it. If b_block is set
  613.  * to 0, VLC_AddIntf will return immediately and let the interface run in a
  614.  * separate thread. If b_block is set to 1, VLC_AddIntf will continue until
  615.  * user requests to quit. If b_play is set to 1, VLC_AddIntf will start playing
  616.  * the playlist when it is completely initialised.
  617.  *****************************************************************************/
  618. int VLC_AddIntf( int i_object, char const *psz_module,
  619.                  vlc_bool_t b_block, vlc_bool_t b_play )
  620. {
  621.     int i_err;
  622.     intf_thread_t *p_intf;
  623.     vlc_t *p_vlc = vlc_current_object( i_object );
  624.     if( !p_vlc )
  625.     {
  626.         return VLC_ENOOBJ;
  627.     }
  628. #ifndef WIN32
  629.     if( p_vlc->p_libvlc->b_daemon && b_block && !psz_module )
  630.     {
  631.         /* Daemon mode hack.
  632.          * We prefer the dummy interface if none is specified. */
  633.         char *psz_interface = config_GetPsz( p_vlc, "intf" );
  634.         if( !psz_interface || !*psz_interface ) psz_module = "dummy";
  635.         if( psz_interface ) free( psz_interface );
  636.     }
  637. #endif
  638.     /* Try to create the interface */
  639.     p_intf = intf_Create( p_vlc, psz_module ? psz_module : "$intf" );
  640.     if( p_intf == NULL )
  641.     {
  642.         msg_Err( p_vlc, "interface "%s" initialization failed", psz_module );
  643.         if( i_object ) vlc_object_release( p_vlc );
  644.         return VLC_EGENERIC;
  645.     }
  646.     /* Interface doesn't handle play on start so do it ourselves */
  647.     if( !p_intf->b_play && b_play ) VLC_Play( i_object );
  648.     /* Try to run the interface */
  649.     p_intf->b_play = b_play;
  650.     p_intf->b_block = b_block;
  651.     i_err = intf_RunThread( p_intf );
  652.     if( i_err )
  653.     {
  654.         vlc_object_detach( p_intf );
  655.         intf_Destroy( p_intf );
  656.         if( i_object ) vlc_object_release( p_vlc );
  657.         return i_err;
  658.     }
  659.     if( i_object ) vlc_object_release( p_vlc );
  660.     return VLC_SUCCESS;
  661. }
  662. /*****************************************************************************
  663.  * VLC_Die: ask vlc to die.
  664.  *****************************************************************************
  665.  * This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
  666.  * task. It is your duty to call VLC_CleanUp and VLC_Destroy afterwards.
  667.  *****************************************************************************/
  668. int VLC_Die( int i_object )
  669. {
  670.     vlc_t *p_vlc = vlc_current_object( i_object );
  671.     if( !p_vlc )
  672.     {
  673.         return VLC_ENOOBJ;
  674.     }
  675.     p_vlc->b_die = VLC_TRUE;
  676.     if( i_object ) vlc_object_release( p_vlc );
  677.     return VLC_SUCCESS;
  678. }
  679. /*****************************************************************************
  680.  * VLC_CleanUp: CleanUp all the intf, playlist, vout, aout
  681.  *****************************************************************************/
  682. int VLC_CleanUp( int i_object )
  683. {
  684.     intf_thread_t      * p_intf;
  685.     playlist_t         * p_playlist;
  686.     vout_thread_t      * p_vout;
  687.     aout_instance_t    * p_aout;
  688.     announce_handler_t * p_announce;
  689.     vlc_t *p_vlc = vlc_current_object( i_object );
  690.     /* Check that the handle is valid */
  691.     if( !p_vlc )
  692.     {
  693.         return VLC_ENOOBJ;
  694.     }
  695.     /*
  696.      * Ask the interfaces to stop and destroy them
  697.      */
  698.     msg_Dbg( p_vlc, "removing all interfaces" );
  699.     while( (p_intf = vlc_object_find( p_vlc, VLC_OBJECT_INTF, FIND_CHILD )) )
  700.     {
  701.         intf_StopThread( p_intf );
  702.         vlc_object_detach( p_intf );
  703.         vlc_object_release( p_intf );
  704.         intf_Destroy( p_intf );
  705.     }
  706.     /*
  707.      * Free playlists
  708.      */
  709.     msg_Dbg( p_vlc, "removing all playlists" );
  710.     while( (p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST,
  711.                                           FIND_CHILD )) )
  712.     {
  713.         vlc_object_detach( p_playlist );
  714.         vlc_object_release( p_playlist );
  715.         playlist_Destroy( p_playlist );
  716.     }
  717.     /*
  718.      * Free video outputs
  719.      */
  720.     msg_Dbg( p_vlc, "removing all video outputs" );
  721.     while( (p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD )) )
  722.     {
  723.         vlc_object_detach( p_vout );
  724.         vlc_object_release( p_vout );
  725.         vout_Destroy( p_vout );
  726.     }
  727.     /*
  728.      * Free audio outputs
  729.      */
  730.     msg_Dbg( p_vlc, "removing all audio outputs" );
  731.     while( (p_aout = vlc_object_find( p_vlc, VLC_OBJECT_AOUT, FIND_CHILD )) )
  732.     {
  733.         vlc_object_detach( (vlc_object_t *)p_aout );
  734.         vlc_object_release( (vlc_object_t *)p_aout );
  735.         aout_Delete( p_aout );
  736.     }
  737.     /*
  738.      * Free announce handler(s?)
  739.      */
  740.     msg_Dbg( p_vlc, "removing announce handler" );
  741.     while( (p_announce = vlc_object_find( p_vlc, VLC_OBJECT_ANNOUNCE,
  742.                                                  FIND_CHILD ) ) )
  743.    {
  744.         vlc_object_detach( p_announce );
  745.         vlc_object_release( p_announce );
  746.         announce_HandlerDestroy( p_announce );
  747.    }
  748.     if( i_object ) vlc_object_release( p_vlc );
  749.     return VLC_SUCCESS;
  750. }
  751. /*****************************************************************************
  752.  * VLC_Destroy: Destroy everything.
  753.  *****************************************************************************
  754.  * This function requests the running threads to finish, waits for their
  755.  * termination, and destroys their structure.
  756.  *****************************************************************************/
  757. int VLC_Destroy( int i_object )
  758. {
  759.     vlc_t *p_vlc = vlc_current_object( i_object );
  760.     if( !p_vlc )
  761.     {
  762.         return VLC_ENOOBJ;
  763.     }
  764.     /*
  765.      * Free allocated memory
  766.      */
  767.     if( p_vlc->p_memcpy_module )
  768.     {
  769.         module_Unneed( p_vlc, p_vlc->p_memcpy_module );
  770.         p_vlc->p_memcpy_module = NULL;
  771.     }
  772.     /*
  773.      * Free module bank !
  774.      */
  775.     module_EndBank( p_vlc );
  776.     if( p_vlc->psz_homedir )
  777.     {
  778.         free( p_vlc->psz_homedir );
  779.         p_vlc->psz_homedir = NULL;
  780.     }
  781.     if( p_vlc->psz_configfile )
  782.     {
  783.         free( p_vlc->psz_configfile );
  784.         p_vlc->psz_configfile = NULL;
  785.     }
  786.     if( p_vlc->p_hotkeys )
  787.     {
  788.         free( p_vlc->p_hotkeys );
  789.         p_vlc->p_hotkeys = NULL;
  790.     }
  791.     /*
  792.      * System specific cleaning code
  793.      */
  794.     system_End( p_vlc );
  795.     /* Destroy mutexes */
  796.     vlc_mutex_destroy( &p_vlc->config_lock );
  797.     vlc_object_detach( p_vlc );
  798.     /* Release object before destroying it */
  799.     if( i_object ) vlc_object_release( p_vlc );
  800.     vlc_object_destroy( p_vlc );
  801.     /* Stop thread system: last one out please shut the door! */
  802.     vlc_threads_end( p_libvlc );
  803.     return VLC_SUCCESS;
  804. }
  805. /*****************************************************************************
  806.  * VLC_VariableSet: set a vlc variable
  807.  *****************************************************************************/
  808. int VLC_VariableSet( int i_object, char const *psz_var, vlc_value_t value )
  809. {
  810.     vlc_t *p_vlc = vlc_current_object( i_object );
  811.     int i_ret;
  812.     if( !p_vlc )
  813.     {
  814.         return VLC_ENOOBJ;
  815.     }
  816.     /* FIXME: Temporary hack for Mozilla, if variable starts with conf:: then
  817.      * we handle it as a configuration variable. Don't tell Gildas :) -- sam */
  818.     if( !strncmp( psz_var, "conf::", 6 ) )
  819.     {
  820.         module_config_t *p_item;
  821.         char const *psz_newvar = psz_var + 6;
  822.         p_item = config_FindConfig( VLC_OBJECT(p_vlc), psz_newvar );
  823.         if( p_item )
  824.         {
  825.             switch( p_item->i_type )
  826.             {
  827.                 case CONFIG_ITEM_BOOL:
  828.                     config_PutInt( p_vlc, psz_newvar, value.b_bool );
  829.                     break;
  830.                 case CONFIG_ITEM_INTEGER:
  831.                     config_PutInt( p_vlc, psz_newvar, value.i_int );
  832.                     break;
  833.                 case CONFIG_ITEM_FLOAT:
  834.                     config_PutFloat( p_vlc, psz_newvar, value.f_float );
  835.                     break;
  836.                 default:
  837.                     config_PutPsz( p_vlc, psz_newvar, value.psz_string );
  838.                     break;
  839.             }
  840.             if( i_object ) vlc_object_release( p_vlc );
  841.             return VLC_SUCCESS;
  842.         }
  843.     }
  844.     i_ret = var_Set( p_vlc, psz_var, value );
  845.     if( i_object ) vlc_object_release( p_vlc );
  846.     return i_ret;
  847. }
  848. /*****************************************************************************
  849.  * VLC_VariableGet: get a vlc variable
  850.  *****************************************************************************/
  851. int VLC_VariableGet( int i_object, char const *psz_var, vlc_value_t *p_value )
  852. {
  853.     vlc_t *p_vlc = vlc_current_object( i_object );
  854.     int i_ret;
  855.     if( !p_vlc )
  856.     {
  857.         return VLC_ENOOBJ;
  858.     }
  859.     i_ret = var_Get( p_vlc , psz_var, p_value );
  860.     if( i_object ) vlc_object_release( p_vlc );
  861.     return i_ret;
  862. }
  863. /*****************************************************************************
  864.  * VLC_AddTarget: adds a target for playing.
  865.  *****************************************************************************
  866.  * This function adds psz_target to the current playlist. If a playlist does
  867.  * not exist, it will create one.
  868.  *****************************************************************************/
  869. int VLC_AddTarget( int i_object, char const *psz_target,
  870.                    char const **ppsz_options, int i_options,
  871.                    int i_mode, int i_pos )
  872. {
  873.     int i_err;
  874.     playlist_t *p_playlist;
  875.     vlc_t *p_vlc = vlc_current_object( i_object );
  876.     if( !p_vlc )
  877.     {
  878.         return VLC_ENOOBJ;
  879.     }
  880.     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
  881.     if( p_playlist == NULL )
  882.     {
  883.         msg_Dbg( p_vlc, "no playlist present, creating one" );
  884.         p_playlist = playlist_Create( p_vlc );
  885.         if( p_playlist == NULL )
  886.         {
  887.             if( i_object ) vlc_object_release( p_vlc );
  888.             return VLC_EGENERIC;
  889.         }
  890.         vlc_object_yield( p_playlist );
  891.     }
  892.     i_err = playlist_AddExt( p_playlist, psz_target, psz_target,
  893.                              i_mode, i_pos, -1, ppsz_options, i_options);
  894.     vlc_object_release( p_playlist );
  895.     if( i_object ) vlc_object_release( p_vlc );
  896.     return i_err;
  897. }
  898. /*****************************************************************************
  899.  * VLC_Play: play
  900.  *****************************************************************************/
  901. int VLC_Play( int i_object )
  902. {
  903.     playlist_t * p_playlist;
  904.     vlc_t *p_vlc = vlc_current_object( i_object );
  905.     /* Check that the handle is valid */
  906.     if( !p_vlc )
  907.     {
  908.         return VLC_ENOOBJ;
  909.     }
  910.     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
  911.     if( !p_playlist )
  912.     {
  913.         if( i_object ) vlc_object_release( p_vlc );
  914.         return VLC_ENOOBJ;
  915.     }
  916.     playlist_Play( p_playlist );
  917.     vlc_object_release( p_playlist );
  918.     if( i_object ) vlc_object_release( p_vlc );
  919.     return VLC_SUCCESS;
  920. }
  921. /*****************************************************************************
  922.  * VLC_Pause: toggle pause
  923.  *****************************************************************************/
  924. int VLC_Pause( int i_object )
  925. {
  926.     playlist_t * p_playlist;
  927.     vlc_t *p_vlc = vlc_current_object( i_object );
  928.     /* Check that the handle is valid */
  929.     if( !p_vlc )
  930.     {
  931.         return VLC_ENOOBJ;
  932.     }
  933.     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
  934.     if( !p_playlist )
  935.     {
  936.         if( i_object ) vlc_object_release( p_vlc );
  937.         return VLC_ENOOBJ;
  938.     }
  939.     playlist_Pause( p_playlist );
  940.     vlc_object_release( p_playlist );
  941.     if( i_object ) vlc_object_release( p_vlc );
  942.     return VLC_SUCCESS;
  943. }
  944. /*****************************************************************************
  945.  * VLC_Pause: toggle pause
  946.  *****************************************************************************/
  947. int VLC_Stop( int i_object )
  948. {
  949.     playlist_t * p_playlist;
  950.     vlc_t *p_vlc = vlc_current_object( i_object );
  951.     /* Check that the handle is valid */
  952.     if( !p_vlc )
  953.     {
  954.         return VLC_ENOOBJ;
  955.     }
  956.     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
  957.     if( !p_playlist )
  958.     {
  959.         if( i_object ) vlc_object_release( p_vlc );
  960.         return VLC_ENOOBJ;
  961.     }
  962.     playlist_Stop( p_playlist );
  963.     vlc_object_release( p_playlist );
  964.     if( i_object ) vlc_object_release( p_vlc );
  965.     return VLC_SUCCESS;
  966. }
  967. /*****************************************************************************
  968.  * VLC_IsPlaying: Query for Playlist Status
  969.  *****************************************************************************/
  970. vlc_bool_t VLC_IsPlaying( int i_object )
  971. {
  972.     playlist_t * p_playlist;
  973.     vlc_bool_t   b_playing;
  974.     vlc_t *p_vlc = vlc_current_object( i_object );
  975.     /* Check that the handle is valid */
  976.     if( !p_vlc )
  977.     {
  978.         return VLC_ENOOBJ;
  979.     }
  980.     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
  981.     if( !p_playlist )
  982.     {
  983.         if( i_object ) vlc_object_release( p_vlc );
  984.         return VLC_ENOOBJ;
  985.     }
  986.     b_playing = playlist_IsPlaying( p_playlist );
  987.     vlc_object_release( p_playlist );
  988.     if( i_object ) vlc_object_release( p_vlc );
  989.     return b_playing;
  990. }
  991. /**
  992.  * Get the current position in a input
  993.  *
  994.  * Return the current position as a float
  995.  * note For some inputs, this will be unknown.
  996.  *
  997.  * param i_object a vlc object id
  998.  * return a float in the range of 0.0 - 1.0
  999.  */
  1000. float VLC_PositionGet( int i_object )
  1001. {
  1002.     input_thread_t *p_input;
  1003.     vlc_value_t val;
  1004.     vlc_t *p_vlc = vlc_current_object( i_object );
  1005.     /* Check that the handle is valid */
  1006.     if( !p_vlc )
  1007.     {
  1008.         return VLC_ENOOBJ;
  1009.     }
  1010.     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
  1011.     if( !p_input )
  1012.     {
  1013.         if( i_object ) vlc_object_release( p_vlc );
  1014.         return VLC_ENOOBJ;
  1015.     }
  1016.     var_Get( p_input, "position", &val );
  1017.     vlc_object_release( p_input );
  1018.     if( i_object ) vlc_object_release( p_vlc );
  1019.     return val.f_float;
  1020. }
  1021. /**
  1022.  * Set the current position in a input
  1023.  *
  1024.  * Set the current position in a input and then return
  1025.  * the current position as a float.
  1026.  * note For some inputs, this will be unknown.
  1027.  *
  1028.  * param i_object a vlc object id
  1029.  * param i_position a float in the range of 0.0 - 1.0
  1030.  * return a float in the range of 0.0 - 1.0
  1031.  */
  1032. float VLC_PositionSet( int i_object, float i_position )
  1033. {
  1034.     input_thread_t *p_input;
  1035.     vlc_value_t val;
  1036.     vlc_t *p_vlc = vlc_current_object( i_object );
  1037.     /* Check that the handle is valid */
  1038.     if( !p_vlc )
  1039.     {
  1040.         return VLC_ENOOBJ;
  1041.     }
  1042.     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
  1043.     if( !p_input )
  1044.     {
  1045.         if( i_object ) vlc_object_release( p_vlc );
  1046.         return VLC_ENOOBJ;
  1047.     }
  1048.     val.f_float = i_position;
  1049.     var_Set( p_input, "position", val );
  1050.     var_Get( p_input, "position", &val );
  1051.     vlc_object_release( p_input );
  1052.     if( i_object ) vlc_object_release( p_vlc );
  1053.     return val.f_float;
  1054. }
  1055. /**
  1056.  * Get the current position in a input
  1057.  *
  1058.  * Return the current position in seconds from the start.
  1059.  * note For some inputs, this will be unknown.
  1060.  *
  1061.  * param i_object a vlc object id
  1062.  * return the offset from 0:00 in seconds
  1063.  */
  1064. int VLC_TimeGet( int i_object )
  1065. {
  1066.     input_thread_t *p_input;
  1067.     vlc_value_t val;
  1068.     vlc_t *p_vlc = vlc_current_object( i_object );
  1069.     /* Check that the handle is valid */
  1070.     if( !p_vlc )
  1071.     {
  1072.         return VLC_ENOOBJ;
  1073.     }
  1074.     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
  1075.     if( !p_input )
  1076.     {
  1077.         if( i_object ) vlc_object_release( p_vlc );
  1078.         return VLC_ENOOBJ;
  1079.     }
  1080.     var_Get( p_input, "time", &val );
  1081.     vlc_object_release( p_input );
  1082.     if( i_object ) vlc_object_release( p_vlc );
  1083.     return val.i_time  / 1000000;
  1084. }
  1085. /**
  1086.  * Seek to a position in the current input
  1087.  *
  1088.  * Seek i_seconds in the current input. If b_relative is set,
  1089.  * then the seek will be relative to the current position, otherwise
  1090.  * it will seek to i_seconds from the beginning of the input.
  1091.  * note For some inputs, this will be unknown.
  1092.  *
  1093.  * param i_object a vlc object id
  1094.  * param i_seconds seconds from current position or from beginning of input
  1095.  * param b_relative seek relative from current position
  1096.  * return VLC_SUCCESS on success
  1097.  */
  1098. int VLC_TimeSet( int i_object, int i_seconds, vlc_bool_t b_relative )
  1099. {
  1100.     input_thread_t *p_input;
  1101.     vlc_value_t val;
  1102.     vlc_t *p_vlc = vlc_current_object( i_object );
  1103.     /* Check that the handle is valid */
  1104.     if( !p_vlc )
  1105.     {
  1106.         return VLC_ENOOBJ;
  1107.     }
  1108.     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
  1109.     if( !p_input )
  1110.     {
  1111.         if( i_object ) vlc_object_release( p_vlc );
  1112.         return VLC_ENOOBJ;
  1113.     }
  1114.     if( b_relative )
  1115.     {
  1116.         val.i_time = i_seconds * 1000000;
  1117.         var_Set( p_input, "time-offset", val );
  1118.     }
  1119.     else
  1120.     {
  1121.         val.i_time = i_seconds * 1000000;
  1122.         var_Set( p_input, "time", val );
  1123.     }
  1124.     vlc_object_release( p_input );
  1125.     if( i_object ) vlc_object_release( p_vlc );
  1126.     return VLC_SUCCESS;
  1127. }
  1128. /**
  1129.  * Get the total length of a input
  1130.  *
  1131.  * Return the total length in seconds from the current input.
  1132.  * note For some inputs, this will be unknown.
  1133.  *
  1134.  * param i_object a vlc object id
  1135.  * return the length in seconds
  1136.  */
  1137. int VLC_LengthGet( int i_object )
  1138. {
  1139.     input_thread_t *p_input;
  1140.     vlc_value_t val;
  1141.     vlc_t *p_vlc = vlc_current_object( i_object );
  1142.     /* Check that the handle is valid */
  1143.     if( !p_vlc )
  1144.     {
  1145.         return VLC_ENOOBJ;
  1146.     }
  1147.     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
  1148.     if( !p_input )
  1149.     {
  1150.         if( i_object ) vlc_object_release( p_vlc );
  1151.         return VLC_ENOOBJ;
  1152.     }
  1153.     var_Get( p_input, "length", &val );
  1154.     vlc_object_release( p_input );
  1155.     if( i_object ) vlc_object_release( p_vlc );
  1156.     return val.i_time  / 1000000;
  1157. }
  1158. /**
  1159.  * Play the input faster than realtime
  1160.  *
  1161.  * 2x, 4x, 8x faster than realtime
  1162.  * note For some inputs, this will be impossible.
  1163.  *
  1164.  * param i_object a vlc object id
  1165.  * return the current speedrate
  1166.  */
  1167. float VLC_SpeedFaster( int i_object )
  1168. {
  1169.     input_thread_t *p_input;
  1170.     vlc_value_t val;
  1171.     vlc_t *p_vlc = vlc_current_object( i_object );
  1172.     /* Check that the handle is valid */
  1173.     if( !p_vlc )
  1174.     {
  1175.         return VLC_ENOOBJ;
  1176.     }
  1177.     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
  1178.     if( !p_input )
  1179.     {
  1180.         if( i_object ) vlc_object_release( p_vlc );
  1181.         return VLC_ENOOBJ;
  1182.     }
  1183.     val.b_bool = VLC_TRUE;
  1184.     var_Set( p_input, "rate-faster", val );
  1185.     var_Get( p_input, "rate", &val );
  1186.     vlc_object_release( p_input );
  1187.     if( i_object ) vlc_object_release( p_vlc );
  1188.     return val.f_float / INPUT_RATE_DEFAULT;
  1189. }
  1190. /**
  1191.  * Play the input slower than realtime
  1192.  *
  1193.  * 1/2x, 1/4x, 1/8x slower than realtime
  1194.  * note For some inputs, this will be impossible.
  1195.  *
  1196.  * param i_object a vlc object id
  1197.  * return the current speedrate
  1198.  */
  1199. float VLC_SpeedSlower( int i_object )
  1200. {
  1201.     input_thread_t *p_input;
  1202.     vlc_value_t val;
  1203.     vlc_t *p_vlc = vlc_current_object( i_object );
  1204.     /* Check that the handle is valid */
  1205.     if( !p_vlc )
  1206.     {
  1207.         return VLC_ENOOBJ;
  1208.     }
  1209.     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
  1210.     if( !p_input )
  1211.     {
  1212.         if( i_object ) vlc_object_release( p_vlc );
  1213.         return VLC_ENOOBJ;
  1214.     }
  1215.     val.b_bool = VLC_TRUE;
  1216.     var_Set( p_input, "rate-slower", val );
  1217.     var_Get( p_input, "rate", &val );
  1218.     vlc_object_release( p_input );
  1219.     if( i_object ) vlc_object_release( p_vlc );
  1220.     return val.f_float / INPUT_RATE_DEFAULT;
  1221. }
  1222. /**
  1223.  * Return the current playlist item
  1224.  *
  1225.  * Returns the index of the playlistitem that is currently selected for play.
  1226.  * This is valid even if nothing is currently playing.
  1227.  *
  1228.  * param i_object a vlc object id
  1229.  * return the current index
  1230.  */
  1231. int VLC_PlaylistIndex( int i_object )
  1232. {
  1233.     int i_index;
  1234.     playlist_t * p_playlist;
  1235.     vlc_t *p_vlc = vlc_current_object( i_object );
  1236.     /* Check that the handle is valid */
  1237.     if( !p_vlc )
  1238.     {
  1239.         return VLC_ENOOBJ;
  1240.     }
  1241.     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
  1242.     if( !p_playlist )
  1243.     {
  1244.         if( i_object ) vlc_object_release( p_vlc );
  1245.         return VLC_ENOOBJ;
  1246.     }
  1247.     i_index = p_playlist->i_index;
  1248.     vlc_object_release( p_playlist );
  1249.     if( i_object ) vlc_object_release( p_vlc );
  1250.     return i_index;
  1251. }
  1252. /**
  1253.  * Total amount of items in the playlist
  1254.  *
  1255.  * param i_object a vlc object id
  1256.  * return amount of playlist items
  1257.  */
  1258. int VLC_PlaylistNumberOfItems( int i_object )
  1259. {
  1260.     int i_size;
  1261.     playlist_t * p_playlist;
  1262.     vlc_t *p_vlc = vlc_current_object( i_object );
  1263.     /* Check that the handle is valid */
  1264.     if( !p_vlc )
  1265.     {
  1266.         return VLC_ENOOBJ;
  1267.     }
  1268.     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
  1269.     if( !p_playlist )
  1270.     {
  1271.         if( i_object ) vlc_object_release( p_vlc );
  1272.         return VLC_ENOOBJ;
  1273.     }
  1274.     i_size = p_playlist->i_size;
  1275.     vlc_object_release( p_playlist );
  1276.     if( i_object ) vlc_object_release( p_vlc );
  1277.     return i_size;
  1278. }
  1279. /**
  1280.  * Next playlist item
  1281.  *
  1282.  * Skip to the next playlistitem and play it.
  1283.  *
  1284.  * param i_object a vlc object id
  1285.  * return VLC_SUCCESS on success
  1286.  */
  1287. int VLC_PlaylistNext( int i_object )
  1288. {
  1289.     playlist_t * p_playlist;
  1290.     vlc_t *p_vlc = vlc_current_object( i_object );
  1291.     /* Check that the handle is valid */
  1292.     if( !p_vlc )
  1293.     {
  1294.         return VLC_ENOOBJ;
  1295.     }
  1296.     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
  1297.     if( !p_playlist )
  1298.     {
  1299.         if( i_object ) vlc_object_release( p_vlc );
  1300.         return VLC_ENOOBJ;
  1301.     }
  1302.     playlist_Next( p_playlist );
  1303.     vlc_object_release( p_playlist );
  1304.     if( i_object ) vlc_object_release( p_vlc );
  1305.     return VLC_SUCCESS;
  1306. }
  1307. /**
  1308.  * Previous playlist item
  1309.  *
  1310.  * Skip to the previous playlistitem and play it.
  1311.  *
  1312.  * param i_object a vlc object id
  1313.  * return VLC_SUCCESS on success
  1314.  */
  1315. int VLC_PlaylistPrev( int i_object )
  1316. {
  1317.     playlist_t * p_playlist;
  1318.     vlc_t *p_vlc = vlc_current_object( i_object );
  1319.     /* Check that the handle is valid */
  1320.     if( !p_vlc )
  1321.     {
  1322.         return VLC_ENOOBJ;
  1323.     }
  1324.     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
  1325.     if( !p_playlist )
  1326.     {
  1327.         if( i_object ) vlc_object_release( p_vlc );
  1328.         return VLC_ENOOBJ;
  1329.     }
  1330.     playlist_Prev( p_playlist );
  1331.     vlc_object_release( p_playlist );
  1332.     if( i_object ) vlc_object_release( p_vlc );
  1333.     return VLC_SUCCESS;
  1334. }
  1335. /*****************************************************************************
  1336.  * VLC_PlaylistClear: Empty the playlist
  1337.  *****************************************************************************/
  1338. int VLC_PlaylistClear( int i_object )
  1339. {
  1340.     int i_err;
  1341.     playlist_t * p_playlist;
  1342.     vlc_t *p_vlc = vlc_current_object( i_object );
  1343.     /* Check that the handle is valid */
  1344.     if( !p_vlc )
  1345.     {
  1346.         return VLC_ENOOBJ;
  1347.     }
  1348.     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
  1349.     if( !p_playlist )
  1350.     {
  1351.         if( i_object ) vlc_object_release( p_vlc );
  1352.         return VLC_ENOOBJ;
  1353.     }
  1354.     i_err = playlist_Clear( p_playlist );
  1355.     vlc_object_release( p_playlist );
  1356.     if( i_object ) vlc_object_release( p_vlc );
  1357.     return i_err;
  1358. }
  1359. /**
  1360.  * Change the volume
  1361.  *
  1362.  * param i_object a vlc object id
  1363.  * param i_volume something in a range from 0-200
  1364.  * return the new volume (range 0-200 %)
  1365.  */
  1366. int VLC_VolumeSet( int i_object, int i_volume )
  1367. {
  1368.     audio_volume_t i_vol = 0;
  1369.     vlc_t *p_vlc = vlc_current_object( i_object );
  1370.     /* Check that the handle is valid */
  1371.     if( !p_vlc )
  1372.     {
  1373.         return VLC_ENOOBJ;
  1374.     }
  1375.     if( i_volume >= 0 && i_volume <= 200 )
  1376.     {
  1377.         i_vol = i_volume * AOUT_VOLUME_MAX / 200;
  1378.         aout_VolumeSet( p_vlc, i_vol );
  1379.     }
  1380.     if( i_object ) vlc_object_release( p_vlc );
  1381.     return i_vol * 200 / AOUT_VOLUME_MAX;
  1382. }
  1383. /**
  1384.  * Get the current volume
  1385.  *
  1386.  * Retrieve the current volume.
  1387.  *
  1388.  * param i_object a vlc object id
  1389.  * return the current volume (range 0-200 %)
  1390.  */
  1391. int VLC_VolumeGet( int i_object )
  1392. {
  1393.     audio_volume_t i_volume;
  1394.     vlc_t *p_vlc = vlc_current_object( i_object );
  1395.     /* Check that the handle is valid */
  1396.     if( !p_vlc )
  1397.     {
  1398.         return VLC_ENOOBJ;
  1399.     }
  1400.     aout_VolumeGet( p_vlc, &i_volume );
  1401.     if( i_object ) vlc_object_release( p_vlc );
  1402.     return i_volume*200/AOUT_VOLUME_MAX;
  1403. }
  1404. /**
  1405.  * Mute/Unmute the volume
  1406.  *
  1407.  * param i_object a vlc object id
  1408.  * return VLC_SUCCESS on success
  1409.  */
  1410. int VLC_VolumeMute( int i_object )
  1411. {
  1412.     vlc_t *p_vlc = vlc_current_object( i_object );
  1413.     /* Check that the handle is valid */
  1414.     if( !p_vlc )
  1415.     {
  1416.         return VLC_ENOOBJ;
  1417.     }
  1418.     aout_VolumeMute( p_vlc, NULL );
  1419.     if( i_object ) vlc_object_release( p_vlc );
  1420.     return VLC_SUCCESS;
  1421. }
  1422. /*****************************************************************************
  1423.  * VLC_FullScreen: toggle fullscreen mode
  1424.  *****************************************************************************/
  1425. int VLC_FullScreen( int i_object )
  1426. {
  1427.     vout_thread_t *p_vout;
  1428.     vlc_t *p_vlc = vlc_current_object( i_object );
  1429.     if( !p_vlc )
  1430.     {
  1431.         return VLC_ENOOBJ;
  1432.     }
  1433.     p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD );
  1434.     if( !p_vout )
  1435.     {
  1436.         if( i_object ) vlc_object_release( p_vlc );
  1437.         return VLC_ENOOBJ;
  1438.     }
  1439.     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
  1440.     vlc_object_release( p_vout );
  1441.     if( i_object ) vlc_object_release( p_vlc );
  1442.     return VLC_SUCCESS;
  1443. }
  1444. /* following functions are local */
  1445. /*****************************************************************************
  1446.  * SetLanguage: set the interface language.
  1447.  *****************************************************************************
  1448.  * We set the LC_MESSAGES locale category for interface messages and buttons,
  1449.  * as well as the LC_CTYPE category for string sorting and possible wide
  1450.  * character support.
  1451.  *****************************************************************************/
  1452. static void SetLanguage ( char const *psz_lang )
  1453. {
  1454. #if defined( ENABLE_NLS ) 
  1455.      && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
  1456.     char *          psz_path;
  1457. #if defined( SYS_DARWIN ) || defined ( WIN32 ) || defined( SYS_BEOS )
  1458.     char            psz_tmp[1024];
  1459. #endif
  1460.     if( psz_lang && !*psz_lang )
  1461.     {
  1462. #   if defined( HAVE_LC_MESSAGES )
  1463.         setlocale( LC_MESSAGES, psz_lang );
  1464. #   endif
  1465.         setlocale( LC_CTYPE, psz_lang );
  1466.     }
  1467.     else if( psz_lang )
  1468.     {
  1469. #ifdef SYS_DARWIN
  1470.         /* I need that under Darwin, please check it doesn't disturb
  1471.          * other platforms. --Meuuh */
  1472.         setenv( "LANG", psz_lang, 1 );
  1473. #elif defined( SYS_BEOS ) || defined( WIN32 )
  1474.         /* We set LC_ALL manually because it is the only way to set
  1475.          * the language at runtime under eg. Windows. Beware that this
  1476.          * makes the environment unconsistent when libvlc is unloaded and
  1477.          * should probably be moved to a safer place like vlc.c. */
  1478.         static char psz_lcall[20];
  1479.         snprintf( psz_lcall, 19, "LC_ALL=%s", psz_lang );
  1480.         psz_lcall[19] = '';
  1481.         putenv( psz_lcall );
  1482. #endif
  1483.         setlocale( LC_ALL, psz_lang );
  1484.     }
  1485.     /* Specify where to find the locales for current domain */
  1486. #if !defined( SYS_DARWIN ) && !defined( WIN32 ) && !defined( SYS_BEOS )
  1487.     psz_path = LOCALEDIR;
  1488. #else
  1489.     snprintf( psz_tmp, sizeof(psz_tmp), "%s/%s", libvlc.psz_vlcpath,
  1490.               "locale" );
  1491.     psz_path = psz_tmp;
  1492. #endif
  1493.     if( !bindtextdomain( PACKAGE_NAME, psz_path ) )
  1494.     {
  1495.         fprintf( stderr, "warning: no domain %s in directory %sn",
  1496.                  PACKAGE_NAME, psz_path );
  1497.     }
  1498.     /* Set the default domain */
  1499.     textdomain( PACKAGE_NAME );
  1500. #if defined( ENABLE_UTF8 )
  1501.     bind_textdomain_codeset( PACKAGE_NAME, "UTF-8" );
  1502. #endif
  1503. #endif
  1504. }
  1505. /*****************************************************************************
  1506.  * GetFilenames: parse command line options which are not flags
  1507.  *****************************************************************************
  1508.  * Parse command line for input files as well as their associated options.
  1509.  * An option always follows its associated input and begins with a ":".
  1510.  *****************************************************************************/
  1511. static int GetFilenames( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
  1512. {
  1513.     int i_opt, i_options;
  1514.     /* We assume that the remaining parameters are filenames
  1515.      * and their input options */
  1516.     for( i_opt = i_argc - 1; i_opt >= optind; i_opt-- )
  1517.     {
  1518.         i_options = 0;
  1519.         /* Count the input options */
  1520.         while( *ppsz_argv[ i_opt ] == ':' && i_opt > optind )
  1521.         {
  1522.             i_options++;
  1523.             i_opt--;
  1524.         }
  1525.         /* TODO: write an internal function of this one, to avoid
  1526.          *       unnecessary lookups. */
  1527.         VLC_AddTarget( p_vlc->i_object_id, ppsz_argv[ i_opt ],
  1528.                        (char const **)( i_options ? &ppsz_argv[i_opt + 1] :
  1529.                                         NULL ), i_options,
  1530.                        PLAYLIST_INSERT, 0 );
  1531.     }
  1532.     return VLC_SUCCESS;
  1533. }
  1534. /*****************************************************************************
  1535.  * Usage: print program usage
  1536.  *****************************************************************************
  1537.  * Print a short inline help. Message interface is initialized at this stage.
  1538.  *****************************************************************************/
  1539. static void Usage( vlc_t *p_this, char const *psz_module_name )
  1540. {
  1541. #define FORMAT_STRING "  %s --%s%s%s%s%s%s%s "
  1542.     /* short option ------'    |     | | | |  | |
  1543.      * option name ------------'     | | | |  | |
  1544.      * <bra -------------------------' | | |  | |
  1545.      * option type or "" --------------' | |  | |
  1546.      * ket> -----------------------------' |  | |
  1547.      * padding spaces ---------------------'  | |
  1548.      * comment -------------------------------' |
  1549.      * comment suffix --------------------------'
  1550.      *
  1551.      * The purpose of having bra and ket is that we might i18n them as well.
  1552.      */
  1553. #define LINE_START 8
  1554. #define PADDING_SPACES 25
  1555.     vlc_list_t *p_list;
  1556.     module_t *p_parser;
  1557.     module_config_t *p_item;
  1558.     char psz_spaces[PADDING_SPACES+LINE_START+1];
  1559.     char psz_format[sizeof(FORMAT_STRING)];
  1560.     char psz_buffer[1000];
  1561.     char psz_short[4];
  1562.     int i_index;
  1563.     int i_width = ConsoleWidth() - (PADDING_SPACES+LINE_START+1);
  1564.     vlc_bool_t b_advanced = config_GetInt( p_this, "advanced" );
  1565.     memset( psz_spaces, ' ', PADDING_SPACES+LINE_START );
  1566.     psz_spaces[PADDING_SPACES+LINE_START] = '';
  1567.     strcpy( psz_format, FORMAT_STRING );
  1568. #ifdef WIN32
  1569.     ShowConsole();
  1570. #endif
  1571.     /* List all modules */
  1572.     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
  1573.     /* Enumerate the config for each module */
  1574.     for( i_index = 0; i_index < p_list->i_count; i_index++ )
  1575.     {
  1576.         vlc_bool_t b_help_module;
  1577.         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
  1578.         if( psz_module_name && strcmp( psz_module_name,
  1579.                                        p_parser->psz_object_name ) )
  1580.         {
  1581.             continue;
  1582.         }
  1583.         /* Ignore modules without config options */
  1584.         if( !p_parser->i_config_items )
  1585.         {
  1586.             continue;
  1587.         }
  1588.         /* Ignore modules with only advanced config options if requested */
  1589.         if( !b_advanced )
  1590.         {
  1591.             for( p_item = p_parser->p_config;
  1592.                  p_item->i_type != CONFIG_HINT_END;
  1593.                  p_item++ )
  1594.             {
  1595.                 if( (p_item->i_type & CONFIG_ITEM) &&
  1596.                     !p_item->b_advanced ) break;
  1597.             }
  1598.             if( p_item->i_type == CONFIG_HINT_END ) continue;
  1599.         }
  1600.         /* Print name of module */
  1601.         if( strcmp( "main", p_parser->psz_object_name ) )
  1602.         fprintf( stdout, "n %sn", p_parser->psz_longname );
  1603.         b_help_module = !strcmp( "help", p_parser->psz_object_name );
  1604.         /* Print module options */
  1605.         for( p_item = p_parser->p_config;
  1606.              p_item->i_type != CONFIG_HINT_END;
  1607.              p_item++ )
  1608.         {
  1609.             char *psz_text;
  1610.             char *psz_bra = NULL, *psz_type = NULL, *psz_ket = NULL;
  1611.             char *psz_suf = "", *psz_prefix = NULL;
  1612.             int i;
  1613.             /* Skip advanced options if requested */
  1614.             if( p_item->b_advanced && !b_advanced )
  1615.             {
  1616.                 continue;
  1617.             }
  1618.             switch( p_item->i_type )
  1619.             {
  1620.             case CONFIG_HINT_CATEGORY:
  1621.             case CONFIG_HINT_USAGE:
  1622.                 if( !strcmp( "main", p_parser->psz_object_name ) )
  1623.                 fprintf( stdout, "n %sn", p_item->psz_text );
  1624.                 break;
  1625.             case CONFIG_ITEM_STRING:
  1626.             case CONFIG_ITEM_FILE:
  1627.             case CONFIG_ITEM_DIRECTORY:
  1628.             case CONFIG_ITEM_MODULE: /* We could also have "=<" here */
  1629.                 if( !p_item->ppsz_list )
  1630.                 {
  1631.                     psz_bra = " <"; psz_type = _("string"); psz_ket = ">";
  1632.                     break;
  1633.                 }
  1634.                 else
  1635.                 {
  1636.                     psz_bra = " {";
  1637.                     psz_type = psz_buffer;
  1638.                     psz_type[0] = '';
  1639.                     for( i = 0; p_item->ppsz_list[i]; i++ )
  1640.                     {
  1641.                         if( i ) strcat( psz_type, "," );
  1642.                         strcat( psz_type, p_item->ppsz_list[i] );
  1643.                     }
  1644.                     psz_ket = "}";
  1645.                     break;
  1646.                 }
  1647.             case CONFIG_ITEM_INTEGER:
  1648.             case CONFIG_ITEM_KEY: /* FIXME: do something a bit more clever */
  1649.                 psz_bra = " <"; psz_type = _("integer"); psz_ket = ">";
  1650.                 break;
  1651.             case CONFIG_ITEM_FLOAT:
  1652.                 psz_bra = " <"; psz_type = _("float"); psz_ket = ">";
  1653.                 break;
  1654.             case CONFIG_ITEM_BOOL:
  1655.                 psz_bra = ""; psz_type = ""; psz_ket = "";
  1656.                 if( !b_help_module )
  1657.                 {
  1658.                     psz_suf = p_item->i_value ? _(" (default enabled)") :
  1659.                                                 _(" (default disabled)");
  1660.                 }
  1661.                 break;
  1662.             }
  1663.             if( !psz_type )
  1664.             {
  1665.                 continue;
  1666.             }
  1667.             /* Add short option if any */
  1668.             if( p_item->i_short )
  1669.             {
  1670.                 sprintf( psz_short, "-%c,", p_item->i_short );
  1671.             }
  1672.             else
  1673.             {
  1674.                 strcpy( psz_short, "   " );
  1675.             }
  1676.             i = PADDING_SPACES - strlen( p_item->psz_name )
  1677.                  - strlen( psz_bra ) - strlen( psz_type )
  1678.                  - strlen( psz_ket ) - 1;
  1679.             if( p_item->i_type == CONFIG_ITEM_BOOL && !b_help_module )
  1680.             {
  1681.                 /* If option is of type --foo-bar, we print its counterpart
  1682.                  * as --no-foo-bar, but if it is of type --foobar (without
  1683.                  * dashes in the name) we print it as --nofoobar. Both
  1684.                  * values are of course valid, only the display changes. */
  1685.                 psz_prefix = strchr( p_item->psz_name, '-' ) ? ", --no-"
  1686.                                                              : ", --no";
  1687.                 i -= strlen( p_item->psz_name ) + strlen( psz_prefix );
  1688.             }
  1689.             if( i < 0 )
  1690.             {
  1691.                 psz_spaces[0] = 'n';
  1692.                 i = 0;
  1693.             }
  1694.             else
  1695.             {
  1696.                 psz_spaces[i] = '';
  1697.             }
  1698.             if( p_item->i_type == CONFIG_ITEM_BOOL && !b_help_module )
  1699.             {
  1700.                 fprintf( stdout, psz_format, psz_short, p_item->psz_name,
  1701.                          psz_prefix, p_item->psz_name, psz_bra, psz_type,
  1702.                          psz_ket, psz_spaces );
  1703.             }
  1704.             else
  1705.             {
  1706.                 fprintf( stdout, psz_format, psz_short, p_item->psz_name,
  1707.                          "", "", psz_bra, psz_type, psz_ket, psz_spaces );
  1708.             }
  1709.             psz_spaces[i] = ' ';
  1710.             /* We wrap the rest of the output */
  1711.             sprintf( psz_buffer, "%s%s", p_item->psz_text, psz_suf );
  1712.             psz_text = psz_buffer;
  1713.             while( *psz_text )
  1714.             {
  1715.                 char *psz_parser, *psz_word;
  1716.                 int i_end = strlen( psz_text );
  1717.                 /* If the remaining text fits in a line, print it. */
  1718.                 if( i_end <= i_width )
  1719.                 {
  1720.                     fprintf( stdout, "%sn", psz_text );
  1721.                     break;
  1722.                 }
  1723.                 /* Otherwise, eat as many words as possible */
  1724.                 psz_parser = psz_text;
  1725.                 do
  1726.                 {
  1727.                     psz_word = psz_parser;
  1728.                     psz_parser = strchr( psz_word, ' ' );
  1729.                     /* If no space was found, we reached the end of the text
  1730.                      * block; otherwise, we skip the space we just found. */
  1731.                     psz_parser = psz_parser ? psz_parser + 1
  1732.                                             : psz_text + i_end;
  1733.                 } while( psz_parser - psz_text <= i_width );
  1734.                 /* We cut a word in one of these cases:
  1735.                  *  - it's the only word in the line and it's too long.
  1736.                  *  - we used less than 80% of the width and the word we are
  1737.                  *    going to wrap is longer than 40% of the width, and even
  1738.                  *    if the word would have fit in the next line. */
  1739.                 if( psz_word == psz_text
  1740.                      || ( psz_word - psz_text < 80 * i_width / 100
  1741.                            && psz_parser - psz_word > 40 * i_width / 100 ) )
  1742.                 {
  1743.                     char c = psz_text[i_width];
  1744.                     psz_text[i_width] = '';
  1745.                     fprintf( stdout, "%sn%s", psz_text, psz_spaces );
  1746.                     psz_text += i_width;
  1747.                     psz_text[0] = c;
  1748.                 }
  1749.                 else
  1750.                 {
  1751.                     psz_word[-1] = '';
  1752.                     fprintf( stdout, "%sn%s", psz_text, psz_spaces );
  1753.                     psz_text = psz_word;
  1754.                 }
  1755.             }
  1756.         }
  1757.     }
  1758.     /* Release the module list */
  1759.     vlc_list_release( p_list );
  1760. #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
  1761.     PauseConsole();
  1762. #endif
  1763. }
  1764. /*****************************************************************************
  1765.  * ListModules: list the available modules with their description
  1766.  *****************************************************************************
  1767.  * Print a list of all available modules (builtins and plugins) and a short
  1768.  * description for each one.
  1769.  *****************************************************************************/
  1770. static void ListModules( vlc_t *p_this )
  1771. {
  1772.     vlc_list_t *p_list;
  1773.     module_t *p_parser;
  1774.     char psz_spaces[22];
  1775.     int i_index;
  1776.     memset( psz_spaces, ' ', 22 );
  1777. #ifdef WIN32
  1778.     ShowConsole();
  1779. #endif
  1780.     /* Usage */
  1781.     fprintf( stdout, _("Usage: %s [options] [items]...nn"),
  1782.                      p_this->p_vlc->psz_object_name );
  1783.     fprintf( stdout, _("[module]              [description]n") );
  1784.     /* List all modules */
  1785.     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
  1786.     /* Enumerate each module */
  1787.     for( i_index = 0; i_index < p_list->i_count; i_index++ )
  1788.     {
  1789.         int i;
  1790.         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
  1791.         /* Nasty hack, but right now I'm too tired to think about a nice
  1792.          * solution */
  1793.         i = 22 - strlen( p_parser->psz_object_name ) - 1;
  1794.         if( i < 0 ) i = 0;
  1795.         psz_spaces[i] = 0;
  1796.         fprintf( stdout, "  %s%s %sn", p_parser->psz_object_name,
  1797.                          psz_spaces, p_parser->psz_longname );
  1798.         psz_spaces[i] = ' ';
  1799.     }
  1800.     vlc_list_release( p_list );
  1801. #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
  1802.     PauseConsole();
  1803. #endif
  1804. }
  1805. /*****************************************************************************
  1806.  * Version: print complete program version
  1807.  *****************************************************************************
  1808.  * Print complete program version and build number.
  1809.  *****************************************************************************/
  1810. static void Version( void )
  1811. {
  1812. #ifdef WIN32
  1813.     ShowConsole();
  1814. #endif
  1815.     fprintf( stdout, VERSION_MESSAGE "n" );
  1816.     fprintf( stdout,
  1817.       _("This program comes with NO WARRANTY, to the extent permitted by "
  1818.         "law.nYou may redistribute it under the terms of the GNU General "
  1819.         "Public License;nsee the file named COPYING for details.n"
  1820.         "Written by the VideoLAN team; see the AUTHORS file.n") );
  1821. #ifdef WIN32        /* Pause the console because it's destroyed when we exit */
  1822.     PauseConsole();
  1823. #endif
  1824. }
  1825. /*****************************************************************************
  1826.  * ShowConsole: On Win32, create an output console for debug messages
  1827.  *****************************************************************************
  1828.  * This function is useful only on Win32.
  1829.  *****************************************************************************/
  1830. #ifdef WIN32 /*  */
  1831. static void ShowConsole( void )
  1832. {
  1833. #   ifndef UNDER_CE
  1834.     if( getenv( "PWD" ) && getenv( "PS1" ) ) return; /* cygwin shell */
  1835.     AllocConsole();
  1836.     freopen( "CONOUT$", "w", stdout );
  1837.     freopen( "CONOUT$", "w", stderr );
  1838.     freopen( "CONIN$", "r", stdin );
  1839. #   endif
  1840. }
  1841. #endif
  1842. /*****************************************************************************
  1843.  * PauseConsole: On Win32, wait for a key press before closing the console
  1844.  *****************************************************************************
  1845.  * This function is useful only on Win32.
  1846.  *****************************************************************************/
  1847. #ifdef WIN32 /*  */
  1848. static void PauseConsole( void )
  1849. {
  1850. #   ifndef UNDER_CE
  1851.     if( getenv( "PWD" ) && getenv( "PS1" ) ) return; /* cygwin shell */
  1852.     fprintf( stdout, _("nPress the RETURN key to continue...n") );
  1853.     getchar();
  1854. #   endif
  1855. }
  1856. #endif
  1857. /*****************************************************************************
  1858.  * ConsoleWidth: Return the console width in characters
  1859.  *****************************************************************************
  1860.  * We use the stty shell command to get the console width; if this fails or
  1861.  * if the width is less than 80, we default to 80.
  1862.  *****************************************************************************/
  1863. static int ConsoleWidth( void )
  1864. {
  1865.     int i_width = 80;
  1866. #ifndef WIN32
  1867.     char buf[20], *psz_parser;
  1868.     FILE *file;
  1869.     int i_ret;
  1870.     file = popen( "stty size 2>/dev/null", "r" );
  1871.     if( file )
  1872.     {
  1873.         i_ret = fread( buf, 1, 20, file );
  1874.         if( i_ret > 0 )
  1875.         {
  1876.             buf[19] = '';
  1877.             psz_parser = strchr( buf, ' ' );
  1878.             if( psz_parser )
  1879.             {
  1880.                 i_ret = atoi( psz_parser + 1 );
  1881.                 if( i_ret >= 80 )
  1882.                 {
  1883.                     i_width = i_ret;
  1884.                 }
  1885.             }
  1886.         }
  1887.         pclose( file );
  1888.     }
  1889. #endif
  1890.     return i_width;
  1891. }
  1892. static int VerboseCallback( vlc_object_t *p_this, const char *psz_variable,
  1893.                      vlc_value_t old_val, vlc_value_t new_val, void *param)
  1894. {
  1895.     vlc_t *p_vlc = (vlc_t *)p_this;
  1896.     if( new_val.i_int >= -1 )
  1897.     {
  1898.         p_vlc->p_libvlc->i_verbose = __MIN( new_val.i_int, 2 );
  1899.     }
  1900.     return VLC_SUCCESS;
  1901. }
  1902. /*****************************************************************************
  1903.  * InitDeviceValues: initialize device values
  1904.  *****************************************************************************
  1905.  * This function inits the dvd, vcd and cd-audio values
  1906.  *****************************************************************************/
  1907. static void InitDeviceValues( vlc_t *p_vlc )
  1908. {
  1909. #ifdef HAVE_HAL
  1910.     LibHalContext * ctx;
  1911.     int i, i_devices;
  1912.     char **devices;
  1913.     char *block_dev;
  1914.     dbus_bool_t b_dvd;
  1915.     if( ( ctx = hal_initialize( NULL, FALSE ) ) )
  1916.     {
  1917.         if( ( devices = hal_get_all_devices( ctx, &i_devices ) ) )
  1918.         {
  1919.             for( i = 0; i < i_devices; i++ )
  1920.             {
  1921.                 if( !hal_device_property_exists( ctx, devices[ i ],
  1922.                                                 "storage.cdrom.dvd" ) )
  1923.                 {
  1924.                     continue;
  1925.                 }
  1926.                 b_dvd = hal_device_get_property_bool( ctx, devices[ i ],
  1927.                                                       "storage.cdrom.dvd" );
  1928.                 block_dev = hal_device_get_property_string( ctx, devices[ i ],
  1929.                                                             "block.device" );
  1930.                 if( b_dvd )
  1931.                 {
  1932.                     config_PutPsz( p_vlc, "dvd", block_dev );
  1933.                 }
  1934.                 config_PutPsz( p_vlc, "vcd", block_dev );
  1935.                 config_PutPsz( p_vlc, "cd-audio", block_dev );
  1936.                 hal_free_string( block_dev );
  1937.             }
  1938.         }
  1939.         hal_shutdown( ctx );
  1940.     }
  1941. #endif
  1942. }