libvlc.c 81.4 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
97
98
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 );

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

#ifdef WIN32
static void ShowConsole   ( void );
110
static void PauseConsole  ( void );
111
#endif
112
static int  ConsoleWidth  ( void );
113

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

117
118
static void InitDeviceValues( vlc_t * );

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

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

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

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

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

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

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

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

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

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

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

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

221
        /* Initialize message queue */
222
        msg_Create( p_libvlc );
223
224

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

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

        libvlc.b_ready = VLC_TRUE;
232
233
234

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

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

    p_vlc->psz_object_name = "root";

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

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

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

    return p_vlc->i_object_id;
263
264
265
}

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

292
    if( !p_vlc )
293
    {
294
        return VLC_ENOOBJ;
295
296
297
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

564
565
566
567
568
    /*
     * Init device values
     */
    InitDeviceValues( p_vlc );

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

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

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

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

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

609
610
611
    /*
     * Message queue options
     */
hartman's avatar
hartman committed
612
613

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

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

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

629
    /* p_vlc initialization. FIXME ? */
630

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

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

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

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

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

687
688
    libvlc.b_stats = config_GetInt( p_vlc, "stats" );

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

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

713
714
715
716
717
718
719
    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
720

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

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

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

768
769
770
771
772
773
774
775
776
777
778
    /*
     * 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

779
780
781
782
783
784
785
786
787
788
    if( config_GetInt( p_vlc, "file-logging" ) == 1 )
    {
        VLC_AddIntf( 0, "logger", VLC_FALSE, VLC_FALSE );
    }
    if( config_GetInt( p_vlc, "syslog" ) == 1 )
    {
        char *psz_logmode = "logmode=syslog";
        AddIntfInternal( 0, "logger", VLC_FALSE, VLC_FALSE, 1, &psz_logmode );
    }

789
790
791
792
793
794
795
796
797
798
    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 );
    }

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

815
816
817
    /* Create volume callback system. */
    var_Create( p_vlc, "volume-change", VLC_VAR_BOOL );

818
819
820
821
822
    /*
     * Get input filenames given as commandline arguments
     */
    GetFilenames( p_vlc, i_argc, ppsz_argv );

823
824
825
826
827
828
829
830
831
832
833
834
    /*
     * 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
835
    if( i_object ) vlc_object_release( p_vlc );
836
837
838
839
    return VLC_SUCCESS;
}

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

854

855
/*****************************************************************************
hartman's avatar
hartman committed
856
857
858
859
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
 * 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
886
    stats_handler_t    * p_stats;
hartman's avatar
hartman committed
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
    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
908
     * Free playlist
hartman's avatar
hartman committed
909
     */
zorglub's avatar
zorglub committed
910
    msg_Dbg( p_vlc, "removing playlist handler" );
hartman's avatar
hartman committed
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
    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
941
942
    while( ( p_stats = vlc_object_find( p_vlc, VLC_OBJECT_STATS, FIND_CHILD) ))
    {
zorglub's avatar
zorglub committed
943
        stats_HandlerDestroy( p_stats );
zorglub's avatar
zorglub committed
944
945
946
947
948
        vlc_object_detach( (vlc_object_t*) p_stats );
        vlc_object_release( (vlc_object_t *)p_stats );
        // TODO: Delete it
    }

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

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

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

975
    if( !p_vlc )
976
    {
977
        return VLC_ENOOBJ;
978
979
    }

980
981
982
983
984
985
986
    /*
     * Free allocated memory
     */
    if( p_vlc->p_memcpy_module )
    {
        module_Unneed( p_vlc, p_vlc->p_memcpy_module );
        p_vlc->p_memcpy_module = NULL;
987
988
    }

989
    /*
990
     * Free module bank !
991
992
993
     */
    module_EndBank( p_vlc );

994
995
996
997
998
    if( p_vlc->psz_homedir )
    {
        free( p_vlc->psz_homedir );
        p_vlc->psz_homedir = NULL;
    }
999

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
1000
    if( p_vlc->psz_userdir )