248 lines
9.6 KiB
C++
248 lines
9.6 KiB
C++
#pragma once
|
||
|
||
#include <signal.h>
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include <vector>
|
||
#include <algorithm>
|
||
#include <string>
|
||
#include <map>
|
||
#include <stdio.h>
|
||
#if defined(WIN32) || defined(_WIN64)
|
||
#define bzero(b, s) memset(b, 0, s)
|
||
#else
|
||
#include <iconv.h>
|
||
#endif
|
||
#include "../sdk/hginclude/huagaoxxx_warraper_ex.h"
|
||
#include "sane/sane_ex.h"
|
||
|
||
#define ENABLE_SLAVE_OPTION_CONTROL
|
||
#define ALIGN_INT(n) ((((n) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))
|
||
|
||
#ifdef OEM_HANWANG
|
||
#define hg_sane_middleware hw_sane_middleware
|
||
#elif defined(OEM_LISICHENG)
|
||
#define hg_sane_middleware lsc_sane_middleware
|
||
#endif
|
||
|
||
class json;
|
||
class sane_std_opts;
|
||
typedef struct _device_option
|
||
{
|
||
// std::string dev_name;
|
||
int option_no;
|
||
int fixed_no; // 固定ID
|
||
std::string opt_name;
|
||
SANE_Option_Descriptor* desc;
|
||
}DEVOPT;
|
||
typedef struct _cur_val
|
||
{
|
||
std::string name;
|
||
std::string type;
|
||
std::string val; /*参数全部字符串化*/
|
||
|
||
bool operator==(const std::string& n)
|
||
{
|
||
return name == n;
|
||
}
|
||
}CURVAL;
|
||
typedef struct _master_option
|
||
{
|
||
std::string name;
|
||
SANE_Value_Type type;
|
||
std::string limit_l;
|
||
std::string limit_r;
|
||
bool(*compare_val)(const char* cur_val, const char* limit_l, const char* limit_r); // ==, !=, >, >=, <, <=, [l, r], ![l, r]
|
||
}MASTEROP;
|
||
typedef struct _slave_option
|
||
{
|
||
std::string name;
|
||
bool enable_now;
|
||
std::vector<MASTEROP> master;
|
||
bool (*is_enable)(scanner_handle hdev, const std::vector<MASTEROP>& master
|
||
, std::vector<CURVAL>& curvals/*参数全部字符串化*/); // logic 'and', 'or' opertions
|
||
}SLAVEOP;
|
||
typedef struct _opt_status
|
||
{
|
||
std::string name;
|
||
bool enable;
|
||
|
||
bool operator==(const std::string& opt)
|
||
{
|
||
return name == opt;
|
||
}
|
||
}OPTENABLE;
|
||
typedef struct _dev_inst
|
||
{
|
||
scanner_handle dev;
|
||
std::string name;
|
||
sane_std_opts* std_opt;
|
||
std::vector<DEVOPT> opts;
|
||
std::vector<CURVAL> cur_vals;
|
||
std::vector<SLAVEOP> slaves;
|
||
std::vector<std::string> masters;
|
||
std::map<sane_option_id, int> fixed_id;
|
||
|
||
bool operator==(const char* n)
|
||
{
|
||
return strcmp(name.c_str(), n) == 0;
|
||
}
|
||
bool operator==(scanner_handle h)
|
||
{
|
||
return dev == h;
|
||
}
|
||
|
||
_dev_inst()
|
||
{
|
||
dev = nullptr;
|
||
name = "";
|
||
std_opt = nullptr;
|
||
}
|
||
}DEVINST, * LPDEVINST;
|
||
class hg_sane_middleware
|
||
{
|
||
// std::vector<DEVOPT> opts_;
|
||
SANE_Option_Descriptor* opt_0_;
|
||
bool init_ok_;
|
||
|
||
//typedef struct _openning_scanner_option
|
||
//{
|
||
// std::string dev_name;
|
||
// scanner_handle handle;
|
||
// int scan_count;
|
||
//
|
||
// //struct _openning_scanner_option()
|
||
// //{
|
||
// // dev_name = "";
|
||
// // handle = NULL;
|
||
// // option_no = 0;
|
||
// // desc = NULL;
|
||
// //}
|
||
// bool operator==(const char* name)
|
||
// {
|
||
// return strcmp(dev_name.c_str(), name) == 0;
|
||
// }
|
||
// bool operator==(scanner_handle h)
|
||
// {
|
||
// return handle == h;
|
||
// }
|
||
//}OPENDEV;
|
||
//std::vector<OPENDEV> openning_;
|
||
|
||
static hg_sane_middleware *inst_;
|
||
static const SANE_Device** dev_list_;
|
||
|
||
static void language_changed(int cp, void* param);
|
||
static const SANE_Device** to_sane_device(ScannerInfo* hgscanner, int count); // 将驱动层传回的设备列表数据,转换为标准SANE协议的设备列表
|
||
static void free_sane_device(SANE_Device** dev); // 释放由to_sane_device返回的指针
|
||
static void device_pnp(int sig); // 热插拔事件监控
|
||
static SANE_Fixed double_2_sane_fixed(double v);
|
||
static double sane_fixed_2_double(SANE_Fixed v);
|
||
static void set_value_to_var(void* val, size_t bytes, void* param);
|
||
static void set_value_to_new(void* val, size_t bytes, void* param);
|
||
|
||
void reload_options(scanner_handle dev = nullptr);
|
||
void set_status_by_depends(scanner_handle hdev, SLAVEOP& so, std::vector<CURVAL>& vals, SANE_Option_Descriptor* desc);
|
||
SANE_Status open(SANE_String_Const devicename, SANE_Handle* handle, const char* name, const char* pwd, const char* method, char* rsc);
|
||
SANE_Option_Descriptor* from_json(scanner_handle h, const std::string& name, json* jsn);
|
||
std::string get_option_json(scanner_handle handle, void* opt, std::string* key = nullptr, SANE_Int* id = nullptr);
|
||
SANE_Option_Descriptor* find_stored_descriptor(scanner_handle handle, const void* option, SANE_Int* id = nullptr, SANE_Int* fix_id = nullptr);
|
||
|
||
void reload_current_value(scanner_handle handle, std::vector<std::string>* changed = NULL);
|
||
bool get_current_value(scanner_handle handle, const void* option, void(*setv)(void*, size_t, void*), void* value, SANE_Value_Type* type = NULL);
|
||
void* get_default_value(scanner_handle handle, const void* option, int* bytes = nullptr, bool log = false); // caller should call local_utility::free_memory to free the returned value
|
||
|
||
/// <summary>
|
||
/// 关联项处理
|
||
|
||
// 添加对多依赖项的支持 - 2022-03-10
|
||
//std::vector<CURVAL> cur_vals_;
|
||
bool refresh_current_value(LPDEVINST dev, const char* name, json* jsn); // return whether changed old value
|
||
bool refresh_current_value(LPDEVINST dev, const char* name, const char* val);
|
||
|
||
static bool compare_val_equal(const char* cur_val, const char* limit_l, const char* limit_r);
|
||
static bool compare_val_not_equal(const char* cur_val, const char* limit_l, const char* limit_r);
|
||
static bool compare_val_great(const char* cur_val, const char* limit_l, const char* limit_r);
|
||
static bool compare_val_not_less(const char* cur_val, const char* limit_l, const char* limit_r);
|
||
static bool compare_val_less(const char* cur_val, const char* limit_l, const char* limit_r);
|
||
static bool compare_val_not_great(const char* cur_val, const char* limit_l, const char* limit_r);
|
||
static bool compare_val_between(const char* cur_val, const char* limit_l, const char* limit_r);
|
||
static bool compare_val_not_between(const char* cur_val, const char* limit_l, const char* limit_r);
|
||
|
||
static bool is_enable_and(scanner_handle hdev, const std::vector<MASTEROP>& master, std::vector<CURVAL>& curvals);
|
||
static bool is_enable_or(scanner_handle hdev, const std::vector<MASTEROP>& master, std::vector<CURVAL>& curvals);
|
||
//std::vector<SLAVEOP> slave_options_;
|
||
//std::vector<std::string> master_options_;
|
||
|
||
|
||
bool parse_master_option(const char* depend_str, MASTEROP& mo);
|
||
bool parse_depends(scanner_handle h, json* jsn, SLAVEOP& so, std::vector<std::string>& master);
|
||
|
||
bool is_associatived(const SLAVEOP& slave, const char* master_name);
|
||
bool set_stored_option_enabled(scanner_handle h, const void* option, bool enable, int* size = NULL);
|
||
int something_after_do(LPDEVINST dev, const char* master_name, const char* cur_val);
|
||
OPTEN* get_control_enalbe_data(LPDEVINST dev, const SLAVEOP& slave);
|
||
void free_control_enable_data(OPTEN* opt);
|
||
void on_SCANNER_ERR_CONFIGURATION_CHANGED(LPDEVINST dev);
|
||
|
||
std::vector<LPDEVINST> openning_;
|
||
std::vector<LPDEVINST>::iterator find_openning_device_in_que(scanner_handle h);
|
||
std::vector<LPDEVINST>::iterator find_openning_device_in_que(const char* name);
|
||
/// 关联项处理结束
|
||
|
||
static void free_device_inst(LPDEVINST dev, bool del = true);
|
||
scanner_handle find_openning_device(SANE_Handle h, bool rmv = false, LPDEVINST* dev = NULL);
|
||
|
||
protected:
|
||
hg_sane_middleware(void);
|
||
~hg_sane_middleware();
|
||
|
||
public:
|
||
static std::string sane_path(void);
|
||
static hg_sane_middleware* instance(void);
|
||
static void set_callback(sane_callback cb, void* param);
|
||
static void clear(void);
|
||
static std::string option_value_2_string(SANE_Value_Type type, void* val);
|
||
static scanner_handle sane_handle_to_scanner(SANE_Handle h);
|
||
static SANE_Handle scanner_handle_to_sane(scanner_handle h);
|
||
static SANE_Option_Descriptor* allocate_descriptor(const char* name, const char* title, const char* desc);
|
||
static void free_descriptor(SANE_Option_Descriptor* desc);
|
||
static SANE_Option_Descriptor* string_option_to_SANE_descriptor(const char* name, const char* title, const char* desc
|
||
, const std::vector<std::string>& values);
|
||
static SANE_Option_Descriptor* number_option_to_SANE_descriptor(const char* name, const char* title, const char* desc
|
||
, bool double_val, double* lower, double* upper, double* step); // NO constraint if lower or upper were NULL
|
||
static SANE_Option_Descriptor* number_option_to_SANE_descriptor(const char* name, const char* title, const char* desc
|
||
, const std::vector<int>& values); // NO constraint if values was empty
|
||
static SANE_Option_Descriptor* number_option_to_SANE_descriptor(const char* name, const char* title, const char* desc
|
||
, const std::vector<double>& values); // NO constraint if values was empty
|
||
static std::string get_string_in_json(json* jsn, const char* key);
|
||
|
||
// methods ...
|
||
public:
|
||
SANE_Status get_devices(const SANE_Device*** device_list, SANE_Bool local_only);
|
||
SANE_Status open_device(SANE_String_Const devicename, SANE_Handle* handle);
|
||
SANE_Status close_device(SANE_Handle h);
|
||
SANE_Status get_image_parameters(SANE_Handle handle, SANE_Parameters* params);
|
||
SANE_Status start(SANE_Handle h, void* async_event);
|
||
SANE_Status read(SANE_Handle h, void* buf, int* bytes);
|
||
SANE_Status stop(SANE_Handle h);
|
||
|
||
SANE_Option_Descriptor* get_option_descriptor(SANE_Handle h, const void* option);
|
||
SANE_Status set_option(SANE_Handle h, const void* option, SANE_Action action, void* value, SANE_Int* after_do);
|
||
bool get_cur_value(SANE_Handle handle, void* option, void* value, SANE_Value_Type* type = nullptr); // SANE_type
|
||
void* get_cur_value(SANE_Handle handle, void* option, SANE_Value_Type* type = nullptr); // caller should call local_utility::free_memory to free the returned value, SANE_type
|
||
void* get_def_value(SANE_Handle handle, void* option, int* bytes = nullptr, bool log = false); // caller should call local_utility::free_memory to free the returned value, SANE_type
|
||
|
||
// extension ...
|
||
SANE_Status io_control(SANE_Handle h, unsigned long code, void* data, unsigned* len);
|
||
|
||
public:
|
||
bool is_ready(void);
|
||
};
|
||
|
||
namespace local_utility
|
||
{
|
||
void free_memory(void* m);
|
||
int sane_statu_2_scanner_err(int statu);
|
||
}
|