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.");
预览效果
作者:无脑仔的小明 出处:http://www.cnblogs.com/wunaozai/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 如果文中有什么错误,欢迎指出。以免更多的人被误导。有需要沟通的,可以站内私信,文章留言,或者关注“无脑仔的小明”公众号私信我。一定尽力回答。 |