1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2007-2008 the VideoLAN team
7 * Authors: Antoine Cellerier <dionoea at videolan tod org>
8 * Pierre d'Herbemont <pdherbemont # videolan.org>
9 * RĂ©mi Duraffort <ivoire # videolan tod org>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
37 #include <vlc_common.h>
38 #include <vlc_plugin.h>
41 #include <vlc_interface.h>
44 #include <lua.h> /* Low level lua C API */
45 #include <lauxlib.h> /* Higher level C API */
46 #include <lualib.h> /* Lua libs */
51 /*****************************************************************************
52 * Internal lua<->vlc utils
53 *****************************************************************************/
54 static void vlclua_set_object( lua_State *L, void *id, void *value )
56 lua_pushlightuserdata( L, id );
57 lua_pushlightuserdata( L, value );
58 lua_rawset( L, LUA_REGISTRYINDEX );
61 static void *vlclua_get_object( lua_State *L, void *id )
63 lua_pushlightuserdata( L, id );
64 lua_rawget( L, LUA_REGISTRYINDEX );
65 const void *p = lua_topointer( L, -1 );
70 #undef vlclua_set_this
71 void vlclua_set_this( lua_State *L, vlc_object_t *p_this )
73 vlclua_set_object( L, vlclua_set_this, p_this );
76 vlc_object_t * vlclua_get_this( lua_State *L )
78 return vlclua_get_object( L, vlclua_set_this );
81 void vlclua_set_intf( lua_State *L, intf_sys_t *p_intf )
83 vlclua_set_object( L, vlclua_set_intf, p_intf );
86 static intf_sys_t * vlclua_get_intf( lua_State *L )
88 return vlclua_get_object( L, vlclua_set_intf );
91 /*****************************************************************************
92 * VLC error code translation
93 *****************************************************************************/
94 int vlclua_push_ret( lua_State *L, int i_error )
96 lua_pushnumber( L, i_error );
97 lua_pushstring( L, vlc_error( i_error ) );
101 /*****************************************************************************
102 * Get the VLC version string
103 *****************************************************************************/
104 static int vlclua_version( lua_State *L )
106 lua_pushstring( L, VLC_Version() );
110 /*****************************************************************************
111 * Get the VLC copyright
112 *****************************************************************************/
113 static int vlclua_copyright( lua_State *L )
115 lua_pushliteral( L, COPYRIGHT_MESSAGE );
119 /*****************************************************************************
120 * Get the VLC license msg/disclaimer
121 *****************************************************************************/
122 static int vlclua_license( lua_State *L )
124 lua_pushstring( L, LICENSE_MSG );
128 /*****************************************************************************
130 *****************************************************************************/
131 static int vlclua_quit( lua_State *L )
133 vlc_object_t *p_this = vlclua_get_this( L );
134 /* The rc.c code also stops the playlist ... not sure if this is needed
136 libvlc_Quit( p_this->p_libvlc );
140 /*****************************************************************************
141 * Global properties getters
142 *****************************************************************************/
143 static int vlclua_datadir( lua_State *L )
145 char *psz_data = config_GetDataDir( vlclua_get_this( L ) );
146 lua_pushstring( L, psz_data );
151 static int vlclua_userdatadir( lua_State *L )
153 char *dir = config_GetUserDir( VLC_DATA_DIR );
154 lua_pushstring( L, dir );
159 static int vlclua_homedir( lua_State *L )
161 char *home = config_GetUserDir( VLC_HOME_DIR );
162 lua_pushstring( L, home );
167 static int vlclua_configdir( lua_State *L )
169 char *dir = config_GetUserDir( VLC_CONFIG_DIR );
170 lua_pushstring( L, dir );
175 static int vlclua_cachedir( lua_State *L )
177 char *dir = config_GetUserDir( VLC_CACHE_DIR );
178 lua_pushstring( L, dir );
183 static int vlclua_datadir_list( lua_State *L )
185 const char *psz_dirname = luaL_checkstring( L, 1 );
186 char **ppsz_dir_list = NULL;
189 if( vlclua_dir_list( vlclua_get_this( L ), psz_dirname, &ppsz_dir_list )
193 for( char **ppsz_dir = ppsz_dir_list; *ppsz_dir; ppsz_dir++ )
195 lua_pushstring( L, *ppsz_dir );
196 lua_rawseti( L, -2, i );
199 vlclua_dir_list_free( ppsz_dir_list );
202 /*****************************************************************************
204 *****************************************************************************/
205 static int vlclua_lock_and_wait( lua_State *L )
207 intf_sys_t *p_sys = vlclua_get_intf( L );
209 vlc_mutex_lock( &p_sys->lock );
210 mutex_cleanup_push( &p_sys->lock );
211 while( !p_sys->exiting )
212 vlc_cond_wait( &p_sys->wait, &p_sys->lock );
214 lua_pushboolean( L, 1 );
218 static int vlclua_mdate( lua_State *L )
220 lua_pushnumber( L, mdate() );
224 static int vlclua_mwait( lua_State *L )
226 double f = luaL_checknumber( L, 1 );
231 static int vlclua_intf_should_die( lua_State *L )
233 intf_sys_t *p_sys = vlclua_get_intf( L );
234 lua_pushboolean( L, p_sys->exiting );
238 static int vlclua_action_id( lua_State *L )
240 vlc_key_t i_key = vlc_GetActionId( luaL_checkstring( L, 1 ) );
243 lua_pushnumber( L, i_key );
247 /*****************************************************************************
249 *****************************************************************************/
250 static int vlclua_timer_schedule( lua_State *L );
251 static int vlclua_timer_getoverrun( lua_State *L);
253 static const luaL_Reg vlclua_timer_reg[] = {
254 { "schedule", vlclua_timer_schedule },
255 { "getoverrun", vlclua_timer_getoverrun },
266 static int vlclua_timer_schedule( lua_State *L )
268 vlclua_timer_t **pp_timer = (vlclua_timer_t**)luaL_checkudata( L, 1, "timer" );
269 if( !pp_timer || !*pp_timer )
270 luaL_error( L, "Can't get pointer to timer" );
272 bool b_relative = luaL_checkboolean( L, 2 );
273 mtime_t i_value = luaL_checkinteger( L, 3 );
274 mtime_t i_interval = luaL_checkinteger( L, 4 );
276 vlc_timer_schedule( (*pp_timer)->timer, b_relative, i_value, i_interval );
280 static int vlclua_timer_getoverrun( lua_State *L )
282 vlclua_timer_t **pp_timer = (vlclua_timer_t**)luaL_checkudata(L, 1, "timer" );
283 if( !pp_timer || !*pp_timer )
284 luaL_error( L, "Can't get pointer to timer" );
286 lua_pushinteger( L, vlc_timer_getoverrun( (*pp_timer)->timer ) );
290 static void vlclua_timer_callback( void *data )
292 vlclua_timer_t *p_timer = (vlclua_timer_t*)data;
293 lua_State *L = p_timer->L;
295 lua_getglobal( L, p_timer->psz_callback );
296 if( lua_pcall( L, 0, 0, 0 ) )
298 const char *psz_err = lua_tostring( L, -1 );
299 msg_Err( vlclua_get_this( L ), "Error while running the timer callback: '%s'", psz_err );
304 static int vlclua_timer_delete( lua_State *L )
306 vlclua_timer_t **pp_timer = (vlclua_timer_t**)luaL_checkudata( L, 1, "timer" );
307 if( !pp_timer || !*pp_timer )
308 luaL_error( L, "Can't get pointer to timer" );
310 vlc_timer_destroy( (*pp_timer)->timer );
311 free( (*pp_timer)->psz_callback );
315 static int vlclua_timer_create( lua_State *L )
317 vlclua_timer_t *p_timer = malloc( sizeof( vlclua_timer_t ) );
318 if( !lua_isstring( L, 1 ) )
319 return luaL_error( L, "timer(function_name)" );
321 if( vlc_timer_create( &p_timer->timer, vlclua_timer_callback, p_timer ) )
322 return luaL_error( L, "Cannot initialize the timer" );
325 p_timer->psz_callback = strdup( luaL_checkstring( L, 1 ) );
327 vlclua_timer_t **pp_timer = lua_newuserdata( L, sizeof( vlclua_timer_t* ) );
330 /* Create the object */
331 if( luaL_newmetatable( L, "timer" ) )
334 luaL_register( L, NULL, vlclua_timer_reg );
335 lua_setfield( L, -2, "__index" );
336 lua_pushcfunction( L, vlclua_timer_delete );
337 lua_setfield( L, -2, "__gc" );
339 lua_setmetatable( L, -2 );
344 /*****************************************************************************
346 *****************************************************************************/
347 static const luaL_Reg vlclua_misc_reg[] = {
348 { "version", vlclua_version },
349 { "copyright", vlclua_copyright },
350 { "license", vlclua_license },
352 { "datadir", vlclua_datadir },
353 { "userdatadir", vlclua_userdatadir },
354 { "homedir", vlclua_homedir },
355 { "configdir", vlclua_configdir },
356 { "cachedir", vlclua_cachedir },
357 { "datadir_list", vlclua_datadir_list },
359 { "action_id", vlclua_action_id },
361 { "mdate", vlclua_mdate },
362 { "mwait", vlclua_mwait },
364 { "lock_and_wait", vlclua_lock_and_wait },
366 { "should_die", vlclua_intf_should_die },
367 { "quit", vlclua_quit },
369 { "timer", vlclua_timer_create },
374 void luaopen_misc( lua_State *L )
377 luaL_register( L, NULL, vlclua_misc_reg );
378 lua_setfield( L, -2, "misc" );