Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
13a1c6b8
Commit
13a1c6b8
authored
May 31, 2008
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove VLC_* dead APIs
parent
5ba2255e
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
1875 additions
and
2550 deletions
+1875
-2550
po/POTFILES.in
po/POTFILES.in
+0
-2
src/Makefile.am
src/Makefile.am
+0
-1
src/libvlc-common.c
src/libvlc-common.c
+0
-2063
src/libvlc.c
src/libvlc.c
+1875
-484
No files found.
po/POTFILES.in
View file @
13a1c6b8
...
...
@@ -14,7 +14,6 @@ include/vlc_codec.h
include/vlc_codecs.h
include/vlc_codec_synchro.h
include/vlc_common.h
include/vlc/common.h
include/vlc_config_cat.h
include/vlc_config.h
include/vlc_configuration.h
...
...
@@ -133,7 +132,6 @@ src/interface/interface.c
src/interface/interface.h
src/interface/intf_eject.c
src/libvlc.c
src/libvlc-common.c
src/libvlc.h
src/libvlc-module.c
src/misc/action.c
...
...
src/Makefile.am
View file @
13a1c6b8
...
...
@@ -264,7 +264,6 @@ SOURCES_libvlc_getopt = \
SOURCES_libvlc_common
=
\
libvlc.c
\
libvlc-common.c
\
libvlc.h
\
libvlc-module.c
\
version.c
\
...
...
src/libvlc-common.c
deleted
100644 → 0
View file @
5ba2255e
/*****************************************************************************
* libvlc-common.c: libvlc instances creation and deletion, interfaces handling
*****************************************************************************
* Copyright (C) 1998-2006 the VideoLAN team
* $Id$
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
* Gildas Bazin <gbazin@videolan.org>
* Derk-Jan Hartman <hartman at videolan dot org>
* Rémi Denis-Courmont <rem # videolan : org>
*
* 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/** \file
* This file contains functions to create and destroy libvlc instances
*/
/*****************************************************************************
* Preamble
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <vlc_common.h>
#include "control/libvlc_internal.h"
#include <vlc_input.h>
#include "modules/modules.h"
#include "config/configuration.h"
#include "interface/interface.h"
#include <errno.h>
/* ENOMEM */
#include <stdio.h>
/* sprintf() */
#include <string.h>
#include <stdlib.h>
/* free() */
#ifndef WIN32
# include <netinet/in.h>
/* BSD: struct in_addr */
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#elif defined( WIN32 ) && !defined( UNDER_CE )
# include <io.h>
#endif
#ifdef WIN32
/* optind, getopt(), included in unistd.h */
# include "extras/getopt.h"
#endif
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
#ifdef HAVE_DBUS_3
/* used for one-instance mode */
# include <dbus/dbus.h>
#endif
#ifdef HAVE_HAL
# include <hal/libhal.h>
#endif
#include <vlc_playlist.h>
#include <vlc_interface.h>
#include <vlc_aout.h>
#include "audio_output/aout_internal.h"
#include <vlc_vout.h>
#include <vlc_sout.h>
#include "stream_output/stream_output.h"
#include <vlc_charset.h>
#include "libvlc.h"
#include "playlist/playlist_internal.h"
#include <vlc_vlm.h>
#include <assert.h>
/*****************************************************************************
* The evil global variables. We handle them with care, don't worry.
*****************************************************************************/
static
libvlc_int_t
*
p_static_vlc
=
NULL
;
static
unsigned
i_instances
=
0
;
static
bool
b_daemon
=
false
;
/*****************************************************************************
* Local prototypes
*****************************************************************************/
#if defined( ENABLE_NLS ) && (defined (__APPLE__) || defined (WIN32)) && \
( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
static
void
SetLanguage
(
char
const
*
);
#endif
static
inline
int
LoadMessages
(
void
);
static
int
GetFilenames
(
libvlc_int_t
*
,
int
,
const
char
*
[]
);
static
void
Help
(
libvlc_int_t
*
,
char
const
*
psz_help_name
);
static
void
Usage
(
libvlc_int_t
*
,
char
const
*
psz_module_name
);
static
void
ListModules
(
libvlc_int_t
*
,
bool
);
static
void
Version
(
void
);
#ifdef WIN32
static
void
ShowConsole
(
bool
);
static
void
PauseConsole
(
void
);
#endif
static
int
ConsoleWidth
(
void
);
static
int
VerboseCallback
(
vlc_object_t
*
,
char
const
*
,
vlc_value_t
,
vlc_value_t
,
void
*
);
static
void
InitDeviceValues
(
libvlc_int_t
*
);
/*****************************************************************************
* 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.
*****************************************************************************/
libvlc_int_t
*
vlc_current_object
(
int
i_object
)
{
return
i_object
?
vlc_object_get
(
i_object
)
:
p_static_vlc
;
}
/**
* Allocate a libvlc instance, initialize global data if needed
* It also initializes the threading system
*/
libvlc_int_t
*
libvlc_InternalCreate
(
void
)
{
libvlc_int_t
*
p_libvlc
;
libvlc_priv_t
*
priv
;
char
*
psz_env
=
NULL
;
/* vlc_threads_init *must* be the first internal call! No other call is
* allowed before the thread system has been initialized. */
if
(
vlc_threads_init
())
return
NULL
;
libvlc_global_data_t
*
p_libvlc_global
=
vlc_global
();
/* Now that the thread system is initialized, we don't have much, but
* at least we have variables */
vlc_mutex_t
*
lock
=
var_AcquireMutex
(
"libvlc"
);
if
(
i_instances
==
0
)
{
/* Guess what CPU we have */
cpu_flags
=
CPUCapabilities
();
/* The module bank will be initialized later */
p_libvlc_global
->
p_module_bank
=
NULL
;
}
/* Allocate a libvlc instance object */
p_libvlc
=
vlc_custom_create
(
VLC_OBJECT
(
p_libvlc_global
),
sizeof
(
*
p_libvlc
)
+
sizeof
(
libvlc_priv_t
),
VLC_OBJECT_LIBVLC
,
"libvlc"
);
if
(
p_libvlc
!=
NULL
)
i_instances
++
;
vlc_mutex_unlock
(
lock
);
if
(
p_libvlc
==
NULL
)
return
NULL
;
priv
=
libvlc_priv
(
p_libvlc
);
priv
->
p_playlist
=
NULL
;
priv
->
p_interaction
=
NULL
;
priv
->
p_vlm
=
NULL
;
p_libvlc
->
psz_object_name
=
strdup
(
"libvlc"
);
/* Initialize message queue */
msg_Create
(
p_libvlc
);
/* Find verbosity from VLC_VERBOSE environment variable */
psz_env
=
getenv
(
"VLC_VERBOSE"
);
if
(
psz_env
!=
NULL
)
priv
->
i_verbose
=
atoi
(
psz_env
);
else
priv
->
i_verbose
=
3
;
#if defined( HAVE_ISATTY ) && !defined( WIN32 )
priv
->
b_color
=
isatty
(
2
);
/* 2 is for stderr */
#else
priv
->
b_color
=
false
;
#endif
/* Announce who we are - Do it only for first instance ? */
msg_Dbg
(
p_libvlc
,
COPYRIGHT_MESSAGE
);
msg_Dbg
(
p_libvlc
,
"libvlc was configured with %s"
,
CONFIGURE_LINE
);
/* Initialize mutexes */
vlc_mutex_init
(
&
priv
->
timer_lock
);
vlc_mutex_init
(
&
priv
->
config_lock
);
/* Store data for the non-reentrant API */
p_static_vlc
=
p_libvlc
;
return
p_libvlc
;
}
/**
* Initialize a libvlc instance
* This function initializes a previously allocated libvlc instance:
* - CPU detection
* - gettext initialization
* - message queue, module bank and playlist initialization
* - configuration and commandline parsing
*/
int
libvlc_InternalInit
(
libvlc_int_t
*
p_libvlc
,
int
i_argc
,
const
char
*
ppsz_argv
[]
)
{
libvlc_global_data_t
*
p_libvlc_global
=
vlc_global
();
libvlc_priv_t
*
priv
=
libvlc_priv
(
p_libvlc
);
char
p_capabilities
[
200
];
char
*
p_tmp
=
NULL
;
char
*
psz_modules
=
NULL
;
char
*
psz_parser
=
NULL
;
char
*
psz_control
=
NULL
;
bool
b_exit
=
false
;
int
i_ret
=
VLC_EEXIT
;
playlist_t
*
p_playlist
=
NULL
;
vlc_value_t
val
;
#if defined( ENABLE_NLS ) \
&& ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
# if defined (WIN32) || defined (__APPLE__)
char
*
psz_language
;
#endif
#endif
/* System specific initialization code */
system_Init
(
p_libvlc
,
&
i_argc
,
ppsz_argv
);
/* Get the executable name (similar to the basename command) */
if
(
i_argc
>
0
&&
ppsz_argv
[
0
][
0
]
)
{
free
(
p_libvlc
->
psz_object_name
);
const
char
*
psz_exe
=
strrchr
(
ppsz_argv
[
0
],
'/'
);
if
(
psz_exe
&&
*
(
psz_exe
+
1
)
)
p_libvlc
->
psz_object_name
=
strdup
(
psz_exe
+
1
);
else
p_libvlc
->
psz_object_name
=
strdup
(
ppsz_argv
[
0
]
);
}
/*
* Support for gettext
*/
LoadMessages
();
/* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
msg_Dbg
(
p_libvlc
,
"translation test: code is
\"
%s
\"
"
,
_
(
"C"
)
);
/* 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) */
module_InitBank
(
p_libvlc
);
if
(
config_LoadCmdLine
(
p_libvlc
,
&
i_argc
,
ppsz_argv
,
true
)
)
{
module_EndBank
(
p_libvlc
);
return
VLC_EGENERIC
;
}
#ifdef __APPLE__
/* vlc_thread_set_priority needs to query the config,
* so this is the earliest moment where we can set this */
vlc_thread_set_priority
(
p_libvlc
,
VLC_THREAD_PRIORITY_LOW
);
#endif
/* Check for short help option */
if
(
config_GetInt
(
p_libvlc
,
"help"
)
>
0
)
{
Help
(
p_libvlc
,
"help"
);
b_exit
=
true
;
i_ret
=
VLC_EEXITSUCCESS
;
}
/* Check for version option */
else
if
(
config_GetInt
(
p_libvlc
,
"version"
)
>
0
)
{
Version
();
b_exit
=
true
;
i_ret
=
VLC_EEXITSUCCESS
;
}
/* Set the config file stuff */
priv
->
psz_configfile
=
config_GetCustomConfigFile
(
p_libvlc
);
/* Check for plugins cache options */
if
(
config_GetInt
(
p_libvlc
,
"reset-plugins-cache"
)
>
0
)
{
p_libvlc_global
->
p_module_bank
->
b_cache_delete
=
true
;
}
/* Will be re-done properly later on */
priv
->
i_verbose
=
config_GetInt
(
p_libvlc
,
"verbose"
);
/* Check for daemon mode */
#ifndef WIN32
if
(
config_GetInt
(
p_libvlc
,
"daemon"
)
>
0
)
{
#ifdef HAVE_DAEMON
char
*
psz_pidfile
=
NULL
;
if
(
daemon
(
1
,
0
)
!=
0
)
{
msg_Err
(
p_libvlc
,
"Unable to fork vlc to daemon mode"
);
b_exit
=
true
;
}
b_daemon
=
true
;
/* lets check if we need to write the pidfile */
psz_pidfile
=
config_GetPsz
(
p_libvlc
,
"pidfile"
);
if
(
psz_pidfile
!=
NULL
)
{
FILE
*
pidfile
;
pid_t
i_pid
=
getpid
();
msg_Dbg
(
p_libvlc
,
"PID is %d, writing it to %s"
,
i_pid
,
psz_pidfile
);
pidfile
=
utf8_fopen
(
psz_pidfile
,
"w"
);
if
(
pidfile
!=
NULL
)
{
utf8_fprintf
(
pidfile
,
"%d"
,
(
int
)
i_pid
);
fclose
(
pidfile
);
}
else
{
msg_Err
(
p_libvlc
,
"cannot open pid file for writing: %s (%m)"
,
psz_pidfile
);
}
}
free
(
psz_pidfile
);
#else
pid_t
i_pid
;
if
(
(
i_pid
=
fork
()
)
<
0
)
{
msg_Err
(
p_libvlc
,
"unable to fork vlc to daemon mode"
);
b_exit
=
true
;
}
else
if
(
i_pid
)
{
/* This is the parent, exit right now */
msg_Dbg
(
p_libvlc
,
"closing parent process"
);
b_exit
=
true
;
i_ret
=
VLC_EEXITSUCCESS
;
}
else
{
/* We are the child */
msg_Dbg
(
p_libvlc
,
"daemon spawned"
);
close
(
STDIN_FILENO
);
close
(
STDOUT_FILENO
);
close
(
STDERR_FILENO
);
b_daemon
=
true
;
}
#endif
}
#endif
if
(
b_exit
)
{
module_EndBank
(
p_libvlc
);
return
i_ret
;
}
/* Check for translation config option */
#if defined( ENABLE_NLS ) \
&& ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
# if defined (WIN32) || defined (__APPLE__)
/* This ain't really nice to have to reload the config here but it seems
* the only way to do it. */
if
(
!
config_GetInt
(
p_libvlc
,
"ignore-config"
)
)
config_LoadConfigFile
(
p_libvlc
,
"main"
);
config_LoadCmdLine
(
p_libvlc
,
&
i_argc
,
ppsz_argv
,
true
);
/* Check if the user specified a custom language */
psz_language
=
config_GetPsz
(
p_libvlc
,
"language"
);
if
(
psz_language
&&
*
psz_language
&&
strcmp
(
psz_language
,
"auto"
)
)
{
bool
b_cache_delete
=
p_libvlc_global
->
p_module_bank
->
b_cache_delete
;
/* Reset the default domain */
SetLanguage
(
psz_language
);
/* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
msg_Dbg
(
p_libvlc
,
"translation test: code is
\"
%s
\"
"
,
_
(
"C"
)
);
module_EndBank
(
p_libvlc
);
module_InitBank
(
p_libvlc
);
if
(
!
config_GetInt
(
p_libvlc
,
"ignore-config"
)
)
config_LoadConfigFile
(
p_libvlc
,
"main"
);
config_LoadCmdLine
(
p_libvlc
,
&
i_argc
,
ppsz_argv
,
true
);
p_libvlc_global
->
p_module_bank
->
b_cache_delete
=
b_cache_delete
;
}
free
(
psz_language
);
# endif
#endif
/*
* 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.
*/
module_LoadBuiltins
(
p_libvlc
);
module_LoadPlugins
(
p_libvlc
);
if
(
p_libvlc
->
b_die
)
{
b_exit
=
true
;
}
msg_Dbg
(
p_libvlc
,
"module bank initialized, found %i modules"
,
vlc_internals
(
p_libvlc_global
->
p_module_bank
)
->
i_children
);
/* Check for help on modules */
if
(
(
p_tmp
=
config_GetPsz
(
p_libvlc
,
"module"
))
)
{
Help
(
p_libvlc
,
p_tmp
);
free
(
p_tmp
);
b_exit
=
true
;
i_ret
=
VLC_EEXITSUCCESS
;
}
/* Check for long help option */
else
if
(
config_GetInt
(
p_libvlc
,
"longhelp"
)
>
0
)
{
Help
(
p_libvlc
,
"longhelp"
);
b_exit
=
true
;
i_ret
=
VLC_EEXITSUCCESS
;
}
/* Check for module list option */
else
if
(
config_GetInt
(
p_libvlc
,
"list"
)
>
0
)
{
ListModules
(
p_libvlc
,
false
);
b_exit
=
true
;
i_ret
=
VLC_EEXITSUCCESS
;
}
else
if
(
config_GetInt
(
p_libvlc
,
"list-verbose"
)
>
0
)
{
ListModules
(
p_libvlc
,
true
);
b_exit
=
true
;
i_ret
=
VLC_EEXITSUCCESS
;
}
/* Check for config file options */
if
(
!
config_GetInt
(
p_libvlc
,
"ignore-config"
)
)
{
if
(
config_GetInt
(
p_libvlc
,
"reset-config"
)
>
0
)
{
config_ResetAll
(
p_libvlc
);
config_LoadCmdLine
(
p_libvlc
,
&
i_argc
,
ppsz_argv
,
true
);
config_SaveConfigFile
(
p_libvlc
,
NULL
);
}
if
(
config_GetInt
(
p_libvlc
,
"save-config"
)
>
0
)
{
config_LoadConfigFile
(
p_libvlc
,
NULL
);
config_LoadCmdLine
(
p_libvlc
,
&
i_argc
,
ppsz_argv
,
true
);
config_SaveConfigFile
(
p_libvlc
,
NULL
);
}
}
if
(
b_exit
)
{
module_EndBank
(
p_libvlc
);
return
i_ret
;
}
/*
* Init device values
*/
InitDeviceValues
(
p_libvlc
);
/*
* Override default configuration with config file settings
*/
if
(
!
config_GetInt
(
p_libvlc
,
"ignore-config"
)
)
config_LoadConfigFile
(
p_libvlc
,
NULL
);
/*
* Override configuration with command line settings
*/
if
(
config_LoadCmdLine
(
p_libvlc
,
&
i_argc
,
ppsz_argv
,
false
)
)
{
#ifdef WIN32
ShowConsole
(
false
);
/* 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.
\n
"
);
PauseConsole
();
#endif
module_EndBank
(
p_libvlc
);
return
VLC_EGENERIC
;
}
/*
* System specific configuration
*/
system_Configure
(
p_libvlc
,
&
i_argc
,
ppsz_argv
);
/* FIXME: could be replaced by using Unix sockets */
#ifdef HAVE_DBUS_3
dbus_threads_init_default
();
if
(
config_GetInt
(
p_libvlc
,
"one-instance"
)
>
0
)
{
/* Initialise D-Bus interface, check for other instances */
DBusConnection
*
p_conn
=
NULL
;
DBusError
dbus_error
;
dbus_error_init
(
&
dbus_error
);
/* connect to the session bus */
p_conn
=
dbus_bus_get
(
DBUS_BUS_SESSION
,
&
dbus_error
);
if
(
!
p_conn
)
{
msg_Err
(
p_libvlc
,
"Failed to connect to D-Bus session daemon: %s"
,
dbus_error
.
message
);
dbus_error_free
(
&
dbus_error
);
}
else
{
/* check if VLC is available on the bus
* if not: D-Bus control is not enabled on the other
* instance and we can't pass MRLs to it */
DBusMessage
*
p_test_msg
=
NULL
;
DBusMessage
*
p_test_reply
=
NULL
;
p_test_msg
=
dbus_message_new_method_call
(
"org.mpris.vlc"
,
"/"
,
"org.freedesktop.MediaPlayer"
,
"Identity"
);
/* block until a reply arrives */
p_test_reply
=
dbus_connection_send_with_reply_and_block
(
p_conn
,
p_test_msg
,
-
1
,
&
dbus_error
);
dbus_message_unref
(
p_test_msg
);
if
(
p_test_reply
==
NULL
)
{
dbus_error_free
(
&
dbus_error
);
msg_Dbg
(
p_libvlc
,
"No Media Player is running. "
"Continuing normally."
);
}
else
{
int
i_input
;
DBusMessage
*
p_dbus_msg
=
NULL
;
DBusMessageIter
dbus_args
;
DBusPendingCall
*
p_dbus_pending
=
NULL
;
dbus_bool_t
b_play
;
dbus_message_unref
(
p_test_reply
);
msg_Warn
(
p_libvlc
,
"Another Media Player is running. Exiting"
);
for
(
i_input
=
optind
;
i_input
<
i_argc
;
i_input
++
)
{
msg_Dbg
(
p_libvlc
,
"Adds %s to the running Media Player"
,
ppsz_argv
[
i_input
]
);
p_dbus_msg
=
dbus_message_new_method_call
(
"org.mpris.vlc"
,
"/TrackList"
,
"org.freedesktop.MediaPlayer"
,
"AddTrack"
);
if
(
NULL
==
p_dbus_msg
)
{
msg_Err
(
p_libvlc
,
"D-Bus problem"
);
system_End
(
p_libvlc
);
exit
(
VLC_ETIMEOUT
);
}
/* append MRLs */
dbus_message_iter_init_append
(
p_dbus_msg
,
&
dbus_args
);
if
(
!
dbus_message_iter_append_basic
(
&
dbus_args
,
DBUS_TYPE_STRING
,
&
ppsz_argv
[
i_input
]
)
)
{
msg_Err
(
p_libvlc
,
"Out of memory"
);
dbus_message_unref
(
p_dbus_msg
);
system_End
(
p_libvlc
);
exit
(
VLC_ENOMEM
);
}
b_play
=
TRUE
;
if
(
config_GetInt
(
p_libvlc
,
"playlist-enqueue"
)
>
0
)
b_play
=
FALSE
;
if
(
!
dbus_message_iter_append_basic
(
&
dbus_args
,
DBUS_TYPE_BOOLEAN
,
&
b_play
)
)
{
msg_Err
(
p_libvlc
,
"Out of memory"
);
dbus_message_unref
(
p_dbus_msg
);
system_End
(
p_libvlc
);
exit
(
VLC_ENOMEM
);
}
/* send message and get a handle for a reply */
if
(
!
dbus_connection_send_with_reply
(
p_conn
,
p_dbus_msg
,
&
p_dbus_pending
,
-
1
)
)
{
msg_Err
(
p_libvlc
,
"D-Bus problem"
);
dbus_message_unref
(
p_dbus_msg
);
system_End
(
p_libvlc
);
exit
(
VLC_ETIMEOUT
);
}
if
(
NULL
==
p_dbus_pending
)
{
msg_Err
(
p_libvlc
,
"D-Bus problem"
);
dbus_message_unref
(
p_dbus_msg
);
system_End
(
p_libvlc
);
exit
(
VLC_ETIMEOUT
);
}
dbus_connection_flush
(
p_conn
);
dbus_message_unref
(
p_dbus_msg
);
/* block until we receive a reply */
dbus_pending_call_block
(
p_dbus_pending
);
dbus_pending_call_unref
(
p_dbus_pending
);
}
/* processes all command line MRLs */
/* bye bye */
system_End
(
p_libvlc
);
exit
(
VLC_SUCCESS
);
}
}
/* we unreference the connection when we've finished with it */
if
(
p_conn
)
dbus_connection_unref
(
p_conn
);
}
#endif
/*
* Message queue options
*/
var_Create
(
p_libvlc
,
"verbose"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
);
if
(
config_GetInt
(
p_libvlc
,
"quiet"
)
>
0
)
{
val
.
i_int
=
-
1
;
var_Set
(
p_libvlc
,
"verbose"
,
val
);
}
var_AddCallback
(
p_libvlc
,
"verbose"
,
VerboseCallback
,
NULL
);
var_Change
(
p_libvlc
,
"verbose"
,
VLC_VAR_TRIGGER_CALLBACKS
,
NULL
,
NULL
);
if
(
priv
->
b_color
)
priv
->
b_color
=
config_GetInt
(
p_libvlc
,
"color"
)
>
0
;
/*
* Output messages that may still be in the queue
*/
msg_Flush
(
p_libvlc
);
if
(
!
config_GetInt
(
p_libvlc
,
"fpu"
)
)
cpu_flags
&=
~
CPU_CAPABILITY_FPU
;
#if defined( __i386__ ) || defined( __x86_64__ )
if
(
!
config_GetInt
(
p_libvlc
,
"mmx"
)
)
cpu_flags
&=
~
CPU_CAPABILITY_MMX
;
if
(
!
config_GetInt
(
p_libvlc
,
"3dn"
)
)
cpu_flags
&=
~
CPU_CAPABILITY_3DNOW
;
if
(
!
config_GetInt
(
p_libvlc
,
"mmxext"
)
)
cpu_flags
&=
~
CPU_CAPABILITY_MMXEXT
;
if
(
!
config_GetInt
(
p_libvlc
,
"sse"
)
)
cpu_flags
&=
~
CPU_CAPABILITY_SSE
;
if
(
!
config_GetInt
(
p_libvlc
,
"sse2"
)
)
cpu_flags
&=
~
CPU_CAPABILITY_SSE2
;
#endif
#if defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ )
if
(
!
config_GetInt
(
p_libvlc
,
"altivec"
)
)
cpu_flags
&=
~
CPU_CAPABILITY_ALTIVEC
;
#endif
#define PRINT_CAPABILITY( capability, string ) \
if( vlc_CPU() & capability ) \
{ \
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_SSE2
,
"SSE2"
);
PRINT_CAPABILITY
(
CPU_CAPABILITY_ALTIVEC
,
"AltiVec"
);
PRINT_CAPABILITY
(
CPU_CAPABILITY_FPU
,
"FPU"
);
msg_Dbg
(
p_libvlc
,
"CPU has capabilities %s"
,
p_capabilities
);
/*
* Choose the best memcpy module
*/
priv
->
p_memcpy_module
=
module_Need
(
p_libvlc
,
"memcpy"
,
"$memcpy"
,
0
);
priv
->
b_stats
=
config_GetInt
(
p_libvlc
,
"stats"
)
>
0
;
priv
->
i_timers
=
0
;
priv
->
pp_timers
=
NULL
;
/* Init stats */
p_libvlc
->
p_stats
=
(
global_stats_t
*
)
malloc
(
sizeof
(
global_stats_t
)
);
if
(
!
p_libvlc
->
p_stats
)
{
vlc_object_release
(
p_libvlc
);
return
VLC_ENOMEM
;
}
vlc_mutex_init
(
&
p_libvlc
->
p_stats
->
lock
);
priv
->
p_stats_computer
=
NULL
;
/* Init the array that holds every input item */
ARRAY_INIT
(
priv
->
input_items
);
priv
->
i_last_input_id
=
0
;
/*
* Initialize hotkey handling
*/
var_Create
(
p_libvlc
,
"key-pressed"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"key-action"
,
VLC_VAR_INTEGER
);
p_libvlc
->
p_hotkeys
=
malloc
(
libvlc_hotkeys_size
);
/* Do a copy (we don't need to modify the strings) */
memcpy
(
p_libvlc
->
p_hotkeys
,
libvlc_hotkeys
,
libvlc_hotkeys_size
);
var_AddCallback
(
p_libvlc
,
"key-pressed"
,
vlc_key_to_action
,
p_libvlc
->
p_hotkeys
);
/* Initialize interaction */
priv
->
p_interaction
=
interaction_Init
(
p_libvlc
);
/* Initialize playlist and get commandline files */
playlist_ThreadCreate
(
p_libvlc
);
if
(
!
priv
->
p_playlist
)
{
msg_Err
(
p_libvlc
,
"playlist initialization failed"
);
if
(
priv
->
p_memcpy_module
!=
NULL
)
{
module_Unneed
(
p_libvlc
,
priv
->
p_memcpy_module
);
}
module_EndBank
(
p_libvlc
);
return
VLC_EGENERIC
;
}
p_playlist
=
priv
->
p_playlist
;
psz_modules
=
config_GetPsz
(
p_playlist
,
"services-discovery"
);
if
(
psz_modules
&&
*
psz_modules
)
{
/* Add service discovery modules */
playlist_ServicesDiscoveryAdd
(
p_playlist
,
psz_modules
);
}
free
(
psz_modules
);
#ifdef ENABLE_SOUT
/* Initialize VLM if vlm-conf is specified */
psz_parser
=
config_GetPsz
(
p_libvlc
,
"vlm-conf"
);
if
(
psz_parser
&&
*
psz_parser
)
{
priv
->
p_vlm
=
vlm_New
(
p_libvlc
);
if
(
!
priv
->
p_vlm
)
msg_Err
(
p_libvlc
,
"VLM initialization failed"
);
}
free
(
psz_parser
);
#endif
/*
* Load background interfaces
*/
psz_modules
=
config_GetPsz
(
p_libvlc
,
"extraintf"
);
psz_control
=
config_GetPsz
(
p_libvlc
,
"control"
);
if
(
psz_modules
&&
*
psz_modules
&&
psz_control
&&
*
psz_control
)
{
psz_modules
=
(
char
*
)
realloc
(
psz_modules
,
strlen
(
psz_modules
)
+
strlen
(
psz_control
)
+
1
);
sprintf
(
psz_modules
,
"%s:%s"
,
psz_modules
,
psz_control
);
}
else
if
(
psz_control
&&
*
psz_control
)
{
free
(
psz_modules
);
psz_modules
=
strdup
(
psz_control
);
}
psz_parser
=
psz_modules
;
while
(
psz_parser
&&
*
psz_parser
)
{
char
*
psz_module
,
*
psz_temp
;
psz_module
=
psz_parser
;
psz_parser
=
strchr
(
psz_module
,
':'
);
if
(
psz_parser
)
{
*
psz_parser
=
'\0'
;
psz_parser
++
;
}
psz_temp
=
(
char
*
)
malloc
(
strlen
(
psz_module
)
+
sizeof
(
",none"
)
);
if
(
psz_temp
)
{
sprintf
(
psz_temp
,
"%s,none"
,
psz_module
);
libvlc_InternalAddIntf
(
p_libvlc
,
psz_temp
,
false
);
free
(
psz_temp
);
}
}
free
(
psz_modules
);
free
(
psz_control
);
/*
* Always load the hotkeys interface if it exists
*/
libvlc_InternalAddIntf
(
p_libvlc
,
"hotkeys,none"
,
false
);
#ifdef HAVE_DBUS_3
/* loads dbus control interface if in one-instance mode
* we do it only when playlist exists, because dbus module needs it */
if
(
config_GetInt
(
p_libvlc
,
"one-instance"
)
>
0
)
libvlc_InternalAddIntf
(
p_libvlc
,
"dbus,none"
,
false
);
/* Prevents the power management daemon from suspending the system
* when VLC is active */
if
(
config_GetInt
(
p_libvlc
,
"inhibit"
)
>
0
)
libvlc_InternalAddIntf
(
p_libvlc
,
"inhibit,none"
,
false
);
#endif
/*
* If needed, load the Xscreensaver interface
* Currently, only for X
*/
#ifdef HAVE_X11_XLIB_H
if
(
config_GetInt
(
p_libvlc
,
"disable-screensaver"
)
)
{
libvlc_InternalAddIntf
(
p_libvlc
,
"screensaver,none"
,
false
);
}
#endif
if
(
config_GetInt
(
p_libvlc
,
"file-logging"
)
>
0
)
{
libvlc_InternalAddIntf
(
p_libvlc
,
"logger,none"
,
false
);
}
#ifdef HAVE_SYSLOG_H
if
(
config_GetInt
(
p_libvlc
,
"syslog"
)
>
0
)
{
char
*
logmode
=
var_CreateGetString
(
p_libvlc
,
"logmode"
);
var_SetString
(
p_libvlc
,
"logmode"
,
"syslog"
);
libvlc_InternalAddIntf
(
p_libvlc
,
"logger,none"
,
false
);
if
(
logmode
)
{
var_SetString
(
p_libvlc
,
"logmode"
,
logmode
);
free
(
logmode
);
}
else
var_Destroy
(
p_libvlc
,
"logmode"
);
}
#endif
if
(
config_GetInt
(
p_libvlc
,
"show-intf"
)
>
0
)
{
libvlc_InternalAddIntf
(
p_libvlc
,
"showintf,none"
,
false
);
}
if
(
config_GetInt
(
p_libvlc
,
"network-synchronisation"
)
>
0
)
{
libvlc_InternalAddIntf
(
p_libvlc
,
"netsync,none"
,
false
);
}
#ifdef WIN32
if
(
config_GetInt
(
p_libvlc
,
"prefer-system-codecs"
)
>
0
)
{
char
*
psz_codecs
=
config_GetPsz
(
p_playlist
,
"codec"
);
if
(
psz_codecs
)
{
char
*
psz_morecodecs
;
asprintf
(
&
psz_morecodecs
,
"%s,dmo,quicktime"
,
psz_codecs
);
if
(
psz_morecodecs
)
{
config_PutPsz
(
p_libvlc
,
"codec"
,
psz_morecodecs
);
free
(
psz_morecodecs
);
}
}
else
config_PutPsz
(
p_libvlc
,
"codec"
,
"dmo,quicktime"
);
free
(
psz_codecs
);
}
#endif
/*
* FIXME: kludge to use a p_libvlc-local variable for the Mozilla plugin
*/
var_Create
(
p_libvlc
,
"drawable"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-view-top"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-view-left"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-view-bottom"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-view-right"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-clip-top"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-clip-left"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-clip-bottom"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-clip-right"
,
VLC_VAR_INTEGER
);
/* Create volume callback system. */
var_Create
(
p_libvlc
,
"volume-change"
,
VLC_VAR_BOOL
);
/*
* Get input filenames given as commandline arguments
*/
GetFilenames
(
p_libvlc
,
i_argc
,
ppsz_argv
);
/*
* Get --open argument
*/
var_Create
(
p_libvlc
,
"open"
,
VLC_VAR_STRING
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_libvlc
,
"open"
,
&
val
);
if
(
val
.
psz_string
!=
NULL
&&
*
val
.
psz_string
)
{
playlist_t
*
p_playlist
=
pl_Yield
(
p_libvlc
);
playlist_AddExt
(
p_playlist
,
val
.
psz_string
,
NULL
,
PLAYLIST_INSERT
,
0
,
-
1
,
NULL
,
0
,
true
,
false
);
pl_Release
(
p_libvlc
);
}
free
(
val
.
psz_string
);
return
VLC_SUCCESS
;
}
/**
* Cleanup a libvlc instance. The instance is not completely deallocated
* \param p_libvlc the instance to clean
*/
int
libvlc_InternalCleanup
(
libvlc_int_t
*
p_libvlc
)
{
intf_thread_t
*
p_intf
=
NULL
;
vout_thread_t
*
p_vout
=
NULL
;
libvlc_priv_t
*
priv
=
libvlc_priv
(
p_libvlc
);
/* Ask the interfaces to stop and destroy them */
msg_Dbg
(
p_libvlc
,
"removing all interfaces"
);
while
(
(
p_intf
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_INTF
,
FIND_CHILD
))
)
{
intf_StopThread
(
p_intf
);
vlc_object_detach
(
p_intf
);
vlc_object_release
(
p_intf
);
/* for intf_Create() */
vlc_object_release
(
p_intf
);
/* for vlc_object_find() */
}
/* Free video outputs */
msg_Dbg
(
p_libvlc
,
"removing all video outputs"
);
while
(
(
p_vout
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_VOUT
,
FIND_CHILD
))
)
{
vlc_object_detach
(
p_vout
);
vlc_object_release
(
p_vout
);
vout_Destroy
(
p_vout
);
}
#ifdef ENABLE_SOUT
playlist_t
*
p_playlist
;
sout_instance_t
*
p_sout
;
p_playlist
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_PLAYLIST
,
FIND_CHILD
);
if
(
p_playlist
)
{
p_sout
=
vlc_object_find
(
p_playlist
,
VLC_OBJECT_SOUT
,
FIND_CHILD
);
if
(
p_sout
)
{
msg_Dbg
(
p_sout
,
"removing kept stream output"
);
vlc_object_detach
(
(
vlc_object_t
*
)
p_sout
);
vlc_object_release
(
(
vlc_object_t
*
)
p_sout
);
sout_DeleteInstance
(
p_sout
);
}
vlc_object_release
(
p_playlist
);
}
/* Destroy VLM if created in libvlc_InternalInit */
if
(
priv
->
p_vlm
)
{
vlm_Delete
(
priv
->
p_vlm
);
}
#endif
/* Free playlist */
msg_Dbg
(
p_libvlc
,
"removing playlist"
);
vlc_object_release
(
priv
->
p_playlist
);
/* Free interaction */
msg_Dbg
(
p_libvlc
,
"removing interaction"
);
vlc_object_release
(
priv
->
p_interaction
);
stats_TimersDumpAll
(
p_libvlc
);
stats_TimersCleanAll
(
p_libvlc
);
#ifdef ENABLE_SOUT
announce_handler_t
*
p_announce
;
/* Free announce handler(s?) */
while
(
(
p_announce
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_ANNOUNCE
,
FIND_CHILD
)
)
)
{
msg_Dbg
(
p_libvlc
,
"removing announce handler"
);
vlc_object_detach
(
p_announce
);
vlc_object_release
(
p_announce
);
announce_HandlerDestroy
(
p_announce
);
}
#endif
bool
b_clean
=
true
;
FOREACH_ARRAY
(
input_item_t
*
p_del
,
priv
->
input_items
)
msg_Err
(
p_libvlc
,
"input item %p has not been deleted properly: refcount %d, name %s"
,
p_del
,
p_del
->
i_gc_refcount
,
p_del
->
psz_name
?
p_del
->
psz_name
:
"(null)"
);
b_clean
=
false
;
FOREACH_END
();
assert
(
b_clean
);
ARRAY_RESET
(
priv
->
input_items
);
msg_Dbg
(
p_libvlc
,
"removing stats"
);
vlc_mutex_destroy
(
&
p_libvlc
->
p_stats
->
lock
);
FREENULL
(
p_libvlc
->
p_stats
);
return
VLC_SUCCESS
;
}
/**
* Destroy everything.
* This function requests the running threads to finish, waits for their
* termination, and destroys their structure.
* It stops the thread systems: no instance can run after this has run
* \param p_libvlc the instance to destroy
* \param b_release whether we should do a release on the instance
*/
int
libvlc_InternalDestroy
(
libvlc_int_t
*
p_libvlc
,
bool
b_release
)
{
if
(
!
p_libvlc
)
return
VLC_EGENERIC
;
libvlc_priv_t
*
priv
=
libvlc_priv
(
p_libvlc
);
#ifndef WIN32
char
*
psz_pidfile
=
NULL
;
if
(
b_daemon
)
{
psz_pidfile
=
config_GetPsz
(
p_libvlc
,
"pidfile"
);
if
(
psz_pidfile
!=
NULL
)
{
msg_Dbg
(
p_libvlc
,
"removing pid file %s"
,
psz_pidfile
);
if
(
unlink
(
psz_pidfile
)
==
-
1
)
{
msg_Dbg
(
p_libvlc
,
"removing pid file %s: %m"
,
psz_pidfile
);
}
}
free
(
psz_pidfile
);
}
#endif
if
(
priv
->
p_memcpy_module
)
{
module_Unneed
(
p_libvlc
,
priv
->
p_memcpy_module
);
priv
->
p_memcpy_module
=
NULL
;
}
/* Free module bank. It is refcounted, so we call this each time */
module_EndBank
(
p_libvlc
);
FREENULL
(
priv
->
psz_configfile
);
var_DelCallback
(
p_libvlc
,
"key-pressed"
,
vlc_key_to_action
,
p_libvlc
->
p_hotkeys
);
FREENULL
(
p_libvlc
->
p_hotkeys
);
vlc_mutex_t
*
lock
=
var_AcquireMutex
(
"libvlc"
);
i_instances
--
;
if
(
i_instances
==
0
)
{
/* System specific cleaning code */
system_End
(
p_libvlc
);
}
vlc_mutex_unlock
(
lock
);
msg_Flush
(
p_libvlc
);
msg_Destroy
(
p_libvlc
);
/* Destroy mutexes */
vlc_mutex_destroy
(
&
priv
->
config_lock
);
vlc_mutex_destroy
(
&
priv
->
timer_lock
);
if
(
b_release
)
vlc_object_release
(
p_libvlc
);
vlc_object_release
(
p_libvlc
);
p_libvlc
=
NULL
;
/* Stop thread system: last one out please shut the door!
* The number of initializations of the thread system is counted, we
* can call this each time */
vlc_threads_end
();
return
VLC_SUCCESS
;
}
/**
* Add an interface plugin and run it
*/
int
libvlc_InternalAddIntf
(
libvlc_int_t
*
p_libvlc
,
char
const
*
psz_module
,
bool
b_play
)
{
int
i_err
;
intf_thread_t
*
p_intf
=
NULL
;
if
(
!
p_libvlc
)
return
VLC_EGENERIC
;
if
(
!
psz_module
)
/* requesting the default interface */
{
char
*
psz_interface
=
config_GetPsz
(
p_libvlc
,
"intf"
);
if
(
!
psz_interface
||
!*
psz_interface
)
/* "intf" has not been set */
{
#ifndef WIN32
if
(
b_daemon
)
/* Daemon mode hack.
* We prefer the dummy interface if none is specified. */
psz_module
=
"dummy"
;
else
#endif
msg_Info
(
p_libvlc
,
_
(
"Running vlc with the default interface. Use 'cvlc' to use vlc without interface."
)
);
}
free
(
psz_interface
);
}
/* Try to create the interface */
p_intf
=
intf_Create
(
p_libvlc
,
psz_module
?
psz_module
:
"$intf"
);
if
(
p_intf
==
NULL
)
{
msg_Err
(
p_libvlc
,
"interface
\"
%s
\"
initialization failed"
,
psz_module
);
return
VLC_EGENERIC
;
}
/* Interface doesn't handle play on start so do it ourselves */
if
(
!
p_intf
->
b_play
&&
b_play
)
playlist_Play
(
libvlc_priv
(
p_libvlc
)
->
p_playlist
);
/* Try to run the interface */
p_intf
->
b_play
=
b_play
;
i_err
=
intf_RunThread
(
p_intf
);
if
(
i_err
)
{
vlc_object_detach
(
p_intf
);
vlc_object_release
(
p_intf
);
return
i_err
;
}
return
VLC_SUCCESS
;
};
#if defined( ENABLE_NLS ) && (defined (__APPLE__) || defined (WIN32)) && \
( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
/*****************************************************************************
* 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
(
const
char
*
psz_lang
)
{
#ifdef __APPLE__
/* I need that under Darwin, please check it doesn't disturb
* other platforms. --Meuuh */
setenv
(
"LANG"
,
psz_lang
,
1
);
#else
/* 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
);
#endif
setlocale
(
LC_ALL
,
psz_lang
);
}
#endif
static
inline
int
LoadMessages
(
void
)
{
#if defined( ENABLE_NLS ) \
&& ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
/* Specify where to find the locales for current domain */
#if !defined( __APPLE__ ) && !defined( WIN32 ) && !defined( SYS_BEOS )
static
const
char
psz_path
[]
=
LOCALEDIR
;
#else
char
psz_path
[
1024
];
if
(
snprintf
(
psz_path
,
sizeof
(
psz_path
),
"%s/%s"
,
vlc_global
()
->
psz_vlcpath
,
"locale"
)
>=
(
int
)
sizeof
(
psz_path
))
return
-
1
;
#endif
if
(
bindtextdomain
(
PACKAGE_NAME
,
psz_path
)
==
NULL
)
{
fprintf
(
stderr
,
"Warning: cannot bind text domain "
PACKAGE_NAME
" to directory %s
\n
"
,
psz_path
);
return
-
1
;
}
/* LibVLC wants all messages in UTF-8.
* Unfortunately, we cannot ask UTF-8 for strerror_r(), strsignal_r()
* and other functions that are not part of our text domain.
*/
if
(
bind_textdomain_codeset
(
PACKAGE_NAME
,
"UTF-8"
)
==
NULL
)
{
fprintf
(
stderr
,
"Error: cannot set Unicode encoding for text domain "
PACKAGE_NAME
"
\n
"
);
// Unbinds the text domain to avoid broken encoding
bindtextdomain
(
PACKAGE_NAME
,
"DOES_NOT_EXIST"
);
return
-
1
;
}
/* LibVLC does NOT set the default textdomain, since it is a library.
* This could otherwise break programs using LibVLC (other than VLC).
* textdomain (PACKAGE_NAME);
*/
#endif
return
0
;
}
/*****************************************************************************
* GetFilenames: parse command line options which are not flags
*****************************************************************************
* Parse command line for input files as well as their associated options.
* An option always follows its associated input and begins with a ":".
*****************************************************************************/
static
int
GetFilenames
(
libvlc_int_t
*
p_vlc
,
int
i_argc
,
const
char
*
ppsz_argv
[]
)
{
int
i_opt
,
i_options
;
/* We assume that the remaining parameters are filenames
* and their input options */
for
(
i_opt
=
i_argc
-
1
;
i_opt
>=
optind
;
i_opt
--
)
{
i_options
=
0
;
/* Count the input options */
while
(
*
ppsz_argv
[
i_opt
]
==
':'
&&
i_opt
>
optind
)
{
i_options
++
;
i_opt
--
;
}
/* TODO: write an internal function of this one, to avoid
* unnecessary lookups. */
playlist_t
*
p_playlist
=
pl_Yield
(
p_vlc
);
playlist_AddExt
(
p_playlist
,
ppsz_argv
[
i_opt
],
NULL
,
PLAYLIST_INSERT
,
0
,
-
1
,
(
i_options
?
&
ppsz_argv
[
i_opt
+
1
]
:
NULL
),
i_options
,
true
,
false
);
pl_Release
(
p_vlc
);
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Help: print program help
*****************************************************************************
* Print a short inline help. Message interface is initialized at this stage.
*****************************************************************************/
static
void
Help
(
libvlc_int_t
*
p_this
,
char
const
*
psz_help_name
)
{
#ifdef WIN32
ShowConsole
(
true
);
#endif
if
(
psz_help_name
&&
!
strcmp
(
psz_help_name
,
"help"
)
)
{
utf8_fprintf
(
stdout
,
vlc_usage
,
p_this
->
psz_object_name
);
Usage
(
p_this
,
"help"
);
Usage
(
p_this
,
"main"
);
}
else
if
(
psz_help_name
&&
!
strcmp
(
psz_help_name
,
"longhelp"
)
)
{
utf8_fprintf
(
stdout
,
vlc_usage
,
p_this
->
psz_object_name
);
Usage
(
p_this
,
NULL
);
}
else
if
(
psz_help_name
)
{
Usage
(
p_this
,
psz_help_name
);
}
#ifdef WIN32
/* Pause the console because it's destroyed when we exit */
PauseConsole
();
#endif
}
/*****************************************************************************
* Usage: print module usage
*****************************************************************************
* Print a short inline help. Message interface is initialized at this stage.
*****************************************************************************/
static
void
Usage
(
libvlc_int_t
*
p_this
,
char
const
*
psz_module_name
)
{
#define FORMAT_STRING " %s --%s%s%s%s%s%s%s "
/* short option ------' | | | | | | |
* option name ------------' | | | | | |
* <bra ---------------------' | | | | |
* option type or "" ----------' | | | |
* ket> -------------------------' | | |
* padding spaces -----------------' | |
* comment --------------------------' |
* comment suffix ---------------------'
*
* The purpose of having bra and ket is that we might i18n them as well.
*/
# define COL(x) "\033[" #x ";1m"
# define RED COL(31)
# define GREEN COL(32)
# define YELLOW COL(33)
# define BLUE COL(34)
# define MAGENTA COL(35)
# define CYAN COL(36)
# define WHITE COL(0)
# define GRAY "\033[0m"
#define COLOR_FORMAT_STRING (WHITE" %s --%s"YELLOW"%s%s%s%s%s%s "GRAY)
#define COLOR_FORMAT_STRING_BOOL (WHITE" %s --%s%s%s%s%s%s%s "GRAY)
#define LINE_START 8
#define PADDING_SPACES 25
#ifdef WIN32
# define OPTION_VALUE_SEP "="
#else
# define OPTION_VALUE_SEP " "
#endif
vlc_list_t
*
p_list
=
NULL
;
char
psz_spaces_text
[
PADDING_SPACES
+
LINE_START
+
1
];
char
psz_spaces_longtext
[
LINE_START
+
3
];
char
psz_format
[
sizeof
(
COLOR_FORMAT_STRING
)];
char
psz_format_bool
[
sizeof
(
COLOR_FORMAT_STRING_BOOL
)];
char
psz_buffer
[
10000
];
char
psz_short
[
4
];
int
i_index
;
int
i_width
=
ConsoleWidth
()
-
(
PADDING_SPACES
+
LINE_START
+
1
);
int
i_width_description
=
i_width
+
PADDING_SPACES
-
1
;
bool
b_advanced
=
config_GetInt
(
p_this
,
"advanced"
)
>
0
;
bool
b_description
=
config_GetInt
(
p_this
,
"help-verbose"
)
>
0
;
bool
b_description_hack
;
bool
b_color
=
config_GetInt
(
p_this
,
"color"
)
>
0
;
bool
b_has_advanced
=
false
;
memset
(
psz_spaces_text
,
' '
,
PADDING_SPACES
+
LINE_START
);
psz_spaces_text
[
PADDING_SPACES
+
LINE_START
]
=
'\0'
;
memset
(
psz_spaces_longtext
,
' '
,
LINE_START
+
2
);
psz_spaces_longtext
[
LINE_START
+
2
]
=
'\0'
;
#ifdef WIN32
b_color
=
false
;
// don't put color control codes in a .txt file
#endif
if
(
b_color
)
{
strcpy
(
psz_format
,
COLOR_FORMAT_STRING
);
strcpy
(
psz_format_bool
,
COLOR_FORMAT_STRING_BOOL
);
}
else
{
strcpy
(
psz_format
,
FORMAT_STRING
);
strcpy
(
psz_format_bool
,
FORMAT_STRING
);
}
/* List all modules */
p_list
=
vlc_list_find
(
p_this
,
VLC_OBJECT_MODULE
,
FIND_ANYWHERE
);
/* Ugly hack to make sure that the help options always come first
* (part 1) */
if
(
!
psz_module_name
)
Usage
(
p_this
,
"help"
);
/* Enumerate the config for each module */
for
(
i_index
=
0
;
i_index
<
p_list
->
i_count
;
i_index
++
)
{
bool
b_help_module
;
module_t
*
p_parser
=
(
module_t
*
)
p_list
->
p_values
[
i_index
].
p_object
;
module_config_t
*
p_item
=
NULL
;
module_config_t
*
p_end
=
p_parser
->
p_config
+
p_parser
->
confsize
;
if
(
psz_module_name
&&
strcmp
(
psz_module_name
,
p_parser
->
psz_object_name
)
)
{
const
char
*
const
*
pp_shortcut
=
p_parser
->
pp_shortcuts
;
while
(
*
pp_shortcut
)
{
if
(
!
strcmp
(
psz_module_name
,
*
pp_shortcut
)
)
break
;
pp_shortcut
++
;
}
if
(
!*
pp_shortcut
)
continue
;
}
/* Ignore modules without config options */
if
(
!
p_parser
->
i_config_items
)
{
continue
;
}
b_help_module
=
!
strcmp
(
"help"
,
p_parser
->
psz_object_name
);
/* Ugly hack to make sure that the help options always come first
* (part 2) */
if
(
!
psz_module_name
&&
b_help_module
)
continue
;
/* Ignore modules with only advanced config options if requested */
if
(
!
b_advanced
)
{
for
(
p_item
=
p_parser
->
p_config
;
p_item
<
p_end
;
p_item
++
)
{
if
(
(
p_item
->
i_type
&
CONFIG_ITEM
)
&&
!
p_item
->
b_advanced
)
break
;
}
}
/* Print name of module */
if
(
strcmp
(
"main"
,
p_parser
->
psz_object_name
)
)
{
if
(
b_color
)
utf8_fprintf
(
stdout
,
"
\n
"
GREEN
"%s"
GRAY
"
\n
"
,
p_parser
->
psz_longname
);
else
utf8_fprintf
(
stdout
,
"
\n
%s
\n
"
,
p_parser
->
psz_longname
);
}
if
(
p_parser
->
psz_help
)
{
if
(
b_color
)
utf8_fprintf
(
stdout
,
CYAN
" %s
\n
"
GRAY
,
p_parser
->
psz_help
);
else
utf8_fprintf
(
stdout
,
" %s
\n
"
,
p_parser
->
psz_help
);
}
/* Print module options */
for
(
p_item
=
p_parser
->
p_config
;
p_item
<
p_end
;
p_item
++
)
{
char
*
psz_text
,
*
psz_spaces
=
psz_spaces_text
;
const
char
*
psz_bra
=
NULL
,
*
psz_type
=
NULL
,
*
psz_ket
=
NULL
;
const
char
*
psz_suf
=
""
,
*
psz_prefix
=
NULL
;
signed
int
i
;
size_t
i_cur_width
;
/* Skip removed options */
if
(
p_item
->
b_removed
)
{
continue
;
}
/* Skip advanced options if requested */
if
(
p_item
->
b_advanced
&&
!
b_advanced
)
{
b_has_advanced
=
true
;
continue
;
}
switch
(
p_item
->
i_type
)
{
case
CONFIG_HINT_CATEGORY
:
case
CONFIG_HINT_USAGE
:
if
(
!
strcmp
(
"main"
,
p_parser
->
psz_object_name
)
)
{
if
(
b_color
)
utf8_fprintf
(
stdout
,
GREEN
"
\n
%s
\n
"
GRAY
,
p_item
->
psz_text
);
else
utf8_fprintf
(
stdout
,
"
\n
%s
\n
"
,
p_item
->
psz_text
);
}
if
(
b_description
&&
p_item
->
psz_longtext
)
{
if
(
b_color
)
utf8_fprintf
(
stdout
,
CYAN
" %s
\n
"
GRAY
,
p_item
->
psz_longtext
);
else
utf8_fprintf
(
stdout
,
" %s
\n
"
,
p_item
->
psz_longtext
);
}
break
;
case
CONFIG_HINT_SUBCATEGORY
:
if
(
strcmp
(
"main"
,
p_parser
->
psz_object_name
)
)
break
;
case
CONFIG_SECTION
:
if
(
b_color
)
{
utf8_fprintf
(
stdout
,
RED
" %s:
\n
"
GRAY
,
p_item
->
psz_text
);
if
(
b_description
&&
p_item
->
psz_longtext
)
utf8_fprintf
(
stdout
,
MAGENTA
" %s
\n
"
GRAY
,
p_item
->
psz_longtext
);
}
else
{
utf8_fprintf
(
stdout
,
" %s:
\n
"
,
p_item
->
psz_text
);
if
(
b_description
&&
p_item
->
psz_longtext
)
utf8_fprintf
(
stdout
,
" %s
\n
"
,
p_item
->
psz_longtext
);
}
break
;
case
CONFIG_ITEM_STRING
:
case
CONFIG_ITEM_FILE
:
case
CONFIG_ITEM_DIRECTORY
:
case
CONFIG_ITEM_MODULE
:
/* We could also have "=<" here */
case
CONFIG_ITEM_MODULE_CAT
:
case
CONFIG_ITEM_MODULE_LIST
:
case
CONFIG_ITEM_MODULE_LIST_CAT
:
case
CONFIG_ITEM_FONT
:
case
CONFIG_ITEM_PASSWORD
:
psz_bra
=
OPTION_VALUE_SEP
"<"
;
psz_type
=
_
(
"string"
);
psz_ket
=
">"
;
if
(
p_item
->
ppsz_list
)
{
psz_bra
=
OPTION_VALUE_SEP
"{"
;
psz_type
=
psz_buffer
;
psz_buffer
[
0
]
=
'\0'
;
for
(
i
=
0
;
p_item
->
ppsz_list
[
i
];
i
++
)
{
if
(
i
)
strcat
(
psz_buffer
,
","
);
strcat
(
psz_buffer
,
p_item
->
ppsz_list
[
i
]
);
}
psz_ket
=
"}"
;
}
break
;
case
CONFIG_ITEM_INTEGER
:
case
CONFIG_ITEM_KEY
:
/* FIXME: do something a bit more clever */
psz_bra
=
OPTION_VALUE_SEP
"<"
;
psz_type
=
_
(
"integer"
);
psz_ket
=
">"
;
if
(
p_item
->
min
.
i
||
p_item
->
max
.
i
)
{
sprintf
(
psz_buffer
,
"%s [%i .. %i]"
,
psz_type
,
p_item
->
min
.
i
,
p_item
->
max
.
i
);
psz_type
=
psz_buffer
;
}
if
(
p_item
->
i_list
)
{
psz_bra
=
OPTION_VALUE_SEP
"{"
;
psz_type
=
psz_buffer
;
psz_buffer
[
0
]
=
'\0'
;
for
(
i
=
0
;
p_item
->
ppsz_list_text
[
i
];
i
++
)
{
if
(
i
)
strcat
(
psz_buffer
,
", "
);
sprintf
(
psz_buffer
+
strlen
(
psz_buffer
),
"%i (%s)"
,
p_item
->
pi_list
[
i
],
p_item
->
ppsz_list_text
[
i
]
);
}
psz_ket
=
"}"
;
}
break
;
case
CONFIG_ITEM_FLOAT
:
psz_bra
=
OPTION_VALUE_SEP
"<"
;
psz_type
=
_
(
"float"
);
psz_ket
=
">"
;
if
(
p_item
->
min
.
f
||
p_item
->
max
.
f
)
{
sprintf
(
psz_buffer
,
"%s [%f .. %f]"
,
psz_type
,
p_item
->
min
.
f
,
p_item
->
max
.
f
);
psz_type
=
psz_buffer
;
}
break
;
case
CONFIG_ITEM_BOOL
:
psz_bra
=
""
;
psz_type
=
""
;
psz_ket
=
""
;
if
(
!
b_help_module
)
{
psz_suf
=
p_item
->
value
.
i
?
_
(
" (default enabled)"
)
:
_
(
" (default disabled)"
);
}
break
;
}
if
(
!
psz_type
)
{
continue
;
}
/* Add short option if any */
if
(
p_item
->
i_short
)
{
sprintf
(
psz_short
,
"-%c,"
,
p_item
->
i_short
);
}
else
{
strcpy
(
psz_short
,
" "
);
}
i
=
PADDING_SPACES
-
strlen
(
p_item
->
psz_name
)
-
strlen
(
psz_bra
)
-
strlen
(
psz_type
)
-
strlen
(
psz_ket
)
-
1
;
if
(
p_item
->
i_type
==
CONFIG_ITEM_BOOL
&&
!
b_help_module
)
{
psz_prefix
=
", --no-"
;
i
-=
strlen
(
p_item
->
psz_name
)
+
strlen
(
psz_prefix
);
}
if
(
i
<
0
)
{
psz_spaces
[
0
]
=
'\n'
;
i
=
0
;
}
else
{
psz_spaces
[
i
]
=
'\0'
;
}
if
(
p_item
->
i_type
==
CONFIG_ITEM_BOOL
&&
!
b_help_module
)
{
utf8_fprintf
(
stdout
,
psz_format_bool
,
psz_short
,
p_item
->
psz_name
,
psz_prefix
,
p_item
->
psz_name
,
psz_bra
,
psz_type
,
psz_ket
,
psz_spaces
);
}
else
{
utf8_fprintf
(
stdout
,
psz_format
,
psz_short
,
p_item
->
psz_name
,
""
,
""
,
psz_bra
,
psz_type
,
psz_ket
,
psz_spaces
);
}
psz_spaces
[
i
]
=
' '
;
/* We wrap the rest of the output */
sprintf
(
psz_buffer
,
"%s%s"
,
p_item
->
psz_text
,
psz_suf
);
b_description_hack
=
b_description
;
description:
psz_text
=
psz_buffer
;
i_cur_width
=
b_description
&&
!
b_description_hack
?
i_width_description
:
i_width
;
while
(
*
psz_text
)
{
char
*
psz_parser
,
*
psz_word
;
size_t
i_end
=
strlen
(
psz_text
);
/* If the remaining text fits in a line, print it. */
if
(
i_end
<=
i_cur_width
)
{
if
(
b_color
)
{
if
(
!
b_description
||
b_description_hack
)
utf8_fprintf
(
stdout
,
BLUE
"%s
\n
"
GRAY
,
psz_text
);
else
utf8_fprintf
(
stdout
,
"%s
\n
"
,
psz_text
);
}
else
{
utf8_fprintf
(
stdout
,
"%s
\n
"
,
psz_text
);
}
break
;
}
/* Otherwise, eat as many words as possible */
psz_parser
=
psz_text
;
do
{
psz_word
=
psz_parser
;
psz_parser
=
strchr
(
psz_word
,
' '
);
/* If no space was found, we reached the end of the text
* block; otherwise, we skip the space we just found. */
psz_parser
=
psz_parser
?
psz_parser
+
1
:
psz_text
+
i_end
;
}
while
(
(
size_t
)(
psz_parser
-
psz_text
)
<=
i_cur_width
);
/* We cut a word in one of these cases:
* - it's the only word in the line and it's too long.
* - we used less than 80% of the width and the word we are
* going to wrap is longer than 40% of the width, and even
* if the word would have fit in the next line. */
if
(
psz_word
==
psz_text
||
(
(
size_t
)(
psz_word
-
psz_text
)
<
80
*
i_cur_width
/
100
&&
(
size_t
)(
psz_parser
-
psz_word
)
>
40
*
i_cur_width
/
100
)
)
{
char
c
=
psz_text
[
i_cur_width
];
psz_text
[
i_cur_width
]
=
'\0'
;
if
(
b_color
)
{
if
(
!
b_description
||
b_description_hack
)
utf8_fprintf
(
stdout
,
BLUE
"%s
\n
%s"
GRAY
,
psz_text
,
psz_spaces
);
else
utf8_fprintf
(
stdout
,
"%s
\n
%s"
,
psz_text
,
psz_spaces
);
}
else
{
utf8_fprintf
(
stdout
,
"%s
\n
%s"
,
psz_text
,
psz_spaces
);
}
psz_text
+=
i_cur_width
;
psz_text
[
0
]
=
c
;
}
else
{
psz_word
[
-
1
]
=
'\0'
;
if
(
b_color
)
{
if
(
!
b_description
||
b_description_hack
)
utf8_fprintf
(
stdout
,
BLUE
"%s
\n
%s"
GRAY
,
psz_text
,
psz_spaces
);
else
utf8_fprintf
(
stdout
,
"%s
\n
%s"
,
psz_text
,
psz_spaces
);
}
else
{
utf8_fprintf
(
stdout
,
"%s
\n
%s"
,
psz_text
,
psz_spaces
);
}
psz_text
=
psz_word
;
}
}
if
(
b_description_hack
&&
p_item
->
psz_longtext
)
{
sprintf
(
psz_buffer
,
"%s%s"
,
p_item
->
psz_longtext
,
psz_suf
);
b_description_hack
=
false
;
psz_spaces
=
psz_spaces_longtext
;
utf8_fprintf
(
stdout
,
"%s"
,
psz_spaces
);
goto
description
;
}
}
}
if
(
b_has_advanced
)
{
if
(
b_color
)
utf8_fprintf
(
stdout
,
"
\n
"
WHITE
"%s"
GRAY
" %s
\n
"
,
_
(
"Note:"
),
_
(
"add --advanced to your command line to see advanced options."
));
else
utf8_fprintf
(
stdout
,
"
\n
%s %s
\n
"
,
_
(
"Note:"
),
_
(
"add --advanced to your command line to see advanced options."
));
}
/* Release the module list */
vlc_list_release
(
p_list
);
}
/*****************************************************************************
* ListModules: list the available modules with their description
*****************************************************************************
* Print a list of all available modules (builtins and plugins) and a short
* description for each one.
*****************************************************************************/
static
void
ListModules
(
libvlc_int_t
*
p_this
,
bool
b_verbose
)
{
vlc_list_t
*
p_list
=
NULL
;
module_t
*
p_parser
=
NULL
;
char
psz_spaces
[
22
];
int
i_index
;
bool
b_color
=
config_GetInt
(
p_this
,
"color"
)
>
0
;
memset
(
psz_spaces
,
' '
,
22
);
#ifdef WIN32
ShowConsole
(
true
);
#endif
/* List all modules */
p_list
=
vlc_list_find
(
p_this
,
VLC_OBJECT_MODULE
,
FIND_ANYWHERE
);
/* Enumerate each module */
for
(
i_index
=
0
;
i_index
<
p_list
->
i_count
;
i_index
++
)
{
int
i
;
p_parser
=
(
module_t
*
)
p_list
->
p_values
[
i_index
].
p_object
;
/* Nasty hack, but right now I'm too tired to think about a nice
* solution */
i
=
22
-
strlen
(
p_parser
->
psz_object_name
)
-
1
;
if
(
i
<
0
)
i
=
0
;
psz_spaces
[
i
]
=
0
;
if
(
b_color
)
utf8_fprintf
(
stdout
,
GREEN
" %s%s "
WHITE
"%s
\n
"
GRAY
,
p_parser
->
psz_object_name
,
psz_spaces
,
p_parser
->
psz_longname
);
else
utf8_fprintf
(
stdout
,
" %s%s %s
\n
"
,
p_parser
->
psz_object_name
,
psz_spaces
,
p_parser
->
psz_longname
);
if
(
b_verbose
)
{
const
char
*
const
*
pp_shortcut
=
p_parser
->
pp_shortcuts
;
while
(
*
pp_shortcut
)
{
if
(
strcmp
(
*
pp_shortcut
,
p_parser
->
psz_object_name
)
)
{
if
(
b_color
)
utf8_fprintf
(
stdout
,
CYAN
" s %s
\n
"
GRAY
,
*
pp_shortcut
);
else
utf8_fprintf
(
stdout
,
" s %s
\n
"
,
*
pp_shortcut
);
}
pp_shortcut
++
;
}
if
(
p_parser
->
psz_capability
)
{
if
(
b_color
)
utf8_fprintf
(
stdout
,
MAGENTA
" c %s (%d)
\n
"
GRAY
,
p_parser
->
psz_capability
,
p_parser
->
i_score
);
else
utf8_fprintf
(
stdout
,
" c %s (%d)
\n
"
,
p_parser
->
psz_capability
,
p_parser
->
i_score
);
}
}
psz_spaces
[
i
]
=
' '
;
}
vlc_list_release
(
p_list
);
#ifdef WIN32
/* Pause the console because it's destroyed when we exit */
PauseConsole
();
#endif
}
/*****************************************************************************
* Version: print complete program version
*****************************************************************************
* Print complete program version and build number.
*****************************************************************************/
static
void
Version
(
void
)
{
#ifdef WIN32
ShowConsole
(
true
);
#endif
utf8_fprintf
(
stdout
,
_
(
"VLC version %s
\n
"
),
VLC_Version
()
);
utf8_fprintf
(
stdout
,
_
(
"Compiled by %s@%s.%s
\n
"
),
VLC_CompileBy
(),
VLC_CompileHost
(),
VLC_CompileDomain
()
);
utf8_fprintf
(
stdout
,
_
(
"Compiler: %s
\n
"
),
VLC_Compiler
()
);
if
(
strcmp
(
VLC_Changeset
(),
"exported"
)
)
utf8_fprintf
(
stdout
,
_
(
"Based upon Git commit [%s]
\n
"
),
VLC_Changeset
()
);
utf8_fprintf
(
stdout
,
LICENSE_MSG
);
#ifdef WIN32
/* Pause the console because it's destroyed when we exit */
PauseConsole
();
#endif
}
/*****************************************************************************
* ShowConsole: On Win32, create an output console for debug messages
*****************************************************************************
* This function is useful only on Win32.
*****************************************************************************/
#ifdef WIN32
/* */
static
void
ShowConsole
(
bool
b_dofile
)
{
# ifndef UNDER_CE
FILE
*
f_help
=
NULL
;
if
(
getenv
(
"PWD"
)
&&
getenv
(
"PS1"
)
)
return
;
/* cygwin shell */
AllocConsole
();
/* Use the ANSI code page (e.g. Windows-1252) as expected by the LibVLC
* Unicode/locale subsystem. By default, we have the obsolecent OEM code
* page (e.g. CP437 or CP850). */
SetConsoleOutputCP
(
GetACP
());
SetConsoleTitle
(
"VLC media player version "
PACKAGE_VERSION
);
freopen
(
"CONOUT$"
,
"w"
,
stderr
);
freopen
(
"CONIN$"
,
"r"
,
stdin
);
if
(
b_dofile
&&
(
f_help
=
fopen
(
"vlc-help.txt"
,
"wt"
))
)
{
fclose
(
f_help
);
freopen
(
"vlc-help.txt"
,
"wt"
,
stdout
);
utf8_fprintf
(
stderr
,
_
(
"
\n
Dumped content to vlc-help.txt file.
\n
"
)
);
}
else
freopen
(
"CONOUT$"
,
"w"
,
stdout
);
# endif
}
#endif
/*****************************************************************************
* PauseConsole: On Win32, wait for a key press before closing the console
*****************************************************************************
* This function is useful only on Win32.
*****************************************************************************/
#ifdef WIN32
/* */
static
void
PauseConsole
(
void
)
{
# ifndef UNDER_CE
if
(
getenv
(
"PWD"
)
&&
getenv
(
"PS1"
)
)
return
;
/* cygwin shell */
utf8_fprintf
(
stderr
,
_
(
"
\n
Press the RETURN key to continue...
\n
"
)
);
getchar
();
fclose
(
stdout
);
# endif
}
#endif
/*****************************************************************************
* ConsoleWidth: Return the console width in characters
*****************************************************************************
* We use the stty shell command to get the console width; if this fails or
* if the width is less than 80, we default to 80.
*****************************************************************************/
static
int
ConsoleWidth
(
void
)
{
unsigned
i_width
=
80
;
#ifndef WIN32
FILE
*
file
=
popen
(
"stty size 2>/dev/null"
,
"r"
);
if
(
file
!=
NULL
)
{
if
(
fscanf
(
file
,
"%*u %u"
,
&
i_width
)
<=
0
)
i_width
=
80
;
pclose
(
file
);
}
#else
CONSOLE_SCREEN_BUFFER_INFO
buf
;
if
(
GetConsoleScreenBufferInfo
(
GetStdHandle
(
STD_OUTPUT_HANDLE
),
&
buf
))
i_width
=
buf
.
dwSize
.
X
;
#endif
return
i_width
;
}
static
int
VerboseCallback
(
vlc_object_t
*
p_this
,
const
char
*
psz_variable
,
vlc_value_t
old_val
,
vlc_value_t
new_val
,
void
*
param
)
{
libvlc_int_t
*
p_libvlc
=
(
libvlc_int_t
*
)
p_this
;
(
void
)
psz_variable
;
(
void
)
old_val
;
(
void
)
param
;
if
(
new_val
.
i_int
>=
-
1
)
{
libvlc_priv
(
p_libvlc
)
->
i_verbose
=
__MIN
(
new_val
.
i_int
,
2
);
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* InitDeviceValues: initialize device values
*****************************************************************************
* This function inits the dvd, vcd and cd-audio values
*****************************************************************************/
static
void
InitDeviceValues
(
libvlc_int_t
*
p_vlc
)
{
#ifdef HAVE_HAL
LibHalContext
*
ctx
=
NULL
;
int
i
,
i_devices
;
char
**
devices
=
NULL
;
char
*
block_dev
=
NULL
;
dbus_bool_t
b_dvd
;
#ifdef HAVE_HAL_1
DBusConnection
*
p_connection
=
NULL
;
DBusError
error
;
ctx
=
libhal_ctx_new
();
if
(
!
ctx
)
return
;
dbus_error_init
(
&
error
);
p_connection
=
dbus_bus_get
(
DBUS_BUS_SYSTEM
,
&
error
);
if
(
dbus_error_is_set
(
&
error
)
||
!
p_connection
)
{
libhal_ctx_free
(
ctx
);
dbus_error_free
(
&
error
);
return
;
}
libhal_ctx_set_dbus_connection
(
ctx
,
p_connection
);
if
(
libhal_ctx_init
(
ctx
,
&
error
)
)
#else
ctx
=
hal_initialize
(
NULL
,
FALSE
);
if
(
ctx
)
#endif
{
#ifdef HAVE_HAL_1
if
(
(
devices
=
libhal_get_all_devices
(
ctx
,
&
i_devices
,
NULL
)
)
)
#else
if
(
(
devices
=
hal_get_all_devices
(
ctx
,
&
i_devices
)
)
)
#endif
{
for
(
i
=
0
;
i
<
i_devices
;
i
++
)
{
#ifdef HAVE_HAL_1
if
(
!
libhal_device_property_exists
(
ctx
,
devices
[
i
],
"storage.cdrom.dvd"
,
NULL
)
)
#else
if
(
!
hal_device_property_exists
(
ctx
,
devices
[
i
],
"storage.cdrom.dvd"
)
)
#endif
{
continue
;
}
#ifdef HAVE_HAL_1
b_dvd
=
libhal_device_get_property_bool
(
ctx
,
devices
[
i
],
"storage.cdrom.dvd"
,
NULL
);
block_dev
=
libhal_device_get_property_string
(
ctx
,
devices
[
i
],
"block.device"
,
NULL
);
#else
b_dvd
=
hal_device_get_property_bool
(
ctx
,
devices
[
i
],
"storage.cdrom.dvd"
);
block_dev
=
hal_device_get_property_string
(
ctx
,
devices
[
i
],
"block.device"
);
#endif
if
(
b_dvd
)
{
config_PutPsz
(
p_vlc
,
"dvd"
,
block_dev
);
}
config_PutPsz
(
p_vlc
,
"vcd"
,
block_dev
);
config_PutPsz
(
p_vlc
,
"cd-audio"
,
block_dev
);
#ifdef HAVE_HAL_1
libhal_free_string
(
block_dev
);
#else
hal_free_string
(
block_dev
);
#endif
}
#ifdef HAVE_HAL_1
libhal_free_string_array
(
devices
);
#else
hal_free_string_array
(
devices
);
#endif
}
#ifdef HAVE_HAL_1
libhal_ctx_shutdown
(
ctx
,
NULL
);
dbus_connection_unref
(
p_connection
);
libhal_ctx_free
(
ctx
);
#else
hal_shutdown
(
ctx
);
#endif
}
else
{
msg_Warn
(
p_vlc
,
"Unable to get HAL device properties"
);
}
#else
(
void
)
p_vlc
;
#endif
/* HAVE_HAL */
}
src/libvlc.c
View file @
13a1c6b8
/*****************************************************************************
* libvlc.c:
Implementation of the old libvlc API
* libvlc.c:
libvlc instances creation and deletion, interfaces handling
*****************************************************************************
* Copyright (C) 1998-200
7
the VideoLAN team
* Copyright (C) 1998-200
8
the VideoLAN team
* $Id$
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
...
...
@@ -25,12 +25,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Pretend we are a builtin module
*****************************************************************************/
#define MODULE_NAME main
#define MODULE_PATH main
#define __BUILTIN__
/** \file
* This file contains functions to create and destroy libvlc instances
*/
/*****************************************************************************
* Preamble
...
...
@@ -40,633 +37,2027 @@
#endif
#include <vlc_common.h>
#include "control/libvlc_internal.h"
#include "libvlc.h"
#include <vlc_playlist.h>
#include <vlc_aout.h>
#include <vlc_vout.h>
#include <vlc_input.h>
#define LIBVLC_FUNC \
libvlc_int_t * p_libvlc = vlc_current_object( i_object ); \
if( !p_libvlc ) return VLC_ENOOBJ;
#define LIBVLC_FUNC_END \
if( i_object ) vlc_object_release( p_libvlc );
#include "modules/modules.h"
#include "config/configuration.h"
#include "interface/interface.h"
#include <errno.h>
/* ENOMEM */
#include <stdio.h>
/* sprintf() */
#include <string.h>
#include <stdlib.h>
/* free() */
/*****************************************************************************
* VLC_VariableSet: set a "safe" vlc variable
*****************************************************************************/
int
VLC_VariableSet
(
int
i_object
,
char
const
*
psz_var
,
vlc_value_t
value
)
{
int
i_ret
;
LIBVLC_FUNC
;
#ifndef WIN32
# include <netinet/in.h>
/* BSD: struct in_addr */
#endif
/* 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
)
)
{
module_config_t
*
p_item
;
char
const
*
psz_newvar
=
psz_var
+
6
;
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#elif defined( WIN32 ) && !defined( UNDER_CE )
# include <io.h>
#endif
p_item
=
config_FindConfig
(
VLC_OBJECT
(
p_libvlc
),
psz_newvar
);
#ifdef WIN32
/* optind, getopt(), included in unistd.h */
# include "extras/getopt.h"
#endif
if
(
p_item
)
{
/* VLC_VariableSet is only used from the browser plugins, so we
* can pretty much assume that the input is _not_ trusted. */
if
(
!
p_item
->
b_safe
)
return
VLC_EGENERIC
;
#ifdef HAVE_LOCALE_H
# include <locale.h>
#endif
switch
(
p_item
->
i_type
)
{
case
CONFIG_ITEM_BOOL
:
config_PutInt
(
p_libvlc
,
psz_newvar
,
value
.
b_bool
);
break
;
case
CONFIG_ITEM_INTEGER
:
config_PutInt
(
p_libvlc
,
psz_newvar
,
value
.
i_int
);
break
;
case
CONFIG_ITEM_FLOAT
:
config_PutFloat
(
p_libvlc
,
psz_newvar
,
value
.
f_float
);
break
;
default:
config_PutPsz
(
p_libvlc
,
psz_newvar
,
value
.
psz_string
);
break
;
}
if
(
i_object
)
vlc_object_release
(
p_libvlc
);
return
VLC_SUCCESS
;
}
}
/* EXPLICIT HACK (this is the legacy API anyway):
* VLC_VariableSet is only used from the browser plugins, so we
* can pretty much assume that the input is _not_ trusted. */
module_config_t
*
p_item
;
p_item
=
config_FindConfig
(
VLC_OBJECT
(
p_libvlc
),
psz_var
);
if
(
!
p_item
)
return
VLC_ENOVAR
;
if
(
!
p_item
->
b_safe
)
return
VLC_EGENERIC
;
#ifdef HAVE_DBUS_3
/* used for one-instance mode */
# include <dbus/dbus.h>
#endif
i_ret
=
var_Set
(
p_libvlc
,
psz_var
,
value
);
#ifdef HAVE_HAL
# include <hal/libhal.h>
#endif
LIBVLC_FUNC_END
;
return
i_ret
;
}
#include <vlc_playlist.h>
#include <vlc_interface.h>
/*****************************************************************************
* VLC_VariableGet: get a vlc variable
*****************************************************************************/
int
VLC_VariableGet
(
int
i_object
,
char
const
*
psz_var
,
vlc_value_t
*
p_value
)
{
int
i_ret
;
LIBVLC_FUNC
;
i_ret
=
var_Get
(
p_libvlc
,
psz_var
,
p_value
);
LIBVLC_FUNC_END
;
return
i_ret
;
}
#include <vlc_aout.h>
#include "audio_output/aout_internal.h"
/*****************************************************************************
* VLC_VariableType: get a vlc variable type
*****************************************************************************/
int
VLC_VariableType
(
int
i_object
,
char
const
*
psz_var
,
int
*
pi_type
)
{
int
i_type
;
LIBVLC_FUNC
;
/* 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
)
)
{
module_config_t
*
p_item
;
char
const
*
psz_newvar
=
psz_var
+
6
;
#include <vlc_vout.h>
p_item
=
config_FindConfig
(
VLC_OBJECT
(
p_libvlc
),
psz_newvar
);
#include <vlc_sout.h>
#include "stream_output/stream_output.h"
if
(
p_item
)
{
switch
(
p_item
->
i_type
)
{
case
CONFIG_ITEM_BOOL
:
i_type
=
VLC_VAR_BOOL
;
break
;
case
CONFIG_ITEM_INTEGER
:
i_type
=
VLC_VAR_INTEGER
;
break
;
case
CONFIG_ITEM_FLOAT
:
i_type
=
VLC_VAR_FLOAT
;
break
;
default:
i_type
=
VLC_VAR_STRING
;
break
;
}
}
else
i_type
=
0
;
}
else
i_type
=
VLC_VAR_TYPE
&
var_Type
(
p_libvlc
,
psz_var
);
#include <vlc_charset.h>
LIBVLC_FUNC_END
;
#include "libvlc.h"
if
(
i_type
>
0
)
{
*
pi_type
=
i_type
;
return
VLC_SUCCESS
;
}
return
VLC_ENOVAR
;
}
#include "playlist/playlist_internal.h"
#define LIBVLC_PLAYLIST_FUNC \
libvlc_int_t *p_libvlc = vlc_current_object( i_object );\
if( !p_libvlc ) return VLC_ENOOBJ; \
playlist_t *p_playlist = pl_Yield( p_libvlc ); \
if( !p_playlist ) return VLC_ENOOBJ
#include <vlc_vlm.h>
#define LIBVLC_PLAYLIST_FUNC_END \
pl_Release( p_libvlc ); \
if( i_object ) vlc_object_release( p_libvlc );
#include <assert.h>
/*****************************************************************************
* VLC_AddTarget: adds a target for playing.
*****************************************************************************
* This function adds psz_target to the playlist
* The evil global variables. We handle them with care, don't worry.
*****************************************************************************/
static
libvlc_int_t
*
p_static_vlc
=
NULL
;
static
unsigned
i_instances
=
0
;
int
VLC_AddTarget
(
int
i_object
,
char
const
*
psz_target
,
char
const
**
ppsz_options
,
int
i_options
,
int
i_mode
,
int
i_pos
)
{
int
i_err
;
LIBVLC_PLAYLIST_FUNC
;
i_err
=
playlist_AddExt
(
p_playlist
,
psz_target
,
NULL
,
i_mode
,
i_pos
,
-
1
,
ppsz_options
,
i_options
,
true
,
false
);
LIBVLC_PLAYLIST_FUNC_END
;
return
i_err
;
}
static
bool
b_daemon
=
false
;
/*****************************************************************************
*
VLC_Play: play the playlist
*
Local prototypes
*****************************************************************************/
int
VLC_Play
(
int
i_object
)
{
LIBVLC_PLAYLIST_FUNC
;
playlist_Play
(
p_playlist
);
LIBVLC_PLAYLIST_FUNC_END
;
return
VLC_SUCCESS
;
}
#if defined( ENABLE_NLS ) && (defined (__APPLE__) || defined (WIN32)) && \
( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
static
void
SetLanguage
(
char
const
*
);
#endif
static
inline
int
LoadMessages
(
void
);
static
int
GetFilenames
(
libvlc_int_t
*
,
int
,
const
char
*
[]
);
static
void
Help
(
libvlc_int_t
*
,
char
const
*
psz_help_name
);
static
void
Usage
(
libvlc_int_t
*
,
char
const
*
psz_module_name
);
static
void
ListModules
(
libvlc_int_t
*
,
bool
);
static
void
Version
(
void
);
#ifdef WIN32
static
void
ShowConsole
(
bool
);
static
void
PauseConsole
(
void
);
#endif
static
int
ConsoleWidth
(
void
);
/*****************************************************************************
* VLC_Pause: toggle pause
*****************************************************************************/
int
VLC_Pause
(
int
i_object
)
{
LIBVLC_PLAYLIST_FUNC
;
playlist_Pause
(
p_playlist
);
LIBVLC_PLAYLIST_FUNC_END
;
return
VLC_SUCCESS
;
}
static
int
VerboseCallback
(
vlc_object_t
*
,
char
const
*
,
vlc_value_t
,
vlc_value_t
,
void
*
);
static
void
InitDeviceValues
(
libvlc_int_t
*
);
/*****************************************************************************
* VLC_Stop: stop playback
* 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.
*****************************************************************************/
int
VLC_Stop
(
int
i_object
)
libvlc_int_t
*
vlc_current_object
(
int
i_object
)
{
LIBVLC_PLAYLIST_FUNC
;
playlist_Stop
(
p_playlist
);
LIBVLC_PLAYLIST_FUNC_END
;
return
VLC_SUCCESS
;
return
i_object
?
vlc_object_get
(
i_object
)
:
p_static_vlc
;
}
/*****************************************************************************
* VLC_IsPlaying: Query for Playlist Status
*****************************************************************************/
bool
VLC_IsPlaying
(
int
i_object
)
{
bool
b_playing
;
LIBVLC_PLAYLIST_FUNC
;
if
(
p_playlist
->
p_input
)
/**
* Allocate a libvlc instance, initialize global data if needed
* It also initializes the threading system
*/
libvlc_int_t
*
libvlc_InternalCreate
(
void
)
{
libvlc_int_t
*
p_libvlc
;
libvlc_priv_t
*
priv
;
char
*
psz_env
=
NULL
;
/* vlc_threads_init *must* be the first internal call! No other call is
* allowed before the thread system has been initialized. */
if
(
vlc_threads_init
())
return
NULL
;
libvlc_global_data_t
*
p_libvlc_global
=
vlc_global
();
/* Now that the thread system is initialized, we don't have much, but
* at least we have variables */
vlc_mutex_t
*
lock
=
var_AcquireMutex
(
"libvlc"
);
if
(
i_instances
==
0
)
{
vlc_value_t
val
;
var_Get
(
p_playlist
->
p_input
,
"state"
,
&
val
);
b_playing
=
(
val
.
i_int
==
PLAYING_S
);
/* Guess what CPU we have */
cpu_flags
=
CPUCapabilities
();
/* The module bank will be initialized later */
p_libvlc_global
->
p_module_bank
=
NULL
;
}
/* Allocate a libvlc instance object */
p_libvlc
=
vlc_custom_create
(
VLC_OBJECT
(
p_libvlc_global
),
sizeof
(
*
p_libvlc
)
+
sizeof
(
libvlc_priv_t
),
VLC_OBJECT_LIBVLC
,
"libvlc"
);
if
(
p_libvlc
!=
NULL
)
i_instances
++
;
vlc_mutex_unlock
(
lock
);
if
(
p_libvlc
==
NULL
)
return
NULL
;
priv
=
libvlc_priv
(
p_libvlc
);
priv
->
p_playlist
=
NULL
;
priv
->
p_interaction
=
NULL
;
priv
->
p_vlm
=
NULL
;
p_libvlc
->
psz_object_name
=
strdup
(
"libvlc"
);
/* Initialize message queue */
msg_Create
(
p_libvlc
);
/* Find verbosity from VLC_VERBOSE environment variable */
psz_env
=
getenv
(
"VLC_VERBOSE"
);
if
(
psz_env
!=
NULL
)
priv
->
i_verbose
=
atoi
(
psz_env
);
else
{
b_playing
=
playlist_IsPlaying
(
p_playlist
);
}
LIBVLC_PLAYLIST_FUNC_END
;
return
b_playing
;
priv
->
i_verbose
=
3
;
#if defined( HAVE_ISATTY ) && !defined( WIN32 )
priv
->
b_color
=
isatty
(
2
);
/* 2 is for stderr */
#else
priv
->
b_color
=
false
;
#endif
/* Announce who we are - Do it only for first instance ? */
msg_Dbg
(
p_libvlc
,
COPYRIGHT_MESSAGE
);
msg_Dbg
(
p_libvlc
,
"libvlc was configured with %s"
,
CONFIGURE_LINE
);
/* Initialize mutexes */
vlc_mutex_init
(
&
priv
->
timer_lock
);
vlc_mutex_init
(
&
priv
->
config_lock
);
/* Store data for the non-reentrant API */
p_static_vlc
=
p_libvlc
;
return
p_libvlc
;
}
/**
* Get the current position in a input
*
* Return the current position as a float
* \note For some inputs, this will be unknown.
*
* \param i_object a vlc object id
* \return a float in the range of 0.0 - 1.0
* Initialize a libvlc instance
* This function initializes a previously allocated libvlc instance:
* - CPU detection
* - gettext initialization
* - message queue, module bank and playlist initialization
* - configuration and commandline parsing
*/
float
VLC_PositionGet
(
int
i_object
)
int
libvlc_InternalInit
(
libvlc_int_t
*
p_libvlc
,
int
i_argc
,
const
char
*
ppsz_argv
[]
)
{
input_thread_t
*
p_input
;
libvlc_global_data_t
*
p_libvlc_global
=
vlc_global
();
libvlc_priv_t
*
priv
=
libvlc_priv
(
p_libvlc
);
char
p_capabilities
[
200
];
char
*
p_tmp
=
NULL
;
char
*
psz_modules
=
NULL
;
char
*
psz_parser
=
NULL
;
char
*
psz_control
=
NULL
;
bool
b_exit
=
false
;
int
i_ret
=
VLC_EEXIT
;
playlist_t
*
p_playlist
=
NULL
;
vlc_value_t
val
;
LIBVLC_FUNC
;
#if defined( ENABLE_NLS ) \
&& ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
# if defined (WIN32) || defined (__APPLE__)
char
*
psz_language
;
#endif
#endif
p_input
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_INPUT
,
FIND_CHILD
);
/* System specific initialization code */
system_Init
(
p_libvlc
,
&
i_argc
,
ppsz_argv
);
if
(
!
p_input
)
/* Get the executable name (similar to the basename command) */
if
(
i_argc
>
0
&&
ppsz_argv
[
0
][
0
]
)
{
if
(
i_object
)
vlc_object_release
(
p_libvlc
);
return
VLC_ENOOBJ
;
free
(
p_libvlc
->
psz_object_name
);
const
char
*
psz_exe
=
strrchr
(
ppsz_argv
[
0
],
'/'
);
if
(
psz_exe
&&
*
(
psz_exe
+
1
)
)
p_libvlc
->
psz_object_name
=
strdup
(
psz_exe
+
1
);
else
p_libvlc
->
psz_object_name
=
strdup
(
ppsz_argv
[
0
]
);
}
var_Get
(
p_input
,
"position"
,
&
val
);
vlc_object_release
(
p_input
);
/*
* Support for gettext
*/
LoadMessages
();
LIBVLC_FUNC_END
;
return
val
.
f_float
;
}
/* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
msg_Dbg
(
p_libvlc
,
"translation test: code is
\"
%s
\"
"
,
_
(
"C"
)
);
/**
* Set the current position in a input
*
* Set the current position in a input and then return
* the current position as a float.
* \note For some inputs, this will be unknown.
*
* \param i_object a vlc object id
* \param i_position a float in the range of 0.0 - 1.0
* \return a float in the range of 0.0 - 1.0
*/
float
VLC_PositionSet
(
int
i_object
,
float
i_position
)
{
input_thread_t
*
p_input
;
vlc_value_t
val
;
libvlc_int_t
*
p_libvlc
=
vlc_current_object
(
i_object
);
/* 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) */
module_InitBank
(
p_libvlc
);
/* Check that the handle is valid */
if
(
!
p_libvlc
)
if
(
config_LoadCmdLine
(
p_libvlc
,
&
i_argc
,
ppsz_argv
,
true
)
)
{
return
VLC_ENOOBJ
;
module_EndBank
(
p_libvlc
);
return
VLC_EGENERIC
;
}
p_input
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_INPUT
,
FIND_CHILD
);
#ifdef __APPLE__
/* vlc_thread_set_priority needs to query the config,
* so this is the earliest moment where we can set this */
vlc_thread_set_priority
(
p_libvlc
,
VLC_THREAD_PRIORITY_LOW
);
#endif
if
(
!
p_input
)
/* Check for short help option */
if
(
config_GetInt
(
p_libvlc
,
"help"
)
>
0
)
{
if
(
i_object
)
vlc_object_release
(
p_libvlc
);
return
VLC_ENOOBJ
;
Help
(
p_libvlc
,
"help"
);
b_exit
=
true
;
i_ret
=
VLC_EEXITSUCCESS
;
}
/* Check for version option */
else
if
(
config_GetInt
(
p_libvlc
,
"version"
)
>
0
)
{
Version
();
b_exit
=
true
;
i_ret
=
VLC_EEXITSUCCESS
;
}
val
.
f_float
=
i_position
;
var_Set
(
p_input
,
"position"
,
val
);
var_Get
(
p_input
,
"position"
,
&
val
);
vlc_object_release
(
p_input
);
/* Set the config file stuff */
priv
->
psz_configfile
=
config_GetCustomConfigFile
(
p_libvlc
);
if
(
i_object
)
vlc_object_release
(
p_libvlc
);
return
val
.
f_float
;
}
/* Check for plugins cache options */
if
(
config_GetInt
(
p_libvlc
,
"reset-plugins-cache"
)
>
0
)
{
p_libvlc_global
->
p_module_bank
->
b_cache_delete
=
true
;
}
/**
* Get the current position in a input
*
* Return the current position in seconds from the start.
* \note For some inputs, this will be unknown.
*
* \param i_object a vlc object id
* \return the offset from 0:00 in seconds
*/
int
VLC_TimeGet
(
int
i_object
)
{
input_thread_t
*
p_input
;
vlc_value_t
val
;
libvlc_int_t
*
p_libvlc
=
vlc_current_object
(
i_object
);
/* Will be re-done properly later on */
priv
->
i_verbose
=
config_GetInt
(
p_libvlc
,
"verbose"
);
/* Check that the handle is valid */
if
(
!
p_libvlc
)
/* Check for daemon mode */
#ifndef WIN32
if
(
config_GetInt
(
p_libvlc
,
"daemon"
)
>
0
)
{
#ifdef HAVE_DAEMON
char
*
psz_pidfile
=
NULL
;
if
(
daemon
(
1
,
0
)
!=
0
)
{
msg_Err
(
p_libvlc
,
"Unable to fork vlc to daemon mode"
);
b_exit
=
true
;
}
b_daemon
=
true
;
/* lets check if we need to write the pidfile */
psz_pidfile
=
config_GetPsz
(
p_libvlc
,
"pidfile"
);
if
(
psz_pidfile
!=
NULL
)
{
FILE
*
pidfile
;
pid_t
i_pid
=
getpid
();
msg_Dbg
(
p_libvlc
,
"PID is %d, writing it to %s"
,
i_pid
,
psz_pidfile
);
pidfile
=
utf8_fopen
(
psz_pidfile
,
"w"
);
if
(
pidfile
!=
NULL
)
{
utf8_fprintf
(
pidfile
,
"%d"
,
(
int
)
i_pid
);
fclose
(
pidfile
);
}
else
{
return
VLC_ENOOBJ
;
msg_Err
(
p_libvlc
,
"cannot open pid file for writing: %s (%m)"
,
psz_pidfile
);
}
}
free
(
psz_pidfile
);
p_input
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_INPUT
,
FIND_CHILD
);
#else
pid_t
i_pid
;
if
(
!
p_input
)
if
(
(
i_pid
=
fork
()
)
<
0
)
{
msg_Err
(
p_libvlc
,
"unable to fork vlc to daemon mode"
);
b_exit
=
true
;
}
else
if
(
i_pid
)
{
if
(
i_object
)
vlc_object_release
(
p_libvlc
);
return
VLC_ENOOBJ
;
/* This is the parent, exit right now */
msg_Dbg
(
p_libvlc
,
"closing parent process"
);
b_exit
=
true
;
i_ret
=
VLC_EEXITSUCCESS
;
}
else
{
/* We are the child */
msg_Dbg
(
p_libvlc
,
"daemon spawned"
);
close
(
STDIN_FILENO
);
close
(
STDOUT_FILENO
);
close
(
STDERR_FILENO
);
var_Get
(
p_input
,
"time"
,
&
val
);
vlc_object_release
(
p_input
);
b_daemon
=
true
;
}
#endif
}
#endif
if
(
i_object
)
vlc_object_release
(
p_libvlc
);
return
val
.
i_time
/
1000000
;
}
if
(
b_exit
)
{
module_EndBank
(
p_libvlc
);
return
i_ret
;
}
/**
* Seek to a position in the current input
*
* Seek i_seconds in the current input. If b_relative is set,
* then the seek will be relative to the current position, otherwise
* it will seek to i_seconds from the beginning of the input.
* \note For some inputs, this will be unknown.
*
* \param i_object a vlc object id
* \param i_seconds seconds from current position or from beginning of input
* \param b_relative seek relative from current position
* \return VLC_SUCCESS on success
*/
int
VLC_TimeSet
(
int
i_object
,
int
i_seconds
,
bool
b_relative
)
{
input_thread_t
*
p_input
;
vlc_value_t
val
;
libvlc_int_t
*
p_libvlc
=
vlc_current_object
(
i_object
);
/* Check for translation config option */
#if defined( ENABLE_NLS ) \
&& ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
# if defined (WIN32) || defined (__APPLE__)
/* This ain't really nice to have to reload the config here but it seems
* the only way to do it. */
/* Check that the handle is valid */
if
(
!
p_libvlc
)
if
(
!
config_GetInt
(
p_libvlc
,
"ignore-config"
)
)
config_LoadConfigFile
(
p_libvlc
,
"main"
);
config_LoadCmdLine
(
p_libvlc
,
&
i_argc
,
ppsz_argv
,
true
);
/* Check if the user specified a custom language */
psz_language
=
config_GetPsz
(
p_libvlc
,
"language"
);
if
(
psz_language
&&
*
psz_language
&&
strcmp
(
psz_language
,
"auto"
)
)
{
bool
b_cache_delete
=
p_libvlc_global
->
p_module_bank
->
b_cache_delete
;
/* Reset the default domain */
SetLanguage
(
psz_language
);
/* Translate "C" to the language code: "fr", "en_GB", "nl", "ru"... */
msg_Dbg
(
p_libvlc
,
"translation test: code is
\"
%s
\"
"
,
_
(
"C"
)
);
module_EndBank
(
p_libvlc
);
module_InitBank
(
p_libvlc
);
if
(
!
config_GetInt
(
p_libvlc
,
"ignore-config"
)
)
config_LoadConfigFile
(
p_libvlc
,
"main"
);
config_LoadCmdLine
(
p_libvlc
,
&
i_argc
,
ppsz_argv
,
true
);
p_libvlc_global
->
p_module_bank
->
b_cache_delete
=
b_cache_delete
;
}
free
(
psz_language
);
# endif
#endif
/*
* 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.
*/
module_LoadBuiltins
(
p_libvlc
);
module_LoadPlugins
(
p_libvlc
);
if
(
p_libvlc
->
b_die
)
{
return
VLC_ENOOBJ
;
b_exit
=
true
;
}
p_input
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_INPUT
,
FIND_CHILD
);
msg_Dbg
(
p_libvlc
,
"module bank initialized, found %i modules"
,
vlc_internals
(
p_libvlc_global
->
p_module_bank
)
->
i_children
);
if
(
!
p_input
)
/* Check for help on modules */
if
(
(
p_tmp
=
config_GetPsz
(
p_libvlc
,
"module"
))
)
{
Help
(
p_libvlc
,
p_tmp
);
free
(
p_tmp
);
b_exit
=
true
;
i_ret
=
VLC_EEXITSUCCESS
;
}
/* Check for long help option */
else
if
(
config_GetInt
(
p_libvlc
,
"longhelp"
)
>
0
)
{
Help
(
p_libvlc
,
"longhelp"
);
b_exit
=
true
;
i_ret
=
VLC_EEXITSUCCESS
;
}
/* Check for module list option */
else
if
(
config_GetInt
(
p_libvlc
,
"list"
)
>
0
)
{
ListModules
(
p_libvlc
,
false
);
b_exit
=
true
;
i_ret
=
VLC_EEXITSUCCESS
;
}
else
if
(
config_GetInt
(
p_libvlc
,
"list-verbose"
)
>
0
)
{
if
(
i_object
)
vlc_object_release
(
p_libvlc
);
return
VLC_ENOOBJ
;
ListModules
(
p_libvlc
,
true
);
b_exit
=
true
;
i_ret
=
VLC_EEXITSUCCESS
;
}
if
(
b_relative
)
/* Check for config file options */
if
(
!
config_GetInt
(
p_libvlc
,
"ignore-config"
)
)
{
val
.
i_time
=
i_seconds
;
val
.
i_time
=
val
.
i_time
*
1000000L
;
var_Set
(
p_input
,
"time-offset"
,
val
);
if
(
config_GetInt
(
p_libvlc
,
"reset-config"
)
>
0
)
{
config_ResetAll
(
p_libvlc
);
config_LoadCmdLine
(
p_libvlc
,
&
i_argc
,
ppsz_argv
,
true
);
config_SaveConfigFile
(
p_libvlc
,
NULL
);
}
else
if
(
config_GetInt
(
p_libvlc
,
"save-config"
)
>
0
)
{
val
.
i_time
=
i_seconds
;
val
.
i_time
=
val
.
i_time
*
1000000L
;
var_Set
(
p_input
,
"time"
,
val
);
config_LoadConfigFile
(
p_libvlc
,
NULL
);
config_LoadCmdLine
(
p_libvlc
,
&
i_argc
,
ppsz_argv
,
true
);
config_SaveConfigFile
(
p_libvlc
,
NULL
);
}
}
vlc_object_release
(
p_input
);
if
(
i_object
)
vlc_object_release
(
p_libvlc
);
return
VLC_SUCCESS
;
}
if
(
b_exit
)
{
module_EndBank
(
p_libvlc
);
return
i_ret
;
}
/**
* Get the total length of a input
*
* Return the total length in seconds from the current input.
* \note For some inputs, this will be unknown.
*
* \param i_object a vlc object id
* \return the length in seconds
/*
* Init device values
*/
int
VLC_LengthGet
(
int
i_object
)
{
input_thread_t
*
p_input
;
vlc_value_t
val
;
libvlc_int_t
*
p_libvlc
=
vlc_current_object
(
i_object
);
InitDeviceValues
(
p_libvlc
);
/* Check that the handle is valid */
if
(
!
p_libvlc
)
/*
* Override default configuration with config file settings
*/
if
(
!
config_GetInt
(
p_libvlc
,
"ignore-config"
)
)
config_LoadConfigFile
(
p_libvlc
,
NULL
);
/*
* Override configuration with command line settings
*/
if
(
config_LoadCmdLine
(
p_libvlc
,
&
i_argc
,
ppsz_argv
,
false
)
)
{
return
VLC_ENOOBJ
;
#ifdef WIN32
ShowConsole
(
false
);
/* 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.
\n
"
);
PauseConsole
();
#endif
module_EndBank
(
p_libvlc
);
return
VLC_EGENERIC
;
}
p_input
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_INPUT
,
FIND_CHILD
);
/*
* System specific configuration
*/
system_Configure
(
p_libvlc
,
&
i_argc
,
ppsz_argv
);
/* FIXME: could be replaced by using Unix sockets */
#ifdef HAVE_DBUS_3
dbus_threads_init_default
();
if
(
config_GetInt
(
p_libvlc
,
"one-instance"
)
>
0
)
{
/* Initialise D-Bus interface, check for other instances */
DBusConnection
*
p_conn
=
NULL
;
DBusError
dbus_error
;
dbus_error_init
(
&
dbus_error
);
if
(
!
p_input
)
/* connect to the session bus */
p_conn
=
dbus_bus_get
(
DBUS_BUS_SESSION
,
&
dbus_error
);
if
(
!
p_conn
)
{
if
(
i_object
)
vlc_object_release
(
p_libvlc
);
return
VLC_ENOOBJ
;
msg_Err
(
p_libvlc
,
"Failed to connect to D-Bus session daemon: %s"
,
dbus_error
.
message
);
dbus_error_free
(
&
dbus_error
);
}
else
{
/* check if VLC is available on the bus
* if not: D-Bus control is not enabled on the other
* instance and we can't pass MRLs to it */
DBusMessage
*
p_test_msg
=
NULL
;
DBusMessage
*
p_test_reply
=
NULL
;
p_test_msg
=
dbus_message_new_method_call
(
"org.mpris.vlc"
,
"/"
,
"org.freedesktop.MediaPlayer"
,
"Identity"
);
/* block until a reply arrives */
p_test_reply
=
dbus_connection_send_with_reply_and_block
(
p_conn
,
p_test_msg
,
-
1
,
&
dbus_error
);
dbus_message_unref
(
p_test_msg
);
if
(
p_test_reply
==
NULL
)
{
dbus_error_free
(
&
dbus_error
);
msg_Dbg
(
p_libvlc
,
"No Media Player is running. "
"Continuing normally."
);
}
else
{
int
i_input
;
DBusMessage
*
p_dbus_msg
=
NULL
;
DBusMessageIter
dbus_args
;
DBusPendingCall
*
p_dbus_pending
=
NULL
;
dbus_bool_t
b_play
;
var_Get
(
p_input
,
"length"
,
&
val
);
vlc_object_release
(
p_input
);
dbus_message_unref
(
p_test_reply
);
msg_Warn
(
p_libvlc
,
"Another Media Player is running. Exiting"
);
if
(
i_object
)
vlc_object_release
(
p_libvlc
);
return
val
.
i_time
/
1000000L
;
}
for
(
i_input
=
optind
;
i_input
<
i_argc
;
i_input
++
)
{
msg_Dbg
(
p_libvlc
,
"Adds %s to the running Media Player"
,
ppsz_argv
[
i_input
]
);
/**
* Play the input faster than realtime
*
* 2x, 4x, 8x faster than realtime
* \note For some inputs, this will be impossible.
*
* \param i_object a vlc object id
* \return the current speedrate
*/
float
VLC_SpeedFaster
(
int
i_object
)
{
input_thread_t
*
p_input
;
vlc_value_t
val
;
libvlc_int_t
*
p_libvlc
=
vlc_current_object
(
i_object
);
p_dbus_msg
=
dbus_message_new_method_call
(
"org.mpris.vlc"
,
"/TrackList"
,
"org.freedesktop.MediaPlayer"
,
"AddTrack"
);
/* Check that the handle is valid */
if
(
!
p_libvlc
)
if
(
NULL
==
p_dbus_msg
)
{
return
VLC_ENOOBJ
;
msg_Err
(
p_libvlc
,
"D-Bus problem"
);
system_End
(
p_libvlc
);
exit
(
VLC_ETIMEOUT
);
}
p_input
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_INPUT
,
FIND_CHILD
);
if
(
!
p_input
)
/* append MRLs */
dbus_message_iter_init_append
(
p_dbus_msg
,
&
dbus_args
);
if
(
!
dbus_message_iter_append_basic
(
&
dbus_args
,
DBUS_TYPE_STRING
,
&
ppsz_argv
[
i_input
]
)
)
{
if
(
i_object
)
vlc_object_release
(
p_libvlc
);
return
VLC_ENOOBJ
;
msg_Err
(
p_libvlc
,
"Out of memory"
);
dbus_message_unref
(
p_dbus_msg
);
system_End
(
p_libvlc
);
exit
(
VLC_ENOMEM
);
}
b_play
=
TRUE
;
if
(
config_GetInt
(
p_libvlc
,
"playlist-enqueue"
)
>
0
)
b_play
=
FALSE
;
if
(
!
dbus_message_iter_append_basic
(
&
dbus_args
,
DBUS_TYPE_BOOLEAN
,
&
b_play
)
)
{
msg_Err
(
p_libvlc
,
"Out of memory"
);
dbus_message_unref
(
p_dbus_msg
);
system_End
(
p_libvlc
);
exit
(
VLC_ENOMEM
);
}
val
.
b_bool
=
true
;
var_Set
(
p_input
,
"rate-faster"
,
val
);
var_Get
(
p_input
,
"rate"
,
&
val
);
vlc_object_release
(
p_input
);
/* send message and get a handle for a reply */
if
(
!
dbus_connection_send_with_reply
(
p_conn
,
p_dbus_msg
,
&
p_dbus_pending
,
-
1
)
)
{
msg_Err
(
p_libvlc
,
"D-Bus problem"
);
dbus_message_unref
(
p_dbus_msg
);
system_End
(
p_libvlc
);
exit
(
VLC_ETIMEOUT
);
}
if
(
i_object
)
vlc_object_release
(
p_libvlc
);
return
val
.
f_float
/
INPUT_RATE_DEFAULT
;
}
if
(
NULL
==
p_dbus_pending
)
{
msg_Err
(
p_libvlc
,
"D-Bus problem"
);
dbus_message_unref
(
p_dbus_msg
);
system_End
(
p_libvlc
);
exit
(
VLC_ETIMEOUT
);
}
dbus_connection_flush
(
p_conn
);
dbus_message_unref
(
p_dbus_msg
);
/* block until we receive a reply */
dbus_pending_call_block
(
p_dbus_pending
);
dbus_pending_call_unref
(
p_dbus_pending
);
}
/* processes all command line MRLs */
/* bye bye */
system_End
(
p_libvlc
);
exit
(
VLC_SUCCESS
);
}
}
/* we unreference the connection when we've finished with it */
if
(
p_conn
)
dbus_connection_unref
(
p_conn
);
}
#endif
/**
* Play the input slower than realtime
*
* 1/2x, 1/4x, 1/8x slower than realtime
* \note For some inputs, this will be impossible.
*
* \param i_object a vlc object id
* \return the current speedrate
/*
* Message queue options
*/
float
VLC_SpeedSlower
(
int
i_object
)
{
input_thread_t
*
p_input
;
vlc_value_t
val
;
libvlc_int_t
*
p_libvlc
=
vlc_current_object
(
i_object
);
/* Check that the handle is valid */
if
(
!
p_libvlc
)
var_Create
(
p_libvlc
,
"verbose"
,
VLC_VAR_INTEGER
|
VLC_VAR_DOINHERIT
);
if
(
config_GetInt
(
p_libvlc
,
"quiet"
)
>
0
)
{
return
VLC_ENOOBJ
;
val
.
i_int
=
-
1
;
var_Set
(
p_libvlc
,
"verbose"
,
val
);
}
var_AddCallback
(
p_libvlc
,
"verbose"
,
VerboseCallback
,
NULL
);
var_Change
(
p_libvlc
,
"verbose"
,
VLC_VAR_TRIGGER_CALLBACKS
,
NULL
,
NULL
);
p_input
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_INPUT
,
FIND_CHILD
);
if
(
priv
->
b_color
)
priv
->
b_color
=
config_GetInt
(
p_libvlc
,
"color"
)
>
0
;
if
(
!
p_input
)
{
if
(
i_object
)
vlc_object_release
(
p_libvlc
);
return
VLC_ENOOBJ
;
/*
* Output messages that may still be in the queue
*/
msg_Flush
(
p_libvlc
);
if
(
!
config_GetInt
(
p_libvlc
,
"fpu"
)
)
cpu_flags
&=
~
CPU_CAPABILITY_FPU
;
#if defined( __i386__ ) || defined( __x86_64__ )
if
(
!
config_GetInt
(
p_libvlc
,
"mmx"
)
)
cpu_flags
&=
~
CPU_CAPABILITY_MMX
;
if
(
!
config_GetInt
(
p_libvlc
,
"3dn"
)
)
cpu_flags
&=
~
CPU_CAPABILITY_3DNOW
;
if
(
!
config_GetInt
(
p_libvlc
,
"mmxext"
)
)
cpu_flags
&=
~
CPU_CAPABILITY_MMXEXT
;
if
(
!
config_GetInt
(
p_libvlc
,
"sse"
)
)
cpu_flags
&=
~
CPU_CAPABILITY_SSE
;
if
(
!
config_GetInt
(
p_libvlc
,
"sse2"
)
)
cpu_flags
&=
~
CPU_CAPABILITY_SSE2
;
#endif
#if defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ )
if
(
!
config_GetInt
(
p_libvlc
,
"altivec"
)
)
cpu_flags
&=
~
CPU_CAPABILITY_ALTIVEC
;
#endif
#define PRINT_CAPABILITY( capability, string ) \
if( vlc_CPU() & capability ) \
{ \
strncat( p_capabilities, string " ", \
sizeof(p_capabilities) - strlen(p_capabilities) ); \
p_capabilities[sizeof(p_capabilities) - 1] = '\0'; \
}
val
.
b_bool
=
true
;
var_Set
(
p_input
,
"rate-slower"
,
val
);
var_Get
(
p_input
,
"rate"
,
&
val
);
vlc_object_release
(
p_input
);
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_SSE2
,
"SSE2"
);
PRINT_CAPABILITY
(
CPU_CAPABILITY_ALTIVEC
,
"AltiVec"
);
PRINT_CAPABILITY
(
CPU_CAPABILITY_FPU
,
"FPU"
);
msg_Dbg
(
p_libvlc
,
"CPU has capabilities %s"
,
p_capabilities
);
/*
* Choose the best memcpy module
*/
priv
->
p_memcpy_module
=
module_Need
(
p_libvlc
,
"memcpy"
,
"$memcpy"
,
0
);
if
(
i_object
)
vlc_object_release
(
p_libvlc
)
;
return
val
.
f_float
/
INPUT_RATE_DEFAULT
;
}
priv
->
b_stats
=
config_GetInt
(
p_libvlc
,
"stats"
)
>
0
;
priv
->
i_timers
=
0
;
priv
->
pp_timers
=
NULL
;
/**
* Return the current playlist item
*
* Returns the index of the playlistitem that is currently selected for play.
* This is valid even if nothing is currently playing.
*
* \param i_object a vlc object id
* \return the current index
*/
int
VLC_PlaylistIndex
(
int
i_object
)
{
(
void
)
i_object
;
printf
(
"This function is deprecated and should not be used anymore"
);
return
-
1
;
}
/* Init stats */
p_libvlc
->
p_stats
=
(
global_stats_t
*
)
malloc
(
sizeof
(
global_stats_t
)
);
if
(
!
p_libvlc
->
p_stats
)
{
vlc_object_release
(
p_libvlc
);
return
VLC_ENOMEM
;
}
vlc_mutex_init
(
&
p_libvlc
->
p_stats
->
lock
);
priv
->
p_stats_computer
=
NULL
;
/**
* Total number of items in the playlist
*
* \param i_object a vlc object id
* \return amount of playlist items
*/
int
VLC_PlaylistNumberOfItems
(
int
i_object
)
{
int
i_size
;
LIBVLC_PLAYLIST_FUNC
;
i_size
=
p_playlist
->
items
.
i_size
;
LIBVLC_PLAYLIST_FUNC_END
;
return
i_size
;
}
/* Init the array that holds every input item */
ARRAY_INIT
(
priv
->
input_items
);
priv
->
i_last_input_id
=
0
;
/**
* Go to next playlist item
* \param i_object a vlc object id
* \return VLC_SUCCESS on success
/*
* Initialize hotkey handling
*/
int
VLC_PlaylistNext
(
int
i_object
)
{
LIBVLC_PLAYLIST_FUNC
;
playlist_Next
(
p_playlist
);
LIBVLC_PLAYLIST_FUNC_END
;
var_Create
(
p_libvlc
,
"key-pressed"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"key-action"
,
VLC_VAR_INTEGER
);
p_libvlc
->
p_hotkeys
=
malloc
(
libvlc_hotkeys_size
);
/* Do a copy (we don't need to modify the strings) */
memcpy
(
p_libvlc
->
p_hotkeys
,
libvlc_hotkeys
,
libvlc_hotkeys_size
);
var_AddCallback
(
p_libvlc
,
"key-pressed"
,
vlc_key_to_action
,
p_libvlc
->
p_hotkeys
);
/* Initialize interaction */
priv
->
p_interaction
=
interaction_Init
(
p_libvlc
);
/* Initialize playlist and get commandline files */
playlist_ThreadCreate
(
p_libvlc
);
if
(
!
priv
->
p_playlist
)
{
msg_Err
(
p_libvlc
,
"playlist initialization failed"
);
if
(
priv
->
p_memcpy_module
!=
NULL
)
{
module_Unneed
(
p_libvlc
,
priv
->
p_memcpy_module
);
}
module_EndBank
(
p_libvlc
);
return
VLC_EGENERIC
;
}
p_playlist
=
priv
->
p_playlist
;
psz_modules
=
config_GetPsz
(
p_playlist
,
"services-discovery"
);
if
(
psz_modules
&&
*
psz_modules
)
{
/* Add service discovery modules */
playlist_ServicesDiscoveryAdd
(
p_playlist
,
psz_modules
);
}
free
(
psz_modules
);
#ifdef ENABLE_SOUT
/* Initialize VLM if vlm-conf is specified */
psz_parser
=
config_GetPsz
(
p_libvlc
,
"vlm-conf"
);
if
(
psz_parser
&&
*
psz_parser
)
{
priv
->
p_vlm
=
vlm_New
(
p_libvlc
);
if
(
!
priv
->
p_vlm
)
msg_Err
(
p_libvlc
,
"VLM initialization failed"
);
}
free
(
psz_parser
);
#endif
/*
* Load background interfaces
*/
psz_modules
=
config_GetPsz
(
p_libvlc
,
"extraintf"
);
psz_control
=
config_GetPsz
(
p_libvlc
,
"control"
);
if
(
psz_modules
&&
*
psz_modules
&&
psz_control
&&
*
psz_control
)
{
psz_modules
=
(
char
*
)
realloc
(
psz_modules
,
strlen
(
psz_modules
)
+
strlen
(
psz_control
)
+
1
);
sprintf
(
psz_modules
,
"%s:%s"
,
psz_modules
,
psz_control
);
}
else
if
(
psz_control
&&
*
psz_control
)
{
free
(
psz_modules
);
psz_modules
=
strdup
(
psz_control
);
}
psz_parser
=
psz_modules
;
while
(
psz_parser
&&
*
psz_parser
)
{
char
*
psz_module
,
*
psz_temp
;
psz_module
=
psz_parser
;
psz_parser
=
strchr
(
psz_module
,
':'
);
if
(
psz_parser
)
{
*
psz_parser
=
'\0'
;
psz_parser
++
;
}
psz_temp
=
(
char
*
)
malloc
(
strlen
(
psz_module
)
+
sizeof
(
",none"
)
);
if
(
psz_temp
)
{
sprintf
(
psz_temp
,
"%s,none"
,
psz_module
);
libvlc_InternalAddIntf
(
p_libvlc
,
psz_temp
,
false
);
free
(
psz_temp
);
}
}
free
(
psz_modules
);
free
(
psz_control
);
/*
* Always load the hotkeys interface if it exists
*/
libvlc_InternalAddIntf
(
p_libvlc
,
"hotkeys,none"
,
false
);
#ifdef HAVE_DBUS_3
/* loads dbus control interface if in one-instance mode
* we do it only when playlist exists, because dbus module needs it */
if
(
config_GetInt
(
p_libvlc
,
"one-instance"
)
>
0
)
libvlc_InternalAddIntf
(
p_libvlc
,
"dbus,none"
,
false
);
/* Prevents the power management daemon from suspending the system
* when VLC is active */
if
(
config_GetInt
(
p_libvlc
,
"inhibit"
)
>
0
)
libvlc_InternalAddIntf
(
p_libvlc
,
"inhibit,none"
,
false
);
#endif
/*
* If needed, load the Xscreensaver interface
* Currently, only for X
*/
#ifdef HAVE_X11_XLIB_H
if
(
config_GetInt
(
p_libvlc
,
"disable-screensaver"
)
)
{
libvlc_InternalAddIntf
(
p_libvlc
,
"screensaver,none"
,
false
);
}
#endif
if
(
config_GetInt
(
p_libvlc
,
"file-logging"
)
>
0
)
{
libvlc_InternalAddIntf
(
p_libvlc
,
"logger,none"
,
false
);
}
#ifdef HAVE_SYSLOG_H
if
(
config_GetInt
(
p_libvlc
,
"syslog"
)
>
0
)
{
char
*
logmode
=
var_CreateGetString
(
p_libvlc
,
"logmode"
);
var_SetString
(
p_libvlc
,
"logmode"
,
"syslog"
);
libvlc_InternalAddIntf
(
p_libvlc
,
"logger,none"
,
false
);
if
(
logmode
)
{
var_SetString
(
p_libvlc
,
"logmode"
,
logmode
);
free
(
logmode
);
}
else
var_Destroy
(
p_libvlc
,
"logmode"
);
}
#endif
if
(
config_GetInt
(
p_libvlc
,
"show-intf"
)
>
0
)
{
libvlc_InternalAddIntf
(
p_libvlc
,
"showintf,none"
,
false
);
}
if
(
config_GetInt
(
p_libvlc
,
"network-synchronisation"
)
>
0
)
{
libvlc_InternalAddIntf
(
p_libvlc
,
"netsync,none"
,
false
);
}
#ifdef WIN32
if
(
config_GetInt
(
p_libvlc
,
"prefer-system-codecs"
)
>
0
)
{
char
*
psz_codecs
=
config_GetPsz
(
p_playlist
,
"codec"
);
if
(
psz_codecs
)
{
char
*
psz_morecodecs
;
asprintf
(
&
psz_morecodecs
,
"%s,dmo,quicktime"
,
psz_codecs
);
if
(
psz_morecodecs
)
{
config_PutPsz
(
p_libvlc
,
"codec"
,
psz_morecodecs
);
free
(
psz_morecodecs
);
}
}
else
config_PutPsz
(
p_libvlc
,
"codec"
,
"dmo,quicktime"
);
free
(
psz_codecs
);
}
#endif
/*
* FIXME: kludge to use a p_libvlc-local variable for the Mozilla plugin
*/
var_Create
(
p_libvlc
,
"drawable"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-view-top"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-view-left"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-view-bottom"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-view-right"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-clip-top"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-clip-left"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-clip-bottom"
,
VLC_VAR_INTEGER
);
var_Create
(
p_libvlc
,
"drawable-clip-right"
,
VLC_VAR_INTEGER
);
/* Create volume callback system. */
var_Create
(
p_libvlc
,
"volume-change"
,
VLC_VAR_BOOL
);
/*
* Get input filenames given as commandline arguments
*/
GetFilenames
(
p_libvlc
,
i_argc
,
ppsz_argv
);
/*
* Get --open argument
*/
var_Create
(
p_libvlc
,
"open"
,
VLC_VAR_STRING
|
VLC_VAR_DOINHERIT
);
var_Get
(
p_libvlc
,
"open"
,
&
val
);
if
(
val
.
psz_string
!=
NULL
&&
*
val
.
psz_string
)
{
playlist_t
*
p_playlist
=
pl_Yield
(
p_libvlc
);
playlist_AddExt
(
p_playlist
,
val
.
psz_string
,
NULL
,
PLAYLIST_INSERT
,
0
,
-
1
,
NULL
,
0
,
true
,
false
);
pl_Release
(
p_libvlc
);
}
free
(
val
.
psz_string
);
return
VLC_SUCCESS
;
}
/**
* Go to previous playlist item
* \param i_object a vlc object id
* \return VLC_SUCCESS on success
* Cleanup a libvlc instance. The instance is not completely deallocated
* \param p_libvlc the instance to clean
*/
int
VLC_PlaylistPrev
(
int
i_object
)
int
libvlc_InternalCleanup
(
libvlc_int_t
*
p_libvlc
)
{
LIBVLC_PLAYLIST_FUNC
;
playlist_Prev
(
p_playlist
);
LIBVLC_PLAYLIST_FUNC_END
;
intf_thread_t
*
p_intf
=
NULL
;
vout_thread_t
*
p_vout
=
NULL
;
libvlc_priv_t
*
priv
=
libvlc_priv
(
p_libvlc
);
/* Ask the interfaces to stop and destroy them */
msg_Dbg
(
p_libvlc
,
"removing all interfaces"
);
while
(
(
p_intf
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_INTF
,
FIND_CHILD
))
)
{
intf_StopThread
(
p_intf
);
vlc_object_detach
(
p_intf
);
vlc_object_release
(
p_intf
);
/* for intf_Create() */
vlc_object_release
(
p_intf
);
/* for vlc_object_find() */
}
/* Free video outputs */
msg_Dbg
(
p_libvlc
,
"removing all video outputs"
);
while
(
(
p_vout
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_VOUT
,
FIND_CHILD
))
)
{
vlc_object_detach
(
p_vout
);
vlc_object_release
(
p_vout
);
vout_Destroy
(
p_vout
);
}
#ifdef ENABLE_SOUT
playlist_t
*
p_playlist
;
sout_instance_t
*
p_sout
;
p_playlist
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_PLAYLIST
,
FIND_CHILD
);
if
(
p_playlist
)
{
p_sout
=
vlc_object_find
(
p_playlist
,
VLC_OBJECT_SOUT
,
FIND_CHILD
);
if
(
p_sout
)
{
msg_Dbg
(
p_sout
,
"removing kept stream output"
);
vlc_object_detach
(
(
vlc_object_t
*
)
p_sout
);
vlc_object_release
(
(
vlc_object_t
*
)
p_sout
);
sout_DeleteInstance
(
p_sout
);
}
vlc_object_release
(
p_playlist
);
}
/* Destroy VLM if created in libvlc_InternalInit */
if
(
priv
->
p_vlm
)
{
vlm_Delete
(
priv
->
p_vlm
);
}
#endif
/* Free playlist */
msg_Dbg
(
p_libvlc
,
"removing playlist"
);
vlc_object_release
(
priv
->
p_playlist
);
/* Free interaction */
msg_Dbg
(
p_libvlc
,
"removing interaction"
);
vlc_object_release
(
priv
->
p_interaction
);
stats_TimersDumpAll
(
p_libvlc
);
stats_TimersCleanAll
(
p_libvlc
);
#ifdef ENABLE_SOUT
announce_handler_t
*
p_announce
;
/* Free announce handler(s?) */
while
(
(
p_announce
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_ANNOUNCE
,
FIND_CHILD
)
)
)
{
msg_Dbg
(
p_libvlc
,
"removing announce handler"
);
vlc_object_detach
(
p_announce
);
vlc_object_release
(
p_announce
);
announce_HandlerDestroy
(
p_announce
);
}
#endif
bool
b_clean
=
true
;
FOREACH_ARRAY
(
input_item_t
*
p_del
,
priv
->
input_items
)
msg_Err
(
p_libvlc
,
"input item %p has not been deleted properly: refcount %d, name %s"
,
p_del
,
p_del
->
i_gc_refcount
,
p_del
->
psz_name
?
p_del
->
psz_name
:
"(null)"
);
b_clean
=
false
;
FOREACH_END
();
assert
(
b_clean
);
ARRAY_RESET
(
priv
->
input_items
);
msg_Dbg
(
p_libvlc
,
"removing stats"
);
vlc_mutex_destroy
(
&
p_libvlc
->
p_stats
->
lock
);
FREENULL
(
p_libvlc
->
p_stats
);
return
VLC_SUCCESS
;
}
/**
* Empty the playlist
* Destroy everything.
* This function requests the running threads to finish, waits for their
* termination, and destroys their structure.
* It stops the thread systems: no instance can run after this has run
* \param p_libvlc the instance to destroy
* \param b_release whether we should do a release on the instance
*/
int
VLC_PlaylistClear
(
int
i_object
)
int
libvlc_InternalDestroy
(
libvlc_int_t
*
p_libvlc
,
bool
b_release
)
{
LIBVLC_PLAYLIST_FUNC
;
playlist_Clear
(
p_playlist
,
true
);
LIBVLC_PLAYLIST_FUNC_END
;
if
(
!
p_libvlc
)
return
VLC_EGENERIC
;
libvlc_priv_t
*
priv
=
libvlc_priv
(
p_libvlc
);
#ifndef WIN32
char
*
psz_pidfile
=
NULL
;
if
(
b_daemon
)
{
psz_pidfile
=
config_GetPsz
(
p_libvlc
,
"pidfile"
);
if
(
psz_pidfile
!=
NULL
)
{
msg_Dbg
(
p_libvlc
,
"removing pid file %s"
,
psz_pidfile
);
if
(
unlink
(
psz_pidfile
)
==
-
1
)
{
msg_Dbg
(
p_libvlc
,
"removing pid file %s: %m"
,
psz_pidfile
);
}
}
free
(
psz_pidfile
);
}
#endif
if
(
priv
->
p_memcpy_module
)
{
module_Unneed
(
p_libvlc
,
priv
->
p_memcpy_module
);
priv
->
p_memcpy_module
=
NULL
;
}
/* Free module bank. It is refcounted, so we call this each time */
module_EndBank
(
p_libvlc
);
FREENULL
(
priv
->
psz_configfile
);
var_DelCallback
(
p_libvlc
,
"key-pressed"
,
vlc_key_to_action
,
p_libvlc
->
p_hotkeys
);
FREENULL
(
p_libvlc
->
p_hotkeys
);
vlc_mutex_t
*
lock
=
var_AcquireMutex
(
"libvlc"
);
i_instances
--
;
if
(
i_instances
==
0
)
{
/* System specific cleaning code */
system_End
(
p_libvlc
);
}
vlc_mutex_unlock
(
lock
);
msg_Flush
(
p_libvlc
);
msg_Destroy
(
p_libvlc
);
/* Destroy mutexes */
vlc_mutex_destroy
(
&
priv
->
config_lock
);
vlc_mutex_destroy
(
&
priv
->
timer_lock
);
if
(
b_release
)
vlc_object_release
(
p_libvlc
);
vlc_object_release
(
p_libvlc
);
p_libvlc
=
NULL
;
/* Stop thread system: last one out please shut the door!
* The number of initializations of the thread system is counted, we
* can call this each time */
vlc_threads_end
();
return
VLC_SUCCESS
;
}
/**
* Change the volume
*
* \param i_object a vlc object id
* \param i_volume something in a range from 0-200
* \return the new volume (range 0-200 %)
* Add an interface plugin and run it
*/
int
VLC_VolumeSet
(
int
i_object
,
int
i_volume
)
int
libvlc_InternalAddIntf
(
libvlc_int_t
*
p_libvlc
,
char
const
*
psz_module
,
bool
b_play
)
{
audio_volume_t
i_vol
=
0
;
LIBVLC_FUNC
;
int
i_err
;
intf_thread_t
*
p_intf
=
NULL
;
if
(
i_volume
>=
0
&&
i_volume
<=
200
)
if
(
!
p_libvlc
)
return
VLC_EGENERIC
;
if
(
!
psz_module
)
/* requesting the default interface */
{
char
*
psz_interface
=
config_GetPsz
(
p_libvlc
,
"intf"
);
if
(
!
psz_interface
||
!*
psz_interface
)
/* "intf" has not been set */
{
i_vol
=
i_volume
*
AOUT_VOLUME_MAX
/
200
;
aout_VolumeSet
(
p_libvlc
,
i_vol
);
#ifndef WIN32
if
(
b_daemon
)
/* Daemon mode hack.
* We prefer the dummy interface if none is specified. */
psz_module
=
"dummy"
;
else
#endif
msg_Info
(
p_libvlc
,
_
(
"Running vlc with the default interface. Use 'cvlc' to use vlc without interface."
)
);
}
free
(
psz_interface
);
}
LIBVLC_FUNC_END
;
return
i_vol
*
200
/
AOUT_VOLUME_MAX
;
/* Try to create the interface */
p_intf
=
intf_Create
(
p_libvlc
,
psz_module
?
psz_module
:
"$intf"
);
if
(
p_intf
==
NULL
)
{
msg_Err
(
p_libvlc
,
"interface
\"
%s
\"
initialization failed"
,
psz_module
);
return
VLC_EGENERIC
;
}
/* Interface doesn't handle play on start so do it ourselves */
if
(
!
p_intf
->
b_play
&&
b_play
)
playlist_Play
(
libvlc_priv
(
p_libvlc
)
->
p_playlist
);
/* Try to run the interface */
p_intf
->
b_play
=
b_play
;
i_err
=
intf_RunThread
(
p_intf
);
if
(
i_err
)
{
vlc_object_detach
(
p_intf
);
vlc_object_release
(
p_intf
);
return
i_err
;
}
return
VLC_SUCCESS
;
};
#if defined( ENABLE_NLS ) && (defined (__APPLE__) || defined (WIN32)) && \
( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
/*****************************************************************************
* 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
(
const
char
*
psz_lang
)
{
#ifdef __APPLE__
/* I need that under Darwin, please check it doesn't disturb
* other platforms. --Meuuh */
setenv
(
"LANG"
,
psz_lang
,
1
);
#else
/* 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
);
#endif
setlocale
(
LC_ALL
,
psz_lang
);
}
#endif
/**
* Get the current volume
*
* Retrieve the current volume.
*
* \param i_object a vlc object id
* \return the current volume (range 0-200 %)
static
inline
int
LoadMessages
(
void
)
{
#if defined( ENABLE_NLS ) \
&& ( defined( HAVE_GETTEXT ) || defined( HAVE_INCLUDED_GETTEXT ) )
/* Specify where to find the locales for current domain */
#if !defined( __APPLE__ ) && !defined( WIN32 ) && !defined( SYS_BEOS )
static
const
char
psz_path
[]
=
LOCALEDIR
;
#else
char
psz_path
[
1024
];
if
(
snprintf
(
psz_path
,
sizeof
(
psz_path
),
"%s/%s"
,
vlc_global
()
->
psz_vlcpath
,
"locale"
)
>=
(
int
)
sizeof
(
psz_path
))
return
-
1
;
#endif
if
(
bindtextdomain
(
PACKAGE_NAME
,
psz_path
)
==
NULL
)
{
fprintf
(
stderr
,
"Warning: cannot bind text domain "
PACKAGE_NAME
" to directory %s
\n
"
,
psz_path
);
return
-
1
;
}
/* LibVLC wants all messages in UTF-8.
* Unfortunately, we cannot ask UTF-8 for strerror_r(), strsignal_r()
* and other functions that are not part of our text domain.
*/
if
(
bind_textdomain_codeset
(
PACKAGE_NAME
,
"UTF-8"
)
==
NULL
)
{
fprintf
(
stderr
,
"Error: cannot set Unicode encoding for text domain "
PACKAGE_NAME
"
\n
"
);
// Unbinds the text domain to avoid broken encoding
bindtextdomain
(
PACKAGE_NAME
,
"DOES_NOT_EXIST"
);
return
-
1
;
}
/* LibVLC does NOT set the default textdomain, since it is a library.
* This could otherwise break programs using LibVLC (other than VLC).
* textdomain (PACKAGE_NAME);
*/
int
VLC_VolumeGet
(
int
i_object
)
#endif
return
0
;
}
/*****************************************************************************
* GetFilenames: parse command line options which are not flags
*****************************************************************************
* Parse command line for input files as well as their associated options.
* An option always follows its associated input and begins with a ":".
*****************************************************************************/
static
int
GetFilenames
(
libvlc_int_t
*
p_vlc
,
int
i_argc
,
const
char
*
ppsz_argv
[]
)
{
int
i_opt
,
i_options
;
/* We assume that the remaining parameters are filenames
* and their input options */
for
(
i_opt
=
i_argc
-
1
;
i_opt
>=
optind
;
i_opt
--
)
{
i_options
=
0
;
/* Count the input options */
while
(
*
ppsz_argv
[
i_opt
]
==
':'
&&
i_opt
>
optind
)
{
i_options
++
;
i_opt
--
;
}
/* TODO: write an internal function of this one, to avoid
* unnecessary lookups. */
playlist_t
*
p_playlist
=
pl_Yield
(
p_vlc
);
playlist_AddExt
(
p_playlist
,
ppsz_argv
[
i_opt
],
NULL
,
PLAYLIST_INSERT
,
0
,
-
1
,
(
i_options
?
&
ppsz_argv
[
i_opt
+
1
]
:
NULL
),
i_options
,
true
,
false
);
pl_Release
(
p_vlc
);
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* Help: print program help
*****************************************************************************
* Print a short inline help. Message interface is initialized at this stage.
*****************************************************************************/
static
void
Help
(
libvlc_int_t
*
p_this
,
char
const
*
psz_help_name
)
{
audio_volume_t
i_volume
;
LIBVLC_FUNC
;
aout_VolumeGet
(
p_libvlc
,
&
i_volume
);
LIBVLC_FUNC_END
;
return
i_volume
*
200
/
AOUT_VOLUME_MAX
;
#ifdef WIN32
ShowConsole
(
true
);
#endif
if
(
psz_help_name
&&
!
strcmp
(
psz_help_name
,
"help"
)
)
{
utf8_fprintf
(
stdout
,
vlc_usage
,
p_this
->
psz_object_name
);
Usage
(
p_this
,
"help"
);
Usage
(
p_this
,
"main"
);
}
else
if
(
psz_help_name
&&
!
strcmp
(
psz_help_name
,
"longhelp"
)
)
{
utf8_fprintf
(
stdout
,
vlc_usage
,
p_this
->
psz_object_name
);
Usage
(
p_this
,
NULL
);
}
else
if
(
psz_help_name
)
{
Usage
(
p_this
,
psz_help_name
);
}
#ifdef WIN32
/* Pause the console because it's destroyed when we exit */
PauseConsole
();
#endif
}
/**
* Mute/Unmute the volume
/*****************************************************************************
* Usage: print module usage
*****************************************************************************
* Print a short inline help. Message interface is initialized at this stage.
*****************************************************************************/
static
void
Usage
(
libvlc_int_t
*
p_this
,
char
const
*
psz_module_name
)
{
#define FORMAT_STRING " %s --%s%s%s%s%s%s%s "
/* short option ------' | | | | | | |
* option name ------------' | | | | | |
* <bra ---------------------' | | | | |
* option type or "" ----------' | | | |
* ket> -------------------------' | | |
* padding spaces -----------------' | |
* comment --------------------------' |
* comment suffix ---------------------'
*
* \param i_object a vlc object id
* \return VLC_SUCCESS on success
* The purpose of having bra and ket is that we might i18n them as well.
*/
int
VLC_VolumeMute
(
int
i_object
)
# define COL(x) "\033[" #x ";1m"
# define RED COL(31)
# define GREEN COL(32)
# define YELLOW COL(33)
# define BLUE COL(34)
# define MAGENTA COL(35)
# define CYAN COL(36)
# define WHITE COL(0)
# define GRAY "\033[0m"
#define COLOR_FORMAT_STRING (WHITE" %s --%s"YELLOW"%s%s%s%s%s%s "GRAY)
#define COLOR_FORMAT_STRING_BOOL (WHITE" %s --%s%s%s%s%s%s%s "GRAY)
#define LINE_START 8
#define PADDING_SPACES 25
#ifdef WIN32
# define OPTION_VALUE_SEP "="
#else
# define OPTION_VALUE_SEP " "
#endif
vlc_list_t
*
p_list
=
NULL
;
char
psz_spaces_text
[
PADDING_SPACES
+
LINE_START
+
1
];
char
psz_spaces_longtext
[
LINE_START
+
3
];
char
psz_format
[
sizeof
(
COLOR_FORMAT_STRING
)];
char
psz_format_bool
[
sizeof
(
COLOR_FORMAT_STRING_BOOL
)];
char
psz_buffer
[
10000
];
char
psz_short
[
4
];
int
i_index
;
int
i_width
=
ConsoleWidth
()
-
(
PADDING_SPACES
+
LINE_START
+
1
);
int
i_width_description
=
i_width
+
PADDING_SPACES
-
1
;
bool
b_advanced
=
config_GetInt
(
p_this
,
"advanced"
)
>
0
;
bool
b_description
=
config_GetInt
(
p_this
,
"help-verbose"
)
>
0
;
bool
b_description_hack
;
bool
b_color
=
config_GetInt
(
p_this
,
"color"
)
>
0
;
bool
b_has_advanced
=
false
;
memset
(
psz_spaces_text
,
' '
,
PADDING_SPACES
+
LINE_START
);
psz_spaces_text
[
PADDING_SPACES
+
LINE_START
]
=
'\0'
;
memset
(
psz_spaces_longtext
,
' '
,
LINE_START
+
2
);
psz_spaces_longtext
[
LINE_START
+
2
]
=
'\0'
;
#ifdef WIN32
b_color
=
false
;
// don't put color control codes in a .txt file
#endif
if
(
b_color
)
{
strcpy
(
psz_format
,
COLOR_FORMAT_STRING
);
strcpy
(
psz_format_bool
,
COLOR_FORMAT_STRING_BOOL
);
}
else
{
strcpy
(
psz_format
,
FORMAT_STRING
);
strcpy
(
psz_format_bool
,
FORMAT_STRING
);
}
/* List all modules */
p_list
=
vlc_list_find
(
p_this
,
VLC_OBJECT_MODULE
,
FIND_ANYWHERE
);
/* Ugly hack to make sure that the help options always come first
* (part 1) */
if
(
!
psz_module_name
)
Usage
(
p_this
,
"help"
);
/* Enumerate the config for each module */
for
(
i_index
=
0
;
i_index
<
p_list
->
i_count
;
i_index
++
)
{
bool
b_help_module
;
module_t
*
p_parser
=
(
module_t
*
)
p_list
->
p_values
[
i_index
].
p_object
;
module_config_t
*
p_item
=
NULL
;
module_config_t
*
p_end
=
p_parser
->
p_config
+
p_parser
->
confsize
;
if
(
psz_module_name
&&
strcmp
(
psz_module_name
,
p_parser
->
psz_object_name
)
)
{
const
char
*
const
*
pp_shortcut
=
p_parser
->
pp_shortcuts
;
while
(
*
pp_shortcut
)
{
if
(
!
strcmp
(
psz_module_name
,
*
pp_shortcut
)
)
break
;
pp_shortcut
++
;
}
if
(
!*
pp_shortcut
)
continue
;
}
/* Ignore modules without config options */
if
(
!
p_parser
->
i_config_items
)
{
continue
;
}
b_help_module
=
!
strcmp
(
"help"
,
p_parser
->
psz_object_name
);
/* Ugly hack to make sure that the help options always come first
* (part 2) */
if
(
!
psz_module_name
&&
b_help_module
)
continue
;
/* Ignore modules with only advanced config options if requested */
if
(
!
b_advanced
)
{
for
(
p_item
=
p_parser
->
p_config
;
p_item
<
p_end
;
p_item
++
)
{
if
(
(
p_item
->
i_type
&
CONFIG_ITEM
)
&&
!
p_item
->
b_advanced
)
break
;
}
}
/* Print name of module */
if
(
strcmp
(
"main"
,
p_parser
->
psz_object_name
)
)
{
if
(
b_color
)
utf8_fprintf
(
stdout
,
"
\n
"
GREEN
"%s"
GRAY
"
\n
"
,
p_parser
->
psz_longname
);
else
utf8_fprintf
(
stdout
,
"
\n
%s
\n
"
,
p_parser
->
psz_longname
);
}
if
(
p_parser
->
psz_help
)
{
if
(
b_color
)
utf8_fprintf
(
stdout
,
CYAN
" %s
\n
"
GRAY
,
p_parser
->
psz_help
);
else
utf8_fprintf
(
stdout
,
" %s
\n
"
,
p_parser
->
psz_help
);
}
/* Print module options */
for
(
p_item
=
p_parser
->
p_config
;
p_item
<
p_end
;
p_item
++
)
{
char
*
psz_text
,
*
psz_spaces
=
psz_spaces_text
;
const
char
*
psz_bra
=
NULL
,
*
psz_type
=
NULL
,
*
psz_ket
=
NULL
;
const
char
*
psz_suf
=
""
,
*
psz_prefix
=
NULL
;
signed
int
i
;
size_t
i_cur_width
;
/* Skip removed options */
if
(
p_item
->
b_removed
)
{
continue
;
}
/* Skip advanced options if requested */
if
(
p_item
->
b_advanced
&&
!
b_advanced
)
{
b_has_advanced
=
true
;
continue
;
}
switch
(
p_item
->
i_type
)
{
case
CONFIG_HINT_CATEGORY
:
case
CONFIG_HINT_USAGE
:
if
(
!
strcmp
(
"main"
,
p_parser
->
psz_object_name
)
)
{
if
(
b_color
)
utf8_fprintf
(
stdout
,
GREEN
"
\n
%s
\n
"
GRAY
,
p_item
->
psz_text
);
else
utf8_fprintf
(
stdout
,
"
\n
%s
\n
"
,
p_item
->
psz_text
);
}
if
(
b_description
&&
p_item
->
psz_longtext
)
{
if
(
b_color
)
utf8_fprintf
(
stdout
,
CYAN
" %s
\n
"
GRAY
,
p_item
->
psz_longtext
);
else
utf8_fprintf
(
stdout
,
" %s
\n
"
,
p_item
->
psz_longtext
);
}
break
;
case
CONFIG_HINT_SUBCATEGORY
:
if
(
strcmp
(
"main"
,
p_parser
->
psz_object_name
)
)
break
;
case
CONFIG_SECTION
:
if
(
b_color
)
{
utf8_fprintf
(
stdout
,
RED
" %s:
\n
"
GRAY
,
p_item
->
psz_text
);
if
(
b_description
&&
p_item
->
psz_longtext
)
utf8_fprintf
(
stdout
,
MAGENTA
" %s
\n
"
GRAY
,
p_item
->
psz_longtext
);
}
else
{
utf8_fprintf
(
stdout
,
" %s:
\n
"
,
p_item
->
psz_text
);
if
(
b_description
&&
p_item
->
psz_longtext
)
utf8_fprintf
(
stdout
,
" %s
\n
"
,
p_item
->
psz_longtext
);
}
break
;
case
CONFIG_ITEM_STRING
:
case
CONFIG_ITEM_FILE
:
case
CONFIG_ITEM_DIRECTORY
:
case
CONFIG_ITEM_MODULE
:
/* We could also have "=<" here */
case
CONFIG_ITEM_MODULE_CAT
:
case
CONFIG_ITEM_MODULE_LIST
:
case
CONFIG_ITEM_MODULE_LIST_CAT
:
case
CONFIG_ITEM_FONT
:
case
CONFIG_ITEM_PASSWORD
:
psz_bra
=
OPTION_VALUE_SEP
"<"
;
psz_type
=
_
(
"string"
);
psz_ket
=
">"
;
if
(
p_item
->
ppsz_list
)
{
psz_bra
=
OPTION_VALUE_SEP
"{"
;
psz_type
=
psz_buffer
;
psz_buffer
[
0
]
=
'\0'
;
for
(
i
=
0
;
p_item
->
ppsz_list
[
i
];
i
++
)
{
if
(
i
)
strcat
(
psz_buffer
,
","
);
strcat
(
psz_buffer
,
p_item
->
ppsz_list
[
i
]
);
}
psz_ket
=
"}"
;
}
break
;
case
CONFIG_ITEM_INTEGER
:
case
CONFIG_ITEM_KEY
:
/* FIXME: do something a bit more clever */
psz_bra
=
OPTION_VALUE_SEP
"<"
;
psz_type
=
_
(
"integer"
);
psz_ket
=
">"
;
if
(
p_item
->
min
.
i
||
p_item
->
max
.
i
)
{
sprintf
(
psz_buffer
,
"%s [%i .. %i]"
,
psz_type
,
p_item
->
min
.
i
,
p_item
->
max
.
i
);
psz_type
=
psz_buffer
;
}
if
(
p_item
->
i_list
)
{
psz_bra
=
OPTION_VALUE_SEP
"{"
;
psz_type
=
psz_buffer
;
psz_buffer
[
0
]
=
'\0'
;
for
(
i
=
0
;
p_item
->
ppsz_list_text
[
i
];
i
++
)
{
if
(
i
)
strcat
(
psz_buffer
,
", "
);
sprintf
(
psz_buffer
+
strlen
(
psz_buffer
),
"%i (%s)"
,
p_item
->
pi_list
[
i
],
p_item
->
ppsz_list_text
[
i
]
);
}
psz_ket
=
"}"
;
}
break
;
case
CONFIG_ITEM_FLOAT
:
psz_bra
=
OPTION_VALUE_SEP
"<"
;
psz_type
=
_
(
"float"
);
psz_ket
=
">"
;
if
(
p_item
->
min
.
f
||
p_item
->
max
.
f
)
{
sprintf
(
psz_buffer
,
"%s [%f .. %f]"
,
psz_type
,
p_item
->
min
.
f
,
p_item
->
max
.
f
);
psz_type
=
psz_buffer
;
}
break
;
case
CONFIG_ITEM_BOOL
:
psz_bra
=
""
;
psz_type
=
""
;
psz_ket
=
""
;
if
(
!
b_help_module
)
{
psz_suf
=
p_item
->
value
.
i
?
_
(
" (default enabled)"
)
:
_
(
" (default disabled)"
);
}
break
;
}
if
(
!
psz_type
)
{
continue
;
}
/* Add short option if any */
if
(
p_item
->
i_short
)
{
sprintf
(
psz_short
,
"-%c,"
,
p_item
->
i_short
);
}
else
{
strcpy
(
psz_short
,
" "
);
}
i
=
PADDING_SPACES
-
strlen
(
p_item
->
psz_name
)
-
strlen
(
psz_bra
)
-
strlen
(
psz_type
)
-
strlen
(
psz_ket
)
-
1
;
if
(
p_item
->
i_type
==
CONFIG_ITEM_BOOL
&&
!
b_help_module
)
{
psz_prefix
=
", --no-"
;
i
-=
strlen
(
p_item
->
psz_name
)
+
strlen
(
psz_prefix
);
}
if
(
i
<
0
)
{
psz_spaces
[
0
]
=
'\n'
;
i
=
0
;
}
else
{
psz_spaces
[
i
]
=
'\0'
;
}
if
(
p_item
->
i_type
==
CONFIG_ITEM_BOOL
&&
!
b_help_module
)
{
utf8_fprintf
(
stdout
,
psz_format_bool
,
psz_short
,
p_item
->
psz_name
,
psz_prefix
,
p_item
->
psz_name
,
psz_bra
,
psz_type
,
psz_ket
,
psz_spaces
);
}
else
{
utf8_fprintf
(
stdout
,
psz_format
,
psz_short
,
p_item
->
psz_name
,
""
,
""
,
psz_bra
,
psz_type
,
psz_ket
,
psz_spaces
);
}
psz_spaces
[
i
]
=
' '
;
/* We wrap the rest of the output */
sprintf
(
psz_buffer
,
"%s%s"
,
p_item
->
psz_text
,
psz_suf
);
b_description_hack
=
b_description
;
description:
psz_text
=
psz_buffer
;
i_cur_width
=
b_description
&&
!
b_description_hack
?
i_width_description
:
i_width
;
while
(
*
psz_text
)
{
char
*
psz_parser
,
*
psz_word
;
size_t
i_end
=
strlen
(
psz_text
);
/* If the remaining text fits in a line, print it. */
if
(
i_end
<=
i_cur_width
)
{
if
(
b_color
)
{
if
(
!
b_description
||
b_description_hack
)
utf8_fprintf
(
stdout
,
BLUE
"%s
\n
"
GRAY
,
psz_text
);
else
utf8_fprintf
(
stdout
,
"%s
\n
"
,
psz_text
);
}
else
{
utf8_fprintf
(
stdout
,
"%s
\n
"
,
psz_text
);
}
break
;
}
/* Otherwise, eat as many words as possible */
psz_parser
=
psz_text
;
do
{
psz_word
=
psz_parser
;
psz_parser
=
strchr
(
psz_word
,
' '
);
/* If no space was found, we reached the end of the text
* block; otherwise, we skip the space we just found. */
psz_parser
=
psz_parser
?
psz_parser
+
1
:
psz_text
+
i_end
;
}
while
(
(
size_t
)(
psz_parser
-
psz_text
)
<=
i_cur_width
);
/* We cut a word in one of these cases:
* - it's the only word in the line and it's too long.
* - we used less than 80% of the width and the word we are
* going to wrap is longer than 40% of the width, and even
* if the word would have fit in the next line. */
if
(
psz_word
==
psz_text
||
(
(
size_t
)(
psz_word
-
psz_text
)
<
80
*
i_cur_width
/
100
&&
(
size_t
)(
psz_parser
-
psz_word
)
>
40
*
i_cur_width
/
100
)
)
{
char
c
=
psz_text
[
i_cur_width
];
psz_text
[
i_cur_width
]
=
'\0'
;
if
(
b_color
)
{
if
(
!
b_description
||
b_description_hack
)
utf8_fprintf
(
stdout
,
BLUE
"%s
\n
%s"
GRAY
,
psz_text
,
psz_spaces
);
else
utf8_fprintf
(
stdout
,
"%s
\n
%s"
,
psz_text
,
psz_spaces
);
}
else
{
utf8_fprintf
(
stdout
,
"%s
\n
%s"
,
psz_text
,
psz_spaces
);
}
psz_text
+=
i_cur_width
;
psz_text
[
0
]
=
c
;
}
else
{
psz_word
[
-
1
]
=
'\0'
;
if
(
b_color
)
{
if
(
!
b_description
||
b_description_hack
)
utf8_fprintf
(
stdout
,
BLUE
"%s
\n
%s"
GRAY
,
psz_text
,
psz_spaces
);
else
utf8_fprintf
(
stdout
,
"%s
\n
%s"
,
psz_text
,
psz_spaces
);
}
else
{
utf8_fprintf
(
stdout
,
"%s
\n
%s"
,
psz_text
,
psz_spaces
);
}
psz_text
=
psz_word
;
}
}
if
(
b_description_hack
&&
p_item
->
psz_longtext
)
{
sprintf
(
psz_buffer
,
"%s%s"
,
p_item
->
psz_longtext
,
psz_suf
);
b_description_hack
=
false
;
psz_spaces
=
psz_spaces_longtext
;
utf8_fprintf
(
stdout
,
"%s"
,
psz_spaces
);
goto
description
;
}
}
}
if
(
b_has_advanced
)
{
if
(
b_color
)
utf8_fprintf
(
stdout
,
"
\n
"
WHITE
"%s"
GRAY
" %s
\n
"
,
_
(
"Note:"
),
_
(
"add --advanced to your command line to see advanced options."
));
else
utf8_fprintf
(
stdout
,
"
\n
%s %s
\n
"
,
_
(
"Note:"
),
_
(
"add --advanced to your command line to see advanced options."
));
}
/* Release the module list */
vlc_list_release
(
p_list
);
}
/*****************************************************************************
* ListModules: list the available modules with their description
*****************************************************************************
* Print a list of all available modules (builtins and plugins) and a short
* description for each one.
*****************************************************************************/
static
void
ListModules
(
libvlc_int_t
*
p_this
,
bool
b_verbose
)
{
LIBVLC_FUNC
;
aout_VolumeMute
(
p_libvlc
,
NULL
);
LIBVLC_FUNC_END
;
return
VLC_SUCCESS
;
vlc_list_t
*
p_list
=
NULL
;
module_t
*
p_parser
=
NULL
;
char
psz_spaces
[
22
];
int
i_index
;
bool
b_color
=
config_GetInt
(
p_this
,
"color"
)
>
0
;
memset
(
psz_spaces
,
' '
,
22
);
#ifdef WIN32
ShowConsole
(
true
);
#endif
/* List all modules */
p_list
=
vlc_list_find
(
p_this
,
VLC_OBJECT_MODULE
,
FIND_ANYWHERE
);
/* Enumerate each module */
for
(
i_index
=
0
;
i_index
<
p_list
->
i_count
;
i_index
++
)
{
int
i
;
p_parser
=
(
module_t
*
)
p_list
->
p_values
[
i_index
].
p_object
;
/* Nasty hack, but right now I'm too tired to think about a nice
* solution */
i
=
22
-
strlen
(
p_parser
->
psz_object_name
)
-
1
;
if
(
i
<
0
)
i
=
0
;
psz_spaces
[
i
]
=
0
;
if
(
b_color
)
utf8_fprintf
(
stdout
,
GREEN
" %s%s "
WHITE
"%s
\n
"
GRAY
,
p_parser
->
psz_object_name
,
psz_spaces
,
p_parser
->
psz_longname
);
else
utf8_fprintf
(
stdout
,
" %s%s %s
\n
"
,
p_parser
->
psz_object_name
,
psz_spaces
,
p_parser
->
psz_longname
);
if
(
b_verbose
)
{
const
char
*
const
*
pp_shortcut
=
p_parser
->
pp_shortcuts
;
while
(
*
pp_shortcut
)
{
if
(
strcmp
(
*
pp_shortcut
,
p_parser
->
psz_object_name
)
)
{
if
(
b_color
)
utf8_fprintf
(
stdout
,
CYAN
" s %s
\n
"
GRAY
,
*
pp_shortcut
);
else
utf8_fprintf
(
stdout
,
" s %s
\n
"
,
*
pp_shortcut
);
}
pp_shortcut
++
;
}
if
(
p_parser
->
psz_capability
)
{
if
(
b_color
)
utf8_fprintf
(
stdout
,
MAGENTA
" c %s (%d)
\n
"
GRAY
,
p_parser
->
psz_capability
,
p_parser
->
i_score
);
else
utf8_fprintf
(
stdout
,
" c %s (%d)
\n
"
,
p_parser
->
psz_capability
,
p_parser
->
i_score
);
}
}
psz_spaces
[
i
]
=
' '
;
}
vlc_list_release
(
p_list
);
#ifdef WIN32
/* Pause the console because it's destroyed when we exit */
PauseConsole
();
#endif
}
/*****************************************************************************
* VLC_FullScreen: toggle fullscreen mode
* Version: print complete program version
*****************************************************************************
* Print complete program version and build number.
*****************************************************************************/
int
VLC_FullScreen
(
int
i_object
)
static
void
Version
(
void
)
{
vout_thread_t
*
p_vout
;
LIBVLC_FUNC
;
p_vout
=
vlc_object_find
(
p_libvlc
,
VLC_OBJECT_VOUT
,
FIND_CHILD
);
#ifdef WIN32
ShowConsole
(
true
)
;
#endif
if
(
!
p_vout
)
utf8_fprintf
(
stdout
,
_
(
"VLC version %s
\n
"
),
VLC_Version
()
);
utf8_fprintf
(
stdout
,
_
(
"Compiled by %s@%s.%s
\n
"
),
VLC_CompileBy
(),
VLC_CompileHost
(),
VLC_CompileDomain
()
);
utf8_fprintf
(
stdout
,
_
(
"Compiler: %s
\n
"
),
VLC_Compiler
()
);
if
(
strcmp
(
VLC_Changeset
(),
"exported"
)
)
utf8_fprintf
(
stdout
,
_
(
"Based upon Git commit [%s]
\n
"
),
VLC_Changeset
()
);
utf8_fprintf
(
stdout
,
LICENSE_MSG
);
#ifdef WIN32
/* Pause the console because it's destroyed when we exit */
PauseConsole
();
#endif
}
/*****************************************************************************
* ShowConsole: On Win32, create an output console for debug messages
*****************************************************************************
* This function is useful only on Win32.
*****************************************************************************/
#ifdef WIN32
/* */
static
void
ShowConsole
(
bool
b_dofile
)
{
# ifndef UNDER_CE
FILE
*
f_help
=
NULL
;
if
(
getenv
(
"PWD"
)
&&
getenv
(
"PS1"
)
)
return
;
/* cygwin shell */
AllocConsole
();
/* Use the ANSI code page (e.g. Windows-1252) as expected by the LibVLC
* Unicode/locale subsystem. By default, we have the obsolecent OEM code
* page (e.g. CP437 or CP850). */
SetConsoleOutputCP
(
GetACP
());
SetConsoleTitle
(
"VLC media player version "
PACKAGE_VERSION
);
freopen
(
"CONOUT$"
,
"w"
,
stderr
);
freopen
(
"CONIN$"
,
"r"
,
stdin
);
if
(
b_dofile
&&
(
f_help
=
fopen
(
"vlc-help.txt"
,
"wt"
))
)
{
if
(
i_object
)
vlc_object_release
(
p_libvlc
);
return
VLC_ENOOBJ
;
fclose
(
f_help
);
freopen
(
"vlc-help.txt"
,
"wt"
,
stdout
);
utf8_fprintf
(
stderr
,
_
(
"
\n
Dumped content to vlc-help.txt file.
\n
"
)
);
}
else
freopen
(
"CONOUT$"
,
"w"
,
stdout
);
p_vout
->
i_changes
|=
VOUT_FULLSCREEN_CHANGE
;
vlc_object_release
(
p_vout
);
LIBVLC_FUNC_END
;
# endif
}
#endif
/*****************************************************************************
* PauseConsole: On Win32, wait for a key press before closing the console
*****************************************************************************
* This function is useful only on Win32.
*****************************************************************************/
#ifdef WIN32
/* */
static
void
PauseConsole
(
void
)
{
# ifndef UNDER_CE
if
(
getenv
(
"PWD"
)
&&
getenv
(
"PS1"
)
)
return
;
/* cygwin shell */
utf8_fprintf
(
stderr
,
_
(
"
\n
Press the RETURN key to continue...
\n
"
)
);
getchar
();
fclose
(
stdout
);
# endif
}
#endif
/*****************************************************************************
* ConsoleWidth: Return the console width in characters
*****************************************************************************
* We use the stty shell command to get the console width; if this fails or
* if the width is less than 80, we default to 80.
*****************************************************************************/
static
int
ConsoleWidth
(
void
)
{
unsigned
i_width
=
80
;
#ifndef WIN32
FILE
*
file
=
popen
(
"stty size 2>/dev/null"
,
"r"
);
if
(
file
!=
NULL
)
{
if
(
fscanf
(
file
,
"%*u %u"
,
&
i_width
)
<=
0
)
i_width
=
80
;
pclose
(
file
);
}
#else
CONSOLE_SCREEN_BUFFER_INFO
buf
;
if
(
GetConsoleScreenBufferInfo
(
GetStdHandle
(
STD_OUTPUT_HANDLE
),
&
buf
))
i_width
=
buf
.
dwSize
.
X
;
#endif
return
i_width
;
}
static
int
VerboseCallback
(
vlc_object_t
*
p_this
,
const
char
*
psz_variable
,
vlc_value_t
old_val
,
vlc_value_t
new_val
,
void
*
param
)
{
libvlc_int_t
*
p_libvlc
=
(
libvlc_int_t
*
)
p_this
;
(
void
)
psz_variable
;
(
void
)
old_val
;
(
void
)
param
;
if
(
new_val
.
i_int
>=
-
1
)
{
libvlc_priv
(
p_libvlc
)
->
i_verbose
=
__MIN
(
new_val
.
i_int
,
2
);
}
return
VLC_SUCCESS
;
}
/*****************************************************************************
* InitDeviceValues: initialize device values
*****************************************************************************
* This function inits the dvd, vcd and cd-audio values
*****************************************************************************/
static
void
InitDeviceValues
(
libvlc_int_t
*
p_vlc
)
{
#ifdef HAVE_HAL
LibHalContext
*
ctx
=
NULL
;
int
i
,
i_devices
;
char
**
devices
=
NULL
;
char
*
block_dev
=
NULL
;
dbus_bool_t
b_dvd
;
#ifdef HAVE_HAL_1
DBusConnection
*
p_connection
=
NULL
;
DBusError
error
;
ctx
=
libhal_ctx_new
();
if
(
!
ctx
)
return
;
dbus_error_init
(
&
error
);
p_connection
=
dbus_bus_get
(
DBUS_BUS_SYSTEM
,
&
error
);
if
(
dbus_error_is_set
(
&
error
)
||
!
p_connection
)
{
libhal_ctx_free
(
ctx
);
dbus_error_free
(
&
error
);
return
;
}
libhal_ctx_set_dbus_connection
(
ctx
,
p_connection
);
if
(
libhal_ctx_init
(
ctx
,
&
error
)
)
#else
ctx
=
hal_initialize
(
NULL
,
FALSE
);
if
(
ctx
)
#endif
{
#ifdef HAVE_HAL_1
if
(
(
devices
=
libhal_get_all_devices
(
ctx
,
&
i_devices
,
NULL
)
)
)
#else
if
(
(
devices
=
hal_get_all_devices
(
ctx
,
&
i_devices
)
)
)
#endif
{
for
(
i
=
0
;
i
<
i_devices
;
i
++
)
{
#ifdef HAVE_HAL_1
if
(
!
libhal_device_property_exists
(
ctx
,
devices
[
i
],
"storage.cdrom.dvd"
,
NULL
)
)
#else
if
(
!
hal_device_property_exists
(
ctx
,
devices
[
i
],
"storage.cdrom.dvd"
)
)
#endif
{
continue
;
}
#ifdef HAVE_HAL_1
b_dvd
=
libhal_device_get_property_bool
(
ctx
,
devices
[
i
],
"storage.cdrom.dvd"
,
NULL
);
block_dev
=
libhal_device_get_property_string
(
ctx
,
devices
[
i
],
"block.device"
,
NULL
);
#else
b_dvd
=
hal_device_get_property_bool
(
ctx
,
devices
[
i
],
"storage.cdrom.dvd"
);
block_dev
=
hal_device_get_property_string
(
ctx
,
devices
[
i
],
"block.device"
);
#endif
if
(
b_dvd
)
{
config_PutPsz
(
p_vlc
,
"dvd"
,
block_dev
);
}
config_PutPsz
(
p_vlc
,
"vcd"
,
block_dev
);
config_PutPsz
(
p_vlc
,
"cd-audio"
,
block_dev
);
#ifdef HAVE_HAL_1
libhal_free_string
(
block_dev
);
#else
hal_free_string
(
block_dev
);
#endif
}
#ifdef HAVE_HAL_1
libhal_free_string_array
(
devices
);
#else
hal_free_string_array
(
devices
);
#endif
}
#ifdef HAVE_HAL_1
libhal_ctx_shutdown
(
ctx
,
NULL
);
dbus_connection_unref
(
p_connection
);
libhal_ctx_free
(
ctx
);
#else
hal_shutdown
(
ctx
);
#endif
}
else
{
msg_Warn
(
p_vlc
,
"Unable to get HAL device properties"
);
}
#else
(
void
)
p_vlc
;
#endif
/* HAVE_HAL */
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment