diff --git a/hgdriver/hgdev/common_setting.cpp b/hgdriver/hgdev/common_setting.cpp index 470564c..6c0d3f6 100644 --- a/hgdriver/hgdev/common_setting.cpp +++ b/hgdriver/hgdev/common_setting.cpp @@ -134,6 +134,73 @@ static struct paper_size {PAPER_B5_LATERAL, {250, 176}}, // {PAPER_B5, {182, 257}}, {PAPER_B6_LATERAL, {176, 125}} }; +// Custom 纸张的大小由用户定义. +// Letter Letter 纸(216 毫米 × 279 毫米). +// Legal Legal 纸(216 毫米 × 356 毫米). +// A4 A4 纸(210 毫米 × 297 毫米). +// CSheet C 纸(432 毫米 × 559 毫米). +// DSheet D 纸(559 毫米 × 864 毫米). +// ESheet E 纸(864 毫米 × 1118 毫米). +// LetterSmall Letter small 纸(216 毫米 × 279 毫米). +// Tabloid Tabloid 纸(279 毫米 × 432 毫米). +// Ledger Ledger 纸(432 毫米 × 279 毫米). +// Statement Statement 纸(140 毫米 × 216 毫米). +// Executive Executive 纸(184 毫米 × 267 毫米). +// A3 A3 纸(297 毫米 × 420 毫米). +// A4Small A4 small 纸(210 毫米 × 297 毫米). +// A5 A5 纸(148 毫米 × 210 毫米). +// B4 B4 纸(250 × 353 毫米). +// B5 B5 纸(176 毫米 × 250 毫米). +// Folio Folio 纸(216 毫米 × 330 毫米). +// Quarto Quarto 纸(215 毫米 × 275 毫米). +// Standard10x14 Standard 纸(254 毫米 × 356 毫米). +// Standard11x17 Standard 纸(279 毫米 × 432 毫米). +// Note Note 纸(216 毫米 × 279 毫米). +// Number9Envelope #9 envelope(98 毫米 × 225 毫米). +// Number10Envelope #10 envelope(105 毫米 × 241 毫米). +// Number11Envelope #11 envelope(114 毫米 × 263 毫米). +// Number12Envelope #12 envelope(120 毫米 × 279 毫米). +// Number14Envelope #14 envelope(127 毫米 × 292 毫米). +// DLEnvelope DL 信封(110 毫米 × 220 毫米). +// C5Envelope C5 信封(162 毫米 × 229 毫米). +// C3Envelope C3 信封(324 毫米 × 458 毫米). +// C4Envelope C4 信封(229 毫米 × 324 毫米). +// C6Envelope C6 信封(114 毫米 × 162 毫米). +// C65Envelope C65 信封(114 毫米 × 229 毫米). +// B4Envelope B4 信封(250 × 353 毫米). +// B5Envelope B5 信封(176 毫米 × 250 毫米). +// B6Envelope B6 信封(176 毫米 × 125 毫米). +// ItalyEnvelope Italy envelope(110 毫米 × 230 毫米). +// MonarchEnvelope Monarch envelope(98 毫米 × 191 毫米). +// PersonalEnvelope 6 3 / 4 envelope(92 毫米 × 165 毫米). +// USStandardFanfold US standard fanfold(378 毫米 × 279 毫米). +// GermanStandardFanfold German standard fanfold(216 毫米 × 305 毫米). +// GermanLegalFanfold German legal fanfold(216 毫米 × 330 毫米). +// IsoB4 ISO B4(250 毫米 × 353 毫米). +// JapanesePostcard Japanese postcard(100 毫米 × 148 毫米). +// Standard9x11 Standard 纸(229 毫米 × 279 毫米). +// Standard10x11 Standard 纸(254 毫米 × 279 毫米). +// Standard15x11 Standard 纸(381 毫米 × 279 毫米). +// InviteEnvelope 邀请函信封(220 毫米 × 220 毫米). +// LetterExtra Letter extra 纸(236 毫米 × 305 毫米).该值特定于 PostScript 驱动程序, 仅供 Linotronic 打印机使用以节省纸张. +// LegalExtra Legal extra 纸(236 毫米 × 381 毫米).该值特定于 PostScript 驱动程序, 仅供 Linotronic 打印机使用以节省纸张. +// TabloidExtra Tabloid extra 纸(297 毫米 × 457 毫米).该值特定于 PostScript 驱动程序, 仅供 Linotronic 打印机使用以节省纸张. +// A4Extra A4 extra 纸(236 毫米 × 322 毫米).该值是针对 PostScript 驱动程序的, 仅供 Linotronic 打印机使用以节省纸张. +// LetterTransverse Letter transverse 纸(210 毫米 × 279 毫米). +// A4Transverse A4 transverse 纸(210 毫米 × 297 毫米). +// LetterExtraTransverse Letter extra transverse 纸(236 毫米 × 305 毫米). +// APlus SuperA / SuperA / A4 纸(227 毫米 × 356 毫米). +// BPlus SuperB / SuperB / A3 纸(305 毫米 × 487 毫米). +// LetterPlus Letter plus 纸(216 毫米 × 322 毫米). +// A4Plus A4 plus 纸(210 毫米 × 330 毫米). +// A5Transverse A5 transverse 纸(148 毫米 × 210 毫米). +// B5Transverse JIS B5 transverse 纸(182 毫米 × 257 毫米). +// A3Extra A3 extra 纸(322 毫米 × 445 毫米). +// A5Extra A5 extra 纸(174 毫米 × 235 毫米). +// B5Extra ISO B5 extra 纸(201 毫米 × 276 毫米). +// A2 A2 纸(420 毫米 × 594 毫米). +// A3Transverse A3 transverse 纸(297 毫米 × 420 毫米). +// A3ExtraTransverse A3 extra transverse 纸(322 毫米 × 445 毫米). static int match_best(struct _fixed_option* arr, size_t num, std::string& val, bool& exact) { diff --git a/hgdriver/hgdev/hg_scanner.cpp b/hgdriver/hgdev/hg_scanner.cpp index 5e30a42..21bdcd9 100644 --- a/hgdriver/hgdev/hg_scanner.cpp +++ b/hgdriver/hgdev/hg_scanner.cpp @@ -2384,12 +2384,45 @@ int hg_scanner::device_io_control(unsigned long code, void* data, unsigned* len) return clear_roller_num(); } + else if (code == IO_CTRL_CODE_GET_FINAL_IMAGE_FORMAT) + { + SANE_FinalImgFormat* fmt = (SANE_FinalImgFormat*)data; + if (!fmt) + { + *len = sizeof(SANE_FinalImgFormat); + + return SCANNER_ERR_INSUFFICIENT_MEMORY; + } + + if (img_type_ == ".bmp") + fmt->img_format = SANE_IMAGE_TYPE_BMP; + else if (img_type_ == ".jpg") + fmt->img_format = SANE_IMAGE_TYPE_JPG; + else if (img_type_ == ".png") + fmt->img_format = SANE_IMAGE_TYPE_PNG; + else if (img_type_ == ".gif") + fmt->img_format = SANE_IMAGE_TYPE_GIF; + else + fmt->img_format = SANE_IMAGE_TYPE_BMP; + + return SCANNER_ERR_OK; + } else if (code == IO_CTRL_CODE_SET_FINAL_IMAGE_FORMAT) { SANE_FinalImgFormat* fmt = (SANE_FinalImgFormat*)data; return set_final_image_format(fmt); } + else if (code == IO_CTRL_CODE_GET_FINAL_COMPRESSION) + { + *(int*)data = SANE_COMPRESSION_NONE; + + return SCANNER_ERR_OK; + } + else if (code == IO_CTRL_CODE_SET_FINAL_COMPRESSION) + { + return SCANNER_ERR_DEVICE_NOT_SUPPORT; + } else if(code == IO_CTRL_CODE_TEST_SINGLE) { return set_leaflet_scan(); @@ -2527,6 +2560,13 @@ int hg_scanner::device_io_control(unsigned long code, void* data, unsigned* len) //setting_help(data); return SCANNER_ERR_OK; } + else if (code == IO_CTRL_CODE_GET_IMAGE_QUEUE_COUNT) + { + *len = final_imgs_.size(); + + return wait_img_.is_waiting() && wait_usb_.is_waiting() ? SCANNER_ERR_NO_DATA : SCANNER_ERR_OK; + } + return SCANNER_ERR_DEVICE_NOT_SUPPORT; } std::string hg_scanner::get_firmware_version(void) @@ -2592,7 +2632,7 @@ int hg_scanner::set_final_image_format(SANE_FinalImgFormat* fmt) case SANE_IMAGE_TYPE_SVG: return SCANNER_ERR_INVALID_PARAMETER; default: - img_type_ = ""; + img_type_ = ".bmp"; break; } return SCANNER_ERR_OK; diff --git a/hgdriver/hgdev/scanner_manager.cpp b/hgdriver/hgdev/scanner_manager.cpp index 1ca729f..d1c7f8c 100644 --- a/hgdriver/hgdev/scanner_manager.cpp +++ b/hgdriver/hgdev/scanner_manager.cpp @@ -415,6 +415,8 @@ scanner_err hg_scanner_mgr::hg_scanner_enum(ScannerInfo* scanner_list, long* cou { 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, g_supporting_devices[devusbuf[i].ind].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); diff --git a/hgsane/sane_hg_mdw.cpp b/hgsane/sane_hg_mdw.cpp index 0c6b2eb..10b69f6 100644 --- a/hgsane/sane_hg_mdw.cpp +++ b/hgsane/sane_hg_mdw.cpp @@ -68,6 +68,36 @@ namespace local_utility return (SANE_Status)hgerr; } + int sane_statu_2_scanner_err(int statu) + { +#define RETURN_MATCH_ERROR(hg, sane) \ + if(statu == sane) \ + return hg; + + RETURN_MATCH_ERROR(SCANNER_ERR_OK, SANE_STATUS_GOOD); + RETURN_MATCH_ERROR(SCANNER_ERR_INVALID_PARAMETER, SANE_STATUS_INVAL); + RETURN_MATCH_ERROR(SCANNER_ERR_INSUFFICIENT_MEMORY, SANE_STATUS_NO_MEM); + RETURN_MATCH_ERROR(SCANNER_ERR_ACCESS_DENIED, SANE_STATUS_ACCESS_DENIED); + RETURN_MATCH_ERROR(SCANNER_ERR_IO_PENDING, SANE_STATUS_GOOD); + RETURN_MATCH_ERROR(SCANNER_ERR_NOT_EXACT, SANE_STATUS_GOOD); + RETURN_MATCH_ERROR(SCANNER_ERR_CONFIGURATION_CHANGED, SANE_STATUS_GOOD); + RETURN_MATCH_ERROR(SCANNER_ERR_NOT_OPEN, SANE_STATUS_NO_DOCS); + RETURN_MATCH_ERROR(SCANNER_ERR_NOT_START, SANE_STATUS_NO_DOCS); + RETURN_MATCH_ERROR(SCANNER_ERR_NO_DATA, SANE_STATUS_EOF); + RETURN_MATCH_ERROR(SCANNER_ERR_HAS_DATA_YET, SANE_STATUS_IO_ERROR); + RETURN_MATCH_ERROR(SCANNER_ERR_OUT_OF_RANGE, SANE_STATUS_NO_MEM); + RETURN_MATCH_ERROR(SCANNER_ERR_IO, SANE_STATUS_IO_ERROR); + RETURN_MATCH_ERROR(SCANNER_ERR_TIMEOUT, SANE_STATUS_IO_ERROR); + + RETURN_MATCH_ERROR(SCANNER_ERR_DEVICE_NOT_FOUND, SANE_STATUS_NO_DOCS); + RETURN_MATCH_ERROR(SCANNER_ERR_DEVICE_NOT_SUPPORT, SANE_STATUS_UNSUPPORTED); + RETURN_MATCH_ERROR(SCANNER_ERR_DEVICE_BUSY, SANE_STATUS_DEVICE_BUSY); + RETURN_MATCH_ERROR(SCANNER_ERR_DEVICE_COVER_OPENNED, SANE_STATUS_COVER_OPEN); + RETURN_MATCH_ERROR(SCANNER_ERR_DEVICE_NO_PAPER, SANE_STATUS_NO_DOCS); + RETURN_MATCH_ERROR(SCANNER_ERR_DEVICE_PAPER_JAMMED, SANE_STATUS_JAMMED); + + return statu; + } void* acquire_memory(size_t bytes, const char* info) { @@ -437,6 +467,7 @@ hg_sane_middleware* hg_sane_middleware::instance(void) } void hg_sane_middleware::clear(void) { + local_utility::stop_work(); if (hg_sane_middleware::inst_) { delete hg_sane_middleware::inst_; @@ -992,10 +1023,30 @@ SANE_Option_Descriptor* hg_sane_middleware::find_stored_descriptor(SANE_Handle h return find_stored_descriptor(dev.dev_name.c_str(), option); } -bool hg_sane_middleware::get_current_value(scanner_handle handle, int option, void* value, SANE_Value_Type *type) +void hg_sane_middleware::reload_current_value(scanner_handle handle, std::vector* changed) +{ + long count = 0; + + if (changed) + changed->clear(); + hg_scanner_get_parameter(handle, 0, NULL, &count); + for (int i = 1; i < count; ++i) + { + std::string val(get_option_json(handle, i)); + json* jsn = new json(); + if (jsn->attach_text(&val[0]) && + jsn->get_value("type", val)) + { + if (refresh_current_value(i, jsn)) + changed->push_back(i); + } + delete jsn; + } +} +bool hg_sane_middleware::get_current_value(scanner_handle handle, int option, void* value, SANE_Value_Type* type) { std::string val(get_option_json(handle, option)); - json* jsn = new json(); + json* jsn = new json(); int estimate = 20; bool ret = false; @@ -1052,8 +1103,8 @@ bool hg_sane_middleware::get_current_value(scanner_handle handle, int option, vo void* hg_sane_middleware::get_default_value(scanner_handle handle, int option) { std::string val(get_option_json(handle, option)); - void* data = nullptr; - json* jsn = new json(); + void* data = nullptr; + json* jsn = new json(); if (jsn->attach_text(&val[0]) && jsn->get_value("type", val)) @@ -1105,28 +1156,13 @@ void* hg_sane_middleware::get_default_value(scanner_handle handle, int option) } } delete jsn; - - return data; -} -void hg_sane_middleware::reload_current_value(scanner_handle handle, std::vector* changed) -{ - long count = 0; - if (changed) - changed->clear(); - hg_scanner_get_parameter(handle, 0, NULL, &count); - for (int i = 1; i < count; ++i) + if (!data && std_opt_) { - std::string val(get_option_json(handle, i)); - json* jsn = new json(); - if (jsn->attach_text(&val[0]) && - jsn->get_value("type", val)) - { - if (refresh_current_value(i, jsn)) - changed->push_back(i); - } - delete jsn; + data = std_opt_->get_default_value(handle, option); } + + return data; } SANE_Status hg_sane_middleware::get_devices(const SANE_Device*** device_list, SANE_Bool local_only) { @@ -1452,6 +1488,24 @@ SANE_Status hg_sane_middleware::set_option(SANE_Handle h, SANE_Int option, SANE_ return status; } } +bool hg_sane_middleware::get_cur_value(SANE_Handle handle, int option, void* value, SANE_Value_Type* type) +{ + scanner_handle h = find_openning_device(handle); + + if (!h) + return false; + + return get_current_value(h, option, value, type); +} +void* hg_sane_middleware::get_def_value(SANE_Handle handle, int option) +{ + scanner_handle h = find_openning_device(handle); + + if (!h) + return NULL; + + return get_default_value(h, option); +} SANE_Status hg_sane_middleware::io_control(SANE_Handle h, unsigned long code, void* data, unsigned* len) { OPENDEV od; @@ -1873,7 +1927,6 @@ extern "C" { // avoid compiler exporting name in C++ style !!! } void inner_sane_exit(void) { - local_utility::stop_work(); hg_sane_middleware::clear(); } SANE_Status inner_sane_get_devices(const SANE_Device*** device_list, SANE_Bool local_only) @@ -1974,6 +2027,10 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) } } } + else if (reason == DLL_PROCESS_DETACH) + { + inner_sane_exit(); + } return TRUE; } diff --git a/hgsane/sane_hg_mdw.h b/hgsane/sane_hg_mdw.h index 799073a..4d3f8b2 100644 --- a/hgsane/sane_hg_mdw.h +++ b/hgsane/sane_hg_mdw.h @@ -80,9 +80,9 @@ class hg_sane_middleware SANE_Option_Descriptor* find_stored_descriptor(const char* name, int option); SANE_Option_Descriptor* find_stored_descriptor(SANE_Handle handle, int option); - bool get_current_value(scanner_handle handle, int option, void* value, SANE_Value_Type *type = NULL); - void* get_default_value(scanner_handle handle, int option); // caller should call local_utility::free_memory to free the returned value void reload_current_value(scanner_handle handle, std::vector* changed = NULL); + bool get_current_value(scanner_handle handle, int option, void* value, SANE_Value_Type* type = NULL); + void* get_default_value(scanner_handle handle, int option); // caller should call local_utility::free_memory to free the returned value /// /// 关联项处理 @@ -185,9 +185,17 @@ public: SANE_Option_Descriptor* get_option_descriptor(SANE_Handle h, SANE_Int option); SANE_Status set_option(SANE_Handle h, SANE_Int option, SANE_Action action, void* value, SANE_Int* after_do); + bool get_cur_value(SANE_Handle handle, int option, void* value, SANE_Value_Type* type = NULL); + void* get_def_value(SANE_Handle handle, int option); // caller should call local_utility::free_memory to free the returned value // extension ... SANE_Status io_control(SANE_Handle h, unsigned long code, void* data, unsigned* len); public: }; + +namespace local_utility +{ + void free_memory(void* m); + int sane_statu_2_scanner_err(int statu); +} diff --git a/hgsane/sane_option.cpp b/hgsane/sane_option.cpp index f2e6935..e50656f 100644 --- a/hgsane/sane_option.cpp +++ b/hgsane/sane_option.cpp @@ -263,6 +263,7 @@ void sane_std_opts::init_known_opt(int option, SANE_Option_Descriptor* desc) om.known.desc->title = "Duplex"; om.known.desc->type = SANE_TYPE_BOOL; om.known.desc->unit = SANE_UNIT_NONE; + om.init = "true"; known_opts_.push_back(om); } } @@ -287,6 +288,7 @@ void sane_std_opts::init_known_opt(int option, SANE_Option_Descriptor* desc) om.known.desc->title = "Page Width"; om.known.desc->type = SANE_TYPE_INT; om.known.desc->unit = SANE_UNIT_MM; + om.init = "210"; known_opts_.push_back(om); om.known.opt = opt_num_base_ + known_opts_.size(); @@ -300,6 +302,7 @@ void sane_std_opts::init_known_opt(int option, SANE_Option_Descriptor* desc) om.known.desc->title = "Page Height"; om.known.desc->type = SANE_TYPE_INT; om.known.desc->unit = SANE_UNIT_MM; + om.init = "297"; known_opts_.push_back(om); } } @@ -319,6 +322,39 @@ bool sane_std_opts::is_known_option(int opt, SANE_Option_Descriptor** user) return sod != nullptr; } +void* sane_std_opts::get_default_value(scanner_handle h, int opt) +{ + int ind = -1; + void* ret = nullptr; + + if (get_known_option(opt, &ind)) + { + OPTMAP* op = &known_opts_[ind]; + if (op->known.desc->type == SANE_TYPE_BOOL) + { + ret = local_utility::acquire_memory(sizeof(SANE_Bool), nullptr); + *(SANE_Bool*)ret = op->init == "true" ? SANE_TRUE : SANE_FALSE; + } + else if (op->known.desc->type == SANE_TYPE_INT) + { + ret = local_utility::acquire_memory(sizeof(SANE_Int), nullptr); + *(SANE_Int*)ret = atoi(op->init.c_str()); + } + else if(op->known.desc->type == SANE_TYPE_FIXED) + { + ret = local_utility::acquire_memory(sizeof(SANE_Fixed), nullptr); + *(SANE_Fixed*)ret = SANE_FIX(atof(op->init.c_str())); + } + else if (op->known.desc->type == SANE_TYPE_STRING) + { + ret = local_utility::acquire_memory(op->known.desc->size + 4, nullptr); + memset(ret, 0, op->known.desc->size + 4); + strcpy((char*)ret, op->init.c_str()); + } + } + + return ret; +} scanner_err sane_std_opts::get_value(scanner_handle h, int opt, void* buf) { int ind = -1; diff --git a/hgsane/sane_option.h b/hgsane/sane_option.h index aa825ac..bc888ce 100644 --- a/hgsane/sane_option.h +++ b/hgsane/sane_option.h @@ -33,6 +33,7 @@ class sane_std_opts { SANEOPT known; SANEOPT user; + std::string init; }OPTMAP; std::vector known_opts_; int opt_num_base_; @@ -57,6 +58,7 @@ public: SANE_Option_Descriptor* get_option(int option); bool is_known_option(int opt, SANE_Option_Descriptor** user = nullptr); + void* get_default_value(scanner_handle h, int opt); // call local_utility::free_memory to free the returned buffer scanner_err get_value(scanner_handle h, int opt, void* buf); // call this ONLY when is_known_option returnning true scanner_err set_value(scanner_handle h, int opt, void* buf); // call this ONLY when is_known_option returnning true }; diff --git a/sdk/hginclude/huagaoxxx_warraper_ex.h b/sdk/hginclude/huagaoxxx_warraper_ex.h index 125276a..267b5b8 100644 --- a/sdk/hginclude/huagaoxxx_warraper_ex.h +++ b/sdk/hginclude/huagaoxxx_warraper_ex.h @@ -30,9 +30,9 @@ #ifdef WIN32 #ifndef HGSCANNER_EXPORT #ifdef _DEBUG -#pragma comment(lib, "debug/hgscanner.lib") +#pragma comment(lib, "debug/scanner.lib") #else -#pragma comment(lib, "release/hgscanner.lib") +#pragma comment(lib, "release/scanner.lib") #endif #endif #endif @@ -134,6 +134,8 @@ typedef struct _device { + unsigned short vid; + unsigned short pid; char name[MAX_NAME_LEN]; // 设备ANSI名称,驱动需要保证该名称唯一, // 即使在有几台同类设备同时连接上时,也能通过该名称访问指定的设备 // 参考命名:名称+资源,如“HG200 USB1”