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

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

/*****************************************************************************
 * Preamble
 *****************************************************************************/
38
#include <vlc/vlc.h>
Laurent Aimar's avatar
Laurent Aimar committed
39
#include <vlc/input.h>
40

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

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

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

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

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

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

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

72
#include "vlc_error.h"
73

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

#include "audio_output.h"

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

zorglub's avatar
zorglub committed
82
#include "stream_output.h"
83
#include "charset.h"
zorglub's avatar
zorglub committed
84

85
86
87
#include "libvlc.h"

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

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

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

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

hartman's avatar
hartman committed
116
117
static int  VerboseCallback( vlc_object_t *, char const *,
                             vlc_value_t, vlc_value_t, void * );
118

119
120
static void InitDeviceValues( vlc_t * );

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*****************************************************************************
 * 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;
}

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

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

157
158
DECLARE_VLC_VERSION( CompileBy, COMPILE_BY );
DECLARE_VLC_VERSION( CompileHost, COMPILE_HOST );
Christophe Mutricy's avatar
Typo    
Christophe Mutricy committed
159
DECLARE_VLC_VERSION( CompileDomain, COMPILE_DOMAIN );
160
161
162
163
164
165
166
DECLARE_VLC_VERSION( Compiler, COMPILER );

extern const char psz_vlc_changeset[];
char const * VLC_Changeset( void )
{
    return psz_vlc_changeset;
}
167

168
169
170
171
172
173
174
175
176
177
/*****************************************************************************
 * 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
178
179
180
181
182
183
184
/*****************************************************************************
 * 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 )
185
{
186
    int i_ret;
187
    vlc_t * p_vlc = NULL;
188
    vlc_value_t lockval;
189

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

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

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

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

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

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

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

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

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

        libvlc.b_ready = VLC_TRUE;
234
235
236

        /* UTF-8 convertor are initialized after the locale */
        libvlc.from_locale = libvlc.to_locale = (vlc_iconv_t)(-1);
237
    }
238
    vlc_mutex_unlock( lockval.p_address );
239
    var_Destroy( p_libvlc, "libvlc" );
240
241

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

    p_vlc->psz_object_name = "root";

    /* Initialize mutexes */
252
    vlc_mutex_init( p_vlc, &p_vlc->config_lock );
253
#ifdef __APPLE__
hartman's avatar
hartman committed
254
    vlc_mutex_init( p_vlc, &p_vlc->quicktime_lock );
255
    vlc_thread_set_priority( p_vlc, VLC_THREAD_PRIORITY_LOW );
hartman's avatar
hartman committed
256
#endif
257
258

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

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

    return p_vlc->i_object_id;
265
266
267
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
268
 * VLC_Init: initialize a vlc_t structure.
269
270
271
272
273
274
275
 *****************************************************************************
 * 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
276
int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
277
{
278
279
    char         p_capabilities[200];
    char *       p_tmp;
280
281
    char *       psz_modules;
    char *       psz_parser;
zorglub's avatar
zorglub committed
282
    char *       psz_control;
283
    vlc_bool_t   b_exit = VLC_FALSE;
284
    int          i_ret = VLC_EEXIT;
285
    vlc_t *      p_vlc = vlc_current_object( i_object );
286
287
    module_t    *p_help_module;
    playlist_t  *p_playlist;
288
    vlc_value_t  val;
289
290
#if defined( ENABLE_NLS ) \
     && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
291
    char *       psz_language;
292
#endif
293

294
    if( !p_vlc )
295
    {
296
        return VLC_ENOOBJ;
297
298
299
    }

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

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

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

324
325
326
327
328
329
    /*
     * Global iconv, must be done after setlocale()
     * so that vlc_current_charset() works.
     */
    LocaleInit();

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

333
334
335
336
    /* 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) */
337
    module_InitBank( p_vlc );
338

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

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

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

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

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

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

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

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

        p_vlc->p_libvlc->b_daemon = VLC_TRUE;

#else
        pid_t i_pid;
gbazin's avatar
gbazin committed
424
425
426
427
428
429
430
431
432
433
434

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

            p_vlc->p_libvlc->b_daemon = VLC_TRUE;
        }
447
#endif
gbazin's avatar
gbazin committed
448
449
450
    }
#endif

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

gbazin's avatar
   
gbazin committed
460
    /* Check for translation config option */
gbazin's avatar
   
gbazin committed
461
462
463
464
465
466
467
468
#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 );

469
470
471
    /* 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
472
    {
473
474
        vlc_bool_t b_cache_delete = libvlc.p_module_bank->b_cache_delete;

gbazin's avatar
   
gbazin committed
475
        /* Reset the default domain */
476
        SetLanguage( psz_language );
477
478
        LocaleDeinit();
        LocaleInit();
gbazin's avatar
   
gbazin committed
479

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

gbazin's avatar
   
gbazin committed
483
        module_EndBank( p_vlc );
484
        module_InitBank( p_vlc );
485
        config_LoadConfigFile( p_vlc, "main" );
gbazin's avatar
   
gbazin committed
486
        config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
487
        libvlc.p_module_bank->b_cache_delete = b_cache_delete;
gbazin's avatar
   
gbazin committed
488
    }
489
    if( psz_language ) free( psz_language );
490
#endif
gbazin's avatar
   
gbazin committed
491

492
493
494
495
496
497
    /*
     * 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.
     */
498
499
500
501
502
503
504
    module_LoadBuiltins( p_vlc );
    module_LoadPlugins( p_vlc );
    if( p_vlc->b_die )
    {
        b_exit = VLC_TRUE;
    }

505
    msg_Dbg( p_vlc, "module bank initialized, found %i modules",
506
                    libvlc.p_module_bank->i_children );
507
508

    /* Hack: insert the help module here */
509
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
510
511
512
513
514
    /* End hack */

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

gbazin's avatar
   
gbazin committed
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
    /* 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 );
    }

553
    /* Hack: remove the help module here */
554
    vlc_object_detach( p_help_module );
555
556
    /* End hack */

557
558
    if( b_exit )
    {
gbazin's avatar
   
gbazin committed
559
560
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
561
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
562
        if( i_object ) vlc_object_release( p_vlc );
563
        return i_ret;
564
565
    }

566
567
568
569
570
    /*
     * Init device values
     */
    InitDeviceValues( p_vlc );

571
572
573
    /*
     * Override default configuration with config file settings
     */
574
    config_LoadConfigFile( p_vlc, NULL );
575

gbazin's avatar
   
gbazin committed
576
577
578
579
    /* Hack: insert the help module here */
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
    /* End hack */

580
581
582
    /*
     * Override configuration with command line settings
     */
Sam Hocevar's avatar
Sam Hocevar committed
583
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
584
585
586
587
588
    {
#ifdef WIN32
        ShowConsole();
        /* Pause the console because it's destroyed when we exit */
        fprintf( stderr, "The command line options couldn't be loaded, check "
589
590
                 "that they are valid.\n" );
        PauseConsole();
591
#endif
gbazin's avatar
   
gbazin committed
592
593
594
        vlc_object_detach( p_help_module );
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
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;
    }

gbazin's avatar
   
gbazin committed
600
601
602
603
604
605
    /* 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 */

606
607
608
    /*
     * System specific configuration
     */
gbazin's avatar
   
gbazin committed
609
    system_Configure( p_vlc, &i_argc, ppsz_argv );
610

611
612
613
    /*
     * Message queue options
     */
hartman's avatar
hartman committed
614
615

    var_Create( p_vlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
616
617
    if( config_GetInt( p_vlc, "quiet" ) )
    {
hartman's avatar
hartman committed
618
619
        val.i_int = -1;
        var_Set( p_vlc, "verbose", val );
620
    }
hartman's avatar
hartman committed
621
622
    var_AddCallback( p_vlc, "verbose", VerboseCallback, NULL );
    var_Change( p_vlc, "verbose", VLC_VAR_TRIGGER_CALLBACKS, NULL, NULL );
zorglub's avatar
zorglub committed
623

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

626
627
628
629
630
    /*
     * Output messages that may still be in the queue
     */
    msg_Flush( p_vlc );

631
    /* p_vlc initialization. FIXME ? */
632

633
634
635
    if( !config_GetInt( p_vlc, "fpu" ) )
        libvlc.i_cpu &= ~CPU_CAPABILITY_FPU;

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

#define PRINT_CAPABILITY( capability, string )                              \
654
    if( libvlc.i_cpu & capability )                                         \
655
656
657
658
659
660
661
662
663
664
665
666
667
668
    {                                                                       \
        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
669
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE2, "SSE2" );
670
671
672
673
674
675
676
    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
677
    p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy", 0 );
678

679
    if( p_vlc->pf_memcpy == NULL )
680
681
682
    {
        p_vlc->pf_memcpy = memcpy;
    }
683
684
685
686
687

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

689
690
    libvlc.b_stats = config_GetInt( p_vlc, "stats" );

sigmunau's avatar
sigmunau committed
691
692
693
694
    /*
     * Initialize hotkey handling
     */
    var_Create( p_vlc, "key-pressed", VLC_VAR_INTEGER );
gbazin's avatar
   
gbazin committed
695
696
    p_vlc->p_hotkeys = malloc( sizeof(p_hotkeys) );
    /* Do a copy (we don't need to modify the strings) */
697
    memcpy( p_vlc->p_hotkeys, p_hotkeys, sizeof(p_hotkeys) );
gbazin's avatar
   
gbazin committed
698

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

715
716
717
718
719
720
721
    psz_modules = config_GetPsz( p_playlist, "services-discovery" );
    if( psz_modules && *psz_modules )
    {
        /* Add service discovery modules */
        playlist_AddSDModules( p_playlist, psz_modules );
    }
    if( psz_modules ) free( psz_modules );
zorglub's avatar
zorglub committed
722

723
724
725
726
    /*
     * Load background interfaces
     */
    psz_modules = config_GetPsz( p_vlc, "extraintf" );
zorglub's avatar
zorglub committed
727
728
729
730
731
732
    psz_control = config_GetPsz( p_vlc, "control" );

    if( psz_modules && *psz_modules && psz_control && *psz_control )
    {
        psz_modules = (char *)realloc( psz_modules, strlen( psz_modules ) +
                                                    strlen( psz_control ) + 1 );
733
        sprintf( psz_modules, "%s:%s", psz_modules, psz_control );
zorglub's avatar
zorglub committed
734
735
736
737
738
739
740
    }
    else if( psz_control && *psz_control )
    {
        if( psz_modules ) free( psz_modules );
        psz_modules = strdup( psz_control );
    }

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

sigmunau's avatar
sigmunau committed
765
    /*
766
     * Always load the hotkeys interface if it exists
sigmunau's avatar
sigmunau committed
767
     */
768
    VLC_AddIntf( 0, "hotkeys,none", VLC_FALSE, VLC_FALSE );
sigmunau's avatar
sigmunau committed
769

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

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

793
794
795
796
797
798
799
800
801
802
    if( config_GetInt( p_vlc, "show-intf" ) == 1 )
    {
        VLC_AddIntf( 0, "showintf", VLC_FALSE, VLC_FALSE );
    }

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

803
804
805
806
    /*
     * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin
     */
    var_Create( p_vlc, "drawable", VLC_VAR_INTEGER );
807
808
809
810
811
812
813
814
815
816
817
    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 );
818

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

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

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

gbazin's avatar
   
gbazin committed
839
    if( i_object ) vlc_object_release( p_vlc );
840
841
842
843
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
844
 * VLC_AddIntf: add an interface
845
846
 *****************************************************************************
 * This function opens an interface plugin and runs it. If b_block is set
Sam Hocevar's avatar
Sam Hocevar committed
847
848
 * 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
849
850
 * user requests to quit. If b_play is set to 1, VLC_AddIntf will start playing
 * the playlist when it is completely initialised.
851
 *****************************************************************************/
852
853
int VLC_AddIntf( int i_object, char const *psz_module,
                 vlc_bool_t b_block, vlc_bool_t b_play )
854
{
855
    return AddIntfInternal( i_object, psz_module, b_block, b_play, 0, NULL );
856
857
}

858

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

    if( !p_vlc )
    {
        return VLC_ENOOBJ;
    }

    p_vlc->b_die = VLC_TRUE;

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

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

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

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

    /*
zorglub's avatar
zorglub committed
912
     * Free playlist
hartman's avatar
hartman committed
913
     */
zorglub's avatar
zorglub committed
914
    msg_Dbg( p_vlc, "removing playlist handler" );
hartman's avatar
hartman committed
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
    while( (p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST,
                                          FIND_CHILD )) )
    {
        vlc_object_detach( p_playlist );
        vlc_object_release( p_playlist );
        playlist_Destroy( p_playlist );
    }

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

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

zorglub's avatar
zorglub committed
945
946
    while( ( p_stats = vlc_object_find( p_vlc, VLC_OBJECT_STATS, FIND_CHILD) ))
    {
zorglub's avatar
zorglub committed
947
        stats_TimersDumpAll( p_vlc );
zorglub's avatar
zorglub committed
948
        stats_HandlerDestroy( p_stats );
zorglub's avatar
zorglub committed
949
950
951
952
953
        vlc_object_detach( (vlc_object_t*) p_stats );
        vlc_object_release( (vlc_object_t *)p_stats );
        // TODO: Delete it
    }

hartman's avatar
hartman committed
954
955
956
957
958
    /*
     * Free announce handler(s?)
     */
    while( (p_announce = vlc_object_find( p_vlc, VLC_OBJECT_ANNOUNCE,
                                                 FIND_CHILD ) ) )
zorglub's avatar
zorglub committed
959
960
    {
        msg_Dbg( p_vlc, "removing announce handler" );
hartman's avatar
hartman committed
961
962
963
        vlc_object_detach( p_announce );
        vlc_object_release( p_announce );
        announce_HandlerDestroy( p_announce );
zorglub's avatar
zorglub committed
964
    }
hartman's avatar
hartman committed
965
966
967
968
969
970
971

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

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

980
    if( !p_vlc )
981
    {
982
        return VLC_ENOOBJ;
983
984
    }

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

994
    /*
995
     * Free module bank !
996
997
998
     */
    module_EndBank( p_vlc );

999
1000
    if( p_vlc->psz_homedir )
    {