xuneo / luavgl Goto Github PK
View Code? Open in Web Editor NEWlua + lvgl = luavgl An optimized lvgl Lua binding
License: MIT License
lua + lvgl = luavgl An optimized lvgl Lua binding
License: MIT License
How do I add my own properties to the LVGL objects? I want to do something like this, but this doesn't work quite right.
local function createBtn(parent, x, y, w, h, name, index)
local root = parent:Object {
x = x,
y = y,
w = w,
h = h,
}
getmetatable(root).__index = {
index = index
}
root:add_style(style_default, lvgl.STATE.DEFAULT)
root:add_style(style_pressed, lvgl.STATE.PRESSED)
root:onevent(lvgl.EVENT.CLICKED, function (obj, code)
print(obj.index_, " clicked")
end)
No response
I think Lua is very good language for embedded systems, however LVGL doesn't have an officially supported Lua binding yet.
Your solution seems quite complete and actively maintained.
I would be happy to promote your Lua binding (similar to MicroPython), so I wonder if you would be interested migrating this repository under the LVGL organization. Of course you (and anyone you name) would receive maintainer/write permission.
LVGL currently doesn't support return an event handler so it can be removed later.
The only solution is comparing all event dsc user_data.
The issue can be solved by simply storing the event dsc pointer to lvgl internal array and return it to user.
For lua, it needs to remember which events are added from lua side, so when obj is cleaned up, those events can be removed separately with native added events.
Use dsc pointer in lvgl internal array, and use lv_array to store events added from lua.
Crash only happen with luajit but not lua.
Another crash may be related with following reproduce steps:
AddressSanitizer:DEADLYSIGNAL
=================================================================
==1680078==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x5644a0de7ee6 bp 0x7ffe84f88d30 sp 0x7ffe84f88d10 T0)
==1680078==The signal is caused by a READ memory access.
==1680078==Hint: address points to the zero page.
#0 0x5644a0de7ee5 in luavgl_indev_gc ../src/indev.c:278
#1 0x7fdeb4679fb6 (/lib/x86_64-linux-gnu/libluajit-5.1.so.2+0x8fb6)
#2 0x7fdeb4686f59 (/lib/x86_64-linux-gnu/libluajit-5.1.so.2+0x15f59)
#3 0x7fdeb46a7105 (/lib/x86_64-linux-gnu/libluajit-5.1.so.2+0x36105)
#4 0x7fdeb46a7267 (/lib/x86_64-linux-gnu/libluajit-5.1.so.2+0x36267)
#5 0x7fdeb467a325 (/lib/x86_64-linux-gnu/libluajit-5.1.so.2+0x9325)
#6 0x7fdeb46c8bed in lua_close (/lib/x86_64-linux-gnu/libluajit-5.1.so.2+0x57bed)
#7 0x5644a0dd2dfc in lua_terminate ../simulator/main.c:290
#8 0x5644a0dd2e3a in reload_cb ../simulator/main.c:302
#9 0x5644a0df80fa in event_send_core ../deps/lvgl/src/core/lv_event.c:467
#10 0x5644a0df4f0c in lv_event_send ../deps/lvgl/src/core/lv_event.c:75
#11 0x5644a0e011c8 in indev_proc_release ../deps/lvgl/src/core/lv_indev.c:980
#12 0x5644a0dfd32d in indev_pointer_proc ../deps/lvgl/src/core/lv_indev.c:384
#13 0x5644a0dfadbd in lv_indev_read_timer_cb ../deps/lvgl/src/core/lv_indev.c:101
#14 0x5644a0ec0e46 in lv_timer_exec ../deps/lvgl/src/misc/lv_timer.c:313
#15 0x5644a0ec05b4 in lv_timer_handler ../deps/lvgl/src/misc/lv_timer.c:109
#16 0x5644a0dd2f43 in main ../simulator/main.c:335
#17 0x7fdeb4443082 in __libc_start_main ../csu/libc-start.c:308
#18 0x5644a0dcd58d in _start (/home/neo/projects/luavgl/build/simulator/simulator+0x4d58d)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ../src/indev.c:278 in luavgl_indev_gc
==1680078==ABORTING
How can I attach an event handler to the top level screen? I would like to capture gestures.
void scr_event_cb(lv_obj_t * obj, lv_event_t e)
{
if(e == LV_EVENT_GESTURE) {
lv_gesture_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act());
printf("Dir: %d\n", dir);
}
}
lv_obj_set_event_cb(lv_scr_act(), scr_event_cb);
No response
Would need these three API and some constants.
lv_palette_main(LV_PALETTE_...)
lv_palette_lighten(LV_PALETTE_..., v)
lv_palette_darken(LV_PALETTE_..., v)
No response
FYI issue for the future. I had a lot of widgets selectively turned off in LVGL to save RAM on my device. I had to turn a bunch of them back on since Luavgl didn't compile with them turned off. For example I don't need a keyboard and textarea but I had to turn them back on because Luavgl didn't support having them off. This is no big deal, when I get back to minimizing RAM I can #ifdef luavgl as needed for my use case.
things like this....
CONFIG_LV_USE_ROLLER=y
CONFIG_LV_USE_KEYBOARD=y
CONFIG_LV_USE_TEXTAREA=y
BTW, I am using Luavgl with NodeMCU on an ESP32S3 with an RGB LCD.
No response
I don't see any way to construct an image, either draw_ctx or canvas. I need to construct RGB and HSL spectrum gradient bitmaps. I can make them in C and pass back to Lua, but do you have plans for a drawing API?
No response
APIs for lvgl.display is missing in file lvgl.lua
No response
Add missing config, add PNG, JPEG lib support, similar to lv_port_pc_eclipse
.
No response
set/get
methodsAdd one simple build test is enough for now.
No response
Use LVGL's property API instead of manually calling every widget's property API like lv_image_set_rotation
could simplify the porting layer between LVGL and LUA.
Also need to finish missing property ID definitions in LVGL.
No response
Could I please get support for lv_font_load()?
LVGL should be able to load fonts from SPIFFS, right?
Custom fonts added at build time are working fine, I already added one to my app.
No response
Hello Xu,
Thanks for your great work.
Can you add more information about how to prepare the lvgl environment ?
I remember that the luavgl library should be a dynamic library (.so file). so lua can find it when local lvgl = require("lvgl").
It it right ?
NodeMCU has made some interesting macros which might be worth copying.
https://github.com/nodemcu/nodemcu-firmware/blob/release/app/lua53/lnodemcu.h
example use:
https://github.com/nodemcu/nodemcu-firmware/blob/release/app/modules/i2c.c#L149
NodeMCU doesn't need a file like lvgl.lua. I don't know enough about Lua yet to understand why or which way is better.
No response
Avoid including string.h etc. directly since it may not be available.
No response
Continue of #10.
To free resources added to obj from LUA code, we monitor if obj is deleted by event LV_EVENT_DELETE
and clean up in the event callback.
Lines 846 to 847 in 964eeba
However, the event callback registered to lvgl is called from below code.
Note the for loop is actually accessing the event array. So it's crucial not to mess up the array in the event callback we registered.
So below code will report heap-use-after-free, because luavgl_obj_delete
will remove events registered from lua, thus modifying event array while iterating it.
Lines 50 to 69 in 964eeba
No response
I'm trying to get this to build and run on Win-10 using MSVC /clang-cl. But have nothing but troubles.
But first off, the example on the main page does not even parse with my Lua 5.4: lua.exe test.lua
:
lua.exe: test.lua:13: '}' expected (to close '{' at line 8) near 'pad_all'
It should read:
bg_color = "#112233", -- #RRGGBB, 0xRRGGBB or "#RGB"
pad_all = 0
}
and not bg_color = "#112233", -- #RRGGBB, 0xRRGGBB or "#RGB",
But then after adding a require "lvgl"
at the top, a lua.exe test.lua
crashes good inside lv_mem.c
. Call-stack:
lvgl!search_suitable_block(struct control_t * control = 0x00000000`00000000, int * fli = 0x000000cc`dedeea20, int * sli = 0x000000cc`dedeea24)+0x40
lvgl!block_locate_free(struct control_t * control = 0x00000000`00000000, unsigned int64 size = 0x38)+0x5e
lvgl!lv_tlsf_malloc(void * tlsf = 0x00000000`00000000, unsigned int64 size = 0x38)+0x3b
lvgl!lv_mem_alloc(unsigned int64 size = 0x38)+0x55
lvgl!lv_obj_class_create_obj(struct _lv_obj_class_t * class_p = 0x00007ffa`d8145098, struct _lv_obj_t * parent = 0x00000000`00000000)+0x2d
lvgl!lv_obj_create(struct _lv_obj_t * parent = 0x00000000`00000000)+0x44
lvgl!luaopen_lvgl(struct lua_State * L = 0x000001ef`00157658)+0x131
lua54_x64!luaD_precall(struct lua_State * L = 0x000001ef`00157658, union StackValue * func = 0x000001ef`00157d80, int nresults = 0n1)+0x22c
lua54_x64!ccall(struct lua_State * L = 0x000001ef`00157658, union StackValue * func = 0x000001ef`00157d80, int nResults = 0n1, int inc = 0n65537)+0x4c
lua54_x64!lua_callk(struct lua_State * L = 0x000001ef`00157658, int nargs = <Value unavailable error>, int nresults = 0n1, int64 ctx = <Value unavailable error>, <function> * k = 0x00000000`00000000)+0x5f
lua54_x64!ll_require(struct lua_State * L = 0x000001ef`00157658)+0x1fc
lua54_x64!luaD_precall(struct lua_State * L = 0x000001ef`00157658, union StackValue * func = 0x000001ef`00157d20, int nresults = 0n0)+0x22c
lua54_x64!luaV_execute(struct lua_State * L = 0x000001ef`00157658, struct CallInfo * ci = 0x000001ef`0017c230)+0x29e4
lua54_x64!ccall(struct lua_State * L = 0x000001ef`00157658, union StackValue * func = 0x000001ef`00157d00, int nResults = 0n-1, int inc = 0n65537)+0x65
lua54_x64!luaD_rawrunprotected(struct lua_State * L = 0x000001ef`00157658, <function> * f = 0x00007ffb`1eeb60c0, void * ud = 0x000000cc`dedef5a0)+0x73
lua54_x64!luaD_pcall(struct lua_State * L = 0x000001ef`00157658, <function> * func = <Value unavailable error>, void * u = <Value unavailable error>, int64 old_top = 0n80, int64 ef = 0n64)+0x40
lua54_x64!lua_pcallk(struct lua_State * L = 0x000001ef`00157658, int nargs = <Value unavailable error>, int nresults = 0n-1, int errfunc = <Value unavailable error>, int64 ctx = 0n0, <function> * k = 0x00000000`00000000)+0x10d
lua!docall(struct lua_State * L = 0x000001ef`00157658, int narg = 0n0, int nres = 0n-1)+0x7c
lua!handle_script(void)+0xfe
lua!pmain(struct lua_State * L = 0x000001ef`00157658)+0x589
lua54_x64!luaD_precall(struct lua_State * L = 0x000001ef`00157658, union StackValue * func = 0x000001ef`00157cc0, int nresults = 0n1)+0x22c
lua54_x64!ccall(struct lua_State * L = 0x000001ef`00157658, union StackValue * func = 0x000001ef`00157cc0, int nResults = 0n1, int inc = 0n65537)+0x4c
lua54_x64!luaD_rawrunprotected(struct lua_State * L = 0x000001ef`00157658, <function> * f = 0x00007ffb`1eeb60c0, void * ud = 0x000000cc`dedef8f0)+0x73
lua54_x64!luaD_pcall(struct lua_State * L = 0x000001ef`00157658, <function> * func = <Value unavailable error>, void * u = <Value unavailable error>, int64 old_top = 0n16, int64 ef = 0n0)+0x40
lua54_x64!lua_pcallk(struct lua_State * L = 0x000001ef`00157658, int nargs = <Value unavailable error>, int nresults = 0n1, int errfunc = <Value unavailable error>, int64 ctx = 0n0, <function> * k = 0x00000000`00000000)+0x10d
lua!main(int argc = <Value unavailable error>, char ** argv = 0x000001ef`00178130)+0xec
lua!invoke_main(void)+0x22
lua!__scrt_common_main_seh(void)+0x10c
KERNEL32!BaseThreadInitThunk+0x14
ntdll!RtlUserThreadStart+0x21
presumably since lv_mem_init()
was not called for LV_MEM_CUSTOM == 0
.
So I really have no idea how to use this library. Seems not very robust.
And BTW, why is not LuaJIT supported? Much faster AFAICS.
And it does not build with LVGL from master
. Why not?
I am using the lvgl-v8 branch on an ESP32 which doesn't have v9 available yet.
Most things are working, adding this failed: local scr = lvgl.disp.get_scr_act()
I traced down to this:
luavgl_disp_t *v = luaL_checkudata(L, idx, "lv_disp");
p is null, so it calls typeerror()
luavgl_disp_init() is getting called and it makes the metatable.
/init.lua:1: bad argument #1 to 'get_scr_act' (lv_disp expected, got no value)
stack traceback:
[C]: in field 'get_scr_act'
/init.lua:1: in main chunk
[C]: in ?
No response
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.