libvlc.c 63.8 KB
Newer Older
1
2
3
/*****************************************************************************
 * libvlc.c: main libvlc source
 *****************************************************************************
zorglub's avatar
zorglub committed
4
 * Copyright (C) 1998-2004 VideoLAN
zorglub's avatar
zorglub committed
5
 * $Id$
6
7
8
9
 *
 * Authors: Vincent Seguin <seguin@via.ecp.fr>
 *          Samuel Hocevar <sam@zoy.org>
 *          Gildas Bazin <gbazin@netcourrier.com>
hartman's avatar
hartman committed
10
 *          Derk-Jan Hartman <hartman at videolan dot org>
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 *
 * 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
31
#define MODULE_PATH main
32
33
34
35
36
#define __BUILTIN__

/*****************************************************************************
 * Preamble
 *****************************************************************************/
37
#include <vlc/vlc.h>
Laurent Aimar's avatar
Laurent Aimar committed
38
#include <vlc/input.h>
39
40
41
42

#ifdef HAVE_ERRNO_H
#   include <errno.h>                                              /* ENOMEM */
#endif
43
44
45
46
47
48
49
50
51
52
#include <stdio.h>                                              /* sprintf() */
#include <string.h>                                            /* strerror() */
#include <stdlib.h>                                                /* free() */

#ifndef WIN32
#   include <netinet/in.h>                            /* BSD: struct in_addr */
#endif

#ifdef HAVE_UNISTD_H
#   include <unistd.h>
gbazin's avatar
   
gbazin committed
53
#elif defined( WIN32 ) && !defined( UNDER_CE )
54
55
56
#   include <io.h>
#endif

57
#ifdef WIN32                       /* optind, getopt(), included in unistd.h */
58
#   include "extras/getopt.h"
59
60
#endif

61
62
63
64
65
#ifdef HAVE_LOCALE_H
#   include <locale.h>
#endif

#include "vlc_cpu.h"                                        /* CPU detection */
66
#include "os_specific.h"
67

68
#include "vlc_error.h"
69

70
#include "vlc_playlist.h"
71
#include "vlc_interface.h"
72
73
74

#include "audio_output.h"

75
#include "vlc_video.h"
76
77
#include "video_output.h"

zorglub's avatar
zorglub committed
78
79
#include "stream_output.h"

80
81
82
#include "libvlc.h"

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

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

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

hartman's avatar
hartman committed
103
104
static int  VerboseCallback( vlc_object_t *, char const *,
                             vlc_value_t, vlc_value_t, void * );
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

/*****************************************************************************
 * vlc_current_object: return the current object.
 *****************************************************************************
 * If i_object is non-zero, return the corresponding object. Otherwise,
 * return the statically allocated p_vlc object.
 *****************************************************************************/
vlc_t * vlc_current_object( int i_object )
{
    if( i_object )
    {
         return vlc_object_get( p_libvlc, i_object );
    }

    return p_static_vlc;
}

122
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
123
 * VLC_Version: return the libvlc version.
124
 *****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
125
 * This function returns full version string (numeric version and codename).
126
 *****************************************************************************/
127
char const * VLC_Version( void )
128
{
Sam Hocevar's avatar
Sam Hocevar committed
129
    return VERSION_MESSAGE;
130
131
}

132
133
134
135
136
137
138
139
140
141
/*****************************************************************************
 * 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
142
143
144
145
146
147
148
/*****************************************************************************
 * 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 )
149
{
150
    int i_ret;
151
    vlc_t * p_vlc = NULL;
152
    vlc_value_t lockval;
153

154
155
156
    /* &libvlc never changes, so we can safely call this multiple times. */
    p_libvlc = &libvlc;

157
158
    /* vlc_threads_init *must* be the first internal call! No other call is
     * allowed before the thread system has been initialized. */
159
    i_ret = vlc_threads_init( p_libvlc );
Sam Hocevar's avatar
Sam Hocevar committed
160
    if( i_ret < 0 )
161
    {
Sam Hocevar's avatar
Sam Hocevar committed
162
        return i_ret;
163
164
165
    }

    /* Now that the thread system is initialized, we don't have much, but
166
     * at least we have var_Create */
167
168
    var_Create( p_libvlc, "libvlc", VLC_VAR_MUTEX );
    var_Get( p_libvlc, "libvlc", &lockval );
169
    vlc_mutex_lock( lockval.p_address );
170
171
    if( !libvlc.b_ready )
    {
172
173
        char *psz_env;

174
175
176
        /* Guess what CPU we have */
        libvlc.i_cpu = CPUCapabilities();

177
178
        /* Find verbosity from VLC_VERBOSE environment variable */
        psz_env = getenv( "VLC_VERBOSE" );
179
        libvlc.i_verbose = psz_env ? atoi( psz_env ) : -1;
180

gbazin's avatar
   
gbazin committed
181
#if defined( HAVE_ISATTY ) && !defined( WIN32 )
182
183
184
185
186
        libvlc.b_color = isatty( 2 ); /* 2 is for stderr */
#else
        libvlc.b_color = VLC_FALSE;
#endif

187
        /* Initialize message queue */
188
        msg_Create( p_libvlc );
189
190

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

194
195
        /* The module bank will be initialized later */
        libvlc.p_module_bank = NULL;
196
197

        libvlc.b_ready = VLC_TRUE;
198
    }
199
    vlc_mutex_unlock( lockval.p_address );
200
    var_Destroy( p_libvlc, "libvlc" );
201
202

    /* Allocate a vlc object */
203
    p_vlc = vlc_object_create( p_libvlc, VLC_OBJECT_VLC );
204
205
    if( p_vlc == NULL )
    {
Sam Hocevar's avatar
Sam Hocevar committed
206
        return VLC_EGENERIC;
207
    }
208
    p_vlc->thread_id = 0;
209
    vlc_thread_set_priority( p_vlc, VLC_THREAD_PRIORITY_LOW );
210
211
212
213

    p_vlc->psz_object_name = "root";

    /* Initialize mutexes */
214
    vlc_mutex_init( p_vlc, &p_vlc->config_lock );
hartman's avatar
hartman committed
215
216
217
#ifdef SYS_DARWIN
    vlc_mutex_init( p_vlc, &p_vlc->quicktime_lock );
#endif
218
219

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

Sam Hocevar's avatar
Sam Hocevar committed
222
223
224
225
    /* Store data for the non-reentrant API */
    p_static_vlc = p_vlc;

    return p_vlc->i_object_id;
226
227
228
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
229
 * VLC_Init: initialize a vlc_t structure.
230
231
232
233
234
235
236
 *****************************************************************************
 * 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
237
int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] )
238
{
239
240
    char         p_capabilities[200];
    char *       p_tmp;
241
242
    char *       psz_modules;
    char *       psz_parser;
243
    char *       psz_language;
244
    vlc_bool_t   b_exit = VLC_FALSE;
245
    vlc_t *      p_vlc = vlc_current_object( i_object );
246
247
    module_t    *p_help_module;
    playlist_t  *p_playlist;
248

249
    if( !p_vlc )
250
    {
251
        return VLC_ENOOBJ;
252
253
254
    }

    /*
255
     * System specific initialization code
256
     */
257
    system_Init( p_vlc, &i_argc, ppsz_argv );
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273

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

274
275
276
277
    /*
     * Support for gettext
     */
    SetLanguage( "" );
Sam Hocevar's avatar
Sam Hocevar committed
278
279

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

282
283
284
285
    /* 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) */
286
    module_InitBank( p_vlc );
287

288
289
290
291
    /* Hack: insert the help module here */
    p_help_module = vlc_object_create( p_vlc, VLC_OBJECT_MODULE );
    if( p_help_module == NULL )
    {
292
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
293
        if( i_object ) vlc_object_release( p_vlc );
294
295
296
        return VLC_EGENERIC;
    }
    p_help_module->psz_object_name = "help";
gbazin's avatar
   
gbazin committed
297
    p_help_module->psz_longname = N_("Help options");
298
    config_Duplicate( p_help_module, p_help_config );
299
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
300
301
    /* End hack */

Sam Hocevar's avatar
Sam Hocevar committed
302
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
303
    {
304
        vlc_object_detach( p_help_module );
305
306
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
307
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
308
        if( i_object ) vlc_object_release( p_vlc );
309
310
311
312
313
314
        return VLC_EGENERIC;
    }

    /* Check for short help option */
    if( config_GetInt( p_vlc, "help" ) )
    {
gbazin's avatar
   
gbazin committed
315
        fprintf( stdout, _("Usage: %s [options] [items]...\n"),
316
                         p_vlc->psz_object_name );
317
        Usage( p_vlc, "main" );
318
319
        Usage( p_vlc, "help" );
        b_exit = VLC_TRUE;
320
321
    }
    /* Check for version option */
322
    else if( config_GetInt( p_vlc, "version" ) )
323
324
    {
        Version();
325
326
327
        b_exit = VLC_TRUE;
    }

gbazin's avatar
   
gbazin committed
328
329
330
331
    /* Set the config file stuff */
    p_vlc->psz_homedir = config_GetHomeDir();
    p_vlc->psz_configfile = config_GetPsz( p_vlc, "config" );

332
333
334
335
336
337
    /* Check for plugins cache options */
    if( config_GetInt( p_vlc, "reset-plugins-cache" ) )
    {
        libvlc.p_module_bank->b_cache_delete = VLC_TRUE;
    }

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

gbazin's avatar
gbazin committed
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
    /* Will be re-done properly later on */
    p_vlc->p_libvlc->i_verbose = config_GetInt( p_vlc, "verbose" );

    /* Check for daemon mode */
#ifndef WIN32
    if( config_GetInt( p_vlc, "daemon" ) )
    {
        pid_t i_pid = 0;

        if( ( i_pid = fork() ) < 0 )
        {
            msg_Err( p_vlc, "Unable to fork vlc to daemon mode" );
            b_exit = VLC_TRUE;
        }
        else if( i_pid )
        {
            /* This is the parent, exit right now */
            msg_Dbg( p_vlc, "closing parent process" );
            b_exit = VLC_TRUE;
        }
        else
        {
            /* We are the child */
            msg_Dbg( p_vlc, "daemon spawned" );
            close( 0 );
            close( 1 );
            close( 2 );

            p_vlc->p_libvlc->b_daemon = VLC_TRUE;
        }
    }
#endif

375
376
    if( b_exit )
    {
377
378
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
379
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
380
        if( i_object ) vlc_object_release( p_vlc );
381
382
383
        return VLC_EEXIT;
    }

gbazin's avatar
   
gbazin committed
384
    /* Check for translation config option */
gbazin's avatar
   
gbazin committed
385
386
387
388
389
390
391
392
#if defined( ENABLE_NLS ) \
     && ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )

    /* This ain't really nice to have to reload the config here but it seems
     * the only way to do it. */
    config_LoadConfigFile( p_vlc, "main" );
    config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );

393
394
395
    /* Check if the user specified a custom language */
    psz_language = config_GetPsz( p_vlc, "language" );
    if( psz_language && *psz_language && strcmp( psz_language, "auto" ) )
gbazin's avatar
   
gbazin committed
396
    {
397
398
        vlc_bool_t b_cache_delete = libvlc.p_module_bank->b_cache_delete;

gbazin's avatar
   
gbazin committed
399
        /* Reset the default domain */
400
        SetLanguage( psz_language );
gbazin's avatar
   
gbazin committed
401

gbazin's avatar
   
gbazin committed
402
403
404
        /* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
        msg_Dbg( p_vlc, "translation test: code is \"%s\"", _("C") );

405
        textdomain( PACKAGE );
gbazin's avatar
   
gbazin committed
406

gbazin's avatar
   
gbazin committed
407
#if defined( ENABLE_UTF8 )
408
409
410
        bind_textdomain_codeset( PACKAGE, "UTF-8" );
#endif

gbazin's avatar
   
gbazin committed
411
        module_EndBank( p_vlc );
412
        module_InitBank( p_vlc );
413
        config_LoadConfigFile( p_vlc, "main" );
gbazin's avatar
   
gbazin committed
414
        config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
415
        libvlc.p_module_bank->b_cache_delete = b_cache_delete;
gbazin's avatar
   
gbazin committed
416
    }
417
    if( psz_language ) free( psz_language );
418
#endif
gbazin's avatar
   
gbazin committed
419

420
421
422
423
424
425
    /*
     * 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.
     */
426
427
428
429
430
431
432
    module_LoadBuiltins( p_vlc );
    module_LoadPlugins( p_vlc );
    if( p_vlc->b_die )
    {
        b_exit = VLC_TRUE;
    }

433
    msg_Dbg( p_vlc, "module bank initialized, found %i modules",
434
                    libvlc.p_module_bank->i_children );
435
436

    /* Hack: insert the help module here */
437
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
438
439
440
441
442
    /* End hack */

    /* Check for help on modules */
    if( (p_tmp = config_GetPsz( p_vlc, "module" )) )
    {
443
        Usage( p_vlc, p_tmp );
444
        free( p_tmp );
445
        b_exit = VLC_TRUE;
446
447
    }
    /* Check for long help option */
448
    else if( config_GetInt( p_vlc, "longhelp" ) )
449
    {
450
        Usage( p_vlc, NULL );
451
        b_exit = VLC_TRUE;
452
453
    }
    /* Check for module list option */
454
    else if( config_GetInt( p_vlc, "list" ) )
455
    {
456
        ListModules( p_vlc );
457
        b_exit = VLC_TRUE;
458
459
    }

gbazin's avatar
   
gbazin committed
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
    /* Check for config file options */
    if( config_GetInt( p_vlc, "reset-config" ) )
    {
        vlc_object_detach( p_help_module );
        config_ResetAll( p_vlc );
        config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
        config_SaveConfigFile( p_vlc, NULL );
        vlc_object_attach( p_help_module, libvlc.p_module_bank );
    }
    if( config_GetInt( p_vlc, "save-config" ) )
    {
        vlc_object_detach( p_help_module );
        config_LoadConfigFile( p_vlc, NULL );
        config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
        config_SaveConfigFile( p_vlc, NULL );
        vlc_object_attach( p_help_module, libvlc.p_module_bank );
    }

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

482
483
    if( b_exit )
    {
gbazin's avatar
   
gbazin committed
484
485
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
486
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
487
        if( i_object ) vlc_object_release( p_vlc );
488
489
490
        return VLC_EEXIT;
    }

491
492
493
    /*
     * Override default configuration with config file settings
     */
494
    config_LoadConfigFile( p_vlc, NULL );
495

gbazin's avatar
   
gbazin committed
496
497
498
499
    /* Hack: insert the help module here */
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
    /* End hack */

500
501
502
    /*
     * Override configuration with command line settings
     */
Sam Hocevar's avatar
Sam Hocevar committed
503
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
504
505
506
507
508
509
510
511
    {
#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
gbazin's avatar
   
gbazin committed
512
513
514
        vlc_object_detach( p_help_module );
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
515
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
516
        if( i_object ) vlc_object_release( p_vlc );
517
518
519
        return VLC_EGENERIC;
    }

gbazin's avatar
   
gbazin committed
520
521
522
523
524
525
    /* Hack: remove the help module here */
    vlc_object_detach( p_help_module );
    config_Free( p_help_module );
    vlc_object_destroy( p_help_module );
    /* End hack */

526
527
528
    /*
     * System specific configuration
     */
gbazin's avatar
   
gbazin committed
529
    system_Configure( p_vlc, &i_argc, ppsz_argv );
530

531
532
533
    /*
     * Message queue options
     */
hartman's avatar
hartman committed
534
535

    var_Create( p_vlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
536
537
    if( config_GetInt( p_vlc, "quiet" ) )
    {
hartman's avatar
hartman committed
538
539
540
        vlc_value_t val;
        val.i_int = -1;
        var_Set( p_vlc, "verbose", val );
541
    }
hartman's avatar
hartman committed
542
543
    var_AddCallback( p_vlc, "verbose", VerboseCallback, NULL );
    var_Change( p_vlc, "verbose", VLC_VAR_TRIGGER_CALLBACKS, NULL, NULL );
zorglub's avatar
zorglub committed
544

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

547
548
549
550
551
    /*
     * Output messages that may still be in the queue
     */
    msg_Flush( p_vlc );

552
    /* p_vlc initialization. FIXME ? */
553

554
#if defined( __i386__ )
555
    if( !config_GetInt( p_vlc, "mmx" ) )
556
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMX;
557
    if( !config_GetInt( p_vlc, "3dn" ) )
558
        libvlc.i_cpu &= ~CPU_CAPABILITY_3DNOW;
559
    if( !config_GetInt( p_vlc, "mmxext" ) )
560
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMXEXT;
561
    if( !config_GetInt( p_vlc, "sse" ) )
562
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE;
sigmunau's avatar
sigmunau committed
563
564
    if( !config_GetInt( p_vlc, "sse2" ) )
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE2;
565
566
#endif
#if defined( __powerpc__ ) || defined( SYS_DARWIN )
567
    if( !config_GetInt( p_vlc, "altivec" ) )
568
        libvlc.i_cpu &= ~CPU_CAPABILITY_ALTIVEC;
569
#endif
570
571

#define PRINT_CAPABILITY( capability, string )                              \
572
    if( libvlc.i_cpu & capability )                                         \
573
574
575
576
577
578
579
580
581
582
583
584
585
586
    {                                                                       \
        strncat( p_capabilities, string " ",                                \
                 sizeof(p_capabilities) - strlen(p_capabilities) );         \
        p_capabilities[sizeof(p_capabilities) - 1] = '\0';                  \
    }

    p_capabilities[0] = '\0';
    PRINT_CAPABILITY( CPU_CAPABILITY_486, "486" );
    PRINT_CAPABILITY( CPU_CAPABILITY_586, "586" );
    PRINT_CAPABILITY( CPU_CAPABILITY_PPRO, "Pentium Pro" );
    PRINT_CAPABILITY( CPU_CAPABILITY_MMX, "MMX" );
    PRINT_CAPABILITY( CPU_CAPABILITY_3DNOW, "3DNow!" );
    PRINT_CAPABILITY( CPU_CAPABILITY_MMXEXT, "MMXEXT" );
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE, "SSE" );
sigmunau's avatar
sigmunau committed
587
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE2, "SSE2" );
588
589
590
591
592
593
594
    PRINT_CAPABILITY( CPU_CAPABILITY_ALTIVEC, "AltiVec" );
    PRINT_CAPABILITY( CPU_CAPABILITY_FPU, "FPU" );
    msg_Dbg( p_vlc, "CPU has capabilities %s", p_capabilities );

    /*
     * Choose the best memcpy module
     */
gbazin's avatar
   
gbazin committed
595
    p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy", 0 );
596

597
    if( p_vlc->pf_memcpy == NULL )
598
599
600
    {
        p_vlc->pf_memcpy = memcpy;
    }
601
602
603
604
605

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

sigmunau's avatar
sigmunau committed
607
608
609
610
    /*
     * Initialize hotkey handling
     */
    var_Create( p_vlc, "key-pressed", VLC_VAR_INTEGER );
gbazin's avatar
   
gbazin committed
611
612
    p_vlc->p_hotkeys = malloc( sizeof(p_hotkeys) );
    /* Do a copy (we don't need to modify the strings) */
613
    memcpy( p_vlc->p_hotkeys, p_hotkeys, sizeof(p_hotkeys) );
gbazin's avatar
   
gbazin committed
614

615
616
617
    /*
     * Initialize playlist and get commandline files
     */
618
    p_playlist = playlist_Create( p_vlc );
619
620
621
    if( !p_playlist )
    {
        msg_Err( p_vlc, "playlist initialization failed" );
622
623
        if( p_vlc->p_memcpy_module != NULL )
        {
624
            module_Unneed( p_vlc, p_vlc->p_memcpy_module );
625
        }
626
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
627
        if( i_object ) vlc_object_release( p_vlc );
628
629
630
        return VLC_EGENERIC;
    }

631
632
633
634
635
636
637
    /*
     * Load background interfaces
     */
    psz_modules = config_GetPsz( p_vlc, "extraintf" );
    psz_parser = psz_modules;
    while ( psz_parser && *psz_parser )
    {
gbazin's avatar
   
gbazin committed
638
        char *psz_module, *psz_temp;
639
640
641
642
643
644
645
        psz_module = psz_parser;
        psz_parser = strchr( psz_module, ',' );
        if ( psz_parser )
        {
            *psz_parser = '\0';
            psz_parser++;
        }
gbazin's avatar
   
gbazin committed
646
647
648
649
        psz_temp = (char *)malloc( strlen(psz_module) + sizeof(",none") );
        if( psz_temp )
        {
            sprintf( psz_temp, "%s,none", psz_module );
650
            VLC_AddIntf( 0, psz_temp, VLC_FALSE, VLC_FALSE );
gbazin's avatar
   
gbazin committed
651
652
            free( psz_temp );
        }
653
654
655
656
657
    }
    if ( psz_modules )
    {
        free( psz_modules );
    }
658

sigmunau's avatar
sigmunau committed
659
660
661
    /*
     * Allways load the hotkeys interface if it exists
     */
662
    VLC_AddIntf( 0, "hotkeys,none", VLC_FALSE, VLC_FALSE );
sigmunau's avatar
sigmunau committed
663

664
665
666
667
    /*
     * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin
     */
    var_Create( p_vlc, "drawable", VLC_VAR_INTEGER );
668
669
670
671
672
673
674
675
676
677
678
    var_Create( p_vlc, "drawableredraw", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawablet", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawablel", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawableb", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawabler", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawablex", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawabley", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawablew", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawableh", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawableportx", VLC_VAR_INTEGER );
    var_Create( p_vlc, "drawableporty", VLC_VAR_INTEGER );
679

680
681
682
683
684
    /*
     * Get input filenames given as commandline arguments
     */
    GetFilenames( p_vlc, i_argc, ppsz_argv );

gbazin's avatar
   
gbazin committed
685
    if( i_object ) vlc_object_release( p_vlc );
686
687
688
689
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
690
 * VLC_AddIntf: add an interface
691
692
 *****************************************************************************
 * This function opens an interface plugin and runs it. If b_block is set
Sam Hocevar's avatar
Sam Hocevar committed
693
694
 * 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
695
696
 * user requests to quit. If b_play is set to 1, VLC_AddIntf will start playing
 * the playlist when it is completely initialised.
697
 *****************************************************************************/
698
699
int VLC_AddIntf( int i_object, char const *psz_module,
                 vlc_bool_t b_block, vlc_bool_t b_play )
700
{
Sam Hocevar's avatar
Sam Hocevar committed
701
    int i_err;
702
    intf_thread_t *p_intf;
703
    vlc_t *p_vlc = vlc_current_object( i_object );
Sam Hocevar's avatar
Sam Hocevar committed
704

705
    if( !p_vlc )
706
    {
707
        return VLC_ENOOBJ;
708
709
    }

gbazin's avatar
gbazin committed
710
711
712
713
714
715
716
717
718
719
720
#ifndef WIN32
    if( p_vlc->p_libvlc->b_daemon && b_block && !psz_module )
    {
        /* Daemon mode hack.
         * We prefer the dummy interface if none is specified. */
        char *psz_interface = config_GetPsz( p_vlc, "intf" );
        if( !psz_interface || !*psz_interface ) psz_module = "dummy";
        if( psz_interface ) free( psz_interface );
    }
#endif

721
    /* Try to create the interface */
722
    p_intf = intf_Create( p_vlc, psz_module ? psz_module : "$intf" );
723
724
725

    if( p_intf == NULL )
    {
gbazin's avatar
   
gbazin committed
726
        msg_Err( p_vlc, "interface \"%s\" initialization failed", psz_module );
gbazin's avatar
   
gbazin committed
727
        if( i_object ) vlc_object_release( p_vlc );
728
729
730
        return VLC_EGENERIC;
    }

731
732
733
    /* Interface doesn't handle play on start so do it ourselves */
    if( !p_intf->b_play && b_play ) VLC_Play( i_object );

734
    /* Try to run the interface */
735
    p_intf->b_play = b_play;
736
    p_intf->b_block = b_block;
Sam Hocevar's avatar
Sam Hocevar committed
737
738
    i_err = intf_RunThread( p_intf );
    if( i_err )
739
    {
740
        vlc_object_detach( p_intf );
741
        intf_Destroy( p_intf );
gbazin's avatar
   
gbazin committed
742
        if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
743
        return i_err;
744
745
    }

gbazin's avatar
   
gbazin committed
746
    if( i_object ) vlc_object_release( p_vlc );
747
748
749
750
    return VLC_SUCCESS;
}

/*****************************************************************************
hartman's avatar
hartman committed
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
 * VLC_Die: ask vlc to die.
 *****************************************************************************
 * This function sets p_vlc->b_die to VLC_TRUE, but does not do any other
 * task. It is your duty to call VLC_CleanUp and VLC_Destroy afterwards.
 *****************************************************************************/
int VLC_Die( int i_object )
{
    vlc_t *p_vlc = vlc_current_object( i_object );

    if( !p_vlc )
    {
        return VLC_ENOOBJ;
    }

    p_vlc->b_die = VLC_TRUE;

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

/*****************************************************************************
 * VLC_CleanUp: CleanUp all the intf, playlist, vout, aout
 *****************************************************************************/
int VLC_CleanUp( int i_object )
{
    intf_thread_t      * p_intf;
    playlist_t         * p_playlist;
    vout_thread_t      * p_vout;
    aout_instance_t    * p_aout;
    announce_handler_t * p_announce;
    vlc_t *p_vlc = vlc_current_object( i_object );

    /* Check that the handle is valid */
    if( !p_vlc )
    {
        return VLC_ENOOBJ;
    }

    /*
     * Ask the interfaces to stop and destroy them
     */
    msg_Dbg( p_vlc, "removing all interfaces" );
    while( (p_intf = vlc_object_find( p_vlc, VLC_OBJECT_INTF, FIND_CHILD )) )
    {
        intf_StopThread( p_intf );
        vlc_object_detach( p_intf );
        vlc_object_release( p_intf );
        intf_Destroy( p_intf );
    }

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

    /*
     * Free audio outputs
     */
    msg_Dbg( p_vlc, "removing all audio outputs" );
    while( (p_aout = vlc_object_find( p_vlc, VLC_OBJECT_AOUT, FIND_CHILD )) )
    {
        vlc_object_detach( (vlc_object_t *)p_aout );
        vlc_object_release( (vlc_object_t *)p_aout );
        aout_Delete( p_aout );
    }

    /*
     * Free announce handler(s?)
     */
    msg_Dbg( p_vlc, "removing announce handler" );
    while( (p_announce = vlc_object_find( p_vlc, VLC_OBJECT_ANNOUNCE,
                                                 FIND_CHILD ) ) )
   {
        vlc_object_detach( p_announce );
        vlc_object_release( p_announce );
        announce_HandlerDestroy( p_announce );
   }

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

/*****************************************************************************
 * VLC_Destroy: Destroy everything.
853
 *****************************************************************************
854
 * This function requests the running threads to finish, waits for their
855
856
 * termination, and destroys their structure.
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
857
int VLC_Destroy( int i_object )
858
{
859
    vlc_t *p_vlc = vlc_current_object( i_object );
860

861
    if( !p_vlc )
862
    {
863
        return VLC_ENOOBJ;
864
865
    }

866
867
868
869
870
871
872
    /*
     * Free allocated memory
     */
    if( p_vlc->p_memcpy_module )
    {
        module_Unneed( p_vlc, p_vlc->p_memcpy_module );
        p_vlc->p_memcpy_module = NULL;
873
874
    }

875
    /*
876
     * Free module bank !
877
878
879
     */
    module_EndBank( p_vlc );

880
881
882
883
884
    if( p_vlc->psz_homedir )
    {
        free( p_vlc->psz_homedir );
        p_vlc->psz_homedir = NULL;
    }
885

gbazin's avatar
   
gbazin committed
886
887
888
889
890
891
    if( p_vlc->psz_configfile )
    {
        free( p_vlc->psz_configfile );
        p_vlc->psz_configfile = NULL;
    }

892
893
894
895
896
897
    if( p_vlc->p_hotkeys )
    {
        free( p_vlc->p_hotkeys );
        p_vlc->p_hotkeys = NULL;
    }

898
899
900
901
    /*
     * System specific cleaning code
     */
    system_End( p_vlc );
902

903
904
905
    /* Destroy mutexes */
    vlc_mutex_destroy( &p_vlc->config_lock );

906
907
    vlc_object_detach( p_vlc );

908
909
910
    /* Release object before destroying it */
    if( i_object ) vlc_object_release( p_vlc );

911
912
    vlc_object_destroy( p_vlc );

913
    /* Stop thread system: last one out please shut the door! */
914
    vlc_threads_end( p_libvlc );
915

916
917
918
    return VLC_SUCCESS;
}

919
/*****************************************************************************
hartman's avatar
hartman committed
920
 * VLC_VariableSet: set a vlc variable
921
 *****************************************************************************/
hartman's avatar
hartman committed
922
int VLC_VariableSet( int i_object, char const *psz_var, vlc_value_t value )
923
{
924
    vlc_t *p_vlc = vlc_current_object( i_object );
gbazin's avatar
   
gbazin committed
925
    int i_ret;
926
927
928

    if( !p_vlc )
    {
929
        return VLC_ENOOBJ;
930
931
    }

Sam Hocevar's avatar
Sam Hocevar committed
932
933
934
    /* 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 ) )
935
    {
Sam Hocevar's avatar
Sam Hocevar committed
936
        module_config_t *p_item;
937
        char const *psz_newvar = psz_var + 6;
938

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

Sam Hocevar's avatar
Sam Hocevar committed
941
        if( p_item )
942
        {
Sam Hocevar's avatar
Sam Hocevar committed
943
            switch( p_item->i_type )
944
            {
Sam Hocevar's avatar
Sam Hocevar committed
945
946
947
948
949
950
951
952
953
954
955
956
                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;
957
            }
gbazin's avatar
   
gbazin committed
958
            if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
959
            return VLC_SUCCESS;
960
961
962
        }
    }

gbazin's avatar
   
gbazin committed
963
964
965
966
    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
967
968
969
}

/*****************************************************************************
hartman's avatar
hartman committed
970
 * VLC_VariableGet: get a vlc variable
Sam Hocevar's avatar
Sam Hocevar committed
971
 *****************************************************************************/
972
int VLC_Get( int i_object, char const *psz_var, vlc_value_t *p_value )
Sam Hocevar's avatar
Sam Hocevar committed
973
{
974
    vlc_t *p_vlc = vlc_current_object( i_object );
gbazin's avatar
   
gbazin committed
975
    int i_ret;
Sam Hocevar's avatar
Sam Hocevar committed
976
977

    if( !p_vlc )
978
    {
979
        return VLC_ENOOBJ;
980
981
    }

gbazin's avatar
   
gbazin committed
982
983
984
985
    i_ret = var_Get( p_vlc, psz_var, p_value );

    if( i_object ) vlc_object_release( p_vlc );
    return i_ret;
986
987
}

988
/*****************************************************************************
hartman's avatar
hartman committed
989
990
991
992
 * VLC_AddTarget: adds a target for playing.
 *****************************************************************************
 * This function adds psz_target to the current playlist. If a playlist does
 * not exist, it will create one.
993
 *****************************************************************************/
hartman's avatar
hartman committed
994
995
996
int VLC_AddTarget( int i_object, char const *psz_target,
                   char const **ppsz_options, int i_options,
                   int i_mode, int i_pos )
997
{
hartman's avatar
hartman committed
998
999
    int i_err;
    playlist_t *p_playlist;
1000
1001
1002
1003
1004
1005
1006
    vlc_t *p_vlc = vlc_current_object( i_object );

    if( !p_vlc )
    {
        return VLC_ENOOBJ;
    }

hartman's avatar
hartman committed
1007
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
1008

hartman's avatar
hartman committed
1009
    if( p_playlist == NULL )
1010
    {
hartman's avatar
hartman committed
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
        msg_Dbg( p_vlc, "no playlist present, creating one" );
        p_playlist = playlist_Create( p_vlc );

        if( p_playlist == NULL )
        {
            if( i_object ) vlc_object_release( p_vlc );
            return VLC_EGENERIC;
        }

        vlc_object_yield( p_playlist );
1021
1022
    }

hartman's avatar
hartman committed
1023
1024
    i_err = playlist_AddExt( p_playlist, psz_target, psz_target,
                             i_mode, i_pos, -1, ppsz_options, i_options);
1025
1026
1027
1028

    vlc_object_release( p_playlist );

    if( i_object ) vlc_object_release( p_vlc );
hartman's avatar
hartman committed
1029
    return i_err;
1030
1031
1032
}

/*****************************************************************************
hartman's avatar
hartman committed
1033
 * VLC_Play: play
1034
 *****************************************************************************/
hartman's avatar
hartman committed
1035
int VLC_Play( int i_object )
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
{
    playlist_t * p_playlist;
    vlc_t *p_vlc = vlc_current_object( i_object );

    /* Check that the handle is valid */
    if( !p_vlc )
    {
        return VLC_ENOOBJ;
    }

    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );

    if( !p_playlist )
    {
        if( i_object ) vlc_object_release( p_vlc );
        return VLC_ENOOBJ;
    }

hartman's avatar
hartman committed
1054
    playlist_Play( p_playlist );
1055
1056
1057
    vlc_object_release( p_playlist );

    if( i_object ) vlc_object_release( p_vlc );
hartman's avatar
hartman committed
1058
    return VLC_SUCCESS;
1059
1060
}

1061
/*****************************************************************************
hartman's avatar
hartman committed
1062
 * VLC_Pause: toggle pause
1063
 *****************************************************************************/
hartman's avatar
hartman committed
1064
int VLC_Pause( int i_object )
1065
1066
{
    playlist_t * p_playlist;
1067
    vlc_t *p_vlc = vlc_current_object( i_object );
1068
1069

    /* Check that the handle is valid */
1070
    if( !p_vlc )
1071
    {
1072
        return VLC_ENOOBJ;
1073
    }
1074

1075
1076
1077
1078
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );

    if( !p_playlist )
    {
gbazin's avatar
   
gbazin committed
1079
        if( i_object ) vlc_object_release( p_vlc );
1080
        return VLC_ENOOBJ;
1081
1082
    }

hartman's avatar
hartman committed
1083
    playlist_Pause( p_playlist );
1084
1085
    vlc_object_release( p_playlist );