#include "scanner_manager.h" #include "../wrapper/hg_log.h" #include #include #include "raw_src.h" #include "char_const.h" #include "../../../sdk/include/huagao/brand.h" #if !defined(WIN32) && !defined(_WIN64) #endif // kinds of scanners ... #define SCAN_PTR(ptr) ((hg_scanner*)ptr) #include "hg_scanner_200.h" #include "hg_scanner_239.h" #include "hg_scanner_300.h" #include "hg_scanner_302.h" /// /// supporting devices : /// #define TO_STR(s) #s #define PID_AND_NAME(p, n) 0x##p, std::string(n) + " - " + TO_STR(p) #define GET_LANG(str,b) from_default_language(str,b) static struct { uint16_t vid; // vendor ID uint16_t pid; // product ID std::string name; // product name std::string type; // product type std::string rsc; // USB resource, version-addr. e.g. "USB2.0-1" hg_scanner* (* create_scanner)(const char*, usb_io*, scanner_handle*); } g_supporting_devices[] = { #ifdef OEM_LISICHENG #ifdef LISICHENG_SPECIAL {0x31c9, PID_AND_NAME(8426, SCANNER_NAME_LSC_G42S), "G4245F", "", &hg_scanner_mgr::create_scanner_g300} , {0x31c9, PID_AND_NAME(8626, SCANNER_NAME_LSC_G62S), "G6290U", "", &hg_scanner_mgr::create_scanner_g239} #else {0x31c9, PID_AND_NAME(8200, SCANNER_NAME_LSC_G42S), "G42S", "", &hg_scanner_mgr::create_scanner_g300} , {0x31c9, PID_AND_NAME(8420, SCANNER_NAME_LSC_G42S), "G42S", "", &hg_scanner_mgr::create_scanner_g300} , {0x31c9, PID_AND_NAME(8429, SCANNER_NAME_LSC_G42S), "G42S", "", &hg_scanner_mgr::create_scanner_empty} , {0x31c9, PID_AND_NAME(8520, SCANNER_NAME_LSC_G52S), "G52S", "", &hg_scanner_mgr::create_scanner_g400} , {0x31c9, PID_AND_NAME(8529, SCANNER_NAME_LSC_G52S), "G52S", "", &hg_scanner_mgr::create_scanner_g439} , {0x31c9, PID_AND_NAME(8620, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g100} , {0x31c9, PID_AND_NAME(8629, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g239} , {0x31c9, PID_AND_NAME(8730, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g100} , {0x31c9, PID_AND_NAME(8739, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g239} #endif #elif defined(OEM_HANWANG) {0x2903, 0x1000, SCANNER_NAME_HW_1000, SCANNER_NAME_HW_1000, "", &hg_scanner_mgr::create_scanner_g300} // "HW-1060A" , {0x2903, 0x1002, SCANNER_NAME_HW_1002, SCANNER_NAME_HW_1002, "", &hg_scanner_mgr::create_scanner_g302} // "HW-1060A" , {0x2903, 0x7000, SCANNER_NAME_HW_7000, SCANNER_NAME_HW_7000, "", &hg_scanner_mgr::create_scanner_g400} // "HW-74x0WA" , {0x2903, 0x7002, SCANNER_NAME_HW_7002, SCANNER_NAME_HW_7002, "", &hg_scanner_mgr::create_scanner_g402} // "HW-7002" , {0x2903, 0x7039, SCANNER_NAME_HW_7039, SCANNER_NAME_HW_7039, "", &hg_scanner_mgr::create_scanner_g439} // "HW-7039F" , {0x2903, 0x8000, SCANNER_NAME_HW_8000, SCANNER_NAME_HW_8000, "", &hg_scanner_mgr::create_scanner_g239} // "HW-8090F" , {0x2903, 0x9000, SCANNER_NAME_HW_9000, SCANNER_NAME_HW_9000, "", &hg_scanner_mgr::create_scanner_g239} // "HW-9110E" #elif defined(OEM_CANGTIAN) {0x3072, 0x0303, SCANNER_NAME_CT_4520, SCANNER_NAME_CT_4520, "", &hg_scanner_mgr::create_scanner_g300} , {0x3072, 0x0403, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g439} , {0x3072, 0x0138, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g239} , {0x3072, 0x0238, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g239} , {0x3308, 0x0138, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g239} , {0x3308, 0x0238, SCANNER_NAME_CT_238, SCANNER_NAME_CT_238, "", &hg_scanner_mgr::create_scanner_g239} , {0x3308, 0x6006, SCANNER_NAME_CT_9020, SCANNER_NAME_CT_9020, "", &hg_scanner_mgr::create_scanner_g239} , {0x3308, 0x6005, SCANNER_NAME_CT_4520, SCANNER_NAME_CT_4520, "", &hg_scanner_mgr::create_scanner_g300} #elif defined(OEM_ZHONGJING) {0X05DA, 0x9220, SCANNER_NAME_ZJ_6500, "S6570", "",& hg_scanner_mgr::create_scanner_g439} #elif defined(OEM_ZIGUANG) {0x32ec, 0x0200, SANNNER_NAME_ZG_Q7110,"Q7110", "", & hg_scanner_mgr::create_scanner_g239} , {0x32ec, 0x0210, SANNNER_NAME_ZG_Q1070, "Q1070", "", &hg_scanner_mgr::create_scanner_g402} #elif defined(OEM_NEUTRAL) {0x3072, PID_AND_NAME(100, SCANNER_NAME_HGNEU_G100), "G100", "",& hg_scanner_mgr::create_scanner_g100} , {0x3072, PID_AND_NAME(139, SCANNER_NAME_HGNEU_G100), "G100", "", &hg_scanner_mgr::create_scanner_g239} , {0x3072, PID_AND_NAME(200, SCANNER_NAME_HGNEU_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100} , {0x3072, PID_AND_NAME(239, SCANNER_NAME_HGNEU_G200), "G200", "", &hg_scanner_mgr::create_scanner_g239} , {0x3072, PID_AND_NAME(300, SCANNER_NAME_HGNEU_G300), "G300", "", &hg_scanner_mgr::create_scanner_g300} , {0x3072, PID_AND_NAME(302, SCANNER_NAME_HGNEU_G300), "G300", "", &hg_scanner_mgr::create_scanner_g302} , {0x3072, PID_AND_NAME(339, SCANNER_NAME_HGNEU_G300), "G300", "", &hg_scanner_mgr::create_scanner_empty} , {0x3072, PID_AND_NAME(400, SCANNER_NAME_HGNEU_G400), "G400", "", &hg_scanner_mgr::create_scanner_g400} , {0x3072, PID_AND_NAME(402, SCANNER_NAME_HGNEU_G400), "G400", "", &hg_scanner_mgr::create_scanner_g402} , {0x3072, PID_AND_NAME(439, SCANNER_NAME_HGNEU_G400), "G400", "", &hg_scanner_mgr::create_scanner_g439} , {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HGNEU_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100} , {0x31c9, PID_AND_NAME(8200, SCANNER_NAME_LSC_G42S), "G42S", "",& hg_scanner_mgr::create_scanner_g300} , {0x31c9, PID_AND_NAME(8420, SCANNER_NAME_LSC_G42S), "G42S", "", &hg_scanner_mgr::create_scanner_g300} , {0x31c9, PID_AND_NAME(8429, SCANNER_NAME_LSC_G42S), "G42S", "", &hg_scanner_mgr::create_scanner_empty} , {0x31c9, PID_AND_NAME(8520, SCANNER_NAME_LSC_G52S), "G52S", "", &hg_scanner_mgr::create_scanner_g400} , {0x31c9, PID_AND_NAME(8529, SCANNER_NAME_LSC_G52S), "G52S", "", &hg_scanner_mgr::create_scanner_g439} , {0x31c9, PID_AND_NAME(8620, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g100} , {0x31c9, PID_AND_NAME(8629, SCANNER_NAME_LSC_G62S), "G62S", "", &hg_scanner_mgr::create_scanner_g239} , {0x31c9, PID_AND_NAME(8730, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g100} , {0x31c9, PID_AND_NAME(8739, SCANNER_NAME_LSC_G73S), "G73S", "", &hg_scanner_mgr::create_scanner_g239} , {0x32ec, 0x0200, SANNNER_NAME_ZG_Q7110,"", "",& hg_scanner_mgr::create_scanner_g239} , {0x32ec, 0x0210, SANNNER_NAME_ZG_Q1070, "", "", &hg_scanner_mgr::create_scanner_g402} , {0X05DA, 0x9220, SCANNER_NAME_ZJ_6500, "S6500", "",&hg_scanner_mgr::create_scanner_g439} , {0x3308, 0x6006, SCANNER_NAME_CT_9020, SCANNER_NAME_CT_9020, "",& hg_scanner_mgr::create_scanner_g239} , {0x3308, 0x6005, SCANNER_NAME_CT_4520, SCANNER_NAME_CT_4520, "", &hg_scanner_mgr::create_scanner_g300} , {0x3308, 0x0238, SCANNER_NAME_CT_138, SCANNER_NAME_CT_138, "", &hg_scanner_mgr::create_scanner_g239} , {0x3308, 0x0138, SCANNER_NAME_CT_238, SCANNER_NAME_CT_238, "", &hg_scanner_mgr::create_scanner_g239} , {0x3072, 0x0303, SCANNER_NAME_CT_4520, SCANNER_NAME_CT_4520, "", &hg_scanner_mgr::create_scanner_g300} #elif defined(OEM_DELI) {0x300E, PID_AND_NAME(401C, SANNER_NAME_DL_S3000), "S3000", "", &hg_scanner_mgr::create_scanner_g239} , {0x300E, PID_AND_NAME(4020, SANNER_NAME_DL_S3400), "S3000", "", &hg_scanner_mgr::create_scanner_g239} , {0x300E, PID_AND_NAME(4015, SANNER_NAME_DL_S2000), "S2000", "", &hg_scanner_mgr::create_scanner_g300} , {0x300E, PID_AND_NAME(4019, SANNER_NAME_DL_DL9000), "DL9000", "", &hg_scanner_mgr::create_scanner_g439} #else {0x3072, PID_AND_NAME(100, SCANNER_NAME_HG_G100), "G100", "", &hg_scanner_mgr::create_scanner_g100} , {0x3072, PID_AND_NAME(139, SCANNER_NAME_HG_G100), "G100", "", &hg_scanner_mgr::create_scanner_g239} , {0x3072, PID_AND_NAME(200, SCANNER_NAME_HG_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100} , {0x3072, PID_AND_NAME(239, SCANNER_NAME_HG_G200), "G200", "", &hg_scanner_mgr::create_scanner_g239} , {0x3072, PID_AND_NAME(300, SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g300} , {0x3072, PID_AND_NAME(302, SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g302} , {0x3072, PID_AND_NAME(339, SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_empty} , {0x3072, PID_AND_NAME(400, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g400} , {0x3072, PID_AND_NAME(402, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g402} , {0x3072, PID_AND_NAME(439, SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g439} , {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G300), "G300", "", &hg_scanner_mgr::create_scanner_g300} , {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G200), "G200", "", &hg_scanner_mgr::create_scanner_g100} , {0x064B, PID_AND_NAME(7823,SCANNER_NAME_HG_G400), "G400", "", &hg_scanner_mgr::create_scanner_g400} #endif }; bool islang = false; //static std::string g_vendor = GET_LANG(COMPANY_NAME, &islang); #define BRAND_LOGO_SIZE 8 * 1024 #define MOVE_TO_NEXT_STR(str) str += strlen(str) + 1 /// hg_scanner_mgr* hg_scanner_mgr::inst_ = NULL; sane_callback hg_scanner_mgr::event_callback_ = NULL; bool hg_scanner_mgr::async_io_enabled_ = false; int hg_scanner_mgr::ver_major_ = 1; int hg_scanner_mgr::ver_minor_ = 0; int hg_scanner_mgr::ver_build_ = 0; int hg_scanner_mgr::ver_patch_ = 1; std::string hg_scanner_mgr::pe_path_(""); std::string hg_scanner_mgr::pe_name_(""); std::string hg_scanner_mgr::last_open_msg_(""); 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), user_(""), pwd_(""), cf_name("") { cf_name = hg_log::ini_get("devs_name", "name"); usb_manager::instance()->register_hotplug(&hg_scanner_mgr::usb_event_handle, this); int code_page = lang_get_cur_code_page(); url_en = BRAND_COMPANY_URL; url_link_en = BRAND_URL_COMPANY_URL; if (code_page == 20127) { url_en = BRAND_COMPANY_URL_EN; url_link_en = BRAND_URL_COMPANY_URL_EN; } } hg_scanner_mgr::~hg_scanner_mgr() { { std::lock_guard lock(mutex_dev_); for (auto& v : online_devices_) libusb_unref_device(v.dev); online_devices_.clear(); } usb_manager::clear(); } int hg_scanner_mgr::ui_default_callback(scanner_handle h, int ev, void* data, unsigned int* len, void* param) { // if (!hg_scanner_mgr::async_io_enabled_ && // ev == SANE_EVENT_IS_MEMORY_ENOUGH) // { // struct sysinfo si; // if(sysinfo(&si) == 0) // return si.freeram * si.mem_unit > *len + 200 * 1024 * 1024 ? SCANNER_ERR_OK : SCANNER_ERR_INSUFFICIENT_MEMORY; // return SCANNER_ERR_OK; // } if (hg_scanner_mgr::event_callback_) return hg_scanner_mgr::event_callback_(h, ev, data, len, param); return SCANNER_ERR_OK; } hg_scanner_mgr* hg_scanner_mgr::instance(sane_callback cb) { if (!hg_scanner_mgr::inst_) { hg_scanner_mgr::event_callback_ = cb; if (cb) hg_scanner_mgr::async_io_enabled_ = cb(NULL, SANE_EVENT_SUPPORT_ASYNC_IO, NULL, NULL, NULL) == 0; hg_scanner_mgr::unique_img_id_ = (uint32_t)INT_MAX + 1; hg_scanner_mgr::inst_ = new hg_scanner_mgr(); VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "async image transferring is %s\n", hg_scanner_mgr::async_io_enabled_ ? "enabled" : "disabled"); } return hg_scanner_mgr::inst_; } void hg_scanner_mgr::clear(void) { if (hg_scanner_mgr::inst_) { { std::lock_guard lock(hg_scanner_mgr::inst_->mutex_dev_); hg_scanner_mgr::event_callback_ = nullptr; } delete hg_scanner_mgr::inst_; hg_scanner_mgr::inst_ = NULL; } } void hg_scanner_mgr::set_version(int hh, int hl, int lh, int ll) { hg_scanner_mgr::ver_major_ = hh; hg_scanner_mgr::ver_minor_ = hl; hg_scanner_mgr::ver_build_ = lh; hg_scanner_mgr::ver_patch_ = ll; } void hg_scanner_mgr::set_exe_name(const char* path, const char* name) { hg_scanner_mgr::pe_path_ = path ? path : ""; hg_scanner_mgr::pe_name_ = name ? name : ""; std::string str = hg_log::get_scanimage_ver(); bool is_scanimg =false; is_scanimg = str >= "1.0.29" ? true : false; VLOG_MINI_2(LOG_LEVEL_ALL, "imgascan ver is: %s is_scanimg is:%d\n", str.c_str(),is_scanimg); if (name && *name) { // int ret = system("scanimage -V"); std::string eof(hg_log::ini_get("read_eof", name)); if (eof.empty()) { if(is_scanimg) hg_scanner_mgr::read_over_with_eof_ = STRICMP(name, "simple-scan") != 0; else hg_scanner_mgr::read_over_with_eof_ = STRICMP(name, "simple-scan") != 0 && (!is_scanimg? (STRICMP(name, "scanimage") != 0) : 1); } else hg_scanner_mgr::read_over_with_eof_ = eof != "0"; } else { std::string eof(hg_log::ini_get("read_eof", "first")); if (eof.empty()) hg_scanner_mgr::read_over_with_eof_ = true; else hg_scanner_mgr::read_over_with_eof_ = eof != "0"; } VLOG_MINI_1(LOG_LEVEL_ALL, "read image data end with EOF: %s\n", hg_scanner_mgr::read_over_with_eof_ ? "true" : "false"); } std::string hg_scanner_mgr::get_pe_name(std::string* path) { if (path) *path = hg_scanner_mgr::pe_path_; return hg_scanner_mgr::pe_name_; } uint32_t hg_scanner_mgr::unique_id(int type) { if (type == UNIQUE_ID_IMG) { std::lock_guard lock(hg_scanner_mgr::mutex_img_id); return hg_scanner_mgr::unique_img_id_++; } return -1; } hg_scanner* hg_scanner_mgr::create_scanner_empty(const char* name, usb_io* io, scanner_handle* h) { if (h) *h = nullptr; return nullptr; } hg_scanner* hg_scanner_mgr::create_scanner_g100(const char* name, usb_io* io, scanner_handle* h) { hg_scanner_200* s = new hg_scanner_200(name, 0x100, io); if (h) *h = s; return dynamic_cast(s); } hg_scanner* hg_scanner_mgr::create_scanner_g239(const char* name, usb_io* io, scanner_handle* h) { hg_scanner_239* s = new hg_scanner_239(name, 0x239, io); if (h) *h = s; return dynamic_cast(s); } hg_scanner* hg_scanner_mgr::create_scanner_g300(const char* name, usb_io* io, scanner_handle* h) { hg_scanner_300* s = new hg_scanner_300(name, 0x300, io); if (h) *h = s; return dynamic_cast(s); } hg_scanner* hg_scanner_mgr::create_scanner_g400(const char* name, usb_io* io, scanner_handle* h) { hg_scanner_300* s = new hg_scanner_300(name, 0x400, io); if (h) *h = s; return dynamic_cast(s); } hg_scanner* hg_scanner_mgr::create_scanner_g302(const char* name, usb_io* io, scanner_handle* h) { hg_scanner_302* s = new hg_scanner_302(name, 0x302, io); // image_process needs PID 402, we should add 302 ... if (h) *h = s; return dynamic_cast(s); } hg_scanner* hg_scanner_mgr::create_scanner_g402(const char* name, usb_io* io, scanner_handle* h) { hg_scanner_302* s = new hg_scanner_302(name, 0x402, io); if (h) *h = s; return dynamic_cast(s); } hg_scanner* hg_scanner_mgr::create_scanner_g439(const char* name, usb_io* io, scanner_handle* h) { hg_scanner_239* s = new hg_scanner_239(name, 0x439, io); if (h) *h = s; return dynamic_cast(s); } void hg_scanner_mgr::usb_event_handle(usb_event ev, libusb_device* device, int vid, int pid, int usb_ver_h, int usb_ver_l, bool* retry, void* user) // usb_ver_h.usb_ver_l { hg_scanner_mgr* obj = (hg_scanner_mgr*)user; obj->on_hgscanner_pnp(ev, device, vid, pid, usb_ver_h, usb_ver_l, retry); } void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int vid, int pid, int usb_ver_h, int usb_ver_l, bool* retry) { char model[40], vendor[40]; SANE_Device_Ex de; int ev_ui = 0; scanner_handle h = NULL; unsigned int len = sizeof(de); std::string name(""), type(""); std::lock_guard lock(mutex_dev_); sprintf(model, "%x", pid); sprintf(vendor, "%x", vid); de.model = model; de.name = NULL; de.type = NULL; de.vendor = vendor; de.openned = SANE_FALSE; if (ev == USB_EVENT_DEVICE_ARRIVED) { int index = -1; for (int i = 0; i < _countof(g_supporting_devices); ++i) { // 064B 婢舵艾褰寸拋鎯ь槵娴h法鏁ゆ潻娆庨嚋vid閿涘本澧嶆禒銉ュ鏉炶姤妞傛稉宥勭窗濞撳懏顨熺憰浣瑰ⅵ瀵偓閸濐亙绔撮崣鎷岊啎婢跺浄绱濋崣顏呮箒闁俺绻冩径鏍劥鏉╂稖顢戦崝鐘烘祰閺€鐟板綁鐎圭偘绶? if (g_supporting_devices[i].vid == vid && g_supporting_devices[i].pid == pid) { index = i; ev_ui = SANE_EVENT_DEVICE_ARRIVED; name = g_supporting_devices[i].name.c_str(); type = g_supporting_devices[i].type.c_str(); if (vid == 0x064B && !cf_name.empty()) { if (cf_name == g_supporting_devices[i].type) { name = g_supporting_devices[i].name.c_str(); type = g_supporting_devices[i].type.c_str(); break; } } else break; } } if (index != -1) { bool add = true; size_t i = 0; for (; i < online_devices_.size(); ++i) { if (online_devices_[i].dev == device) // 濮濄倕顦╅崑鍥х暰閸氬奔绔撮崣鎷岊啎婢跺洭鍣搁弬鎷岀箾閹恒儱鎮楅敍宀冾啎婢跺洤顕挒鈾€鈧竸evice閳ユ繀绻氶幐浣风瑝閸欐﹫绱辨俊鍌涚亯閸嬪洩顔曟稉宥嗗灇缁斿绱濇导姘嚤閼风顔曟径鍥櫢鏉╃偞绉烽幁顖欑瑝閼宠姤顒滅敮鍛婂复閺€璁圭礉缂佹垵鐣鹃崚鎷岊嚉鐠佹儳顦惃鍓哻anner鐎电钖勫妞剧瑝閸掍即鍣撮? { online_devices_[i].ind = index; add = false; break; } } if (add) // 婢跺嫮鎮婄€电钖勯垾娓別vice閳ユ繃鏁奸崣妯兼畱閹懏? { i = 0; for (auto& v : online_devices_) { if (v.ind == index && (v.scanner && !v.scanner->is_online())) { add = false; break; } i++; } } if (add) { OLSCANNER ols; ols.dev = device; ols.ind = index; ols.scanner = NULL; ols.display_name = g_supporting_devices[ols.ind].name; if (std::find(online_devices_.begin(), online_devices_.end(), ols.ind) != online_devices_.end()) { char buf[40]; sprintf(buf, " - %u", same_ind_++); ols.display_name += buf; } libusb_ref_device(ols.dev); // ref to the device of queue online_devices_ online_devices_.push_back(ols); name = ols.display_name; VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "%s connected.\n", name.c_str()); type = g_supporting_devices[ols.ind].type; } else if (online_devices_[i].scanner && !online_devices_[i].scanner->is_online()) { usb_io* io = NULL; name = online_devices_[i].display_name; type = g_supporting_devices[index].type; if (online_devices_[i].dev) libusb_unref_device(online_devices_[i].dev); online_devices_[i].dev = device; libusb_ref_device(online_devices_[i].dev); h = online_devices_[i].scanner; if (pid == 0x300 || pid == 0x400) std::this_thread::sleep_for(std::chrono::milliseconds(1000)); len = usb_manager::instance()->open(device, &io); VLOG_MINI_3(LOG_LEVEL_WARNING, "[%04x:%04x]%s re-connected.\n", pid, vid, online_devices_[i].display_name.c_str()); if (len == SCANNER_ERR_OK) { online_devices_[i].scanner->reset_io(io); de.openned = SANE_TRUE; } if (io) io->release(); add = false; } } } else if (ev == USB_EVENT_DEVICE_LEFT) { std::vector::iterator it = std::find(online_devices_.begin(), online_devices_.end(), device); if (it != online_devices_.end()) { ev_ui = SANE_EVENT_DEVICE_LEFT; name = it->display_name; type = g_supporting_devices[it->ind].type; h = it->scanner; VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "%s Dis-connected.\n", name.c_str()); if (it->scanner) it->scanner->io_disconnected(); else { libusb_unref_device(it->dev); // unref the device of queue online_devices_ online_devices_.erase(it); } } } if (ev_ui) { de.name = name.c_str(); de.type = type.c_str(); hg_scanner_mgr::ui_default_callback(h, ev_ui, &de, &len, NULL); } } void hg_scanner_mgr::get_online_devices(std::vector& devs) { std::lock_guard lock(mutex_dev_); devs = online_devices_; } 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) { #ifdef BRAND_DISPLAY_ALL_EXPAND if (!info || *info == 0) info = GET_LANG(BRAND_COMMUNICATION_FAIL,&islang); #endif if (info && strlen(info)) { about->appendix[count].key = ptr; strcpy(ptr, key); MOVE_TO_NEXT_STR(ptr); about->appendix[count].content = ptr; strcpy(ptr, info); MOVE_TO_NEXT_STR(ptr); if (url) { about->appendix[count++].url = ptr; strcpy(ptr, url); MOVE_TO_NEXT_STR(ptr); } else { about->appendix[count].url = NULL; count++; } } } scanner_err hg_scanner_mgr::get_about_info(scanner_handle h, void* data, unsigned* len) { hg_scanner* scanner = (hg_scanner*)h; unsigned bytes = sizeof(SANE_About) + 40; SANE_About tmp; size_t append_cnt = 1; bytes += sizeof(g_logo); bytes += strlen(GET_LANG(BRAND_APP_NAME, &islang)) + 8; append_cnt++; bytes += strlen(GET_LANG(BRAND_TITLE_VERSION,&islang)) + 8; append_cnt++; bytes += strlen(GET_LANG(BRAND_TITLE_COPYRIGHT,&islang)) + 8; append_cnt++; bytes += strlen(GET_LANG(BRAND_COPYRIGHT,&islang)) + 8; append_cnt++; bytes += strlen(GET_LANG(BRAND_TITE_MANUFACTOR,&islang)) + 8; append_cnt++; bytes += strlen(GET_LANG(BRAND_TITLE_URL,&islang)) + 8; append_cnt++; bytes += strlen(GET_LANG(url_en.c_str(), &islang)) + 8; append_cnt++; bytes += strlen(GET_LANG(url_link_en.c_str(), &islang)) + 8; append_cnt++; bytes += strlen(GET_LANG(BRAND_TITLE_TEL,&islang)) + 8; append_cnt++; bytes += strlen(GET_LANG(BRAND_COMPANY_TEL,&islang)) + 8; append_cnt++; bytes += strlen(GET_LANG(BRAND_TITLE_ADDRESS,&islang)) + 8; append_cnt++; bytes += strlen(GET_LANG(BRAND_COMPANY_ADDRESS,&islang)) + 8; append_cnt++; bytes += strlen(GET_LANG(BRAND_TITLE_GPS,&islang)) + 8; append_cnt++; bytes += strlen(GET_LANG(BRAND_COMPANY_GPS,&islang)) + 8; append_cnt++; bytes += strlen(GET_LANG(BRAND_URL_GPS,&islang)) + 8; append_cnt++; // bytes += 5 * sizeof(tmp.appendix[0]); #ifndef BRAND_DISPLAY_ALL_EXPAND if (scanner) #endif { bytes += sizeof(tmp.appendix[0]) + BRAND_INFO_MAX_LENGTH + 8 + strlen(GET_LANG(BRAND_SOFTWARE_VERSION, &islang)) + 8; bytes += sizeof(tmp.appendix[0]) + BRAND_INFO_MAX_LENGTH + 8 + strlen(GET_LANG(BRAND_TITLE_DEVICE_MODEL, &islang)) + 8; append_cnt++; bytes += sizeof(tmp.appendix[0]) + BRAND_INFO_MAX_LENGTH + 8 + strlen(GET_LANG(BRAND_TITLE_FIRM_VERSION,&islang)) + 8; append_cnt++; bytes += sizeof(tmp.appendix[0]) + BRAND_INFO_MAX_LENGTH + 8 + strlen(GET_LANG(BRAND_TITLE_SERIAL_NUM,&islang)) + 8; append_cnt++; bytes += sizeof(tmp.appendix[0]) + BRAND_INFO_MAX_LENGTH + 8 + strlen(GET_LANG(BRAND_TITLE_IP,&islang)) + 8; append_cnt++; bytes += sizeof(tmp.appendix[0]) + 28 + strlen(GET_LANG(BRAND_TITLE_ROLLER_COUNT,&islang)) + 8; append_cnt++; bytes += sizeof(tmp.appendix[0]) + 28 + strlen(GET_LANG(BRAND_TITLE_HISTORY_COUNT,&islang)) + 8; append_cnt++; bytes += sizeof(tmp.appendix[0]) + 28 + strlen(GET_LANG(BRAND_TITLE_DEVICE_INITIAL_POWER_ON_TIME, &islang)) + 8; append_cnt++; bytes += sizeof(tmp.appendix[0]); append_cnt++; } if (!data || *len < bytes) { *len = bytes; return SCANNER_ERR_INSUFFICIENT_MEMORY; } // filling info to flat buffer ... SANE_About* about = (SANE_About*)data; std::string info(""); char* ptr = (char*)data + sizeof(SANE_About) + append_cnt * sizeof(about->appendix[0]); about->title = ptr; strcpy(ptr, GET_LANG(BRAND_APP_NAME,&islang)); MOVE_TO_NEXT_STR(ptr); about->version = ptr; sprintf(ptr, "%d.%d.%d.%d", hg_scanner_mgr::ver_major_, hg_scanner_mgr::ver_minor_, hg_scanner_mgr::ver_build_, hg_scanner_mgr::ver_patch_); MOVE_TO_NEXT_STR(ptr); about->copyright = ptr; std::string s = GET_LANG(BRAND_COPYRIGHT, &islang); strcpy(ptr, s.c_str()); MOVE_TO_NEXT_STR(ptr); about->logo_bytes = sizeof(g_logo);; about->logo = ptr; memcpy(ptr, g_logo, about->logo_bytes); ptr += about->logo_bytes + 1; int count = 0, rolls = 0, ret = SCANNER_ERR_OK; #ifdef TEST set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_SOFTWARE_VERSION, &islang), BRAND_SOFTWARE_VERSION_TEST, NULL); #endif std::string g_vendor = GET_LANG(COMPANY_NAME, &islang); set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITE_MANUFACTOR,&islang), g_vendor.c_str(), NULL); set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_URL,&islang), GET_LANG(url_en.c_str(), &islang), GET_LANG(url_link_en.c_str(), &islang)); set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_TEL,&islang), GET_LANG(BRAND_COMPANY_TEL,&islang), NULL); set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_ADDRESS,&islang), GET_LANG(BRAND_COMPANY_ADDRESS,&islang), NULL); if (strlen(BRAND_TITLE_GPS) > 1) { set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_GPS, &islang), GET_LANG(BRAND_COMPANY_GPS, &islang), GET_LANG(BRAND_URL_GPS, &islang)); } if (scanner) { set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_FIRM_VERSION,&islang), scanner->get_firmware_version().c_str(), NULL); set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_SERIAL_NUM,&islang), scanner->get_serial_num().c_str(), NULL); info = scanner->get_ip(); if (info.length() > 10 && !info.empty()) set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_IP,&islang), info.c_str(), NULL); info.clear(); info = scanner->get_device_model(); if (!info.empty()) set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_DEVICE_MODEL, &islang), info.c_str(), NULL); ret = scanner->get_devs_time(info); if (ret == SCANNER_ERR_OK && !info.empty()) { set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_ROLLER_COUNT, &islang), info.c_str(), NULL); } ret = scanner->get_roller_num(rolls); if (ret == SCANNER_ERR_OK) { char buf[40]; sprintf(buf, "%u", rolls); set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_ROLLER_COUNT,&islang), buf, NULL); } #ifdef BRAND_DISPLAY_ALL_EXPAND else set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_ROLLER_COUNT,&islang), rolls == -1 ? GET_LANG(BRAND_COMMUNICATION_FAIL,&islang) : GET_LANG(BRAND_DEVICE_NOT_SUPPORT,&islang), NULL); #endif ret = scanner->get_history_scan_count(rolls); if (ret == SCANNER_ERR_OK) { char buf[40]; sprintf(buf, "%u", rolls); set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_HISTORY_COUNT,&islang), buf, NULL); } #ifdef BRAND_DISPLAY_ALL_EXPAND else set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_HISTORY_COUNT,&islang), rolls == -1 ? GET_LANG(BRAND_COMMUNICATION_FAIL,&islang) : GET_LANG(BRAND_DEVICE_NOT_SUPPORT,&islang), NULL); #endif } #ifdef BRAND_DISPLAY_ALL_EXPAND else { set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_FIRM_VERSION,&islang), GET_LANG(BRAND_NO_DEVICE,&islang), NULL); set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_SERIAL_NUM,&islang), GET_LANG(BRAND_NO_DEVICE,&islang), NULL); set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_IP,&islang), GET_LANG(BRAND_NO_DEVICE,&islang), NULL); set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_ROLLER_COUNT,&islang), GET_LANG(BRAND_NO_DEVICE,&islang), NULL); set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_HISTORY_COUNT,&islang), GET_LANG(BRAND_NO_DEVICE,&islang), NULL); } #endif about->appendix[count].key = NULL; about->appendix[count].content = NULL; about->appendix[count].url = NULL; return SCANNER_ERR_OK; } scanner_err hg_scanner_mgr::hg_scanner_enum(ScannerInfo* scanner_list, long* count, bool local_only) { std::vector devusbuf; long size = *count; scanner_err ret = SCANNER_ERR_OK; std::string g_vendor = GET_LANG(COMPANY_NAME, &islang); get_online_devices(devusbuf); *count = devusbuf.size(); if (*count > size) { ret = SCANNER_ERR_INSUFFICIENT_MEMORY; } else { for (size_t i = 0; i < devusbuf.size(); i++) { scanner_list->vid = g_supporting_devices[devusbuf[i].ind].vid; scanner_list->pid = g_supporting_devices[devusbuf[i].ind].pid; strcpy(scanner_list->name, devusbuf[i].display_name.c_str()); strcpy(scanner_list->type, g_supporting_devices[devusbuf[i].ind].type.c_str()); sprintf(scanner_list->model, "%x", g_supporting_devices[devusbuf[i].ind].pid); strcpy(scanner_list->vendor, g_vendor.c_str()); scanner_list++; } } return ret; } scanner_err hg_scanner_mgr::hg_scanner_open(scanner_handle* h, const char* name, bool shared, const char* user, const char* pwd, const char* check, char* rsc) { std::vector devs; std::vector::iterator it; usb_io* io = NULL; scanner_err ret = SCANNER_ERR_DEVICE_NOT_FOUND; *h = NULL; get_online_devices(devs); it = std::find(devs.begin(), devs.end(), name); if (it != devs.end()) { hg_scanner_mgr::last_open_msg_ = ""; ret = (scanner_err)usb_manager::instance()->open(it->dev, &io, &hg_scanner_mgr::last_open_msg_); if (ret == SCANNER_ERR_OK) { hg_scanner* scanner = g_supporting_devices[it->ind].create_scanner(it->display_name.c_str(), io, h); if (!scanner) { if (g_supporting_devices[it->ind].pid == 0x100 || g_supporting_devices[it->ind].pid == 0x200 || g_supporting_devices[it->ind].pid == 0x8620 || g_supporting_devices[it->ind].pid == 0x8730) { hg_scanner_200* s200 = new hg_scanner_200(it->display_name.c_str(), 0x100, io); scanner = dynamic_cast(s200); *h = (scanner_handle)s200; } else if (g_supporting_devices[it->ind].pid == 0x239 || g_supporting_devices[it->ind].pid == 0x139 || g_supporting_devices[it->ind].pid == 0x8000 || g_supporting_devices[it->ind].pid == 0x9000 || g_supporting_devices[it->ind].pid == 0x8739 || g_supporting_devices[it->ind].pid == 0x8629 || g_supporting_devices[it->ind].pid == 0x0439 || g_supporting_devices[it->ind].pid == 0x7039 || g_supporting_devices[it->ind].pid == 0x8529) { hg_scanner_239* s239 = new hg_scanner_239(it->display_name.c_str(), 0x239, io); scanner = dynamic_cast(s239); *h = (scanner_handle)s239; } else if (g_supporting_devices[it->ind].pid == 0x400 || g_supporting_devices[it->ind].pid == 0x7000 || g_supporting_devices[it->ind].pid == 0x8520) { hg_scanner_300* s400 = new hg_scanner_300(it->display_name.c_str(), 0x400, io); scanner = dynamic_cast(s400); *h = (scanner_handle)s400; } else if (g_supporting_devices[it->ind].pid == 0x300 || g_supporting_devices[it->ind].pid == 0x1000 || g_supporting_devices[it->ind].pid == 0x8420) { hg_scanner_300* s300 = new hg_scanner_300(it->display_name.c_str(), 0x300, io); scanner = dynamic_cast(s300); *h = (scanner_handle)s300; } } if (scanner) { 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].type.c_str()); scanner->set_read_over_with_no_data(hg_scanner_mgr::read_over_with_eof_); } std::lock_guard lock(mutex_dev_); std::vector::iterator ptr = std::find(online_devices_.begin(), online_devices_.end(), name); if (ptr != online_devices_.end()) ptr->scanner = (hg_scanner*)*h; } else if(hg_scanner_mgr::last_open_msg_.length()) hg_scanner_mgr::ui_default_callback(nullptr, SANE_EVENT_ERROR, (void*)hg_scanner_mgr::last_open_msg_.c_str(), (unsigned int*)&ret, nullptr); if(io) io->release(); } return *h ? SCANNER_ERR_OK : ret; } scanner_err hg_scanner_mgr::hg_scanner_close(scanner_handle h, bool force) { { std::lock_guard lock(mutex_dev_); for (size_t i = 0; i < online_devices_.size(); ++i) { if (online_devices_[i].scanner == h) { online_devices_[i].scanner = NULL; break; } } } SCAN_PTR(h)->close(force); 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, SANE_Int* id) { if (!len) return SCANNER_ERR_INVALID_PARAMETER; // global options ... if (!IS_PTR_NUMBER(name)) { if (strcmp(name, SANE_STD_OPT_NAME_DRIVER_VERSION) == 0) { char buf[40] = { 0 }; sprintf(buf, "%d.%d.%d.%d", hg_scanner_mgr::ver_major_, hg_scanner_mgr::ver_minor_, hg_scanner_mgr::ver_build_, hg_scanner_mgr::ver_patch_); if (*len <= strlen(buf)) { *len = strlen(buf) + 1; return SCANNER_ERR_INSUFFICIENT_MEMORY; } strcpy(data, buf); *len = strlen(buf); return SCANNER_ERR_OK; } #define TRY_STR_OPT(n, optn) \ if (strcmp(name, SANE_STD_OPT_NAME_##n) == 0) \ { \ std::string n(GET_LANG(optn, nullptr)); \ if (*len <= n.length()) \ { \ *len = n.length() + 1; \ \ return SCANNER_ERR_INSUFFICIENT_MEMORY; \ } \ \ strcpy(data, n.c_str()); \ *len = n.length(); \ \ return SCANNER_ERR_OK; \ } TRY_STR_OPT(MANUFACTURER, COMPANY_NAME); TRY_STR_OPT(COPYRIGHT, BRAND_COPYRIGHT); TRY_STR_OPT(CO_URL, url_link_en.c_str()); TRY_STR_OPT(CO_TEL, BRAND_COMPANY_TEL); TRY_STR_OPT(CO_ADDR, BRAND_COMPANY_ADDRESS); TRY_STR_OPT(CO_GPS, BRAND_URL_GPS); // 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, len); } if (strcmp(SANE_STD_OPT_NAME_DRIVER_LOG, name) == 0) { if (!data) return SCANNER_ERR_INVALID_PARAMETER; if (user_ == ADMIN_NAME && pwd_ == ADMIN_PWD) { std::string f(hg_log::log_file_path()); if (f.empty()) return SCANNER_ERR_NO_DATA; { std::ifstream in(f.c_str(), ios::in | ios::binary); std::ofstream out(data, ios::out | ios::binary); out << in.rdbuf(); } remove(f.c_str()); return SCANNER_ERR_OK; } else return SCANNER_ERR_ACCESS_DENIED; } else if (strcmp(SANE_STD_OPT_NAME_DEVICE_LOG, name) == 0) { if (!data) return SCANNER_ERR_INVALID_PARAMETER; if (user_ == ADMIN_NAME && pwd_ == ADMIN_PWD) { 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_LOGIN, name) == 0 || strcmp(SANE_STD_OPT_NAME_LOGOUT, name) == 0 || 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; } } int l = *len, err = SCAN_PTR(h)->get_setting(name, data, &l, id); *len = l; return (scanner_err)err; } scanner_err hg_scanner_mgr::hg_scanner_set_parameter(scanner_handle h, const char* name, void* data, long* len) { if (!IS_PTR_NUMBER(name)) { if (strcmp(SANE_STD_OPT_NAME_CO_GPS, name) == 0 || strcmp(SANE_STD_OPT_NAME_CO_ADDR, name) == 0 || strcmp(SANE_STD_OPT_NAME_CO_TEL, name) == 0 || strcmp(SANE_STD_OPT_NAME_CO_URL, name) == 0 || strcmp(SANE_STD_OPT_NAME_COPYRIGHT, name) == 0 || strcmp(SANE_STD_OPT_NAME_MANUFACTURER, name) == 0 || strcmp(SANE_STD_OPT_NAME_DRIVER_VERSION, name) == 0) return SCANNER_ERR_DEVICE_NOT_SUPPORT; if (strcmp(SANE_STD_OPT_NAME_LOGIN, name) == 0) { // str32 + 32 char* n = (char*)data, * p = n + 32; user_ = n; pwd_ = p; return SCANNER_ERR_OK; SCANNER_ERR_ACCESS_DENIED; } else if (strcmp(SANE_STD_OPT_NAME_LOGOUT, name) == 0) { // str32 + 32 char* n = (char*)data, * p = n + 32; if (user_ == n && pwd_ == p) { user_ = ""; pwd_ = ""; return SCANNER_ERR_OK; } return SCANNER_ERR_ACCESS_DENIED; } else if (strcmp(SANE_STD_OPT_NAME_DRIVER_LOG, name) == 0) { if (user_ == ADMIN_NAME && pwd_ == ADMIN_PWD) { hg_log::clear_log(); return SCANNER_ERR_OK; } return SCANNER_ERR_ACCESS_DENIED; } else if (strcmp(SANE_STD_OPT_NAME_DEVICE_LOG, name) == 0) { if (user_ == ADMIN_NAME && pwd_ == ADMIN_PWD) { return SCANNER_ERR_DEVICE_NOT_SUPPORT; } return SCANNER_ERR_ACCESS_DENIED; } else if (strcmp(SANE_STD_OPT_NAME_ROLLER_COUNT, name) == 0) { if (user_ == ADMIN_NAME && pwd_ == ADMIN_PWD) { 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) 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) { 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; 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; } } return (scanner_err)SCAN_PTR(h)->set_setting(name, data, len); } scanner_err hg_scanner_mgr::hg_scanner_start(scanner_handle h, void* async_event, int num) { return (scanner_err)SCAN_PTR(h)->start(); } scanner_err hg_scanner_mgr::hg_scanner_stop(scanner_handle h) { scanner_err err = (scanner_err)SCAN_PTR(h)->stop(true); // call from APP, block when all working-threads stopped - added on 2023-10-18 when handled double-feeding in SANE while (SCAN_PTR(h)->is_running() != hg_scanner::THREAD_RUNNING_IDLE) std::this_thread::sleep_for(std::chrono::milliseconds(3)); return err; } scanner_err hg_scanner_mgr::hg_scanner_get_img_info(scanner_handle h, SANE_Parameters* bmi, long len) { return (scanner_err)SCAN_PTR(h)->get_image_info(bmi, (int)len); } scanner_err hg_scanner_mgr::hg_scanner_read_img_data(scanner_handle h, unsigned char* data, long* len) { if (!len) return SCANNER_ERR_INVALID_PARAMETER; int l = *len, err = SCAN_PTR(h)->read_image_data(data, &l); *len = l; return (scanner_err)err; } scanner_err hg_scanner_mgr::hg_scanner_get_status(scanner_handle h, int setstutas) { return (scanner_err)SCAN_PTR(h)->status(); } scanner_err hg_scanner_mgr::hg_scanner_reset(scanner_handle h) { return (scanner_err)SCAN_PTR(h)->reset(); } scanner_err hg_scanner_mgr::hg_scanner_control(scanner_handle h, unsigned long code, void* data, unsigned* len) { //if (!len && code != IO_CTRL_CODE_TEST_SINGLE) // return SCANNER_ERR_INVALID_PARAMETER; if (code == IO_CTRL_CODE_ABOUT_INFO) return get_about_info(h, data, len); else if (code == IO_CTRL_CODE_GET_LOG_FILE && len && *len == LOG_FILE_DRIVER) { if (!data) return SCANNER_ERR_INVALID_PARAMETER; std::string f(hg_log::log_file_path()); if (f.empty()) *((char*)data) = 0; else strcpy((char*)data, f.c_str()); return SCANNER_ERR_OK; } else if (!h) return SCANNER_ERR_INVALID_PARAMETER; else return (scanner_err)SCAN_PTR(h)->device_io_control(code, data, len); } void hg_scanner_mgr::on_language_changed(void) { std::lock_guard lock(mutex_dev_); for (auto& v: online_devices_) { if (v.scanner) v.scanner->on_language_changed(); } } const char* hg_scanner_mgr::last_open_message(void) { return hg_scanner_mgr::last_open_msg_.c_str(); }