diff --git a/sane/s2t_api.h b/sane/s2t_api.h index a322f46..7975835 100644 --- a/sane/s2t_api.h +++ b/sane/s2t_api.h @@ -122,7 +122,7 @@ enum twain_xfer TWAIN_XFER_Memory = 2, // to be implementing ... }; -typedef bool(__stdcall* set_opt_value)(void* val, value_role role, void* param); // return false to stop the callback +typedef bool(__stdcall* set_opt_value)(void* val, value_role role, value_limit limit, void* param); // return false to stop the callback struct __declspec(novtable) IRef { COM_API_DECLARE(long, add_ref(void)); @@ -302,67 +302,87 @@ struct delete_scanner #include namespace sane_opts { + enum + { + RANGE_POS_CURRENT = 0, + RANGE_POS_DEFAULT, + RANGE_POS_ENUM_BEGIN, + RANGE_POS_LOWER = RANGE_POS_ENUM_BEGIN, + RANGE_POS_UPPER, + RANGE_POS_STEP, + }; + template class get_opts { public: - T* init_; - T* cur_; - T* lower_; - T* upper_; - T* step_; - std::vector* vvs_; - std::list* lvs_; + // 0 - cur val; 1 - def val; + // + // LIST: 2 - elements ... + // + // RANGE: 2 - lower; 3 - upper; 4 - step + T range[5]; + value_limit lmt_; + + std::vector* lvs_; + value_limit* limit_; public: - get_opts(T* cur = NULL, T* init = NULL, std::vector* vs = NULL, std::list* ls = NULL, T* lower = NULL, T* upper = NULL, T* step = NULL) - : init_(init), cur_(cur), vvs_(vs), lvs_(ls) - , lower_(lower), upper_(upper), step_(step) + get_opts(value_limit* limit, std::vector* ls) : limit_(limit), lvs_(ls) {} ~get_opts() {} + + void re_order(void) + { + if (limit_) + *limit_ = lmt_; + + if (lmt_ == VAL_LIMIT_RANGE || lmt_ == VAL_LIMIT_NONE) + { + if (lvs_) + { + lvs_->clear(); + for (size_t i = 0; i < _countof(range); ++i) + lvs_->push_back(range[i]); + } + } + else if(lvs_) + { + lvs_->insert(lvs_->begin(), range[RANGE_POS_DEFAULT]); + lvs_->insert(lvs_->begin(), range[RANGE_POS_CURRENT]); + } + } }; template - bool __stdcall set_opt_value(void* val, value_role role, void* param) + bool __stdcall set_opt_value(void* val, value_role role, value_limit limit, void* param) { get_opts* v = (get_opts*)param; bool go = true; + v->lmt_ = limit; if (role & VAL_ROLE_CURRENT) { - if (v->cur_) - { - *v->cur_ = *(T*)val; - } + v->range[RANGE_POS_CURRENT] = *(T*)val; } if (role & VAL_ROLE_DEFAULT) { - if (v->init_) - { - *v->init_ = *(T*)val; - } + v->range[RANGE_POS_DEFAULT] = *(T*)val; } if (role & VAL_ROLE_LOWER) { - if (v->lower_) - *v->lower_ = *(T*)val; + v->range[RANGE_POS_LOWER] = *(T*)val; } if (role & VAL_ROLE_UPPER) { - if (v->upper_) - *v->upper_ = *(T*)val; + v->range[RANGE_POS_UPPER] = *(T*)val; } + if (role & VAL_ROLE_STEP) { - if (v->step_) - *v->step_ = *(T*)val; - - return go; + v->range[RANGE_POS_STEP] = *(T*)val; } - - if (v->vvs_) - v->vvs_->push_back(*(T*)val); else if (v->lvs_) v->lvs_->push_back(*(T*)val); @@ -370,25 +390,17 @@ namespace sane_opts } } -#define GET_SANE_OPT(type, object, id_name, cur, init, vec, lst) \ +#define GET_SANE_OPT(type, object, id_name, limit, vct) \ { \ int ind = object->sane_opt_id_##id_name##(); \ + sane_opts::get_opts op(limit, vct); \ if(ind > 0) \ - { \ - sane_opts::get_opts op(cur, init, vec, lst); \ object->get_value(ind, sane_opts::set_opt_value, &op);\ - } \ - } -#define GET_SANE_OPT_RANGE(type, object, id_name, cur, init, low, up, step) \ - { \ - int ind = object->sane_opt_id_##id_name##(); \ - if(ind > 0) \ - { \ - sane_opts::get_opts op(cur, init, NULL, NULL, low, up, step); \ - object->get_value(ind, sane_opts::set_opt_value, &op);\ - if(step && fabs(*step) < .000001) *step = 1; \ - } \ + else \ + return capUnsupported(); \ + op.re_order(); \ } + #define SET_SANE_OPT(ret, object, id_name, val) \ { \ int ind = object->sane_opt_id_##id_name##(); \ diff --git a/sane/sane.def b/sane/sane.def index 7b08bc3..13abb0a 100644 --- a/sane/sane.def +++ b/sane/sane.def @@ -21,4 +21,7 @@ EXPORTS sane_hgsane_strstatus sane_hgsane_init_ex sane_hgsane_io_control - sane_hgsane_err_desc \ No newline at end of file + sane_hgsane_err_desc + sane_hgsane_get_option_descriptor_ex + sane_hgsane_control_option_ex + sane_hgsane_read_ext_info \ No newline at end of file diff --git a/sane/scanner.cpp b/sane/scanner.cpp index c152720..fca243b 100644 --- a/sane/scanner.cpp +++ b/sane/scanner.cpp @@ -508,7 +508,7 @@ void __stdcall scanner::ui_callback(int uev, void* sender, void* param) } bool scanner::is_option_float(int sn, void* param) { - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor((SANE_Handle)param, sn); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor((SANE_Handle)param, (const void*)sn); if (desc) return desc->type == SANE_TYPE_FIXED; @@ -614,7 +614,7 @@ void scanner::apply_config(void) { void* data = &v[0]; SANE_Fixed fixed = 0; - const SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, id); + const SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (const void*)id); if (desc) { char* buf = NULL; @@ -627,7 +627,7 @@ void scanner::apply_config(void) strcpy(buf, v.c_str()); data = buf; } - hg_sane_middleware::instance()->set_option(handle_, id, SANE_ACTION_SET_VALUE, data, &after); + hg_sane_middleware::instance()->set_option(handle_, (const void*)id, SANE_ACTION_SET_VALUE, data, &after); if (buf) delete[] buf; @@ -799,9 +799,9 @@ int scanner::init_options_id(void) #define SET_OPT_ID(var, predef, func) \ SET_SANE_OPT_ID(op_id, var, predef, desc->name, func) - while ((desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, op_id))) + while ((desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (const void*)op_id))) { - void* val = hg_sane_middleware::instance()->get_def_value(handle_, op_id, NULL, true); + void* val = hg_sane_middleware::instance()->get_def_value(handle_, (void*)op_id, NULL, true); if (val) { size_t len = 0; @@ -906,6 +906,7 @@ int scanner::init_options_id(void) EXAPI ea; \ ea.ind = ex_##name##_id_ = ex_id_++; \ ea.ex_api = &scanner::handle_ex_##name; \ + ea.base_ind = -1; \ ex_opts_.push_back(ea); \ } EX_APPENDIX_API(final_compression); @@ -1087,23 +1088,23 @@ bool scanner::get_option_value_with_parent(int sn, set_opt_value setv, void* par if (sn == scan_count_id_) { - SANE_Option_Descriptor* parent = hg_sane_middleware::instance()->get_option_descriptor(handle_, scan_mode_id_); + SANE_Option_Descriptor* parent = hg_sane_middleware::instance()->get_option_descriptor(handle_, (const void*)scan_mode_id_); char* buf = new char[parent->size + 4]; memset(buf, 0, parent->size); - hg_sane_middleware::instance()->get_cur_value(handle_, scan_mode_id_, buf); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)scan_mode_id_, buf); handled = compare_sane_opt(OPTION_VALUE_SMZS_LXSM, buf); delete[] buf; if (handled) { int count = -1; value_role role = VAL_ROLE_CURRENT; - buf = (char*)hg_sane_middleware::instance()->get_def_value(handle_, scan_mode_id_); + buf = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)scan_mode_id_); if (compare_sane_opt(OPTION_VALUE_SMZS_LXSM, buf)) role = value_role(role | VAL_ROLE_DEFAULT); local_utility::free_memory(buf); - setv(&count, value_role(VAL_ROLE_CURRENT | VAL_ROLE_DEFAULT), param); + setv(&count, value_role(VAL_ROLE_CURRENT | VAL_ROLE_DEFAULT), VAL_LIMIT_NONE, param); } } else @@ -1117,24 +1118,24 @@ bool scanner::set_option_value_with_parent(int sn, void* data, int* err) // retu if (sn == scan_count_id_) { - SANE_Option_Descriptor* parent = hg_sane_middleware::instance()->get_option_descriptor(handle_, scan_mode_id_); + SANE_Option_Descriptor* parent = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)scan_mode_id_); char* val = new char[parent->size + 4]; SANE_Int after = 0; memset(val, 0, parent->size + 4); - hg_sane_middleware::instance()->get_cur_value(handle_, scan_mode_id_, val); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)scan_mode_id_, val); if (compare_sane_opt(OPTION_VALUE_SMZS_LXSM, val)) { if (*(int*)data != -1) { strcpy(val, OPTION_VALUE_SMZS_SMZDZS); - *err = hg_sane_middleware::instance()->set_option(handle_, scan_mode_id_, SANE_ACTION_SET_VALUE, val, &after); + *err = hg_sane_middleware::instance()->set_option(handle_, (void*)scan_mode_id_, SANE_ACTION_SET_VALUE, val, &after); } } else if (*(int*)data == -1) { strcpy(val, OPTION_VALUE_SMZS_LXSM); - *err = hg_sane_middleware::instance()->set_option(handle_, scan_mode_id_, SANE_ACTION_SET_VALUE, val, &after); + *err = hg_sane_middleware::instance()->set_option(handle_, (void*)scan_mode_id_, SANE_ACTION_SET_VALUE, val, &after); } delete[] val; } @@ -1173,7 +1174,7 @@ int scanner::set_option_value(int sn, SANE_Value_Type type, int size, void* data val = buf; } - ret = hg_sane_middleware::instance()->set_option(handle_, sn, SANE_ACTION_SET_VALUE, val, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)sn, SANE_ACTION_SET_VALUE, val, &after); if (type == SANE_TYPE_BOOL) { @@ -1195,6 +1196,26 @@ int scanner::set_option_value(int sn, SANE_Value_Type type, int size, void* data return ret; } +int scanner::set_is_multiout(bool enable) +{ + int ret = SCANNER_ERR_OK; + + if (is_multiout_id_ > 0) + { + SANE_Bool multi = SANE_FALSE; + SANE_Int after = 0; + + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)is_multiout_id_, &multi); // parent item ... + if (enable ^ (multi == SANE_TRUE)) + { + multi = enable ? SANE_TRUE : SANE_FALSE; + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)is_multiout_id_, SANE_ACTION_SET_VALUE, &multi, &after); + after = 0; + } + } + + return ret; +} scanner::EXAPIPOS scanner::find_ex_api(int op_id) { @@ -1204,30 +1225,25 @@ scanner::EXAPIPOS scanner::find_ex_api(int op_id) EX_OPTION_HANDLER_IMPL(multiout) { int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); + SANE_Bool parent = SANE_FALSE; + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)is_multiout_id_, &parent); if (setv) { - char* cur = new char[desc->size], - * def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, base_id); - int now = 0, // sane_opt_trans::multiout_value_to_twain(cur) + char* cur = (char*)hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id), + * def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); + int now = sane_opt_trans::multiout_value_to_twain(cur), init = sane_opt_trans::multiout_value_to_twain(def), val = 0; local_utility::free_memory(def); - memset(cur, 0, desc->size); - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, cur); - now = sane_opt_trans::multiout_value_to_twain(cur); - delete[] cur; + local_utility::free_memory(cur); { // parent item ... - SANE_Bool enable = SANE_TRUE; - if (hg_sane_middleware::instance()->get_cur_value(handle_, is_multiout_id_, &enable)) - { - if (!enable) - now = MULTI_OUT_NONE; - } + if (!parent) + now = MULTI_OUT_NONE; } do @@ -1237,7 +1253,9 @@ EX_OPTION_HANDLER_IMPL(multiout) // we have no 'MULTI_OUT_NONE' item in this option, this is used as is_multiout_id_ val = MULTI_OUT_NONE; value_role role = val == now ? VAL_ROLE_CURRENT : VAL_ROLE_NONE; - if (!setv(&val, role, data)) + if (val == init) + role = (value_role)(role | VAL_ROLE_DEFAULT); + if (!setv(&val, role, VAL_LIMIT_ENUM, data)) break; for (int i = 0; desc->constraint.string_list[i]; ++i) { @@ -1247,7 +1265,7 @@ EX_OPTION_HANDLER_IMPL(multiout) role = VAL_ROLE_CURRENT; if (val == init) role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&val, role, data)) + if (!setv(&val, role, VAL_LIMIT_ENUM, data)) break; } } @@ -1263,19 +1281,18 @@ EX_OPTION_HANDLER_IMPL(multiout) if (in && strcmp(in, "\346\227\240")) { - // enable multi-out ... - *((SANE_Bool*)val) = SANE_TRUE; - ret = hg_sane_middleware::instance()->set_option(handle_, is_multiout_id_, SANE_ACTION_SET_VALUE, val, &after); - strcpy(val, in); + ret = set_is_multiout(true); + if (ret == SANE_STATUS_GOOD) + { + strcpy(val, in); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, val, &after); + } } else { - // disable multi-out, let multiout type side - base_id = is_multiout_id_; - *((SANE_Bool*)val) = SANE_FALSE; + // disable multi-out, let multiout type aside + ret = set_is_multiout(false); } - if (ret == SANE_STATUS_GOOD) - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, val, &after); delete[] val; ret = local_utility::sane_statu_2_scanner_err(ret); } @@ -1285,23 +1302,31 @@ EX_OPTION_HANDLER_IMPL(multiout) EX_OPTION_HANDLER_IMPL(auto_color_type) { int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); int len = desc->size + 4; char* buf = new char[len]; memset(buf, 0, len); - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, buf); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); if (setv) { + char* def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); + int init = sane_opt_trans::auto_color_type_to_twain(def); + + local_utility::free_memory(def); len = sane_opt_trans::auto_color_type_to_twain(buf); - setv(&len, VAL_ROLE_CURRENT, data); + set_cur_and_def_value(len, init, setv, data); } else { SANE_Int after = 0; - strcpy(buf, sane_opt_trans::auto_color_type_from_twain(*(int*)data)); - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, buf, &after); + // ret = set_is_multiout(false); + if (ret == SCANNER_ERR_OK) + { + strcpy(buf, sane_opt_trans::auto_color_type_from_twain(*(int*)data)); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); + } ret = local_utility::sane_statu_2_scanner_err(ret); } delete[] buf; @@ -1311,21 +1336,18 @@ EX_OPTION_HANDLER_IMPL(auto_color_type) EX_OPTION_HANDLER_IMPL(color_mode) { int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); if (setv) { - char* cur = new char[desc->size], - * def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, base_id); - int now = 0, // sane_opt_trans::multiout_value_to_twain(cur) + char* cur = (char*)hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id), + * def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); + int now = sane_opt_trans::color_mode_to_twain(cur), // sane_opt_trans::multiout_value_to_twain(cur) init = sane_opt_trans::color_mode_to_twain(def), val = 0; local_utility::free_memory(def); - memset(cur, 0, desc->size); - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, cur); - now = sane_opt_trans::color_mode_to_twain(cur); - delete[] cur; + local_utility::free_memory(cur); do { @@ -1339,7 +1361,7 @@ EX_OPTION_HANDLER_IMPL(color_mode) role = VAL_ROLE_CURRENT; if (val == init) role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&val, role, data)) + if (!setv(&val, role, VAL_LIMIT_ENUM, data)) break; } } @@ -1349,13 +1371,18 @@ EX_OPTION_HANDLER_IMPL(color_mode) } else { - char* val = new char[desc->size]; - const char* in = sane_opt_trans::color_mode_from_twain(*(int*)data); SANE_Int after = 0; - strcpy(val, in); - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, val, &after); - delete[] val; + // ret = set_is_multiout(false); + if (ret == SCANNER_ERR_OK) + { + char* val = new char[desc->size]; + const char* in = sane_opt_trans::color_mode_from_twain(*(int*)data); + + strcpy(val, in); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, val, &after); + delete[] val; + } ret = local_utility::sane_statu_2_scanner_err(ret); } @@ -1364,21 +1391,18 @@ EX_OPTION_HANDLER_IMPL(color_mode) EX_OPTION_HANDLER_IMPL(sharpen) { int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); if (setv) { - char* cur = new char[desc->size], - * def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, base_id); - int now = 0, // sane_opt_trans::multiout_value_to_twain(cur) + char* cur = (char*)hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id), + * def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); + int now = sane_opt_trans::multiout_value_to_twain(cur), init = sane_opt_trans::sharpen_to_twain(def), val = 0; local_utility::free_memory(def); - memset(cur, 0, desc->size); - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, cur); - now = sane_opt_trans::sharpen_to_twain(cur); - delete[] cur; + local_utility::free_memory(cur); do { @@ -1392,7 +1416,7 @@ EX_OPTION_HANDLER_IMPL(sharpen) role = VAL_ROLE_CURRENT; if (val == init) role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&val, role, data)) + if (!setv(&val, role, VAL_LIMIT_ENUM, data)) break; } } @@ -1406,7 +1430,8 @@ EX_OPTION_HANDLER_IMPL(sharpen) const char* in = sane_opt_trans::sharpen_from_twain(*(int*)data); SANE_Int after = 0; - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, val, &after); + strcpy(val, in); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, val, &after); delete[] val; ret = local_utility::sane_statu_2_scanner_err(ret); } @@ -1416,15 +1441,15 @@ EX_OPTION_HANDLER_IMPL(sharpen) EX_OPTION_HANDLER_IMPL(paper) { int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); int len = desc->size + 4; char* buf = new char[len]; memset(buf, 0, len); if (setv) { - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, buf); - char* def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, base_id); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); + char* def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); int now = sane_opt_trans::paper_to_twain(buf), init = sane_opt_trans::paper_to_twain(def), val = 0; @@ -1444,7 +1469,7 @@ EX_OPTION_HANDLER_IMPL(paper) role = VAL_ROLE_CURRENT; if (val == init) role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&val, role, data)) + if (!setv(&val, role, VAL_LIMIT_ENUM, data)) break; } } @@ -1456,7 +1481,7 @@ EX_OPTION_HANDLER_IMPL(paper) { SANE_Int after = 0; strcpy(buf, sane_opt_trans::paper_from_twain(*(int*)data)); - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, buf, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); } else ret = SCANNER_ERR_INVALID_PARAMETER; @@ -1468,19 +1493,19 @@ EX_OPTION_HANDLER_IMPL(paper) EX_OPTION_HANDLER_IMPL(paper_lateral) { int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); int len = desc->size + 4; char* buf = new char[len]; const char* lateral_swap = NULL; bool lateral = false; memset(buf, 0, len); - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, buf); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); lateral_swap = sane_opt_trans::switch_paper_lateral(buf); lateral = sane_opt_trans::is_paper_lateral(buf); if (setv) { - setv(&lateral, VAL_ROLE_CURRENT, data); + set_cur_and_def_value(lateral, false, setv, data); } else if (lateral_swap) { @@ -1488,7 +1513,7 @@ EX_OPTION_HANDLER_IMPL(paper_lateral) if (lateral != *(bool*)data) { strcpy(buf, lateral_swap); - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, buf, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); ret = local_utility::sane_statu_2_scanner_err(ret); } } @@ -1499,7 +1524,7 @@ EX_OPTION_HANDLER_IMPL(paper_lateral) { // set to A4Lateral ... strcpy(buf, OPTION_VALUE_ZZCC_A4HX); - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, buf, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); ret = local_utility::sane_statu_2_scanner_err(ret); } //ret = SCANNER_ERR_DEVICE_NOT_SUPPORT; @@ -1512,22 +1537,26 @@ EX_OPTION_HANDLER_IMPL(paper_lateral) EX_OPTION_HANDLER_IMPL(auto_paper_size) { int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); int len = desc->size + 4; char* buf = new char[len]; memset(buf, 0, len); - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, buf); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); if (setv) { - bool yes = strcmp(buf, OPTION_VALUE_ZZCC_PPYSCC) == 0; - setv(&yes, VAL_ROLE_CURRENT, data); + char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); + bool yes = strcmp(buf, OPTION_VALUE_ZZCC_PPYSCC) == 0, + def = strcmp(init, OPTION_VALUE_ZZCC_PPYSCC) == 0; + + local_utility::free_memory(init); + set_cur_and_def_value(yes, def, setv, data); } else { SANE_Int after = 0; strcpy(buf, *(bool*)data ? OPTION_VALUE_ZZCC_PPYSCC : OPTION_VALUE_ZZCC_A4); - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, buf, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); ret = local_utility::sane_statu_2_scanner_err(ret); } delete[] buf; @@ -1537,22 +1566,26 @@ EX_OPTION_HANDLER_IMPL(auto_paper_size) EX_OPTION_HANDLER_IMPL(auto_paper_crop) { int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); int len = desc->size + 4; char* buf = new char[len]; memset(buf, 0, len); - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, buf); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); if (setv) { - bool yes = strcmp(buf, OPTION_VALUE_ZZCC_ZDSMCCZDCQ) == 0; - setv(&yes, VAL_ROLE_CURRENT, data); + char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); + bool yes = strcmp(buf, OPTION_VALUE_ZZCC_ZDSMCCZDCQ) == 0, + def = strcmp(init, OPTION_VALUE_ZZCC_ZDSMCCZDCQ) == 0; + + local_utility::free_memory(init); + set_cur_and_def_value(yes, def, setv, data); } else { SANE_Int after = 0; strcpy(buf, *(bool*)data ? OPTION_VALUE_ZZCC_ZDSMCCZDCQ : OPTION_VALUE_ZZCC_ZDSMCC); - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, buf, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); ret = local_utility::sane_statu_2_scanner_err(ret); } delete[] buf; @@ -1562,18 +1595,18 @@ EX_OPTION_HANDLER_IMPL(auto_paper_crop) EX_OPTION_HANDLER_IMPL(text_direction) { int ret = SCANNER_ERR_OK; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); int len = desc->size + 4; char* buf = new char[len]; memset(buf, 0, len); if (setv) { - char* def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, base_id); + char* def = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); float now = .0f, init = sane_opt_trans::text_direction_to_twain(def), val = .0f; local_utility::free_memory(def); - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, buf); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); now = sane_opt_trans::text_direction_to_twain(buf); do { @@ -1587,7 +1620,7 @@ EX_OPTION_HANDLER_IMPL(text_direction) role = VAL_ROLE_CURRENT; if (IS_DOUBLE_EQUAL(val, init)) role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&val, role, data)) + if (!setv(&val, role, VAL_LIMIT_ENUM, data)) break; } } @@ -1600,7 +1633,7 @@ EX_OPTION_HANDLER_IMPL(text_direction) SANE_Int after = 0; strcpy(buf, sane_opt_trans::text_direction_from_twain(*(float*)data)); - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, buf, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); ret = local_utility::sane_statu_2_scanner_err(ret); } delete[] buf; @@ -1611,39 +1644,24 @@ EX_OPTION_HANDLER_IMPL(duplex) { int ret = SCANNER_ERR_OK; bool val = *(bool*)data; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); unsigned len = desc->size + 4; char* buf = new char[len]; memset(buf, 0, len); if (setv) { - void* init = hg_sane_middleware::instance()->get_def_value(handle_, base_id); - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, buf); - val = strcmp(buf, OPTION_VALUE_SMYM_SM) == 0; - if (val && strcmp((char*)init, OPTION_VALUE_SMYM_SM) == 0 || - !val && strcmp((char*)init, OPTION_VALUE_SMYM_DM) == 0) - setv(&val, value_role(VAL_ROLE_CURRENT | VAL_ROLE_DEFAULT), data); - else if (setv(&val, VAL_ROLE_CURRENT, data)) - { - if (strcmp((char*)init, OPTION_VALUE_SMYM_SM) == 0) - { - val = true; - setv(&val, VAL_ROLE_DEFAULT, data); - } - if (strcmp((char*)init, OPTION_VALUE_SMYM_DM) == 0) - { - val = false; - setv(&val, VAL_ROLE_DEFAULT, data); - } - } + char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); + + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); + set_cur_and_def_value(strcmp(buf, OPTION_VALUE_SMYM_SM) == 0, strcmp(init, OPTION_VALUE_SMYM_SM) == 0, setv, data); local_utility::free_memory(init); } else { strcpy(buf, val ? OPTION_VALUE_SMYM_SM : OPTION_VALUE_SMYM_DM); SANE_Int after = 0; - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, buf, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); ret = local_utility::sane_statu_2_scanner_err(ret); } delete[] buf; @@ -1654,15 +1672,15 @@ EX_OPTION_HANDLER_IMPL(fill_background) { int ret = SCANNER_ERR_OK; bool val = *(bool*)data; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); unsigned len = desc->size + 4; char* buf = new char[len]; memset(buf, 0, len); if (setv) { - char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, base_id); - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, buf); + char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); val = strcmp(buf, OPTION_VALUE_SMYM_SM) == 0; set_cur_and_def_value(strcmp(buf, OPTION_VALUE_BJTCFS_TDBX) == 0, strcmp(init, OPTION_VALUE_BJTCFS_TDBX) == 0, setv, data); local_utility::free_memory(init); @@ -1671,7 +1689,7 @@ EX_OPTION_HANDLER_IMPL(fill_background) { strcpy(buf, val ? OPTION_VALUE_BJTCFS_TDBX : OPTION_VALUE_BJTCFS_ADBX); SANE_Int after = 0; - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, buf, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); ret = local_utility::sane_statu_2_scanner_err(ret); } delete[] buf; @@ -1682,16 +1700,20 @@ EX_OPTION_HANDLER_IMPL(discard_blank_page) { int ret = SCANNER_ERR_OK; bool val = *(bool*)data; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); unsigned len = desc->size + 4; char* buf = new char[len]; memset(buf, 0, len); if (setv) { - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, buf); + char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); + bool def = strcmp(init, OPTION_VALUE_SMYM_TGKBYTY) == 0; + + local_utility::free_memory(init); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); val = strcmp(buf, OPTION_VALUE_SMYM_TGKBYTY) == 0; - setv(&val, VAL_ROLE_CURRENT, data); + set_cur_and_def_value(val, def, setv, data); } else { @@ -1699,12 +1721,12 @@ EX_OPTION_HANDLER_IMPL(discard_blank_page) strcpy(buf, OPTION_VALUE_SMYM_TGKBYTY); else { - char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, base_id); + char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); strcpy(buf, init); local_utility::free_memory(init); } SANE_Int after = 0; - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, buf, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); ret = local_utility::sane_statu_2_scanner_err(ret); } delete[] buf; @@ -1715,16 +1737,20 @@ EX_OPTION_HANDLER_IMPL(discard_blank_receipt) { int ret = SCANNER_ERR_OK; bool val = *(bool*)data; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); unsigned len = desc->size + 4; char* buf = new char[len]; memset(buf, 0, len); if (setv) { - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, buf); + char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); + bool def = strcmp(init, OPTION_VALUE_SMYM_TGKBYFPZ) == 0; + + local_utility::free_memory(init); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); val = strcmp(buf, OPTION_VALUE_SMYM_TGKBYFPZ) == 0; - setv(&val, VAL_ROLE_CURRENT, data); + set_cur_and_def_value(val, def, setv, data); } else { @@ -1732,12 +1758,12 @@ EX_OPTION_HANDLER_IMPL(discard_blank_receipt) strcpy(buf, OPTION_VALUE_SMYM_TGKBYFPZ); else { - char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, base_id); + char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); strcpy(buf, init); local_utility::free_memory(init); } SANE_Int after = 0; - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, buf, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); ret = local_utility::sane_statu_2_scanner_err(ret); } delete[] buf; @@ -1748,16 +1774,20 @@ EX_OPTION_HANDLER_IMPL(page_fold) { int ret = SCANNER_ERR_OK; bool val = *(bool*)data; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); unsigned len = desc->size + 4; char* buf = new char[len]; memset(buf, 0, len); if (setv) { - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, buf); + char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); + bool def = strcmp(init, OPTION_VALUE_SMYM_DZ) == 0; + + local_utility::free_memory(init); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); val = strcmp(buf, OPTION_VALUE_SMYM_DZ) == 0; - setv(&val, VAL_ROLE_CURRENT, data); + set_cur_and_def_value(val, def, setv, data); } else { @@ -1765,12 +1795,12 @@ EX_OPTION_HANDLER_IMPL(page_fold) strcpy(buf, OPTION_VALUE_SMYM_DZ); else { - char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, base_id); + char* init = (char*)hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id); strcpy(buf, init); local_utility::free_memory(init); } SANE_Int after = 0; - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, buf, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); ret = local_utility::sane_statu_2_scanner_err(ret); } delete[] buf; @@ -1780,7 +1810,7 @@ EX_OPTION_HANDLER_IMPL(page_fold) EX_OPTION_HANDLER_IMPL(color_filter) // int (filter_value) { int ret = SCANNER_ERR_DEVICE_NOT_SUPPORT; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); char* buf = NULL; unsigned int len = 0; @@ -1793,7 +1823,7 @@ EX_OPTION_HANDLER_IMPL(color_filter) // int (filter_value) { bool filter = false; int val = FILTER_NONE, now = FILTER_NONE; - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, buf); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); now = sane_opt_trans::filter_enhance_value_to_twain(buf, &filter); if (!filter) now = val; @@ -1811,7 +1841,7 @@ EX_OPTION_HANDLER_IMPL(color_filter) // int (filter_value) role = VAL_ROLE_CURRENT; if (v == val) role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&v, role, data)) + if (!setv(&v, role, VAL_LIMIT_ENUM, data)) break; } } @@ -1823,7 +1853,7 @@ EX_OPTION_HANDLER_IMPL(color_filter) // int (filter_value) SANE_Int after = 0; strcpy(buf, val); - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, buf, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); ret = local_utility::sane_statu_2_scanner_err(ret); } delete[] buf; @@ -1834,7 +1864,7 @@ EX_OPTION_HANDLER_IMPL(color_filter) // int (filter_value) EX_OPTION_HANDLER_IMPL(color_enhance) // int (enhance_value) { int ret = SCANNER_ERR_DEVICE_NOT_SUPPORT; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, base_id); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); char* buf = NULL; unsigned int len = 0; @@ -1847,7 +1877,7 @@ EX_OPTION_HANDLER_IMPL(color_enhance) // int (enhance_value) { bool filter = false; int val = ENHANCE_NONE, now = ENHANCE_NONE; - hg_sane_middleware::instance()->get_cur_value(handle_, base_id, buf); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id, buf); now = sane_opt_trans::filter_enhance_value_to_twain(buf, &filter); if (filter) now = val; @@ -1865,7 +1895,7 @@ EX_OPTION_HANDLER_IMPL(color_enhance) // int (enhance_value) role = VAL_ROLE_CURRENT; if (v == val) role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&v, role, data)) + if (!setv(&v, role, VAL_LIMIT_ENUM, data)) break; } } @@ -1877,7 +1907,7 @@ EX_OPTION_HANDLER_IMPL(color_enhance) // int (enhance_value) SANE_Int after = 0; strcpy(buf, val); - ret = hg_sane_middleware::instance()->set_option(handle_, base_id, SANE_ACTION_SET_VALUE, buf, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)base_id, SANE_ACTION_SET_VALUE, buf, &after); ret = local_utility::sane_statu_2_scanner_err(ret); } delete[] buf; @@ -1907,7 +1937,7 @@ EX_OPTION_HANDLER_IMPL(final_compression) if (i == SANE_COMPRESSION_NONE) role = value_role(role | VAL_ROLE_DEFAULT); int v = sane_opt_trans::compression_to_twain(i); - if (!setv(&v, role, data)) + if (!setv(&v, role, VAL_LIMIT_ENUM, data)) break; } } @@ -1943,7 +1973,7 @@ EX_OPTION_HANDLER_IMPL(final_format) role = VAL_ROLE_CURRENT; if (ff.img_format == init) role = value_role(role | VAL_ROLE_DEFAULT); - if (!setv(&ff, role, data)) + if (!setv(&ff, role, VAL_LIMIT_ENUM, data)) break; } } @@ -1965,7 +1995,7 @@ EX_OPTION_HANDLER_IMPL(serial) ret = control_read_string(IO_CTRL_CODE_GET_SERIAL, val); if (ret == SANE_STATUS_GOOD) - setv(&val, VAL_ROLE_CURRENT, data); + setv(&val, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, data); } return ret; @@ -1982,7 +2012,8 @@ EX_OPTION_HANDLER_IMPL(to_be_scan) if (ret == SANE_STATUS_GOOD) { bool val = wait_paper == SANE_TRUE; - setv(&val, VAL_ROLE_CURRENT, data); + + set_cur_and_def_value(val, false, setv, data); } } else @@ -2006,7 +2037,8 @@ EX_OPTION_HANDLER_IMPL(scan_with_hole) if (ret == SANE_STATUS_GOOD) { bool val = with_hole == SANE_TRUE; - setv(&val, VAL_ROLE_CURRENT, data); + + set_cur_and_def_value(val, false, setv, data); } } else @@ -2027,7 +2059,7 @@ EX_OPTION_HANDLER_IMPL(device_code) ret = control_read_string(IO_CTRL_CODE_GET_DEVICE_CODE, val); if (ret == SANE_STATUS_GOOD) - setv(&val, VAL_ROLE_CURRENT, data); + setv(&val, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, data); } return ret; @@ -2051,7 +2083,7 @@ EX_OPTION_HANDLER_IMPL(power) role = value_role(role | VAL_ROLE_DEFAULT); SANE_Power power = (SANE_Power)i; - if (!setv(&power, role, data)) + if (!setv(&power, role, VAL_LIMIT_ENUM, data)) break; } } @@ -2074,7 +2106,7 @@ EX_OPTION_HANDLER_IMPL(hardware_version) ret = control_read_string(IO_CTRL_CODE_GET_HARDWARE_VERSION, val); if (ret == SANE_STATUS_GOOD) - setv(&val, VAL_ROLE_CURRENT, data); + setv(&val, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, data); } return ret; @@ -2088,7 +2120,7 @@ EX_OPTION_HANDLER_IMPL(ip) ret = control_read_string(IO_CTRL_CODE_GET_IP, val); if (ret == SANE_STATUS_GOOD) - setv(&val, VAL_ROLE_CURRENT, data); + setv(&val, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, data); } return ret; @@ -2098,27 +2130,32 @@ EX_OPTION_HANDLER_IMPL(erase_hole) int ret = SCANNER_ERR_DEVICE_NOT_SUPPORT; if (is_erase_hole_l_id_ != -1 || is_erase_hole_r_id_ != -1) { - SANE_Bool yes = SANE_FALSE; + SANE_Bool yes = SANE_FALSE, def = SANE_FALSE; SANE_Int after = 0; if (setv) { if (is_erase_hole_l_id_ != -1) - hg_sane_middleware::instance()->set_option(handle_, is_erase_hole_l_id_, SANE_ACTION_GET_VALUE, &yes, &after); + { + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)is_erase_hole_l_id_, &yes); + hg_sane_middleware::instance()->get_def_value(handle_, (void*)is_erase_hole_l_id_, &def); + } if (!yes && is_erase_hole_r_id_ != -1) - hg_sane_middleware::instance()->set_option(handle_, is_erase_hole_r_id_, SANE_ACTION_GET_VALUE, &yes, &after); + { + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)is_erase_hole_r_id_, &yes); + hg_sane_middleware::instance()->get_def_value(handle_, (void*)is_erase_hole_r_id_, &def); + } - bool v = yes == SANE_TRUE; - setv(&v, VAL_ROLE_CURRENT, data); + set_cur_and_def_value(yes == SANE_TRUE, def == SANE_TRUE, setv, data); ret = SCANNER_ERR_OK; } else { yes = *(bool*)data ? SANE_TRUE : SANE_FALSE; if (is_erase_hole_l_id_ != -1) - ret = hg_sane_middleware::instance()->set_option(handle_, is_erase_hole_l_id_, SANE_ACTION_SET_VALUE, &yes, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)is_erase_hole_l_id_, SANE_ACTION_SET_VALUE, &yes, &after); yes = *(bool*)data ? SANE_TRUE : SANE_FALSE; if (is_erase_hole_r_id_ != -1) - ret = hg_sane_middleware::instance()->set_option(handle_, is_erase_hole_r_id_, SANE_ACTION_SET_VALUE, &yes, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)is_erase_hole_r_id_, SANE_ACTION_SET_VALUE, &yes, &after); } } @@ -2131,30 +2168,38 @@ EX_OPTION_HANDLER_IMPL(search_hole_range) { SANE_Fixed val = 0; SANE_Int after = 0; - double rv = .0f; + double rv = .0f, def = .0f; if (setv) { - if (search_hole_range_l_id_ != -1) - hg_sane_middleware::instance()->set_option(handle_, search_hole_range_l_id_, SANE_ACTION_GET_VALUE, &val, &after); - rv = SANE_UNFIX(val); - if (search_hole_range_r_id_ != -1) - { - hg_sane_middleware::instance()->set_option(handle_, search_hole_range_r_id_, SANE_ACTION_GET_VALUE, &val, &after); - if (rv < SANE_UNFIX(val)) - rv = SANE_UNFIX(val); - } + const SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)base_id); + void* init = hg_sane_middleware::instance()->get_def_value(handle_, (void*)base_id), + * cur = hg_sane_middleware::instance()->get_cur_value(handle_, (void*)base_id); + float n = SANE_UNFIX(*(SANE_Fixed*)cur), + d = SANE_UNFIX(*(SANE_Fixed*)init); + + if (desc->constraint_type == SANE_CONSTRAINT_RANGE) + { + float l = SANE_UNFIX(desc->constraint.range->min), + u = SANE_UNFIX(desc->constraint.range->max), + s = SANE_UNFIX(desc->constraint.range->quant); + set_value_range(*(SANE_Fixed*)cur, *(SANE_Fixed*)init, desc->constraint.range->min, desc->constraint.range->max, desc->constraint.range->quant, setv, data, &scanner::to_float); + } + else + set_cur_and_def_value(n, d, setv, data); + local_utility::free_memory(init); + local_utility::free_memory(cur); - setv(&rv, VAL_ROLE_CURRENT, data); ret = SCANNER_ERR_OK; } else { - val = SANE_FIX(*(double*)data); + rv = (double)*(float*)data; + val = SANE_FIX(rv); if (search_hole_range_l_id_ != -1) - ret = hg_sane_middleware::instance()->set_option(handle_, search_hole_range_l_id_, SANE_ACTION_SET_VALUE, &val, &after); - val = SANE_FIX(*(double*)data); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)search_hole_range_l_id_, SANE_ACTION_SET_VALUE, &val, &after); + val = SANE_FIX(rv); if (search_hole_range_r_id_ != -1) - ret = hg_sane_middleware::instance()->set_option(handle_, search_hole_range_r_id_, SANE_ACTION_SET_VALUE, &val, &after); + ret = hg_sane_middleware::instance()->set_option(handle_, (void*)search_hole_range_r_id_, SANE_ACTION_SET_VALUE, &val, &after); } } @@ -2312,7 +2357,7 @@ COM_API_IMPLEMENT(scanner, bool, is_paper_on(void)) COM_API_IMPLEMENT(scanner, bool, get_option_info(int sn, value_type* type, value_limit* limit, int* bytes)) { EXAPIPOS ex = find_ex_api(sn); - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, ex == ex_opts_.end() ? sn : ex->base_ind); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, ex == ex_opts_.end() ? (void*)sn : (void*)ex->base_ind); bool ret = false; if (desc) @@ -2340,24 +2385,40 @@ COM_API_IMPLEMENT(scanner, bool, get_value(int sn, set_opt_value setval, void* p if (get_option_value_with_parent(sn, setval, param)) return true; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, sn); - void* init = hg_sane_middleware::instance()->get_def_value(handle_, sn); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)sn); + void* init = hg_sane_middleware::instance()->get_def_value(handle_, (void*)sn); ret = SANE_STATUS_GOOD; if (desc->type == SANE_TYPE_BOOL) { SANE_Bool v = SANE_FALSE; bool val = false; - hg_sane_middleware::instance()->get_cur_value(handle_, sn, &v); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)sn, &v); val = v == SANE_TRUE; - set_cur_and_def_value(val, *(SANE_Bool*)init == SANE_TRUE, setval, param); + //set_cur_and_def_value(val, *(SANE_Bool*)init == SANE_TRUE, setval, param); + { + int role = VAL_ROLE_NONE; + val = false; + if (*(SANE_Bool*)init == SANE_FALSE) + role |= VAL_ROLE_DEFAULT; + if (v == SANE_FALSE) + role |= VAL_ROLE_CURRENT; + setval(&val, (value_role)role, VAL_LIMIT_ENUM, param); + val = true; + role = VAL_ROLE_NONE; + if (*(SANE_Bool*)init == SANE_TRUE) + role |= VAL_ROLE_DEFAULT; + if (v == SANE_TRUE) + role |= VAL_ROLE_CURRENT; + setval(&val, (value_role)role, VAL_LIMIT_ENUM, param); + } } else if (desc->type == SANE_TYPE_INT) { SANE_Int cur = 0, def = *(SANE_Int*)init; int val = 0; - hg_sane_middleware::instance()->get_cur_value(handle_, sn, &cur); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)sn, &cur); val = cur; if (sn == resolution_id_) dpi_ = cur; @@ -2378,7 +2439,7 @@ COM_API_IMPLEMENT(scanner, bool, get_value(int sn, set_opt_value setval, void* p if (v[i + 1] == *(SANE_Int*)init) role = value_role(role | VAL_ROLE_DEFAULT); val = v[i + 1]; - if (!setval(&val, role, param)) + if (!setval(&val, role, VAL_LIMIT_ENUM, param)) break; } } @@ -2392,7 +2453,7 @@ COM_API_IMPLEMENT(scanner, bool, get_value(int sn, set_opt_value setval, void* p SANE_Fixed cur = 0, def = *(SANE_Fixed*)init; float val = .0f; - hg_sane_middleware::instance()->get_cur_value(handle_, sn, &cur); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)sn, &cur); if (sn == resolution_id_) dpi_ = (int)(SANE_UNFIX(cur) + .5f); do @@ -2412,7 +2473,7 @@ COM_API_IMPLEMENT(scanner, bool, get_value(int sn, set_opt_value setval, void* p if (v[i + 1] == def) role = value_role(role | VAL_ROLE_DEFAULT); val = (float)SANE_UNFIX(v[i + 1]); - if (!setval(&val, role, param)) + if (!setval(&val, role, VAL_LIMIT_ENUM, param)) break; } } @@ -2426,7 +2487,7 @@ COM_API_IMPLEMENT(scanner, bool, get_value(int sn, set_opt_value setval, void* p std::string val(""), def((char*)init); memset(buf, 0, desc->size + 4); - hg_sane_middleware::instance()->get_cur_value(handle_, sn, buf); + hg_sane_middleware::instance()->get_cur_value(handle_, (void*)sn, buf); val = buf; do { @@ -2441,7 +2502,7 @@ COM_API_IMPLEMENT(scanner, bool, get_value(int sn, set_opt_value setval, void* p role = value_role(role | VAL_ROLE_DEFAULT); val = desc->constraint.string_list[i]; - if (!setval(&val, role, param)) + if (!setval(&val, role, VAL_LIMIT_ENUM, param)) break; } } @@ -2468,15 +2529,15 @@ COM_API_IMPLEMENT(scanner, int, set_value(int sn, void* val)) EXAPIPOS ex = find_ex_api(sn); int ret = SANE_STATUS_INVAL; SANE_Int after = 0; - SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, sn); + SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)sn); { wchar_t msg[256] = { 0 }; if (ex == ex_opts_.end()) swprintf_s(msg, _countof(msg) - 1, L"set_value of %s(%s) of ID %d\r\n", local_trans::a2u(desc->name, CP_UTF8).c_str(), local_trans::a2u(hg_sane_middleware::option_value_2_string(desc->type, val).c_str(), CP_UTF8).c_str(), sn); - else + else if(ex->base_ind != -1) { - desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, ex->base_ind); + desc = hg_sane_middleware::instance()->get_option_descriptor(handle_, (void*)ex->base_ind); swprintf_s(msg, _countof(msg) - 1, L"set_value of %s(0x%x) of ID %d, base id = %d)\r\n", local_trans::a2u(desc->name, CP_UTF8).c_str(), *(unsigned*)val, sn, ex->base_ind); } log_info(msg, 0); @@ -2931,9 +2992,10 @@ extern "C" { init_log(); hg_sane_middleware::set_callback(callback::sane_event_callback, NULL); - hg_sane_middleware::instance(); - - return SANE_STATUS_GOOD; + if (hg_sane_middleware::instance()->is_ready()) + return SANE_STATUS_GOOD; + else + return SCANNER_ERR_LANG_PAK_LOST; } #ifdef EXPORT_SANE_API __declspec(dllexport) diff --git a/sane/scanner.h b/sane/scanner.h index 63044c2..180dfde 100644 --- a/sane/scanner.h +++ b/sane/scanner.h @@ -84,6 +84,7 @@ class scanner : public ISaneInvoker, virtual public refer bool get_option_value_with_parent(int sn, set_opt_value setv, void* param); // return true if handled bool set_option_value_with_parent(int sn, void* data, int* err); // return true if handled sn int set_option_value(int sn, SANE_Value_Type type, int size, void* data); + int set_is_multiout(bool enable); typedef struct _ex_api { @@ -133,53 +134,32 @@ class scanner : public ISaneInvoker, virtual public refer bool set_cur_and_def_value(T cur, T def, set_opt_value setv, void* param) { if (cur == def) - return setv(&cur, value_role(VAL_ROLE_CURRENT | VAL_ROLE_DEFAULT), param); - else if (setv(&cur, VAL_ROLE_CURRENT, param)) - return setv(&def, VAL_ROLE_DEFAULT, param); - else - return false; + return setv(&cur, (value_role)(VAL_ROLE_CURRENT | VAL_ROLE_DEFAULT), VAL_LIMIT_NONE, param); + else if (setv(&cur, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, param)) + return setv(&def, VAL_ROLE_DEFAULT, VAL_LIMIT_NONE, param); + + return false; } template void set_value_range(S cur, S def, S l, S u, S s, set_opt_value setv, void* param, T(__stdcall* to_t)(S)) { - struct + T v = to_t(cur); + while (setv(&v, VAL_ROLE_CURRENT, VAL_LIMIT_RANGE, param)) { - int role; - S val; - }vals[5]; - int count = 0; - std::vector sv; - - sv.push_back(cur); - sv.push_back(def); - sv.push_back(l); - sv.push_back(u); - std::sort(sv.begin(), sv.end()); - for (int i = 0; i < (int)sv.size(); ++i) - { - if (i && sv[i] == sv[i - 1]) - continue; - - vals[count].val = sv[i]; - vals[count].role = 0; - if (sv[i] == cur) - vals[count].role |= VAL_ROLE_CURRENT; - if (sv[i] == def) - vals[count].role |= VAL_ROLE_DEFAULT; - if (sv[i] == l) - vals[count].role |= VAL_ROLE_LOWER; - if (sv[i] == u) - vals[count].role |= VAL_ROLE_UPPER; - count++; - } - vals[count].val = s; - vals[count++].role = VAL_ROLE_STEP; - - for (int i = 0; i < count; ++i) - { - T v = to_t(vals[i].val); - if (!setv(&v, (value_role)vals[i].role, param)) + v = to_t(def); + if (!setv(&v, VAL_ROLE_DEFAULT, VAL_LIMIT_RANGE, param)) break; + + v = to_t(l); + if (!setv(&v, VAL_ROLE_LOWER, VAL_LIMIT_RANGE, param)) + break; + v = to_t(u); + if (!setv(&v, VAL_ROLE_UPPER, VAL_LIMIT_RANGE, param)) + break; + v = to_t(s); + setv(&v, VAL_ROLE_STEP, VAL_LIMIT_RANGE, param); + + break; } } diff --git a/twain/load_sane.cpp b/twain/load_sane.cpp index 3695ee7..38ef566 100644 --- a/twain/load_sane.cpp +++ b/twain/load_sane.cpp @@ -95,7 +95,7 @@ namespace load_sane_util swprintf_s(info, _countof(info) - 1, L" = %d\r\n", ret); OutputDebugStringW((L"[TWAIN]Load: " + std::wstring(path_dll) + info).c_str()); - if (!h && ret == ERROR_MOD_NOT_FOUND) + if (!h && (ret == ERROR_MOD_NOT_FOUND || ret == ERROR_BAD_EXE_FORMAT)) { std::wstring dir(path_dll); size_t pos = dir.rfind(L'\\'); @@ -107,6 +107,7 @@ namespace load_sane_util OutputDebugStringW((L"[TWAIN]Load: try change directory to " + dir + L"\r\n").c_str()); SetDllDirectoryW(dir.c_str()); h = LoadLibraryW(path_dll); + // h = LoadLibraryExW(path_dll, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); ret = GetLastError(); swprintf_s(info, _countof(info) - 1, L" = %d\r\n", ret); OutputDebugStringW((L"[TWAIN]Load: " + std::wstring(path_dll) + info).c_str()); diff --git a/twain/twain/huagaods.cpp b/twain/twain/huagaods.cpp index 9ad8352..b5c1700 100644 --- a/twain/twain/huagaods.cpp +++ b/twain/twain/huagaods.cpp @@ -491,6 +491,34 @@ static void copy_type(std::string& to, Str64 from) to = load_sane_util::ansi2utf8(from.data()); } +template +bool list_value_at(std::list& lst, int ind, T& t) +{ + bool found = false; + + if (ind >= 0) + { + typename std::list::iterator it = lst.begin(); + for (; it != lst.end(); ++it, --ind) + { + if (ind == 0) + { + t = *it; + found = true; + break; + } + } + } + + return found; +} +template +int distance(std::vector& vec, const T& v, int offset = sane_opts::RANGE_POS_ENUM_BEGIN) +{ + return std::distance(vec.begin() + offset, + std::find(vec.begin() + offset, vec.end(), v)); +} + UINT16 bit_depth_from_sane(int sane) { if (sane == COLOR_BW) @@ -500,7 +528,7 @@ UINT16 bit_depth_from_sane(int sane) else if (sane == COLOR_RGB) return 24; else - return sane; + return /*sane*/24; } static ImageFileFormat from_sane_image_type(int sane_img_type) { @@ -895,8 +923,8 @@ Result huagao_ds::setupMemXferGet(const Identity& id, SetupMemXfer& data) { int def_w = 2000, def_h = 6000; - data.setMinSize(def_w * 3); - data.setPreferredSize(def_w * 3); + data.setMinSize(def_w * 3 * def_h); + data.setPreferredSize(def_w * 3 * def_h); data.setMaxSize(def_w * 3 * def_h); } return success(); @@ -959,6 +987,42 @@ Result huagao_ds::userInterfaceEnableUiOnly(const Identity&, UserInterface& ui) // as a minimal source, we do not support GUI that just saves settings return showTwainUI(ui, true); } +Twpp::Result huagao_ds::extImageInfoGet(const Identity& origin, ExtImageInfo& data) +{ + for (int i = 0; i < data.size(); ++i) + { + InfoId id = data.at(i).id(); + Twpp::Info& info = data.at(i); + + if (id == InfoId::BarCodeCount) + { + info.allocSimple(Type::UInt32); + *info.items()[0].data() = 2; + } + //else if (id == InfoId::BarCodeType) + //{ + // info.allocSimple(Type::UInt32); + // *info.items()[0].data() = BarCodeType::ThreeOfNine; + //} + else if(id == InfoId::BarCodeTextLength) + { + info.allocSimple(Type::UInt32); + *info.items()[0].data() = 16; + } + else if (id == InfoId::BarCodeText) + { + info.allocSimple(Type::Str255, 2); + info.items()[0].data()->setData("6922868285266"); + info.items()[1].data()->setData("6971513684121"); + } + else + info.setReturnCode(ReturnCode::InfoNotSupported); + } + + return success(); + + return { ReturnCode::Failure, ConditionCode::NoMedia }; +} Result huagao_ds::imageInfoGet(const Identity&, ImageInfo& data) { SANE_Parameters head; @@ -1071,6 +1135,7 @@ Result huagao_ds::imageMemXferGet(const Identity& origin, ImageMemXfer& data) IScanImg *img = pending_xfer_.img ? pending_xfer_.img : scanner_->take_first_image(TWAIN_XFER_Memory); unsigned long long off = pending_xfer_.img ? pending_xfer_.off : 0; unsigned char *dst = (unsigned char*)data.memory().data().data(); + UInt32 buf_l = data.memory().size(); unsigned int line_l = img->line_bytes(), rows = data.memory().size() / line_l; size_t want_read = rows * line_l; @@ -1096,11 +1161,21 @@ Result huagao_ds::imageMemXferGet(const Identity& origin, ImageMemXfer& data) data.setCompression(m_compression); if (m_compression != Compression::None) { - want_read = img->bytes(); - off = 0; + want_read = img->bytes() - off; + if (buf_l < want_read) + { + want_read = buf_l; + } img->read(dst, &want_read, off); - data.setRows(img->height()); data.setBytesWritten(want_read); + off += want_read; + if (off < img->bytes()) + { + pending_xfer_.img = img; + pending_xfer_.off = (unsigned int)off; + img->add_ref(); + ret = success(); + } } else if (img->read(dst, &want_read, off) == SCANNER_ERR_OK) { @@ -1169,7 +1244,7 @@ Twpp::Result huagao_ds::imageFileXferGet(const Twpp::Identity& origin) if (!scanner_.get() || scanner_->get_scanned_images(-1) == 0) return seqError(); - IScanImg *img = scanner_->take_first_image(TWAIN_XFER_File); + IScanImg* img = scanner_->take_first_image(TWAIN_XFER_File); Twpp::Result ret = seqError(); FILE* dst = NULL; @@ -1288,7 +1363,7 @@ Twpp::Result huagao_ds::imageFileXferGet(const Twpp::Identity& origin) { std::wstring info(load_sane_util::ansi2unic(m_fileXfer.filePath().string().c_str())); wchar_t r[80] = { 0 }; - swprintf_s(r, _countof(r) - 1, L": status = %d(Fail: 0x%x)\r\n", ret.status(), cv_e); + swprintf_s(r, _countof(r) - 1, L": status = %d(Fail: 0x%x)\r\n", (int)ret.status(), cv_e); load_sane_util::log_info((info + r).c_str(), 0); } } @@ -1395,9 +1470,20 @@ Twpp::Result huagao_ds::showTwainUI(Twpp::UserInterface& data, bool bUiOnly) } void huagao_ds::init_support_caps(void) { +#define SANE_ID(name) scanner_->sane_opt_id_##name##() + m_query.clear(); m_caps.clear(); + //m_query[CapType::IExtImageInfo] = msgSupportGetAll; + //m_caps[CapType::IExtImageInfo] = std::bind(enmGet, _1, _2, Bool(true)); + + m_query[CapType::ISupportedExtImageInfo] = msgSupportGetAll; + m_caps[CapType::ISupportedExtImageInfo] = [this](Msg msg, Capability& data) { + data = Capability::createArray< CapType::ISupportedExtImageInfo>({ InfoId::BarCodeCount, InfoId::BarCodeText, InfoId::BarCodeType, InfoId::BarCodeTextLength }); + return success(); + }; + m_query[CapType::SupportedCaps] = msgSupportGetAll; m_caps[CapType::SupportedCaps] = [this](Msg msg, Capability& data) { log_attr_access((int)CapType::SupportedCaps, (int)msg); @@ -1432,10 +1518,10 @@ void huagao_ds::init_support_caps(void) SET_SANE_OPT(ret, scanner_, scan_count, &count); return ret == SCANNER_ERR_OK ? success() : badValue(); } - int count = -1; + std::vector count; Int16 tmp_count = 0; - GET_SANE_OPT(int, scanner_, scan_count, &count, NULL, NULL, NULL); - tmp_count = count; + GET_SANE_OPT(int, scanner_, scan_count, NULL, &count); + tmp_count = count[sane_opts::RANGE_POS_CURRENT]; return oneValGetSet(msg, data, tmp_count, -1); }; @@ -1498,30 +1584,6 @@ void huagao_ds::init_support_caps(void) return badValue(); } return CapSupGetAllReset(msg, data, { Compression::None, Compression::Group4 }, m_compression, Compression::None, m_compression == Compression::None ? 0 : 1, 0); - //if (msg == Msg::Set || msg == Msg::Reset) - //{ - // int mech = (int)data.currentItem(); - // if (msg == Msg::Reset) - // GET_SANE_OPT(int, scanner_, ex_final_compression, NULL, &mech, NULL, NULL); - - // int ret = SCANNER_ERR_OK; - // SET_SANE_OPT(ret, scanner_, ex_final_compression, (int*)&mech); - // return ret == SCANNER_ERR_OK ? success() : badValue(); - //} - //std::vector values; - //int init = 0, now = 0; - //std::list vals; - //Compression Now, Init; - //UInt32 ni = 0, ii = 0; - - //GET_SANE_OPT(int, scanner_, ex_final_compression, &now, &init, &values, NULL); - //Now = (Compression)now; - //Init = (Compression)init; - //for (const auto& v : values) - // vals.push_back((Compression)v); - //ni = std::distance(values.begin(), std::find(values.begin(), values.end(), now)); - //ii = std::distance(values.begin(), std::find(values.begin(), values.end(), init)); - //return cap_get_enum_values(msg, data, vals, Now, Init, ni, ii); }; m_query[CapType::IUnits] = msgSupportGetAllSetReset; @@ -1530,37 +1592,43 @@ void huagao_ds::init_support_caps(void) m_query[CapType::IBitDepth] = msgSupportGetAllSetReset; m_caps[CapType::IBitDepth] = [this](Msg msg, Capability& data) -> Result { log_attr_access((int)CapType::IBitDepth, (int)msg); - int now = 0, init = 0; std::vector all; - GET_SANE_OPT(int, scanner_, ex_color_mode, &now, &init, &all, NULL); + int val = 0; + GET_SANE_OPT(int, scanner_, ex_color_mode, NULL, &all); if (Msg::Set == msg || Msg::Reset == msg) { - auto mech = data.currentItem(); int ret = SCANNER_ERR_INVALID_PARAMETER; - { - wchar_t info[128] = { 0 }; - swprintf_s(info, _countof(info) - 1, L"set CapType::IBitDepth = %d\r\n", mech); - load_sane_util::log_info(info, 0); - } + val = all[sane_opts::RANGE_POS_DEFAULT]; if (Msg::Set == msg) { + auto mech = data.currentItem(); if (mech == 1) - init = COLOR_BW; + val = COLOR_BW; else if (mech == 8) - init = COLOR_GRAY; + val = COLOR_GRAY; else if (mech == 24) - init = COLOR_RGB; + val = COLOR_RGB; else - init = mech; + val = mech; + } + { + wchar_t info[128] = { 0 }; + swprintf_s(info, _countof(info) - 1, L"set CapType::IBitDepth = %d\r\n", val); + load_sane_util::log_info(info, 0); + } + SET_SANE_OPT(ret, scanner_, ex_color_mode, &val); + if (Msg::Reset == msg) + { + UINT16 v = val; + data = Capability::createOneValue(CapType::IBitDepth, v); } - SET_SANE_OPT(ret, scanner_, ex_color_mode, &init); return ret == SCANNER_ERR_OK ? success() : badValue(); } - UINT16 Now = bit_depth_from_sane(now), Init = bit_depth_from_sane(init); + UINT16 Now = bit_depth_from_sane(all[sane_opts::RANGE_POS_CURRENT]), Init = bit_depth_from_sane(all[sane_opts::RANGE_POS_DEFAULT]); std::list vals; - UInt32 ni = std::distance(all.begin(), std::find(all.begin(), all.end(), now)), - ii = std::distance(all.begin(), std::find(all.begin(), all.end(), init)); - for (auto& v : all) - vals.push_back(bit_depth_from_sane(v)); + UInt32 ni = distance(all, all[sane_opts::RANGE_POS_CURRENT]), + ii = distance(all, all[sane_opts::RANGE_POS_DEFAULT]); + for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < all.size(); ++i) + vals.push_back(bit_depth_from_sane(all[i])); return cap_get_enum_values(msg, data, vals, Now, Init, ni, ii); }; @@ -1571,19 +1639,25 @@ void huagao_ds::init_support_caps(void) m_caps[CapType::IPlanarChunky] = std::bind(enmGetSetConst, _1, _2, PlanarChunky::Chunky); m_query[CapType::IXResolution] = msgSupportGetAllSetReset; - m_caps[CapType::IXResolution] = [this](Msg msg, Capability& data) { + m_caps[CapType::IXResolution] = /*m_caps[CapTypeEx::CAP_EX_SANE_resolution];*/ [this](Msg msg, Capability& data) { log_attr_access((int)CapType::IXResolution, (int)msg); if (!scanner_.get()) return seqError(); std::vector values; value_limit limit = VAL_LIMIT_RANGE; int init = 0, now = 0; - GET_SANE_OPT(int, scanner_, resolution, &now, &init, &values, NULL); + GET_SANE_OPT(int, scanner_, resolution, NULL, &values); + init = values[sane_opts::RANGE_POS_DEFAULT]; + now = values[sane_opts::RANGE_POS_CURRENT]; switch (msg) { case Msg::Get: if (limit == VAL_LIMIT_RANGE) { - data = Capability::createRange(Fix32((float)values[0]), Fix32((float)values[1]), Fix32(50.0f), Fix32((float)now), Fix32((float)init)); + data = Capability::createRange(Fix32((float)values[sane_opts::RANGE_POS_LOWER]) + , Fix32((float)values[sane_opts::RANGE_POS_UPPER]) + , Fix32((float)values[sane_opts::RANGE_POS_STEP]) + , Fix32((float)values[sane_opts::RANGE_POS_CURRENT]) + , Fix32((float)values[sane_opts::RANGE_POS_DEFAULT])); return success(); } else if (limit == VAL_LIMIT_ENUM) @@ -1591,10 +1665,10 @@ void huagao_ds::init_support_caps(void) std::list vals; Fix32 Now, Init; UInt32 ni, ii; - for (const auto& v : values) + for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < values.size(); ++i) { Fix32 f; - float vf = (float)v; + float vf = (float)values[i]; copy_type(f, vf); vals.push_back(f); } @@ -1627,7 +1701,15 @@ void huagao_ds::init_support_caps(void) }; m_query[CapType::IYResolution] = msgSupportGetAllSetReset; - m_caps[CapType::IYResolution] = m_caps[CapType::IXResolution]; + m_caps[CapType::IYResolution] = /*m_caps[CapType::IXResolution];*/ [this](Msg msg, Capability& data) + { + Result ret = m_caps[CapType::IXResolution](msg, data); + + if (data.type() == CapType::IXResolution) + data.dangerous_set_cap(CapType::IYResolution); + + return ret; + }; m_query[CapType::IXNativeResolution] = msgSupportGetAll; m_caps[CapType::IXNativeResolution] = std::bind(enmGet, _1, _2, Fix32(200.0)); @@ -1641,7 +1723,9 @@ void huagao_ds::init_support_caps(void) int now = 0, init = 0; std::vector all; - GET_SANE_OPT(int, scanner_, ex_paper, &now, &init, &all, NULL); + GET_SANE_OPT(int, scanner_, ex_paper, NULL, &all); + now = all[sane_opts::RANGE_POS_CURRENT]; + init = all[sane_opts::RANGE_POS_DEFAULT]; if (msg == Msg::Set || msg == Msg::Reset) { if(msg == Msg::Set) @@ -1656,10 +1740,10 @@ void huagao_ds::init_support_caps(void) std::list vals; Twpp::PaperSize Now = (PaperSize)now, Init = (PaperSize)init; - UInt32 ni = std::distance(all.begin(), std::find(all.begin(), all.end(), now)), - ii = std::distance(all.begin(), std::find(all.begin(), all.end(), init)); - for (auto& v : all) - vals.push_back((PaperSize)v); + UInt32 ni = distance(all, now), + ii = distance(all, init); + for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < all.size(); ++i) + vals.push_back((PaperSize)all[i]); return cap_get_enum_values(msg, data, vals, Now, Init, ni, ii); }; @@ -1675,7 +1759,6 @@ void huagao_ds::init_support_caps(void) float init = 10.0f; int cur = 200; SANE_Parameters param = { 0 }; - // GET_SANE_OPT(int, scanner_, resolution, &cur, NULL, NULL, NULL); if (scanner_.get() && scanner_->get_first_image_header(¶m, NULL, &cur)) init = param.bytes_per_line * 1.0f / cur; data = Capability::createOneValue(data.type(), Fix32(init)); @@ -1697,7 +1780,6 @@ void huagao_ds::init_support_caps(void) float init = 10.0f; int cur = 200; SANE_Parameters param = { 0 }; - // GET_SANE_OPT(int, scanner_, resolution, &cur, NULL, NULL, NULL); if (scanner_.get() && scanner_->get_first_image_header(¶m, NULL, &cur)) init = param.lines * 1.0f / cur; data = Capability::createOneValue(data.type(), Fix32(init)); @@ -1741,7 +1823,9 @@ void huagao_ds::init_support_caps(void) std::vector values; int init = 0, now = 0; - GET_SANE_OPT(int, scanner_, ex_color_mode, &now, &init, &values, NULL); + GET_SANE_OPT(int, scanner_, ex_color_mode, NULL, &values); + now = values[sane_opts::RANGE_POS_CURRENT]; + init = values[sane_opts::RANGE_POS_DEFAULT]; if (Msg::Reset == msg || Msg::Set == msg) { if(Msg::Set == msg) @@ -1764,12 +1848,10 @@ void huagao_ds::init_support_caps(void) if (1) { std::list vals; - UInt32 ni, ii; + UInt32 ni = distance(values, now), ii = distance(values, init); Twpp::PixelType Init = (Twpp::PixelType)init, Now = (Twpp::PixelType)now; - for (const auto& v : values) - vals.push_back((Twpp::PixelType)v); - ni = std::distance(vals.begin(), std::find(vals.begin(), vals.end(), (Twpp::PixelType)now)); - ii = std::distance(vals.begin(), std::find(vals.begin(), vals.end(), (Twpp::PixelType)init)); + for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < values.size(); ++i) + vals.push_back((Twpp::PixelType)values[i]); return cap_get_enum_values(msg, data, vals, Now, Init, ni, ii); } case Msg::GetCurrent: @@ -1792,9 +1874,9 @@ void huagao_ds::init_support_caps(void) return success(); } - int cur = 0; - GET_SANE_OPT(int, scanner_, ex_auto_color_type, &cur, NULL, NULL, NULL); - int twpt = cur == COLOR_AUTO_MATCH ? 1 : 0; + std::vector all; + GET_SANE_OPT(int, scanner_, ex_auto_color_type, NULL, &all); + int twpt = all[sane_opts::RANGE_POS_CURRENT] == COLOR_AUTO_MATCH ? 1 : 0; return CapSupGetAllReset(msg, data, { FALSE,TRUE }, twpt, false, twpt ? 1 : 0, 0); }; @@ -1803,9 +1885,6 @@ void huagao_ds::init_support_caps(void) log_attr_access((int)CapType::IAutomaticColorNonColorPixelType, (int)msg); if (msg == Msg::Set) { int mech = (int)data.currentItem(); - //int now = 0; - //GET_SANE_OPT(int, scanner_, color_mode, &now, NULL, NULL, NULL); - //if (now == TWPT_AUTOMATIC_COLOR) { if ((UInt16)mech == 0 || (UInt16)mech == 1) { int ret = SCANNER_ERR_OK, @@ -1861,9 +1940,9 @@ void huagao_ds::init_support_caps(void) SET_SANE_OPT(ret, scanner_, ex_paper_lateral, &lateral); return ret == SCANNER_ERR_OK ? success() : badValue(); } - bool is_lateral = false; - GET_SANE_OPT(bool, scanner_, ex_paper_lateral, &is_lateral, NULL, NULL, NULL); - int lateral = is_lateral ? (int)Orientation::Landscape : (int)Orientation::Portrait; + std::vector values; + GET_SANE_OPT(bool, scanner_, ex_paper_lateral, NULL, &values); + int lateral = values[sane_opts::RANGE_POS_CURRENT] ? (int)Orientation::Landscape : (int)Orientation::Portrait; return CapSupGetAllReset(msg, data, { Orientation::Portrait, Orientation::Landscape }, lateral, Orientation::Portrait, lateral == 0 ? 0 : 1, 0); }; @@ -1877,18 +1956,16 @@ void huagao_ds::init_support_caps(void) SET_SANE_OPT(ret, scanner_, ex_text_direction, &angle); return ret == SCANNER_ERR_OK ? success() : badValue(); } - float init = .0f, now = .0f; - std::list values; + std::vector values; - GET_SANE_OPT(float, scanner_, ex_text_direction, &now, &init, NULL, &values); + GET_SANE_OPT(float, scanner_, ex_text_direction, NULL, &values); - Fix32 Init = Fix32(init), Now = Fix32(now); + Fix32 Init = Fix32(values[sane_opts::RANGE_POS_DEFAULT]), Now = Fix32(values[sane_opts::RANGE_POS_CURRENT]); std::list vls; - UInt32 i = 0, n = 0; - for (const auto& v : values) - vls.push_back(Fix32(v)); - i = std::distance(vls.begin(), std::find(vls.begin(), vls.end(), Init)); - n = std::distance(vls.begin(), std::find(vls.begin(), vls.end(), Now)); + UInt32 i = distance(values, values[sane_opts::RANGE_POS_DEFAULT]), + n = distance(values, values[sane_opts::RANGE_POS_CURRENT]); + for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < values.size(); ++i) + vls.push_back(Fix32(values[i])); return cap_get_enum_values(msg, data, vls, Now, Init, n, i); }; @@ -1908,7 +1985,7 @@ void huagao_ds::init_support_caps(void) m_bFeederEnabled = mech; return success(); } - return CapSupGetAllReset(msg, data, m_bFeederEnabled, Bool(true)); + return CapSupGetAllReset(msg, data, m_bFeederEnabled, Bool(true)); }; m_query[CapType::Duplex] = msgSupportGetAll; @@ -1924,7 +2001,9 @@ void huagao_ds::init_support_caps(void) return ret == SCANNER_ERR_OK ? success() : badValue(); } BYTE dup = 1; - GET_SANE_OPT(bool, scanner_, ex_duplex, (bool*)&dup, NULL, NULL, NULL); + std::vector all; + GET_SANE_OPT(bool, scanner_, ex_duplex, NULL, &all); + dup = all[sane_opts::RANGE_POS_CURRENT]; return CapSupGetAllReset(msg, data, dup, Bool(true)); }; @@ -1944,22 +2023,31 @@ void huagao_ds::init_support_caps(void) log_attr_access((int)CapType::IImageFileFormat, (int)msg); SANE_FinalImgFormat now, init; std::vector all; - GET_SANE_OPT(SANE_FinalImgFormat, scanner_, ex_final_format, &now, &init, &all, NULL); + GET_SANE_OPT(SANE_FinalImgFormat, scanner_, ex_final_format, NULL, &all); + init = all[sane_opts::RANGE_POS_DEFAULT]; + now = all[sane_opts::RANGE_POS_CURRENT]; if (Msg::Set == msg || Msg::Reset == msg) { - auto fmt = data.currentItem(); - if (fmt != Twpp::ImageFileFormat::Bmp && - fmt != Twpp::ImageFileFormat::Jfif && - fmt != Twpp::ImageFileFormat::Tiff) - return badValue(); - m_fileXfer.setFormat((Twpp::ImageFileFormat)data.currentItem()); + if (Msg::Set == msg) { - if (fmt == Twpp::ImageFileFormat::Bmp) - load_sane_util::log_info(L"set CapType::IImageFileFormat = Bmp\r\n", 0); - else if (fmt == Twpp::ImageFileFormat::Jfif) - load_sane_util::log_info(L"set CapType::IImageFileFormat = Jfif\r\n", 0); - else if (fmt == Twpp::ImageFileFormat::Tiff) - load_sane_util::log_info(L"set CapType::IImageFileFormat = Tiff\r\n", 0); + auto fmt = data.currentItem(); + if (fmt != Twpp::ImageFileFormat::Bmp && + fmt != Twpp::ImageFileFormat::Jfif && + fmt != Twpp::ImageFileFormat::Tiff) + return badValue(); + init.img_format = (SANE_ImageType)fmt; + { + if (fmt == Twpp::ImageFileFormat::Bmp) + load_sane_util::log_info(L"set CapType::IImageFileFormat = Bmp\r\n", 0); + else if (fmt == Twpp::ImageFileFormat::Jfif) + load_sane_util::log_info(L"set CapType::IImageFileFormat = Jfif\r\n", 0); + else if (fmt == Twpp::ImageFileFormat::Tiff) + load_sane_util::log_info(L"set CapType::IImageFileFormat = Tiff\r\n", 0); + } } + else + data = Capability::createOneValue((Twpp::ImageFileFormat)init.img_format); + + m_fileXfer.setFormat((Twpp::ImageFileFormat)init.img_format); return success(); //if(Msg::Set == msg) // init.img_format = (SANE_ImageType)(int)data.currentItem(); @@ -1970,11 +2058,16 @@ void huagao_ds::init_support_caps(void) // ImageFileFormat Now = (ImageFileFormat)(int)now.img_format, Init = (ImageFileFormat)(int)init.img_format; ImageFileFormat Now = m_fileXfer.format() , Init = Twpp::ImageFileFormat::Bmp; std::list vals; - UInt32 i = 0, n = 0; - for (const auto& v : all) - vals.push_back((ImageFileFormat)(int)v.img_format); - i = std::distance(vals.begin(), std::find(vals.begin(), vals.end(), Init)); - n = std::distance(vals.begin(), std::find(vals.begin(), vals.end(), Now)); + UInt32 i = 0, // distance(all, init), + n = 0; // distance(all, now); + for (size_t ind = sane_opts::RANGE_POS_ENUM_BEGIN; ind < all.size(); ++ind) + { + vals.push_back((ImageFileFormat)(int)all[ind].img_format); + if (all[ind].img_format == init.img_format) + i = ind; + else if (all[ind].img_format == now.img_format) + n = ind; + } return cap_get_enum_values(msg, data, vals, Now, Init, n, i); }; @@ -1989,7 +2082,9 @@ void huagao_ds::init_support_caps(void) return ret == SCANNER_ERR_OK ? success() : seqError(); } BYTE ato = 1; - GET_SANE_OPT(bool, scanner_, is_auto_deskew, (bool*)&ato, NULL, NULL, NULL); + std::vector all; + GET_SANE_OPT(bool, scanner_, is_auto_deskew, NULL, &all); + ato = all[sane_opts::RANGE_POS_CURRENT]; return CapSupGetAllReset(msg, data, ato, true); }; @@ -2005,7 +2100,9 @@ void huagao_ds::init_support_caps(void) } float direction = .0f; BYTE am = 0; - GET_SANE_OPT(float, scanner_, ex_text_direction, &direction, NULL, NULL, NULL); + std::vector all; + GET_SANE_OPT(float, scanner_, ex_text_direction, NULL, &all); + direction = all[sane_opts::RANGE_POS_CURRENT]; am = IS_DOUBLE_EQUAL(direction, AUTO_MATIC_ROTATE); return CapSupGetAllReset(msg, data, am, false); }; @@ -2014,24 +2111,35 @@ void huagao_ds::init_support_caps(void) m_caps[CapType::SerialNumber] = [this](Msg msg, Capability& data)->Result { log_attr_access((int)CapType::SerialNumber, (int)msg); Str255 str; - std::string v(""); - GET_SANE_OPT(std::string, scanner_, ex_serial, &v, NULL, NULL, NULL); - strcpy(str.data(), v.c_str()); + std::vector all; + GET_SANE_OPT(std::string, scanner_, ex_serial, NULL, &all); + strcpy(str.data(), all[sane_opts::RANGE_POS_CURRENT].c_str()); return CapSupGetAll(msg, data, str, str); }; - m_query[CapType::AutoScan] = msgSupportGetAllSetReset; - m_caps[CapType::AutoScan] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapType::AutoScan, (int)msg); - if (Msg::Set == msg) { - auto autoscan = data.currentItem(); - m_autoscan = autoscan; - return success(); - } - //data = Capability::createOneValue(CapType::AutoScan, m_autoscan); - //return success(); - return CapSupGetAllReset(msg, data, m_autoscan, FALSE); - }; + if (SANE_ID(ex_to_be_scan) > 0) + { + m_query[CapType::AutoScan] = msgSupportGetAllSetReset; + m_caps[CapType::AutoScan] = [this](Msg msg, Capability& data)->Result { + log_attr_access((int)CapType::AutoScan, (int)msg); + if (Msg::Set == msg || Msg::Reset == msg) { + bool val = false; + if(Msg::Set == msg) + val = (bool)data.currentItem(); + int ret = SANE_STATUS_GOOD; + m_autoscan = val; + SET_SANE_OPT(ret, scanner_, ex_to_be_scan, &val); + return ret == SANE_STATUS_GOOD ? success() : badValue(); + } + std::vector all; + GET_SANE_OPT(bool, scanner_, ex_to_be_scan, NULL, &all); + m_autoscan = (bool)all[sane_opts::RANGE_POS_CURRENT]; + //return oneValGetSet(msg, data, (Bool)all[sane_opts::RANGE_POS_CURRENT], 0); + //data = Capability::createOneValue(CapType::AutoScan, (BYTE)all[sane_opts::RANGE_POS_CURRENT]); + //return success(); + return CapSupGetAllReset(msg, data, m_autoscan, FALSE); + }; + } m_query[CapType::IAutoSize] = msgSupportGetAllSetReset; m_caps[CapType::IAutoSize] = [this](Msg msg, Capability& data)->Result { @@ -2044,9 +2152,9 @@ void huagao_ds::init_support_caps(void) SET_SANE_OPT(ret, scanner_, ex_auto_paper_size, &match); return ret == SCANNER_ERR_OK ? success() : badValue(); } - bool match = true; - GET_SANE_OPT(bool, scanner_, ex_auto_paper_size, &match, NULL, NULL, NULL); - UInt16 size = match ? (UInt16)AutoSize::Auto : (UInt16)AutoSize::None; + std::vector all; + GET_SANE_OPT(bool, scanner_, ex_auto_paper_size, NULL, &all); + UInt16 size = all[sane_opts::RANGE_POS_CURRENT] ? (UInt16)AutoSize::Auto : (UInt16)AutoSize::None; return CapSupGetAllReset(msg, data, { AutoSize::None, AutoSize::Auto }, size, AutoSize::None, (size == (UInt16)AutoSize::Auto) ? 1 : 0, 0); }; @@ -2059,12 +2167,12 @@ void huagao_ds::init_support_caps(void) SET_SANE_OPT(ret, scanner_, is_erase_black_frame, (bool*)&autodetectborder); return ret == SCANNER_ERR_OK ? success() : badValue(); } - bool val = false, cur = false; Bool init = false, erase = false; - GET_SANE_OPT(bool, scanner_, is_erase_black_frame, &cur, &val, NULL, NULL); - init = val; - erase = cur; + std::vector all; + GET_SANE_OPT(bool, scanner_, is_erase_black_frame, NULL, &all); + init = (bool)all[sane_opts::RANGE_POS_DEFAULT]; + erase = (bool)all[sane_opts::RANGE_POS_CURRENT]; return CapSupGetAllReset(msg, data, { false,true }, erase, init, erase ? 1 : 0, 0); }; @@ -2078,9 +2186,9 @@ void huagao_ds::init_support_caps(void) SET_SANE_OPT(ret, scanner_, ex_discard_blank_page, &discard); return ret == SCANNER_ERR_OK ? success() : badValue(); } - bool discard = false; - GET_SANE_OPT(bool, scanner_, ex_discard_blank_page, &discard, NULL, NULL, NULL); - DiscardBlankPages autodiscradblank = discard ? DiscardBlankPages::Auto : DiscardBlankPages::Disabled; + std::vector all; + GET_SANE_OPT(bool, scanner_, ex_discard_blank_page, NULL, &all); + DiscardBlankPages autodiscradblank = all[sane_opts::RANGE_POS_CURRENT] ? DiscardBlankPages::Auto : DiscardBlankPages::Disabled; return CapSupGetAllReset(msg, data, autodiscradblank, DiscardBlankPages::Disabled); }; @@ -2094,9 +2202,9 @@ void huagao_ds::init_support_caps(void) SET_SANE_OPT(ret, scanner_, ex_discard_blank_receipt, &discard); return ret == SCANNER_ERR_OK ? success() : badValue(); } - bool discard = false; - GET_SANE_OPT(bool, scanner_, ex_discard_blank_receipt, &discard, NULL, NULL, NULL); - DiscardBlankPages autodiscradblank = discard ? DiscardBlankPages::Auto : DiscardBlankPages::Disabled; + std::vector all; + GET_SANE_OPT(bool, scanner_, ex_discard_blank_receipt, NULL, &all); + DiscardBlankPages autodiscradblank = all[sane_opts::RANGE_POS_CURRENT] ? DiscardBlankPages::Auto : DiscardBlankPages::Disabled; return CapSupGetAllResetEx(msg, data, autodiscradblank, DiscardBlankPages::Disabled); // return success(); }; @@ -2112,26 +2220,17 @@ void huagao_ds::init_support_caps(void) } int cur = FILTER_NONE, def = FILTER_NONE; std::vector vals; - GET_SANE_OPT(int, scanner_, ex_color_filter, &cur, &def, &vals, NULL); + GET_SANE_OPT(int, scanner_, ex_color_filter, NULL, &vals); std::list vs; - Filter now = Filter::None, init = Filter::None; - UInt32 curInd = 0, defInd = 0, ind = 0; + Filter now = from_sane_filter(vals[sane_opts::RANGE_POS_CURRENT]), + init = from_sane_filter(vals[sane_opts::RANGE_POS_DEFAULT]); + UInt32 curInd = distance(vals, vals[sane_opts::RANGE_POS_CURRENT]), + defInd = distance(vals, vals[sane_opts::RANGE_POS_DEFAULT]);; - for (auto& v : vals) + for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < vals.size(); ++i) { - vs.push_back(from_sane_filter(v)); - if (v == cur) - { - curInd = ind; - now = from_sane_filter(v); - } - else if (v == def) - { - defInd = ind; - init = from_sane_filter(v); - } - ind++; + vs.push_back(from_sane_filter(vals[i])); } BYTE f = (BYTE)now; return CapSupGetAllReset(msg, data, vs, f, init, curInd, defInd); @@ -2142,7 +2241,13 @@ void huagao_ds::init_support_caps(void) log_attr_access((int)CapType::IBrightness, (int)msg); int init = 128, l = 1, u = 255, step = 1, now = 128; int ret = SCANNER_ERR_OK; - GET_SANE_OPT_RANGE(int, scanner_, bright, &now, &init, &l, &u, &step); + std::vector all; + GET_SANE_OPT(int, scanner_, bright, NULL, &all); + init = all[sane_opts::RANGE_POS_DEFAULT]; + now = all[sane_opts::RANGE_POS_CURRENT]; + l = all[sane_opts::RANGE_POS_LOWER]; + u = all[sane_opts::RANGE_POS_UPPER]; + step = all[sane_opts::RANGE_POS_STEP]; float sf = trans_range((float)step, (float)l, (float)u, -1000.0f, 1000.0f, true), nf = trans_range((float)now, (float)l, (float)u, -1000.0f, 1000.0f), initf = trans_range((float)init, (float)l, (float)u, -1000.0f, 1000.0f); @@ -2157,17 +2262,21 @@ void huagao_ds::init_support_caps(void) case Msg::GetDefault: data = Capability::createOneValue(Fix32(initf)); return success(); - case Msg::Reset: - data = Capability::createOneValue(Fix32(initf)); case Msg::Set: { auto mech = data.currentItem(); if (mech > 1000.0f || mech < -1000.0f) return badValue(); - sf = mech.toFloat(); - now = (int)(trans_range(sf, -1000.0f, 1000.0f, (float)l, (float)u) + .5f); - SET_SANE_OPT(ret, scanner_, bright, &now); - return ret == SCANNER_ERR_OK ? success() : badValue(); + initf = mech.toFloat(); } + case Msg::Reset: + now = (int)(trans_range(initf, -1000.0f, 1000.0f, (float)l, (float)u) + .5f); + SET_SANE_OPT(ret, scanner_, bright, &now); + if (Msg::Reset == msg) + { + initf = trans_range((float)now, (float)l, (float)u, -1000.0f, 1000.0f, true); + data = Capability::createOneValue(Fix32(initf)); + } + return ret == SCANNER_ERR_OK ? success() : badValue(); default: return capBadOperation(); } @@ -2178,13 +2287,19 @@ void huagao_ds::init_support_caps(void) log_attr_access((int)CapType::IContrast, (int)msg); int init = 4, l = 1, u = 7, step = 1, now = 4; int ret = SCANNER_ERR_OK; - GET_SANE_OPT_RANGE(int, scanner_, contrast, &now, &init, &l, &u, &step); + std::vector all; + GET_SANE_OPT(int, scanner_, contrast, NULL, &all); + init = all[sane_opts::RANGE_POS_DEFAULT]; + now = all[sane_opts::RANGE_POS_CURRENT]; + l = all[sane_opts::RANGE_POS_LOWER]; + u = all[sane_opts::RANGE_POS_UPPER]; + step = all[sane_opts::RANGE_POS_STEP]; float sf = trans_range((float)step, (float)l, (float)u, -1000.0f, 1000.0f, true), nf = trans_range((float)now, (float)l, (float)u, -1000.0f, 1000.0f), initf = trans_range((float)init, (float)l, (float)u, -1000.0f, 1000.0f); switch (msg) { case Msg::Get: - sf = 333.333f; + // sf = 333.333f; data = Capability::createRange(Fix32(-1000.0f), Fix32(1000.0f), Fix32(sf), Fix32(nf), Fix32(initf)); return success(); case Msg::GetCurrent: @@ -2193,17 +2308,21 @@ void huagao_ds::init_support_caps(void) case Msg::GetDefault: data = Capability::createOneValue(Fix32(initf)); return success(); - case Msg::Reset: - data = Capability::createOneValue(Fix32(initf)); case Msg::Set: { auto mech = data.currentItem(); if (mech > 1000.0f || mech < -1000.0f) return badValue(); - sf = mech.toFloat(); - now = (int)(trans_range(sf, -1000.0f, 1000.0f, (float)l, (float)u) + .5f); - SET_SANE_OPT(ret, scanner_, contrast, &now); - return ret == SCANNER_ERR_OK ? success() : badValue(); + initf = mech.toFloat(); } + case Msg::Reset: + now = (int)(trans_range(initf, -1000.0f, 1000.0f, (float)l, (float)u) + .5f); + SET_SANE_OPT(ret, scanner_, contrast, &now); + if (Msg::Reset == msg) + { + initf = trans_range((float)now, (float)l, (float)u, -1000.0f, 1000.0f, true); + data = Capability::createOneValue(Fix32(initf)); + } + return ret == SCANNER_ERR_OK ? success() : badValue(); default: return capBadOperation(); } @@ -2213,13 +2332,14 @@ void huagao_ds::init_support_caps(void) m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_FILL_HOLE_RATIO] = [this](Msg msg, Capability& data)->Result { log_attr_access((int)CapTypeEx::CAP_TYPE_EX_FILL_HOLE_RATIO, (int)msg); float init = .0f, l = .0f, u = .0f, step = .0f, now = .0f; + std::vector all; int ret = SCANNER_ERR_OK; - GET_SANE_OPT_RANGE(float, scanner_, search_hole_range, &now, &init, &l, &u, &step); - init *= 100; init += .5f; - l *= 100; l += .5f; - u *= 100; u += .5f; - step *= 100; step += .5f; - now *= 100; now += .5f; + GET_SANE_OPT(float, scanner_, search_hole_range, NULL, &all); + init = all[sane_opts::RANGE_POS_DEFAULT] * 100.0f; + now = all[sane_opts::RANGE_POS_CURRENT] * 100.0f; + l = all[sane_opts::RANGE_POS_LOWER] * 100.0f; + u = all[sane_opts::RANGE_POS_UPPER] * 100.0f; + step = all[sane_opts::RANGE_POS_STEP] * 100.0f; switch (msg) { case Msg::Get: data = Capability::createRange((CapType)CapTypeEx::CAP_TYPE_EX_FILL_HOLE_RATIO, UInt32(l), UInt32(u), UInt32(step), UInt32(now), UInt32(init)); @@ -2230,17 +2350,16 @@ void huagao_ds::init_support_caps(void) case Msg::GetDefault: data = Capability::createOneValue((CapType)CapTypeEx::CAP_TYPE_EX_FILL_HOLE_RATIO, UInt32(init)); return success(); - case Msg::Reset: - data = Capability::createOneValue((CapType)CapTypeEx::CAP_TYPE_EX_FILL_HOLE_RATIO, UInt32(init)); case Msg::Set: { auto mech = data.currentItem(); if (mech > u || mech < l) return badValue(); - float v = (float)mech; - v /= 100.0f; - SET_SANE_OPT(ret, scanner_, search_hole_range, &v); - return ret == SCANNER_ERR_OK ? success() : badValue(); + init = (float)mech; } + case Msg::Reset: + init /= 100.0f; + SET_SANE_OPT(ret, scanner_, search_hole_range, &init); + return ret == SCANNER_ERR_OK ? success() : badValue(); default: return capBadOperation(); } @@ -2250,8 +2369,14 @@ void huagao_ds::init_support_caps(void) m_caps[CapType::IGamma] = [this](Msg msg, Capability& data)->Result { log_attr_access((int)CapType::IGamma, (int)msg); float init = .0f, l = .0f, u = .0f, step = .0f, now = .0f; + std::vector all; int ret = SCANNER_ERR_OK; - GET_SANE_OPT_RANGE(float, scanner_, gamma, &now, &init, &l, &u, &step); + GET_SANE_OPT(float, scanner_, gamma, NULL, &all); + init = all[sane_opts::RANGE_POS_DEFAULT]; + now = all[sane_opts::RANGE_POS_CURRENT]; + l = all[sane_opts::RANGE_POS_LOWER]; + u = all[sane_opts::RANGE_POS_UPPER]; + step = all[sane_opts::RANGE_POS_STEP]; switch (msg) { case Msg::Get: data = Capability::createRange(Fix32(l), Fix32(u), Fix32(step), Fix32(now), Fix32(init)); @@ -2260,17 +2385,17 @@ void huagao_ds::init_support_caps(void) data = Capability::createOneValue(Fix32(now)); return success(); case Msg::GetDefault: - case Msg::Reset: data = Capability::createOneValue(Fix32(init)); return success(); case Msg::Set: { auto mech = data.currentItem(); if (mech > u || mech < l) return badValue(); - now = mech.toFloat(); - SET_SANE_OPT(ret, scanner_, gamma, &now); - return ret == SCANNER_ERR_OK ? success() : badValue(); + init = mech.toFloat(); } + case Msg::Reset: + SET_SANE_OPT(ret, scanner_, gamma, &init); + return ret == SCANNER_ERR_OK ? success() : badValue(); default: return capBadOperation(); } @@ -2293,19 +2418,19 @@ void huagao_ds::init_support_caps(void) return ret == SCANNER_ERR_OK ? success() : seqError(); } DoubleFeedDetection init = DoubleFeedDetection::Ultrasonic; - bool enable = true, def = true; - GET_SANE_OPT(bool, scanner_, is_ultrasonic_check, &enable, &def, NULL, NULL); - BYTE ato = !enable; - init = def ? DoubleFeedDetection::Ultrasonic : DoubleFeedDetection::ByLength; + std::vector all; + GET_SANE_OPT(bool, scanner_, is_ultrasonic_check, NULL, &all); + BYTE ato = !all[sane_opts::RANGE_POS_CURRENT]; + init = all[sane_opts::RANGE_POS_DEFAULT] ? DoubleFeedDetection::Ultrasonic : DoubleFeedDetection::ByLength; return CapSupGetAllReset(msg, data, ato, init); }; m_query[CapType::IAutomaticCropUsesFrame] = msgSupportGetAll; m_caps[CapType::IAutomaticCropUsesFrame] = [this](Msg msg, Capability& data)->Result { log_attr_access((int)CapType::IAutomaticCropUsesFrame, (int)msg); - bool yes = false; - GET_SANE_OPT(bool, scanner_, ex_is_paper_auto_crop, &yes, NULL, NULL, NULL); - BYTE crop = yes; + std::vector all; + GET_SANE_OPT(bool, scanner_, ex_is_paper_auto_crop, NULL, &all); + BYTE crop = all[sane_opts::RANGE_POS_CURRENT]; return CapSupGetAll(msg, data, crop, false); }; @@ -2316,251 +2441,279 @@ void huagao_ds::init_support_caps(void) return CapSupGetAll(msg, data, paperon, paperon); }; - m_query[CapType(CapTypeEx::CAP_TYPE_EX_FOLD)] = msgSupportGetAllSetReset; - m_caps[CapType(CapTypeEx::CAP_TYPE_EX_FOLD)] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_FOLD, (int)msg); - if (Msg::Set == msg || Msg::Reset == msg) { - auto fold = data.currentItem(); - if (msg == Msg::Reset) - fold = false; - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_is_page_fold, &fold); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - bool yes = false; - GET_SANE_OPT(bool, scanner_, ex_is_page_fold, &yes, NULL, NULL, NULL); - BYTE fold = yes; - return CapSupGetAllResetEx(msg, data, fold, 0); - }; + if (SANE_ID(ex_is_page_fold) > 0) + { + m_query[CapType(CapTypeEx::CAP_TYPE_EX_FOLD)] = msgSupportGetAllSetReset; + m_caps[CapType(CapTypeEx::CAP_TYPE_EX_FOLD)] = [this](Msg msg, Capability& data)->Result { + log_attr_access((int)CapTypeEx::CAP_TYPE_EX_FOLD, (int)msg); + if (Msg::Set == msg || Msg::Reset == msg) { + bool fold = false; + if (msg == Msg::Set) + fold = (bool)data.currentItem();; + int ret = SCANNER_ERR_OK; + SET_SANE_OPT(ret, scanner_, ex_is_page_fold, &fold); + return ret == SCANNER_ERR_OK ? success() : badValue(); + } + std::vector all; + GET_SANE_OPT(bool, scanner_, ex_is_page_fold, NULL, &all); + BYTE fold = all[sane_opts::RANGE_POS_CURRENT]; + return CapSupGetAllResetEx(msg, data, fold, 0); + }; + } - m_query[(CapType)(CapTypeEx::CAP_TYPE_EX_DOGEAR_DIST)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::CAP_TYPE_EX_DOGEAR_DIST)] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_DOGEAR_DIST, (int)msg); - int now = 10, init = 10, l = 0, u = 100, s = 10; - GET_SANE_OPT_RANGE(int, scanner_, dogear_size, &now, &init, &l, &u, &s); - if (Msg::Set == msg || Msg::Reset == msg) { - auto mech = data.currentItem(); - if (mech < 10 || mech > 300) - return badValue(); - int ret = SCANNER_ERR_OK; - int val = (int)(trans_range((float)mech, 10.0f, 300.0f, (float)l, (float)u) + .5f); - SET_SANE_OPT(ret, scanner_, dogear_size, &val); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - UInt32 Now = UInt32(trans_range((float)now, (float)l, (float)u, 10.0f, 300.0f) + .5f), + if (SANE_ID(dogear_size) > 0) + { + m_query[(CapType)(CapTypeEx::CAP_TYPE_EX_DOGEAR_DIST)] = msgSupportGetAllSetReset; + m_caps[(CapType)(CapTypeEx::CAP_TYPE_EX_DOGEAR_DIST)] = [this](Msg msg, Capability& data)->Result { + log_attr_access((int)CapTypeEx::CAP_TYPE_EX_DOGEAR_DIST, (int)msg); + int now = 10, init = 10, l = 0, u = 100, s = 10; + std::vector all; + GET_SANE_OPT(int, scanner_, dogear_size, NULL, &all); + init = all[sane_opts::RANGE_POS_DEFAULT]; + now = all[sane_opts::RANGE_POS_CURRENT]; + l = all[sane_opts::RANGE_POS_LOWER]; + u = all[sane_opts::RANGE_POS_UPPER]; + s = all[sane_opts::RANGE_POS_STEP]; + if (Msg::Set == msg || Msg::Reset == msg) { + if (Msg::Set == msg) + { + auto mech = data.currentItem(); + if (mech < 10 || mech > 300) + return badValue(); + init = (int)(trans_range((float)mech, 10.0f, 300.0f, (float)l, (float)u) + .5f); + } + int ret = SCANNER_ERR_OK; + SET_SANE_OPT(ret, scanner_, dogear_size, &init); + return ret == SCANNER_ERR_OK ? success() : badValue(); + } + UInt32 Now = UInt32(trans_range((float)now, (float)l, (float)u, 10.0f, 300.0f) + .5f), Init = UInt32(trans_range((float)init, (float)l, (float)u, 10.0f, 300.0f) + .5f); - return CapSupGetAllResetEx(msg, data, Now, Init); - }; + return CapSupGetAllResetEx(msg, data, Now, Init); + }; + } - m_query[(CapType)(CapTypeEx::CAP_TYPE_EX_CROP_MODEL)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::CAP_TYPE_EX_CROP_MODEL)] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_CROP_MODEL, (int)msg); - bool cur = false, def = false; - GET_SANE_OPT(bool, scanner_, ex_is_paper_auto_crop, &cur, &def, NULL, NULL); - if (Msg::Set == msg || Msg::Reset == msg) - { - if (Msg::Set == msg) - def = data.currentItem() == 1; - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_is_paper_auto_crop, &def); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - BYTE crop = cur; - return CapSupGetAll(msg, data, crop, def); - }; - - m_query[(CapType)CapTypeEx::CAP_TYPE_EX_MULTI_OUT_TYPE] = msgSupportGetAllSetReset; - m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_MULTI_OUT_TYPE] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_MULTI_OUT_TYPE, (int)msg); - int cur = MULTI_OUT_NONE, def = MULTI_OUT_NONE; - std::vector all; - GET_SANE_OPT(int, scanner_, ex_multiout_type, &cur, &def, &all, NULL); - if (Msg::Set == msg || Msg::Reset == msg) { - auto mech = data.currentItem(); - if (msg == Msg::Reset) - mech = def; - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_multiout_type, &mech); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - Int32 now = cur, init = def, ind = 0, curInd = 0, defInd = 0; - std::list vals; - for (auto& v : all) - { - vals.push_back(v); - if (v == cur) - curInd = ind; - else if (v == def) - defInd = ind; - ind++; - } - return CapSupGetAllResetEx(msg, data, vals, now, init, curInd, defInd); - }; - - m_query[CapType(CapTypeEx::CAP_TYPE_EX_TO_BE_SCAN)] = msgSupportGetAllSetReset; - m_caps[CapType(CapTypeEx::CAP_TYPE_EX_TO_BE_SCAN)] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_TO_BE_SCAN, (int)msg); - if (Msg::Set == msg || Msg::Reset == msg) { - auto tobe = data.currentItem(); - if (msg == Msg::Reset) - tobe = false; - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_to_be_scan, &tobe); - return ret == SCANNER_ERR_OK ? success() : seqError(); - } - bool val = false; - GET_SANE_OPT(bool, scanner_, ex_to_be_scan, &val, NULL, NULL, NULL); - BYTE tobe = val; - return CapSupGetAllResetEx(msg, data, tobe, 0); - }; - - m_query[CapType(CapTypeEx::CAP_TYPE_EX_SCAN_WITH_HOLE)] = msgSupportGetAllSetReset; - m_caps[CapType(CapTypeEx::CAP_TYPE_EX_SCAN_WITH_HOLE)] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_SCAN_WITH_HOLE, (int)msg); - if (Msg::Set == msg || Msg::Reset == msg) { - auto tobe = data.currentItem(); - if (msg == Msg::Reset) - tobe = false; - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_scan_with_hole, &tobe); - return ret == SCANNER_ERR_OK ? success() : seqError(); - } - bool val = false; - GET_SANE_OPT(bool, scanner_, ex_scan_with_hole, &val, NULL, NULL, NULL); - BYTE tobe = val; - return CapSupGetAllResetEx(msg, data, tobe, 0); - }; - - m_query[(CapType)(CapTypeEx::CAP_TYPE_EX_ENCODE)] = msgSupportGetAll; - m_caps[(CapType)(CapTypeEx::CAP_TYPE_EX_ENCODE)] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_ENCODE, (int)msg); - std::string code(""); - GET_SANE_OPT(std::string, scanner_, ex_device_code, &code, NULL, NULL, NULL); - Str255 str; - str.setData(code.c_str(), 32); - data = Capability::createOneValue((CapType)CapTypeEx::CAP_TYPE_EX_ENCODE, str); - return success(); - }; - - m_query[(CapType)(CapTypeEx::CAP_TYPE_EX_POWER_LEVEL)] = msgSupportGetAllSetReset; - m_caps[(CapType)(CapTypeEx::CAP_TYPE_EX_POWER_LEVEL)] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_POWER_LEVEL, (int)msg); - int cur = SANE_POWER_MINUTES_30, def = SANE_POWER_MINUTES_30; - std::vector all; - GET_SANE_OPT(int, scanner_, ex_power, &cur, &def, &all, NULL); - if (Msg::Set == msg || Msg::Reset == msg) { - if(msg == Msg::Set) - def = data.currentItem(); - - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_power, &def); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - UInt32 now = cur, init = def, ind = 0, curInd = 0, defInd = 0; - std::list vals; - for (auto& v : all) - { - vals.push_back(v); - if (v == cur) - curInd = ind; - else if (v == def) - defInd = ind; - ind++; - } - return CapSupGetAllResetEx(msg, data, vals, now, init, curInd, defInd); - }; - - m_query[(CapType)CapTypeEx::CAP_TYPE_EX_BKG_FILLING_METHOD] = msgSupportGetAllSetReset; - m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_BKG_FILLING_METHOD] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_BKG_FILLING_METHOD, (int)msg); - if (Msg::Set == msg) { - auto convex = data.currentItem(); - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_fill_background, (bool*)&convex); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - bool val = false, cur = false; - Bool init = false, - erase = false; - GET_SANE_OPT(bool, scanner_, ex_fill_background, &cur, &val, NULL, NULL); - init = val; - erase = cur; - return CapSupGetAllResetEx(msg, data, { false,true }, erase, init, erase ? 1 : 0, 0); - }; - - m_query[(CapType)CapTypeEx::CAP_TYPE_EX_SHARPEN] = msgSupportGetAllSetReset; - m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_SHARPEN] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_SHARPEN, (int)msg); - int cur = MULTI_OUT_NONE, def = MULTI_OUT_NONE; - std::vector all; - GET_SANE_OPT(int, scanner_, ex_sharpen, &cur, &def, &all, NULL); - if (Msg::Set == msg || Msg::Reset == msg) { - auto mech = data.currentItem(); - if (msg == Msg::Reset) - mech = def; - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_sharpen, &mech); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - Int32 now = cur, init = def, ind = 0, curInd = 0, defInd = 0; - std::list vals; - for (auto& v : all) - { - vals.push_back(v); - if (v == cur) - curInd = ind; - else if (v == def) - defInd = ind; - ind++; - } - return CapSupGetAllResetEx(msg, data, vals, now, init, curInd, defInd); - }; - - m_query[(CapType)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR] = msgSupportGetAllSetReset; - m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR] = [this](Msg msg, Capability& data)->Result { - log_attr_access((int)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR, (int)msg); - int cur = FILTER_NONE, def = FILTER_NONE; - std::vector vals; - GET_SANE_OPT(int, scanner_, ex_color_enhance, &cur, &def, &vals, NULL); - if (Msg::Set == msg || Msg::Reset == msg) { - if(Msg::Set == msg) - def = data.currentItem(); - int ret = SCANNER_ERR_OK; - SET_SANE_OPT(ret, scanner_, ex_color_filter, &def); - return ret == SCANNER_ERR_OK ? success() : badValue(); - } - - std::list vs; - Filter now = from_sane_filter(cur), init = from_sane_filter(def); - UInt32 curInd = 0, defInd = 0, ind = 0; - - for (auto& v : vals) - { - vs.push_back(from_sane_filter(v)); - if (v == cur) + if (SANE_ID(ex_is_paper_auto_crop) > 0) + { + m_query[(CapType)(CapTypeEx::CAP_TYPE_EX_CROP_MODEL)] = msgSupportGetAllSetReset; + m_caps[(CapType)(CapTypeEx::CAP_TYPE_EX_CROP_MODEL)] = [this](Msg msg, Capability& data)->Result { + log_attr_access((int)CapTypeEx::CAP_TYPE_EX_CROP_MODEL, (int)msg); + std::vector all; + GET_SANE_OPT(bool, scanner_, ex_is_paper_auto_crop, NULL, &all); + if (Msg::Set == msg || Msg::Reset == msg) { - curInd = ind; + bool def = all[sane_opts::RANGE_POS_DEFAULT]; + if (Msg::Set == msg) + def = data.currentItem() == 1; + int ret = SCANNER_ERR_OK; + SET_SANE_OPT(ret, scanner_, ex_is_paper_auto_crop, &def); + return ret == SCANNER_ERR_OK ? success() : badValue(); } - else if (v == def) + BYTE crop = all[sane_opts::RANGE_POS_CURRENT]; + return CapSupGetAll(msg, data, crop, all[sane_opts::RANGE_POS_DEFAULT]); + }; + } + + if (SANE_ID(ex_multiout_type) > 0) + { + m_query[(CapType)CapTypeEx::CAP_TYPE_EX_MULTI_OUT_TYPE] = msgSupportGetAllSetReset; + m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_MULTI_OUT_TYPE] = [this](Msg msg, Capability& data)->Result { + log_attr_access((int)CapTypeEx::CAP_TYPE_EX_MULTI_OUT_TYPE, (int)msg); + int cur = MULTI_OUT_NONE, def = MULTI_OUT_NONE; + std::vector all; + GET_SANE_OPT(int, scanner_, ex_multiout_type, NULL, &all); + cur = all[sane_opts::RANGE_POS_CURRENT]; + def = all[sane_opts::RANGE_POS_DEFAULT]; + if (Msg::Set == msg || Msg::Reset == msg) { + auto mech = def; + if (msg == Msg::Set) + mech = data.currentItem(); + int ret = SCANNER_ERR_OK; + SET_SANE_OPT(ret, scanner_, ex_multiout_type, &mech); + return ret == SCANNER_ERR_OK ? success() : badValue(); + } + Int32 now = cur, init = def, ind = 0, + curInd = distance(all, cur), + defInd = distance(all, def); + std::list vals; + for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < all.size(); ++i) + vals.push_back(all[i]); + return CapSupGetAllResetEx(msg, data, vals, now, init, curInd, defInd); + }; + } + + if (SANE_ID(ex_to_be_scan) > 0) + { + m_query[CapType(CapTypeEx::CAP_TYPE_EX_TO_BE_SCAN)] = msgSupportGetAllSetReset; + m_caps[CapType(CapTypeEx::CAP_TYPE_EX_TO_BE_SCAN)] = [this](Msg msg, Capability& data)->Result { + log_attr_access((int)CapTypeEx::CAP_TYPE_EX_TO_BE_SCAN, (int)msg); + if (Msg::Set == msg || Msg::Reset == msg) { + auto tobe = false; + if (msg == Msg::Set) + tobe = data.currentItem(); + int ret = SCANNER_ERR_OK; + SET_SANE_OPT(ret, scanner_, ex_to_be_scan, &tobe); + return ret == SCANNER_ERR_OK ? success() : seqError(); + } + std::vector all; + GET_SANE_OPT(bool, scanner_, ex_to_be_scan, NULL, &all); + BYTE tobe = all[sane_opts::RANGE_POS_CURRENT]; + return CapSupGetAllResetEx(msg, data, tobe, 0); + }; + } + + if (SANE_ID(ex_scan_with_hole) > 0) + { + m_query[CapType(CapTypeEx::CAP_TYPE_EX_SCAN_WITH_HOLE)] = msgSupportGetAllSetReset; + m_caps[CapType(CapTypeEx::CAP_TYPE_EX_SCAN_WITH_HOLE)] = [this](Msg msg, Capability& data)->Result { + log_attr_access((int)CapTypeEx::CAP_TYPE_EX_SCAN_WITH_HOLE, (int)msg); + if (Msg::Set == msg || Msg::Reset == msg) { + auto tobe = false; + if (msg == Msg::Set) + tobe = data.currentItem(); + int ret = SCANNER_ERR_OK; + SET_SANE_OPT(ret, scanner_, ex_scan_with_hole, &tobe); + return ret == SCANNER_ERR_OK ? success() : seqError(); + } + std::vector all; + GET_SANE_OPT(bool, scanner_, ex_scan_with_hole, NULL, &all); + BYTE tobe = all[sane_opts::RANGE_POS_CURRENT];; + return CapSupGetAllResetEx(msg, data, tobe, 0); + }; + } + + if (SANE_ID(ex_device_code) > 0) + { + m_query[(CapType)(CapTypeEx::CAP_TYPE_EX_ENCODE)] = msgSupportGetAll; + m_caps[(CapType)(CapTypeEx::CAP_TYPE_EX_ENCODE)] = [this](Msg msg, Capability& data)->Result { + log_attr_access((int)CapTypeEx::CAP_TYPE_EX_ENCODE, (int)msg); + std::vector all; + GET_SANE_OPT(std::string, scanner_, ex_device_code, NULL, &all); + Str255 str; + str.setData(all[sane_opts::RANGE_POS_CURRENT].c_str(), 32); + data = Capability::createOneValue((CapType)CapTypeEx::CAP_TYPE_EX_ENCODE, str); + return success(); + }; + } + + if (SANE_ID(ex_power) > 0) + { + m_query[(CapType)(CapTypeEx::CAP_TYPE_EX_POWER_LEVEL)] = msgSupportGetAllSetReset; + m_caps[(CapType)(CapTypeEx::CAP_TYPE_EX_POWER_LEVEL)] = [this](Msg msg, Capability& data)->Result { + log_attr_access((int)CapTypeEx::CAP_TYPE_EX_POWER_LEVEL, (int)msg); + int cur = SANE_POWER_MINUTES_30, def = SANE_POWER_MINUTES_30; + std::vector all; + GET_SANE_OPT(int, scanner_, ex_power, NULL, &all); + cur = all[sane_opts::RANGE_POS_CURRENT]; + def = all[sane_opts::RANGE_POS_DEFAULT]; + if (Msg::Set == msg || Msg::Reset == msg) { + if (msg == Msg::Set) + def = data.currentItem(); + + int ret = SCANNER_ERR_OK; + SET_SANE_OPT(ret, scanner_, ex_power, &def); + return ret == SCANNER_ERR_OK ? success() : badValue(); + } + UInt32 now = cur, init = def, ind = 0, + curInd = distance(all, cur), + defInd = distance(all, def); + std::list vals; + for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < all.size(); ++i) { - defInd = ind; + vals.push_back(all[i]); } - ind++; - } - UInt32 val = (UInt32)now; - return CapSupGetAllResetEx(msg, data, vs, val, init, curInd, defInd); - }; + return CapSupGetAllResetEx(msg, data, vals, now, init, curInd, defInd); + }; + } + + if (SANE_ID(ex_fill_background) > 0) + { + m_query[(CapType)CapTypeEx::CAP_TYPE_EX_BKG_FILLING_METHOD] = msgSupportGetAllSetReset; + m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_BKG_FILLING_METHOD] = [this](Msg msg, Capability& data)->Result { + log_attr_access((int)CapTypeEx::CAP_TYPE_EX_BKG_FILLING_METHOD, (int)msg); + if (Msg::Set == msg) { + auto convex = data.currentItem(); + int ret = SCANNER_ERR_OK; + SET_SANE_OPT(ret, scanner_, ex_fill_background, (bool*)&convex); + return ret == SCANNER_ERR_OK ? success() : badValue(); + } + bool val = false, cur = false; + Bool init = false, + erase = false; + std::vector all; + GET_SANE_OPT(bool, scanner_, ex_fill_background, NULL, &all); + init = (bool)all[sane_opts::RANGE_POS_DEFAULT]; + erase = (bool)all[sane_opts::RANGE_POS_CURRENT]; + return CapSupGetAllResetEx(msg, data, { false,true }, erase, init, erase ? 1 : 0, 0); + }; + } + + if (SANE_ID(ex_sharpen) > 0) + { + m_query[(CapType)CapTypeEx::CAP_TYPE_EX_SHARPEN] = msgSupportGetAllSetReset; + m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_SHARPEN] = [this](Msg msg, Capability& data)->Result { + log_attr_access((int)CapTypeEx::CAP_TYPE_EX_SHARPEN, (int)msg); + int cur = MULTI_OUT_NONE, def = MULTI_OUT_NONE; + std::vector all; + GET_SANE_OPT(int, scanner_, ex_sharpen, NULL, &all); + cur = all[sane_opts::RANGE_POS_CURRENT]; + def = all[sane_opts::RANGE_POS_DEFAULT]; + if (Msg::Set == msg || Msg::Reset == msg) { + auto mech = def; + if (msg == Msg::Set) + mech = data.currentItem(); + int ret = SCANNER_ERR_OK; + SET_SANE_OPT(ret, scanner_, ex_sharpen, &mech); + return ret == SCANNER_ERR_OK ? success() : badValue(); + } + Int32 now = cur, init = def, + curInd = distance(all, cur), + defInd = distance(all, def); + std::list vals; + for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < all.size(); ++i) + vals.push_back(all[i]); + return CapSupGetAllResetEx(msg, data, vals, now, init, curInd, defInd); + }; + } + + if (SANE_ID(ex_color_enhance) > 0) + { + m_query[(CapType)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR] = msgSupportGetAllSetReset; + m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR] = [this](Msg msg, Capability& data)->Result { + log_attr_access((int)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR, (int)msg); + int cur = FILTER_NONE, def = FILTER_NONE; + std::vector vals; + GET_SANE_OPT(int, scanner_, ex_color_enhance, NULL, &vals); + cur = vals[sane_opts::RANGE_POS_CURRENT]; + def = vals[sane_opts::RANGE_POS_DEFAULT]; + if (Msg::Set == msg || Msg::Reset == msg) { + if (Msg::Set == msg) + def = data.currentItem(); + int ret = SCANNER_ERR_OK; + SET_SANE_OPT(ret, scanner_, ex_color_filter, &def); + return ret == SCANNER_ERR_OK ? success() : badValue(); + } + + std::list vs; + Filter now = from_sane_filter(cur), init = from_sane_filter(def); + UInt32 curInd = distance(vals, cur), defInd = distance(vals, def); + + for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < vals.size(); ++i) + vs.push_back(from_sane_filter(vals[i])); + UInt32 val = (UInt32)now; + return CapSupGetAllResetEx(msg, data, vs, val, init, curInd, defInd); + }; + } init_support_caps_ex(); m_query[(CapType)CapTypeEx::CAP_TYPE_EX_HARDWARE_VERSION] = msgSupportGetAll; m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_HARDWARE_VERSION] = [this](Msg msg, Capability& data)->Result { log_attr_access((int)CapTypeEx::CAP_TYPE_EX_HARDWARE_VERSION, (int)msg); - std::string ver(""); - GET_SANE_OPT(std::string, scanner_, ex_hardware_version, &ver, NULL, NULL, NULL); + std::vector all; + GET_SANE_OPT(std::string, scanner_, ex_hardware_version, NULL, &all); Str255 str; - strcpy(str.data(), ver.c_str()); + strcpy(str.data(), all[sane_opts::RANGE_POS_CURRENT].c_str()); data = Capability::createOneValue((CapType)CapTypeEx::CAP_TYPE_EX_HARDWARE_VERSION, str); return success(); }; @@ -2568,10 +2721,10 @@ void huagao_ds::init_support_caps(void) m_query[(CapType)CapTypeEx::CAP_TYPE_EX_IP] = msgSupportGetAll; m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_IP] = [this](Msg msg, Capability& data)->Result { log_attr_access((int)CapTypeEx::CAP_TYPE_EX_IP, (int)msg); - std::string ip(""); - GET_SANE_OPT(std::string, scanner_, ex_ip, &ip, NULL, NULL, NULL); + std::vector all; + GET_SANE_OPT(std::string, scanner_, ex_ip, NULL, &all); Str255 str; - strcpy(str.data(), ip.c_str()); + strcpy(str.data(), all[sane_opts::RANGE_POS_CURRENT].c_str()); data = Capability::createOneValue((CapType)CapTypeEx::CAP_TYPE_EX_IP, str); return success(); // CapSupGetAll(msg, data, str, str); }; @@ -2613,7 +2766,9 @@ void huagao_ds::init_support_caps_ex(void) log_attr_access((int)CAP_EX_SANE_##name, (int)msg); \ ctype now, init; \ std::vector all; \ - GET_SANE_OPT(ctype, scanner_, name, &now, &init, &all, NULL); \ + GET_SANE_OPT(ctype, scanner_, name, NULL, &all); \ + init = all[sane_opts::RANGE_POS_DEFAULT]; \ + now = all[sane_opts::RANGE_POS_CURRENT]; \ if (msg == Msg::Set || msg == Msg::Reset) \ { \ if (msg == Msg::Set) \ @@ -2623,7 +2778,13 @@ void huagao_ds::init_support_caps_ex(void) } \ int ret = SCANNER_ERR_OK; \ SET_SANE_OPT(ret, scanner_, name, &init); \ - return ret == SCANNER_ERR_OK ? success() : badValue(); \ + if(msg == Msg::Reset) \ + { \ + ttype v; \ + copy_type(v, init); \ + data = Capability::createOneValue((CapType)CAP_EX_SANE_##name, v); \ + } \ + return ret == SCANNER_ERR_OK ? success() : badValue(); \ } \ else if (msg == Msg::GetCurrent || msg == Msg::GetDefault) \ { \ @@ -2637,20 +2798,13 @@ void huagao_ds::init_support_caps_ex(void) } \ else \ { \ - ttype Now, Init, t; \ std::list vals; \ - UInt32 ni = 0, ii = 0, ind = 0; \ - copy_type(Now, now); \ - copy_type(Init, init); \ - for (auto& v : all) \ + UInt32 ni = distance(all, now), ii = distance(all, init); \ + for (size_t i = sane_opts::RANGE_POS_ENUM_BEGIN; i < all.size(); ++i) \ { \ - copy_type(t, v); \ + ttype t; \ + copy_type(t, all[i]); \ vals.push_back(t); \ - if (v == now) \ - ni = ind; \ - if (v == init) \ - ii = ind; \ - ind++; \ } \ data = Capability::createEnumeration((CapType)CAP_EX_SANE_##name, vals, ni, ii); \ return { ReturnCode::Success, ConditionCode::Success }; \ @@ -2663,7 +2817,12 @@ void huagao_ds::init_support_caps_ex(void) log_attr_access((int)CAP_EX_SANE_##name, (int)msg); \ ctype now, init, lower, upper, step; \ std::vector all; \ - GET_SANE_OPT_RANGE(ctype, scanner_, name, &now, &init, &lower, &upper, &step); \ + GET_SANE_OPT(ctype, scanner_, name, NULL, &all); \ + now = all[sane_opts::RANGE_POS_CURRENT]; \ + init = all[sane_opts::RANGE_POS_DEFAULT]; \ + lower = all[sane_opts::RANGE_POS_LOWER]; \ + upper = all[sane_opts::RANGE_POS_UPPER]; \ + step = all[sane_opts::RANGE_POS_STEP]; \ if (msg == Msg::Set || msg == Msg::Reset) \ { \ if (msg == Msg::Set) \ @@ -2673,7 +2832,13 @@ void huagao_ds::init_support_caps_ex(void) } \ int ret = SCANNER_ERR_OK; \ SET_SANE_OPT(ret, scanner_, name, &init); \ - return ret == SCANNER_ERR_OK ? success() : badValue(); \ + if(msg == Msg::Reset) \ + { \ + ttype v; \ + copy_type(v, init); \ + data = Capability::createOneValue((CapType)CAP_EX_SANE_##name, v); \ + } \ + return ret == SCANNER_ERR_OK ? success() : badValue(); \ } \ else if (msg == Msg::GetCurrent || msg == Msg::GetDefault) \ { \ @@ -2703,7 +2868,10 @@ void huagao_ds::init_support_caps_ex(void) m_caps[(CapType)CAP_EX_SANE_##name] = [this](Msg msg, Capability& data) -> Result { \ log_attr_access((int)CAP_EX_SANE_##name, (int)msg); \ ctype now, init; \ - GET_SANE_OPT(ctype, scanner_, name, &now, &init, NULL, NULL); \ + std::vector all; \ + GET_SANE_OPT(ctype, scanner_, name, NULL, &all); \ + now = all[sane_opts::RANGE_POS_CURRENT]; \ + init = all[sane_opts::RANGE_POS_DEFAULT]; \ if (msg == Msg::Set || msg == Msg::Reset) \ { \ if (msg == Msg::Set) \ @@ -2713,7 +2881,13 @@ void huagao_ds::init_support_caps_ex(void) } \ int ret = SCANNER_ERR_OK; \ SET_SANE_OPT(ret, scanner_, name, &init); \ - return ret == SCANNER_ERR_OK ? success() : badValue(); \ + if(msg == Msg::Reset) \ + { \ + ttype v; \ + copy_type(v, init); \ + data = Capability::createOneValue((CapType)CAP_EX_SANE_##name, v); \ + } \ + return ret == SCANNER_ERR_OK ? success() : badValue(); \ } \ else if (msg == Msg::GetCurrent || msg == Msg::GetDefault) \ { \ @@ -2754,7 +2928,7 @@ void huagao_ds::init_support_caps_ex(void) } \ else \ { \ - SET_SANE_CAP_ENUM(std::string, Str64, name) \ + SET_SANE_CAP_ENUM(std::string, Str255, name) \ } \ } \ else if(limit == VAL_LIMIT_RANGE) \ @@ -2772,7 +2946,39 @@ void huagao_ds::init_support_caps_ex(void) { \ if(type == VAL_TYPE_BOOL) \ { \ - SET_SANE_CAP(bool, BYTE, name) \ + m_query[(CapType)CAP_EX_SANE_##name] = msgSupportGetAllSetReset; \ + m_caps[(CapType)CAP_EX_SANE_##name] = [this](Msg msg, Capability& data) -> Result { \ + log_attr_access((int)CAP_EX_SANE_##name, (int)msg); \ + std::vector all; \ + bool now = false, init = false; \ + GET_SANE_OPT(bool, scanner_, name, NULL, &all); \ + now = all[sane_opts::RANGE_POS_CURRENT]; \ + init = all[sane_opts::RANGE_POS_DEFAULT]; \ + if (msg == Msg::Set || msg == Msg::Reset) \ + { \ + if (msg == Msg::Set) \ + init = (bool)data.currentItem(); \ + int ret = SCANNER_ERR_OK; \ + SET_SANE_OPT(ret, scanner_, name, &init); \ + return ret == SCANNER_ERR_OK ? success() : badValue(); \ + } \ + else if (msg == Msg::GetCurrent || msg == Msg::GetDefault) \ + { \ + Bool t; \ + if(msg == Msg::GetCurrent) \ + t = now; \ + else \ + t = init; \ + data = Capability::createOneValue((CapType)CAP_EX_SANE_##name, t); \ + return { ReturnCode::Success, ConditionCode::Success }; \ + } \ + else \ + { \ + UInt32 ni = now ? 1 : 0, ii = init ? 1 : 0; \ + data = Capability::createEnumeration((CapType)CAP_EX_SANE_##name, { FALSE, TRUE }, ni, ii); \ + return { ReturnCode::Success, ConditionCode::Success }; \ + } \ + }; \ } \ else if(type == VAL_TYPE_INT) \ { \ diff --git a/twain/twain/huagaods.hpp b/twain/twain/huagaods.hpp index e6156b0..4a96d96 100644 --- a/twain/twain/huagaods.hpp +++ b/twain/twain/huagaods.hpp @@ -104,6 +104,7 @@ protected: virtual Twpp::Result userInterfaceDisable(const Twpp::Identity& origin, Twpp::UserInterface& data) override; virtual Twpp::Result userInterfaceEnable(const Twpp::Identity& origin, Twpp::UserInterface& data) override; virtual Twpp::Result userInterfaceEnableUiOnly(const Twpp::Identity& origin, Twpp::UserInterface& data) override; + virtual Twpp::Result extImageInfoGet(const Twpp::Identity& origin, Twpp::ExtImageInfo& data) override; virtual Twpp::Result imageInfoGet(const Twpp::Identity& origin, Twpp::ImageInfo& data) override; virtual Twpp::Result imageLayoutGet(const Twpp::Identity& origin, Twpp::ImageLayout& data) override; virtual Twpp::Result imageLayoutGetDefault(const Twpp::Identity& origin, Twpp::ImageLayout& data) override; diff --git a/twain/twain/twpp/capability.hpp b/twain/twain/twpp/capability.hpp index 6c96bb2..6f08b43 100644 --- a/twain/twain/twpp/capability.hpp +++ b/twain/twain/twpp/capability.hpp @@ -1638,6 +1638,11 @@ public: return m_cap; } + /// dangerous set CapType + void dangerous_set_cap(CapType cap) { + m_cap = cap; + } + /// Container type. ConType container() const noexcept{ return m_conType; diff --git a/twain/twain/twpp/extimageinfo.hpp b/twain/twain/twpp/extimageinfo.hpp index 3fb452f..f2a3246 100644 --- a/twain/twain/twpp/extimageinfo.hpp +++ b/twain/twain/twpp/extimageinfo.hpp @@ -418,14 +418,14 @@ public: /// are required to fill data in existing instance. /// \param ids List of requested info IDs to be filled in by the source. ExtImageInfo(std::initializer_list ids) : - m_data(new char[sizeof(Detail::ExtImageInfoData) - sizeof(Info) + ids.size() * sizeof(Info)]()){ + m_data(new char[sizeof(Detail::ExtImageInfoData) - sizeof(Info) + ids.size() * sizeof(Info)]()) { d()->m_numInfos = static_cast(ids.size()); Info* infos = d()->m_infos; UInt32 i = 0; - for (auto id : ids){ + for (auto id : ids) { auto& info = infos[i]; i++; @@ -433,6 +433,21 @@ public: info.m_itemType = Type::DontCare; } } + void set_data(const std::list& ids) noexcept { + m_data.reset(new char[sizeof(Detail::ExtImageInfoData) - sizeof(Info) + ids.size() * sizeof(Info)]); + + d()->m_numInfos = static_cast(ids.size()); + + Info* infos = d()->m_infos; + UInt32 i = 0; + for (const auto id : ids) { + auto& info = infos[i]; + i++; + + info.m_infoId = id; + info.m_itemType = Type::DontCare; + } + } ExtImageInfo(ExtImageInfo&&) = default; ExtImageInfo& operator=(ExtImageInfo&&) = default;