扫描仪事件处理不只依赖于eventProcess,增加回调方式;处理好分数调用流程

This commit is contained in:
gb 2022-10-21 16:46:20 +08:00
parent 84e0b6996d
commit eeeb3214f4
4 changed files with 220 additions and 25 deletions

View File

@ -147,9 +147,10 @@ struct __declspec(novtable) IScanImg : public IRef
};
struct __declspec(novtable) ISaneInvoker : public IRef
{
COM_API_DECLARE(int, start(int(__stdcall* handle_ev)(int, void*) = NULL, void* para = NULL));
COM_API_DECLARE(int, start(void));
COM_API_DECLARE(int, stop(void));
COM_API_DECLARE(int, get_event(void));
COM_API_DECLARE(void, set_event_callback(int(__stdcall* handle_ev)(int, void*) = NULL, void* para = NULL));
COM_API_DECLARE(bool, wait_image(DWORD milliseconds = -1));
COM_API_DECLARE(int, get_scanned_images(DWORD milliseconds = 0));
COM_API_DECLARE(IScanImg*, take_first_image(twain_xfer xfer = TWAIN_XFER_Native)); // call 'release' on returned value, plz

View File

@ -15,7 +15,6 @@
#pragma comment(lib, "Shlwapi.lib")
static IMPLEMENT_OPTION_STRING_COMPARE(compare_sane_opt);
#define SET_SANE_OPT_ID(id, id_name, name, val, extension) \
@ -55,6 +54,7 @@ extern "C"
extern SANE_Status inner_sane_init_ex(SANE_Int* version_code, sane_callback cb, void* param);
extern SANE_Status inner_sane_io_control(SANE_Handle h, unsigned long code, void* data, unsigned* len);
extern const char* inner_sane_err_desc(SANE_Status err);
}
namespace callback
@ -229,6 +229,91 @@ namespace callback
return "";
}
static BOOL CALLBACK main_wnd(HWND hwnd, LPARAM param)
{
DWORD pid = 0;
GetWindowThreadProcessId(hwnd, &pid);
if (pid != GetCurrentProcessId())
return TRUE;
if (((void**)param)[1] == NULL)
{
HWND parent = GetParent(hwnd);
while (IsWindow(parent))
{
hwnd = parent;
parent = GetParent(hwnd);
}
parent = hwnd;
if (!IsWindowVisible(parent))
return TRUE;
RECT r = { 0 };
GetWindowRect(parent, &r);
if (RECT_H(r) > 50 && RECT_W(r) > 50)
{
*(HWND*)param = parent;
return FALSE;
}
}
else
{
wchar_t val[128] = { 0 };
GetClassNameW(hwnd, val, _countof(val) - 1);
if (wcscmp(val, L"#32770"))
return TRUE;
GetWindowTextW(hwnd, val, _countof(val) - 1);
if (*((std::wstring**)param)[1] == val)
{
*(HWND*)param = hwnd;
return FALSE;
}
}
return TRUE;
}
static HWND find_main_wnd(void)
{
HWND wnd[2] = { NULL };
EnumWindows(main_wnd, (LPARAM)wnd);
return wnd[0];
}
static DWORD WINAPI btm(LPVOID para)
{
std::wstring* title[2] = { NULL, (std::wstring*)para };
Sleep(100);
EnumWindows(main_wnd, (LPARAM)title);
if (IsWindow((HWND)title[0]))
{
RECT r = { 0 };
GetWindowRect((HWND)title[0], &r);
SetWindowPos((HWND)title[0], HWND_TOPMOST, r.left, r.top, RECT_W(r), RECT_H(r), SWP_SHOWWINDOW | SWP_NOSENDCHANGING);
SetFocus((HWND)title[0]);
}
delete title[1];
return 0;
}
static void bring_message_box_topmost(const wchar_t* title)
{
DWORD id = 0;
std::wstring* t(new std::wstring(title));
HANDLE h = CreateThread(NULL, 0, btm, t, 0, &id);
if (h)
CloseHandle(h);
else
delete t;
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -236,6 +321,7 @@ namespace callback
scanner::scanner(SCANNERID id) : handle_(NULL), id_(id), ex_id_(EXTENSION_ID_BASE), prev_start_result_(SCANNER_ERR_NOT_START)
, dpi_(200), tmp_path_(L""), img_ind_(0)
, scanner_name_(L""), cfg_(NULL), is_ui_wait_img_(false), is_scanning_(false)
, scanner_ev_handler_(NULL), evh_param_(NULL), app_wnd_(NULL)
{
cfg_ = new gb::sane_config();
tmp_path_ = local_trans::a2u(hg_sane_middleware::sane_path().c_str());
@ -463,7 +549,9 @@ void scanner::update_config(void)
notice.erase(0, pos + 2);
pos = notice.find("\r\n");
}
MessageBoxW(NULL, msg.c_str(), L"\u52A0\u8F7D\u914D\u7F6E", MB_OK | MB_ICONINFORMATION);
if (!IsWindow(app_wnd_))
callback::bring_message_box_topmost(L"\u52A0\u8F7D\u914D\u7F6E");
MessageBoxW(app_wnd_, msg.c_str(), L"\u52A0\u8F7D\u914D\u7F6E", MB_OK | MB_ICONINFORMATION);
}
}
void scanner::load_config(const wchar_t* file)
@ -533,11 +621,25 @@ void scanner::apply_config(void)
}
void scanner::on_ui_event(int uev, void* sender)
{
int(__stdcall * h)(int, void*) = scanner_ev_handler_;
if (h)
{
h(uev, evh_param_);
return;
}
bool indicator = sender == indicator_.get();
if (prev_start_result_ != SANE_STATUS_GOOD && indicator)
indicator_.reset();
else
{
if (uev == SANE_EVENT_UI_SCAN_COMMAND)
{
ui_show_progress(NULL);
start();
return;
}
if (/*events_.count() > 5 && !is_ui_wait_img_ &&*/
(uev == SANE_EVENT_UI_CLOSE_CANCEL || uev == SANE_EVENT_UI_CLOSE_NORMAL || uev == SANE_EVENT_UI_CLOSE_SETTING))
{
@ -551,10 +653,6 @@ void scanner::on_ui_event(int uev, void* sender)
events_.save(uev);
}
int(__stdcall * h)(int, void*) = scanner_ev_handler_;
if (h)
h(uev, evh_param_);
}
std::string scanner::choose_scanner(const std::vector<std::string>& scanners)
{
@ -631,7 +729,11 @@ int scanner::open(void)
else
{
std::wstring msg(local_trans::a2u(hg_scanner_err_description(ret), CP_UTF8));
MessageBoxW(NULL, msg.c_str(), L"\u6253\u5F00\u5931\u8D25", MB_OK | MB_ICONERROR);
HWND parent = callback::find_main_wnd();
if (!IsWindow(parent))
callback::bring_message_box_topmost(L"\u6253\u5F00\u5931\u8D25");
MessageBoxW(parent, msg.c_str(), L"\u6253\u5F00\u5931\u8D25", MB_OK | MB_ICONERROR);
}
return ret;
@ -2025,17 +2127,15 @@ EX_OPTION_HANDLER_IMPL(search_hole_range)
}
// ISaneInvoker
COM_API_IMPLEMENT(scanner, int, start(int(__stdcall* handle_ev)(int, void*), void* para))
COM_API_IMPLEMENT(scanner, int, start(void))
{
int ret = SANE_STATUS_GOOD;
scanner_ev_handler_ = handle_ev;
evh_param_ = para;
events_.clear();
images_.clear();
scan_msg_ = "OK";
scan_err_ = false;
app_wnd_ = setting_.get() ? setting_->hwnd() : callback::find_main_wnd();
ret = hg_sane_middleware::instance()->start(handle_, NULL);
// the third-APPs in linux will call 'stop' after every start, but it not happens in windows-apps, so we handle this as following ...
@ -2060,10 +2160,12 @@ COM_API_IMPLEMENT(scanner, int, start(int(__stdcall* handle_ev)(int, void*), voi
else
{
std::wstring msg(local_trans::a2u(hg_scanner_err_description(ret), CP_UTF8));
HWND parent = setting_.get() ? setting_->hwnd() : NULL;
if (indicator_.get())
indicator_->show(false);
MessageBoxW(parent, msg.c_str(), L"\u542F\u52A8\u5931\u8D25", MB_OK | MB_ICONERROR);
if (!IsWindow(app_wnd_))
callback::bring_message_box_topmost(L"\u542F\u52A8\u5931\u8D25");
MessageBoxW(app_wnd_, msg.c_str(), L"\u542F\u52A8\u5931\u8D25", MB_OK | MB_ICONERROR);
}
prev_start_result_ = ret;
is_scanning_ = ret == SANE_STATUS_GOOD;
@ -2079,6 +2181,11 @@ COM_API_IMPLEMENT(scanner, int, get_event(void))
{
return events_.take();
}
COM_API_IMPLEMENT(scanner, void, set_event_callback(int(__stdcall* handle_ev)(int, void*), void* para))
{
scanner_ev_handler_ = handle_ev;
evh_param_ = para;
}
COM_API_IMPLEMENT(scanner, bool, wait_image(DWORD milliseconds))
{
int count = get_scanned_images(milliseconds);
@ -2553,6 +2660,8 @@ COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent))
{
if (setting_.get() && IsWindowVisible(setting_->hwnd()))
parent = setting_->hwnd();
else if (!IsWindow(parent))
parent = callback::find_main_wnd();
indicator_.reset(new dlg_indicator(parent));
indicator_->set_ui_event_notify(&scanner::ui_callback, this);
@ -2619,10 +2728,20 @@ int scanner::handle_device_event(int ev_code, void* data, unsigned int* len)
}
else if (ev_code == SANE_EVENT_SCAN_FINISHED)
{
err_ = *len;
if (indicator_.get())
indicator_->notify_scan_over((char*)data, *len != SCANNER_ERR_OK);
else
{
if (*len)
{
std::wstring msg(local_trans::a2u((char*)data, CP_UTF8));
if(!IsWindow(app_wnd_))
callback::bring_message_box_topmost(L"\u9519\u8BEF");
MessageBoxW(app_wnd_, msg.c_str(), L"\u9519\u8BEF", MB_OK);
}
on_ui_event(ev_code, (void*)ev_code);
}
is_scanning_ = false;
{

View File

@ -55,6 +55,7 @@ class scanner : public ISaneInvoker, virtual public refer
int(__stdcall* scanner_ev_handler_)(int, void*);
void* evh_param_;
HWND app_wnd_; // for MessageBox
void transport_config_file(void);
void update_config(void);
@ -204,9 +205,10 @@ public:
// ISaneInvoker
public:
COM_API_OVERRIDE(int, start(int(__stdcall* handle_ev)(int, void*) = NULL, void* para = NULL));
COM_API_OVERRIDE(int, start(void));
COM_API_OVERRIDE(int, stop(void));
COM_API_OVERRIDE(int, get_event(void));
COM_API_OVERRIDE(void, set_event_callback(int(__stdcall* handle_ev)(int, void*) = NULL, void* para = NULL));
COM_API_OVERRIDE(bool, wait_image(DWORD milliseconds = -1));
COM_API_OVERRIDE(int, get_scanned_images(DWORD milliseconds = 0));
COM_API_OVERRIDE(IScanImg*, take_first_image(twain_xfer xfer = TWAIN_XFER_Native)); // call 'release' on returned value, plz

View File

@ -604,7 +604,24 @@ float trans_range(float val, float min_from, float max_from, float min_to, float
return val;
}
static void log_attr_access(int attr, int method)
{
wchar_t msg[128] = { 0 };
const wchar_t* op = L"Unknown Oper";
#define METHOD_DESC(oper) \
if (method == (int)Msg::oper) \
op = L###oper;
METHOD_DESC(Set)
else METHOD_DESC(Reset)
else METHOD_DESC(Get)
else METHOD_DESC(GetCurrent)
else METHOD_DESC(GetDefault)
swprintf_s(msg, _countof(msg) - 1, L"%s %04x\r\n", op, attr);
load_sane_util::log_info(msg, 0);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// huagao_ds ...
@ -750,6 +767,7 @@ Result huagao_ds::eventProcess(const Identity&, Event& event)
{
int ev = scanner_->get_event();
if(ev)
handle_scanner_event(ev);
}
// event.setMessage(Msg::Null);
@ -808,6 +826,7 @@ Result huagao_ds::identityOpenDs(const Identity& id)
return { ReturnCode::Failure, huagao_ds::condition_code_from_hg_error(err) };
}
// ui_.reset(new twain_ui(local_utility::reg_get_app_installing_path().c_str()));
scanner_->set_event_callback(&huagao_ds::on_scanner_event, this);
if (get_config_number(L"twain-app", L"flow") == TWAIN_APP_TRANSFER_REVERSE)
{
cur_head_ = new SANE_Parameters;
@ -825,6 +844,7 @@ Result huagao_ds::identityCloseDs(const Identity&)
// ui_.reset();
if (scanner_.get())
{
scanner_->set_event_callback();
scanner_.reset();
}
if (singleton_)
@ -915,17 +935,16 @@ Result huagao_ds::userInterfaceEnable(const Identity&, UserInterface& ui)
if (m_bIndicator && !scanner_->ui_show_progress((HWND)ui.parent().raw()))
return seqError();
int(__stdcall * evf)(int, void*) = m_bIndicator ? NULL : &huagao_ds::on_scanner_event;
scanner_->twain_set_transfer((twain_xfer)m_capXferMech);
int err = scanner_->start(evf, this);
int err = scanner_->start();
if (err == SCANNER_ERR_OK)
{
return success();
}
else
{
if (err == SCANNER_ERR_DEVICE_NO_PAPER)
return { ReturnCode::Failure, ConditionCode::NoMedia };
// if (err == SCANNER_ERR_DEVICE_NO_PAPER)
return { ReturnCode::Failure, huagao_ds::condition_code_from_hg_error(err) };
return bummer();
}
@ -956,7 +975,7 @@ Result huagao_ds::imageInfoGet(const Identity&, ImageInfo& data)
if (!scanner_->wait_image())
{
notifyCloseOk();
return bummer();
return success(); // ºÃ·ÖÊýÐèÒª·µ»Ø³É¹¦
}
ok = scanner_->get_first_image_header(&head);
}
@ -1366,6 +1385,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::SupportedCaps] = msgSupportGetAll;
m_caps[CapType::SupportedCaps] = [this](Msg msg, Capability& data) {
log_attr_access((int)CapType::SupportedCaps, (int)msg);
if ((msg == Msg::Get) || (Msg::GetCurrent == msg) || (Msg::GetDefault == msg)) {
data = Capability::createArray<CapType::SupportedCaps>(m_caps.size());
auto arr = data.array<CapType::SupportedCaps>();
@ -1386,6 +1406,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::XferCount] = msgSupportGetAllSetReset;
m_caps[CapType::XferCount] = [this](Msg msg, Capability& data) -> Result {
log_attr_access((int)CapType::XferCount, (int)msg);
if (msg == Msg::Set) {
auto item = data.currentItem<Int16>();
if (item > 65535 || item < -1 || item == 0) {
@ -1411,6 +1432,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::Indicators] = msgSupportGetAllSetReset;
m_caps[CapType::Indicators] = [this](Msg msg, Capability& data) -> Result {
log_attr_access((int)CapType::Indicators, (int)msg);
if (Msg::Set == msg) {
auto show = data.currentItem<CapType::Indicators>();
m_bIndicator = show;
@ -1423,7 +1445,8 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::DeviceOnline] = msgSupportGetAll;
m_caps[CapType::DeviceOnline] = [this](Msg msg, Capability& data) -> Result {
CapabilityPrintf(msg, enum2str(CapType::DeviceOnline));
log_attr_access((int)CapType::DeviceOnline, (int)msg);
// CapabilityPrintf(msg, enum2str(CapType::DeviceOnline));
switch (msg) {
case Msg::Get:
case Msg::GetCurrent:
@ -1441,6 +1464,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::ICompression] = msgSupportGetAllSetReset;
m_caps[CapType::ICompression] = [this](Msg msg, Capability& data)->Result {
log_attr_access((int)CapType::ICompression, (int)msg);
if (!scanner_.get())
return seqError();
if (Msg::Set == msg) {
@ -1490,6 +1514,7 @@ 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<int> all;
GET_SANE_OPT(int, scanner_, ex_color_mode, &now, &init, &all, NULL);
@ -1532,6 +1557,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IXResolution] = msgSupportGetAllSetReset;
m_caps[CapType::IXResolution] = [this](Msg msg, Capability& data) {
log_attr_access((int)CapType::IXResolution, (int)msg);
if (!scanner_.get())
return seqError();
std::vector<int> values;
@ -1596,6 +1622,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::ISupportedSizes] = msgSupportGetAllSetReset;
m_caps[CapType::ISupportedSizes] = [this](Msg msg, Capability& data) {
log_attr_access((int)CapType::ISupportedSizes, (int)msg);
int now = 0,
init = 0;
std::vector<int> all;
@ -1624,6 +1651,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IPhysicalWidth] = msgSupportGetAll;
m_caps[CapType::IPhysicalWidth] = [this](Msg msg, Capability& data) -> Result {
log_attr_access((int)CapType::IPhysicalWidth, (int)msg);
switch (msg) {
case Msg::Get:
case Msg::GetCurrent:
@ -1645,6 +1673,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IPhysicalHeight] = msgSupportGetAll;
m_caps[CapType::IPhysicalHeight] = [this](Msg msg, Capability& data) -> Result {
log_attr_access((int)CapType::IPhysicalHeight, (int)msg);
switch (msg) {
case Msg::Get:
case Msg::GetCurrent:
@ -1669,6 +1698,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IXferMech] = msgSupportGetAllSetReset;
m_caps[CapType::IXferMech] = [this](Msg msg, Capability& data) -> Result {
log_attr_access((int)CapType::IXferMech, (int)msg);
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IXferMech>();
if (mech == XferMech::Native || mech == XferMech::Memory || mech == XferMech::File) {
@ -1690,6 +1720,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IPixelType] = msgSupportGetAllSetReset;
m_caps[CapType::IPixelType] = [this](Msg msg, Capability& data) -> Result {
log_attr_access((int)CapType::IPixelType, (int)msg);
if (!scanner_.get())
return seqError();
std::vector<int> values;
@ -1735,6 +1766,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IAutomaticColorEnabled] = msgSupportGetAllSetReset;
m_caps[CapType::IAutomaticColorEnabled] = [this](Msg msg, Capability& data)->Result {
log_attr_access((int)CapType::IAutomaticColorEnabled, (int)msg);
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IAutomaticColorEnabled>();
int ret = SCANNER_ERR_OK, val = mech ? COLOR_AUTO_MATCH : COLOR_RGB;
@ -1750,6 +1782,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IAutomaticColorNonColorPixelType] = msgSupportGetAllSetReset;
m_caps[CapType::IAutomaticColorNonColorPixelType] = [this](Msg msg, Capability& data)->Result {
log_attr_access((int)CapType::IAutomaticColorNonColorPixelType, (int)msg);
if (msg == Msg::Set) {
int mech = (int)data.currentItem<CapType::IAutomaticColorNonColorPixelType>();
//int now = 0;
@ -1774,6 +1807,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IJpegQuality] = msgSupportGetAllSetReset;
m_caps[CapType::IJpegQuality] = [this](Msg msg, Capability& data)->Result {
log_attr_access((int)CapType::IJpegQuality, (int)msg);
SANE_FinalImgFormat fif;
fif.img_format = SANE_IMAGE_TYPE_JPG;
if (Msg::Set == msg) {
@ -1800,6 +1834,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IOrientation] = msgSupportGetAllSetReset;
m_caps[CapType::IOrientation] = [this](Msg msg, Capability& data) -> Result {
log_attr_access((int)CapType::IOrientation, (int)msg);
CapabilityPrintf(msg, enum2str(CapTypeEx::IOrientation), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IOrientation>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IOrientation>();
@ -1816,6 +1851,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IRotation] = msgSupportGetAllSetReset;
m_caps[CapType::IRotation] = [this](Msg msg, Capability& data) -> Result {
log_attr_access((int)CapType::IRotation, (int)msg);
if (Msg::Set == msg) {
auto res = data.currentItem<Fix32>();
float angle = res.toFloat();
@ -1847,6 +1883,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::FeederEnabled] = msgSupportGetAllSetReset;
m_caps[CapType::FeederEnabled] = [this](Msg msg, Capability& data) -> Result {
log_attr_access((int)CapType::FeederEnabled, (int)msg);
CapabilityPrintf(msg, enum2str(CapType::FeederEnabled), msg == Msg::Set ? to_string((int)data.currentItem<CapType::FeederEnabled>()) : "");
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::FeederEnabled>();
@ -1861,6 +1898,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::DuplexEnabled] = msgSupportGetAllSetReset;
m_caps[CapType::DuplexEnabled] = [this](Msg msg, Capability& data) -> Result {
log_attr_access((int)CapType::DuplexEnabled, (int)msg);
if (Msg::Set == msg) {
bool mech = data.currentItem<CapType::DuplexEnabled>();
int ret = SCANNER_ERR_OK;
@ -1874,6 +1912,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::AutoFeed] = msgSupportGetAllSetReset;
m_caps[CapType::AutoFeed] = [this](Msg msg, Capability& data) -> Result {
log_attr_access((int)CapType::AutoFeed, (int)msg);
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::AutoFeed>();
m_bAutoFeed = mech;
@ -1884,6 +1923,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IImageFileFormat] = msgSupportGetAllSetReset;
m_caps[CapType::IImageFileFormat] = [this](Msg msg, Capability& data) -> Result {
log_attr_access((int)CapType::IImageFileFormat, (int)msg);
SANE_FinalImgFormat now, init;
std::vector<SANE_FinalImgFormat> all;
GET_SANE_OPT(SANE_FinalImgFormat, scanner_, ex_final_format, &now, &init, &all, NULL);
@ -1923,6 +1963,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IAutomaticDeskew] = msgSupportGetAllSetReset;
m_caps[CapType::IAutomaticDeskew] = [this](Msg msg, Capability& data)->Result {
log_attr_access((int)CapType::IAutomaticDeskew, (int)msg);
if (Msg::Set == msg) {
auto atuodsw = data.currentItem<CapType::IAutomaticDeskew>();
int ret = SCANNER_ERR_OK;
@ -1936,6 +1977,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IAutomaticRotate] = msgSupportGetAllSetReset;
m_caps[CapType::IAutomaticRotate] = [this](Msg msg, Capability& data)->Result {
log_attr_access((int)CapType::IAutomaticRotate, (int)msg);
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IAutomaticRotate>();
float direction = mech ? AUTO_MATIC_ROTATE : .0f;
@ -1952,6 +1994,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::SerialNumber] = msgSupportGetAll;
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);
@ -1961,6 +2004,7 @@ void huagao_ds::init_support_caps(void)
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<CapType::AutoScan>();
m_autoscan = autoscan;
@ -1973,6 +2017,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IAutoSize] = msgSupportGetAllSetReset;
m_caps[CapType::IAutoSize] = [this](Msg msg, Capability& data)->Result {
log_attr_access((int)CapType::IAutoSize, (int)msg);
CapabilityPrintf(msg, enum2str(CapType::IAutoSize), msg == Msg::Set ? to_string((int)data.currentItem<CapType::IAutoSize>()) : "");
if (Msg::Set == msg) {
auto autosize = data.currentItem<CapType::IAutoSize>();
@ -1989,6 +2034,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IAutomaticBorderDetection] = msgSupportGetAllSetReset;
m_caps[CapType::IAutomaticBorderDetection] = [this](Msg msg, Capability& data)->Result {
log_attr_access((int)CapType::IAutomaticBorderDetection, (int)msg);
if (Msg::Set == msg) {
auto autodetectborder = data.currentItem<CapType::IAutomaticBorderDetection>();
int ret = SCANNER_ERR_OK;
@ -2006,6 +2052,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IAutoDiscardBlankPages] = msgSupportGetAllSetReset;
m_caps[CapType::IAutoDiscardBlankPages] = [this](Msg msg, Capability& data)->Result {
log_attr_access((int)CapType::IAutoDiscardBlankPages, (int)msg);
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IAutoDiscardBlankPages>();
bool discard = mech == DiscardBlankPages::Auto;
@ -2021,6 +2068,7 @@ void huagao_ds::init_support_caps(void)
m_query[(CapType)CAP_TYPE_EX_DISCARD_BLANK_RECEIPT] = msgSupportGetAllSetReset;
m_caps[(CapType)CAP_TYPE_EX_DISCARD_BLANK_RECEIPT] = [this](Msg msg, Capability& data)->Result {
log_attr_access((int)CAP_TYPE_EX_DISCARD_BLANK_RECEIPT, (int)msg);
if (Msg::Set == msg) {
auto mech = data.currentItem<DiscardBlankPages>();
bool discard = mech == DiscardBlankPages::Auto;
@ -2037,6 +2085,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IFilter] = msgSupportGetAllSetReset;
m_caps[CapType::IFilter] = [this](Msg msg, Capability& data)->Result {
log_attr_access((int)CapType::IFilter, (int)msg);
if (Msg::Set == msg) {
auto mech = data.currentItem<CapType::IFilter>();
int ret = SCANNER_ERR_OK, val = to_sane_filter((Filter)mech);
@ -2072,6 +2121,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IBrightness] = msgSupportGetAllSetReset;
m_caps[CapType::IBrightness] = [this](Msg msg, Capability& data)->Result {
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);
@ -2107,6 +2157,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IContrast] = msgSupportGetAllSetReset;
m_caps[CapType::IContrast] = [this](Msg msg, Capability& data)->Result {
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);
@ -2142,6 +2193,7 @@ void huagao_ds::init_support_caps(void)
m_query[(CapType)CapTypeEx::CAP_TYPE_EX_FILL_HOLE_RATIO] = msgSupportGetAllSetReset;
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;
int ret = SCANNER_ERR_OK;
GET_SANE_OPT_RANGE(float, scanner_, search_hole_range, &now, &init, &l, &u, &step);
@ -2178,6 +2230,7 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::IGamma] = msgSupportGetAllSetReset;
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;
int ret = SCANNER_ERR_OK;
GET_SANE_OPT_RANGE(float, scanner_, gamma, &now, &init, &l, &u, &step);
@ -2207,11 +2260,13 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::CustomDsData] = msgSupportGetAll;
m_caps[CapType::CustomDsData] = [this](Msg msg, Capability& data) -> Result {
log_attr_access((int)CapType::CustomDsData, (int)msg);
return CapSupGetAll<Bool, Bool, CapType::CustomDsData>(msg, data, Bool(true), Bool(true));
};
m_query[CapType::DoubleFeedDetection] = msgSupportGetAllSetReset;
m_caps[CapType::DoubleFeedDetection] = [this](Msg msg, Capability& data)->Result {
log_attr_access((int)CapType::DoubleFeedDetection, (int)msg);
if (Msg::Set == msg) {
auto atuodsw = data.currentItem<CapType::DoubleFeedDetection>();
int ret = SCANNER_ERR_OK;
@ -2229,6 +2284,7 @@ void huagao_ds::init_support_caps(void)
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;
@ -2237,12 +2293,14 @@ void huagao_ds::init_support_caps(void)
m_query[CapType::FeederLoaded] = msgSupportGetAll;
m_caps[CapType::FeederLoaded] = [this](Msg msg, Capability& data) -> Result {
log_attr_access((int)CapType::FeederLoaded, (int)msg);
Bool paperon = scanner_->is_paper_on();
return CapSupGetAll<Bool, Bool, CapType::FeederLoaded>(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<Int32>();
if (msg == Msg::Reset)
@ -2259,6 +2317,7 @@ void huagao_ds::init_support_caps(void)
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) {
@ -2278,6 +2337,7 @@ void huagao_ds::init_support_caps(void)
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)
@ -2294,6 +2354,7 @@ void huagao_ds::init_support_caps(void)
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<int> all;
GET_SANE_OPT(int, scanner_, ex_multiout_type, &cur, &def, &all, NULL);
@ -2321,6 +2382,7 @@ void huagao_ds::init_support_caps(void)
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<Int32>();
if (msg == Msg::Reset)
@ -2337,6 +2399,7 @@ void huagao_ds::init_support_caps(void)
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<Int32>();
if (msg == Msg::Reset)
@ -2353,6 +2416,7 @@ void huagao_ds::init_support_caps(void)
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;
@ -2363,6 +2427,7 @@ void huagao_ds::init_support_caps(void)
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<int> all;
GET_SANE_OPT(int, scanner_, ex_power, &cur, &def, &all, NULL);
@ -2390,6 +2455,7 @@ void huagao_ds::init_support_caps(void)
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<Bool>();
int ret = SCANNER_ERR_OK;
@ -2407,6 +2473,7 @@ void huagao_ds::init_support_caps(void)
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<int> all;
GET_SANE_OPT(int, scanner_, ex_sharpen, &cur, &def, &all, NULL);
@ -2434,6 +2501,7 @@ void huagao_ds::init_support_caps(void)
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<int> vals;
GET_SANE_OPT(int, scanner_, ex_color_enhance, &cur, &def, &vals, NULL);
@ -2470,6 +2538,7 @@ void huagao_ds::init_support_caps(void)
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);
Str255 str;
@ -2480,6 +2549,7 @@ 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);
Str255 str;
@ -2522,6 +2592,7 @@ void huagao_ds::init_support_caps_ex(void)
#define SET_SANE_CAP_ENUM(ctype, ttype, 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); \
ctype now, init; \
std::vector<ctype> all; \
GET_SANE_OPT(ctype, scanner_, name, &now, &init, &all, NULL); \
@ -2571,6 +2642,7 @@ void huagao_ds::init_support_caps_ex(void)
#define SET_SANE_CAP_RANGE(ctype, ttype, 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); \
ctype now, init, lower, upper, step; \
std::vector<ctype> all; \
GET_SANE_OPT_RANGE(ctype, scanner_, name, &now, &init, &lower, &upper, &step); \
@ -2611,6 +2683,7 @@ void huagao_ds::init_support_caps_ex(void)
#define SET_SANE_CAP(ctype, ttype, 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); \
ctype now, init; \
GET_SANE_OPT(ctype, scanner_, name, &now, &init, NULL, NULL); \
if (msg == Msg::Set || msg == Msg::Reset) \