]> git.sesse.net Git - vlc/blob - src/libvlc.c
Remove unneeded #include <vlc_aout.h>
[vlc] / src / libvlc.c
1 /*****************************************************************************
2  * libvlc.c: libvlc instances creation and deletion, interfaces handling
3  *****************************************************************************
4  * Copyright (C) 1998-2008 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Vincent Seguin <seguin@via.ecp.fr>
8  *          Samuel Hocevar <sam@zoy.org>
9  *          Gildas Bazin <gbazin@videolan.org>
10  *          Derk-Jan Hartman <hartman at videolan dot org>
11  *          RĂ©mi Denis-Courmont <rem # videolan : org>
12  *
13  * This program is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU Lesser General Public License as published by
15  * the Free Software Foundation; either version 2.1 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26  *****************************************************************************/
27
28 /** \file
29  * This file contains functions to create and destroy libvlc instances
30  */
31
32 /*****************************************************************************
33  * Preamble
34  *****************************************************************************/
35 #ifdef HAVE_CONFIG_H
36 # include "config.h"
37 #endif
38
39 #include <vlc_common.h>
40 #include "../lib/libvlc_internal.h"
41 #include <vlc_input.h>
42
43 #include "modules/modules.h"
44 #include "config/configuration.h"
45
46 #include <stdio.h>                                              /* sprintf() */
47 #include <string.h>
48 #include <stdlib.h>                                                /* free() */
49
50 #include "config/vlc_getopt.h"
51
52 #ifdef HAVE_LOCALE_H
53 #   include <locale.h>
54 #endif
55 #ifdef HAVE_UNISTD_H
56 #   include <unistd.h> /* isatty() */
57 #endif
58
59 #ifdef HAVE_DBUS
60 /* used for one-instance mode */
61 #   include <dbus/dbus.h>
62 #endif
63
64
65 #include <vlc_media_library.h>
66 #include <vlc_playlist.h>
67 #include <vlc_interface.h>
68
69 #include <vlc_charset.h>
70 #include <vlc_fs.h>
71 #include <vlc_cpu.h>
72 #include <vlc_url.h>
73 #include <vlc_atomic.h>
74 #include <vlc_modules.h>
75
76 #include "libvlc.h"
77
78 #include "playlist/playlist_internal.h"
79
80 #include <vlc_vlm.h>
81
82 #ifdef __APPLE__
83 # include <libkern/OSAtomic.h>
84 #endif
85
86 #include <assert.h>
87
88 /*****************************************************************************
89  * The evil global variables. We handle them with care, don't worry.
90  *****************************************************************************/
91
92 #if !defined(WIN32) && !defined(__OS2__)
93 static bool b_daemon = false;
94 #endif
95
96 #undef vlc_gc_init
97 #undef vlc_hold
98 #undef vlc_release
99
100 /**
101  * Atomically set the reference count to 1.
102  * @param p_gc reference counted object
103  * @param pf_destruct destruction calback
104  * @return p_gc.
105  */
106 void *vlc_gc_init (gc_object_t *p_gc, void (*pf_destruct) (gc_object_t *))
107 {
108     /* There is no point in using the GC if there is no destructor... */
109     assert (pf_destruct);
110     p_gc->pf_destructor = pf_destruct;
111
112     vlc_atomic_set (&p_gc->refs, 1);
113     return p_gc;
114 }
115
116 /**
117  * Atomically increment the reference count.
118  * @param p_gc reference counted object
119  * @return p_gc.
120  */
121 void *vlc_hold (gc_object_t * p_gc)
122 {
123     uintptr_t refs;
124
125     assert( p_gc );
126     refs = vlc_atomic_inc (&p_gc->refs);
127     assert (refs != 1); /* there had to be a reference already */
128     return p_gc;
129 }
130
131 /**
132  * Atomically decrement the reference count and, if it reaches zero, destroy.
133  * @param p_gc reference counted object.
134  */
135 void vlc_release (gc_object_t *p_gc)
136 {
137     uintptr_t refs;
138
139     assert( p_gc );
140     refs = vlc_atomic_dec (&p_gc->refs);
141     assert (refs != (uintptr_t)(-1)); /* reference underflow?! */
142     if (refs == 0)
143         p_gc->pf_destructor (p_gc);
144 }
145
146 /*****************************************************************************
147  * Local prototypes
148  *****************************************************************************/
149 #if defined( ENABLE_NLS ) && (defined (__APPLE__) || defined (WIN32)) && \
150     ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
151 static void SetLanguage   ( char const * );
152 #endif
153 static void GetFilenames  ( libvlc_int_t *, unsigned, const char *const [] );
154
155 /**
156  * Allocate a libvlc instance, initialize global data if needed
157  * It also initializes the threading system
158  */
159 libvlc_int_t * libvlc_InternalCreate( void )
160 {
161     libvlc_int_t *p_libvlc;
162     libvlc_priv_t *priv;
163     char *psz_env = NULL;
164
165     /* Now that the thread system is initialized, we don't have much, but
166      * at least we have variables */
167     /* Allocate a libvlc instance object */
168     p_libvlc = vlc_custom_create( (vlc_object_t *)NULL, sizeof (*priv),
169                                   "libvlc" );
170     if( p_libvlc == NULL )
171         return NULL;
172
173     priv = libvlc_priv (p_libvlc);
174     priv->p_playlist = NULL;
175     priv->p_ml = NULL;
176     priv->p_dialog_provider = NULL;
177     priv->p_vlm = NULL;
178
179     /* Find verbosity from VLC_VERBOSE environment variable */
180     psz_env = getenv( "VLC_VERBOSE" );
181     if( psz_env != NULL )
182         priv->i_verbose = atoi( psz_env );
183     else
184         priv->i_verbose = 3;
185 #if defined( HAVE_ISATTY ) && !defined( WIN32 )
186     priv->b_color = isatty( 2 ); /* 2 is for stderr */
187 #else
188     priv->b_color = false;
189 #endif
190
191     /* Initialize mutexes */
192     vlc_mutex_init( &priv->ml_lock );
193     vlc_ExitInit( &priv->exit );
194
195     return p_libvlc;
196 }
197
198 /**
199  * Initialize a libvlc instance
200  * This function initializes a previously allocated libvlc instance:
201  *  - CPU detection
202  *  - gettext initialization
203  *  - message queue, module bank and playlist initialization
204  *  - configuration and commandline parsing
205  */
206 int libvlc_InternalInit( libvlc_int_t *p_libvlc, int i_argc,
207                          const char *ppsz_argv[] )
208 {
209     libvlc_priv_t *priv = libvlc_priv (p_libvlc);
210     char *       psz_modules = NULL;
211     char *       psz_parser = NULL;
212     char *       psz_control = NULL;
213     playlist_t  *p_playlist = NULL;
214     char        *psz_val;
215
216     /* System specific initialization code */
217     system_Init();
218
219     /* Initialize the module bank and load the configuration of the
220      * main module. We need to do this at this stage to be able to display
221      * a short help if required by the user. (short help == main module
222      * options) */
223     module_InitBank ();
224
225     /* Get command line options that affect module loading. */
226     if( config_LoadCmdLine( p_libvlc, i_argc, ppsz_argv, NULL ) )
227     {
228         module_EndBank (false);
229         return VLC_EGENERIC;
230     }
231     priv->i_verbose = var_InheritInteger( p_libvlc, "verbose" );
232
233     /* Announce who we are (TODO: only first instance?) */
234     msg_Dbg( p_libvlc, "VLC media player - %s", VERSION_MESSAGE );
235     msg_Dbg( p_libvlc, "%s", COPYRIGHT_MESSAGE );
236     msg_Dbg( p_libvlc, "revision %s", psz_vlc_changeset );
237     msg_Dbg( p_libvlc, "configured with %s", CONFIGURE_LINE );
238
239     /* Load the builtins and plugins into the module_bank.
240      * We have to do it before config_Load*() because this also gets the
241      * list of configuration options exported by each module and loads their
242      * default values. */
243     size_t module_count = module_LoadPlugins (p_libvlc);
244
245     /*
246      * Override default configuration with config file settings
247      */
248     if( !var_InheritBool( p_libvlc, "ignore-config" ) )
249     {
250         if( var_InheritBool( p_libvlc, "reset-config" ) )
251             config_SaveConfigFile( p_libvlc ); /* Save default config */
252         else
253             config_LoadConfigFile( p_libvlc );
254     }
255
256     /*
257      * Override configuration with command line settings
258      */
259     int vlc_optind;
260     if( config_LoadCmdLine( p_libvlc, i_argc, ppsz_argv, &vlc_optind ) )
261     {
262 #ifdef WIN32
263         MessageBox (NULL, TEXT("The command line options could not be parsed.\n"
264                     "Make sure they are valid."), TEXT("VLC media player"),
265                     MB_OK|MB_ICONERROR);
266 #endif
267         module_EndBank (true);
268         return VLC_EGENERIC;
269     }
270     priv->i_verbose = var_InheritInteger( p_libvlc, "verbose" );
271
272     /*
273      * Support for gettext
274      */
275 #if defined( ENABLE_NLS ) \
276      && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
277 # if defined (WIN32) || defined (__APPLE__)
278     /* Check if the user specified a custom language */
279     char *lang = var_InheritString (p_libvlc, "language");
280     if (lang != NULL && strcmp (lang, "auto"))
281         SetLanguage (lang);
282     free (lang);
283 # endif
284     vlc_bindtextdomain (PACKAGE_NAME);
285 #endif
286     /*xgettext: Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
287     msg_Dbg( p_libvlc, "translation test: code is \"%s\"", _("C") );
288
289     if (config_PrintHelp (VLC_OBJECT(p_libvlc)))
290     {
291         module_EndBank (true);
292         return VLC_EEXITSUCCESS;
293     }
294
295     if( module_count <= 1 )
296     {
297         msg_Err( p_libvlc, "No plugins found! Check your VLC installation.");
298         module_EndBank (true);
299         return VLC_ENOITEM;
300     }
301
302 #ifdef HAVE_DAEMON
303     /* Check for daemon mode */
304     if( var_InheritBool( p_libvlc, "daemon" ) )
305     {
306         char *psz_pidfile = NULL;
307
308         if( daemon( 1, 0) != 0 )
309         {
310             msg_Err( p_libvlc, "Unable to fork vlc to daemon mode" );
311             module_EndBank (true);
312             return VLC_EEXIT;
313         }
314         b_daemon = true;
315
316         /* lets check if we need to write the pidfile */
317         psz_pidfile = var_CreateGetNonEmptyString( p_libvlc, "pidfile" );
318         if( psz_pidfile != NULL )
319         {
320             FILE *pidfile;
321             pid_t i_pid = getpid ();
322             msg_Dbg( p_libvlc, "PID is %d, writing it to %s",
323                                i_pid, psz_pidfile );
324             pidfile = vlc_fopen( psz_pidfile,"w" );
325             if( pidfile != NULL )
326             {
327                 utf8_fprintf( pidfile, "%d", (int)i_pid );
328                 fclose( pidfile );
329             }
330             else
331             {
332                 msg_Err( p_libvlc, "cannot open pid file for writing: %s (%m)",
333                          psz_pidfile );
334             }
335         }
336         free( psz_pidfile );
337     }
338 #endif
339
340 /* FIXME: could be replaced by using Unix sockets */
341 #ifdef HAVE_DBUS
342     dbus_threads_init_default();
343
344     if( var_InheritBool( p_libvlc, "one-instance" )
345     || ( var_InheritBool( p_libvlc, "one-instance-when-started-from-file" )
346       && var_InheritBool( p_libvlc, "started-from-file" ) ) )
347     {
348         /* Initialise D-Bus interface, check for other instances */
349         DBusConnection  *p_conn = NULL;
350         DBusError       dbus_error;
351
352         dbus_error_init( &dbus_error );
353
354         /* connect to the session bus */
355         p_conn = dbus_bus_get( DBUS_BUS_SESSION, &dbus_error );
356         if( !p_conn )
357         {
358             msg_Err( p_libvlc, "Failed to connect to D-Bus session daemon: %s",
359                     dbus_error.message );
360             dbus_error_free( &dbus_error );
361         }
362         else
363         {
364             /* check if VLC is available on the bus
365              * if not: D-Bus control is not enabled on the other
366              * instance and we can't pass MRLs to it */
367             DBusMessage *p_test_msg   = NULL;
368             DBusMessage *p_test_reply = NULL;
369
370             p_test_msg =  dbus_message_new_method_call(
371                     "org.mpris.MediaPlayer2.vlc", "/org/mpris/MediaPlayer2",
372                     "org.freedesktop.DBus.Introspectable", "Introspect" );
373
374             /* block until a reply arrives */
375             p_test_reply = dbus_connection_send_with_reply_and_block(
376                     p_conn, p_test_msg, -1, &dbus_error );
377             dbus_message_unref( p_test_msg );
378             if( p_test_reply == NULL )
379             {
380                 dbus_error_free( &dbus_error );
381                 msg_Dbg( p_libvlc, "No Media Player is running. "
382                         "Continuing normally." );
383             }
384             else
385             {
386                 int i_input;
387                 DBusMessage* p_dbus_msg = NULL;
388                 DBusMessageIter dbus_args;
389                 DBusPendingCall* p_dbus_pending = NULL;
390                 dbus_bool_t b_play;
391
392                 dbus_message_unref( p_test_reply );
393                 msg_Warn( p_libvlc, "Another Media Player is running. Exiting");
394
395                 for( i_input = vlc_optind; i_input < i_argc;i_input++ )
396                 {
397                     /* Skip input options, we can't pass them through D-Bus */
398                     if( ppsz_argv[i_input][0] == ':' )
399                     {
400                         msg_Warn( p_libvlc, "Ignoring option %s",
401                                   ppsz_argv[i_input] );
402                         continue;
403                     }
404
405                     /* We need to resolve relative paths in this instance */
406                     char *psz_mrl = make_URI( ppsz_argv[i_input], NULL );
407                     const char *psz_after_track = "/";
408
409                     if( psz_mrl == NULL )
410                         continue;
411                     msg_Dbg( p_libvlc, "Adds %s to the running Media Player",
412                              psz_mrl );
413
414                     p_dbus_msg = dbus_message_new_method_call(
415                         "org.mpris.MediaPlayer2.vlc", "/org/mpris/MediaPlayer2",
416                         "org.mpris.MediaPlayer2.TrackList", "AddTrack" );
417
418                     if ( NULL == p_dbus_msg )
419                     {
420                         msg_Err( p_libvlc, "D-Bus problem" );
421                         free( psz_mrl );
422                         system_End( );
423                         exit( 1 );
424                     }
425
426                     /* append MRLs */
427                     dbus_message_iter_init_append( p_dbus_msg, &dbus_args );
428                     if ( !dbus_message_iter_append_basic( &dbus_args,
429                                 DBUS_TYPE_STRING, &psz_mrl ) )
430                     {
431                         dbus_message_unref( p_dbus_msg );
432                         free( psz_mrl );
433                         system_End( );
434                         exit( 1 );
435                     }
436                     free( psz_mrl );
437
438                     if( !dbus_message_iter_append_basic( &dbus_args,
439                                 DBUS_TYPE_OBJECT_PATH, &psz_after_track ) )
440                     {
441                         dbus_message_unref( p_dbus_msg );
442                         system_End( );
443                         exit( 1 );
444                     }
445
446                     b_play = TRUE;
447                     if( var_InheritBool( p_libvlc, "playlist-enqueue" ) )
448                         b_play = FALSE;
449
450                     if ( !dbus_message_iter_append_basic( &dbus_args,
451                                 DBUS_TYPE_BOOLEAN, &b_play ) )
452                     {
453                         dbus_message_unref( p_dbus_msg );
454                         system_End( );
455                         exit( 1 );
456                     }
457
458                     /* send message and get a handle for a reply */
459                     if ( !dbus_connection_send_with_reply ( p_conn,
460                                 p_dbus_msg, &p_dbus_pending, -1 ) )
461                     {
462                         msg_Err( p_libvlc, "D-Bus problem" );
463                         dbus_message_unref( p_dbus_msg );
464                         system_End( );
465                         exit( 1 );
466                     }
467
468                     if ( NULL == p_dbus_pending )
469                     {
470                         msg_Err( p_libvlc, "D-Bus problem" );
471                         dbus_message_unref( p_dbus_msg );
472                         system_End( );
473                         exit( 1 );
474                     }
475                     dbus_connection_flush( p_conn );
476                     dbus_message_unref( p_dbus_msg );
477                     /* block until we receive a reply */
478                     dbus_pending_call_block( p_dbus_pending );
479                     dbus_pending_call_unref( p_dbus_pending );
480                 } /* processes all command line MRLs */
481
482                 /* bye bye */
483                 system_End( );
484                 exit( 0 );
485             }
486         }
487         /* we unreference the connection when we've finished with it */
488         if( p_conn ) dbus_connection_unref( p_conn );
489     }
490 #endif
491
492     /*
493      * Message queue options
494      */
495     /* Last chance to set the verbosity. Once we start interfaces and other
496      * threads, verbosity becomes read-only. */
497     var_Create( p_libvlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
498     if( var_InheritBool( p_libvlc, "quiet" ) )
499     {
500         var_SetInteger( p_libvlc, "verbose", -1 );
501         priv->i_verbose = -1;
502     }
503     vlc_threads_setup( p_libvlc );
504
505     if( priv->b_color )
506         priv->b_color = var_InheritBool( p_libvlc, "color" );
507
508     vlc_CPU_dump( VLC_OBJECT(p_libvlc) );
509     /*
510      * Choose the best memcpy module
511      */
512     priv->p_memcpy_module = module_need( p_libvlc, "memcpy", "$memcpy", false );
513     /* Avoid being called "memcpy":*/
514     vlc_object_set_name( p_libvlc, "main" );
515
516     priv->b_stats = var_InheritBool( p_libvlc, "stats" );
517
518     /*
519      * Initialize hotkey handling
520      */
521     priv->actions = vlc_InitActions( p_libvlc );
522
523     /* Create a variable for showing the fullscreen interface */
524     var_Create( p_libvlc, "intf-toggle-fscontrol", VLC_VAR_BOOL );
525     var_SetBool( p_libvlc, "intf-toggle-fscontrol", true );
526
527     /* Create a variable for the Boss Key */
528     var_Create( p_libvlc, "intf-boss", VLC_VAR_VOID );
529
530     /* Create a variable for showing the main interface */
531     var_Create( p_libvlc, "intf-show", VLC_VAR_BOOL );
532
533     /* Create a variable for showing the right click menu */
534     var_Create( p_libvlc, "intf-popupmenu", VLC_VAR_BOOL );
535
536     /* variables for signalling creation of new files */
537     var_Create( p_libvlc, "snapshot-file", VLC_VAR_STRING );
538     var_Create( p_libvlc, "record-file", VLC_VAR_STRING );
539
540     /* some default internal settings */
541     var_Create( p_libvlc, "window", VLC_VAR_STRING );
542     var_Create( p_libvlc, "user-agent", VLC_VAR_STRING );
543     var_SetString( p_libvlc, "user-agent", "(LibVLC "VERSION")" );
544
545     /* Initialize playlist and get commandline files */
546     p_playlist = playlist_Create( VLC_OBJECT(p_libvlc) );
547     if( !p_playlist )
548     {
549         msg_Err( p_libvlc, "playlist initialization failed" );
550         if( priv->p_memcpy_module != NULL )
551         {
552             module_unneed( p_libvlc, priv->p_memcpy_module );
553         }
554         module_EndBank (true);
555         return VLC_EGENERIC;
556     }
557
558     /* System specific configuration */
559     system_Configure( p_libvlc, i_argc - vlc_optind, ppsz_argv + vlc_optind );
560
561 #if defined(MEDIA_LIBRARY)
562     /* Get the ML */
563     if( var_GetBool( p_libvlc, "load-media-library-on-startup" ) )
564     {
565         priv->p_ml = ml_Create( VLC_OBJECT( p_libvlc ), NULL );
566         if( !priv->p_ml )
567         {
568             msg_Err( p_libvlc, "ML initialization failed" );
569             return VLC_EGENERIC;
570         }
571     }
572     else
573     {
574         priv->p_ml = NULL;
575     }
576 #endif
577
578     /* Add service discovery modules */
579     psz_modules = var_InheritString( p_libvlc, "services-discovery" );
580     if( psz_modules )
581     {
582         char *p = psz_modules, *m;
583         while( ( m = strsep( &p, " :," ) ) != NULL )
584             playlist_ServicesDiscoveryAdd( p_playlist, m );
585         free( psz_modules );
586     }
587
588 #ifdef ENABLE_VLM
589     /* Initialize VLM if vlm-conf is specified */
590     psz_parser = var_CreateGetNonEmptyString( p_libvlc, "vlm-conf" );
591     if( psz_parser )
592     {
593         priv->p_vlm = vlm_New( p_libvlc );
594         if( !priv->p_vlm )
595             msg_Err( p_libvlc, "VLM initialization failed" );
596     }
597     free( psz_parser );
598 #endif
599
600     /*
601      * Load background interfaces
602      */
603     psz_modules = var_CreateGetNonEmptyString( p_libvlc, "extraintf" );
604     psz_control = var_CreateGetNonEmptyString( p_libvlc, "control" );
605
606     if( psz_modules && psz_control )
607     {
608         char* psz_tmp;
609         if( asprintf( &psz_tmp, "%s:%s", psz_modules, psz_control ) != -1 )
610         {
611             free( psz_modules );
612             psz_modules = psz_tmp;
613         }
614     }
615     else if( psz_control )
616     {
617         free( psz_modules );
618         psz_modules = strdup( psz_control );
619     }
620
621     psz_parser = psz_modules;
622     while ( psz_parser && *psz_parser )
623     {
624         char *psz_module, *psz_temp;
625         psz_module = psz_parser;
626         psz_parser = strchr( psz_module, ':' );
627         if ( psz_parser )
628         {
629             *psz_parser = '\0';
630             psz_parser++;
631         }
632         if( asprintf( &psz_temp, "%s,none", psz_module ) != -1)
633         {
634             intf_Create( p_libvlc, psz_temp );
635             free( psz_temp );
636         }
637     }
638     free( psz_modules );
639     free( psz_control );
640
641     /*
642      * Always load the hotkeys interface if it exists
643      */
644     intf_Create( p_libvlc, "hotkeys,none" );
645
646     if( var_InheritBool( p_libvlc, "file-logging" )
647 #ifdef HAVE_SYSLOG_H
648         && !var_InheritBool( p_libvlc, "syslog" )
649 #endif
650         )
651     {
652         intf_Create( p_libvlc, "logger,none" );
653     }
654 #ifdef HAVE_SYSLOG_H
655     if( var_InheritBool( p_libvlc, "syslog" ) )
656     {
657         char *logmode = var_CreateGetNonEmptyString( p_libvlc, "logmode" );
658         var_SetString( p_libvlc, "logmode", "syslog" );
659         intf_Create( p_libvlc, "logger,none" );
660
661         if( logmode )
662         {
663             var_SetString( p_libvlc, "logmode", logmode );
664             free( logmode );
665         }
666         var_Destroy( p_libvlc, "logmode" );
667     }
668 #endif
669
670     if( var_InheritBool( p_libvlc, "network-synchronisation") )
671     {
672         intf_Create( p_libvlc, "netsync,none" );
673     }
674
675 #ifdef __APPLE__
676     var_Create( p_libvlc, "drawable-view-top", VLC_VAR_INTEGER );
677     var_Create( p_libvlc, "drawable-view-left", VLC_VAR_INTEGER );
678     var_Create( p_libvlc, "drawable-view-bottom", VLC_VAR_INTEGER );
679     var_Create( p_libvlc, "drawable-view-right", VLC_VAR_INTEGER );
680     var_Create( p_libvlc, "drawable-clip-top", VLC_VAR_INTEGER );
681     var_Create( p_libvlc, "drawable-clip-left", VLC_VAR_INTEGER );
682     var_Create( p_libvlc, "drawable-clip-bottom", VLC_VAR_INTEGER );
683     var_Create( p_libvlc, "drawable-clip-right", VLC_VAR_INTEGER );
684     var_Create( p_libvlc, "drawable-nsobject", VLC_VAR_ADDRESS );
685 #endif
686 #if defined (WIN32) || defined (__OS2__)
687     var_Create( p_libvlc, "drawable-hwnd", VLC_VAR_INTEGER );
688 #endif
689
690     /*
691      * Get input filenames given as commandline arguments.
692      * We assume that the remaining parameters are filenames
693      * and their input options.
694      */
695     GetFilenames( p_libvlc, i_argc - vlc_optind, ppsz_argv + vlc_optind );
696
697     /*
698      * Get --open argument
699      */
700     psz_val = var_InheritString( p_libvlc, "open" );
701     if ( psz_val != NULL )
702     {
703         playlist_AddExt( p_playlist, psz_val, NULL, PLAYLIST_INSERT, 0,
704                          -1, 0, NULL, 0, true, pl_Unlocked );
705         free( psz_val );
706     }
707
708     return VLC_SUCCESS;
709 }
710
711 /**
712  * Cleanup a libvlc instance. The instance is not completely deallocated
713  * \param p_libvlc the instance to clean
714  */
715 void libvlc_InternalCleanup( libvlc_int_t *p_libvlc )
716 {
717     libvlc_priv_t *priv = libvlc_priv (p_libvlc);
718     playlist_t    *p_playlist = libvlc_priv (p_libvlc)->p_playlist;
719
720     /* Deactivate the playlist */
721     msg_Dbg( p_libvlc, "deactivating the playlist" );
722     pl_Deactivate( p_libvlc );
723
724     /* Remove all services discovery */
725     msg_Dbg( p_libvlc, "removing all services discovery tasks" );
726     playlist_ServicesDiscoveryKillAll( p_playlist );
727
728     /* Ask the interfaces to stop and destroy them */
729     msg_Dbg( p_libvlc, "removing all interfaces" );
730     libvlc_Quit( p_libvlc );
731     intf_DestroyAll( p_libvlc );
732
733 #ifdef ENABLE_VLM
734     /* Destroy VLM if created in libvlc_InternalInit */
735     if( priv->p_vlm )
736     {
737         vlm_Delete( priv->p_vlm );
738     }
739 #endif
740
741 #if defined(MEDIA_LIBRARY)
742     media_library_t* p_ml = priv->p_ml;
743     if( p_ml )
744     {
745         ml_Destroy( VLC_OBJECT( p_ml ) );
746         vlc_object_release( p_ml );
747         libvlc_priv(p_playlist->p_libvlc)->p_ml = NULL;
748     }
749 #endif
750
751     /* Free playlist now, all threads are gone */
752     playlist_Destroy( p_playlist );
753
754     msg_Dbg( p_libvlc, "removing stats" );
755
756 #if !defined( WIN32 ) && !defined( __OS2__ )
757     char* psz_pidfile = NULL;
758
759     if( b_daemon )
760     {
761         psz_pidfile = var_CreateGetNonEmptyString( p_libvlc, "pidfile" );
762         if( psz_pidfile != NULL )
763         {
764             msg_Dbg( p_libvlc, "removing pid file %s", psz_pidfile );
765             if( unlink( psz_pidfile ) == -1 )
766             {
767                 msg_Dbg( p_libvlc, "removing pid file %s: %m",
768                         psz_pidfile );
769             }
770         }
771         free( psz_pidfile );
772     }
773 #endif
774
775     if( priv->p_memcpy_module )
776     {
777         module_unneed( p_libvlc, priv->p_memcpy_module );
778         priv->p_memcpy_module = NULL;
779     }
780
781     /* Save the configuration */
782     if( !var_InheritBool( p_libvlc, "ignore-config" ) )
783         config_AutoSaveConfigFile( VLC_OBJECT(p_libvlc) );
784
785     /* Free module bank. It is refcounted, so we call this each time  */
786     module_EndBank (true);
787
788     vlc_DeinitActions( p_libvlc, priv->actions );
789 }
790
791 /**
792  * Destroy everything.
793  * This function requests the running threads to finish, waits for their
794  * termination, and destroys their structure.
795  * It stops the thread systems: no instance can run after this has run
796  * \param p_libvlc the instance to destroy
797  */
798 void libvlc_InternalDestroy( libvlc_int_t *p_libvlc )
799 {
800     libvlc_priv_t *priv = libvlc_priv( p_libvlc );
801
802     system_End( );
803
804     /* Destroy mutexes */
805     vlc_ExitDestroy( &priv->exit );
806     vlc_mutex_destroy( &priv->ml_lock );
807
808 #ifndef NDEBUG /* Hack to dump leaked objects tree */
809     if( vlc_internals( p_libvlc )->i_refcount > 1 )
810         while( vlc_internals( p_libvlc )->i_refcount > 0 )
811             vlc_object_release( p_libvlc );
812 #endif
813
814     assert( vlc_internals( p_libvlc )->i_refcount == 1 );
815     vlc_object_release( p_libvlc );
816 }
817
818 /**
819  * Add an interface plugin and run it
820  */
821 int libvlc_InternalAddIntf( libvlc_int_t *p_libvlc, char const *psz_module )
822 {
823     if( !p_libvlc )
824         return VLC_EGENERIC;
825
826     if( !psz_module ) /* requesting the default interface */
827     {
828         char *psz_interface = var_CreateGetNonEmptyString( p_libvlc, "intf" );
829         if( !psz_interface ) /* "intf" has not been set */
830         {
831 #if !defined( WIN32 ) && !defined( __OS2__ )
832             if( b_daemon )
833                  /* Daemon mode hack.
834                   * We prefer the dummy interface if none is specified. */
835                 psz_module = "dummy";
836             else
837 #endif
838                 msg_Info( p_libvlc, "%s",
839                           _("Running vlc with the default interface. "
840                             "Use 'cvlc' to use vlc without interface.") );
841         }
842         free( psz_interface );
843         var_Destroy( p_libvlc, "intf" );
844     }
845
846     /* Try to create the interface */
847     int ret = intf_Create( p_libvlc, psz_module ? psz_module : "$intf" );
848     if( ret )
849         msg_Err( p_libvlc, "interface \"%s\" initialization failed",
850                  psz_module ? psz_module : "default" );
851     return ret;
852 }
853
854 #if defined( ENABLE_NLS ) && (defined (__APPLE__) || defined (WIN32)) && \
855     ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
856 /*****************************************************************************
857  * SetLanguage: set the interface language.
858  *****************************************************************************
859  * We set the LC_MESSAGES locale category for interface messages and buttons,
860  * as well as the LC_CTYPE category for string sorting and possible wide
861  * character support.
862  *****************************************************************************/
863 static void SetLanguage ( const char *psz_lang )
864 {
865 #ifdef __APPLE__
866     /* I need that under Darwin, please check it doesn't disturb
867      * other platforms. --Meuuh */
868     setenv( "LANG", psz_lang, 1 );
869
870 #else
871     /* We set LC_ALL manually because it is the only way to set
872      * the language at runtime under eg. Windows. Beware that this
873      * makes the environment unconsistent when libvlc is unloaded and
874      * should probably be moved to a safer place like vlc.c. */
875     setenv( "LC_ALL", psz_lang, 1 );
876
877 #endif
878
879     setlocale( LC_ALL, psz_lang );
880 }
881 #endif
882
883 /*****************************************************************************
884  * GetFilenames: parse command line options which are not flags
885  *****************************************************************************
886  * Parse command line for input files as well as their associated options.
887  * An option always follows its associated input and begins with a ":".
888  *****************************************************************************/
889 static void GetFilenames( libvlc_int_t *p_vlc, unsigned n,
890                           const char *const args[] )
891 {
892     while( n > 0 )
893     {
894         /* Count the input options */
895         unsigned i_options = 0;
896
897         while( args[--n][0] == ':' )
898         {
899             i_options++;
900             if( n == 0 )
901             {
902                 msg_Warn( p_vlc, "options %s without item", args[n] );
903                 return; /* syntax!? */
904             }
905         }
906
907         char *mrl = make_URI( args[n], NULL );
908         if( !mrl )
909             continue;
910
911         playlist_AddExt( pl_Get( p_vlc ), mrl, NULL, PLAYLIST_INSERT,
912                 0, -1, i_options, ( i_options ? &args[n + 1] : NULL ),
913                 VLC_INPUT_OPTION_TRUSTED, true, pl_Unlocked );
914         free( mrl );
915     }
916 }