#pragma once #include #include #include #include #include #include #include #ifdef WIN32 #define bzero(b, s) memset(b, 0, s) #else #include #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)) class json; class hg_sane_middleware { typedef struct _device_option { std::string dev_name; int option_no; SANE_Option_Descriptor* desc; }DEVOPT; std::vector opts_; 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 openning_; static hg_sane_middleware *inst_; static const SANE_Device** dev_list_; static const SANE_Device** to_sane_device(HGScannerInfo* 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 std::string option_value_2_string(SANE_Value_Type type, void* val); 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, json* jsn, int opt_no); scanner_handle find_openning_device(SANE_Handle h, bool rmv = false, OPENDEV* dev = NULL); std::string get_option_json(scanner_handle handle, int opt_no); SANE_Option_Descriptor* find_stored_descriptor(const char* name, int option); SANE_Option_Descriptor* find_stored_descriptor(SANE_Handle handle, int option); bool get_current_value(scanner_handle handle, int option, void* value, SANE_Value_Type *type = NULL); void reload_current_value(scanner_handle handle, std::vector* changed = NULL); /// /// 关联项处理 // 添加对多依赖项的支持 - 2022-03-10 typedef struct _cur_val { int opt_no; std::string type; std::string val; /*参数全部字符串化*/ bool operator==(int sn) { return opt_no == sn; } }CURVAL; std::vector cur_vals_; bool refresh_current_value(int opt, json* jsn); // return whether changed old value bool refresh_current_value(int opt, 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); typedef struct _master_option { int option_no; 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; static bool is_enable_and(const std::vector& master, std::vector& curvals); static bool is_enable_or(const std::vector& master, std::vector& curvals); typedef struct _slave_option { int option_no; bool enable_now; std::vector master; bool (*is_enable)(const std::vector& master , std::vector& curvals/*参数全部字符串化*/); // logic 'and', 'or' opertions }SLAVEOP; std::vector slave_options_; std::vector master_options_; bool parse_master_option(const char* depend_str, MASTEROP& mo); bool parse_depends(json* jsn, SLAVEOP& so); typedef struct _opt_enabled { int opt_no; bool enable; bool operator==(const int& opt) { return opt_no == opt; } }OPTENABLE; bool is_associatived(const SLAVEOP& slave, int master_opt); bool set_stored_option_enabled(const char* dev_name, int option, bool enable, int* size = NULL); int something_after_do(scanner_handle h, const char* dev_name, int option_no, const char* cur_val); OPTEN* get_control_enalbe_data(const SLAVEOP& slave); void free_control_enable_data(OPTEN* opt); void on_HG_ERR_CONFIGURATION_CHANGED(scanner_handle handle, const char* dev_name); /// 关联项处理结束 protected: hg_sane_middleware(void); ~hg_sane_middleware(); public: static hg_sane_middleware* instance(void); static void clear(void); static scanner_handle sane_handle_to_scanner(SANE_Handle h); static SANE_Handle scanner_handle_to_sane(scanner_handle h); static SANE_Option_Descriptor* string_option_to_SANE_descriptor(const char* name, const char* title, const char* desc , const std::vector& 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); // 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& 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& values); // NO constraint if values was empty // 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, SANE_Int option); SANE_Status set_option(SANE_Handle h, SANE_Int option, SANE_Action action, void* value, SANE_Int* after_do); // extension ... SANE_Status io_control(SANE_Handle h, unsigned long code, void* data, unsigned* len); public: };