libvlc.c 66.3 KB
Newer Older
1 2 3
/*****************************************************************************
 * libvlc.c: main libvlc source
 *****************************************************************************
4
 * Copyright (C) 1998-2004 VideoLAN
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 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
 *
 * 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
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

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

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

40
#include <errno.h>                                                 /* ENOMEM */
41 42 43 44 45 46 47 48 49 50
#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
51
#elif defined( WIN32 ) && !defined( UNDER_CE )
52 53 54
#   include <io.h>
#endif

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

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

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

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

70
#include "vlc_error.h"
71

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

#include "audio_output.h"

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

80 81
#include "stream_output.h"

82 83 84
#include "libvlc.h"

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

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
94
static void SetLanguage   ( char const * );
95
static int  GetFilenames  ( vlc_t *, int, char *[] );
96
static void Usage         ( vlc_t *, char const *psz_module_name );
97
static void ListModules   ( vlc_t * );
98 99 100 101
static void Version       ( void );

#ifdef WIN32
static void ShowConsole   ( void );
102
static void PauseConsole  ( void );
103
#endif
104
static int  ConsoleWidth  ( void );
105

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
106 107
static int  VerboseCallback( vlc_object_t *, char const *,
                             vlc_value_t, vlc_value_t, void * );
108

109 110
static void InitDeviceValues( vlc_t * );

111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
/*****************************************************************************
 * 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;
}

127
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
128
 * VLC_Version: return the libvlc version.
129
 *****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
130
 * This function returns full version string (numeric version and codename).
131
 *****************************************************************************/
132
char const * VLC_Version( void )
133
{
Sam Hocevar's avatar
Sam Hocevar committed
134
    return VERSION_MESSAGE;
135 136
}

137 138 139 140 141 142 143 144 145 146
/*****************************************************************************
 * 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
147 148 149 150 151 152 153
/*****************************************************************************
 * 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 )
154
{
155
    int i_ret;
156
    vlc_t * p_vlc = NULL;
157
    vlc_value_t lockval;
158

159 160 161
    /* &libvlc never changes, so we can safely call this multiple times. */
    p_libvlc = &libvlc;

162 163
    /* vlc_threads_init *must* be the first internal call! No other call is
     * allowed before the thread system has been initialized. */
164
    i_ret = vlc_threads_init( p_libvlc );
Sam Hocevar's avatar
Sam Hocevar committed
165
    if( i_ret < 0 )
166
    {
Sam Hocevar's avatar
Sam Hocevar committed
167
        return i_ret;
168 169 170
    }

    /* Now that the thread system is initialized, we don't have much, but
171
     * at least we have var_Create */
172 173
    var_Create( p_libvlc, "libvlc", VLC_VAR_MUTEX );
    var_Get( p_libvlc, "libvlc", &lockval );
174
    vlc_mutex_lock( lockval.p_address );
175 176
    if( !libvlc.b_ready )
    {
177 178
        char *psz_env;

179 180 181
        /* Guess what CPU we have */
        libvlc.i_cpu = CPUCapabilities();

182 183
        /* Find verbosity from VLC_VERBOSE environment variable */
        psz_env = getenv( "VLC_VERBOSE" );
184
        libvlc.i_verbose = psz_env ? atoi( psz_env ) : -1;
185

Gildas Bazin's avatar
 
Gildas Bazin committed
186
#if defined( HAVE_ISATTY ) && !defined( WIN32 )
187 188 189 190 191
        libvlc.b_color = isatty( 2 ); /* 2 is for stderr */
#else
        libvlc.b_color = VLC_FALSE;
#endif

192
        /* Initialize message queue */
193
        msg_Create( p_libvlc );
194 195

        /* Announce who we are */
196 197
        msg_Dbg( p_libvlc, COPYRIGHT_MESSAGE );
        msg_Dbg( p_libvlc, "libvlc was configured with %s", CONFIGURE_LINE );
198

199 200
        /* The module bank will be initialized later */
        libvlc.p_module_bank = NULL;
201 202

        libvlc.b_ready = VLC_TRUE;
203
    }
204
    vlc_mutex_unlock( lockval.p_address );
205
    var_Destroy( p_libvlc, "libvlc" );
206 207

    /* Allocate a vlc object */
208
    p_vlc = vlc_object_create( p_libvlc, VLC_OBJECT_VLC );
209 210
    if( p_vlc == NULL )
    {
Sam Hocevar's avatar
Sam Hocevar committed
211
        return VLC_EGENERIC;
212
    }
213
    p_vlc->thread_id = 0;
214
    vlc_thread_set_priority( p_vlc, VLC_THREAD_PRIORITY_LOW );
215 216 217 218

    p_vlc->psz_object_name = "root";

    /* Initialize mutexes */
219
    vlc_mutex_init( p_vlc, &p_vlc->config_lock );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
220 221 222
#ifdef SYS_DARWIN
    vlc_mutex_init( p_vlc, &p_vlc->quicktime_lock );
#endif
223 224

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

Sam Hocevar's avatar
Sam Hocevar committed
227 228 229 230
    /* Store data for the non-reentrant API */
    p_static_vlc = p_vlc;

    return p_vlc->i_object_id;
231 232 233
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
234
 * VLC_Init: initialize a vlc_t structure.
235 236 237 238 239 240 241
 *****************************************************************************
 * 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
242
int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
243
{
244 245
    char         p_capabilities[200];
    char *       p_tmp;
246 247
    char *       psz_modules;
    char *       psz_parser;
248
    char *       psz_language;
249
    vlc_bool_t   b_exit = VLC_FALSE;
250
    vlc_t *      p_vlc = vlc_current_object( i_object );
251 252
    module_t    *p_help_module;
    playlist_t  *p_playlist;
253

254
    if( !p_vlc )
255
    {
256
        return VLC_ENOOBJ;
257 258 259
    }

    /*
260
     * System specific initialization code
261
     */
262
    system_Init( p_vlc, &i_argc, ppsz_argv );
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278

    /* 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";
    }

279 280 281 282
    /*
     * Support for gettext
     */
    SetLanguage( "" );
Sam Hocevar's avatar
Sam Hocevar committed
283 284

    /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
285 286
    msg_Dbg( p_vlc, "translation test: code is \"%s\"", _("C") );

287 288 289 290
    /* 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) */
291
    module_InitBank( p_vlc );
292

293 294 295 296
    /* Hack: insert the help module here */
    p_help_module = vlc_object_create( p_vlc, VLC_OBJECT_MODULE );
    if( p_help_module == NULL )
    {
297
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
298
        if( i_object ) vlc_object_release( p_vlc );
299 300 301
        return VLC_EGENERIC;
    }
    p_help_module->psz_object_name = "help";
Gildas Bazin's avatar
 
Gildas Bazin committed
302
    p_help_module->psz_longname = N_("Help options");
303
    config_Duplicate( p_help_module, p_help_config );
304
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
305 306
    /* End hack */

Sam Hocevar's avatar
Sam Hocevar committed
307
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
308
    {
309
        vlc_object_detach( p_help_module );
310 311
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
312
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
313
        if( i_object ) vlc_object_release( p_vlc );
314 315 316 317 318 319
        return VLC_EGENERIC;
    }

    /* Check for short help option */
    if( config_GetInt( p_vlc, "help" ) )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
320
        fprintf( stdout, _("Usage: %s [options] [items]...\n"),
321
                         p_vlc->psz_object_name );
322
        Usage( p_vlc, "main" );
323 324
        Usage( p_vlc, "help" );
        b_exit = VLC_TRUE;
325 326
    }
    /* Check for version option */
327
    else if( config_GetInt( p_vlc, "version" ) )
328 329
    {
        Version();
330 331 332
        b_exit = VLC_TRUE;
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
333 334 335 336
    /* Set the config file stuff */
    p_vlc->psz_homedir = config_GetHomeDir();
    p_vlc->psz_configfile = config_GetPsz( p_vlc, "config" );

337 338 339 340 341 342
    /* Check for plugins cache options */
    if( config_GetInt( p_vlc, "reset-plugins-cache" ) )
    {
        libvlc.p_module_bank->b_cache_delete = VLC_TRUE;
    }

343 344 345 346
    /* Hack: remove the help module here */
    vlc_object_detach( p_help_module );
    /* End hack */

Gildas Bazin's avatar
Gildas Bazin committed
347 348 349 350 351 352 353
    /* 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" ) )
    {
354 355 356 357 358 359 360 361 362 363 364
#if HAVE_DAEMON
        if( daemon( 0, 0) != 0 )
        {
            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
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380

        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;
        }
        else
        {
            /* We are the child */
            msg_Dbg( p_vlc, "daemon spawned" );
381 382 383
            close( STDIN_FILENO );
            close( STDOUT_FILENO );
            close( STDERR_FILENO );
Gildas Bazin's avatar
Gildas Bazin committed
384 385 386

            p_vlc->p_libvlc->b_daemon = VLC_TRUE;
        }
387
#endif
Gildas Bazin's avatar
Gildas Bazin committed
388 389 390
    }
#endif

391 392
    if( b_exit )
    {
393 394
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
395
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
396
        if( i_object ) vlc_object_release( p_vlc );
397 398 399
        return VLC_EEXIT;
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
400
    /* Check for translation config option */
Gildas Bazin's avatar
 
Gildas Bazin committed
401 402 403 404 405 406 407 408
#if defined( ENABLE_NLS ) \
     && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )

    /* 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 );

409 410 411
    /* 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
412
    {
413 414
        vlc_bool_t b_cache_delete = libvlc.p_module_bank->b_cache_delete;

Gildas Bazin's avatar
 
Gildas Bazin committed
415
        /* Reset the default domain */
416
        SetLanguage( psz_language );
Gildas Bazin's avatar
 
Gildas Bazin committed
417

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

Sam Hocevar's avatar
Sam Hocevar committed
421
        textdomain( PACKAGE_NAME );
Gildas Bazin's avatar
 
Gildas Bazin committed
422

Gildas Bazin's avatar
 
Gildas Bazin committed
423
#if defined( ENABLE_UTF8 )
Sam Hocevar's avatar
Sam Hocevar committed
424
        bind_textdomain_codeset( PACKAGE_NAME, "UTF-8" );
425 426
#endif

Gildas Bazin's avatar
 
Gildas Bazin committed
427
        module_EndBank( p_vlc );
428
        module_InitBank( p_vlc );
429
        config_LoadConfigFile( p_vlc, "main" );
Gildas Bazin's avatar
 
Gildas Bazin committed
430
        config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
431
        libvlc.p_module_bank->b_cache_delete = b_cache_delete;
Gildas Bazin's avatar
 
Gildas Bazin committed
432
    }
433
    if( psz_language ) free( psz_language );
434
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
435

436 437 438 439 440 441
    /*
     * 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.
     */
442 443 444 445 446 447 448
    module_LoadBuiltins( p_vlc );
    module_LoadPlugins( p_vlc );
    if( p_vlc->b_die )
    {
        b_exit = VLC_TRUE;
    }

449
    msg_Dbg( p_vlc, "module bank initialized, found %i modules",
450
                    libvlc.p_module_bank->i_children );
451 452

    /* Hack: insert the help module here */
453
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
454 455 456 457 458
    /* End hack */

    /* Check for help on modules */
    if( (p_tmp = config_GetPsz( p_vlc, "module" )) )
    {
459
        Usage( p_vlc, p_tmp );
460
        free( p_tmp );
461
        b_exit = VLC_TRUE;
462 463
    }
    /* Check for long help option */
464
    else if( config_GetInt( p_vlc, "longhelp" ) )
465
    {
466
        Usage( p_vlc, NULL );
467
        b_exit = VLC_TRUE;
468 469
    }
    /* Check for module list option */
470
    else if( config_GetInt( p_vlc, "list" ) )
471
    {
472
        ListModules( p_vlc );
473
        b_exit = VLC_TRUE;
474 475
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
    /* 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 );
    }

494
    /* Hack: remove the help module here */
495
    vlc_object_detach( p_help_module );
496 497
    /* End hack */

498 499
    if( b_exit )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
500 501
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
502
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
503
        if( i_object ) vlc_object_release( p_vlc );
504 505 506
        return VLC_EEXIT;
    }

507 508 509 510 511
    /*
     * Init device values
     */
    InitDeviceValues( p_vlc );

512 513 514
    /*
     * Override default configuration with config file settings
     */
515
    config_LoadConfigFile( p_vlc, NULL );
516

Gildas Bazin's avatar
 
Gildas Bazin committed
517 518 519 520
    /* Hack: insert the help module here */
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
    /* End hack */

521 522 523
    /*
     * Override configuration with command line settings
     */
Sam Hocevar's avatar
Sam Hocevar committed
524
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
525 526 527 528 529
    {
#ifdef WIN32
        ShowConsole();
        /* Pause the console because it's destroyed when we exit */
        fprintf( stderr, "The command line options couldn't be loaded, check "
530 531
                 "that they are valid.\n" );
        PauseConsole();
532
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
533 534 535
        vlc_object_detach( p_help_module );
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
536
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
537
        if( i_object ) vlc_object_release( p_vlc );
538 539 540
        return VLC_EGENERIC;
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
541 542 543 544 545 546
    /* 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 */

547 548 549
    /*
     * System specific configuration
     */
Gildas Bazin's avatar
 
Gildas Bazin committed
550
    system_Configure( p_vlc, &i_argc, ppsz_argv );
551

552 553 554
    /*
     * Message queue options
     */
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
555 556

    var_Create( p_vlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
557 558
    if( config_GetInt( p_vlc, "quiet" ) )
    {
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
559 560 561
        vlc_value_t val;
        val.i_int = -1;
        var_Set( p_vlc, "verbose", val );
562
    }
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
563 564
    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
565

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

568 569 570 571 572
    /*
     * Output messages that may still be in the queue
     */
    msg_Flush( p_vlc );

573
    /* p_vlc initialization. FIXME ? */
574

575
#if defined( __i386__ )
576
    if( !config_GetInt( p_vlc, "mmx" ) )
577
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMX;
578
    if( !config_GetInt( p_vlc, "3dn" ) )
579
        libvlc.i_cpu &= ~CPU_CAPABILITY_3DNOW;
580
    if( !config_GetInt( p_vlc, "mmxext" ) )
581
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMXEXT;
582
    if( !config_GetInt( p_vlc, "sse" ) )
583
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE;
584 585
    if( !config_GetInt( p_vlc, "sse2" ) )
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE2;
586 587
#endif
#if defined( __powerpc__ ) || defined( SYS_DARWIN )
588
    if( !config_GetInt( p_vlc, "altivec" ) )
589
        libvlc.i_cpu &= ~CPU_CAPABILITY_ALTIVEC;
590
#endif
591 592

#define PRINT_CAPABILITY( capability, string )                              \
593
    if( libvlc.i_cpu & capability )                                         \
594 595 596 597 598 599 600 601 602 603 604 605 606 607
    {                                                                       \
        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" );
608
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE2, "SSE2" );
609 610 611 612 613 614 615
    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
616
    p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy", 0 );
617

618
    if( p_vlc->pf_memcpy == NULL )
619 620 621
    {
        p_vlc->pf_memcpy = memcpy;
    }
622 623 624 625 626

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

Sigmund Augdal Helberg's avatar
Sigmund Augdal Helberg committed
628 629 630 631
    /*
     * Initialize hotkey handling
     */
    var_Create( p_vlc, "key-pressed", VLC_VAR_INTEGER );
Gildas Bazin's avatar
 
Gildas Bazin committed
632 633
    p_vlc->p_hotkeys = malloc( sizeof(p_hotkeys) );
    /* Do a copy (we don't need to modify the strings) */
634
    memcpy( p_vlc->p_hotkeys, p_hotkeys, sizeof(p_hotkeys) );
Gildas Bazin's avatar
 
Gildas Bazin committed
635

636 637 638
    /*
     * Initialize playlist and get commandline files
     */
639
    p_playlist = playlist_Create( p_vlc );
640 641 642
    if( !p_playlist )
    {
        msg_Err( p_vlc, "playlist initialization failed" );
643 644
        if( p_vlc->p_memcpy_module != NULL )
        {
645
            module_Unneed( p_vlc, p_vlc->p_memcpy_module );
646
        }
647
        module_EndBank( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
648
        if( i_object ) vlc_object_release( p_vlc );
649 650 651
        return VLC_EGENERIC;
    }

652 653 654 655 656 657 658
    /*
     * Load background interfaces
     */
    psz_modules = config_GetPsz( p_vlc, "extraintf" );
    psz_parser = psz_modules;
    while ( psz_parser && *psz_parser )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
659
        char *psz_module, *psz_temp;
660 661 662 663 664 665 666
        psz_module = psz_parser;
        psz_parser = strchr( psz_module, ',' );
        if ( psz_parser )
        {
            *psz_parser = '\0';
            psz_parser++;
        }
Gildas Bazin's avatar
 
Gildas Bazin committed
667 668 669 670
        psz_temp = (char *)malloc( strlen(psz_module) + sizeof(",none") );
        if( psz_temp )
        {
            sprintf( psz_temp, "%s,none", psz_module );
671
            VLC_AddIntf( 0, psz_temp, VLC_FALSE, VLC_FALSE );
Gildas Bazin's avatar
 
Gildas Bazin committed
672 673
            free( psz_temp );
        }
674 675 676 677 678
    }
    if ( psz_modules )
    {
        free( psz_modules );
    }
679

Sigmund Augdal Helberg's avatar
Sigmund Augdal Helberg committed
680 681 682
    /*
     * Allways load the hotkeys interface if it exists
     */
683
    VLC_AddIntf( 0, "hotkeys,none", VLC_FALSE, VLC_FALSE );
Sigmund Augdal Helberg's avatar
Sigmund Augdal Helberg committed
684

685 686 687 688
    /*
     * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin
     */
    var_Create( p_vlc, "drawable", VLC_VAR_INTEGER );
689 690 691 692 693 694 695 696 697 698 699
    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 );
700

701 702 703 704 705
    /*
     * Get input filenames given as commandline arguments
     */
    GetFilenames( p_vlc, i_argc, ppsz_argv );

Gildas Bazin's avatar
 
Gildas Bazin committed
706
    if( i_object ) vlc_object_release( p_vlc );
707 708 709 710
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
711
 * VLC_AddIntf: add an interface
712 713
 *****************************************************************************
 * This function opens an interface plugin and runs it. If b_block is set
Sam Hocevar's avatar
Sam Hocevar committed
714 715
 * 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
716 717
 * user requests to quit. If b_play is set to 1, VLC_AddIntf will start playing
 * the playlist when it is completely initialised.
718
 *****************************************************************************/
719 720
int VLC_AddIntf( int i_object, char const *psz_module,
                 vlc_bool_t b_block, vlc_bool_t b_play )
721
{
Sam Hocevar's avatar
Sam Hocevar committed
722
    int i_err;
723
    intf_thread_t *p_intf;
724
    vlc_t *p_vlc = vlc_current_object( i_object );
Sam Hocevar's avatar
Sam Hocevar committed
725

726
    if( !p_vlc )
727
    {
728
        return VLC_ENOOBJ;
729 730
    }

Gildas Bazin's avatar
Gildas Bazin committed
731 732 733 734 735 736 737 738 739 740 741
#ifndef WIN32
    if( p_vlc->p_libvlc->b_daemon && b_block && !psz_module )
    {
        /* Daemon mode hack.
         * We prefer the dummy interface if none is specified. */
        char *psz_interface = config_GetPsz( p_vlc, "intf" );
        if( !psz_interface || !*psz_interface ) psz_module = "dummy";
        if( psz_interface ) free( psz_interface );
    }
#endif

742
    /* Try to create the interface */
743
    p_intf = intf_Create( p_vlc, psz_module ? psz_module : "$intf" );
744 745 746

    if( p_intf == NULL )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
747
        msg_Err( p_vlc, "interface \"%s\" initialization failed", psz_module );
Gildas Bazin's avatar
 
Gildas Bazin committed
748
        if( i_object ) vlc_object_release( p_vlc );
749 750 751
        return VLC_EGENERIC;
    }

752 753 754
    /* Interface doesn't handle play on start so do it ourselves */
    if( !p_intf->b_play && b_play ) VLC_Play( i_object );

755
    /* Try to run the interface */
756
    p_intf->b_play = b_play;
757
    p_intf->b_block = b_block;
Sam Hocevar's avatar
Sam Hocevar committed
758 759
    i_err = intf_RunThread( p_intf );
    if( i_err )
760
    {
761
        vlc_object_detach( p_intf );
762
        intf_Destroy( p_intf );
Gildas Bazin's avatar
 
Gildas Bazin committed
763
        if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
764
        return i_err;
765 766
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
767
    if( i_object ) vlc_object_release( p_vlc );
768 769 770 771
    return VLC_SUCCESS;
}

/*****************************************************************************
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873
 * 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;
    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 );
    }

    /*
     * Free playlists
     */
    msg_Dbg( p_vlc, "removing all playlists" );
    while( (p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST,
                                          FIND_CHILD )) )
    {
        vlc_object_detach( p_playlist );
        vlc_object_release( p_playlist );
        playlist_Destroy( p_playlist );
    }

    /*
     * 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 );
    }

    /*
     * Free announce handler(s?)
     */
    msg_Dbg( p_vlc, "removing announce handler" );
    while( (p_announce = vlc_object_find( p_vlc, VLC_OBJECT_ANNOUNCE,
                                                 FIND_CHILD ) ) )
   {
        vlc_object_detach( p_announce );
        vlc_object_release( p_announce );
        announce_HandlerDestroy( p_announce );
   }

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

/*****************************************************************************
 * VLC_Destroy: Destroy everything.
874
 *****************************************************************************
875
 * This function requests the running threads to finish, waits for their
876 877
 * termination, and destroys their structure.
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
878
int VLC_Destroy( int i_object )
879
{
880
    vlc_t *p_vlc = vlc_current_object( i_object );
881

882
    if( !p_vlc )
883
    {
884
        return VLC_ENOOBJ;
885 886
    }

887 888 889 890 891 892 893
    /*
     * Free allocated memory
     */
    if( p_vlc->p_memcpy_module )
    {
        module_Unneed( p_vlc, p_vlc->p_memcpy_module );
        p_vlc->p_memcpy_module = NULL;
894 895
    }

896
    /*
897
     * Free module bank !
898 899 900
     */
    module_EndBank( p_vlc );

901 902 903 904 905
    if( p_vlc->psz_homedir )
    {
        free( p_vlc->psz_homedir );
        p_vlc->psz_homedir = NULL;
    }
906

Gildas Bazin's avatar
 
Gildas Bazin committed
907 908 909 910 911 912
    if( p_vlc->psz_configfile )
    {
        free( p_vlc->psz_configfile );
        p_vlc->psz_configfile = NULL;
    }

913 914 915 916 917 918
    if( p_vlc->p_hotkeys )
    {
        free( p_vlc->p_hotkeys );
        p_vlc->p_hotkeys = NULL;
    }

919 920 921 922
    /*
     * System specific cleaning code
     */
    system_End( p_vlc );
923

924 925 926
    /* Destroy mutexes */
    vlc_mutex_destroy( &p_vlc->config_lock );

927 928
    vlc_object_detach( p_vlc );

929 930 931
    /* Release object before destroying it */
    if( i_object ) vlc_object_release( p_vlc );

932 933
    vlc_object_destroy( p_vlc );

934
    /* Stop thread system: last one out please shut the door! */
935
    vlc_threads_end( p_libvlc );
936

937 938 939
    return VLC_SUCCESS;
}

940
/*****************************************************************************
941
 * VLC_VariableSet: set a vlc variable
942
 *****************************************************************************/
943
int VLC_VariableSet( int i_object, char const *psz_var, vlc_value_t value )
944
{
945
    vlc_t *p_vlc = vlc_current_object( i_object );
Gildas Bazin's avatar
 
Gildas Bazin committed
946
    int i_ret;
947 948 949

    if( !p_vlc )
    {
950
        return VLC_ENOOBJ;
951 952
    }

Sam Hocevar's avatar
Sam Hocevar committed
953 954 955
    /* 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 ) )
956
    {
Sam Hocevar's avatar
Sam Hocevar committed
957
        module_config_t *p_item;
958
        char const *psz_newvar = psz_var + 6;
959

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

Sam Hocevar's avatar
Sam Hocevar committed
962
        if( p_item )
963
        {
Sam Hocevar's avatar
Sam Hocevar committed
964
            switch( p_item->i_type )
965
            {
Sam Hocevar's avatar
Sam Hocevar committed
966 967 968 969 970 971 972 973 974 975 976 977
                case CONFIG_ITEM_BOOL:
                    config_PutInt( p_vlc, psz_newvar, value.b_bool );
                    break;
                case CONFIG_ITEM_INTEGER:
                    config_PutInt( p_vlc, psz_newvar, value.i_int );
                    break;
                case CONFIG_ITEM_FLOAT:
                    config_PutFloat( p_vlc, psz_newvar, value.f_float );
                    break;
                default:
                    config_PutPsz( p_vlc, psz_newvar, value.psz_string );
                    break;
978
            }
Gildas Bazin's avatar
 
Gildas Bazin committed
979
            if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
980
            return VLC_SUCCESS;
981 982 983
        }
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
984 985 986 987
    i_ret = var_Set( p_vlc, psz_var, value );

    if( i_object ) vlc_object_release( p_vlc );
    return i_ret;
Sam Hocevar's avatar
Sam Hocevar committed
988 989 990
}

/*****************************************************************************
991
 * VLC_VariableGet: get a vlc variable
Sam Hocevar's avatar
Sam Hocevar committed
992
 *****************************************************************************/
993
int VLC_VariableGet( int i_object, char const *psz_var, vlc_value_t *p_value )
Sam Hocevar's avatar
Sam Hocevar committed
994
{
995
    vlc_t *p_vlc = vlc_current_object( i_object );
Gildas Bazin's avatar
 
Gildas Bazin committed
996
    int i_ret;
Sam Hocevar's avatar
Sam Hocevar committed
997 998

    if( !p_vlc )
999
    {
1000
        return VLC_ENOOBJ;
1001 1002
    }

1003
    i_ret = var_Get( p_vlc , psz_var, p_value );
Gildas Bazin's avatar
 
Gildas Bazin committed
1004 1005 1006

    if( i_object ) vlc_object_release( p_vlc );
    return i_ret;
1007 1008
}

1009
/*****************************************************************************
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1010 1011 1012 1013
 * VLC_AddTarget: adds a target for playing.
 *****************************************************************************
 * This function adds psz_target to the current playlist. If a playlist does
 * not exist, it will create one.
1014
 *****************************************************************************/
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1015 1016 1017
int VLC_AddTarget( int i_object, char const *psz_target,
                   char const **ppsz_options, int i_options,
                   int i_mode, int i_pos )
1018
{
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1019 1020
    int i_err;
    playlist_t *p_playlist;
1021 1022 1023 1024 1025 1026 1027
    vlc_t *p_vlc = vlc_current_object( i_object );

    if( !p_vlc )
    {
        return VLC_ENOOBJ;
    }

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1028
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
1029

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1030
    if( p_playlist == NULL )
1031
    {
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041
        msg_Dbg( p_vlc, "no playlist present, creating one" );
        p_playlist = playlist_Create( p_vlc );

        if( p_playlist == NULL )
        {
            if( i_object ) vlc_object_release( p_vlc );
            return VLC_EGENERIC;
        }

        vlc_object_yield( p_playlist );
1042 1043
    }

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1044 1045
    i_err = playlist_AddExt( p_playlist, psz_target, psz_target,
                             i_mode, i_pos, -1, ppsz_options, i_options);
1046 1047 1048 1049

    vlc_object_release( p_playlist );

    if( i_object ) vlc_object_release( p_vlc );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1050
    return i_err;
1051 1052 1053
}

/*****************************************************************************
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1054
 * VLC_Play: play
1055
 *****************************************************************************/
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1056
int VLC_Play( int i_object )
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074
{
    playlist_t * p_playlist;
    vlc_t *p_vlc = vlc_current_object( i_object );

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

    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );

    if( !p_playlist )
    {
        if( i_object ) vlc_object_release( p_vlc );
        return VLC_ENOOBJ;
    }

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1075
    playlist_Play( p_playlist );
1076 1077 1078
    vlc_object_release( p_playlist );

    if( i_object ) vlc_object_release( p_vlc );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1079
    return VLC_SUCCESS;
1080 1081
}

1082
/*****************************************************************************
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1083
 * VLC_Pause: toggle pause
1084
 *****************************************************************************/
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1085
int VLC_Pause( int i_object )
1086 1087
{
    playlist_t * p_playlist;
1088
    vlc_t *p_vlc = vlc_current_object( i_object );
1089 1090

    /* Check that the handle is valid */
1091
    if( !p_vlc )
1092
    {
1093
        return VLC_ENOOBJ;
1094
    }
1095

1096 1097 1098 1099
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );

    if( !p_playlist )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
1100
        if( i_object ) vlc_object_release( p_vlc );
1101
        return VLC_ENOOBJ;
1102 1103
    }

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1104
    playlist_Pause( p_playlist );
1105 1106
    vlc_object_release( p_playlist );

Gildas Bazin's avatar
 
Gildas Bazin committed
1107
    if( i_object ) vlc_object_release( p_vlc );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1108
    return VLC_SUCCESS;
1109 1110 1111
}

/*****************************************************************************
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1112
 * VLC_Pause: toggle pause
1113
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
1114
int VLC_Stop( int i_object )
1115
{
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1116
    playlist_t * p_playlist;
1117
    vlc_t *p_vlc = vlc_current_object( i_object );
1118 1119

    /* Check that the handle is valid */
1120
    if( !p_vlc )
1121
    {
1122
        return VLC_ENOOBJ;
1123 1124
    }

Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
1125
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );
1126

</