优化UI与服务程序通信;属性菜单由服务程序动态添加
This commit is contained in:
parent
bf151014ea
commit
1443eb9445
|
@ -90,20 +90,21 @@
|
|||
"cur": "G2393B0500",
|
||||
"default": "G2393B0500"
|
||||
},
|
||||
"roller-life": {
|
||||
"total-cnt": {
|
||||
"cat": "base",
|
||||
"group": "about",
|
||||
"title": "滚轴寿命",
|
||||
"desc": "该设备滚轴过纸的最大张数",
|
||||
"title": "历史张数",
|
||||
"desc": "该设备历史总计扫描张数",
|
||||
"type": "int",
|
||||
"fix-id": 34907,
|
||||
"fix-id": 34889,
|
||||
"ui-pos": 20,
|
||||
"auth": 0,
|
||||
"readonly": true,
|
||||
"size": 4,
|
||||
"auto": false,
|
||||
"cur": 450000,
|
||||
"default": 450000
|
||||
"ownread": true,
|
||||
"cur": 0,
|
||||
"default": 0
|
||||
},
|
||||
"roll-cnt": {
|
||||
"cat": "base",
|
||||
|
@ -121,21 +122,20 @@
|
|||
"cur": 0,
|
||||
"default": 0
|
||||
},
|
||||
"total-cnt": {
|
||||
"roller-life": {
|
||||
"cat": "base",
|
||||
"group": "about",
|
||||
"title": "历史张数",
|
||||
"desc": "该设备历史总计扫描张数",
|
||||
"title": "滚轴寿命",
|
||||
"desc": "该设备滚轴过纸的最大张数",
|
||||
"type": "int",
|
||||
"fix-id": 34889,
|
||||
"fix-id": 34907,
|
||||
"ui-pos": 22,
|
||||
"auth": 0,
|
||||
"readonly": true,
|
||||
"size": 4,
|
||||
"auto": false,
|
||||
"ownread": true,
|
||||
"cur": 0,
|
||||
"default": 0
|
||||
"cur": 450000,
|
||||
"default": 450000
|
||||
},
|
||||
"ip-addr": {
|
||||
"cat": "base",
|
||||
|
|
|
@ -543,13 +543,18 @@ int scanner_hw::scan_one_turn(LPPACKIMAGE img, safe_fifo<int>* cism, int* cism_c
|
|||
mem->release();
|
||||
mem = nullptr;
|
||||
retrieve_v4l2_mem(cism, cism_cnt);
|
||||
|
||||
resok = res_(TASK_CAPTURER, false, 0);
|
||||
dbg_print_("\t%d: to check resource spend %ums.\n", ++oper_index, chronograph::from_process_born() - bgn);
|
||||
}
|
||||
#else
|
||||
resok = res_(TASK_CAPTURER, false, 0);
|
||||
dbg_print_("\t%d: to check resource spend %ums.\n", ++oper_index, chronograph::from_process_born() - bgn);
|
||||
#endif
|
||||
|
||||
int fatal = 0;
|
||||
ret = SCANNER_ERR_DEVICE_HD_002;
|
||||
words = ID_WORDS_STATUS_DEVICE_HD_002;
|
||||
resok = res_(TASK_CAPTURER, false, 0);
|
||||
dbg_print_("\t%d: to check resource spend %ums.\n", ++oper_index, chronograph::from_process_born() - bgn);
|
||||
|
||||
if(!motor_->wait_event(MOTOR_BORD_EVENT_PAPER_PASSING, &ret, to_paper_out_, &fatal, &words))
|
||||
{
|
||||
|
@ -561,6 +566,7 @@ int scanner_hw::scan_one_turn(LPPACKIMAGE img, safe_fifo<int>* cism, int* cism_c
|
|||
if(mbstopped)
|
||||
*mbstopped = true;
|
||||
printf("-->scan done event received from motorboard.\n");
|
||||
utils::to_log(LOG_LEVEL_ALL, "scan done from motorboard.\n");
|
||||
}
|
||||
// else
|
||||
break;
|
||||
|
|
|
@ -125,49 +125,6 @@ async_scanner::async_scanner() : usb_(nullptr), cfg_mgr_(nullptr), scan_id_(0)
|
|||
, global_info::page_size, global_info::page_map_size, global_info::cluster_size, global_info::stack_size);
|
||||
res_mgr_.reset(new resource_mgr());
|
||||
init();
|
||||
|
||||
auto bulk_handle = [&](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* required) -> dyn_mem_ptr
|
||||
{
|
||||
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
|
||||
|
||||
if(used)
|
||||
*used = data->get_rest();
|
||||
|
||||
return handle_bulk_cmd(pack, used, required, data->get_session_id());
|
||||
};
|
||||
auto on_connect = [this](bool connected) -> void
|
||||
{
|
||||
utils::to_log(LOG_LEVEL_ALL, "USB %s\n", connected ? "connected" : "dis-connected");
|
||||
connected_ = connected;
|
||||
if(!connected)
|
||||
cis_->stop_scan();
|
||||
};
|
||||
|
||||
auto user = [&](int priv) -> bool
|
||||
{
|
||||
return user_->has_privilege(priv);
|
||||
};
|
||||
auto on_log = [&](const char* msg) -> void
|
||||
{
|
||||
utils::log_info(msg, LOG_LEVEL_DEBUG);
|
||||
};
|
||||
|
||||
cfg_mgr_ = new device_option(true, user, on_log);
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "OPT - initializing ...\n");
|
||||
user_ = new user_priv();
|
||||
|
||||
cfg_mgr_->add(const_opts_);
|
||||
cis_->set_value(SANE_OPT_NAME(DEVICE_MODEL), &cfg_mgr_->get_option_value(SANE_OPT_NAME(DEVICE_MODEL), SANE_ACTION_GET_VALUE)[0]);
|
||||
cfg_mgr_->add(cis_);
|
||||
cfg_mgr_->add(user_);
|
||||
img_prcr_ = new imgproc_mgr(cfg_mgr_, &async_scanner::image_sender, (void*)this, &async_scanner::resource_check, (void*)res_mgr_.get());
|
||||
cfg_mgr_->add(img_prcr_);
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "OPT - initialized %u options.\n", cfg_mgr_->count());
|
||||
|
||||
usb_ = new async_usb_gadget(bulk_handle, on_connect);
|
||||
last_err_ = usb_->last_error();
|
||||
|
||||
devui::send_status_message(ID_WORDS_STATUS_SCANNER_CONN + 1);
|
||||
}
|
||||
|
||||
async_scanner::~async_scanner()
|
||||
|
@ -226,6 +183,26 @@ void async_scanner::image_sender(SENDER_PROTO)
|
|||
|
||||
obj->usb_->write_bulk(ptr);
|
||||
}
|
||||
dyn_mem_ptr async_scanner::option_changed_packet(const char* name, void* val, size_t val_len, int pkid, int err)
|
||||
{
|
||||
size_t name_len = strlen(name) + 1,
|
||||
size = sizeof(PACK_BASE) + sizeof(CFGVAL) + name_len + val_len + 1;
|
||||
dyn_mem_ptr ptr = dyn_mem::memory(size);
|
||||
LPPACK_BASE pck = (LPPACK_BASE)ptr->ptr();
|
||||
LPCFGVAL cfg = (LPCFGVAL)pck->payload;
|
||||
|
||||
BASE_PACKET_REPLY(*pck, PACK_CMD_SETTING_SET, pkid, err);
|
||||
pck->payload_len = sizeof(CFGVAL) + name_len + val_len + 1;
|
||||
cfg->after_do = 0;
|
||||
cfg->name_off = 0;
|
||||
cfg->val_size = val_len;
|
||||
strcpy(cfg->data, name);
|
||||
cfg->val_off = name_len;
|
||||
memcpy(cfg->data + cfg->val_off, val, val_len);
|
||||
ptr->set_len(size);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
dyn_mem_ptr async_scanner::handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session)
|
||||
{
|
||||
|
@ -297,7 +274,13 @@ void async_scanner::init(void)
|
|||
|
||||
auto uicb = [this](devui::LPMSGSTREAM pack) -> void
|
||||
{
|
||||
if(devui::UI_CMD_COUNT_PAPER == pack->msg)
|
||||
if(devui::UI_STATUS_PEER_CONNECTED == pack->msg)
|
||||
{
|
||||
// add feed-strength && time-to-sleep menu ...
|
||||
add_option_to_ui_menu(SANE_OPT_NAME(FEED_STRENGTH), 0);
|
||||
add_option_to_ui_menu(SANE_OPT_NAME(TIME_TO_SLEEP), 1);
|
||||
}
|
||||
else if(devui::UI_CMD_COUNT_PAPER == pack->msg)
|
||||
{
|
||||
auto receiver = [this](dyn_mem_ptr data, bool img, LPPACKIMAGE lpinfo) -> void
|
||||
{
|
||||
|
@ -320,19 +303,120 @@ void async_scanner::init(void)
|
|||
{
|
||||
cis_->clean_paper_passway();
|
||||
}
|
||||
else if(devui::UI_CMD_GET_HISTORY_COUNT == pack->msg)
|
||||
else if(devui::UI_CMD_SET_OPTION_VALUE == pack->msg)
|
||||
{
|
||||
const_opts_->set_history_count(*(uint32_t*)pack->data);
|
||||
}
|
||||
else if(devui::UI_CMD_GET_ROLLER_COUNT == pack->msg)
|
||||
{
|
||||
const_opts_->set_roller_count(*(uint32_t*)pack->data);
|
||||
char *name = (char*)pack->data,
|
||||
*val = utils::next_string(name);
|
||||
std::string type(cfg_mgr_->get_option_value_type(name)),
|
||||
rv(sane_opt_provider::sane_value_from_readable_text(type.c_str(), val));
|
||||
dyn_mem_ptr ptr = async_scanner::option_changed_packet(name, &rv[0], rv.length());
|
||||
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "From UI set '%s' to '%s'.\n", name, val);
|
||||
|
||||
cfg_mgr_->update_data(name, &rv[0], true, false);
|
||||
|
||||
if(!usb_)
|
||||
{
|
||||
int cond = MUST_COND_ROLLER_CNT | MUST_COND_HISTORY_CNT;
|
||||
|
||||
if(strcmp(name, SANE_OPT_NAME(ROLLER_COUNT)) == 0)
|
||||
must_ready_ |= MUST_COND_ROLLER_CNT;
|
||||
else if(strcmp(name, SANE_OPT_NAME(HISTORY_COUNT)) == 0)
|
||||
must_ready_ |= MUST_COND_HISTORY_CNT;
|
||||
if((must_ready_ & cond) == cond)
|
||||
init_usb();
|
||||
}
|
||||
if(usb_)
|
||||
{
|
||||
ptr->set_session_id(usb_->current_session());
|
||||
usb_->write_bulk(ptr);
|
||||
}
|
||||
ptr->release();
|
||||
}
|
||||
};
|
||||
|
||||
auto user = [this](int priv) -> bool
|
||||
{
|
||||
return user_->has_privilege(priv);
|
||||
};
|
||||
auto on_log = [&](const char* msg) -> void
|
||||
{
|
||||
utils::log_info(msg, LOG_LEVEL_DEBUG);
|
||||
};
|
||||
|
||||
cfg_mgr_ = new device_option(true, user, on_log);
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "OPT - initializing ...\n");
|
||||
user_ = new user_priv();
|
||||
|
||||
cfg_mgr_->add(const_opts_);
|
||||
cis_->set_value(SANE_OPT_NAME(DEVICE_MODEL), &cfg_mgr_->get_option_value(SANE_OPT_NAME(DEVICE_MODEL), SANE_ACTION_GET_VALUE)[0]);
|
||||
cfg_mgr_->add(cis_);
|
||||
cfg_mgr_->add(user_);
|
||||
img_prcr_ = new imgproc_mgr(cfg_mgr_, &async_scanner::image_sender, (void*)this, &async_scanner::resource_check, (void*)res_mgr_.get());
|
||||
cfg_mgr_->add(img_prcr_);
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "OPT - initialized %u options.\n", cfg_mgr_->count());
|
||||
|
||||
// init_usb();
|
||||
|
||||
devui::init_ui(uicb, false);
|
||||
devui::send_message(devui::UI_CMD_GET_HISTORY_COUNT);
|
||||
devui::send_message(devui::UI_CMD_GET_ROLLER_COUNT);
|
||||
devui::send_message(devui::UI_STATUS_READY, nullptr, 0);
|
||||
}
|
||||
void async_scanner::init_usb(void)
|
||||
{
|
||||
auto bulk_handle = [this](dyn_mem_ptr data, uint32_t* used, packet_data_base_ptr* required) -> dyn_mem_ptr
|
||||
{
|
||||
LPPACK_BASE pack = (LPPACK_BASE)data->ptr();
|
||||
|
||||
if(used)
|
||||
*used = data->get_rest();
|
||||
|
||||
return handle_bulk_cmd(pack, used, required, data->get_session_id());
|
||||
};
|
||||
auto on_connect = [this](bool connected) -> void
|
||||
{
|
||||
utils::to_log(LOG_LEVEL_ALL, "USB %s\n", connected ? "connected" : "dis-connected");
|
||||
connected_ = connected;
|
||||
if(!connected)
|
||||
cis_->stop_scan();
|
||||
};
|
||||
|
||||
usb_ = new async_usb_gadget(bulk_handle, on_connect);
|
||||
last_err_ = usb_->last_error();
|
||||
}
|
||||
void async_scanner::add_option_to_ui_menu(const char* name, int pos)
|
||||
{
|
||||
SANE_Constraint_Type constraint = SANE_CONSTRAINT_NONE;
|
||||
std::string vals(cfg_mgr_->get_option_value(name, SANE_ACTION_GET_ALL_VALUES, nullptr, nullptr, &constraint)),
|
||||
cur(vals.c_str()),
|
||||
title(cfg_mgr_->get_option_field_string(name, "title"));
|
||||
const char *val = utils::next_string(vals.c_str());
|
||||
devui::LPOPTMENU opl = nullptr;
|
||||
size_t len = sizeof(devui::OPTMENU) + strlen(name) + 1 + title.length() + 1;
|
||||
|
||||
val = utils::next_string(val);
|
||||
if(val)
|
||||
vals.erase(0, val - vals.c_str());
|
||||
else
|
||||
vals = std::string("\0\0\0\0", 4);
|
||||
len += vals.length();
|
||||
opl = (devui::LPOPTMENU)malloc(len);
|
||||
memset(opl, 0, len);
|
||||
opl->title_off = strlen(name) + 1;
|
||||
strcpy(opl->name, name);
|
||||
strcpy(opl->name + opl->title_off, title.c_str());
|
||||
opl->value_off = opl->title_off + title.length() + 1;
|
||||
memcpy(opl->name + opl->value_off, vals.c_str(), vals.length());
|
||||
opl->pos = pos;
|
||||
val = vals.c_str();
|
||||
while(val)
|
||||
{
|
||||
if(cur == val)
|
||||
break;
|
||||
val = utils::next_string(val);
|
||||
opl->cur_sel++;
|
||||
}
|
||||
devui::send_message(devui::UI_CMD_ADD_MENU, (uint8_t*)opl, len);
|
||||
free(opl);
|
||||
}
|
||||
bool async_scanner::on_energy_conservation(bool normal)
|
||||
{
|
||||
|
|
|
@ -21,6 +21,12 @@ class user_priv;
|
|||
class imgproc_mgr;
|
||||
class resource_mgr;
|
||||
|
||||
enum must_cond
|
||||
{
|
||||
MUST_COND_ROLLER_CNT = 1 << 0,
|
||||
MUST_COND_HISTORY_CNT = 1 << 1,
|
||||
};
|
||||
|
||||
class async_scanner : public refer
|
||||
{
|
||||
async_usb_gadget *usb_ = nullptr;
|
||||
|
@ -29,6 +35,7 @@ class async_scanner : public refer
|
|||
scanner_hw *cis_ = nullptr;
|
||||
user_priv *user_ = nullptr;
|
||||
imgproc_mgr *img_prcr_ = nullptr;
|
||||
uint32_t must_ready_ = 0;
|
||||
|
||||
MUTEX locker_;
|
||||
volatile bool connected_ = false;
|
||||
|
@ -45,9 +52,12 @@ class async_scanner : public refer
|
|||
|
||||
static bool resource_check(RES_CHK_PROTO);
|
||||
static void image_sender(SENDER_PROTO);
|
||||
static dyn_mem_ptr option_changed_packet(const char* name, void* val, size_t val_len, int pkid = 0, int err = 0);
|
||||
|
||||
dyn_mem_ptr handle_bulk_cmd(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session);
|
||||
void init(void);
|
||||
void init_usb(void);
|
||||
void add_option_to_ui_menu(const char* name, int pos = -1);
|
||||
bool on_energy_conservation(bool normal/*true - working status; false - go to sleep*/); // return true to enable get into 'normal' status
|
||||
|
||||
dyn_mem_ptr handle_simple_roger(LPPACK_BASE pack, uint32_t* used, packet_data_base_ptr* required, uint32_t session);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <sane/sane_ex.h>
|
||||
#include <string.h>
|
||||
#include <base/ui.h>
|
||||
|
||||
#include <huagao/hgscanner_error.h>
|
||||
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// option json:
|
||||
static std::string device_opt_json[] = {
|
||||
"{\"dev-vid\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"USB-VID\",\"desc\":\"\\u8bbe\\u5907\\u5236\\u9020\\u5546\\u5728USB\\u7ec4\\u7ec7\\u7684ID\",\"type\":\"string\",\"fix-id\":34898,\"ui-pos\":10,\"auth\":0,\"readonly\":true,\"size\":16,\"auto\":false,\"cur\":\"3072\",\"default\":\"3072\"},\"dev-pid\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"USB-PID\",\"desc\":\"\\u8bbe\\u5907\\u5728USB\\u7ec4\\u7ec7\\u4e2d\\u7684\\u4ea7\\u54c1ID\",\"type\":\"string\",\"fix-id\":34899,\"ui-pos\":11,\"auth\":0,\"readonly\":true,\"size\":16,\"auto\":false,\"cur\":\"0306\",\"default\":\"0306\"},\"dev-name\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"\\u8bbe\\u5907\\u540d\\u79f0\",\"desc\":\"\\u8bbe\\u5907\\u540d\\u79f0\",\"type\":\"string\",\"fix-id\":34900,\"ui-pos\":12,\"auth\":0,\"readonly\":true,\"size\":96,\"auto\":false,\"cur\":\"HUAGOSCAN G200\",\"default\":\"HUAGOSCAN G200\"},\"dev-model\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"\\u4ea7\\u54c1\\u7cfb\\u5217\",\"desc\":\"\\u8bbe\\u5907\\u6240\\u5c5e\\u4ea7\\u54c1\\u7cfb\\u5217\\u540d\\u79f0\",\"type\":\"string\",\"fix-id\":34901,\"ui-pos\":13,\"auth\":0,\"readonly\":true,\"size\":96,\"auto\":false,\"cur\":\"G200\",\"default\":\"G200\"},\"dev-sn\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"\\u5e8f\\u5217\\u53f7\",\"desc\":\"\\u8bbe\\u5907\\u5e8f\\u5217\\u53f7\",\"type\":\"string\",\"fix-id\":34902,\"ui-pos\":14,\"auth\":0,\"readonly\":true,\"size\":32,\"auto\":false,\"ownread\":true,\"cur\":\"GB20231201\",\"default\":\"GB20231201\"},\"fmw-ver\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"\\u56fa\\u4ef6\\u7248\\u672c\",\"desc\":\"\\u8bbe\\u5907\\u56fa\\u4ef6\\u7248\\u672c\\u53f7\",\"type\":\"string\",\"fix-id\":34903,\"ui-pos\":15,\"auth\":0,\"readonly\":true,\"size\":32,\"auto\":false,\"cur\":\"G2393B0500\",\"default\":\"G2393B0500\"},\"roller-life\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"\\u6eda\\u8f74\\u5bff\\u547d\",\"desc\":\"\\u8be5\\u8bbe\\u5907\\u6eda\\u8f74\\u8fc7\\u7eb8\\u7684\\u6700\\u5927\\u5f20\\u6570\",\"type\":\"int\",\"fix-id\":34907,\"ui-pos\":20,\"auth\":0,\"readonly\":true,\"size\":4,\"auto\":false,\"cur\":450000,\"default\":450000},\"roll-cnt\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"\\u6eda\\u8f74\\u5f20\\u6570\",\"desc\":\"\\u5f53\\u524d\\u6eda\\u8f74\\u626b\\u63cf\\u5f20\\u6570\",\"type\":\"int\",\"fix-id\":39170,\"ui-pos\":21,\"auth\":0,\"readonly\":true,\"size\":4,\"auto\":false,\"ownread\":true,\"cur\":0,\"default\":0},\"total-cnt\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"\\u5386\\u53f2\\u5f20\\u6570\",\"desc\":\"\\u8be5\\u8bbe\\u5907\\u5386\\u53f2\\u603b\\u8ba1\\u626b\\u63cf\\u5f20\\u6570\",\"type\":\"int\",\"fix-id\":34889,\"ui-pos\":22,\"auth\":0,\"readonly\":true,\"size\":4,\"auto\":false,\"ownread\":true,\"cur\":0,\"default\":0},\"ip-addr\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"IP\",\"desc\":\"\\u8bbe\\u5907\\u8054\\u7f51\\u65f6\\u6240\\u5206\\u914d\\u7684IP\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34904,\"ui-pos\":30,\"auth\":0,\"readonly\":true,\"size\":96,\"auto\":false,\"ownread\":true,\"cur\":\"0\",\"default\":\"0\"},\"mac-addr\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"MAC\",\"desc\":\"\\u8bbe\\u5907\\u7f51\\u5361\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34905,\"ui-pos\":31,\"auth\":0,\"readonly\":true,\"size\":96,\"auto\":false,\"ownread\":true,\"cur\":\"0\",\"default\":\"0\"}}"
|
||||
"{\"dev-vid\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"USB-VID\",\"desc\":\"\\u8bbe\\u5907\\u5236\\u9020\\u5546\\u5728USB\\u7ec4\\u7ec7\\u7684ID\",\"type\":\"string\",\"fix-id\":34898,\"ui-pos\":10,\"auth\":0,\"readonly\":true,\"size\":16,\"auto\":false,\"cur\":\"3072\",\"default\":\"3072\"},\"dev-pid\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"USB-PID\",\"desc\":\"\\u8bbe\\u5907\\u5728USB\\u7ec4\\u7ec7\\u4e2d\\u7684\\u4ea7\\u54c1ID\",\"type\":\"string\",\"fix-id\":34899,\"ui-pos\":11,\"auth\":0,\"readonly\":true,\"size\":16,\"auto\":false,\"cur\":\"0306\",\"default\":\"0306\"},\"dev-name\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"\\u8bbe\\u5907\\u540d\\u79f0\",\"desc\":\"\\u8bbe\\u5907\\u540d\\u79f0\",\"type\":\"string\",\"fix-id\":34900,\"ui-pos\":12,\"auth\":0,\"readonly\":true,\"size\":96,\"auto\":false,\"cur\":\"HUAGOSCAN G200\",\"default\":\"HUAGOSCAN G200\"},\"dev-model\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"\\u4ea7\\u54c1\\u7cfb\\u5217\",\"desc\":\"\\u8bbe\\u5907\\u6240\\u5c5e\\u4ea7\\u54c1\\u7cfb\\u5217\\u540d\\u79f0\",\"type\":\"string\",\"fix-id\":34901,\"ui-pos\":13,\"auth\":0,\"readonly\":true,\"size\":96,\"auto\":false,\"cur\":\"G200\",\"default\":\"G200\"},\"dev-sn\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"\\u5e8f\\u5217\\u53f7\",\"desc\":\"\\u8bbe\\u5907\\u5e8f\\u5217\\u53f7\",\"type\":\"string\",\"fix-id\":34902,\"ui-pos\":14,\"auth\":0,\"readonly\":true,\"size\":32,\"auto\":false,\"ownread\":true,\"cur\":\"GB20231201\",\"default\":\"GB20231201\"},\"fmw-ver\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"\\u56fa\\u4ef6\\u7248\\u672c\",\"desc\":\"\\u8bbe\\u5907\\u56fa\\u4ef6\\u7248\\u672c\\u53f7\",\"type\":\"string\",\"fix-id\":34903,\"ui-pos\":15,\"auth\":0,\"readonly\":true,\"size\":32,\"auto\":false,\"cur\":\"G2393B0500\",\"default\":\"G2393B0500\"},\"total-cnt\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"\\u5386\\u53f2\\u5f20\\u6570\",\"desc\":\"\\u8be5\\u8bbe\\u5907\\u5386\\u53f2\\u603b\\u8ba1\\u626b\\u63cf\\u5f20\\u6570\",\"type\":\"int\",\"fix-id\":34889,\"ui-pos\":20,\"auth\":0,\"readonly\":true,\"size\":4,\"auto\":false,\"ownread\":true,\"cur\":0,\"default\":0},\"roll-cnt\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"\\u6eda\\u8f74\\u5f20\\u6570\",\"desc\":\"\\u5f53\\u524d\\u6eda\\u8f74\\u626b\\u63cf\\u5f20\\u6570\",\"type\":\"int\",\"fix-id\":39170,\"ui-pos\":21,\"auth\":0,\"readonly\":true,\"size\":4,\"auto\":false,\"ownread\":true,\"cur\":0,\"default\":0},\"roller-life\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"\\u6eda\\u8f74\\u5bff\\u547d\",\"desc\":\"\\u8be5\\u8bbe\\u5907\\u6eda\\u8f74\\u8fc7\\u7eb8\\u7684\\u6700\\u5927\\u5f20\\u6570\",\"type\":\"int\",\"fix-id\":34907,\"ui-pos\":22,\"auth\":0,\"readonly\":true,\"size\":4,\"auto\":false,\"cur\":450000,\"default\":450000},\"ip-addr\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"IP\",\"desc\":\"\\u8bbe\\u5907\\u8054\\u7f51\\u65f6\\u6240\\u5206\\u914d\\u7684IP\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34904,\"ui-pos\":30,\"auth\":0,\"readonly\":true,\"size\":96,\"auto\":false,\"ownread\":true,\"cur\":\"0\",\"default\":\"0\"},\"mac-addr\":{\"cat\":\"base\",\"group\":\"about\",\"title\":\"MAC\",\"desc\":\"\\u8bbe\\u5907\\u7f51\\u5361\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34905,\"ui-pos\":31,\"auth\":0,\"readonly\":true,\"size\":96,\"auto\":false,\"ownread\":true,\"cur\":\"0\",\"default\":\"0\"}}"
|
||||
};
|
||||
|
||||
|
||||
|
@ -227,14 +227,10 @@ char* scanner_const_opts::get_value(const char* name, void* value, size_t* size,
|
|||
}
|
||||
else if(strcmp(SANE_OPT_NAME(ROLLER_COUNT), name) == 0)
|
||||
{
|
||||
devui::send_message(devui::UI_CMD_GET_ROLLER_COUNT);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
val = std::string((char*)&roller_cnt_, sizeof(roller_cnt_));
|
||||
}
|
||||
else if(strcmp(SANE_OPT_NAME(HISTORY_COUNT), name) == 0)
|
||||
{
|
||||
devui::send_message(devui::UI_CMD_GET_HISTORY_COUNT);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
val = std::string((char*)&hist_cnt_, sizeof(hist_cnt_));
|
||||
}
|
||||
else if(err)
|
||||
|
@ -244,19 +240,29 @@ char* scanner_const_opts::get_value(const char* name, void* value, size_t* size,
|
|||
{
|
||||
ret = (char*)malloc(val.length() + 1);
|
||||
memset(ret, 0, val.length() + 1);
|
||||
strcpy(ret, val.c_str());
|
||||
memcpy(ret, val.c_str(), val.length());
|
||||
if(size)
|
||||
*size = val.length();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
int scanner_const_opts::set_value(const char* name, void* val)
|
||||
{
|
||||
int ret = SCANNER_ERR_OK;
|
||||
|
||||
void scanner_const_opts::set_roller_count(uint32_t cnt)
|
||||
{
|
||||
roller_cnt_ = cnt;
|
||||
}
|
||||
void scanner_const_opts::set_history_count(uint32_t cnt)
|
||||
{
|
||||
hist_cnt_ = cnt;
|
||||
if(strcmp(SANE_OPT_NAME(ROLLER_COUNT), name) == 0)
|
||||
{
|
||||
roller_cnt_ = *(int*)val;
|
||||
}
|
||||
else if(strcmp(SANE_OPT_NAME(HISTORY_COUNT), name) == 0)
|
||||
{
|
||||
hist_cnt_ = *(int*)val;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = SCANNER_ERR_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -26,10 +26,7 @@ protected:
|
|||
public:
|
||||
// return malloc(), real data size stored in parameter 'size'. invoker should free() the returned value
|
||||
virtual char* get_value(const char* name, void* value, size_t* size, int* err = nullptr) override;
|
||||
|
||||
public:
|
||||
void set_roller_count(uint32_t cnt);
|
||||
void set_history_count(uint32_t cnt);
|
||||
virtual int set_value(const char* name, void* val) override;
|
||||
};
|
||||
|
||||
|
||||
|
|
118
sdk/base/ui.cpp
118
sdk/base/ui.cpp
|
@ -5,6 +5,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define PIPE_PROTO_VER MAKEWORD(0, 1)
|
||||
|
||||
|
@ -12,6 +13,7 @@
|
|||
// ipc class
|
||||
namespace devui
|
||||
{
|
||||
// open reader will be blocked until the sender openned !!!
|
||||
class pipe_reader : public refer
|
||||
{
|
||||
std::string pipe_path_;
|
||||
|
@ -170,8 +172,8 @@ namespace devui
|
|||
std::function<void(LPMSGSTREAM)> cb_;
|
||||
safe_fifo<std::string> sent_que_;
|
||||
volatile bool run_ = true;
|
||||
volatile bool ready_ = false;
|
||||
bool ui_;
|
||||
bool ready_ = true;
|
||||
safe_thread workers_;
|
||||
int fdo_ = -1;
|
||||
int fdi_ = -1;
|
||||
|
@ -205,16 +207,12 @@ namespace devui
|
|||
}
|
||||
else
|
||||
{
|
||||
auto r = [this](void*) -> void
|
||||
{
|
||||
receiver();
|
||||
};
|
||||
auto s = [this](void*) -> void
|
||||
{
|
||||
sender();
|
||||
};
|
||||
workers_.start(r, nullptr, SIZE_MB(1), "receiver");
|
||||
workers_.start(s, nullptr, SIZE_MB(1), "sender");
|
||||
ready_ = true;
|
||||
workers_.start(s, nullptr, SIZE_MB(1), "sender", (void*)&ui_messenger::sender);
|
||||
}
|
||||
}
|
||||
void close(void)
|
||||
|
@ -234,48 +232,66 @@ namespace devui
|
|||
chronograph watch;
|
||||
|
||||
printf("ui-receiver running ...\n");
|
||||
while(run_)
|
||||
init();
|
||||
if(ready_)
|
||||
{
|
||||
watch.reset();
|
||||
int r = read(fdi_, buf, _countof(buf));
|
||||
if(r == -1)
|
||||
MSGSTREAM ms;
|
||||
memset(&ms, 0, sizeof(ms));
|
||||
ms.ver = PIPE_PROTO_VER;
|
||||
ms.msg = UI_STATUS_PEER_CONNECTED;
|
||||
cb_(&ms);
|
||||
|
||||
while(run_)
|
||||
{
|
||||
printf("Read UI message failed: %d(%s)\n", errno, strerror(errno));
|
||||
utils::to_log(LOG_LEVEL_FATAL, "Read UI message failed: %d(%s)\n", errno, strerror(errno));
|
||||
this->close();
|
||||
break;
|
||||
}
|
||||
else if(r == 0 /*&& errno == ENOENT*/) // errno maybe ZERO, here ommit the error code
|
||||
{
|
||||
// peer closed, wait 10ms ...
|
||||
if(watch.elapse_ms() > 10)
|
||||
watch.reset();
|
||||
int r = read(fdi_, buf, _countof(buf));
|
||||
if(r == -1)
|
||||
{
|
||||
MSGSTREAM ms;
|
||||
memset(&ms, 0, sizeof(ms));
|
||||
ms.ver = PIPE_PROTO_VER;
|
||||
ms.msg = UI_STATUS_PEER_CLOSED;
|
||||
printf("Read UI message failed: %d(%s)\n", errno, strerror(errno));
|
||||
utils::to_log(LOG_LEVEL_FATAL, "Read UI message failed: %d(%s)\n", errno, strerror(errno));
|
||||
this->close();
|
||||
break;
|
||||
}
|
||||
else if(r == 0 /*&& errno == ENOENT*/) // errno maybe ZERO, here ommit the error code
|
||||
{
|
||||
// peer closed, wait 10ms ...
|
||||
// if(watch.elapse_ms() > 10)
|
||||
if(ready_)
|
||||
{
|
||||
ready_ = false;
|
||||
|
||||
MSGSTREAM ms;
|
||||
memset(&ms, 0, sizeof(ms));
|
||||
ms.ver = PIPE_PROTO_VER;
|
||||
ms.msg = UI_STATUS_PEER_CLOSED;
|
||||
cb_(&ms);
|
||||
|
||||
printf("[%s] PIPE: peer closed(read ZERO byte and error = %d).\n", utils::format_current_time().c_str(), errno);
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "PIPE: peer closed(read ZERO byte and error = %d).\n", errno);
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!ready_)
|
||||
{
|
||||
ready_ = true;
|
||||
cb_(&ms);
|
||||
|
||||
printf("[%s] PIPE: peer closed(read ZERO byte and error = %d).\n", utils::format_current_time().c_str(), errno);
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "PIPE: peer closed(read ZERO byte and error = %d).\n", errno);
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
continue;
|
||||
}
|
||||
|
||||
rcv += std::string(buf, r);
|
||||
if(rcv.length())
|
||||
{
|
||||
int off = 0;
|
||||
pack = (LPMSGSTREAM)&rcv[off];
|
||||
while(pack->whole_size() <= rcv.length() - off)
|
||||
rcv += std::string(buf, r);
|
||||
if(rcv.length())
|
||||
{
|
||||
cb_(pack);
|
||||
off += pack->whole_size();
|
||||
int off = 0;
|
||||
pack = (LPMSGSTREAM)&rcv[off];
|
||||
while(pack->whole_size() <= rcv.length() - off)
|
||||
{
|
||||
cb_(pack);
|
||||
off += pack->whole_size();
|
||||
pack = (LPMSGSTREAM)&rcv[off];
|
||||
}
|
||||
if(off)
|
||||
rcv.erase(0, off);
|
||||
}
|
||||
if(off)
|
||||
rcv.erase(0, off);
|
||||
}
|
||||
}
|
||||
printf("ui-receiver exited.\n");
|
||||
|
@ -296,11 +312,14 @@ namespace devui
|
|||
{
|
||||
printf("Send UI message failed: %d(%s)\n", errno, strerror(errno));
|
||||
utils::to_log(LOG_LEVEL_FATAL, "Send UI message failed: %d(%s)\n", errno, strerror(errno));
|
||||
this->close();
|
||||
if(ready_)
|
||||
this->close();
|
||||
else
|
||||
s = 0;
|
||||
break;
|
||||
}
|
||||
off += s;
|
||||
}while(off < cont.length());
|
||||
}while(ready_ && off < cont.length());
|
||||
if(s == -1)
|
||||
break;
|
||||
}
|
||||
|
@ -313,12 +332,19 @@ namespace devui
|
|||
, bool ui) : sent_que_("ui-sent-que")
|
||||
, cb_(uicb), ui_(ui)
|
||||
{
|
||||
// to avoid crash when write a closed pipe
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
sent_que_.enable_wait_log(false);
|
||||
init();
|
||||
|
||||
auto r = [this](void*) -> void
|
||||
{
|
||||
receiver();
|
||||
};
|
||||
workers_.start(r, nullptr, SIZE_MB(1), "receiver", (void*)&ui_messenger::receiver);
|
||||
}
|
||||
~ui_messenger()
|
||||
{
|
||||
close();
|
||||
stop();
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -331,8 +357,8 @@ namespace devui
|
|||
}
|
||||
void stop(void)
|
||||
{
|
||||
sent_que_.trigger();
|
||||
run_ = false;
|
||||
sent_que_.trigger();
|
||||
this->close();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -18,6 +18,12 @@ namespace devui
|
|||
SCAN_NORMAL,
|
||||
SCAN_COUNT_MODE,
|
||||
};
|
||||
enum strength
|
||||
{
|
||||
STRENGTH_LOW = 1,
|
||||
STRENGTH_MID,
|
||||
STRENGTH_HIGH,
|
||||
};
|
||||
enum uicmd
|
||||
{
|
||||
UI_CMD_COUNT_PAPER = 0x10,
|
||||
|
@ -25,14 +31,16 @@ namespace devui
|
|||
|
||||
UI_CMD_CLEAN_PASSWAY = 0x30,
|
||||
|
||||
UI_CMD_GET_HISTORY_COUNT = 0x50,
|
||||
UI_CMD_GET_ROLLER_COUNT,
|
||||
UI_CMD_ADD_MENU = 0x100, // data: LPADDMENU
|
||||
UI_CMD_SET_OPTION_VALUE, // data: string array - name + value
|
||||
|
||||
UI_STATUS_SCANNING = 0x1000, // begin scanning. data: (LPSCANSTREAM)
|
||||
UI_STATUS_PAPER_CNT, // ONE paper has pass through. data: (uint32_t*)milliseconds for paper pass through
|
||||
UI_STATUS_MESSAGE, // status message, hold screen. data: LPSTATMSG
|
||||
UI_STATUS_READY = 0x1000,
|
||||
UI_STATUS_SCANNING, // begin scanning. data: (LPSCANSTREAM)
|
||||
UI_STATUS_PAPER_CNT, // ONE paper has pass through. data: (uint32_t*)milliseconds for paper pass through
|
||||
UI_STATUS_MESSAGE, // status message, hold screen. data: LPSTATMSG
|
||||
|
||||
UI_STATUS_PEER_CLOSED = 0x8000, // peer closed.
|
||||
UI_STATUS_PEER_CONNECTED = 0x8000, // peer connected.
|
||||
UI_STATUS_PEER_CLOSED,
|
||||
};
|
||||
enum align_component
|
||||
{
|
||||
|
@ -79,6 +87,14 @@ namespace devui
|
|||
uint32_t font : 8; // font size
|
||||
uint32_t reserved : 14;
|
||||
}STATMSG, *LPSTATMSG;
|
||||
typedef struct _opt_menu
|
||||
{
|
||||
uint32_t pos; // -1 is not care
|
||||
uint8_t cur_sel;
|
||||
uint8_t title_off; // -1 is no title
|
||||
uint16_t value_off;
|
||||
char name[4];
|
||||
}OPTMENU, *LPOPTMENU;
|
||||
#pragma pack(pop)
|
||||
|
||||
void init_ui(std::function<void(LPMSGSTREAM)> uicb, bool ui);
|
||||
|
|
|
@ -1101,6 +1101,46 @@ namespace utils
|
|||
return str.c_str();
|
||||
}
|
||||
|
||||
std::string string_array(const std::vector<std::string>& strs)
|
||||
{
|
||||
std::string stra("");
|
||||
|
||||
for(const auto& v: strs)
|
||||
{
|
||||
stra += v;
|
||||
stra.append(1, '\0');
|
||||
}
|
||||
stra.append(2, '\0');
|
||||
|
||||
return std::move(stra);
|
||||
}
|
||||
void add_2_string_array(std::string& stra, const char* str)
|
||||
{
|
||||
if(stra.length() >= 2)
|
||||
stra.erase(stra.length() - 2);
|
||||
|
||||
stra += std::string(str, strlen(str) + 1);
|
||||
stra.append(2, '\0');
|
||||
}
|
||||
const char* next_string(const char* stra)
|
||||
{
|
||||
if(*stra)
|
||||
stra += strlen(stra) + 1;
|
||||
if(*stra == 0)
|
||||
stra = nullptr;
|
||||
|
||||
return stra;
|
||||
}
|
||||
char* next_string(char* stra)
|
||||
{
|
||||
if(*stra)
|
||||
stra += strlen(stra) + 1;
|
||||
if(*stra == 0)
|
||||
stra = nullptr;
|
||||
|
||||
return stra;
|
||||
}
|
||||
|
||||
int get_stack_size(void)
|
||||
{
|
||||
int size = 0;
|
||||
|
|
|
@ -95,6 +95,12 @@ namespace utils
|
|||
const char* to_lower(std::string& str); // return str.c_str()
|
||||
const char* trim(std::string& str, const char* sp = "\r\n\t "); // return str.c_str()
|
||||
|
||||
// string array
|
||||
std::string string_array(const std::vector<std::string>& strs);
|
||||
void add_2_string_array(std::string& stra, const char* str);
|
||||
const char* next_string(const char* stra);
|
||||
char* next_string(char* stra);
|
||||
|
||||
int get_stack_size(void);
|
||||
|
||||
bool from_hex_string(const char* hex, uint8_t* val);
|
||||
|
|
|
@ -36,7 +36,7 @@ WORDS_AND_ID_IMPL(WORDS_FILLBG_CONVEX, "\345\207\270\345\244\232\350
|
|||
|
||||
WORDS_AND_ID_IMPL(WORDS_MENU_WELCOME, "\346\254\242\350\277\216");
|
||||
WORDS_AND_ID_IMPL(WORDS_MENU_SELECTED, "\342\210\232");
|
||||
WORDS_AND_ID_IMPL(WORDS_MENU_RETURN, "\350\277\224\345\233\236\344\270\212\347\272\247\350\217\234\345\215\225");
|
||||
WORDS_AND_ID_IMPL(WORDS_MENU_RETURN, "\350\277\224\345\233\236");
|
||||
WORDS_AND_ID_IMPL(WORDS_MENU_SEPARATE_STRENGTH, "\345\210\206\347\272\270\345\274\272\345\272\246");
|
||||
WORDS_AND_ID_IMPL(WORDS_MENU_LOW, "\344\275\216");
|
||||
WORDS_AND_ID_IMPL(WORDS_MENU_MID, "\344\270\255");
|
||||
|
|
|
@ -139,6 +139,7 @@ extern "C" {
|
|||
SANE_ACTION_GET_DEFAULT_VALUE = 100, // 获取设置项默认值,参数同SANE_ACTION_GET_VALUE
|
||||
SANE_ACTION_GET_FIX_ID, // 获取属性的固定ID,void* = SANE_Int*
|
||||
SANE_ACTION_GET_ENTIRE_JSON, // 获取该属性JSON文本
|
||||
SANE_ACTION_GET_ALL_VALUES, // 获取该属性所有值,see SANE_Value_Index.
|
||||
|
||||
// Function: 枚举对SANE协议不可见的固定ID属性(以使TWAIN可访问)
|
||||
//
|
||||
|
@ -146,7 +147,17 @@ extern "C" {
|
|||
SANE_ACTION_ENUM_INVISIBLE_FIX_ID = 0x0FEC7,
|
||||
};
|
||||
|
||||
enum SANE_Frame_Ex // after SANE_Frame
|
||||
enum SANE_Value_Index // when get constrainted value list, the index of special value. DO NOT change their sequence !!!
|
||||
{
|
||||
SANE_VAL_IND_CURRENT = 0, // current value
|
||||
SANE_VAL_IND_DEFAULT,
|
||||
SANE_VAL_IND_LIST_0, // the first value of list
|
||||
SANE_VAL_IND_RANGE_LOWER = SANE_VAL_IND_LIST_0, // lower value of range
|
||||
SANE_VAL_IND_RANGE_UPPER,
|
||||
SANE_VAL_IND_RANGE_STEP,
|
||||
};
|
||||
|
||||
enum SANE_Frame_Ex // after SANE_Frame
|
||||
{
|
||||
SANE_FRAME_RAW = 100,
|
||||
SANE_FRAME_MIME, // MIME descriptor
|
||||
|
|
|
@ -5,7 +5,45 @@
|
|||
#include <sane/sane_ex.h>
|
||||
#include <string.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template<class T>
|
||||
static void get_range_values(std::string& ret, gb_json* range, bool* isrange)
|
||||
{
|
||||
std::string values("");
|
||||
T v;
|
||||
|
||||
if(range->get_value("min", v))
|
||||
{
|
||||
if(isrange)
|
||||
*isrange = true;
|
||||
ret += std::string((char*)&v, sizeof(v));
|
||||
|
||||
range->get_value("max", v);
|
||||
ret += std::string((char*)&v, sizeof(v));
|
||||
|
||||
range->get_value("step", v);
|
||||
ret += std::string((char*)&v, sizeof(v));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(isrange)
|
||||
*isrange = false;
|
||||
|
||||
gb_json* val = range->first_child();
|
||||
while(val)
|
||||
{
|
||||
val->value(v);
|
||||
ret += std::string((char*)&v, sizeof(v));
|
||||
|
||||
val->release();
|
||||
val = range->next_child();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
sane_opt_provider::sane_opt_provider()
|
||||
{
|
||||
set_where(nullptr);
|
||||
|
@ -18,7 +56,20 @@ sane_opt_provider::~sane_opt_provider()
|
|||
following_.clear();
|
||||
}
|
||||
|
||||
std::string sane_opt_provider::sane_value_2_text(const char* type, void* value)
|
||||
std::string sane_opt_provider::sane_value_2_readable_text(SANE_Value_Type type, void* value)
|
||||
{
|
||||
if(type == SANE_TYPE_BOOL)
|
||||
return *(bool*)value ? "true" : "false";
|
||||
else if(type == SANE_TYPE_INT)
|
||||
return std::to_string(*(int*)value);
|
||||
else if(type == SANE_TYPE_FIXED)
|
||||
return std::to_string(*(double*)value);
|
||||
else if(type == SANE_TYPE_STRING)
|
||||
return (char*)value;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
std::string sane_opt_provider::sane_value_2_readable_text(const char* type, void* value)
|
||||
{
|
||||
if(strcmp(type, JSON_SANE_TYPE_BOOL) == 0)
|
||||
return *(bool*)value ? "true" : "false";
|
||||
|
@ -31,6 +82,58 @@ std::string sane_opt_provider::sane_value_2_text(const char* type, void* value)
|
|||
else
|
||||
return "";
|
||||
}
|
||||
std::string sane_opt_provider::sane_value_from_readable_text(SANE_Value_Type type, const char* text)
|
||||
{
|
||||
std::string val("");
|
||||
|
||||
if(type == SANE_TYPE_BOOL)
|
||||
{
|
||||
bool v = strcmp(text, "true") == 0;
|
||||
val = std::string((char*)&v, sizeof(v));
|
||||
}
|
||||
else if(type == SANE_TYPE_INT)
|
||||
{
|
||||
int v = atoi(text);
|
||||
val = std::string((char*)&v, sizeof(v));
|
||||
}
|
||||
else if(type == SANE_TYPE_FIXED)
|
||||
{
|
||||
double v = atof(text);
|
||||
val = std::string((char*)&v, sizeof(v));
|
||||
}
|
||||
else if(type == SANE_TYPE_STRING)
|
||||
{
|
||||
val = text;
|
||||
}
|
||||
|
||||
return std::move(val);
|
||||
}
|
||||
std::string sane_opt_provider::sane_value_from_readable_text(const char* type, const char* text)
|
||||
{
|
||||
std::string val("");
|
||||
|
||||
if(strcmp(type, JSON_SANE_TYPE_BOOL) == 0)
|
||||
{
|
||||
bool v = strcmp(text, "true") == 0;
|
||||
val = std::string((char*)&v, sizeof(v));
|
||||
}
|
||||
else if(strcmp(type, JSON_SANE_TYPE_INT) == 0)
|
||||
{
|
||||
int v = atoi(text);
|
||||
val = std::string((char*)&v, sizeof(v));
|
||||
}
|
||||
else if(strcmp(type, JSON_SANE_TYPE_FIXED) == 0)
|
||||
{
|
||||
double v = atof(text);
|
||||
val = std::string((char*)&v, sizeof(v));
|
||||
}
|
||||
else if(strcmp(type, JSON_SANE_TYPE_STRING) == 0)
|
||||
{
|
||||
val = text;
|
||||
}
|
||||
|
||||
return std::move(val);
|
||||
}
|
||||
bool sane_opt_provider::set_opt_value(gb_json* opt, void* value, const char* key)
|
||||
{
|
||||
std::string type("");
|
||||
|
@ -89,6 +192,105 @@ bool sane_opt_provider::is_opt_value_equal(gb_json* opt, void* v1, void* v2)
|
|||
|
||||
return ret;
|
||||
}
|
||||
std::string sane_opt_provider::option_value(gb_json* jsn, bool def_val, SANE_Value_Type* type)
|
||||
{
|
||||
std::string vt(""), key(def_val ? "default" : "cur");
|
||||
|
||||
jsn->get_value("type", vt);
|
||||
if (vt == "bool")
|
||||
{
|
||||
bool v = false;
|
||||
jsn->get_value(key.c_str(), v);
|
||||
vt = std::string((char*)&v, sizeof(v));
|
||||
if(type)
|
||||
*type = SANE_TYPE_BOOL;
|
||||
}
|
||||
else if (vt == "int")
|
||||
{
|
||||
int v = 0;
|
||||
jsn->get_value(key.c_str(), v);
|
||||
vt = std::string((char*)&v, sizeof(v));
|
||||
if(type)
|
||||
*type = SANE_TYPE_INT;
|
||||
}
|
||||
else if (vt == "float")
|
||||
{
|
||||
double v = .0f;
|
||||
jsn->get_value(key.c_str(), v);
|
||||
vt = std::string((char*)&v, sizeof(v));
|
||||
if(type)
|
||||
*type = SANE_TYPE_FIXED;
|
||||
}
|
||||
else if (vt == "string")
|
||||
{
|
||||
if (!jsn->get_value(key.c_str(), vt))
|
||||
vt = "";
|
||||
if(type)
|
||||
*type = SANE_TYPE_STRING;
|
||||
}
|
||||
else
|
||||
{
|
||||
vt = "";
|
||||
}
|
||||
|
||||
return std::move(vt);
|
||||
}
|
||||
std::string sane_opt_provider::get_all_values(gb_json* opt, SANE_Constraint_Type* constraint, SANE_Value_Type* type)
|
||||
{
|
||||
std::string vt(""), value("");
|
||||
SANE_Value_Type t = SANE_TYPE_BOOL;
|
||||
gb_json *range = nullptr, *child = nullptr;
|
||||
|
||||
if(!type)
|
||||
type = &t;
|
||||
value = sane_opt_provider::option_value(opt, false, type);
|
||||
opt->get_value("range", range);
|
||||
if(*type == SANE_TYPE_STRING)
|
||||
{
|
||||
value.append(3, '\0');
|
||||
utils::add_2_string_array(value, sane_opt_provider::option_value(opt, true).c_str());
|
||||
if(range)
|
||||
{
|
||||
if(constraint)
|
||||
*constraint = SANE_CONSTRAINT_STRING_LIST;
|
||||
|
||||
child = range->first_child();
|
||||
while(child)
|
||||
{
|
||||
child->value(vt);
|
||||
utils::add_2_string_array(value, vt.c_str());
|
||||
child->release();
|
||||
child = range->next_child();
|
||||
}
|
||||
range->release();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value += sane_opt_provider::option_value(opt, true);
|
||||
if(range)
|
||||
{
|
||||
bool isrng = false;
|
||||
if(*type == SANE_TYPE_BOOL)
|
||||
{
|
||||
get_range_values<bool>(value, range, &isrng);
|
||||
}
|
||||
else if(*type == SANE_TYPE_INT)
|
||||
{
|
||||
get_range_values<int>(value, range, &isrng);
|
||||
}
|
||||
else if(*type == SANE_TYPE_FIXED)
|
||||
{
|
||||
get_range_values<double>(value, range, &isrng);
|
||||
}
|
||||
range->release();
|
||||
if(constraint)
|
||||
*constraint = isrng ? SANE_CONSTRAINT_RANGE : SANE_CONSTRAINT_WORD_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(value);
|
||||
}
|
||||
|
||||
bool sane_opt_provider::set_opt_json_text(char* txt)
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <string>
|
||||
#include <map>
|
||||
#include <base/utils.h> // for refer
|
||||
#include <sane/sane_ex.h>
|
||||
|
||||
class gb_json;
|
||||
|
||||
|
@ -24,9 +25,14 @@ protected:
|
|||
public:
|
||||
sane_opt_provider();
|
||||
|
||||
static std::string sane_value_2_text(const char* type, void* value); // convert to readable text. e.g. bool to "true" or "false", ...
|
||||
static std::string sane_value_2_readable_text(SANE_Value_Type type, void* value); // convert to readable text. e.g. bool to "true" or "false", ...
|
||||
static std::string sane_value_2_readable_text(const char* type, void* value); // convert to readable text. e.g. bool to "true" or "false", ...
|
||||
static std::string sane_value_from_readable_text(SANE_Value_Type type, const char* text); // convert from readable text. e.g. bool to "true" or "false", ...
|
||||
static std::string sane_value_from_readable_text(const char* type, const char* text); // convert from readable text. e.g. bool to "true" or "false", ...
|
||||
static bool set_opt_value(gb_json* opt, void* value, const char* key = "cur");
|
||||
static bool is_opt_value_equal(gb_json* opt, void* v1, void* v2);
|
||||
static std::string option_value(gb_json* jsn, bool def_val, SANE_Value_Type* type = nullptr);
|
||||
static std::string get_all_values(gb_json* opt, SANE_Constraint_Type* constraint, SANE_Value_Type* type);
|
||||
|
||||
protected:
|
||||
virtual ~sane_opt_provider();
|
||||
|
|
|
@ -1251,7 +1251,7 @@ void device_option::insert_option(gb_json* opt, sane_opt_provider* from, const c
|
|||
// std::string type("");
|
||||
// opt->get_value("type", type);
|
||||
// val.resize(size);
|
||||
// type = sane_opt_provider::sane_value_2_text(type.c_str(), &val[0]);
|
||||
// type = sane_opt_provider::sane_value_2_readable_text(type.c_str(), &val[0]);
|
||||
// write_log("Set option '%s' to default value: '%s'\n", opt->key().c_str(), type.c_str());
|
||||
// from->set_value(opt->key().c_str(), &val[0]);
|
||||
// sane_opt_provider::set_opt_value(opt, &val[0]);
|
||||
|
@ -1823,41 +1823,6 @@ bool device_option::is_hidden_option(gb_json* opt)
|
|||
return hidden;
|
||||
}
|
||||
|
||||
std::string device_option::option_value(gb_json* jsn, bool def_val)
|
||||
{
|
||||
std::string type(""), key(def_val ? "default" : "cur");
|
||||
|
||||
jsn->get_value("type", type);
|
||||
if (type == "bool")
|
||||
{
|
||||
bool v = false;
|
||||
jsn->get_value(key.c_str(), v);
|
||||
type = std::string((char*)&v, sizeof(v));
|
||||
}
|
||||
else if (type == "int")
|
||||
{
|
||||
int v = 0;
|
||||
jsn->get_value(key.c_str(), v);
|
||||
type = std::string((char*)&v, sizeof(v));
|
||||
}
|
||||
else if (type == "float")
|
||||
{
|
||||
double v = .0f;
|
||||
jsn->get_value(key.c_str(), v);
|
||||
type = std::string((char*)&v, sizeof(v));
|
||||
}
|
||||
else if (type == "string")
|
||||
{
|
||||
if (!jsn->get_value(key.c_str(), type))
|
||||
type = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
type = "";
|
||||
}
|
||||
|
||||
return std::move(type);
|
||||
}
|
||||
void device_option::revise_number_type(gb_json* opt, bool to_double)
|
||||
{
|
||||
gb_json* child = nullptr;
|
||||
|
@ -1993,7 +1958,7 @@ bool device_option::refine_data(const char* name, void* value)
|
|||
{
|
||||
std::string type(""), org(""), result("");
|
||||
child->get_value("type", type);
|
||||
org = sane_opt_provider::sane_value_2_text(type.c_str(), value);
|
||||
org = sane_opt_provider::sane_value_2_readable_text(type.c_str(), value);
|
||||
if (type == JSON_SANE_TYPE_BOOL)
|
||||
{
|
||||
refined = refine_data_to_range<bool>(child, value);
|
||||
|
@ -2012,7 +1977,7 @@ bool device_option::refine_data(const char* name, void* value)
|
|||
}
|
||||
if(refined)
|
||||
{
|
||||
result = sane_opt_provider::sane_value_2_text(type.c_str(), value);
|
||||
result = sane_opt_provider::sane_value_2_readable_text(type.c_str(), value);
|
||||
write_log("Refine value of '%s' from '%s' to '%s'.\n", name, org.c_str(), result.c_str());
|
||||
}
|
||||
|
||||
|
@ -2021,7 +1986,7 @@ bool device_option::refine_data(const char* name, void* value)
|
|||
|
||||
return refined;
|
||||
}
|
||||
int device_option::update_data(const char* name, void* value, bool reorder_if_need)
|
||||
int device_option::update_data(const char* name, void* value, bool reorder_if_need, bool from_user)
|
||||
{
|
||||
int err = SCANNER_ERR_NO_DATA;
|
||||
|
||||
|
@ -2040,8 +2005,8 @@ int device_option::update_data(const char* name, void* value, bool reorder_if_ne
|
|||
if (child)
|
||||
{
|
||||
bool ro = false;
|
||||
if ((child->get_value("readonly", ro) && ro)
|
||||
|| (child->get_value("auth", err) && user_ && !user_(err)))
|
||||
if (from_user && ((child->get_value("readonly", ro) && ro)
|
||||
|| (child->get_value("auth", err) && user_ && !user_(err))))
|
||||
{
|
||||
err = SCANNER_ERR_ACCESS_DENIED;
|
||||
|
||||
|
@ -2050,14 +2015,14 @@ int device_option::update_data(const char* name, void* value, bool reorder_if_ne
|
|||
}
|
||||
else
|
||||
{
|
||||
std::string pre(device_option::option_value(child, false));
|
||||
std::string pre(sane_opt_provider::option_value(child, false));
|
||||
bool changed = false;
|
||||
|
||||
// pass to sane_opt_provider ...
|
||||
err = update_provider_value(name, value);
|
||||
|
||||
child->get_value("type", type);
|
||||
write_log("set option '%s' value to '%s' = %d.\n", name, sane_opt_provider::sane_value_2_text(type.c_str(), value).c_str(), err);
|
||||
write_log("set option '%s' value to '%s' = %d.\n", name, sane_opt_provider::sane_value_2_readable_text(type.c_str(), value).c_str(), err);
|
||||
|
||||
if (err == SCANNER_ERR_OK || err == SCANNER_ERR_NOT_EXACT
|
||||
|| err == SCANNER_ERR_RELOAD_IMAGE_PARAM || err == SCANNER_ERR_RELOAD_OPT_PARAM
|
||||
|
@ -2165,7 +2130,7 @@ int device_option::restore(sane_opt_provider* holder)
|
|||
// && is_auto_restore_default(child)
|
||||
)
|
||||
{
|
||||
std::string val(device_option::option_value(child, true));
|
||||
std::string val(sane_opt_provider::option_value(child, true));
|
||||
update_data(child->key().c_str(), &val[0], false);
|
||||
}
|
||||
child->release();
|
||||
|
@ -2207,6 +2172,25 @@ bool device_option::is_auto_restore_default(gb_json* jsn)
|
|||
|
||||
return support;
|
||||
}
|
||||
int device_option::sane_id_from_name(const char* name)
|
||||
{
|
||||
gb_json* jsn = now_ ? now_ : origin_;
|
||||
int sn = -1;
|
||||
|
||||
if(jsn)
|
||||
{
|
||||
gb_json* child = nullptr;
|
||||
|
||||
jsn->get_value(name, child);
|
||||
if(child)
|
||||
{
|
||||
sn = jsn->index(child) + 1;
|
||||
child->release();
|
||||
}
|
||||
}
|
||||
|
||||
return sn;
|
||||
}
|
||||
std::string device_option::get_name_by_sane_id(int sane_ind)
|
||||
{
|
||||
std::string value("");
|
||||
|
@ -2247,7 +2231,7 @@ std::string device_option::get_option_value_type(const char* name, size_t* size)
|
|||
|
||||
return std::move(value);
|
||||
}
|
||||
std::string device_option::get_option_value(const char* name, int type, int* size, void* in_data)
|
||||
std::string device_option::get_option_value(const char* name, int type, int* size, void* in_data, SANE_Constraint_Type *constraint)
|
||||
{
|
||||
std::string value("");
|
||||
gb_json* jsn = now_ ? now_ : origin_;
|
||||
|
@ -2264,10 +2248,13 @@ std::string device_option::get_option_value(const char* name, int type, int* siz
|
|||
{
|
||||
if (is_hidden_option(child)) // The option count must stay the same in SANE protocol, replace hidden option with meaninless option here
|
||||
{
|
||||
char key[40] = { 0 };
|
||||
|
||||
child->get_value("group", value);
|
||||
child->release();
|
||||
child = device_option::meaningless_option(value.c_str());
|
||||
child->key() = "hidden-" + std::to_string(++hidden);
|
||||
sprintf(key, "%p-%d", this, ++hidden);
|
||||
child->key() = key; // "hidden-" + std::to_string(++hidden); // the same hidden id ...
|
||||
}
|
||||
filter->set_value(child->key().c_str(), child);
|
||||
child->release();
|
||||
|
@ -2293,6 +2280,10 @@ std::string device_option::get_option_value(const char* name, int type, int* siz
|
|||
{
|
||||
if (type == SANE_ACTION_GET_ENTIRE_JSON)
|
||||
value = child->to_string();
|
||||
else if(type == SANE_ACTION_GET_ALL_VALUES)
|
||||
{
|
||||
value = sane_opt_provider::get_all_values(child, constraint, nullptr);
|
||||
}
|
||||
else if (child->get_value("ownread", own_read) && own_read)
|
||||
{
|
||||
if (src_.count(name))
|
||||
|
@ -2307,7 +2298,7 @@ std::string device_option::get_option_value(const char* name, int type, int* siz
|
|||
}
|
||||
}
|
||||
else
|
||||
value = device_option::option_value(child, type == SANE_ACTION_GET_DEFAULT_VALUE);
|
||||
value = sane_opt_provider::option_value(child, type == SANE_ACTION_GET_DEFAULT_VALUE);
|
||||
|
||||
if (size)
|
||||
{
|
||||
|
@ -2362,7 +2353,7 @@ std::string device_option::get_option_value_type(int sane_ind, size_t* size)
|
|||
|
||||
return std::move(value);
|
||||
}
|
||||
std::string device_option::get_option_value(int sane_ind, int type, int* size, void* in_data)
|
||||
std::string device_option::get_option_value_by_id(int sane_ind, int type, int* size, void* in_data)
|
||||
{
|
||||
std::string value("");
|
||||
|
||||
|
|
|
@ -202,7 +202,6 @@ class device_option : public refer
|
|||
bool is_hidden_option(gb_json* opt);
|
||||
|
||||
protected:
|
||||
static std::string option_value(gb_json* jsn, bool def_val);
|
||||
static void revise_number_type(gb_json* opt, bool to_double);
|
||||
|
||||
template<class T>
|
||||
|
@ -376,16 +375,17 @@ public:
|
|||
bool add(sane_opt_provider* sop, bool apply_default_val = true);
|
||||
bool remove(sane_opt_provider* sop);
|
||||
bool refine_data(const char* name, void* value); // return true if the 'value' is out of range and refined it in the range
|
||||
int update_data(const char* name, void* value, bool reorder_if_need = true); // return scanner_err. name and value would be null if invoked for language changed
|
||||
int update_data(const char* name, void* value, bool reorder_if_need = true, bool from_user = true); // return scanner_err. name and value would be null if invoked for language changed
|
||||
int restore(sane_opt_provider* holder); //
|
||||
|
||||
int count(void); // return option count
|
||||
bool is_auto_restore_default(gb_json* jsn);
|
||||
int sane_id_from_name(const char* name);
|
||||
std::string get_name_by_sane_id(int sane_ind);
|
||||
std::string get_option_value_type(const char* name, size_t* size = nullptr);
|
||||
std::string get_option_value_type(int sane_ind, size_t* size = nullptr);
|
||||
std::string get_option_field_string(const char* name, const char* key);
|
||||
std::string get_option_value(const char* name, int type/*OPT_VAL_xxx*/, int* size = nullptr, void* in_data = nullptr); // return whole json-text if name was null
|
||||
std::string get_option_value(int sane_ind, int type/*OPT_VAL_xxx*/, int* size = nullptr, void* in_data = nullptr); // return whole json-text if name was null
|
||||
std::string get_option_value(const char* name, int type/*SANE_ACTION_GET_xxx*/, int* size = nullptr, void* in_data = nullptr, SANE_Constraint_Type *constraint = nullptr/*used in SANE_ACTION_GET_ALL_VALUES*/); // return whole json-text if name was null
|
||||
std::string get_option_value_by_id(int sane_ind, int type/*SANE_ACTION_GET_xxx*/, int* size = nullptr, void* in_data = nullptr); // return whole json-text if name was null
|
||||
};
|
||||
|
||||
|
|
359
ui/dev_menu.cpp
359
ui/dev_menu.cpp
|
@ -3,6 +3,7 @@
|
|||
#include <string.h>
|
||||
// #include "Displaydef.h"
|
||||
#include <base/words.h>
|
||||
#include <sane/sane_name.h>
|
||||
#include <base/ui.h>
|
||||
#include "keymonitor.h"
|
||||
#include "Lcd.h"
|
||||
|
@ -73,7 +74,7 @@ void dev_menu::set_parent(dev_menu* parent)
|
|||
}
|
||||
}
|
||||
|
||||
bool dev_menu::add_menu(const char* text, int id)
|
||||
bool dev_menu::add_menu(const char* text, int id, int pos)
|
||||
{
|
||||
int ind = find_item(text);
|
||||
|
||||
|
@ -85,11 +86,14 @@ bool dev_menu::add_menu(const char* text, int id)
|
|||
mi.id = id;
|
||||
mi.leaf = true;
|
||||
mi.text = text;
|
||||
items_.push_back(mi);
|
||||
if(pos < 0 || pos >= items_.size())
|
||||
items_.push_back(mi);
|
||||
else
|
||||
items_.insert(items_.begin() + pos, mi);
|
||||
|
||||
return true;
|
||||
}
|
||||
bool dev_menu::add_menu(const char* text, dev_menu* submenu)
|
||||
bool dev_menu::add_menu(const char* text, dev_menu* submenu, int pos)
|
||||
{
|
||||
int ind = find_item(text);
|
||||
|
||||
|
@ -101,7 +105,10 @@ bool dev_menu::add_menu(const char* text, dev_menu* submenu)
|
|||
mi.child = submenu;
|
||||
mi.leaf = false;
|
||||
mi.text = text;
|
||||
items_.push_back(mi);
|
||||
if(pos < 0 || pos >= items_.size())
|
||||
items_.push_back(mi);
|
||||
else
|
||||
items_.insert(items_.begin() + pos, mi);
|
||||
submenu->add_ref();
|
||||
submenu->set_parent(this);
|
||||
|
||||
|
@ -173,13 +180,79 @@ void dev_menu::set_default_pos(std::function<void(dev_menu*)> f)
|
|||
{
|
||||
reset_pos_ = f;
|
||||
}
|
||||
void dev_menu::clear(std::function<void(const char*)> erase_func)
|
||||
{
|
||||
for(auto& v: items_)
|
||||
{
|
||||
if(v.leaf)
|
||||
{
|
||||
if(erase_func)
|
||||
erase_func(v.text.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
v.child->clear(erase_func);
|
||||
v.child->release();
|
||||
}
|
||||
}
|
||||
items_.clear();
|
||||
}
|
||||
int dev_menu::count(void)
|
||||
{
|
||||
return items_.size();
|
||||
}
|
||||
std::string& dev_menu::name(void)
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
dev_menu* dev_menu::get_sub_menu(const char* text)
|
||||
{
|
||||
dev_menu* sub = nullptr;
|
||||
|
||||
dev_menu* dev_menu::enter(int* id)
|
||||
for(auto& v: items_)
|
||||
{
|
||||
if(v.text == text)
|
||||
{
|
||||
if(!v.leaf)
|
||||
{
|
||||
sub = v.child;
|
||||
sub->add_ref();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sub;
|
||||
}
|
||||
dev_menu* dev_menu::get_sub_menu(int index, std::string* title)
|
||||
{
|
||||
dev_menu* sub = nullptr;
|
||||
|
||||
if(title)
|
||||
*title = "";
|
||||
|
||||
if(index >= 0 && index < items_.size())
|
||||
{
|
||||
if(!items_[index].leaf)
|
||||
{
|
||||
sub = items_[index].child;
|
||||
sub->add_ref();
|
||||
}
|
||||
if(title)
|
||||
*title = items_[index].text;
|
||||
}
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
||||
dev_menu* dev_menu::enter(int* id, std::string* text)
|
||||
{
|
||||
dev_menu *menu = this;
|
||||
|
||||
if(id)
|
||||
*id = -1;
|
||||
if(text)
|
||||
*text = "";
|
||||
if(cur_ >= 0 && cur_ < items_.size())
|
||||
{
|
||||
if(items_[cur_].leaf)
|
||||
|
@ -189,9 +262,12 @@ dev_menu* dev_menu::enter(int* id)
|
|||
if(parent_)
|
||||
menu = parent_;
|
||||
}
|
||||
else if(id)
|
||||
else
|
||||
{
|
||||
*id = items_[cur_].id;
|
||||
if(id)
|
||||
*id = items_[cur_].id;
|
||||
if(text)
|
||||
*text = items_[cur_].text;
|
||||
if(check_item_)
|
||||
sel_ = cur_;
|
||||
}
|
||||
|
@ -486,7 +562,11 @@ ui_mgr::ui_mgr() : disp_data_("lcd-msg")
|
|||
{
|
||||
utils::log_mem_info("status message", pack, pack->whole_size());
|
||||
|
||||
if(pack->msg == devui::UI_STATUS_SCANNING)
|
||||
if(pack->msg == devui::UI_STATUS_PEER_CONNECTED)
|
||||
{
|
||||
send_paper_count();
|
||||
}
|
||||
else if(pack->msg == devui::UI_STATUS_SCANNING)
|
||||
{
|
||||
devui::LPSCANSTREAM scan = (devui::LPSCANSTREAM)pack->data;
|
||||
scanning_ = scan->mode != devui::SCAN_STOPPED;
|
||||
|
@ -514,11 +594,13 @@ ui_mgr::ui_mgr() : disp_data_("lcd-msg")
|
|||
display_scan_title();
|
||||
perm_data_->set_speed(scan->speed);
|
||||
paper_total_ = 0;
|
||||
send_paper_count();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
perm_data_->save();
|
||||
send_paper_count();
|
||||
if(scan->err)
|
||||
{
|
||||
devui::STATMSG msg;
|
||||
|
@ -568,6 +650,37 @@ ui_mgr::ui_mgr() : disp_data_("lcd-msg")
|
|||
if(((devui::LPSTATMSG)pack->data)->msg_words_id == ID_WORDS_STATUS_SCANNER_CONN + 1)
|
||||
set_ready_status_enabled(true);
|
||||
}
|
||||
else if(pack->msg == devui::UI_STATUS_READY)
|
||||
{
|
||||
set_ready_status_enabled(true);
|
||||
}
|
||||
else if(pack->msg == devui::UI_CMD_ADD_MENU)
|
||||
{
|
||||
add_menu((devui::LPOPTMENU)pack->data);
|
||||
}
|
||||
else if(pack->msg == devui::UI_CMD_SET_OPTION_VALUE)
|
||||
{
|
||||
char *name = (char*)pack->data;
|
||||
|
||||
for(int i = 0; i < root_->count(); ++i)
|
||||
{
|
||||
dev_menu* m = root_->get_sub_menu(i);
|
||||
if(m)
|
||||
{
|
||||
bool over = false;
|
||||
if(m->name() == name)
|
||||
{
|
||||
char* val = utils::next_string(name);
|
||||
over = true;
|
||||
m->select(val, true);
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "select menu '%s' to '%s'\n", name, val);
|
||||
}
|
||||
m->release();
|
||||
if(over)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(pack->msg == devui::UI_STATUS_PEER_CLOSED)
|
||||
{
|
||||
peer_connected_ = *(bool*)pack->data;
|
||||
|
@ -582,16 +695,6 @@ ui_mgr::ui_mgr() : disp_data_("lcd-msg")
|
|||
if(!display_status(&msg))
|
||||
set_ready_status_enabled(true);
|
||||
}
|
||||
else if(pack->msg == devui::UI_CMD_GET_HISTORY_COUNT)
|
||||
{
|
||||
uint32_t cnt = (uint32_t)perm_data_->history_count();
|
||||
devui::send_message(pack->msg, (uint8_t*)&cnt, sizeof(cnt));
|
||||
}
|
||||
else if(pack->msg == devui::UI_CMD_GET_ROLLER_COUNT)
|
||||
{
|
||||
uint32_t cnt = (uint32_t)perm_data_->roller_count();
|
||||
devui::send_message(pack->msg, (uint8_t*)&cnt, sizeof(cnt));
|
||||
}
|
||||
};
|
||||
devui::init_ui(statu, true);
|
||||
}
|
||||
|
@ -608,19 +711,65 @@ ui_mgr::~ui_mgr()
|
|||
utils::uninit();
|
||||
}
|
||||
|
||||
bool ui_mgr::do_menu_command(int cmd)
|
||||
void ui_mgr::add_menu(void* data)
|
||||
{
|
||||
devui::LPOPTMENU opt = (devui::LPOPTMENU)data;
|
||||
char *title = opt->name + opt->title_off,
|
||||
*val = utils::next_string(title);
|
||||
dev_menu *menu = root_->get_sub_menu(title);
|
||||
std::string cur("");
|
||||
auto f = [this](MEMNU_CMD_HANDLER_PARAM) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
set_option_value(menu->name().c_str(), text, strlen(text));
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
root_->remove_menu(title);
|
||||
if(menu)
|
||||
{
|
||||
auto ef = [this](const char* text) -> void
|
||||
{
|
||||
handler_s_.erase(text);
|
||||
};
|
||||
menu->clear(ef);
|
||||
menu->release();
|
||||
menu = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
handler_s_.erase(title);
|
||||
}
|
||||
|
||||
menu = new dev_menu(true);
|
||||
menu->name() = opt->name;
|
||||
while(val)
|
||||
{
|
||||
if(opt->cur_sel-- == 0)
|
||||
cur = val;
|
||||
handler_s_[val] = f;
|
||||
menu->add_menu(val, MENU_ID_BY_TEXT);
|
||||
val = utils::next_string(val);
|
||||
}
|
||||
menu->select(cur.c_str(), true);
|
||||
root_->add_menu(title, menu, opt->pos);
|
||||
menu->release();
|
||||
}
|
||||
bool ui_mgr::do_menu_command(int cmd, const char* text)
|
||||
{
|
||||
bool holdui = false;
|
||||
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "Do menu command: %s\n", menu_command::command_string(cmd).c_str());
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "Do menu command: %s(%s - %s)\n", menu_command::command_string(cmd).c_str(), cur_->name().c_str(), text);
|
||||
|
||||
if(cmd >= menu_command::MENU_CMD_ID_SEQ_0 && cmd <= menu_command::MENU_CMD_ID_SEQ_LAST)
|
||||
{
|
||||
if(handler_.count(menu_command::MENU_CMD_ID_SEQ_0))
|
||||
holdui = handler_[menu_command::MENU_CMD_ID_SEQ_0](cur_, cmd - menu_command::MENU_CMD_ID_SEQ_0);
|
||||
holdui = handler_[menu_command::MENU_CMD_ID_SEQ_0](cur_, cmd - menu_command::MENU_CMD_ID_SEQ_0, text);
|
||||
}
|
||||
else if(handler_.count(cmd))
|
||||
holdui = handler_[cmd](cur_, cmd);
|
||||
holdui = handler_[cmd](cur_, cmd, text);
|
||||
else if(text && *text && handler_s_.count(text))
|
||||
holdui = handler_s_[text](cur_, cmd, text);
|
||||
|
||||
// at last, we return to main menu OR parent ?
|
||||
if(holdui)
|
||||
|
@ -634,127 +783,35 @@ bool ui_mgr::do_menu_command(int cmd)
|
|||
|
||||
return holdui;
|
||||
}
|
||||
bool ui_mgr::set_option_value(const char* name, const char* val, size_t size)
|
||||
{
|
||||
std::string str(name);
|
||||
|
||||
str.append(1, '\0');
|
||||
str += std::string(val, size);
|
||||
str.append(2, '\0');
|
||||
|
||||
return devui::send_message(devui::UI_CMD_SET_OPTION_VALUE, (uint8_t*)&str[0], str.length());
|
||||
}
|
||||
bool ui_mgr::send_paper_count(void)
|
||||
{
|
||||
std::string val(std::to_string(perm_data_->roller_count()));
|
||||
|
||||
set_option_value(SANE_OPT_NAME(ROLLER_COUNT), val.c_str(), val.length());
|
||||
val = std::to_string(perm_data_->history_count());
|
||||
|
||||
return set_option_value(SANE_OPT_NAME(HISTORY_COUNT), val.c_str(), val.length());
|
||||
}
|
||||
void ui_mgr::init(void)
|
||||
{
|
||||
dev_menu *child = nullptr;
|
||||
|
||||
root_ = new dev_menu();
|
||||
|
||||
// 分纸强度(低中高)
|
||||
{
|
||||
child = new dev_menu(true);
|
||||
child->add_menu(WORDS_MENU_LOW, menu_command::MENU_CMD_ID_SEPARATE_LOW);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
handler_[menu_command::MENU_CMD_ID_SEPARATE_LOW] = f;
|
||||
}
|
||||
child->add_menu(WORDS_MENU_MID, menu_command::MENU_CMD_ID_SEPARATE_MID);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
handler_[menu_command::MENU_CMD_ID_SEPARATE_MID] = f;
|
||||
}
|
||||
child->add_menu(WORDS_MENU_HIGH, menu_command::MENU_CMD_ID_SEPARATE_HIGH);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
handler_[menu_command::MENU_CMD_ID_SEPARATE_HIGH] = f;
|
||||
}
|
||||
child->select(WORDS_MENU_MID);
|
||||
root_->add_menu(WORDS_MENU_SEPARATE_STRENGTH, child);
|
||||
child->release();
|
||||
}
|
||||
// 休眠时间(不休眠,5min, 10min, 20min, 30min, 1h, 2h, 4h)
|
||||
{
|
||||
child = new dev_menu(true);
|
||||
child->add_menu(WORDS_MENU_SLEEP_NONE, menu_command::MENU_CMD_ID_SLEEP_NEVER);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
handler_[menu_command::MENU_CMD_ID_SLEEP_NEVER] = f;
|
||||
}
|
||||
child->add_menu(WORDS_MENU_SLEEP_NOW, menu_command::MENU_CMD_ID_SLEEP_IMMEDIATELY);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
handler_[menu_command::MENU_CMD_ID_SLEEP_IMMEDIATELY] = f;
|
||||
}
|
||||
child->add_menu(WORDS_MENU_SLEEP_5_MIN, menu_command::MENU_CMD_ID_SLEEP_5MIN);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
handler_[menu_command::MENU_CMD_ID_SLEEP_5MIN] = f;
|
||||
}
|
||||
child->add_menu(WORDS_MENU_SLEEP_10_MIN, menu_command::MENU_CMD_ID_SLEEP_10MIN);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
handler_[menu_command::MENU_CMD_ID_SLEEP_10MIN] = f;
|
||||
}
|
||||
child->add_menu(WORDS_MENU_SLEEP_20_MIN, menu_command::MENU_CMD_ID_SLEEP_20MIN);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
handler_[menu_command::MENU_CMD_ID_SLEEP_20MIN] = f;
|
||||
}
|
||||
child->add_menu(WORDS_MENU_SLEEP_30_MIN, menu_command::MENU_CMD_ID_SLEEP_30MIN);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
handler_[menu_command::MENU_CMD_ID_SLEEP_30MIN] = f;
|
||||
}
|
||||
child->add_menu(WORDS_MENU_SLEEP_1_HOUR, menu_command::MENU_CMD_ID_SLEEP_1H);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
handler_[menu_command::MENU_CMD_ID_SLEEP_1H] = f;
|
||||
}
|
||||
child->add_menu(WORDS_MENU_SLEEP_2_HOUR, menu_command::MENU_CMD_ID_SLEEP_2H);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
handler_[menu_command::MENU_CMD_ID_SLEEP_2H] = f;
|
||||
}
|
||||
child->add_menu(WORDS_MENU_SLEEP_4_HOUR, menu_command::MENU_CMD_ID_SLEEP_4H);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
handler_[menu_command::MENU_CMD_ID_SLEEP_4H] = f;
|
||||
}
|
||||
child->select(WORDS_MENU_SLEEP_NONE);
|
||||
root_->add_menu(WORDS_MENU_POWER, child);
|
||||
child->release();
|
||||
}
|
||||
|
||||
// 计数模式、手动模式、清理纸道、历史张数、滚轴张数、清除滚轴张数(确定,取消)、进入休眠、关机
|
||||
root_->add_menu(WORDS_MENU_COUNT_MODE, menu_command::MENU_CMD_ID_COUNT_MODE);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
auto f = [this](MEMNU_CMD_HANDLER_PARAM) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
// 保持界面:第一行显示当前保持的功能
|
||||
// 第二行显示当前功能的信息,过程中只更新该行
|
||||
|
@ -791,7 +848,7 @@ void ui_mgr::init(void)
|
|||
}
|
||||
root_->add_menu(WORDS_MENU_MANUAL_MODE, menu_command::MENU_CMD_ID_HANDLE_MODE);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
auto f = [this](MEMNU_CMD_HANDLER_PARAM) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
@ -799,7 +856,7 @@ void ui_mgr::init(void)
|
|||
}
|
||||
root_->add_menu(WORDS_MENU_CLEAR_PASSWAY, menu_command::MENU_CMD_ID_CLEAR_PASSWAY);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
auto f = [this](MEMNU_CMD_HANDLER_PARAM) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
devui::send_message(devui::UI_CMD_CLEAN_PASSWAY);
|
||||
|
||||
|
@ -809,7 +866,7 @@ void ui_mgr::init(void)
|
|||
}
|
||||
root_->add_menu(WORDS_MENU_HISTORY_COUNT, menu_command::MENU_CMD_ID_GET_HISTORY_COUNT);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
auto f = [this](MEMNU_CMD_HANDLER_PARAM) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
DISPDATA dd;
|
||||
|
||||
|
@ -833,7 +890,7 @@ void ui_mgr::init(void)
|
|||
}
|
||||
root_->add_menu(WORDS_MENU_ROLLER_COUNT, menu_command::MENU_CMD_ID_GET_ROLLER_COUNT);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
auto f = [this](MEMNU_CMD_HANDLER_PARAM) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
DISPDATA dd;
|
||||
char cnt[40] = {0};
|
||||
|
@ -861,9 +918,14 @@ void ui_mgr::init(void)
|
|||
child = new dev_menu(false, false);
|
||||
child->add_menu(WORDS_MENU_YES, menu_command::MENU_CMD_ID_CLEAR_ROLLER_CNT);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
auto f = [this](MEMNU_CMD_HANDLER_PARAM) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
std::string str("");
|
||||
|
||||
perm_data_->clear_roller_count();
|
||||
utils::add_2_string_array(str, SANE_OPT_NAME(ROLLER_COUNT));
|
||||
utils::add_2_string_array(str, "0");
|
||||
devui::send_message(devui::UI_CMD_SET_OPTION_VALUE, (uint8_t*)&str[0], str.length());
|
||||
|
||||
return false;
|
||||
};
|
||||
|
@ -879,7 +941,7 @@ void ui_mgr::init(void)
|
|||
child = new dev_menu(true);
|
||||
child->add_menu(WORDS_MENU_LOW, menu_command::MENU_CMD_ID_LIFTER_LOW);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
auto f = [this](MEMNU_CMD_HANDLER_PARAM) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
@ -887,7 +949,7 @@ void ui_mgr::init(void)
|
|||
}
|
||||
child->add_menu(WORDS_MENU_MID, menu_command::MENU_CMD_ID_LIFTER_MID);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
auto f = [this](MEMNU_CMD_HANDLER_PARAM) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
@ -895,7 +957,7 @@ void ui_mgr::init(void)
|
|||
}
|
||||
child->add_menu(WORDS_MENU_HIGH, menu_command::MENU_CMD_ID_LIFTER_HIGH);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
auto f = [this](MEMNU_CMD_HANDLER_PARAM) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
@ -907,7 +969,7 @@ void ui_mgr::init(void)
|
|||
}
|
||||
// 调整系统时间
|
||||
{
|
||||
auto adjtm = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
auto adjtm = [this](MEMNU_CMD_HANDLER_PARAM) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
int hour = -1,
|
||||
min = -1;
|
||||
|
@ -995,7 +1057,7 @@ void ui_mgr::init(void)
|
|||
child = new dev_menu(false, false);
|
||||
child->add_menu(WORDS_MENU_YES, menu_command::MENU_CMD_ID_SHUTDOWN);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
auto f = [this](MEMNU_CMD_HANDLER_PARAM) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
system("poweroff");
|
||||
|
||||
|
@ -1011,7 +1073,7 @@ void ui_mgr::init(void)
|
|||
|
||||
root_->add_menu(WORDS_MENU_WELCOME, menu_command::MENU_CMD_ID_WELCOME);
|
||||
{
|
||||
auto f = [this](dev_menu* m, int id) -> MENU_CMD_HANDLER_RET
|
||||
auto f = [this](MEMNU_CMD_HANDLER_PARAM) -> MENU_CMD_HANDLER_RET
|
||||
{
|
||||
DISPDATA dd;
|
||||
dd.mask = 0;
|
||||
|
@ -1097,12 +1159,13 @@ void ui_mgr::enter(void)
|
|||
{
|
||||
int id = -1;
|
||||
dev_menu* bef = cur_;
|
||||
std::string text("");
|
||||
|
||||
cur_ = cur_->enter(&id);
|
||||
cur_ = cur_->enter(&id, &text);
|
||||
bef->release();
|
||||
if(id != -1)
|
||||
if(id != -1 || !text.empty())
|
||||
{
|
||||
bool holdui = do_menu_command(id);
|
||||
bool holdui = do_menu_command(id, text.c_str());
|
||||
set_ready_status_enabled(!holdui);
|
||||
}
|
||||
if(cur_ != bef)
|
||||
|
|
|
@ -23,14 +23,16 @@
|
|||
#include <string.h>
|
||||
|
||||
#define MENU_ID_RETURN -1 // ID of menu item that return to parent
|
||||
#define MENU_ID_BY_TEXT -2
|
||||
#define LINK_DEFINE(x, y) x##y
|
||||
#define MEMNU_CMD_HANDLER_PARAM dev_menu* menu, int id
|
||||
#define MENU_CMD_HANDLER_RET bool
|
||||
#define MEMNU_CMD_HANDLER_PARAM dev_menu* menu, int id, const char* text
|
||||
#define MENU_CMD_HANDLER_RET bool // whether hold ui
|
||||
#define MENU_CMD_CALLBACK std::function<MENU_CMD_HANDLER_RET(MEMNU_CMD_HANDLER_PARAM)>
|
||||
|
||||
class dev_menu : public refer
|
||||
{
|
||||
dev_menu* parent_ = nullptr;
|
||||
std::string name_ = "";
|
||||
|
||||
typedef struct _menu_item
|
||||
{
|
||||
|
@ -61,8 +63,8 @@ protected:
|
|||
void set_parent(dev_menu* parent);
|
||||
|
||||
public:
|
||||
bool add_menu(const char* text, int id);
|
||||
bool add_menu(const char* text, dev_menu* submenu);
|
||||
bool add_menu(const char* text, int id, int pos = -1);
|
||||
bool add_menu(const char* text, dev_menu* submenu, int pos = -1);
|
||||
bool remove_menu(const char* text);
|
||||
void set_need_return_parent(bool need);
|
||||
bool move_to(bool next); // true - move to next, false - move to previous. if at end position of move direction, return false
|
||||
|
@ -70,13 +72,20 @@ public:
|
|||
void reset_pos(void);
|
||||
void set_default_pos(int pos = 0);
|
||||
void set_default_pos(std::function<void(dev_menu*)> f);
|
||||
void clear(std::function<void(const char*)> erase_func = std::function<void(const char*)>());
|
||||
int count(void);
|
||||
std::string& name(void);
|
||||
dev_menu* get_sub_menu(const char* text);
|
||||
dev_menu* get_sub_menu(int index, std::string* title = nullptr);
|
||||
|
||||
// Function: access current menu
|
||||
//
|
||||
// Parameter: id - to receive ID of current menu item if leaf, fill '-1' if a submenu
|
||||
//
|
||||
// text - to receive text of current menu if leaf, empty if submenu
|
||||
//
|
||||
// Return: current menu, user should call 'release' after use
|
||||
dev_menu* enter(int* id);
|
||||
dev_menu* enter(int* id, std::string* text);
|
||||
|
||||
// Function: get all menus text
|
||||
//
|
||||
|
@ -111,6 +120,7 @@ class ui_mgr : public refer
|
|||
POINT hold_pos_ = {0, 0};
|
||||
|
||||
std::map<int, MENU_CMD_CALLBACK> handler_;
|
||||
std::map<std::string, MENU_CMD_CALLBACK> handler_s_;
|
||||
std::unique_ptr<Lcd> lcd_;
|
||||
std::unique_ptr<KeyMonitor> keyboard_;
|
||||
|
||||
|
@ -285,7 +295,10 @@ class ui_mgr : public refer
|
|||
};
|
||||
refer_guard<permanent_data> perm_data_;
|
||||
|
||||
bool do_menu_command(int cmd); // return whether should hold UI ?
|
||||
void add_menu(void* data);
|
||||
bool do_menu_command(int cmd, const char* text); // return whether should hold UI ?
|
||||
bool set_option_value(const char* name, const char* val, size_t size);
|
||||
bool send_paper_count(void);
|
||||
void init(void);
|
||||
void clear(void);
|
||||
void refresh_lcd(bool cur_at_top);
|
||||
|
|
53
ui/font.cpp
53
ui/font.cpp
|
@ -806,6 +806,54 @@ namespace custom_font
|
|||
};
|
||||
font_map_["\345\274\200"] = kai;
|
||||
|
||||
static uint8_t ban1[] = {16, 16
|
||||
, 0x80, 0x80, 0xFC, 0x96, 0xE5, 0x84, 0xFC, 0x00, 0xA0, 0x9E, 0x82, 0x82, 0x9E, 0xA0, 0x20, 0x00
|
||||
, 0x80, 0x60, 0x1F, 0x02, 0x4C, 0x80, 0x7F, 0x80, 0x80, 0x43, 0x2C, 0x10, 0x2C, 0x43, 0x80, 0x00
|
||||
};
|
||||
font_map_["\350\210\254"] = ban1;
|
||||
|
||||
static uint8_t ruo[] = {16, 16
|
||||
, 0x00, 0xF2, 0x92, 0x92, 0x92, 0x92, 0x9E, 0x00, 0xF2, 0x92, 0x92, 0x92, 0x92, 0x9E, 0x00, 0x00
|
||||
, 0x00, 0x10, 0x11, 0x4A, 0x88, 0x44, 0x3F, 0x00, 0x10, 0x11, 0x4A, 0x88, 0x44, 0x3F, 0x00, 0x00
|
||||
};
|
||||
font_map_["\345\274\261"] = ruo;
|
||||
|
||||
static uint8_t wu3[] = {16, 16
|
||||
, 0x00, 0x02, 0x42, 0x42, 0x42, 0xC2, 0x7E, 0x42, 0x42, 0x42, 0x42, 0xC2, 0x02, 0x02, 0x00, 0x00
|
||||
, 0x40, 0x40, 0x40, 0x40, 0x78, 0x47, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7F, 0x40, 0x40, 0x40, 0x00
|
||||
};
|
||||
font_map_["\344\272\224"] = wu3;
|
||||
|
||||
static uint8_t shi2[] = {16, 16
|
||||
, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xFF, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00
|
||||
, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
font_map_["\345\215\201"] = shi2;
|
||||
|
||||
static uint8_t ban4[] = {16, 16
|
||||
, 0x00, 0x00, 0x42, 0x44, 0x58, 0x40, 0x40, 0xFF, 0x40, 0x40, 0x50, 0x48, 0x46, 0x00, 0x00, 0x00
|
||||
, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0xFF, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00
|
||||
};
|
||||
font_map_["\345\215\212"] = ban4;
|
||||
|
||||
static uint8_t liang[] = {16, 16
|
||||
, 0x02, 0xE2, 0x22, 0x22, 0x22, 0xFE, 0x22, 0x22, 0x22, 0xFE, 0x22, 0x22, 0x22, 0xE2, 0x02, 0x00
|
||||
, 0x00, 0xFF, 0x00, 0x08, 0x06, 0x01, 0x16, 0x08, 0x06, 0x01, 0x02, 0x4C, 0x80, 0x7F, 0x00, 0x00
|
||||
};
|
||||
font_map_["\344\270\244"] = liang;
|
||||
|
||||
static uint8_t si[] = {16, 16
|
||||
, 0x00, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0x04, 0x04, 0x04, 0xFC, 0x00, 0x00
|
||||
, 0x00, 0x7F, 0x28, 0x24, 0x23, 0x20, 0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x22, 0x7F, 0x00, 0x00
|
||||
};
|
||||
font_map_["\345\233\233"] = si;
|
||||
|
||||
static uint8_t xiao3[] = {16, 16
|
||||
, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x20, 0x40, 0x80, 0x00, 0x00
|
||||
, 0x08, 0x04, 0x03, 0x00, 0x00, 0x40, 0x80, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0E, 0x00
|
||||
};
|
||||
font_map_["\345\260\217"] = xiao3;
|
||||
|
||||
}
|
||||
~font_init()
|
||||
{}
|
||||
|
@ -819,6 +867,7 @@ namespace custom_font
|
|||
return font_map8x8_[str];
|
||||
}
|
||||
|
||||
printf("%s(8) not found\n", str);
|
||||
return custom_font::question8x8;
|
||||
}
|
||||
else if(fs == FONT_SIZE_16)
|
||||
|
@ -827,7 +876,7 @@ namespace custom_font
|
|||
{
|
||||
return font_map_[str];
|
||||
}
|
||||
|
||||
printf("%s(16) not found\n", str);
|
||||
return custom_font::question;
|
||||
}
|
||||
else if(fs == FONT_SIZE_32)
|
||||
|
@ -836,7 +885,7 @@ namespace custom_font
|
|||
{
|
||||
return font_map32x32_[str];
|
||||
}
|
||||
|
||||
printf("%s(32) not found\n", str);
|
||||
return custom_font::question32x32;
|
||||
}
|
||||
|
||||
|
|
|
@ -897,6 +897,10 @@ int async_usb_gadget::last_error(void)
|
|||
{
|
||||
return last_err_;
|
||||
}
|
||||
uint32_t async_usb_gadget::current_session(void)
|
||||
{
|
||||
return session_id_;
|
||||
}
|
||||
|
||||
void async_usb_gadget::get_ep_status(LPEP0REPLYSTATUS status)
|
||||
{
|
||||
|
|
|
@ -122,6 +122,7 @@ public:
|
|||
int stop(void);
|
||||
int write_bulk(data_source_ptr data); // return sent-que length
|
||||
int last_error(void);
|
||||
uint32_t current_session(void);
|
||||
|
||||
void get_ep_status(LPEP0REPLYSTATUS status);
|
||||
};
|
||||
|
|
|
@ -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=20240318")
|
||||
add_defines("VER_BUILD=15")
|
||||
add_defines("VER_DATE=20240321")
|
||||
add_defines("VER_BUILD=21")
|
||||
|
||||
target("conf")
|
||||
set_kind("phony")
|
||||
|
|
Loading…
Reference in New Issue