libvlc.c 65.9 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
 *
 * Authors: Vincent Seguin <seguin@via.ecp.fr>
 *          Samuel Hocevar <sam@zoy.org>
9
 *          Gildas Bazin <gbazin@videolan.org>
hartman's avatar
hartman committed
10
 *          Derk-Jan Hartman <hartman at videolan dot org>
11
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
#ifdef HAVE_LOCALE_H
#   include <locale.h>
#endif

65
66
67
68
#ifdef HAVE_HAL
#   include <hal/libhal.h>
#endif

69
#include "vlc_cpu.h"                                        /* CPU detection */
70
#include "os_specific.h"
71

72
#include "vlc_error.h"
73

74
#include "vlc_playlist.h"
75
#include "vlc_interface.h"
76
77
78

#include "audio_output.h"

79
#include "vlc_video.h"
80
81
#include "video_output.h"

zorglub's avatar
zorglub committed
82
83
#include "stream_output.h"

84
85
86
#include "libvlc.h"

/*****************************************************************************
87
 * The evil global variable. We handle it with care, don't worry.
88
 *****************************************************************************/
89
90
91
static libvlc_t   libvlc;
static libvlc_t * p_libvlc;
static vlc_t *    p_static_vlc;
92
93
94
95

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

#ifdef WIN32
static void ShowConsole   ( void );
#endif
105
static int  ConsoleWidth  ( void );
106

hartman's avatar
hartman committed
107
108
static int  VerboseCallback( vlc_object_t *, char const *,
                             vlc_value_t, vlc_value_t, void * );
109

110
111
static void InitDeviceValues( vlc_t * );

112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*****************************************************************************
 * 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;
}

128
/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
129
 * VLC_Version: return the libvlc version.
130
 *****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
131
 * This function returns full version string (numeric version and codename).
132
 *****************************************************************************/
133
char const * VLC_Version( void )
134
{
Sam Hocevar's avatar
Sam Hocevar committed
135
    return VERSION_MESSAGE;
136
137
}

138
139
140
141
142
143
144
145
146
147
/*****************************************************************************
 * 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
148
149
150
151
152
153
154
/*****************************************************************************
 * 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 )
155
{
156
    int i_ret;
157
    vlc_t * p_vlc = NULL;
158
    vlc_value_t lockval;
159

160
161
162
    /* &libvlc never changes, so we can safely call this multiple times. */
    p_libvlc = &libvlc;

163
164
    /* vlc_threads_init *must* be the first internal call! No other call is
     * allowed before the thread system has been initialized. */
165
    i_ret = vlc_threads_init( p_libvlc );
Sam Hocevar's avatar
Sam Hocevar committed
166
    if( i_ret < 0 )
167
    {
Sam Hocevar's avatar
Sam Hocevar committed
168
        return i_ret;
169
170
171
    }

    /* Now that the thread system is initialized, we don't have much, but
172
     * at least we have var_Create */
173
174
    var_Create( p_libvlc, "libvlc", VLC_VAR_MUTEX );
    var_Get( p_libvlc, "libvlc", &lockval );
175
    vlc_mutex_lock( lockval.p_address );
176
177
    if( !libvlc.b_ready )
    {
178
179
        char *psz_env;

180
181
182
        /* Guess what CPU we have */
        libvlc.i_cpu = CPUCapabilities();

183
184
        /* Find verbosity from VLC_VERBOSE environment variable */
        psz_env = getenv( "VLC_VERBOSE" );
185
        libvlc.i_verbose = psz_env ? atoi( psz_env ) : -1;
186

gbazin's avatar
   
gbazin committed
187
#if defined( HAVE_ISATTY ) && !defined( WIN32 )
188
189
190
191
192
        libvlc.b_color = isatty( 2 ); /* 2 is for stderr */
#else
        libvlc.b_color = VLC_FALSE;
#endif

193
        /* Initialize message queue */
194
        msg_Create( p_libvlc );
195
196

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

200
201
        /* The module bank will be initialized later */
        libvlc.p_module_bank = NULL;
202
203

        libvlc.b_ready = VLC_TRUE;
204
    }
205
    vlc_mutex_unlock( lockval.p_address );
206
    var_Destroy( p_libvlc, "libvlc" );
207
208

    /* Allocate a vlc object */
209
    p_vlc = vlc_object_create( p_libvlc, VLC_OBJECT_VLC );
210
211
    if( p_vlc == NULL )
    {
Sam Hocevar's avatar
Sam Hocevar committed
212
        return VLC_EGENERIC;
213
    }
214
    p_vlc->thread_id = 0;
215
    vlc_thread_set_priority( p_vlc, VLC_THREAD_PRIORITY_LOW );
216
217
218
219

    p_vlc->psz_object_name = "root";

    /* Initialize mutexes */
220
    vlc_mutex_init( p_vlc, &p_vlc->config_lock );
hartman's avatar
hartman committed
221
222
223
#ifdef SYS_DARWIN
    vlc_mutex_init( p_vlc, &p_vlc->quicktime_lock );
#endif
224
225

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

Sam Hocevar's avatar
Sam Hocevar committed
228
229
230
231
    /* Store data for the non-reentrant API */
    p_static_vlc = p_vlc;

    return p_vlc->i_object_id;
232
233
234
}

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

255
    if( !p_vlc )
256
    {
257
        return VLC_ENOOBJ;
258
259
260
    }

    /*
261
     * System specific initialization code
262
     */
263
    system_Init( p_vlc, &i_argc, ppsz_argv );
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279

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

280
281
282
283
    /*
     * Support for gettext
     */
    SetLanguage( "" );
Sam Hocevar's avatar
Sam Hocevar committed
284
285

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

288
289
290
291
    /* 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) */
292
    module_InitBank( p_vlc );
293

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

Sam Hocevar's avatar
Sam Hocevar committed
308
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE ) )
309
    {
310
        vlc_object_detach( p_help_module );
311
312
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
313
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
314
        if( i_object ) vlc_object_release( p_vlc );
315
316
317
318
319
320
        return VLC_EGENERIC;
    }

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

gbazin's avatar
   
gbazin committed
334
335
336
337
    /* Set the config file stuff */
    p_vlc->psz_homedir = config_GetHomeDir();
    p_vlc->psz_configfile = config_GetPsz( p_vlc, "config" );

338
339
340
341
342
343
    /* Check for plugins cache options */
    if( config_GetInt( p_vlc, "reset-plugins-cache" ) )
    {
        libvlc.p_module_bank->b_cache_delete = VLC_TRUE;
    }

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

gbazin's avatar
gbazin committed
348
349
350
351
352
353
354
    /* 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" ) )
    {
355
356
357
358
359
360
361
362
363
364
365
#if HAVE_DAEMON
        if( daemon( 0, 0) != 0 )
        {
            msg_Err( p_vlc, "Unable to fork vlc to daemon mode" );
            b_exit = VLC_TRUE;
        }

        p_vlc->p_libvlc->b_daemon = VLC_TRUE;

#else
        pid_t i_pid;
gbazin's avatar
gbazin committed
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

        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" );
382
383
384
            close( STDIN_FILENO );
            close( STDOUT_FILENO );
            close( STDERR_FILENO );
gbazin's avatar
gbazin committed
385
386
387

            p_vlc->p_libvlc->b_daemon = VLC_TRUE;
        }
388
#endif
gbazin's avatar
gbazin committed
389
390
391
    }
#endif

392
393
    if( b_exit )
    {
394
395
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
396
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
397
        if( i_object ) vlc_object_release( p_vlc );
398
399
400
        return VLC_EEXIT;
    }

gbazin's avatar
   
gbazin committed
401
    /* Check for translation config option */
gbazin's avatar
   
gbazin committed
402
403
404
405
406
407
408
409
#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 );

410
411
412
    /* 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
413
    {
414
415
        vlc_bool_t b_cache_delete = libvlc.p_module_bank->b_cache_delete;

gbazin's avatar
   
gbazin committed
416
        /* Reset the default domain */
417
        SetLanguage( psz_language );
gbazin's avatar
   
gbazin committed
418

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

Sam Hocevar's avatar
Sam Hocevar committed
422
        textdomain( PACKAGE_NAME );
gbazin's avatar
   
gbazin committed
423

gbazin's avatar
   
gbazin committed
424
#if defined( ENABLE_UTF8 )
Sam Hocevar's avatar
Sam Hocevar committed
425
        bind_textdomain_codeset( PACKAGE_NAME, "UTF-8" );
426
427
#endif

gbazin's avatar
   
gbazin committed
428
        module_EndBank( p_vlc );
429
        module_InitBank( p_vlc );
430
        config_LoadConfigFile( p_vlc, "main" );
gbazin's avatar
   
gbazin committed
431
        config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_TRUE );
432
        libvlc.p_module_bank->b_cache_delete = b_cache_delete;
gbazin's avatar
   
gbazin committed
433
    }
434
    if( psz_language ) free( psz_language );
435
#endif
gbazin's avatar
   
gbazin committed
436

437
438
439
440
441
442
    /*
     * 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.
     */
443
444
445
446
447
448
449
    module_LoadBuiltins( p_vlc );
    module_LoadPlugins( p_vlc );
    if( p_vlc->b_die )
    {
        b_exit = VLC_TRUE;
    }

450
    msg_Dbg( p_vlc, "module bank initialized, found %i modules",
451
                    libvlc.p_module_bank->i_children );
452
453

    /* Hack: insert the help module here */
454
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
455
456
457
458
459
    /* End hack */

    /* Check for help on modules */
    if( (p_tmp = config_GetPsz( p_vlc, "module" )) )
    {
460
        Usage( p_vlc, p_tmp );
461
        free( p_tmp );
462
        b_exit = VLC_TRUE;
463
464
    }
    /* Check for long help option */
465
    else if( config_GetInt( p_vlc, "longhelp" ) )
466
    {
467
        Usage( p_vlc, NULL );
468
        b_exit = VLC_TRUE;
469
470
    }
    /* Check for module list option */
471
    else if( config_GetInt( p_vlc, "list" ) )
472
    {
473
        ListModules( p_vlc );
474
        b_exit = VLC_TRUE;
475
476
    }

gbazin's avatar
   
gbazin committed
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
    /* 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 );
    }

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

499
500
    if( b_exit )
    {
gbazin's avatar
   
gbazin committed
501
502
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
503
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
504
        if( i_object ) vlc_object_release( p_vlc );
505
506
507
        return VLC_EEXIT;
    }

508
509
510
511
512
    /*
     * Init device values
     */
    InitDeviceValues( p_vlc );

513
514
515
    /*
     * Override default configuration with config file settings
     */
516
    config_LoadConfigFile( p_vlc, NULL );
517

gbazin's avatar
   
gbazin committed
518
519
520
521
    /* Hack: insert the help module here */
    vlc_object_attach( p_help_module, libvlc.p_module_bank );
    /* End hack */

522
523
524
    /*
     * Override configuration with command line settings
     */
Sam Hocevar's avatar
Sam Hocevar committed
525
    if( config_LoadCmdLine( p_vlc, &i_argc, ppsz_argv, VLC_FALSE ) )
526
527
528
529
530
531
532
533
    {
#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
534
535
536
        vlc_object_detach( p_help_module );
        config_Free( p_help_module );
        vlc_object_destroy( p_help_module );
537
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
538
        if( i_object ) vlc_object_release( p_vlc );
539
540
541
        return VLC_EGENERIC;
    }

gbazin's avatar
   
gbazin committed
542
543
544
545
546
547
    /* 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 */

548
549
550
    /*
     * System specific configuration
     */
gbazin's avatar
   
gbazin committed
551
    system_Configure( p_vlc, &i_argc, ppsz_argv );
552

553
554
555
    /*
     * Message queue options
     */
hartman's avatar
hartman committed
556
557

    var_Create( p_vlc, "verbose", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
558
559
    if( config_GetInt( p_vlc, "quiet" ) )
    {
hartman's avatar
hartman committed
560
561
562
        vlc_value_t val;
        val.i_int = -1;
        var_Set( p_vlc, "verbose", val );
563
    }
hartman's avatar
hartman committed
564
565
    var_AddCallback( p_vlc, "verbose", VerboseCallback, NULL );
    var_Change( p_vlc, "verbose", VLC_VAR_TRIGGER_CALLBACKS, NULL, NULL );
zorglub's avatar
zorglub committed
566

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

569
570
571
572
573
    /*
     * Output messages that may still be in the queue
     */
    msg_Flush( p_vlc );

574
    /* p_vlc initialization. FIXME ? */
575

576
#if defined( __i386__ )
577
    if( !config_GetInt( p_vlc, "mmx" ) )
578
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMX;
579
    if( !config_GetInt( p_vlc, "3dn" ) )
580
        libvlc.i_cpu &= ~CPU_CAPABILITY_3DNOW;
581
    if( !config_GetInt( p_vlc, "mmxext" ) )
582
        libvlc.i_cpu &= ~CPU_CAPABILITY_MMXEXT;
583
    if( !config_GetInt( p_vlc, "sse" ) )
584
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE;
sigmunau's avatar
sigmunau committed
585
586
    if( !config_GetInt( p_vlc, "sse2" ) )
        libvlc.i_cpu &= ~CPU_CAPABILITY_SSE2;
587
588
#endif
#if defined( __powerpc__ ) || defined( SYS_DARWIN )
589
    if( !config_GetInt( p_vlc, "altivec" ) )
590
        libvlc.i_cpu &= ~CPU_CAPABILITY_ALTIVEC;
591
#endif
592
593

#define PRINT_CAPABILITY( capability, string )                              \
594
    if( libvlc.i_cpu & capability )                                         \
595
596
597
598
599
600
601
602
603
604
605
606
607
608
    {                                                                       \
        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
609
    PRINT_CAPABILITY( CPU_CAPABILITY_SSE2, "SSE2" );
610
611
612
613
614
615
616
    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
617
    p_vlc->p_memcpy_module = module_Need( p_vlc, "memcpy", "$memcpy", 0 );
618

619
    if( p_vlc->pf_memcpy == NULL )
620
621
622
    {
        p_vlc->pf_memcpy = memcpy;
    }
623
624
625
626
627

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

sigmunau's avatar
sigmunau committed
629
630
631
632
    /*
     * Initialize hotkey handling
     */
    var_Create( p_vlc, "key-pressed", VLC_VAR_INTEGER );
gbazin's avatar
   
gbazin committed
633
634
    p_vlc->p_hotkeys = malloc( sizeof(p_hotkeys) );
    /* Do a copy (we don't need to modify the strings) */
635
    memcpy( p_vlc->p_hotkeys, p_hotkeys, sizeof(p_hotkeys) );
gbazin's avatar
   
gbazin committed
636

637
638
639
    /*
     * Initialize playlist and get commandline files
     */
640
    p_playlist = playlist_Create( p_vlc );
641
642
643
    if( !p_playlist )
    {
        msg_Err( p_vlc, "playlist initialization failed" );
644
645
        if( p_vlc->p_memcpy_module != NULL )
        {
646
            module_Unneed( p_vlc, p_vlc->p_memcpy_module );
647
        }
648
        module_EndBank( p_vlc );
gbazin's avatar
   
gbazin committed
649
        if( i_object ) vlc_object_release( p_vlc );
650
651
652
        return VLC_EGENERIC;
    }

653
654
655
656
657
658
659
    /*
     * Load background interfaces
     */
    psz_modules = config_GetPsz( p_vlc, "extraintf" );
    psz_parser = psz_modules;
    while ( psz_parser && *psz_parser )
    {
gbazin's avatar
   
gbazin committed
660
        char *psz_module, *psz_temp;
661
662
663
664
665
666
667
        psz_module = psz_parser;
        psz_parser = strchr( psz_module, ',' );
        if ( psz_parser )
        {
            *psz_parser = '\0';
            psz_parser++;
        }
gbazin's avatar
   
gbazin committed
668
669
670
671
        psz_temp = (char *)malloc( strlen(psz_module) + sizeof(",none") );
        if( psz_temp )
        {
            sprintf( psz_temp, "%s,none", psz_module );
672
            VLC_AddIntf( 0, psz_temp, VLC_FALSE, VLC_FALSE );
gbazin's avatar
   
gbazin committed
673
674
            free( psz_temp );
        }
675
676
677
678
679
    }
    if ( psz_modules )
    {
        free( psz_modules );
    }
680

sigmunau's avatar
sigmunau committed
681
682
683
    /*
     * Allways load the hotkeys interface if it exists
     */
684
    VLC_AddIntf( 0, "hotkeys,none", VLC_FALSE, VLC_FALSE );
sigmunau's avatar
sigmunau committed
685

686
687
688
689
    /*
     * FIXME: kludge to use a p_vlc-local variable for the Mozilla plugin
     */
    var_Create( p_vlc, "drawable", VLC_VAR_INTEGER );
690
691
692
693
694
695
696
697
698
699
700
    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 );
701

702
703
704
705
706
    /*
     * Get input filenames given as commandline arguments
     */
    GetFilenames( p_vlc, i_argc, ppsz_argv );

gbazin's avatar
   
gbazin committed
707
    if( i_object ) vlc_object_release( p_vlc );
708
709
710
711
    return VLC_SUCCESS;
}

/*****************************************************************************
Sam Hocevar's avatar
Sam Hocevar committed
712
 * VLC_AddIntf: add an interface
713
714
 *****************************************************************************
 * This function opens an interface plugin and runs it. If b_block is set
Sam Hocevar's avatar
Sam Hocevar committed
715
716
 * 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
717
718
 * user requests to quit. If b_play is set to 1, VLC_AddIntf will start playing
 * the playlist when it is completely initialised.
719
 *****************************************************************************/
720
721
int VLC_AddIntf( int i_object, char const *psz_module,
                 vlc_bool_t b_block, vlc_bool_t b_play )
722
{
Sam Hocevar's avatar
Sam Hocevar committed
723
    int i_err;
724
    intf_thread_t *p_intf;
725
    vlc_t *p_vlc = vlc_current_object( i_object );
Sam Hocevar's avatar
Sam Hocevar committed
726

727
    if( !p_vlc )
728
    {
729
        return VLC_ENOOBJ;
730
731
    }

gbazin's avatar
gbazin committed
732
733
734
735
736
737
738
739
740
741
742
#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

743
    /* Try to create the interface */
744
    p_intf = intf_Create( p_vlc, psz_module ? psz_module : "$intf" );
745
746
747

    if( p_intf == NULL )
    {
gbazin's avatar
   
gbazin committed
748
        msg_Err( p_vlc, "interface \"%s\" initialization failed", psz_module );
gbazin's avatar
   
gbazin committed
749
        if( i_object ) vlc_object_release( p_vlc );
750
751
752
        return VLC_EGENERIC;
    }

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

756
    /* Try to run the interface */
757
    p_intf->b_play = b_play;
758
    p_intf->b_block = b_block;
Sam Hocevar's avatar
Sam Hocevar committed
759
760
    i_err = intf_RunThread( p_intf );
    if( i_err )
761
    {
762
        vlc_object_detach( p_intf );
763
        intf_Destroy( p_intf );
gbazin's avatar
   
gbazin committed
764
        if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
765
        return i_err;
766
767
    }

gbazin's avatar
   
gbazin committed
768
    if( i_object ) vlc_object_release( p_vlc );
769
770
771
772
    return VLC_SUCCESS;
}

/*****************************************************************************
hartman's avatar
hartman committed
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
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
 * 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.
875
 *****************************************************************************
876
 * This function requests the running threads to finish, waits for their
877
878
 * termination, and destroys their structure.
 *****************************************************************************/
Sam Hocevar's avatar
Sam Hocevar committed
879
int VLC_Destroy( int i_object )
880
{
881
    vlc_t *p_vlc = vlc_current_object( i_object );
882

883
    if( !p_vlc )
884
    {
885
        return VLC_ENOOBJ;
886
887
    }

888
889
890
891
892
893
894
    /*
     * Free allocated memory
     */
    if( p_vlc->p_memcpy_module )
    {
        module_Unneed( p_vlc, p_vlc->p_memcpy_module );
        p_vlc->p_memcpy_module = NULL;
895
896
    }

897
    /*
898
     * Free module bank !
899
900
901
     */
    module_EndBank( p_vlc );

902
903
904
905
906
    if( p_vlc->psz_homedir )
    {
        free( p_vlc->psz_homedir );
        p_vlc->psz_homedir = NULL;
    }
907

gbazin's avatar
   
gbazin committed
908
909
910
911
912
913
    if( p_vlc->psz_configfile )
    {
        free( p_vlc->psz_configfile );
        p_vlc->psz_configfile = NULL;
    }

914
915
916
917
918
919
    if( p_vlc->p_hotkeys )
    {
        free( p_vlc->p_hotkeys );
        p_vlc->p_hotkeys = NULL;
    }

920
921
922
923
    /*
     * System specific cleaning code
     */
    system_End( p_vlc );
924

925
926
927
    /* Destroy mutexes */
    vlc_mutex_destroy( &p_vlc->config_lock );

928
929
    vlc_object_detach( p_vlc );

930
931
932
    /* Release object before destroying it */
    if( i_object ) vlc_object_release( p_vlc );

933
934
    vlc_object_destroy( p_vlc );

935
    /* Stop thread system: last one out please shut the door! */
936
    vlc_threads_end( p_libvlc );
937

938
939
940
    return VLC_SUCCESS;
}

941
/*****************************************************************************
hartman's avatar
hartman committed
942
 * VLC_VariableSet: set a vlc variable
943
 *****************************************************************************/
hartman's avatar
hartman committed
944
int VLC_VariableSet( int i_object, char const *psz_var, vlc_value_t value )
945
{
946
    vlc_t *p_vlc = vlc_current_object( i_object );
gbazin's avatar
   
gbazin committed
947
    int i_ret;
948
949
950

    if( !p_vlc )
    {
951
        return VLC_ENOOBJ;
952
953
    }

Sam Hocevar's avatar
Sam Hocevar committed
954
955
956
    /* 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 ) )
957
    {
Sam Hocevar's avatar
Sam Hocevar committed
958
        module_config_t *p_item;
959
        char const *psz_newvar = psz_var + 6;
960

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

Sam Hocevar's avatar
Sam Hocevar committed
963
        if( p_item )
964
        {
Sam Hocevar's avatar
Sam Hocevar committed
965
            switch( p_item->i_type )
966
            {
Sam Hocevar's avatar
Sam Hocevar committed
967
968
969
970
971
972
973
974
975
976
977
978
                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;
979
            }
gbazin's avatar
   
gbazin committed
980
            if( i_object ) vlc_object_release( p_vlc );
Sam Hocevar's avatar
Sam Hocevar committed
981
            return VLC_SUCCESS;
982
983
984
        }
    }

gbazin's avatar
   
gbazin committed
985
986
987
988
    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
989
990
991
}

/*****************************************************************************
hartman's avatar
hartman committed
992
 * VLC_VariableGet: get a vlc variable
Sam Hocevar's avatar
Sam Hocevar committed
993
 *****************************************************************************/
994
int VLC_VariableGet( int i_object, char const *psz_var, vlc_value_t *p_value )
Sam Hocevar's avatar
Sam Hocevar committed
995
{
996
    vlc_t *p_vlc = vlc_current_object( i_object );
gbazin's avatar
   
gbazin committed
997
    int i_ret;
Sam Hocevar's avatar
Sam Hocevar committed
998
999

    if( !p_vlc )
1000
    {
1001
        return VLC_ENOOBJ;
1002
1003
    }

1004
    i_ret = var_Get( p_vlc , psz_var, p_value );
gbazin's avatar
   
gbazin committed
1005
1006
1007

    if( i_object ) vlc_object_release( p_vlc );
    return i_ret;
1008
1009
}

1010
/*****************************************************************************
hartman's avatar
hartman committed
1011
1012
1013
1014
 * 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.
1015
 *****************************************************************************/
hartman's avatar
hartman committed
1016
1017
1018
int VLC_AddTarget( int i_object, char const *psz_target,
                   char const **ppsz_options, int i_options,
                   int i_mode, int i_pos )
1019
{
hartman's avatar
hartman committed
1020
1021
    int i_err;
    playlist_t *p_playlist;
1022
1023
1024
1025
1026
1027
1028
    vlc_t *p_vlc = vlc_current_object( i_object );

    if( !p_vlc )
    {
        return VLC_ENOOBJ;
    }

hartman's avatar
hartman committed
1029
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
1030

hartman's avatar
hartman committed
1031
    if( p_playlist == NULL )
1032
    {
hartman's avatar
hartman committed
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
        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 );
1043
1044
    }

hartman's avatar
hartman committed
1045
1046
    i_err = playlist_AddExt( p_playlist, psz_target, psz_target,
                             i_mode, i_pos, -1, ppsz_options, i_options);
1047
1048
1049
1050

    vlc_object_release( p_playlist );

    if( i_object ) vlc_object_release( p_vlc );
hartman's avatar
hartman committed
1051
    return i_err;
1052
1053
1054
}

/*****************************************************************************
hartman's avatar
hartman committed
1055
 * VLC_Play: play
1056
 *****************************************************************************/
hartman's avatar
hartman committed
1057
int VLC_Play( int i_object )
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
{
    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
1076
    playlist_Play( p_playlist );
1077
1078
1079
    vlc_object_release( p_playlist );

    if( i_object ) vlc_object_release( p_vlc );
hartman's avatar
hartman committed
1080
    return VLC_SUCCESS;
1081
1082
}

1083
/*****************************************************************************
hartman's avatar
hartman committed
1084
 * VLC_Pause: toggle pause
1085
 *****************************************************************************/
hartman's avatar
hartman committed
1086
int VLC_Pause( int i_object )
1087
1088
{
    playlist_t * p_playlist;
1089
    vlc_t *p_vlc = vlc_current_object( i_object );
1090
1091

    /* Check that the handle is valid */
1092
    if( !p_vlc )
1093
    {
1094
        return VLC_ENOOBJ;
1095
    }
1096

1097
1098
1099
1100
    p_playlist = vlc_object_find( p_vlc, VLC_OBJECT_PLAYLIST, FIND_CHILD );

    if( !p_playlist )
    {
gbazin's avatar
   
gbazin committed
1101
        if( i_object ) vlc_object_release( p_vlc );
1102
        return VLC_ENOOBJ;
1103
1104
    }

hartman's avatar
hartman committed
1105
    playlist_Pause( p_playlist );
1106
1107
    vlc_object_release( p_playlist );

gbazin's avatar
   
gbazin committed
1108
    if( i_object ) vlc_object_release( p_vlc );
hartman's avatar
hartman committed
1109
    return VLC_SUCCESS;
1110
1111
1112
}