Commit 79c1ddfd authored by Antoine Cellerier's avatar Antoine Cellerier

* Make it possible to give names to vlc objects (psz_object_name

already existed but was only used by modules as far as is know). This
is done in the module_Need function. Needed module names now have this
syntax: '<module>[@<name>]'. If the @<name> part is present, once the
needed module is found it will change p_this->psz_object_name to <name>.
In about 99% of the module_Need calls, p_this is the module's parent
object so this is ok. The remaining calls won't use this syntax so it's
ok i guess :)

* Add new vlc_object_find_name function. It works like vlc_object_find
but uses a string (name) instead of an integer (type) as its second
argument.

* Change the marq, mosaic and logo commands in rc.c. They now take the
target object's name as first argument. Example:

Launch vlc with:
./vlc -I rc --no-audio --sub-filter "marq@test{marquee=Hello}:marq@testouille{marquee=Test}" ~/media/redefined-nintendo.mpg

Then issue the following command to move the second marq:
marq-x testouille 100

(and while testing I fixed #745)
parent cafb1863
......@@ -101,6 +101,7 @@ VLC_EXPORT( void, __vlc_object_attach, ( vlc_object_t *, vlc_object_t * ) );
VLC_EXPORT( void, __vlc_object_detach, ( vlc_object_t * ) );
VLC_EXPORT( void *, __vlc_object_get, ( vlc_object_t *, int ) );
VLC_EXPORT( void *, __vlc_object_find, ( vlc_object_t *, int, int ) );
VLC_EXPORT( void *, __vlc_object_find_name, ( vlc_object_t *, const char *, int ) );
VLC_EXPORT( void, __vlc_object_yield, ( vlc_object_t * ) );
VLC_EXPORT( void, __vlc_object_release, ( vlc_object_t * ) );
VLC_EXPORT( vlc_list_t *, __vlc_list_find, ( vlc_object_t *, int, int ) );
......@@ -128,6 +129,9 @@ VLC_EXPORT( libvlc_int_t *, vlc_current_object, ( int ) );
#define vlc_object_find(a,b,c) \
__vlc_object_find( VLC_OBJECT(a),b,c)
#define vlc_object_find_name(a,b,c) \
__vlc_object_find_name( VLC_OBJECT(a),b,c)
#define vlc_object_yield(a) \
__vlc_object_yield( VLC_OBJECT(a) )
......
......@@ -841,94 +841,94 @@ static void Help( intf_thread_t *p_intf, vlc_bool_t b_longhelp)
{
msg_rc(_("+----[ Remote control commands ]"));
msg_rc( "| ");
msg_rc(_("| add XYZ . . . . . . . . . . add XYZ to playlist"));
msg_rc(_("| enqueue XYZ . . . . . . . queue XYZ to playlist"));
msg_rc(_("| playlist . . . show items currently in playlist"));
msg_rc(_("| play . . . . . . . . . . . . . . . . play stream"));
msg_rc(_("| stop . . . . . . . . . . . . . . . . stop stream"));
msg_rc(_("| next . . . . . . . . . . . . next playlist item"));
msg_rc(_("| prev . . . . . . . . . . previous playlist item"));
msg_rc(_("| goto . . . . . . . . . . . . goto item at index"));
msg_rc(_("| repeat [on|off] . . toggle playlist item repeat"));
msg_rc(_("| loop [on|off] . . . . toggle playlist item loop"));
msg_rc(_("| clear . . . . . . . . . . . clear the playlist"));
msg_rc(_("| status . . . . . . . . . current playlist status"));
msg_rc(_("| title [X] . . . . set/get title in current item"));
msg_rc(_("| title_n . . . . . . next title in current item"));
msg_rc(_("| title_p . . . . previous title in current item"));
msg_rc(_("| chapter [X] . . set/get chapter in current item"));
msg_rc(_("| chapter_n . . . . next chapter in current item"));
msg_rc(_("| chapter_p . . previous chapter in current item"));
msg_rc(_("| add XYZ . . . . . . . . . . . . add XYZ to playlist"));
msg_rc(_("| enqueue XYZ . . . . . . . . . queue XYZ to playlist"));
msg_rc(_("| playlist . . . . . show items currently in playlist"));
msg_rc(_("| play . . . . . . . . . . . . . . . . . . play stream"));
msg_rc(_("| stop . . . . . . . . . . . . . . . . . . stop stream"));
msg_rc(_("| next . . . . . . . . . . . . . . next playlist item"));
msg_rc(_("| prev . . . . . . . . . . . . previous playlist item"));
msg_rc(_("| goto . . . . . . . . . . . . . . goto item at index"));
msg_rc(_("| repeat [on|off] . . . . toggle playlist item repeat"));
msg_rc(_("| loop [on|off] . . . . . . toggle playlist item loop"));
msg_rc(_("| clear . . . . . . . . . . . . . clear the playlist"));
msg_rc(_("| status . . . . . . . . . . . current playlist status"));
msg_rc(_("| title [X] . . . . . . set/get title in current item"));
msg_rc(_("| title_n . . . . . . . . next title in current item"));
msg_rc(_("| title_p . . . . . . previous title in current item"));
msg_rc(_("| chapter [X] . . . . set/get chapter in current item"));
msg_rc(_("| chapter_n . . . . . . next chapter in current item"));
msg_rc(_("| chapter_p . . . . previous chapter in current item"));
msg_rc( "| ");
msg_rc(_("| seek X . seek in seconds, for instance `seek 12'"));
msg_rc(_("| pause . . . . . . . . . . . . . . toggle pause"));
msg_rc(_("| fastforward . . . . . . . set to maximum rate"));
msg_rc(_("| rewind . . . . . . . . . . set to minimum rate"));
msg_rc(_("| faster . . . . . . . . faster playing of stream"));
msg_rc(_("| slower . . . . . . . . slower playing of stream"));
msg_rc(_("| normal . . . . . . . . normal playing of stream"));
msg_rc(_("| f [on|off] . . . . . . . . . . toggle fullscreen"));
msg_rc(_("| info . . . information about the current stream"));
msg_rc(_("| seek X . . . seek in seconds, for instance `seek 12'"));
msg_rc(_("| pause . . . . . . . . . . . . . . . . toggle pause"));
msg_rc(_("| fastforward . . . . . . . . . set to maximum rate"));
msg_rc(_("| rewind . . . . . . . . . . . . set to minimum rate"));
msg_rc(_("| faster . . . . . . . . . . faster playing of stream"));
msg_rc(_("| slower . . . . . . . . . . slower playing of stream"));
msg_rc(_("| normal . . . . . . . . . . normal playing of stream"));
msg_rc(_("| f [on|off] . . . . . . . . . . . . toggle fullscreen"));
msg_rc(_("| info . . . . . information about the current stream"));
msg_rc(_("| get_time . . seconds elapsed since stream's beginning"));
msg_rc(_("| is_playing . . 1 if a stream plays, 0 otherwise"));
msg_rc(_("| get_title . . . the title of the current stream"));
msg_rc(_("| get_length . . the length of the current stream"));
msg_rc(_("| is_playing . . . . 1 if a stream plays, 0 otherwise"));
msg_rc(_("| get_title . . . . . the title of the current stream"));
msg_rc(_("| get_length . . . . the length of the current stream"));
msg_rc( "| ");
msg_rc(_("| volume [X] . . . . . . . . set/get audio volume"));
msg_rc(_("| volup [X] . . . . . raise audio volume X steps"));
msg_rc(_("| voldown [X] . . . . lower audio volume X steps"));
msg_rc(_("| adev [X] . . . . . . . . . set/get audio device"));
msg_rc(_("| achan [X]. . . . . . . . set/get audio channels"));
msg_rc(_("| atrack [X] . . . . . . . . . set/get audio track"));
msg_rc(_("| vtrack [X] . . . . . . . . . set/get video track"));
msg_rc(_("| vratio [X] . . . . . set/get video aspect ratio"));
msg_rc(_("| vcrop [X] . . . . . . . . . set/get video crop"));
msg_rc(_("| vzoom [X] . . . . . . . . . set/get video zoom"));
msg_rc(_("| strack [X] . . . . . . . set/get subtitles track"));
msg_rc(_("| key [hotkey name] . . . . simulate hotkey press"));
msg_rc(_("| menu [on|off|up|down|left|right|select] use menu"));
msg_rc(_("| volume [X] . . . . . . . . . . set/get audio volume"));
msg_rc(_("| volup [X] . . . . . . . raise audio volume X steps"));
msg_rc(_("| voldown [X] . . . . . . lower audio volume X steps"));
msg_rc(_("| adev [X] . . . . . . . . . . . set/get audio device"));
msg_rc(_("| achan [X]. . . . . . . . . . set/get audio channels"));
msg_rc(_("| atrack [X] . . . . . . . . . . . set/get audio track"));
msg_rc(_("| vtrack [X] . . . . . . . . . . . set/get video track"));
msg_rc(_("| vratio [X] . . . . . . . set/get video aspect ratio"));
msg_rc(_("| vcrop [X] . . . . . . . . . . . set/get video crop"));
msg_rc(_("| vzoom [X] . . . . . . . . . . . set/get video zoom"));
msg_rc(_("| strack [X] . . . . . . . . . set/get subtitles track"));
msg_rc(_("| key [hotkey name] . . . . . . simulate hotkey press"));
msg_rc(_("| menu . . [on|off|up|down|left|right|select] use menu"));
msg_rc( "| ");
if (b_longhelp)
{
msg_rc(_("| marq-marquee STRING . . overlay STRING in video"));
msg_rc(_("| marq-x X . . . . . . . . . . . .offset from left"));
msg_rc(_("| marq-y Y . . . . . . . . . . . . offset from top"));
msg_rc(_("| marq-position #. . . .relative position control"));
msg_rc(_("| marq-color # . . . . . . . . . . font color, RGB"));
msg_rc(_("| marq-opacity # . . . . . . . . . . . . . opacity"));
msg_rc(_("| marq-timeout T. . . . . . . . . . timeout, in ms"));
msg_rc(_("| marq-size # . . . . . . . . font size, in pixels"));
msg_rc(_("| marq-marquee name STRING . . overlay STRING in video"));
msg_rc(_("| marq-x name X . . . . . . . . . . . .offset from left"));
msg_rc(_("| marq-y name Y . . . . . . . . . . . . offset from top"));
msg_rc(_("| marq-position name #. . . .relative position control"));
msg_rc(_("| marq-color name # . . . . . . . . . . font color, RGB"));
msg_rc(_("| marq-opacity name # . . . . . . . . . . . . . opacity"));
msg_rc(_("| marq-timeout name T. . . . . . . . . . timeout, in ms"));
msg_rc(_("| marq-size name # . . . . . . . . font size, in pixels"));
msg_rc( "| ");
msg_rc(_("| logo-file STRING . . .the overlay file path/name"));
msg_rc(_("| logo-x X . . . . . . . . . . . .offset from left"));
msg_rc(_("| logo-y Y . . . . . . . . . . . . offset from top"));
msg_rc(_("| logo-position #. . . . . . . . relative position"));
msg_rc(_("| logo-transparency #. . . . . . . . .transparency"));
msg_rc(_("| logo-file name STRING . . .the overlay file path/name"));
msg_rc(_("| logo-x name X . . . . . . . . . . . .offset from left"));
msg_rc(_("| logo-y name Y . . . . . . . . . . . . offset from top"));
msg_rc(_("| logo-position name #. . . . . . . . relative position"));
msg_rc(_("| logo-transparency name #. . . . . . . . .transparency"));
msg_rc( "| ");
msg_rc(_("| mosaic-alpha # . . . . . . . . . . . . . . alpha"));
msg_rc(_("| mosaic-height #. . . . . . . . . . . . . .height"));
msg_rc(_("| mosaic-width # . . . . . . . . . . . . . . width"));
msg_rc(_("| mosaic-xoffset # . . . .top left corner position"));
msg_rc(_("| mosaic-yoffset # . . . .top left corner position"));
msg_rc(_("| mosaic-offsets x,y(,x,y)*. . . . list of offsets"));
msg_rc(_("| mosaic-align 0..2,4..6,8..10. . .mosaic alignment"));
msg_rc(_("| mosaic-vborder # . . . . . . . . vertical border"));
msg_rc(_("| mosaic-hborder # . . . . . . . horizontal border"));
msg_rc(_("| mosaic-position {0=auto,1=fixed} . . . .position"));
msg_rc(_("| mosaic-rows #. . . . . . . . . . .number of rows"));
msg_rc(_("| mosaic-cols #. . . . . . . . . . .number of cols"));
msg_rc(_("| mosaic-order id(,id)* . . . . order of pictures "));
msg_rc(_("| mosaic-keep-aspect-ratio {0,1} . . .aspect ratio"));
msg_rc(_("| mosaic-alpha name # . . . . . . . . . . . . . . alpha"));
msg_rc(_("| mosaic-height name #. . . . . . . . . . . . . .height"));
msg_rc(_("| mosaic-width name # . . . . . . . . . . . . . . width"));
msg_rc(_("| mosaic-xoffset name # . . . .top left corner position"));
msg_rc(_("| mosaic-yoffset name # . . . .top left corner position"));
msg_rc(_("| mosaic-offsets name x,y(,x,y)*. . . . list of offsets"));
msg_rc(_("| mosaic-align name 0..2,4..6,8..10. . .mosaic alignment"));
msg_rc(_("| mosaic-vborder name # . . . . . . . . vertical border"));
msg_rc(_("| mosaic-hborder name # . . . . . . . horizontal border"));
msg_rc(_("| mosaic-position name {0=auto,1=fixed} . . . .position"));
msg_rc(_("| mosaic-rows name #. . . . . . . . . . .number of rows"));
msg_rc(_("| mosaic-cols name #. . . . . . . . . . .number of cols"));
msg_rc(_("| mosaic-order name id(,id)* . . . . order of pictures "));
msg_rc(_("| mosaic-keep-aspect-ratio name {0,1} . . .aspect ratio"));
msg_rc( "| ");
msg_rc(_("| check-updates [newer] [equal] [older]\n"
"| [undef] [info] [source] [binary] [plugin]"));
msg_rc( "| ");
}
msg_rc(_("| help . . . . . . . . . . . . . this help message"));
msg_rc(_("| longhelp . . . . . . . . . a longer help message"));
msg_rc(_("| logout . . . . . exit (if in socket connection)"));
msg_rc(_("| quit . . . . . . . . . . . . . . . . . quit vlc"));
msg_rc(_("| help . . . . . . . . . . . . . . . this help message"));
msg_rc(_("| longhelp . . . . . . . . . . . a longer help message"));
msg_rc(_("| logout . . . . . . . exit (if in socket connection)"));
msg_rc(_("| quit . . . . . . . . . . . . . . . . . . . quit vlc"));
msg_rc( "| ");
msg_rc(_("+----[ end of help ]"));
}
......@@ -1472,8 +1472,10 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd,
}
/* Parse miscellaneous commands */
if( newval.psz_string )
{
static const char vars[] =
"marq-marquee\0"
"marq-x\0" "marq-y\0" "marq-position\0" "marq-color\0"
"marq-opacity\0" "marq-size\0" "marq-timeout\0"
"mosaic-alpha\0" "mosaic-height\0" "mosaic-width\0"
......@@ -1484,31 +1486,57 @@ static int Other( vlc_object_t *p_this, char const *psz_cmd,
"logo-file\0" "logo-x\0" "logo-y\0" "logo-position\0"
"logo-transparency\0";
const char *psz_name = NULL;
char *psz_alias = strdup( newval.psz_string );
char *psz_arg = strchr( psz_alias, ' ' );
if( newval.psz_string )
for( psz_name = vars; *psz_name; psz_name += strlen( psz_name ) + 1 )
if( !psz_arg )
{
if( strcmp( psz_name, psz_cmd ) == 0 )
msg_rc( "Missing second argument." );
}
else
{
*psz_arg = '\0';
psz_arg ++;
for( psz_name = vars; *psz_name; psz_name += strlen( psz_name )+1 )
{
int i_type = var_Type( p_input->p_libvlc_global, psz_name );
if( i_type & VLC_VAR_INTEGER )
if( !strcmp( psz_name, psz_cmd ) )
{
var_SetInteger( p_input->p_libvlc_global, psz_name,
atoi( newval.psz_string ) );
break;
}
else if( i_type & VLC_VAR_STRING )
{
var_SetString( p_input->p_libvlc_global, psz_name,
newval.psz_string );
int i_type;
vlc_object_t *p_obj =
vlc_object_find_name( p_input->p_libvlc, psz_alias,
FIND_CHILD );
if( !p_obj )
{
msg_rc( "Unknown destination object!" );
break;
}
i_type = var_Type( p_obj, psz_name );
if( i_type & VLC_VAR_INTEGER )
{
var_SetInteger( p_obj, psz_name,
atoi( psz_arg ) );
}
else if( i_type & VLC_VAR_STRING )
{
var_SetString( p_obj, psz_name,
psz_arg );
}
vlc_object_release( p_obj );
break;
}
}
}
if( *psz_name == '\0' )
msg_rc( "Unknown command!" );
if( *psz_name == '\0' )
msg_rc( "Unknown command!" );
}
free( psz_alias );
}
else
{
msg_rc( "Incomplete command!" );
}
vlc_object_release( p_playlist );
......
......@@ -428,7 +428,7 @@ module_t * __module_Need( vlc_object_t *p_this, const char *psz_capability,
module_t *p_module;
int i_shortcuts = 0;
char *psz_shortcuts = NULL, *psz_var = NULL;
char *psz_shortcuts = NULL, *psz_var = NULL, *psz_alias = NULL;
vlc_bool_t b_force_backup = p_this->b_force;
......@@ -523,9 +523,15 @@ module_t * __module_Need( vlc_object_t *p_this, const char *psz_capability,
{
for( unsigned i = 0; p_module->pp_shortcuts[i]; i++ )
{
if( !strcasecmp( psz_name, p_module->pp_shortcuts[i] ) )
char *c;
if( ( c = strchr( psz_name, '@' ) )
? !strncasecmp( psz_name, p_module->pp_shortcuts[i],
c-psz_name )
: !strcasecmp( psz_name, p_module->pp_shortcuts[i] ) )
{
/* Found it */
if( c && c[1] )
psz_alias = c+1;
i_shortcut_bonus = i_short * 10000;
goto found_shortcut;
}
......@@ -705,6 +711,12 @@ found_shortcut:
else
msg_StackSet( VLC_EGENERIC, "no suitable %s module", psz_capability );
if( psz_alias && !p_this->psz_object_name )
/* This assumes that p_this is the object which will be using the
* module. That's not always the case ... but it is in most cases.
*/
p_this->psz_object_name = strdup( psz_alias );
if( psz_shortcuts )
{
free( psz_shortcuts );
......
......@@ -71,6 +71,7 @@ static int DumpCommand( vlc_object_t *, char const *,
vlc_value_t, vlc_value_t, void * );
static vlc_object_t * FindObject ( vlc_object_t *, int, int );
static vlc_object_t * FindObjectName( vlc_object_t *, const char *, int );
static void DetachObject ( vlc_object_t * );
static void PrintObject ( vlc_object_t *, const char * );
static void DumpStructure ( vlc_object_t *, int, char * );
......@@ -557,6 +558,60 @@ void * __vlc_object_find( vlc_object_t *p_this, int i_type, int i_mode )
return p_found;
}
/**
****************************************************************************
* find a named object and increment its refcount
*****************************************************************************
* This function recursively looks for a given object name. i_mode can be one
* of FIND_PARENT, FIND_CHILD or FIND_ANYWHERE.
*****************************************************************************/
void * __vlc_object_find_name( vlc_object_t *p_this, const char *psz_name,
int i_mode )
{
vlc_object_t *p_found;
vlc_mutex_lock( &structure_lock );
/* If have the requested name ourselves, don't look further */
if( !(i_mode & FIND_STRICT)
&& p_this->psz_object_name
&& !strcmp( p_this->psz_object_name, psz_name ) )
{
p_this->i_refcount++;
vlc_mutex_unlock( &structure_lock );
return p_this;
}
/* Otherwise, recursively look for the object */
if( (i_mode & 0x000f) == FIND_ANYWHERE )
{
vlc_object_t *p_root = p_this;
/* Find the root */
while( p_root->p_parent != NULL &&
p_root != VLC_OBJECT( p_this->p_libvlc ) )
{
p_root = p_root->p_parent;
}
p_found = FindObjectName( p_root, psz_name,
(i_mode & ~0x000f)|FIND_CHILD );
if( p_found == NULL && p_root != VLC_OBJECT( p_this->p_libvlc ) )
{
p_found = FindObjectName( VLC_OBJECT( p_this->p_libvlc ),
psz_name, (i_mode & ~0x000f)|FIND_CHILD );
}
}
else
{
p_found = FindObjectName( p_this, psz_name, i_mode );
}
vlc_mutex_unlock( &structure_lock );
return p_found;
}
/**
****************************************************************************
* increment an object refcount
......@@ -974,6 +1029,61 @@ static vlc_object_t * FindObject( vlc_object_t *p_this, int i_type, int i_mode )
return NULL;
}
static vlc_object_t * FindObjectName( vlc_object_t *p_this,
const char *psz_name,
int i_mode )
{
int i;
vlc_object_t *p_tmp;
switch( i_mode & 0x000f )
{
case FIND_PARENT:
p_tmp = p_this->p_parent;
if( p_tmp )
{
if( p_tmp->psz_object_name
&& !strcmp( p_tmp->psz_object_name, psz_name ) )
{
p_tmp->i_refcount++;
return p_tmp;
}
else
{
return FindObjectName( p_tmp, psz_name, i_mode );
}
}
break;
case FIND_CHILD:
for( i = p_this->i_children; i--; )
{
p_tmp = p_this->pp_children[i];
if( p_tmp->psz_object_name
&& !strcmp( p_tmp->psz_object_name, psz_name ) )
{
p_tmp->i_refcount++;
return p_tmp;
}
else if( p_tmp->i_children )
{
p_tmp = FindObjectName( p_tmp, psz_name, i_mode );
if( p_tmp )
{
return p_tmp;
}
}
}
break;
case FIND_ANYWHERE:
/* Handled in vlc_object_find */
break;
}
return NULL;
}
static void DetachObject( vlc_object_t *p_this )
{
vlc_object_t *p_parent = p_this->p_parent;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment