libvlc.c 51.2 KB
Newer Older
1
2
3
/*****************************************************************************
 * libvlc.c: main libvlc source
 *****************************************************************************
zorglub's avatar
zorglub committed
4
 * Copyright (C) 1998-2004 VideoLAN
gbazin's avatar
   
gbazin committed
5
 * $Id: libvlc.c,v 1.111 2004/01/25 11:32:32 gbazin 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>
gbazin's avatar
   
gbazin 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

hartman's avatar
hartman committed
102
103
static int  VerboseCallback( vlc_object_t *, char const *,
                             vlc_value_t, vlc_value_t, void * );
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

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

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

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

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

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

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

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

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

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

186
        /* Initialize message queue */
187
        msg_Create( p_libvlc );
188
189

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

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

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

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

    p_vlc->psz_object_name = "root";

    /* Initialize mutexes */
212
    vlc_mutex_init( p_vlc, &p_vlc->config_lock );
hartman's avatar
hartman committed
213
214
215
#ifdef SYS_DARWIN
    vlc_mutex_init( p_vlc, &p_vlc->quicktime_lock );
#endif
216
217

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

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

    return p_vlc->i_object_id;
224
225
226
}

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

248
    if( !p_vlc )
249
    {
250
        return VLC_ENOOBJ;
251
252
253
    }

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

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

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

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

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

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

Sam Hocevar's avatar
Sam Hocevar committed
309
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
310
    {
311
        vlc_object_detach( p_help_module );
312
313
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
sigmunau's avatar
sigmunau committed
314
        /*module_EndBank( p_vlc );*/
gbazin's avatar
   
gbazin committed
315
        if( i_object ) vlc_object_release( p_vlc );
316
317
318
319
320
321
        return VLC_EGENERIC;
    }

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

gbazin's avatar
   
gbazin committed
335
336
337
338
    /* Set the config file stuff */
    p_vlc->psz_homedir = config_GetHomeDir();
    p_vlc->psz_configfile = config_GetPsz( p_vlc, "config" );

339
340
341
342
343
344
    /* Hack: remove the help module here */
    vlc_object_detach( p_help_module );
    /* End hack */

    if( b_exit )
    {
345
346
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
sigmunau's avatar
sigmunau committed
347
        /*module_EndBank( p_vlc );*/
gbazin's avatar
   
gbazin committed
348
        if( i_object ) vlc_object_release( p_vlc );
349
350
351
        return VLC_EEXIT;
    }

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

361
362
363
    /* Check if the user specified a custom language */
    psz_language = config_GetPsz( p_vlc, "language" );
    if( psz_language && *psz_language && strcmp( psz_language, "auto" ) )
gbazin's avatar
   
gbazin committed
364
365
    {
        /* Reset the default domain */
366
        SetLanguage( psz_language );
gbazin's avatar
   
gbazin committed
367

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

371
        textdomain( PACKAGE );
gbazin's avatar
   
gbazin committed
372

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

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

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

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

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

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

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

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

450
451
    if( b_exit )
    {
gbazin's avatar
   
gbazin committed
452
453
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
sigmunau's avatar
sigmunau committed
454
        /*module_EndBank( p_vlc );*/
gbazin's avatar
   
gbazin committed
455
        if( i_object ) vlc_object_release( p_vlc );
456
457
458
        return VLC_EEXIT;
    }

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

gbazin's avatar
   
gbazin committed
464
465
466
467
    /* Hack: insert the help module here */
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
    /* End hack */

468
469
470
    /*
     * Override configuration with command line settings
     */
Sam Hocevar's avatar
Sam Hocevar committed
471
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
472
473
474
475
476
477
478
479
    {
#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
gbazin's avatar
   
gbazin committed
480
481
482
        vlc_object_detach( p_help_module );
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
sigmunau's avatar
sigmunau committed
483
        /*module_EndBank( p_vlc );*/
gbazin's avatar
   
gbazin committed
484
        if( i_object ) vlc_object_release( p_vlc );
485
486
487
        return VLC_EGENERIC;
    }

gbazin's avatar
   
gbazin committed
488
489
490
491
492
493
    /* 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 */

494
495
496
    /*
     * System specific configuration
     */
gbazin's avatar
   
gbazin committed
497
    system_Configure( p_vlc, &i_argc, ppsz_argv );
498

499
500
501
    /*
     * Message queue options
     */
hartman's avatar
hartman committed
502
503

    var_Create( p_vlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
504
505
    if( config_GetInt( p_vlc, "quiet" ) )
    {
hartman's avatar
hartman committed
506
507
508
        vlc_value_t val;
        val.i_int = -1;
        var_Set( p_vlc, "verbose", val );
509
    }
hartman's avatar
hartman committed
510
511
512
    var_AddCallback( p_vlc, "verbose", VerboseCallback, NULL );
    var_Change( p_vlc, "verbose", VLC_VAR_TRIGGER_CALLBACKS, NULL, NULL );
    
gbazin's avatar
   
gbazin committed
513
    libvlc.b_color = libvlc.b_color && config_GetInt( p_vlc, "color" );
514

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

520
    /* p_vlc initialization. FIXME ? */
521

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

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

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

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

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

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

596
597
598
599
600
601
602
    /*
     * Load background interfaces
     */
    psz_modules = config_GetPsz( p_vlc, "extraintf" );
    psz_parser = psz_modules;
    while ( psz_parser && *psz_parser )
    {
gbazin's avatar
   
gbazin committed
603
        char *psz_module, *psz_temp;
604
605
606
607
608
609
610
        psz_module = psz_parser;
        psz_parser = strchr( psz_module, ',' );
        if ( psz_parser )
        {
            *psz_parser = '\0';
            psz_parser++;
        }
gbazin's avatar
   
gbazin committed
611
612
613
614
615
616
617
        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 );
        }
618
619
620
621
622
    }
    if ( psz_modules )
    {
        free( psz_modules );
    }
623

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

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

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

gbazin's avatar
   
gbazin committed
650
    if( i_object ) vlc_object_release( p_vlc );
651
652
653
654
    return VLC_SUCCESS;
}

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

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

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

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

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

gbazin's avatar
   
gbazin committed
694
    if( i_object ) vlc_object_release( p_vlc );
695
696
697
698
    return VLC_SUCCESS;
}

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

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

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

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

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

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

740
741
742
    /*
     * XXX: Free module bank !
     */
sigmunau's avatar
sigmunau committed
743
    /*module_EndBank( p_vlc );*/
744

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

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

756
757
    vlc_object_detach( p_vlc );

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

761
762
    vlc_object_destroy( p_vlc );

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

766
767
768
    return VLC_SUCCESS;
}

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

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

    p_vlc->b_die = VLC_TRUE;

gbazin's avatar
   
gbazin committed
786
    if( i_object ) vlc_object_release( p_vlc );
787
788
789
790
    return VLC_SUCCESS;
}

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

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

Sam Hocevar's avatar
Sam Hocevar committed
810
811
812
813
814
815
816
817
818
    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 )
        {
gbazin's avatar
   
gbazin committed
819
            if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
820
821
822
823
824
825
            return VLC_EGENERIC;
        }

        vlc_object_yield( p_playlist );
    }

826
    i_err = playlist_Add( p_playlist, psz_target, psz_target,
gbazin's avatar
   
gbazin committed
827
                          i_mode, i_pos );
Sam Hocevar's avatar
Sam Hocevar committed
828

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

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

gbazin's avatar
   
gbazin committed
836
    if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
837
    return i_err;
838
839
}

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

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

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

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

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

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

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

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

gbazin's avatar
   
gbazin committed
907
908
909
910
    i_ret = var_Get( p_vlc, psz_var, p_value );

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

Sam Hocevar's avatar
Sam Hocevar committed
913
/* FIXME: temporary hacks */
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
985

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


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

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

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

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

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

gbazin's avatar
   
gbazin committed
1021
    if( i_object ) vlc_object_release( p_vlc );
1022
1023
1024
1025
    return VLC_SUCCESS;
}

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

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

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

1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
    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
     */
1058
    
1059
1060
1061
1062
1063
1064
1065
1066
    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 );
    }
1067
    
1068
1069