libvlc.c 43.5 KB
Newer Older
1
2
3
/*****************************************************************************
 * libvlc.c: main libvlc source
 *****************************************************************************
4
 * Copyright (C) 1998-2002 VideoLAN
5
 * $Id: libvlc.c,v 1.66 2003/02/20 01:52:46 sigmunau Exp $
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 *
 * Authors: Vincent Seguin <seguin@via.ecp.fr>
 *          Samuel Hocevar <sam@zoy.org>
 *          Gildas Bazin <gbazin@netcourrier.com>
 *
 * 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
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

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

/*****************************************************************************
 * Preamble
 *****************************************************************************/
36
37
38
39
40
#include <vlc/vlc.h>

#ifdef HAVE_ERRNO_H
#   include <errno.h>                                              /* ENOMEM */
#endif
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>
51
#elif defined( _MSC_VER ) && 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
63
#ifdef HAVE_LOCALE_H
#   include <locale.h>
#endif

#include "vlc_cpu.h"                                        /* CPU detection */
64
#include "os_specific.h"
65

66
#include "error.h"
67
68
69
70
71
#include "netutils.h"                                 /* network_ChannelJoin */

#include "stream_control.h"
#include "input_ext-intf.h"

72
#include "vlc_playlist.h"
73
74
75
76
77
78
79
80
81
82
#include "interface.h"

#include "audio_output.h"

#include "video.h"
#include "video_output.h"

#include "libvlc.h"

/*****************************************************************************
83
 * The evil global variable. We handle it with care, don't worry.
84
 *****************************************************************************/
85
static libvlc_t libvlc;
Sam Hocevar's avatar
Sam Hocevar committed
86
static vlc_t *  p_static_vlc;
87
88
89
90

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
91
static void SetLanguage   ( char const * );
92
static int  GetFilenames  ( vlc_t *, int, char *[] );
93
static void Usage         ( vlc_t *, char const *psz_module_name );
94
static void ListModules   ( vlc_t * );
95
96
97
98
99
static void Version       ( void );

#ifdef WIN32
static void ShowConsole   ( void );
#endif
100
static int  ConsoleWidth  ( void );
101
102

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
103
 * VLC_Version: return the libvlc version.
104
 *****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
105
 * This function returns full version string (numeric version and codename).
106
 *****************************************************************************/
107
char const * VLC_Version( void )
108
{
Sam Hocevar's avatar
Sam Hocevar committed
109
    return VERSION_MESSAGE;
110
111
}

112
113
114
115
116
117
118
119
120
121
/*****************************************************************************
 * 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
122
123
124
125
126
127
128
/*****************************************************************************
 * 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 )
129
{
130
    int i_ret;
131
    vlc_t * p_vlc = NULL;
132
    vlc_value_t lockval;
133

134
135
136
    /* vlc_threads_init *must* be the first internal call! No other call is
     * allowed before the thread system has been initialized. */
    i_ret = vlc_threads_init( &libvlc );
Sam Hocevar's avatar
Sam Hocevar committed
137
    if( i_ret < 0 )
138
    {
Sam Hocevar's avatar
Sam Hocevar committed
139
        return i_ret;
140
141
142
    }

    /* Now that the thread system is initialized, we don't have much, but
143
144
145
146
     * at least we have var_Create */
    var_Create( &libvlc, "libvlc", VLC_VAR_MUTEX );
    var_Get( &libvlc, "libvlc", &lockval );
    vlc_mutex_lock( lockval.p_address );
147
148
    if( !libvlc.b_ready )
    {
149
150
        char *psz_env;

151
152
153
        /* Guess what CPU we have */
        libvlc.i_cpu = CPUCapabilities();

154
155
        /* Find verbosity from VLC_VERBOSE environment variable */
        psz_env = getenv( "VLC_VERBOSE" );
156
        libvlc.i_verbose = psz_env ? atoi( psz_env ) : -1;
157
158
159
160
161
162
163

#ifdef HAVE_ISATTY
        libvlc.b_color = isatty( 2 ); /* 2 is for stderr */
#else
        libvlc.b_color = VLC_FALSE;
#endif

164
165
166
167
168
169
170
        /* Initialize message queue */
        msg_Create( &libvlc );

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

171
172
        /* The module bank will be initialized later */
        libvlc.p_module_bank = NULL;
173
174

        libvlc.b_ready = VLC_TRUE;
175
    }
176
177
    vlc_mutex_unlock( lockval.p_address );
    var_Destroy( &libvlc, "libvlc" );
178
179
180

    /* Allocate a vlc object */
    p_vlc = vlc_object_create( &libvlc, VLC_OBJECT_VLC );
181
182
    if( p_vlc == NULL )
    {
Sam Hocevar's avatar
Sam Hocevar committed
183
        return VLC_EGENERIC;
184
185
186
187
188
    }

    p_vlc->psz_object_name = "root";

    /* Initialize mutexes */
189
    vlc_mutex_init( p_vlc, &p_vlc->config_lock );
190
191

    /* Store our newly allocated structure in the global list */
192
    vlc_object_attach( p_vlc, &libvlc );
193

Sam Hocevar's avatar
Sam Hocevar committed
194
195
196
197
    /* Store data for the non-reentrant API */
    p_static_vlc = p_vlc;

    return p_vlc->i_object_id;
198
199
200
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
201
 * VLC_Init: initialize a vlc_t structure.
202
203
204
205
206
207
208
 *****************************************************************************
 * 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
209
int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
210
{
211
212
    char         p_capabilities[200];
    char *       p_tmp;
213
214
    char *       psz_modules;
    char *       psz_parser;
215
    vlc_bool_t   b_exit = VLC_FALSE;
Sam Hocevar's avatar
Sam Hocevar committed
216
    vlc_t *      p_vlc;
217
218
    module_t    *p_help_module;
    playlist_t  *p_playlist;
219
    vlc_value_t  lockval;
220

Sam Hocevar's avatar
Sam Hocevar committed
221
222
    p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;

223
    if( !p_vlc )
224
    {
225
        return VLC_ENOOBJ;
226
227
228
    }

    /*
229
     * System specific initialization code
230
     */
231
    system_Init( p_vlc, &i_argc, ppsz_argv );
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247

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

248
249
250
251
    /*
     * Support for gettext
     */
    SetLanguage( "" );
Sam Hocevar's avatar
Sam Hocevar committed
252
253

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

256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
    /* 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) */
    var_Create( &libvlc, "libvlc", VLC_VAR_MUTEX );
    var_Get( &libvlc, "libvlc", &lockval );
    vlc_mutex_lock( lockval.p_address );
    if( libvlc.p_module_bank == NULL )
    {
        module_InitBank( &libvlc );
        module_LoadMain( &libvlc );
    }
    vlc_mutex_unlock( lockval.p_address );
    var_Destroy( &libvlc, "libvlc" );

271
272
273
274
    /* Hack: insert the help module here */
    p_help_module = vlc_object_create( p_vlc, VLC_OBJECT_MODULE );
    if( p_help_module == NULL )
    {
275
        //module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
276
        if( i_object ) vlc_object_release( p_vlc );
277
278
279
280
        return VLC_EGENERIC;
    }
    p_help_module->psz_object_name = "help";
    config_Duplicate( p_help_module, p_help_config );
281
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
282
283
    /* End hack */

Sam Hocevar's avatar
Sam Hocevar committed
284
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
285
    {
286
        vlc_object_detach( p_help_module );
287
288
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
289
        //module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
290
        if( i_object ) vlc_object_release( p_vlc );
291
292
293
294
295
296
        return VLC_EGENERIC;
    }

    /* Check for short help option */
    if( config_GetInt( p_vlc, "help" ) )
    {
297
        fprintf( stdout, _("Usage: %s [options] [items]...\n\n"),
298
                         p_vlc->psz_object_name );
299
        Usage( p_vlc, "main" );
300
301
        Usage( p_vlc, "help" );
        b_exit = VLC_TRUE;
302
303
    }
    /* Check for version option */
304
    else if( config_GetInt( p_vlc, "version" ) )
305
306
    {
        Version();
307
308
309
310
311
312
313
314
315
        b_exit = VLC_TRUE;
    }

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

    if( b_exit )
    {
316
317
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
318
        //module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
319
        if( i_object ) vlc_object_release( p_vlc );
320
321
322
323
324
325
326
327
328
        return VLC_EEXIT;
    }

    /*
     * 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.
     */
329
330
    module_LoadBuiltins( &libvlc );
    module_LoadPlugins( &libvlc );
331
    msg_Dbg( p_vlc, "module bank initialized, found %i modules",
332
                    libvlc.p_module_bank->i_children );
333
334

    /* Hack: insert the help module here */
335
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
336
337
338
339
340
    /* End hack */

    /* Check for help on modules */
    if( (p_tmp = config_GetPsz( p_vlc, "module" )) )
    {
341
        Usage( p_vlc, p_tmp );
342
        free( p_tmp );
343
        b_exit = VLC_TRUE;
344
345
    }
    /* Check for long help option */
346
    else if( config_GetInt( p_vlc, "longhelp" ) )
347
    {
348
        Usage( p_vlc, NULL );
349
        b_exit = VLC_TRUE;
350
351
    }
    /* Check for module list option */
352
    else if( config_GetInt( p_vlc, "list" ) )
353
    {
354
        ListModules( p_vlc );
355
        b_exit = VLC_TRUE;
356
357
358
    }

    /* Hack: remove the help module here */
359
    vlc_object_detach( p_help_module );
360
361
362
363
    config_Free( p_help_module );
    vlc_object_destroy( p_help_module );
    /* End hack */

364
365
    if( b_exit )
    {
366
        //module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
367
        if( i_object ) vlc_object_release( p_vlc );
368
369
370
        return VLC_EEXIT;
    }

371
372
373
374
    /*
     * Override default configuration with config file settings
     */
    p_vlc->psz_homedir = config_GetHomeDir();
375
    config_LoadConfigFile( p_vlc, NULL );
376
377
378
379

    /*
     * Override configuration with command line settings
     */
Sam Hocevar's avatar
Sam Hocevar committed
380
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
381
382
383
384
385
386
387
388
    {
#ifdef WIN32
        ShowConsole();
        /* 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.\nPress the RETURN key to continue..." );
        getchar();
#endif
389
        //module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
390
        if( i_object ) vlc_object_release( p_vlc );
391
392
393
394
395
396
        return VLC_EGENERIC;
    }

    /*
     * System specific configuration
     */
397
    system_Configure( p_vlc );
398

399
400
401
402
403
    /*
     * Message queue options
     */
    if( config_GetInt( p_vlc, "quiet" ) )
    {
404
        libvlc.i_verbose = -1;
405
406
407
408
    }
    else
    {
        int i_tmp = config_GetInt( p_vlc, "verbose" );
409
        if( i_tmp >= 0 )
410
        {
411
            libvlc.i_verbose = __MIN( i_tmp, 2 );
412
413
414
415
        }
    }
    libvlc.b_color = libvlc.b_color || config_GetInt( p_vlc, "color" );

416
417
418
419
420
    /*
     * Output messages that may still be in the queue
     */
    msg_Flush( p_vlc );

421
    /* p_vlc initialization. FIXME ? */
422
    p_vlc->i_desync = config_GetInt( p_vlc, "desync" ) * (mtime_t)1000;
423

424
#if defined( __i386__ )
425
    if( !config_GetInt( p_vlc, "mmx" ) )
426
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMX;
427
    if( !config_GetInt( p_vlc, "3dn" ) )
428
        libvlc.i_cpu &= ~CPU_CAPABILITY_3DNOW;
429
    if( !config_GetInt( p_vlc, "mmxext" ) )
430
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMXEXT;
431
    if( !config_GetInt( p_vlc, "sse" ) )
432
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE;
433
434
#endif
#if defined( __powerpc__ ) || defined( SYS_DARWIN )
435
    if( !config_GetInt( p_vlc, "altivec" ) )
436
        libvlc.i_cpu &= ~CPU_CAPABILITY_ALTIVEC;
437
#endif
438
439

#define PRINT_CAPABILITY( capability, string )                              \
440
    if( libvlc.i_cpu & capability )                                         \
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
    {                                                                       \
        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" );
    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
     */
462
    p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy" );
463

464
    if( p_vlc->pf_memcpy == NULL )
465
466
467
    {
        p_vlc->pf_memcpy = memcpy;
    }
468
469
470
471
472

    if( p_vlc->pf_memset == NULL )
    {
        p_vlc->pf_memset = memset;
    }
473
474
475
476
477

    /*
     * Initialize shared resources and libraries
     */
    if( config_GetInt( p_vlc, "network-channel" )
478
         && network_ChannelCreate( p_vlc ) )
479
480
    {
        /* On error during Channels initialization, switch off channels */
481
482
        msg_Warn( p_vlc,
                  "channels initialization failed, deactivating channels" );
Sam Hocevar's avatar
Sam Hocevar committed
483
        config_PutInt( p_vlc, "network-channel", VLC_FALSE );
484
485
486
487
488
    }

    /*
     * Initialize playlist and get commandline files
     */
489
    p_playlist = playlist_Create( p_vlc );
490
491
492
    if( !p_playlist )
    {
        msg_Err( p_vlc, "playlist initialization failed" );
493
494
        if( p_vlc->p_memcpy_module != NULL )
        {
495
            module_Unneed( p_vlc, p_vlc->p_memcpy_module );
496
        }
497
        //module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
498
        if( i_object ) vlc_object_release( p_vlc );
499
500
501
        return VLC_EGENERIC;
    }

502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
    /*
     * Load background interfaces
     */
    psz_modules = config_GetPsz( p_vlc, "extraintf" );
    psz_parser = psz_modules;
    while ( psz_parser && *psz_parser )
    {
        char *psz_module;
        psz_module = psz_parser;
        psz_parser = strchr( psz_module, ',' );
        if ( psz_parser )
        {
            *psz_parser = '\0';
            psz_parser++;
        }
        VLC_AddIntf( 0, psz_module, VLC_FALSE );
    }
    if ( psz_modules )
    {
        free( psz_modules );
    }
523

524
525
526
527
528
    /*
     * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin
     */
    var_Create( p_vlc, "drawable", VLC_VAR_INTEGER );

529
530
531
532
533
    /*
     * Get input filenames given as commandline arguments
     */
    GetFilenames( p_vlc, i_argc, ppsz_argv );

gbazin's avatar
   
gbazin committed
534
    if( i_object ) vlc_object_release( p_vlc );
535
536
537
538
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
539
 * VLC_AddIntf: add an interface
540
541
 *****************************************************************************
 * This function opens an interface plugin and runs it. If b_block is set
Sam Hocevar's avatar
Sam Hocevar committed
542
543
 * 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
544
545
 * user requests to quit.
 *****************************************************************************/
546
int VLC_AddIntf( int i_object, char const *psz_module, vlc_bool_t b_block )
547
{
Sam Hocevar's avatar
Sam Hocevar committed
548
    int i_err;
549
    intf_thread_t *p_intf;
Sam Hocevar's avatar
Sam Hocevar committed
550
    vlc_t *p_vlc;
551

Sam Hocevar's avatar
Sam Hocevar committed
552
553
    p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;

554
    if( !p_vlc )
555
    {
556
        return VLC_ENOOBJ;
557
558
559
    }

    /* Try to create the interface */
560
    p_intf = intf_Create( p_vlc, psz_module ? psz_module : "$intf" );
561
562
563
564

    if( p_intf == NULL )
    {
        msg_Err( p_vlc, "interface initialization failed" );
gbazin's avatar
   
gbazin committed
565
        if( i_object ) vlc_object_release( p_vlc );
566
567
568
569
570
        return VLC_EGENERIC;
    }

    /* Try to run the interface */
    p_intf->b_block = b_block;
Sam Hocevar's avatar
Sam Hocevar committed
571
572
    i_err = intf_RunThread( p_intf );
    if( i_err )
573
    {
574
        vlc_object_detach( p_intf );
575
        intf_Destroy( p_intf );
gbazin's avatar
   
gbazin committed
576
        if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
577
        return i_err;
578
579
    }

gbazin's avatar
   
gbazin committed
580
    if( i_object ) vlc_object_release( p_vlc );
581
582
583
584
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
585
 * VLC_Destroy: stop playing and destroy everything.
586
 *****************************************************************************
587
 * This function requests the running threads to finish, waits for their
588
589
 * termination, and destroys their structure.
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
590
int VLC_Destroy( int i_object )
591
{
Sam Hocevar's avatar
Sam Hocevar committed
592
593
594
    vlc_t *p_vlc;

    p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
595

596
    if( !p_vlc )
597
    {
598
        return VLC_ENOOBJ;
599
600
    }

601
602
603
604
    /*
     * Go back into channel 0 which is the network
     */
    if( config_GetInt( p_vlc, "network-channel" ) && p_vlc->p_channel )
605
    {
606
607
        network_ChannelJoin( p_vlc, COMMON_CHANNEL );
    }
608

609
610
611
612
613
614
615
    /*
     * Free allocated memory
     */
    if( p_vlc->p_memcpy_module )
    {
        module_Unneed( p_vlc, p_vlc->p_memcpy_module );
        p_vlc->p_memcpy_module = NULL;
616
617
    }

618
619
620
621
622
    if( p_vlc->psz_homedir )
    {
        free( p_vlc->psz_homedir );
        p_vlc->psz_homedir = NULL;
    }
623

624
625
626
627
    /*
     * XXX: Free module bank !
     */
    //module_EndBank( p_vlc );
628

629
630
631
632
    /*
     * System specific cleaning code
     */
    system_End( p_vlc );
633

634
635
636
    /* Destroy mutexes */
    vlc_mutex_destroy( &p_vlc->config_lock );

637
638
    vlc_object_detach( p_vlc );

639
640
641
    /* Release object before destroying it */
    if( i_object ) vlc_object_release( p_vlc );

642
643
    vlc_object_destroy( p_vlc );

644
645
646
    /* Stop thread system: last one out please shut the door! */
    vlc_threads_end( &libvlc );

647
648
649
    return VLC_SUCCESS;
}

650
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
651
 * VLC_Die: ask vlc to die.
652
653
 *****************************************************************************
 * This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
Sam Hocevar's avatar
Sam Hocevar committed
654
 * task. It is your duty to call vlc_end and VLC_Destroy afterwards.
655
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
656
int VLC_Die( int i_object )
657
{
Sam Hocevar's avatar
Sam Hocevar committed
658
659
660
    vlc_t *p_vlc;

    p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
661
662
663

    if( !p_vlc )
    {
664
        return VLC_ENOOBJ;
665
666
667
668
    }

    p_vlc->b_die = VLC_TRUE;

gbazin's avatar
   
gbazin committed
669
    if( i_object ) vlc_object_release( p_vlc );
670
671
672
673
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
674
 * VLC_AddTarget: adds a target for playing.
675
676
677
678
 *****************************************************************************
 * This function adds psz_target to the current playlist. If a playlist does
 * not exist, it will create one.
 *****************************************************************************/
679
int VLC_AddTarget( int i_object, char const *psz_target, int i_mode, int i_pos )
680
{
Sam Hocevar's avatar
Sam Hocevar committed
681
    int i_err;
Sam Hocevar's avatar
Sam Hocevar committed
682
    playlist_t *p_playlist;
Sam Hocevar's avatar
Sam Hocevar committed
683
684
685
    vlc_t *p_vlc;

    p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
Sam Hocevar's avatar
Sam Hocevar committed
686

687
    if( !p_vlc )
688
    {
689
        return VLC_ENOOBJ;
690
691
    }

Sam Hocevar's avatar
Sam Hocevar committed
692
693
694
695
696
697
698
699
700
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );

    if( p_playlist == NULL )
    {
        msg_Dbg( p_vlc, "no playlist present, creating one" );
        p_playlist = playlist_Create( p_vlc );

        if( p_playlist == NULL )
        {
gbazin's avatar
   
gbazin committed
701
            if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
702
703
704
705
706
707
            return VLC_EGENERIC;
        }

        vlc_object_yield( p_playlist );
    }

Sam Hocevar's avatar
Sam Hocevar committed
708
    i_err = playlist_Add( p_playlist, psz_target, i_mode, i_pos );
Sam Hocevar's avatar
Sam Hocevar committed
709
710

    vlc_object_release( p_playlist );
711

gbazin's avatar
   
gbazin committed
712
    if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
713
    return i_err;
714
715
}

716
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
717
 * VLC_Set: set a vlc variable
718
719
720
 *****************************************************************************
 *
 *****************************************************************************/
721
int VLC_Set( int i_object, char const *psz_var, vlc_value_t value )
722
{
Sam Hocevar's avatar
Sam Hocevar committed
723
    vlc_t *p_vlc;
gbazin's avatar
   
gbazin committed
724
    int i_ret;
725

Sam Hocevar's avatar
Sam Hocevar committed
726
    p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
727
728
729

    if( !p_vlc )
    {
730
        return VLC_ENOOBJ;
731
732
    }

Sam Hocevar's avatar
Sam Hocevar committed
733
734
735
    /* FIXME: Temporary hack for Mozilla, if variable starts with conf:: then
     * we handle it as a configuration variable. Don't tell Gildas :) -- sam */
    if( !strncmp( psz_var, "conf::", 6 ) )
736
    {
Sam Hocevar's avatar
Sam Hocevar committed
737
        module_config_t *p_item;
738
        char const *psz_newvar = psz_var + 6;
739

Sam Hocevar's avatar
Sam Hocevar committed
740
        p_item = config_FindConfig( VLC_OBJECT(p_vlc), psz_newvar );
741

Sam Hocevar's avatar
Sam Hocevar committed
742
        if( p_item )
743
        {
Sam Hocevar's avatar
Sam Hocevar committed
744
            switch( p_item->i_type )
745
            {
Sam Hocevar's avatar
Sam Hocevar committed
746
747
748
749
750
751
752
753
754
755
756
757
                case CONFIG_ITEM_BOOL:
                    config_PutInt( p_vlc, psz_newvar, value.b_bool );
                    break;
                case CONFIG_ITEM_INTEGER:
                    config_PutInt( p_vlc, psz_newvar, value.i_int );
                    break;
                case CONFIG_ITEM_FLOAT:
                    config_PutFloat( p_vlc, psz_newvar, value.f_float );
                    break;
                default:
                    config_PutPsz( p_vlc, psz_newvar, value.psz_string );
                    break;
758
            }
gbazin's avatar
   
gbazin committed
759
            if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
760
            return VLC_SUCCESS;
761
762
763
        }
    }

gbazin's avatar
   
gbazin committed
764
765
766
767
    i_ret = var_Set( p_vlc, psz_var, value );

    if( i_object ) vlc_object_release( p_vlc );
    return i_ret;
Sam Hocevar's avatar
Sam Hocevar committed
768
769
770
771
772
773
774
}

/*****************************************************************************
 * VLC_Get: get a vlc variable
 *****************************************************************************
 *
 *****************************************************************************/
775
int VLC_Get( int i_object, char const *psz_var, vlc_value_t *p_value )
Sam Hocevar's avatar
Sam Hocevar committed
776
777
{
    vlc_t *p_vlc;
gbazin's avatar
   
gbazin committed
778
    int i_ret;
Sam Hocevar's avatar
Sam Hocevar committed
779
780
781
782

    p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;

    if( !p_vlc )
783
    {
784
        return VLC_ENOOBJ;
785
786
    }

gbazin's avatar
   
gbazin committed
787
788
789
790
    i_ret = var_Get( p_vlc, psz_var, p_value );

    if( i_object ) vlc_object_release( p_vlc );
    return i_ret;
791
792
}

Sam Hocevar's avatar
Sam Hocevar committed
793
/* FIXME: temporary hacks */
794
795

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
796
 * VLC_Play: play
797
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
798
int VLC_Play( int i_object )
799
800
{
    playlist_t * p_playlist;
Sam Hocevar's avatar
Sam Hocevar committed
801
802
803
    vlc_t *p_vlc;

    p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
804
805

    /* Check that the handle is valid */
806
    if( !p_vlc )
807
    {
808
        return VLC_ENOOBJ;
809
    }
810

811
812
    vlc_thread_set_priority( p_vlc, VLC_THREAD_PRIORITY_LOW );

813
814
815
816
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );

    if( !p_playlist )
    {
gbazin's avatar
   
gbazin committed
817
        if( i_object ) vlc_object_release( p_vlc );
818
        return VLC_ENOOBJ;
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
    }

    vlc_mutex_lock( &p_playlist->object_lock );
    if( p_playlist->i_size )
    {
        vlc_mutex_unlock( &p_playlist->object_lock );
        playlist_Play( p_playlist );
    }
    else
    {
        vlc_mutex_unlock( &p_playlist->object_lock );
    }

    vlc_object_release( p_playlist );

gbazin's avatar
   
gbazin committed
834
    if( i_object ) vlc_object_release( p_vlc );
835
836
837
838
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
839
 * VLC_Stop: stop
840
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
841
int VLC_Stop( int i_object )
842
843
844
845
846
{
    intf_thread_t *   p_intf;
    playlist_t    *   p_playlist;
    vout_thread_t *   p_vout;
    aout_instance_t * p_aout;
Sam Hocevar's avatar
Sam Hocevar committed
847
848
849
    vlc_t *p_vlc;

    p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
850
851

    /* Check that the handle is valid */
852
    if( !p_vlc )
853
    {
854
        return VLC_ENOOBJ;
855
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
886
887
888
    }

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

    /*
     * Free playlists
     */
    msg_Dbg( p_vlc, "removing all playlists" );
    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 );
889
        vout_Destroy( p_vout );
890
891
892
893
894
895
896
897
898
899
900
901
902
    }

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

gbazin's avatar
   
gbazin committed
903
    if( i_object ) vlc_object_release( p_vlc );
904
905
906
907
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
908
 * VLC_Pause: toggle pause
909
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
910
int VLC_Pause( int i_object )
911
912
{
    input_thread_t *p_input;
Sam Hocevar's avatar
Sam Hocevar committed
913
914
915
916
917
918
    vlc_t *p_vlc;

    p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;

    if( !p_vlc )
    {
919
        return VLC_ENOOBJ;
Sam Hocevar's avatar
Sam Hocevar committed
920
    }
921
922
923
924
925

    p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );

    if( !p_input )
    {
gbazin's avatar
   
gbazin committed
926
        if( i_object ) vlc_object_release( p_vlc );
927
        return VLC_ENOOBJ;
928
929
930
931
932
    }

    input_SetStatus( p_input, INPUT_STATUS_PAUSE );
    vlc_object_release( p_input );

gbazin's avatar
   
gbazin committed
933
    if( i_object ) vlc_object_release( p_vlc );
934
935
936
937
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
938
 * VLC_FullScreen: toggle fullscreen mode
939
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
940
int VLC_FullScreen( int i_object )
941
942
{
    vout_thread_t *p_vout;
Sam Hocevar's avatar
Sam Hocevar committed
943
944
945
946
947
948
    vlc_t *p_vlc;

    p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;

    if( !p_vlc )
    {
949
        return VLC_ENOOBJ;
Sam Hocevar's avatar
Sam Hocevar committed
950
    }
951
952
953
954
955

    p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD );

    if( !p_vout )
    {
gbazin's avatar
   
gbazin committed
956
        if( i_object ) vlc_object_release( p_vlc );
957
        return VLC_ENOOBJ;
958
959
960
961
962
    }

    p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
    vlc_object_release( p_vout );

gbazin's avatar
   
gbazin committed
963
    if( i_object ) vlc_object_release( p_vlc );
964
965
966
    return VLC_SUCCESS;
}

967
968
/* following functions are local */

Sam Hocevar's avatar
Sam Hocevar committed
969
970
971
972
973
974
975
976
977
/*****************************************************************************
 * SetLanguage: set the interface language.
 *****************************************************************************
 * We set the LC_MESSAGES locale category for interface messages and buttons,
 * as well as the LC_CTYPE category for string sorting and possible wide
 * character support.
 *****************************************************************************/
static void SetLanguage ( char const *psz_lang )
{
978
979
980
#if defined( ENABLE_NLS ) \
     && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )

981
982
983
984
985
    char *          psz_path;
#ifdef SYS_DARWIN
    char            psz_tmp[1024];
#endif

986
987
#   if defined( HAVE_INCLUDED_GETTEXT ) && !defined( HAVE_LC_MESSAGES )
    if( *psz_lang )
Sam Hocevar's avatar
Sam Hocevar committed
988
    {
989
990
991
992
993
994
995
996
        /* We set LC_ALL manually because it is the only way to set
         * the language at runtime under eg. Windows. Beware that this
         * makes the environment unconsistent when libvlc is unloaded and
         * should probably be moved to a safer place like vlc.c. */
        static char psz_lcall[20];
        snprintf( psz_lcall, 19, "LC_ALL=%s", psz_lang );
        psz_lcall[19] = '\0';
        putenv( psz_lcall );
Sam Hocevar's avatar
Sam Hocevar committed
997
    }
998
#   endif
Sam Hocevar's avatar
Sam Hocevar committed
999

1000
#   if defined( HAVE_LC_MESSAGES )