From 03b32ffa7e11e1f65ce197a2b3083bb7b761f0d4 Mon Sep 17 00:00:00 2001 From: Daniel Barlow Date: Fri, 1 Jul 2022 22:17:41 +0100 Subject: [PATCH] make event_loop_add_fd available to Lua on kiwmi singleton CAUTION - the implementation is unfinished, as it doesn't clean up when the fd is closed --- kiwmi/kiwmi/luak/kiwmi_server.c | 67 +++++++++++++++++++++++++++++++++ kiwmi/lua_docs.md | 7 ++++ 2 files changed, 74 insertions(+) diff --git a/kiwmi/kiwmi/luak/kiwmi_server.c b/kiwmi/kiwmi/luak/kiwmi_server.c index b5188c4..de0ad14 100644 --- a/kiwmi/kiwmi/luak/kiwmi_server.c +++ b/kiwmi/kiwmi/luak/kiwmi_server.c @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -208,6 +209,71 @@ l_kiwmi_server_quit(lua_State *L) return 0; } +static int +kiwmi_server_event_loop_fd_handler(int fd, uint32_t mask, void *data) +{ + struct kiwmi_lua_callback *lc = data; + lua_State *L = lc->server->lua->L; + + lua_rawgeti(L, LUA_REGISTRYINDEX, lc->callback_ref); + lua_pushvalue(L, -1); + lua_pushinteger(L, fd); + lua_pushinteger(L, mask); + + if (lua_pcall(L, 2, 0, 0)) { + wlr_log(WLR_ERROR, "%s", lua_tostring(L, -1)); + } + /* + FIXME we need to call + luaL_unref(L, LUA_REGISTRYINDEX, lc->callback_ref); + free(lc); + + when the file is closed, but probably not before then + */ + return true; +} + +static int +l_kiwmi_server_event_loop_add_fd(lua_State *L) +{ + /* args : self, fd, mode, handler */ + struct kiwmi_object *obj = + *(struct kiwmi_object **)luaL_checkudata(L, 1, "kiwmi_server"); + + struct kiwmi_server *server = obj->object; + + + int fd = lua_tonumber(L, 2); + int mode = lua_tonumber(L, 3); + luaL_checktype(L, 4, LUA_TFUNCTION); // callback + + int event_types; + switch(mode) { + case O_WRONLY: event_types = WL_EVENT_WRITABLE; break; + case O_RDONLY: event_types = WL_EVENT_READABLE; break; + default: event_types = WL_EVENT_WRITABLE | WL_EVENT_READABLE; break; + } + + struct kiwmi_lua_callback *lc = malloc(sizeof(*lc)); + if (!lc) { + return luaL_error(L, "failed to allocate kiwmi_lua_callback"); + } + + wlr_log(WLR_INFO, "add fd %d lc=%x\n", fd, lc); + + lc->server = server; + /* luaL_ref pops last parameter (callback) from stack */ + lc->callback_ref = luaL_ref(L, LUA_REGISTRYINDEX); + + wl_event_loop_add_fd(server->wl_event_loop, + fd, + event_types, + kiwmi_server_event_loop_fd_handler, + lc); + return true; +} + + static int kiwmi_server_schedule_handler(void *data) { @@ -395,6 +461,7 @@ static const luaL_Reg kiwmi_server_methods[] = { {"verbosity", l_kiwmi_server_verbosity}, {"view_at", l_kiwmi_server_view_at}, {"outputs", l_kiwmi_server_next_output}, + {"event_loop_add_fd", l_kiwmi_server_event_loop_add_fd}, {NULL, NULL}, }; diff --git a/kiwmi/lua_docs.md b/kiwmi/lua_docs.md index f04a920..607dddc 100644 --- a/kiwmi/lua_docs.md +++ b/kiwmi/lua_docs.md @@ -33,6 +33,13 @@ Sets the background color (shown behind all views) to `color` (in the format #rr Returns a reference to the cursor object. +#### kiwmi:event_loop_add_fd(fd, mode, callback) + +By registering with the event loop, arrange for `callback` to be called +whenever there is activity on the file descriptor `fd`. The `mode` parameter +is one of `O_RDWR`, `O_RDONLY`, `O_WRONLY` as defined in luaposix +`posix.fcntl` module. + #### kiwmi:focused_view() Returns the currently focused view.