libvlc.c 80.2 KB
Newer Older
1
2
3
/*****************************************************************************
 * libvlc.c: main libvlc source
 *****************************************************************************
4
 * Copyright (C) 1998-2004 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
12
13
14
15
16
17
18
19
20
21
22
23
 *
 * 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
24
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25
26
27
28
29
30
 *****************************************************************************/

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

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

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

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

#ifdef HAVE_UNISTD_H
#   include <unistd.h>
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
#ifdef HAVE_LOCALE_H
#   include <locale.h>
#endif

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

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

70
#include "vlc_error.h"
71

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

#include "audio_output.h"

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

zorglub's avatar
zorglub committed
80
#include "stream_output.h"
81
#include "charset.h"
zorglub's avatar
zorglub committed
82

83
84
85
#include "libvlc.h"

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

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
95
96
static void LocaleInit( void );
static void LocaleDeinit( void );
Sam Hocevar's avatar
Sam Hocevar committed
97
static void SetLanguage   ( char const * );
98
static int  GetFilenames  ( vlc_t *, int, char *[] );
99
static void Help          ( vlc_t *, char const *psz_help_name );
100
static void Usage         ( vlc_t *, char const *psz_module_name );
101
static void ListModules   ( vlc_t * );
102
103
104
105
static void Version       ( void );

#ifdef WIN32
static void ShowConsole   ( void );
106
static void PauseConsole  ( void );
107
#endif
108
static int  ConsoleWidth  ( void );
109

hartman's avatar
hartman committed
110
111
static int  VerboseCallback( vlc_object_t *, char const *,
                             vlc_value_t, vlc_value_t, void * );
112

113
114
static void InitDeviceValues( vlc_t * );

115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*****************************************************************************
 * 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;
}

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

141
/*****************************************************************************
142
 * VLC_CompileBy, VLC_CompileHost, VLC_CompileDomain,
143
144
145
146
147
 * VLC_Compiler, VLC_Changeset
 *****************************************************************************/
#define DECLARE_VLC_VERSION( func, var )                                    \
char const * VLC_##func ( void )                                            \
{                                                                           \
148
    return VLC_##var ;                                                      \
149
150
}

151
152
DECLARE_VLC_VERSION( CompileBy, COMPILE_BY );
DECLARE_VLC_VERSION( CompileHost, COMPILE_HOST );
Christophe Mutricy's avatar
Typo    
Christophe Mutricy committed
153
DECLARE_VLC_VERSION( CompileDomain, COMPILE_DOMAIN );
154
155
156
157
158
159
160
DECLARE_VLC_VERSION( Compiler, COMPILER );

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

162
163
164
165
166
167
168
169
170
171
/*****************************************************************************
 * 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
172
173
174
175
176
177
178
/*****************************************************************************
 * 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 )
179
{
180
    int i_ret;
181
    vlc_t * p_vlc = NULL;
182
    vlc_value_t lockval;
183

184
185
186
    /* &libvlc never changes, so we can safely call this multiple times. */
    p_libvlc = &libvlc;

187
188
    /* vlc_threads_init *must* be the first internal call! No other call is
     * allowed before the thread system has been initialized. */
189
    i_ret = vlc_threads_init( p_libvlc );
Sam Hocevar's avatar
Sam Hocevar committed
190
    if( i_ret < 0 )
191
    {
Sam Hocevar's avatar
Sam Hocevar committed
192
        return i_ret;
193
194
195
    }

    /* Now that the thread system is initialized, we don't have much, but
196
     * at least we have var_Create */
197
198
    var_Create( p_libvlc, "libvlc", VLC_VAR_MUTEX );
    var_Get( p_libvlc, "libvlc", &lockval );
199
    vlc_mutex_lock( lockval.p_address );
200
201
    if( !libvlc.b_ready )
    {
202
203
        char *psz_env;

204
205
206
        /* Guess what CPU we have */
        libvlc.i_cpu = CPUCapabilities();

207
208
        /* Find verbosity from VLC_VERBOSE environment variable */
        psz_env = getenv( "VLC_VERBOSE" );
209
        libvlc.i_verbose = psz_env ? atoi( psz_env ) : -1;
210

gbazin's avatar
   
gbazin committed
211
#if defined( HAVE_ISATTY ) && !defined( WIN32 )
212
213
214
215
216
        libvlc.b_color = isatty( 2 ); /* 2 is for stderr */
#else
        libvlc.b_color = VLC_FALSE;
#endif

217
        /* Initialize message queue */
218
        msg_Create( p_libvlc );
219
220

        /* Announce who we are */
221
222
        msg_Dbg( p_libvlc, COPYRIGHT_MESSAGE );
        msg_Dbg( p_libvlc, "libvlc was configured with %s", CONFIGURE_LINE );
223

224
225
        /* The module bank will be initialized later */
        libvlc.p_module_bank = NULL;
226
227

        libvlc.b_ready = VLC_TRUE;
228
229
230

        /* UTF-8 convertor are initialized after the locale */
        libvlc.from_locale = libvlc.to_locale = (vlc_iconv_t)(-1);
231
    }
232
    vlc_mutex_unlock( lockval.p_address );
233
    var_Destroy( p_libvlc, "libvlc" );
234
235

    /* Allocate a vlc object */
236
    p_vlc = vlc_object_create( p_libvlc, VLC_OBJECT_VLC );
237
238
    if( p_vlc == NULL )
    {
Sam Hocevar's avatar
Sam Hocevar committed
239
        return VLC_EGENERIC;
240
    }
241
    p_vlc->thread_id = 0;
242
243
244
245

    p_vlc->psz_object_name = "root";

    /* Initialize mutexes */
246
    vlc_mutex_init( p_vlc, &p_vlc->config_lock );
hartman's avatar
hartman committed
247
248
#ifdef SYS_DARWIN
    vlc_mutex_init( p_vlc, &p_vlc->quicktime_lock );
249
    vlc_thread_set_priority( p_vlc, VLC_THREAD_PRIORITY_LOW );
hartman's avatar
hartman committed
250
#endif
251
252

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

Sam Hocevar's avatar
Sam Hocevar committed
255
256
257
258
    /* Store data for the non-reentrant API */
    p_static_vlc = p_vlc;

    return p_vlc->i_object_id;
259
260
261
}

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

288
    if( !p_vlc )
289
    {
290
        return VLC_ENOOBJ;
291
292
293
    }

    /*
294
     * System specific initialization code
295
     */
296
    system_Init( p_vlc, &i_argc, ppsz_argv );
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312

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

313
314
315
316
    /*
     * Support for gettext
     */
    SetLanguage( "" );
Sam Hocevar's avatar
Sam Hocevar committed
317

318
319
320
321
322
323
    /*
     * Global iconv, must be done after setlocale()
     * so that vlc_current_charset() works.
     */
    LocaleInit();

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

327
328
329
330
    /* 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) */
331
    module_InitBank( p_vlc );
332

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

Sam Hocevar's avatar
Sam Hocevar committed
347
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
348
    {
349
        vlc_object_detach( p_help_module );
350
351
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
352
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
353
        if( i_object ) vlc_object_release( p_vlc );
354
355
356
357
358
359
        return VLC_EGENERIC;
    }

    /* Check for short help option */
    if( config_GetInt( p_vlc, "help" ) )
    {
360
        Help( p_vlc, "help" );
361
        b_exit = VLC_TRUE;
362
        i_ret = VLC_EEXITSUCCESS;
363
364
    }
    /* Check for version option */
365
    else if( config_GetInt( p_vlc, "version" ) )
366
367
    {
        Version();
368
        b_exit = VLC_TRUE;
369
        i_ret = VLC_EEXITSUCCESS;
370
371
    }

gbazin's avatar
   
gbazin committed
372
373
    /* Set the config file stuff */
    p_vlc->psz_homedir = config_GetHomeDir();
374
375
376
    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
377
    p_vlc->psz_configfile = config_GetPsz( p_vlc, "config" );
378
379
380
    if( p_vlc->psz_configfile != NULL && p_vlc->psz_configfile[0] == '~'
         && p_vlc->psz_configfile[1] == '/' )
    {
381
        char *psz = malloc( strlen(p_vlc->psz_userdir)
382
383
                             + strlen(p_vlc->psz_configfile) );
        /* This is incomplete : we should also support the ~cmassiot/ syntax. */
384
        sprintf( psz, "%s/%s", p_vlc->psz_userdir,
385
386
387
388
                               p_vlc->psz_configfile + 2 );
        free( p_vlc->psz_configfile );
        p_vlc->psz_configfile = psz;
    }
gbazin's avatar
   
gbazin committed
389

390
391
392
393
394
395
    /* Check for plugins cache options */
    if( config_GetInt( p_vlc, "reset-plugins-cache" ) )
    {
        libvlc.p_module_bank->b_cache_delete = VLC_TRUE;
    }

396
397
398
399
    /* Hack: remove the help module here */
    vlc_object_detach( p_help_module );
    /* End hack */

gbazin's avatar
gbazin committed
400
401
402
403
404
405
406
    /* 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" ) )
    {
407
#if HAVE_DAEMON
408
        if( daemon( 1, 0) != 0 )
409
410
411
412
413
414
415
416
417
        {
            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
418
419
420
421
422
423
424
425
426
427
428

        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;
429
            i_ret = VLC_EEXITSUCCESS;
gbazin's avatar
gbazin committed
430
431
432
433
434
        }
        else
        {
            /* We are the child */
            msg_Dbg( p_vlc, "daemon spawned" );
435
436
437
            close( STDIN_FILENO );
            close( STDOUT_FILENO );
            close( STDERR_FILENO );
gbazin's avatar
gbazin committed
438
439
440

            p_vlc->p_libvlc->b_daemon = VLC_TRUE;
        }
441
#endif
gbazin's avatar
gbazin committed
442
443
444
    }
#endif

445
446
    if( b_exit )
    {
447
448
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
449
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
450
        if( i_object ) vlc_object_release( p_vlc );
451
        return i_ret;
452
453
    }

gbazin's avatar
   
gbazin committed
454
    /* Check for translation config option */
gbazin's avatar
   
gbazin committed
455
456
457
458
459
460
461
462
#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 );

463
464
465
    /* 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
466
    {
467
468
        vlc_bool_t b_cache_delete = libvlc.p_module_bank->b_cache_delete;

gbazin's avatar
   
gbazin committed
469
        /* Reset the default domain */
470
        SetLanguage( psz_language );
471
472
        LocaleDeinit();
        LocaleInit();
gbazin's avatar
   
gbazin committed
473

gbazin's avatar
   
gbazin committed
474
475
476
        /* 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
477
        module_EndBank( p_vlc );
478
        module_InitBank( p_vlc );
479
        config_LoadConfigFile( p_vlc, "main" );
gbazin's avatar
   
gbazin committed
480
        config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
481
        libvlc.p_module_bank->b_cache_delete = b_cache_delete;
gbazin's avatar
   
gbazin committed
482
    }
483
    if( psz_language ) free( psz_language );
484
#endif
gbazin's avatar
   
gbazin committed
485

486
487
488
489
490
491
    /*
     * 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.
     */
492
493
494
495
496
497
498
    module_LoadBuiltins( p_vlc );
    module_LoadPlugins( p_vlc );
    if( p_vlc->b_die )
    {
        b_exit = VLC_TRUE;
    }

499
    msg_Dbg( p_vlc, "module bank initialized, found %i modules",
500
                    libvlc.p_module_bank->i_children );
501
502

    /* Hack: insert the help module here */
503
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
504
505
506
507
508
    /* End hack */

    /* Check for help on modules */
    if( (p_tmp = config_GetPsz( p_vlc, "module" )) )
    {
509
        Help( p_vlc, p_tmp );
510
        free( p_tmp );
511
        b_exit = VLC_TRUE;
512
        i_ret = VLC_EEXITSUCCESS;
513
514
    }
    /* Check for long help option */
515
    else if( config_GetInt( p_vlc, "longhelp" ) )
516
    {
517
        Help( p_vlc, "longhelp" );
518
        b_exit = VLC_TRUE;
519
        i_ret = VLC_EEXITSUCCESS;
520
521
    }
    /* Check for module list option */
522
    else if( config_GetInt( p_vlc, "list" ) )
523
    {
524
        ListModules( p_vlc );
525
        b_exit = VLC_TRUE;
526
        i_ret = VLC_EEXITSUCCESS;
527
528
    }

gbazin's avatar
   
gbazin committed
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
    /* 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 );
    }

547
    /* Hack: remove the help module here */
548
    vlc_object_detach( p_help_module );
549
550
    /* End hack */

551
552
    if( b_exit )
    {
gbazin's avatar
   
gbazin committed
553
554
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
555
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
556
        if( i_object ) vlc_object_release( p_vlc );
557
        return i_ret;
558
559
    }

560
561
562
563
564
    /*
     * Init device values
     */
    InitDeviceValues( p_vlc );

565
566
567
    /*
     * Override default configuration with config file settings
     */
568
    config_LoadConfigFile( p_vlc, NULL );
569

gbazin's avatar
   
gbazin committed
570
571
572
573
    /* Hack: insert the help module here */
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
    /* End hack */

574
575
576
    /*
     * Override configuration with command line settings
     */
Sam Hocevar's avatar
Sam Hocevar committed
577
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
578
579
580
581
582
    {
#ifdef WIN32
        ShowConsole();
        /* Pause the console because it's destroyed when we exit */
        fprintf( stderr, "The command line options couldn't be loaded, check "
583
584
                 "that they are valid.\n" );
        PauseConsole();
585
#endif
gbazin's avatar
   
gbazin committed
586
587
588
        vlc_object_detach( p_help_module );
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
589
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
590
        if( i_object ) vlc_object_release( p_vlc );
591
592
593
        return VLC_EGENERIC;
    }

gbazin's avatar
   
gbazin committed
594
595
596
597
598
599
    /* 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 */

600
601
602
    /*
     * System specific configuration
     */
gbazin's avatar
   
gbazin committed
603
    system_Configure( p_vlc, &i_argc, ppsz_argv );
604

605
606
607
    /*
     * Message queue options
     */
hartman's avatar
hartman committed
608
609

    var_Create( p_vlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
610
611
    if( config_GetInt( p_vlc, "quiet" ) )
    {
hartman's avatar
hartman committed
612
613
        val.i_int = -1;
        var_Set( p_vlc, "verbose", val );
614
    }
hartman's avatar
hartman committed
615
616
    var_AddCallback( p_vlc, "verbose", VerboseCallback, NULL );
    var_Change( p_vlc, "verbose", VLC_VAR_TRIGGER_CALLBACKS, NULL, NULL );
zorglub's avatar
zorglub committed
617

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

620
621
622
623
624
    /*
     * Output messages that may still be in the queue
     */
    msg_Flush( p_vlc );

625
    /* p_vlc initialization. FIXME ? */
626

627
628
629
    if( !config_GetInt( p_vlc, "fpu" ) )
        libvlc.i_cpu &= ~CPU_CAPABILITY_FPU;

Christophe Massiot's avatar
Christophe Massiot committed
630
#if defined( __i386__ ) || defined( __x86_64__ )
631
    if( !config_GetInt( p_vlc, "mmx" ) )
632
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMX;
633
    if( !config_GetInt( p_vlc, "3dn" ) )
634
        libvlc.i_cpu &= ~CPU_CAPABILITY_3DNOW;
635
    if( !config_GetInt( p_vlc, "mmxext" ) )
636
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMXEXT;
637
    if( !config_GetInt( p_vlc, "sse" ) )
638
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE;
sigmunau's avatar
sigmunau committed
639
640
    if( !config_GetInt( p_vlc, "sse2" ) )
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE2;
641
642
#endif
#if defined( __powerpc__ ) || defined( SYS_DARWIN )
643
    if( !config_GetInt( p_vlc, "altivec" ) )
644
        libvlc.i_cpu &= ~CPU_CAPABILITY_ALTIVEC;
645
#endif
646
647

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

673
    if( p_vlc->pf_memcpy == NULL )
674
675
676
    {
        p_vlc->pf_memcpy = memcpy;
    }
677
678
679
680
681

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

683
684
    libvlc.b_stats = config_GetInt( p_vlc, "stats" );

sigmunau's avatar
sigmunau committed
685
686
687
688
    /*
     * Initialize hotkey handling
     */
    var_Create( p_vlc, "key-pressed", VLC_VAR_INTEGER );
gbazin's avatar
   
gbazin committed
689
690
    p_vlc->p_hotkeys = malloc( sizeof(p_hotkeys) );
    /* Do a copy (we don't need to modify the strings) */
691
    memcpy( p_vlc->p_hotkeys, p_hotkeys, sizeof(p_hotkeys) );
gbazin's avatar
   
gbazin committed
692

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

709
710
711
712
713
714
715
    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
716

717
718
719
720
    /*
     * Load background interfaces
     */
    psz_modules = config_GetPsz( p_vlc, "extraintf" );
zorglub's avatar
zorglub committed
721
722
723
724
725
726
    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 );
727
        sprintf( psz_modules, "%s:%s", psz_modules, psz_control );
zorglub's avatar
zorglub committed
728
729
730
731
732
733
734
    }
    else if( psz_control && *psz_control )
    {
        if( psz_modules ) free( psz_modules );
        psz_modules = strdup( psz_control );
    }

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

sigmunau's avatar
sigmunau committed
759
    /*
760
     * Always load the hotkeys interface if it exists
sigmunau's avatar
sigmunau committed
761
     */
762
    VLC_AddIntf( 0, "hotkeys,none", VLC_FALSE, VLC_FALSE );
sigmunau's avatar
sigmunau committed
763

764
765
766
767
768
769
770
771
772
773
774
    /*
     * 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

775
776
777
778
    /*
     * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin
     */
    var_Create( p_vlc, "drawable", VLC_VAR_INTEGER );
779
780
781
782
783
784
785
786
787
788
789
    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 );
790

791
792
793
    /* Create volume callback system. */
    var_Create( p_vlc, "volume-change", VLC_VAR_BOOL );

794
795
796
797
798
    /*
     * Get input filenames given as commandline arguments
     */
    GetFilenames( p_vlc, i_argc, ppsz_argv );

799
800
801
802
803
804
805
806
807
808
809
810
    /*
     * 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
811
    if( i_object ) vlc_object_release( p_vlc );
812
813
814
815
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
816
 * VLC_AddIntf: add an interface
817
818
 *****************************************************************************
 * This function opens an interface plugin and runs it. If b_block is set
Sam Hocevar's avatar
Sam Hocevar committed
819
820
 * 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
821
822
 * user requests to quit. If b_play is set to 1, VLC_AddIntf will start playing
 * the playlist when it is completely initialised.
823
 *****************************************************************************/
824
825
int VLC_AddIntf( int i_object, char const *psz_module,
                 vlc_bool_t b_block, vlc_bool_t b_play )
826
{
Sam Hocevar's avatar
Sam Hocevar committed
827
    int i_err;
828
    intf_thread_t *p_intf;
829
    vlc_t *p_vlc = vlc_current_object( i_object );
Sam Hocevar's avatar
Sam Hocevar committed
830

831
    if( !p_vlc )
832
    {
833
        return VLC_ENOOBJ;
834
835
    }

gbazin's avatar
gbazin committed
836
837
838
839
840
841
842
843
844
845
846
#ifndef WIN32
    if( p_vlc->p_libvlc->b_daemon && b_block && !psz_module )
    {
        /* Daemon mode hack.
         * We prefer the dummy interface if none is specified. */
        char *psz_interface = config_GetPsz( p_vlc, "intf" );
        if( !psz_interface || !*psz_interface ) psz_module = "dummy";
        if( psz_interface ) free( psz_interface );
    }
#endif

847
    /* Try to create the interface */
848
    p_intf = intf_Create( p_vlc, psz_module ? psz_module : "$intf" );
849
850
851

    if( p_intf == NULL )
    {
gbazin's avatar
   
gbazin committed
852
        msg_Err( p_vlc, "interface \"%s\" initialization failed", psz_module );
gbazin's avatar
   
gbazin committed
853
        if( i_object ) vlc_object_release( p_vlc );
854
855
856
        return VLC_EGENERIC;
    }

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

860
    /* Try to run the interface */
861
    p_intf->b_play = b_play;
862
    p_intf->b_block = b_block;
Sam Hocevar's avatar
Sam Hocevar committed
863
864
    i_err = intf_RunThread( p_intf );
    if( i_err )
865
    {
866
        vlc_object_detach( p_intf );
867
        intf_Destroy( p_intf );
gbazin's avatar
   
gbazin committed
868
        if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
869
        return i_err;
870
871
    }

gbazin's avatar
   
gbazin committed
872
    if( i_object ) vlc_object_release( p_vlc );
873
874
875
876
    return VLC_SUCCESS;
}

/*****************************************************************************
hartman's avatar
hartman committed
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
 * 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
907
    stats_handler_t    * p_stats;
hartman's avatar
hartman committed
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
    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
929
     * Free playlist
hartman's avatar
hartman committed
930
     */
zorglub's avatar
zorglub committed
931
    msg_Dbg( p_vlc, "removing playlist handler" );
hartman's avatar
hartman committed
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
    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
962
963
964
965
966
967
968
    while( ( p_stats = vlc_object_find( p_vlc, VLC_OBJECT_STATS, FIND_CHILD) ))
    {
        vlc_object_detach( (vlc_object_t*) p_stats );
        vlc_object_release( (vlc_object_t *)p_stats );
        // TODO: Delete it
    }

hartman's avatar
hartman committed
969
970
971
972
973
    /*
     * Free announce handler(s?)
     */
    while( (p_announce = vlc_object_find( p_vlc, VLC_OBJECT_ANNOUNCE,
                                                 FIND_CHILD ) ) )
zorglub's avatar
zorglub committed
974
975
    {
        msg_Dbg( p_vlc, "removing announce handler" );
hartman's avatar
hartman committed
976
977
978
        vlc_object_detach( p_announce );
        vlc_object_release( p_announce );
        announce_HandlerDestroy( p_announce );
zorglub's avatar
zorglub committed
979
    }
hartman's avatar
hartman committed
980
981
982
983
984
985
986

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

/*****************************************************************************
 * VLC_Destroy: Destroy everything.
987
 *****************************************************************************
988
 * This function requests the running threads to finish, waits for their
989
990
 * termination, and destroys their structure.
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
991
int VLC_Destroy( int i_object )
992
{
993
    vlc_t *p_vlc = vlc_current_object( i_object );
994

995
    if( !p_vlc )
996
    {
997
        return VLC_ENOOBJ;
998
999
    }

1000
    /*