X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fvariables.c;h=6f3e901cc9bc59e6cc3d590a43bceac8668d3957;hb=f90eeab1ee15fdcc7c4121d877c44eacf5cea3fb;hp=ce9f4a9f6caad90300d6c0e4cf3c33d113ff7757;hpb=69343b742ab5c63e5ab45997ce2927809afecc10;p=vlc diff --git a/src/misc/variables.c b/src/misc/variables.c index ce9f4a9f6c..6f3e901cc9 100644 --- a/src/misc/variables.c +++ b/src/misc/variables.c @@ -36,6 +36,8 @@ #include #include +#include +#include /***************************************************************************** * Private types @@ -49,12 +51,21 @@ struct callback_entry_t /***************************************************************************** * Local comparison functions, returns 0 if v == w, < 0 if v < w, > 0 if v > w *****************************************************************************/ -static int CmpBool( vlc_value_t v, vlc_value_t w ) { return v.b_bool ? w.b_bool ? 0 : 1 : w.b_bool ? -1 : 0; } -static int CmpInt( vlc_value_t v, vlc_value_t w ) { return v.i_int == w.i_int ? 0 : v.i_int > w.i_int ? 1 : -1; } +static int CmpBool( vlc_value_t v, vlc_value_t w ) +{ + return v.b_bool ? w.b_bool ? 0 : 1 : w.b_bool ? -1 : 0; +} + +static int CmpInt( vlc_value_t v, vlc_value_t w ) +{ + return v.i_int == w.i_int ? 0 : v.i_int > w.i_int ? 1 : -1; +} + static int CmpTime( vlc_value_t v, vlc_value_t w ) { return v.i_time == w.i_time ? 0 : v.i_time > w.i_time ? 1 : -1; } + static int CmpString( vlc_value_t v, vlc_value_t w ) { if( !v.psz_string ) @@ -74,41 +85,6 @@ static void DupString( vlc_value_t *p_val ) p_val->psz_string = strdup( p_val->psz_string ? p_val->psz_string : "" ); } -static void DupList( vlc_value_t *p_val ) -{ - int i; - vlc_list_t *p_list = malloc( sizeof(vlc_list_t) ); - - p_list->i_count = p_val->p_list->i_count; - if( p_val->p_list->i_count ) - { - p_list->p_values = malloc( p_list->i_count * sizeof(vlc_value_t) ); - p_list->pi_types = malloc( p_list->i_count * sizeof(int) ); - } - else - { - p_list->p_values = NULL; - p_list->pi_types = NULL; - } - - for( i = 0; i < p_list->i_count; i++ ) - { - p_list->p_values[i] = p_val->p_list->p_values[i]; - p_list->pi_types[i] = p_val->p_list->pi_types[i]; - switch( p_val->p_list->pi_types[i] & VLC_VAR_CLASS ) - { - case VLC_VAR_STRING: - - DupString( &p_list->p_values[i] ); - break; - default: - break; - } - } - - p_val->p_list = p_list; -} - static void FreeDummy( vlc_value_t *p_val ) { (void)p_val; /* unused */ } static void FreeString( vlc_value_t *p_val ) { free( p_val->psz_string ); } static void FreeMutex( vlc_value_t *p_val ) { vlc_mutex_destroy( (vlc_mutex_t*)p_val->p_address ); free( p_val->p_address ); } @@ -145,10 +121,10 @@ addr_ops = { CmpAddress, DupDummy, FreeDummy, }, bool_ops = { CmpBool, DupDummy, FreeDummy, }, float_ops = { CmpFloat, DupDummy, FreeDummy, }, int_ops = { CmpInt, DupDummy, FreeDummy, }, -list_ops = { CmpAddress, DupList, FreeList, }, mutex_ops = { CmpAddress, DupDummy, FreeMutex, }, string_ops = { CmpString, DupString, FreeString, }, -time_ops = { CmpTime, DupDummy, FreeDummy, }; +time_ops = { CmpTime, DupDummy, FreeDummy, }, +coords_ops = { NULL, DupDummy, FreeDummy, }; /***************************************************************************** * Local prototypes @@ -198,6 +174,7 @@ static void Destroy( variable_t *p_var ) free( p_var ); } +#undef var_Create /** * Initialize a vlc variable * @@ -210,9 +187,8 @@ static void Destroy( variable_t *p_var ) * \param i_type The variables type. Must be one of \ref var_type combined with * zero or more \ref var_flags */ -int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type ) +int var_Create( vlc_object_t *p_this, const char *psz_name, int i_type ) { - static vlc_list_t dummy_null_list = {0, NULL, NULL}; assert( p_this ); variable_t *p_var = calloc( 1, sizeof( *p_var ) ); @@ -261,6 +237,10 @@ int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type ) p_var->ops = &time_ops; p_var->val.i_time = 0; break; + case VLC_VAR_COORDS: + p_var->ops = &coords_ops; + p_var->val.coords.x = p_var->val.coords.y = 0; + break; case VLC_VAR_ADDRESS: p_var->ops = &addr_ops; p_var->val.p_address = NULL; @@ -270,14 +250,10 @@ int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type ) p_var->val.p_address = malloc( sizeof(vlc_mutex_t) ); vlc_mutex_init( (vlc_mutex_t*)p_var->val.p_address ); break; - case VLC_VAR_LIST: - p_var->ops = &list_ops; - p_var->val.p_list = &dummy_null_list; - break; default: p_var->ops = &void_ops; #ifndef NDEBUG - if( i_type & VLC_VAR_CLASS != VLC_VAR_VOID ) + if( (i_type & VLC_VAR_CLASS) != VLC_VAR_VOID ) msg_Err( p_this, "Creating the variable '%s' without a type", psz_name ); #endif @@ -332,6 +308,7 @@ int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type ) return ret; } +#undef var_Destroy /** * Destroy a vlc variable * @@ -341,7 +318,7 @@ int __var_Create( vlc_object_t *p_this, const char *psz_name, int i_type ) * \param p_this The object that holds the variable * \param psz_name The name of the variable */ -int __var_Destroy( vlc_object_t *p_this, const char *psz_name ) +int var_Destroy( vlc_object_t *p_this, const char *psz_name ) { variable_t *p_var; @@ -383,6 +360,7 @@ void var_DestroyAll( vlc_object_t *obj ) tdestroy( priv->var_root, CleanupVar ); } +#undef var_Change /** * Perform an action on a variable * @@ -392,8 +370,8 @@ void var_DestroyAll( vlc_object_t *obj ) * \param p_val First action parameter * \param p_val2 Second action parameter */ -int __var_Change( vlc_object_t *p_this, const char *psz_name, - int i_action, vlc_value_t *p_val, vlc_value_t *p_val2 ) +int var_Change( vlc_object_t *p_this, const char *psz_name, + int i_action, vlc_value_t *p_val, vlc_value_t *p_val2 ) { int i; variable_t *p_var; @@ -620,7 +598,7 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name, return VLC_SUCCESS; } - +#undef var_GetAndSet /** * Perform a Get and Set on a variable * @@ -630,14 +608,15 @@ int __var_Change( vlc_object_t *p_this, const char *psz_name, * \param p_val: The action parameter * \return vlc error codes */ -int __var_GetAndSet( vlc_object_t *p_this, const char *psz_name, int i_action, - vlc_value_t val ) +int var_GetAndSet( vlc_object_t *p_this, const char *psz_name, int i_action, + vlc_value_t *p_val ) { int i_ret; variable_t *p_var; vlc_value_t oldval; assert( p_this ); + assert( p_val ); vlc_object_internals_t *p_priv = vlc_internals( p_this ); @@ -660,13 +639,21 @@ int __var_GetAndSet( vlc_object_t *p_this, const char *psz_name, int i_action, /* depending of the action requiered */ switch( i_action ) { - case VLC_VAR_TOGGLE_BOOL: + case VLC_VAR_BOOL_TOGGLE: assert( ( p_var->i_type & VLC_VAR_BOOL ) == VLC_VAR_BOOL ); p_var->val.b_bool = !p_var->val.b_bool; break; - case VLC_VAR_INTEGER_INCDEC: + case VLC_VAR_INTEGER_ADD: + assert( ( p_var->i_type & VLC_VAR_INTEGER ) == VLC_VAR_INTEGER ); + p_var->val.i_int += p_val->i_int; + break; + case VLC_VAR_INTEGER_OR: assert( ( p_var->i_type & VLC_VAR_INTEGER ) == VLC_VAR_INTEGER ); - p_var->val.i_int += val.i_int; + p_var->val.i_int |= p_val->i_int; + break; + case VLC_VAR_INTEGER_NAND: + assert( ( p_var->i_type & VLC_VAR_INTEGER ) == VLC_VAR_INTEGER ); + p_var->val.i_int &= ~p_val->i_int; break; default: vlc_mutex_unlock( &p_priv->var_lock ); @@ -675,6 +662,7 @@ int __var_GetAndSet( vlc_object_t *p_this, const char *psz_name, int i_action, /* Check boundaries */ CheckValue( p_var, &p_var->val ); + *p_val = p_var->val; /* Deal with callbacks.*/ i_ret = TriggerCallback( p_this, p_var, psz_name, oldval ); @@ -684,7 +672,7 @@ int __var_GetAndSet( vlc_object_t *p_this, const char *psz_name, int i_action, return i_ret; } - +#undef var_Type /** * Request a variable's type * @@ -692,7 +680,7 @@ int __var_GetAndSet( vlc_object_t *p_this, const char *psz_name, int i_action, * variable could not be found. * \see \ref var_type */ -int __var_Type( vlc_object_t *p_this, const char *psz_name ) +int var_Type( vlc_object_t *p_this, const char *psz_name ) { variable_t *p_var; int i_type = 0; @@ -712,6 +700,7 @@ int __var_Type( vlc_object_t *p_this, const char *psz_name ) return i_type; } +#undef var_SetChecked int var_SetChecked( vlc_object_t *p_this, const char *psz_name, int expected_type, vlc_value_t val ) { @@ -734,6 +723,12 @@ int var_SetChecked( vlc_object_t *p_this, const char *psz_name, assert( expected_type == 0 || (p_var->i_type & VLC_VAR_CLASS) == expected_type ); +#ifndef NDEBUG + /* Alert if the type is VLC_VAR_VOID */ + if( ( p_var->i_type & VLC_VAR_TYPE ) == VLC_VAR_VOID ) + msg_Warn( p_this, "Calling var_Set on the void variable '%s' (0x%04x)", psz_name, p_var->i_type ); +#endif + WaitUnused( p_this, p_var ); @@ -760,7 +755,7 @@ int var_SetChecked( vlc_object_t *p_this, const char *psz_name, return i_ret; } - +#undef var_Set /** * Set a variable's value * @@ -768,11 +763,12 @@ int var_SetChecked( vlc_object_t *p_this, const char *psz_name, * \param psz_name The name of the variable * \param val the value to set */ -int __var_Set( vlc_object_t *p_this, const char *psz_name, vlc_value_t val ) +int var_Set( vlc_object_t *p_this, const char *psz_name, vlc_value_t val ) { return var_SetChecked( p_this, psz_name, 0, val ); } +#undef var_GetChecked int var_GetChecked( vlc_object_t *p_this, const char *psz_name, int expected_type, vlc_value_t *p_val ) { @@ -796,7 +792,7 @@ int var_GetChecked( vlc_object_t *p_this, const char *psz_name, #ifndef NDEBUG /* Alert if the type is VLC_VAR_VOID */ if( ( p_var->i_type & VLC_VAR_TYPE ) == VLC_VAR_VOID ) - msg_Warn( p_this, "Calling var_GetVoid on the void variable '%s' (0x%04x)", psz_name, p_var->i_type ); + msg_Warn( p_this, "Calling var_Get on the void variable '%s' (0x%04x)", psz_name, p_var->i_type ); #endif /* Duplicate value if needed */ @@ -809,6 +805,7 @@ int var_GetChecked( vlc_object_t *p_this, const char *psz_name, return err; } +#undef var_Get /** * Get a variable's value * @@ -817,11 +814,12 @@ int var_GetChecked( vlc_object_t *p_this, const char *psz_name, * \param p_val Pointer to a vlc_value_t that will hold the variable's value * after the function is finished */ -int __var_Get( vlc_object_t *p_this, const char *psz_name, vlc_value_t *p_val ) +int var_Get( vlc_object_t *p_this, const char *psz_name, vlc_value_t *p_val ) { return var_GetChecked( p_this, psz_name, 0, p_val ); } +#undef var_AddCallback /** * Register a callback in a variable * @@ -838,8 +836,8 @@ int __var_Get( vlc_object_t *p_this, const char *psz_name, vlc_value_t *p_val ) * the variable. Use proper locking. This thread may not have much * time to spare, so keep callback functions short. */ -int __var_AddCallback( vlc_object_t *p_this, const char *psz_name, - vlc_callback_t pf_callback, void *p_data ) +int var_AddCallback( vlc_object_t *p_this, const char *psz_name, + vlc_callback_t pf_callback, void *p_data ) { variable_t *p_var; callback_entry_t entry; @@ -875,14 +873,15 @@ int __var_AddCallback( vlc_object_t *p_this, const char *psz_name, return VLC_SUCCESS; } +#undef var_DelCallback /** * Remove a callback from a variable * * pf_callback and p_data have to be given again, because different objects * might have registered the same callback function. */ -int __var_DelCallback( vlc_object_t *p_this, const char *psz_name, - vlc_callback_t pf_callback, void *p_data ) +int var_DelCallback( vlc_object_t *p_this, const char *psz_name, + vlc_callback_t pf_callback, void *p_data ) { int i_entry; variable_t *p_var; @@ -937,13 +936,14 @@ int __var_DelCallback( vlc_object_t *p_this, const char *psz_name, return VLC_SUCCESS; } +#undef var_TriggerCallback /** * Trigger callback on a variable * * \param p_this The object that hold the variable * \param psz_name The name of the variable */ -int __var_TriggerCallback( vlc_object_t *p_this, const char *psz_name ) +int var_TriggerCallback( vlc_object_t *p_this, const char *psz_name ) { int i_ret; variable_t *p_var; @@ -1007,12 +1007,7 @@ void var_OptionParse( vlc_object_t *p_obj, const char *psz_option, if( psz_value != NULL ) *psz_value++ = '\0'; - /* FIXME: :programs should be handled generically */ - if( !strcmp( psz_name, "programs" ) ) - i_type = VLC_VAR_LIST; - else - i_type = config_GetType( p_obj, psz_name ); - + i_type = config_GetType( p_obj, psz_name ); if( !i_type && !psz_value ) { /* check for "no-foo" or "nofoo" */ @@ -1050,7 +1045,7 @@ void var_OptionParse( vlc_object_t *p_obj, const char *psz_option, /* Create the variable in the input object. * Children of the input object will be able to retreive this value * thanks to the inheritance property of the object variables. */ - __var_Create( p_obj, psz_name, i_type ); + var_Create( p_obj, psz_name, i_type ); switch( i_type ) { @@ -1073,45 +1068,11 @@ void var_OptionParse( vlc_object_t *p_obj, const char *psz_option, val.psz_string = psz_value; break; - case VLC_VAR_LIST: - { - char *psz_orig, *psz_var; - vlc_list_t *p_list = malloc(sizeof(vlc_list_t)); - val.p_list = p_list; - p_list->i_count = 0; - - psz_var = psz_orig = strdup(psz_value); - while( psz_var && *psz_var ) - { - char *psz_item = psz_var; - vlc_value_t val2; - while( *psz_var && *psz_var != ',' ) psz_var++; - if( *psz_var == ',' ) - { - *psz_var = '\0'; - psz_var++; - } - val2.i_int = strtol( psz_item, NULL, 0 ); - INSERT_ELEM( p_list->p_values, p_list->i_count, - p_list->i_count, val2 ); - /* 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: goto cleanup; } - __var_Set( p_obj, psz_name, val ); - - /* If that's a list, remove all elements allocated */ - if( i_type == VLC_VAR_LIST ) - FreeList( &val ); + var_Set( p_obj, psz_name, val ); cleanup: free( psz_name ); @@ -1264,35 +1225,6 @@ int var_Inherit( vlc_object_t *p_this, const char *psz_name, int i_type, 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: msg_Warn( p_this, "Could not inherit value for var %s " "from config. Invalid Type", psz_name ); @@ -1303,6 +1235,57 @@ int var_Inherit( vlc_object_t *p_this, const char *psz_name, int i_type, } +/** + * It inherits a string as an unsigned rational number (it also accepts basic + * float number). + * + * It returns an error if the rational number cannot be parsed (0/0 is valid). + * The rational is already reduced. + */ +int (var_InheritURational)(vlc_object_t *object, + unsigned *num, unsigned *den, + const char *var) +{ + /* */ + *num = 0; + *den = 0; + + /* */ + char *tmp = var_InheritString(object, var); + if (!tmp) + goto error; + + char *next; + unsigned n = strtol(tmp, &next, 0); + unsigned d = strtol(*next ? &next[1] : "0", NULL, 0); + + if (*next == '.') { + /* Interpret as a float number */ + double r = us_atof(tmp); + double c = ceil(r); + if (c >= UINT_MAX) + goto error; + unsigned m = c; + if (m > 0) { + d = UINT_MAX / m; + n = r * d; + } else { + n = 0; + d = 0; + } + } + + if (n > 0 && d > 0) + vlc_ureduce(num, den, n, d, 0); + + free(tmp); + return VLC_SUCCESS; + +error: + free(tmp); + return VLC_EGENERIC; +} + /********************************************************************** * Trigger the callbacks. * Tell we're in a callback, release the lock, call stored functions, @@ -1338,12 +1321,12 @@ static int TriggerCallback( vlc_object_t *p_this, variable_t *p_var, return VLC_SUCCESS; } - +#undef var_Command /********************************************************************** * 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 ) +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 );