code_device/hgsane/sane_hg_mdw.h

248 lines
9.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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, bool* can_auto = nullptr); // 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);
}