Exemple #1
0
/*****************************************************************************
 * Variables handling
 *****************************************************************************/
static int vlclua_pushvalue( lua_State *L, int i_type, vlc_value_t val, bool b_error_void )
{
    switch( i_type & VLC_VAR_CLASS )
    {
        case VLC_VAR_VOID:
            if( b_error_void )
                vlclua_error( L );
            else
                lua_pushnil( L );
            break;
        case VLC_VAR_BOOL:
            lua_pushboolean( L, val.b_bool );
            break;
        case VLC_VAR_INTEGER:
            lua_pushinteger( L, val.i_int );
            break;
        case VLC_VAR_STRING:
            lua_pushstring( L, val.psz_string );
            break;
        case VLC_VAR_FLOAT:
            lua_pushnumber( L, val.f_float );
            break;
        case VLC_VAR_ADDRESS:
            vlclua_error( L );
            break;
        default:
            vlclua_error( L );
    }
    return 1;
}
Exemple #2
0
/*****************************************************************************
 * Variables handling
 *****************************************************************************/
static int vlclua_pushvalue( lua_State *L, int i_type, vlc_value_t val, bool b_error_void )
{
    switch( i_type & VLC_VAR_CLASS )
    {
        case VLC_VAR_VOID:
            if( b_error_void )
                vlclua_error( L );
            else
                lua_pushnil( L );
            break;
        case VLC_VAR_BOOL:
            lua_pushboolean( L, val.b_bool );
            break;
        case VLC_VAR_INTEGER:
            lua_pushinteger( L, val.i_int );
            break;
        case VLC_VAR_STRING:
            lua_pushstring( L, val.psz_string );
            break;
        case VLC_VAR_FLOAT:
            lua_pushnumber( L, val.f_float );
            break;
        case VLC_VAR_TIME:
            /* FIXME? (we're losing some precision, but does it really matter?) */
            lua_pushnumber( L, ((double)val.i_time)/1000000. );
            break;
        case VLC_VAR_ADDRESS:
            vlclua_error( L );
            break;
        default:
            vlclua_error( L );
    }
    return 1;
}
Exemple #3
0
static int vlclua_tovalue( lua_State *L, int i_type, vlc_value_t *val )
{
    switch( i_type & VLC_VAR_CLASS )
    {
        case VLC_VAR_VOID:
            break;
        case VLC_VAR_BOOL:
            val->b_bool = luaL_checkboolean( L, -1 );
            break;
        case VLC_VAR_INTEGER:
            val->i_int = (int)luaL_checkinteger( L, -1 );
            break;
        case VLC_VAR_STRING:
            val->psz_string = (char*)luaL_checkstring( L, -1 ); /* XXX: Beware, this only stays valid as long as (L,-1) stays in the stack */
            break;
        case VLC_VAR_FLOAT:
            val->f_float = luaL_checknumber( L, -1 );
            break;
        case VLC_VAR_ADDRESS:
            vlclua_error( L );
            break;
        default:
            vlclua_error( L );
    }
    return 1;
}
static int vlclua_from_charset( lua_State *L )
{
    if( lua_gettop( L ) < 2 ) return vlclua_error( L );

    size_t i_in_bytes;
    const char *psz_input = luaL_checklstring( L, 2, &i_in_bytes );
    if( i_in_bytes == 0 ) return vlclua_error( L );

    const char *psz_charset = luaL_checkstring( L, 1 );
    char *psz_output = FromCharset( psz_charset, psz_input, i_in_bytes );
    lua_pushstring( L, psz_output ? psz_output : "" );
    free( psz_output );
    return 1;
}
Exemple #5
0
/*****************************************************************************
 * Variables handling
 *****************************************************************************/
int vlclua_pushvalue( lua_State *L, int i_type, vlc_value_t val )
{
    switch( i_type &= VLC_VAR_CLASS )
    {
        case VLC_VAR_VOID:
            vlclua_error( L );
            break;
        case VLC_VAR_BOOL:
            lua_pushboolean( L, val.b_bool );
            break;
        case VLC_VAR_INTEGER:
            lua_pushinteger( L, val.i_int );
            break;
        case VLC_VAR_STRING:
            lua_pushstring( L, val.psz_string );
            break;
        case VLC_VAR_FLOAT:
            lua_pushnumber( L, val.f_float );
            break;
        case VLC_VAR_TIME:
            /* FIXME? (we're losing some precision, but does it really matter?) */
            lua_pushnumber( L, ((double)val.i_time)/1000000. );
            break;
        case VLC_VAR_ADDRESS:
            vlclua_error( L );
            break;
        case VLC_VAR_MUTEX:
            vlclua_error( L );
            break;
        case VLC_VAR_LIST:
            {
                int i_count = val.p_list->i_count;
                int i;
                lua_createtable( L, i_count, 0 );
                for( i = 0; i < i_count; i++ )
                {
                    lua_pushinteger( L, i+1 );
                    if( !vlclua_pushvalue( L, val.p_list->pi_types[i],
                                           val.p_list->p_values[i] ) )
                        lua_pushnil( L );
                    lua_settable( L, -3 );
                }
            }
            break;
        default:
            vlclua_error( L );
    }
    return 1;
}
Exemple #6
0
static int vlclua_config_set( lua_State *L )
{
    vlc_object_t *p_this = vlclua_get_this( L );
    const char *psz_name = luaL_checkstring( L, 1 );
    switch( config_GetType( p_this, psz_name ) )
    {
        case VLC_VAR_STRING:
            config_PutPsz( p_this, psz_name, luaL_checkstring( L, 2 ) );
            break;

        case VLC_VAR_INTEGER:
            config_PutInt( p_this, psz_name, luaL_checkinteger( L, 2 ) );
            break;

        case VLC_VAR_BOOL:
            config_PutInt( p_this, psz_name, luaL_checkboolean( L, 2 ) );
            break;

        case VLC_VAR_FLOAT:
            config_PutFloat( p_this, psz_name,
                             luaL_checknumber( L, 2 ) );
            break;

        default:
            return vlclua_error( L );
    }
    return 0;
}
Exemple #7
0
/*****************************************************************************
 * Config handling
 *****************************************************************************/
static int vlclua_config_get( lua_State *L )
{
    vlc_object_t * p_this = vlclua_get_this( L );
    const char *psz_name = luaL_checkstring( L, 1 );
    switch( config_GetType( p_this, psz_name ) )
    {
        case VLC_VAR_STRING:
        {
            char *psz = config_GetPsz( p_this, psz_name );
            lua_pushstring( L, psz );
            free( psz );
            break;
        }

        case VLC_VAR_INTEGER:
            lua_pushinteger( L, config_GetInt( p_this, psz_name ) );
            break;

        case VLC_VAR_BOOL:
            lua_pushboolean( L, config_GetInt( p_this, psz_name ) );
            break;

        case VLC_VAR_FLOAT:
            lua_pushnumber( L, config_GetFloat( p_this, psz_name ) );
            break;

        default:
            return vlclua_error( L );

    }
    return 1;
}
Exemple #8
0
int vlclua_var_toggle_or_set( lua_State *L, vlc_object_t *p_obj,
                              const char *psz_name )
{
    bool b_bool;
    if( lua_gettop( L ) > 1 ) return vlclua_error( L );

    if( lua_gettop( L ) == 0 )
    {
        b_bool = var_ToggleBool( p_obj, psz_name );
        goto end;
    }

    /* lua_gettop( L ) == 1 */
    const char *s = luaL_checkstring( L, -1 );
    lua_pop( L, 1 );

    if( s && !strcmp(s, "on") )
        b_bool = true;
    else if( s && !strcmp(s, "off") )
        b_bool = false;
    else
    {
        b_bool = var_GetBool( p_obj, psz_name );
        goto end;
    }

    if( b_bool != var_GetBool( p_obj, psz_name ) )
        var_SetBool( p_obj, psz_name, b_bool );

end:
    lua_pushboolean( L, b_bool );
    return 1;
}
Exemple #9
0
static int vlclua_tovalue( lua_State *L, int i_type, vlc_value_t *val )
{
    switch( i_type & VLC_VAR_CLASS )
    {
        case VLC_VAR_VOID:
            break;
        case VLC_VAR_BOOL:
            val->b_bool = luaL_checkboolean( L, -1 );
            break;
        case VLC_VAR_INTEGER:
            /* Lua may only support 32-bit integers. If so, we need to
             * get the value as a float instead so we can even know if
             * there would be an overflow.
             */
            // TODO: check using LUA_MININTEGER and LUA_MAXINTEGER macros
            // if and when we require lua >= 5.3
            if( sizeof( lua_Integer ) < sizeof( val->i_int ) )
            {
                lua_Number f = luaL_checknumber( L, -1 );
                // Calling vlc.var.set() on integer object variables with
                // an out-of-range float value is not handled.
                val->i_int = (int64_t)llround( f );
                if( INT32_MIN < val->i_int && val->i_int < INT32_MAX )
                    val->i_int = luaL_checkinteger( L, -1 );
            }
            else
                val->i_int = luaL_checkinteger( L, -1 );
            break;
        case VLC_VAR_STRING:
            val->psz_string = (char*)luaL_checkstring( L, -1 ); /* XXX: Beware, this only stays valid as long as (L,-1) stays in the stack */
            break;
        case VLC_VAR_FLOAT:
            val->f_float = luaL_checknumber( L, -1 );
            break;
        case VLC_VAR_ADDRESS:
            vlclua_error( L );
            break;
        default:
            vlclua_error( L );
    }
    return 1;
}
Exemple #10
0
/*****************************************************************************
 * Vout control
 *****************************************************************************/
static int vlclua_fullscreen( lua_State *L )
{
    vout_thread_t *p_vout;
    int i_ret;

    input_thread_t * p_input = vlclua_get_input_internal( L );
    if( !p_input ) return vlclua_error( L );

    p_vout = input_GetVout( p_input );
    if( !p_vout )
    {
        vlc_object_release( p_input );
        return vlclua_error( L );
    }

    i_ret = vlclua_var_toggle_or_set( L, p_vout, "fullscreen" );

    vlc_object_release( p_vout );
    vlc_object_release( p_input );
    return i_ret;
}
Exemple #11
0
/*****************************************************************************
 * Variables handling
 *****************************************************************************/
static int vlclua_pushvalue( lua_State *L, int i_type, vlc_value_t val )
{
    switch( i_type & VLC_VAR_CLASS )
    {
        case VLC_VAR_BOOL:
            lua_pushboolean( L, val.b_bool );
            break;
        case VLC_VAR_INTEGER:
            /* Lua may only support 32-bit integers. If so, and the
             * value requires a higher range, push it as a float. We
             * lose some precision, but object variables are not a
             * recommended API for lua scripts: functionality requiring
             * high precision should be provided with a dedicated lua
             * binding instead of object variables.
             */
            // TODO: check using LUA_MININTEGER and LUA_MAXINTEGER macros
            // if and when we require lua >= 5.3
            if( sizeof( lua_Integer ) < sizeof( val.i_int ) &&
                ( val.i_int < INT32_MIN || INT32_MAX < val.i_int ) )
                lua_pushnumber( L, (lua_Number)val.i_int );
            else
                lua_pushinteger( L, val.i_int );
            break;
        case VLC_VAR_STRING:
            lua_pushstring( L, val.psz_string );
            break;
        case VLC_VAR_FLOAT:
            lua_pushnumber( L, val.f_float );
            break;
        case VLC_VAR_ADDRESS:
            vlclua_error( L );
            break;
        case VLC_VAR_VOID:
        default:
            vlclua_error( L );
    }
    return 1;
}
Exemple #12
0
static int vlclua_tovalue( lua_State *L, int i_type, vlc_value_t *val )
{
    switch( i_type & 0xf0 )
    {
        case VLC_VAR_VOID:
            break;
        case VLC_VAR_BOOL:
            val->b_bool = luaL_checkboolean( L, -1 );
            break;
        case VLC_VAR_INTEGER:
            val->i_int = luaL_checkint( L, -1 );
            break;
        case VLC_VAR_STRING:
            val->psz_string = (char*)luaL_checkstring( L, -1 ); /* XXX: Beware, this only stays valid as long as (L,-1) stays in the stack */
            break;
        case VLC_VAR_FLOAT:
            val->f_float = luaL_checknumber( L, -1 );
            break;
        case VLC_VAR_TIME:
            {
                double f = luaL_checknumber( L, -1 );
                val->i_time = (int64_t)(f*1000000.);
            }
            break;
        case VLC_VAR_ADDRESS:
            vlclua_error( L );
            break;
        case VLC_VAR_MUTEX:
            vlclua_error( L );
            break;
        case VLC_VAR_LIST:
            vlclua_error( L );
            break;
        default:
            vlclua_error( L );
    }
    return 1;
}
Exemple #13
0
static int vlclua_stream_add_filter( lua_State *L )
{
    vlc_object_t *p_this = vlclua_get_this( L );

    /* Make sure that we have 1 argument (+ 1 object) */
    lua_settop( L, 2 );

    stream_t **pp_stream = (stream_t **)luaL_checkudata( L, 1, "stream" );
    if( !*pp_stream ) return vlclua_error( L );
    const char *psz_filter = NULL;

    if( lua_isstring( L, 2 ) )
        psz_filter = lua_tostring( L, 2 );

    if( !psz_filter || !*psz_filter )
    {
        msg_Dbg( p_this, "adding all automatic stream filters" );
        while( true )
        {
            /* Add next automatic stream */
            stream_t *p_filtered = vlc_stream_FilterNew( *pp_stream, NULL );
            if( !p_filtered )
                break;
            else
            {
                msg_Dbg( p_this, "inserted an automatic stream filter" );
                *pp_stream = p_filtered;
            }
        }
        luaL_getmetatable( L, "stream" );
        lua_setmetatable( L, 1 );
    }
    else
    {
        /* Add a named filter */
        stream_t *p_filter = vlc_stream_FilterNew( *pp_stream, psz_filter );
        if( !p_filter )
            msg_Dbg( p_this, "Unable to open requested stream filter '%s'",
                     psz_filter );
        else
        {
            *pp_stream = p_filter;
            luaL_getmetatable( L, "stream" );
            lua_setmetatable( L, 1 );
        }
    }

    return 1;
}
Exemple #14
0
static int vlclua_stream_read( lua_State *L )
{
    int i_read;
    stream_t **pp_stream = (stream_t **)luaL_checkudata( L, 1, "stream" );
    int n = luaL_checkint( L, 2 );
    uint8_t *p_read = malloc( n );
    if( !p_read ) return vlclua_error( L );

    i_read = vlc_stream_Read( *pp_stream, p_read, n );
    if( i_read > 0 )
        lua_pushlstring( L, (const char *)p_read, i_read );
    else
        lua_pushnil( L );
    free( p_read );
    return 1;
}
int __vlclua_var_toggle_or_set( lua_State *L, vlc_object_t *p_obj,
                                const char *psz_name )
{
    bool b_bool;
    if( lua_gettop( L ) > 1 ) return vlclua_error( L );

    if( lua_gettop( L ) == 0 )
        b_bool = var_ToggleBool( p_obj, psz_name );
    else /* lua_gettop( L ) == 1 */
    {
        b_bool = luaL_checkboolean( L, -1 );
        lua_pop( L, 1 );
        if( b_bool != var_GetBool( p_obj, psz_name ) )
            var_SetBool( p_obj, psz_name, b_bool );
    }

    lua_pushboolean( L, b_bool );
    return 1;
}
Exemple #16
0
static int vlclua_add_callback( lua_State *L )
{
    vlclua_callback_t *p_callback;
    static int i_index = 0;
    vlc_object_t **pp_obj = luaL_checkudata( L, 1, "vlc_object" );
    const char *psz_var = luaL_checkstring( L, 2 );
    lua_settop( L, 4 ); /* makes sure that optional data arg is set */
    if( !lua_isfunction( L, 3 ) )
        return vlclua_error( L );

    if( !pp_obj || !*pp_obj )
        return vlclua_error( L );

    /* Check variable type, in order to avoid PANIC */
    switch( var_Type( *pp_obj, psz_var ) )
    {
        case VLC_VAR_BOOL:
        case VLC_VAR_INTEGER:
        case VLC_VAR_STRING:
        case VLC_VAR_FLOAT:
        case VLC_VAR_TIME:
            break;
        case VLC_VAR_ADDRESS:
        case VLC_VAR_VOID:
        case VLC_VAR_MUTEX:
        case VLC_VAR_LIST:
        default:
            return vlclua_error( L );
    }

    i_index++;

    p_callback = (vlclua_callback_t*)malloc( sizeof( vlclua_callback_t ) );
    if( !p_callback )
        return vlclua_error( L );

    /* obj var func data */
    lua_getglobal( L, "vlc" );
    /* obj var func data vlc */
    lua_getfield( L, -1, "callbacks" );
    if( lua_isnil( L, -1 ) )
    {
        lua_pop( L, 1 );
        lua_newtable( L );
        lua_setfield( L, -2, "callbacks" );
        lua_getfield( L, -1, "callbacks" );
    }
    /* obj var func data vlc callbacks */
    lua_remove( L, -2 );
    /* obj var func data callbacks */
    lua_pushinteger( L, i_index );
    /* obj var func data callbacks index */
    lua_insert( L, -4 );
    /* obj var index func data callbacks */
    lua_insert( L, -4 );
    /* obj var callbacks index func data */
    lua_createtable( L, 0, 0 );
    /* obj var callbacks index func data cbtable */
    lua_insert( L, -2 );
    /* obj var callbacks index func cbtable data */
    lua_setfield( L, -2, "data" );
    /* obj var callbacks index func cbtable */
    lua_insert( L, -2 );
    /* obj var callbacks index cbtable func */
    lua_setfield( L, -2, "callback" );
    /* obj var callbacks index cbtable */
    lua_pushlightuserdata( L, *pp_obj ); /* will be needed in vlclua_del_callback */
    /* obj var callbacks index cbtable p_obj */
    lua_setfield( L, -2, "private1" );
    /* obj var callbacks index cbtable */
    lua_pushvalue( L, 2 ); /* will be needed in vlclua_del_callback */
    /* obj var callbacks index cbtable var */
    lua_setfield( L, -2, "private2" );
    /* obj var callbacks index cbtable */
    lua_pushlightuserdata( L, p_callback ); /* will be needed in vlclua_del_callback */
    /* obj var callbacks index cbtable p_callback */
    lua_setfield( L, -2, "private3" );
    /* obj var callbacks index cbtable */
    lua_settable( L, -3 );
    /* obj var callbacks */
    lua_pop( L, 3 );
    /* <empty stack> */

    /* Do not move this before the lua specific code (it somehow changes
     * the function in the stack to nil) */
    p_callback->i_index = i_index;
    p_callback->i_type = var_Type( *pp_obj, psz_var );
    p_callback->L = lua_newthread( L ); /* Do we have to keep a reference to this thread somewhere to prevent garbage collection? */

    var_AddCallback( *pp_obj, psz_var, vlclua_callback, p_callback );
    return 0;
}
Exemple #17
0
static int vlclua_del_callback( lua_State *L )
{
    vlclua_callback_t *p_callback;
    bool b_found = false;
    vlc_object_t **pp_obj = luaL_checkudata( L, 1, "vlc_object" );
    const char *psz_var = luaL_checkstring( L, 2 );
    lua_settop( L, 4 ); /* makes sure that optional data arg is set */
    if( !lua_isfunction( L, 3 ) )
        return vlclua_error( L );

    /* obj var func data */
    lua_getglobal( L, "vlc" );
    /* obj var func data vlc */
    lua_getfield( L, -1, "callbacks" );
    if( lua_isnil( L, -1 ) )
        return luaL_error( L, "Couldn't find matching callback." );
    /* obj var func data vlc callbacks */
    lua_remove( L, -2 );
    /* obj var func data callbacks */
    lua_pushnil( L );
    /* obj var func data callbacks index */
    while( lua_next( L, -2 ) )
    {
        /* obj var func data callbacks index value */
        if( lua_isnumber( L, -2 ) )
        {
            lua_getfield( L, -1, "private2" );
            /* obj var func data callbacks index value private2 */
            if( lua_equal( L, 2, -1 ) ) /* var name is equal */
            {
                lua_pop( L, 1 );
                /* obj var func data callbacks index value */
                lua_getfield( L, -1, "callback" );
                /* obj var func data callbacks index value callback */
                if( lua_equal( L, 3, -1 ) ) /* callback function is equal */
                {
                    lua_pop( L, 1 );
                    /* obj var func data callbacks index value */
                    lua_getfield( L, -1, "data" ); /* callback data is equal */
                    /* obj var func data callbacks index value data */
                    if( lua_equal( L, 4, -1 ) )
                    {
                        vlc_object_t *p_obj2;
                        lua_pop( L, 1 );
                        /* obj var func data callbacks index value */
                        lua_getfield( L, -1, "private1" );
                        /* obj var func data callbacks index value private1 */
                        p_obj2 = (vlc_object_t*)luaL_checklightuserdata( L, -1 );
                        if( p_obj2 == *pp_obj ) /* object is equal */
                        {
                            lua_pop( L, 1 );
                            /* obj var func data callbacks index value */
                            lua_getfield( L, -1, "private3" );
                            /* obj var func data callbacks index value private3 */
                            p_callback = (vlclua_callback_t*)luaL_checklightuserdata( L, -1 );
                            lua_pop( L, 2 );
                            /* obj var func data callbacks index */
                            b_found = true;
                            break;
                        }
                        else
                        {
                            /* obj var func data callbacks index value private1 */
                            lua_pop( L, 1 );
                            /* obj var func data callbacks index value */
                        }
                    }
                    else
                    {
                        /* obj var func data callbacks index value data */
                        lua_pop( L, 1 );
                        /* obj var func data callbacks index value */
                    }
                }
                else
                {
                    /* obj var func data callbacks index value callback */
                    lua_pop( L, 1 );
                    /* obj var func data callbacks index value */
                }
            }
            else
            {
                /* obj var func data callbacks index value private2 */
                lua_pop( L, 1 );
                /* obj var func data callbacks index value */
            }
        }
        /* obj var func data callbacks index value */
        lua_pop( L, 1 );
        /* obj var func data callbacks index */
    }
    if( b_found == false )
        /* obj var func data callbacks */
        return luaL_error( L, "Couldn't find matching callback." );
    /* else */
        /* obj var func data callbacks index*/

    var_DelCallback( *pp_obj, psz_var, vlclua_callback, p_callback );
    free( p_callback );

    /* obj var func data callbacks index */
    lua_pushnil( L );
    /* obj var func data callbacks index nil */
    lua_settable( L, -3 ); /* delete the callback table entry */
    /* obj var func data callbacks */
    lua_pop( L, 5 );
    /* <empty stack> */
    return 0;
}