--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/glib_main_context.c Sun Feb 01 21:28:57 2009 +0200
@@ -0,0 +1,248 @@
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <glib.h>
+
+#include "glib_types.h"
+
+/// g.main_context
+/// Glib main context object. Mainly useful when lua needs to
+/// manage glib-based libs.
+
+/// g.main_context.new
+/// Creates new main context object.
+/// R: g main context object
+static int lglib_main_context_new (lua_State *L)
+{
+ GMainContext *context = g_main_context_new ();
+ lglib_main_context_bless (L, context);
+ g_main_context_unref (context);
+ return 1;
+}
+
+/// g.main_context.bless
+/// Blesses given pointer to g main context object.
+/// A: lightuserdata (C g main context object)
+/// R: g main context object
+static int lglib_main_context_bless_lua (lua_State *L)
+{
+ luaL_argcheck (L, lua_islightuserdata (L, 1), 1, "g main context lightuserdata expected");
+ lglib_main_context_bless (L, lua_touserdata (L, 1));
+ return 1;
+}
+
+/// g.main_context.default
+/// Returns default main context object.
+/// R: g main context object
+static int lglib_main_context_default (lua_State *L)
+{
+ GMainContext *context = g_main_context_default ();
+ lglib_main_context_bless (L, context);
+ // XXX g_main_context_unref (context);
+ return 1;
+}
+
+/// main_context:iteration
+/// Performs single full iteration in blocking or non-blocking manner,
+/// depending on value of argument.
+/// Returns true, if some events have been handled.
+/// A: boolean (optional)
+/// R: boolean
+static int lglib_main_context_iteration (lua_State *L)
+{
+ lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
+ int may_block = 0;
+ if ( lua_gettop (L) > 1 ) {
+ luaL_checktype (L, 2, LUA_TBOOLEAN);
+ may_block = lua_toboolean (L, 2);
+ }
+ lua_pushboolean (L, g_main_context_iteration (object->main_context, may_block));
+ return 1;
+}
+
+/// main_context:pending
+/// Indicates, if there are present events in sources.
+/// R: boolean
+static int lglib_main_context_pending (lua_State *L)
+{
+ lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
+ lua_pushboolean (L, g_main_context_pending (object->main_context));
+ return 1;
+}
+
+/// main_context:find_source
+/// Returns source with given id.
+/// A: integer (source id)
+/// R: g main context object or nil
+static int lglib_main_context_find_source (lua_State *L)
+{
+ lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
+ int id = luaL_checkint (L, 2);
+ GSource *source = g_main_context_find_source_by_id (object->main_context, id);
+ if (source) {
+ lglib_source_bless (L, source);
+ // XXX g_source_unref (source)
+ } else
+ lua_pushnil (L);
+ return 1;
+}
+
+/// main_context:wakeup
+/// Awakes main context if it currently poll() ing.
+/// XXX Seems to be threading-related routine, how lua will work in this case?
+static int lglib_main_context_wakeup (lua_State *L)
+{
+ lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
+ g_main_context_wakeup (object->main_context);
+ return 0;
+}
+
+/// main_context:acquire
+/// Tries to own main context.
+/// R: boolean (success)
+static int lglib_main_context_acquire (lua_State *L)
+{
+ lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
+ lua_pushboolean (L, g_main_context_acquire (object->main_context));
+ return 1;
+}
+
+/// main_context:release
+/// Disowns acquired context.
+/// Note: release context as many times, as you acquired it.
+static int lglib_main_context_release (lua_State *L)
+{
+ lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
+ g_main_context_release (object->main_context);
+ return 0;
+}
+
+/// main_context:owner
+/// Indicates if current thread is owner of context.
+/// R: boolean
+static int lglib_main_context_owner (lua_State *L)
+{
+ lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
+ lua_pushboolean (L, g_main_context_is_owner (object->main_context));
+ return 1;
+}
+
+/// main_context:wait
+/// For now this will not be implemented, as it requires threading part of glib
+
+/// WARNING: conventions for next four methods are likely to change
+/// as I become more familiar with all that stuff.
+
+/// main_context:prepare
+/// Polling preparation step.
+/// R: boolean (indicates readiness for dispatching before polling), integer (priority of most important ready source, if first value is true)
+static int lglib_main_context_prepare (lua_State *L)
+{
+ lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
+ gint priority;
+ gboolean ready = g_main_context_prepare (object->main_context, &priority);
+ lua_pushboolean (L, ready);
+ if (!ready)
+ return 1;
+ lua_pushnumber (L, priority);
+ return 0;
+}
+
+/// main_context:query
+/// Get necessary for polling information.
+/// A: integer (maximum priority), integer (number of fds to allocate)
+/// R: userdata (GPollFDs), integer (number of fds required), integer (timeout)
+static int lglib_main_context_query (lua_State *L)
+{
+ lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
+ int priority = luaL_checkint (L, 2);
+ int nfds = luaL_checkint (L, 3);
+ gint timeout;
+ GPollFD *fds = lua_newuserdata (L, sizeof (GPollFD) * nfds);
+ lua_pushnumber (L, g_main_context_query (object->main_context, priority, &timeout, fds, nfds));
+ lua_pushnumber (L, timeout);
+ return 3;
+}
+
+/// main_context:check
+/// Passes results of polling back to main loop.
+/// A: integer (priority), userdata (GPollFDs), integer (number of fds)
+/// R: boolean (readiness for dispatching)
+static int lglib_main_context_check (lua_State *L)
+{
+ lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
+ int priority = luaL_checkint (L, 2);
+ GPollFD *fds = lua_touserdata (L, 3); // FIXME
+ int nfds = luaL_checkint (L, 4);
+ lua_pushboolean (L, g_main_context_check (object->main_context, priority, fds, nfds));
+ return 1;
+}
+
+/// main_context:dispatch
+/// Actually dispatches pending event sources
+static int lglib_main_context_dispatch (lua_State *L)
+{
+ lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
+ g_main_context_dispatch (object->main_context);
+ return 0;
+}
+
+/// main_context:poll_function
+/// main_context:add_poll
+/// main_context:remove_poll
+/// Let's delay implementing this until fd objects will be ready...
+
+/// main_context:pointer
+/// Returns pointe to underlying C structure.
+/// A: g main context object
+/// R: lightuserdata
+static int lglib_main_context_pointer (lua_State *L)
+{
+ lglib_main_context_t *object = luaL_checklglib_main_context (L, 1);
+ lua_pushlightuserdata (L, object->main_context);
+ return 1;
+}
+
+static int lglib_main_context_gc (lua_State *L)
+{
+ lglib_main_context_t *object = lua_touserdata (L, 1);
+ g_main_context_unref (object->main_context);
+ return 0;
+}
+
+static const luaL_Reg lglib_main_context_reg_f[] = {
+ { "new", lglib_main_context_new },
+ { "bless", lglib_main_context_bless_lua },
+ { "default", lglib_main_context_default },
+ { NULL, NULL },
+};
+
+static const luaL_Reg lglib_main_context_reg_m[] = {
+ { "iteration", lglib_main_context_iteration },
+ { "pending", lglib_main_context_pending },
+ { "find_source", lglib_main_context_find_source },
+ { "wakeup", lglib_main_context_wakeup },
+ { "acquire", lglib_main_context_acquire },
+ { "release", lglib_main_context_release },
+ { "owner", lglib_main_context_owner },
+ { "prepare", lglib_main_context_prepare },
+ { "query", lglib_main_context_query },
+ { "check", lglib_main_context_check },
+ { "dispatch", lglib_main_context_dispatch },
+ { "pointer", lglib_main_context_pointer },
+ { "__gc", lglib_main_context_gc },
+ { NULL, NULL },
+};
+
+int luaopen_glib_main_context (lua_State *L)
+{
+ luaL_newmetatable (L, "glib.main_context" );
+ lua_pushstring (L, "__index");
+ lua_pushvalue (L, -2);
+ lua_settable (L, -3);
+ luaL_register (L, NULL, lglib_main_context_reg_m);
+ lua_pop (L, 1);
+ luaL_register (L, "g.main_context", lglib_main_context_reg_f);
+ return 1;
+}
+