libvlc.c 76.8 KB
Newer Older
1 2 3
/*****************************************************************************
 * libvlc.c: main libvlc source
 *****************************************************************************
4
 * Copyright (C) 1998-2006 the VideoLAN team
5
 * $Id$
6 7 8
 *
 * Authors: Vincent Seguin <seguin@via.ecp.fr>
 *          Samuel Hocevar <sam@zoy.org>
9
 *          Gildas Bazin <gbazin@videolan.org>
10
 *          Derk-Jan Hartman <hartman at videolan dot org>
11
 *          Rémi Denis-Courmont <rem # videolan : org>
12 13 14 15 16 17 18 19 20 21 22 23 24
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
Antoine Cellerier's avatar
Antoine Cellerier committed
25
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 27 28 29 30 31
 *****************************************************************************/

/*****************************************************************************
 * Pretend we are a builtin module
 *****************************************************************************/
#define MODULE_NAME main
32
#define MODULE_PATH main
33 34 35 36 37
#define __BUILTIN__

/*****************************************************************************
 * Preamble
 *****************************************************************************/
38
#include <vlc/vlc.h>
39
#include <vlc/input.h>
40

41
#include <errno.h>                                                 /* ENOMEM */
42 43 44 45 46 47 48 49 50 51
#include <stdio.h>                                              /* sprintf() */
#include <string.h>                                            /* strerror() */
#include <stdlib.h>                                                /* free() */

#ifndef WIN32
#   include <netinet/in.h>                            /* BSD: struct in_addr */
#endif

#ifdef HAVE_UNISTD_H
#   include <unistd.h>
Gildas Bazin's avatar
 
Gildas Bazin committed
52
#elif defined( WIN32 ) && !defined( UNDER_CE )
53 54 55
#   include <io.h>
#endif

56
#ifdef WIN32                       /* optind, getopt(), included in unistd.h */
57
#   include "extras/getopt.h"
58 59
#endif

60 61 62 63
#ifdef HAVE_LOCALE_H
#   include <locale.h>
#endif

64 65 66 67
#ifdef HAVE_HAL
#   include <hal/libhal.h>
#endif

68
#include "vlc_cpu.h"                                        /* CPU detection */
69
#include "os_specific.h"
70

71
#include "vlc_error.h"
72

73
#include "vlc_playlist.h"
74
#include "vlc_interface.h"
75 76 77

#include "audio_output.h"

78
#include "vlc_video.h"
79 80
#include "video_output.h"

81
#include "stream_output.h"
82
#include "charset.h"
83

84 85 86
#include "libvlc.h"

/*****************************************************************************
87
 * The evil global variable. We handle it with care, don't worry.
88
 *****************************************************************************/
89 90 91
static libvlc_t   libvlc;
static libvlc_t * p_libvlc;
static vlc_t *    p_static_vlc;
92 93 94 95

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
96 97 98 99
static int AddIntfInternal( int i_object, char const *psz_module,
                             vlc_bool_t b_block, vlc_bool_t b_play,
                             int i_options, char **ppsz_options );

100 101
void LocaleInit( vlc_object_t * );
void LocaleDeinit( void );
Sam Hocevar's avatar
Sam Hocevar committed
102
static void SetLanguage   ( char const * );
103
static int  GetFilenames  ( vlc_t *, int, char *[] );
104
static void Help          ( vlc_t *, char const *psz_help_name );
105
static void Usage         ( vlc_t *, char const *psz_module_name );
106
static void ListModules   ( vlc_t * );
107 108 109
static void Version       ( void );

#ifdef WIN32
110
static void ShowConsole   ( vlc_bool_t );
111
static void PauseConsole  ( void );
112
#endif
113
static int  ConsoleWidth  ( void );
114

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
115 116
static int  VerboseCallback( vlc_object_t *, char const *,
                             vlc_value_t, vlc_value_t, void * );
117

118 119
static void InitDeviceValues( vlc_t * );

120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
/*****************************************************************************
 * vlc_current_object: return the current object.
 *****************************************************************************
 * If i_object is non-zero, return the corresponding object. Otherwise,
 * return the statically allocated p_vlc object.
 *****************************************************************************/
vlc_t * vlc_current_object( int i_object )
{
    if( i_object )
    {
         return vlc_object_get( p_libvlc, i_object );
    }

    return p_static_vlc;
}

136
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
137
 * VLC_Version: return the libvlc version.
138
 *****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
139
 * This function returns full version string (numeric version and codename).
140
 *****************************************************************************/
141
char const * VLC_Version( void )
142
{
Sam Hocevar's avatar
Sam Hocevar committed
143
    return VERSION_MESSAGE;
144 145
}

146
/*****************************************************************************
147
 * VLC_CompileBy, VLC_CompileHost, VLC_CompileDomain,
148 149 150 151 152
 * VLC_Compiler, VLC_Changeset
 *****************************************************************************/
#define DECLARE_VLC_VERSION( func, var )                                    \
char const * VLC_##func ( void )                                            \
{                                                                           \
153
    return VLC_##var ;                                                      \
154 155
}

156 157
DECLARE_VLC_VERSION( CompileBy, COMPILE_BY );
DECLARE_VLC_VERSION( CompileHost, COMPILE_HOST );
Christophe Mutricy's avatar
Typo  
Christophe Mutricy committed
158
DECLARE_VLC_VERSION( CompileDomain, COMPILE_DOMAIN );
159 160
DECLARE_VLC_VERSION( Compiler, COMPILER );

161
#ifndef HAVE_SHARED_LIBVLC
162 163 164 165 166
extern const char psz_vlc_changeset[];
char const * VLC_Changeset( void )
{
    return psz_vlc_changeset;
}
167
#endif
168

169 170 171 172 173 174 175 176 177 178
/*****************************************************************************
 * 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 );
}

Sam Hocevar's avatar
Sam Hocevar committed
179 180 181 182 183 184 185
/*****************************************************************************
 * VLC_Create: allocate a vlc_t structure, and initialize libvlc if needed.
 *****************************************************************************
 * This function allocates a vlc_t structure and returns a negative value
 * in case of failure. Also, the thread system is initialized.
 *****************************************************************************/
int VLC_Create( void )
186
{
187
    int i_ret;
188
    vlc_t * p_vlc = NULL;
189
    vlc_value_t lockval;
190

191 192 193
    /* &libvlc never changes, so we can safely call this multiple times. */
    p_libvlc = &libvlc;

194 195
    /* vlc_threads_init *must* be the first internal call! No other call is
     * allowed before the thread system has been initialized. */
196
    i_ret = vlc_threads_init( p_libvlc );
Sam Hocevar's avatar
Sam Hocevar committed
197
    if( i_ret < 0 )
198
    {
Sam Hocevar's avatar
Sam Hocevar committed
199
        return i_ret;
200 201 202
    }

    /* Now that the thread system is initialized, we don't have much, but
203
     * at least we have var_Create */
204 205
    var_Create( p_libvlc, "libvlc", VLC_VAR_MUTEX );
    var_Get( p_libvlc, "libvlc", &lockval );
206
    vlc_mutex_lock( lockval.p_address );
207 208
    if( !libvlc.b_ready )
    {
209 210
        char *psz_env;

211 212 213
        /* Guess what CPU we have */
        libvlc.i_cpu = CPUCapabilities();

214 215
        /* Find verbosity from VLC_VERBOSE environment variable */
        psz_env = getenv( "VLC_VERBOSE" );
216
        libvlc.i_verbose = psz_env ? atoi( psz_env ) : -1;
217

Gildas Bazin's avatar
 
Gildas Bazin committed
218
#if defined( HAVE_ISATTY ) && !defined( WIN32 )
219 220 221 222 223
        libvlc.b_color = isatty( 2 ); /* 2 is for stderr */
#else
        libvlc.b_color = VLC_FALSE;
#endif

224
        /* Initialize message queue */
225
        msg_Create( p_libvlc );
226 227

        /* Announce who we are */
228 229
        msg_Dbg( p_libvlc, COPYRIGHT_MESSAGE );
        msg_Dbg( p_libvlc, "libvlc was configured with %s", CONFIGURE_LINE );
230

231 232
        /* The module bank will be initialized later */
        libvlc.p_module_bank = NULL;
233 234

        libvlc.b_ready = VLC_TRUE;
235
    }
236
    vlc_mutex_unlock( lockval.p_address );
237
    var_Destroy( p_libvlc, "libvlc" );
238 239

    /* Allocate a vlc object */
240
    p_vlc = vlc_object_create( p_libvlc, VLC_OBJECT_VLC );
241 242
    if( p_vlc == NULL )
    {
Sam Hocevar's avatar
Sam Hocevar committed
243
        return VLC_EGENERIC;
244
    }
245
    p_vlc->thread_id = 0;
246 247 248 249

    p_vlc->psz_object_name = "root";

    /* Initialize mutexes */
250
    vlc_mutex_init( p_vlc, &p_vlc->config_lock );
251
#ifdef __APPLE__
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
252
    vlc_mutex_init( p_vlc, &p_vlc->quicktime_lock );
253
    vlc_thread_set_priority( p_vlc, VLC_THREAD_PRIORITY_LOW );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
254
#endif
255 256

    /* Store our newly allocated structure in the global list */
257
    vlc_object_attach( p_vlc, p_libvlc );
258

Sam Hocevar's avatar
Sam Hocevar committed
259 260 261 262
    /* Store data for the non-reentrant API */
    p_static_vlc = p_vlc;

    return p_vlc->i_object_id;
263 264 265
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
266
 * VLC_Init: initialize a vlc_t structure.
267 268 269 270 271 272 273
 *****************************************************************************
 * This function initializes a previously allocated vlc_t structure:
 *  - CPU detection
 *  - gettext initialization
 *  - message queue, module bank and playlist initialization
 *  - configuration and commandline parsing
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
274
int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
275
{
276 277
    char         p_capabilities[200];
    char *       p_tmp;
278 279
    char *       psz_modules;
    char *       psz_parser;
280
    char *       psz_control;
281
    vlc_bool_t   b_exit = VLC_FALSE;
282
    int          i_ret = VLC_EEXIT;
283
    vlc_t *      p_vlc = vlc_current_object( i_object );
284 285
    module_t    *p_help_module;
    playlist_t  *p_playlist;
286
    vlc_value_t  val;
287 288
#if defined( ENABLE_NLS ) \
     && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
289
    char *       psz_language;
290
#endif
291

292
    if( !p_vlc )
293
    {
294
        return VLC_ENOOBJ;
295 296 297
    }

    /*
298
     * System specific initialization code
299
     */
300
    system_Init( p_vlc, &i_argc, ppsz_argv );
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316

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

317 318 319 320
    /*
     * Support for gettext
     */
    SetLanguage( "" );
Sam Hocevar's avatar
Sam Hocevar committed
321

322 323 324 325
    /*
     * Global iconv, must be done after setlocale()
     * so that vlc_current_charset() works.
     */
326
    LocaleInit( (vlc_object_t *)p_vlc );
327

Sam Hocevar's avatar
Sam Hocevar committed
328
    /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
329 330
    msg_Dbg( p_vlc, "translation test: code is \"%s\"", _("C") );

331 332 333 334
    /* Initialize the module bank and load the configuration of the
     * main module. We need to do this at this stage to be able to display
     * a short help if required by the user. (short help == main module
     * options) */
335
    module_InitBank( p_vlc );
336

337 338 339 340
    /* Hack: insert the help module here */
    p_help_module = vlc_object_create( p_vlc, VLC_OBJECT_MODULE );
    if( p_help_module == NULL )
    {
341
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
342
        if( i_object ) vlc_object_release( p_vlc );
343 344 345
        return VLC_EGENERIC;
    }
    p_help_module->psz_object_name = "help";
Gildas Bazin's avatar
 
Gildas Bazin committed
346
    p_help_module->psz_longname = N_("Help options");
347
    config_Duplicate( p_help_module, p_help_config );
348
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
349 350
    /* End hack */

Sam Hocevar's avatar
Sam Hocevar committed
351
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
352
    {
353
        vlc_object_detach( p_help_module );
354 355
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
356
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
357
        if( i_object ) vlc_object_release( p_vlc );
358 359 360 361 362 363
        return VLC_EGENERIC;
    }

    /* Check for short help option */
    if( config_GetInt( p_vlc, "help" ) )
    {
364
        Help( p_vlc, "help" );
365
        b_exit = VLC_TRUE;
366
        i_ret = VLC_EEXITSUCCESS;
367 368
    }
    /* Check for version option */
369
    else if( config_GetInt( p_vlc, "version" ) )
370 371
    {
        Version();
372
        b_exit = VLC_TRUE;
373
        i_ret = VLC_EEXITSUCCESS;
374 375
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
376 377
    /* Set the config file stuff */
    p_vlc->psz_homedir = config_GetHomeDir();
378 379 380
    p_vlc->psz_userdir = config_GetUserDir();
    if( p_vlc->psz_userdir == NULL )
        p_vlc->psz_userdir = strdup(p_vlc->psz_homedir);
Gildas Bazin's avatar
 
Gildas Bazin committed
381
    p_vlc->psz_configfile = config_GetPsz( p_vlc, "config" );
382 383 384
    if( p_vlc->psz_configfile != NULL && p_vlc->psz_configfile[0] == '~'
         && p_vlc->psz_configfile[1] == '/' )
    {
385
        char *psz = malloc( strlen(p_vlc->psz_userdir)
386 387
                             + strlen(p_vlc->psz_configfile) );
        /* This is incomplete : we should also support the ~cmassiot/ syntax. */
388
        sprintf( psz, "%s/%s", p_vlc->psz_userdir,
389 390 391 392
                               p_vlc->psz_configfile + 2 );
        free( p_vlc->psz_configfile );
        p_vlc->psz_configfile = psz;
    }
Gildas Bazin's avatar
 
Gildas Bazin committed
393

394 395 396 397 398 399
    /* Check for plugins cache options */
    if( config_GetInt( p_vlc, "reset-plugins-cache" ) )
    {
        libvlc.p_module_bank->b_cache_delete = VLC_TRUE;
    }

400 401 402 403
    /* Hack: remove the help module here */
    vlc_object_detach( p_help_module );
    /* End hack */

Gildas Bazin's avatar
Gildas Bazin committed
404 405 406 407 408 409 410
    /* Will be re-done properly later on */
    p_vlc->p_libvlc->i_verbose = config_GetInt( p_vlc, "verbose" );

    /* Check for daemon mode */
#ifndef WIN32
    if( config_GetInt( p_vlc, "daemon" ) )
    {
411
#if HAVE_DAEMON
412
        if( daemon( 1, 0) != 0 )
413 414 415 416 417 418 419 420 421
        {
            msg_Err( p_vlc, "Unable to fork vlc to daemon mode" );
            b_exit = VLC_TRUE;
        }

        p_vlc->p_libvlc->b_daemon = VLC_TRUE;

#else
        pid_t i_pid;
Gildas Bazin's avatar
Gildas Bazin committed
422 423 424 425 426 427 428 429 430 431 432

        if( ( i_pid = fork() ) < 0 )
        {
            msg_Err( p_vlc, "Unable to fork vlc to daemon mode" );
            b_exit = VLC_TRUE;
        }
        else if( i_pid )
        {
            /* This is the parent, exit right now */
            msg_Dbg( p_vlc, "closing parent process" );
            b_exit = VLC_TRUE;
433
            i_ret = VLC_EEXITSUCCESS;
Gildas Bazin's avatar
Gildas Bazin committed
434 435 436 437 438
        }
        else
        {
            /* We are the child */
            msg_Dbg( p_vlc, "daemon spawned" );
439 440 441
            close( STDIN_FILENO );
            close( STDOUT_FILENO );
            close( STDERR_FILENO );
Gildas Bazin's avatar
Gildas Bazin committed
442 443 444

            p_vlc->p_libvlc->b_daemon = VLC_TRUE;
        }
445
#endif
Gildas Bazin's avatar
Gildas Bazin committed
446 447 448
    }
#endif

449 450
    if( b_exit )
    {
451 452
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
453
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
454
        if( i_object ) vlc_object_release( p_vlc );
455
        return i_ret;
456 457
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
458
    /* Check for translation config option */
Gildas Bazin's avatar
 
Gildas Bazin committed
459 460
#if defined( ENABLE_NLS ) \
     && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
461
# if defined (WIN32) || defined (__APPLE__)
Gildas Bazin's avatar
 
Gildas Bazin committed
462 463 464 465 466
    /* This ain't really nice to have to reload the config here but it seems
     * the only way to do it. */
    config_LoadConfigFile( p_vlc, "main" );
    config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );

467 468 469
    /* Check if the user specified a custom language */
    psz_language = config_GetPsz( p_vlc, "language" );
    if( psz_language && *psz_language && strcmp( psz_language, "auto" ) )
Gildas Bazin's avatar
 
Gildas Bazin committed
470
    {
471 472
        vlc_bool_t b_cache_delete = libvlc.p_module_bank->b_cache_delete;

Gildas Bazin's avatar
 
Gildas Bazin committed
473
        /* Reset the default domain */
474
        SetLanguage( psz_language );
475

Gildas Bazin's avatar
 
Gildas Bazin committed
476 477 478
        /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
        msg_Dbg( p_vlc, "translation test: code is \"%s\"", _("C") );

Gildas Bazin's avatar
 
Gildas Bazin committed
479
        module_EndBank( p_vlc );
480
        module_InitBank( p_vlc );
481
        config_LoadConfigFile( p_vlc, "main" );
Gildas Bazin's avatar
 
Gildas Bazin committed
482
        config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
483
        libvlc.p_module_bank->b_cache_delete = b_cache_delete;
Gildas Bazin's avatar
 
Gildas Bazin committed
484
    }
485
    if( psz_language ) free( psz_language );
486
# endif
487
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
488

489 490 491 492 493 494
    /*
     * Load the builtins and plugins into the module_bank.
     * We have to do it before config_Load*() because this also gets the
     * list of configuration options exported by each module and loads their
     * default values.
     */
495 496 497 498 499 500 501
    module_LoadBuiltins( p_vlc );
    module_LoadPlugins( p_vlc );
    if( p_vlc->b_die )
    {
        b_exit = VLC_TRUE;
    }

502
    msg_Dbg( p_vlc, "module bank initialized, found %i modules",
503
                    libvlc.p_module_bank->i_children );
504 505

    /* Hack: insert the help module here */
506
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
507 508 509 510 511
    /* End hack */

    /* Check for help on modules */
    if( (p_tmp = config_GetPsz( p_vlc, "module" )) )
    {
512
        Help( p_vlc, p_tmp );
513
        free( p_tmp );
514
        b_exit = VLC_TRUE;
515
        i_ret = VLC_EEXITSUCCESS;
516 517
    }
    /* Check for long help option */
518
    else if( config_GetInt( p_vlc, "longhelp" ) )
519
    {
520
        Help( p_vlc, "longhelp" );
521
        b_exit = VLC_TRUE;
522
        i_ret = VLC_EEXITSUCCESS;
523 524
    }
    /* Check for module list option */
525
    else if( config_GetInt( p_vlc, "list" ) )
526
    {
527
        ListModules( p_vlc );
528
        b_exit = VLC_TRUE;
529
        i_ret = VLC_EEXITSUCCESS;
530 531
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
    /* Check for config file options */
    if( config_GetInt( p_vlc, "reset-config" ) )
    {
        vlc_object_detach( p_help_module );
        config_ResetAll( p_vlc );
        config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
        config_SaveConfigFile( p_vlc, NULL );
        vlc_object_attach( p_help_module, libvlc.p_module_bank );
    }
    if( config_GetInt( p_vlc, "save-config" ) )
    {
        vlc_object_detach( p_help_module );
        config_LoadConfigFile( p_vlc, NULL );
        config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
        config_SaveConfigFile( p_vlc, NULL );
        vlc_object_attach( p_help_module, libvlc.p_module_bank );
    }

550
    /* Hack: remove the help module here */
551
    vlc_object_detach( p_help_module );
552 553
    /* End hack */

554 555
    if( b_exit )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
556 557
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
558
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
559
        if( i_object ) vlc_object_release( p_vlc );
560
        return i_ret;
561 562
    }

563 564 565 566 567
    /*
     * Init device values
     */
    InitDeviceValues( p_vlc );

568 569 570
    /*
     * Override default configuration with config file settings
     */
571
    config_LoadConfigFile( p_vlc, NULL );
572

Gildas Bazin's avatar
 
Gildas Bazin committed
573 574 575 576
    /* Hack: insert the help module here */
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
    /* End hack */

577 578 579
    /*
     * Override configuration with command line settings
     */
Sam Hocevar's avatar
Sam Hocevar committed
580
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
581 582
    {
#ifdef WIN32
583
        ShowConsole( VLC_FALSE );
584 585
        /* Pause the console because it's destroyed when we exit */
        fprintf( stderr, "The command line options couldn't be loaded, check "
586 587
                 "that they are valid.\n" );
        PauseConsole();
588
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
589 590 591
        vlc_object_detach( p_help_module );
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
592
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
593
        if( i_object ) vlc_object_release( p_vlc );
594 595 596
        return VLC_EGENERIC;
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
597 598 599 600 601 602
    /* Hack: remove the help module here */
    vlc_object_detach( p_help_module );
    config_Free( p_help_module );
    vlc_object_destroy( p_help_module );
    /* End hack */

603 604 605
    /*
     * System specific configuration
     */
Gildas Bazin's avatar
 
Gildas Bazin committed
606
    system_Configure( p_vlc, &i_argc, ppsz_argv );
607

608 609 610
    /*
     * Message queue options
     */
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
611 612

    var_Create( p_vlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
613 614
    if( config_GetInt( p_vlc, "quiet" ) )
    {
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
615 616
        val.i_int = -1;
        var_Set( p_vlc, "verbose", val );
617
    }
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
618 619
    var_AddCallback( p_vlc, "verbose", VerboseCallback, NULL );
    var_Change( p_vlc, "verbose", VLC_VAR_TRIGGER_CALLBACKS, NULL, NULL );
Clément Stenac's avatar
Clément Stenac committed
620

Gildas Bazin's avatar
 
Gildas Bazin committed
621
    libvlc.b_color = libvlc.b_color && config_GetInt( p_vlc, "color" );
622

623 624 625 626 627
    /*
     * Output messages that may still be in the queue
     */
    msg_Flush( p_vlc );

628
    /* p_vlc initialization. FIXME ? */
629

630 631 632
    if( !config_GetInt( p_vlc, "fpu" ) )
        libvlc.i_cpu &= ~CPU_CAPABILITY_FPU;

Christophe Massiot's avatar
Christophe Massiot committed
633
#if defined( __i386__ ) || defined( __x86_64__ )
634
    if( !config_GetInt( p_vlc, "mmx" ) )
635
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMX;
636
    if( !config_GetInt( p_vlc, "3dn" ) )
637
        libvlc.i_cpu &= ~CPU_CAPABILITY_3DNOW;
638
    if( !config_GetInt( p_vlc, "mmxext" ) )
639
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMXEXT;
640
    if( !config_GetInt( p_vlc, "sse" ) )
641
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE;
642 643
    if( !config_GetInt( p_vlc, "sse2" ) )
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE2;
644
#endif
645
#if defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ )
646
    if( !config_GetInt( p_vlc, "altivec" ) )
647
        libvlc.i_cpu &= ~CPU_CAPABILITY_ALTIVEC;
648
#endif
649 650

#define PRINT_CAPABILITY( capability, string )                              \
651
    if( libvlc.i_cpu & capability )                                         \
652 653 654 655 656 657 658 659 660 661 662 663 664 665
    {                                                                       \
        strncat( p_capabilities, string " ",                                \
                 sizeof(p_capabilities) - strlen(p_capabilities) );         \
        p_capabilities[sizeof(p_capabilities) - 1] = '\0';                  \
    }

    p_capabilities[0] = '\0';
    PRINT_CAPABILITY( CPU_CAPABILITY_486, "486" );
    PRINT_CAPABILITY( CPU_CAPABILITY_586, "586" );
    PRINT_CAPABILITY( CPU_CAPABILITY_PPRO, "Pentium Pro" );
    PRINT_CAPABILITY( CPU_CAPABILITY_MMX, "MMX" );
    PRINT_CAPABILITY( CPU_CAPABILITY_3DNOW, "3DNow!" );
    PRINT_CAPABILITY( CPU_CAPABILITY_MMXEXT, "MMXEXT" );
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE, "SSE" );
666
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE2, "SSE2" );
667 668 669 670 671 672 673
    PRINT_CAPABILITY( CPU_CAPABILITY_ALTIVEC, "AltiVec" );
    PRINT_CAPABILITY( CPU_CAPABILITY_FPU, "FPU" );
    msg_Dbg( p_vlc, "CPU has capabilities %s", p_capabilities );

    /*
     * Choose the best memcpy module
     */
Gildas Bazin's avatar
 
Gildas Bazin committed
674
    p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy", 0 );
675

676
    if( p_vlc->pf_memcpy == NULL )
677 678 679
    {
        p_vlc->pf_memcpy = memcpy;
    }
680 681 682 683 684

    if( p_vlc->pf_memset == NULL )
    {
        p_vlc->pf_memset = memset;
    }
685

686
    libvlc.b_stats = config_GetInt( p_vlc, "stats" );
687
    libvlc.p_stats = NULL;
688

Sigmund Augdal Helberg's avatar
Sigmund Augdal Helberg committed
689 690 691 692
    /*
     * Initialize hotkey handling
     */
    var_Create( p_vlc, "key-pressed", VLC_VAR_INTEGER );
Gildas Bazin's avatar
 
Gildas Bazin committed
693 694
    p_vlc->p_hotkeys = malloc( sizeof(p_hotkeys) );
    /* Do a copy (we don't need to modify the strings) */
695
    memcpy( p_vlc->p_hotkeys, p_hotkeys, sizeof(p_hotkeys) );
Gildas Bazin's avatar
 
Gildas Bazin committed
696

697 698 699
    /*
     * Initialize playlist and get commandline files
     */
700
    p_playlist = playlist_ThreadCreate( p_vlc );
701 702 703
    if( !p_playlist )
    {
        msg_Err( p_vlc, "playlist initialization failed" );
704 705
        if( p_vlc->p_memcpy_module != NULL )
        {
706
            module_Unneed( p_vlc, p_vlc->p_memcpy_module );
707
        }
708
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
709
        if( i_object ) vlc_object_release( p_vlc );
710 711 712
        return VLC_EGENERIC;
    }

713 714 715 716 717 718 719
    psz_modules = config_GetPsz( p_playlist, "services-discovery" );
    if( psz_modules && *psz_modules )
    {
        /* Add service discovery modules */
        playlist_AddSDModules( p_playlist, psz_modules );
    }
    if( psz_modules ) free( psz_modules );
720

721 722 723 724
    /*
     * Load background interfaces
     */
    psz_modules = config_GetPsz( p_vlc, "extraintf" );
725 726 727 728 729 730
    psz_control = config_GetPsz( p_vlc, "control" );

    if( psz_modules && *psz_modules && psz_control && *psz_control )
    {
        psz_modules = (char *)realloc( psz_modules, strlen( psz_modules ) +
                                                    strlen( psz_control ) + 1 );
731
        sprintf( psz_modules, "%s:%s", psz_modules, psz_control );
732 733 734 735 736 737 738
    }
    else if( psz_control && *psz_control )
    {
        if( psz_modules ) free( psz_modules );
        psz_modules = strdup( psz_control );
    }

739 740 741
    psz_parser = psz_modules;
    while ( psz_parser && *psz_parser )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
742
        char *psz_module, *psz_temp;
743
        psz_module = psz_parser;
744
        psz_parser = strchr( psz_module, ':' );
745 746 747 748 749
        if ( psz_parser )
        {
            *psz_parser = '\0';
            psz_parser++;
        }
Gildas Bazin's avatar
 
Gildas Bazin committed
750 751 752 753
        psz_temp = (char *)malloc( strlen(psz_module) + sizeof(",none") );
        if( psz_temp )
        {
            sprintf( psz_temp, "%s,none", psz_module );
754
            VLC_AddIntf( 0, psz_temp, VLC_FALSE, VLC_FALSE );
Gildas Bazin's avatar
 
Gildas Bazin committed
755 756
            free( psz_temp );
        }
757 758 759 760 761
    }
    if ( psz_modules )
    {
        free( psz_modules );
    }
762

Sigmund Augdal Helberg's avatar
Sigmund Augdal Helberg committed
763
    /*
764
     * Always load the hotkeys interface if it exists
Sigmund Augdal Helberg's avatar
Sigmund Augdal Helberg committed
765
     */
766
    VLC_AddIntf( 0, "hotkeys,none", VLC_FALSE, VLC_FALSE );
Sigmund Augdal Helberg's avatar
Sigmund Augdal Helberg committed
767

768 769 770 771 772 773 774
    /*
     * If needed, load the Xscreensaver interface
     * Currently, only for X
     */
#ifdef HAVE_X11_XLIB_H
    if( config_GetInt( p_vlc, "disable-screensaver" ) == 1 )
    {
775
        VLC_AddIntf( 0, "screensaver,none", VLC_FALSE, VLC_FALSE );
776 777 778
    }
#endif

779 780
    if( config_GetInt( p_vlc, "file-logging" ) == 1 )
    {
781
        VLC_AddIntf( 0, "logger,none", VLC_FALSE, VLC_FALSE );
782
    }
783
#ifdef HAVE_SYSLOG_H
784 785 786
    if( config_GetInt( p_vlc, "syslog" ) == 1 )
    {
        char *psz_logmode = "logmode=syslog";
787
        AddIntfInternal( 0, "logger,none", VLC_FALSE, VLC_FALSE, 1, &psz_logmode );
788
    }
789
#endif
790

791 792
    if( config_GetInt( p_vlc, "show-intf" ) == 1 )
    {
793
        VLC_AddIntf( 0, "showintf,none", VLC_FALSE, VLC_FALSE );
794 795 796 797
    }

    if( config_GetInt( p_vlc, "network-synchronisation") == 1 )
    {
798
        VLC_AddIntf( 0, "netsync,none", VLC_FALSE, VLC_FALSE );
799 800
    }

801 802 803 804
    /*
     * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin
     */
    var_Create( p_vlc, "drawable", VLC_VAR_INTEGER );
805 806 807 808 809 810 811 812 813 814 815
    var_Create( p_vlc, "drawableredraw", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawablet", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawablel", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawableb", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawabler", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawablex", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawabley", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawablew", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawableh", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawableportx", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawableporty", VLC_VAR_INTEGER );
816

817 818 819
    /* Create volume callback system. */
    var_Create( p_vlc, "volume-change", VLC_VAR_BOOL );

820 821 822 823 824
    /*
     * Get input filenames given as commandline arguments
     */
    GetFilenames( p_vlc, i_argc, ppsz_argv );

825 826 827 828 829 830 831 832 833 834 835 836
    /*
     * Get --open argument
     */
    var_Create( p_vlc, "open", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
    var_Get( p_vlc, "open", &val );
    if ( val.psz_string != NULL && *val.psz_string )
    {
        VLC_AddTarget( p_vlc->i_object_id, val.psz_string, NULL, 0,
                       PLAYLIST_INSERT, 0 );
    }
    if ( val.psz_string != NULL ) free( val.psz_string );

Gildas Bazin's avatar
 
Gildas Bazin committed
837
    if( i_object ) vlc_object_release( p_vlc );
838 839 840 841
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
842
 * VLC_AddIntf: add an interface
843 844
 *****************************************************************************
 * This function opens an interface plugin and runs it. If b_block is set
Sam Hocevar's avatar
Sam Hocevar committed
845 846
 * to 0, VLC_AddIntf will return immediately and let the interface run in a
 * separate thread. If b_block is set to 1, VLC_AddIntf will continue until
847 848
 * user requests to quit. If b_play is set to 1, VLC_AddIntf will start playing
 * the playlist when it is completely initialised.
849
 *****************************************************************************/
850 851
int VLC_AddIntf( int i_object, char const *psz_module,
                 vlc_bool_t b_block, vlc_bool_t b_play )
852
{
853
    return AddIntfInternal( i_object, psz_module, b_block, b_play, 0, NULL );
854 855
}

856

857
/*****************************************************************************
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887
 * VLC_Die: ask vlc to die.
 *****************************************************************************
 * This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
 * task. It is your duty to call VLC_CleanUp and VLC_Destroy afterwards.
 *****************************************************************************/
int VLC_Die( int i_object )
{
    vlc_t *p_vlc = vlc_current_object( i_object );

    if( !p_vlc )
    {
        return VLC_ENOOBJ;
    }

    p_vlc->b_die = VLC_TRUE;

    if( i_object ) vlc_object_release( p_vlc );
    return VLC_SUCCESS;
}

/*****************************************************************************
 * VLC_CleanUp: CleanUp all the intf, playlist, vout, aout
 *****************************************************************************/
int VLC_CleanUp( int i_object )
{
    intf_thread_t      * p_intf;
    playlist_t         * p_playlist;
    vout_thread_t      * p_vout;
    aout_instance_t    * p_aout;
    announce_handler_t * p_announce;
888
    stats_handler_t    * p_stats;
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909
    vlc_t *p_vlc = vlc_current_object( i_object );

    /* Check that the handle is valid */
    if( !p_vlc )
    {
        return VLC_ENOOBJ;
    }

    /*
     * Ask the interfaces to stop and destroy them
     */
    msg_Dbg( p_vlc, "removing all interfaces" );
    while( (p_intf = vlc_object_find( p_vlc, VLC_OBJECT_INTF, FIND_CHILD )) )
    {
        intf_StopThread( p_intf );
        vlc_object_detach( p_intf );
        vlc_object_release( p_intf );
        intf_Destroy( p_intf );
    }

    /*
Clément Stenac's avatar
Clément Stenac committed
910
     * Free playlist
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
911
     */
Clément Stenac's avatar
Clément Stenac committed
912
    msg_Dbg( p_vlc, "removing playlist handler" );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
913 914 915 916 917
    while( (p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST,
                                          FIND_CHILD )) )
    {
        vlc_object_detach( p_playlist );
        vlc_object_release( p_playlist );
918
        playlist_ThreadDestroy( p_playlist );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942
    }

    /*
     * Free video outputs
     */
    msg_Dbg( p_vlc, "removing all video outputs" );
    while( (p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD )) )
    {
        vlc_object_detach( p_vout );
        vlc_object_release( p_vout );
        vout_Destroy( p_vout );
    }

    /*
     * Free audio outputs
     */
    msg_Dbg( p_vlc, "removing all audio outputs" );
    while( (p_aout = vlc_object_find( p_vlc, VLC_OBJECT_AOUT, FIND_CHILD )) )
    {
        vlc_object_detach( (vlc_object_t *)p_aout );
        vlc_object_release( (vlc_object_t *)p_aout );
        aout_Delete( p_aout );
    }

943 944
    while( ( p_stats = vlc_object_find( p_vlc, VLC_OBJECT_STATS, FIND_CHILD) ))
    {
945
        stats_TimersDumpAll( p_vlc );
Clément Stenac's avatar
Clément Stenac committed
946
        stats_HandlerDestroy( p_stats );
947 948 949 950 951
        vlc_object_detach( (vlc_object_t*) p_stats );
        vlc_object_release( (vlc_object_t *)p_stats );
        // TODO: Delete it
    }

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
952 953 954 955 956
    /*
     * Free announce handler(s?)
     */
    while( (p_announce = vlc_object_find( p_vlc, VLC_OBJECT_ANNOUNCE,
                                                 FIND_CHILD ) ) )
Clément Stenac's avatar
Clément Stenac committed
957 958
    {
        msg_Dbg( p_vlc, "removing announce handler" );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
959 960 961
        vlc_object_detach( p_announce );
        vlc_object_release( p_announce );
        announce_HandlerDestroy( p_announce );
Clément Stenac's avatar
Clément Stenac committed
962
    }
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
963 964 965 966 967 968 969

    if( i_object ) vlc_object_release( p_vlc );
    return VLC_SUCCESS;
}

/*****************************************************************************
 * VLC_Destroy: Destroy everything.
970
 *****************************************************************************
971
 * This function requests the running threads to finish, waits for their
972 973
 * termination, and destroys their structure.
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
974
int VLC_Destroy( int i_object )
975
{
976
    vlc_t *p_vlc = vlc_current_object( i_object );
977

978
    if( !p_vlc )
979
    {
980
        return VLC_ENOOBJ;
981 982
    }

983 984 985 986 987 988 989
    /*
     * Free allocated memory
     */
    if( p_vlc->p_memcpy_module )
    {
        module_Unneed( p_vlc, p_vlc->p_memcpy_module );
        p_vlc->p_memcpy_module = NULL;
990 991
    }

992
    /*
993
     * Free module bank !
994 995 996
     */
    module_EndBank( p_vlc );

997 998 999 1000 1001
    if( p_vlc->psz_homedir )
    {
        free( p_vlc->psz_homedir );
        p_vlc->psz_homedir = NULL;
    }
1002

1003 1004 1005 1006 1007 1008
    if( p_vlc->psz_userdir )
    {
        free( p_vlc->psz_userdir );
        p_vlc->psz_userdir = NULL;
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
1009 1010 1011 1012 1013 1014
    if( p_vlc->psz_configfile )
    {
        free( p_vlc->psz_configfile );
        p_vlc->psz_configfile = NULL;
    }

1015 1016 1017 1018 1019 1020
    if( p_vlc->p_hotkeys )
    {
        free( p_vlc->p_hotkeys );
        p_vlc->p_hotkeys = NULL;
    }

1021 1022 1023 1024
    /*
     * System specific cleaning code
     */
    system_End( p_vlc );
1025

1026 1027 1028 1029 1030 1031 1032
    /*
     * Free message queue.
     * Nobody shall use msg_* afterward.
     */
    msg_Flush( p_vlc );
    msg_Destroy( p_libvlc );

1033
    /* Destroy global iconv */
1034
    LocaleDeinit();
1035

1036 1037 1038
    /* Destroy mutexes */
    vlc_mutex_destroy( &p_vlc->config_lock );

1039 1040
    vlc_object_detach( p_vlc );

1041 1042 1043
    /* Release object before destroying it */
    if( i_object ) vlc_object_release( p_vlc );

1044 1045
    vlc_object_destroy( p_vlc );

1046
    /* Stop thread system: last one out please shut the door! */
1047
    vlc_threads_end( p_libvlc );
1048

1049 1050 1051
    return VLC_SUCCESS;
}

1052
/*****************************************************************************
1053
 * VLC_VariableSet: set a vlc variable
1054
 *****************************************************************************/
1055
int VLC_VariableSet( int i_object, char const *psz_var, vlc_value_t value )
1056
{
1057
    vlc_t *p_vlc = vlc_current_object( i_object );
Gildas Bazin's avatar
 
Gildas Bazin committed
1058
    int i_ret;
1059 1060 1061

    if( !p_vlc )
    {
1062
        return VLC_ENOOBJ;
1063 1064
    }

Sam Hocevar's avatar
Sam Hocevar committed
1065 1066 1067
    /* FIXME: Temporary hack for Mozilla, if variable starts with conf:: then
     * we handle it as a configuration variable. Don't tell Gildas :) -- sam */
    if( !strncmp( psz_var, "conf::", 6 ) )
1068
    {
Sam Hocevar's avatar
Sam Hocevar committed
1069
        module_config_t *p_item;
1070
        char const *psz_newvar = psz_var + 6;
1071

Sam Hocevar's avatar
Sam Hocevar committed
1072
        p_item = config_FindConfig( VLC_OBJECT(p_vlc), psz_newvar );
1073

Sam Hocevar's avatar
Sam Hocevar committed
1074
        if( p_item )
1075
        {
Sam Hocevar's avatar
Sam Hocevar committed
1076
            switch( p_item->i_type )
1077
            {
Sam Hocevar's avatar
Sam Hocevar committed
1078 1079 1080 1081 1082 1083 1084 1085 1086 1087