From ac089c602ea0295b131a5ee924a786aafc5713eb Mon Sep 17 00:00:00 2001 From: gb <741021719@qq.com> Date: Thu, 8 Feb 2024 17:33:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0UTF8=E5=AD=97=E7=AC=A6?= =?UTF-8?q?=E5=88=86=E5=89=B2=E7=AE=97=E6=B3=95=EF=BC=9B=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=8D=95=E5=B7=A5=E7=AE=A1=E9=81=93=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sdk/base/ui.cpp | 153 +++++++++++++++++++++++++++++++++++++++++++++ sdk/base/utils.cpp | 95 ++++++++++++++++++++++++++++ sdk/base/utils.h | 25 ++++++++ ui/dev_menu.cpp | 50 +++++++-------- ui/font.cpp | 4 +- xmake.lua | 4 +- 6 files changed, 303 insertions(+), 28 deletions(-) diff --git a/sdk/base/ui.cpp b/sdk/base/ui.cpp index e2f415e..a254bf7 100644 --- a/sdk/base/ui.cpp +++ b/sdk/base/ui.cpp @@ -10,6 +10,159 @@ // ipc class namespace devui { + class pipe_reader : public refer + { + std::string pipe_path_; + int fd_ = -1; + safe_thread worker_; + volatile bool run_ = true; + std::function handler_; + + void worker(void) + { + uint8_t buf[512] = {0}; + + while(run_) + { + int len = read(fd_, buf, sizeof(buf)); + if(len == -1) + break; + + handler_(buf, len); + } + } + + public: + pipe_reader(const char* fifo, std::function h) : pipe_path_(fifo), handler_(h) + { + auto r = [this](void) -> void + { + int cycle = 0; + while(run_) + { + fd_ = ::open(pipe_path_.c_str(), O_RDONLY); + utils::to_log(LOG_LEVEL_ALL, "open pipe_reader(%s) %d times = %d\n", ++cycle, fd_); + if(fd_ != -1) + { + worker(); + if(fd_ != -1) + { + ::close(fd_); + fd_ = -1; + } + } + } + }; + + worker_.start(r, "worker", (void*)&pipe_reader::worker); + } + protected: + virtual ~pipe_reader() + { + stop(); + } + + public: + bool is_ready(void) + { + return fd_ != -1; + } + void stop(void) + { + run_ = false; + if(fd_ != -1) + { + int fd = fd_; + fd_ = -1; + ::close(fd); + } + } + }; + class pipe_sender : public refer + { + std::string pipe_path_; + int fd_ = -1; + safe_thread worker_; + volatile bool run_ = true; + safe_fifo sent_que_; + + void worker(void) + { + while(run_) + { + std::string cont(""); + if(sent_que_.take(cont, true)) + { + int s = 0, off = 0; + do + { + s = write(fd_, cont.c_str() + off, cont.length() - off); + if(s == -1) + { + utils::to_log(LOG_LEVEL_FATAL, "Send UI message failed: %d(%s)\n", errno, strerror(errno)); + break; + } + off += s; + }while(off < cont.length()); + if(s == -1) + break; + } + } + } + + public: + pipe_sender(const char* fifo) : pipe_path_(fifo), sent_que_("sent-que") + { + sent_que_.enable_wait_log(false); + + auto r = [this](void) -> void + { + int cycle = 0; + while(run_) + { + fd_ = ::open(pipe_path_.c_str(), O_WRONLY); + utils::to_log(LOG_LEVEL_ALL, "open pipe_sender(%s) %d times = %d\n", ++cycle, fd_); + if(fd_ != -1) + { + worker(); + if(fd_ != -1) + { + ::close(fd_); + fd_ = -1; + } + } + } + }; + + worker_.start(r, "worker", (void*)&pipe_sender::worker); + } + protected: + virtual ~pipe_sender() + { + stop(); + } + + public: + bool is_ready(void) + { + return fd_ != -1; + } + void stop(void) + { + run_ = false; + if(fd_ != -1) + { + int fd = fd_; + fd_ = -1; + ::close(fd); + } + } + void send(std::string& msg) + { + sent_que_.save(msg, true); + } + }; + class ui_messenger { std::function cb_; diff --git a/sdk/base/utils.cpp b/sdk/base/utils.cpp index b7e9420..67ae266 100644 --- a/sdk/base/utils.cpp +++ b/sdk/base/utils.cpp @@ -549,6 +549,101 @@ namespace utils } #endif + int parse_utf8_char(const char*& str, char ch[]) + { + uint8_t first = *str, ind = 0; + int ret = EINVAL; + + if(first < 0x80) + { + ret = 0; + ch[ind++] = *str++; + } + else if(first >= 0x0c00) + { + ret = 0; + first &= 0x0fc; + while(first & 0x80) + { + ch[ind] = str[ind]; + if(ch[ind] == 0) + { + ret = ENODATA; + break; + } + ind++; + first <<= 1; + } + if(ret == 0) + str += ind; + + } + ch[ind++] = 0; + + return ret; + } + int utf16_2_8(unsigned short* &in, char ch[]) + { + int len = 0; + int ret = 0, used = 0; + + if(in[0] >= 0 && in[0] <= 0x7f) + { + ch[len++] = *in++; + } + else if(in[0] >= 0x0dc00 && in[0] <= 0x0dfff) + { + ret = EINVAL; + } + else + { + unsigned int val = in[0]; + if(in[0] >= 0x0d800 && in[0] <= 0x0dbff) + { + if(in[1] < 0x0dc00 || in[1] > 0x0dfff) + ret = EINVAL; + else + { + used = 1; + val = 0x10000 + (((val & 0x3ff) << 10) | (in[1] & 0x3ff)); + } + } + if(ret == 0) + { + static unsigned char lead[] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + char *ptr = ch; + + used++; + len = 4; + if(val < 0x80) + len = 1; + else if(val < 0x800) + len = 2; + else if(val < 0x10000) + len = 3; + ptr += len; + switch(len) + { + case 4: + *--ptr = (val | 0x80) & 0x0bf; + val >>= 6; + case 3: + *--ptr = (val | 0x80) & 0x0bf; + val >>= 6; + case 2: + *--ptr = (val | 0x80) & 0x0bf; + val >>= 6; + case 1: + *--ptr = val | lead[len]; + } + } + } + ch[len++] = 0; + in += used; + + return ret; + } + std::string get_command_result(const char* cmd, int len, int *err) { std::string result(""); diff --git a/sdk/base/utils.h b/sdk/base/utils.h index 6353505..2562157 100644 --- a/sdk/base/utils.h +++ b/sdk/base/utils.h @@ -37,6 +37,31 @@ namespace utils std::string utf82ansi(const char* utf8); std::string ansi2utf8(const char* ansi); + // Function: parse ONE character from a utf8 string + // + // Parameters: str - [in]: head of utf8 string + // + // [out]: beginning of the next character if success or no changes on failure + // + // ch - to receive the character, at least 8 bytes + // + // Return: 0 - success + // EINVAL - invalid utf8 string + // ENODATA - need more data + int parse_utf8_char(const char*& str, char ch[8]); + + // Function: transfere from utf16 to utf8 + // + // Parameters: in - [in]: head of utf16 beginning + // + // [out]: beginning of the next character if success or no changes on failure + // ch - to receive the character, at least 8 bytes + // + // Return: 0 - success + // EINVAL - invalid utf8 string + // ENODATA - need more data + int utf16_2_8(unsigned short* &in, char ch[8]); + std::string get_command_result(const char* cmd, int len = -1, int *err = nullptr); std::string get_local_data_path(void); std::string temporary_path(void); diff --git a/ui/dev_menu.cpp b/ui/dev_menu.cpp index 985f416..0b3757b 100644 --- a/ui/dev_menu.cpp +++ b/ui/dev_menu.cpp @@ -249,30 +249,30 @@ namespace menu_command static std::string command_string(int cmd) { - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_CANCEL); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SEPARATE_LOW); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SEPARATE_MID); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SEPARATE_HIGH); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_NEVER); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_IMMEDIATELY); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_5MIN); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_10MIN); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_20MIN); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_30MIN); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_1H); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_2H); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SLEEP_4H); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_LIFTER_LOW); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_LIFTER_MID); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_LIFTER_HIGH); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_COUNT_MODE); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_HANDLE_MODE); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_CLEAR_PASSWAY); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_GET_HISTORY_COUNT); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_CLEAR_ROLLER_CNT); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_GET_ROLLER_COUNT); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_SHUTDOWN); - RETURN_ENUM_STR(cmd, menu_command::MENU_CMD_ID_WELCOME); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_CANCEL); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_SEPARATE_LOW); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_SEPARATE_MID); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_SEPARATE_HIGH); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_SLEEP_NEVER); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_SLEEP_IMMEDIATELY); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_SLEEP_5MIN); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_SLEEP_10MIN); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_SLEEP_20MIN); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_SLEEP_30MIN); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_SLEEP_1H); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_SLEEP_2H); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_SLEEP_4H); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_LIFTER_LOW); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_LIFTER_MID); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_LIFTER_HIGH); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_COUNT_MODE); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_HANDLE_MODE); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_CLEAR_PASSWAY); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_GET_HISTORY_COUNT); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_CLEAR_ROLLER_CNT); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_GET_ROLLER_COUNT); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_SHUTDOWN); + RETURN_ENUM_STR(cmd, MENU_CMD_ID_WELCOME); char unk[40] = {0}; sprintf(unk, "Unknown menu command: %d", cmd); @@ -929,7 +929,7 @@ void ui_mgr::thread_display(void) lcd_->write_line(dd.ptr, dd.cnt, dd.x, dd.y, dd.mask); else lcd_->clear(dd.x, dd.y, dd.cnt, dd.mask); - wait = 3; + wait = 6; } else if(ready_enable_) { diff --git a/ui/font.cpp b/ui/font.cpp index 64d96de..eecbf02 100644 --- a/ui/font.cpp +++ b/ui/font.cpp @@ -598,7 +598,9 @@ font_map_["\342\200\246"] = ellipsis; } else { - ind += 3; + int num = (text[ind] >> 5) & 3; + utf8[num] = 0; + ind += num; } ptr[cnt] = get_font_data(utf8, fs); } diff --git a/xmake.lua b/xmake.lua index d717241..cb386f9 100644 --- a/xmake.lua +++ b/xmake.lua @@ -60,8 +60,8 @@ add_packagedirs("sdk") add_defines("BUILD_AS_DEVICE") add_defines("VER_MAIN=2") add_defines("VER_FAMILY=200") -add_defines("VER_DATE=20240207") -add_defines("VER_BUILD=43") +add_defines("VER_DATE=20240208") +add_defines("VER_BUILD=2") target("conf") set_kind("phony")