2023-07-10 07:28:45 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "scanned_img.h"
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <functional>
|
|
|
|
|
#include <map>
|
|
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define EXTENSION_ID_BASE 0x300
|
|
|
|
|
|
|
|
|
|
class scanner : public ISaneInvoker, virtual public refer
|
|
|
|
|
{
|
2023-09-21 03:23:38 +00:00
|
|
|
|
SANE_Handle handle_;
|
|
|
|
|
std::string model_;
|
|
|
|
|
int err_;
|
|
|
|
|
int ex_id_;
|
|
|
|
|
int prev_start_result_;
|
|
|
|
|
int dpi_;
|
|
|
|
|
int fetch_imgs_ = 0; // count for images has fetched by APP
|
|
|
|
|
bool is_bIndicator;
|
|
|
|
|
bool is_show_setting_;
|
2023-07-10 07:28:45 +00:00
|
|
|
|
unsigned int img_ind_;
|
|
|
|
|
std::string scanner_name_;
|
|
|
|
|
std::string tmp_path_;
|
|
|
|
|
std::string cfg_path_;
|
|
|
|
|
std::string scan_msg_;
|
|
|
|
|
bool scan_err_;
|
|
|
|
|
volatile bool is_ui_wait_img_;
|
|
|
|
|
volatile bool is_scanning_;
|
|
|
|
|
volatile bool user_cancel_;
|
|
|
|
|
twain_xfer xfer_;
|
|
|
|
|
safe_img_queue images_;
|
|
|
|
|
size_t max_img_mem_;
|
|
|
|
|
safe_queue<int> events_; //如果有界面,则全部保存从界面传回的消息;否则只保存开始扫描和结束扫描的事件
|
|
|
|
|
int ev_cnt_;
|
|
|
|
|
SANE_FinalImgFormat img_fmt_;
|
|
|
|
|
bool twain_set_;
|
|
|
|
|
SANEAPI sane_api_;
|
|
|
|
|
std::function<void(int, void*, int)> ui_notify;
|
|
|
|
|
int(* scanner_ev_handler_)(int, void*);
|
|
|
|
|
void* evh_param_;
|
|
|
|
|
HWND app_wnd_; // for MessageBox
|
|
|
|
|
bool is_show_ui_;
|
|
|
|
|
|
2023-09-21 03:23:38 +00:00
|
|
|
|
typedef struct _sane_opt
|
|
|
|
|
{
|
|
|
|
|
int opt_sn;
|
|
|
|
|
value_type type;
|
|
|
|
|
value_limit limit;
|
|
|
|
|
int size;
|
|
|
|
|
int cap; // sane capability
|
|
|
|
|
}SANEOPT;
|
|
|
|
|
std::map<int, SANEOPT> sane_opts_; // <fix-id, SANEOPT>
|
|
|
|
|
|
|
|
|
|
|
2023-07-10 07:28:45 +00:00
|
|
|
|
int transfer_id(int id); // transfer fixed SANE option ID to real id, -1 is none
|
|
|
|
|
void transport_config_file(void);
|
|
|
|
|
void update_config(void);
|
|
|
|
|
void load_config(const wchar_t* file);
|
|
|
|
|
void save_config(const wchar_t* file);
|
|
|
|
|
void apply_config(void);
|
|
|
|
|
void on_ui_event(int uev, void* sender);
|
|
|
|
|
std::string choose_scanner(const std::vector<std::string>& scanners);
|
|
|
|
|
int close(void);
|
|
|
|
|
int init_options_id(void);
|
|
|
|
|
char* get_opt_value(int id, int size, bool def_val/*false - current value*/); // call delete[] to free returned value
|
|
|
|
|
bool get_opt_value(int id, void* buf, bool def_val/*false - current value*/); // call delete[] to free returned value
|
|
|
|
|
int control_read_string(int io_code, std::string& val);
|
|
|
|
|
|
|
|
|
|
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 thread_start(void);
|
|
|
|
|
std::unique_ptr<std::thread> thread_starting_;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
|
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), 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<class S, class T>
|
|
|
|
|
void set_value_range(S cur, S def, S l, S u, S s, set_opt_value setv, void* param, T(* to_t)(S))
|
|
|
|
|
{
|
|
|
|
|
T v = to_t(cur);
|
|
|
|
|
while (setv(&v, VAL_ROLE_CURRENT, VAL_LIMIT_RANGE, 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int to_int(SANE_Int v);
|
2023-09-21 03:23:38 +00:00
|
|
|
|
static double to_double(SANE_Fixed v);
|
2023-07-10 07:28:45 +00:00
|
|
|
|
static void ui_callback(int uev, void* sender, void* param);
|
|
|
|
|
static bool is_option_float(int sn, void* param);
|
|
|
|
|
|
2023-09-21 03:23:38 +00:00
|
|
|
|
int language_id_;
|
|
|
|
|
|
2023-07-10 07:28:45 +00:00
|
|
|
|
public:
|
2023-09-21 03:23:38 +00:00
|
|
|
|
scanner(const char* model);
|
|
|
|
|
|
2023-07-10 07:28:45 +00:00
|
|
|
|
protected:
|
|
|
|
|
~scanner();
|
|
|
|
|
|
|
|
|
|
public:
|
2023-09-21 03:23:38 +00:00
|
|
|
|
static void get_scanner_name(const char* model, std::vector<std::string>& names);
|
2023-07-10 07:28:45 +00:00
|
|
|
|
static value_type from_sane_type(SANE_Value_Type type);
|
|
|
|
|
static value_limit from_sane_constraint(SANE_Constraint_Type type);
|
|
|
|
|
|
|
|
|
|
// IRef
|
|
|
|
|
public:
|
|
|
|
|
COM_API_OVERRIDE(long, add_ref(void));
|
|
|
|
|
COM_API_OVERRIDE(long, release(void));
|
|
|
|
|
|
|
|
|
|
// ISaneInvoker
|
|
|
|
|
public:
|
|
|
|
|
COM_API_OVERRIDE(int, start(void));
|
|
|
|
|
COM_API_OVERRIDE(int, stop(void));
|
|
|
|
|
COM_API_OVERRIDE(int, get_event(void));
|
2023-09-21 03:23:38 +00:00
|
|
|
|
COM_API_OVERRIDE(void, set_event_callback(int(*handle_ev)(int, void*) = nullptr, void* para = nullptr));
|
2023-07-10 07:28:45 +00:00
|
|
|
|
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
|
2023-09-21 03:23:38 +00:00
|
|
|
|
COM_API_OVERRIDE(bool, get_first_image_header(SANE_Parameters* header, size_t* bytes = nullptr, int* dpi = nullptr));
|
2023-08-04 05:13:36 +00:00
|
|
|
|
COM_API_OVERRIDE(bool, discard_first_image(void));
|
2023-09-21 03:23:38 +00:00
|
|
|
|
COM_API_OVERRIDE(int, convert_image(SANE_ImageFormatConvert* conv));
|
2023-07-10 07:28:45 +00:00
|
|
|
|
COM_API_OVERRIDE(bool, is_online(void));
|
|
|
|
|
COM_API_OVERRIDE(bool, is_paper_on(void));
|
|
|
|
|
COM_API_OVERRIDE(int, last_error(void));
|
2023-09-21 03:23:38 +00:00
|
|
|
|
COM_API_OVERRIDE(int, image_fetched(IScanImg* tx)); // notify the image 'tx' has fetched by APP
|
2023-07-10 07:28:45 +00:00
|
|
|
|
|
|
|
|
|
// ui ...
|
2023-09-21 03:23:38 +00:00
|
|
|
|
COM_API_OVERRIDE(bool, ui_is_ok(void));
|
2023-07-10 07:28:45 +00:00
|
|
|
|
COM_API_OVERRIDE(bool, ui_show_setting(HWND parent, bool with_scan, bool indicator = true));
|
|
|
|
|
COM_API_OVERRIDE(bool, ui_show_progress(HWND parent, bool bIndicator));
|
|
|
|
|
COM_API_OVERRIDE(void, ui_hide(void));
|
|
|
|
|
|
|
|
|
|
// twain
|
|
|
|
|
COM_API_OVERRIDE(void, twain_set_transfer(twain_xfer xfer));
|
2023-09-21 03:23:38 +00:00
|
|
|
|
COM_API_OVERRIDE(void, twain_set_compression(SANE_CompressionType compression, void* detail = nullptr));
|
2023-07-10 07:28:45 +00:00
|
|
|
|
COM_API_OVERRIDE(int, twain_get_config(char* buf, size_t* len));
|
|
|
|
|
COM_API_OVERRIDE(int, twain_set_config(char* buf, size_t len));
|
|
|
|
|
|
2023-09-21 03:23:38 +00:00
|
|
|
|
COM_API_OVERRIDE(bool, get_option_info(int sn, value_type* type, value_limit* limit, int* bytes, bool* readonly));
|
2023-09-23 08:07:23 +00:00
|
|
|
|
COM_API_OVERRIDE(int, get_fixed_ids(SANE_Bool(*cb)(int id, void* param), void* param));
|
2023-09-21 03:23:38 +00:00
|
|
|
|
|
|
|
|
|
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(int, set_value(int sn, void* val));
|
|
|
|
|
|
2023-07-10 07:28:45 +00:00
|
|
|
|
// methods:
|
|
|
|
|
public:
|
2023-09-22 08:26:22 +00:00
|
|
|
|
int open(void);
|
2023-09-21 03:23:38 +00:00
|
|
|
|
int last_err(void);
|
2023-07-10 07:28:45 +00:00
|
|
|
|
int handle_device_event(int ev_code, void* data, unsigned int* len);
|
|
|
|
|
};
|