#pragma once #include #include #include #include #include #include #include #include #if defined(WIN32) || defined(_WIN64) #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)) #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 master; bool (*is_enable)(scanner_handle hdev, const std::vector& master , std::vector& 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 opts; std::vector cur_vals; std::vector slaves; std::vector masters; std::map 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 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 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& 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* 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 /// /// 关联项处理 // 添加对多依赖项的支持 - 2022-03-10 //std::vector 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& master, std::vector& curvals); static bool is_enable_or(scanner_handle hdev, const std::vector& master, std::vector& curvals); //std::vector slave_options_; //std::vector master_options_; bool parse_master_option(const char* depend_str, MASTEROP& mo); bool parse_depends(scanner_handle h, json* jsn, SLAVEOP& so, std::vector& 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 openning_; std::vector::iterator find_openning_device_in_que(scanner_handle h); std::vector::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& 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& 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 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); }