调整SANE属性结构

This commit is contained in:
gb 2023-10-31 14:51:14 +08:00
parent 64d05ae35c
commit 1ecf5e5795
31 changed files with 1140 additions and 812 deletions

View File

@ -643,7 +643,7 @@ tiny_buffer::tiny_buffer(unsigned int size
, const char* name_leading
, const char* ext
, unsigned int uniq_id)
: size_(size), buf_(nullptr), img_statu_(SANE_Image_Statu_OK)
: size_(size), buf_(nullptr), img_statu_(IMG_STATUS_OK)
{
init(tmp_path, name_leading, ext, uniq_id);
}

View File

@ -181,6 +181,7 @@ typedef struct _img_header
int bits;
int channels;
int line_bytes;
int statu; // SANE_Image_Statu
unsigned bytes;
uint32_t src_id;
}IMH;

View File

@ -166,7 +166,6 @@ hg_scanner::hg_scanner(ScannerSerial serial, const char* dev_name, usb_io* io, i
, firmware_sup_wait_paper_(false),firmware_sup_pick_strength_(false),firmware_sup_log_export_(false),firmware_sup_color_corr_(false),firmware_sup_wake_device_(false)
, firmware_sup_double_img(false),firmware_sup_devs_lock_(false),firmware_sup_dpi_300(false),firmware_sup_dpi_600(false),firmware_sup_auto_speed_(false),firmware_sup_morr_(false)
, firmware_sup_color_fill_(false),firmware_sup_history_cnt(false), is_discardblank(false)
, setting_jsn_(new device_option())
, auto_scan_restore_(false), auto_scan_prev_(is_auto_paper_scan)
{
#if !defined(_WIN32) && !defined(_WIN64) &&defined(x86_64)
@ -280,7 +279,6 @@ hg_scanner::~hg_scanner()
name_ += lang_load_string(ID_STATU_DESC_SCANNER_ERR_DEVICE_IS_CLOSE, nullptr);
notify_ui_working_status(name_.c_str(), SANE_EVENT_SCANNER_CLOSED);
utils::to_log(LOG_LEVEL_DEBUG, "%s(%p) destroyed.\n", name_.c_str(), this);
delete setting_jsn_; // ->release();
}
std::string hg_scanner::temporary_file(char* tail, char* head)
@ -704,18 +702,6 @@ void hg_scanner::init_setting_func_map(void)
setting_map_[SANE_STD_OPT_NAME_MOTOR_VER] = &hg_scanner::setting_get_motor_ver;
setting_map_[SANE_STD_OPT_NAME_INITIAL_BOOT_TIME] = &hg_scanner::setting_get_initial_boot_time;
}
int hg_scanner::restore(const char* name)
{
std::string type(setting_jsn_->get_option_value_type(name)), val("");
int ret = SCANNER_ERR_OK, size = 0;
if (type != JSON_SANE_TYPE_BOOL && type != JSON_SANE_TYPE_INT && type != JSON_SANE_TYPE_FIXED && type != JSON_SANE_TYPE_STRING)
return ret;
ret = set_setting(name, nullptr, true);
return ret;
}
bool hg_scanner::is_to_file(void)
{
return resolution_ > 200
@ -907,42 +893,6 @@ void hg_scanner::working_done(void*)
test_1_paper_ = false;
}
bool hg_scanner::jsn_reorganize()
{
gb_json* paper = nullptr, * range = nullptr;
if (!firmware_sup_wait_paper_ && pid_ == 0x239)
{
erase_option(SANE_STD_OPT_NAME_WAIT_TO_SCAN);
erase_option(SANE_STD_OPT_NAME_WAIT_SCAN_EXIT);
}
if (!firmware_sup_pick_strength_ && pid_ == 0x239)
{
erase_option(SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH);
erase_option(SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE);
erase_option(SANE_STD_OPT_NAME_FEED_STRENGTH);
}
if (!firmware_sup_color_fill_ && (pid_ == 0x239 || pid_ == 0x439))
{
erase_option(SANE_STD_OPT_NAME_IS_FILL_COLOR);
}
if (!firmware_sup_color_corr_ && (pid_ == 0x239 || pid_ == 0x439))
{
erase_option(SANE_STD_OPT_NAME_COLOR_CORRECTION);
}
if (!firmware_sup_morr_)
{
erase_option(SANE_STD_OPT_NAME_RID_MORR);
}
if (pid_ == 0x239 || pid_ == 0x439) //固件不支持防止渗透等级
{
erase_option(SANE_STD_OPT_NAME_ANTI_PERMEATE_LEVEL);
}
erase_option(SANE_STD_OPT_NAME_RID_GRID); //全系移除 除网纹
return true;
}
int hg_scanner::hgpaper_to_devspaper(Paper_Map papermap[], int len, int& paper, bool* exact, TwSS* type)
{
int ind = 0;
@ -975,7 +925,7 @@ int hg_scanner::invoke_setting_xxx(int(hg_scanner::*func)(void*, long*), void* d
{
if (it->second == func)
{
ret = set_setting(it->first.c_str(), data, false);
ret = set_setting(it->first.c_str(), data);
break;
}
++it;
@ -985,11 +935,7 @@ int hg_scanner::invoke_setting_xxx(int(hg_scanner::*func)(void*, long*), void* d
}
int hg_scanner::setting_restore(void* data, long* len)
{
// restore ...
notify_setting_result_ = false;
for (int i = 0; i < setting_jsn_->count(); ++i)
restore(setting_jsn_->get_name_by_sane_id(i + 1).c_str());
notify_setting_result_ = true;
// move to scanner manager ...
return SCANNER_ERR_CONFIGURATION_CHANGED;
}
@ -1547,7 +1493,7 @@ int hg_scanner::setting_scan_mode(void* data, long* len)
}
else
{
scan_count_ = *(int*)setting_jsn_->get_option_value(SANE_STD_OPT_NAME_SCAN_COUNT, OPT_VAL_CURRENT).c_str();
scan_count_ = 1; // *(int*)setting_jsn_->get_option_value(SANE_STD_OPT_NAME_SCAN_COUNT, SANE_ACTION_GET_VALUE).c_str();
// 智学网设置该参数时,程序取消待纸扫描
if (!auto_scan_restore_) // 连续调用时,保留最初状态
@ -1571,13 +1517,13 @@ int hg_scanner::setting_scan_mode(void* data, long* len)
int hg_scanner::setting_scan_count(void* data, long* len)
{
int ret = SCANNER_ERR_OK;
std::string val(get_setting_item_string(SANE_STD_OPT_NAME_SCAN_MODE, "cur"));
//std::string val(get_setting_item_string(SANE_STD_OPT_NAME_SCAN_MODE, "cur"));
if (val == lang_load_string(ID_OPTION_VALUE_SMZS_LXSM, nullptr))
{
scan_count_ = -1;
}
else
//if (val == lang_load_string(ID_OPTION_VALUE_SMZS_LXSM, nullptr))
//{
// scan_count_ = -1;
//}
//else
{
scan_count_ = *((int*)data);
}
@ -2231,58 +2177,74 @@ hg_imgproc::IMGPRCPARAM hg_scanner::get_image_process_object(int model)
}
SANE_Image_Statu hg_scanner::last_usb_image_statu(int err)
{
SANE_Image_Statu statu = SANE_Image_Statu_OK;
SANE_Image_Statu statu = IMG_STATUS_OK;
if (!is_continue_when_double_paper(double_paper_handle_) &&
is_save_img_when_double_paper(double_paper_handle_))
{
if (err == SCANNER_ERR_DEVICE_DOUBLE_FEEDING)
statu = SANE_Image_Statu_Double;
statu = IMG_STATUS_DOUBLE;
//else if (err == SCANNER_ERR_DEVICE_PAPER_JAMMED)
//statu = SANE_Image_Statu_Jammed;
}
return statu;
}
void hg_scanner::erase_option(const char* name)
{
//erase_depend_.push_back(name);
//setting_jsn_->remove(name);
}
void hg_scanner::init_settings(const char* json_setting_text)
{
const char* lang = language_option_descriptor();
bool empty = true;
std::string text(json_setting_text);
gb_json* jsn = new gb_json();
if (lang && *lang)
// set fixed values ... dev-vid/dev-pid/dev-name/dev-model/roller-life
if (jsn->attach_text(&text[0]))
{
std::string txt(json_setting_text);
size_t pos = txt.rfind('}');
if (pos != std::string::npos)
gb_json* child = nullptr;
jsn->get_value(SANE_STD_OPT_NAME_DEVICE_VID, child);
if (child)
{
txt[pos] = ',';
child->set_value("cur", io_->get_vid());
child->set_value("default", io_->get_vid());
child->release();
}
if (strstr(lang, "{"))
txt += strstr(lang, "{") + 1;
setting_jsn_->init(txt.c_str());
empty = setting_jsn_->count() != 0;
}
if(empty)
{
std::string txt(json_setting_text);
setting_jsn_->init(txt.c_str());
jsn->get_value(SANE_STD_OPT_NAME_DEVICE_PID, child);
if (child)
{
child->set_value("cur", io_->get_pid());
child->set_value("default", io_->get_pid());
child->release();
}
jsn->get_value(SANE_STD_OPT_NAME_DEVICE_NAME, child);
if (child)
{
child->set_value("cur", name_.c_str());
child->set_value("default", name_.c_str());
child->release();
}
jsn->get_value(SANE_STD_OPT_NAME_DEVICE_MODEL, child);
if (child)
{
child->set_value("cur", io_->get_vid());
child->set_value("default", io_->get_vid());
child->release();
}
jsn->get_value(SANE_STD_OPT_NAME_ROLLER_LIFE, child);
if (child)
{
child->set_value("cur", 450000);
child->set_value("default", 450000);
child->release();
}
text = std::move(jsn->to_string());
}
jsn->release();
jsn_reorganize();
utils::to_log(LOG_LEVEL_ALL, "------>Initialize %d settings ...<------\n", setting_jsn_->count());
notify_setting_result_ = false;
setting_restore(nullptr, nullptr); // restore to default value
utils::to_log(LOG_LEVEL_ALL, "------>Initialize %d settings ... OK<------\n", setting_jsn_->count());
if (lang_get_cur_code_page() != DEFAULT_CODE_PAGE)
on_language_changed();
notify_setting_result_ = true;
set_opt_json_text(&text[0]);
}
int hg_scanner::init_settings(int pid)
{
@ -2304,10 +2266,6 @@ int hg_scanner::init_settings(int pid)
return SCANNER_ERR_OK;
}
std::string hg_scanner::get_setting_item_string(const char* name, const char* key)
{
return std::move(setting_jsn_->get_option_field_string(name, key));
}
int hg_scanner::on_scann_error(int err)
{
status_ = err;
@ -2320,7 +2278,10 @@ int hg_scanner::on_scann_error(int err)
}
int hg_scanner::try_third_app_handle_start(bool& handled)
{
int ret = SCANNER_ERR_OK; // status_
int ret = SCANNER_ERR_OK;
handled = false;
return ret;
handled = !async_io_;
if (handled)
@ -2369,13 +2330,14 @@ int hg_scanner::try_third_app_handle_start(bool& handled)
}
int hg_scanner::try_third_app_after_start(int err)
{
if (!async_io_)
{
while (wait_img_.is_waiting() && !wait_usb_.is_waiting())
std::this_thread::sleep_for(std::chrono::milliseconds(10));
if (wait_img_.is_waiting() && wait_usb_.is_waiting())
err = status_;
}
//if (!async_io_)
//{
// while (wait_img_.is_waiting() && !wait_usb_.is_waiting())
// std::this_thread::sleep_for(std::chrono::milliseconds(10));
// if (wait_img_.is_waiting() && wait_usb_.is_waiting())
// err = status_;
//
//}
return err;
}
@ -2728,36 +2690,13 @@ int hg_scanner::close(bool force)
return ret;
}
int hg_scanner::set_setting(const char* name, void* data, bool to_default)
int hg_scanner::set_setting(const char* name, void* data)
{
int ret = SCANNER_ERR_OUT_OF_RANGE, refine = 0;
bool hit = false, del_mem = false;
long len = 0;
std::string real_n(name);
int ret = SCANNER_ERR_OUT_OF_RANGE, refine = 0;
bool hit = setting_map_.count(real_n) > 0;
long len = 0;
if (to_default)
{
if (!setting_jsn_->is_auto_restore_default(name))
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
int size = 0;
std::string val(setting_jsn_->get_option_value(name, OPT_VAL_DEFAULT, &size));
if (!data)
{
data = new char[size];
memset(data, 0, size);
del_mem = true;
}
if (setting_jsn_->get_option_value_type(name) == JSON_SANE_TYPE_STRING)
strcpy((char*)data, val.c_str());
else
memcpy(data, &val[0], val.length());
}
else
refine = setting_jsn_->refine_data(real_n.c_str(), data);
hit = setting_map_.count(real_n) > 0;
if (hit)
{
ret = (this->*setting_map_[real_n])(data, &len);
@ -2767,67 +2706,14 @@ int hg_scanner::set_setting(const char* name, void* data, bool to_default)
utils::to_log(LOG_LEVEL_WARNING, "Setting '%s' is not found in base setting functions.\n", real_n.c_str());
ret = set_setting_value(real_n.c_str(), data, &len);
}
if (setting_jsn_->update_data(real_n.c_str(), data) == SCANNER_ERR_RELOAD_OPT_PARAM)
ret = SCANNER_ERR_RELOAD_OPT_PARAM;
if (del_mem)
delete[] data;
return ret;
}
int hg_scanner::get_setting(const char* name, char* buf, int* len, int type)
int hg_scanner::get_setting(const char* name, char* buf, int* len)
{
if (!len)
return SCANNER_ERR_INVALID_PARAMETER;
if (name == nullptr)
{
*len = setting_jsn_->count() + 1;
return SCANNER_ERR_OK;
}
else if (name == PARAM_ALL)
{
std::string text(setting_jsn_->get_option_value(nullptr, OPT_VAL_JSON));
if (*len <= text.length())
{
*len = text.length() + 4;
return SCANNER_ERR_INSUFFICIENT_MEMORY;
}
::strcpy(buf, text.c_str());
*len = text.length();
return SCANNER_ERR_OK;
}
std::string real_n(name);
if (real_n.empty())
{
return SCANNER_ERR_OUT_OF_RANGE;
}
else
{
int size = 0;
std::string val(setting_jsn_->get_option_value(name, OPT_VAL_CURRENT, &size));
if (val.empty())
return SCANNER_ERR_INVALID_PARAMETER;
if (*len < val.length())
{
*len = size;
return SCANNER_ERR_INSUFFICIENT_MEMORY;
}
memcpy(buf, &val[0], val.length());
if (setting_jsn_->get_option_value_type(name) == JSON_SANE_TYPE_STRING)
buf[val.length()] = 0;
}
return SCANNER_ERR_OK;
}
std::string hg_scanner::name(void)
@ -2850,13 +2736,100 @@ bool hg_scanner::is_online(void)
void hg_scanner::on_language_changed(void)
{
// change the 'size' member of string settings ...
setting_jsn_->update_data(nullptr, nullptr);
//setting_jsn_->update_data(nullptr, nullptr);
}
int hg_scanner::wait_one_image_from_start(bool& handled)
{
int ret = SCANNER_ERR_OK;
handled = false;
if (!async_io_) // non-callback
{
while (is_running() != THREAD_RUNNING_IDLE)
{
handled = true;
if (final_imgs_.size())
{
break;
}
}
if (final_imgs_.size())
{
IMH head = { 0 };
handled = true;
if (final_imgs_.front(&head))
{
if (head.statu & IMG_STATUS_DOUBLE)
ret = SCANNER_ERR_DEVICE_DOUBLE_FEEDING;
else if (head.statu & IMG_STATUS_JAM)
ret = SCANNER_ERR_DEVICE_PAPER_JAMMED;
else if (head.statu & IMG_STATUS_STAPLE)
ret = SCANNER_ERR_DEVICE_STAPLE_ON;
else if (head.statu & IMG_STATUS_SIZE_ERR)
ret = SCANNER_ERR_DEVICE_SIZE_CHECK;
else if (head.statu & IMG_STATUS_DOGEAR)
ret = SCANNER_ERR_DEVICE_DOGEAR;
}
}
else if (handled) // overed normal or exception
{
if (status_ == SCANNER_ERR_OK
|| status_ == SCANNER_ERR_DEVICE_DOUBLE_FEEDING) // 双张特殊处理,视为成功
{
SANE_Bool has_paper = SANE_FALSE;
get_scanner_paperon(has_paper);
if (has_paper == SANE_TRUE)
handled = false;
else
ret = SCANNER_ERR_DEVICE_NO_PAPER;
}
else
ret = status_;
}
}
return ret;
}
int hg_scanner::start(void)
{
user_cancel_ = false;
int ret = SCANNER_ERR_OK;
bool handled = false;
return status_;
if (user_cancel_)
{
user_cancel_ = false; // stopped by user, reset flag and starting a new scanning ...
utils::to_log(LOG_LEVEL_DEBUG, "start after user stopped just now while with %d image(s) in queue, a new scanning will to be started ...\n", final_imgs_.size());
}
else
{
ret = wait_one_image_from_start(handled);
if (handled)
{
utils::to_log(LOG_LEVEL_DEBUG, "start in previous scanning and result is %s, image count %d\n", hg_scanner_err_description(ret), final_imgs_.size());
return ret;
}
}
// clear ...
imgs_.Clear();
final_imgs_.clear();
usb_img_index_ = final_img_index_ = 0;
status_ = SCANNER_ERR_OK;
// start ...
ret = do_start();
if (ret == SCANNER_ERR_OK)
{
// wait ONE picture or stopped
ret = wait_one_image_from_start(handled);
}
utils::to_log(LOG_LEVEL_DEBUG, "start scanning result = %s\n", hg_scanner_err_description(ret));
return ret;
}
int hg_scanner::get_image_info(SANE_Parameters* ii)
{
@ -2945,9 +2918,21 @@ int hg_scanner::read_image_data(unsigned char* buf, int* len)
}
int hg_scanner::stop(void)
{
user_cancel_ = true;
int ret = SCANNER_ERR_OK;
return status_;
user_cancel_ = true;
ret = do_stop();
// wait until really stopped ...
if (ret == SCANNER_ERR_OK)
{
while (is_running() != THREAD_RUNNING_IDLE)
std::this_thread::sleep_for(std::chrono::milliseconds(3));
ret = status_;
}
utils::to_log(LOG_LEVEL_DEBUG, "user stopped result = %s\n", hg_scanner_err_description(ret));
return ret;
}
int hg_scanner::reset(void)
{
@ -2984,23 +2969,23 @@ int hg_scanner::device_io_control(unsigned long code, void* data, unsigned* len)
}
else if (code == IO_CTRL_CODE_GET_DEFAULT_VALUE)
{
if (*len <= 0)
{
*len = setting_jsn_->count() + 1;
//if (*len <= 0)
//{
// *len = setting_jsn_->count() + 1;
// return SCANNER_ERR_OK;
//}
//else if (*len >= setting_jsn_->count())
//{
// return SCANNER_ERR_OUT_OF_RANGE;
//}
//else
//{
// std::string val(setting_jsn_->get_option_value((int)*len, SANE_ACTION_GET_DEFAULT_VALUE));
// memcpy(data, &val[0], val.length());
return SCANNER_ERR_OK;
}
else if (*len >= setting_jsn_->count())
{
return SCANNER_ERR_OUT_OF_RANGE;
}
else
{
std::string val(setting_jsn_->get_option_value((int)*len, OPT_VAL_DEFAULT));
memcpy(data, &val[0], val.length());
return SCANNER_ERR_OK;
}
//}
}
else if (code == IO_CTRL_CODE_SET_CLEAR_ROLLER_COUNT)
{
@ -4239,4 +4224,31 @@ int hg_scanner::image_configuration(SCANCONF& ic)
utils::to_log(LOG_LEVEL_DEBUG, "ic.is_colorcast =%d\r\n", ic.is_colorcast);
utils::to_log(LOG_LEVEL_DEBUG, "ic.isuoloadexceptionimage=%d\r\n", ic.isuoloadexceptionimage);
return ret;
}
}
std::string hg_scanner::get_value(const char* name, void* value, int* err)
{
std::string val("");
int result = SCANNER_ERR_OK;
if (err)
*err = result;
return std::move(val);
}
int hg_scanner::set_value(const char* name, void* val)
{
int err = SCANNER_ERR_DEVICE_NOT_SUPPORT;
if (setting_map_.count(name))
{
long len = 0;
err = (this->*setting_map_[name])(val, &len);
}
return err;
}
void hg_scanner::enable(const char* name, bool able)
{
}

View File

@ -32,6 +32,8 @@
#endif
#ifndef WIN32
#define __stdcall
#endif
@ -71,7 +73,9 @@ typedef HGResult(__stdcall* SDKHGVersion_Free_)(HGVersionMgr mgr);
class gb_json;
class device_option;
class hg_scanner
#include "../../sdk/hginclude/base_opt.h"
class hg_scanner : public sane_opt_provider
{
HGVersionMgr HGVersion_mgr_;
SDKHGVersion_Init_ HGVersion_Init_;
@ -113,7 +117,6 @@ class hg_scanner
void dump_image_real(hg_imgproc::HIMGPRC himg, const char* desc);
void init_setting_func_map(void);
int restore(const char* name);
bool is_to_file(void);
void thread_handle_image_process(void);
@ -121,7 +124,6 @@ class hg_scanner
void working_done(void*);
void image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id);
bool jsn_reorganize(); // 固件版本不同 初始化gb_json要做出相对应的删除
public:
@ -282,8 +284,6 @@ protected:
bool cb_mem_;
bool test_1_paper_; // 是否为单张扫描模式
std::vector<string> erase_depend_; //需要删除父依赖项
//gb_json *setting_jsn_;
device_option *setting_jsn_;
IMGPRCFIXPARAM image_prc_param_;
int erase_bkg_range_; // 背景移除像素范围
@ -390,10 +390,8 @@ protected:
uint32_t fetching_id_; // for sane read image ext info. added on 2023-01-13
void erase_option(const char* name);
void init_settings(const char* json_setting_text);
int init_settings(int pid);
std::string get_setting_item_string(const char* name, const char* key);
int on_scann_error(int err); // 返回“0”忽略错误继续执行其它值则停止后续工作
int try_third_app_handle_start(bool& handled);
int try_third_app_after_start(int err);
@ -408,6 +406,7 @@ protected:
int save_final_image(hg_imgproc::LPIMGHEAD head, void* buf, uint32_t id = -1);
void adjust_filling_hole(LPSCANCONF conf);
int wait_one_image_from_start(bool& handled);
////////////////////////////////////////////////////////////////
// 新增自定义伽玛曲线及扫描区域属性 - 2022-05-05
@ -430,6 +429,9 @@ protected:
bool is_white_0_; // 是否0代表白色
public:
int start(void);
int stop(void);
void set_ui_callback(sane_callback cb, bool enable_async_io);
void set_dev_family(const char* family);
void set_read_over_with_no_data(bool no_data);
@ -438,8 +440,8 @@ public:
int get_pid(void);
int get_vid(void);
int close(bool force);
int set_setting(const char* name, void* data, bool to_default);
int get_setting(const char* name, char* buf, int* len, int type);
int set_setting(const char* name, void* data);
int get_setting(const char* name, char* buf, int* len);
int hgpaper_to_devspaper(Paper_Map papermap[], int len, int& paper, bool* exact, TwSS* type);
int image_configuration(SCANCONF &ic);
std::string name(void);
@ -456,10 +458,10 @@ public:
int is_running(void); // return thread_running
public:
virtual int start(void);
virtual int do_start(void) = 0;
virtual int do_stop(void) = 0;
virtual int get_image_info(SANE_Parameters* ii);
virtual int read_image_data(unsigned char* buf, int* len);
virtual int stop(void);
virtual int reset(void);
virtual int device_io_control(unsigned long code, void* data, unsigned* len);
virtual int discard_all_images(void) = 0;
@ -536,7 +538,18 @@ public:
virtual int set_devs_time(string times); //设置设备时间 //3399设备支持
virtual int get_devs_time(string &times); //获取设备时间 //3399设备支持
// sane_opt_provider
public:
virtual std::string get_value(const char* name, void* value, int* err = nullptr);
virtual int set_value(const char* name, void* val);
virtual void enable(const char* name, bool able);
};
//TEST 测试GIT切换
//TEST 测试GIT切换
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// NEW

View File

@ -267,7 +267,7 @@ void hg_scanner_200::thread_handle_usb_read(void)
}
utils::to_log(LOG_LEVEL_DEBUG, "USB thread exit with code: %s, status = %s\n", hg_scanner_err_name(ret), hg_scanner_err_description(status_));
}
int hg_scanner_200::start(void)
int hg_scanner_200::do_start(void)
{
bool handled = false;
int ret = try_third_app_handle_start(handled),
@ -320,7 +320,7 @@ int hg_scanner_200::start(void)
return ret;
}
int hg_scanner_200::stop(void)
int hg_scanner_200::do_stop(void)
{
int ret = SCANNER_ERR_OK;

View File

@ -48,8 +48,8 @@ public:
~hg_scanner_200();
public:
virtual int start(void)override;
virtual int stop(void)override;
virtual int do_start(void) override;
virtual int do_stop(void) override;
private:
int initdevice();
@ -57,7 +57,7 @@ private:
int readusb(USBCB &usb);
int pop_image();
int get_scanner_status(USBCB &usb);
int get_img_data(unsigned int bytes, SANE_Image_Statu statu = SANE_Image_Statu_OK);
int get_img_data(unsigned int bytes, SANE_Image_Statu statu = IMG_STATUS_OK);
int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_DSP *d = NULL);
void writedown_image_configuration(void);
void printf_devconfig(setting_hardware::HGSCANCONF_DSP *d = NULL);

File diff suppressed because one or more lines are too long

View File

@ -41,7 +41,7 @@ class hg_scanner_239 : public hg_scanner
int writedown_device_configuration(bool type = false, setting_hardware::HGSCANCONF_3399* dev_conf = NULL);//false 在start再把type置为true,其他做设置时不发
int writedown_image_configuration(void);
int pop_first_image(void);
int read_one_image_from_usb(SANE_Image_Statu statu = SANE_Image_Statu_OK);
int read_one_image_from_usb(SANE_Image_Statu statu = IMG_STATUS_OK);
bool is_dev_image_process_done(void);
bool is_dev_image_keep_last_paper(void);
@ -60,15 +60,15 @@ protected:
protected:
virtual int on_color_mode_changed(int& color_mode) override; //颜色切换
virtual int on_paper_changed(int& paper) override; //纸张大小设置
virtual int on_paper_check_changed(bool& check) override; //尺寸检测
virtual int on_resolution_changed(int& dpi) override; //分辨率设置
virtual int on_ultrasonic_check_changed(bool& check) override; //设置超声波检测
virtual int on_staple_check_changed(bool& check) override; //设置订书针检测
virtual int on_skew_check_changed(bool& check) override; //设置歪斜检测
virtual int on_skew_check_level_changed(int& check) override; //设置歪斜检测强度
virtual int on_paper_check_changed(bool& check) override; //尺寸检�
virtual int on_resolution_changed(int& dpi) override; //分辨率设�
virtual int on_ultrasonic_check_changed(bool& check) override; //设置超声波检�
virtual int on_staple_check_changed(bool& check) override; //设置订书针检�
virtual int on_skew_check_changed(bool& check) override; //设置歪斜检�
virtual int on_skew_check_level_changed(int& check) override; //设置歪斜检测强�
virtual int on_get_feedmode(int& feedmode) override; //获取分纸强度
virtual int on_set_feedmode(int feedmode) override; //设置分纸强度
virtual int on_pic_type(bool& pic)override; //照片模式或者文本模式
virtual int on_pic_type(bool& pic)override; //照片模å¼<EFBFBD>æˆè€…æ‡æœ¬æ¨¡å¼?
virtual int on_pick_paper(bool autostrength)override; //自动分纸强度
virtual int on_pick_paper_threshold(double threshold)override;
virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描
@ -82,8 +82,8 @@ public:
public:
//virtual int get_image_info(IMG_PARAM* ii) override;
//virtual int read_image_data(unsigned char* buf, int* len) override;
virtual int start(void) override;
virtual int stop(void) override;
virtual int do_start(void) override;
virtual int do_stop(void) override;
virtual int reset(void) override;
virtual int device_io_control(unsigned long code, void* data, unsigned* len) override;
virtual int get_roller_life(void) override;
@ -96,44 +96,44 @@ public:
virtual std::string get_device_model(void);
virtual int set_device_model(string str);
virtual int set_serial_num(string str) override; //设置序列号
virtual int set_serial_num(string str) override; //设置åº<EFBFBD>列å<EFBFBD>?
virtual int set_vid_pid(int data) override; //设置vidpid
virtual int get_vid_pid(int& data)override; //获取vidpid
/////////////////成功返回:SCANNER_ERR_OK /////////////
/////////////////失败返回:IO错误码 or SCANNER_ERR_DEVICE_NOT_SUPPORT /////////////
/////////////////失败返回:IO错误�or SCANNER_ERR_DEVICE_NOT_SUPPORT /////////////
virtual int set_leaflet_scan(void) override; //单张扫描
virtual int set_clear_roller_num(void) override; //清除滚轴计数
virtual int set_clear_history_num(void) override; //清除历史张数
virtual int get_device_code(void); //获取设备编码 不支持
virtual int get_device_code(void); //获å<EFBFBD>设备ç¼ç <EFBFBD> ä¸<C3A4>支æŒ?
virtual int get_scanner_paperon(SANE_Bool& type) override; //获取设备有无纸张 /*/ type : 0无纸 1有纸 */
virtual int get_scan_is_sleep(SANE_Bool& type) override; //获取设备是否休眠当中 /*/ type : 0休眠 1唤醒状态*/
virtual int get_sleep_time(int& data) override; //获取功耗模式(休眠) /*/ data > 0*/
virtual int set_sleep_time(int data) override; //设置功耗模式(休眠) /*/ data > 0*/
virtual int get_scan_is_sleep(SANE_Bool& type) override; //获å<EFBFBD>设备是å<EFBFBD>¦ä¼çœ å½“中 /*/ type : 0ä¼çœ  1唤é†çŠ¶æ€?/
virtual int get_sleep_time(int& data) override; //获å<EFBFBD>功耗模å¼<EFBFBD>(ä¼çœ ï¼? /*/ data > 0*/
virtual int set_sleep_time(int data) override; //设置功耗模å¼<EFBFBD>(ä¼çœ ï¼? /*/ data > 0*/
virtual int get_history_scan_count(int& data) override; //获取历史扫描张数 /*/ data > 0*/
virtual int get_roller_num(int& data) override; //获取滚轮张数 /*/ data > 0*/
virtual int set_notify_sleep(void) override; //唤醒设备
virtual int get_device_log(string& log) override; //获取设备日志 /*/ log :储存路径*/
virtual int set_devreboot(int data) override; //设置设备重启
virtual int set_devshtudown() override; //设置设备关机
virtual int set_scan_islock(SANE_Bool type) override; //设置设备是否锁定 /*/ type:0解锁1锁定*/
virtual int get_scan_islock(SANE_Bool& type) override; //获取设备是否锁定 /*/ type:0解锁1锁定*/
virtual int set_scan_lock_check_val(string str) override; //获取设备是否锁定 /*/ str:校验码*/
virtual int set_firmware_upgrade(std::string str) override; //固件升级 /*/ str:文件名路径*/
virtual int set_scan_islock(SANE_Bool type) override; //设置设备是å<EFBFBD>¦é”<EFBFBD>定 /*/ type:0解é”<C3A9>ï¼?é”<C3A9>定*/
virtual int get_scan_islock(SANE_Bool& type) override; //获å<EFBFBD>设备是å<EFBFBD>¦é”<EFBFBD>定 /*/ type:0解é”<C3A9>ï¼?é”<C3A9>定*/
virtual int set_scan_lock_check_val(string str) override; //获å<EFBFBD>设备是å<EFBFBD>¦é”<EFBFBD>定 /*/ str:校验ç ?/
virtual int set_firmware_upgrade(std::string str) override; //åºä»¶å<EFBFBD>‡çº§ /*/ str:æ‡ä»¶å<C2B6><C3A5>è·¯å¾?/
virtual int set_clean_paper_road() override; //清理纸道
virtual int get_dev_islock_file(int& data) override; //获取设备文件 /*/ data:0 未上锁1 上锁。-1 未发现黑名单列表 -2列表没有信息*/
virtual int get_dev_islock_file(int& data) override; //获å<EFBFBD>设备æ‡ä»¶ /*/ data:0 未上é”<C3A9>,1 上é”<C3A9>ã€?1 未å<C2AA>现é»å<E28098><C3A5>å<EFBFBD>•åˆ—表 -2列表没有信æ<C2A1>¯*/
virtual int set_dev_islock_file(int data) override; //设置设备文件 /*/ data:0 未上锁1 上锁*/
virtual int get_scan_mode(bool& type); //获取是否是计数模式 /*/ type : fasle计数模式 true非计数 */
virtual int get_scan_mode(bool& type); //获å<EFBFBD>是å<EFBFBD>¦æ˜¯è®¡æ•°æ¨¡å¼? /*/ type : fasle计数模å¼<C3A5> trueé<65>žè®¡æ•?*/
virtual int set_speed_mode(int data) override; //设置速度模式 /*/ data:100,110,120
virtual int get_speed_mode(int& data)override; //获取速度模式 /*/ data:100,110,120
virtual int set_devs_distortion_check_val(float data) override; //设置畸变矫正值
virtual int get_devs_distortion_check_val(float &data) override; //获取畸变矫正值
virtual int set_devs_distortion_check_val(float data) override; //设置畸å<EFBFBD>˜çŸ«æ­£å€?
virtual int get_devs_distortion_check_val(float &data) override; //获å<EFBFBD>畸å<EFBFBD>˜çŸ«æ­£å€?
virtual int set_auto_flat(int data); //设置自动平场校正
// data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color)

View File

@ -116,7 +116,7 @@ void hg_scanner_300::thread_handle_usb_read(void)
status = SCANNER_ERR_OK;
StopWatch sw;
sw.reset();
SANE_Image_Statu statu = SANE_Image_Statu_OK;
SANE_Image_Statu statu = IMG_STATUS_OK;
int img_num = 0;
savestatus_.clear();
while (run_)
@ -160,7 +160,7 @@ void hg_scanner_300::thread_handle_usb_read(void)
ret != SCANNER_ERR_DEVICE_AUTO_FAIL_OVER &&
ret != SCANNER_ERR_DEVICE_AUTO_FAIL_INFO)
{
statu = SANE_Image_Statu_OK;
statu = IMG_STATUS_OK;
}
else if (ret == SCANNER_ERR_DEVICE_AUTO_FAIL_OVER)
{
@ -313,7 +313,7 @@ int hg_scanner_300::get_roller_life(void)
{
return pid_ == 300 ? 150000 : 200000;
}
int hg_scanner_300::start(void)
int hg_scanner_300::do_start(void)
{
bool handled = false;
int ret = try_third_app_handle_start(handled), //sane调用是每次都会调用一次start和stop
@ -387,7 +387,7 @@ int hg_scanner_300::start(void)
utils::to_log(LOG_LEVEL_WARNING, "----------Main start scan status : %s----------\n", hg_scanner_err_description(ret));
return ret;
}
int hg_scanner_300::stop(void)
int hg_scanner_300::do_stop(void)
{
int ret = SCANNER_ERR_OK;

View File

@ -48,8 +48,9 @@ public:
hg_scanner_300(const char* dev_name,int pid, usb_io* io);
~hg_scanner_300();
public:
virtual int start(void)override;
virtual int stop(void)override;
virtual int do_start(void) override;
virtual int do_stop(void) override;
private:
int set_kernelsnap_ver();
int agreement(TwSS tw,int align);

View File

@ -967,7 +967,7 @@ void hg_scanner_302::thread_handle_usb_read(void)
while ((count = get_image_count()) > 0)
{
int s = SANE_Image_Statu_OK;
int s = IMG_STATUS_OK;
if (count <= 2)
{
if (image_prc_param_.bits.page == PAGE_SINGLE)
@ -1005,7 +1005,7 @@ void hg_scanner_302::thread_handle_usb_read(void)
utils::to_log(LOG_LEVEL_FATAL, "V4L2 error: %d\n", info->Code);
{
bool cancel = user_cancel_;
stop();
do_stop();
user_cancel_ = cancel;
go = false;
}
@ -1037,7 +1037,7 @@ void hg_scanner_302::thread_handle_usb_read(void)
}
utils::to_log(LOG_LEVEL_DEBUG, "USB thread exit with code: %s, status = %s\n", hg_scanner_err_name(ret), hg_scanner_err_name(status_));
}
int hg_scanner_302::start(void)
int hg_scanner_302::do_start(void)
{
bool handled = false;
@ -1114,7 +1114,7 @@ int hg_scanner_302::start(void)
return ret;
}
int hg_scanner_302::stop(void)
int hg_scanner_302::do_stop(void)
{
std::lock_guard<std::mutex> lock(io_lock_);
int ret = SCANNER_ERR_OK;
@ -1124,7 +1124,7 @@ int hg_scanner_302::stop(void)
// io_->set_timeout(500);
//final_imgs_.clear();
return status_;
return ret;
}
int hg_scanner_302::reset(void)
{

View File

@ -51,7 +51,7 @@ class hg_scanner_302 : public hg_scanner
int writedown_image_configuration(void);
int pop_first_image(void);
int read_one_image_from_usb(SANE_Image_Statu statu = SANE_Image_Statu_OK);
int read_one_image_from_usb(SANE_Image_Statu statu = IMG_STATUS_OK);
virtual int discard_all_images();
virtual int get_roller_life(void) override;
@ -82,10 +82,9 @@ public:
~hg_scanner_302();
public:
virtual int start(void) override;
//virtual int get_image_info(IMG_PARAM* ii) override;
//virtual int read_image_data(unsigned char* buf, int* len) override;
virtual int stop(void) override;
virtual int do_start(void) override;
virtual int do_stop(void) override;
virtual int reset(void) override;
virtual int device_io_control(unsigned long code, void* data, unsigned* len) override;

View File

@ -221,7 +221,7 @@ namespace hg_imgproc
// construction
public:
imgproc(int pid, bool isx86_Advan) : pid_(pid),papersize_(pid_)
, img_statu_(SANE_Image_Statu_OK)
, img_statu_(IMG_STATUS_OK)
, my_path_(utils::get_module_full_path())
,ocrinit_(NULL),ocrgetdirectimage_(NULL)
,ocrexit_(NULL),HGBase_CreatImg(NULL)

View File

@ -9,6 +9,8 @@
#include "user-opt/user.h"
#include "user-opt/offline_opt.h"
#include "user-opt/device_opt.h"
#if !defined(WIN32) && !defined(_WIN64)
#endif
@ -132,6 +134,75 @@ bool islang = false;
/// </summary>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// language option ...
class lang_opt : public sane_opt_provider
{
public:
lang_opt()
{
set_where("language-option");
const char* lang = language_option_descriptor();
if (lang && *lang)
{
std::string t(lang);
set_opt_json_text(&t[0]);
}
}
protected:
virtual ~lang_opt()
{}
public:
virtual int set_value(const char* name, void* val) override
{
if (strcmp(name, "language"))
return SCANNER_ERR_NO_DATA;
LANATTR** pla = lang_get_supported_languages();
int err = SCANNER_ERR_OK;
if (!pla)
err = SCANNER_ERR_DEVICE_NOT_SUPPORT;
else
{
std::string n(to_default_language((char*)val, nullptr)), now("");
int id = -1, cur = lang_get_cur_code_page();
for (int i = 0; pla[i]; ++i)
{
if (pla[i]->cp == cur)
now = pla[i]->name;
if (n == pla[i]->name)
{
id = pla[i]->cp;
break;
}
}
if (id == -1)
{
err = SCANNER_ERR_NOT_EXACT;
::strcpy((char*)val, now.c_str());
}
else if (cur != id)
{
err = SCANNER_ERR_CONFIGURATION_CHANGED;
lang_set_code_page(id);
}
}
return err;
}
};
static lang_opt* g_language = nullptr;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
hg_scanner_mgr* hg_scanner_mgr::inst_ = NULL;
sane_callback hg_scanner_mgr::event_callback_ = NULL;
bool hg_scanner_mgr::async_io_enabled_ = false;
@ -147,7 +218,7 @@ bool hg_scanner_mgr::read_over_with_eof_ = true;
uint32_t hg_scanner_mgr::unique_img_id_ = 0;;
std::mutex hg_scanner_mgr::mutex_img_id;
hg_scanner_mgr::hg_scanner_mgr() : same_ind_(1), cf_name("")
hg_scanner_mgr::hg_scanner_mgr() : same_ind_(1), cf_name(""), dev_opts_(new device_option())
{
std::string cfgf(utils::get_local_data_path() + PATH_SEPARATOR + "config" + PATH_SEPARATOR + "debug.cfg");
char buf[260] = {0};
@ -167,6 +238,9 @@ hg_scanner_mgr::hg_scanner_mgr() : same_ind_(1), cf_name("")
user_ = new hguser();
offline_ = new offline_opts(user_);
g_language = new lang_opt();
reset_device_opts();
}
hg_scanner_mgr::~hg_scanner_mgr()
{
@ -177,9 +251,14 @@ hg_scanner_mgr::~hg_scanner_mgr()
libusb_unref_device(v.dev);
online_devices_.clear();
}
dev_opts_->clear();
delete dev_opts_;
usb_manager::clear();
offline_->release();
delete user_;
g_language->release();
}
int hg_scanner_mgr::ui_default_callback(scanner_handle h, int ev, void* data, unsigned int* len, void* param)
@ -530,6 +609,17 @@ void hg_scanner_mgr::get_online_devices(std::vector<OLSCANNER>& devs)
devs = online_devices_;
}
void hg_scanner_mgr::reset_device_opts(sane_opt_provider* scanner)
{
dev_opts_->clear();
// Four sources: offline, language, algorithm, scanner
dev_opts_->add(dynamic_cast<sane_opt_provider*>(offline_));
dev_opts_->add(dynamic_cast<sane_opt_provider*>(g_language));
if (scanner)
dev_opts_->add(scanner);
}
void hg_scanner_mgr::set_appendix_info_for_about(SANE_About* about, char*& ptr, int& count, const char* key, const char* info, const char* url)
{
@ -803,6 +893,8 @@ scanner_err hg_scanner_mgr::hg_scanner_open(scanner_handle* h, const char* name,
scanner->set_ui_callback(&hg_scanner_mgr::ui_default_callback, hg_scanner_mgr::async_io_enabled_);
scanner->set_dev_family(g_supporting_devices[it->ind].family.c_str());
scanner->set_read_over_with_no_data(hg_scanner_mgr::read_over_with_eof_);
reset_device_opts(dynamic_cast<sane_opt_provider*>(scanner));
}
std::lock_guard<std::mutex> lock(mutex_dev_);
@ -833,183 +925,72 @@ scanner_err hg_scanner_mgr::hg_scanner_close(scanner_handle h, bool force)
}
}
reset_device_opts();
SCAN_PTR(h)->close(force);
delete SCAN_PTR(h);
SCAN_PTR(h)->release();
//delete SCAN_PTR(h);
return SCANNER_ERR_OK;
}
scanner_err hg_scanner_mgr::hg_scanner_get_parameter(scanner_handle h, const char* name, char* data, long* len, int type)
{
scanner_err err = SCANNER_ERR_OK;
scanner_err err = SCANNER_ERR_INVALID_PARAMETER;
if (!len)
return SCANNER_ERR_INVALID_PARAMETER;
if (!h)
if (len)
{
if (name == PARAM_ALL)
{
std::string all(offline_->get_json_text());
if (*len <= all.length())
{
*len = all.length() + 1;
std::string raw(dev_opts_->get_option_value(name == PARAM_ALL ? nullptr : name, type, nullptr, data));
err = SCANNER_ERR_INSUFFICIENT_MEMORY;
}
else
{
strcpy(data, all.c_str());
*len = all.length();
}
if (*len < raw.length())
{
*len = raw.length();
err = SCANNER_ERR_INSUFFICIENT_MEMORY;
}
else
err = (scanner_err)offline_->get_value(name, data, (int*)len, type == OPT_VAL_CURRENT);
return err;
}
else if (name && name != PARAM_ALL)
{
err = (scanner_err)offline_->get_value(name, data, (int*)len, type == OPT_VAL_CURRENT);
if (err != SCANNER_ERR_NO_DATA)
return err;
}
// global options ...
if (!IS_PTR_NUMBER(name))
{
// following options getting operation is implemented in 'set' ...
{
if (strcmp(SANE_STD_OPT_NAME_DEVICE_VID, name) == 0 ||
strcmp(SANE_STD_OPT_NAME_DEVICE_PID, name) == 0 ||
strcmp(SANE_STD_OPT_NAME_DEVICE_NAME, name) == 0 ||
strcmp(SANE_STD_OPT_NAME_DEVICE_MODEL, name) == 0 ||
strcmp(SANE_STD_OPT_NAME_DEVICE_SERIAL_NO, name) == 0 ||
strcmp(SANE_STD_OPT_NAME_FIRMWARE_VERSION, name) == 0 ||
strcmp(SANE_STD_OPT_NAME_DEVICE_IP_ADDR, name) == 0 ||
strcmp(SANE_STD_OPT_NAME_ROLLER_COUNT, name) == 0 ||
strcmp(SANE_STD_OPT_NAME_TOTAL_COUNT, name) == 0 ||
strcmp(SANE_STD_OPT_NAME_MOTOR_VER, name) == 0 ||
strcmp(SANE_STD_OPT_NAME_INITIAL_BOOT_TIME, name) == 0)
return (scanner_err)SCAN_PTR(h)->set_setting(name, data, false);
}
if (strcmp(SANE_STD_OPT_NAME_DEVICE_LOG, name) == 0)
{
if (!data)
return SCANNER_ERR_INVALID_PARAMETER;
if (user_->has_privilege(USER_PRIVILEGE_LOCAL_MGR))
{
char path[300] = { 0 };
int l = LOG_FILE_DEVICE,
ret = hg_scanner_control(h, IO_CTRL_CODE_GET_LOG_FILE, path, (unsigned*)&l);
if (ret == SCANNER_ERR_OK)
{
{
std::ifstream in(path, ios::in | ios::binary);
std::ofstream out(data, ios::out | ios::binary);
out << in.rdbuf();
}
remove(path);
}
return (scanner_err)ret;
}
else
return SCANNER_ERR_ACCESS_DENIED;
}
else if (strcmp(SANE_STD_OPT_NAME_CUSTOM_GAMMA, name) == 0)
return (scanner_err)SCAN_PTR(h)->device_io_control(IO_CTRL_CODE_GET_CUSTOM_GAMMA, data, (unsigned int*)len);
if (strcmp(SANE_STD_OPT_NAME_TRANSFORM_IMAGE_FORMAT, name) == 0 ||
strcmp(SANE_STD_OPT_NAME_FREE_BUFFER, name) == 0)
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
if (strcmp(SANE_STD_OPT_NAME_ROLLER_LIFE, name) == 0)
{
if (*len < sizeof(SANE_Int))
{
*len = sizeof(SANE_Int);
return SCANNER_ERR_INSUFFICIENT_MEMORY;
}
*(SANE_Int*)data = SCAN_PTR(h)->get_roller_life();
return SCANNER_ERR_OK;
memcpy(data, raw.c_str(), raw.length());
*len = raw.length();
err = SCANNER_ERR_OK;
}
}
int l = *len;
err = (scanner_err)SCAN_PTR(h)->get_setting(name, data, &l, type);
*len = l;
return err;
}
scanner_err hg_scanner_mgr::hg_scanner_set_parameter(scanner_handle h, const char* name, void* data, bool to_default)
{
scanner_err err = SCANNER_ERR_INVALID_PARAMETER;
scanner_err err = SCANNER_ERR_OK, se = SCANNER_ERR_OK;
std::string init("");
if (!h)
// do restore here ?
if (name && strcmp(name, SANE_STD_OPT_NAME_RESTORE) == 0)
{
if (name)
err = (scanner_err)offline_->set_value(name, data);
return err;
}
else if (name)
else
{
err = (scanner_err)offline_->set_value(name, data);
if (err != SCANNER_ERR_NO_DATA)
return err;
}
if (!IS_PTR_NUMBER(name))
{
if (strcmp(SANE_STD_OPT_NAME_DEVICE_LOG, name) == 0)
if (to_default)
{
if (user_->has_privilege(USER_PRIVILEGE_LOCAL_MGR))
int size = 0;
init = dev_opts_->get_option_value(name, SANE_ACTION_GET_DEFAULT_VALUE, &size);
if (size > init.length())
{
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
std::string t(std::move(init));
init.reserve(size);
memset(&init[0], 0, size);
memcpy(&init[0], &t[0], t.length());
}
return SCANNER_ERR_ACCESS_DENIED;
data = &init[0];
}
else if (strcmp(SANE_STD_OPT_NAME_ROLLER_COUNT, name) == 0)
else
{
if (user_->has_privilege(USER_PRIVILEGE_LOCAL_MGR))
{
int* len = nullptr;
return (scanner_err)SCAN_PTR(h)->device_io_control(IO_CTRL_CODE_SET_CLEAR_ROLLER_COUNT, data, (unsigned*)len);
}
return SCANNER_ERR_ACCESS_DENIED;
}
else if (strcmp(SANE_STD_OPT_NAME_CUSTOM_GAMMA, name) == 0)
{
int* len = nullptr;
return (scanner_err)SCAN_PTR(h)->device_io_control(IO_CTRL_CODE_SET_CUSTOM_GAMMA, data, (unsigned int*)len);
}
else if (strcmp(SANE_STD_OPT_NAME_TRANSFORM_IMAGE_FORMAT, name) == 0)
{
int* len = nullptr;
return (scanner_err)SCAN_PTR(h)->device_io_control(IO_CTRL_CODE_CONVERT_IMAGE_FORMAT, data, (unsigned int*)len);
}
else if (strcmp(SANE_STD_OPT_NAME_FREE_BUFFER, name) == 0)
{
void* ptr = data ? *(void**)data : nullptr;
int* len = nullptr;
scanner_err ret = (scanner_err)SCAN_PTR(h)->device_io_control(IO_CTRL_CODE_FREE_MEMORY, ptr, (unsigned int*)len);
if (data)
*(void**)data = nullptr;
return ret;
err = dev_opts_->refine_data(name, data) ? SCANNER_ERR_NOT_EXACT : SCANNER_ERR_OK;
}
se = (scanner_err)dev_opts_->update_data(name, data);
if (se != SCANNER_ERR_OK)
err = se;
}
return (scanner_err)SCAN_PTR(h)->set_setting(name, data, to_default);
return err;
}
scanner_err hg_scanner_mgr::hg_scanner_start(scanner_handle h, void* async_event, int num)
{

View File

@ -39,6 +39,8 @@
class hg_scanner;
class hguser;
class offline_opts;
class device_option;
class sane_opt_provider;
class hg_scanner_mgr
{
@ -68,6 +70,7 @@ class hg_scanner_mgr
hguser* user_;
offline_opts* offline_;
device_option* dev_opts_;
static sane_callback event_callback_;
static bool async_io_enabled_;
@ -90,6 +93,7 @@ class hg_scanner_mgr
void on_hgscanner_pnp(usb_event ev, libusb_device* device, int vid, int pid, int usb_ver_h, int usb_ver_l, bool* retry); // usb_ver_h.usb_ver_l
void get_online_devices(std::vector<OLSCANNER>& devs);
void reset_device_opts(sane_opt_provider* scanner = nullptr);
void set_appendix_info_for_about(SANE_About* about, char*& ptr, int& count, const char* key, const char* info, const char* url);
scanner_err get_about_info(scanner_handle h, void* data, unsigned* len);

View File

@ -1,27 +0,0 @@
#pragma once
// SANE-Option
//
// created on 2022-09-22
//
#include <string>
#include "../hg_ipc.h" // for refer
class sane_opt_provider : public refer
{
public:
sane_opt_provider()
{}
protected:
virtual ~sane_opt_provider()
{}
public:
virtual std::string get_json_text(void) = 0;
virtual int get_value(const char* name, void* buf, int* len, bool curval = true) = 0;
virtual int set_value(const char* name, void* value) = 0;
virtual bool has_option(const char* name) = 0;
};

View File

@ -1,8 +1,8 @@
#include "device_opt.h"
#include <hginclude/utils.h>
#include <huagao/hgscanner_error.h>
#include "../../../sdk/hginclude/huagaoxxx_warraper_ex.h"
#include "../../../sdk/hginclude/base_opt.h"
#include <lang/app_language.h>
#include <string.h>
#include <algorithm>
@ -230,7 +230,7 @@ bool device_option::condition_value::set_value(gb_json* jsn, const char* type, d
std::string device_option::condition_value::value(bool(*compare)(const char*, void*), void* param)
{
if (parent_)
return parent_->get_option_value(vals_[0].value.c_str(), OPT_VAL_CURRENT);
return parent_->get_option_value(vals_[0].value.c_str(), SANE_ACTION_GET_VALUE);
for (auto& v : vals_)
{
@ -358,8 +358,8 @@ bool device_option::range_value::set_value(gb_json* jsn, const char* type, devic
}
device_option::device_option(std::function<bool(int)> user_priv) : origin_(nullptr), now_(nullptr)
, user_(user_priv)
device_option::device_option(std::function<bool(int)> user_priv, std::function<void(const char*)> log) : origin_(nullptr), now_(nullptr)
, user_(user_priv), log_(log)
{}
device_option::~device_option()
{
@ -792,13 +792,11 @@ bool device_option::calc_simple_logic_expression(const char* expr, void* param)
return ret;
}
void device_option::clear(void)
void device_option::clear_for_reconstruct(void)
{
if (origin_)
origin_->release();
if (now_)
now_->release();
origin_ = now_ = nullptr;
now_ = nullptr;
master_opts_.clear();
compare_.clear();
@ -830,80 +828,259 @@ gb_json* device_option::group_opt(const char* title)
return jsn;
}
bool device_option::arrange_raw_json(const char* txt)
int device_option::next_group(int start)
{
for (; start < origin_->children(); ++start)
{
gb_json* child = origin_->child(start);
std::string str("");
child->get_value("type", str);
child->release();
if (str == JSON_SANE_TYPE_GROUP)
break;
}
return start;
}
int device_option::insert_group(const char* name, const char* title)
{
gb_json* group = nullptr;
int ind = origin_->children();
origin_->get_value(name, group);
if (group)
{
ind = origin_->index(group);
group->release();
}
else
{
for (auto& v : g_known_group_with_sn)
{
if (v.name == name)
{
title = v.title.c_str();
break;
}
gb_json* child = nullptr;
origin_->get_value(v.name.c_str(), child);
if (child)
{
if (group)
group->release();
group = child;
}
}
if (group)
{
ind = origin_->index(group) + 1;
group->release();
}
else
ind = 0;
ind = next_group(ind);
group = group_opt(title);
origin_->insert(ind, name, group);
group->release();
}
return ind;
}
void device_option::insert_option(gb_json* opt, sane_opt_provider* from, const char* group)
{
// first compare version, reserve higher version
// second compare position, replace with last insertion
// last, sort by position
gb_json* existing = nullptr;
origin_->get_value(opt->key().c_str(), existing);
if (existing)
{
int vo = 0, vn = 0;
opt->get_value("ver", vn);
existing->get_value("ver", vo);
if (vn > vo)
{
// replace and discard all following options ...
write_log("SANE-OPT: use %s::%s(ver: %d) replaced with %s::%s(ver: %d)\n", src_[existing->key()]->from().c_str(), existing->key().c_str(), vo
, from->from().c_str(), opt->key().c_str(), vn);
vo = origin_->index(existing);
origin_->remove(vo);
if (src_.count(existing->key()))
{
src_[existing->key()]->release();
src_.erase(existing->key());
}
origin_->insert(vo, opt->key().c_str(), opt);
opt->add_ref();
src_[opt->key()] = from;
from->add_ref();
}
else if (vn == vo)
{
// insert into following queue ...
write_log("SANE-OPT: inserting %s::%s to provider queue ...\n", from->from().c_str(), opt->key().c_str());
opt->get_value("pos", vn);
existing->get_value("pos", vo);
if (vo < vn)
{
sane_opt_provider* prev = src_[existing->key()],
*que = src_[existing->key()]->get_following(existing->key().c_str());
prev->add_ref();
while (que)
{
std::string text(que->get_opt_json());
gb_json* jsn = new gb_json(), *child = nullptr;
jsn->attach_text(&text[0]);
jsn->get_value(existing->key().c_str(), child);
if (child)
{
child->get_value("ver", vo);
child->release();
}
jsn->release();
if (vo >= vn)
break;
prev->release();
prev = que;
que = que->get_following(existing->key().c_str());
}
prev->set_following_provider(opt->key().c_str(), from);
if (vo == vn)
{
// replace ...
if(que)
{
sane_opt_provider* next = que->get_following(opt->key().c_str());
que->set_following_provider(opt->key().c_str(), nullptr);
if (next)
{
from->set_following_provider(opt->key().c_str(), next);
next->release();
}
que->release(); // release get_following reference
}
}
else
{
// insert ...
from->set_following_provider(opt->key().c_str(), que);
if (que)
que->release();
}
prev->release();
}
else if (vo > vn)
{
from->set_following_provider(opt->key().c_str(), src_[existing->key()]);
src_[existing->key()]->release();
src_[opt->key()] = from;
from->add_ref();
}
else
{
// replace ...
vo = origin_->index(existing);
origin_->remove(vo);
if (src_.count(existing->key()))
{
sane_opt_provider* next = src_[existing->key()]->get_following(existing->key().c_str());
src_[existing->key()]->set_following_provider(existing->key().c_str(), nullptr);
src_[existing->key()]->release();
src_.erase(existing->key());
while (next)
{
sane_opt_provider* next1 = next->get_following(existing->key().c_str());
next->set_following_provider(existing->key().c_str(), nullptr);
next->release();
next = next1;
}
}
origin_->insert(vo, opt->key().c_str(), opt);
opt->add_ref();
src_[opt->key()] = from;
from->add_ref();
}
{
write_log("SANE-OPT: option '%s' queue: %s", opt->key().c_str(), src_[opt->key().c_str()]->from().c_str());
sane_opt_provider* next = src_[opt->key().c_str()]->get_following(opt->key().c_str());
while (next)
{
write_log(" -> %s", next->from().c_str());
sane_opt_provider* next1 = next;
next = next->get_following(opt->key().c_str());
next1->release();
}
write_log("\n");
}
}
else
{
// discard new option ...
write_log("SANE-OPT: discard %s::%s(ver: %d) for %s::%s(ver: %d) existed!\n", from->from().c_str(), opt->key().c_str(), vn
, src_[existing->key()]->from().c_str(), existing->key().c_str(), vo);
}
existing->release();
}
else
{
int index = -1;
if (group)
index = insert_group(group, group);
index = next_group(index + 1);
origin_->insert(index, opt->key().c_str(), opt);
src_[opt->key()] = from;
from->add_ref();
}
}
bool device_option::arrange_raw_json(sane_opt_provider* sop)
{
std::vector<std::string> groups;
std::vector<gb_json*> ungroup;
std::map<std::string, std::vector<gb_json*>> ingroup;
gb_json* jsn = new gb_json(), *child = nullptr;
std::string text(txt), str("");
std::string text(sop->get_opt_json()), str("");
bool ret = jsn->attach_text(&text[0]);
if (jsn->attach_text(&text[0]))
if (ret)
{
if (!origin_)
origin_ = new gb_json();
text.clear();
child = jsn->first_child();
while (child)
{
child->get_value("group", str);
if (str.empty())
ungroup.push_back(child);
else if (ingroup.count(str))
ingroup[str].push_back(child);
else
child->get_value("type", str);
if (str != JSON_SANE_TYPE_GROUP) // omit group
{
std::vector<gb_json*> c;
c.push_back(child);
ingroup[str] = c;
child->get_value("group", str);
insert_option(child, sop, str.empty() ? nullptr : str.c_str());
}
child->release();
child = jsn->next_child();
}
}
jsn->release();
if (ungroup.size() || ingroup.size())
{
origin_ = new gb_json();
for (auto& v : ungroup)
{
origin_->set_value(v->key().c_str(), v);
v->release();
}
// named group ...
int grpind = 1;
for (auto& v : g_known_group_with_sn)
{
if (ingroup.count(v.name))
{
gb_json* grp = group_opt(v.title.c_str());
origin_->set_value(("grp-" + std::to_string(grpind++)).c_str(), grp);
grp->release();
for (auto& opt : ingroup[v.name])
{
origin_->set_value(opt->key().c_str(), opt);
opt->release();
}
ingroup.erase(v.name);
}
}
for (auto& v : ingroup)
{
gb_json* grp = group_opt(v.first.c_str());
origin_->set_value(("grp-" + std::to_string(grpind++)).c_str(), grp);
grp->release();
for (auto& opt : v.second)
{
origin_->set_value(opt->key().c_str(), opt);
opt->release();
}
}
}
return origin_ != nullptr;
return ret;
}
void device_option::init_depends(gb_json* opt)
{
@ -1296,12 +1473,24 @@ std::string device_option::get_group(int ind, bool title)
return "";
}
bool device_option::init(const char* opt_json)
void device_option::clear(void)
{
clear_for_reconstruct();
if (origin_)
origin_->release();
origin_ = nullptr;
for (auto& v : src_)
v.second->release();
src_.clear();
}
bool device_option::add(sane_opt_provider* sop)
{
bool ret = false;
clear();
if (arrange_raw_json(opt_json))
clear_for_reconstruct();
if (arrange_raw_json(sop))
{
ret = to_now(true, nullptr);
if (!ret)
@ -1348,64 +1537,84 @@ bool device_option::refine_data(const char* name, void* value)
}
int device_option::update_data(const char* name, void* value)
{
int err = SCANNER_ERR_NO_DATA;
if (!name)
{
to_now(false, nullptr);
return SCANNER_ERR_RELOAD_OPT_PARAM;
err = SCANNER_ERR_RELOAD_OPT_PARAM;
}
else if(now_)
{
std::string type("");
gb_json* child = nullptr;
err = SCANNER_ERR_DEVICE_NOT_SUPPORT;
now_->get_value(name, child);
if (child)
{
std::string pre(device_option::option_value(child, false));
bool changed = false;
bool ro = false;
if (child->get_value("readonly", ro) && ro)
{
child->release();
child->get_value("type", type);
if (type == JSON_SANE_TYPE_BOOL)
{
child->set_value("cur", *(bool*)value);
changed = *(bool*)value != *(bool*)pre.c_str();
err = SCANNER_ERR_ACCESS_DENIED;
}
else if (type == JSON_SANE_TYPE_INT)
else
{
child->set_value("cur", *(int*)value);
changed = *(int*)value != *(int*)pre.c_str();
}
else if (type == JSON_SANE_TYPE_FIXED)
{
child->set_value("cur", *(double*)value);
changed = !IS_DOUBLE_EQUAL(*(double*)value, *(double*)pre.c_str());
}
else if (type == JSON_SANE_TYPE_STRING)
{
child->set_value("cur", (char*)value);
changed = pre != (char*)value;
}
child->release();
std::string pre(device_option::option_value(child, false));
bool changed = false;
if (changed && // value has changed
std::find(master_opts_.begin(), master_opts_.end(), name) != master_opts_.end()) // can affect others
{
changed = false;
// pass to sane_opt_provider ...
err = SCANNER_ERR_OK;
if (src_.count(name))
err = src_[name]->set_value(name, value);
do
if (err == SCANNER_ERR_OK || err == SCANNER_ERR_NOT_EXACT
|| err == SCANNER_ERR_RELOAD_IMAGE_PARAM || err == SCANNER_ERR_RELOAD_OPT_PARAM)
{
changed = false;
to_now(false, &changed);
} while (changed);
child->get_value("type", type);
if (type == JSON_SANE_TYPE_BOOL)
{
child->set_value("cur", *(bool*)value);
changed = *(bool*)value != *(bool*)pre.c_str();
}
else if (type == JSON_SANE_TYPE_INT)
{
child->set_value("cur", *(int*)value);
changed = *(int*)value != *(int*)pre.c_str();
}
else if (type == JSON_SANE_TYPE_FIXED)
{
child->set_value("cur", *(double*)value);
changed = !IS_DOUBLE_EQUAL(*(double*)value, *(double*)pre.c_str());
}
else if (type == JSON_SANE_TYPE_STRING)
{
child->set_value("cur", (char*)value);
changed = pre != (char*)value;
}
child->release();
return SCANNER_ERR_RELOAD_OPT_PARAM;
}
}
}
if (changed && // value has changed
std::find(master_opts_.begin(), master_opts_.end(), name) != master_opts_.end()) // can affect others
{
changed = false;
return SCANNER_ERR_OK;
do
{
changed = false;
to_now(false, &changed);
} while (changed);
err = SCANNER_ERR_RELOAD_OPT_PARAM;
}
} // provider has processed right
} // not read-only option
} // has option named 'name'
} // has initialized
return err;
}
int device_option::count(void)
@ -1468,7 +1677,7 @@ std::string device_option::get_option_value_type(const char* name)
return std::move(value);
}
std::string device_option::get_option_value(const char* name, int type, int* size)
std::string device_option::get_option_value(const char* name, int type, int* size, void* in_data)
{
std::string value("");
gb_json* jsn = now_ ? now_ : origin_;
@ -1482,14 +1691,20 @@ std::string device_option::get_option_value(const char* name, int type, int* siz
else
{
gb_json* child = nullptr;
bool own_read = false;
jsn->get_value(name, child);
if (child)
{
if (type == OPT_VAL_JSON)
if (type == SANE_ACTION_GET_ENTIRE_JSON)
value = child->to_string();
else if (child->get_value("ownread", own_read) && own_read)
{
if (src_.count(name))
value = std::move(src_[name]->get_value(name, in_data));
}
else
value = device_option::option_value(child, type == OPT_VAL_DEFAULT);
value = device_option::option_value(child, type == SANE_ACTION_GET_DEFAULT_VALUE);
if (size)
{
@ -1538,7 +1753,7 @@ std::string device_option::get_option_value_type(int sane_ind)
return std::move(value);
}
std::string device_option::get_option_value(int sane_ind, int type, int* size)
std::string device_option::get_option_value(int sane_ind, int type, int* size, void* in_data)
{
std::string value("");
@ -1546,25 +1761,15 @@ std::string device_option::get_option_value(int sane_ind, int type, int* size)
{
if (sane_ind <= 0)
{
value = now_->to_string();
value = std::move(now_->to_string());
}
else if(sane_ind - 1 < now_->children())
{
gb_json* child = now_->child(sane_ind - 1);
if (type == OPT_VAL_JSON)
value = child->to_string();
else
value = device_option::option_value(child, type == OPT_VAL_DEFAULT);
if (size)
{
int n = 0;
child->get_value("size", n);
*size = n;
}
std::string name(child->key());
child->release();
value = std::move(get_option_value(name.c_str(), type, size, in_data));
}
}

View File

@ -15,14 +15,17 @@
#include "simple_logic.h"
#include <json/gb_json.h>
class sane_opt_provider;
class device_option
{
gb_json* origin_;
gb_json* now_;
std::map<std::string, sane_opt_provider*> src_;
std::vector<std::string> master_opts_; // options that value changed will affect others
std::map<std::string, simple_logic*> slaver_;
std::function<bool(int)> user_;
std::function<void(const char*)> log_;
typedef struct _expr_calc
{
@ -155,9 +158,12 @@ class device_option
static void init_condition(const char* expr, void* param);
static bool calc_simple_logic_expression(const char* expr, void* param);
void clear(void);
void clear_for_reconstruct(void);
gb_json* group_opt(const char* title);
bool arrange_raw_json(const char* txt); // create origin_ and re-arrange groups
int next_group(int start); // return index of the next group
int insert_group(const char* name, const char* title); // return index of the group
void insert_option(gb_json* opt, sane_opt_provider* from, const char* group = nullptr);
bool arrange_raw_json(sane_opt_provider* sop); // create origin_ and re-arrange groups
void init_depends(gb_json* opt);
gb_json* copy_opt(gb_json* from);
int visibility(gb_json* jsn);
@ -308,54 +314,63 @@ protected:
return refined;
}
template<typename ... Args>
void write_log(const char* fmt, Args ... args)
{
if (log_)
{
size_t size = snprintf(nullptr, 0, fmt, args ...) + 2;
std::unique_ptr<char[]> buf(new char[size]);
snprintf(buf.get(), size, fmt, args ...);
log_(buf.get());
}
}
public:
device_option(std::function<bool(int)> user_priv = std::function<bool(int)>());
device_option(std::function<bool(int)> user_priv = std::function<bool(int)>()
, std::function<void(const char*)> log = std::function<void(const char*)>());
~device_option();
static std::string trans_group(const char* utf8, bool to_title);
static std::string get_group(int ind, bool title);
public:
bool init(const char* opt_json);
void clear(void);
bool add(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); // 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(const char* name);
std::string get_name_by_sane_id(int sane_ind);
std::string get_option_value_type(const char* name);
std::string get_option_value(const char* name, int type/*OPT_VAL_xxx*/, int* size = nullptr); // return whole json-text if name was null
std::string get_option_field_string(const char* name, const char* key);
std::string get_option_value_type(int sane_ind);
std::string get_option_value(int sane_ind, int type/*OPT_VAL_xxx*/, int* size = nullptr); // return whole json-text if name was null
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
};
//{
// "noise-size": {
// "resolution": {
// "cat": "base",
// "group" : "base",
// "title" : " 噪点优化尺寸",
// "desc" : "设置需要去除的黑",
// "ver" : 0,
// "pos" : 0,
// "fix-id" : 0,
// "title" : "分辨率",
// "desc" : "设置扫描图像的分辨率",
// "type" : "int",
// "unit" : "none",
// "affect" : 0,
// "readonly" : false,
// "visible" : true,
// "enabled" : false,
// "fix-id" : 34840,
// "size" : 4,
// "cur" : 10,
// "default" : 10,
// "cur" : 200,
// "default" : 200,
// "range" : {
// "min": 1,
// "max" : {
// "paper==A3": 50, // condition value
// "default": 45} ,
// "min": 100,
// "max" : {
// "default": 600,
// "paper==最大扫描尺寸自动裁切 || paper==最大扫描尺寸 || paper==三联试卷" : 500
// },
// "step" : 1
// },
// "depend_or": ["is-noise-optimize==true"]
// }
// },
//
// "paper": {
@ -363,20 +378,17 @@ public:
// "group" : "base",
// "title" : "纸张尺寸",
// "desc" : "设置出图大小",
// "ver" : 0,
// "pos" : 0,
// "fix-id" : 0,
// "type" : "string",
// "unit" : "none",
// "affect" : 0,
// "readonly" : false,
// "visible" : true,
// "enabled" : false,
// "size" : 96,
// "fix-id" : 34831,
// "size" : 44,
// "cur" : "匹配原始尺寸",
// "default" : "匹配原始尺寸",
// "range" : ["A3", "8开", {
// "mode==24位彩色": "A4" // condition value
// }, "A4横向", "16开", "16开横向", "A5", "A5横向", "A6", "A6横向", "B4", "B5", "B5横向", "B6", "B6横向", "Letter", "Letter横向", "Double Letter", "LEGAL", "匹配原始尺寸", "最大扫描尺寸自动裁切", "最大扫描尺寸", "三联试卷"]
// "range" : ["A3", "8开", "A4", "16开", "A5", "A6", "B4", "B5", "B6", "Letter", "Double Letter", "LEGAL", "匹配原始尺寸", {
// "resolution<500": "最大扫描尺寸自动裁切"
// }, {
// "resolution<500": "最大扫描尺寸"
// }, {
// "resolution<500": "三联试卷"
// }]
// }
//}
//}

View File

@ -12,7 +12,7 @@
#include "user.h"
static std::string device_opt_json[] = {
"{\"company\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u5236\\u9020\\u5546\",\"desc\":\"\\u8bbe\\u5907\\u5236\\u9020\\u5546\",\"ver\":0,\"pos\":0,\"fix-id\":34891,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"copyright\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u7248\\u672c\\u4fe1\\u606f\",\"desc\":\"\\u7248\\u6743\\u58f0\\u660e\\u7b49\\u4fe1\\u606f\",\"ver\":0,\"pos\":0,\"fix-id\":34892,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-url\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8\\u7f51\\u5740\",\"desc\":\"\\u516c\\u53f8\\u5b98\\u7f51\\u6216\\u552e\\u540e\\u670d\\u52a1\\u7f51\\u7ad9\\u5730\\u5740\",\"ver\":0,\"pos\":0,\"fix-id\":34893,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-tel\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8\\u7535\\u8bdd\",\"desc\":\"\\u516c\\u53f8\\u8054\\u7cfb\\u7535\\u8bdd\",\"ver\":0,\"pos\":0,\"fix-id\":34894,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":129,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-addr\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8\\u5730\\u5740\",\"desc\":\"\\u516c\\u53f8\\u5730\\u5740\",\"ver\":0,\"pos\":0,\"fix-id\":34895,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-gps\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8GPS\",\"desc\":\"\\u516c\\u53f8\\u5730\\u56fe\\u5730\\u5740\",\"ver\":0,\"pos\":0,\"fix-id\":34896,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"drv-ver\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u9a71\\u52a8\\u7248\\u672c\\u53f7\",\"desc\":\"PC\\u7aef\\u9a71\\u52a8\\u7a0b\\u5e8f\\u7248\\u672c\",\"ver\":0,\"pos\":0,\"fix-id\":34890,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":48,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"login\":{\"cat\":\"advanced\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u767b\\u5f55\",\"desc\":\"\\u7528\\u6237\\u767b\\u5f55\\u64cd\\u4f5c\",\"ver\":0,\"pos\":0,\"fix-id\":39168,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"visible\":1,\"size\":64,\"auto\":false,\"cur\":\"false\",\"default\":\"false\"},\"logout\":{\"cat\":\"advanced\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u767b\\u51fa\",\"desc\":\"\\u7528\\u6237\\u767b\\u51fa\\u64cd\\u4f5c\",\"ver\":0,\"pos\":0,\"fix-id\":39169,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"visible\":1,\"size\":64,\"auto\":false,\"cur\":\"false\",\"default\":\"false\"},\"drv-log\":{\"cat\":\"advanced\",\"group\":\"\\u9ad8\\u7ea7\\u8bbe\\u7f6e\",\"title\":\"\\u9a71\\u52a8\\u65e5\\u5fd7\",\"desc\":\"PC\\u7aef\\u9a71\\u52a8\\u5de5\\u4f5c\\u65e5\\u5fd7\",\"ver\":0,\"pos\":0,\"fix-id\":39171,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"visible\":1,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"}}"
"{\"company\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u5236\\u9020\\u5546\",\"desc\":\"\\u8bbe\\u5907\\u5236\\u9020\\u5546\",\"type\":\"string\",\"fix-id\":34891,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"copyright\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u7248\\u672c\\u4fe1\\u606f\",\"desc\":\"\\u7248\\u6743\\u58f0\\u660e\\u7b49\\u4fe1\\u606f\",\"type\":\"string\",\"fix-id\":34892,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-url\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u516c\\u53f8\\u7f51\\u5740\",\"desc\":\"\\u516c\\u53f8\\u5b98\\u7f51\\u6216\\u552e\\u540e\\u670d\\u52a1\\u7f51\\u7ad9\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34893,\"readonly\":true,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-tel\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u516c\\u53f8\\u7535\\u8bdd\",\"desc\":\"\\u516c\\u53f8\\u8054\\u7cfb\\u7535\\u8bdd\",\"type\":\"string\",\"fix-id\":34894,\"readonly\":true,\"size\":129,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-addr\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u516c\\u53f8\\u5730\\u5740\",\"desc\":\"\\u516c\\u53f8\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34895,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-gps\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u516c\\u53f8GPS\",\"desc\":\"\\u516c\\u53f8\\u5730\\u56fe\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34896,\"readonly\":true,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"drv-ver\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u9a71\\u52a8\\u7248\\u672c\\u53f7\",\"desc\":\"PC\\u7aef\\u9a71\\u52a8\\u7a0b\\u5e8f\\u7248\\u672c\",\"type\":\"string\",\"fix-id\":34890,\"readonly\":true,\"size\":48,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"login\":{\"cat\":\"advanced\",\"group\":\"\\u7528\\u6237\",\"title\":\"\\u767b\\u5f55\",\"desc\":\"\\u7528\\u6237\\u767b\\u5f55\\u64cd\\u4f5c\",\"type\":\"string\",\"fix-id\":39168,\"visible\":1,\"size\":64,\"auto\":false,\"cur\":\"false\",\"default\":\"false\"},\"logout\":{\"cat\":\"advanced\",\"group\":\"\\u7528\\u6237\",\"title\":\"\\u767b\\u51fa\",\"desc\":\"\\u7528\\u6237\\u767b\\u51fa\\u64cd\\u4f5c\",\"type\":\"string\",\"fix-id\":39169,\"visible\":1,\"size\":64,\"auto\":false,\"cur\":\"false\",\"default\":\"false\"},\"drv-log\":{\"cat\":\"advanced\",\"group\":\"\\u7528\\u6237\",\"title\":\"\\u9a71\\u52a8\\u65e5\\u5fd7\",\"desc\":\"PC\\u7aef\\u9a71\\u52a8\\u5de5\\u4f5c\\u65e5\\u5fd7\",\"type\":\"string\",\"fix-id\":39171,\"visible\":1,\"size\":256,\"auto\":false,\"ownread\":true,\"cur\":\"0\",\"default\":\"0\"}}"
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -27,6 +27,7 @@ offline_opts::offline_opts(hguser* user) : user_(user)
+ "." + std::to_string(ll);
init();
set_where("offline_opts");
}
offline_opts::~offline_opts()
{
@ -34,160 +35,57 @@ offline_opts::~offline_opts()
void offline_opts::init(void)
{
gb_json* child = nullptr, * jsn_ = new gb_json();
gb_json* child = nullptr, * jsn = new gb_json();
std::string text("");
for (auto& v : device_opt_json)
text += v;
jsn_->attach_text(&text[0]);
jsn->attach_text(&text[0]);
#define INIT_SIMPLE_VAL(n, v) \
jsn_->get_value(SANE_STD_OPT_NAME_##n, child); \
jsn->get_value(SANE_STD_OPT_NAME_##n, child); \
if (child) \
{ \
auto func = [this](bool read, void* buf, int* len, bool curval) -> int \
{ \
if (!read) \
return SCANNER_ERR_DEVICE_NOT_SUPPORT; \
if (!len) \
return SCANNER_ERR_INVALID_PARAMETER; \
\
std::string val(from_default_language(v)); \
if (*len < val.length()) \
{ \
*len = val.length() + 1; \
\
return SCANNER_ERR_INSUFFICIENT_MEMORY; \
} \
\
strcpy((char*)buf, val.c_str()); \
\
return SCANNER_ERR_OK; \
}; \
oper_[SANE_STD_OPT_NAME_##n] = func; \
child->set_value("cur", v); \
child->set_value("default", v); \
\
child->release(); \
}
INIT_SIMPLE_VAL(MANUFACTURER, COMPANY_NAME);
INIT_SIMPLE_VAL(CO_URL, BRAND_COMPANY_URL);
INIT_SIMPLE_VAL(CO_TEL, BRAND_COMPANY_TEL);
INIT_SIMPLE_VAL(CO_ADDR, BRAND_COMPANY_ADDRESS);
INIT_SIMPLE_VAL(CO_GPS, BRAND_URL_GPS);
INIT_SIMPLE_VAL(MANUFACTURER , COMPANY_NAME);
INIT_SIMPLE_VAL(CO_URL , BRAND_COMPANY_URL);
INIT_SIMPLE_VAL(CO_TEL , BRAND_COMPANY_TEL);
INIT_SIMPLE_VAL(CO_ADDR , BRAND_COMPANY_ADDRESS);
INIT_SIMPLE_VAL(CO_GPS , BRAND_URL_GPS);
INIT_SIMPLE_VAL(COPYRIGHT , BRAND_COPYRIGHT);
INIT_SIMPLE_VAL(DRIVER_VERSION , drv_ver_.c_str());
INIT_SIMPLE_VAL(COPYRIGHT, BRAND_COPYRIGHT);
INIT_SIMPLE_VAL(DRIVER_VERSION, drv_ver_.c_str());
text = std::move(jsn->to_string());
set_opt_json_text(&text[0]);
// driver log
jsn_->get_value(SANE_STD_OPT_NAME_DRIVER_LOG, child);
if (child)
{
auto func = [this](bool read, void* buf, int* len, bool curval) -> int
{
if (user_ && user_->has_privilege(USER_PRIVILEGE_LOCAL_MGR))
{
if (read)
{
if (!buf)
return SCANNER_ERR_INVALID_PARAMETER;
return utils::copy_log_file_to((char*)buf);
}
else
{
return utils::clear_log_file();
}
}
else
{
return SCANNER_ERR_ACCESS_DENIED;
}
};
oper_[SANE_STD_OPT_NAME_DRIVER_LOG] = func;
child->release();
}
// login && logout
jsn_->get_value(SANE_STD_OPT_NAME_LOGIN, child);
if (child)
{
if (user_)
{
auto login = [this](bool read, void* buf, int* len, bool curval) -> int
{
if (read)
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
if (!buf)
return SCANNER_ERR_INVALID_PARAMETER;
char* n = (char*)buf,
* pwd = n + 32;
scanner_err ret = (scanner_err)user_->login(n, pwd);
if (ret == SCANNER_ERR_OK)
ret = SCANNER_ERR_RELOAD_OPT_PARAM;
return ret;
};
auto logout = [this](bool read, void* buf, int* len, bool curval) -> int
{
if (read)
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
if (!buf)
return SCANNER_ERR_INVALID_PARAMETER;
char* n = (char*)buf,
* pwd = n + 32;
scanner_err ret = (scanner_err)user_->logout(n, pwd);
if (ret == SCANNER_ERR_OK)
ret = SCANNER_ERR_RELOAD_OPT_PARAM;
return ret;
};
oper_[SANE_STD_OPT_NAME_LOGIN] = login;
oper_[SANE_STD_OPT_NAME_LOGOUT] = logout;
}
child->release();
}
jsn_->release();
jsn->release();
}
std::string offline_opts::get_json_text(void)
std::string offline_opts::get_value(const char* name, void* value, int* err)
{
std::string text("");
std::string ret("");
for (auto& v : device_opt_json)
text += v;
if (user_ && !user_->has_privilege(USER_PRIVILEGE_LOCAL_MGR))
if (IS_SANE_OPT(name, DRIVER_LOG))
{
gb_json* jsn = new gb_json();
if (jsn->attach_text(&text[0]))
if (user_ && user_->has_privilege(USER_PRIVILEGE_LOCAL_MGR))
{
jsn->remove(SANE_STD_OPT_NAME_LOGOUT);
jsn->remove(SANE_STD_OPT_NAME_DRIVER_LOG);
text = jsn->to_string();
}
jsn->release();
}
return std::move(text);
}
int offline_opts::get_value(const char* name, void* buf, int* len, bool curval)
{
int ret = SCANNER_ERR_NO_DATA;
int e = utils::copy_log_file_to((char*)value);
if (oper_.count(name))
{
ret = oper_[name](true, buf, len, curval);
ret = (char*)value;
if (err)
*err = e;
}
else if (err)
*err = SCANNER_ERR_ACCESS_DENIED;
}
else if (err)
*err = SCANNER_ERR_NO_DATA;
return ret;
}
@ -195,14 +93,40 @@ int offline_opts::set_value(const char* name, void* value)
{
int ret = SCANNER_ERR_NO_DATA;
if (oper_.count(name))
if (IS_SANE_OPT(name, DRIVER_LOG))
{
ret = oper_[name](false, value, nullptr, true);
if (user_ && user_->has_privilege(USER_PRIVILEGE_LOCAL_MGR))
{
ret = utils::clear_log_file();
}
else
{
ret = SCANNER_ERR_ACCESS_DENIED;
}
}
else if (IS_SANE_OPT(name, LOGIN) || IS_SANE_OPT(name, LOGOUT))
{
char* n = (char*)value,
* pwd = n + 32;
scanner_err ret = IS_SANE_OPT(name, LOGIN) ? (scanner_err)user_->login(n, pwd) : (scanner_err)user_->logout(n, pwd);
if (ret == SCANNER_ERR_OK)
ret = SCANNER_ERR_RELOAD_OPT_PARAM;
}
else if (IS_SANE_OPT(name, MANUFACTURER)
|| IS_SANE_OPT(name, CO_URL)
|| IS_SANE_OPT(name, CO_TEL)
|| IS_SANE_OPT(name, CO_ADDR)
|| IS_SANE_OPT(name, CO_GPS)
|| IS_SANE_OPT(name, COPYRIGHT)
|| IS_SANE_OPT(name, DRIVER_VERSION)
)
ret = SCANNER_ERR_ACCESS_DENIED;
return ret;
}
bool offline_opts::has_option(const char* name)
void offline_opts::enable(const char* name, bool able)
{
return oper_.count(name) > 0;
}
}

View File

@ -6,15 +6,12 @@
//
#include "base_opt.h"
#include <functional>
#include <map>
class hguser;
class offline_opts : public sane_opt_provider
{
hguser* user_;
std::string drv_ver_;
std::map<std::string, std::function<int(bool/*read?*/, void*/*buf*/, int*/*len*/, bool/*read cur value*/)>> oper_;
void init(void);
@ -25,9 +22,8 @@ protected:
virtual ~offline_opts();
public:
virtual std::string get_json_text(void) override;
virtual int get_value(const char* name, void* buf, int* len, bool curval = true) override;
virtual std::string get_value(const char* name, void* value, int* err = nullptr) override;
virtual int set_value(const char* name, void* value) override;
virtual bool has_option(const char* name) override;
virtual void enable(const char* name, bool able) override;
};

View File

@ -375,10 +375,14 @@ extern "C"
const char* hg_scanner_image_statu_name(int img_statu)
{
RETURN_IF(img_statu, SANE_Image_Statu_OK);
RETURN_IF(img_statu, SANE_Image_Statu_Blank);
RETURN_IF(img_statu, SANE_Image_Statu_Double);
RETURN_IF(img_statu, SANE_Image_Statu_Jammed);
RETURN_IF(img_statu, IMG_STATUS_OK);
RETURN_IF(img_statu, IMG_STATUS_BLANK);
RETURN_IF(img_statu, IMG_STATUS_DOUBLE);
RETURN_IF(img_statu, IMG_STATUS_JAM);
RETURN_IF(img_statu, IMG_STATUS_STAPLE);
RETURN_IF(img_statu, IMG_STATUS_SIZE_ERR);
RETURN_IF(img_statu, IMG_STATUS_DOGEAR);
RETURN_IF(img_statu, IMG_STATUS_DOGEAR_PARTIAL);
// NOTE: multi-thread unsafe here
static char g_unk_statu[80] = { 0 };

View File

@ -220,12 +220,10 @@ hg_sane_middleware::hg_sane_middleware(void) : init_ok_(false), offline_(nullptr
init_ok_ = true;
sprintf(sane_ver, "%u.%u.%u", SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, VERSION_BUILD);
#if defined(WIN32)
hg_scanner_set_sane_info("sane", sane_ver);
#else
#if !defined(WIN32)
signal(SIGUSR1, &hg_sane_middleware::device_pnp);
hg_scanner_set_sane_info(GET_BACKEND_NAME, sane_ver);
#endif
hg_scanner_set_sane_info(MODULE_NAME_SANE, sane_ver);
hg_scanner_initialize(local_utility::ui_cb, nullptr);
// initialize offline options with scanner_handle nullptr:
@ -395,12 +393,12 @@ bool hg_sane_middleware::reload_options(LPDEVINST inst)
{
long len = 0;
char *buf = nullptr;
scanner_err err = hg_scanner_get_option(inst->dev, PARAM_ALL, buf, &len, OPT_VAL_JSON);
scanner_err err = hg_scanner_get_option(inst->dev, PARAM_ALL, buf, &len, SANE_ACTION_GET_ENTIRE_JSON);
if (err == SCANNER_ERR_INSUFFICIENT_MEMORY)
{
buf = new char[len + 4];
err = hg_scanner_get_option(inst->dev, PARAM_ALL, buf, &len, OPT_VAL_JSON);
err = hg_scanner_get_option(inst->dev, PARAM_ALL, buf, &len, SANE_ACTION_GET_ENTIRE_JSON);
}
if (err == SCANNER_ERR_OK && len)
@ -422,7 +420,7 @@ scanner_err hg_sane_middleware::read_value(scanner_handle h, const char* name, S
{
bool v = false;
long len = sizeof(v);
err = hg_scanner_get_option(h, name, (char*)&v, &len, to_default ? OPT_VAL_DEFAULT : OPT_VAL_CURRENT);
err = hg_scanner_get_option(h, name, (char*)&v, &len, to_default ? SANE_ACTION_GET_DEFAULT_VALUE : SANE_ACTION_GET_VALUE);
if (value)
*(SANE_Bool*)value = v ? SANE_TRUE : SANE_FALSE;
}
@ -430,7 +428,7 @@ scanner_err hg_sane_middleware::read_value(scanner_handle h, const char* name, S
{
int v = 0;
long len = sizeof(v);
err = hg_scanner_get_option(h, name, (char*)&v, &len, to_default ? OPT_VAL_DEFAULT : OPT_VAL_CURRENT);
err = hg_scanner_get_option(h, name, (char*)&v, &len, to_default ? SANE_ACTION_GET_DEFAULT_VALUE : SANE_ACTION_GET_VALUE);
if (value)
*(SANE_Int*)value = v;
}
@ -438,14 +436,14 @@ scanner_err hg_sane_middleware::read_value(scanner_handle h, const char* name, S
{
double v = .0f;
long len = sizeof(v);
err = hg_scanner_get_option(h, name, (char*)&v, &len, to_default ? OPT_VAL_DEFAULT : OPT_VAL_CURRENT);
err = hg_scanner_get_option(h, name, (char*)&v, &len, to_default ? SANE_ACTION_GET_DEFAULT_VALUE : SANE_ACTION_GET_VALUE);
if (value)
*(SANE_Fixed*)value = hg_sane_middleware::double_2_sane_fixed(v);
}
else
{
long l = len;
err = hg_scanner_get_option(h, name, (char*)value, &l, to_default ? OPT_VAL_DEFAULT : OPT_VAL_CURRENT);
err = hg_scanner_get_option(h, name, (char*)value, &l, to_default ? SANE_ACTION_GET_DEFAULT_VALUE : SANE_ACTION_GET_VALUE);
}
return err;

View File

@ -0,0 +1,97 @@
#include "base_opt.h"
#include "../json/gb_json.h"
#include "../../../sdk/include/huagao/hgscanner_error.h"
sane_opt_provider::sane_opt_provider()
{
set_where(nullptr);
}
sane_opt_provider::~sane_opt_provider()
{
for (auto& v : following_)
v.second->release();
following_.clear();
}
bool sane_opt_provider::set_opt_json_text(char* txt)
{
gb_json* jsn = new gb_json();
bool ret = jsn->attach_text(txt);
jsn->release();
if (ret)
opt_jsn_txt_ = txt;
else
opt_jsn_txt_ = "";
return ret;
}
void sane_opt_provider::set_where(const char* where)
{
if (where && *where)
{
where_ = where;
}
else
{
char buf[20] = { 0 };
sprintf(buf, "%p", this);
where_ = buf;
}
}
std::string sane_opt_provider::get_opt_json(void)
{
return opt_jsn_txt_;
}
std::string sane_opt_provider::from(void)
{
return where_;
}
void sane_opt_provider::set_following_provider(const char* name, sane_opt_provider* following)
{
if (following_.count(name))
{
following_[name]->release();
following_.erase(name);
}
if (following)
{
following_[name] = following;
following->add_ref();
}
}
sane_opt_provider* sane_opt_provider::get_following(const char* name)
{
sane_opt_provider* prvd = nullptr;
if (following_.count(name))
{
prvd = following_[name];
if (prvd)
prvd->add_ref();
}
return prvd;
}
std::string sane_opt_provider::get_value(const char* name, void* value, int* err)
{
if (err)
*err = SCANNER_ERR_DEVICE_NOT_SUPPORT;
return "";
}
int sane_opt_provider::set_value(const char* name, void* val)
{
if (following_.count(name))
return following_[name]->set_value(name, val);
else
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
}
void sane_opt_provider::enable(const char* name, bool able)
{}

41
sdk/hginclude/base_opt.h Normal file
View File

@ -0,0 +1,41 @@
#pragma once
// SANE-Option
//
// created on 2022-10-24
//
#include <string>
#include <map>
#include "utils.h" // for refer
#include "../../../sdk/include/sane/sane_ex.h"
class sane_opt_provider : public refer
{
std::string opt_jsn_txt_;
std::string where_;
protected:
std::map<std::string, sane_opt_provider*> following_;
public:
sane_opt_provider();
protected:
virtual ~sane_opt_provider();
bool set_opt_json_text(char* txt);
void set_where(const char* where);
public:
std::string get_opt_json(void);
std::string from(void);
void set_following_provider(const char* name, sane_opt_provider* following); // when option has provided by more than one
sane_opt_provider* get_following(const char* name); // caller should ->release returned value
public:
virtual std::string get_value(const char* name, void* value, int* err = nullptr);
virtual int set_value(const char* name, void* val);
virtual void enable(const char* name, bool able);
};

View File

@ -177,12 +177,6 @@ enum hg_control_code
HG_CONTROL_CODE_OPTION_ENABLE = IO_CTRL_CODE_LAST + 1, // 配置项使能状态改变. data - OPTEN*, len - unused, be NULL
};
enum option_value
{
OPT_VAL_CURRENT = 0,
OPT_VAL_DEFAULT,
OPT_VAL_JSON,
};
//
// 可变参数数据使用JSON格式配置utf-8编码
//
@ -325,12 +319,12 @@ extern "C"{
// 如果“name==null”则返回最大可配置的参数号
// 该参数必须非空如果为NULL则会返回 EPARAMETERINVAL 的错误
//
// type - 获取的值类型:0 - 当前值1 - 默认值;……
// type - 获取的值类型:SANE_Action
//
// Return: 错误代码E_OK or E_INSUFFICIENTMEM or E_PARAMETERINVAL or E_DEVICENOTFOUND or E_OUTOFRANGE
//
// NOTE: 'data'空间由用户分配,如果空间太小(包含传入NULL)会在len中返回所需要的最小空间字节数并返回 EINSUFFICIENTMEM
scanner_err hg_scanner_get_option(scanner_handle h, const char* name, char* data, long* len, int type = OPT_VAL_CURRENT);
scanner_err hg_scanner_get_option(scanner_handle h, const char* name, char* data, long* len, int type = SANE_ACTION_GET_VALUE);
// Function: 设置设备的配置参数
//

View File

@ -731,6 +731,34 @@ int gb_json::index_move_to(gb_json* child, int ind)
return ind;
}
int gb_json::insert(int ind, const char* key, gb_json* child)
{
int i = index(child);
if (i == -1)
{
if (ind < 0)
ind = 0;
else if (ind > arr_val_.size())
ind = arr_val_.size();
child->key() = key ? key : "";
arr_val_.insert(arr_val_.begin() + ind, child);
child->add_ref();
}
else if(i != ind)
{
arr_val_.erase(arr_val_.begin() + i);
if (ind < 0)
ind = 0;
if (ind > arr_val_.size())
ind = arr_val_.size();
child->key() = key ? key : "";
arr_val_.insert(arr_val_.begin() + ind, child);
}
return ind;
}
bool gb_json::value(bool& val)
{

View File

@ -98,9 +98,10 @@ public:
bool remove(gb_json* child);
bool remove(int ind);
// position management
// position management, return index
int index(gb_json* child);
int index_move_to(gb_json* child, int ind);
int insert(int ind, const char* key, gb_json* child);
// leaf node value ...
bool value(bool& val);

View File

@ -3904,10 +3904,13 @@ int huagao_ds::handle_scanner_event(int ev, bool from_event_proc)
utils::log_info(msg, 1);
}
}
else
{
notifyXferReady(); // scan from UI, should notify this state mannually
}
//else
//{
// notifyXferReady(); // scan from UI, should notify this state mannually
//}
break;
case SANE_EVENT_TWAIN_XFER_READY:
notifyXferReady(); // notify ready when the first image arrived
break;
}

View File

@ -188,7 +188,7 @@ int image_buf::read(void* buf, size_t* bytes, unsigned long long off)
// class scanned_img
scanned_img::scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsigned int len, int dpi, const char* tmp_file
, twain_xfer xfer, SANE_FinalImgFormat* fmt) : head_(head), dpi_(dpi), header_size_(0)
, file_(tmp_file ? tmp_file : ""), dev_(dev), status_(SANE_Image_Statu_OK)
, file_(tmp_file ? tmp_file : ""), dev_(dev), status_(IMG_STATUS_OK)
{
const bool prepare_data = true;

View File

@ -324,6 +324,37 @@ bool scanner::is_option_float(int sn, void* param)
else
return false;
}
void scanner::scan_done(void)
{
std::string msg(scan_msg_);
while (images_.count())
std::this_thread::sleep_for(std::chrono::milliseconds(5));
if (ui_notify)
ui_notify(SANE_EVENT_SCAN_FINISHED, &msg[0], err_);
else
is_scanning_ = false;
//else
//{
// if (err_)
// {
// if (callback::show_messagebox_ui)
// {
// callback::show_messagebox_ui(app_wnd_, SANE_EVENT_SCAN_FINISHED, (void*)&msg[0], 0);
// }
// else // windows message box ...
// {
// std::wstring text(local_trans::a2u(msg.c_str(), CP_UTF8));
// if (!IsWindow(app_wnd_))
// callback::bring_message_box_topmost(local_trans::lang_trans_between_hz936(CONST_STRING_ERROR).c_str());
// MessageBoxW(app_wnd_, text.c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_ERROR).c_str(), MB_OK);
// }
// }
// on_ui_event(SANE_EVENT_SCAN_FINISHED, (void*)SANE_EVENT_SCAN_FINISHED);
//}
// is_scanning_ = false;
}
int scanner::transfer_id(int id)
{
@ -514,6 +545,10 @@ int scanner::open(void)
}
int scanner::close(void)
{
images_.clear();
if (done_.get() && done_->joinable())
done_->join();
scanner_ev_handler_ = nullptr;
ui_hide();
callback::unreg_callback(this);
@ -1351,6 +1386,10 @@ int scanner::handle_device_event(int ev_code, void* data, unsigned int* len)
if (ui_notify)
ui_notify(ev_code, data, img_ind_);
// notifyXferReady 改为有图片才通知防止部分APP在imgGetInfo中返回错误不能退出的问题 - 22023-10-25
if (img_ind_ == 1)
on_ui_event(SANE_EVENT_TWAIN_XFER_READY, nullptr);
{
char msg[128] = { 0 };
sprintf_s(msg, _countof(msg) - 1, "New image(%u) received with %u bytes\r\n", img_ind_, simg->bytes);
@ -1367,19 +1406,11 @@ int scanner::handle_device_event(int ev_code, void* data, unsigned int* len)
else if (ev_code == SANE_EVENT_SCAN_FINISHED)
{
err_ = *len;
if (ui_notify)
ui_notify(ev_code, data, *len);
else
{
if (*len)
{
if (callback::show_messagebox_ui)
{
callback::show_messagebox_ui(app_wnd_, ev_code, (void*)data, 0);
}
}
on_ui_event(ev_code, (void*)ev_code);
}
scan_msg_ = data ? (char*)data : "OK";
if (done_.get() && done_->joinable())
done_->join();
done_.reset(new std::thread(&scanner::scan_done, this));
// is_scanning_ = false;
{

View File

@ -40,6 +40,7 @@ class scanner : public ISaneInvoker, virtual public refer
SANE_FinalImgFormat img_fmt_;
bool twain_set_;
SANEAPI sane_api_;
std::unique_ptr<std::thread> done_;
std::function<void(int, void*, int)> ui_notify;
int(* scanner_ev_handler_)(int, void*);
void* evh_param_;
@ -117,6 +118,8 @@ class scanner : public ISaneInvoker, virtual public refer
static void ui_callback(int uev, void* sender, void* param);
static bool is_option_float(int sn, void* param);
void scan_done(void);
int language_id_;
public: