code_device/twain/ds/scanner.h

179 lines
5.9 KiB
C
Raw Normal View History

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
{
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_;
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);
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);
int language_id_;
2023-07-10 07:28:45 +00:00
public:
scanner(const char* model);
2023-07-10 07:28:45 +00:00
protected:
~scanner();
public:
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(int32_t, add_ref(void));
COM_API_OVERRIDE(int32_t, release(void));
2023-07-10 07:28:45 +00:00
// ISaneInvoker
public:
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(*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
COM_API_OVERRIDE(bool, get_first_image_header(SANE_Parameters* header, size_t* bytes = nullptr, int* dpi = nullptr));
COM_API_OVERRIDE(bool, discard_first_image(void));
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));
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 ...
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));
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));
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(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, 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:
int open(void);
2023-07-10 07:28:45 +00:00
int handle_device_event(int ev_code, void* data, unsigned int* len);
};