glib_source.c
changeset 0 84fdfb0344c9
--- /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 <lua.h>
+#include <lauxlib.h>
+#include <glib.h>
+
+#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;
+}
+