luat_lib_lvgl7.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /*
  2. @module lvgl
  3. @summary LVGL图像库
  4. @version 1.0
  5. @date 2021.06.01
  6. */
  7. #include "luat_base.h"
  8. #include "luat_lvgl.h"
  9. #include "luat_mem.h"
  10. #include "luat_zbuff.h"
  11. typedef struct luat_lv {
  12. lv_disp_t* disp;
  13. lv_disp_buf_t disp_buf;
  14. int buff_ref;
  15. int buff2_ref;
  16. }luat_lv_t;
  17. static luat_lv_t LV = {0};
  18. //static lv_disp_drv_t my_disp_drv;
  19. /**
  20. 初始化LVGL
  21. @api lvgl.init(w, h, lcd, buff_size, buff_mode)
  22. @int 屏幕宽,可选,默认从lcd取
  23. @int 屏幕高,可选,默认从lcd取
  24. @userdata lcd指针,可选,lcd初始化后有默认值,预留的多屏入口
  25. @int 缓冲区大小,默认宽*10, 不含色深.
  26. @int 缓冲模式,默认0, 单buff模式, 可选1,双buff模式
  27. @return bool 成功返回true,否则返回false
  28. */
  29. int luat_lv_init(lua_State *L);
  30. #ifdef LUAT_USE_LVGL_SDL2
  31. #include "luat_lcd.h"
  32. // SDL2 模式
  33. extern lv_disp_t *lv_sdl_init_display(const char* win_name, int width, int height);
  34. extern lv_indev_t *lv_sdl_init_input(void);
  35. #endif
  36. #if defined(LUAT_EMULATOR_MODE)
  37. // 模拟器模式
  38. int luat_lv_init(lua_State *L) {
  39. LLOGE("emulator mode init");
  40. int w = 480;
  41. int h = 320;
  42. if (lua_isnumber(L, 1) && lua_isnumber(L, 2)) {
  43. w = luaL_checkinteger(L, 1);
  44. h = luaL_checkinteger(L, 2);
  45. }
  46. extern void emulator_lvgl_init(int w, int h);
  47. emulator_lvgl_init(w, h);
  48. return 0;
  49. }
  50. // #elif defined(LUA_USE_WINDOWS)
  51. // // win32遗留模式
  52. // #include <windows.h>
  53. // extern uint32_t WINDOW_HOR_RES;
  54. // extern uint32_t WINDOW_VER_RES;
  55. // int luat_lv_init(lua_State *L) {
  56. // if (lua_isnumber(L, 1) && lua_isnumber(L, 2)) {
  57. // WINDOW_HOR_RES = luaL_checkinteger(L, 1);
  58. // WINDOW_VER_RES = luaL_checkinteger(L, 2);
  59. // }
  60. // LLOGD("win32 lvgl init %d %d", WINDOW_HOR_RES, WINDOW_VER_RES);
  61. // HWND windrv_init(void);
  62. // windrv_init();
  63. // lua_pushboolean(L, 1);
  64. // return 1;
  65. // }
  66. #elif defined(LUAT_USE_LVGL_INIT_CUSTOM)
  67. // 自定义模式, 这个由bsp自行实现了
  68. #else
  69. // 普通MCU模式
  70. #include "luat_lcd.h"
  71. static luat_lcd_conf_t* lcd_conf;
  72. static lv_color_t *fbuffer = NULL;
  73. static lv_color_t *fbuffer2 = NULL;
  74. LUAT_WEAK void luat_lv_disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) {
  75. //-----
  76. if (lcd_conf != NULL) {
  77. luat_lcd_draw(lcd_conf, area->x1, area->y1, area->x2, area->y2, color_p);
  78. if (disp_drv->buffer->flushing_last)
  79. luat_lcd_flush(lcd_conf);
  80. }
  81. //LLOGD("CALL disp_flush (%d, %d, %d, %d)", area->x1, area->y1, area->x2, area->y2);
  82. lv_disp_flush_ready(disp_drv);
  83. }
  84. int luat_lv_init(lua_State *L) {
  85. int w = 0;
  86. int h = 0;
  87. if (LV.disp != NULL) {
  88. lua_pushboolean(L, 0);
  89. return 1;
  90. }
  91. if (lua_isnumber(L, 1) && lua_isnumber(L, 2)) {
  92. w = luaL_checkinteger(L, 1);
  93. h = luaL_checkinteger(L, 2);
  94. }
  95. size_t fbuff_size = 0;
  96. size_t buffmode = 0;
  97. if (lua_isuserdata(L, 3)) {
  98. lcd_conf = lua_touserdata(L, 3);
  99. }
  100. else {
  101. lcd_conf = luat_lcd_get_default();
  102. }
  103. if (lcd_conf == NULL) {
  104. #if defined(LUA_USE_LINUX) || defined(LUA_USE_WINDOWS)
  105. if (w == 0 || h == 0) {
  106. w = 800;
  107. h = 640;
  108. }
  109. #else
  110. LLOGE("setup lcd first!!");
  111. return 0;
  112. #endif
  113. }
  114. if (w == 0 || h == 0) {
  115. w = lcd_conf->w;
  116. h = lcd_conf->h;
  117. }
  118. if (lua_isinteger(L, 4)) {
  119. fbuff_size = luaL_checkinteger(L, 4);
  120. if (fbuff_size < w*10)
  121. fbuff_size = w * 10;
  122. }
  123. else {
  124. fbuff_size = w * 10;
  125. }
  126. if (lua_isinteger(L, 5)) {
  127. buffmode = luaL_checkinteger(L, 5);
  128. }
  129. if (lcd_conf != NULL && lcd_conf->buff != NULL) {
  130. // LLOGD("use LCD buff");
  131. fbuffer = lcd_conf->buff;
  132. fbuff_size = w * h;
  133. }
  134. else if (buffmode & 0x02) {
  135. //LLOGD("use HEAP buff");
  136. fbuffer = luat_heap_malloc(fbuff_size * sizeof(lv_color_t));
  137. if (fbuffer == NULL) {
  138. LLOGD("not enough memory");
  139. return 0;
  140. }
  141. if (buffmode & 0x01) {
  142. fbuffer2 = luat_heap_malloc(fbuff_size * sizeof(lv_color_t));
  143. if (fbuffer2 == NULL) {
  144. luat_heap_free(fbuffer);
  145. LLOGD("not enough memory");
  146. return 0;
  147. }
  148. }
  149. }
  150. else {
  151. //LLOGD("use VM buff");
  152. fbuffer = lua_newuserdata(L, fbuff_size * sizeof(lv_color_t));
  153. if (fbuffer == NULL) {
  154. LLOGD("not enough memory");
  155. return 0;
  156. }
  157. if (buffmode & 0x01) {
  158. fbuffer2 = lua_newuserdata(L, fbuff_size * sizeof(lv_color_t));
  159. if (fbuffer2 == NULL) {
  160. LLOGD("not enough memory");
  161. return 0;
  162. }
  163. }
  164. // 引用即弹出
  165. if (fbuffer2)
  166. LV.buff2_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  167. LV.buff_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  168. }
  169. LLOGD("w %d h %d buff %d mode %d", w, h, fbuff_size, buffmode);
  170. lv_disp_buf_init(&LV.disp_buf, fbuffer, fbuffer2, fbuff_size);
  171. lv_disp_drv_t my_disp_drv;
  172. lv_disp_drv_init(&my_disp_drv);
  173. my_disp_drv.flush_cb = luat_lv_disp_flush;
  174. my_disp_drv.hor_res = w;
  175. my_disp_drv.ver_res = h;
  176. my_disp_drv.buffer = &LV.disp_buf;
  177. #ifdef LUAT_USE_LVGL_SDL2
  178. if (lcd_conf == NULL) {
  179. LLOGD("use LVGL-SDL2 分辨率 %dx%d", w, h);
  180. LV.disp =lv_sdl_init_display("LuatOS", w, h);
  181. lv_sdl_init_input();
  182. lua_pushboolean(L, LV.disp != NULL ? 1 : 0);
  183. return 1;
  184. }
  185. #endif
  186. LV.disp = lv_disp_drv_register(&my_disp_drv);
  187. if (LV.disp == NULL) {
  188. LLOGE("lv_disp_drv_register error");
  189. }
  190. lua_pushboolean(L, LV.disp != NULL ? 1 : 0);
  191. #ifdef LUAT_USE_LVGL_SDL2
  192. LLOGD("use LVGL-LCD-SDL2 swap %d", LV_COLOR_16_SWAP);
  193. lv_sdl_init_input();
  194. #endif
  195. #ifdef __LVGL_SLEEP_ENABLE__
  196. luat_lvgl_tick_sleep(0);
  197. #endif
  198. return 1;
  199. }
  200. #endif