diff --git a/project/entry/gui_demo/awtk/res/assets/__assets_all_dark.inc b/project/entry/gui_demo/awtk/res/assets/__assets_all_dark.inc index b5a939b9..ad462b7a 100644 --- a/project/entry/gui_demo/awtk/res/assets/__assets_all_dark.inc +++ b/project/entry/gui_demo/awtk/res/assets/__assets_all_dark.inc @@ -98,6 +98,7 @@ extern TK_CONST_DATA_ALIGN(const unsigned char ui_menu_right_middle[]); extern TK_CONST_DATA_ALIGN(const unsigned char ui_kb_default_t9ext[]); extern TK_CONST_DATA_ALIGN(const unsigned char ui_dragger[]); extern TK_CONST_DATA_ALIGN(const unsigned char ui_dialog2[]); +extern TK_CONST_DATA_ALIGN(const unsigned char ui_t[]); extern TK_CONST_DATA_ALIGN(const unsigned char ui_color_picker_hsv[]); extern TK_CONST_DATA_ALIGN(const unsigned char ui_menu_down_right[]); extern TK_CONST_DATA_ALIGN(const unsigned char ui_tab_bottom[]); @@ -1025,6 +1026,7 @@ ret_t assets_init_dark(void) { assets_manager_add(am, ui_kb_default_t9ext); assets_manager_add(am, ui_dragger); assets_manager_add(am, ui_dialog2); + assets_manager_add(am, ui_t); assets_manager_add(am, ui_color_picker_hsv); assets_manager_add(am, ui_menu_down_right); assets_manager_add(am, ui_tab_bottom); diff --git a/project/entry/gui_demo/awtk/res/assets/__assets_all_default.inc b/project/entry/gui_demo/awtk/res/assets/__assets_all_default.inc index a0b47ff6..75becc50 100644 --- a/project/entry/gui_demo/awtk/res/assets/__assets_all_default.inc +++ b/project/entry/gui_demo/awtk/res/assets/__assets_all_default.inc @@ -98,6 +98,7 @@ #include "default/inc/ui/kb_default_t9ext.data" #include "default/inc/ui/dragger.data" #include "default/inc/ui/dialog2.data" +#include "default/inc/ui/t.data" #include "default/inc/ui/color_picker_hsv.data" #include "default/inc/ui/menu_down_right.data" #include "default/inc/ui/tab_bottom.data" @@ -1025,6 +1026,7 @@ ret_t assets_init_default(void) { assets_manager_add(am, ui_kb_default_t9ext); assets_manager_add(am, ui_dragger); assets_manager_add(am, ui_dialog2); + assets_manager_add(am, ui_t); assets_manager_add(am, ui_color_picker_hsv); assets_manager_add(am, ui_menu_down_right); assets_manager_add(am, ui_tab_bottom); diff --git a/project/entry/gui_demo/awtk/res/assets/__assets_old_dark.inc b/project/entry/gui_demo/awtk/res/assets/__assets_old_dark.inc index f579a255..dfaaaf15 100644 --- a/project/entry/gui_demo/awtk/res/assets/__assets_old_dark.inc +++ b/project/entry/gui_demo/awtk/res/assets/__assets_old_dark.inc @@ -93,6 +93,7 @@ extern TK_CONST_DATA_ALIGN(const unsigned char ui_menu_right_middle[]); extern TK_CONST_DATA_ALIGN(const unsigned char ui_kb_default_t9ext[]); extern TK_CONST_DATA_ALIGN(const unsigned char ui_dragger[]); extern TK_CONST_DATA_ALIGN(const unsigned char ui_dialog2[]); +extern TK_CONST_DATA_ALIGN(const unsigned char ui_t[]); extern TK_CONST_DATA_ALIGN(const unsigned char ui_color_picker_hsv[]); extern TK_CONST_DATA_ALIGN(const unsigned char ui_menu_down_right[]); extern TK_CONST_DATA_ALIGN(const unsigned char ui_tab_bottom[]); @@ -641,6 +642,7 @@ ret_t assets_init_dark(void) { assets_manager_add(am, ui_kb_default_t9ext); assets_manager_add(am, ui_dragger); assets_manager_add(am, ui_dialog2); + assets_manager_add(am, ui_t); assets_manager_add(am, ui_color_picker_hsv); assets_manager_add(am, ui_menu_down_right); assets_manager_add(am, ui_tab_bottom); diff --git a/project/entry/gui_demo/awtk/res/assets/__assets_old_default.inc b/project/entry/gui_demo/awtk/res/assets/__assets_old_default.inc index f01d5446..43edad6f 100644 --- a/project/entry/gui_demo/awtk/res/assets/__assets_old_default.inc +++ b/project/entry/gui_demo/awtk/res/assets/__assets_old_default.inc @@ -93,6 +93,7 @@ #include "default/inc/ui/kb_default_t9ext.data" #include "default/inc/ui/dragger.data" #include "default/inc/ui/dialog2.data" +#include "default/inc/ui/t.data" #include "default/inc/ui/color_picker_hsv.data" #include "default/inc/ui/menu_down_right.data" #include "default/inc/ui/tab_bottom.data" @@ -641,6 +642,7 @@ ret_t assets_init_default(void) { assets_manager_add(am, ui_kb_default_t9ext); assets_manager_add(am, ui_dragger); assets_manager_add(am, ui_dialog2); + assets_manager_add(am, ui_t); assets_manager_add(am, ui_color_picker_hsv); assets_manager_add(am, ui_menu_down_right); assets_manager_add(am, ui_tab_bottom); diff --git a/project/entry/gui_demo/awtk/res/assets/default/inc/styles/button.data b/project/entry/gui_demo/awtk/res/assets/default/inc/styles/button.data index e7cbf043..15544531 100644 --- a/project/entry/gui_demo/awtk/res/assets/default/inc/styles/button.data +++ b/project/entry/gui_demo/awtk/res/assets/default/inc/styles/button.data @@ -1,152 +1,172 @@ TK_CONST_DATA_ALIGN(const unsigned char style_button[]) = { -0x03,0x00,0x00,0x01,0xa6,0x19,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00, +0x03,0x00,0x00,0x01,0xc8,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0xfd,0xfc,0xfb,0xfa,0x00,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0xc4,0x0b,0x00,0x00, +0x00,0x00,0x00,0x00,0xfd,0xfc,0xfb,0xfa,0x00,0x00,0x00,0x00,0x22,0x00,0x00,0x00,0x54,0x0d,0x00,0x00, 0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x6f,0x75,0x6e,0x64,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x16,0x0c,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa6,0x0d,0x00,0x00, 0x70,0x72,0x65,0x73,0x73,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x6f,0x75,0x6e,0x64,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8a,0x0c,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x0e,0x00,0x00, 0x6f,0x76,0x65,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x6f,0x75,0x6e,0x64,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xdc,0x0c,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0x0e,0x00,0x00, 0x64,0x69,0x73,0x61,0x62,0x6c,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x6f,0x75,0x6e,0x64,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2e,0x0d,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbe,0x0e,0x00,0x00, 0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x74,0x6f, 0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcb,0x0d,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5b,0x0f,0x00,0x00, 0x70,0x72,0x65,0x73,0x73,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x74,0x6f, 0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8a,0x0e,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x10,0x00,0x00, 0x6f,0x76,0x65,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x74,0x6f, 0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x27,0x0f,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xb7,0x10,0x00,0x00, 0x64,0x69,0x73,0x61,0x62,0x6c,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x74,0x6f, 0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc4,0x0f,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x11,0x00,0x00, 0x66,0x6f,0x63,0x75,0x73,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x74,0x6f, 0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x10,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf1,0x11,0x00,0x00, 0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x62,0x6f, 0x74,0x74,0x6f,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x11,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x93,0x12,0x00,0x00, 0x70,0x72,0x65,0x73,0x73,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x62,0x6f, 0x74,0x74,0x6f,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc7,0x11,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x57,0x13,0x00,0x00, 0x6f,0x76,0x65,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x62,0x6f, 0x74,0x74,0x6f,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x12,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf9,0x13,0x00,0x00, 0x64,0x69,0x73,0x61,0x62,0x6c,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x62,0x6f, 0x74,0x74,0x6f,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfb,0x12,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8b,0x14,0x00,0x00, 0x66,0x6f,0x63,0x75,0x73,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x62,0x6f, 0x74,0x74,0x6f,0x6d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9d,0x13,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2d,0x15,0x00,0x00, +0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x63,0x6f,0x6e,0x5f,0x74,0x6f,0x70, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x89,0x15,0x00,0x00, +0x70,0x72,0x65,0x73,0x73,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x63,0x6f,0x6e,0x5f,0x74,0x6f,0x70, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x16,0x00,0x00, +0x6f,0x76,0x65,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x63,0x6f,0x6e,0x5f,0x74,0x6f,0x70, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x16,0x00,0x00, +0x64,0x69,0x73,0x61,0x62,0x6c,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x63,0x6f,0x6e,0x5f,0x74,0x6f,0x70, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xbf,0x16,0x00,0x00, 0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x63,0x6f,0x6e,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe9,0x13,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0b,0x17,0x00,0x00, 0x70,0x72,0x65,0x73,0x73,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x63,0x6f,0x6e,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x57,0x14,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x79,0x17,0x00,0x00, 0x6f,0x76,0x65,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x63,0x6f,0x6e,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0x14,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x17,0x00,0x00, 0x64,0x69,0x73,0x61,0x62,0x6c,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x63,0x6f,0x6e,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xef,0x14,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x18,0x00,0x00, 0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x65,0x64,0x5f,0x62,0x74,0x6e,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x15,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5a,0x18,0x00,0x00, 0x70,0x72,0x65,0x73,0x73,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x65,0x64,0x5f,0x62,0x74,0x6e,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0x15,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xc5,0x18,0x00,0x00, 0x6f,0x76,0x65,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0x65,0x64,0x5f,0x62,0x74,0x6e,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xec,0x15,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x19,0x00,0x00, 0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x6d,0x61,0x67,0x65,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x13,0x16,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x19,0x00,0x00, 0x70,0x72,0x65,0x73,0x73,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x6d,0x61,0x67,0x65,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5c,0x16,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x19,0x00,0x00, 0x6f,0x76,0x65,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x69,0x6d,0x61,0x67,0x65,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x83,0x16,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xa5,0x19,0x00,0x00, 0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x6c,0x6f,0x73,0x65,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1e,0x17,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x1a,0x00,0x00, 0x64,0x69,0x73,0x61,0x62,0x6c,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x6c,0x6f,0x73,0x65,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x98,0x17,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xba,0x1a,0x00,0x00, 0x66,0x6f,0x63,0x75,0x73,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x6c,0x6f,0x73,0x65,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x18,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x1b,0x00,0x00, 0x6f,0x76,0x65,0x72,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x6c,0x6f,0x73,0x65,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xad,0x18,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xcf,0x1b,0x00,0x00, 0x70,0x72,0x65,0x73,0x73,0x65,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x6c,0x6f,0x73,0x65,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3b,0x19,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5d,0x1c,0x00,0x00, 0x6e,0x6f,0x72,0x6d,0x61,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x73,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -252,81 +272,101 @@ TK_CONST_DATA_ALIGN(const unsigned char style_button[]) = { 0x6f,0x6d,0x5f,0x72,0x69,0x67,0x68,0x74,0x00,0x08,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65,0x78, 0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0x00,0xff,0x15,0x09,0x14,0x00,0x62,0x67,0x5f,0x63, 0x6f,0x6c,0x6f,0x72,0x00,0xb4,0x00,0x01,0x02,0xcd,0xcc,0x4c,0x3e,0xff,0x00,0x00,0xff,0xcd,0xcc,0x4c, -0x3f,0x00,0x00,0xff,0xff,0x04,0x00,0x00,0x00,0x07,0x09,0x04,0x00,0x62,0x67,0x5f,0x63,0x6f,0x6c,0x6f, -0x72,0x00,0xf0,0xf0,0xf0,0xff,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65,0x72,0x5f,0x63,0x6f,0x6c, -0x6f,0x72,0x00,0xa0,0xa0,0xa0,0xff,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f, -0x72,0x00,0x00,0x00,0x00,0xff,0x0e,0x05,0x06,0x00,0x69,0x63,0x6f,0x6e,0x00,0x65,0x61,0x72,0x74,0x68, -0x00,0x06,0x00,0x00,0x00,0x07,0x09,0x04,0x00,0x62,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xc0,0xc0, -0xc0,0xff,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65,0x72,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xa0, +0x3f,0x00,0x00,0xff,0xff,0x05,0x00,0x00,0x00,0x06,0x08,0x04,0x00,0x69,0x63,0x6f,0x6e,0x5f,0x61,0x74, +0x00,0x03,0x00,0x00,0x00,0x07,0x09,0x04,0x00,0x62,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xf0,0xf0, +0xf0,0xff,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65,0x72,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xa0, 0xa0,0xa0,0xff,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00, -0x00,0xff,0x07,0x09,0x04,0x00,0x78,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x00,0x03,0x00,0x00,0x00,0x07, -0x09,0x04,0x00,0x79,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x00,0x03,0x00,0x00,0x00,0x0e,0x05,0x06,0x00, -0x69,0x63,0x6f,0x6e,0x00,0x65,0x61,0x72,0x74,0x68,0x00,0x04,0x00,0x00,0x00,0x07,0x09,0x04,0x00,0x62, -0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xe0,0xe0,0xe0,0xff,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64, +0x00,0xff,0x0e,0x05,0x06,0x00,0x69,0x63,0x6f,0x6e,0x00,0x65,0x61,0x72,0x74,0x68,0x00,0x07,0x00,0x00, +0x00,0x06,0x08,0x04,0x00,0x69,0x63,0x6f,0x6e,0x5f,0x61,0x74,0x00,0x03,0x00,0x00,0x00,0x07,0x09,0x04, +0x00,0x62,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xc0,0xc0,0xc0,0xff,0x07,0x0d,0x04,0x00,0x62,0x6f, +0x72,0x64,0x65,0x72,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xa0,0xa0,0xa0,0xff,0x07,0x0b,0x04,0x00,0x74, +0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0x00,0xff,0x07,0x09,0x04,0x00,0x78,0x5f, +0x6f,0x66,0x66,0x73,0x65,0x74,0x00,0x03,0x00,0x00,0x00,0x07,0x09,0x04,0x00,0x79,0x5f,0x6f,0x66,0x66, +0x73,0x65,0x74,0x00,0x03,0x00,0x00,0x00,0x0e,0x05,0x06,0x00,0x69,0x63,0x6f,0x6e,0x00,0x65,0x61,0x72, +0x74,0x68,0x00,0x05,0x00,0x00,0x00,0x06,0x08,0x04,0x00,0x69,0x63,0x6f,0x6e,0x5f,0x61,0x74,0x00,0x03, +0x00,0x00,0x00,0x07,0x09,0x04,0x00,0x62,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xe0,0xe0,0xe0,0xff, +0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65,0x72,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xa0,0xa0,0xa0, +0xff,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0x00,0xff, +0x0e,0x05,0x06,0x00,0x69,0x63,0x6f,0x6e,0x00,0x65,0x61,0x72,0x74,0x68,0x00,0x05,0x00,0x00,0x00,0x06, +0x08,0x04,0x00,0x69,0x63,0x6f,0x6e,0x5f,0x61,0x74,0x00,0x03,0x00,0x00,0x00,0x07,0x09,0x04,0x00,0x62, +0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xbe,0xbe,0xbe,0xff,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64, 0x65,0x72,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xa0,0xa0,0xa0,0xff,0x07,0x0b,0x04,0x00,0x74,0x65,0x78, -0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0x00,0xff,0x0e,0x05,0x06,0x00,0x69,0x63,0x6f,0x6e, +0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xd0,0xd0,0xd0,0xff,0x0e,0x05,0x06,0x00,0x69,0x63,0x6f,0x6e, 0x00,0x65,0x61,0x72,0x74,0x68,0x00,0x04,0x00,0x00,0x00,0x07,0x09,0x04,0x00,0x62,0x67,0x5f,0x63,0x6f, -0x6c,0x6f,0x72,0x00,0xbe,0xbe,0xbe,0xff,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65,0x72,0x5f,0x63, +0x6c,0x6f,0x72,0x00,0xf0,0xf0,0xf0,0xff,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65,0x72,0x5f,0x63, 0x6f,0x6c,0x6f,0x72,0x00,0xa0,0xa0,0xa0,0xff,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63,0x6f, -0x6c,0x6f,0x72,0x00,0xd0,0xd0,0xd0,0xff,0x0e,0x05,0x06,0x00,0x69,0x63,0x6f,0x6e,0x00,0x65,0x61,0x72, -0x74,0x68,0x00,0x03,0x00,0x00,0x00,0x06,0x13,0x04,0x00,0x62,0x67,0x5f,0x69,0x6d,0x61,0x67,0x65,0x5f, -0x64,0x72,0x61,0x77,0x5f,0x74,0x79,0x70,0x65,0x00,0x13,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65, -0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0xff,0xff,0x0e,0x09,0x0a,0x00,0x62,0x67,0x5f, -0x69,0x6d,0x61,0x67,0x65,0x00,0x72,0x65,0x64,0x5f,0x62,0x74,0x6e,0x5f,0x6e,0x00,0x05,0x00,0x00,0x00, -0x06,0x13,0x04,0x00,0x62,0x67,0x5f,0x69,0x6d,0x61,0x67,0x65,0x5f,0x64,0x72,0x61,0x77,0x5f,0x74,0x79, -0x70,0x65,0x00,0x13,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f, -0x72,0x00,0x00,0x00,0xff,0xff,0x07,0x09,0x04,0x00,0x78,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x00,0x03, -0x00,0x00,0x00,0x07,0x09,0x04,0x00,0x79,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x00,0x03,0x00,0x00,0x00, -0x0e,0x09,0x0a,0x00,0x62,0x67,0x5f,0x69,0x6d,0x61,0x67,0x65,0x00,0x72,0x65,0x64,0x5f,0x62,0x74,0x6e, -0x5f,0x70,0x00,0x03,0x00,0x00,0x00,0x06,0x13,0x04,0x00,0x62,0x67,0x5f,0x69,0x6d,0x61,0x67,0x65,0x5f, -0x64,0x72,0x61,0x77,0x5f,0x74,0x79,0x70,0x65,0x00,0x13,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65, -0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0xff,0xff,0x0e,0x09,0x0a,0x00,0x62,0x67,0x5f, -0x69,0x6d,0x61,0x67,0x65,0x00,0x72,0x65,0x64,0x5f,0x62,0x74,0x6e,0x5f,0x6f,0x00,0x02,0x00,0x00,0x00, -0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0xff,0xff,0x0e, -0x05,0x07,0x00,0x69,0x63,0x6f,0x6e,0x00,0x70,0x6c,0x61,0x79,0x5f,0x6e,0x00,0x04,0x00,0x00,0x00,0x07, -0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0xff,0xff,0x07,0x09, -0x04,0x00,0x78,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x00,0x01,0x00,0x00,0x00,0x07,0x09,0x04,0x00,0x79, -0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x00,0x01,0x00,0x00,0x00,0x0e,0x05,0x07,0x00,0x69,0x63,0x6f,0x6e, -0x00,0x70,0x6c,0x61,0x79,0x5f,0x70,0x00,0x02,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74, -0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0xff,0xff,0x0e,0x05,0x07,0x00,0x69,0x63,0x6f,0x6e,0x00, -0x70,0x6c,0x61,0x79,0x5f,0x6f,0x00,0x05,0x00,0x00,0x00,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65, -0x72,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xa0,0xa0,0xa0,0xff,0x07,0x0d,0x04,0x00,0x72,0x6f,0x75,0x6e, -0x64,0x5f,0x72,0x61,0x64,0x69,0x75,0x73,0x00,0x08,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65,0x78, -0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0x00,0xff,0x15,0x09,0x14,0x00,0x62,0x67,0x5f,0x63, -0x6f,0x6c,0x6f,0x72,0x00,0xb4,0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x6a,0xb2,0xff,0xff,0x00,0x00,0x80, -0x3f,0x0d,0x81,0xff,0xff,0x0e,0x0c,0x29,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c,0x61,0x79,0x6f,0x75,0x74, -0x00,0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x78,0x3d,0x63,0x65,0x6e,0x74,0x65,0x72,0x2c,0x79,0x3d, -0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x35,0x30,0x2c,0x77,0x3d,0x35,0x30,0x25,0x2c,0x68,0x3d,0x33,0x30, -0x29,0x00,0x04,0x00,0x00,0x00,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65,0x72,0x5f,0x63,0x6f,0x6c, -0x6f,0x72,0x00,0xd9,0xd9,0xd9,0xff,0x07,0x0d,0x04,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x72,0x61,0x64, -0x69,0x75,0x73,0x00,0x08,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c, -0x6f,0x72,0x00,0xbe,0xbe,0xbe,0xff,0x0e,0x0c,0x29,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c,0x61,0x79,0x6f, +0x6c,0x6f,0x72,0x00,0x00,0x00,0x00,0xff,0x0e,0x05,0x06,0x00,0x69,0x63,0x6f,0x6e,0x00,0x65,0x61,0x72, +0x74,0x68,0x00,0x06,0x00,0x00,0x00,0x07,0x09,0x04,0x00,0x62,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00, +0xc0,0xc0,0xc0,0xff,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65,0x72,0x5f,0x63,0x6f,0x6c,0x6f,0x72, +0x00,0xa0,0xa0,0xa0,0xff,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00, +0x00,0x00,0x00,0xff,0x07,0x09,0x04,0x00,0x78,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x00,0x03,0x00,0x00, +0x00,0x07,0x09,0x04,0x00,0x79,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x00,0x03,0x00,0x00,0x00,0x0e,0x05, +0x06,0x00,0x69,0x63,0x6f,0x6e,0x00,0x65,0x61,0x72,0x74,0x68,0x00,0x04,0x00,0x00,0x00,0x07,0x09,0x04, +0x00,0x62,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xe0,0xe0,0xe0,0xff,0x07,0x0d,0x04,0x00,0x62,0x6f, +0x72,0x64,0x65,0x72,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xa0,0xa0,0xa0,0xff,0x07,0x0b,0x04,0x00,0x74, +0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0x00,0xff,0x0e,0x05,0x06,0x00,0x69,0x63, +0x6f,0x6e,0x00,0x65,0x61,0x72,0x74,0x68,0x00,0x04,0x00,0x00,0x00,0x07,0x09,0x04,0x00,0x62,0x67,0x5f, +0x63,0x6f,0x6c,0x6f,0x72,0x00,0xbe,0xbe,0xbe,0xff,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65,0x72, +0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xa0,0xa0,0xa0,0xff,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f, +0x63,0x6f,0x6c,0x6f,0x72,0x00,0xd0,0xd0,0xd0,0xff,0x0e,0x05,0x06,0x00,0x69,0x63,0x6f,0x6e,0x00,0x65, +0x61,0x72,0x74,0x68,0x00,0x03,0x00,0x00,0x00,0x06,0x13,0x04,0x00,0x62,0x67,0x5f,0x69,0x6d,0x61,0x67, +0x65,0x5f,0x64,0x72,0x61,0x77,0x5f,0x74,0x79,0x70,0x65,0x00,0x13,0x00,0x00,0x00,0x07,0x0b,0x04,0x00, +0x74,0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0xff,0xff,0x0e,0x09,0x0a,0x00,0x62, +0x67,0x5f,0x69,0x6d,0x61,0x67,0x65,0x00,0x72,0x65,0x64,0x5f,0x62,0x74,0x6e,0x5f,0x6e,0x00,0x05,0x00, +0x00,0x00,0x06,0x13,0x04,0x00,0x62,0x67,0x5f,0x69,0x6d,0x61,0x67,0x65,0x5f,0x64,0x72,0x61,0x77,0x5f, +0x74,0x79,0x70,0x65,0x00,0x13,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63,0x6f, +0x6c,0x6f,0x72,0x00,0x00,0x00,0xff,0xff,0x07,0x09,0x04,0x00,0x78,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74, +0x00,0x03,0x00,0x00,0x00,0x07,0x09,0x04,0x00,0x79,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x00,0x03,0x00, +0x00,0x00,0x0e,0x09,0x0a,0x00,0x62,0x67,0x5f,0x69,0x6d,0x61,0x67,0x65,0x00,0x72,0x65,0x64,0x5f,0x62, +0x74,0x6e,0x5f,0x70,0x00,0x03,0x00,0x00,0x00,0x06,0x13,0x04,0x00,0x62,0x67,0x5f,0x69,0x6d,0x61,0x67, +0x65,0x5f,0x64,0x72,0x61,0x77,0x5f,0x74,0x79,0x70,0x65,0x00,0x13,0x00,0x00,0x00,0x07,0x0b,0x04,0x00, +0x74,0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0xff,0xff,0x0e,0x09,0x0a,0x00,0x62, +0x67,0x5f,0x69,0x6d,0x61,0x67,0x65,0x00,0x72,0x65,0x64,0x5f,0x62,0x74,0x6e,0x5f,0x6f,0x00,0x02,0x00, +0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0xff, +0xff,0x0e,0x05,0x07,0x00,0x69,0x63,0x6f,0x6e,0x00,0x70,0x6c,0x61,0x79,0x5f,0x6e,0x00,0x04,0x00,0x00, +0x00,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0xff,0xff, +0x07,0x09,0x04,0x00,0x78,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x00,0x01,0x00,0x00,0x00,0x07,0x09,0x04, +0x00,0x79,0x5f,0x6f,0x66,0x66,0x73,0x65,0x74,0x00,0x01,0x00,0x00,0x00,0x0e,0x05,0x07,0x00,0x69,0x63, +0x6f,0x6e,0x00,0x70,0x6c,0x61,0x79,0x5f,0x70,0x00,0x02,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65, +0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0xff,0xff,0x0e,0x05,0x07,0x00,0x69,0x63,0x6f, +0x6e,0x00,0x70,0x6c,0x61,0x79,0x5f,0x6f,0x00,0x05,0x00,0x00,0x00,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72, +0x64,0x65,0x72,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xa0,0xa0,0xa0,0xff,0x07,0x0d,0x04,0x00,0x72,0x6f, +0x75,0x6e,0x64,0x5f,0x72,0x61,0x64,0x69,0x75,0x73,0x00,0x08,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74, +0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0x00,0xff,0x15,0x09,0x14,0x00,0x62,0x67, +0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xb4,0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x6a,0xb2,0xff,0xff,0x00, +0x00,0x80,0x3f,0x0d,0x81,0xff,0xff,0x0e,0x0c,0x29,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c,0x61,0x79,0x6f, 0x75,0x74,0x00,0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x78,0x3d,0x63,0x65,0x6e,0x74,0x65,0x72,0x2c, 0x79,0x3d,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x35,0x30,0x2c,0x77,0x3d,0x35,0x30,0x25,0x2c,0x68,0x3d, 0x33,0x30,0x29,0x00,0x04,0x00,0x00,0x00,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65,0x72,0x5f,0x63, -0x6f,0x6c,0x6f,0x72,0x00,0x3b,0x9a,0xfc,0xff,0x07,0x0d,0x04,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x72, +0x6f,0x6c,0x6f,0x72,0x00,0xd9,0xd9,0xd9,0xff,0x07,0x0d,0x04,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x72, 0x61,0x64,0x69,0x75,0x73,0x00,0x08,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63, -0x6f,0x6c,0x6f,0x72,0x00,0x7a,0x7a,0x7a,0xff,0x0e,0x0c,0x29,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c,0x61, +0x6f,0x6c,0x6f,0x72,0x00,0xbe,0xbe,0xbe,0xff,0x0e,0x0c,0x29,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c,0x61, 0x79,0x6f,0x75,0x74,0x00,0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x78,0x3d,0x63,0x65,0x6e,0x74,0x65, 0x72,0x2c,0x79,0x3d,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x35,0x30,0x2c,0x77,0x3d,0x35,0x30,0x25,0x2c, -0x68,0x3d,0x33,0x30,0x29,0x00,0x05,0x00,0x00,0x00,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65,0x72, -0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xa0,0xa0,0xa0,0xff,0x07,0x0d,0x04,0x00,0x72,0x6f,0x75,0x6e,0x64, +0x68,0x3d,0x33,0x30,0x29,0x00,0x04,0x00,0x00,0x00,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65,0x72, +0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x3b,0x9a,0xfc,0xff,0x07,0x0d,0x04,0x00,0x72,0x6f,0x75,0x6e,0x64, 0x5f,0x72,0x61,0x64,0x69,0x75,0x73,0x00,0x08,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74, -0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0x00,0xff,0x15,0x09,0x14,0x00,0x62,0x67,0x5f,0x63,0x6f, -0x6c,0x6f,0x72,0x00,0xb4,0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x6a,0xb2,0xff,0xff,0x00,0x00,0x80,0x3f, -0x0d,0x81,0xff,0xff,0x0e,0x0c,0x29,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c,0x61,0x79,0x6f,0x75,0x74,0x00, -0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x78,0x3d,0x63,0x65,0x6e,0x74,0x65,0x72,0x2c,0x79,0x3d,0x62, -0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x35,0x30,0x2c,0x77,0x3d,0x35,0x30,0x25,0x2c,0x68,0x3d,0x33,0x30,0x29, -0x00,0x05,0x00,0x00,0x00,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65,0x72,0x5f,0x63,0x6f,0x6c,0x6f, -0x72,0x00,0x00,0x71,0xeb,0xff,0x07,0x0d,0x04,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x72,0x61,0x64,0x69, -0x75,0x73,0x00,0x08,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f, -0x72,0x00,0x00,0x00,0x00,0xff,0x0e,0x08,0x08,0x00,0x62,0x67,0x5f,0x67,0x63,0x6f,0x6c,0x00,0x23,0x30, -0x30,0x37,0x41,0x45,0x42,0x00,0x0e,0x0c,0x29,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c,0x61,0x79,0x6f,0x75, +0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x7a,0x7a,0x7a,0xff,0x0e,0x0c,0x29,0x00,0x73,0x65,0x6c,0x66,0x5f, +0x6c,0x61,0x79,0x6f,0x75,0x74,0x00,0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x78,0x3d,0x63,0x65,0x6e, +0x74,0x65,0x72,0x2c,0x79,0x3d,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x35,0x30,0x2c,0x77,0x3d,0x35,0x30, +0x25,0x2c,0x68,0x3d,0x33,0x30,0x29,0x00,0x05,0x00,0x00,0x00,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64, +0x65,0x72,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0xa0,0xa0,0xa0,0xff,0x07,0x0d,0x04,0x00,0x72,0x6f,0x75, +0x6e,0x64,0x5f,0x72,0x61,0x64,0x69,0x75,0x73,0x00,0x08,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65, +0x78,0x74,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x00,0x00,0x00,0x00,0xff,0x15,0x09,0x14,0x00,0x62,0x67,0x5f, +0x63,0x6f,0x6c,0x6f,0x72,0x00,0xb4,0x00,0x01,0x02,0x00,0x00,0x00,0x00,0x6a,0xb2,0xff,0xff,0x00,0x00, +0x80,0x3f,0x0d,0x81,0xff,0xff,0x0e,0x0c,0x29,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c,0x61,0x79,0x6f,0x75, 0x74,0x00,0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x78,0x3d,0x63,0x65,0x6e,0x74,0x65,0x72,0x2c,0x79, 0x3d,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x35,0x30,0x2c,0x77,0x3d,0x35,0x30,0x25,0x2c,0x68,0x3d,0x33, -0x30,0x29,0x00,0x02,0x00,0x00,0x00,0x0e,0x10,0x20,0x00,0x63,0x68,0x69,0x6c,0x64,0x72,0x65,0x6e,0x5f, -0x6c,0x61,0x79,0x6f,0x75,0x74,0x00,0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x72,0x6f,0x77,0x3d,0x34, -0x2c,0x63,0x6f,0x6c,0x3d,0x31,0x2c,0x73,0x70,0x61,0x63,0x69,0x6e,0x67,0x3d,0x31,0x30,0x29,0x00,0x0e, -0x0c,0x23,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c,0x61,0x79,0x6f,0x75,0x74,0x00,0x64,0x65,0x66,0x61,0x75, -0x6c,0x74,0x28,0x78,0x3d,0x63,0x65,0x6e,0x74,0x65,0x72,0x2c,0x79,0x3d,0x31,0x30,0x2c,0x77,0x3d,0x35, -0x30,0x25,0x2c,0x68,0x3d,0x31,0x34,0x38,0x29,0x00,0x00,0x00,0x00,0x00,};/*6614*/ +0x30,0x29,0x00,0x05,0x00,0x00,0x00,0x07,0x0d,0x04,0x00,0x62,0x6f,0x72,0x64,0x65,0x72,0x5f,0x63,0x6f, +0x6c,0x6f,0x72,0x00,0x00,0x71,0xeb,0xff,0x07,0x0d,0x04,0x00,0x72,0x6f,0x75,0x6e,0x64,0x5f,0x72,0x61, +0x64,0x69,0x75,0x73,0x00,0x08,0x00,0x00,0x00,0x07,0x0b,0x04,0x00,0x74,0x65,0x78,0x74,0x5f,0x63,0x6f, +0x6c,0x6f,0x72,0x00,0x00,0x00,0x00,0xff,0x0e,0x08,0x08,0x00,0x62,0x67,0x5f,0x67,0x63,0x6f,0x6c,0x00, +0x23,0x30,0x30,0x37,0x41,0x45,0x42,0x00,0x0e,0x0c,0x29,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c,0x61,0x79, +0x6f,0x75,0x74,0x00,0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x78,0x3d,0x63,0x65,0x6e,0x74,0x65,0x72, +0x2c,0x79,0x3d,0x62,0x6f,0x74,0x74,0x6f,0x6d,0x3a,0x35,0x30,0x2c,0x77,0x3d,0x35,0x30,0x25,0x2c,0x68, +0x3d,0x33,0x30,0x29,0x00,0x02,0x00,0x00,0x00,0x0e,0x10,0x20,0x00,0x63,0x68,0x69,0x6c,0x64,0x72,0x65, +0x6e,0x5f,0x6c,0x61,0x79,0x6f,0x75,0x74,0x00,0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x72,0x6f,0x77, +0x3d,0x34,0x2c,0x63,0x6f,0x6c,0x3d,0x31,0x2c,0x73,0x70,0x61,0x63,0x69,0x6e,0x67,0x3d,0x31,0x30,0x29, +0x00,0x0e,0x0c,0x23,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c,0x61,0x79,0x6f,0x75,0x74,0x00,0x64,0x65,0x66, +0x61,0x75,0x6c,0x74,0x28,0x78,0x3d,0x63,0x65,0x6e,0x74,0x65,0x72,0x2c,0x79,0x3d,0x31,0x30,0x2c,0x77, +0x3d,0x35,0x30,0x25,0x2c,0x68,0x3d,0x31,0x34,0x38,0x29,0x00,0x00,0x00,0x00,0x00,};/*7416*/ diff --git a/project/entry/gui_demo/awtk/res/assets/default/inc/ui/button.data b/project/entry/gui_demo/awtk/res/assets/default/inc/ui/button.data index 7d25376b..345c68d3 100644 --- a/project/entry/gui_demo/awtk/res/assets/default/inc/ui/button.data +++ b/project/entry/gui_demo/awtk/res/assets/default/inc/ui/button.data @@ -1,5 +1,5 @@ TK_CONST_DATA_ALIGN(const unsigned char ui_button[]) = { -0x04,0x00,0x01,0x01,0xae,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00, +0x04,0x00,0x01,0x01,0xb2,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x12,0x12,0x22,0x11,0x77,0x69,0x6e,0x64,0x6f,0x77,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, @@ -43,22 +43,22 @@ TK_CONST_DATA_ALIGN(const unsigned char ui_button[]) = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xaa,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x3c,0x00, 0x00,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c,0x61,0x79,0x6f,0x75,0x74,0x00,0x64,0x65,0x66,0x61,0x75,0x6c, 0x74,0x28,0x78,0x3d,0x63,0x2c,0x79,0x3d,0x31,0x37,0x30,0x2c,0x77,0x3d,0x36,0x30,0x2c,0x68,0x3d,0x36, -0x30,0x29,0x00,0x73,0x74,0x79,0x6c,0x65,0x00,0x69,0x63,0x6f,0x6e,0x00,0x74,0x65,0x78,0x74,0x00,0x54, -0x65,0x78,0x74,0x00,0x6e,0x61,0x6d,0x65,0x00,0x63,0x75,0x72,0x73,0x6f,0x72,0x5f,0x74,0x65,0x78,0x74, -0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0, -0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c,0x61,0x79,0x6f, -0x75,0x74,0x00,0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x78,0x3d,0x63,0x2c,0x79,0x3d,0x32,0x34,0x30, -0x2c,0x77,0x3d,0x36,0x30,0x2c,0x68,0x3d,0x36,0x30,0x29,0x00,0x73,0x74,0x79,0x6c,0x65,0x00,0x69,0x63, -0x6f,0x6e,0x00,0x6e,0x61,0x6d,0x65,0x00,0x63,0x75,0x72,0x73,0x6f,0x72,0x5f,0x68,0x61,0x6e,0x64,0x00, -0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x01, -0x00,0x00,0x1e,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c,0x61,0x79,0x6f,0x75, -0x74,0x00,0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x78,0x3d,0x63,0x2c,0x79,0x3d,0x33,0x31,0x30,0x2c, -0x77,0x3d,0x33,0x30,0x2c,0x68,0x3d,0x33,0x30,0x29,0x00,0x73,0x74,0x79,0x6c,0x65,0x00,0x69,0x6d,0x61, -0x67,0x65,0x00,0x6e,0x61,0x6d,0x65,0x00,0x63,0x75,0x72,0x73,0x6f,0x72,0x00,0x00,0x00,0x62,0x75,0x74, -0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x29,0x00,0x73,0x74,0x79,0x6c,0x65,0x00,0x69,0x63,0x6f,0x6e,0x5f,0x74,0x6f,0x70,0x00,0x74,0x65, +0x78,0x74,0x00,0x54,0x65,0x78,0x74,0x00,0x6e,0x61,0x6d,0x65,0x00,0x63,0x75,0x72,0x73,0x6f,0x72,0x5f, +0x74,0x65,0x78,0x74,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x6e,0x61,0x6d,0x65,0x00,0x63,0x6c,0x6f,0x73,0x65,0x00,0x73,0x74,0x79,0x6c, -0x65,0x00,0x63,0x6c,0x6f,0x73,0x65,0x00,0x74,0x65,0x78,0x74,0x00,0x43,0x6c,0x6f,0x73,0x65,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,};/*1246*/ +0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x3c,0x00,0x00,0x00,0x73,0x65,0x6c,0x66,0x5f, +0x6c,0x61,0x79,0x6f,0x75,0x74,0x00,0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x78,0x3d,0x63,0x2c,0x79, +0x3d,0x32,0x34,0x30,0x2c,0x77,0x3d,0x36,0x30,0x2c,0x68,0x3d,0x36,0x30,0x29,0x00,0x73,0x74,0x79,0x6c, +0x65,0x00,0x69,0x63,0x6f,0x6e,0x00,0x6e,0x61,0x6d,0x65,0x00,0x63,0x75,0x72,0x73,0x6f,0x72,0x5f,0x68, +0x61,0x6e,0x64,0x00,0x00,0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x36,0x01,0x00,0x00,0x1e,0x00,0x00,0x00,0x1e,0x00,0x00,0x00,0x73,0x65,0x6c,0x66,0x5f,0x6c, +0x61,0x79,0x6f,0x75,0x74,0x00,0x64,0x65,0x66,0x61,0x75,0x6c,0x74,0x28,0x78,0x3d,0x63,0x2c,0x79,0x3d, +0x33,0x31,0x30,0x2c,0x77,0x3d,0x33,0x30,0x2c,0x68,0x3d,0x33,0x30,0x29,0x00,0x73,0x74,0x79,0x6c,0x65, +0x00,0x69,0x6d,0x61,0x67,0x65,0x00,0x6e,0x61,0x6d,0x65,0x00,0x63,0x75,0x72,0x73,0x6f,0x72,0x00,0x00, +0x00,0x62,0x75,0x74,0x74,0x6f,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6e,0x61,0x6d,0x65,0x00,0x63,0x6c,0x6f,0x73,0x65,0x00, +0x73,0x74,0x79,0x6c,0x65,0x00,0x63,0x6c,0x6f,0x73,0x65,0x00,0x74,0x65,0x78,0x74,0x00,0x43,0x6c,0x6f, +0x73,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,};/*1250*/ diff --git a/project/entry/gui_demo/awtk/res/assets/default/raw/styles/button.bin b/project/entry/gui_demo/awtk/res/assets/default/raw/styles/button.bin index 21eaa121..2abb4078 100644 Binary files a/project/entry/gui_demo/awtk/res/assets/default/raw/styles/button.bin and b/project/entry/gui_demo/awtk/res/assets/default/raw/styles/button.bin differ diff --git a/project/entry/gui_demo/awtk/res/assets/default/raw/ui/button.bin b/project/entry/gui_demo/awtk/res/assets/default/raw/ui/button.bin index 0900e012..762a9bf8 100644 Binary files a/project/entry/gui_demo/awtk/res/assets/default/raw/ui/button.bin and b/project/entry/gui_demo/awtk/res/assets/default/raw/ui/button.bin differ diff --git a/project/entry/gui_demo/awtk/res/assets_all_dark.inc b/project/entry/gui_demo/awtk/res/assets_all_dark.inc index e2ce257b..741185e7 100644 --- a/project/entry/gui_demo/awtk/res/assets_all_dark.inc +++ b/project/entry/gui_demo/awtk/res/assets_all_dark.inc @@ -98,6 +98,7 @@ #include "assets/default/inc/ui/kb_default_t9ext.data" #include "assets/default/inc/ui/dragger.data" #include "assets/default/inc/ui/dialog2.data" +#include "assets/default/inc/ui/t.data" #include "assets/default/inc/ui/color_picker_hsv.data" #include "assets/default/inc/ui/menu_down_right.data" #include "assets/default/inc/ui/tab_bottom.data" @@ -1025,6 +1026,7 @@ ret_t assets_init(void) { assets_manager_add(am, ui_kb_default_t9ext); assets_manager_add(am, ui_dragger); assets_manager_add(am, ui_dialog2); + assets_manager_add(am, ui_t); assets_manager_add(am, ui_color_picker_hsv); assets_manager_add(am, ui_menu_down_right); assets_manager_add(am, ui_tab_bottom); diff --git a/project/entry/gui_demo/awtk/res/assets_all_default.inc b/project/entry/gui_demo/awtk/res/assets_all_default.inc index d314583f..efe12ce0 100644 --- a/project/entry/gui_demo/awtk/res/assets_all_default.inc +++ b/project/entry/gui_demo/awtk/res/assets_all_default.inc @@ -98,6 +98,7 @@ #include "assets/default/inc/ui/kb_default_t9ext.data" #include "assets/default/inc/ui/dragger.data" #include "assets/default/inc/ui/dialog2.data" +#include "assets/default/inc/ui/t.data" #include "assets/default/inc/ui/color_picker_hsv.data" #include "assets/default/inc/ui/menu_down_right.data" #include "assets/default/inc/ui/tab_bottom.data" @@ -1025,6 +1026,7 @@ ret_t assets_init(void) { assets_manager_add(am, ui_kb_default_t9ext); assets_manager_add(am, ui_dragger); assets_manager_add(am, ui_dialog2); + assets_manager_add(am, ui_t); assets_manager_add(am, ui_color_picker_hsv); assets_manager_add(am, ui_menu_down_right); assets_manager_add(am, ui_tab_bottom); diff --git a/project/entry/gui_demo/awtk/res/assets_old_dark.inc b/project/entry/gui_demo/awtk/res/assets_old_dark.inc index 9e75c1c7..91f973cf 100644 --- a/project/entry/gui_demo/awtk/res/assets_old_dark.inc +++ b/project/entry/gui_demo/awtk/res/assets_old_dark.inc @@ -93,6 +93,7 @@ #include "assets/default/inc/ui/kb_default_t9ext.data" #include "assets/default/inc/ui/dragger.data" #include "assets/default/inc/ui/dialog2.data" +#include "assets/default/inc/ui/t.data" #include "assets/default/inc/ui/color_picker_hsv.data" #include "assets/default/inc/ui/menu_down_right.data" #include "assets/default/inc/ui/tab_bottom.data" @@ -641,6 +642,7 @@ ret_t assets_init(void) { assets_manager_add(am, ui_kb_default_t9ext); assets_manager_add(am, ui_dragger); assets_manager_add(am, ui_dialog2); + assets_manager_add(am, ui_t); assets_manager_add(am, ui_color_picker_hsv); assets_manager_add(am, ui_menu_down_right); assets_manager_add(am, ui_tab_bottom); diff --git a/project/entry/gui_demo/awtk/res/assets_old_default.inc b/project/entry/gui_demo/awtk/res/assets_old_default.inc index be6038bf..26cd510f 100644 --- a/project/entry/gui_demo/awtk/res/assets_old_default.inc +++ b/project/entry/gui_demo/awtk/res/assets_old_default.inc @@ -93,6 +93,7 @@ #include "assets/default/inc/ui/kb_default_t9ext.data" #include "assets/default/inc/ui/dragger.data" #include "assets/default/inc/ui/dialog2.data" +#include "assets/default/inc/ui/t.data" #include "assets/default/inc/ui/color_picker_hsv.data" #include "assets/default/inc/ui/menu_down_right.data" #include "assets/default/inc/ui/tab_bottom.data" @@ -641,6 +642,7 @@ ret_t assets_init(void) { assets_manager_add(am, ui_kb_default_t9ext); assets_manager_add(am, ui_dragger); assets_manager_add(am, ui_dialog2); + assets_manager_add(am, ui_t); assets_manager_add(am, ui_color_picker_hsv); assets_manager_add(am, ui_menu_down_right); assets_manager_add(am, ui_tab_bottom); diff --git a/project/gui/awtk/src/Makefile b/project/gui/awtk/src/Makefile index ff64ba98..554b5ae8 100644 --- a/project/gui/awtk/src/Makefile +++ b/project/gui/awtk/src/Makefile @@ -20,7 +20,9 @@ obj-y += lcd/ obj-y += main_loop/ obj-y += native_window/ obj-y += platforms/ +obj-y += remote_ui/ obj-y += romfs/ +obj-y += service/ obj-y += streams/ obj-y += svg/ obj-y += tkc/ diff --git a/project/gui/awtk/src/base/widget.c b/project/gui/awtk/src/base/widget.c index dc6acd2d..6e34a8a0 100644 --- a/project/gui/awtk/src/base/widget.c +++ b/project/gui/awtk/src/base/widget.c @@ -1512,8 +1512,9 @@ ret_t widget_calc_icon_text_rect(const rect_t* ir, int32_t font_size, float_t te } case ICON_AT_LEFT: default: { - *r_icon = rect_init(ir->x, ir->y, ir->h, ir->h); - *r_text = rect_init(ir->x + ir->h + spacer, ir->y, ir->w - ir->h - spacer, ir->h); + wh_t w = tk_min(ir->h, ir->w); + *r_icon = rect_init(ir->x, ir->y, w, ir->h); + *r_text = rect_init(ir->x + w + spacer, ir->y, ir->w - w - spacer, ir->h); break; } } @@ -5268,3 +5269,50 @@ ret_t widget_dispatch_model_event(widget_t* widget, const char* name, const char return RET_OK; } + +widget_t* widget_find_by_path(widget_t* widget, const char* path, bool_t recursive) { + bool_t is_first = TRUE; + tokenizer_t tokenizer; + widget_t* iter = widget; + tokenizer_t* t = NULL; + return_value_if_fail(widget != NULL && path != NULL, NULL); + if (strchr(path, '.') == NULL) { + const char* name = path; + if (tk_str_eq(name, STR_PROP_PARENT)) { + return widget->parent; + } else if (tk_str_eq(name, STR_PROP_SELF)) { + return widget; + } else if (tk_str_eq(name, STR_PROP_WINDOW)) { + return widget_get_window(widget); + } else if (tk_str_eq(name, STR_PROP_WINDOW_MANAGER)) { + return widget_get_window_manager(widget); + } else { + return widget_lookup(widget, name, recursive); + } + } + t = tokenizer_init(&tokenizer, path, strlen(path), "."); + return_value_if_fail(t != NULL, NULL); + + while (tokenizer_has_more(t) && iter != NULL) { + const char* name = tokenizer_next(t); + if (is_first) { + if (tk_str_eq(name, STR_PROP_PARENT)) { + iter = widget->parent; + } else if (tk_str_eq(name, STR_PROP_SELF)) { + iter = widget; + } else if (tk_str_eq(name, STR_PROP_WINDOW)) { + iter = widget_get_window(widget); + } else if (tk_str_eq(name, STR_PROP_WINDOW_MANAGER)) { + iter = widget_get_window_manager(widget); + } else { + iter = widget_child(iter, name); + } + is_first = FALSE; + } else { + iter = widget_child(iter, name); + } + } + tokenizer_deinit(t); + + return iter; +} \ No newline at end of file diff --git a/project/gui/awtk/src/base/widget.h b/project/gui/awtk/src/base/widget.h index 71ffc15f..c6e2e05f 100644 --- a/project/gui/awtk/src/base/widget.h +++ b/project/gui/awtk/src/base/widget.h @@ -3389,6 +3389,8 @@ rect_t widget_get_content_area_ex(widget_t* widget, int32_t default_margin); ret_t widget_draw_image_with_region(widget_t* widget, canvas_t* c, bitmap_t* img, const char* region, const rect_t* dst, image_draw_type_t draw_type); +widget_t* widget_find_by_path(widget_t* widget, const char* path, bool_t recursive); + END_C_DECLS #endif /*TK_WIDGET_H*/ diff --git a/project/gui/awtk/src/fscript_ext/fscript_widget.c b/project/gui/awtk/src/fscript_ext/fscript_widget.c index fa8bb9df..bf4a8f2b 100644 --- a/project/gui/awtk/src/fscript_ext/fscript_widget.c +++ b/project/gui/awtk/src/fscript_ext/fscript_widget.c @@ -3,7 +3,7 @@ * Author: AWTK Develop Team * Brief: widget functions for fscript * - * Copyright (c) 2020 - 2022 Guangzhou ZHIYUAN Electronics Co.,Ltd. + * Copyright (c) 2020 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd. * */ @@ -31,54 +31,6 @@ #include "file_browser/file_dialog.h" #include "ui_loader/ui_builder_default.h" -static widget_t* find_target_widget(widget_t* widget, const char* path, uint32_t len, - bool_t recursive) { - bool_t is_first = TRUE; - tokenizer_t tokenizer; - widget_t* iter = widget; - tokenizer_t* t = NULL; - return_value_if_fail(widget != NULL && path != NULL, NULL); - if (strchr(path, '.') == NULL) { - const char* name = path; - if (tk_str_eq(name, STR_PROP_PARENT)) { - return widget->parent; - } else if (tk_str_eq(name, STR_PROP_SELF)) { - return widget; - } else if (tk_str_eq(name, STR_PROP_WINDOW)) { - return widget_get_window(widget); - } else if (tk_str_eq(name, STR_PROP_WINDOW_MANAGER)) { - return widget_get_window_manager(widget); - } else { - return widget_lookup(widget, name, recursive); - } - } - t = tokenizer_init(&tokenizer, path, len, "."); - return_value_if_fail(t != NULL, NULL); - - while (tokenizer_has_more(t) && iter != NULL) { - const char* name = tokenizer_next(t); - if (is_first) { - if (tk_str_eq(name, STR_PROP_PARENT)) { - iter = widget->parent; - } else if (tk_str_eq(name, STR_PROP_SELF)) { - iter = widget; - } else if (tk_str_eq(name, STR_PROP_WINDOW)) { - iter = widget_get_window(widget); - } else if (tk_str_eq(name, STR_PROP_WINDOW_MANAGER)) { - iter = widget_get_window_manager(widget); - } else { - iter = widget_child(iter, name); - } - is_first = FALSE; - } else { - iter = widget_child(iter, name); - } - } - tokenizer_deinit(t); - - return iter; -} - static widget_t* to_widget(fscript_t* fscript, const value_t* v) { widget_t* widget = NULL; if (v->type == VALUE_TYPE_STRING) { @@ -86,9 +38,9 @@ static widget_t* to_widget(fscript_t* fscript, const value_t* v) { const char* path = value_str(v); return_value_if_fail(path != NULL, NULL); - widget = find_target_widget(self, path, strlen(path), TRUE); + widget = widget_find_by_path(self, path, TRUE); if (widget == NULL) { - widget = find_target_widget(widget_get_window(self), path, strlen(path), TRUE); + widget = widget_find_by_path(widget_get_window(self), path, TRUE); } return widget; @@ -189,7 +141,10 @@ static ret_t widget_set(widget_t* self, const char* path, const value_t* v) { widget_t* widget = self; const char* prop = strrchr(path, '.'); if (prop != NULL) { - widget = find_target_widget(self, path, prop - path, TRUE); + char name[MAX_PATH+1] = {0}; + int32_t len = tk_min_int(prop - path, MAX_PATH); + tk_strncpy(name, path, len); + widget = widget_find_by_path(self, name, TRUE); prop++; } else { prop = path; @@ -204,7 +159,10 @@ static ret_t widget_get(widget_t* self, const char* path, value_t* v) { widget_t* widget = self; const char* prop = strrchr(path, '.'); if (prop != NULL) { - widget = find_target_widget(self, path, prop - path, TRUE); + char name[MAX_PATH+1] = {0}; + int32_t len = tk_min_int(prop - path, MAX_PATH); + tk_strncpy(name, path, len); + widget = widget_find_by_path(self, name, TRUE); prop++; } else { prop = path; @@ -257,7 +215,8 @@ static ret_t func_widget_layout(fscript_t* fscript, fscript_args_t* args, value_ return RET_OK; } -static ret_t func_widget_request_relayout(fscript_t* fscript, fscript_args_t* args, value_t* result) { +static ret_t func_widget_request_relayout(fscript_t* fscript, fscript_args_t* args, + value_t* result) { widget_t* widget = NULL; FSCRIPT_FUNC_CHECK(args->size == 1, RET_BAD_PARAMS); widget = to_widget(fscript, args->args); @@ -285,7 +244,7 @@ static ret_t func_widget_lookup(fscript_t* fscript, fscript_args_t* args, value_ } FSCRIPT_FUNC_CHECK(widget != NULL && path != NULL, RET_BAD_PARAMS); - widget = find_target_widget(widget, path, strlen(path), recursive); + widget = widget_find_by_path(widget, path, recursive); if (widget == NULL) { result->type = VALUE_TYPE_INVALID; return RET_NOT_FOUND; @@ -809,8 +768,8 @@ static ret_t func_show_fps(fscript_t* fscript, fscript_args_t* args, value_t* re static ret_t func_set_screen_saver_time(fscript_t* fscript, fscript_args_t* args, value_t* result) { FSCRIPT_FUNC_CHECK(args->size == 1, RET_BAD_PARAMS); - value_set_bool(result, - window_manager_set_screen_saver_time(window_manager(), value_uint32(args->args)) == RET_OK); + value_set_bool(result, window_manager_set_screen_saver_time(window_manager(), + value_uint32(args->args)) == RET_OK); return RET_OK; } diff --git a/project/gui/awtk/src/remote_ui/Makefile b/project/gui/awtk/src/remote_ui/Makefile new file mode 100644 index 00000000..f4915be9 --- /dev/null +++ b/project/gui/awtk/src/remote_ui/Makefile @@ -0,0 +1,2 @@ +obj-y += service/ +obj-y += client/ diff --git a/project/gui/awtk/src/remote_ui/client/Makefile b/project/gui/awtk/src/remote_ui/client/Makefile new file mode 100644 index 00000000..309eeaab --- /dev/null +++ b/project/gui/awtk/src/remote_ui/client/Makefile @@ -0,0 +1 @@ +obj-y += remote_ui.o diff --git a/project/gui/awtk/src/remote_ui/client/remote_ui.c b/project/gui/awtk/src/remote_ui/client/remote_ui.c new file mode 100644 index 00000000..aedd4d9c --- /dev/null +++ b/project/gui/awtk/src/remote_ui/client/remote_ui.c @@ -0,0 +1,609 @@ +/** + * File: remote_ui.c + * Author: AWTK Develop Team + * Brief: remote ui client + * + * Copyright (c) 2018 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * License file for more details. + * + */ + +/** + * History: + * ================================================================ + * 2023-11-04 Li XianJing created + * + */ + +#include "tkc/fs.h" +#include "tkc/mem.h" +#include "tkc/crc.h" +#include "tkc/utils.h" +#include "base/keys.h" +#include "base/events.h" +#include "conf_io/conf_ubjson.h" +#include "tkc/object_default.h" + +#include "remote_ui/client/remote_ui.h" +#include "remote_ui/shared/remote_ui_types_def.h" + +#define REMOTE_UI_ISTREAM_TIMEOUT 100 * 1000 + +remote_ui_t* remote_ui_create(tk_iostream_t* io) { + remote_ui_t* ui = NULL; + return_value_if_fail(io != NULL, NULL); + + ui = (remote_ui_t*)TKMEM_ZALLOC(remote_ui_t); + return_value_if_fail(ui != NULL, NULL); + + ui->io = io; + ui->event_handlers = object_default_create_ex(FALSE); + wbuffer_init_extendable(&(ui->wb)); + + return ui; +} + +static ret_t remote_ui_send_req(tk_iostream_t* io, uint32_t type, uint32_t data_type, + wbuffer_t* wb) { + int32_t ret = 0; + const void* data = NULL; + uint32_t size = 0; + uint32_t timeout = TK_OSTREAM_DEFAULT_TIMEOUT; + uint16_t crc_value = PPPINITFCS16; + remote_ui_msg_header_t header; + memset(&header, 0x00, sizeof(header)); + return_value_if_fail(io != NULL && wb != NULL, RET_BAD_PARAMS); + + size = wb->cursor; + data = wb->data; + if (size > 0) { + return_value_if_fail(data != NULL, RET_BAD_PARAMS); + } + + header.type = type; + header.size = size; + header.data_type = data_type; + + crc_value = tk_crc16(crc_value, &header, sizeof(header)); + if (data != NULL && size > 0) { + crc_value = tk_crc16(crc_value, data, size); + } + ret = tk_iostream_write_len(io, &header, sizeof(header), timeout); + return_value_if_fail(ret == sizeof(header), RET_IO); + + if (size > 0) { + timeout = TK_OSTREAM_DEFAULT_TIMEOUT * (size / 10240) + TK_OSTREAM_DEFAULT_TIMEOUT; + ret = tk_iostream_write_len(io, data, size, timeout); + return_value_if_fail(ret == size, RET_IO); + } + + ret = tk_iostream_write_len(io, &crc_value, sizeof(crc_value), TK_OSTREAM_DEFAULT_TIMEOUT); + return_value_if_fail(ret == sizeof(crc_value), RET_IO); + + return RET_OK; +} + +static ret_t remote_ui_read_resp(tk_iostream_t* io, remote_ui_msg_header_t* header, wbuffer_t* wb) { + int32_t ret = 0; + uint16_t crc_value = 0; + uint16_t real_crc_value = PPPINITFCS16; + return_value_if_fail(io != NULL && header != NULL && wb != NULL, RET_BAD_PARAMS); + + wbuffer_rewind(wb); + ret = tk_iostream_read_len(io, header, sizeof(*header), REMOTE_UI_ISTREAM_TIMEOUT); + return_value_if_fail(ret == sizeof(*header), RET_IO); + + real_crc_value = tk_crc16(real_crc_value, header, sizeof(*header)); + if (header->size > 0) { + return_value_if_fail(wbuffer_extend_capacity(wb, header->size) == RET_OK, RET_OOM); + ret = tk_iostream_read_len(io, wb->data, header->size, REMOTE_UI_ISTREAM_TIMEOUT); + return_value_if_fail(ret == header->size, RET_IO); + real_crc_value = tk_crc16(real_crc_value, wb->data, header->size); + } + + ret = tk_iostream_read_len(io, &crc_value, sizeof(crc_value), REMOTE_UI_ISTREAM_TIMEOUT); + return_value_if_fail(ret == sizeof(crc_value), RET_IO); + return_value_if_fail(real_crc_value == crc_value, RET_CRC); + + wb->cursor = header->size; + + return header->resp_code; +} + +static ret_t remote_ui_request(tk_iostream_t* io, uint32_t type, uint32_t data_type, + wbuffer_t* wb) { + ret_t ret = remote_ui_send_req(io, type, data_type, wb); + if (ret == RET_OK) { + remote_ui_msg_header_t header; + memset(&header, 0x00, sizeof(header)); + ret = remote_ui_read_resp(io, &header, wb); + } + + return ret; +} + +static ubjson_writer_t* remote_ui_client_get_writer(remote_ui_t* ui) { + wbuffer_t* wb = &(ui->wb); + ubjson_writer_t* writer = &(ui->writer); + + wb->cursor = 0; + return ubjson_writer_init(writer, (ubjson_write_callback_t)wbuffer_write_binary, wb); +} + +ret_t remote_ui_login(remote_ui_t* ui, const char* username, const char* password) { + ubjson_writer_t* writer = NULL; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(username != NULL, RET_BAD_PARAMS); + return_value_if_fail(password != NULL, RET_BAD_PARAMS); + writer = remote_ui_client_get_writer(ui); + + ubjson_writer_write_object_begin(writer); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_USERNAME, username); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_PASSWORD, password); + ubjson_writer_write_object_end(writer); + + return remote_ui_request(ui->io, REMOTE_UI_REQ_LOGIN, REMOTE_UI_DATA_TYPE_UBJSON, &(ui->wb)); +} + +ret_t remote_ui_logout(remote_ui_t* ui) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + + wbuffer_rewind(&(ui->wb)); + return remote_ui_request(ui->io, REMOTE_UI_REQ_LOGOUT, REMOTE_UI_DATA_TYPE_NONE, &(ui->wb)); +} + +ret_t remote_ui_get_dev_info(remote_ui_t* ui, remote_ui_dev_info_t* info) { + ret_t ret = RET_FAIL; + wbuffer_t* wb = NULL; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(info != NULL, RET_BAD_PARAMS); + + wb = &(ui->wb); + wbuffer_rewind(wb); + memset(info, 0x00, sizeof(*info)); + ret = remote_ui_request(ui->io, REMOTE_UI_REQ_GET_DEV_INFO, REMOTE_UI_DATA_TYPE_UBJSON, wb); + if (ret == RET_OK) { + tk_object_t* obj = conf_ubjson_load_from_buff(wb->data, wb->cursor, FALSE); + if (obj != NULL) { + const char* p = NULL; + p = tk_object_get_prop_str(obj, REMOTE_UI_KEY_DEV_NAME); + if (p != NULL) { + tk_strncpy(info->name, p, sizeof(info->name) - 1); + } + + p = tk_object_get_prop_str(obj, REMOTE_UI_KEY_DEV_VERSION); + if (p != NULL) { + tk_strncpy(info->version, p, sizeof(info->version) - 1); + } + + p = tk_object_get_prop_str(obj, REMOTE_UI_KEY_DEV_OS); + if (p != NULL) { + tk_strncpy(info->os, p, sizeof(info->os) - 1); + } + + p = tk_object_get_prop_str(obj, REMOTE_UI_KEY_DEV_ARCH); + if (p != NULL) { + tk_strncpy(info->arch, p, sizeof(info->arch) - 1); + } + + info->screen_width = tk_object_get_prop_int(obj, REMOTE_UI_KEY_DEV_SCREEN_WIDTH, 0); + info->screen_height = tk_object_get_prop_int(obj, REMOTE_UI_KEY_DEV_SCREEN_HEIGHT, 0); + info->dpi = tk_object_get_prop_int(obj, REMOTE_UI_KEY_DEV_DPI, 0); + + TK_OBJECT_UNREF(obj); + } + } + + return ret; +} + +ret_t remote_ui_reboot(remote_ui_t* ui, remote_ui_reboot_type_t reboot_type) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + + wbuffer_rewind(&(ui->wb)); + wbuffer_write_int32(&(ui->wb), reboot_type); + return remote_ui_request(ui->io, REMOTE_UI_REQ_REBOOT, REMOTE_UI_DATA_TYPE_NONE, &(ui->wb)); +} + +ret_t remote_ui_upload_file(remote_ui_t* ui, const char* remote_file, const char* local_file) { + wbuffer_t wb; + int32_t len = 0; + ret_t ret = RET_OK; + fs_file_t* file = NULL; + uint8_t buff[4096] = {0}; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(remote_file != NULL, RET_BAD_PARAMS); + return_value_if_fail(local_file != NULL, RET_BAD_PARAMS); + + file = fs_open_file(os_fs(), local_file, "rb"); + return_value_if_fail(file != NULL, RET_BAD_PARAMS); + + wbuffer_init(&wb, (void*)remote_file, strlen(remote_file) + 1); + wb.cursor = wb.capacity; + ret = remote_ui_request(ui->io, REMOTE_UI_REQ_UPLOAD_FILE_BEGIN, REMOTE_UI_DATA_TYPE_STRING, &wb); + goto_error_if_fail(ret == RET_OK); + + while ((len = fs_file_read(file, buff, sizeof(buff))) > 0) { + wbuffer_init(&wb, buff, len); + wb.cursor = len; + ret = + remote_ui_request(ui->io, REMOTE_UI_REQ_UPLOAD_FILE_DATA, REMOTE_UI_DATA_TYPE_BINARY, &wb); + break_if_fail(ret == RET_OK); + } + + wbuffer_rewind(&wb); + ret = remote_ui_request(ui->io, REMOTE_UI_REQ_UPLOAD_FILE_END, REMOTE_UI_DATA_TYPE_NONE, &wb); + + fs_file_close(file); + + return ret; +error: + fs_file_close(file); + + return RET_FAIL; +} + +ret_t remote_ui_download_file(remote_ui_t* ui, const char* remote_file, const char* local_file) { + int32_t len = 0; + ret_t ret = RET_OK; + fs_file_t* file = NULL; + wbuffer_t* wb = NULL; + remote_ui_msg_header_t header; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(remote_file != NULL, RET_BAD_PARAMS); + return_value_if_fail(local_file != NULL, RET_BAD_PARAMS); + + file = fs_open_file(os_fs(), local_file, "wb+"); + return_value_if_fail(file != NULL, RET_BAD_PARAMS); + + wb = &(ui->wb); + wbuffer_rewind(wb); + wbuffer_write_string(wb, remote_file); + ret = + remote_ui_request(ui->io, REMOTE_UI_REQ_DOWNLOAD_FILE_BEGIN, REMOTE_UI_DATA_TYPE_STRING, wb); + goto_error_if_fail(ret == RET_OK); + + memset(&header, 0x00, sizeof(header)); + + while ((ret = remote_ui_read_resp(ui->io, &header, wb)) == RET_OK) { + if (header.type == REMOTE_UI_RESP_DOWNLOAD_FILE_DATA) { + len = fs_file_write(file, wb->data, wb->cursor); + break_if_fail(len == wb->cursor); + } else if (header.type == REMOTE_UI_RESP_DOWNLOAD_FILE_END) { + ret = RET_OK; + break; + } else { + assert(!"impossible"); + ret = RET_FAIL; + break; + } + } + fs_file_close(file); + + return ret; +error: + fs_file_close(file); + + return ret; +} + +ret_t remote_ui_create_dir(remote_ui_t* ui, const char* remote_dir) { + ret_t ret = RET_OK; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(remote_dir != NULL, RET_BAD_PARAMS); + + wbuffer_rewind(&(ui->wb)); + wbuffer_write_string(&(ui->wb), remote_dir); + ret = remote_ui_request(ui->io, REMOTE_UI_REQ_CREATE_DIR, REMOTE_UI_DATA_TYPE_STRING, &(ui->wb)); + + return ret; +} + +ret_t remote_ui_remove_dir(remote_ui_t* ui, const char* remote_dir) { + ret_t ret = RET_OK; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(remote_dir != NULL, RET_BAD_PARAMS); + + wbuffer_rewind(&(ui->wb)); + wbuffer_write_string(&(ui->wb), remote_dir); + ret = remote_ui_request(ui->io, REMOTE_UI_REQ_REMOVE_DIR, REMOTE_UI_DATA_TYPE_STRING, &(ui->wb)); + + return ret; +} + +ret_t remote_ui_remove_file(remote_ui_t* ui, const char* remote_file) { + ret_t ret = RET_OK; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(remote_file != NULL, RET_BAD_PARAMS); + + wbuffer_rewind(&(ui->wb)); + wbuffer_write_string(&(ui->wb), remote_file); + ret = remote_ui_request(ui->io, REMOTE_UI_REQ_REMOVE_FILE, REMOTE_UI_DATA_TYPE_STRING, &(ui->wb)); + + return ret; +} + +ret_t remote_ui_take_screen_shot(remote_ui_t* ui, const char* file) { + return remote_ui_download_file(ui, REMOTE_UI_FILE_SCREEN_SHOT, file); +} + +ret_t remote_ui_get_manifest(remote_ui_t* ui, const char* file) { + return remote_ui_download_file(ui, REMOTE_UI_FILE_MANIFEST, file); +} + +ret_t remote_ui_get_xml_source(remote_ui_t* ui, const char* file) { + return remote_ui_download_file(ui, REMOTE_UI_FILE_XML_SOURCE, file); +} + +ret_t remote_ui_on_event(remote_ui_t* ui, const char* target, uint32_t event, event_func_t func, + void* ctx) { + emitter_t* emitter = NULL; + ubjson_writer_t* writer = NULL; + return_value_if_fail(ui != NULL && ui->event_handlers != NULL, RET_BAD_PARAMS); + return_value_if_fail(target != NULL, RET_BAD_PARAMS); + return_value_if_fail(func != NULL, RET_BAD_PARAMS); + + emitter = tk_object_get_prop_pointer(ui->event_handlers, target); + if (emitter == NULL) { + emitter = emitter_create(); + return_value_if_fail(emitter != NULL, RET_OOM); + tk_object_set_prop_pointer_ex(ui->event_handlers, target, emitter, + (tk_destroy_t)emitter_destroy); + } + emitter_on(emitter, event, func, ctx); + + writer = remote_ui_client_get_writer(ui); + + ubjson_writer_write_object_begin(writer); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_TARGET, target); + ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_EVENT, event); + ubjson_writer_write_object_end(writer); + + return remote_ui_request(ui->io, REMOTE_UI_REQ_ON_EVENT, REMOTE_UI_DATA_TYPE_UBJSON, &(ui->wb)); +} + +ret_t remote_ui_off_event(remote_ui_t* ui, const char* target, uint32_t event) { + emitter_t* emitter = NULL; + ubjson_writer_t* writer = NULL; + return_value_if_fail(ui != NULL && ui->event_handlers != NULL, RET_BAD_PARAMS); + return_value_if_fail(target != NULL, RET_BAD_PARAMS); + + emitter = tk_object_get_prop_pointer(ui->event_handlers, target); + if (emitter != NULL) { + emitter_off(emitter, event); + } + + writer = remote_ui_client_get_writer(ui); + ubjson_writer_write_object_begin(writer); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_TARGET, target); + ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_EVENT, event); + ubjson_writer_write_object_end(writer); + + return remote_ui_request(ui->io, REMOTE_UI_REQ_OFF_EVENT, REMOTE_UI_DATA_TYPE_UBJSON, &(ui->wb)); +} + +ret_t remote_ui_send_event(remote_ui_t* ui, const char* target, event_t* event) { + ubjson_writer_t* writer = NULL; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(target != NULL, RET_BAD_PARAMS); + return_value_if_fail(event != NULL, RET_BAD_PARAMS); + + writer = remote_ui_client_get_writer(ui); + ubjson_writer_write_object_begin(writer); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_TARGET, target); + ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_EVENT, event->type); + switch (event->type) { + case EVT_CLICK: + case EVT_POINTER_DOWN: + case EVT_POINTER_UP: + case EVT_POINTER_MOVE: { + pointer_event_t* e = (pointer_event_t*)event; + ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_X, e->x); + ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_Y, e->y); + break; + } + case EVT_KEY_DOWN: + case EVT_KEY_UP: { + key_event_t* e = (key_event_t*)event; + ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_CODE, e->key); + break; + } + default: { + log_debug("not supported event type:%d\n", event->type); + return RET_NOT_IMPL; + } + } + ubjson_writer_write_object_end(writer); + + return remote_ui_request(ui->io, REMOTE_UI_REQ_SEND_EVENT, REMOTE_UI_DATA_TYPE_UBJSON, &(ui->wb)); +} + +ret_t remote_ui_open_window(remote_ui_t* ui, const char* name, const char* xml, + const char* init_json) { + ubjson_writer_t* writer = NULL; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(name != NULL, RET_BAD_PARAMS); + + writer = remote_ui_client_get_writer(ui); + ubjson_writer_write_object_begin(writer); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_NAME, name); + if (xml != NULL) { + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_XML, xml); + } + if (init_json != NULL) { + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_INIT, init_json); + } + ubjson_writer_write_object_end(writer); + + return remote_ui_request(ui->io, REMOTE_UI_REQ_OPEN_WINDOW, REMOTE_UI_DATA_TYPE_UBJSON, + &(ui->wb)); +} + +static ret_t remote_ui_show_dialog(remote_ui_t* ui, const char* type, const char* title, + const char* content, uint32_t duration) { + ubjson_writer_t* writer = NULL; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(type != NULL, RET_BAD_PARAMS); + + writer = remote_ui_client_get_writer(ui); + ubjson_writer_write_object_begin(writer); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_TYPE, type); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_TITLE, title); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_CONTENT, content); + ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_DURATION, duration); + ubjson_writer_write_object_end(writer); + + return remote_ui_request(ui->io, REMOTE_UI_REQ_OPEN_DIALOG, REMOTE_UI_DATA_TYPE_UBJSON, + &(ui->wb)); +} + +ret_t remote_ui_show_confirm(remote_ui_t* ui, const char* title, const char* content) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(title != NULL, RET_BAD_PARAMS); + return_value_if_fail(content != NULL, RET_BAD_PARAMS); + + return remote_ui_show_dialog(ui, REMOTE_UI_DIALOG_TYPE_CONFIRM, title, content, 0); +} + +ret_t remote_ui_show_warn(remote_ui_t* ui, const char* title, const char* content) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(title != NULL, RET_BAD_PARAMS); + return_value_if_fail(content != NULL, RET_BAD_PARAMS); + + return remote_ui_show_dialog(ui, REMOTE_UI_DIALOG_TYPE_WARN, title, content, 0); +} + +ret_t remote_ui_show_info(remote_ui_t* ui, const char* title, const char* content) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(title != NULL, RET_BAD_PARAMS); + return_value_if_fail(content != NULL, RET_BAD_PARAMS); + + return remote_ui_show_dialog(ui, NULL, title, content, 0); +} + +ret_t remote_ui_show_toast(remote_ui_t* ui, uint32_t duration, const char* content) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(content != NULL, RET_BAD_PARAMS); + + return remote_ui_show_dialog(ui, REMOTE_UI_DIALOG_TYPE_TOAST, "", content, duration); +} + +ret_t remote_ui_close_window(remote_ui_t* ui, const char* name) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(name != NULL, RET_BAD_PARAMS); + + wbuffer_rewind(&(ui->wb)); + wbuffer_write_string(&(ui->wb), name); + return remote_ui_request(ui->io, REMOTE_UI_REQ_CLOSE_WINDOW, REMOTE_UI_DATA_TYPE_STRING, + &(ui->wb)); +} + +ret_t remote_ui_back_to_prev(remote_ui_t* ui) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + + wbuffer_rewind(&(ui->wb)); + return remote_ui_request(ui->io, REMOTE_UI_REQ_BACK_TO_PREV, REMOTE_UI_DATA_TYPE_NONE, &(ui->wb)); +} + +ret_t remote_ui_back_to_home(remote_ui_t* ui) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + + wbuffer_rewind(&(ui->wb)); + return remote_ui_request(ui->io, REMOTE_UI_REQ_BACK_TO_HOME, REMOTE_UI_DATA_TYPE_NONE, &(ui->wb)); +} + +ret_t remote_ui_set_prop(remote_ui_t* ui, const char* target, const char* name, + const value_t* value) { + ubjson_writer_t* writer = NULL; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(target != NULL, RET_BAD_PARAMS); + return_value_if_fail(name != NULL, RET_BAD_PARAMS); + return_value_if_fail(value != NULL, RET_BAD_PARAMS); + + writer = remote_ui_client_get_writer(ui); + ubjson_writer_write_object_begin(writer); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_TARGET, target); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_NAME, name); + ubjson_writer_write_kv_value(writer, REMOTE_UI_KEY_VALUE, value); + ubjson_writer_write_object_end(writer); + + return remote_ui_request(ui->io, REMOTE_UI_REQ_SET_PROP, REMOTE_UI_DATA_TYPE_UBJSON, &(ui->wb)); +} + +ret_t remote_ui_get_prop(remote_ui_t* ui, const char* target, const char* name, value_t* value) { + ret_t ret = RET_OK; + ubjson_writer_t* writer = NULL; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(target != NULL, RET_BAD_PARAMS); + return_value_if_fail(name != NULL, RET_BAD_PARAMS); + return_value_if_fail(value != NULL, RET_BAD_PARAMS); + + writer = remote_ui_client_get_writer(ui); + ubjson_writer_write_object_begin(writer); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_TARGET, target); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_NAME, name); + ubjson_writer_write_kv_value(writer, REMOTE_UI_KEY_VALUE, value); + ubjson_writer_write_object_end(writer); + + ret = remote_ui_request(ui->io, REMOTE_UI_REQ_GET_PROP, REMOTE_UI_DATA_TYPE_UBJSON, &(ui->wb)); + return_value_if_fail(ret == RET_OK, ret); + + value_dup_str_with_len(value, (char*)(ui->wb.data), ui->wb.cursor); + + return RET_OK; +} + +ret_t remote_ui_set_theme(remote_ui_t* ui, const char* theme) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(theme != NULL, RET_BAD_PARAMS); + + wbuffer_rewind(&(ui->wb)); + wbuffer_write_string(&(ui->wb), theme); + return remote_ui_request(ui->io, REMOTE_UI_REQ_SET_THEME, REMOTE_UI_DATA_TYPE_STRING, &(ui->wb)); +} + +ret_t remote_ui_set_language(remote_ui_t* ui, const char* language) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(language != NULL, RET_BAD_PARAMS); + + wbuffer_rewind(&(ui->wb)); + wbuffer_write_string(&(ui->wb), language); + return remote_ui_request(ui->io, REMOTE_UI_REQ_SET_LANGUAGE, REMOTE_UI_DATA_TYPE_STRING, + &(ui->wb)); +} + +ret_t remote_ui_exec_fscript(remote_ui_t* ui, const char* script, str_t* str) { + ret_t ret = RET_OK; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(script != NULL, RET_BAD_PARAMS); + + wbuffer_rewind(&(ui->wb)); + wbuffer_write_string(&(ui->wb), script); + ret = + remote_ui_request(ui->io, REMOTE_UI_REQ_EXEC_FSCRIPT, REMOTE_UI_DATA_TYPE_STRING, &(ui->wb)); + if (ret == RET_OK) { + str_set_with_len(str, (char*)(ui->wb.data), ui->wb.cursor); + } + + return ret; +} + +ret_t remote_ui_dispatch(remote_ui_t* ui) { + /*TODO*/ + return RET_OK; +} + +ret_t remote_ui_destroy(remote_ui_t* ui) { + return_value_if_fail(ui != NULL, RET_BAD_PARAMS); + + TK_OBJECT_UNREF(ui->io); + TK_OBJECT_UNREF(ui->event_handlers); + wbuffer_deinit(&(ui->wb)); + TKMEM_FREE(ui); + + return RET_OK; +} diff --git a/project/gui/awtk/src/remote_ui/client/remote_ui.h b/project/gui/awtk/src/remote_ui/client/remote_ui.h new file mode 100644 index 00000000..81b92519 --- /dev/null +++ b/project/gui/awtk/src/remote_ui/client/remote_ui.h @@ -0,0 +1,398 @@ +/** + * File: remote_ui.h + * Author: AWTK Develop Team + * Brief: remote ui client + * + * Copyright (c) 2018 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * License file for more details. + * + */ + +/** + * History: + * ================================================================ + * 2023-11-04 Li XianJing created + * + */ + +#ifndef TK_REMOTE_UI_H +#define TK_REMOTE_UI_H + +#include "tkc/buffer.h" +#include "tkc/darray.h" +#include "tkc/iostream.h" +#include "ubjson/ubjson_writer.h" +#include "remote_ui/shared/remote_ui_types_def.h" + +BEGIN_C_DECLS + +/** + * @class remote_ui_t + * remote ui客户端。 +*/ +typedef struct _remote_ui_t { + /** + * @property {tk_iostream_t*} io + * @annotation ["readable"] + * IO stream。 + */ + tk_iostream_t* io; + + /*private*/ + wbuffer_t wb; + ubjson_writer_t writer; + tk_object_t* event_handlers; +} remote_ui_t; + +/** + * @method remote_ui_create + * 创建remote ui客户端。 + * + * @param {tk_iostream_t*} io IO流。 + * + * @return {remote_ui_t*} 返回remote ui客户端对象。 + */ +remote_ui_t* remote_ui_create(tk_iostream_t* io); + +/** + * @method remote_ui_login + * 登录。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} username 用户名。 + * @param {const char*} password 密码。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_login(remote_ui_t* ui, const char* username, const char* password); + +/** + * @method remote_ui_logout + * 登出。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_logout(remote_ui_t* ui); + +/** + * @method remote_ui_get_dev_info + * 获取设备信息。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {remote_ui_dev_info_t*} info 设备信息。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_get_dev_info(remote_ui_t* ui, remote_ui_dev_info_t* info); + +/** + * @method remote_ui_reboot + * @param {remote_ui_t*} ui remote ui客户端对象。 + * 重新启动。 + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_reboot(remote_ui_t* ui, remote_ui_reboot_type_t type); + +/** + * @method remote_ui_upload_file + * 上传文件。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} remote_file 远程文件。 + * @param {const char*} local_file 本地文件。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_upload_file(remote_ui_t* ui, const char* remote_file, const char* local_file); + +/** + * @method remote_ui_download_file + * 下载文件。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} remote_file 远程文件。 + * @param {const char*} local_file 本地文件。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_download_file(remote_ui_t* ui, const char* remote_file, const char* local_file); + +/** + * @method remote_ui_create_dir + * 创建目录。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} remote_dir 远程目录。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_create_dir(remote_ui_t* ui, const char* remote_dir); + +/** + * @method remote_ui_remove_dir + * 删除目录。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} remote_dir 远程目录。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_remove_dir(remote_ui_t* ui, const char* remote_dir); + +/** + * @method remote_ui_remove_file + * 删除文件。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} remote_file 远程文件。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_remove_file(remote_ui_t* ui, const char* remote_file); + +/** + * @method remote_ui_take_screen_shot + * 截屏。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} file 文件名。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_take_screen_shot(remote_ui_t* ui, const char* file); + +/** + * @method remote_ui_get_manifest + * 获取manifest。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} file 文件名。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_get_manifest(remote_ui_t* ui, const char* file); + +/** + * @method remote_ui_get_xml_source + * 获取当前窗口的XML源码。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} file 文件名。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_get_xml_source(remote_ui_t* ui, const char* file); + +/** + * @method remote_ui_on_event + * 注册事件。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} target 目标。 + * @param {uint32_t} event 事件。 + * @param {event_func_t} func 事件处理函数。 + * @param {void*} ctx 上下文。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_on_event(remote_ui_t* ui, const char* target, uint32_t event, event_func_t func, + void* ctx); + +/** + * @method remote_ui_off_event + * 注销事件。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} target 目标。 + * @param {uint32_t} event 事件。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_off_event(remote_ui_t* ui, const char* target, uint32_t event); + +/** + * @method remote_ui_send_event + * 发送事件。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} target 目标。 + * @param {event_t*} event 事件。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_send_event(remote_ui_t* ui, const char* target, event_t* event); + +/** + * @method remote_ui_open_window + * 打开窗口。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} name 窗口名称。 + * @param {const char*} xml 窗口XML。 + * @param {const char*} init_json 初始化JSON。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_open_window(remote_ui_t* ui, const char* name, const char* xml, + const char* init_json); + +/** + * @method remote_ui_show_confirm + * 显示确认对话框。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} title 标题。 + * @param {const char*} content 内容。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_show_confirm(remote_ui_t* ui, const char* title, + const char* content); +/** + * @method remote_ui_show_warn + * 显示警告对话框。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} title 标题。 + * @param {const char*} content 内容。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_show_warn(remote_ui_t* ui, const char* title, + const char* content); + +/** + * @method remote_ui_show_info + * 显示信息对话框。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} title 标题。 + * @param {const char*} content 内容。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_show_info(remote_ui_t* ui, const char* title, + const char* content); +/** + * @method remote_ui_show_toast + * 显示信息对话框。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {uint32_t} duration 时长。 + * @param {const char*} content 内容。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_show_toast(remote_ui_t* ui, uint32_t duration, + const char* content); +/** + * @method remote_ui_close_window + * 关闭窗口。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} name 窗口名称。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_close_window(remote_ui_t* ui, const char* name); + +/** + * @method remote_ui_back_to_prev + * 返回上一个窗口。 + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_back_to_prev(remote_ui_t* ui); + +/** + * @method remote_ui_back_to_home + * 返回主窗口。 + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 +*/ +ret_t remote_ui_back_to_home(remote_ui_t* ui); + +/** + * @method remote_ui_set_prop + * 设置属性。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} target 目标。 + * @param {const char*} name 属性名称。 + * @param {const value_t*} value 属性值。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_set_prop(remote_ui_t* ui, const char* target, const char* name, + const value_t* value); + +/** + * @method remote_ui_get_prop + * 获取属性。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} target 目标。 + * @param {const char*} name 属性名称。 + * @param {value_t*} value 属性值。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_get_prop(remote_ui_t* ui, const char* target, const char* name, value_t* value); + +/** + * @method remote_ui_set_theme + * 设置主题。 + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} theme 主题名称。 + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 +*/ +ret_t remote_ui_set_theme(remote_ui_t* ui, const char* theme); + +/** + * @method remote_ui_set_language + * 设置语言。 + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} language 语言名称。 + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 +*/ +ret_t remote_ui_set_language(remote_ui_t* ui, const char* language); + +/** + * @method remote_ui_exec_fscript + * 执行fscript脚本。 + * @param {remote_ui_t*} ui remote ui客户端对象。 + * @param {const char*} script 脚本。 + * @param {str_t*} result 执行结果。 + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 +*/ +ret_t remote_ui_exec_fscript(remote_ui_t* ui, const char* script, str_t* result); + +/** + * @method remote_ui_dispatch + * 分发事件。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_dispatch(remote_ui_t* ui); + +/** + * @method remote_ui_destroy + * 销毁remote ui客户端。 + * + * @param {remote_ui_t*} ui remote ui客户端对象。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t remote_ui_destroy(remote_ui_t* ui); + +END_C_DECLS + +#endif /*TK_REMOTE_UI_H*/ diff --git a/project/gui/awtk/src/remote_ui/service/Makefile b/project/gui/awtk/src/remote_ui/service/Makefile new file mode 100644 index 00000000..08343ece --- /dev/null +++ b/project/gui/awtk/src/remote_ui/service/Makefile @@ -0,0 +1 @@ +obj-y += remote_ui_service.o diff --git a/project/gui/awtk/src/remote_ui/service/remote_ui_service.c b/project/gui/awtk/src/remote_ui/service/remote_ui_service.c new file mode 100644 index 00000000..1d22deff --- /dev/null +++ b/project/gui/awtk/src/remote_ui/service/remote_ui_service.c @@ -0,0 +1,816 @@ +/** + * File: remote_ui_service.c + * Author: AWTK Develop Team + * Brief: remote ui service + * + * Copyright (c) 2018 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * License file for more details. + * + */ + +/** + * History: + * ================================================================ + * 2023-11-04 Li XianJing created + * + */ + +#include "tkc/fs.h" +#include "tkc/mem.h" +#include "tkc/crc.h" +#include "tkc/path.h" +#include "tkc/utils.h" +#include "tkc/fscript.h" +#include "base/bitmap.h" +#include "base/window.h" +#include "base/window_manager.h" +#include "base/ui_loader.h" +#include "base/dialog.h" +#include "conf_io/conf_ubjson.h" +#include "tkc/object_default.h" +#include "ui_loader/ui_serializer.h" +#include "remote_ui/shared/remote_ui_types_def.h" +#include "remote_ui/service/remote_ui_service.h" + +#include "base/events.h" +#include "base/keys.h" + +static ret_t remote_ui_service_dispatch(remote_ui_service_t* ui); +static ret_t remote_ui_service_destroy(remote_ui_service_t* ui); + +tk_service_t* remote_ui_service_create(tk_iostream_t* io, void* args) { + remote_ui_service_t* ui = NULL; + remote_ui_service_args_t* service_args = (remote_ui_service_args_t*)args; + + return_value_if_fail(io != NULL, NULL); + + ui = (remote_ui_service_t*)TKMEM_ZALLOC(remote_ui_service_t); + return_value_if_fail(ui != NULL, NULL); + + ui->io = io; + ui->service.dispatch = (tk_service_dispatch_t)remote_ui_service_dispatch; + ui->service.destroy = (tk_service_destroy_t)remote_ui_service_destroy; + + wbuffer_init_extendable(&(ui->wb)); + if (service_args != NULL && service_args->auth != NULL) { + ui->auth = service_args->auth; + } + + return (tk_service_t*)ui; +} + +static ret_t remote_ui_service_send_resp(tk_iostream_t* io, uint32_t type, uint32_t data_type, + uint32_t resp_code, wbuffer_t* wb) { + int32_t ret = 0; + uint32_t size = 0; + const void* data = NULL; + remote_ui_msg_header_t header; + uint16_t crc_value = PPPINITFCS16; + uint32_t timeout = TK_OSTREAM_DEFAULT_TIMEOUT; + + memset(&header, 0x00, sizeof(header)); + return_value_if_fail(io != NULL && wb != NULL, RET_BAD_PARAMS); + + data = wb->data; + size = wb->cursor; + if (size > 0) { + return_value_if_fail(data != NULL, RET_BAD_PARAMS); + } + + header.type = type; + header.size = size; + header.data_type = data_type; + header.resp_code = resp_code; + + crc_value = tk_crc16(crc_value, &header, sizeof(header)); + if (data != NULL && size > 0) { + crc_value = tk_crc16(crc_value, data, size); + } + + ret = tk_iostream_write_len(io, &header, sizeof(header), timeout); + return_value_if_fail(ret == sizeof(header), RET_IO); + + if (size > 0) { + timeout = TK_OSTREAM_DEFAULT_TIMEOUT * (size / 10240) + TK_OSTREAM_DEFAULT_TIMEOUT; + ret = tk_iostream_write_len(io, data, size, timeout); + return_value_if_fail(ret == size, RET_IO); + } + + ret = tk_iostream_write_len(io, &crc_value, sizeof(crc_value), TK_OSTREAM_DEFAULT_TIMEOUT); + return_value_if_fail(ret == sizeof(crc_value), RET_IO); + + return RET_OK; +} + +static ret_t remote_ui_service_read_req(tk_iostream_t* io, remote_ui_msg_header_t* header, + wbuffer_t* wb) { + int32_t ret = 0; + uint16_t crc_value = 0; + uint16_t real_crc_value = PPPINITFCS16; + return_value_if_fail(io != NULL && header != NULL && wb != NULL, RET_BAD_PARAMS); + + wbuffer_rewind(wb); + ret = tk_iostream_read_len(io, header, sizeof(*header), TK_ISTREAM_DEFAULT_TIMEOUT); + if (ret == 0) { + return RET_IO; + } + return_value_if_fail(ret == sizeof(*header), RET_IO); + + real_crc_value = tk_crc16(real_crc_value, header, sizeof(*header)); + if (header->size > 0) { + return_value_if_fail(wbuffer_extend_capacity(wb, header->size) == RET_OK, RET_OOM); + ret = tk_iostream_read_len(io, wb->data, header->size, TK_ISTREAM_DEFAULT_TIMEOUT); + return_value_if_fail(ret == header->size, RET_IO); + real_crc_value = tk_crc16(real_crc_value, wb->data, header->size); + } + + ret = tk_iostream_read_len(io, &crc_value, sizeof(crc_value), TK_ISTREAM_DEFAULT_TIMEOUT); + return_value_if_fail(ret == sizeof(crc_value), RET_IO); + return_value_if_fail(crc_value == real_crc_value, RET_CRC); + + wb->cursor = header->size; + + return header->resp_code; +} + +static ubjson_writer_t* remote_ui_service_get_writer(remote_ui_service_t* ui) { + wbuffer_t* wb = &(ui->wb); + ubjson_writer_t* writer = &(ui->writer); + + wb->cursor = 0; + return ubjson_writer_init(writer, (ubjson_write_callback_t)wbuffer_write_binary, wb); +} + +static ret_t remote_ui_service_login(remote_ui_service_t* ui, const char* username, const char* password) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + if (ui->auth != NULL) { + if (ui->auth((tk_service_t*)ui, username, password) == RET_OK) { + ui->is_login = TRUE; + return RET_OK; + } else { + return RET_FAIL; + } + } else { + return RET_OK; + } +} + +static ret_t remote_ui_service_logout(remote_ui_service_t* ui) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + + ui->is_login = FALSE; + + return RET_OK; +} + +static ret_t remote_ui_service_get_dev_info(remote_ui_service_t* ui, remote_ui_dev_info_t* info) { + ret_t ret = RET_OK; + widget_t* wm = window_manager(); + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(info != NULL, RET_BAD_PARAMS); + + memset(info, 0x00, sizeof(*info)); + info->screen_width = wm->w; + info->screen_height = wm->h; + /*TODO*/ + return ret; +} + +static ret_t remote_ui_service_reboot(remote_ui_service_t* ui, remote_ui_reboot_type_t reboot_type) { + /*TODO*/ + return RET_OK; +} + +static ret_t remote_ui_service_upload_file(remote_ui_service_t* ui, const char* filename) { + int32_t len = 0; + ret_t ret = RET_OK; + fs_file_t* file = NULL; + wbuffer_t* wb = NULL; + remote_ui_msg_header_t header; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(filename != NULL, RET_BAD_PARAMS); + + wb = &(ui->wb); + wbuffer_rewind(wb); + file = fs_open_file(os_fs(), filename, "wb+"); + if (file != NULL) { + remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_UPLOAD_FILE_BEGIN, REMOTE_UI_DATA_TYPE_NONE, + RET_OK, wb); + } else { + remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_UPLOAD_FILE_BEGIN, REMOTE_UI_DATA_TYPE_NONE, + RET_FAIL, wb); + } + return_value_if_fail(file != NULL, RET_BAD_PARAMS); + + memset(&header, 0x00, sizeof(header)); + while ((ret = remote_ui_service_read_req(ui->io, &header, wb)) == RET_OK) { + if (header.type == REMOTE_UI_REQ_UPLOAD_FILE_DATA) { + len = fs_file_write(file, wb->data, wb->cursor); + ret = (len == wb->cursor) ? RET_OK : RET_FAIL; + remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_UPLOAD_FILE_DATA, REMOTE_UI_DATA_TYPE_NONE, + ret, wb); + break_if_fail(ret == RET_OK); + } else if (header.type == REMOTE_UI_REQ_UPLOAD_FILE_END) { + ret = RET_OK; + ret = remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_UPLOAD_FILE_END, + REMOTE_UI_DATA_TYPE_NONE, ret, wb); + break_if_fail(ret == RET_OK); + break; + } else { + assert(!"impossible"); + ret = RET_FAIL; + remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_UPLOAD_FILE_END, REMOTE_UI_DATA_TYPE_NONE, + ret, wb); + break; + } + } + fs_file_close(file); + + return RET_OK; +} + +static ret_t remote_ui_service_download_file(remote_ui_service_t* ui, const char* filename) { + wbuffer_t wb; + int32_t len = 0; + ret_t ret = RET_OK; + fs_file_t* file = NULL; + uint8_t buff[4096] = {0}; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(filename != NULL, RET_BAD_PARAMS); + + wbuffer_init(&wb, buff, sizeof(buff)); + file = fs_open_file(os_fs(), filename, "rb"); + if (file != NULL) { + remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_DOWNLOAD_FILE_BEGIN, + REMOTE_UI_DATA_TYPE_NONE, RET_OK, &wb); + } else { + remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_DOWNLOAD_FILE_BEGIN, + REMOTE_UI_DATA_TYPE_NONE, RET_FAIL, &wb); + } + return_value_if_fail(file != NULL, RET_BAD_PARAMS); + + while ((len = fs_file_read(file, buff, sizeof(buff))) > 0) { + wbuffer_init(&wb, buff, len); + wb.cursor = len; + ret = remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_DOWNLOAD_FILE_DATA, + REMOTE_UI_DATA_TYPE_BINARY, RET_OK, &wb); + break_if_fail(ret == RET_OK); + } + + wbuffer_rewind(&wb); + ret = remote_ui_service_send_resp(ui->io, REMOTE_UI_RESP_DOWNLOAD_FILE_END, + REMOTE_UI_DATA_TYPE_NONE, ret, &wb); + + fs_file_close(file); + + return RET_OK; +} + +static ret_t remote_ui_service_create_dir(remote_ui_service_t* ui, const char* path) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(path != NULL, RET_BAD_PARAMS); + + return fs_create_dir_r(os_fs(), path); +} + +static ret_t remote_ui_service_remove_dir(remote_ui_service_t* ui, const char* path) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(path != NULL, RET_BAD_PARAMS); + + return fs_remove_dir_r(os_fs(), path); +} + +static ret_t remote_ui_service_remove_file(remote_ui_service_t* ui, const char* filename) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(filename != NULL, RET_BAD_PARAMS); + + return fs_remove_file(os_fs(), filename); +} + +static ret_t remote_ui_service_get_manifest(remote_ui_service_t* ui, str_t* result) { + ret_t ret = RET_OK; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(result != NULL, RET_BAD_PARAMS); + + str_set(result, "todo"); + + /*TODO*/ + return ret; +} + +static ret_t remote_ui_service_take_screen_shot(remote_ui_service_t* ui, const char* filename) { + ret_t ret = RET_OK; + bitmap_t* image = NULL; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(filename != NULL, RET_BAD_PARAMS); + + image = widget_take_snapshot(window_manager()); + if (image != NULL) { + ret = bitmap_save_png(image, filename); + } else { + fs_remove_file(os_fs(), filename); + } + + return ret; +} + +static ret_t remote_ui_service_prepare_manifest(remote_ui_service_t* ui, const char* filename) { + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(filename != NULL, RET_BAD_PARAMS); + + return file_write(filename, "TODO", 5); +} + +static ret_t remote_ui_service_prepare_xml_source(remote_ui_service_t* ui, const char* filename) { + str_t str; + ret_t ret = RET_OK; + widget_t* win = window_manager_get_top_window(window_manager()); + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(filename != NULL, RET_BAD_PARAMS); + + str_init(&str, 10000); + widget_to_xml(win, &str); + ret = file_write(filename, str.str, str.size); + str_reset(&str); + + return ret; +} + +static ret_t remote_ui_service_on_event_func(void* ctx, event_t* e) { + remote_ui_service_t* ui = (remote_ui_service_t*)ctx; + return_value_if_fail(ui != NULL, RET_BAD_PARAMS); + /*TODO*/ + return RET_OK; +} + + +static ret_t remote_ui_service_on_event(remote_ui_service_t* ui, const char* target, uint32_t event) { + widget_t* win = window_manager_get_top_window(window_manager()); + widget_t* widget = widget_find_by_path(win, target, TRUE); + return_value_if_fail(widget != NULL, RET_BAD_PARAMS); + + widget_on(widget, event, remote_ui_service_on_event_func, ui); + + return RET_OK; +} + +static ret_t remote_ui_service_off_event(remote_ui_service_t* ui, const char* target, uint32_t event) { + widget_t* win = window_manager_get_top_window(window_manager()); + widget_t* widget = widget_find_by_path(win, target, TRUE); + return_value_if_fail(widget != NULL, RET_BAD_PARAMS); + + widget_off_by_func(widget, event, remote_ui_service_on_event_func, ui); + + return RET_OK; +} + +static ret_t remote_ui_service_send_event(remote_ui_service_t* ui, const char* target, event_t* event) { + widget_t* win = window_manager_get_top_window(window_manager()); + widget_t* widget = widget_find_by_path(win, target, TRUE); + return_value_if_fail(widget != NULL, RET_BAD_PARAMS); + + switch (event->type) { + case EVT_CLICK: { + event->type = EVT_POINTER_DOWN; + widget_on_pointer_down(widget, pointer_event_cast(event)); + + event->type = EVT_POINTER_UP; + return widget_on_pointer_up(widget, pointer_event_cast(event)); + } + case EVT_POINTER_DOWN: { + return widget_on_pointer_down(widget, pointer_event_cast(event)); + } + case EVT_POINTER_MOVE: { + return widget_on_pointer_move(widget, pointer_event_cast(event)); + } + case EVT_POINTER_UP: { + return widget_on_pointer_up(widget, pointer_event_cast(event)); + } + case EVT_KEY_DOWN: { + return widget_on_keydown(widget, key_event_cast(event)); + } + case EVT_KEY_UP: { + return widget_on_keyup(widget, key_event_cast(event)); + } + default: { + break; + } + } + + return RET_FAIL; +} + +static ret_t remote_ui_service_open_dialog(remote_ui_service_t* ui, const char* type, const char* title, + const char* content, uint32_t duration) { + if (tk_str_eq(type, REMOTE_UI_DIALOG_TYPE_CONFIRM)) { + return dialog_confirm(title, content); + } else if (tk_str_eq(type, REMOTE_UI_DIALOG_TYPE_INFO)) { + return dialog_info(title, content); + } else if (tk_str_eq(type, REMOTE_UI_DIALOG_TYPE_WARN)) { + return dialog_warn(title, content); + } else { + return dialog_toast(content, duration); + } + + return RET_OK; +} + +static ret_t remote_ui_service_open_window(remote_ui_service_t* ui, const char* name, const char* xml, + const char* init_json) { + widget_t* win = NULL; + if (TK_STR_IS_NOT_EMPTY(xml)) { + win = ui_loader_load_widget_from_xml(NULL, xml, strlen(xml)); + } else { + win = window_open(name); + } + + return_value_if_fail(win != NULL, RET_BAD_PARAMS); + + if (init_json != NULL) { + /*TODO*/ + } + + return RET_OK; +} + +static ret_t remote_ui_service_close_window(remote_ui_service_t* ui, const char* name) { + widget_t* win = widget_child(window_manager(), name); + return_value_if_fail(win != NULL, RET_BAD_PARAMS); + + return window_manager_close_window(window_manager(), win); +} + +static ret_t remote_ui_service_back_to_prev(remote_ui_service_t* ui) { + window_manager_back(window_manager()); + + return RET_OK; +} + +static ret_t remote_ui_service_back_to_home(remote_ui_service_t* ui) { + window_manager_back_to_home(window_manager()); + + return RET_OK; +} + +static ret_t remote_ui_service_set_prop(remote_ui_service_t* ui, const char* target, const char* name, + const value_t* value) { + widget_t* win = window_manager_get_top_window(window_manager()); + widget_t* widget = widget_find_by_path(win, target, TRUE); + return_value_if_fail(widget != NULL, RET_BAD_PARAMS); + + return widget_set_prop(widget, name, value); +} + +static ret_t remote_ui_service_get_prop(remote_ui_service_t* ui, const char* target, const char* name, + value_t* value) { + widget_t* win = window_manager_get_top_window(window_manager()); + widget_t* widget = widget_find_by_path(win, target, TRUE); + return_value_if_fail(widget != NULL, RET_BAD_PARAMS); + + return widget_get_prop(widget, name, value); +} + +static ret_t remote_ui_service_set_theme(remote_ui_service_t* ui, const char* theme) { + return widget_set_theme(window_manager(), theme); +} + +static ret_t remote_ui_service_exec_script(remote_ui_service_t* ui, const char* script, value_t* v) { + tk_object_t* obj = object_default_create(); + ret_t ret = fscript_eval(obj, script, v); + TK_OBJECT_UNREF(obj); + + return ret; +} + +static ret_t remote_ui_service_set_language(remote_ui_service_t* ui, const char* language) { + const char* p = NULL; + char lang[TK_NAME_LEN + 1] = {0}; + char country[TK_NAME_LEN + 1] = {0}; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(language != NULL, RET_BAD_PARAMS); + + p = strchr(language, '_'); + if (p != NULL) { + tk_strncpy(lang, language, p - language); + tk_strcpy(country, p + 1); + } else { + tk_strcpy(lang, language); + } + + return locale_info_change(locale_info(), lang, country); +} + +static ret_t remote_ui_dev_info_write(ubjson_writer_t* writer, remote_ui_dev_info_t* info) { + return_value_if_fail(writer != NULL && info != NULL, RET_BAD_PARAMS); + + ubjson_writer_write_object_begin(writer); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_DEV_NAME, info->name); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_DEV_OS, info->os); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_DEV_VERSION, info->version); + ubjson_writer_write_kv_str(writer, REMOTE_UI_KEY_DEV_ARCH, info->arch); + ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_DEV_SCREEN_WIDTH, info->screen_width); + ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_DEV_SCREEN_HEIGHT, info->screen_height); + ubjson_writer_write_kv_int(writer, REMOTE_UI_KEY_DEV_DPI, info->dpi); + ubjson_writer_write_object_end(writer); + + return RET_OK; +} + +static ret_t remote_ui_service_dispatch_impl(remote_ui_service_t* ui, remote_ui_msg_header_t* req, + wbuffer_t* wb) { + value_t v; + char buff[1024] = {0}; + ret_t ret = RET_FAIL; + tk_object_t* obj = NULL; + ubjson_writer_t* writer = NULL; + remote_ui_msg_header_t resp; + char local_file[MAX_PATH + 1] = {0}; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + return_value_if_fail(req != NULL && wb != NULL, RET_BAD_PARAMS); + + memset(&resp, 0x00, sizeof(resp)); + if (req->data_type == REMOTE_UI_DATA_TYPE_UBJSON) { + obj = conf_ubjson_load_from_buff(wb->data, wb->cursor, FALSE); + } + + switch (req->type) { + case REMOTE_UI_REQ_LOGIN: { + const char* username = tk_object_get_prop_str(obj, "username"); + const char* password = tk_object_get_prop_str(obj, "password"); + resp.resp_code = remote_ui_service_login(ui, username, password); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_LOGIN; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_LOGOUT: { + resp.resp_code = remote_ui_service_logout(ui); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_LOGOUT; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_GET_DEV_INFO: { + remote_ui_dev_info_t info; + memset(&info, 0x00, sizeof(info)); + resp.resp_code = remote_ui_service_get_dev_info(ui, &info); + resp.data_type = REMOTE_UI_DATA_TYPE_UBJSON; + resp.type = REMOTE_UI_RESP_GET_DEV_INFO; + writer = remote_ui_service_get_writer(ui); + ret = remote_ui_dev_info_write(writer, &info); + break; + } + case REMOTE_UI_REQ_REBOOT: { + rbuffer_t rb; + uint32_t reboot_type = REMOTE_UI_REBOOT_DEFAULT; + rbuffer_init(&rb, wb->data, wb->cursor); + + rbuffer_read_uint32(&rb, &reboot_type); + resp.resp_code = remote_ui_service_reboot(ui, reboot_type); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_REBOOT; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_UPLOAD_FILE_BEGIN: { + const char* filename = (const char*)(wb->data); + filename = path_prepend_app_root(local_file, filename); + resp.resp_code = remote_ui_service_upload_file(ui, filename); + return RET_OK; + break; + } + case REMOTE_UI_REQ_DOWNLOAD_FILE_BEGIN: { + const char* filename = (const char*)(wb->data); + + if (tk_str_eq(filename, REMOTE_UI_FILE_SCREEN_SHOT)) { + filename = path_prepend_temp_path(local_file, filename); + resp.resp_code = remote_ui_service_take_screen_shot(ui, filename); + } else if (tk_str_eq(filename, REMOTE_UI_FILE_MANIFEST)) { + filename = path_prepend_temp_path(local_file, filename); + resp.resp_code = remote_ui_service_prepare_manifest(ui, filename); + } else if (tk_str_eq(filename, REMOTE_UI_FILE_XML_SOURCE)) { + filename = path_prepend_temp_path(local_file, filename); + resp.resp_code = remote_ui_service_prepare_xml_source(ui, filename); + } else { + filename = path_prepend_app_root(local_file, filename); + } + + resp.resp_code = remote_ui_service_download_file(ui, filename); + return RET_OK; + } + case REMOTE_UI_REQ_CREATE_DIR: { + const char* filename = (const char*)(wb->data); + filename = path_prepend_app_root(local_file, filename); + + resp.resp_code = remote_ui_service_create_dir(ui, filename); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_CREATE_DIR; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_REMOVE_DIR: { + const char* filename = (const char*)(wb->data); + filename = path_prepend_app_root(local_file, filename); + + resp.resp_code = remote_ui_service_remove_dir(ui, filename); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_REMOVE_DIR; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_REMOVE_FILE: { + const char* filename = (const char*)(wb->data); + filename = path_prepend_app_root(local_file, filename); + resp.resp_code = remote_ui_service_remove_file(ui, filename); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_REMOVE_FILE; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_OPEN_WINDOW: { + const char* name = tk_object_get_prop_str(obj, REMOTE_UI_KEY_NAME); + const char* xml = tk_object_get_prop_str(obj, REMOTE_UI_KEY_XML); + const char* init_json = tk_object_get_prop_str(obj, REMOTE_UI_KEY_INIT); + resp.resp_code = remote_ui_service_open_window(ui, name, xml, init_json); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_OPEN_WINDOW; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_OPEN_DIALOG: { + const char* type = tk_object_get_prop_str(obj, REMOTE_UI_KEY_TYPE); + const char* title = tk_object_get_prop_str(obj, REMOTE_UI_KEY_TITLE); + const char* content = tk_object_get_prop_str(obj, REMOTE_UI_KEY_CONTENT); + uint32_t duration = tk_object_get_prop_uint32(obj, REMOTE_UI_KEY_DURATION, 3000); + + resp.resp_code = remote_ui_service_open_dialog(ui, type, title, content, duration); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_OPEN_WINDOW; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_BACK_TO_PREV: { + resp.resp_code = remote_ui_service_back_to_prev(ui); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_BACK_TO_PREV; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_BACK_TO_HOME: { + resp.resp_code = remote_ui_service_back_to_home(ui); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_BACK_TO_HOME; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_CLOSE_WINDOW: { + const char* name = (const char*)(wb->data); + resp.resp_code = remote_ui_service_close_window(ui, name); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_CLOSE_WINDOW; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_SET_PROP: { + value_t v; + const char* target = tk_object_get_prop_str(obj, REMOTE_UI_KEY_TARGET); + const char* name = tk_object_get_prop_str(obj, REMOTE_UI_KEY_NAME); + + if (tk_object_get_prop(obj, REMOTE_UI_KEY_VALUE, &v) == RET_OK) { + resp.resp_code = remote_ui_service_set_prop(ui, target, name, &v); + } else { + resp.resp_code = RET_FAIL; + } + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_GET_PROP: { + const char* str = NULL; + const char* target = tk_object_get_prop_str(obj, REMOTE_UI_KEY_TARGET); + const char* name = tk_object_get_prop_str(obj, REMOTE_UI_KEY_NAME); + + value_set_int(&v, 0); + resp.resp_code = remote_ui_service_get_prop(ui, target, name, &v); + resp.data_type = REMOTE_UI_DATA_TYPE_STRING; + str = value_str_ex(&v, buff, sizeof(buff)); + wbuffer_rewind(wb); + wbuffer_write_string(wb, str); + break; + } + case REMOTE_UI_REQ_SET_LANGUAGE: { + const char* language = (const char*)(wb->data); + resp.resp_code = remote_ui_service_set_language(ui, language); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_SET_LANGUAGE; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_SET_THEME: { + const char* theme = (const char*)(wb->data); + resp.resp_code = remote_ui_service_set_theme(ui, theme); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_SET_THEME; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_EXEC_FSCRIPT: { + const char* script = (const char*)(wb->data); + + value_set_int(&v, 0); + resp.resp_code = remote_ui_service_exec_script(ui, script, &v); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_EXEC_FSCRIPT; + wbuffer_rewind(wb); + wbuffer_write_string(wb, value_str_ex(&v, buff, sizeof(buff))); + + break; + } + case REMOTE_UI_REQ_ON_EVENT: { + const char* target = tk_object_get_prop_str(obj, REMOTE_UI_KEY_TARGET); + uint32_t event_type = tk_object_get_prop_int(obj, REMOTE_UI_KEY_EVENT, 0); + resp.resp_code = remote_ui_service_on_event(ui, target, event_type); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_ON_EVENT; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_OFF_EVENT: { + const char* target = tk_object_get_prop_str(obj, REMOTE_UI_KEY_TARGET); + uint32_t event_type = tk_object_get_prop_int(obj, REMOTE_UI_KEY_EVENT, 0); + resp.resp_code = remote_ui_service_off_event(ui, target, event_type); + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_OFF_EVENT; + wbuffer_rewind(wb); + break; + } + case REMOTE_UI_REQ_SEND_EVENT: { + event_t* e = NULL; + const char* target = tk_object_get_prop_str(obj, REMOTE_UI_KEY_TARGET); + uint32_t event_type = tk_object_get_prop_int(obj, REMOTE_UI_KEY_EVENT, 0); + + switch (event_type) { + case EVT_CLICK: + case EVT_POINTER_DOWN: + case EVT_POINTER_UP: + case EVT_POINTER_MOVE: { + pointer_event_t evt; + int x = tk_object_get_prop_int(obj, REMOTE_UI_KEY_X, 0); + int y = tk_object_get_prop_int(obj, REMOTE_UI_KEY_Y, 0); + e = pointer_event_init(&evt, event_type, NULL, x, y); + break; + } + case EVT_KEY_DOWN: + case EVT_KEY_UP: { + key_event_t evt; + uint32_t key = tk_object_get_prop_int(obj, REMOTE_UI_KEY_CODE, 0); + e = key_event_init(&evt, event_type, NULL, key); + break; + } + default: + break; + } + if (e != NULL) { + resp.resp_code = remote_ui_service_send_event(ui, target, e); + } else { + resp.resp_code = RET_FAIL; + } + resp.data_type = REMOTE_UI_DATA_TYPE_NONE; + resp.type = REMOTE_UI_RESP_SEND_EVENT; + wbuffer_rewind(wb); + break; + } + default: { + ret = RET_NOT_IMPL; + break; + } + } + TK_OBJECT_UNREF(obj); + + return remote_ui_service_send_resp(ui->io, resp.type, resp.data_type, resp.resp_code, wb); +} + +static ret_t remote_ui_service_dispatch(remote_ui_service_t* ui) { + ret_t ret = RET_OK; + remote_ui_msg_header_t header; + return_value_if_fail(ui != NULL && ui->io != NULL, RET_BAD_PARAMS); + + memset(&header, 0x00, sizeof(header)); + ret = remote_ui_service_read_req(ui->io, &header, &(ui->wb)); + return_value_if_fail(ret == RET_OK, ret); + + return remote_ui_service_dispatch_impl(ui, &header, &(ui->wb)); +} + +static ret_t remote_ui_service_destroy(remote_ui_service_t* ui) { + return_value_if_fail(ui != NULL, RET_BAD_PARAMS); + + wbuffer_deinit(&(ui->wb)); + TKMEM_FREE(ui); + + return RET_OK; +} diff --git a/project/gui/awtk/src/remote_ui/service/remote_ui_service.h b/project/gui/awtk/src/remote_ui/service/remote_ui_service.h new file mode 100644 index 00000000..54968c1d --- /dev/null +++ b/project/gui/awtk/src/remote_ui/service/remote_ui_service.h @@ -0,0 +1,82 @@ +/** + * File: remote_ui_service.h + * Author: AWTK Develop Team + * Brief: remote ui service + * + * Copyright (c) 2018 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * License file for more details. + * + */ + +/** + * History: + * ================================================================ + * 2023-11-04 Li XianJing created + * + */ + +#ifndef TK_REMOTE_UI_SERVICE_H +#define TK_REMOTE_UI_SERVICE_H + +#include "tkc/buffer.h" +#include "tkc/darray.h" +#include "tkc/iostream.h" +#include "ubjson/ubjson_writer.h" +#include "service/service.h" +#include "remote_ui/shared/remote_ui_types_def.h" + +BEGIN_C_DECLS + +/** + * @class remote_ui_service_args_t + * remote ui服务端启动参数。 +*/ +typedef struct _remote_ui_service_args_t { + /** + * @property {tk_service_auth_t} auth + * @annotation ["readable"] + * 登陆认证函数。 + */ + tk_service_auth_t auth; +} remote_ui_service_args_t; + +/** + * @class remote_ui_service_t + * remote ui服务端。 +*/ +typedef struct _remote_ui_service_t { + tk_service_t service; + + /** + * @property {tk_iostream_t*} io + * @annotation ["readable"] + * IO stream。 + */ + tk_iostream_t* io; + + /*private*/ + wbuffer_t wb; + ubjson_writer_t writer; + tk_object_t* event_handlers; + bool_t is_login; + tk_service_auth_t auth; +} remote_ui_service_t; + +/** + * @method remote_ui_service_create + * 创建remote ui客户端。 + * + * @param {tk_iostream_t*} io IO流(由service释放)。 + * @param {void*} args 参数。 + * + * @return {tk_service_t*} 返回service对象。 + */ +tk_service_t* remote_ui_service_create(tk_iostream_t* io, void* args); + +END_C_DECLS + +#endif /*TK_REMOTE_UI_SERVICE_H*/ diff --git a/project/gui/awtk/src/remote_ui/shared/remote_ui_types_def.h b/project/gui/awtk/src/remote_ui/shared/remote_ui_types_def.h new file mode 100644 index 00000000..aac731f5 --- /dev/null +++ b/project/gui/awtk/src/remote_ui/shared/remote_ui_types_def.h @@ -0,0 +1,465 @@ +/** + * File: remote_ui_types_def.h + * Author: AWTK Develop Team + * Brief: remote ui types def + * + * Copyright (c) 2018 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * License file for more details. + * + */ + +/** + * History: + * ================================================================ + * 2023-11-04 Li XianJing created + * + */ + +#ifndef TK_REMOTE_UI_TYPES_DEF_H +#define TK_REMOTE_UI_TYPES_DEF_H + +#include "tkc/types_def.h" + +BEGIN_C_DECLS + +/** + * @enum remote_ui_msg_code_t + * @prefix REMOTE_UI_ + * 消息类型。 + * + */ +typedef enum _remote_ui_msg_code_t { + /** + * @const REMOTE_UI_MSG_NONE + * 无效消息。 + */ + REMOTE_UI_MSG_NONE = 0, + /** + * @const REMOTE_UI_REQ_LOGIN + * 登录请求。 + */ + REMOTE_UI_REQ_LOGIN, + /** + * @const REMOTE_UI_REQ_LOGOUT + * 登出请求。 + */ + REMOTE_UI_REQ_LOGOUT, + /** + * @const REMOTE_UI_REQ_GET_DEV_INFO + * 获取设备信息。 + */ + REMOTE_UI_REQ_GET_DEV_INFO, + /** + * @const REMOTE_UI_REQ_REBOOT + * 重新加载请求。 + */ + REMOTE_UI_REQ_REBOOT, + /** + * @const REMOTE_UI_REQ_UPLOAD_FILE_BEGIN + * 上传文件请求开始。 + */ + REMOTE_UI_REQ_UPLOAD_FILE_BEGIN, + /** + * @const REMOTE_UI_REQ_UPLOAD_FILE_DATA + * 上传文件请求数据。 + */ + REMOTE_UI_REQ_UPLOAD_FILE_DATA, + /** + * @const REMOTE_UI_REQ_UPLOAD_FILE_END + * 上传文件请求结束。 + */ + REMOTE_UI_REQ_UPLOAD_FILE_END, + /** + * @const REMOTE_UI_REQ_DOWNLOAD_FILE_BEGIN + * 下载文件请求。 + */ + REMOTE_UI_REQ_DOWNLOAD_FILE_BEGIN, + /** + * @const REMOTE_UI_REQ_CREATE_DIR + * 创建目录请求。 + */ + REMOTE_UI_REQ_CREATE_DIR, + /** + * @const REMOTE_UI_REQ_REMOVE_DIR + * 删除目录请求。 + */ + REMOTE_UI_REQ_REMOVE_DIR, + /** + * @const REMOTE_UI_REQ_REMOVE_FILE + * 删除文件请求。 + */ + REMOTE_UI_REQ_REMOVE_FILE, + /** + * @const REMOTE_UI_REQ_ON_EVENT + * 注册事件请求。 + */ + REMOTE_UI_REQ_ON_EVENT, + /** + * @const REMOTE_UI_REQ_OFF_EVENT + * 注销事件请求。 + */ + REMOTE_UI_REQ_OFF_EVENT, + /** + * @const REMOTE_UI_REQ_SEND_EVENT + * 发送事件请求。 + */ + REMOTE_UI_REQ_SEND_EVENT, + /** + * @const REMOTE_UI_REQ_OPEN_WINDOW + * 打开窗口请求。 + */ + REMOTE_UI_REQ_OPEN_WINDOW, + /** + * @const REMOTE_UI_REQ_OPEN_DIALOG + * 打开基本对话框请求。 + */ + REMOTE_UI_REQ_OPEN_DIALOG, + /** + * @const REMOTE_UI_REQ_CLOSE_WINDOW + * 关闭窗口请求。 + */ + REMOTE_UI_REQ_CLOSE_WINDOW, + /** + * @const REMOTE_UI_REQ_BACK_TO_PREV + * 返回请求。 + */ + REMOTE_UI_REQ_BACK_TO_PREV, + /** + * @const REMOTE_UI_REQ_BACK_TO_HOME + * 返回主页请求。 + */ + REMOTE_UI_REQ_BACK_TO_HOME, + /** + * @const REMOTE_UI_REQ_SET_PROP + * 设置属性请求。 + */ + REMOTE_UI_REQ_SET_PROP, + /** + * @const REMOTE_UI_REQ_GET_PROP + * 获取属性请求。 + */ + REMOTE_UI_REQ_GET_PROP, + /** + * @const REMOTE_UI_REQ_SET_THEME + * 设置主题请求。 + */ + REMOTE_UI_REQ_SET_THEME, + /** + * @const REMOTE_UI_REQ_SET_LANGUAGE + * 设置语言请求。 + */ + REMOTE_UI_REQ_SET_LANGUAGE, + /** + * @const REMOTE_UI_REQ_GET_XML_SOURCE + * 获取xml源码请求。 + */ + REMOTE_UI_REQ_GET_XML_SOURCE, + /** + * @const REMOTE_UI_REQ_EXEC_FSCRIPT + * 执行脚本请求。 + */ + REMOTE_UI_REQ_EXEC_FSCRIPT, + + /** + * @const REMOTE_UI_RESP_LOGIN + * 登录响应。 + */ + REMOTE_UI_RESP_LOGIN, + /** + * @const REMOTE_UI_RESP_LOGOUT + * 登出响应。 + */ + REMOTE_UI_RESP_LOGOUT, + /** + * @const REMOTE_UI_RESP_GET_DEV_INFO + * 获取设备信息响应。 + */ + REMOTE_UI_RESP_GET_DEV_INFO, + /** + * @const REMOTE_UI_RESP_REBOOT + * 重新加载响应。 + */ + REMOTE_UI_RESP_REBOOT, + /** + * @const REMOTE_UI_RESP_UPLOAD_FILE_BEGIN + * 上传文件开始响应。 + */ + REMOTE_UI_RESP_UPLOAD_FILE_BEGIN, + /** + * @const REMOTE_UI_RESP_UPLOAD_FILE_DATA + * 上传文件数据响应。 + */ + REMOTE_UI_RESP_UPLOAD_FILE_DATA, + /** + * @const REMOTE_UI_RESP_UPLOAD_FILE_END + * 上传文件结束响应。 + */ + REMOTE_UI_RESP_UPLOAD_FILE_END, + /** + * @const REMOTE_UI_RESP_DOWNLOAD_FILE_BEGIN + * 下载文件开始响应。 + */ + REMOTE_UI_RESP_DOWNLOAD_FILE_BEGIN, + /** + * @const REMOTE_UI_RESP_DOWNLOAD_FILE_DATA + * 下载文件数据响应。 + */ + REMOTE_UI_RESP_DOWNLOAD_FILE_DATA, + /** + * @const REMOTE_UI_RESP_DOWNLOAD_FILE_END + * 下载文件数据响应。 + */ + REMOTE_UI_RESP_DOWNLOAD_FILE_END, + /** + * @const REMOTE_UI_RESP_CREATE_DIR + * 创建目录响应。 + */ + REMOTE_UI_RESP_CREATE_DIR, + /** + * @const REMOTE_UI_RESP_REMOVE_DIR + * 删除目录响应。 + */ + REMOTE_UI_RESP_REMOVE_DIR, + /** + * @const REMOTE_UI_RESP_REMOVE_FILE + * 删除文件响应。 + */ + REMOTE_UI_RESP_REMOVE_FILE, + /** + * @const REMOTE_UI_RESP_ON_EVENT + * 注册事件响应。 + */ + REMOTE_UI_RESP_ON_EVENT, + /** + * @const REMOTE_UI_RESP_OFF_EVENT + * 注销事件响应。 + */ + REMOTE_UI_RESP_OFF_EVENT, + /** + * @const REMOTE_UI_RESP_SEND_EVENT + * 发送事件响应。 + */ + REMOTE_UI_RESP_SEND_EVENT, + /** + * @const REMOTE_UI_RESP_OPEN_WINDOW + * 打开窗口响应。 + */ + REMOTE_UI_RESP_OPEN_WINDOW, + /** + * @const REMOTE_UI_RESP_OPEN_DIALOG + * 打开基本对话框响应。 + */ + REMOTE_UI_RESP_OPEN_DIALOG, + /** + * @const REMOTE_UI_RESP_CLOSE_WINDOW + * 关闭窗口响应。 + */ + REMOTE_UI_RESP_CLOSE_WINDOW, + /** + * @const REMOTE_UI_RESP_BACK_TO_PREV + * 返回响应。 + */ + REMOTE_UI_RESP_BACK_TO_PREV, + /** + * @const REMOTE_UI_RESP_BACK_TO_HOME + * 返回主页响应。 + */ + REMOTE_UI_RESP_BACK_TO_HOME, + /** + * @const REMOTE_UI_RESP_SET_PROP + * 设置属性响应。 + */ + REMOTE_UI_RESP_SET_PROP, + /** + * @const REMOTE_UI_RESP_GET_PROP + * 获取属性响应。 + */ + REMOTE_UI_RESP_GET_PROP, + /** + * @const REMOTE_UI_RESP_SET_THEME + * 设置主题响应。 + */ + REMOTE_UI_RESP_SET_THEME, + /** + * @const REMOTE_UI_RESP_SET_LANGUAGE + * 设置语言响应。 + */ + REMOTE_UI_RESP_SET_LANGUAGE, + /** + * @const REMOTE_UI_RESP_GET_XML_SOURCE + * 获取xml源码响应。 + */ + REMOTE_UI_RESP_GET_XML_SOURCE, + /** + * @const REMOTE_UI_RESP_EXEC_FSCRIPT + * 执行脚本响应。 + */ + REMOTE_UI_RESP_EXEC_FSCRIPT, + /** + * @const REMOTE_UI_NOTIFY + * 事件通知。 + */ + REMOTE_UI_NOTIFY, +} remote_ui_msg_code_t; + +/** + * @enum remote_ui_data_type_t + * @prefix REMOTE_UI_DATA_TYPE_ + * 数据类型。 +*/ +typedef enum _remote_ui_data_type_t { + /** + * @const REMOTE_UI_DATA_TYPE_NONE + * 无效数据类型。 + */ + REMOTE_UI_DATA_TYPE_NONE = 0, + /** + * @const REMOTE_UI_DATA_TYPE_UBJSON + * JSON数据类型。 + */ + REMOTE_UI_DATA_TYPE_UBJSON, + /** + * @const REMOTE_UI_DATA_TYPE_STRING + * 字符串数据类型。 + */ + REMOTE_UI_DATA_TYPE_STRING, + /** + * @const REMOTE_UI_DATA_TYPE_BINARY + * 二进制数据类型。 + */ + REMOTE_UI_DATA_TYPE_BINARY +} remote_ui_data_type_t; + +/** + * @class remote_ui_msg_header_t + * 消息头。 +*/ +typedef struct _remote_ui_msg_header_t { + /** + * @property {uint32_t} size + * 消息体的大小。 + */ + uint32_t size; + /** + * @property {uint16_t} type + * 消息类型。 + */ + uint16_t type; + /** + * @property {uint8_t} data_type + * 数据类型。 + */ + uint8_t data_type; + /** + * @property {uint8_t} resp_code + * 响应码(仅适用于resp)。 + */ + uint8_t resp_code; +} remote_ui_msg_header_t; + +/** + * @class remote_ui_dev_info_t + * 设备信息。 +*/ +typedef struct _remote_ui_dev_info_t { + /** + * @property {char*} name + * 设备名称。 + */ + char name[64]; + /** + * @property {char*} version + * 设备版本。 + */ + char version[64]; + /** + * @property {char*} os + * 操作系统。 + */ + char os[16]; + + /** + * @property {char*} arch + * CPU架构。 + */ + char arch[16]; + + /** + * @property {uint32_t} screen_width + * 屏幕宽度。 + */ + uint32_t screen_width; + /** + * @property {uint32_t} screen_height + * 屏幕高度。 + */ + uint32_t screen_height; + /** + * @property {uint32_t} dpi + * 屏幕DPI。 + */ + uint32_t dpi; +} remote_ui_dev_info_t; + +/** + * @enum remote_ui_reboot_type_t + * @prefix REMOTE_UI_REBOOT_ + * 重启类型。 +*/ +typedef enum _remote_ui_reboot_type_t { + /** + * @const REMOTE_UI_REBOOT_DEFAULT + * 重启。 + */ + REMOTE_UI_REBOOT_DEFAULT = 0, + /** + * @const REMOTE_UI_REBOOT_RELOAD + * 重新加载。 + */ + REMOTE_UI_REBOOT_RELOAD, + /** + * @const REMOTE_UI_REBOOT_POWEROFF + * 关机。 + */ + REMOTE_UI_REBOOT_POWEROFF +} remote_ui_reboot_type_t; + +#define REMOTE_UI_KEY_USERNAME "username" +#define REMOTE_UI_KEY_PASSWORD "password" + +#define REMOTE_UI_KEY_DEV_NAME "dev_name" +#define REMOTE_UI_KEY_DEV_OS "dev_os" +#define REMOTE_UI_KEY_DEV_ARCH "dev_arch" +#define REMOTE_UI_KEY_DEV_VERSION "dev_version" +#define REMOTE_UI_KEY_DEV_SCREEN_WIDTH "dev_screen_width" +#define REMOTE_UI_KEY_DEV_SCREEN_HEIGHT "dev_screen_height" +#define REMOTE_UI_KEY_DEV_DPI "dev_dpi" +#define REMOTE_UI_KEY_TARGET "target" +#define REMOTE_UI_KEY_NAME "name" +#define REMOTE_UI_KEY_VALUE "value" +#define REMOTE_UI_KEY_EVENT "event" +#define REMOTE_UI_KEY_XML "xml" +#define REMOTE_UI_KEY_INIT "init" +#define REMOTE_UI_KEY_X "x" +#define REMOTE_UI_KEY_Y "y" +#define REMOTE_UI_KEY_CODE "code" +#define REMOTE_UI_KEY_TYPE "type" +#define REMOTE_UI_KEY_TITLE "title" +#define REMOTE_UI_KEY_CONTENT "content" +#define REMOTE_UI_KEY_DURATION "duration" +#define REMOTE_UI_FILE_MANIFEST "__manifest__.txt" +#define REMOTE_UI_FILE_XML_SOURCE "__xml_source__.xml" +#define REMOTE_UI_FILE_SCREEN_SHOT "__screen_shot__.png" + +#define REMOTE_UI_DIALOG_TYPE_CONFIRM "confirm" +#define REMOTE_UI_DIALOG_TYPE_WARN "warn" +#define REMOTE_UI_DIALOG_TYPE_INFO "info" +#define REMOTE_UI_DIALOG_TYPE_TOAST "toast" + +END_C_DECLS + +#endif /*TK_REMOTE_UI_TYPES_DEF_H*/ diff --git a/project/gui/awtk/src/service/Makefile b/project/gui/awtk/src/service/Makefile new file mode 100644 index 00000000..2da17fb2 --- /dev/null +++ b/project/gui/awtk/src/service/Makefile @@ -0,0 +1 @@ +obj-y += service.o diff --git a/project/gui/awtk/src/service/service.c b/project/gui/awtk/src/service/service.c new file mode 100644 index 00000000..638a30cc --- /dev/null +++ b/project/gui/awtk/src/service/service.c @@ -0,0 +1,147 @@ +/** + * File: service.h + * Author: AWTK Develop Team + * Brief: service interface + * + * Copyright (c) 2018 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * License file for more details. + * + */ + +/** + * History: + * ================================================================ + * 2023-11-05 Li XianJing created + * + */ +#include "tkc/url.h" +#include "tkc/utils.h" +#include "service/service.h" +#include "tkc/event_source_fd.h" +#include "streams/inet/iostream_tcp.h" +#include "streams/serial/iostream_serial.h" + +#include "tkc/socket_helper.h" + +ret_t tk_service_dispatch(tk_service_t* service) { + return_value_if_fail(service != NULL && service->dispatch != NULL, RET_BAD_PARAMS); + + return service->dispatch(service); +} + +ret_t tk_service_destroy(tk_service_t* service) { + return_value_if_fail(service != NULL && service->destroy != NULL, RET_BAD_PARAMS); + + return service->destroy(service); +} + +static ret_t tk_service_on_data(event_source_t* source) { + event_source_fd_t* event_source_fd = (event_source_fd_t*)source; + tk_service_t* service = (tk_service_t*)(event_source_fd->ctx); + + if (tk_service_dispatch(service) != RET_OK) { + tk_service_destroy(service); + log_debug("client disconnected\n"); + return RET_REMOVE; + } else { + return RET_OK; + } +} + +static ret_t tk_service_tcp_on_client(event_source_t* source) { + event_source_fd_t* event_source_fd = (event_source_fd_t*)source; + tk_service_create_t create = (tk_service_create_t)(event_source_fd->ctx); + + int listen_sock = event_source_get_fd(source); + int sock = tcp_accept(listen_sock); + + if (sock >= 0) { + log_debug("client connected:%d\n", sock); + tk_iostream_t* io = tk_iostream_tcp_create(sock); + if (io != NULL) { + tk_service_t* service = create(io, event_source_fd->ctx2); + if (service != NULL) { + event_source_manager_t* esm = source->manager; + event_source_t* client_source = event_source_fd_create(sock, tk_service_on_data, service); + event_source_manager_add(esm, client_source); + TK_OBJECT_UNREF(client_source); + } else { + TK_OBJECT_UNREF(io); + } + } else { + log_debug("oom! disconnected:%d\n", sock); + tk_socket_close(sock); + } + } else { + log_debug("error disconnected:%d\n", sock); + tk_socket_close(sock); + } + + return RET_OK; +} + +static ret_t tk_service_start_tcp(event_source_manager_t* esm, const char* url, + tk_service_create_t create, void* args) { + int port = 0; + int listen_sock = -1; + event_source_t* source = NULL; + url_t* aurl = url_create(url); + return_value_if_fail(esm != NULL && aurl != NULL && create != NULL, RET_BAD_PARAMS); + + port = aurl->port; + listen_sock = tcp_listen(port); + url_destroy(aurl); + return_value_if_fail(listen_sock >= 0, RET_BAD_PARAMS); + + log_debug("listen on %d listen_sock=%d\n", port, listen_sock); + + source = event_source_fd_create(listen_sock, tk_service_tcp_on_client, create); + return_value_if_fail(source != NULL, RET_OOM); + EVENT_SOURCE_FD(source)->ctx2 = args; + event_source_manager_add(esm, source); + OBJECT_UNREF(source); + log_debug("service start: %s\n", url); + + return RET_OK; +} + +static ret_t tk_service_start_serial(event_source_manager_t* esm, const char* url, + tk_service_create_t create, void* args) { + tk_iostream_t* io = NULL; + tk_service_t* service = NULL; + return_value_if_fail(esm != NULL && create != NULL, RET_BAD_PARAMS); + + io = tk_iostream_serial_create_ex(url); + return_value_if_fail(io != NULL, RET_BAD_PARAMS); + + service = create(io, args); + if (service != NULL) { + int fd = tk_object_get_prop_int(TK_OBJECT(io), TK_STREAM_PROP_FD, -1); + event_source_t* client_source = event_source_fd_create(fd, tk_service_on_data, service); + event_source_manager_add(esm, client_source); + TK_OBJECT_UNREF(client_source); + log_debug("service start: %s\n", url); + } else { + TK_OBJECT_UNREF(io); + } + + return RET_OK; +} + +ret_t tk_service_start(event_source_manager_t* esm, const char* url, tk_service_create_t create, + void* args) { + return_value_if_fail(esm != NULL && create != NULL, RET_BAD_PARAMS); + + if (tk_str_start_with(url, STR_SCHEMA_TCP)) { + return tk_service_start_tcp(esm, url, create, args); + } else if (tk_str_start_with(url, STR_SCHEMA_SERIAL)) { + return tk_service_start_serial(esm, url, create, args); + } else { + log_debug("not supported: %s\n", url); + return RET_NOT_IMPL; + } +} diff --git a/project/gui/awtk/src/service/service.h b/project/gui/awtk/src/service/service.h new file mode 100644 index 00000000..5fa4a391 --- /dev/null +++ b/project/gui/awtk/src/service/service.h @@ -0,0 +1,86 @@ +/** + * File: service.h + * Author: AWTK Develop Team + * Brief: service interface + * + * Copyright (c) 2018 - 2023 Guangzhou ZHIYUAN Electronics Co.,Ltd. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * License file for more details. + * + */ + +/** + * History: + * ================================================================ + * 2023-11-05 Li XianJing created + * + */ + +#ifndef TK_SERVICE_H +#define TK_SERVICE_H + +#include "tkc/iostream.h" +#include "tkc/event_source_manager.h" + +BEGIN_C_DECLS + +struct _tk_service_t; +typedef struct _tk_service_t tk_service_t; + +typedef tk_service_t* (*tk_service_create_t)(tk_iostream_t* io, void* args); +typedef ret_t (*tk_service_dispatch_t)(tk_service_t* service); +typedef ret_t (*tk_service_destroy_t)(tk_service_t* service); + +typedef ret_t (*tk_service_auth_t)(tk_service_t* service, const char* username, + const char* password); + +/** + * @class tk_service_t + * 服务接口。 + */ +struct _tk_service_t { + tk_service_dispatch_t dispatch; + tk_service_destroy_t destroy; + tk_iostream_t* io; +}; + +/** + * @method tk_service_dispatch + * 处理服务器请求。 + * + * @param {tk_service_t*} service 服务对象。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t tk_service_dispatch(tk_service_t* service); + +/** + * @method tk_service_destroy + * 销毁服务对象。 + * + * @param {tk_service_t*} service 服务对象。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t tk_service_destroy(tk_service_t* service); + +/** + * @method tk_service_start + * 启动服务。 + * + * @param {event_source_manager_t*} esm 事件源管理器。 + * @param {const char*} url 服务地址。 + * @param {tk_service_create_t} create 创建服务对象的函数。 + * @param {void*} args 参数。 + * + * @return {ret_t} 返回RET_OK表示成功,否则表示失败。 + */ +ret_t tk_service_start(event_source_manager_t* esm, const char* url, tk_service_create_t create, + void* args); + +END_C_DECLS + +#endif /*TK_SERVICE_H*/ diff --git a/project/gui/awtk/src/tkc/utils.c b/project/gui/awtk/src/tkc/utils.c index 4bd43c4b..27a2a47f 100644 --- a/project/gui/awtk/src/tkc/utils.c +++ b/project/gui/awtk/src/tkc/utils.c @@ -1,4 +1,4 @@ -/** +/** * File: utils.h * Author: AWTK Develop Team * Brief: utils struct and utils functions. diff --git a/project/gui/awtk/src/widgets/edit.c b/project/gui/awtk/src/widgets/edit.c index 2a43461b..853e410b 100644 --- a/project/gui/awtk/src/widgets/edit.c +++ b/project/gui/awtk/src/widgets/edit.c @@ -2043,7 +2043,11 @@ widget_t* edit_create_ex(widget_t* parent, const widget_vtable_t* vt, xy_t x, xy wstr_init(&(edit->last_changed_text), 0); widget_set_text(widget, L""); wstr_init(&(edit->saved_text), 0); + + edit->model->ignore_layout = TRUE; edit_set_password_visible(widget, FALSE); + edit->model->ignore_layout = FALSE; + edit_set_action_text(widget, ACTION_TEXT_DONE); return widget; diff --git a/project/gui/lvgl/src/misc/lv_types.h b/project/gui/lvgl/src/misc/lv_types.h index ee263c4f..ecfc12d9 100644 --- a/project/gui/lvgl/src/misc/lv_types.h +++ b/project/gui/lvgl/src/misc/lv_types.h @@ -36,6 +36,7 @@ extern "C" { #define LV_OS_PTHREAD 1 #define LV_OS_FREERTOS 2 #define LV_OS_CMSIS_RTOS2 3 +#define LV_OS_RTTHREAD 4 #define LV_OS_CUSTOM 255 #define LV_STDLIB_BUILTIN 0 diff --git a/project/gui/lvgl/src/osal/Makefile b/project/gui/lvgl/src/osal/Makefile index efdafa99..12001a00 100644 --- a/project/gui/lvgl/src/osal/Makefile +++ b/project/gui/lvgl/src/osal/Makefile @@ -2,3 +2,4 @@ obj-y += lv_cmsis_rtos2.o obj-y += lv_freertos.o obj-y += lv_pthread.o obj-y += lv_os_none.o +obj-y += lv_rtthread.o diff --git a/project/gui/lvgl/src/osal/lv_os.h b/project/gui/lvgl/src/osal/lv_os.h index 488686a7..2b007af1 100644 --- a/project/gui/lvgl/src/osal/lv_os.h +++ b/project/gui/lvgl/src/osal/lv_os.h @@ -30,6 +30,8 @@ extern "C" { #include "lv_freertos.h" #elif LV_USE_OS == LV_OS_CMSIS_RTOS2 #include "lv_cmsis_rtos2.h" +#elif LV_USE_OS == LV_OS_RTTHREAD +#include "lv_rtthread.h" #elif LV_USE_OS == LV_OS_CUSTOM #include LV_OS_CUSTOM_INCLUDE #endif diff --git a/project/gui/lvgl/src/osal/lv_rtthread.c b/project/gui/lvgl/src/osal/lv_rtthread.c new file mode 100644 index 00000000..956cbd2a --- /dev/null +++ b/project/gui/lvgl/src/osal/lv_rtthread.c @@ -0,0 +1,184 @@ +/** + * @file lv_rtthread.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include "lv_os.h" + +#if LV_USE_OS == LV_OS_RTTHREAD + +#include "../misc/lv_log.h" + +/********************* + * DEFINES + *********************/ + +#define THREAD_TIMESLICE 20U + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +lv_result_t lv_thread_init(lv_thread_t * thread, lv_thread_prio_t prio, void (*callback)(void *), size_t stack_size, + void * user_data) +{ + thread->thread = rt_thread_create("thread", + callback, + user_data, + stack_size, + prio, + THREAD_TIMESLICE); + rt_err_t ret = rt_thread_startup(thread->thread); + if(ret) { + LV_LOG_WARN("Error: %d", ret); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +lv_result_t lv_thread_delete(lv_thread_t * thread) +{ + rt_err_t ret = rt_thread_delete(thread->thread); + if(ret) { + LV_LOG_WARN("Error: %d", ret); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +lv_result_t lv_mutex_init(lv_mutex_t * mutex) +{ + mutex->mutex = rt_mutex_create("mutex", RT_IPC_FLAG_PRIO); + if(mutex->mutex == RT_NULL) { + LV_LOG_WARN("create mutex failed"); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +lv_result_t lv_mutex_lock(lv_mutex_t * mutex) +{ + rt_err_t ret = rt_mutex_take(mutex->mutex, RT_WAITING_NO); + if(ret) { + LV_LOG_WARN("Error: %d", ret); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex) +{ + rt_err_t ret = rt_mutex_take(mutex->mutex, RT_WAITING_FOREVER); + if(ret) { + LV_LOG_WARN("Error: %d", ret); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +lv_result_t lv_mutex_unlock(lv_mutex_t * mutex) +{ + rt_err_t ret = rt_mutex_release(mutex->mutex); + if(ret) { + LV_LOG_WARN("Error: %d", ret); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +lv_result_t lv_mutex_delete(lv_mutex_t * mutex) +{ + rt_err_t ret = rt_mutex_delete(mutex->mutex); + if(ret) { + LV_LOG_WARN("Error: %d", ret); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync) +{ + sync->sem = rt_sem_create("sem", RT_IPC_FLAG_PRIO); + if(sync->sem == RT_NULL) { + LV_LOG_WARN("create semaphore failed"); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync) +{ + rt_err_t ret = rt_sem_take(sync->sem, RT_WAITING_FOREVER); + if(ret) { + LV_LOG_WARN("Error: %d", ret); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync) +{ + rt_err_t ret = rt_sem_release(sync->sem); + if(ret) { + LV_LOG_WARN("Error: %d", ret); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) +{ + rt_err_t ret = rt_sem_delete(sync->sem); + if(ret) { + LV_LOG_WARN("Error: %d", ret); + return LV_RESULT_INVALID; + } + else { + return LV_RESULT_OK; + } +} + +/********************** + * STATIC FUNCTIONS + **********************/ + +#endif /*LV_USE_OS == LV_OS_RTTHREAD*/ diff --git a/project/gui/lvgl/src/osal/lv_rtthread.h b/project/gui/lvgl/src/osal/lv_rtthread.h new file mode 100644 index 00000000..255a47af --- /dev/null +++ b/project/gui/lvgl/src/osal/lv_rtthread.h @@ -0,0 +1,54 @@ +/** + * @file lv_rtthread.h + * + */ + +#ifndef LV_RTTHREAD_H +#define LV_RTTHREAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +/********************* + * INCLUDES + *********************/ +#if LV_USE_OS == LV_OS_RTTHREAD + +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ +typedef struct { + rt_thread_t thread; +} lv_thread_t; + +typedef struct { + rt_mutex_t mutex; +} lv_mutex_t; + +typedef struct { + rt_sem_t sem; +} lv_thread_sync_t; + +/********************** + * GLOBAL PROTOTYPES + **********************/ + +/********************** + * MACROS + **********************/ + +#endif /*LV_USE_OS == LV_OS_RTTHREAD*/ + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_RTTHREAD_H*/