libvlc.c 40.5 KB
Newer Older
1
2
3
/*****************************************************************************
 * libvlc.c: main libvlc source
 *****************************************************************************
4
 * Copyright (C) 1998-2002 VideoLAN
5
 * $Id: libvlc.c,v 1.57 2003/01/19 03:16:24 sam 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
100
101
static void Version       ( void );

#ifdef WIN32
static void ShowConsole   ( void );
#endif

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

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

133
134
135
    /* 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
136
    if( i_ret < 0 )
137
    {
Sam Hocevar's avatar
Sam Hocevar committed
138
        return i_ret;
139
140
141
    }

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

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

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

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

163
164
165
166
167
168
169
        /* 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 );

170
        /* Initialize the module bank and load the configuration of the
171
172
173
174
175
         * 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( &libvlc );
        module_LoadMain( &libvlc );
176
177

        libvlc.b_ready = VLC_TRUE;
178
    }
179
180
    vlc_mutex_unlock( lockval.p_address );
    var_Destroy( &libvlc, "libvlc" );
181
182
183

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

    p_vlc->psz_object_name = "root";

    /* Initialize mutexes */
192
    vlc_mutex_init( p_vlc, &p_vlc->config_lock );
193
194

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

Sam Hocevar's avatar
Sam Hocevar committed
197
198
199
200
    /* Store data for the non-reentrant API */
    p_static_vlc = p_vlc;

    return p_vlc->i_object_id;
201
202
203
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
204
 * VLC_Init: initialize a vlc_t structure.
205
206
207
208
209
210
211
 *****************************************************************************
 * 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
212
int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
213
{
214
215
216
    char         p_capabilities[200];
    char *       p_tmp;
    vlc_bool_t   b_exit;
Sam Hocevar's avatar
Sam Hocevar committed
217
    vlc_t *      p_vlc;
218
219
    module_t    *p_help_module;
    playlist_t  *p_playlist;
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
    /* Hack: insert the help module here */
    p_help_module = vlc_object_create( p_vlc, VLC_OBJECT_MODULE );
    if( p_help_module == NULL )
    {
260
        //module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
261
        if( i_object ) vlc_object_release( p_vlc );
262
263
264
265
        return VLC_EGENERIC;
    }
    p_help_module->psz_object_name = "help";
    config_Duplicate( p_help_module, p_help_config );
266
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
267
268
    /* End hack */

Sam Hocevar's avatar
Sam Hocevar committed
269
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
270
    {
271
        vlc_object_detach( p_help_module );
272
273
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
274
        //module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
275
        if( i_object ) vlc_object_release( p_vlc );
276
277
278
        return VLC_EGENERIC;
    }

279
280
    b_exit = VLC_FALSE;

281
282
283
    /* Check for short help option */
    if( config_GetInt( p_vlc, "help" ) )
    {
284
        fprintf( stdout, _("Usage: %s [options] [items]...\n\n"),
285
                         p_vlc->psz_object_name );
286
        Usage( p_vlc, "main" );
287
288
        Usage( p_vlc, "help" );
        b_exit = VLC_TRUE;
289
290
    }
    /* Check for version option */
291
    else if( config_GetInt( p_vlc, "version" ) )
292
293
    {
        Version();
294
295
296
297
298
299
300
301
302
        b_exit = VLC_TRUE;
    }

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

    if( b_exit )
    {
303
304
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
305
        //module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
306
        if( i_object ) vlc_object_release( p_vlc );
307
308
309
310
311
312
313
314
315
        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.
     */
316
317
    module_LoadBuiltins( &libvlc );
    module_LoadPlugins( &libvlc );
318
    msg_Dbg( p_vlc, "module bank initialized, found %i modules",
319
                    libvlc.p_module_bank->i_children );
320
321

    /* Hack: insert the help module here */
322
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
323
324
325
326
327
    /* End hack */

    /* Check for help on modules */
    if( (p_tmp = config_GetPsz( p_vlc, "module" )) )
    {
328
        Usage( p_vlc, p_tmp );
329
        free( p_tmp );
330
        b_exit = VLC_TRUE;
331
332
    }
    /* Check for long help option */
333
    else if( config_GetInt( p_vlc, "longhelp" ) )
334
    {
335
        Usage( p_vlc, NULL );
336
        b_exit = VLC_TRUE;
337
338
    }
    /* Check for module list option */
339
    else if( config_GetInt( p_vlc, "list" ) )
340
    {
341
        ListModules( p_vlc );
342
        b_exit = VLC_TRUE;
343
344
345
    }

    /* Hack: remove the help module here */
346
    vlc_object_detach( p_help_module );
347
348
349
350
    config_Free( p_help_module );
    vlc_object_destroy( p_help_module );
    /* End hack */

351
352
    if( b_exit )
    {
353
        //module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
354
        if( i_object ) vlc_object_release( p_vlc );
355
356
357
        return VLC_EEXIT;
    }

358
359
360
361
    /*
     * Override default configuration with config file settings
     */
    p_vlc->psz_homedir = config_GetHomeDir();
362
    config_LoadConfigFile( p_vlc, NULL );
363
364
365
366

    /*
     * Override configuration with command line settings
     */
Sam Hocevar's avatar
Sam Hocevar committed
367
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
368
369
370
371
372
373
374
375
    {
#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
376
        //module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
377
        if( i_object ) vlc_object_release( p_vlc );
378
379
380
381
382
383
        return VLC_EGENERIC;
    }

    /*
     * System specific configuration
     */
384
    system_Configure( p_vlc );
385

386
387
388
389
390
    /*
     * Message queue options
     */
    if( config_GetInt( p_vlc, "quiet" ) )
    {
391
        libvlc.i_verbose = -1;
392
393
394
395
    }
    else
    {
        int i_tmp = config_GetInt( p_vlc, "verbose" );
396
        if( i_tmp >= 0 )
397
        {
398
            libvlc.i_verbose = __MIN( i_tmp, 2 );
399
400
401
402
        }
    }
    libvlc.b_color = libvlc.b_color || config_GetInt( p_vlc, "color" );

403
404
405
406
407
408
409
    /*
     * Output messages that may still be in the queue
     */
    msg_Flush( p_vlc );

    /* p_vlc inititalization. FIXME ? */
    p_vlc->i_desync = config_GetInt( p_vlc, "desync" ) * (mtime_t)1000;
410

411
#if defined( __i386__ )
412
    if( !config_GetInt( p_vlc, "mmx" ) )
413
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMX;
414
    if( !config_GetInt( p_vlc, "3dn" ) )
415
        libvlc.i_cpu &= ~CPU_CAPABILITY_3DNOW;
416
    if( !config_GetInt( p_vlc, "mmxext" ) )
417
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMXEXT;
418
    if( !config_GetInt( p_vlc, "sse" ) )
419
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE;
420
421
#endif
#if defined( __powerpc__ ) || defined( SYS_DARWIN )
422
    if( !config_GetInt( p_vlc, "altivec" ) )
423
        libvlc.i_cpu &= ~CPU_CAPABILITY_ALTIVEC;
424
#endif
425
426

#define PRINT_CAPABILITY( capability, string )                              \
427
    if( libvlc.i_cpu & capability )                                         \
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
    {                                                                       \
        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
     */
449
    p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy" );
450

451
    if( p_vlc->pf_memcpy == NULL )
452
453
454
    {
        p_vlc->pf_memcpy = memcpy;
    }
455
456
457
458
459

    if( p_vlc->pf_memset == NULL )
    {
        p_vlc->pf_memset = memset;
    }
460
461
462
463
464

    /*
     * Initialize shared resources and libraries
     */
    if( config_GetInt( p_vlc, "network-channel" )
465
         && network_ChannelCreate( p_vlc ) )
466
467
    {
        /* On error during Channels initialization, switch off channels */
468
469
        msg_Warn( p_vlc,
                  "channels initialization failed, deactivating channels" );
Sam Hocevar's avatar
Sam Hocevar committed
470
        config_PutInt( p_vlc, "network-channel", VLC_FALSE );
471
472
473
474
475
    }

    /*
     * Initialize playlist and get commandline files
     */
476
    p_playlist = playlist_Create( p_vlc );
477
478
479
    if( !p_playlist )
    {
        msg_Err( p_vlc, "playlist initialization failed" );
480
481
        if( p_vlc->p_memcpy_module != NULL )
        {
482
            module_Unneed( p_vlc, p_vlc->p_memcpy_module );
483
        }
484
        //module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
485
        if( i_object ) vlc_object_release( p_vlc );
486
487
488
489
490
491
492
493
        return VLC_EGENERIC;
    }

    /*
     * Get input filenames given as commandline arguments
     */
    GetFilenames( p_vlc, i_argc, ppsz_argv );

gbazin's avatar
   
gbazin committed
494
    if( i_object ) vlc_object_release( p_vlc );
495
496
497
498
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
499
 * VLC_AddIntf: add an interface
500
501
 *****************************************************************************
 * This function opens an interface plugin and runs it. If b_block is set
Sam Hocevar's avatar
Sam Hocevar committed
502
503
 * 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
504
505
 * user requests to quit.
 *****************************************************************************/
506
int VLC_AddIntf( int i_object, char const *psz_module, vlc_bool_t b_block )
507
{
Sam Hocevar's avatar
Sam Hocevar committed
508
    int i_err;
509
    intf_thread_t *p_intf;
Sam Hocevar's avatar
Sam Hocevar committed
510
    vlc_t *p_vlc;
511
512
    char *psz_oldmodule = NULL;

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

515
    if( !p_vlc )
516
    {
517
        return VLC_ENOOBJ;
518
519
520
521
522
523
524
525
526
    }

    if( psz_module )
    {
        psz_oldmodule = config_GetPsz( p_vlc, "intf" );
        config_PutPsz( p_vlc, "intf", psz_module );
    }

    /* Try to create the interface */
527
    p_intf = intf_Create( p_vlc );
528
529
530
531
532
533
534
535
536
537
538
539
540

    if( psz_module )
    {
        config_PutPsz( p_vlc, "intf", psz_oldmodule );
        if( psz_oldmodule )
        {
            free( psz_oldmodule );
        }
    }

    if( p_intf == NULL )
    {
        msg_Err( p_vlc, "interface initialization failed" );
gbazin's avatar
   
gbazin committed
541
        if( i_object ) vlc_object_release( p_vlc );
542
543
544
545
546
        return VLC_EGENERIC;
    }

    /* Try to run the interface */
    p_intf->b_block = b_block;
Sam Hocevar's avatar
Sam Hocevar committed
547
548
    i_err = intf_RunThread( p_intf );
    if( i_err )
549
    {
550
        vlc_object_detach( p_intf );
551
        intf_Destroy( p_intf );
gbazin's avatar
   
gbazin committed
552
        if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
553
        return i_err;
554
555
    }

gbazin's avatar
   
gbazin committed
556
    if( i_object ) vlc_object_release( p_vlc );
557
558
559
560
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
561
 * VLC_Destroy: stop playing and destroy everything.
562
 *****************************************************************************
563
 * This function requests the running threads to finish, waits for their
564
565
 * termination, and destroys their structure.
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
566
int VLC_Destroy( int i_object )
567
{
Sam Hocevar's avatar
Sam Hocevar committed
568
569
570
    vlc_t *p_vlc;

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

572
    if( !p_vlc )
573
    {
574
        return VLC_ENOOBJ;
575
576
    }

577
578
579
580
    /*
     * Go back into channel 0 which is the network
     */
    if( config_GetInt( p_vlc, "network-channel" ) && p_vlc->p_channel )
581
    {
582
583
        network_ChannelJoin( p_vlc, COMMON_CHANNEL );
    }
584
    
585
586
587
588
589
590
591
    /*
     * Free allocated memory
     */
    if( p_vlc->p_memcpy_module )
    {
        module_Unneed( p_vlc, p_vlc->p_memcpy_module );
        p_vlc->p_memcpy_module = NULL;
592
593
    }

594
595
596
597
598
    if( p_vlc->psz_homedir )
    {
        free( p_vlc->psz_homedir );
        p_vlc->psz_homedir = NULL;
    }
599

600
601
602
603
604
605
606
607
608
609
    /*
     * XXX: Free module bank !
     */
    //module_EndBank( p_vlc );
    
    /*
     * System specific cleaning code
     */
    system_End( p_vlc );
    
610
611
612
    /* Destroy mutexes */
    vlc_mutex_destroy( &p_vlc->config_lock );

613
614
    vlc_object_detach( p_vlc );

615
616
    vlc_object_destroy( p_vlc );

617
618
619
    /* Stop thread system: last one out please shut the door! */
    vlc_threads_end( &libvlc );

gbazin's avatar
   
gbazin committed
620
    if( i_object ) vlc_object_release( p_vlc );
621
622
623
    return VLC_SUCCESS;
}

624
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
625
 * VLC_Die: ask vlc to die.
626
627
 *****************************************************************************
 * This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
Sam Hocevar's avatar
Sam Hocevar committed
628
 * task. It is your duty to call vlc_end and VLC_Destroy afterwards.
629
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
630
int VLC_Die( int i_object )
631
{
Sam Hocevar's avatar
Sam Hocevar committed
632
633
634
    vlc_t *p_vlc;

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

    if( !p_vlc )
    {
638
        return VLC_ENOOBJ;
639
640
641
642
    }

    p_vlc->b_die = VLC_TRUE;

gbazin's avatar
   
gbazin committed
643
    if( i_object ) vlc_object_release( p_vlc );
644
645
646
647
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
648
 * VLC_AddTarget: adds a target for playing.
649
650
651
652
 *****************************************************************************
 * This function adds psz_target to the current playlist. If a playlist does
 * not exist, it will create one.
 *****************************************************************************/
653
int VLC_AddTarget( int i_object, char const *psz_target, int i_mode, int i_pos )
654
{
Sam Hocevar's avatar
Sam Hocevar committed
655
    int i_err;
Sam Hocevar's avatar
Sam Hocevar committed
656
    playlist_t *p_playlist;
Sam Hocevar's avatar
Sam Hocevar committed
657
658
659
    vlc_t *p_vlc;

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

661
    if( !p_vlc )
662
    {
663
        return VLC_ENOOBJ;
664
665
    }

Sam Hocevar's avatar
Sam Hocevar committed
666
667
668
669
670
671
672
673
674
    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
675
            if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
676
677
678
679
680
681
            return VLC_EGENERIC;
        }

        vlc_object_yield( p_playlist );
    }

Sam Hocevar's avatar
Sam Hocevar committed
682
    i_err = playlist_Add( p_playlist, psz_target, i_mode, i_pos );
Sam Hocevar's avatar
Sam Hocevar committed
683
684

    vlc_object_release( p_playlist );
685

gbazin's avatar
   
gbazin committed
686
    if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
687
    return i_err;
688
689
}

690
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
691
 * VLC_Set: set a vlc variable
692
693
694
 *****************************************************************************
 *
 *****************************************************************************/
695
int VLC_Set( int i_object, char const *psz_var, vlc_value_t value )
696
{
Sam Hocevar's avatar
Sam Hocevar committed
697
    vlc_t *p_vlc;
gbazin's avatar
   
gbazin committed
698
    int i_ret;
699

Sam Hocevar's avatar
Sam Hocevar committed
700
    p_vlc = i_object ? vlc_object_get( &libvlc, i_object ) : p_static_vlc;
701
702
703

    if( !p_vlc )
    {
704
        return VLC_ENOOBJ;
705
706
    }

Sam Hocevar's avatar
Sam Hocevar committed
707
708
709
    /* 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 ) )
710
    {
Sam Hocevar's avatar
Sam Hocevar committed
711
        module_config_t *p_item;
712
        char const *psz_newvar = psz_var + 6;
713

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

Sam Hocevar's avatar
Sam Hocevar committed
716
        if( p_item )
717
        {
Sam Hocevar's avatar
Sam Hocevar committed
718
            switch( p_item->i_type )
719
            {
Sam Hocevar's avatar
Sam Hocevar committed
720
721
722
723
724
725
726
727
728
729
730
731
                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;
732
            }
gbazin's avatar
   
gbazin committed
733
            if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
734
            return VLC_SUCCESS;
735
736
737
        }
    }

gbazin's avatar
   
gbazin committed
738
739
740
741
    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
742
743
744
745
746
747
748
}

/*****************************************************************************
 * VLC_Get: get a vlc variable
 *****************************************************************************
 *
 *****************************************************************************/
749
int VLC_Get( int i_object, char const *psz_var, vlc_value_t *p_value )
Sam Hocevar's avatar
Sam Hocevar committed
750
751
{
    vlc_t *p_vlc;
gbazin's avatar
   
gbazin committed
752
    int i_ret;
Sam Hocevar's avatar
Sam Hocevar committed
753
754
755
756

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

    if( !p_vlc )
757
    {
758
        return VLC_ENOOBJ;
759
760
    }

gbazin's avatar
   
gbazin committed
761
762
763
764
    i_ret = var_Get( p_vlc, psz_var, p_value );

    if( i_object ) vlc_object_release( p_vlc );
    return i_ret;
765
766
}

Sam Hocevar's avatar
Sam Hocevar committed
767
/* FIXME: temporary hacks */
768
769

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
770
 * VLC_Play: play
771
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
772
int VLC_Play( int i_object )
773
774
{
    playlist_t * p_playlist;
Sam Hocevar's avatar
Sam Hocevar committed
775
776
777
    vlc_t *p_vlc;

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

    /* Check that the handle is valid */
780
    if( !p_vlc )
781
    {
782
        return VLC_ENOOBJ;
783
    }
784
785
786
787
788
789
790
    
    /* add pseudo sap interface; non blocking */
    if( config_GetInt( p_vlc, "sap" ) )
    {
        msg_Dbg( p_vlc, "adding sap interface" );
        VLC_AddIntf( 0, "sap", VLC_FALSE );
    }
791

792
793
    vlc_thread_set_priority( p_vlc, VLC_THREAD_PRIORITY_LOW );

794
795
796
797
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );

    if( !p_playlist )
    {
gbazin's avatar
   
gbazin committed
798
        if( i_object ) vlc_object_release( p_vlc );
799
        return VLC_ENOOBJ;
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
    }

    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
815
    if( i_object ) vlc_object_release( p_vlc );
816
817
818
819
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
820
 * VLC_Stop: stop
821
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
822
int VLC_Stop( int i_object )
823
824
825
826
827
{
    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
828
829
830
    vlc_t *p_vlc;

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

    /* Check that the handle is valid */
833
    if( !p_vlc )
834
    {
835
        return VLC_ENOOBJ;
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
    }

    /*
     * 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 );
870
        vout_Destroy( p_vout );
871
872
873
874
875
876
877
878
879
880
881
882
883
    }

    /*
     * 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
884
    if( i_object ) vlc_object_release( p_vlc );
885
886
887
888
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
889
 * VLC_Pause: toggle pause
890
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
891
int VLC_Pause( int i_object )
892
893
{
    input_thread_t *p_input;
Sam Hocevar's avatar
Sam Hocevar committed
894
895
896
897
898
899
    vlc_t *p_vlc;

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

    if( !p_vlc )
    {
900
        return VLC_ENOOBJ;
Sam Hocevar's avatar
Sam Hocevar committed
901
    }
902
903
904
905
906

    p_input = vlc_object_find( p_vlc, VLC_OBJECT_INPUT, FIND_CHILD );

    if( !p_input )
    {
gbazin's avatar
   
gbazin committed
907
        if( i_object ) vlc_object_release( p_vlc );
908
        return VLC_ENOOBJ;
909
910
911
912
913
    }

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

gbazin's avatar
   
gbazin committed
914
    if( i_object ) vlc_object_release( p_vlc );
915
916
917
918
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
919
 * VLC_FullScreen: toggle fullscreen mode
920
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
921
int VLC_FullScreen( int i_object )
922
923
{
    vout_thread_t *p_vout;
Sam Hocevar's avatar
Sam Hocevar committed
924
925
926
927
928
929
    vlc_t *p_vlc;

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

    if( !p_vlc )
    {
930
        return VLC_ENOOBJ;
Sam Hocevar's avatar
Sam Hocevar committed
931
    }
932
933
934
935
936

    p_vout = vlc_object_find( p_vlc, VLC_OBJECT_VOUT, FIND_CHILD );

    if( !p_vout )
    {
gbazin's avatar
   
gbazin committed
937
        if( i_object ) vlc_object_release( p_vlc );
938
        return VLC_ENOOBJ;
939
940
941
942
943
    }

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

gbazin's avatar
   
gbazin committed
944
    if( i_object ) vlc_object_release( p_vlc );
945
946
947
    return VLC_SUCCESS;
}

948
949
/* following functions are local */

Sam Hocevar's avatar
Sam Hocevar committed
950
951
952
953
954
955
956
957
958
/*****************************************************************************
 * 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 )
{
959
960
961
#if defined( ENABLE_NLS ) \
     && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )

962
963
964
965
966
    char *          psz_path;
#ifdef SYS_DARWIN
    char            psz_tmp[1024];
#endif

967
968
#   if defined( HAVE_INCLUDED_GETTEXT ) && !defined( HAVE_LC_MESSAGES )
    if( *psz_lang )
Sam Hocevar's avatar
Sam Hocevar committed
969
    {
970
971
972
973
974
975
976
977
        /* 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
978
    }
979
#   endif
Sam Hocevar's avatar
Sam Hocevar committed
980

981
982
#   if defined( HAVE_LC_MESSAGES )
    setlocale( LC_MESSAGES, psz_lang );
Sam Hocevar's avatar
Sam Hocevar committed
983
#   endif
984
    setlocale( LC_CTYPE, psz_lang );
Sam Hocevar's avatar
Sam Hocevar committed
985

986
    /* Specify where to find the locales for current domain */
987
988
989
#ifndef SYS_DARWIN
    psz_path = LOCALEDIR;
#else
990
    snprintf( psz_tmp, sizeof(psz_tmp), "%s/%s", libvlc.psz_vlcpath,
991
992
993
994
              "locale" );
    psz_path = psz_tmp;
#endif
    if( !bindtextdomain( PACKAGE, psz_path ) )
Sam Hocevar's avatar
Sam Hocevar committed
995
996
    {
        fprintf( stderr, "warning: no domain %s in directory %s\n",
997
                 PACKAGE, psz_path );
Sam Hocevar's avatar
Sam Hocevar committed
998
999
    }

1000
    /* Set the default domain */