⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 variables.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* Free data if needed */    p_var->pf_free( &oldval );    vlc_mutex_unlock( &p_priv->var_lock );    return VLC_SUCCESS;}/** * Get a variable's value * * \param p_this The object that holds the variable * \param psz_name The name of the variable * \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 i_var;    variable_t *p_var;    vlc_object_internals_t *p_priv = vlc_internals( p_this );    vlc_refcheck( p_this );    vlc_mutex_lock( &p_priv->var_lock );    i_var = Lookup( p_priv->p_vars, p_priv->i_vars, psz_name );    if( i_var < 0 )    {        vlc_mutex_unlock( &p_priv->var_lock );        return VLC_ENOVAR;    }    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;}/** * Finds a process-wide mutex, creates it if needed, and locks it. * Unlock with vlc_mutex_unlock(). */vlc_mutex_t *var_AcquireMutex( const char *name ){    libvlc_global_data_t *p_global = vlc_global();    vlc_value_t val;    if( var_Create( p_global, name, VLC_VAR_MUTEX ) )        return NULL;    var_Get( p_global, name, &val );    vlc_mutex_lock( val.p_address );    return val.p_address;}/** * Register a callback in a variable * * We store a function pointer that will be called upon variable * modification. * * \param p_this The object that holds the variable * \param psz_name The name of the variable * \param pf_callback The function pointer * \param p_data A generic pointer that will be passed as the last *               argument to the callback function. * * \warning The callback function is run in the thread that calls var_Set on *          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 i_var;    variable_t *p_var;    callback_entry_t entry;    vlc_object_internals_t *p_priv = vlc_internals( p_this );    vlc_refcheck( p_this );    entry.pf_callback = pf_callback;    entry.p_data = p_data;    vlc_mutex_lock( &p_priv->var_lock );    i_var = GetUnused( p_this, psz_name );    if( i_var < 0 )    {        vlc_mutex_unlock( &p_priv->var_lock );        return i_var;    }    p_var = &p_priv->p_vars[i_var];    INSERT_ELEM( p_var->p_entries,                 p_var->i_entries,                 p_var->i_entries,                 entry );    vlc_mutex_unlock( &p_priv->var_lock );    return VLC_SUCCESS;}/** * 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 i_entry, i_var;    variable_t *p_var;    vlc_object_internals_t *p_priv = vlc_internals( p_this );    vlc_refcheck( p_this );    vlc_mutex_lock( &p_priv->var_lock );    i_var = GetUnused( p_this, psz_name );    if( i_var < 0 )    {        vlc_mutex_unlock( &p_priv->var_lock );        return i_var;    }    p_var = &p_priv->p_vars[i_var];    for( i_entry = p_var->i_entries ; i_entry-- ; )    {        if( p_var->p_entries[i_entry].pf_callback == pf_callback            && p_var->p_entries[i_entry].p_data == p_data )        {            break;        }    }    if( i_entry < 0 )    {        vlc_mutex_unlock( &p_priv->var_lock );        return VLC_EGENERIC;    }    REMOVE_ELEM( p_var->p_entries, p_var->i_entries, i_entry );    vlc_mutex_unlock( &p_priv->var_lock );    return VLC_SUCCESS;}/** * 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 i_var;    variable_t *p_var;    vlc_value_t oldval;    vlc_object_internals_t *p_priv = vlc_internals( p_this );    vlc_mutex_lock( &p_priv->var_lock );    i_var = GetUnused( p_this, psz_name );    if( i_var < 0 )    {        vlc_mutex_unlock( &p_priv->var_lock );        return i_var;    }    p_var = &p_priv->p_vars[i_var];    /* Backup needed stuff */    oldval = p_var->val;    /* Deal with callbacks. Tell we're in a callback, release the lock,     * call stored functions, retake the lock. */    if( p_var->i_entries )    {        int i_var;        int i_entries = p_var->i_entries;        callback_entry_t *p_entries = p_var->p_entries;        p_var->b_incallback = true;        vlc_mutex_unlock( &p_priv->var_lock );        /* The real calls */        for( ; i_entries-- ; )        {            p_entries[i_entries].pf_callback( p_this, psz_name, oldval, oldval,                                              p_entries[i_entries].p_data );        }        vlc_mutex_lock( &p_priv->var_lock );        i_var = Lookup( p_priv->p_vars, p_priv->i_vars, psz_name );        if( i_var < 0 )        {            msg_Err( p_this, "variable %s has disappeared", psz_name );            vlc_mutex_unlock( &p_priv->var_lock );            return VLC_ENOVAR;        }        p_var = &p_priv->p_vars[i_var];        p_var->b_incallback = false;    }    vlc_mutex_unlock( &p_priv->var_lock );    return VLC_SUCCESS;}/** Parse a stringified option * This function parse a string option and create the associated object * variable * The option must be of the form "[no[-]]foo[=bar]" where foo is the * option name and bar is the value of the option. * \param p_obj the object in which the variable must be created * \param psz_option the option to parse * \param trusted whether the option is set by a trusted input or not * \return nothing */void var_OptionParse( vlc_object_t *p_obj, const char *psz_option,                      bool trusted ){    char *psz_name, *psz_value;    int  i_type;    bool b_isno = false;    vlc_value_t val;    val.psz_string = NULL;    /* It's too much of a hassle to remove the ':' when we parse     * the cmd line :) */    if( psz_option[0] == ':' )        psz_option++;    if( !psz_option[0] )        return;    psz_name = strdup( psz_option );    if( psz_name == NULL )        return;    psz_value = strchr( psz_name, '=' );    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 );    if( !i_type && !psz_value )    {        /* check for "no-foo" or "nofoo" */        if( !strncmp( psz_name, "no-", 3 ) )        {            memmove( psz_name, psz_name + 3, strlen(psz_name) + 1 - 3 );        }        else if( !strncmp( psz_name, "no", 2 ) )        {            memmove( psz_name, psz_name + 2, strlen(psz_name) + 1 - 2 );        }        else goto cleanup;           /* Option doesn't exist */        b_isno = true;        i_type = config_GetType( p_obj, psz_name );    }    if( !i_type ) goto cleanup; /* Option doesn't exist */    if( ( i_type != VLC_VAR_BOOL ) &&        ( !psz_value || !*psz_value ) ) goto cleanup; /* Invalid value */    /* check if option is unsafe */    if( !trusted )    {        module_config_t *p_config = config_FindConfig( p_obj, psz_name );        if( !p_config->b_safe )        {            msg_Err( p_obj, "unsafe option \"%s\" has been ignored for "                            "security reasons", psz_name );            return;        }    }    /* 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 );    switch( i_type )    {    case VLC_VAR_BOOL:        val.b_bool = !b_isno;        break;    case VLC_VAR_INTEGER:        val.i_int = strtol( psz_value, NULL, 0 );        break;    case VLC_VAR_FLOAT:        val.f_float = atof( psz_value );        break;    case VLC_VAR_STRING:    case VLC_VAR_MODULE:    case VLC_VAR_FILE:    case VLC_VAR_DIRECTORY:        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 );cleanup:    free( psz_name );}/* Following functions are local *//***************************************************************************** * GetUnused: find an unused variable from its name ***************************************************************************** * We do i_tries tries before giving up, just in case the variable is being * modified and called from a callback. *****************************************************************************/static int GetUnused( vlc_object_t *p_this, const char *psz_name ){    int i_var, i_tries = 0;    vlc_object_internals_t *p_priv = vlc_internals( p_this );    while( true )    {        i_var = Lookup( p_priv->p_vars, p_priv->i_vars, psz_name );        if( i_var < 0 )        {            return VLC_ENOVAR;        }        if( ! p_priv->p_vars[i_var].b_incallback )        {            return i_var;        }        if( i_tries++ > 100 )        {            msg_Err( p_this, "caught in a callback deadlock? ('%s')", psz_name );            return VLC_ETIMEOUT;        }        vlc_mutex_unlock( &p_priv->var_lock );        msleep( THREAD_SLEEP );        vlc_mutex_lock( &p_priv->var_lock );    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -