]> git.sesse.net Git - vlc/blobdiff - src/libvlc.c
* ALL: libvlc now compiles and run under WinCE. I haven't ported any modules
[vlc] / src / libvlc.c
index 787b7b6aa4ec1a6188afc5733bc3a672ba1387d6..4439ed00ec5e6a86f3a46aafa0dcb856c6242a1b 100644 (file)
@@ -2,7 +2,7 @@
  * libvlc.c: main libvlc source
  *****************************************************************************
  * Copyright (C) 1998-2002 VideoLAN
- * $Id: libvlc.c,v 1.38 2002/10/11 22:32:56 sam Exp $
+ * $Id: libvlc.c,v 1.46 2002/11/10 23:41:53 sam Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
-#include <errno.h>                                                 /* ENOMEM */
+#include <vlc/vlc.h>
+
+#ifdef HAVE_ERRNO_H
+#   include <errno.h>                                              /* ENOMEM */
+#endif
 #include <stdio.h>                                              /* sprintf() */
 #include <string.h>                                            /* strerror() */
 #include <stdlib.h>                                                /* free() */
 
-#include <vlc/vlc.h>
-
 #ifndef WIN32
 #   include <netinet/in.h>                            /* BSD: struct in_addr */
 #endif
 
 #ifdef HAVE_UNISTD_H
 #   include <unistd.h>
-#elif defined( _MSC_VER ) && defined( _WIN32 )
+#elif defined( _MSC_VER ) && defined( _WIN32 ) && !defined( UNDER_CE )
 #   include <io.h>
 #endif
 
 #ifdef WIN32                       /* optind, getopt(), included in unistd.h */
-#   include "extras/GNUgetopt/getopt.h"
+#   include "extras/getopt.h"
 #endif
 
 #ifdef HAVE_LOCALE_H
@@ -61,6 +63,7 @@
 #include "vlc_cpu.h"                                        /* CPU detection */
 #include "os_specific.h"
 
+#include "error.h"
 #include "netutils.h"                                 /* network_ChannelJoin */
 
 #include "stream_control.h"
@@ -85,8 +88,9 @@ static vlc_t *  p_static_vlc;
 /*****************************************************************************
  * Local prototypes
  *****************************************************************************/
+static void SetLanguage   ( char const * );
 static int  GetFilenames  ( vlc_t *, int, char *[] );
-static void Usage         ( vlc_t *, const char *psz_module_name );
+static void Usage         ( vlc_t *, char const *psz_module_name );
 static void ListModules   ( vlc_t * );
 static void Version       ( void );
 
@@ -99,11 +103,21 @@ static void ShowConsole   ( void );
  *****************************************************************************
  * This function returns full version string (numeric version and codename).
  *****************************************************************************/
-char * VLC_Version( void )
+char const * VLC_Version( void )
 {
     return VERSION_MESSAGE;
 }
 
+/*****************************************************************************
+ * VLC_Error: strerror() equivalent
+ *****************************************************************************
+ * This function returns full version string (numeric version and codename).
+ *****************************************************************************/
+char const * VLC_Error( int i_err )
+{
+    return vlc_error( i_err );
+}
+
 /*****************************************************************************
  * VLC_Create: allocate a vlc_t structure, and initialize libvlc if needed.
  *****************************************************************************
@@ -114,7 +128,7 @@ int VLC_Create( void )
 {
     int i_ret;
     vlc_t * p_vlc = NULL;
-    vlc_mutex_t * p_libvlc_lock;
+    vlc_value_t lockval;
 
     /* vlc_threads_init *must* be the first internal call! No other call is
      * allowed before the thread system has been initialized. */
@@ -125,9 +139,10 @@ int VLC_Create( void )
     }
 
     /* Now that the thread system is initialized, we don't have much, but
-     * at least we have vlc_mutex_need */
-    p_libvlc_lock = vlc_mutex_need( &libvlc, "libvlc" );
-    vlc_mutex_lock( p_libvlc_lock );
+     * at least we have var_Create */
+    var_Create( &libvlc, "libvlc", VLC_VAR_MUTEX );
+    var_Get( &libvlc, "libvlc", &lockval );
+    vlc_mutex_lock( lockval.p_address );
     if( !libvlc.b_ready )
     {
         char *psz_env;
@@ -161,8 +176,8 @@ int VLC_Create( void )
 
         libvlc.b_ready = VLC_TRUE;
     }
-    vlc_mutex_unlock( p_libvlc_lock );
-    vlc_mutex_unneed( &libvlc, "libvlc" );
+    vlc_mutex_unlock( lockval.p_address );
+    var_Destroy( &libvlc, "libvlc" );
 
     /* Allocate a vlc object */
     p_vlc = vlc_object_create( &libvlc, VLC_OBJECT_VLC );
@@ -182,9 +197,6 @@ int VLC_Create( void )
     /* Store data for the non-reentrant API */
     p_static_vlc = p_vlc;
 
-    /* Update the handle status */
-    p_vlc->i_status = VLC_STATUS_CREATED;
-
     return p_vlc->i_object_id;
 }
 
@@ -208,32 +220,15 @@ int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
 
     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
 
-    /* Check that the handle is valid */
-    if( !p_vlc || p_vlc->i_status != VLC_STATUS_CREATED )
-    {
-        fprintf( stderr, "error: invalid status (!CREATED)\n" );
-        return VLC_ESTATUS;
-    }
-
-    /* Support for gettext */
-#if defined( ENABLE_NLS ) && defined ( HAVE_GETTEXT )
-#   if defined( HAVE_LOCALE_H ) && defined( HAVE_LC_MESSAGES )
-    if( !setlocale( LC_MESSAGES, "" ) )
-    {
-        fprintf( stderr, "warning: unsupported locale settings\n" );
-    }
-
-    setlocale( LC_CTYPE, "" );
-#   endif
-
-    if( !bindtextdomain( PACKAGE, LOCALEDIR ) )
+    if( !p_vlc )
     {
-        fprintf( stderr, "warning: no domain %s in directory %s\n",
-                 PACKAGE, LOCALEDIR );
+        return VLC_ENOOBJ;
     }
 
-    textdomain( PACKAGE );
-#endif
+    /*
+     * Support for gettext
+     */
+    SetLanguage( "" );
 
     /*
      * System specific initialization code
@@ -482,9 +477,6 @@ int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
         return VLC_EGENERIC;
     }
 
-    /* Update the handle status */
-    p_vlc->i_status = VLC_STATUS_STOPPED;
-
     /*
      * Get input filenames given as commandline arguments
      */
@@ -501,7 +493,7 @@ int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
  * separate thread. If b_block is set to 1, VLC_AddIntf will continue until
  * user requests to quit.
  *****************************************************************************/
-int VLC_AddIntf( int i_object, const char *psz_module, vlc_bool_t b_block )
+int VLC_AddIntf( int i_object, char const *psz_module, vlc_bool_t b_block )
 {
     int i_err;
     intf_thread_t *p_intf;
@@ -510,11 +502,9 @@ int VLC_AddIntf( int i_object, const char *psz_module, vlc_bool_t b_block )
 
     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
 
-    /* Check that the handle is valid */
-    if( !p_vlc || p_vlc->i_status != VLC_STATUS_RUNNING )
+    if( !p_vlc )
     {
-        fprintf( stderr, "error: invalid status (!RUNNING)\n" );
-        return VLC_ESTATUS;
+        return VLC_ENOOBJ;
     }
 
     if( psz_module )
@@ -566,52 +556,44 @@ int VLC_Destroy( int i_object )
 
     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
 
-    /* Check that the handle is valid */
-    if( !p_vlc || (p_vlc->i_status != VLC_STATUS_STOPPED
-                    && p_vlc->i_status != VLC_STATUS_CREATED) )
+    if( !p_vlc )
     {
-        fprintf( stderr, "error: invalid status "
-                         "(!STOPPED&&!CREATED)\n" );
-        return VLC_ESTATUS;
+        return VLC_ENOOBJ;
     }
 
-    if( p_vlc->i_status == VLC_STATUS_STOPPED )
+    /*
+     * Go back into channel 0 which is the network
+     */
+    if( config_GetInt( p_vlc, "network-channel" ) && p_vlc->p_channel )
     {
-        /*
-         * Go back into channel 0 which is the network
-         */
-        if( config_GetInt( p_vlc, "network-channel" ) && p_vlc->p_channel )
-        {
-            network_ChannelJoin( p_vlc, COMMON_CHANNEL );
-        }
-    
-        /*
-         * Free allocated memory
-         */
-        if( p_vlc->p_memcpy_module != NULL )
-        {
-            module_Unneed( p_vlc, p_vlc->p_memcpy_module );
-        }
-    
-        free( p_vlc->psz_homedir );
-    
-        /*
-         * XXX: Free module bank !
-         */
-        //module_EndBank( p_vlc );
-    
-        /*
-         * System specific cleaning code
-         */
-        system_End( p_vlc );
+        network_ChannelJoin( p_vlc, COMMON_CHANNEL );
+    }
     
-        /* Update the handle status */
-        p_vlc->i_status = VLC_STATUS_CREATED;
+    /*
+     * Free allocated memory
+     */
+    if( p_vlc->p_memcpy_module )
+    {
+        module_Unneed( p_vlc, p_vlc->p_memcpy_module );
+        p_vlc->p_memcpy_module = NULL;
     }
 
-    /* Update the handle status, just in case */
-    p_vlc->i_status = VLC_STATUS_NONE;
+    if( p_vlc->psz_homedir )
+    {
+        free( p_vlc->psz_homedir );
+        p_vlc->psz_homedir = NULL;
+    }
 
+    /*
+     * XXX: Free module bank !
+     */
+    //module_EndBank( p_vlc );
+    
+    /*
+     * System specific cleaning code
+     */
+    system_End( p_vlc );
+    
     /* Destroy mutexes */
     vlc_mutex_destroy( &p_vlc->config_lock );
 
@@ -639,8 +621,7 @@ int VLC_Die( int i_object )
 
     if( !p_vlc )
     {
-        fprintf( stderr, "error: invalid status (!EXIST)\n" );
-        return VLC_ESTATUS;
+        return VLC_ENOOBJ;
     }
 
     p_vlc->b_die = VLC_TRUE;
@@ -654,7 +635,7 @@ int VLC_Die( int i_object )
  * This function adds psz_target to the current playlist. If a playlist does
  * not exist, it will create one.
  *****************************************************************************/
-int VLC_AddTarget( int i_object, const char *psz_target, int i_mode, int i_pos )
+int VLC_AddTarget( int i_object, char const *psz_target, int i_mode, int i_pos )
 {
     int i_err;
     playlist_t *p_playlist;
@@ -662,11 +643,9 @@ int VLC_AddTarget( int i_object, const char *psz_target, int i_mode, int i_pos )
 
     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
 
-    if( !p_vlc || ( p_vlc->i_status != VLC_STATUS_STOPPED
-                     && p_vlc->i_status != VLC_STATUS_RUNNING ) )
+    if( !p_vlc )
     {
-        fprintf( stderr, "error: invalid status (!STOPPED&&!RUNNING)\n" );
-        return VLC_ESTATUS;
+        return VLC_ENOOBJ;
     }
 
     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
@@ -696,7 +675,7 @@ int VLC_AddTarget( int i_object, const char *psz_target, int i_mode, int i_pos )
  *****************************************************************************
  *
  *****************************************************************************/
-int VLC_Set( int i_object, const char *psz_var, vlc_value_t value )
+int VLC_Set( int i_object, char const *psz_var, vlc_value_t value )
 {
     vlc_t *p_vlc;
 
@@ -704,8 +683,7 @@ int VLC_Set( int i_object, const char *psz_var, vlc_value_t value )
 
     if( !p_vlc )
     {
-        fprintf( stderr, "error: invalid status\n" );
-        return VLC_ESTATUS;
+        return VLC_ENOOBJ;
     }
 
     /* FIXME: Temporary hack for Mozilla, if variable starts with conf:: then
@@ -713,7 +691,7 @@ int VLC_Set( int i_object, const char *psz_var, vlc_value_t value )
     if( !strncmp( psz_var, "conf::", 6 ) )
     {
         module_config_t *p_item;
-        const char *psz_newvar = psz_var + 6;
+        char const *psz_newvar = psz_var + 6;
 
         p_item = config_FindConfig( VLC_OBJECT(p_vlc), psz_newvar );
 
@@ -746,7 +724,7 @@ int VLC_Set( int i_object, const char *psz_var, vlc_value_t value )
  *****************************************************************************
  *
  *****************************************************************************/
-int VLC_Get( int i_object, const char *psz_var, vlc_value_t *p_value )
+int VLC_Get( int i_object, char const *psz_var, vlc_value_t *p_value )
 {
     vlc_t *p_vlc;
 
@@ -754,8 +732,7 @@ int VLC_Get( int i_object, const char *psz_var, vlc_value_t *p_value )
 
     if( !p_vlc )
     {
-        fprintf( stderr, "error: invalid status\n" );
-        return VLC_ESTATUS;
+        return VLC_ENOOBJ;
     }
 
     return var_Get( p_vlc, psz_var, p_value );
@@ -774,20 +751,16 @@ int VLC_Play( int i_object )
     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
 
     /* Check that the handle is valid */
-    if( !p_vlc || p_vlc->i_status != VLC_STATUS_STOPPED )
+    if( !p_vlc )
     {
-        fprintf( stderr, "error: invalid status (!STOPPED)\n" );
-        return VLC_ESTATUS;
+        return VLC_ENOOBJ;
     }
 
-    /* Update the handle status */
-    p_vlc->i_status = VLC_STATUS_RUNNING;
-
     p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
 
     if( !p_playlist )
     {
-        return VLC_EOBJECT;
+        return VLC_ENOOBJ;
     }
 
     vlc_mutex_lock( &p_playlist->object_lock );
@@ -820,11 +793,9 @@ int VLC_Stop( int i_object )
     p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
 
     /* Check that the handle is valid */
-    if( !p_vlc || ( p_vlc->i_status != VLC_STATUS_STOPPED
-                     && p_vlc->i_status != VLC_STATUS_RUNNING ) )
+    if( !p_vlc )
     {
-        fprintf( stderr, "error: invalid status (!STOPPED&&!RUNNING)\n" );
-        return VLC_ESTATUS;
+        return VLC_ENOOBJ;
     }
 
     /*
@@ -873,9 +844,6 @@ int VLC_Stop( int i_object )
         aout_Delete( p_aout );
     }
 
-    /* Update the handle status */
-    p_vlc->i_status = VLC_STATUS_STOPPED;
-
     return VLC_SUCCESS;
 }
 
@@ -891,14 +859,14 @@ int VLC_Pause( int i_object )
 
     if( !p_vlc )
     {
-        return VLC_ESTATUS;
+        return VLC_ENOOBJ;
     }
 
     p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );
 
     if( !p_input )
     {
-        return VLC_EOBJECT;
+        return VLC_ENOOBJ;
     }
 
     input_SetStatus( p_input, INPUT_STATUS_PAUSE );
@@ -919,14 +887,14 @@ int VLC_FullScreen( int i_object )
 
     if( !p_vlc )
     {
-        return VLC_ESTATUS;
+        return VLC_ENOOBJ;
     }
 
     p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD );
 
     if( !p_vout )
     {
-        return VLC_EOBJECT;
+        return VLC_ENOOBJ;
     }
 
     p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
@@ -937,6 +905,49 @@ int VLC_FullScreen( int i_object )
 
 /* following functions are local */
 
+/*****************************************************************************
+ * SetLanguage: set the interface language.
+ *****************************************************************************
+ * We set the LC_MESSAGES locale category for interface messages and buttons,
+ * as well as the LC_CTYPE category for string sorting and possible wide
+ * character support.
+ *****************************************************************************/
+static void SetLanguage ( char const *psz_lang )
+{
+#if defined( ENABLE_NLS ) \
+     && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
+
+#   if defined( HAVE_INCLUDED_GETTEXT ) && !defined( HAVE_LC_MESSAGES )
+    if( *psz_lang )
+    {
+        /* We set LC_ALL manually because it is the only way to set
+         * the language at runtime under eg. Windows. Beware that this
+         * makes the environment unconsistent when libvlc is unloaded and
+         * should probably be moved to a safer place like vlc.c. */
+        static char psz_lcall[20];
+        snprintf( psz_lcall, 19, "LC_ALL=%s", psz_lang );
+        psz_lcall[19] = '\0';
+        putenv( psz_lcall );
+    }
+#   endif
+
+#   if defined( HAVE_LC_MESSAGES )
+    setlocale( LC_MESSAGES, psz_lang );
+#   endif
+    setlocale( LC_CTYPE, psz_lang );
+
+    /* Specify where to find the locales for current domain */
+    if( !bindtextdomain( PACKAGE, LOCALEDIR ) )
+    {
+        fprintf( stderr, "warning: no domain %s in directory %s\n",
+                 PACKAGE, LOCALEDIR );
+    }
+
+    /* Set the default domain */
+    textdomain( PACKAGE );
+#endif
+}
+
 /*****************************************************************************
  * GetFilenames: parse command line options which are not flags
  *****************************************************************************
@@ -947,12 +958,19 @@ static int GetFilenames( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
     int i_opt;
 
     /* We assume that the remaining parameters are filenames */
-    for( i_opt = optind; i_opt < i_argc; i_opt++ )
+    for( i_opt = i_argc - 1; i_opt > optind; i_opt-- )
     {
         /* TODO: write an internal function of this one, to avoid
          *       unnecessary lookups. */
         VLC_AddTarget( p_vlc->i_object_id, ppsz_argv[ i_opt ],
-                          PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
+                       PLAYLIST_INSERT, 0 );
+    }
+
+    /* If there is at least one target, play it */
+    if( i_argc > optind )
+    {
+        VLC_AddTarget( p_vlc->i_object_id, ppsz_argv[ optind ],
+                       PLAYLIST_INSERT | PLAYLIST_GO, 0 );
     }
 
     return VLC_SUCCESS;
@@ -963,7 +981,7 @@ static int GetFilenames( vlc_t *p_vlc, int i_argc, char *ppsz_argv[] )
  *****************************************************************************
  * Print a short inline help. Message interface is initialized at this stage.
  *****************************************************************************/
-static void Usage( vlc_t *p_this, const char *psz_module_name )
+static void Usage( vlc_t *p_this, char const *psz_module_name )
 {
 #define FORMAT_STRING "      --%s%s%s%s%s%s%s %s%s\n"
     /* option name -------------'     | | | |  | |
@@ -1247,10 +1265,12 @@ static void Version( void )
 #ifdef WIN32 /*  */
 static void ShowConsole( void )
 {
+#   ifndef UNDER_CE
     AllocConsole();
     freopen( "CONOUT$", "w", stdout );
     freopen( "CONOUT$", "w", stderr );
     freopen( "CONIN$", "r", stdin );
+#   endif
     return;
 }
 #endif