Fork of Tangara with customizations
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
tangara-fw/lib/luavgl/src/indev.c

351 lines
7.9 KiB

#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);
}
#if 0
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;
}
#endif
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;
}
#if 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);
}
LV_LOG_INFO("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;
}
#endif
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)
{
LV_LOG_INFO("enter");
#if 0
/* 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;
}
#endif
return 0;
}
/**
* luavgl.indev lib
*/
static const luaL_Reg indev_lib[] = {
{"get_act", luavgl_indev_get_act },
#if 0
{"get_obj_act", luavgl_indev_get_obj_act},
#endif
{"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 },
#if 0
{"on_event", luavgl_indev_on_event },
#endif
{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");
}