+
+/*****************************************************************************
+ * InheritValue: try to inherit the value of this variable from the same one
+ * in our closest parent.
+ *****************************************************************************/
+static int InheritValue( vlc_object_t *p_this, const char *psz_name,
+ vlc_value_t *p_val, int i_type )
+{
+ int i_var;
+ variable_t *p_var;
+
+ /* No need to take the structure lock,
+ * we are only looking for our parents */
+
+ if( !p_this->p_parent )
+ {
+ switch( i_type & VLC_VAR_TYPE )
+ {
+ case VLC_VAR_FILE:
+ case VLC_VAR_DIRECTORY:
+ case VLC_VAR_STRING:
+ case VLC_VAR_MODULE:
+ p_val->psz_string = config_GetPsz( p_this, psz_name );
+ if( !p_val->psz_string ) p_val->psz_string = strdup("");
+ break;
+ case VLC_VAR_FLOAT:
+ p_val->f_float = config_GetFloat( p_this, psz_name );
+ break;
+ case VLC_VAR_INTEGER:
+ case VLC_VAR_HOTKEY:
+ p_val->i_int = config_GetInt( p_this, psz_name );
+ break;
+ case VLC_VAR_BOOL:
+ p_val->b_bool = config_GetInt( p_this, psz_name );
+ break;
+ case VLC_VAR_LIST:
+ {
+ char *psz_orig, *psz_var;
+ vlc_list_t *p_list = malloc(sizeof(vlc_list_t));
+ p_val->p_list = p_list;
+ p_list->i_count = 0;
+
+ psz_var = psz_orig = config_GetPsz( p_this, psz_name );
+ while( psz_var && *psz_var )
+ {
+ char *psz_item = psz_var;
+ vlc_value_t val;
+ while( *psz_var && *psz_var != ',' ) psz_var++;
+ if( *psz_var == ',' )
+ {
+ *psz_var = '\0';
+ psz_var++;
+ }
+ val.i_int = strtol( psz_item, NULL, 0 );
+ INSERT_ELEM( p_list->p_values, p_list->i_count,
+ p_list->i_count, val );
+ /* p_list->i_count is incremented twice by INSERT_ELEM */
+ p_list->i_count--;
+ INSERT_ELEM( p_list->pi_types, p_list->i_count,
+ p_list->i_count, VLC_VAR_INTEGER );
+ }
+ free( psz_orig );
+ break;
+ }
+ default:
+ return VLC_ENOOBJ;
+ break;
+ }
+
+ return VLC_SUCCESS;
+ }
+
+ vlc_object_internals_t *p_priv = p_this->p_parent->p_internals;
+
+ /* Look for the variable */
+ vlc_mutex_lock( &p_priv->var_lock );
+
+ i_var = Lookup( p_priv->p_vars, p_priv->i_vars, psz_name );
+
+ if( i_var >= 0 )
+ {
+ /* We found it! */
+ p_var = &p_priv->p_vars[i_var];
+
+ /* Really get the variable */
+ *p_val = p_var->val;
+
+ /* Duplicate value if needed */
+ p_var->pf_dup( p_val );
+
+ vlc_mutex_unlock( &p_priv->var_lock );
+ return VLC_SUCCESS;
+ }
+
+ vlc_mutex_unlock( &p_priv->var_lock );
+
+ /* We're still not there */
+
+ return InheritValue( p_this->p_parent, psz_name, p_val, i_type );
+}
+
+/**********************************************************************
+ * Execute a var command on an object identified by its name
+ **********************************************************************/
+int __var_Command( vlc_object_t *p_this, const char *psz_name,
+ const char *psz_cmd, const char *psz_arg, char **psz_msg )
+{
+ vlc_object_t *p_obj = vlc_object_find_name( p_this->p_libvlc,
+ psz_name, FIND_CHILD );
+ int i_type, i_ret;
+
+ if( !p_obj )
+ {
+ if( psz_msg )
+ *psz_msg = strdup( "Unknown destination object." );
+ return VLC_ENOOBJ;
+ }
+
+ i_type = var_Type( p_obj, psz_cmd );
+ if( !( i_type&VLC_VAR_ISCOMMAND ) )
+ {
+ vlc_object_release( p_obj );
+ if( psz_msg )
+ *psz_msg = strdup( "Variable doesn't exist or isn't a command." );
+ return VLC_EGENERIC;
+ }
+
+ i_type &= 0xf0;
+ switch( i_type )
+ {
+ case VLC_VAR_INTEGER:
+ i_ret = var_SetInteger( p_obj, psz_cmd, atoi( psz_arg ) );
+ break;
+ case VLC_VAR_FLOAT:
+ i_ret = var_SetFloat( p_obj, psz_cmd, atof( psz_arg ) );
+ break;
+ case VLC_VAR_STRING:
+ i_ret = var_SetString( p_obj, psz_cmd, psz_arg );
+ break;
+ case VLC_VAR_BOOL:
+ i_ret = var_SetBool( p_obj, psz_cmd, atoi( psz_arg ) );
+ break;
+ default:
+ i_ret = VLC_EGENERIC;
+ break;
+ }
+
+ vlc_object_release( p_obj );
+
+ if( psz_msg )
+ {
+ *psz_msg = (char*)malloc( 80 );
+ sprintf( *psz_msg, "%s on object %s returned %i (%s)",
+ psz_cmd, psz_name, i_ret, vlc_error( i_ret ) );
+ }
+
+ return i_ret;
+}