quickjs调用lvgl函数

  实现本次使用quickjs的最主要目的,就是通过程序动态加载js,然后调用lvgl函数库,实现渲染。以达到类似小程序的效果。后续还会实现类似小程序效果,通过quickjs解析xml(html),编译成js然后调用lvgl库,实现界面渲染。通过quickjs会调用c语言提供的底层功能,如wifi、蓝牙、串口uart、iic、isp、pwd、led等等硬件io功能。

下面写一些例子,只做技术验证

lvgl_export.h

 1 #include <string.h>
 2 #include <stdlib.h>
 3 #include "quickjs-libc.h"
 4 #include "cutils.h"
 5 #include "lvgl.h"
 6 
 7 #define lv_obj_ptr_t uintptr_t
 8 
 9 extern JSModuleDef *js_init_module_lvgl(JSContext *ctx, const char *module_name);
10 
11 int JS_ToInt8(JSContext *ctx, int8_t *pres, JSValueConst val);
12 int JS_ToUint8(JSContext *ctx, uint8_t *pres, JSValueConst val);
13 int JS_ToInt16(JSContext *ctx, int16_t *pres, JSValueConst val);
14 int JS_ToUint16(JSContext *ctx, uint16_t *pres, JSValueConst val);
15 int JS_ToPointer(JSContext *ctx, lv_obj_ptr_t *pres, JSValueConst val);
16 static inline JSValue JS_NewPointer(JSContext *ctx, lv_obj_ptr_t val);

lvgl_export.c

  1 #include "lvgl_export.h"
  2 
  3 static JSValue lvgl_obj_create(JSContext *ctx, JSValueConst this_val,
  4                                     int argc, JSValueConst *argv)
  5 {
  6   lv_obj_ptr_t p;
  7   JS_ToPointer(ctx, &p, argv[0]);
  8   lv_obj_t * parent = (lv_obj_t *)p;
  9   lv_obj_t * obj = lv_obj_create(parent);
 10   return JS_NewPointer(ctx, (lv_obj_ptr_t)obj);
 11 }
 12 static JSValue lvgl_label_create(JSContext *ctx, JSValueConst this_val,
 13                                     int argc, JSValueConst *argv)
 14 {
 15   lv_obj_ptr_t p;
 16   JS_ToPointer(ctx, &p, argv[0]);
 17   lv_obj_t * parent = (lv_obj_t *)p;
 18   lv_obj_t * lbl = lv_label_create(parent);
 19   return JS_NewPointer(ctx, (lv_obj_ptr_t)lbl);
 20 }
 21 static JSValue lvgl_label_set_text(JSContext *ctx, JSValueConst this_val,
 22                                     int argc, JSValueConst *argv)
 23 {
 24   lv_obj_ptr_t p;
 25   JS_ToPointer(ctx, &p, argv[0]);
 26   lv_obj_t * lbl = (lv_obj_t *)p;
 27   const char * str = JS_ToCString(ctx, argv[1]);
 28   lv_label_set_text(lbl, str);
 29   return JS_NULL;
 30 }
 31 static JSValue lvgl_scr_load(JSContext *ctx, JSValueConst this_val,
 32                                     int argc, JSValueConst *argv)
 33 {
 34   lv_obj_ptr_t p;
 35   JS_ToPointer(ctx, &p, argv[0]);
 36   lv_obj_t * lbl = (lv_obj_t *)p;
 37   lv_scr_load(lbl);
 38   return JS_NULL;
 39 }
 40 static JSValue lvgl_obj_set_pos(JSContext *ctx, JSValueConst this_val,
 41                                     int argc, JSValueConst *argv)
 42 {
 43   lv_obj_ptr_t p;
 44   JS_ToPointer(ctx, &p, argv[0]);
 45   lv_obj_t * obj = (lv_obj_t *)p;
 46   if (argc == 3) {
 47     lv_coord_t x = 0;
 48     JS_ToInt16(ctx, &x, argv[1]);
 49     lv_coord_t y = 0;
 50     JS_ToInt16(ctx, &y, argv[2]);
 51     lv_obj_set_pos(obj, x, y);
 52   }
 53 }
 54 static JSValue lvgl_obj_set_size(JSContext *ctx, JSValueConst this_val,
 55                                     int argc, JSValueConst *argv)
 56 {
 57   lv_obj_ptr_t p;
 58   JS_ToPointer(ctx, &p, argv[0]);
 59   lv_obj_t * obj = (lv_obj_t *)p;
 60   if (argc == 3) {
 61     lv_coord_t w = 0;
 62     JS_ToInt16(ctx, &w, argv[1]);
 63     lv_coord_t h = 0;
 64     JS_ToInt16(ctx, &h, argv[2]);
 65     lv_obj_set_size(obj, w, h);
 66   }
 67 }
 68 static JSValue lvgl_obj_set_style_bg_color(JSContext *ctx, JSValueConst this_val,
 69                                     int argc, JSValueConst *argv)
 70 {
 71   lv_obj_ptr_t p;
 72   JS_ToPointer(ctx, &p, argv[0]);
 73   lv_obj_t * obj = (lv_obj_t *)p;
 74   if (argc == 2) {
 75     uint32_t color = 0;
 76     JS_ToUint32(ctx, &color, argv[1]);
 77     lv_color_t c = lv_color_hex(color);
 78       lv_obj_set_style_bg_color(obj, c, LV_PART_MAIN|LV_STATE_DEFAULT);
 79   }else if(argc == 3){
 80     uint32_t color = 0;
 81     JS_ToUint32(ctx, &color, argv[1]);
 82     lv_color_t c = lv_color_hex(color);
 83     uint32_t mark = 0;
 84     JS_ToUint32(ctx, &mark, argv[2]);
 85     lv_obj_set_style_bg_color(obj, c, mark);
 86   }
 87 }
 88 static JSValue lvgl_obj_set_style_bg_opa(JSContext *ctx, JSValueConst this_val,
 89                                     int argc, JSValueConst *argv)
 90 {
 91   lv_obj_ptr_t p;
 92   JS_ToPointer(ctx, &p, argv[0]);
 93   lv_obj_t * obj = (lv_obj_t *)p;
 94   if (argc == 2) {
 95     uint8_t opa = 0;
 96     JS_ToUint8(ctx, &opa, argv[1]);
 97       lv_obj_set_style_bg_opa(obj, opa, LV_PART_MAIN|LV_STATE_DEFAULT);
 98   }else if(argc == 3){
 99     uint8_t opa = 0;
100     JS_ToUint8(ctx, &opa, argv[1]);
101     uint32_t mark = 0;
102     JS_ToUint32(ctx, &mark, argv[2]);
103     lv_obj_set_style_bg_opa(obj, opa, mark);
104   }
105 }
106 
107 static const JSCFunctionListEntry js_lvgl_funcs[] = {
108   JS_PROP_STRING_DEF("test", "test..", JS_PROP_C_W_E),
109   JS_CFUNC_DEF("lvgl_obj_create", 1, lvgl_obj_create),
110   JS_CFUNC_DEF("lvgl_label_create", 1, lvgl_label_create),
111   JS_CFUNC_DEF("lvgl_label_set_text", 2, lvgl_label_set_text),
112   JS_CFUNC_DEF("lvgl_obj_set_pos", 3, lvgl_obj_set_pos),
113   JS_CFUNC_DEF("lvgl_obj_set_size", 3, lvgl_obj_set_size),
114   JS_CFUNC_DEF("lvgl_obj_set_style_bg_color", 3, lvgl_obj_set_style_bg_color),
115   JS_CFUNC_DEF("lvgl_obj_set_style_bg_opa", 3, lvgl_obj_set_style_bg_opa),
116   JS_CFUNC_DEF("lvgl_scr_load", 1, lvgl_scr_load),
117 };
118 
119 static int js_lvgl_init(JSContext *ctx, JSModuleDef *m)
120 {
121   return JS_SetModuleExportList(ctx, m, js_lvgl_funcs,
122                                 countof(js_lvgl_funcs));
123 }
124 
125 JSModuleDef *js_init_module_lvgl(JSContext *ctx, const char *module_name)
126 {
127   JSModuleDef *m;
128   m = JS_NewCModule(ctx, module_name, js_lvgl_init);
129   if (!m)
130     return NULL;
131   JS_AddModuleExportList(ctx, m, js_lvgl_funcs, countof(js_lvgl_funcs));
132   return m;
133 }
134 
135 
136 int JS_ToInt8(JSContext *ctx, int8_t *pres, JSValueConst val)
137 {
138   uint32_t v;
139   int ret = JS_ToInt32(ctx, &v, val);
140   *pres = v > 0x7f? 0x7f : v < -0x80? -0x80 : v;
141   return ret;
142 }
143 int JS_ToUint8(JSContext *ctx, uint8_t *pres, JSValueConst val)
144 {
145   uint32_t v;
146   int ret = JS_ToUint32(ctx, &v, val);
147   *pres = v > 0xff? 0xff : v;
148   return ret;
149 }
150 int JS_ToInt16(JSContext *ctx, int16_t *pres, JSValueConst val)
151 {
152   int32_t v;
153   int ret = JS_ToInt32(ctx, &v, val);
154   *pres = v > 0x7fff? 0x7fff : v < -0x8000? -0x8000 : v;
155   return ret;
156 }
157 int JS_ToUint16(JSContext *ctx, uint16_t *pres, JSValueConst val)
158 {
159   uint32_t v;
160   int ret = JS_ToUint32(ctx, &v, val);
161   *pres = v > 0xffff? 0xffff : v;
162   return v;
163 }
164 int JS_ToPointer(JSContext *ctx, lv_obj_ptr_t *pres, JSValueConst val)
165 {
166   if (sizeof(lv_obj_ptr_t) == 8)
167   {
168     return JS_ToInt64(ctx, (uint64_t *)pres, val);
169   }
170   else
171   {
172     return JS_ToInt32(ctx, (uint32_t *)pres, val);
173   }
174 }
175 static inline JSValue JS_NewPointer(JSContext *ctx, lv_obj_ptr_t val)
176 {
177   if (sizeof(lv_obj_ptr_t) == 8)
178   {
179     return JS_NewInt64(ctx, val);
180   }
181   else
182   {
183     return JS_NewInt32(ctx, val);
184   }
185 }
  1 #include "lvgl_export.h"
  2 
  3 static JSValue lvgl_obj_create(JSContext *ctx, JSValueConst this_val,
  4                                     int argc, JSValueConst *argv)
  5 {
  6   lv_obj_ptr_t p;
  7   JS_ToPointer(ctx, &p, argv[0]);
  8   lv_obj_t * parent = (lv_obj_t *)p;
  9   lv_obj_t * obj = lv_obj_create(parent);
 10   return JS_NewPointer(ctx, (lv_obj_ptr_t)obj);
 11 }
 12 static JSValue lvgl_label_create(JSContext *ctx, JSValueConst this_val,
 13                                     int argc, JSValueConst *argv)
 14 {
 15   lv_obj_ptr_t p;
 16   JS_ToPointer(ctx, &p, argv[0]);
 17   lv_obj_t * parent = (lv_obj_t *)p;
 18   lv_obj_t * lbl = lv_label_create(parent);
 19   return JS_NewPointer(ctx, (lv_obj_ptr_t)lbl);
 20 }
 21 static JSValue lvgl_label_set_text(JSContext *ctx, JSValueConst this_val,
 22                                     int argc, JSValueConst *argv)
 23 {
 24   lv_obj_ptr_t p;
 25   JS_ToPointer(ctx, &p, argv[0]);
 26   lv_obj_t * lbl = (lv_obj_t *)p;
 27   const char * str = JS_ToCString(ctx, argv[1]);
 28   lv_label_set_text(lbl, str);
 29   return JS_NULL;
 30 }
 31 static JSValue lvgl_scr_load(JSContext *ctx, JSValueConst this_val,
 32                                     int argc, JSValueConst *argv)
 33 {
 34   lv_obj_ptr_t p;
 35   JS_ToPointer(ctx, &p, argv[0]);
 36   lv_obj_t * lbl = (lv_obj_t *)p;
 37   lv_scr_load(lbl);
 38   return JS_NULL;
 39 }
 40 static JSValue lvgl_obj_set_pos(JSContext *ctx, JSValueConst this_val,
 41                                     int argc, JSValueConst *argv)
 42 {
 43   lv_obj_ptr_t p;
 44   JS_ToPointer(ctx, &p, argv[0]);
 45   lv_obj_t * obj = (lv_obj_t *)p;
 46   if (argc == 3) {
 47     lv_coord_t x = 0;
 48     JS_ToInt16(ctx, &x, argv[1]);
 49     lv_coord_t y = 0;
 50     JS_ToInt16(ctx, &y, argv[2]);
 51     lv_obj_set_pos(obj, x, y);
 52   }
 53 }
 54 static JSValue lvgl_obj_set_size(JSContext *ctx, JSValueConst this_val,
 55                                     int argc, JSValueConst *argv)
 56 {
 57   lv_obj_ptr_t p;
 58   JS_ToPointer(ctx, &p, argv[0]);
 59   lv_obj_t * obj = (lv_obj_t *)p;
 60   if (argc == 3) {
 61     lv_coord_t w = 0;
 62     JS_ToInt16(ctx, &w, argv[1]);
 63     lv_coord_t h = 0;
 64     JS_ToInt16(ctx, &h, argv[2]);
 65     lv_obj_set_size(obj, w, h);
 66   }
 67 }
 68 static JSValue lvgl_obj_set_style_bg_color(JSContext *ctx, JSValueConst this_val,
 69                                     int argc, JSValueConst *argv)
 70 {
 71   lv_obj_ptr_t p;
 72   JS_ToPointer(ctx, &p, argv[0]);
 73   lv_obj_t * obj = (lv_obj_t *)p;
 74   if (argc == 2) {
 75     uint32_t color = 0;
 76     JS_ToUint32(ctx, &color, argv[1]);
 77     lv_color_t c = lv_color_hex(color);
 78       lv_obj_set_style_bg_color(obj, c, LV_PART_MAIN|LV_STATE_DEFAULT);
 79   }else if(argc == 3){
 80     uint32_t color = 0;
 81     JS_ToUint32(ctx, &color, argv[1]);
 82     lv_color_t c = lv_color_hex(color);
 83     uint32_t mark = 0;
 84     JS_ToUint32(ctx, &mark, argv[2]);
 85     lv_obj_set_style_bg_color(obj, c, mark);
 86   }
 87 }
 88 static JSValue lvgl_obj_set_style_bg_opa(JSContext *ctx, JSValueConst this_val,
 89                                     int argc, JSValueConst *argv)
 90 {
 91   lv_obj_ptr_t p;
 92   JS_ToPointer(ctx, &p, argv[0]);
 93   lv_obj_t * obj = (lv_obj_t *)p;
 94   if (argc == 2) {
 95     uint8_t opa = 0;
 96     JS_ToUint8(ctx, &opa, argv[1]);
 97       lv_obj_set_style_bg_opa(obj, opa, LV_PART_MAIN|LV_STATE_DEFAULT);
 98   }else if(argc == 3){
 99     uint8_t opa = 0;
100     JS_ToUint8(ctx, &opa, argv[1]);
101     uint32_t mark = 0;
102     JS_ToUint32(ctx, &mark, argv[2]);
103     lv_obj_set_style_bg_opa(obj, opa, mark);
104   }
105 }
106 
107 static const JSCFunctionListEntry js_lvgl_funcs[] = {
108   JS_PROP_STRING_DEF("test", "test..", JS_PROP_C_W_E),
109   JS_CFUNC_DEF("lvgl_obj_create", 1, lvgl_obj_create),
110   JS_CFUNC_DEF("lvgl_label_create", 1, lvgl_label_create),
111   JS_CFUNC_DEF("lvgl_label_set_text", 2, lvgl_label_set_text),
112   JS_CFUNC_DEF("lvgl_obj_set_pos", 3, lvgl_obj_set_pos),
113   JS_CFUNC_DEF("lvgl_obj_set_size", 3, lvgl_obj_set_size),
114   JS_CFUNC_DEF("lvgl_obj_set_style_bg_color", 3, lvgl_obj_set_style_bg_color),
115   JS_CFUNC_DEF("lvgl_obj_set_style_bg_opa", 3, lvgl_obj_set_style_bg_opa),
116   JS_CFUNC_DEF("lvgl_scr_load", 1, lvgl_scr_load),
117 };
118 
119 static int js_lvgl_init(JSContext *ctx, JSModuleDef *m)
120 {
121   return JS_SetModuleExportList(ctx, m, js_lvgl_funcs,
122                                 countof(js_lvgl_funcs));
123 }
124 
125 JSModuleDef *js_init_module_lvgl(JSContext *ctx, const char *module_name)
126 {
127   JSModuleDef *m;
128   m = JS_NewCModule(ctx, module_name, js_lvgl_init);
129   if (!m)
130     return NULL;
131   JS_AddModuleExportList(ctx, m, js_lvgl_funcs, countof(js_lvgl_funcs));
132   return m;
133 }
134 
135 
136 int JS_ToInt8(JSContext *ctx, int8_t *pres, JSValueConst val)
137 {
138   uint32_t v;
139   int ret = JS_ToInt32(ctx, &v, val);
140   *pres = v > 0x7f? 0x7f : v < -0x80? -0x80 : v;
141   return ret;
142 }
143 int JS_ToUint8(JSContext *ctx, uint8_t *pres, JSValueConst val)
144 {
145   uint32_t v;
146   int ret = JS_ToUint32(ctx, &v, val);
147   *pres = v > 0xff? 0xff : v;
148   return ret;
149 }
150 int JS_ToInt16(JSContext *ctx, int16_t *pres, JSValueConst val)
151 {
152   int32_t v;
153   int ret = JS_ToInt32(ctx, &v, val);
154   *pres = v > 0x7fff? 0x7fff : v < -0x8000? -0x8000 : v;
155   return ret;
156 }
157 int JS_ToUint16(JSContext *ctx, uint16_t *pres, JSValueConst val)
158 {
159   uint32_t v;
160   int ret = JS_ToUint32(ctx, &v, val);
161   *pres = v > 0xffff? 0xffff : v;
162   return v;
163 }
164 int JS_ToPointer(JSContext *ctx, lv_obj_ptr_t *pres, JSValueConst val)
165 {
166   if (sizeof(lv_obj_ptr_t) == 8)
167   {
168     return JS_ToInt64(ctx, (uint64_t *)pres, val);
169   }
170   else
171   {
172     return JS_ToInt32(ctx, (uint32_t *)pres, val);
173   }
174 }
175 static inline JSValue JS_NewPointer(JSContext *ctx, lv_obj_ptr_t val)
176 {
177   if (sizeof(lv_obj_ptr_t) == 8)
178   {
179     return JS_NewInt64(ctx, val);
180   }
181   else
182   {
183     return JS_NewInt32(ctx, val);
184   }
185 }

custom.c 关键代码

 1 JSRuntime *rt = NULL;
 2 JSContext *ctx = NULL;
 3 void lvgl_js_init() {
 4   printf("lvgl_js_init\n");
 5   rt = JS_NewRuntime();
 6   js_std_init_handlers(rt);
 7   ctx = JS_NewContext(rt);
 8   js_init_module_std(ctx, "std");
 9   js_init_module_os(ctx, "os");
10   js_init_module_lvgl(ctx, "lvgl");
11 
12   const char *str =
13       "import * as std from 'std';\n"
14       "import * as lvgl from 'lvgl';\n"
15       "import * as os from 'os';\n"
16       "globalThis.std = std;\n"
17       "globalThis.lvgl = lvgl;\n"
18       "var console = {};\n"
19       "console.log = function(value){std.printf(value + '\\n');}\n"
20       "globalThis.console = console\n"
21       "";
22   JSValue init_compile =
23       JS_Eval(ctx, str, strlen(str), "<input>", JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
24 
25   js_module_set_import_meta(ctx, init_compile, 1, 1);
26   JSValue init_run = JS_EvalFunction(ctx, init_compile);
27 }
28 
29 void run_js(){
30   //读取文件,并运行js
31   FILE *fp = fopen("test.js", "r");
32   if(fp == NULL){
33     printf("open file error\n");
34     return;
35   }
36   fseek(fp, 0, SEEK_END);
37   int len = ftell(fp);
38   fseek(fp, 0, SEEK_SET);
39   len = len + 1;
40   char *buf = (char *)malloc(len);
41   memset(buf, 0, len);
42   fread(buf, 1, len, fp);
43   printf("============CODE==========\n");
44   printf("FILE: %d \n\n%s\n", len, buf);
45   printf("==========================\n");
46   fclose(fp);
47 
48   JSValue result = JS_Eval(ctx, buf, strlen(buf), "test", JS_EVAL_TYPE_MODULE);
49   js_std_loop(ctx);
50   int clen;
51   int to_int_32;
52   if ((to_int_32 = JS_ToInt32(ctx, &clen, result)) != 0) {
53     js_std_dump_error(ctx);
54   }
55 
56 }
57 
58 /**
59  * Create a demo application
60  */
61 void custom_init(lv_ui *ui)
62 {
63   /* Add your codes here */
64   lvgl_js_init();
65   run_js();
66 }

test.js

 1 import * as lvgl from 'lvgl';
 2 //如果要在cmd控制台输出中文, 在控制台执行chcp 65001切换至utf-8
 3 console.log("JS Dev utf-8"); 
 4 var screen = lvgl.lvgl_obj_create(); //这个作为页面
 5 
 6 var lbl = lvgl.lvgl_label_create(screen); 
 7 lvgl.lvgl_label_set_text(lbl, "HELLO");
 8 lvgl.lvgl_obj_set_pos(lbl, 150, 10);
 9 lvgl.lvgl_obj_set_size(lbl, 100, 100);
10 lvgl.lvgl_obj_set_style_bg_opa(lbl, 255);
11 lvgl.lvgl_obj_set_style_bg_color(lbl, 0x2195f6);
12 
13 
14 var lbl = lvgl.lvgl_label_create(screen); 
15 lvgl.lvgl_label_set_text(lbl, "WORLD");
16 lvgl.lvgl_obj_set_pos(lbl, 200, 150);
17 lvgl.lvgl_obj_set_size(lbl, 100, 50);
18 lvgl.lvgl_obj_set_style_bg_opa(lbl, 200);
19 lvgl.lvgl_obj_set_style_bg_color(lbl, 0x2195f6);
20 
21 lvgl.lvgl_scr_load(screen);
22 
23 console.log("End.");

预览效果

 

本文地址:https://www.cnblogs.com/wunaozai/p/17852954.html

系列目录:https://www.cnblogs.com/wunaozai/p/17853962.html

posted @ 2023-11-29 09:09  无脑仔的小明  阅读(290)  评论(0编辑  收藏  举报