Exemple #1
0
/**
 * Perform an action on a variable
 *
 * \param p_this The object that holds the variable
 * \param psz_name The name of the variable
 * \param i_action The action to perform. Must be one of \ref var_action
 * \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 ret = VLC_SUCCESS;
    variable_t *p_var;
    vlc_value_t oldval;
    vlc_value_t newval;

    assert( p_this );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
        vlc_mutex_unlock( &p_priv->var_lock );
        return VLC_ENOVAR;
    }

    switch( i_action )
    {
        case VLC_VAR_GETMIN:
            *p_val = p_var->min;
            break;
        case VLC_VAR_GETMAX:
            *p_val = p_var->max;
            break;
        case VLC_VAR_SETMINMAX:
            assert(p_var->ops->pf_free == FreeDummy);
            p_var->min = *p_val;
            p_var->max = *p_val2;
            break;
        case VLC_VAR_SETSTEP:
            assert(p_var->ops->pf_free == FreeDummy);
            p_var->step = *p_val;
            CheckValue( p_var, &p_var->val );
            break;
        case VLC_VAR_GETSTEP:
            switch (p_var->i_type & VLC_VAR_TYPE)
            {
                case VLC_VAR_INTEGER:
                    if (p_var->step.i_int == 0)
                        ret = VLC_EGENERIC;
                    break;
                case VLC_VAR_FLOAT:
                    if (p_var->step.f_float == 0.f)
                        ret = VLC_EGENERIC;
                    break;
                default:
                    ret = VLC_EGENERIC;
            }
            if (ret == VLC_SUCCESS)
                *p_val = p_var->step;
            break;
        case VLC_VAR_ADDCHOICE:
        {
            int i = p_var->choices.i_count;

            TAB_APPEND(p_var->choices.i_count,
                       p_var->choices.p_values, *p_val);
            assert(i == p_var->choices_text.i_count);
            TAB_APPEND(p_var->choices_text.i_count,
                       p_var->choices_text.p_values, *p_val);
            p_var->ops->pf_dup( &p_var->choices.p_values[i] );
            p_var->choices_text.p_values[i].psz_string =
                ( p_val2 && p_val2->psz_string ) ?
                strdup( p_val2->psz_string ) : NULL;

            TriggerListCallback(p_this, p_var, psz_name, VLC_VAR_ADDCHOICE, p_val);
            break;
        }
        case VLC_VAR_DELCHOICE:
        {
            int i;

            for( i = 0 ; i < p_var->choices.i_count ; i++ )
                if( p_var->ops->pf_cmp( p_var->choices.p_values[i], *p_val ) == 0 )
                    break;

            if( i == p_var->choices.i_count )
            {
                /* Not found */
                vlc_mutex_unlock( &p_priv->var_lock );
                return VLC_EGENERIC;
            }

            p_var->ops->pf_free( &p_var->choices.p_values[i] );
            free( p_var->choices_text.p_values[i].psz_string );
            TAB_ERASE(p_var->choices.i_count, p_var->choices.p_values, i);
            TAB_ERASE(p_var->choices_text.i_count,
                      p_var->choices_text.p_values, i);

            TriggerListCallback(p_this, p_var, psz_name, VLC_VAR_DELCHOICE, p_val);
            break;
        }
        case VLC_VAR_CHOICESCOUNT:
            p_val->i_int = p_var->choices.i_count;
            break;
        case VLC_VAR_CLEARCHOICES:
            for( int i = 0 ; i < p_var->choices.i_count ; i++ )
                p_var->ops->pf_free( &p_var->choices.p_values[i] );
            for( int i = 0 ; i < p_var->choices_text.i_count ; i++ )
                free( p_var->choices_text.p_values[i].psz_string );

            if( p_var->choices.i_count ) free( p_var->choices.p_values );
            if( p_var->choices_text.i_count ) free( p_var->choices_text.p_values );

            p_var->choices.i_count = 0;
            p_var->choices.p_values = NULL;
            p_var->choices_text.i_count = 0;
            p_var->choices_text.p_values = NULL;
            TriggerListCallback(p_this, p_var, psz_name, VLC_VAR_CLEARCHOICES, NULL);
            break;
        case VLC_VAR_SETVALUE:
            /* Duplicate data if needed */
            newval = *p_val;
            p_var->ops->pf_dup( &newval );
            /* Backup needed stuff */
            oldval = p_var->val;
            /* Check boundaries and list */
            CheckValue( p_var, &newval );
            /* Set the variable */
            p_var->val = newval;
            /* Free data if needed */
            p_var->ops->pf_free( &oldval );
            break;
        case VLC_VAR_GETCHOICES:
            p_val->p_list = xmalloc( sizeof(vlc_list_t) );
            p_val->p_list->p_values =
                xmalloc( p_var->choices.i_count * sizeof(vlc_value_t) );
            p_val->p_list->i_type = p_var->i_type;
            p_val->p_list->i_count = p_var->choices.i_count;
            if( p_val2 )
            {
                p_val2->p_list = xmalloc( sizeof(vlc_list_t) );
                p_val2->p_list->p_values =
                    xmalloc( p_var->choices.i_count * sizeof(vlc_value_t) );
                p_val2->p_list->i_type = VLC_VAR_STRING;
                p_val2->p_list->i_count = p_var->choices.i_count;
            }
            for( int i = 0 ; i < p_var->choices.i_count ; i++ )
            {
                p_val->p_list->p_values[i] = p_var->choices.p_values[i];
                p_var->ops->pf_dup( &p_val->p_list->p_values[i] );
                if( p_val2 )
                {
                    p_val2->p_list->p_values[i].psz_string =
                        p_var->choices_text.p_values[i].psz_string ?
                    strdup(p_var->choices_text.p_values[i].psz_string) : NULL;
                }
            }
            break;
        case VLC_VAR_SETTEXT:
            free( p_var->psz_text );
            if( p_val && p_val->psz_string )
                p_var->psz_text = strdup( p_val->psz_string );
            else
                p_var->psz_text = NULL;
            break;
        case VLC_VAR_GETTEXT:
            p_val->psz_string = p_var->psz_text ? strdup( p_var->psz_text )
                                                : NULL;
            break;
        default:
            break;
    }

    vlc_mutex_unlock( &p_priv->var_lock );

    return ret;
}
Exemple #2
0
/**
 * Perform an action on a variable
 *
 * \param p_this The object that holds the variable
 * \param psz_name The name of the variable
 * \param i_action The action to perform. Must be one of \ref var_action
 * \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 ret = VLC_SUCCESS;
    variable_t *p_var;
    vlc_value_t oldval;
    vlc_value_t newval;

    assert( p_this );

    vlc_object_internals_t *p_priv = vlc_internals( p_this );

    p_var = Lookup( p_this, psz_name );
    if( p_var == NULL )
    {
        vlc_mutex_unlock( &p_priv->var_lock );
        return VLC_ENOVAR;
    }

    switch( i_action )
    {
        case VLC_VAR_SETMIN:
            if( p_var->i_type & VLC_VAR_HASMIN )
            {
                p_var->ops->pf_free( &p_var->min );
            }
            p_var->i_type |= VLC_VAR_HASMIN;
            p_var->min = *p_val;
            p_var->ops->pf_dup( &p_var->min );
            CheckValue( p_var, &p_var->val );
            break;
        case VLC_VAR_GETMIN:
            if( p_var->i_type & VLC_VAR_HASMIN )
                *p_val = p_var->min;
            else
                ret = VLC_EGENERIC;
            break;
        case VLC_VAR_SETMAX:
            if( p_var->i_type & VLC_VAR_HASMAX )
            {
                p_var->ops->pf_free( &p_var->max );
            }
            p_var->i_type |= VLC_VAR_HASMAX;
            p_var->max = *p_val;
            p_var->ops->pf_dup( &p_var->max );
            CheckValue( p_var, &p_var->val );
            break;
        case VLC_VAR_GETMAX:
            if( p_var->i_type & VLC_VAR_HASMAX )
                *p_val = p_var->max;
            else
                ret = VLC_EGENERIC;
            break;
        case VLC_VAR_SETSTEP:
            if( p_var->i_type & VLC_VAR_HASSTEP )
            {
                p_var->ops->pf_free( &p_var->step );
            }
            p_var->i_type |= VLC_VAR_HASSTEP;
            p_var->step = *p_val;
            p_var->ops->pf_dup( &p_var->step );
            CheckValue( p_var, &p_var->val );
            break;
        case VLC_VAR_GETSTEP:
            if( p_var->i_type & VLC_VAR_HASSTEP )
                *p_val = p_var->step;
            else
                ret = VLC_EGENERIC;
            break;
        case VLC_VAR_ADDCHOICE:
        {
            int i = p_var->choices.i_count;

            INSERT_ELEM( p_var->choices.p_values, p_var->choices.i_count,
                         i, *p_val );
            INSERT_ELEM( p_var->choices_text.p_values,
                         p_var->choices_text.i_count, i, *p_val );
            p_var->ops->pf_dup( &p_var->choices.p_values[i] );
            p_var->choices_text.p_values[i].psz_string =
                ( p_val2 && p_val2->psz_string ) ?
                strdup( p_val2->psz_string ) : NULL;

            CheckValue( p_var, &p_var->val );

            TriggerListCallback(p_this, p_var, psz_name, VLC_VAR_ADDCHOICE, p_val);
            break;
        }
        case VLC_VAR_DELCHOICE:
        {
            int i;

            for( i = 0 ; i < p_var->choices.i_count ; i++ )
                if( p_var->ops->pf_cmp( p_var->choices.p_values[i], *p_val ) == 0 )
                    break;

            if( i == p_var->choices.i_count )
            {
                /* Not found */
                vlc_mutex_unlock( &p_priv->var_lock );
                return VLC_EGENERIC;
            }

            if( p_var->i_default > i )
                p_var->i_default--;
            else if( p_var->i_default == i )
                p_var->i_default = -1;

            p_var->ops->pf_free( &p_var->choices.p_values[i] );
            free( p_var->choices_text.p_values[i].psz_string );
            REMOVE_ELEM( p_var->choices.p_values, p_var->choices.i_count, i );
            REMOVE_ELEM( p_var->choices_text.p_values,
                         p_var->choices_text.i_count, i );

            CheckValue( p_var, &p_var->val );

            TriggerListCallback(p_this, p_var, psz_name, VLC_VAR_DELCHOICE, p_val);
            break;
        }
        case VLC_VAR_CHOICESCOUNT:
            p_val->i_int = p_var->choices.i_count;
            break;
        case VLC_VAR_CLEARCHOICES:
            for( int i = 0 ; i < p_var->choices.i_count ; i++ )
                p_var->ops->pf_free( &p_var->choices.p_values[i] );
            for( int i = 0 ; i < p_var->choices_text.i_count ; i++ )
                free( p_var->choices_text.p_values[i].psz_string );

            if( p_var->choices.i_count ) free( p_var->choices.p_values );
            if( p_var->choices_text.i_count ) free( p_var->choices_text.p_values );

            p_var->choices.i_count = 0;
            p_var->choices.p_values = NULL;
            p_var->choices_text.i_count = 0;
            p_var->choices_text.p_values = NULL;
            p_var->i_default = -1;
            TriggerListCallback(p_this, p_var, psz_name, VLC_VAR_CLEARCHOICES, NULL);
            break;
        case VLC_VAR_SETDEFAULT:
        {
            int i;
            /* FIXME: the list is sorted, dude. Use something cleverer. */
            for( i = 0 ; i < p_var->choices.i_count ; i++ )
                if( p_var->ops->pf_cmp( p_var->choices.p_values[i], *p_val ) == 0 )
                    break;

            if( i == p_var->choices.i_count )
                /* Not found */
                break;

            p_var->i_default = i;
            CheckValue( p_var, &p_var->val );
            break;
        }
        case VLC_VAR_SETVALUE:
            /* Duplicate data if needed */
            newval = *p_val;
            p_var->ops->pf_dup( &newval );
            /* Backup needed stuff */
            oldval = p_var->val;
            /* Check boundaries and list */
            CheckValue( p_var, &newval );
            /* Set the variable */
            p_var->val = newval;
            /* Free data if needed */
            p_var->ops->pf_free( &oldval );
            break;
        case VLC_VAR_GETCHOICES:
            p_val->p_list = xmalloc( sizeof(vlc_list_t) );
            p_val->p_list->p_values =
                xmalloc( p_var->choices.i_count * sizeof(vlc_value_t) );
            p_val->p_list->i_type = p_var->i_type;
            p_val->p_list->i_count = p_var->choices.i_count;
            if( p_val2 )
            {
                p_val2->p_list = xmalloc( sizeof(vlc_list_t) );
                p_val2->p_list->p_values =
                    xmalloc( p_var->choices.i_count * sizeof(vlc_value_t) );
                p_val2->p_list->i_type = VLC_VAR_STRING;
                p_val2->p_list->i_count = p_var->choices.i_count;
            }
            for( int i = 0 ; i < p_var->choices.i_count ; i++ )
            {
                p_val->p_list->p_values[i] = p_var->choices.p_values[i];
                p_var->ops->pf_dup( &p_val->p_list->p_values[i] );
                if( p_val2 )
                {
                    p_val2->p_list->p_values[i].psz_string =
                        p_var->choices_text.p_values[i].psz_string ?
                    strdup(p_var->choices_text.p_values[i].psz_string) : NULL;
                }
            }
            break;
        case VLC_VAR_SETTEXT:
            free( p_var->psz_text );
            if( p_val && p_val->psz_string )
                p_var->psz_text = strdup( p_val->psz_string );
            else
                p_var->psz_text = NULL;
            break;
        case VLC_VAR_GETTEXT:
            p_val->psz_string = p_var->psz_text ? strdup( p_var->psz_text )
                                                : NULL;
            break;
        default:
            break;
    }

    vlc_mutex_unlock( &p_priv->var_lock );

    return ret;
}