回调方式取图
This commit is contained in:
parent
712d49809b
commit
79f8208ea4
|
@ -254,13 +254,14 @@ __declspec(novtable) struct ISaneInvoker : public IRef
|
|||
SANE_OPTION_ID_API_EX(ip); // std::string
|
||||
|
||||
// ui ...
|
||||
COM_API_DECLARE(void, ui_show_main(void));
|
||||
COM_API_DECLARE(void, ui_show_setting(bool with_scan));
|
||||
COM_API_DECLARE(void, ui_show_progress(void));
|
||||
COM_API_DECLARE(bool, ui_show_main(HWND parent));
|
||||
COM_API_DECLARE(bool, ui_show_setting(HWND parent, bool with_scan));
|
||||
COM_API_DECLARE(bool, ui_show_progress(HWND parent));
|
||||
COM_API_DECLARE(void, ui_hide(void));
|
||||
COM_API_DECLARE(void, ui_handle_sane_event(int sane_ev, void* data, unsigned int* len));
|
||||
COM_API_DECLARE(bool, ui_is_ok(void));
|
||||
COM_API_DECLARE(bool, ui_is_progress_ui_showing(void));
|
||||
|
||||
// twain
|
||||
COM_API_DECLARE(void, twain_set_transfer(twain_xfer xfer));
|
||||
};
|
||||
|
||||
struct delete_scanner
|
||||
|
|
|
@ -246,20 +246,20 @@ unsigned char* mapping_buf::buffer(unsigned long long off, unsigned int* bytes)
|
|||
bool mapping_buf::save(const void* data, size_t* bytes, unsigned long long off)
|
||||
{
|
||||
unsigned int len = *bytes, total = 0;
|
||||
unsigned char* buf = buffer(off, &len);
|
||||
unsigned char* buf = buffer(off, &len);
|
||||
bool ret = false;
|
||||
const char* src = (const char*)data;
|
||||
|
||||
while (buf)
|
||||
{
|
||||
if (len > *bytes - total)
|
||||
if (len >= *bytes - total)
|
||||
{
|
||||
memcpy(buf, src, *bytes - total);
|
||||
total = *bytes;
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
memcpy(buf, data, len);
|
||||
memcpy(buf, src, len);
|
||||
total += len;
|
||||
off += len;
|
||||
src += len;
|
||||
|
@ -398,50 +398,48 @@ scanned_img::scanned_img(SANE_Parameters head, SANE_Handle dev, int dpi
|
|||
ok = total + h.length() + dif == data_->bytes();
|
||||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
if (fmt_.img_format == SANE_IMAGE_TYPE_BMP && channel() == 3 &&
|
||||
xfer != TWAIN_XFER_Memory)
|
||||
{
|
||||
// swap RGB
|
||||
unsigned long long off = 0;
|
||||
unsigned int line = line_bytes(), len = line;
|
||||
for (int i = 0; i < height(); ++i)
|
||||
{
|
||||
int l = head_.bytes_per_line, cur = 0;
|
||||
|
||||
off = i * line + h.length();
|
||||
while (l > 0)
|
||||
{
|
||||
len = l;
|
||||
dst = data_->buffer(off + cur, &len);
|
||||
if (!dst)
|
||||
break;
|
||||
if (len > l)
|
||||
len = l;
|
||||
len /= 3;
|
||||
for (int pos = 0; pos < len; ++pos)
|
||||
{
|
||||
unsigned char uc = dst[pos * 3 + 0];
|
||||
dst[pos * 3 + 0] = dst[pos * 3 + 2];
|
||||
dst[pos * 3 + 2] = uc;
|
||||
}
|
||||
l -= len * 3;
|
||||
cur += len * 3;
|
||||
}
|
||||
if (!dst)
|
||||
break;
|
||||
}
|
||||
}
|
||||
data_->unmap();
|
||||
}
|
||||
do_result(ok, xfer);
|
||||
}
|
||||
scanned_img::scanned_img(SANE_Parameters head, void* data, unsigned int len, int dpi, const wchar_t* tmp_file
|
||||
, twain_xfer xfer, SANE_FinalImgFormat* fmt) : head_(head), dpi_(dpi), header_size_(0)
|
||||
{
|
||||
if (fmt)
|
||||
fmt_ = *fmt;
|
||||
else
|
||||
{
|
||||
delete data_;
|
||||
data_ = NULL;
|
||||
header_size_ = 0;
|
||||
fmt_.img_format = SANE_IMAGE_TYPE_BMP;
|
||||
fmt_.detail = 0;
|
||||
}
|
||||
|
||||
size_t bytes = line_bytes() * head.lines;
|
||||
std::string h(file_header(fmt_.img_format, dpi, xfer));
|
||||
unsigned char* dst = NULL, *src = (unsigned char*)data;
|
||||
bool ok = false;
|
||||
|
||||
header_size_ = h.length();
|
||||
data_ = new mapping_buf();
|
||||
bytes += header_size_;
|
||||
dst = data_->allocate(tmp_file, bytes);
|
||||
bytes = h.length();
|
||||
if (dst && data_->save(h.c_str(), &bytes, 0))
|
||||
{
|
||||
unsigned long long off = bytes, line_l = line_bytes();
|
||||
unsigned int buf_len = line_bytes(), row = 0;
|
||||
if (xfer == TWAIN_XFER_Memory)
|
||||
line_l *= -1;
|
||||
else
|
||||
off = data_->bytes() - line_l;
|
||||
for (; row < head.lines; ++row)
|
||||
{
|
||||
bytes = head.bytes_per_line;
|
||||
if (!data_->save(src, &bytes, off))
|
||||
break;
|
||||
off -= line_l;
|
||||
src += head.bytes_per_line;
|
||||
}
|
||||
ok = row == head.lines;
|
||||
}
|
||||
do_result(ok, xfer);
|
||||
}
|
||||
scanned_img::~scanned_img()
|
||||
{
|
||||
|
@ -481,6 +479,59 @@ std::string scanned_img::file_header(SANE_ImageType type, float resolution, twai
|
|||
|
||||
return h;
|
||||
}
|
||||
void scanned_img::do_result(bool ok, twain_xfer xfer)
|
||||
{
|
||||
if (ok)
|
||||
{
|
||||
if (fmt_.img_format == SANE_IMAGE_TYPE_BMP
|
||||
&& channel() == 3
|
||||
&& xfer != TWAIN_XFER_Memory)
|
||||
{
|
||||
// swap RGB
|
||||
swap_rgb();
|
||||
}
|
||||
data_->unmap();
|
||||
}
|
||||
else
|
||||
{
|
||||
delete data_;
|
||||
data_ = NULL;
|
||||
header_size_ = 0;
|
||||
}
|
||||
}
|
||||
void scanned_img::swap_rgb(void)
|
||||
{
|
||||
unsigned long long off = 0;
|
||||
unsigned int line = line_bytes(), len = line;
|
||||
unsigned char* dst = NULL;
|
||||
|
||||
for (int i = 0; i < height(); ++i)
|
||||
{
|
||||
int l = head_.bytes_per_line, cur = 0;
|
||||
|
||||
off = i * line + header_size_;
|
||||
while (l > 0)
|
||||
{
|
||||
len = l;
|
||||
dst = data_->buffer(off + cur, &len);
|
||||
if (!dst)
|
||||
break;
|
||||
if (len > l)
|
||||
len = l;
|
||||
len /= 3;
|
||||
for (int pos = 0; pos < len; ++pos)
|
||||
{
|
||||
unsigned char uc = dst[pos * 3 + 0];
|
||||
dst[pos * 3 + 0] = dst[pos * 3 + 2];
|
||||
dst[pos * 3 + 2] = uc;
|
||||
}
|
||||
l -= len * 3;
|
||||
cur += len * 3;
|
||||
}
|
||||
if (!dst)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// IRef
|
||||
COM_API_IMPLEMENT(scanned_img, long, add_ref(void))
|
||||
|
@ -557,3 +608,70 @@ COM_API_IMPLEMENT(scanned_img, void, copy_header(SANE_Parameters* head))
|
|||
{
|
||||
*head = head_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class safe_img_queue
|
||||
safe_img_queue::safe_img_queue()
|
||||
{}
|
||||
safe_img_queue::~safe_img_queue()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
size_t safe_img_queue::count(void)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(que_lock_);
|
||||
|
||||
return queue_.size();
|
||||
}
|
||||
bool safe_img_queue::save(scanned_img* img)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(que_lock_);
|
||||
|
||||
queue_.push_back(img);
|
||||
|
||||
return true;
|
||||
}
|
||||
bool safe_img_queue::get_header(SANE_Parameters* header)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(que_lock_);
|
||||
bool ok = false;
|
||||
|
||||
if (queue_.size())
|
||||
{
|
||||
queue_[0]->copy_header(header);
|
||||
ok = true;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
scanned_img* safe_img_queue::take(void)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(que_lock_);
|
||||
scanned_img* img = NULL;
|
||||
|
||||
if (queue_.size())
|
||||
{
|
||||
img = queue_[0];
|
||||
queue_.erase(queue_.begin());
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
void safe_img_queue::clear()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(que_lock_);
|
||||
|
||||
for (size_t i = 0; i < queue_.size(); ++i)
|
||||
queue_[i]->release();
|
||||
queue_.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include "s2t_api.h"
|
||||
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
|
||||
class refer : public IRef
|
||||
{
|
||||
|
@ -59,10 +60,14 @@ class scanned_img : public IScanImg, virtual public refer
|
|||
SANE_FinalImgFormat fmt_;
|
||||
|
||||
std::string file_header(SANE_ImageType type, float resolution, twain_xfer xfer);
|
||||
void do_result(bool ok, twain_xfer xfer);
|
||||
void swap_rgb(void);
|
||||
|
||||
public:
|
||||
scanned_img(SANE_Parameters head, SANE_Handle dev, int dpi, const wchar_t* tmp_file
|
||||
, twain_xfer xfer = TWAIN_XFER_Native, SANE_FinalImgFormat *fmt = NULL);
|
||||
scanned_img(SANE_Parameters head, void* data, unsigned int len, int dpi, const wchar_t* tmp_file
|
||||
, twain_xfer xfer = TWAIN_XFER_Native, SANE_FinalImgFormat *fmt = NULL);
|
||||
|
||||
|
||||
protected:
|
||||
|
@ -90,6 +95,23 @@ public:
|
|||
COM_API_OVERRIDE(void, copy_header(SANE_Parameters* head));
|
||||
};
|
||||
|
||||
class safe_img_queue
|
||||
{
|
||||
std::mutex que_lock_;
|
||||
std::vector<scanned_img*> queue_;
|
||||
|
||||
public:
|
||||
safe_img_queue();
|
||||
~safe_img_queue();
|
||||
|
||||
public:
|
||||
size_t count(void);
|
||||
bool save(scanned_img* img);
|
||||
bool get_header(SANE_Parameters* header);
|
||||
scanned_img* take(void);
|
||||
void clear();
|
||||
};
|
||||
|
||||
namespace local_trans
|
||||
{
|
||||
std::string u2a(const wchar_t* unic, UINT cp = CP_ACP);
|
||||
|
|
170
sane/scanner.cpp
170
sane/scanner.cpp
|
@ -6,6 +6,7 @@
|
|||
#include "../../code_device/hgsane/sane_hg_mdw.h"
|
||||
#include "sane_option_trans.h"
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
|
||||
|
||||
static IMPLEMENT_OPTION_STRING_COMPARE(compare_sane_opt);
|
||||
|
@ -18,10 +19,74 @@ static IMPLEMENT_OPTION_STRING_COMPARE(compare_sane_opt);
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// callback
|
||||
namespace callback
|
||||
{
|
||||
static std::mutex cb_lock_;
|
||||
typedef struct _scanner_inst
|
||||
{
|
||||
SANE_Handle dev;
|
||||
scanner* invoker;
|
||||
|
||||
bool operator==(const SANE_Handle& h)
|
||||
{
|
||||
return dev == h;
|
||||
}
|
||||
bool operator==(const scanner* obj)
|
||||
{
|
||||
return invoker == obj;
|
||||
}
|
||||
}SCNINST;
|
||||
std::vector<SCNINST> g_scanner_instances;
|
||||
|
||||
int sane_event_callback( // 注册回调的对象,需要保证该回调是多线程安全的
|
||||
SANE_Handle hdev // 产生事件的设备句柄
|
||||
, int code // 回调事件代码
|
||||
, void* data // 回调事件数据,根据事件代码有所不同,参照具体事件定义
|
||||
, unsigned int* len // 数据长度(字节),或者event_data的缓冲区长度,详细请看相应的事件代码
|
||||
, void* param // 用户自定义数据,与调用sane_init_ex传入时的保持一致
|
||||
) // 返回值依不同的事件代码而定,通常为“0”
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(cb_lock_);
|
||||
std::vector<SCNINST>::iterator it = std::find(g_scanner_instances.begin(), g_scanner_instances.end(), hdev);
|
||||
|
||||
if (it != g_scanner_instances.end())
|
||||
return it->invoker->handle_event(code, data, len);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
void reg_callback(SANE_Handle dev, scanner* invoker)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(cb_lock_);
|
||||
std::vector<SCNINST>::iterator it = std::find(g_scanner_instances.begin(), g_scanner_instances.end(), dev);
|
||||
if (it == g_scanner_instances.end())
|
||||
{
|
||||
SCNINST inst;
|
||||
|
||||
inst.dev = dev;
|
||||
inst.invoker = invoker;
|
||||
g_scanner_instances.push_back(inst);
|
||||
}
|
||||
else
|
||||
it->invoker = invoker;
|
||||
}
|
||||
void unreg_callback(scanner* invoker)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(cb_lock_);
|
||||
std::vector<SCNINST>::iterator it = std::find(g_scanner_instances.begin(), g_scanner_instances.end(), invoker);
|
||||
if (it != g_scanner_instances.end())
|
||||
g_scanner_instances.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// class scanner
|
||||
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)
|
||||
, dpi_(200), tmp_path_(L""), img_ind_(0), cb_invoker_(NULL), cb_param_(NULL), working_(false)
|
||||
{
|
||||
tmp_path_ = local_trans::a2u(hg_sane_middleware::sane_path().c_str());
|
||||
tmp_path_ += L"imgs";
|
||||
|
@ -31,7 +96,9 @@ scanner::scanner(SCANNERID id) : handle_(NULL), id_(id), ex_id_(EXTENSION_ID_BAS
|
|||
err_ = open();
|
||||
}
|
||||
scanner::~scanner()
|
||||
{}
|
||||
{
|
||||
callback::unreg_callback(this);
|
||||
}
|
||||
|
||||
std::string scanner::get_scanner_name(SCANNERID id)
|
||||
{
|
||||
|
@ -113,6 +180,7 @@ int scanner::open(void)
|
|||
ret = hg_sane_middleware::instance()->open_device(name.c_str(), &handle_);
|
||||
if (ret == SANE_STATUS_GOOD)
|
||||
{
|
||||
callback::reg_callback(handle_, this);
|
||||
ret = init_options_id();
|
||||
}
|
||||
|
||||
|
@ -1372,6 +1440,7 @@ COM_API_IMPLEMENT(scanner, int, start(void))
|
|||
unsigned int l = sizeof(img_fmt_);
|
||||
if (hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_GET_FINAL_IMAGE_FORMAT, &img_fmt_, &l))
|
||||
img_fmt_.img_format = SANE_IMAGE_TYPE_BMP;
|
||||
working_ = true;
|
||||
}
|
||||
prev_start_result_ = ret;
|
||||
|
||||
|
@ -1379,10 +1448,13 @@ COM_API_IMPLEMENT(scanner, int, start(void))
|
|||
}
|
||||
COM_API_IMPLEMENT(scanner, int, stop(void))
|
||||
{
|
||||
working_ = false;
|
||||
return hg_sane_middleware::instance()->stop(handle_);
|
||||
}
|
||||
COM_API_IMPLEMENT(scanner, void, set_event_callback(void(*cb)(int ev_type, void* data, unsigned int* len, void* param), void* param))
|
||||
{
|
||||
cb_invoker_ = cb;
|
||||
cb_param_ = param;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanner, bool, wait_image(DWORD milliseconds))
|
||||
{
|
||||
|
@ -1392,24 +1464,18 @@ COM_API_IMPLEMENT(scanner, bool, wait_image(DWORD milliseconds))
|
|||
}
|
||||
COM_API_IMPLEMENT(scanner, int, get_scanned_images(DWORD milliseconds))
|
||||
{
|
||||
unsigned int count = 0;
|
||||
size_t count = images_.count();
|
||||
|
||||
hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_GET_IMAGE_QUEUE_COUNT, NULL, &count);
|
||||
if (count == 0 && milliseconds)
|
||||
while (count == 0 && milliseconds && working_)
|
||||
{
|
||||
while (count == 0)
|
||||
Sleep(10);
|
||||
count = images_.count();
|
||||
if (milliseconds != -1)
|
||||
{
|
||||
Sleep(10);
|
||||
if (hg_sane_middleware::instance()->io_control(handle_, IO_CTRL_CODE_GET_IMAGE_QUEUE_COUNT, NULL, &count)
|
||||
!= SCANNER_ERR_OK)
|
||||
if (milliseconds <= 10)
|
||||
break;
|
||||
if (milliseconds != -1)
|
||||
{
|
||||
if (milliseconds <= 10)
|
||||
break;
|
||||
|
||||
milliseconds -= 10;
|
||||
}
|
||||
milliseconds -= 10;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1417,22 +1483,13 @@ COM_API_IMPLEMENT(scanner, int, get_scanned_images(DWORD milliseconds))
|
|||
}
|
||||
COM_API_IMPLEMENT(scanner, IScanImg*, take_first_image(twain_xfer xfer))
|
||||
{
|
||||
scanned_img* img = NULL;
|
||||
SANE_Parameters head;
|
||||
|
||||
if (hg_sane_middleware::instance()->get_image_parameters(handle_, &head) == SANE_STATUS_GOOD)
|
||||
{
|
||||
wchar_t name[40] = { 0 };
|
||||
|
||||
swprintf_s(name, _countof(name) - 1, L"img_%05u.bmp", ++img_ind_);
|
||||
img = new scanned_img(head, handle_, dpi_, (tmp_path_ + name).c_str(), xfer, &img_fmt_);
|
||||
}
|
||||
scanned_img* img = images_.take();
|
||||
|
||||
return dynamic_cast<IScanImg*>(img);
|
||||
}
|
||||
COM_API_IMPLEMENT(scanner, bool, get_first_image_header(SANE_Parameters* header))
|
||||
{
|
||||
return hg_sane_middleware::instance()->get_image_parameters(handle_, header) == SANE_STATUS_GOOD;
|
||||
return images_.get_header(header);
|
||||
}
|
||||
COM_API_IMPLEMENT(scanner, bool, is_online(void))
|
||||
{
|
||||
|
@ -1712,29 +1769,62 @@ SANE_OPTION_ID_IMPLEMENT(ex_power)
|
|||
SANE_OPTION_ID_IMPLEMENT(ex_hardware_version)
|
||||
SANE_OPTION_ID_IMPLEMENT(ex_ip)
|
||||
|
||||
COM_API_IMPLEMENT(scanner, void, twain_set_transfer(twain_xfer xfer))
|
||||
{
|
||||
xfer_ = xfer;
|
||||
}
|
||||
|
||||
// ui ...
|
||||
COM_API_IMPLEMENT(scanner, void, ui_show_main(void))
|
||||
COM_API_IMPLEMENT(scanner, bool, ui_show_main(HWND parent))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanner, void, ui_show_setting(bool with_scan))
|
||||
COM_API_IMPLEMENT(scanner, bool, ui_show_setting(HWND parent, bool with_scan))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanner, void, ui_show_progress(void))
|
||||
COM_API_IMPLEMENT(scanner, bool, ui_show_progress(HWND parent))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanner, void, ui_hide(void))
|
||||
{
|
||||
}
|
||||
COM_API_IMPLEMENT(scanner, void, ui_handle_sane_event(int sane_ev, void* data, unsigned int* len))
|
||||
{
|
||||
}
|
||||
COM_API_IMPLEMENT(scanner, bool, ui_is_ok(void))
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
COM_API_IMPLEMENT(scanner, bool, ui_is_progress_ui_showing(void))
|
||||
|
||||
|
||||
|
||||
|
||||
int scanner::handle_event(int ev_code, void* data, unsigned int* len)
|
||||
{
|
||||
return false;
|
||||
if (ev_code == SANE_EVENT_IMAGE_OK)
|
||||
{
|
||||
SANE_Image* simg = (SANE_Image*)data;
|
||||
scanned_img* img = NULL;
|
||||
wchar_t name[40] = { 0 };
|
||||
|
||||
swprintf_s(name, _countof(name) - 1, L"img_%05u.bmp", ++img_ind_);
|
||||
img = new scanned_img(simg->header, simg->data, simg->bytes, dpi_, (tmp_path_ + name).c_str(), xfer_, &img_fmt_);
|
||||
if (img->bytes() >= simg->bytes)
|
||||
{
|
||||
images_.save(img);
|
||||
}
|
||||
else
|
||||
{
|
||||
img->release();
|
||||
}
|
||||
}
|
||||
else if (ev_code == SANE_EVENT_SCAN_FINISHED)
|
||||
{
|
||||
working_ = false;
|
||||
//if (cb_invoker_) // calling this when UI exited
|
||||
// cb_invoker_(ev_code, data, len, cb_param_);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1744,6 +1834,14 @@ COM_API_IMPLEMENT(scanner, bool, ui_is_progress_ui_showing(void))
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// exports
|
||||
#ifdef EXPORT_SANE_API
|
||||
|
@ -1753,6 +1851,7 @@ __declspec(dllimport)
|
|||
#endif
|
||||
int __stdcall initialize(void* reserve)
|
||||
{
|
||||
hg_sane_middleware::set_callback(callback::sane_event_callback, NULL);
|
||||
hg_sane_middleware::instance();
|
||||
|
||||
return SANE_STATUS_GOOD;
|
||||
|
@ -1791,6 +1890,7 @@ __declspec(dllimport)
|
|||
#endif
|
||||
int __stdcall uninitialize(void* reserve)
|
||||
{
|
||||
hg_sane_middleware::set_callback(NULL, NULL);
|
||||
hg_sane_middleware::clear();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -26,11 +26,16 @@ class scanner : public ISaneInvoker, virtual public refer
|
|||
SANE_Handle handle_;
|
||||
SCANNERID id_;
|
||||
int err_;
|
||||
void(*cb_invoker_)(int ev_type, void* data, unsigned int* len, void* param);
|
||||
void* cb_param_;
|
||||
int ex_id_;
|
||||
int prev_start_result_;
|
||||
int dpi_;
|
||||
unsigned int img_ind_;
|
||||
std::wstring tmp_path_;
|
||||
twain_xfer xfer_;
|
||||
safe_img_queue images_;
|
||||
volatile bool working_;
|
||||
SANE_FinalImgFormat img_fmt_;
|
||||
|
||||
int open(void);
|
||||
|
@ -264,11 +269,16 @@ public:
|
|||
SANE_OPTION_ID(ex_ip); // std::string
|
||||
|
||||
// ui ...
|
||||
COM_API_OVERRIDE(void, ui_show_main(void));
|
||||
COM_API_OVERRIDE(void, ui_show_setting(bool with_scan));
|
||||
COM_API_OVERRIDE(void, ui_show_progress(void));
|
||||
COM_API_OVERRIDE(bool, ui_show_main(HWND parent));
|
||||
COM_API_OVERRIDE(bool, ui_show_setting(HWND parent, bool with_scan));
|
||||
COM_API_OVERRIDE(bool, ui_show_progress(HWND parent));
|
||||
COM_API_OVERRIDE(void, ui_hide(void));
|
||||
COM_API_OVERRIDE(void, ui_handle_sane_event(int sane_ev, void* data, unsigned int* len));
|
||||
COM_API_OVERRIDE(bool, ui_is_ok(void));
|
||||
COM_API_OVERRIDE(bool, ui_is_progress_ui_showing(void));
|
||||
|
||||
// twain
|
||||
COM_API_OVERRIDE(void, twain_set_transfer(twain_xfer xfer));
|
||||
|
||||
// methods:
|
||||
public:
|
||||
int handle_event(int ev_code, void* data, unsigned int* len);
|
||||
};
|
|
@ -837,8 +837,11 @@ Result huagao_ds::userInterfaceEnable(const Identity&, UserInterface& ui)
|
|||
{
|
||||
if (!ui.showUi())
|
||||
{
|
||||
if (m_bIndicator)
|
||||
scanner_->ui_show_main();
|
||||
if (m_bIndicator && !scanner_->ui_show_progress((HWND)ui.parent().raw()))
|
||||
return seqError();
|
||||
|
||||
scanner_->twain_set_transfer((twain_xfer)m_capXferMech);
|
||||
|
||||
return scanner_->start() == SCANNER_ERR_OK ? success() : seqError();
|
||||
}
|
||||
|
||||
|
@ -1127,12 +1130,7 @@ Result huagao_ds::capCommon(const Identity&, Msg msg, Capability& data) {
|
|||
Twpp::Result huagao_ds::showTwainUI(Twpp::UserInterface& data, bool bUiOnly)
|
||||
{
|
||||
// display user UI ... (setting UI, can we show my own main window here ?)
|
||||
if (bUiOnly)
|
||||
scanner_->ui_show_setting(false);
|
||||
else
|
||||
scanner_->ui_show_main();
|
||||
|
||||
return success();
|
||||
return scanner_->ui_show_setting((HWND)data.parent().raw(), !bUiOnly) ? success() : seqError();
|
||||
}
|
||||
void huagao_ds::init_support_caps(void)
|
||||
{
|
||||
|
@ -1178,10 +1176,21 @@ void huagao_ds::init_support_caps(void)
|
|||
return oneValGetSet<Int16>(msg, data, tmp_count, -1);
|
||||
};
|
||||
|
||||
if (scanner_->ui_is_ok())
|
||||
m_bIndicator = scanner_->ui_is_ok();
|
||||
if (m_bIndicator)
|
||||
{
|
||||
m_query[CapType::UiControllable] = msgSupportGetAll;
|
||||
m_caps[CapType::UiControllable] = std::bind(oneValGet<Bool>, _1, _2, Bool(true));
|
||||
|
||||
m_query[CapType::Indicators] = msgSupportGetAllSetReset;
|
||||
m_caps[CapType::Indicators] = [this](Msg msg, Capability& data) -> Result {
|
||||
if (Msg::Set == msg) {
|
||||
auto show = data.currentItem<CapType::Indicators>();
|
||||
m_bIndicator = show;
|
||||
return success();
|
||||
}
|
||||
return CapSupGetAllReset<bool, Bool, CapType::Indicators>(msg, data, { FALSE,TRUE }, m_bIndicator, TRUE, m_bIndicator ? 1 : 0, 1);
|
||||
};
|
||||
}
|
||||
|
||||
m_query[CapType::DeviceOnline] = msgSupportGetAll;
|
||||
|
@ -1945,16 +1954,6 @@ void huagao_ds::init_support_caps(void)
|
|||
return CapSupGetAll<Bool, Bool, CapType::FeederLoaded>(msg, data, paperon, paperon);
|
||||
};
|
||||
|
||||
m_query[CapType::Indicators] = msgSupportGetAllSetReset;
|
||||
m_caps[CapType::Indicators] = [this](Msg msg, Capability& data) -> Result {
|
||||
if (Msg::Set == msg) {
|
||||
auto show = data.currentItem<CapType::Indicators>();
|
||||
m_bIndicator = show;
|
||||
return success();
|
||||
}
|
||||
return CapSupGetAllReset<bool, Bool, CapType::Indicators>(msg, data, { FALSE,TRUE }, m_bIndicator, TRUE, m_bIndicator ? 1 : 0, 1);
|
||||
};
|
||||
|
||||
m_query[CapType(CapTypeEx::CAP_TYPE_EX_FOLD)] = msgSupportGetAllSetReset;
|
||||
m_caps[CapType(CapTypeEx::CAP_TYPE_EX_FOLD)] = [this](Msg msg, Capability& data)->Result {
|
||||
if (Msg::Set == msg || Msg::Reset == msg) {
|
||||
|
@ -2470,18 +2469,9 @@ void huagao_ds::on_scan_event(int sane_event, void* data, unsigned int* len)
|
|||
{
|
||||
if (scanner_.get())
|
||||
{
|
||||
scanner_->ui_handle_sane_event(sane_event, data, len);
|
||||
if (sane_event == SANE_EVENT_SCAN_FINISHED)
|
||||
{
|
||||
if (scanner_->ui_is_progress_ui_showing())
|
||||
scanner_->ui_hide();
|
||||
else //if (!scanner_->twain_get_to_be_scan())
|
||||
{
|
||||
bool now = false;
|
||||
GET_SANE_OPT(bool, scanner_, ex_to_be_scan, &now, NULL, NULL, NULL);
|
||||
if(!now)
|
||||
scanner_->ui_hide();
|
||||
}
|
||||
notifyCloseOk();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue