SANE不可见属性,在TWAIN中可见

This commit is contained in:
gb 2023-09-23 16:07:23 +08:00
parent f3326d973a
commit 7d0998924a
10 changed files with 134 additions and 43 deletions

File diff suppressed because one or more lines are too long

View File

@ -15,12 +15,6 @@
#include "simple_logic.h" #include "simple_logic.h"
#include <json/gb_json.h> #include <json/gb_json.h>
enum opt_visible_level // "visible" field
{
OPT_VISIBLE_ALL = 0, // visible on ui and accessible
OPT_VISIBLE_ACCESS, // accessible only
OPT_VISIBLE_HIDE, // invisible and inaccessible unless user has DEVELOPE privilege
};
class device_option class device_option
{ {

View File

@ -12,7 +12,7 @@
#include "user.h" #include "user.h"
static std::string device_opt_json[] = { static std::string device_opt_json[] = {
"{\"company\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u5236\\u9020\\u5546\",\"desc\":\"\\u8bbe\\u5907\\u5236\\u9020\\u5546\",\"ver\":0,\"pos\":0,\"fix-id\":34891,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"copyright\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u7248\\u672c\\u4fe1\\u606f\",\"desc\":\"\\u7248\\u6743\\u58f0\\u660e\\u7b49\\u4fe1\\u606f\",\"ver\":0,\"pos\":0,\"fix-id\":34892,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-url\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8\\u7f51\\u5740\",\"desc\":\"\\u516c\\u53f8\\u5b98\\u7f51\\u6216\\u552e\\u540e\\u670d\\u52a1\\u7f51\\u7ad9\\u5730\\u5740\",\"ver\":0,\"pos\":0,\"fix-id\":34893,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-tel\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8\\u7535\\u8bdd\",\"desc\":\"\\u516c\\u53f8\\u8054\\u7cfb\\u7535\\u8bdd\",\"ver\":0,\"pos\":0,\"fix-id\":34894,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":129,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-addr\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8\\u5730\\u5740\",\"desc\":\"\\u516c\\u53f8\\u5730\\u5740\",\"ver\":0,\"pos\":0,\"fix-id\":34895,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-gps\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8GPS\",\"desc\":\"\\u516c\\u53f8\\u5730\\u56fe\\u5730\\u5740\",\"ver\":0,\"pos\":0,\"fix-id\":34896,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"drv-ver\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u9a71\\u52a8\\u7248\\u672c\\u53f7\",\"desc\":\"PC\\u7aef\\u9a71\\u52a8\\u7a0b\\u5e8f\\u7248\\u672c\",\"ver\":0,\"pos\":0,\"fix-id\":34890,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":48,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"login\":{\"cat\":\"advanced\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u767b\\u5f55\",\"desc\":\"\\u7528\\u6237\\u767b\\u5f55\\u64cd\\u4f5c\",\"ver\":0,\"pos\":0,\"fix-id\":39168,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":64,\"auto\":false,\"cur\":\"false\",\"default\":\"false\"},\"logout\":{\"cat\":\"advanced\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u767b\\u51fa\",\"desc\":\"\\u7528\\u6237\\u767b\\u51fa\\u64cd\\u4f5c\",\"ver\":0,\"pos\":0,\"fix-id\":39169,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":64,\"auto\":false,\"cur\":\"false\",\"default\":\"false\"},\"drv-log\":{\"cat\":\"advanced\",\"group\":\"\\u9ad8\\u7ea7\\u8bbe\\u7f6e\",\"title\":\"\\u9a71\\u52a8\\u65e5\\u5fd7\",\"desc\":\"PC\\u7aef\\u9a71\\u52a8\\u5de5\\u4f5c\\u65e5\\u5fd7\",\"ver\":0,\"pos\":0,\"fix-id\":39171,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"}}" "{\"company\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u5236\\u9020\\u5546\",\"desc\":\"\\u8bbe\\u5907\\u5236\\u9020\\u5546\",\"ver\":0,\"pos\":0,\"fix-id\":34891,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"copyright\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u7248\\u672c\\u4fe1\\u606f\",\"desc\":\"\\u7248\\u6743\\u58f0\\u660e\\u7b49\\u4fe1\\u606f\",\"ver\":0,\"pos\":0,\"fix-id\":34892,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-url\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8\\u7f51\\u5740\",\"desc\":\"\\u516c\\u53f8\\u5b98\\u7f51\\u6216\\u552e\\u540e\\u670d\\u52a1\\u7f51\\u7ad9\\u5730\\u5740\",\"ver\":0,\"pos\":0,\"fix-id\":34893,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-tel\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8\\u7535\\u8bdd\",\"desc\":\"\\u516c\\u53f8\\u8054\\u7cfb\\u7535\\u8bdd\",\"ver\":0,\"pos\":0,\"fix-id\":34894,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":129,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-addr\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8\\u5730\\u5740\",\"desc\":\"\\u516c\\u53f8\\u5730\\u5740\",\"ver\":0,\"pos\":0,\"fix-id\":34895,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-gps\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8GPS\",\"desc\":\"\\u516c\\u53f8\\u5730\\u56fe\\u5730\\u5740\",\"ver\":0,\"pos\":0,\"fix-id\":34896,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"drv-ver\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u9a71\\u52a8\\u7248\\u672c\\u53f7\",\"desc\":\"PC\\u7aef\\u9a71\\u52a8\\u7a0b\\u5e8f\\u7248\\u672c\",\"ver\":0,\"pos\":0,\"fix-id\":34890,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":48,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"login\":{\"cat\":\"advanced\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u767b\\u5f55\",\"desc\":\"\\u7528\\u6237\\u767b\\u5f55\\u64cd\\u4f5c\",\"ver\":0,\"pos\":0,\"fix-id\":39168,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"visible\":1,\"size\":64,\"auto\":false,\"cur\":\"false\",\"default\":\"false\"},\"logout\":{\"cat\":\"advanced\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u767b\\u51fa\",\"desc\":\"\\u7528\\u6237\\u767b\\u51fa\\u64cd\\u4f5c\",\"ver\":0,\"pos\":0,\"fix-id\":39169,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"visible\":1,\"size\":64,\"auto\":false,\"cur\":\"false\",\"default\":\"false\"},\"drv-log\":{\"cat\":\"advanced\",\"group\":\"\\u9ad8\\u7ea7\\u8bbe\\u7f6e\",\"title\":\"\\u9a71\\u52a8\\u65e5\\u5fd7\",\"desc\":\"PC\\u7aef\\u9a71\\u52a8\\u5de5\\u4f5c\\u65e5\\u5fd7\",\"ver\":0,\"pos\":0,\"fix-id\":39171,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"visible\":1,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"}}"
}; };
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -798,6 +798,14 @@ SANE_Status hg_sane_middleware::control_option(SANE_Handle h, const void* option
{ {
err = get_option_fixed_id(inst, option, value); err = get_option_fixed_id(inst, option, value);
} }
else if (action == SANE_ACTION_ENUM_INVISIBLE_FIX_ID)
{
struct _fix_id_cb* fcb = (struct _fix_id_cb*)value;
if (!inst->opts->enum_invisible_fix_ids(fcb) && inst != offline_)
offline_->opts->enum_invisible_fix_ids(fcb);
err = SANE_STATUS_GOOD;
}
return err; return err;
} }

View File

@ -7,7 +7,7 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// sane_opt // sane_opt
sane_opt::sane_opt() : fix_id_(-1), sn_(0), enabled_(true) sane_opt::sane_opt() : fix_id_(-1), enabled_(true), visible_(true)
{ {
memset(&opt_desc_, 0, sizeof(opt_desc_)); memset(&opt_desc_, 0, sizeof(opt_desc_));
} }
@ -35,7 +35,6 @@ void sane_opt::clear()
} }
memset(&opt_desc_, 0, sizeof(opt_desc_)); memset(&opt_desc_, 0, sizeof(opt_desc_));
fix_id_ = -1; fix_id_ = -1;
sn_ = 0;
enabled_ = true; enabled_ = true;
} }
void sane_opt::set_opt_desc_string_value(char** buf, const char* val) void sane_opt::set_opt_desc_string_value(char** buf, const char* val)
@ -73,6 +72,12 @@ void sane_opt::init_cap(gb_json* jsn)
if (cat == "advanced") if (cat == "advanced")
opt_desc_.cap |= SANE_CAP_ADVANCED; opt_desc_.cap |= SANE_CAP_ADVANCED;
} }
int visb = 0;
if (jsn->get_value("visible", visb))
{
visible_ = visb == OPT_VISIBLE_ALL;
}
} }
void sane_opt::init_range(gb_json* jsn) void sane_opt::init_range(gb_json* jsn)
{ {
@ -193,10 +198,6 @@ int sane_opt::get_fix_id(void)
{ {
return fix_id_; return fix_id_;
} }
int sane_opt::get_sn(void)
{
return sn_;
}
SANE_Option_Descriptor* sane_opt::get_descriptor(void) SANE_Option_Descriptor* sane_opt::get_descriptor(void)
{ {
return &opt_desc_; return &opt_desc_;
@ -209,8 +210,13 @@ bool sane_opt::is_enabled(void)
{ {
return enabled_; return enabled_;
} }
bool sane_opt::is_visible(void)
{
return visible_;
}
bool sane_opt::from_json_text(int sn, const char* key, const char* json, void(*err_msg)(const char*))
bool sane_opt::from_json_text(const char* key, const char* json, void(*err_msg)(const char*))
{ {
bool ret = false; bool ret = false;
std::string text(json); std::string text(json);
@ -218,7 +224,6 @@ bool sane_opt::from_json_text(int sn, const char* key, const char* json, void(*e
char *buf = nullptr; char *buf = nullptr;
clear(); clear();
sn_ = sn;
while (jsn->attach_text(&text[0])) while (jsn->attach_text(&text[0]))
{ {
jsn->get_value("fix-id", fix_id_); jsn->get_value("fix-id", fix_id_);
@ -321,12 +326,17 @@ device_opts::~device_opts()
void device_opts::clear(void) void device_opts::clear(void)
{ {
std::vector<sane_opt*> tofree;
for (auto& v : opts_) for (auto& v : opts_)
{ {
if(v.first == v.second->get_sn()) // fix-id has the same object, we delete object at it's option number if (std::find(tofree.begin(), tofree.end(), v.second) == tofree.end())
delete v.second; tofree.push_back(v.second);
} }
for (auto& v : tofree)
delete v;
tofree.clear();
opts_.clear(); opts_.clear();
opt_cnt_ = 0; opt_cnt_ = 0;
} }
@ -336,7 +346,7 @@ bool device_opts::init_from(const char* jsn_text/*all options*/, void(*err_msg)(
bool ret = false; bool ret = false;
gb_json* jsn = new gb_json(); gb_json* jsn = new gb_json();
std::string str(jsn_text); std::string str(jsn_text);
int sn = 1; int sn = 0;
clear(); clear();
if (jsn->attach_text(&str[0])) if (jsn->attach_text(&str[0]))
@ -347,7 +357,8 @@ bool device_opts::init_from(const char* jsn_text/*all options*/, void(*err_msg)(
while (child) while (child)
{ {
str = std::move(child->to_string()); str = std::move(child->to_string());
ret = add_or_replace_opt(sn++, child->key().c_str(), str.c_str(), err_msg); sn++;
ret = add_or_replace_opt(sn, child->key().c_str(), str.c_str(), err_msg);
if (!ret) if (!ret)
{ {
child->release(); child->release();
@ -362,26 +373,33 @@ bool device_opts::init_from(const char* jsn_text/*all options*/, void(*err_msg)(
return ret; return ret;
} }
bool device_opts::add_or_replace_opt(int sn, const char* name, const char* jsn_text, void(*err_msg)(const char*)) bool device_opts::add_or_replace_opt(int& sn, const char* name, const char* jsn_text, void(*err_msg)(const char*))
{ {
if (opts_.count(sn)) if (opts_.count(sn))
{ {
bool en = opts_[sn]->is_enabled(), bool en = opts_[sn]->is_enabled(),
ret = opts_[sn]->from_json_text(sn, name, jsn_text, err_msg); ret = opts_[sn]->from_json_text(name, jsn_text, err_msg);
return ret; return ret;
} }
sane_opt* opt = new sane_opt(); sane_opt* opt = new sane_opt();
if (opt->from_json_text(sn, name, jsn_text, err_msg)) if (opt->from_json_text(name, jsn_text, err_msg))
{
if (opt->is_visible())
{ {
opts_[sn] = opt; opts_[sn] = opt;
if (opt->get_fix_id() != -1) opt_cnt_++;
}
else
sn--;
if (opt->get_fix_id() > SANE_OPT_ID_BASE)
{ {
opts_[opt->get_fix_id()] = opt; opts_[opt->get_fix_id()] = opt;
} }
opt_cnt_++; else if (!opt->is_visible()) // no fix-id and SANE_Int number will not be existence
delete opt;
return true; return true;
} }
@ -436,3 +454,21 @@ int device_opts::get_option_count(void)
{ {
return opt_cnt_; return opt_cnt_;
} }
bool device_opts::enum_invisible_fix_ids(struct _fix_id_cb* fcb) // return whether the callback stopped the enumeration
{
bool stopped = false;
for (auto& v : opts_)
{
if (!v.second->is_visible())
{
if (!fcb->cb(v.second->get_fix_id(), fcb->param))
{
stopped = true;
break;
}
}
}
return stopped;
}

View File

@ -20,8 +20,8 @@ class gb_json;
class sane_opt class sane_opt
{ {
int fix_id_; int fix_id_;
int sn_;
bool enabled_; bool enabled_;
bool visible_;
SANE_Option_Descriptor opt_desc_; SANE_Option_Descriptor opt_desc_;
@ -36,24 +36,24 @@ public:
public: public:
int get_fix_id(void); int get_fix_id(void);
int get_sn(void);
SANE_Option_Descriptor* get_descriptor(void); SANE_Option_Descriptor* get_descriptor(void);
const char* name(void); const char* name(void);
bool is_enabled(void); bool is_enabled(void);
bool is_visible(void);
bool from_json_text(int sn, const char* key, const char* json, void(*err_msg)(const char*) = nullptr); bool from_json_text(const char* key, const char* json, void(*err_msg)(const char*) = nullptr);
}; };
class device_opts class device_opts
{ {
std::map<int, sane_opt*> opts_; std::map<int, sane_opt*> opts_; // SANE_Int && fix-id point the same object. SANE_Int is visible and accessible, only accessible by fix-id if without SANE_Int
int opt_cnt_; int opt_cnt_; // count for visible options
SANE_Option_Descriptor opt_0_; SANE_Option_Descriptor opt_0_;
void clear(void); void clear(void);
bool add_or_replace_opt(int sn, const char* name, const char* jsn_text, void(*err_msg)(const char*)); bool add_or_replace_opt(int& sn, const char* name, const char* jsn_text, void(*err_msg)(const char*));
public: public:
device_opts(); device_opts();
@ -63,4 +63,5 @@ public:
bool init_from(const char* jsn_text/*all options*/, void(*err_msg)(const char*)); bool init_from(const char* jsn_text/*all options*/, void(*err_msg)(const char*));
SANE_Option_Descriptor* get_opt_descriptor(const void* opt, int* fix_id = nullptr, int ind_base = 0); SANE_Option_Descriptor* get_opt_descriptor(const void* opt, int* fix_id = nullptr, int ind_base = 0);
int get_option_count(void); int get_option_count(void);
bool enum_invisible_fix_ids(struct _fix_id_cb* fcb); // return whether the callback stopped the enumeration
}; };

View File

@ -765,11 +765,11 @@ static void log_attr_access(int attr, int method)
// get fixed-ids from SANE option ... // get fixed-ids from SANE option ...
static bool got_fixed_id(uint32_t id, void* param) static SANE_Bool got_fixed_id(int id, void* param)
{ {
((std::vector<uint32_t>*)param)->push_back(id); ((std::vector<uint32_t>*)param)->push_back(id);
return true; return SANE_TRUE;
} }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -196,7 +196,7 @@ public:
// //
// bytes - *type 为 VAL_TYPE_STR时需要的最小空间字节数 // bytes - *type 为 VAL_TYPE_STR时需要的最小空间字节数
COM_API_DECLARE(bool, get_option_info(int sn, value_type* type, value_limit* limit, int *bytes, bool* readonly)); COM_API_DECLARE(bool, get_option_info(int sn, value_type* type, value_limit* limit, int *bytes, bool* readonly));
COM_API_DECLARE(int, get_fixed_ids(bool(* cb)(uint32_t id, void* param), void* param)); COM_API_DECLARE(int, get_fixed_ids(SANE_Bool(* cb)(int id, void* param), void* param));
COM_API_DECLARE(bool, get_value(int sn, set_opt_value func, void* param)); COM_API_DECLARE(bool, get_value(int sn, set_opt_value func, void* param));
COM_API_DECLARE(bool, get_value(int sn, void* data, int* len)); // get operation with in-parameter COM_API_DECLARE(bool, get_value(int sn, void* data, int* len)); // get operation with in-parameter

View File

@ -318,6 +318,12 @@ namespace callback
hui = nullptr; hui = nullptr;
} }
} }
static SANE_Bool get_invisible_fix_id(int id, void* param)
{
((std::vector<int>*)param)->push_back(id);
return SANE_TRUE;
}
} }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -657,6 +663,33 @@ int scanner::init_options_id(void)
} }
} }
// invisible option in SANE
{
std::vector<int> inv;
struct _fix_id_cb fcb;
fcb.cb = callback::get_invisible_fix_id;
fcb.param = &inv;
sane_helper_->invoke_sane_control_option(handle_, SANE_OPT_ID_BASE, (SANE_Action)SANE_ACTION_ENUM_INVISIBLE_FIX_ID, &fcb, nullptr);
for (auto& v : inv)
{
desc = sane_helper_->invoke_sane_get_option_descriptor(handle_, v);
if (desc)
{
SANEOPT opt;
opt.opt_sn = v;
if (desc->type == SANE_TYPE_BOOL) // bool to enumeration constraint
opt.limit = VAL_LIMIT_ENUM;
else
opt.limit = scanner::from_sane_constraint(desc->constraint_type);
opt.type = scanner::from_sane_type(desc->type);
opt.size = desc->size;
opt.cap = desc->cap;
sane_opts_[v] = opt;
}
}
}
return ret; return ret;
} }
char* scanner::get_opt_value(int id, int size, bool def_val) char* scanner::get_opt_value(int id, int size, bool def_val)
@ -1089,10 +1122,19 @@ COM_API_IMPLEMENT(scanner, bool, get_option_info(int sn, value_type* type, value
} }
COM_API_IMPLEMENT(scanner, bool, get_value(int sn, set_opt_value setval, void* param)) COM_API_IMPLEMENT(scanner, bool, get_value(int sn, set_opt_value setval, void* param))
{ {
const SANE_Option_Descriptor* desc = sane_helper_->invoke_sane_get_option_descriptor(handle_, sn);
if (desc)
utils::to_log(LOG_LEVEL_DEBUG, "get_value(0x%04X - %s) ...\r\n", sn, desc->name);
else
{
utils::to_log(LOG_LEVEL_WARNING, "get_value(0x%04X, ...), but the option is not found !!!\r\n", sn);
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
}
if (get_option_value_with_parent(sn, setval, param)) if (get_option_value_with_parent(sn, setval, param))
return true; return true;
const SANE_Option_Descriptor* desc = sane_helper_->invoke_sane_get_option_descriptor(handle_, sn);
char* init = get_opt_value(sn, desc->size, true), char* init = get_opt_value(sn, desc->size, true),
* now = get_opt_value(sn, desc->size, false); * now = get_opt_value(sn, desc->size, false);
int ret = SANE_STATUS_GOOD; int ret = SANE_STATUS_GOOD;
@ -1213,8 +1255,13 @@ COM_API_IMPLEMENT(scanner, int, set_value(int sn, void* val))
SANE_Int after = 0; SANE_Int after = 0;
const SANE_Option_Descriptor* desc = sane_helper_->invoke_sane_get_option_descriptor(handle_, sn); const SANE_Option_Descriptor* desc = sane_helper_->invoke_sane_get_option_descriptor(handle_, sn);
{ if (desc)
utils::to_log(LOG_LEVEL_DEBUG, "set_value(0x%04X - %s, '%s') ...\r\n", sn, desc->name, callback::option_value_2_string(desc->type, val).c_str()); utils::to_log(LOG_LEVEL_DEBUG, "set_value(0x%04X - %s, '%s') ...\r\n", sn, desc->name, callback::option_value_2_string(desc->type, val).c_str());
else
{
utils::to_log(LOG_LEVEL_WARNING, "set_value(0x%04X, ...), but the option is not found !!!\r\n", sn);
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
} }
twain_set_ = true; twain_set_ = true;
@ -1227,13 +1274,18 @@ COM_API_IMPLEMENT(scanner, int, convert_image(SANE_ImageFormatConvert* conv))
{ {
return sane_helper_->invoke_sane_control_option(handle_, SANE_OPT_ID_TRANSFORM_IMAGE_FORMAT, SANE_ACTION_SET_VALUE, conv, nullptr); return sane_helper_->invoke_sane_control_option(handle_, SANE_OPT_ID_TRANSFORM_IMAGE_FORMAT, SANE_ACTION_SET_VALUE, conv, nullptr);
} }
COM_API_IMPLEMENT(scanner, int, get_fixed_ids(bool(* cb)(uint32_t id, void* param), void* param)) COM_API_IMPLEMENT(scanner, int, get_fixed_ids(SANE_Bool(* cb)(int id, void* param), void* param))
{ {
bool stopped = false;
for (auto& v : sane_opts_) for (auto& v : sane_opts_)
{ {
if (!cb(v.first, param)) if (!cb(v.first, param))
{
stopped = true;
break; break;
} }
}
return 0; return 0;
} }

View File

@ -165,7 +165,7 @@ public:
COM_API_OVERRIDE(int, twain_set_config(char* buf, size_t len)); COM_API_OVERRIDE(int, twain_set_config(char* buf, size_t len));
COM_API_OVERRIDE(bool, get_option_info(int sn, value_type* type, value_limit* limit, int* bytes, bool* readonly)); COM_API_OVERRIDE(bool, get_option_info(int sn, value_type* type, value_limit* limit, int* bytes, bool* readonly));
COM_API_OVERRIDE(int, get_fixed_ids(bool(*cb)(uint32_t id, void* param), void* param)); COM_API_OVERRIDE(int, get_fixed_ids(SANE_Bool(*cb)(int id, void* param), void* param));
COM_API_OVERRIDE(bool, get_value(int sn, set_opt_value func, void* param)); // get all values COM_API_OVERRIDE(bool, get_value(int sn, set_opt_value func, void* param)); // get all values
COM_API_OVERRIDE(bool, get_value(int sn, void* data, int* len)); // get current value COM_API_OVERRIDE(bool, get_value(int sn, void* data, int* len)); // get current value