diff -r 000000000000 -r 84fdfb0344c9 glib_source.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/glib_source.c Sun Feb 01 21:28:57 2009 +0200 @@ -0,0 +1,133 @@ + +#include +#include +#include + +#include "glib_types.h" +#include "util.h" + +/// g.source.bless +/// Blesses given pointer to g source object. +/// A: lightuserdata (pointer to C glib event source object) +/// R: g source object +static int lglib_source_bless_lua (lua_State *L) +{ + luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "glib source lightuserdata expected"); + lglib_source_bless (L, lua_touserdata (L, 1)); + return 1; +} + +/// source:context +/// Connects event source to main context or returns context, +/// to which this source is connected. +/// A: lglib main context object +/// R: int (source id, when called with args) or g main context object or nil (if called with no args) +static int lglib_source_context (lua_State *L) +{ + lglib_source_t *object = luaL_checklglib_source (L, 1); + if (lua_gettop (L) > 1) { // Attach + lglib_main_context_t *context = luaL_checklglib_main_context (L, 2); + lua_pushnumber (L, g_source_attach (object->source, context->main_context)); + } else { // Get + GMainContext *context = g_source_get_context (object->source); + if (context) { + lglib_main_context_bless (L, context); + // XXX g_main_context_unref (context); + } else + lua_pushnil (L); + } + return 1; +} + +/// source callback function +/// Does processing of events. Return value indicates, if source should not be destroyed. +/// R: boolean (continue) +static gboolean lglib_source_callback (lglib_callback_t *cb) +{ + lua_rawgeti (cb->L, LUA_REGISTRYINDEX, cb->reference); + if (lua_pcall (cb->L, 0, 1, 0)) { + // XXX lua_error (cb->L); + lua_pop (cb->L, 1); + return FALSE; + } + return lua_toboolean (cb->L, -1); +} + +/// source:callback +/// Sets callback function for given event source. +/// A: source callback function +static int lglib_source_set_callback (lua_State *L) +{ + lglib_source_t *object = luaL_checklglib_source (L, 1); + lglib_callback_t *cb; + luaL_argcheck (L, lua_isfunction (L, 2), 2, "function expected"); + + cb = luaL_malloc (L, sizeof (lglib_callback_t)); + cb->reference = luaL_ref (L, LUA_REGISTRYINDEX); + cb->L = L; + + g_source_set_callback (object->source, (GSourceFunc)lglib_source_callback, + cb, (GDestroyNotify)lglib_callback_destroy); + return 0; +} + +/// source:priority +/// Sets or gets priority of source. +/// A: integer (optional priority) +/// R: integer (when called with no args) +static int lglib_source_priority (lua_State *L) +{ + lglib_source_t *object = luaL_checklglib_source (L, 1); + if (lua_gettop (L) > 1) { + g_source_set_priority (object->source, luaL_checkint (L, 2)); + return 0; + } else { + lua_pushnumber (L, g_source_get_priority (object->source)); + return 1; + } +} + +/// source:pointer +/// Returns pointer to underlying C structure. +/// A: g source object +/// R: lightuserdata +static int lglib_source_pointer (lua_State *L) +{ + lglib_source_t *object = luaL_checklglib_source (L, 1); + lua_pushlightuserdata (L, object->source); + return 1; +} + +static int lglib_source_gc (lua_State *L) +{ + lglib_source_t *object = lua_touserdata (L, 1); + g_source_unref (object->source); + return 0; +} + +const luaL_Reg lglib_source_reg_f[] = { + { "bless", lglib_source_bless_lua }, + { NULL, NULL }, +}; + +const luaL_Reg lglib_source_reg_m[] = { + { "context", lglib_source_context }, + { "priority", lglib_source_priority }, + { "callback", lglib_source_set_callback }, + { "pointer", lglib_source_pointer }, + { "__gc", lglib_source_gc }, + { NULL, NULL }, +}; + +int luaopen_glib_source (lua_State *L) +{ + luaL_newmetatable (L, "glib.source"); + lua_pushstring (L, "__index"); + lua_pushvalue (L, -2); + lua_settable (L, -3); + luaL_register (L, NULL, lglib_source_reg_m); + lua_pop (L, 1); + luaL_register (L, "g.source", lglib_source_reg_f); + return 1; +} +