]> git.sesse.net Git - vlc/blob - modules/misc/lua/variables.c
Don't include config.h from the headers - refs #297.
[vlc] / modules / misc / lua / variables.c
1 /*****************************************************************************
2  * variables.c: Generic lua<->vlc variables inteface
3  *****************************************************************************
4  * Copyright (C) 2007 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Antoine Cellerier <dionoea at videolan tod org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #ifndef  _GNU_SOURCE
28 #   define  _GNU_SOURCE
29 #endif
30
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
34
35 #include <vlc/vlc.h>
36
37 #include <lua.h>        /* Low level lua C API */
38 #include <lauxlib.h>    /* Higher level C API */
39 #include <lualib.h>     /* Lua libs */
40
41 #include "vlc.h"
42
43 /*****************************************************************************
44  * Variables handling
45  *****************************************************************************/
46 int vlclua_pushvalue( lua_State *L, int i_type, vlc_value_t val )
47 {
48     switch( i_type &= 0xf0 )
49     {
50         case VLC_VAR_VOID:
51             vlclua_error( L );
52             break;
53         case VLC_VAR_BOOL:
54             lua_pushboolean( L, val.b_bool );
55             break;
56         case VLC_VAR_INTEGER:
57             lua_pushinteger( L, val.i_int );
58             break;
59         case VLC_VAR_STRING:
60             lua_pushstring( L, val.psz_string );
61             break;
62         case VLC_VAR_FLOAT:
63             lua_pushnumber( L, val.f_float );
64             break;
65         case VLC_VAR_TIME:
66             /* FIXME? (we're losing some precision, but does it really matter?) */
67             lua_pushnumber( L, ((double)val.i_time)/1000000. );
68             break;
69         case VLC_VAR_ADDRESS:
70             vlclua_error( L );
71             break;
72         case VLC_VAR_MUTEX:
73             vlclua_error( L );
74             break;
75         case VLC_VAR_LIST:
76             {
77                 int i_count = val.p_list->i_count;
78                 int i;
79                 lua_createtable( L, i_count, 0 );
80                 for( i = 0; i < i_count; i++ )
81                 {
82                     lua_pushinteger( L, i+1 );
83                     if( !vlclua_pushvalue( L, val.p_list->pi_types[i],
84                                            val.p_list->p_values[i] ) )
85                         lua_pushnil( L );
86                     lua_settable( L, -3 );
87                 }
88             }
89             break;
90         default:
91             vlclua_error( L );
92     }
93     return 1;
94 }
95
96 static int vlclua_tovalue( lua_State *L, int i_type, vlc_value_t *val )
97 {
98     switch( i_type & 0xf0 )
99     {
100         case VLC_VAR_VOID:
101             break;
102         case VLC_VAR_BOOL:
103             val->b_bool = luaL_checkboolean( L, -1 );
104             break;
105         case VLC_VAR_INTEGER:
106             val->i_int = luaL_checkint( L, -1 );
107             break;
108         case VLC_VAR_STRING:
109             val->psz_string = (char*)luaL_checkstring( L, -1 ); /* XXX: Beware, this only stays valid as long as (L,-1) stays in the stack */
110             break;
111         case VLC_VAR_FLOAT:
112             val->f_float = luaL_checknumber( L, -1 );
113             break;
114         case VLC_VAR_TIME:
115             {
116                 double f = luaL_checknumber( L, -1 );
117                 val->i_time = (vlc_int64_t)(f*1000000.);
118             }
119             break;
120         case VLC_VAR_ADDRESS:
121             vlclua_error( L );
122             break;
123         case VLC_VAR_MUTEX:
124             vlclua_error( L );
125             break;
126         case VLC_VAR_LIST:
127             vlclua_error( L );
128             break;
129         default:
130             vlclua_error( L );
131     }
132     return 1;
133 }
134
135 int vlclua_var_get( lua_State *L )
136 {
137     int i_type;
138     vlc_value_t val;
139     vlc_object_t *p_obj = vlclua_checkobject( L, 1, 0 );
140     const char *psz_var = luaL_checkstring( L, 2 );
141     i_type = var_Type( p_obj, psz_var );
142     var_Get( p_obj, psz_var, &val );
143     lua_pop( L, 2 );
144     return vlclua_pushvalue( L, i_type, val );
145 }
146
147 int vlclua_var_set( lua_State *L )
148 {
149     int i_type;
150     vlc_value_t val;
151     vlc_object_t *p_obj = vlclua_checkobject( L, 1, 0 );
152     const char *psz_var = luaL_checkstring( L, 2 );
153     int i_ret;
154     i_type = var_Type( p_obj, psz_var );
155     vlclua_tovalue( L, i_type, &val );
156     i_ret = var_Set( p_obj, psz_var, val );
157     lua_pop( L, 3 );
158     return vlclua_push_ret( L, i_ret );
159 }
160
161 int vlclua_var_get_list( lua_State *L )
162 {
163     vlc_value_t val;
164     vlc_value_t text;
165     vlc_object_t *p_obj = vlclua_checkobject( L, 1, 0 );
166     const char *psz_var = luaL_checkstring( L, 2 );
167     int i_ret = var_Change( p_obj, psz_var, VLC_VAR_GETLIST, &val, &text );
168     if( i_ret < 0 ) return vlclua_push_ret( L, i_ret );
169     vlclua_pushvalue( L, VLC_VAR_LIST, val );
170     vlclua_pushvalue( L, VLC_VAR_LIST, text );
171     var_Change( p_obj, psz_var, VLC_VAR_FREELIST, &val, &text );
172     return 2;
173 }
174
175 int vlclua_module_command( lua_State *L )
176 {
177     vlc_object_t * p_this = vlclua_get_this( L );
178     const char *psz_name;
179     const char *psz_cmd;
180     const char *psz_arg;
181     char *psz_msg;
182     psz_name = luaL_checkstring( L, 1 );
183     psz_cmd = luaL_checkstring( L, 2 );
184     psz_arg = luaL_checkstring( L, 3 );
185     lua_pop( L, 3 );
186     var_Command( p_this, psz_name, psz_cmd, psz_arg, &psz_msg );
187     if( psz_msg )
188     {
189         lua_pushstring( L, psz_msg );
190         free( psz_msg );
191     }
192     else
193     {
194         lua_pushstring( L, "" );
195     }
196     return 1;
197 }
198
199 int vlclua_libvlc_command( lua_State *L )
200 {
201     vlc_object_t * p_this = vlclua_get_this( L );
202     const char *psz_cmd;
203     vlc_value_t val_arg;
204     psz_cmd = luaL_checkstring( L, 1 );
205     val_arg.psz_string = strdup( luaL_optstring( L, 2, "" ) );
206     lua_pop( L, 2 );
207     if( !var_Type( p_this->p_libvlc, psz_cmd ) & VLC_VAR_ISCOMMAND )
208     {
209         free( val_arg.psz_string );
210         return luaL_error( L, "libvlc's \"%s\" is not a command",
211                            psz_cmd );
212     }
213
214     return vlclua_push_ret( L,
215                             var_Set( p_this->p_libvlc, psz_cmd, val_arg ) );
216 }