summaryrefslogtreecommitdiff
path: root/lib/luavgl/src/indev.c
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-11-12 19:14:09 +1100
committerjacqueline <me@jacqueline.id.au>2023-11-12 19:14:09 +1100
commit8a0a167adbf3d9b6f8b6f16aaf20ca39ad5549de (patch)
tree02b6cf23f591915747ec2994381854a79979c4a0 /lib/luavgl/src/indev.c
parent8471046a95ab9e00f7d42b56dbbc9ce3e5b424b9 (diff)
downloadtangara-fw-8a0a167adbf3d9b6f8b6f16aaf20ca39ad5549de.tar.gz
Convert the main menu screen to lua lol
Diffstat (limited to 'lib/luavgl/src/indev.c')
-rw-r--r--lib/luavgl/src/indev.c342
1 files changed, 342 insertions, 0 deletions
diff --git a/lib/luavgl/src/indev.c b/lib/luavgl/src/indev.c
new file mode 100644
index 00000000..a21e3ee8
--- /dev/null
+++ b/lib/luavgl/src/indev.c
@@ -0,0 +1,342 @@
+#include "luavgl.h"
+#include "private.h"
+
+typedef struct luavgl_indev_s {
+ lv_indev_t *indev;
+} luavgl_indev_t;
+
+/* group APIs */
+static lv_group_t *luavgl_to_group(lua_State *L, int idx);
+
+static luavgl_indev_t *luavgl_check_indev(lua_State *L, int idx)
+{
+ luavgl_indev_t *v = luaL_checkudata(L, idx, "lv_indev");
+ if (v->indev == NULL) {
+ luaL_error(L, "null indev");
+ }
+
+ return v;
+}
+
+/**
+ * create new luavgl indev userdata.
+ */
+static int luavgl_indev_get(lua_State *L, lv_indev_t *indev)
+{
+ if (indev == NULL) {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ /* check if already exists */
+ lua_pushlightuserdata(L, indev);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+
+ if (lua_isnoneornil(L, -1)) {
+ /* create new indev userdata and add to registry forever */
+ lua_pop(L, 1);
+ luavgl_indev_t *i = lua_newuserdata(L, sizeof(luavgl_indev_t));
+ i->indev = indev;
+
+ luaL_getmetatable(L, "lv_indev");
+ lua_setmetatable(L, -2);
+
+ lua_pushlightuserdata(L, indev);
+ lua_pushvalue(L, -2);
+ lua_rawset(L, LUA_REGISTRYINDEX);
+ }
+
+ return 1;
+}
+
+static int luavgl_indev_get_act(lua_State *L)
+{
+ lv_indev_t *indev = lv_indev_get_act();
+ return luavgl_indev_get(L, indev);
+}
+
+static int luavgl_indev_get_obj_act(lua_State *L)
+{
+ lv_obj_t *obj = lv_indev_get_obj_act();
+ if (obj == NULL) {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ /* registry[obj] */
+ lua_pushlightuserdata(L, obj);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+
+ if (lua_isnoneornil(L, -1)) {
+ luavgl_add_lobj(L, obj)->lua_created = false;
+ }
+
+ return 1;
+}
+
+static int luavgl_indev_get_next(lua_State *L)
+{
+ lv_indev_t *indev = NULL;
+ if (!lua_isnoneornil(L, 1)) {
+ indev = luavgl_check_indev(L, 1)->indev;
+ }
+
+ indev = lv_indev_get_next(indev);
+ return luavgl_indev_get(L, indev);
+}
+
+static int luavgl_indev_get_type(lua_State *L)
+{
+ luavgl_indev_t *i = luavgl_check_indev(L, 1);
+ lv_indev_type_t t = lv_indev_get_type(i->indev);
+ lua_pushinteger(L, t);
+ return 1;
+}
+
+static int luavgl_indev_reset(lua_State *L)
+{
+ luavgl_indev_t *i = luavgl_check_indev(L, 1);
+ lv_obj_t *obj = luavgl_to_obj(L, 2);
+ lv_indev_reset(i->indev, obj);
+ return 0;
+}
+
+static int luavgl_indev_reset_long_press(lua_State *L)
+{
+ luavgl_indev_t *i = luavgl_check_indev(L, 1);
+
+ lv_indev_reset_long_press(i->indev);
+ return 1;
+}
+
+static int luavgl_indev_set_cursor(lua_State *L)
+{
+ luavgl_indev_t *i = luavgl_check_indev(L, 1);
+ lv_obj_t *obj = luavgl_to_obj(L, 2);
+ lv_indev_set_cursor(i->indev, obj);
+ return 0;
+}
+
+static int luavgl_indev_set_group(lua_State *L)
+{
+ luavgl_indev_t *i = luavgl_check_indev(L, 1);
+ lv_group_t *group = luavgl_to_group(L, 2);
+ lv_indev_set_group(i->indev, group);
+ return 0;
+}
+
+static int luavgl_indev_get_point(lua_State *L)
+{
+ luavgl_indev_t *i = luavgl_check_indev(L, 1);
+ lv_point_t point;
+ lv_indev_get_point(i->indev, &point);
+
+ lua_pushinteger(L, point.x);
+ lua_pushinteger(L, point.y);
+ return 2;
+}
+
+static int luavgl_indev_get_gesture_dir(lua_State *L)
+{
+ luavgl_indev_t *i = luavgl_check_indev(L, 1);
+ lv_dir_t dir = lv_indev_get_gesture_dir(i->indev);
+
+ lua_pushinteger(L, dir);
+ return 1;
+}
+
+static int luavgl_indev_get_key(lua_State *L)
+{
+ luavgl_indev_t *i = luavgl_check_indev(L, 1);
+ uint32_t v = lv_indev_get_key(i->indev);
+
+ lua_pushinteger(L, v);
+ return 1;
+}
+
+static int luavgl_indev_get_scroll_dir(lua_State *L)
+{
+ luavgl_indev_t *i = luavgl_check_indev(L, 1);
+ lv_dir_t dir = lv_indev_get_scroll_dir(i->indev);
+
+ lua_pushinteger(L, dir);
+ return 1;
+}
+
+static int luavgl_indev_get_scroll_obj(lua_State *L)
+{
+ luavgl_indev_t *i = luavgl_check_indev(L, 1);
+ lv_obj_t *obj = lv_indev_get_scroll_obj(i->indev);
+ if (obj == NULL) {
+ lua_pushnil(L);
+ return 1;
+ }
+
+ /* registry[obj] */
+ lua_pushlightuserdata(L, obj);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+
+ if (lua_isnoneornil(L, -1)) {
+ luavgl_add_lobj(L, obj)->lua_created = false;
+ }
+
+ return 1;
+}
+
+static int luavgl_indev_get_vect(lua_State *L)
+{
+ luavgl_indev_t *i = luavgl_check_indev(L, 1);
+ lv_point_t point;
+ lv_indev_get_vect(i->indev, &point);
+
+ lua_pushinteger(L, point.x);
+ lua_pushinteger(L, point.y);
+ return 2;
+}
+
+static int luavgl_indev_wait_release(lua_State *L)
+{
+ luavgl_indev_t *i = luavgl_check_indev(L, 1);
+ lv_indev_wait_release(i->indev);
+ return 0;
+}
+
+static void indev_feedback_cb(lv_indev_drv_t *driver, uint8_t code)
+{
+ lua_State *L = driver->user_data;
+ int top = lua_gettop(L);
+ lua_pushlightuserdata(L, driver);
+ lua_rawget(L, LUA_REGISTRYINDEX); /* get indev on stack */
+
+ lua_getuservalue(L, -1); /* stack: indev, uservalue-table */
+ lua_rawgeti(L, -1, code); /* indev, uservalue, cb */
+ if (lua_isnoneornil(L, -1)) {
+ lua_settop(L, top);
+ return;
+ }
+
+ lua_pushvalue(L, 1);
+ lua_pushinteger(L, code);
+ luavgl_pcall_int(L, 2, 0);
+ lua_settop(L, top);
+}
+
+/**
+ * indev:on_event(code, cb)
+ */
+static int luavgl_indev_on_event(lua_State *L)
+{
+ luavgl_indev_t *i = luavgl_check_indev(L, 1);
+ int code = lua_tointeger(L, 2);
+ luavgl_check_callable(L, 3);
+
+ lua_pushlightuserdata(L, i->indev->driver);
+ lua_rawget(L, LUA_REGISTRYINDEX);
+ if (lua_isnoneornil(L, -1)) {
+ lua_pop(L, 1);
+
+ /* set indev to registry using pointer as key */
+ lua_pushlightuserdata(L, i->indev->driver);
+ lua_pushvalue(L, 1);
+ lua_rawset(L, LUA_REGISTRYINDEX);
+ }
+
+ int type = lua_getuservalue(L, 1);
+ if (type != LUA_TTABLE) {
+ lua_pop(L, 1);
+ lua_createtable(L, 0, 1);
+ lua_pushvalue(L, -1);
+ lua_setuservalue(L, 1);
+ }
+
+ debug("add feedback_cb code %d, for indev->driver: %p\n", code,
+ i->indev->driver);
+ lua_pushvalue(L, 3);
+ lua_rawseti(L, -2, code);
+
+ i->indev->driver->feedback_cb = indev_feedback_cb;
+ i->indev->driver->user_data = L;
+ lua_settop(L, 1);
+ return 1;
+}
+
+static int luavgl_indev_tostring(lua_State *L)
+{
+ lua_pushfstring(L, "lv_indev: %p\n", luavgl_check_indev(L, 1));
+ return 1;
+}
+
+static int luavgl_indev_gc(lua_State *L)
+{
+ debug("\n");
+
+ /* If set_feedback_cb is used, then the indev only gets gc'ed when lua vm
+ * exits.
+ */
+ luavgl_indev_t *i = luavgl_check_indev(L, 1);
+ lua_getuservalue(L, 1);
+ if (!lua_isnoneornil(L, -1)) {
+ lua_pushlightuserdata(L, i->indev->driver);
+ lua_pushnil(L);
+ lua_rawset(L, LUA_REGISTRYINDEX);
+ i->indev->driver->feedback_cb = NULL;
+ }
+
+ return 0;
+}
+
+/**
+ * luavgl.indev lib
+ */
+static const luaL_Reg indev_lib[] = {
+ {"get_act", luavgl_indev_get_act },
+ {"get_obj_act", luavgl_indev_get_obj_act},
+ {"get_next", luavgl_indev_get_next },
+
+ {NULL, NULL },
+};
+
+/*
+** methods for file handles
+*/
+static const luaL_Reg methods[] = {
+ {"get_type", luavgl_indev_get_type },
+ {"reset", luavgl_indev_reset },
+ {"reset_long_press", luavgl_indev_reset_long_press},
+ {"set_cursor", luavgl_indev_set_cursor },
+ {"set_group", luavgl_indev_set_group },
+ {"get_point", luavgl_indev_get_point },
+ {"get_gesture_dir", luavgl_indev_get_gesture_dir },
+ {"get_key", luavgl_indev_get_key },
+ {"get_scroll_dir", luavgl_indev_get_scroll_dir },
+ {"get_scroll_obj", luavgl_indev_get_scroll_obj },
+ {"get_vect", luavgl_indev_get_vect },
+ {"wait_release", luavgl_indev_wait_release },
+ {"on_event", luavgl_indev_on_event },
+
+ {NULL, NULL },
+};
+
+static const luaL_Reg meta[] = {
+ {"__gc", luavgl_indev_gc },
+ {"__tostring", luavgl_indev_tostring},
+ {"__index", NULL }, /* place holder */
+
+ {NULL, NULL }
+};
+
+static void luavgl_indev_init(lua_State *L)
+{
+ /* create lv_fs metatable */
+ luaL_newmetatable(L, "lv_indev");
+ luaL_setfuncs(L, meta, 0);
+
+ luaL_newlib(L, methods);
+ lua_setfield(L, -2, "__index");
+
+ lua_pop(L, 1); /* pop metatable */
+
+ /* luavgl.indev lib */
+ luaL_newlib(L, indev_lib);
+ lua_setfield(L, -2, "indev");
+}