libvlc.c 70.7 KB
Newer Older
1
/*****************************************************************************
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
2
 * libvlc.c: libvlc instances creation and deletion, interfaces handling
3
 *****************************************************************************
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
4
 * Copyright (C) 1998-2008 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
 *****************************************************************************/

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
28
29
30
/** \file
 * This file contains functions to create and destroy libvlc instances
 */
31
32
33
34

/*****************************************************************************
 * Preamble
 *****************************************************************************/
35
36
37
38
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

39
#include <vlc_common.h>
zorglub's avatar
zorglub committed
40
#include "control/libvlc_internal.h"
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
41
#include <vlc_input.h>
42

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
43
44
#include "modules/modules.h"
#include "config/configuration.h"
45

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
46
47
48
49
#include <errno.h>                                                 /* ENOMEM */
#include <stdio.h>                                              /* sprintf() */
#include <string.h>
#include <stdlib.h>                                                /* free() */
50

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
51
52
53
#ifndef WIN32
#   include <netinet/in.h>                            /* BSD: struct in_addr */
#endif
54

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
55
56
57
58
59
#ifdef HAVE_UNISTD_H
#   include <unistd.h>
#elif defined( WIN32 ) && !defined( UNDER_CE )
#   include <io.h>
#endif
60

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
61
62
63
#ifdef WIN32                       /* optind, getopt(), included in unistd.h */
#   include "extras/getopt.h"
#endif
64

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
65
66
67
#ifdef HAVE_LOCALE_H
#   include <locale.h>
#endif
68

69
70
71
72
#ifdef ENABLE_NLS
# include <libintl.h> /* bindtextdomain */
#endif

73
#ifdef HAVE_DBUS
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
74
75
76
/* used for one-instance mode */
#   include <dbus/dbus.h>
#endif
77

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
78
79
#include <vlc_playlist.h>
#include <vlc_interface.h>
Sam Hocevar's avatar
Sam Hocevar committed
80

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
81
82
#include <vlc_aout.h>
#include "audio_output/aout_internal.h"
83

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
84
#include <vlc_charset.h>
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
85
#include <vlc_cpu.h>
86
#include <vlc_url.h>
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
87
#include <vlc_keys.h>
88

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
89
#include "libvlc.h"
90

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
91
#include "playlist/playlist_internal.h"
92

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
93
#include <vlc_vlm.h>
94

95
96
97
98
#ifdef __APPLE__
# include <libkern/OSAtomic.h>
#endif

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
99
#include <assert.h>
100

101
/*****************************************************************************
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
102
 * The evil global variables. We handle them with care, don't worry.
103
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
104
static unsigned          i_instances = 0;
105

106
#ifndef WIN32
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
107
static bool b_daemon = false;
108
#endif
109

110
111
112
#undef vlc_gc_init
#undef vlc_hold
#undef vlc_release
113

114
115
116
117
118
119
120
121
/**
 * Atomically set the reference count to 1.
 * @param p_gc reference counted object
 * @param pf_destruct destruction calback
 * @return p_gc.
 */
void *vlc_gc_init (gc_object_t *p_gc, void (*pf_destruct) (gc_object_t *))
{
geal's avatar
geal committed
122
    /* There is no point in using the GC if there is no destructor... */
123
    assert (pf_destruct);
124
125
    p_gc->pf_destructor = pf_destruct;

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
126
    p_gc->refs = 1;
127
#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
128
    __sync_synchronize ();
129
#elif defined (WIN32) && defined (__GNUC__)
130
131
#elif defined(__APPLE__)
    OSMemoryBarrier ();
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
132
#else
133
134
135
136
    /* Nobody else can possibly lock the spin - it's there as a barrier */
    vlc_spin_init (&p_gc->spin);
    vlc_spin_lock (&p_gc->spin);
    vlc_spin_unlock (&p_gc->spin);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
137
#endif
138
    return p_gc;
139
140
}

141
142
143
144
145
146
/**
 * Atomically increment the reference count.
 * @param p_gc reference counted object
 * @return p_gc.
 */
void *vlc_hold (gc_object_t * p_gc)
147
{
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
148
    uintptr_t refs;
149
    assert( p_gc );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
150
    assert ((((uintptr_t)&p_gc->refs) & (sizeof (void *) - 1)) == 0); /* alignment */
151

152
#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
153
    refs = __sync_add_and_fetch (&p_gc->refs, 1);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
154
#elif defined (WIN64)
155
    refs = InterlockedIncrement64 (&p_gc->refs);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
156
157
#elif defined (WIN32)
    refs = InterlockedIncrement (&p_gc->refs);
158
#elif defined(__APPLE__)
159
    refs = OSAtomicIncrement32Barrier((int*)&p_gc->refs);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
160
#else
161
    vlc_spin_lock (&p_gc->spin);
162
    refs = ++p_gc->refs;
163
    vlc_spin_unlock (&p_gc->spin);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
164
#endif
165
    assert (refs != 1); /* there had to be a reference already */
166
    return p_gc;
167
168
}

169
170
171
172
173
/**
 * Atomically decrement the reference count and, if it reaches zero, destroy.
 * @param p_gc reference counted object.
 */
void vlc_release (gc_object_t *p_gc)
174
{
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
175
    unsigned refs;
176
177

    assert( p_gc );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
178
    assert ((((uintptr_t)&p_gc->refs) & (sizeof (void *) - 1)) == 0); /* alignment */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
179

180
#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
181
    refs = __sync_sub_and_fetch (&p_gc->refs, 1);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
182
#elif defined (WIN64)
183
    refs = InterlockedDecrement64 (&p_gc->refs);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
184
185
#elif defined (WIN32)
    refs = InterlockedDecrement (&p_gc->refs);
186
#elif defined(__APPLE__)
187
    refs = OSAtomicDecrement32Barrier((int*)&p_gc->refs);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
188
#else
189
    vlc_spin_lock (&p_gc->spin);
190
    refs = --p_gc->refs;
191
    vlc_spin_unlock (&p_gc->spin);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
192
#endif
193

194
195
    assert (refs != (uintptr_t)(-1)); /* reference underflow?! */
    if (refs == 0)
196
    {
197
#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
geal's avatar
geal committed
198
#elif defined (WIN32) && defined (__GNUC__)
199
200
#elif defined(__APPLE__)
#else
201
        vlc_spin_destroy (&p_gc->spin);
202
#endif
203
204
        p_gc->pf_destructor (p_gc);
    }
205
206
}

207
/*****************************************************************************
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
208
 * Local prototypes
209
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
210
211
212
213
#if defined( ENABLE_NLS ) && (defined (__APPLE__) || defined (WIN32)) && \
    ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
static void SetLanguage   ( char const * );
#endif
214
static inline int LoadMessages (void);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
215
216
static int  GetFilenames  ( libvlc_int_t *, int, const char *[] );
static void Help          ( libvlc_int_t *, char const *psz_help_name );
217
static void Usage         ( libvlc_int_t *, char const *psz_search );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
218
219
220
221
222
223
224
225
static void ListModules   ( libvlc_int_t *, bool );
static void Version       ( void );

#ifdef WIN32
static void ShowConsole   ( bool );
static void PauseConsole  ( void );
#endif
static int  ConsoleWidth  ( void );
226

227
static vlc_mutex_t global_lock = VLC_STATIC_MUTEX;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
228

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
229
230
231
232
233
234
235
236
237
238
239
240
/**
 * Allocate a libvlc instance, initialize global data if needed
 * It also initializes the threading system
 */
libvlc_int_t * libvlc_InternalCreate( void )
{
    libvlc_int_t *p_libvlc;
    libvlc_priv_t *priv;
    char *psz_env = NULL;

    /* Now that the thread system is initialized, we don't have much, but
     * at least we have variables */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
241
    vlc_mutex_lock( &global_lock );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
242
    if( i_instances == 0 )
hartman's avatar
hartman committed
243
    {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
244
245
        /* Guess what CPU we have */
        cpu_flags = CPUCapabilities();
246
        /* The module bank will be initialized later */
247
    }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
248
249

    /* Allocate a libvlc instance object */
250
    p_libvlc = __vlc_custom_create( NULL, sizeof (*priv),
251
                                  VLC_OBJECT_GENERIC, "libvlc" );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
252
253
    if( p_libvlc != NULL )
        i_instances++;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
254
    vlc_mutex_unlock( &global_lock );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
255
256
257
258
259
260

    if( p_libvlc == NULL )
        return NULL;

    priv = libvlc_priv (p_libvlc);
    priv->p_playlist = NULL;
261
    priv->p_dialog_provider = NULL;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
262
263
264
265
266
267
268
269
270
    priv->p_vlm = NULL;

    /* Initialize message queue */
    msg_Create( p_libvlc );

    /* Find verbosity from VLC_VERBOSE environment variable */
    psz_env = getenv( "VLC_VERBOSE" );
    if( psz_env != NULL )
        priv->i_verbose = atoi( psz_env );
271
    else
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
272
273
274
275
276
277
278
279
280
281
282
        priv->i_verbose = 3;
#if defined( HAVE_ISATTY ) && !defined( WIN32 )
    priv->b_color = isatty( 2 ); /* 2 is for stderr */
#else
    priv->b_color = false;
#endif

    /* Initialize mutexes */
    vlc_mutex_init( &priv->timer_lock );

    return p_libvlc;
hartman's avatar
hartman committed
283
284
285
}

/**
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
286
287
288
289
290
291
 * Initialize a libvlc instance
 * This function initializes a previously allocated libvlc instance:
 *  - CPU detection
 *  - gettext initialization
 *  - message queue, module bank and playlist initialization
 *  - configuration and commandline parsing
hartman's avatar
hartman committed
292
 */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
293
294
int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
                         const char *ppsz_argv[] )
hartman's avatar
hartman committed
295
{
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
296
297
298
299
300
301
302
303
    libvlc_priv_t *priv = libvlc_priv (p_libvlc);
    char *       p_tmp = NULL;
    char *       psz_modules = NULL;
    char *       psz_parser = NULL;
    char *       psz_control = NULL;
    bool   b_exit = false;
    int          i_ret = VLC_EEXIT;
    playlist_t  *p_playlist = NULL;
ivoire's avatar
ivoire committed
304
    char        *psz_val;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
305
306
307
308
309
310
#if defined( ENABLE_NLS ) \
     && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
# if defined (WIN32) || defined (__APPLE__)
    char *       psz_language;
#endif
#endif
hartman's avatar
hartman committed
311

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
312
313
    /* System specific initialization code */
    system_Init( p_libvlc, &i_argc, ppsz_argv );
hartman's avatar
hartman committed
314

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
315
316
317
    /*
     * Support for gettext
     */
318
    LoadMessages ();
hartman's avatar
hartman committed
319

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
320
321
322
323
324
    /* 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) */
    module_InitBank( p_libvlc );
hartman's avatar
hartman committed
325

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
326
    if( config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, true ) )
hartman's avatar
hartman committed
327
    {
328
        module_EndBank( p_libvlc, false );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
329
        return VLC_EGENERIC;
hartman's avatar
hartman committed
330
331
    }

332
    priv->i_verbose = config_GetInt( p_libvlc, "verbose" );
333
334
335
    /* Announce who we are - Do it only for first instance ? */
    msg_Dbg( p_libvlc, "%s", COPYRIGHT_MESSAGE );
    msg_Dbg( p_libvlc, "libvlc was configured with %s", CONFIGURE_LINE );
336
    /*xgettext: Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
337
    msg_Dbg( p_libvlc, "translation test: code is \"%s\"", _("C") );
338

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
339
340
341
342
343
344
345
346
347
    /* Check for short help option */
    if( config_GetInt( p_libvlc, "help" ) > 0 )
    {
        Help( p_libvlc, "help" );
        b_exit = true;
        i_ret = VLC_EEXITSUCCESS;
    }
    /* Check for version option */
    else if( config_GetInt( p_libvlc, "version" ) > 0 )
hartman's avatar
hartman committed
348
    {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
349
350
351
        Version();
        b_exit = true;
        i_ret = VLC_EEXITSUCCESS;
hartman's avatar
hartman committed
352
353
    }

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
354
    /* Check for plugins cache options */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
355
    bool b_cache_delete = config_GetInt( p_libvlc, "reset-plugins-cache" ) > 0;
hartman's avatar
hartman committed
356

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
357
358
359
    /* Check for daemon mode */
#ifndef WIN32
    if( config_GetInt( p_libvlc, "daemon" ) > 0 )
hartman's avatar
hartman committed
360
    {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
361
362
363
364
365
366
367
368
369
370
371
#ifdef HAVE_DAEMON
        char *psz_pidfile = NULL;

        if( daemon( 1, 0) != 0 )
        {
            msg_Err( p_libvlc, "Unable to fork vlc to daemon mode" );
            b_exit = true;
        }
        b_daemon = true;

        /* lets check if we need to write the pidfile */
372
        psz_pidfile = var_CreateGetNonEmptyString( p_libvlc, "pidfile" );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
        if( psz_pidfile != NULL )
        {
            FILE *pidfile;
            pid_t i_pid = getpid ();
            msg_Dbg( p_libvlc, "PID is %d, writing it to %s",
                               i_pid, psz_pidfile );
            pidfile = utf8_fopen( psz_pidfile,"w" );
            if( pidfile != NULL )
            {
                utf8_fprintf( pidfile, "%d", (int)i_pid );
                fclose( pidfile );
            }
            else
            {
                msg_Err( p_libvlc, "cannot open pid file for writing: %s (%m)",
                         psz_pidfile );
            }
        }
        free( psz_pidfile );

#else
        pid_t i_pid;
hartman's avatar
hartman committed
395

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
        if( ( i_pid = fork() ) < 0 )
        {
            msg_Err( p_libvlc, "unable to fork vlc to daemon mode" );
            b_exit = true;
        }
        else if( i_pid )
        {
            /* This is the parent, exit right now */
            msg_Dbg( p_libvlc, "closing parent process" );
            b_exit = true;
            i_ret = VLC_EEXITSUCCESS;
        }
        else
        {
            /* We are the child */
            msg_Dbg( p_libvlc, "daemon spawned" );
            close( STDIN_FILENO );
            close( STDOUT_FILENO );
            close( STDERR_FILENO );

            b_daemon = true;
        }
#endif
    }
#endif
hartman's avatar
hartman committed
421

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
422
    if( b_exit )
hartman's avatar
hartman committed
423
    {
424
        module_EndBank( p_libvlc, false );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
425
        return i_ret;
hartman's avatar
hartman committed
426
427
    }

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
428
429
430
431
432
433
    /* Check for translation config option */
#if defined( ENABLE_NLS ) \
     && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
# if defined (WIN32) || defined (__APPLE__)
    /* This ain't really nice to have to reload the config here but it seems
     * the only way to do it. */
hartman's avatar
hartman committed
434

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
435
436
437
    if( !config_GetInt( p_libvlc, "ignore-config" ) )
        config_LoadConfigFile( p_libvlc, "main" );
    config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, true );
438
    priv->i_verbose = config_GetInt( p_libvlc, "verbose" );
hartman's avatar
hartman committed
439

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
440
    /* Check if the user specified a custom language */
441
442
    psz_language = var_CreateGetNonEmptyString( p_libvlc, "language" );
    if( psz_language && strcmp( psz_language, "auto" ) )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
443
444
445
446
447
448
449
    {
        /* Reset the default domain */
        SetLanguage( psz_language );

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

450
        module_EndBank( p_libvlc, false );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
451
452
453
454
        module_InitBank( p_libvlc );
        if( !config_GetInt( p_libvlc, "ignore-config" ) )
            config_LoadConfigFile( p_libvlc, "main" );
        config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, true );
455
        priv->i_verbose = config_GetInt( p_libvlc, "verbose" );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
456
457
458
459
460
461
462
463
464
465
466
    }
    free( psz_language );
# endif
#endif

    /*
     * 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.
     */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
467
    module_LoadPlugins( p_libvlc, b_cache_delete );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
468
    if( p_libvlc->b_die )
hartman's avatar
hartman committed
469
    {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
470
        b_exit = true;
hartman's avatar
hartman committed
471
472
    }

473
474
475
    size_t module_count;
    module_t **list = module_list_get( &module_count );
    module_list_free( list );
hartman's avatar
hartman committed
476
    msg_Dbg( p_libvlc, "module bank initialized (%zu modules)", module_count );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
477
478

    /* Check for help on modules */
479
    if( (p_tmp = var_CreateGetNonEmptyString( p_libvlc, "module" )) )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
480
481
482
483
484
485
    {
        Help( p_libvlc, p_tmp );
        free( p_tmp );
        b_exit = true;
        i_ret = VLC_EEXITSUCCESS;
    }
486
487
488
489
490
491
492
493
494
    /* Check for full help option */
    else if( config_GetInt( p_libvlc, "full-help" ) > 0 )
    {
        config_PutInt( p_libvlc, "advanced", 1);
        config_PutInt( p_libvlc, "help-verbose", 1);
        Help( p_libvlc, "full-help" );
        b_exit = true;
        i_ret = VLC_EEXITSUCCESS;
    }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
    /* Check for long help option */
    else if( config_GetInt( p_libvlc, "longhelp" ) > 0 )
    {
        Help( p_libvlc, "longhelp" );
        b_exit = true;
        i_ret = VLC_EEXITSUCCESS;
    }
    /* Check for module list option */
    else if( config_GetInt( p_libvlc, "list" ) > 0 )
    {
        ListModules( p_libvlc, false );
        b_exit = true;
        i_ret = VLC_EEXITSUCCESS;
    }
    else if( config_GetInt( p_libvlc, "list-verbose" ) > 0 )
    {
        ListModules( p_libvlc, true );
        b_exit = true;
        i_ret = VLC_EEXITSUCCESS;
    }
hartman's avatar
hartman committed
515

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
516
517
    /* Check for config file options */
    if( !config_GetInt( p_libvlc, "ignore-config" ) )
hartman's avatar
hartman committed
518
    {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
519
520
521
522
523
524
525
526
527
528
529
530
        if( config_GetInt( p_libvlc, "reset-config" ) > 0 )
        {
            config_ResetAll( p_libvlc );
            config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, true );
            config_SaveConfigFile( p_libvlc, NULL );
        }
        if( config_GetInt( p_libvlc, "save-config" ) > 0 )
        {
            config_LoadConfigFile( p_libvlc, NULL );
            config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, true );
            config_SaveConfigFile( p_libvlc, NULL );
        }
hartman's avatar
hartman committed
531
532
    }

533
534
535
536
537
538
539
540
    if( module_count <= 1)
    {
        msg_Err( p_libvlc, "No modules were found, refusing to start. Check "
                "that you properly gave a module path with --plugin-path.");
        b_exit = true;
        i_ret = VLC_ENOITEM;
    }

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
541
    if( b_exit )
hartman's avatar
hartman committed
542
    {
543
        module_EndBank( p_libvlc, true );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
544
        return i_ret;
hartman's avatar
hartman committed
545
    }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
546
547
548
549
550
551
552
553
554
555
556

    /*
     * Override default configuration with config file settings
     */
    if( !config_GetInt( p_libvlc, "ignore-config" ) )
        config_LoadConfigFile( p_libvlc, NULL );

    /*
     * Override configuration with command line settings
     */
    if( config_LoadCmdLine( p_libvlc, &i_argc, ppsz_argv, false ) )
hartman's avatar
hartman committed
557
    {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
558
559
560
561
562
563
564
#ifdef WIN32
        ShowConsole( false );
        /* Pause the console because it's destroyed when we exit */
        fprintf( stderr, "The command line options couldn't be loaded, check "
                 "that they are valid.\n" );
        PauseConsole();
#endif
565
        module_EndBank( p_libvlc, true );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
566
        return VLC_EGENERIC;
hartman's avatar
hartman committed
567
    }
568
    priv->i_verbose = config_GetInt( p_libvlc, "verbose" );
hartman's avatar
hartman committed
569

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
570
571
572
573
    /*
     * System specific configuration
     */
    system_Configure( p_libvlc, &i_argc, ppsz_argv );
hartman's avatar
hartman committed
574

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
575
/* FIXME: could be replaced by using Unix sockets */
576
#ifdef HAVE_DBUS
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
577
    dbus_threads_init_default();
hartman's avatar
hartman committed
578

579
580
581
    if( config_GetInt( p_libvlc, "one-instance" ) > 0
        || ( config_GetInt( p_libvlc, "one-instance-when-started-from-file" )
             && config_GetInt( p_libvlc, "started-from-file" ) ) )
hartman's avatar
hartman committed
582
    {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
        /* Initialise D-Bus interface, check for other instances */
        DBusConnection  *p_conn = NULL;
        DBusError       dbus_error;

        dbus_error_init( &dbus_error );

        /* connect to the session bus */
        p_conn = dbus_bus_get( DBUS_BUS_SESSION, &dbus_error );
        if( !p_conn )
        {
            msg_Err( p_libvlc, "Failed to connect to D-Bus session daemon: %s",
                    dbus_error.message );
            dbus_error_free( &dbus_error );
        }
        else
        {
            /* check if VLC is available on the bus
             * if not: D-Bus control is not enabled on the other
             * instance and we can't pass MRLs to it */
            DBusMessage *p_test_msg = NULL;
            DBusMessage *p_test_reply = NULL;
            p_test_msg =  dbus_message_new_method_call(
                    "org.mpris.vlc", "/",
                    "org.freedesktop.MediaPlayer", "Identity" );
            /* block until a reply arrives */
            p_test_reply = dbus_connection_send_with_reply_and_block(
                    p_conn, p_test_msg, -1, &dbus_error );
            dbus_message_unref( p_test_msg );
            if( p_test_reply == NULL )
            {
                dbus_error_free( &dbus_error );
                msg_Dbg( p_libvlc, "No Media Player is running. "
                        "Continuing normally." );
            }
            else
            {
                int i_input;
                DBusMessage* p_dbus_msg = NULL;
                DBusMessageIter dbus_args;
                DBusPendingCall* p_dbus_pending = NULL;
                dbus_bool_t b_play;

                dbus_message_unref( p_test_reply );
                msg_Warn( p_libvlc, "Another Media Player is running. Exiting");

                for( i_input = optind;i_input < i_argc;i_input++ )
                {
                    msg_Dbg( p_libvlc, "Adds %s to the running Media Player",
                            ppsz_argv[i_input] );

                    p_dbus_msg = dbus_message_new_method_call(
                            "org.mpris.vlc", "/TrackList",
                            "org.freedesktop.MediaPlayer", "AddTrack" );

                    if ( NULL == p_dbus_msg )
                    {
                        msg_Err( p_libvlc, "D-Bus problem" );
                        system_End( p_libvlc );
641
                        exit( 1 );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
642
643
644
645
646
647
648
649
650
                    }

                    /* append MRLs */
                    dbus_message_iter_init_append( p_dbus_msg, &dbus_args );
                    if ( !dbus_message_iter_append_basic( &dbus_args,
                                DBUS_TYPE_STRING, &ppsz_argv[i_input] ) )
                    {
                        dbus_message_unref( p_dbus_msg );
                        system_End( p_libvlc );
651
                        exit( 1 );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
652
653
654
655
656
657
658
659
660
                    }
                    b_play = TRUE;
                    if( config_GetInt( p_libvlc, "playlist-enqueue" ) > 0 )
                        b_play = FALSE;
                    if ( !dbus_message_iter_append_basic( &dbus_args,
                                DBUS_TYPE_BOOLEAN, &b_play ) )
                    {
                        dbus_message_unref( p_dbus_msg );
                        system_End( p_libvlc );
661
                        exit( 1 );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
662
663
664
665
666
667
668
669
670
                    }

                    /* send message and get a handle for a reply */
                    if ( !dbus_connection_send_with_reply ( p_conn,
                                p_dbus_msg, &p_dbus_pending, -1 ) )
                    {
                        msg_Err( p_libvlc, "D-Bus problem" );
                        dbus_message_unref( p_dbus_msg );
                        system_End( p_libvlc );
671
                        exit( 1 );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
672
673
674
675
676
677
678
                    }

                    if ( NULL == p_dbus_pending )
                    {
                        msg_Err( p_libvlc, "D-Bus problem" );
                        dbus_message_unref( p_dbus_msg );
                        system_End( p_libvlc );
679
                        exit( 1 );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
680
681
682
683
684
685
686
687
688
689
                    }
                    dbus_connection_flush( p_conn );
                    dbus_message_unref( p_dbus_msg );
                    /* block until we receive a reply */
                    dbus_pending_call_block( p_dbus_pending );
                    dbus_pending_call_unref( p_dbus_pending );
                } /* processes all command line MRLs */

                /* bye bye */
                system_End( p_libvlc );
690
                exit( 0 );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
691
692
693
694
            }
        }
        /* we unreference the connection when we've finished with it */
        if( p_conn ) dbus_connection_unref( p_conn );
hartman's avatar
hartman committed
695
    }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
696
#endif
hartman's avatar
hartman committed
697

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
698
699
700
    /*
     * Message queue options
     */
701
    char * psz_verbose_objects = var_CreateGetNonEmptyString( p_libvlc, "verbose-objects" );
702
703
704
705
706
707
708
709
710
711
712
713
714
715
    if( psz_verbose_objects )
    {
        char * psz_object, * iter = psz_verbose_objects;
        while( (psz_object = strsep( &iter, "," )) )
        {
            switch( psz_object[0] )
            {
                printf("%s\n", psz_object+1);
                case '+': msg_EnableObjectPrinting(p_libvlc, psz_object+1); break;
                case '-': msg_DisableObjectPrinting(p_libvlc, psz_object+1); break;
                default:
                    msg_Err( p_libvlc, "verbose-objects usage: \n"
                            "--verbose-objects=+printthatobject,"
                            "-dontprintthatone\n"
716
                            "(keyword 'all' to applies to all objects)");
717
                    free( psz_verbose_objects );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
718
                    /* FIXME: leaks!!!! */
719
720
721
722
723
                    return VLC_EGENERIC;
            }
        }
        free( psz_verbose_objects );
    }
hartman's avatar
hartman committed
724

725
    /* Last chance to set the verbosity. Once we start interfaces and other
726
     * threads, verbosity becomes read-only. */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
727
728
    var_Create( p_libvlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
    if( config_GetInt( p_libvlc, "quiet" ) > 0 )
hartman's avatar
hartman committed
729
    {
730
731
        var_SetInteger( p_libvlc, "verbose", -1 );
        priv->i_verbose = -1;
hartman's avatar
hartman committed
732
    }
733
    vlc_threads_setup( p_libvlc );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
734
735
736
737

    if( priv->b_color )
        priv->b_color = config_GetInt( p_libvlc, "color" ) > 0;

738
739
740
741
742
743
744
745
746
747
    char p_capabilities[200];
#define PRINT_CAPABILITY( capability, string )                              \
    if( vlc_CPU() & capability )                                            \
    {                                                                       \
        strncat( p_capabilities, string " ",                                \
                 sizeof(p_capabilities) - strlen(p_capabilities) );         \
        p_capabilities[sizeof(p_capabilities) - 1] = '\0';                  \
    }
    p_capabilities[0] = '\0';

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
748
749
750
751
752
753
754
755
756
757
758
#if defined( __i386__ ) || defined( __x86_64__ )
    if( !config_GetInt( p_libvlc, "mmx" ) )
        cpu_flags &= ~CPU_CAPABILITY_MMX;
    if( !config_GetInt( p_libvlc, "3dn" ) )
        cpu_flags &= ~CPU_CAPABILITY_3DNOW;
    if( !config_GetInt( p_libvlc, "mmxext" ) )
        cpu_flags &= ~CPU_CAPABILITY_MMXEXT;
    if( !config_GetInt( p_libvlc, "sse" ) )
        cpu_flags &= ~CPU_CAPABILITY_SSE;
    if( !config_GetInt( p_libvlc, "sse2" ) )
        cpu_flags &= ~CPU_CAPABILITY_SSE2;
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
759
760
    if( !config_GetInt( p_libvlc, "sse3" ) )
        cpu_flags &= ~CPU_CAPABILITY_SSE3;
761
762
763
764
765
766
    if( !config_GetInt( p_libvlc, "ssse3" ) )
        cpu_flags &= ~CPU_CAPABILITY_SSSE3;
    if( !config_GetInt( p_libvlc, "sse41" ) )
        cpu_flags &= ~CPU_CAPABILITY_SSE4_1;
    if( !config_GetInt( p_libvlc, "sse42" ) )
        cpu_flags &= ~CPU_CAPABILITY_SSE4_2;
hartman's avatar
hartman committed
767

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
768
769
770
771
772
    PRINT_CAPABILITY( CPU_CAPABILITY_MMX, "MMX" );
    PRINT_CAPABILITY( CPU_CAPABILITY_3DNOW, "3DNow!" );
    PRINT_CAPABILITY( CPU_CAPABILITY_MMXEXT, "MMXEXT" );
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE, "SSE" );
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE2, "SSE2" );
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
773
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE3, "SSE3" );
774
775
776
777
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE3, "SSSE3" );
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE4_1, "SSE4.1" );
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE4_2, "SSE4.2" );
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE4A,  "SSE4A" );
778
779
780
781
782

#elif defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ )
    if( !config_GetInt( p_libvlc, "altivec" ) )
        cpu_flags &= ~CPU_CAPABILITY_ALTIVEC;

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
783
    PRINT_CAPABILITY( CPU_CAPABILITY_ALTIVEC, "AltiVec" );
784
785
786
787
788
789

#elif defined( __arm__ )
    PRINT_CAPABILITY( CPU_CAPABILITY_NEON, "NEONv1" );

#endif

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
790
791
792
793
794
795
#if HAVE_FPU
    strncat( p_capabilities, "FPU ",
             sizeof(p_capabilities) - strlen( p_capabilities) );
    p_capabilities[sizeof(p_capabilities) - 1] = '\0';
#endif

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
796
797
798
799
800
    msg_Dbg( p_libvlc, "CPU has capabilities %s", p_capabilities );

    /*
     * Choose the best memcpy module
     */
801
    priv->p_memcpy_module = module_need( p_libvlc, "memcpy", "$memcpy", false );
802
803
    /* Avoid being called "memcpy":*/
    vlc_object_set_name( p_libvlc, "main" );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
804
805
806
807
808

    priv->b_stats = config_GetInt( p_libvlc, "stats" ) > 0;
    priv->i_timers = 0;
    priv->pp_timers = NULL;

809
810
    priv->i_last_input_id = 0; /* Not very safe, should be removed */

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
811
812
813
814
815
    /*
     * Initialize hotkey handling
     */
    var_Create( p_libvlc, "key-pressed", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "key-action", VLC_VAR_INTEGER );
816
817
818
819
    {
        struct hotkey *p_keys =
            malloc( (libvlc_actions_count + 1) * sizeof (*p_keys) );

dionoea's avatar
dionoea committed
820
        /* Initialize from configuration */
821
822
823
824
825
826
        for( size_t i = 0; i < libvlc_actions_count; i++ )
        {
            p_keys[i].psz_action = libvlc_actions[i].name;
            p_keys[i].i_key = config_GetInt( p_libvlc,
                                             libvlc_actions[i].name );
            p_keys[i].i_action = libvlc_actions[i].value;
827
828
829
830
831
832
833
834
835
#ifndef NDEBUG
            if (i > 0
             && strcmp(libvlc_actions[i-1].name, libvlc_actions[i].name) >= 0)
            {
                msg_Err(p_libvlc, "%s and %s are not ordered properly",
                        libvlc_actions[i-1].name, libvlc_actions[i].name);
                abort();
            }
#endif
836
837
838
839
840
841
842
843
        }
        p_keys[libvlc_actions_count].psz_action = NULL;
        p_keys[libvlc_actions_count].i_key = 0;
        p_keys[libvlc_actions_count].i_action = 0;
        p_libvlc->p_hotkeys = p_keys;
        var_AddCallback( p_libvlc, "key-pressed", vlc_key_to_action,
                         p_keys );
    }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
844

845
846
847
848
    /* variables for signalling creation of new files */
    var_Create( p_libvlc, "snapshot-file", VLC_VAR_STRING );
    var_Create( p_libvlc, "record-file", VLC_VAR_STRING );

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
849
    /* Initialize playlist and get commandline files */
850
851
    p_playlist = playlist_Create( VLC_OBJECT(p_libvlc) );
    if( !p_playlist )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
852
853
854
855
    {
        msg_Err( p_libvlc, "playlist initialization failed" );
        if( priv->p_memcpy_module != NULL )
        {
856
            module_unneed( p_libvlc, priv->p_memcpy_module );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
857
        }
858
        module_EndBank( p_libvlc, true );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
859
860
        return VLC_EGENERIC;
    }
861
862
    playlist_Activate( p_playlist );
    vlc_object_attach( p_playlist, p_libvlc );
hartman's avatar
hartman committed
863

864
    /* Add service discovery modules */
865
866
    psz_modules = var_CreateGetNonEmptyString( p_playlist, "services-discovery" );
    if( psz_modules )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
867
    {
868
869
870
        char *p = psz_modules, *m;
        while( ( m = strsep( &p, " :," ) ) != NULL )
            playlist_ServicesDiscoveryAdd( p_playlist, m );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
871
872
    }
    free( psz_modules );
hartman's avatar
hartman committed
873

874
#ifdef ENABLE_VLM
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
875
    /* Initialize VLM if vlm-conf is specified */
876
877
    psz_parser = var_CreateGetNonEmptyString( p_libvlc, "vlm-conf" );
    if( psz_parser )
hartman's avatar
hartman committed
878
    {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
879
880
881
        priv->p_vlm = vlm_New( p_libvlc );
        if( !priv->p_vlm )
            msg_Err( p_libvlc, "VLM initialization failed" );
hartman's avatar
hartman committed
882
    }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
883
884
    free( psz_parser );
#endif
hartman's avatar
hartman committed
885

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
886
887
888
    /*
     * Load background interfaces
     */
889
890
891
892
    /* Create volume callback system. (this variable must be created before
       all interfaces as they can use it) */
    var_Create( p_libvlc, "volume-change", VLC_VAR_BOOL );

893
894
    psz_modules = var_CreateGetNonEmptyString( p_libvlc, "extraintf" );
    psz_control = var_CreateGetNonEmptyString( p_libvlc, "control" );
hartman's avatar
hartman committed
895

896
    if( psz_modules && psz_control )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
897
    {
898
899
900
901
902
903
        char* psz_tmp;
        if( asprintf( &psz_tmp, "%s:%s", psz_modules, psz_control ) != -1 )
        {
            free( psz_modules );
            psz_modules = psz_tmp;
        }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
904
    }
905
    else if( psz_control )
hartman's avatar
hartman committed
906
    {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
907
908
        free( psz_modules );
        psz_modules = strdup( psz_control );
hartman's avatar
hartman committed
909
910
    }

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
911
912
913
914
915
916
917
918
919
920
921
    psz_parser = psz_modules;
    while ( psz_parser && *psz_parser )
    {
        char *psz_module, *psz_temp;
        psz_module = psz_parser;
        psz_parser = strchr( psz_module, ':' );
        if ( psz_parser )
        {
            *psz_parser = '\0';
            psz_parser++;
        }
922
        if( asprintf( &psz_temp, "%s,none", psz_module ) != -1)
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
923
        {
924
            intf_Create( p_libvlc, psz_temp );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
925
926
927
928
929
930
931
932
933
            free( psz_temp );
        }
    }
    free( psz_modules );
    free( psz_control );

    /*
     * Always load the hotkeys interface if it exists
     */
934
    intf_Create( p_libvlc, "hotkeys,none" );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
935

936
#ifdef HAVE_DBUS
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
937
938
    /* loads dbus control interface if in one-instance mode
     * we do it only when playlist exists, because dbus module needs it */
939
940
941
    if( config_GetInt( p_libvlc, "one-instance" ) > 0
        || ( config_GetInt( p_libvlc, "one-instance-when-started-from-file" )
             && config_GetInt( p_libvlc, "started-from-file" ) ) )
942
        intf_Create( p_libvlc, "dbus,none" );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
943

944
# if !defined (HAVE_MAEMO)
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
945
946
947
    /* Prevents the power management daemon from suspending the system
     * when VLC is active */
    if( config_GetInt( p_libvlc, "inhibit" ) > 0 )
948
        intf_Create( p_libvlc, "inhibit,none" );
949
# endif
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
950
#endif
hartman's avatar
hartman committed
951

952
953
    if( (config_GetInt( p_libvlc, "file-logging" ) > 0) &&
        !config_GetInt( p_libvlc, "syslog" ) )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
954
    {
955
        intf_Create( p_libvlc, "logger,none" );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
956
957
958
959
    }
#ifdef HAVE_SYSLOG_H
    if( config_GetInt( p_libvlc, "syslog" ) > 0 )
    {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
960
        char *logmode = var_CreateGetNonEmptyString( p_libvlc, "logmode" );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
961
        var_SetString( p_libvlc, "logmode", "syslog" );
962
        intf_Create( p_libvlc, "logger,none" );
hartman's avatar
hartman committed
963

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
964
965
966
967
968
        if( logmode )
        {
            var_SetString( p_libvlc, "logmode", logmode );
            free( logmode );
        }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
969
        var_Destroy( p_libvlc, "logmode" );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
970
971
972
973
974
    }
#endif

    if( config_GetInt( p_libvlc, "network-synchronisation") > 0 )
    {
975
        intf_Create( p_libvlc, "netsync,none" );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
976
    }
hartman's avatar
hartman committed
977

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
978
979
#ifdef WIN32
    if( config_GetInt( p_libvlc, "prefer-system-codecs") > 0 )
hartman's avatar
hartman committed
980
    {
981
        char *psz_codecs = var_CreateGetNonEmptyString( p_playlist, "codec" );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
982
983
984
        if( psz_codecs )
        {
            char *psz_morecodecs;
ivoire's avatar
ivoire committed
985
            if( asprintf(&psz_morecodecs, "%s,dmo,quicktime", psz_codecs) != -1 )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
986
            {
987
                var_SetString( p_libvlc, "codec", psz_morecodecs);
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
988
989
                free( psz_morecodecs );
            }
990
            free( psz_codecs );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
991
992
        }
        else
993
            var_SetString( p_libvlc, "codec", "dmo,quicktime");
hartman's avatar
hartman committed
994
    }
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
995
#endif
hartman's avatar
hartman committed
996

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
997
998
999
1000
1001
1002
1003
1004
1005
1006
    var_Create( p_libvlc, "drawable-view-top", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-view-left", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-view-bottom", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-view-right", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-clip-top", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-clip-left", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-clip-bottom", VLC_VAR_INTEGER );
    var_Create( p_libvlc, "drawable-clip-right", VLC_VAR_INTEGER );


1007
    /* Create a variable for showing the fullscreen interface from hotkeys */
1008
1009
1010
    var_Create( p_libvlc, "intf-show", VLC_VAR_BOOL );
    var_SetBool( p_libvlc, "intf-show", true );

1011
    /* Create a variable for showing the right click menu */
1012
    var_Create( p_libvlc, "intf-popupmenu", VLC_VAR_BOOL );
1013

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
1014
1015
1016
1017
1018
1019
1020
1021
    /*
     * Get input filenames given as commandline arguments
     */
    GetFilenames( p_libvlc, i_argc, ppsz_argv );

    /*
     * Get --open argument
     */
1022
1023
    psz_val = var_CreateGetNonEmptyString( p_libvlc, "open" );
    if ( psz_val != NULL )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
1024
    {
dionoea's avatar
dionoea committed
1025
        playlist_t *p_playlist = pl_Hold( p_libvlc );
ivoire's avatar
ivoire committed
1026
        playlist_AddExt( p_playlist, psz_val, NULL, PLAYLIST_INSERT, 0,
1027
                         -1, 0, NULL, 0, true, pl_Unlocked );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
1028
1029
        pl_Release( p_libvlc );
    }
ivoire's avatar
ivoire committed
1030
    free( psz_val );
hartman's avatar
hartman committed
1031

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
1032
    return VLC_SUCCESS;
hartman's avatar
hartman committed
1033
1034
1035
}

/**
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
1036
1037
 * Cleanup a libvlc instance. The instance is not completely deallocated
 * \param p_libvlc the instance to clean
hartman's avatar
hartman committed
1038
 */
1039
void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
hartman's avatar
hartman committed
1040
{
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
    libvlc_priv_t *priv = libvlc_priv (p_libvlc);
    playlist_t    *p_playlist = priv->p_playlist;

    /* Deactivate the playlist */
    msg_Dbg( p_libvlc, "deactivating the playlist" );
    playlist_Deactivate( p_playlist );

    /* Remove all services discovery */
    msg_Dbg( p_libvlc, "removing all services discovery tasks" );
    playlist_ServicesDiscoveryKillAll( p_playlist );
hartman's avatar
hartman committed
1051

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
1052
1053
    /* Ask the interfaces to stop and destroy them */
    msg_Dbg( p_libvlc, "removing all interfaces" );
1054
    libvlc_Quit( p_libvlc );
1055
    intf_DestroyAll( p_libvlc );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
1056

1057
#ifdef ENABLE_VLM
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
1058
1059
1060
1061
1062
1063
1064
1065
    /* Destroy VLM if created in libvlc_InternalInit */
    if( priv->p_vlm )
    {
        vlm_Delete( priv->p_vlm );
    }
#endif

    /* Free playlist */
dionoea's avatar
dionoea committed
1066
    /* Any thread still running must not assume pl_Hold() succeeds. */
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
1067
    msg_Dbg( p_libvlc, "removing playlist" );
1068

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
1069
    libvlc_priv(p_libvlc)->p_playlist = NULL;
1070
1071
    barrier();  /* FIXME is that correct ? */

1072
    vlc_object_release( p_playlist );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
1073
1074
1075
1076
1077
1078
1079