libvlc.c 50 KB
Newer Older
1 2 3
/*****************************************************************************
 * libvlc.c: main libvlc source
 *****************************************************************************
4
 * Copyright (C) 1998-2002 VideoLAN
5
 * $Id: libvlc.c,v 1.108 2004/01/06 08:50:20 zorglub Exp $
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
 *
 * Authors: Vincent Seguin <seguin@via.ecp.fr>
 *          Samuel Hocevar <sam@zoy.org>
 *          Gildas Bazin <gbazin@netcourrier.com>
 *
 * 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
30
#define MODULE_PATH main
31 32 33 34 35
#define __BUILTIN__

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

#ifdef HAVE_ERRNO_H
#   include <errno.h>                                              /* ENOMEM */
#endif
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 63
#ifdef HAVE_LOCALE_H
#   include <locale.h>
#endif

#include "vlc_cpu.h"                                        /* CPU detection */
64
#include "os_specific.h"
65

66
#include "vlc_error.h"
67 68 69 70

#include "stream_control.h"
#include "input_ext-intf.h"

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

#include "audio_output.h"

76
#include "vlc_video.h"
77 78 79 80 81
#include "video_output.h"

#include "libvlc.h"

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

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

#ifdef WIN32
static void ShowConsole   ( void );
#endif
100
static int  ConsoleWidth  ( void );
101

102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118

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

119
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
120
 * VLC_Version: return the libvlc version.
121
 *****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
122
 * This function returns full version string (numeric version and codename).
123
 *****************************************************************************/
124
char const * VLC_Version( void )
125
{
Sam Hocevar's avatar
Sam Hocevar committed
126
    return VERSION_MESSAGE;
127 128
}

129 130 131 132 133 134 135 136 137 138
/*****************************************************************************
 * 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
139 140 141 142 143 144 145
/*****************************************************************************
 * 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 )
146
{
147
    int i_ret;
148
    vlc_t * p_vlc = NULL;
149
    vlc_value_t lockval;
150

151 152 153
    /* &libvlc never changes, so we can safely call this multiple times. */
    p_libvlc = &libvlc;

154 155
    /* vlc_threads_init *must* be the first internal call! No other call is
     * allowed before the thread system has been initialized. */
156
    i_ret = vlc_threads_init( p_libvlc );
Sam Hocevar's avatar
Sam Hocevar committed
157
    if( i_ret < 0 )
158
    {
Sam Hocevar's avatar
Sam Hocevar committed
159
        return i_ret;
160 161 162
    }

    /* Now that the thread system is initialized, we don't have much, but
163
     * at least we have var_Create */
164 165
    var_Create( p_libvlc, "libvlc", VLC_VAR_MUTEX );
    var_Get( p_libvlc, "libvlc", &lockval );
166
    vlc_mutex_lock( lockval.p_address );
167 168
    if( !libvlc.b_ready )
    {
169 170
        char *psz_env;

171 172 173
        /* Guess what CPU we have */
        libvlc.i_cpu = CPUCapabilities();

174 175
        /* Find verbosity from VLC_VERBOSE environment variable */
        psz_env = getenv( "VLC_VERBOSE" );
176
        libvlc.i_verbose = psz_env ? atoi( psz_env ) : -1;
177

Gildas Bazin's avatar
 
Gildas Bazin committed
178
#if defined( HAVE_ISATTY ) && !defined( WIN32 )
179 180 181 182 183
        libvlc.b_color = isatty( 2 ); /* 2 is for stderr */
#else
        libvlc.b_color = VLC_FALSE;
#endif

184
        /* Initialize message queue */
185
        msg_Create( p_libvlc );
186 187

        /* Announce who we are */
188 189
        msg_Dbg( p_libvlc, COPYRIGHT_MESSAGE );
        msg_Dbg( p_libvlc, "libvlc was configured with %s", CONFIGURE_LINE );
190

191 192
        /* The module bank will be initialized later */
        libvlc.p_module_bank = NULL;
193 194

        libvlc.b_ready = VLC_TRUE;
195
    }
196
    vlc_mutex_unlock( lockval.p_address );
197
    var_Destroy( p_libvlc, "libvlc" );
198 199

    /* Allocate a vlc object */
200
    p_vlc = vlc_object_create( p_libvlc, VLC_OBJECT_VLC );
201 202
    if( p_vlc == NULL )
    {
Sam Hocevar's avatar
Sam Hocevar committed
203
        return VLC_EGENERIC;
204
    }
205
    vlc_thread_set_priority( p_vlc, VLC_THREAD_PRIORITY_LOW );
206 207 208 209

    p_vlc->psz_object_name = "root";

    /* Initialize mutexes */
210
    vlc_mutex_init( p_vlc, &p_vlc->config_lock );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
211 212 213
#ifdef SYS_DARWIN
    vlc_mutex_init( p_vlc, &p_vlc->quicktime_lock );
#endif
214 215

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

Sam Hocevar's avatar
Sam Hocevar committed
218 219 220 221
    /* Store data for the non-reentrant API */
    p_static_vlc = p_vlc;

    return p_vlc->i_object_id;
222 223 224
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
225
 * VLC_Init: initialize a vlc_t structure.
226 227 228 229 230 231 232
 *****************************************************************************
 * 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
233
int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
234
{
235 236
    char         p_capabilities[200];
    char *       p_tmp;
237 238
    char *       psz_modules;
    char *       psz_parser;
239
    char *       psz_language;
240
    vlc_bool_t   b_exit = VLC_FALSE;
241
    vlc_t *      p_vlc = vlc_current_object( i_object );
242 243
    module_t    *p_help_module;
    playlist_t  *p_playlist;
244
    vlc_value_t  lockval;
245

246
    if( !p_vlc )
247
    {
248
        return VLC_ENOOBJ;
249 250 251
    }

    /*
252
     * System specific initialization code
253
     */
254
    system_Init( p_vlc, &i_argc, ppsz_argv );
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270

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

271 272 273 274
    /*
     * Support for gettext
     */
    SetLanguage( "" );
Sam Hocevar's avatar
Sam Hocevar committed
275 276

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

279 280 281 282
    /* 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) */
283 284
    var_Create( p_libvlc, "libvlc", VLC_VAR_MUTEX );
    var_Get( p_libvlc, "libvlc", &lockval );
285 286 287
    vlc_mutex_lock( lockval.p_address );
    if( libvlc.p_module_bank == NULL )
    {
288 289
        module_InitBank( p_vlc );
        module_LoadMain( p_vlc );
290 291
    }
    vlc_mutex_unlock( lockval.p_address );
292
    var_Destroy( p_libvlc, "libvlc" );
293

294 295 296 297
    /* Hack: insert the help module here */
    p_help_module = vlc_object_create( p_vlc, VLC_OBJECT_MODULE );
    if( p_help_module == NULL )
    {
298
        /*module_EndBank( p_vlc );*/
Gildas Bazin's avatar
 
Gildas Bazin committed
299
        if( i_object ) vlc_object_release( p_vlc );
300 301 302 303
        return VLC_EGENERIC;
    }
    p_help_module->psz_object_name = "help";
    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
    /* Hack: remove the help module here */
    vlc_object_detach( p_help_module );
    /* End hack */

    if( b_exit )
    {
343 344
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
345
        /*module_EndBank( p_vlc );*/
Gildas Bazin's avatar
 
Gildas Bazin committed
346
        if( i_object ) vlc_object_release( p_vlc );
347 348 349
        return VLC_EEXIT;
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
350
    /* Check for translation config option */
Gildas Bazin's avatar
 
Gildas Bazin committed
351 352 353 354 355 356 357 358
#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 );

359 360 361
    /* 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
362 363
    {
        /* Reset the default domain */
364
        SetLanguage( psz_language );
Gildas Bazin's avatar
 
Gildas Bazin committed
365

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

369
        textdomain( PACKAGE );
Gildas Bazin's avatar
 
Gildas Bazin committed
370

Gildas Bazin's avatar
 
Gildas Bazin committed
371 372
#if defined( SYS_BEOS ) || defined ( SYS_DARWIN ) || \
    ( defined( WIN32 ) && !defined( HAVE_INCLUDED_GETTEXT ) )
373 374 375 376 377
        /* BeOS only support UTF8 strings */
        /* Mac OS X prefers UTF8 */
        bind_textdomain_codeset( PACKAGE, "UTF-8" );
#endif

Gildas Bazin's avatar
 
Gildas Bazin committed
378
        module_EndBank( p_vlc );
379 380
        module_InitBank( p_vlc );
        module_LoadMain( p_vlc );
Gildas Bazin's avatar
 
Gildas Bazin committed
381
        config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
Gildas Bazin's avatar
 
Gildas Bazin committed
382
    }
383
    if( psz_language ) free( psz_language );
384
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
385

386 387 388 389 390 391
    /*
     * 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.
     */
392 393 394 395 396 397 398
    module_LoadBuiltins( p_vlc );
    module_LoadPlugins( p_vlc );
    if( p_vlc->b_die )
    {
        b_exit = VLC_TRUE;
    }

399
    msg_Dbg( p_vlc, "module bank initialized, found %i modules",
400
                    libvlc.p_module_bank->i_children );
401 402

    /* Hack: insert the help module here */
403
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
404 405 406 407 408
    /* End hack */

    /* Check for help on modules */
    if( (p_tmp = config_GetPsz( p_vlc, "module" )) )
    {
409
        Usage( p_vlc, p_tmp );
410
        free( p_tmp );
411
        b_exit = VLC_TRUE;
412 413
    }
    /* Check for long help option */
414
    else if( config_GetInt( p_vlc, "longhelp" ) )
415
    {
416
        Usage( p_vlc, NULL );
417
        b_exit = VLC_TRUE;
418 419
    }
    /* Check for module list option */
420
    else if( config_GetInt( p_vlc, "list" ) )
421
    {
422
        ListModules( p_vlc );
423
        b_exit = VLC_TRUE;
424 425
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
    /* 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 );
    }

444
    /* Hack: remove the help module here */
445
    vlc_object_detach( p_help_module );
446 447
    /* End hack */

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

457 458 459
    /*
     * Override default configuration with config file settings
     */
460
    config_LoadConfigFile( p_vlc, NULL );
461

Gildas Bazin's avatar
 
Gildas Bazin committed
462 463 464 465
    /* Hack: insert the help module here */
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
    /* End hack */

466 467 468
    /*
     * Override configuration with command line settings
     */
Sam Hocevar's avatar
Sam Hocevar committed
469
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
470 471 472 473 474 475 476 477
    {
#ifdef WIN32
        ShowConsole();
        /* Pause the console because it's destroyed when we exit */
        fprintf( stderr, "The command line options couldn't be loaded, check "
                 "that they are valid.\nPress the RETURN key to continue..." );
        getchar();
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
478 479 480
        vlc_object_detach( p_help_module );
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
481
        /*module_EndBank( p_vlc );*/
Gildas Bazin's avatar
 
Gildas Bazin committed
482
        if( i_object ) vlc_object_release( p_vlc );
483 484 485
        return VLC_EGENERIC;
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
486 487 488 489 490 491
    /* 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 */

492 493 494
    /*
     * System specific configuration
     */
Gildas Bazin's avatar
 
Gildas Bazin committed
495
    system_Configure( p_vlc, &i_argc, ppsz_argv );
496

497 498 499 500 501
    /*
     * Message queue options
     */
    if( config_GetInt( p_vlc, "quiet" ) )
    {
502
        libvlc.i_verbose = -1;
503 504 505 506
    }
    else
    {
        int i_tmp = config_GetInt( p_vlc, "verbose" );
507
        if( i_tmp >= 0 )
508
        {
509
            libvlc.i_verbose = __MIN( i_tmp, 2 );
510 511
        }
    }
Gildas Bazin's avatar
 
Gildas Bazin committed
512
    libvlc.b_color = libvlc.b_color && config_GetInt( p_vlc, "color" );
513

514 515 516 517 518
    /*
     * Output messages that may still be in the queue
     */
    msg_Flush( p_vlc );

519
    /* p_vlc initialization. FIXME ? */
520

521
#if defined( __i386__ )
522
    if( !config_GetInt( p_vlc, "mmx" ) )
523
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMX;
524
    if( !config_GetInt( p_vlc, "3dn" ) )
525
        libvlc.i_cpu &= ~CPU_CAPABILITY_3DNOW;
526
    if( !config_GetInt( p_vlc, "mmxext" ) )
527
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMXEXT;
528
    if( !config_GetInt( p_vlc, "sse" ) )
529
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE;
530 531
#endif
#if defined( __powerpc__ ) || defined( SYS_DARWIN )
532
    if( !config_GetInt( p_vlc, "altivec" ) )
533
        libvlc.i_cpu &= ~CPU_CAPABILITY_ALTIVEC;
534
#endif
535 536

#define PRINT_CAPABILITY( capability, string )                              \
537
    if( libvlc.i_cpu & capability )                                         \
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558
    {                                                                       \
        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" );
    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
     */
559
    p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy" );
560

561
    if( p_vlc->pf_memcpy == NULL )
562 563 564
    {
        p_vlc->pf_memcpy = memcpy;
    }
565 566 567 568 569

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

Sigmund Augdal Helberg's avatar
Sigmund Augdal Helberg committed
571 572 573 574
    /*
     * Initialize hotkey handling
     */
    var_Create( p_vlc, "key-pressed", VLC_VAR_INTEGER );
Gildas Bazin's avatar
 
Gildas Bazin committed
575 576
    p_vlc->p_hotkeys = malloc( sizeof(p_hotkeys) );
    /* Do a copy (we don't need to modify the strings) */
577
    memcpy( p_vlc->p_hotkeys, p_hotkeys, sizeof(p_hotkeys) );
Gildas Bazin's avatar
 
Gildas Bazin committed
578

579 580 581
    /*
     * Initialize playlist and get commandline files
     */
582
    p_playlist = playlist_Create( p_vlc );
583 584 585
    if( !p_playlist )
    {
        msg_Err( p_vlc, "playlist initialization failed" );
586 587
        if( p_vlc->p_memcpy_module != NULL )
        {
588
            module_Unneed( p_vlc, p_vlc->p_memcpy_module );
589
        }
590
        /*module_EndBank( p_vlc );*/
Gildas Bazin's avatar
 
Gildas Bazin committed
591
        if( i_object ) vlc_object_release( p_vlc );
592 593 594
        return VLC_EGENERIC;
    }

595 596 597 598 599 600 601
    /*
     * 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
602
        char *psz_module, *psz_temp;
603 604 605 606 607 608 609
        psz_module = psz_parser;
        psz_parser = strchr( psz_module, ',' );
        if ( psz_parser )
        {
            *psz_parser = '\0';
            psz_parser++;
        }
Gildas Bazin's avatar
 
Gildas Bazin committed
610 611 612 613 614 615 616
        psz_temp = (char *)malloc( strlen(psz_module) + sizeof(",none") );
        if( psz_temp )
        {
            sprintf( psz_temp, "%s,none", psz_module );
            VLC_AddIntf( 0, psz_temp, VLC_FALSE );
            free( psz_temp );
        }
617 618 619 620 621
    }
    if ( psz_modules )
    {
        free( psz_modules );
    }
622

Sigmund Augdal Helberg's avatar
Sigmund Augdal Helberg committed
623 624 625 626 627
    /*
     * Allways load the hotkeys interface if it exists
     */
    VLC_AddIntf( 0, "hotkeys,none", VLC_FALSE );

628 629 630 631
    /*
     * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin
     */
    var_Create( p_vlc, "drawable", VLC_VAR_INTEGER );
632 633 634 635 636 637 638 639 640 641 642
    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 );
643

644 645 646 647 648
    /*
     * Get input filenames given as commandline arguments
     */
    GetFilenames( p_vlc, i_argc, ppsz_argv );

Gildas Bazin's avatar
 
Gildas Bazin committed
649
    if( i_object ) vlc_object_release( p_vlc );
650 651 652 653
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
654
 * VLC_AddIntf: add an interface
655 656
 *****************************************************************************
 * This function opens an interface plugin and runs it. If b_block is set
Sam Hocevar's avatar
Sam Hocevar committed
657 658
 * 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
659 660
 * user requests to quit.
 *****************************************************************************/
661
int VLC_AddIntf( int i_object, char const *psz_module, vlc_bool_t b_block )
662
{
Sam Hocevar's avatar
Sam Hocevar committed
663
    int i_err;
664
    intf_thread_t *p_intf;
665
    vlc_t *p_vlc = vlc_current_object( i_object );
Sam Hocevar's avatar
Sam Hocevar committed
666

667
    if( !p_vlc )
668
    {
669
        return VLC_ENOOBJ;
670 671 672
    }

    /* Try to create the interface */
673
    p_intf = intf_Create( p_vlc, psz_module ? psz_module : "$intf" );
674 675 676

    if( p_intf == NULL )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
677
        msg_Err( p_vlc, "interface \"%s\" initialization failed", psz_module );
Gildas Bazin's avatar
 
Gildas Bazin committed
678
        if( i_object ) vlc_object_release( p_vlc );
679 680 681 682 683
        return VLC_EGENERIC;
    }

    /* Try to run the interface */
    p_intf->b_block = b_block;
Sam Hocevar's avatar
Sam Hocevar committed
684 685
    i_err = intf_RunThread( p_intf );
    if( i_err )
686
    {
687
        vlc_object_detach( p_intf );
688
        intf_Destroy( p_intf );
Gildas Bazin's avatar
 
Gildas Bazin committed
689
        if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
690
        return i_err;
691 692
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
693
    if( i_object ) vlc_object_release( p_vlc );
694 695 696 697
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
698
 * VLC_Destroy: stop playing and destroy everything.
699
 *****************************************************************************
700
 * This function requests the running threads to finish, waits for their
701 702
 * termination, and destroys their structure.
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
703
int VLC_Destroy( int i_object )
704
{
705
    vlc_t *p_vlc = vlc_current_object( i_object );
706

707
    if( !p_vlc )
708
    {
709
        return VLC_ENOOBJ;
710 711
    }

712 713 714 715 716 717 718
    /*
     * Free allocated memory
     */
    if( p_vlc->p_memcpy_module )
    {
        module_Unneed( p_vlc, p_vlc->p_memcpy_module );
        p_vlc->p_memcpy_module = NULL;
719 720
    }

721 722 723 724 725
    if( p_vlc->psz_homedir )
    {
        free( p_vlc->psz_homedir );
        p_vlc->psz_homedir = NULL;
    }
726

Gildas Bazin's avatar
 
Gildas Bazin committed
727 728 729 730 731 732
    if( p_vlc->psz_configfile )
    {
        free( p_vlc->psz_configfile );
        p_vlc->psz_configfile = NULL;
    }

733 734 735 736 737 738
    if( p_vlc->p_hotkeys )
    {
        free( p_vlc->p_hotkeys );
        p_vlc->p_hotkeys = NULL;
    }

739 740 741
    /*
     * XXX: Free module bank !
     */
742
    /*module_EndBank( p_vlc );*/
743

744 745 746 747
    /*
     * System specific cleaning code
     */
    system_End( p_vlc );
748

749 750
    /* Destroy mutexes */
    vlc_mutex_destroy( &p_vlc->config_lock );
Derk-Jan Hartman's avatar
Derk-Jan Hartman committed
751 752 753
#ifdef SYS_DARWIN
    vlc_mutex_destroy( &p_vlc->quicktime_lock );
#endif
754

755 756
    vlc_object_detach( p_vlc );

757 758 759
    /* Release object before destroying it */
    if( i_object ) vlc_object_release( p_vlc );

760 761
    vlc_object_destroy( p_vlc );

762
    /* Stop thread system: last one out please shut the door! */
763
    vlc_threads_end( p_libvlc );
764

765 766 767
    return VLC_SUCCESS;
}

768
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
769
 * VLC_Die: ask vlc to die.
770 771
 *****************************************************************************
 * This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
772
 * task. It is your duty to call VLC_End and VLC_Destroy afterwards.
773
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
774
int VLC_Die( int i_object )
775
{
776
    vlc_t *p_vlc = vlc_current_object( i_object );
777 778 779

    if( !p_vlc )
    {
780
        return VLC_ENOOBJ;
781 782 783 784
    }

    p_vlc->b_die = VLC_TRUE;

Gildas Bazin's avatar
 
Gildas Bazin committed
785
    if( i_object ) vlc_object_release( p_vlc );
786 787 788 789
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
790
 * VLC_AddTarget: adds a target for playing.
791 792 793 794
 *****************************************************************************
 * This function adds psz_target to the current playlist. If a playlist does
 * not exist, it will create one.
 *****************************************************************************/
Gildas Bazin's avatar
 
Gildas Bazin committed
795 796 797
int VLC_AddTarget( int i_object, char const *psz_target,
                   char const **ppsz_options, int i_options,
                   int i_mode, int i_pos )
798
{
799
    int i;
Sam Hocevar's avatar
Sam Hocevar committed
800
    int i_err;
Sam Hocevar's avatar
Sam Hocevar committed
801
    playlist_t *p_playlist;
802
    vlc_t *p_vlc = vlc_current_object( i_object );
Sam Hocevar's avatar
Sam Hocevar committed
803

804
    if( !p_vlc )
805
    {
806
        return VLC_ENOOBJ;
807 808
    }

Sam Hocevar's avatar
Sam Hocevar committed
809 810 811 812 813 814 815 816 817
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );

    if( p_playlist == NULL )
    {
        msg_Dbg( p_vlc, "no playlist present, creating one" );
        p_playlist = playlist_Create( p_vlc );

        if( p_playlist == NULL )
        {
Gildas Bazin's avatar
 
Gildas Bazin committed
818
            if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
819 820 821 822 823 824
            return VLC_EGENERIC;
        }

        vlc_object_yield( p_playlist );
    }

825
    i_err = playlist_Add( p_playlist, psz_target, psz_target,
Gildas Bazin's avatar
 
Gildas Bazin committed
826
                          i_mode, i_pos );
Sam Hocevar's avatar
Sam Hocevar committed
827

828 829 830 831 832
    for( i = 0 ; i< i_options ; i++ )
    {
        playlist_AddOption( p_playlist, i_err , ppsz_options[i] );
    }

Sam Hocevar's avatar
Sam Hocevar committed
833
    vlc_object_release( p_playlist );
834

Gildas Bazin's avatar
 
Gildas Bazin committed
835
    if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
836
    return i_err;
837 838
}

839
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
840
 * VLC_Set: set a vlc variable
841 842 843
 *****************************************************************************
 *
 *****************************************************************************/
844
int VLC_Set( int i_object, char const *psz_var, vlc_value_t value )
845
{
846
    vlc_t *p_vlc = vlc_current_object( i_object );
Gildas Bazin's avatar
 
Gildas Bazin committed
847
    int i_ret;
848 849 850

    if( !p_vlc )
    {
851
        return VLC_ENOOBJ;
852 853
    }

Sam Hocevar's avatar
Sam Hocevar committed
854 855 856
    /* 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 ) )
857
    {
Sam Hocevar's avatar
Sam Hocevar committed
858
        module_config_t *p_item;
859
        char const *psz_newvar = psz_var + 6;
860

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

Sam Hocevar's avatar
Sam Hocevar committed
863
        if( p_item )
864
        {
Sam Hocevar's avatar
Sam Hocevar committed
865
            switch( p_item->i_type )
866
            {
Sam Hocevar's avatar
Sam Hocevar committed
867 868 869 870 871 872 873 874 875 876 877 878
                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;
879
            }
Gildas Bazin's avatar
 
Gildas Bazin committed
880
            if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
881
            return VLC_SUCCESS;
882 883 884
        }
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
885 886 887 888
    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
889 890 891 892 893 894 895
}

/*****************************************************************************
 * VLC_Get: get a vlc variable
 *****************************************************************************
 *
 *****************************************************************************/
896
int VLC_Get( int i_object, char const *psz_var, vlc_value_t *p_value )
Sam Hocevar's avatar
Sam Hocevar committed
897
{
898
    vlc_t *p_vlc = vlc_current_object( i_object );
Gildas Bazin's avatar
 
Gildas Bazin committed
899
    int i_ret;
Sam Hocevar's avatar
Sam Hocevar committed
900 901

    if( !p_vlc )
902
    {
903
        return VLC_ENOOBJ;
904 905
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
906 907 908 909
    i_ret = var_Get( p_vlc, psz_var, p_value );

    if( i_object ) vlc_object_release( p_vlc );
    return i_ret;
910 911
}

Sam Hocevar's avatar
Sam Hocevar committed
912
/* FIXME: temporary hacks */
913

914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984

/*****************************************************************************
 * VLC_IsPlaying: Query for Playlist Status
 *****************************************************************************/
vlc_bool_t VLC_IsPlaying( int i_object )
{

    playlist_t * p_playlist;
    vlc_bool_t   playing;

    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;
    }

    playing = playlist_IsPlaying( p_playlist );

    vlc_object_release( p_playlist );

    if( i_object ) vlc_object_release( p_vlc );

    return playing;

}


/*****************************************************************************
 * VLC_ClearPlaylist: Query for Playlist Status
 *
 * return: 0
 *****************************************************************************/
int VLC_ClearPlaylist( int i_object )
{

    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;
    }

    playlist_Clear(p_playlist);

    vlc_object_release( p_playlist );

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


985
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
986
 * VLC_Play: play
987
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
988
int VLC_Play( int i_object )
989 990
{
    playlist_t * p_playlist;
991
    vlc_t *p_vlc = vlc_current_object( i_object );
992 993

    /* Check that the handle is valid */
994
    if( !p_vlc )
995
    {
996
        return VLC_ENOOBJ;
997
    }
998

999 1000 1001 1002
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );

    if( !p_playlist )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
1003
        if( i_object ) vlc_object_release( p_vlc );
1004
        return VLC_ENOOBJ;
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
    }

    vlc_mutex_lock( &p_playlist->object_lock );
    if( p_playlist->i_size )
    {
        vlc_mutex_unlock( &p_playlist->object_lock );
        playlist_Play( p_playlist );
    }
    else
    {
        vlc_mutex_unlock( &p_playlist->object_lock );
    }

    vlc_object_release( p_playlist );

Gildas Bazin's avatar
 
Gildas Bazin committed
1020
    if( i_object ) vlc_object_release( p_vlc );
1021 1022 1023 1024
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
1025
 * VLC_Stop: stop
1026
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
1027
int VLC_Stop( int i_object )
1028 1029 1030 1031 1032
{
    intf_thread_t *   p_intf;
    playlist_t    *   p_playlist;
    vout_thread_t *   p_vout;
    aout_instance_t * p_aout;
1033
    vlc_t *p_vlc = vlc_current_object( i_object );
1034 1035

    /* Check that the handle is valid */
1036
    if( !p_vlc )
1037
    {
1038
        return VLC_ENOOBJ;
1039 1040 1041 1042 1043 1044
    }

    /*
     * Ask the interfaces to stop and destroy them
     */
    msg_Dbg( p_vlc, "removing all interfaces" );
1045

1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056
    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
     */
1057
    
1058 1059 1060 1061 1062 1063 1064 1065
    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 );
    }
1066
    
1067 1068 1069 1070 1071 1072 1073 1074
    /*
     * 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 );
1075
        vout_Destroy( p_vout );
1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088
    }

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

Gildas Bazin's avatar
 
Gildas Bazin committed
1089
    if( i_object ) vlc_object_release( p_vlc );
1090 1091 1092 1093
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
1094
 * VLC_Pause: toggle pause
1095
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
1096
int VLC_Pause( int i_object )
1097 1098
{
    input_thread_t *p_input;
1099
    vlc_t *p_vlc = vlc_current_object( i_object );
Sam Hocevar's avatar
Sam Hocevar committed
1100 1101 1102

    if( !p_vlc )
    {
1103
        return VLC_ENOOBJ;
Sam Hocevar's avatar
Sam Hocevar committed
1104
    }
1105 1106 1107 1108 1109

    p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );

    if( !p_input )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
1110
        if( i_object ) vlc_object_release( p_vlc );
1111
        return VLC_ENOOBJ;
1112 1113 1114 1115 1116
    }

    input_SetStatus( p_input, INPUT_STATUS_PAUSE );
    vlc_object_release( p_input );

Gildas Bazin's avatar
 
Gildas Bazin committed
1117
    if( i_object ) vlc_object_release( p_vlc );
1118 1119 1120 1121
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
1122
 * VLC_FullScreen: toggle fullscreen mode
1123
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
1124
int VLC_FullScreen( int i_object )
1125 1126
{
    vout_thread_t *p_vout;
1127
    vlc_t *p_vlc = vlc_current_object( i_object );
Sam Hocevar's avatar
Sam Hocevar committed
1128 1129 1130

    if( !p_vlc )
    {
1131
        return VLC_ENOOBJ;
Sam Hocevar's avatar
Sam Hocevar committed
1132
    }
1133 1134 1135 1136 1137

    p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD );

    if( !p_vout )
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
1138
        if( i_object ) vlc_object_release( p_vlc );
1139
        return VLC_ENOOBJ;