libvlc.c 51.7 KB
Newer Older
1
2
3
/*****************************************************************************
 * libvlc.c: main libvlc source
 *****************************************************************************
zorglub's avatar
zorglub committed
4
 * Copyright (C) 1998-2004 VideoLAN
zorglub's avatar
zorglub committed
5
 * $Id$
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
#include "video_output.h"

zorglub's avatar
zorglub committed
79
80
#include "stream_output.h"

81
82
83
#include "libvlc.h"

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

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

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

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

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

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

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

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

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

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

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

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

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

188
        /* Initialize message queue */
189
        msg_Create( p_libvlc );
190
191

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

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

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

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

    p_vlc->psz_object_name = "root";

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

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

Sam Hocevar's avatar
Sam Hocevar committed
223
224
225
226
    /* Store data for the non-reentrant API */
    p_static_vlc = p_vlc;

    return p_vlc->i_object_id;
227
228
229
}

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

251
    if( !p_vlc )
252
    {
253
        return VLC_ENOOBJ;
254
255
256
    }

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

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

276
277
278
279
    /*
     * Support for gettext
     */
    SetLanguage( "" );
Sam Hocevar's avatar
Sam Hocevar committed
280
281

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

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

299
300
301
302
    /* 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
303
        /*module_EndBank( p_vlc );*/
gbazin's avatar
   
gbazin committed
304
        if( i_object ) vlc_object_release( p_vlc );
305
306
307
        return VLC_EGENERIC;
    }
    p_help_module->psz_object_name = "help";
gbazin's avatar
   
gbazin committed
308
    p_help_module->psz_longname = N_("Help options");
309
    config_Duplicate( p_help_module, p_help_config );
310
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
311
312
    /* End hack */

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

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

gbazin's avatar
   
gbazin committed
339
340
341
342
    /* Set the config file stuff */
    p_vlc->psz_homedir = config_GetHomeDir();
    p_vlc->psz_configfile = config_GetPsz( p_vlc, "config" );

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

    if( b_exit )
    {
349
350
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
sigmunau's avatar
sigmunau committed
351
        /*module_EndBank( p_vlc );*/
gbazin's avatar
   
gbazin committed
352
        if( i_object ) vlc_object_release( p_vlc );
353
354
355
        return VLC_EEXIT;
    }

gbazin's avatar
   
gbazin committed
356
    /* Check for translation config option */
gbazin's avatar
   
gbazin committed
357
358
359
360
361
362
363
364
#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 );

365
366
367
    /* 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
368
369
    {
        /* Reset the default domain */
370
        SetLanguage( psz_language );
gbazin's avatar
   
gbazin committed
371

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

375
        textdomain( PACKAGE );
gbazin's avatar
   
gbazin committed
376

gbazin's avatar
   
gbazin committed
377
#if defined( ENABLE_UTF8 )
378
379
380
        bind_textdomain_codeset( PACKAGE, "UTF-8" );
#endif

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

gbazin's avatar
   
gbazin committed
514
    libvlc.b_color = libvlc.b_color && config_GetInt( p_vlc, "color" );
515

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

521
    /* p_vlc initialization. FIXME ? */
522

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

#define PRINT_CAPABILITY( capability, string )                              \
541
    if( libvlc.i_cpu & capability )                                         \
542
543
544
545
546
547
548
549
550
551
552
553
554
555
    {                                                                       \
        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" );
sigmunau's avatar
sigmunau committed
556
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE2, "SSE2" );
557
558
559
560
561
562
563
    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
     */
gbazin's avatar
   
gbazin committed
564
    p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy", 0 );
565

566
    if( p_vlc->pf_memcpy == NULL )
567
568
569
    {
        p_vlc->pf_memcpy = memcpy;
    }
570
571
572
573
574

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

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

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

600
601
602
603
604
605
606
    /*
     * Load background interfaces
     */
    psz_modules = config_GetPsz( p_vlc, "extraintf" );
    psz_parser = psz_modules;
    while ( psz_parser && *psz_parser )
    {
gbazin's avatar
   
gbazin committed
607
        char *psz_module, *psz_temp;
608
609
610
611
612
613
614
        psz_module = psz_parser;
        psz_parser = strchr( psz_module, ',' );
        if ( psz_parser )
        {
            *psz_parser = '\0';
            psz_parser++;
        }
gbazin's avatar
   
gbazin committed
615
616
617
618
        psz_temp = (char *)malloc( strlen(psz_module) + sizeof(",none") );
        if( psz_temp )
        {
            sprintf( psz_temp, "%s,none", psz_module );
619
            VLC_AddIntf( 0, psz_temp, VLC_FALSE, VLC_FALSE );
gbazin's avatar
   
gbazin committed
620
621
            free( psz_temp );
        }
622
623
624
625
626
    }
    if ( psz_modules )
    {
        free( psz_modules );
    }
627

sigmunau's avatar
sigmunau committed
628
629
630
    /*
     * Allways load the hotkeys interface if it exists
     */
631
    VLC_AddIntf( 0, "hotkeys,none", VLC_FALSE, VLC_FALSE );
sigmunau's avatar
sigmunau committed
632

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

649
650
651
652
653
    /*
     * Get input filenames given as commandline arguments
     */
    GetFilenames( p_vlc, i_argc, ppsz_argv );

gbazin's avatar
   
gbazin committed
654
    if( i_object ) vlc_object_release( p_vlc );
655
656
657
658
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
659
 * VLC_AddIntf: add an interface
660
661
 *****************************************************************************
 * This function opens an interface plugin and runs it. If b_block is set
Sam Hocevar's avatar
Sam Hocevar committed
662
663
 * 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
664
665
 * user requests to quit. If b_play is set to 1, VLC_AddIntf will start playing
 * the playlist when it is completely initialised.
666
 *****************************************************************************/
667
668
int VLC_AddIntf( int i_object, char const *psz_module,
                 vlc_bool_t b_block, vlc_bool_t b_play )
669
{
Sam Hocevar's avatar
Sam Hocevar committed
670
    int i_err;
671
    intf_thread_t *p_intf;
672
    vlc_t *p_vlc = vlc_current_object( i_object );
Sam Hocevar's avatar
Sam Hocevar committed
673

674
    if( !p_vlc )
675
    {
676
        return VLC_ENOOBJ;
677
678
679
    }

    /* Try to create the interface */
680
    p_intf = intf_Create( p_vlc, psz_module ? psz_module : "$intf" );
681
682
683

    if( p_intf == NULL )
    {
gbazin's avatar
   
gbazin committed
684
        msg_Err( p_vlc, "interface \"%s\" initialization failed", psz_module );
gbazin's avatar
   
gbazin committed
685
        if( i_object ) vlc_object_release( p_vlc );
686
687
688
        return VLC_EGENERIC;
    }

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

692
    /* Try to run the interface */
693
    p_intf->b_play = b_play;
694
    p_intf->b_block = b_block;
Sam Hocevar's avatar
Sam Hocevar committed
695
696
    i_err = intf_RunThread( p_intf );
    if( i_err )
697
    {
698
        vlc_object_detach( p_intf );
699
        intf_Destroy( p_intf );
gbazin's avatar
   
gbazin committed
700
        if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
701
        return i_err;
702
703
    }

gbazin's avatar
   
gbazin committed
704
    if( i_object ) vlc_object_release( p_vlc );
705
706
707
708
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
709
 * VLC_Destroy: stop playing and destroy everything.
710
 *****************************************************************************
711
 * This function requests the running threads to finish, waits for their
712
713
 * termination, and destroys their structure.
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
714
int VLC_Destroy( int i_object )
715
{
716
    vlc_t *p_vlc = vlc_current_object( i_object );
717

718
    if( !p_vlc )
719
    {
720
        return VLC_ENOOBJ;
721
722
    }

723
724
725
726
727
728
729
    /*
     * Free allocated memory
     */
    if( p_vlc->p_memcpy_module )
    {
        module_Unneed( p_vlc, p_vlc->p_memcpy_module );
        p_vlc->p_memcpy_module = NULL;
730
731
    }

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

gbazin's avatar
   
gbazin committed
738
739
740
741
742
743
    if( p_vlc->psz_configfile )
    {
        free( p_vlc->psz_configfile );
        p_vlc->psz_configfile = NULL;
    }

744
745
746
747
748
749
    if( p_vlc->p_hotkeys )
    {
        free( p_vlc->p_hotkeys );
        p_vlc->p_hotkeys = NULL;
    }

750
751
752
    /*
     * XXX: Free module bank !
     */
sigmunau's avatar
sigmunau committed
753
    /*module_EndBank( p_vlc );*/
754

755
756
757
758
    /*
     * System specific cleaning code
     */
    system_End( p_vlc );
759

760
761
    /* Destroy mutexes */
    vlc_mutex_destroy( &p_vlc->config_lock );
hartman's avatar
hartman committed
762
763
764
#ifdef SYS_DARWIN
    vlc_mutex_destroy( &p_vlc->quicktime_lock );
#endif
765

766
767
    vlc_object_detach( p_vlc );

768
769
770
    /* Release object before destroying it */
    if( i_object ) vlc_object_release( p_vlc );

771
772
    vlc_object_destroy( p_vlc );

773
    /* Stop thread system: last one out please shut the door! */
774
    vlc_threads_end( p_libvlc );
775

776
777
778
    return VLC_SUCCESS;
}

779
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
780
 * VLC_Die: ask vlc to die.
781
782
 *****************************************************************************
 * This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
783
 * task. It is your duty to call VLC_End and VLC_Destroy afterwards.
784
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
785
int VLC_Die( int i_object )
786
{
787
    vlc_t *p_vlc = vlc_current_object( i_object );
788
789
790

    if( !p_vlc )
    {
791
        return VLC_ENOOBJ;
792
793
794
795
    }

    p_vlc->b_die = VLC_TRUE;

gbazin's avatar
   
gbazin committed
796
    if( i_object ) vlc_object_release( p_vlc );
797
798
799
800
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
801
 * VLC_AddTarget: adds a target for playing.
802
803
804
805
 *****************************************************************************
 * This function adds psz_target to the current playlist. If a playlist does
 * not exist, it will create one.
 *****************************************************************************/
gbazin's avatar
   
gbazin committed
806
807
808
int VLC_AddTarget( int i_object, char const *psz_target,
                   char const **ppsz_options, int i_options,
                   int i_mode, int i_pos )
809
{
Sam Hocevar's avatar
Sam Hocevar committed
810
    int i_err;
Sam Hocevar's avatar
Sam Hocevar committed
811
    playlist_t *p_playlist;
812
    vlc_t *p_vlc = vlc_current_object( i_object );
Sam Hocevar's avatar
Sam Hocevar committed
813

814
    if( !p_vlc )
815
    {
816
        return VLC_ENOOBJ;
817
818
    }

Sam Hocevar's avatar
Sam Hocevar committed
819
820
821
822
823
824
825
826
827
    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
828
            if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
829
830
831
832
833
834
            return VLC_EGENERIC;
        }

        vlc_object_yield( p_playlist );
    }

835
836
    i_err = playlist_AddExt( p_playlist, psz_target, psz_target,
                             i_mode, i_pos, -1, ppsz_options, i_options);
837

Sam Hocevar's avatar
Sam Hocevar committed
838
    vlc_object_release( p_playlist );
839

gbazin's avatar
   
gbazin committed
840
    if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
841
    return i_err;
842
843
}

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

    if( !p_vlc )
    {
856
        return VLC_ENOOBJ;
857
858
    }

Sam Hocevar's avatar
Sam Hocevar committed
859
860
861
    /* 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 ) )
862
    {
Sam Hocevar's avatar
Sam Hocevar committed
863
        module_config_t *p_item;
864
        char const *psz_newvar = psz_var + 6;
865

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

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

gbazin's avatar
   
gbazin committed
890
891
892
893
    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
894
895
896
897
898
899
900
}

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

    if( !p_vlc )
907
    {
908
        return VLC_ENOOBJ;
909
910
    }

gbazin's avatar
   
gbazin committed
911
912
913
914
    i_ret = var_Get( p_vlc, psz_var, p_value );

    if( i_object ) vlc_object_release( p_vlc );
    return i_ret;
915
916
}

Sam Hocevar's avatar
Sam Hocevar committed
917
/* FIXME: temporary hacks */
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
986
987
988
989

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


990
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
991
 * VLC_Play: play
992
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
993
int VLC_Play( int i_object )
994
995
{
    playlist_t * p_playlist;
996
    vlc_t *p_vlc = vlc_current_object( i_object );
997
998

    /* Check that the handle is valid */
999
    if( !p_vlc )
1000
    {
1001
        return VLC_ENOOBJ;
1002
    }
1003

1004
1005
1006
1007
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );

    if( !p_playlist )
    {
gbazin's avatar
   
gbazin committed
1008
        if( i_object ) vlc_object_release( p_vlc );
1009
        return VLC_ENOOBJ;
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
    }

    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
1025
    if( i_object ) vlc_object_release( p_vlc );
1026
1027
1028
1029
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
1030
 * VLC_Stop: stop
1031
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
1032
int VLC_Stop( int i_object )
1033
{
zorglub's avatar
zorglub committed
1034
1035
1036
1037
1038
    intf_thread_t      * p_intf;
    playlist_t         * p_playlist;
    vout_thread_t      * p_vout;
    aout_instance_t    * p_aout;
    announce_handler_t * p_announce;
1039
    vlc_t *p_vlc = vlc_current_object( i_object );