2022-06-15 03:04:40 +00:00
# include " scanner.h "
# include <Windows.h>
2022-10-08 09:20:16 +00:00
# include <Shlwapi.h> // for PathFileExistsW
2022-06-15 03:04:40 +00:00
# include "../sdk/hginclude/huagaoxxx_warraper_ex.h"
# include <sane/sane_option_definitions.h>
# include "../../code_device/hgsane/sane_hg_mdw.h"
# include "sane_option_trans.h"
# include <chrono>
2022-06-18 00:54:01 +00:00
# include <mutex>
2022-06-18 08:48:41 +00:00
# include "DlgIndicator.h"
2022-06-20 07:17:55 +00:00
# include "DlgSetting.h"
2022-07-01 07:24:58 +00:00
# include "gb_json.h"
2023-01-29 07:03:32 +00:00
# include "../../sdk/include/lang/app_language.h"
2023-04-04 05:50:10 +00:00
# include <functional>
2022-06-15 03:04:40 +00:00
2022-10-08 09:20:16 +00:00
# pragma comment(lib, "Shlwapi.lib")
2022-06-15 03:04:40 +00:00
static IMPLEMENT_OPTION_STRING_COMPARE ( compare_sane_opt ) ;
2022-10-07 09:51:09 +00:00
# define SET_SANE_OPT_ID(id, id_name, name, val, extension) \
if ( strcmp ( SANE_STD_OPT_NAME_ # # name , val ) = = 0 ) \
2022-06-15 03:04:40 +00:00
{ \
id_name # # _id_ = id ; \
extension ( id ) ; \
}
2022-09-19 06:16:34 +00:00
# ifdef EXPORT_SANE_API
__declspec ( dllexport )
# else
__declspec ( dllimport )
# endif
void __stdcall log_info ( const wchar_t * info , int level ) ;
2022-06-18 00:54:01 +00:00
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// callback
2022-06-20 07:17:55 +00:00
extern " C "
{
extern SANE_Status inner_sane_init ( SANE_Int * version_code , SANE_Auth_Callback authorize ) ;
extern void inner_sane_exit ( void ) ;
extern SANE_Status inner_sane_get_devices ( const SANE_Device * * * device_list , SANE_Bool local_only ) ;
extern SANE_Status inner_sane_open ( SANE_String_Const devicename , SANE_Handle * handle ) ;
extern void inner_sane_close ( SANE_Handle handle ) ;
extern const SANE_Option_Descriptor * inner_sane_get_option_descriptor ( SANE_Handle handle , SANE_Int option ) ;
extern SANE_Status inner_sane_control_option ( SANE_Handle handle , SANE_Int option , SANE_Action action , void * value , SANE_Int * info ) ;
extern SANE_Status inner_sane_get_parameters ( SANE_Handle handle , SANE_Parameters * params ) ;
extern SANE_Status inner_sane_start ( SANE_Handle handle ) ;
extern SANE_Status inner_sane_read ( SANE_Handle handle , SANE_Byte * data , SANE_Int max_length , SANE_Int * length ) ;
extern void inner_sane_cancel ( SANE_Handle handle ) ;
extern SANE_Status inner_sane_set_io_mode ( SANE_Handle handle , SANE_Bool non_blocking ) ;
extern SANE_Status inner_sane_get_select_fd ( SANE_Handle handle , SANE_Int * fd ) ;
extern SANE_String_Const inner_sane_strstatus ( SANE_Status status ) ;
extern SANE_Status inner_sane_init_ex ( SANE_Int * version_code , sane_callback cb , void * param ) ;
extern SANE_Status inner_sane_io_control ( SANE_Handle h , unsigned long code , void * data , unsigned * len ) ;
2022-10-21 08:46:20 +00:00
extern const char * inner_sane_err_desc ( SANE_Status err ) ;
2022-06-20 07:17:55 +00:00
}
2022-06-18 00:54:01 +00:00
namespace callback
{
static std : : mutex cb_lock_ ;
typedef struct _scanner_inst
{
SANE_Handle dev ;
scanner * invoker ;
bool operator = = ( const SANE_Handle & h )
{
return dev = = h ;
}
bool operator = = ( const scanner * obj )
{
return invoker = = obj ;
}
} SCNINST ;
std : : vector < SCNINST > g_scanner_instances ;
int sane_event_callback ( // 注册回调的对象,需要保证该回调是多线程安全的
SANE_Handle hdev // 产生事件的设备句柄
, int code // 回调事件代码
, void * data // 回调事件数据,根据事件代码有所不同,参照具体事件定义
, unsigned int * len // 数据长度( 字节) , 或者event_data的缓冲区长度, 详细请看相应的事件代码
, void * param // 用户自定义数据, 与调用sane_init_ex传入时的保持一致
) // 返回值依不同的事件代码而定, 通常为“0”
{
std : : lock_guard < std : : mutex > lock ( cb_lock_ ) ;
std : : vector < SCNINST > : : iterator it = std : : find ( g_scanner_instances . begin ( ) , g_scanner_instances . end ( ) , hdev ) ;
if ( it ! = g_scanner_instances . end ( ) )
2022-07-02 09:27:21 +00:00
return it - > invoker - > handle_device_event ( code , data , len ) ;
2022-06-18 00:54:01 +00:00
else
2022-09-21 08:44:41 +00:00
{
wchar_t msg [ 218 ] = { 0 } ;
swprintf_s ( msg , _countof ( msg ) - 1 , L " Lost device(0x%08X) when event(%u) occurs! \r \n " , hdev , code ) ;
log_info ( msg , 0 ) ;
2022-06-18 00:54:01 +00:00
return 0 ;
2022-09-21 08:44:41 +00:00
}
2022-06-18 00:54:01 +00:00
}
void reg_callback ( SANE_Handle dev , scanner * invoker )
{
std : : lock_guard < std : : mutex > lock ( cb_lock_ ) ;
std : : vector < SCNINST > : : iterator it = std : : find ( g_scanner_instances . begin ( ) , g_scanner_instances . end ( ) , dev ) ;
if ( it = = g_scanner_instances . end ( ) )
{
SCNINST inst ;
inst . dev = dev ;
inst . invoker = invoker ;
g_scanner_instances . push_back ( inst ) ;
}
else
it - > invoker = invoker ;
}
void unreg_callback ( scanner * invoker )
{
std : : lock_guard < std : : mutex > lock ( cb_lock_ ) ;
std : : vector < SCNINST > : : iterator it = std : : find ( g_scanner_instances . begin ( ) , g_scanner_instances . end ( ) , invoker ) ;
if ( it ! = g_scanner_instances . end ( ) )
g_scanner_instances . erase ( it ) ;
}
2022-10-08 06:13:09 +00:00
struct
{
const char * name ;
const char * title ;
} g_opts [ ] = { { SANE_STD_OPT_NAME_RESTORE , OPTION_TITLE_HFMRSZ }
, { SANE_STD_OPT_NAME_HELP , OPTION_TITLE_BZ }
, { SANE_STD_OPT_NAME_IS_MULTI_OUT , OPTION_TITLE_DLSC }
, { SANE_STD_OPT_NAME_MULTI_OUT_TYPE , OPTION_TITLE_DLSCLX }
, { SANE_STD_OPT_NAME_COLOR_MODE , OPTION_TITLE_YSMS }
, { SANE_STD_OPT_NAME_BINARY_THRESHOLD , OPTION_TITLE_HBTXYZ }
, { SANE_STD_OPT_NAME_REVERSE_01 , OPTION_TITLE_HBTXFSSC }
, { SANE_STD_OPT_NAME_FILTER , OPTION_TITLE_HDHHBTX_CSYZQ }
, { SANE_STD_OPT_NAME_RID_MULTIOUT_RED , OPTION_TITLE_24WCSTX_DLSCCH }
, { SANE_STD_OPT_NAME_RID_ANSWER_SHEET_RED , OPTION_TITLE_24WCSTX_DTKCH }
, { SANE_STD_OPT_NAME_ERASE_BACKGROUND , OPTION_TITLE_BJYC }
, { SANE_STD_OPT_NAME_BKG_COLOR_RANGE , OPTION_TITLE_BJSCFDFW }
, { SANE_STD_OPT_NAME_SHARPEN , OPTION_TITLE_RHYMH }
, { SANE_STD_OPT_NAME_RID_MORR , OPTION_TITLE_QCMW }
, { SANE_STD_OPT_NAME_RID_GRID , OPTION_TITLE_CWW }
, { SANE_STD_OPT_NAME_ERROR_EXTENSION , OPTION_TITLE_CWKS }
, { SANE_STD_OPT_NAME_NOISE_OPTIMIZE , OPTION_TITLE_HBTXZDYH }
, { SANE_STD_OPT_NAME_NOISE_SIZE , OPTION_TITLE_ZDYHCC }
, { SANE_STD_OPT_NAME_PAPER , OPTION_TITLE_ZZCC }
, { SANE_STD_OPT_NAME_CUSTOM_AREA , OPTION_TITLE_ZDYSMQY }
, { SANE_STD_OPT_NAME_CUSTOM_AREA_LEFT , OPTION_TITLE_SMQYZCmm }
, { SANE_STD_OPT_NAME_CUSTOM_AREA_RIGHT , OPTION_TITLE_SMQYYCmm }
, { SANE_STD_OPT_NAME_CUSTOM_AREA_TOP , OPTION_TITLE_SMQYSCmm }
, { SANE_STD_OPT_NAME_CUSTOM_AREA_BOTTOM , OPTION_TITLE_SMQYXCmm }
, { SANE_STD_OPT_NAME_SIZE_CHECK , OPTION_TITLE_CCJC }
, { SANE_STD_OPT_NAME_PAGE , OPTION_TITLE_SMYM }
, { SANE_STD_OPT_NAME_DISCARD_BLANK_SENS , OPTION_TITLE_TGKBYLMD }
, { SANE_STD_OPT_NAME_RESOLUTION , OPTION_TITLE_FBL }
, { SANE_STD_OPT_NAME_TIME_TO_SLEEP , OPTION_TITLE_XMSJ }
, { SANE_STD_OPT_NAME_IMAGE_QUALITY , OPTION_TITLE_HZ }
, { SANE_STD_OPT_NAME_EXCHANGE , OPTION_TITLE_JHZFM }
, { SANE_STD_OPT_NAME_SPLIT , OPTION_TITLE_TXCF }
, { SANE_STD_OPT_NAME_ANTI_SKEW , OPTION_TITLE_ZDJP }
, { SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA , OPTION_TITLE_QYSDQX }
, { SANE_STD_OPT_NAME_GAMMA , OPTION_TITLE_JMZ }
, { SANE_STD_OPT_NAME_BRIGHTNESS , OPTION_TITLE_LDZ }
, { SANE_STD_OPT_NAME_CONTRAST , OPTION_TITLE_DBD }
, { SANE_STD_OPT_NAME_IS_PHOTO_MODE , OPTION_TITLE_ZPMS }
, { SANE_STD_OPT_NAME_ERASE_BLACK_FRAME , OPTION_TITLE_XCHK }
, { SANE_STD_OPT_NAME_DARK_SAMPLE , OPTION_TITLE_SSYZ }
, { SANE_STD_OPT_NAME_THRESHOLD , OPTION_TITLE_YZ }
, { SANE_STD_OPT_NAME_ANTI_NOISE_LEVEL , OPTION_TITLE_BJKZDJ }
, { SANE_STD_OPT_NAME_MARGIN , OPTION_TITLE_BYSJ }
, { SANE_STD_OPT_NAME_FILL_BKG_MODE , OPTION_TITLE_BJTCFS }
, { SANE_STD_OPT_NAME_IS_ANTI_PERMEATE , OPTION_TITLE_FZST }
, { SANE_STD_OPT_NAME_ANTI_PERMEATE_LEVEL , OPTION_TITLE_FZSTDJ }
, { SANE_STD_OPT_NAME_RID_HOLE_L , OPTION_TITLE_CKYCZC }
, { SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_L , OPTION_TITLE_ZCCKSSFWZFMBL }
, { SANE_STD_OPT_NAME_RID_HOLE_R , OPTION_TITLE_CKYCYC }
, { SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_R , OPTION_TITLE_YCCKSSFWZFMBL }
, { SANE_STD_OPT_NAME_RID_HOLE_T , OPTION_TITLE_CKYCSC }
, { SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_T , OPTION_TITLE_SCCKSSFWZFMBL }
, { SANE_STD_OPT_NAME_RID_HOLE_B , OPTION_TITLE_CKYCXC }
, { SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_B , OPTION_TITLE_XCCKSSFWZFMBL }
, { SANE_STD_OPT_NAME_IS_FILL_COLOR , OPTION_TITLE_SCTC }
, { SANE_STD_OPT_NAME_IS_ULTROSONIC_CHECK , OPTION_TITLE_CSBJC }
, { SANE_STD_OPT_NAME_DOUBLE_FEED_HANDLE , OPTION_TITLE_SZTPCL }
, { SANE_STD_OPT_NAME_IS_CHECK_STAPLE , OPTION_TITLE_ZDJC }
, { SANE_STD_OPT_NAME_SCAN_MODE , OPTION_TITLE_SMZS }
, { SANE_STD_OPT_NAME_SCAN_COUNT , OPTION_TITLE_SMSL }
, { SANE_STD_OPT_NAME_TEXT_DIRECTION , OPTION_TITLE_WGFX }
, { SANE_STD_OPT_NAME_IS_ROTATE_BKG_180 , OPTION_TITLE_BMXZ180 }
, { SANE_STD_OPT_NAME_IS_CHECK_DOG_EAR , OPTION_TITLE_ZJJC }
, { SANE_STD_OPT_NAME_DOG_EAR_SIZE , OPTION_TITLE_ZJDX }
, { SANE_STD_OPT_NAME_IS_CHECK_ASKEW , OPTION_TITLE_WXJC }
, { SANE_STD_OPT_NAME_ASKEW_RANGE , OPTION_TITLE_WXRRD }
, { SANE_STD_OPT_NAME_FEED_STRENGTH , OPTION_TITLE_FZQD }
, { SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , OPTION_TITLE_ZDFZQD }
, { SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , OPTION_TITLE_JZSBL }
, { SANE_STD_OPT_NAME_WAIT_TO_SCAN , OPTION_TITLE_DZSM }
2023-02-24 09:44:47 +00:00
, { SANE_STD_OPT_NAME_FOLD_TYPE , OPTION_TITLE_DZMS }
, { SANE_STD_OPT_NAME_COLOR_CORRECTION , OPTION_TITLE_SPJZ }
2022-10-08 06:13:09 +00:00
} ,
g_discard [ ] = { { SANE_STD_OPT_NAME_REVERSE_01 , " \351 \273 \221 \347 \231 \275 \345 \233 \276 \345 \203 \217 \345 \217 \215 \350 \211 \262 \350 \276 \223 \345 \207 \272 \357 \274 \210 \346 \255 \243 \345 \270 \270 \351 \242 \234 \350 \211 \262 \344 \270 \272 \357 \274 \232 0- \351 \273 \221 \350 \211 \262 \357 \274 \233 1- \347 \231 \275 \350 \211 \262 \357 \274 \211 " } // 黑白图像反色输出( 正常颜色为: 0-黑色; 1-白色)
, { SANE_STD_OPT_NAME_FILTER , " \347 \201 \260 \345 \272 \246 \346 \210 \226 \351 \273 \221 \347 \231 \275 \345 \233 \276 \345 \203 \217 - \351 \231 \244 \350 \211 \262 " } // 灰度或黑白图像 - 除色
, { SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , " \350 \207 \252 \345 \212 \250 \346 \220 \223 \347 \272 \270 \345 \274 \272 \345 \272 \246 " } // 自动搓纸强度
, { SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , " \346 \220 \223 \347 \272 \270 \351 \230 \210 \345 \200 \274 " } // " 搓纸阈值"
} ;
2022-10-28 09:09:59 +00:00
const char * option_title_2_name ( const char * title )
2022-10-08 06:13:09 +00:00
{
while ( * title = = ' ' )
title + + ;
for ( size_t i = 0 ; i < _countof ( g_discard ) ; + + i )
{
if ( strcmp ( title , g_discard [ i ] . title ) = = 0 )
return g_discard [ i ] . name ;
}
for ( size_t i = 0 ; i < _countof ( g_opts ) ; + + i )
{
if ( strcmp ( title , g_opts [ i ] . title ) = = 0 )
return g_opts [ i ] . name ;
}
return " " ;
}
const char * __stdcall option_name_2_title ( const char * name )
{
for ( size_t i = 0 ; i < _countof ( g_opts ) ; + + i )
{
if ( strcmp ( name , g_opts [ i ] . name ) = = 0 )
return g_opts [ i ] . title ;
}
return " " ;
}
2022-10-21 08:46:20 +00:00
static BOOL CALLBACK main_wnd ( HWND hwnd , LPARAM param )
{
DWORD pid = 0 ;
GetWindowThreadProcessId ( hwnd , & pid ) ;
if ( pid ! = GetCurrentProcessId ( ) )
return TRUE ;
if ( ( ( void * * ) param ) [ 1 ] = = NULL )
{
HWND parent = GetParent ( hwnd ) ;
while ( IsWindow ( parent ) )
{
hwnd = parent ;
parent = GetParent ( hwnd ) ;
}
parent = hwnd ;
if ( ! IsWindowVisible ( parent ) )
return TRUE ;
RECT r = { 0 } ;
GetWindowRect ( parent , & r ) ;
if ( RECT_H ( r ) > 50 & & RECT_W ( r ) > 50 )
{
* ( HWND * ) param = parent ;
return FALSE ;
}
}
else
{
wchar_t val [ 128 ] = { 0 } ;
GetClassNameW ( hwnd , val , _countof ( val ) - 1 ) ;
if ( wcscmp ( val , L " #32770 " ) )
return TRUE ;
GetWindowTextW ( hwnd , val , _countof ( val ) - 1 ) ;
if ( * ( ( std : : wstring * * ) param ) [ 1 ] = = val )
{
* ( HWND * ) param = hwnd ;
return FALSE ;
}
}
return TRUE ;
}
static HWND find_main_wnd ( void )
{
HWND wnd [ 2 ] = { NULL } ;
EnumWindows ( main_wnd , ( LPARAM ) wnd ) ;
return wnd [ 0 ] ;
}
static DWORD WINAPI btm ( LPVOID para )
{
std : : wstring * title [ 2 ] = { NULL , ( std : : wstring * ) para } ;
Sleep ( 100 ) ;
EnumWindows ( main_wnd , ( LPARAM ) title ) ;
if ( IsWindow ( ( HWND ) title [ 0 ] ) )
{
RECT r = { 0 } ;
GetWindowRect ( ( HWND ) title [ 0 ] , & r ) ;
SetWindowPos ( ( HWND ) title [ 0 ] , HWND_TOPMOST , r . left , r . top , RECT_W ( r ) , RECT_H ( r ) , SWP_SHOWWINDOW | SWP_NOSENDCHANGING ) ;
SetFocus ( ( HWND ) title [ 0 ] ) ;
}
delete title [ 1 ] ;
return 0 ;
}
static void bring_message_box_topmost ( const wchar_t * title )
{
DWORD id = 0 ;
std : : wstring * t ( new std : : wstring ( title ) ) ;
HANDLE h = CreateThread ( NULL , 0 , btm , t , 0 , & id ) ;
if ( h )
CloseHandle ( h ) ;
else
delete t ;
}
2023-02-07 08:55:51 +00:00
static const char * __stdcall language_trans ( const char * in , bool from_hz , void * param )
{
if ( from_hz )
return from_default_language ( in , nullptr ) ;
else
return to_default_language ( in , nullptr ) ;
}
2023-04-04 05:50:10 +00:00
// UI ...
//
// events code, see SANE_Event
//
// callback events: SANE_EVENT_UI_CLOSE_CANCEL/SANE_EVENT_UI_CLOSE_NORMAL/SANE_EVENT_UI_SCAN_COMMAND/SANE_EVENT_UI_CLOSE_SETTING
//
// notify events: SANE_EVENT_WORKING - void*: unused, be NULL, flag - unused, be 0
// SANE_EVENT_SCAN_FINISHED - void*: (utf8*)message, flag - error code (0 is success)
// SANE_EVENT_USB_DATA_RECEIVED- void* unused, be NULL, flag - unused, be 0
// SANE_EVENT_IMAGE_OK - void* unused, be NULL, flag - unused, be 0
int ( * choose_scanner ) ( const std : : vector < DEVQUE > & devs ) = NULL ; // blocked. return selected DEVQUE::id or -1 if user cancelled
void ( * apply_current_config ) ( const char * dev_name , SANE_Handle device , LPSANEAPI api ) = NULL ; // 应用设备的当前配置
void ( * show_setting_ui ) ( SANE_Handle device , HWND parent , LPSANEAPI api , bool with_scan /*是否显示“扫描”按钮*/ , std : : function < void ( int ) > callback ) = NULL ;
void ( * show_progress_ui ) ( HWND parent , std : : function < void ( int ) > callback , std : : function < void ( int /*event*/ , void */ * msg */ , int /*flag*/ ) > * notify ) = NULL ;
static void init_ui ( void )
{
std : : string root ( hg_sane_middleware : : sane_path ( ) ) ;
HMODULE mod = NULL ;
2023-04-20 07:09:19 +00:00
root + = " HGTwainUI.dll " ;
mod = LoadLibraryExA ( root . c_str ( ) , NULL , LOAD_WITH_ALTERED_SEARCH_PATH ) ;
2023-04-04 05:50:10 +00:00
if ( ! mod )
{
std : : wstring info ( L " Load ' " + local_trans : : a2u ( root . c_str ( ) , CP_UTF8 ) ) ;
info + = L " ' failed: " + std : : to_wstring ( GetLastError ( ) ) + L " \r \n " ;
log_info ( info . c_str ( ) , 0 ) ;
}
else
{
# define GET_API(api) \
proc = ( FARPROC * ) & api ; \
* proc = GetProcAddress ( mod , # api ) ;
FARPROC * proc = NULL ;
GET_API ( choose_scanner ) ;
GET_API ( apply_current_config ) ;
GET_API ( show_setting_ui ) ;
GET_API ( show_progress_ui ) ;
}
}
2022-06-18 00:54:01 +00:00
}
2022-06-15 03:04:40 +00:00
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// class scanner
scanner : : scanner ( SCANNERID id ) : handle_ ( NULL ) , id_ ( id ) , ex_id_ ( EXTENSION_ID_BASE ) , prev_start_result_ ( SCANNER_ERR_NOT_START )
2022-07-02 09:27:21 +00:00
, dpi_ ( 200 ) , tmp_path_ ( L " " ) , img_ind_ ( 0 )
2022-09-19 06:16:34 +00:00
, scanner_name_ ( L " " ) , cfg_ ( NULL ) , is_ui_wait_img_ ( false ) , is_scanning_ ( false )
2022-11-25 06:20:06 +00:00
, scanner_ev_handler_ ( NULL ) , evh_param_ ( NULL ) , app_wnd_ ( NULL ) , user_cancel_ ( false )
2023-03-28 07:02:24 +00:00
, max_img_mem_ ( 1 * 1024 ) , twain_set_ ( false ) , ev_cnt_ ( 0 )
2022-06-15 03:04:40 +00:00
{
2023-04-04 05:50:10 +00:00
sane_api_ . sane_cancel_api = inner_sane_cancel ;
sane_api_ . sane_close_api = inner_sane_close ;
sane_api_ . sane_control_option_api = inner_sane_control_option ;
sane_api_ . sane_get_devices_api = inner_sane_get_devices ;
sane_api_ . sane_get_option_descriptor_api = inner_sane_get_option_descriptor ;
sane_api_ . sane_get_parameters_api = inner_sane_get_parameters ;
sane_api_ . sane_get_select_fd_api = inner_sane_get_select_fd ;
sane_api_ . sane_io_control_api = inner_sane_io_control ;
sane_api_ . sane_open_api = inner_sane_open ;
sane_api_ . sane_read_api = inner_sane_read ;
sane_api_ . sane_set_io_mode_api = inner_sane_set_io_mode ;
sane_api_ . sane_start_api = inner_sane_start ;
sane_api_ . sane_strstatus_api = inner_sane_strstatus ;
if ( ! callback : : show_setting_ui )
{
cfg_ = new gb : : scanner_cfg ( ) ;
cfg_ - > set_language_transform ( & callback : : language_trans , NULL ) ;
}
2023-02-07 08:55:51 +00:00
2022-06-16 08:04:58 +00:00
tmp_path_ = local_trans : : a2u ( hg_sane_middleware : : sane_path ( ) . c_str ( ) ) ;
2022-09-23 06:17:41 +00:00
{
char * tmp = getenv ( " LOCALAPPDATA " ) ;
if ( tmp )
{
tmp_path_ = local_trans : : a2u ( tmp ) + L " \\ " ;
tmp_path_ + = local_trans : : a2u ( PRODUCT_VENDOR ) + L " Scan \\ " ;
CreateDirectoryW ( tmp_path_ . c_str ( ) , NULL ) ;
}
}
2022-07-01 07:24:58 +00:00
cfg_path_ = tmp_path_ + L " config " ;
CreateDirectoryW ( cfg_path_ . c_str ( ) , NULL ) ;
cfg_path_ + = L " \\ " ;
2022-06-16 08:04:58 +00:00
tmp_path_ + = L " imgs " ;
CreateDirectoryW ( tmp_path_ . c_str ( ) , NULL ) ;
tmp_path_ + = L " \\ " ;
2022-06-23 06:01:28 +00:00
img_fmt_ . img_format = SANE_IMAGE_TYPE_BMP ;
2022-06-29 08:13:05 +00:00
img_fmt_ . compress . compression = SANE_COMPRESSION_NONE ;
2022-06-16 08:04:58 +00:00
2022-11-25 06:20:06 +00:00
int mem_limit = GetPrivateProfileIntW ( L " mem " , L " max_img " , 0 , ( cfg_path_ + L " debug.cfg " ) . c_str ( ) ) ;
if ( mem_limit > 0 )
{
2022-11-26 08:07:52 +00:00
// this value is same as driver memory limit ...
max_img_mem_ = mem_limit ;
2022-11-25 06:20:06 +00:00
}
2022-06-15 03:04:40 +00:00
err_ = open ( ) ;
}
scanner : : ~ scanner ( )
2022-06-18 00:54:01 +00:00
{
2022-09-23 06:17:41 +00:00
close ( ) ;
2022-07-01 07:24:58 +00:00
if ( cfg_ )
2022-10-25 08:41:09 +00:00
{
cfg_ - > release ( ) ;
cfg_ = NULL ;
}
2022-06-18 00:54:01 +00:00
}
2022-06-15 03:04:40 +00:00
2022-10-09 03:59:45 +00:00
bool scanner : : is_belong_serial ( int vid , int pid , SCANNERID serial )
{
if ( vid = = PRODUCT_VENDOR_HG )
{
if ( GET_SCANNER_VID ( serial ) = = PRODUCT_VENDOR_HG )
{
if ( GET_SCANNER_PID ( serial ) = = 0x100 )
{
2022-11-17 02:26:53 +00:00
return pid = = 0x100 | | pid = = 0x139 ;
2022-10-09 03:59:45 +00:00
}
else if ( GET_SCANNER_PID ( serial ) = = 0x200 )
{
return pid = = 0x200 | | pid = = 0x239 ;
}
else if ( GET_SCANNER_PID ( serial ) = = 0x300 )
{
return pid = = 0x300 | | pid = = 0x302 | | pid = = 0x339 ;
}
else if ( GET_SCANNER_PID ( serial ) = = 0x400 )
{
return pid = = 0x400 | | pid = = 0x402 | | pid = = 0x439 ;
}
2022-11-17 02:26:53 +00:00
else if ( GET_SCANNER_PID ( serial ) = = 0x138 | |
GET_SCANNER_PID ( serial ) = = 0x238 | |
GET_SCANNER_PID ( serial ) = = 0x303 | |
GET_SCANNER_PID ( serial ) = = 0x404 ) // OEM_CANGTIAN
return true ;
2022-10-09 03:59:45 +00:00
}
2023-01-13 09:46:27 +00:00
return false ;
2022-10-09 03:59:45 +00:00
}
else if ( vid = = PRODUCT_VENDOR_HG1 )
{
return pid = = 0x7823 & & GET_SCANNER_VID ( serial ) = = PRODUCT_VENDOR_HG & & GET_SCANNER_PID ( serial ) = = 0x200 ;
}
else if ( vid = = PRODUCT_VENDOR_HW )
{
return GET_SCANNER_VID ( serial ) = = vid & & GET_SCANNER_PID ( serial ) = = pid ;
}
else if ( vid = = PRODUCT_VENDOR_LSC )
{
if ( GET_SCANNER_VID ( serial ) = = PRODUCT_VENDOR_LSC )
{
if ( GET_SCANNER_PID ( serial ) = = 0x8420 )
{
return pid = = 0x8200 | | pid = = 0x8420 | | pid = = 0x8429 ;
}
else if ( GET_SCANNER_PID ( serial ) = = 0x8520 )
{
return pid = = 0x8520 | | pid = = 0x8529 ;
}
else if ( GET_SCANNER_PID ( serial ) = = 0x8620 )
{
return pid = = 0x8620 | | pid = = 0x8629 ;
}
else if ( GET_SCANNER_PID ( serial ) = = 0x8730 )
{
return pid = = 0x8730 | | pid = = 0x8739 ;
}
}
2023-01-13 09:46:27 +00:00
return false ;
2022-10-09 03:59:45 +00:00
}
2023-01-13 09:46:27 +00:00
return true ;
2022-10-09 03:59:45 +00:00
}
void scanner : : get_scanner_name ( SCANNERID id , std : : vector < std : : string > & names )
2022-06-15 03:04:40 +00:00
{
ScannerInfo * devs = NULL ;
long count = 0 ;
2022-10-09 03:59:45 +00:00
names . clear ( ) ;
2022-06-15 03:04:40 +00:00
if ( hg_scanner_enum ( devs , & count , true ) = = SCANNER_ERR_INSUFFICIENT_MEMORY )
{
count + + ;
devs = new ScannerInfo [ count ] ;
2022-10-09 03:59:45 +00:00
memset ( devs , 0 , count * sizeof ( * devs ) ) ;
2022-06-15 03:04:40 +00:00
if ( hg_scanner_enum ( devs , & count , true ) = = SCANNER_ERR_OK )
{
for ( int i = 0 ; i < count ; + + i )
{
2022-10-09 03:59:45 +00:00
if ( scanner : : is_belong_serial ( devs [ i ] . vid , devs [ i ] . pid , id ) )
2022-06-15 03:04:40 +00:00
{
2022-10-09 03:59:45 +00:00
names . push_back ( devs [ i ] . name ) ;
2022-06-15 03:04:40 +00:00
}
}
}
delete [ ] devs ;
}
}
value_type scanner : : from_sane_type ( SANE_Value_Type type )
{
if ( type = = SANE_TYPE_BOOL )
return VAL_TYPE_BOOL ;
else if ( type = = SANE_TYPE_INT )
return VAL_TYPE_INT ;
else if ( type = = SANE_TYPE_FIXED )
return VAL_TYPE_FLOAT ;
else if ( type = = SANE_TYPE_STRING )
return VAL_TYPE_STR ;
else
return VAL_TYPE_NONE ;
}
value_limit scanner : : from_sane_constraint ( SANE_Constraint_Type type )
{
if ( type = = SANE_CONSTRAINT_RANGE )
return VAL_LIMIT_RANGE ;
else if ( type = = SANE_CONSTRAINT_STRING_LIST | | type = = SANE_CONSTRAINT_WORD_LIST )
return VAL_LIMIT_ENUM ;
else
return VAL_LIMIT_NONE ;
}
2022-10-09 03:59:45 +00:00
int scanner : : control_read_string ( SANE_Handle hdev , int code , std : : string & str )
{
char * buf = NULL ;
unsigned len = 0 ;
int err = hg_sane_middleware : : instance ( ) - > io_control ( hdev , code , buf , & len ) ;
str = " " ;
if ( err = = SANE_STATUS_NO_MEM )
{
len + = 4 ;
buf = new char [ len ] ;
memset ( buf , 0 , len ) ;
err = hg_sane_middleware : : instance ( ) - > io_control ( hdev , code , buf , & len ) ;
if ( err = = SANE_STATUS_GOOD )
str = buf ;
delete [ ] buf ;
}
return err ;
}
2022-06-15 03:04:40 +00:00
int __stdcall scanner : : to_int ( SANE_Int v )
{
return v ;
}
float __stdcall scanner : : to_float ( SANE_Fixed v )
{
2022-07-18 02:55:01 +00:00
return ( float ) SANE_UNFIX ( v ) ;
2022-06-15 03:04:40 +00:00
}
2022-07-02 09:27:21 +00:00
void __stdcall scanner : : ui_callback ( int uev , void * sender , void * param )
2022-06-18 08:48:41 +00:00
{
2022-07-02 09:27:21 +00:00
( ( scanner * ) param ) - > on_ui_event ( uev , sender ) ;
2022-06-18 08:48:41 +00:00
}
2022-10-28 09:09:59 +00:00
bool scanner : : is_option_float ( int sn , void * param )
2022-10-08 06:13:09 +00:00
{
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( ( SANE_Handle ) param , ( const void * ) sn ) ;
2022-10-08 06:13:09 +00:00
if ( desc )
return desc - > type = = SANE_TYPE_FIXED ;
else
return false ;
}
2023-02-07 08:55:51 +00:00
void __stdcall scanner : : apply_scheme ( gb : : sane_config_schm * schm , void * param )
{
( ( scanner * ) param ) - > apply_scheme ( schm ) ;
}
2022-06-15 03:04:40 +00:00
// IRef
COM_API_IMPLEMENT ( scanner , long , add_ref ( void ) )
{
return refer : : add_ref ( ) ;
}
COM_API_IMPLEMENT ( scanner , long , release ( void ) )
{
return refer : : release ( ) ;
}
2022-10-08 09:20:16 +00:00
void scanner : : transport_config_file ( void )
{
size_t pos = scanner_name_ . find ( L " - " ) ;
std : : wstring pid ( L " G " ) , old ( L " " ) ;
if ( pos = = std : : wstring : : npos )
return ;
pid + = scanner_name_ . substr ( pos + 3 ) ;
if ( scanner_name_ . find ( L " HUAGOSCAN " ) ! = std : : wstring : : npos )
{
2023-02-07 08:55:51 +00:00
old = local_trans : : lang_trans_between_hz936 ( L " \u534E \u9AD8 \u626B \u63CF \u4EEA \u2014 " ) ;
2022-10-08 09:20:16 +00:00
}
else if ( scanner_name_ . find ( L " LANXUMSCAN " ) ! = std : : wstring : : npos )
{
2023-02-07 08:55:51 +00:00
old = local_trans : : lang_trans_between_hz936 ( L " \u7ACB \u601D \u8FB0 \u626B \u63CF \u4EEA \u2014 " ) ;
2022-10-08 09:20:16 +00:00
pid + = L " S " ;
}
old + = pid ;
if ( PathFileExistsW ( ( cfg_path_ + old ) . c_str ( ) ) )
{
log_info ( ( L " Rename config file ' " + old + L " ' to ' " + scanner_name_ . substr ( 0 , pos ) + L " ' \r \n " ) . c_str ( ) , 0 ) ;
MoveFileW ( ( cfg_path_ + old ) . c_str ( ) , ( cfg_path_ + scanner_name_ . substr ( 0 , pos ) ) . c_str ( ) ) ;
}
}
2022-10-08 06:13:09 +00:00
void scanner : : update_config ( void )
{
2023-04-04 05:50:10 +00:00
if ( ! cfg_ )
return ;
2023-02-07 08:55:51 +00:00
gb : : sane_config_schm * schm = cfg_ - > get_scheme ( ) ;
2022-10-08 06:13:09 +00:00
std : : string notice ( " " ) ;
2023-02-07 08:55:51 +00:00
if ( schm )
{
//schm->update(&scanner::is_option_float, handle_, &callback::option_title_2_name, ¬ice);
//if (notice.length())
//{
// std::wstring msg(local_trans::lang_trans_between_hz936(L"\u4E0B\u5217\u914D\u7F6E\u6570\u636E\u9519\u8BEF\uFF0C\u5DF2\u7ECF\u6062\u590D\u5230\u9ED8\u8BA4\u503C\u3002\u5982\u679C\u9700\u8981\uFF0C\u8BF7\u91CD\u65B0\u8BBE\u7F6E") + L"\r\n\r\n");
// size_t pos = notice.find("\r\n");
//
// while (pos != std::string::npos)
// {
// msg += local_trans::a2u(callback::option_name_2_title(notice.substr(0, pos).c_str()), CP_UTF8) + L"\r\n";
// notice.erase(0, pos + 2);
// pos = notice.find("\r\n");
// }
// if (!IsWindow(app_wnd_))
// callback::bring_message_box_topmost(local_trans::lang_trans_between_hz936(L"\u52A0\u8F7D\u914D\u7F6E").c_str());
// MessageBoxW(app_wnd_, msg.c_str(), local_trans::lang_trans_between_hz936(L"\u52A0\u8F7D\u914D\u7F6E").c_str(), MB_OK | MB_ICONINFORMATION);
//}
schm - > release ( ) ;
2022-10-08 06:13:09 +00:00
}
}
2022-07-01 07:24:58 +00:00
void scanner : : load_config ( const wchar_t * file )
{
2023-04-04 05:50:10 +00:00
if ( cfg_ )
{
cfg_ - > load_file ( local_trans : : u2a ( file ) . c_str ( ) ) ;
update_config ( ) ;
}
2022-07-01 07:24:58 +00:00
}
void scanner : : save_config ( const wchar_t * file )
{
2023-04-04 05:50:10 +00:00
if ( cfg_ )
cfg_ - > save ( local_trans : : u2a ( file ) . c_str ( ) ) ;
2022-07-01 07:24:58 +00:00
}
void scanner : : apply_config ( void )
{
2023-04-04 05:50:10 +00:00
if ( callback : : apply_current_config )
callback : : apply_current_config ( local_trans : : u2a ( scanner_name_ . c_str ( ) , CP_UTF8 ) . c_str ( ) , handle_ , & sane_api_ ) ;
else if ( cfg_ )
{
gb : : sane_config_schm * schm = cfg_ - > get_scheme ( ) ;
2022-10-08 06:13:09 +00:00
2023-04-04 05:50:10 +00:00
if ( ! schm )
return ;
2022-10-08 06:13:09 +00:00
2023-04-04 05:50:10 +00:00
apply_scheme ( schm ) ;
schm - > release ( ) ;
}
2022-07-01 07:24:58 +00:00
}
2022-07-02 09:27:21 +00:00
void scanner : : on_ui_event ( int uev , void * sender )
2022-06-18 08:48:41 +00:00
{
2022-10-21 10:09:33 +00:00
bool indicator = sender = = indicator_ . get ( ) ;
if ( uev = = SANE_EVENT_SCAN_FINISHED | | uev = = SANE_EVENT_UI_CLOSE_NORMAL | | uev = = SANE_EVENT_UI_CLOSE_CANCEL )
{
2022-11-25 06:20:06 +00:00
if ( uev = = SANE_EVENT_UI_CLOSE_CANCEL )
user_cancel_ = true ;
2022-10-21 10:09:33 +00:00
if ( indicator )
indicator_ . reset ( ) ;
2023-03-28 07:02:24 +00:00
is_scanning_ = false ;
2022-10-21 10:09:33 +00:00
if ( err_ & & setting_ . get ( ) )
{
return ;
}
}
2023-03-28 07:02:24 +00:00
//int(__stdcall * h)(int, void*) = scanner_ev_handler_;
//if (h)
//{
// if (SANE_EVENT_UI_CLOSE_SETTING == uev)
// {
// is_scanning_ = false;
// setting_.reset();
// }
2022-10-21 10:09:33 +00:00
2023-03-28 07:02:24 +00:00
// h(uev, evh_param_);
// return;
//}
2022-10-21 08:46:20 +00:00
2023-03-28 07:02:24 +00:00
//if (prev_start_result_ != SANE_STATUS_GOOD && indicator)
// indicator_.reset();
//else
2022-09-19 06:16:34 +00:00
{
2023-03-28 07:02:24 +00:00
//if (uev == SANE_EVENT_UI_SCAN_COMMAND)
//{
// ui_show_progress(NULL);
// start();
// return;
//}
2022-10-21 08:46:20 +00:00
2022-09-19 06:16:34 +00:00
if ( /*events_.count() > 5 && !is_ui_wait_img_ &&*/
2022-09-20 08:23:31 +00:00
( uev = = SANE_EVENT_UI_CLOSE_CANCEL | | uev = = SANE_EVENT_UI_CLOSE_NORMAL | | uev = = SANE_EVENT_UI_CLOSE_SETTING ) )
2022-09-19 06:16:34 +00:00
{
2023-03-28 07:02:24 +00:00
// events_.clear();
2022-09-19 06:16:34 +00:00
ui_hide ( ) ;
2022-10-20 06:29:02 +00:00
if ( indicator | | ! indicator_ . get ( ) )
uev = SANE_EVENT_SCAN_FINISHED ;
2022-09-20 04:41:32 +00:00
else
2022-10-20 06:29:02 +00:00
uev = SANE_EVENT_UI_CLOSE_SETTING ;
2022-09-19 06:16:34 +00:00
}
2022-10-20 06:29:02 +00:00
2022-11-25 06:20:06 +00:00
events_ . save ( uev , sizeof ( uev ) ) ;
2023-03-28 07:02:24 +00:00
ev_cnt_ + + ;
}
if ( ev_cnt_ = = events_ . count ( ) & &
( ev_cnt_ > = 5 | | ( ev_cnt_ > 1 & & ! is_scanning_ ) ) )
{
// maybe no event has been handled by APP, triggered by callback
int ( __stdcall * h ) ( int , void * ) = scanner_ev_handler_ ;
if ( h )
{
wchar_t info [ 128 ] = { 0 } ;
swprintf_s ( info , _countof ( info ) - 1 , L " [CRAZY]%d scanner events stored but APP has no action, we try to trigger it ONCE ... \r \n " , ev_cnt_ ) ;
ev_cnt_ - - ;
h ( events_ . take ( ) , evh_param_ ) ;
}
2022-09-19 06:16:34 +00:00
}
2022-06-18 08:48:41 +00:00
}
2022-10-09 03:59:45 +00:00
std : : string scanner : : choose_scanner ( const std : : vector < std : : string > & scanners )
{
if ( scanners . empty ( ) )
return " " ;
2023-04-04 05:50:10 +00:00
std : : vector < DEVQUE > devs ;
2022-10-09 03:59:45 +00:00
std : : string sel ( " " ) ;
2023-04-04 05:50:10 +00:00
int id = 1 ;
2022-10-09 03:59:45 +00:00
for ( size_t i = 0 ; i < scanners . size ( ) ; + + i )
{
SANE_Handle h = NULL ;
int ret = hg_sane_middleware : : instance ( ) - > open_device ( scanners [ i ] . c_str ( ) , & h ) ;
if ( h )
{
std : : string sn ( " " ) ;
scanner : : control_read_string ( h , IO_CTRL_CODE_GET_SERIAL , sn ) ;
if ( sn . length ( ) )
2023-04-04 05:50:10 +00:00
{
DEVQUE dev ;
dev . id = id + + ;
dev . name = scanners [ i ] ;
dev . sn = sn ;
devs . push_back ( dev ) ;
}
2022-10-09 03:59:45 +00:00
hg_sane_middleware : : instance ( ) - > close_device ( h ) ;
}
}
if ( devs . size ( ) = = 0 )
sel = scanners [ 0 ] ;
else if ( devs . size ( ) = = 1 )
2023-04-04 05:50:10 +00:00
sel = devs [ 0 ] . name ;
else if ( callback : : choose_scanner )
{
id = callback : : choose_scanner ( devs ) ;
if ( id ! = - 1 )
{
for ( auto & v : devs )
{
if ( v . id = = id )
{
sel = v . name ;
break ;
}
}
}
}
2022-10-09 03:59:45 +00:00
else
{
dlg_choose_dev dlg ( NULL , devs ) ;
dlg . show ( true , true ) ;
sel = dlg . get_selected_device ( ) ;
}
return sel ;
}
2022-06-15 03:04:40 +00:00
int scanner : : open ( void )
{
int ret = close ( ) ;
2022-10-09 03:59:45 +00:00
std : : vector < std : : string > que ;
std : : string name ( " " ) ;
scanner : : get_scanner_name ( id_ , que ) ;
2022-06-15 03:04:40 +00:00
2022-06-20 07:17:55 +00:00
scanner_name_ = L " " ;
2022-10-09 03:59:45 +00:00
if ( que . empty ( ) )
2022-06-15 03:04:40 +00:00
return SCANNER_ERR_DEVICE_NOT_FOUND ;
2022-10-09 03:59:45 +00:00
if ( que . size ( ) = = 1 )
name = que [ 0 ] ;
else
{
name = choose_scanner ( que ) ;
if ( name . empty ( ) )
return SCANNER_ERR_USER_CANCELED ;
}
2022-06-15 03:04:40 +00:00
ret = hg_sane_middleware : : instance ( ) - > open_device ( name . c_str ( ) , & handle_ ) ;
if ( ret = = SANE_STATUS_GOOD )
{
2022-10-08 09:31:13 +00:00
size_t pid = - 1 ;
2022-10-08 09:20:16 +00:00
transport_config_file ( ) ;
2022-06-18 00:54:01 +00:00
callback : : reg_callback ( handle_ , this ) ;
2022-09-21 08:44:41 +00:00
scanner_name_ = local_trans : : a2u ( name . c_str ( ) , CP_UTF8 ) ;
2022-10-08 09:31:13 +00:00
pid = scanner_name_ . find ( L " - " ) ;
if ( pid = = - 1 )
pid = scanner_name_ . length ( ) ;
2022-06-15 03:04:40 +00:00
ret = init_options_id ( ) ;
2022-10-08 09:20:16 +00:00
load_config ( ( cfg_path_ + scanner_name_ . substr ( 0 , pid ) + L " .cfg " ) . c_str ( ) ) ;
2022-09-23 06:17:41 +00:00
apply_config ( ) ;
2022-06-15 03:04:40 +00:00
}
2022-09-22 08:25:03 +00:00
else
{
std : : wstring msg ( local_trans : : a2u ( hg_scanner_err_description ( ret ) , CP_UTF8 ) ) ;
2022-10-21 08:46:20 +00:00
HWND parent = callback : : find_main_wnd ( ) ;
if ( ! IsWindow ( parent ) )
2023-02-07 08:55:51 +00:00
callback : : bring_message_box_topmost ( local_trans : : lang_trans_between_hz936 ( CONST_STRING_OPEN_FAILED ) . c_str ( ) ) ;
MessageBoxW ( parent , msg . c_str ( ) , local_trans : : lang_trans_between_hz936 ( CONST_STRING_OPEN_FAILED ) . c_str ( ) , MB_OK | MB_ICONERROR ) ;
2022-09-22 08:25:03 +00:00
}
2022-06-15 03:04:40 +00:00
return ret ;
}
int scanner : : close ( void )
{
2022-10-20 06:29:02 +00:00
scanner_ev_handler_ = NULL ;
2022-10-10 10:09:52 +00:00
ui_hide ( ) ;
2022-09-21 08:44:41 +00:00
callback : : unreg_callback ( this ) ;
2022-06-15 03:04:40 +00:00
if ( handle_ )
2022-09-23 06:17:41 +00:00
{
2022-06-15 03:04:40 +00:00
hg_sane_middleware : : instance ( ) - > close_device ( handle_ ) ;
2022-09-23 06:17:41 +00:00
}
2022-06-15 03:04:40 +00:00
handle_ = NULL ;
ex_id_ = EXTENSION_ID_BASE ;
return SCANNER_ERR_OK ;
}
int scanner : : init_options_id ( void )
{
SANE_Int op_id = 1 ;
const SANE_Option_Descriptor * desc = NULL ;
int ret = SCANNER_ERR_OK ;
# define SET_OPT_ID(var, predef, func) \
2022-10-07 09:51:09 +00:00
SET_SANE_OPT_ID ( op_id , var , predef , desc - > name , func )
2022-06-15 03:04:40 +00:00
2023-01-28 07:20:51 +00:00
while ( ( desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( const void * ) op_id ) ) )
2022-06-15 03:04:40 +00:00
{
2023-01-28 07:20:51 +00:00
void * val = hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) op_id , NULL , true ) ;
2022-07-01 07:24:58 +00:00
if ( val )
{
size_t len = 0 ;
switch ( desc - > type )
{
case SANE_TYPE_BOOL :
len = sizeof ( SANE_Bool ) ;
break ;
case SANE_TYPE_INT :
len = sizeof ( SANE_Int ) ;
break ;
case SANE_TYPE_FIXED :
len = sizeof ( SANE_Fixed ) ;
break ;
case SANE_TYPE_STRING :
len = lstrlenA ( ( char * ) val ) ;
break ;
default :
break ;
}
2023-04-04 05:50:10 +00:00
if ( len & & cfg_ )
2023-01-29 07:03:32 +00:00
{
if ( desc - > type = = SANE_TYPE_STRING )
{
std : : string deflan ( to_default_language ( ( char * ) val , nullptr ) ) ;
2023-02-07 08:55:51 +00:00
cfg_ - > set_default_value ( op_id , desc - > name , desc - > title , & deflan [ 0 ] , deflan . length ( ) , desc - > type ) ;
2023-01-29 07:03:32 +00:00
}
else
2023-02-07 08:55:51 +00:00
cfg_ - > set_default_value ( op_id , desc - > name , desc - > title , ( char * ) val , len , desc - > type ) ;
2023-01-29 07:03:32 +00:00
}
2022-07-01 07:24:58 +00:00
local_utility : : free_memory ( val ) ;
}
2022-10-07 09:51:09 +00:00
SET_OPT_ID ( is_multiout , IS_MULTI_OUT , extension_none )
else SET_OPT_ID ( multiout_type , MULTI_OUT_TYPE , extension_multiout_type )
else SET_OPT_ID ( color_mode , COLOR_MODE , extension_color_mode )
else SET_OPT_ID ( erase_color , FILTER , extension_erase_color )
else SET_OPT_ID ( erase_multiout_red , RID_MULTIOUT_RED , extension_none )
else SET_OPT_ID ( erase_paper_red , RID_ANSWER_SHEET_RED , extension_none )
else SET_OPT_ID ( is_erase_background , ERASE_BACKGROUND , extension_none )
else SET_OPT_ID ( background_color_range , BKG_COLOR_RANGE , extension_none )
else SET_OPT_ID ( sharpen , SHARPEN , extension_sharpen )
else SET_OPT_ID ( erase_morr , RID_MORR , extension_none )
else SET_OPT_ID ( erase_grids , RID_GRID , extension_none )
else SET_OPT_ID ( error_extend , ERROR_EXTENSION , extension_none )
else SET_OPT_ID ( is_noise_modify , NOISE_OPTIMIZE , extension_none )
else SET_OPT_ID ( noise_threshold , NOISE_SIZE , extension_none )
else SET_OPT_ID ( paper , PAPER , extension_paper )
else SET_OPT_ID ( is_custom_area , CUSTOM_AREA , extension_none )
else SET_OPT_ID ( curstom_area_l , CUSTOM_AREA_LEFT , extension_none )
else SET_OPT_ID ( curstom_area_r , CUSTOM_AREA_RIGHT , extension_none )
else SET_OPT_ID ( curstom_area_t , CUSTOM_AREA_TOP , extension_none )
else SET_OPT_ID ( curstom_area_b , CUSTOM_AREA_BOTTOM , extension_none )
else SET_OPT_ID ( is_size_check , SIZE_CHECK , extension_none )
else SET_OPT_ID ( page , PAGE , extension_page )
else SET_OPT_ID ( blank_page_threshold , DISCARD_BLANK_SENS , extension_none )
else SET_OPT_ID ( resolution , RESOLUTION , extension_none )
else SET_OPT_ID ( image_quality , IMAGE_QUALITY , extension_none )
else SET_OPT_ID ( is_swap , EXCHANGE , extension_none )
else SET_OPT_ID ( is_split , SPLIT , extension_none )
else SET_OPT_ID ( is_auto_deskew , ANTI_SKEW , extension_none )
else SET_OPT_ID ( is_custom_gamma , IS_CUSTOM_GAMMA , extension_none )
else SET_OPT_ID ( bright , BRIGHTNESS , extension_none )
else SET_OPT_ID ( contrast , CONTRAST , extension_none )
else SET_OPT_ID ( gamma , GAMMA , extension_none )
else SET_OPT_ID ( is_erase_black_frame , ERASE_BLACK_FRAME , extension_none )
else SET_OPT_ID ( deep_sample , DARK_SAMPLE , extension_none )
else SET_OPT_ID ( threshold , THRESHOLD , extension_none )
else SET_OPT_ID ( anti_noise , ANTI_NOISE_LEVEL , extension_none )
else SET_OPT_ID ( margin , MARGIN , extension_none )
else SET_OPT_ID ( fill_background , FILL_BKG_MODE , extension_fill_bkg_method )
else SET_OPT_ID ( is_anti_permeate , IS_ANTI_PERMEATE , extension_none )
else SET_OPT_ID ( anti_permeate_level , ANTI_PERMEATE_LEVEL , extension_none )
else SET_OPT_ID ( is_erase_hole , RID_HOLE , extension_none )
else SET_OPT_ID ( search_hole_range , SEARCH_HOLE_RANGE , extension_none )
else SET_OPT_ID ( is_filling_color , IS_FILL_COLOR , extension_none )
else SET_OPT_ID ( is_ultrasonic_check , IS_ULTROSONIC_CHECK , extension_none )
else SET_OPT_ID ( is_check_staple , IS_CHECK_STAPLE , extension_none )
else SET_OPT_ID ( scan_mode , SCAN_MODE , extension_none )
else SET_OPT_ID ( scan_count , SCAN_COUNT , extension_none )
else SET_OPT_ID ( text_direction , TEXT_DIRECTION , extension_text_direction )
else SET_OPT_ID ( is_rotate_bkg180 , IS_ROTATE_BKG_180 , extension_none )
else SET_OPT_ID ( is_check_dogear , IS_CHECK_DOG_EAR , extension_none )
else SET_OPT_ID ( dogear_size , DOG_EAR_SIZE , extension_none )
else SET_OPT_ID ( is_check_skew , IS_CHECK_ASKEW , extension_none )
else SET_OPT_ID ( skew_range , ASKEW_RANGE , extension_none )
else SET_OPT_ID ( black_white_threshold , BINARY_THRESHOLD , extension_none )
else SET_OPT_ID ( is_photo_mode , IS_PHOTO_MODE , extension_none )
else SET_OPT_ID ( double_feed_handle , DOUBLE_FEED_HANDLE , extension_none )
else SET_OPT_ID ( scan_when_paper_on , WAIT_TO_SCAN , extension_none )
else SET_OPT_ID ( feed_strength , FEED_STRENGTH , extension_none )
else SET_OPT_ID ( power_scheme , TIME_TO_SLEEP , extension_none )
else SET_OPT_ID ( is_auto_strength , IS_AUTO_FEED_STRENGTH , extension_none )
else SET_OPT_ID ( feed_strength_value , FEED_STRENGTH_VALUE , extension_none )
else SET_OPT_ID ( is_reverse_bw , REVERSE_01 , extension_none )
else SET_OPT_ID ( is_erase_hole_l , RID_HOLE_L , extension_none )
else SET_OPT_ID ( search_hole_range_l , SEARCH_HOLE_RANGE_L , extension_none )
else SET_OPT_ID ( is_erase_hole_r , RID_HOLE_R , extension_none )
else SET_OPT_ID ( search_hole_range_r , SEARCH_HOLE_RANGE_R , extension_none )
else SET_OPT_ID ( is_erase_hole_t , RID_HOLE_T , extension_none )
else SET_OPT_ID ( search_hole_range_t , SEARCH_HOLE_RANGE_T , extension_none )
else SET_OPT_ID ( is_erase_hole_b , RID_HOLE_B , extension_none )
else SET_OPT_ID ( search_hole_range_b , SEARCH_HOLE_RANGE_B , extension_none )
2022-10-24 08:58:09 +00:00
else SET_OPT_ID ( fold_direction , FOLD_TYPE , extension_none )
2023-02-24 09:44:47 +00:00
else SET_OPT_ID ( fold_type , FOLD_TYPE , extension_none )
else SET_OPT_ID ( color_correction , COLOR_CORRECTION , extension_none )
2022-06-15 03:04:40 +00:00
op_id + + ;
}
# define EX_APPENDIX_API(name) \
{ \
EXAPI ea ; \
ea . ind = ex_ # # name # # _id_ = ex_id_ + + ; \
ea . ex_api = & scanner : : handle_ex_ # # name ; \
2023-01-28 07:20:51 +00:00
ea . base_ind = - 1 ; \
2022-06-15 03:04:40 +00:00
ex_opts_ . push_back ( ea ) ; \
}
EX_APPENDIX_API ( final_compression ) ;
EX_APPENDIX_API ( final_format ) ;
EX_APPENDIX_API ( serial ) ;
EX_APPENDIX_API ( to_be_scan ) ;
EX_APPENDIX_API ( scan_with_hole ) ;
EX_APPENDIX_API ( device_code ) ;
EX_APPENDIX_API ( power ) ;
EX_APPENDIX_API ( hardware_version ) ;
EX_APPENDIX_API ( ip ) ;
2022-06-28 09:17:10 +00:00
if ( black_white_threshold_id_ = = - 1 )
black_white_threshold_id_ = 0x8836 ;
2022-09-12 06:45:07 +00:00
if ( is_erase_hole_id_ = = - 1 )
{
// 兼容老的除孔算法
EXAPI ea ;
ea . ind = is_erase_hole_id_ = ex_id_ + + ;
2022-10-14 02:11:43 +00:00
ea . base_ind = is_erase_hole_l_id_ ;
2022-09-12 06:45:07 +00:00
ea . ex_api = & scanner : : handle_ex_erase_hole ;
ex_opts_ . push_back ( ea ) ;
ea . ind = search_hole_range_id_ = ex_id_ + + ;
2022-10-14 02:11:43 +00:00
ea . base_ind = search_hole_range_l_id_ ;
2022-09-12 06:45:07 +00:00
ea . ex_api = & scanner : : handle_ex_search_hole_range ;
ex_opts_ . push_back ( ea ) ;
}
2022-10-08 06:13:09 +00:00
2022-06-15 03:04:40 +00:00
return ret ;
}
int scanner : : control_read_string ( int code , std : : string & ret )
{
2022-10-09 03:59:45 +00:00
return scanner : : control_read_string ( handle_ , code , ret ) ;
2022-06-15 03:04:40 +00:00
}
void scanner : : extension_none ( int id )
{
}
void scanner : : extension_multiout_type ( int id )
{
EXAPI ea ;
ex_multiout_type_id_ = ex_id_ + + ;
ea . ind = ex_multiout_type_id_ ;
ea . base_ind = id ;
ea . ex_api = & scanner : : handle_ex_multiout ;
ex_opts_ . push_back ( ea ) ;
}
void scanner : : extension_color_mode ( int id )
{
EXAPI ea ;
ea . ind = ex_color_mode_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ex_api = & scanner : : handle_ex_color_mode ;
ex_opts_ . push_back ( ea ) ;
ex_auto_color_type_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ind = ex_auto_color_type_id_ ;
ea . ex_api = & scanner : : handle_ex_auto_color_type ;
ex_opts_ . push_back ( ea ) ;
}
void scanner : : extension_sharpen ( int id )
{
EXAPI ea ;
ex_sharpen_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ind = ex_sharpen_id_ ;
ea . ex_api = & scanner : : handle_ex_sharpen ;
ex_opts_ . push_back ( ea ) ;
}
void scanner : : extension_paper ( int id )
{
EXAPI ea ;
ea . ind = ex_paper_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ex_api = & scanner : : handle_ex_paper ;
ex_opts_ . push_back ( ea ) ;
ea . ind = ex_paper_lateral_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ex_api = & scanner : : handle_ex_paper_lateral ;
ex_opts_ . push_back ( ea ) ;
ea . ind = ex_auto_paper_size_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ex_api = & scanner : : handle_ex_auto_paper_size ;
ex_opts_ . push_back ( ea ) ;
ea . ind = ex_is_paper_auto_crop_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ex_api = & scanner : : handle_ex_auto_paper_crop ;
ex_opts_ . push_back ( ea ) ;
}
void scanner : : extension_fill_bkg_method ( int id )
{
EXAPI ea ;
ea . ind = ex_fill_background_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ex_api = & scanner : : handle_ex_fill_background ;
ex_opts_ . push_back ( ea ) ;
}
void scanner : : extension_text_direction ( int id )
{
EXAPI ea ;
ea . ind = ex_text_direction_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ex_api = & scanner : : handle_ex_text_direction ;
ex_opts_ . push_back ( ea ) ;
}
void scanner : : extension_page ( int id )
{
EXAPI ea ;
2022-09-23 08:47:00 +00:00
wchar_t msg [ 128 ] = { 0 } ;
2022-06-15 03:04:40 +00:00
ea . ind = ex_duplex_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ex_api = & scanner : : handle_ex_duplex ;
ex_opts_ . push_back ( ea ) ;
2022-09-23 08:47:00 +00:00
{
swprintf_s ( msg , _countof ( msg ) - 1 , L " handle_ex_duplex of id: %d \r \n " , ea . ind ) ;
log_info ( msg , 0 ) ;
}
2022-06-15 03:04:40 +00:00
ea . ind = ex_discard_blank_page_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ex_api = & scanner : : handle_ex_discard_blank_page ;
ex_opts_ . push_back ( ea ) ;
2022-09-23 08:47:00 +00:00
{
swprintf_s ( msg , _countof ( msg ) - 1 , L " handle_ex_discard_blank_page of id: %d \r \n " , ea . ind ) ;
log_info ( msg , 0 ) ;
}
2022-06-15 03:04:40 +00:00
ea . ind = ex_discard_blank_receipt_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ex_api = & scanner : : handle_ex_discard_blank_receipt ;
ex_opts_ . push_back ( ea ) ;
2022-09-23 08:47:00 +00:00
{
swprintf_s ( msg , _countof ( msg ) - 1 , L " handle_ex_discard_blank_receipt of id: %d \r \n " , ea . ind ) ;
log_info ( msg , 0 ) ;
}
2022-06-15 03:04:40 +00:00
ea . ind = ex_is_page_fold_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ex_api = & scanner : : handle_ex_page_fold ;
ex_opts_ . push_back ( ea ) ;
2022-09-23 08:47:00 +00:00
{
swprintf_s ( msg , _countof ( msg ) - 1 , L " handle_ex_page_fold of id: %d \r \n " , ea . ind ) ;
log_info ( msg , 0 ) ;
}
2022-06-15 03:04:40 +00:00
}
void scanner : : extension_erase_color ( int id )
{
EXAPI ea ;
ea . ind = ex_color_filter_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ex_api = & scanner : : handle_ex_color_filter ;
ex_opts_ . push_back ( ea ) ;
ea . ind = ex_color_enhance_id_ = ex_id_ + + ;
ea . base_ind = id ;
ea . ex_api = & scanner : : handle_ex_color_enhance ;
ex_opts_ . push_back ( ea ) ;
}
bool scanner : : get_option_value_with_parent ( int sn , set_opt_value setv , void * param ) // return true if handled
{
bool handled = true ;
if ( sn = = scan_count_id_ )
{
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * parent = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( const void * ) scan_mode_id_ ) ;
2022-06-15 03:04:40 +00:00
char * buf = new char [ parent - > size + 4 ] ;
memset ( buf , 0 , parent - > size ) ;
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) scan_mode_id_ , buf ) ;
2023-02-07 08:55:51 +00:00
handled = compare_sane_opt ( local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMZS_LXSM , true , nullptr ) , buf ) ;
2022-06-15 03:04:40 +00:00
delete [ ] buf ;
if ( handled )
{
int count = - 1 ;
value_role role = VAL_ROLE_CURRENT ;
2023-01-28 07:20:51 +00:00
buf = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) scan_mode_id_ ) ;
2023-02-07 08:55:51 +00:00
if ( compare_sane_opt ( local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMZS_LXSM , true , nullptr ) , buf ) )
2022-06-15 03:04:40 +00:00
role = value_role ( role | VAL_ROLE_DEFAULT ) ;
local_utility : : free_memory ( buf ) ;
2023-01-28 07:20:51 +00:00
setv ( & count , value_role ( VAL_ROLE_CURRENT | VAL_ROLE_DEFAULT ) , VAL_LIMIT_NONE , param ) ;
2022-06-15 03:04:40 +00:00
}
}
else
handled = false ;
return handled ;
}
2023-01-10 09:30:00 +00:00
bool scanner : : set_option_value_with_parent ( int sn , void * data , int * err ) // return true if handled sn
2022-06-15 03:04:40 +00:00
{
2023-01-10 09:30:00 +00:00
bool handled = false ;
2022-06-15 03:04:40 +00:00
if ( sn = = scan_count_id_ )
{
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * parent = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) scan_mode_id_ ) ;
2022-06-15 03:04:40 +00:00
char * val = new char [ parent - > size + 4 ] ;
SANE_Int after = 0 ;
memset ( val , 0 , parent - > size + 4 ) ;
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) scan_mode_id_ , val ) ;
2023-02-07 08:55:51 +00:00
if ( compare_sane_opt ( local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMZS_LXSM , true , nullptr ) , val ) )
2022-06-15 03:04:40 +00:00
{
if ( * ( int * ) data ! = - 1 )
{
2023-02-07 08:55:51 +00:00
strcpy ( val , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMZS_SMZDZS , true , nullptr ) ) ;
2023-01-28 07:20:51 +00:00
* err = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) scan_mode_id_ , SANE_ACTION_SET_VALUE , val , & after ) ;
2022-06-15 03:04:40 +00:00
}
}
else if ( * ( int * ) data = = - 1 )
{
2023-02-07 08:55:51 +00:00
strcpy ( val , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMZS_LXSM , true , nullptr ) ) ;
2023-01-28 07:20:51 +00:00
* err = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) scan_mode_id_ , SANE_ACTION_SET_VALUE , val , & after ) ;
2022-06-15 03:04:40 +00:00
}
2022-11-19 00:48:39 +00:00
delete [ ] val ;
2022-06-15 03:04:40 +00:00
}
return handled ;
}
int scanner : : set_option_value ( int sn , SANE_Value_Type type , int size , void * data )
{
char * buf = NULL ;
SANE_Bool sb = SANE_FALSE ;
SANE_Int si = 0 , after = 0 ;
SANE_Fixed sf = 0 ;
int ret = SCANNER_ERR_OK ;
2022-06-16 08:04:58 +00:00
void * val = data ;
2022-06-15 03:04:40 +00:00
if ( type = = SANE_TYPE_BOOL )
{
sb = * ( bool * ) data ? SANE_TRUE : SANE_FALSE ;
2022-06-16 08:04:58 +00:00
val = & sb ;
2022-06-15 03:04:40 +00:00
}
else if ( type = = SANE_TYPE_INT )
{
si = * ( int * ) data ;
2022-06-16 08:04:58 +00:00
val = & si ;
2022-06-15 03:04:40 +00:00
}
else if ( type = = SANE_TYPE_FIXED )
{
sf = SANE_FIX ( * ( float * ) data ) ;
2022-06-16 08:04:58 +00:00
val = & sf ;
2022-06-15 03:04:40 +00:00
}
else
{
buf = new char [ size + 4 ] ;
memset ( buf , 0 , size + 4 ) ;
2022-06-15 09:07:51 +00:00
strcpy ( buf , ( ( std : : string * ) data ) - > c_str ( ) ) ;
2022-06-16 08:04:58 +00:00
val = buf ;
2022-06-15 03:04:40 +00:00
}
2022-06-16 08:04:58 +00:00
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) sn , SANE_ACTION_SET_VALUE , val , & after ) ;
2022-06-16 08:04:58 +00:00
if ( type = = SANE_TYPE_BOOL )
{
* ( bool * ) data = sb = = SANE_TRUE ;
}
else if ( type = = SANE_TYPE_INT )
{
* ( int * ) data = si ;
}
else if ( type = = SANE_TYPE_FIXED )
{
2022-07-18 02:55:01 +00:00
* ( float * ) data = ( float ) SANE_UNFIX ( sf ) ;
2022-06-16 08:04:58 +00:00
}
else if ( buf )
{
strcpy ( ( char * ) val , buf ) ;
2022-06-15 03:04:40 +00:00
delete [ ] buf ;
2022-06-16 08:04:58 +00:00
}
2022-06-15 03:04:40 +00:00
return ret ;
}
2023-01-28 07:20:51 +00:00
int scanner : : set_is_multiout ( bool enable )
{
int ret = SCANNER_ERR_OK ;
if ( is_multiout_id_ > 0 )
{
SANE_Bool multi = SANE_FALSE ;
SANE_Int after = 0 ;
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) is_multiout_id_ , & multi ) ; // parent item ...
if ( enable ^ ( multi = = SANE_TRUE ) )
{
multi = enable ? SANE_TRUE : SANE_FALSE ;
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) is_multiout_id_ , SANE_ACTION_SET_VALUE , & multi , & after ) ;
after = 0 ;
}
}
return ret ;
}
2022-06-15 03:04:40 +00:00
scanner : : EXAPIPOS scanner : : find_ex_api ( int op_id )
{
return std : : find ( ex_opts_ . begin ( ) , ex_opts_ . end ( ) , op_id ) ;
}
2023-02-07 08:55:51 +00:00
void scanner : : apply_scheme ( gb : : sane_config_schm * schm )
{
// restore ...
hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_RESTORE_SETTINGS , nullptr , nullptr ) ;
if ( ! schm )
return ;
std : : string n ( " " ) , v ( " " ) , ver ( schm - > get_version ( ) ) ;
if ( schm - > first_config ( n , v ) )
{
do
{
int id = schm - > id_from_name ( n . c_str ( ) ) ;
if ( id = = - 1 )
{
if ( gb : : sane_config_schm : : is_option_data ( n ) )
{
id = schm - > id_from_name ( n . c_str ( ) ) ;
if ( id = = is_custom_gamma_id_ )
{
if ( v . length ( ) = = sizeof ( SANE_Gamma ) )
{
unsigned int l = v . length ( ) ;
hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_SET_CUSTOM_GAMMA , & v [ 0 ] , & l ) ;
}
else
{
wchar_t info [ 128 ] = { 0 } ;
swprintf_s ( info , _countof ( info ) - 1 , L " ERROR: custom gamma data length is %u, but we expect %u. \r \n " , v . length ( ) , sizeof ( SANE_Gamma ) ) ;
log_info ( info , 0 ) ;
}
}
}
}
else
{
v = from_default_language ( v . c_str ( ) , nullptr ) ;
void * data = & v [ 0 ] ;
SANE_Fixed fixed = 0 ;
const SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( const void * ) id ) ;
if ( desc )
{
char * buf = NULL ;
SANE_Int after = 0 ;
if ( desc - > type = = SANE_TYPE_STRING )
{
buf = new char [ desc - > size + 4 ] ;
memset ( buf , 0 , desc - > size + 4 ) ;
strcpy ( buf , v . c_str ( ) ) ;
data = buf ;
}
hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( const void * ) id , SANE_ACTION_SET_VALUE , data , & after ) ;
if ( buf )
delete [ ] buf ;
}
}
} while ( schm - > next_config ( n , v ) ) ;
}
}
2022-06-15 03:04:40 +00:00
EX_OPTION_HANDLER_IMPL ( multiout )
{
int ret = SCANNER_ERR_OK ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
SANE_Bool parent = SANE_FALSE ;
2022-06-15 03:04:40 +00:00
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) is_multiout_id_ , & parent ) ;
2022-06-15 03:04:40 +00:00
if ( setv )
{
2023-01-28 07:20:51 +00:00
char * cur = ( char * ) hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id ) ,
* def = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
int now = sane_opt_trans : : multiout_value_to_twain ( cur ) ,
2022-06-15 03:04:40 +00:00
init = sane_opt_trans : : multiout_value_to_twain ( def ) ,
val = 0 ;
local_utility : : free_memory ( def ) ;
2023-01-28 07:20:51 +00:00
local_utility : : free_memory ( cur ) ;
2022-06-15 03:04:40 +00:00
{
// parent item ...
2023-01-28 07:20:51 +00:00
if ( ! parent )
now = MULTI_OUT_NONE ;
2022-06-15 03:04:40 +00:00
}
do
{
if ( desc - > constraint_type = = SANE_CONSTRAINT_STRING_LIST )
{
// we have no 'MULTI_OUT_NONE' item in this option, this is used as is_multiout_id_
val = MULTI_OUT_NONE ;
value_role role = val = = now ? VAL_ROLE_CURRENT : VAL_ROLE_NONE ;
2023-01-28 07:20:51 +00:00
if ( val = = init )
role = ( value_role ) ( role | VAL_ROLE_DEFAULT ) ;
if ( ! setv ( & val , role , VAL_LIMIT_ENUM , data ) )
2022-06-15 03:04:40 +00:00
break ;
for ( int i = 0 ; desc - > constraint . string_list [ i ] ; + + i )
{
value_role role = VAL_ROLE_NONE ;
val = sane_opt_trans : : multiout_value_to_twain ( desc - > constraint . string_list [ i ] ) ;
if ( val = = now )
role = VAL_ROLE_CURRENT ;
if ( val = = init )
role = value_role ( role | VAL_ROLE_DEFAULT ) ;
2023-01-28 07:20:51 +00:00
if ( ! setv ( & val , role , VAL_LIMIT_ENUM , data ) )
2022-06-15 03:04:40 +00:00
break ;
}
}
else
set_cur_and_def_value < int > ( now , init , setv , data ) ;
} while ( 0 ) ;
}
else
{
char * val = new char [ desc - > size ] ;
const char * in = sane_opt_trans : : multiout_value_from_twain ( * ( int * ) data ) ;
SANE_Int after = 0 ;
if ( in & & strcmp ( in , " \346 \227 \240 " ) )
{
2023-01-28 07:20:51 +00:00
ret = set_is_multiout ( true ) ;
if ( ret = = SANE_STATUS_GOOD )
{
strcpy ( val , in ) ;
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , val , & after ) ;
}
2022-06-15 03:04:40 +00:00
}
else
{
2023-01-28 07:20:51 +00:00
// disable multi-out, let multiout type aside
ret = set_is_multiout ( false ) ;
2022-06-15 03:04:40 +00:00
}
delete [ ] val ;
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
return ret ;
}
EX_OPTION_HANDLER_IMPL ( auto_color_type )
{
int ret = SCANNER_ERR_OK ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
int len = desc - > size + 4 ;
char * buf = new char [ len ] ;
memset ( buf , 0 , len ) ;
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id , buf ) ;
2022-06-15 03:04:40 +00:00
if ( setv )
{
2023-01-28 07:20:51 +00:00
char * def = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
int init = sane_opt_trans : : auto_color_type_to_twain ( def ) ;
local_utility : : free_memory ( def ) ;
2022-06-15 03:04:40 +00:00
len = sane_opt_trans : : auto_color_type_to_twain ( buf ) ;
2023-01-28 07:20:51 +00:00
set_cur_and_def_value < int > ( len , init , setv , data ) ;
2022-06-15 03:04:40 +00:00
}
else
{
SANE_Int after = 0 ;
2023-01-28 07:20:51 +00:00
// ret = set_is_multiout(false);
if ( ret = = SCANNER_ERR_OK )
{
strcpy ( buf , sane_opt_trans : : auto_color_type_from_twain ( * ( int * ) data ) ) ;
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , buf , & after ) ;
}
2022-06-15 03:04:40 +00:00
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
delete [ ] buf ;
return ret ;
}
EX_OPTION_HANDLER_IMPL ( color_mode )
{
int ret = SCANNER_ERR_OK ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
if ( setv )
{
2023-01-28 07:20:51 +00:00
char * cur = ( char * ) hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id ) ,
* def = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
int now = sane_opt_trans : : color_mode_to_twain ( cur ) , // sane_opt_trans::multiout_value_to_twain(cur)
2022-06-15 03:04:40 +00:00
init = sane_opt_trans : : color_mode_to_twain ( def ) ,
val = 0 ;
local_utility : : free_memory ( def ) ;
2023-01-28 07:20:51 +00:00
local_utility : : free_memory ( cur ) ;
2022-06-15 03:04:40 +00:00
do
{
if ( desc - > constraint_type = = SANE_CONSTRAINT_STRING_LIST )
{
for ( int i = 0 ; desc - > constraint . string_list [ i ] ; + + i )
{
value_role role = VAL_ROLE_NONE ;
val = sane_opt_trans : : color_mode_to_twain ( desc - > constraint . string_list [ i ] ) ;
if ( val = = now )
role = VAL_ROLE_CURRENT ;
if ( val = = init )
role = value_role ( role | VAL_ROLE_DEFAULT ) ;
2023-01-28 07:20:51 +00:00
if ( ! setv ( & val , role , VAL_LIMIT_ENUM , data ) )
2022-06-15 03:04:40 +00:00
break ;
}
}
else
set_cur_and_def_value < int > ( now , init , setv , data ) ;
} while ( 0 ) ;
}
else
{
SANE_Int after = 0 ;
2023-01-28 07:20:51 +00:00
// ret = set_is_multiout(false);
if ( ret = = SCANNER_ERR_OK )
{
char * val = new char [ desc - > size ] ;
const char * in = sane_opt_trans : : color_mode_from_twain ( * ( int * ) data ) ;
strcpy ( val , in ) ;
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , val , & after ) ;
delete [ ] val ;
}
2022-06-15 03:04:40 +00:00
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
return ret ;
}
EX_OPTION_HANDLER_IMPL ( sharpen )
{
int ret = SCANNER_ERR_OK ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
if ( setv )
{
2023-01-28 07:20:51 +00:00
char * cur = ( char * ) hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id ) ,
* def = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
int now = sane_opt_trans : : multiout_value_to_twain ( cur ) ,
2022-06-15 03:04:40 +00:00
init = sane_opt_trans : : sharpen_to_twain ( def ) ,
val = 0 ;
local_utility : : free_memory ( def ) ;
2023-01-28 07:20:51 +00:00
local_utility : : free_memory ( cur ) ;
2022-06-15 03:04:40 +00:00
do
{
if ( desc - > constraint_type = = SANE_CONSTRAINT_STRING_LIST )
{
for ( int i = 0 ; desc - > constraint . string_list [ i ] ; + + i )
{
value_role role = VAL_ROLE_NONE ;
val = sane_opt_trans : : sharpen_to_twain ( desc - > constraint . string_list [ i ] ) ;
if ( val = = now )
role = VAL_ROLE_CURRENT ;
if ( val = = init )
role = value_role ( role | VAL_ROLE_DEFAULT ) ;
2023-01-28 07:20:51 +00:00
if ( ! setv ( & val , role , VAL_LIMIT_ENUM , data ) )
2022-06-15 03:04:40 +00:00
break ;
}
}
else
set_cur_and_def_value < int > ( now , init , setv , data ) ;
} while ( 0 ) ;
}
else
{
char * val = new char [ desc - > size ] ;
const char * in = sane_opt_trans : : sharpen_from_twain ( * ( int * ) data ) ;
SANE_Int after = 0 ;
2023-01-28 07:20:51 +00:00
strcpy ( val , in ) ;
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , val , & after ) ;
2022-06-15 03:04:40 +00:00
delete [ ] val ;
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
return ret ;
}
EX_OPTION_HANDLER_IMPL ( paper )
{
int ret = SCANNER_ERR_OK ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
int len = desc - > size + 4 ;
char * buf = new char [ len ] ;
memset ( buf , 0 , len ) ;
if ( setv )
{
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id , buf ) ;
char * def = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
int now = sane_opt_trans : : paper_to_twain ( buf ) ,
init = sane_opt_trans : : paper_to_twain ( def ) ,
val = 0 ;
2022-09-26 09:31:57 +00:00
local_utility : : free_memory ( def ) ;
2022-06-15 03:04:40 +00:00
do
{
if ( desc - > constraint_type = = SANE_CONSTRAINT_STRING_LIST )
{
for ( int i = 0 ; desc - > constraint . string_list [ i ] ; + + i )
{
value_role role = VAL_ROLE_NONE ;
val = sane_opt_trans : : paper_to_twain ( desc - > constraint . string_list [ i ] ) ;
if ( val = = - 1 )
continue ;
if ( val = = now )
role = VAL_ROLE_CURRENT ;
if ( val = = init )
role = value_role ( role | VAL_ROLE_DEFAULT ) ;
2023-01-28 07:20:51 +00:00
if ( ! setv ( & val , role , VAL_LIMIT_ENUM , data ) )
2022-06-15 03:04:40 +00:00
break ;
}
}
else
set_cur_and_def_value < int > ( now , init , setv , data ) ;
} while ( 0 ) ;
}
else if ( sane_opt_trans : : paper_from_twain ( * ( int * ) data ) )
{
SANE_Int after = 0 ;
strcpy ( buf , sane_opt_trans : : paper_from_twain ( * ( int * ) data ) ) ;
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , buf , & after ) ;
2022-06-15 03:04:40 +00:00
}
else
ret = SCANNER_ERR_INVALID_PARAMETER ;
delete [ ] buf ;
return ret ;
}
EX_OPTION_HANDLER_IMPL ( paper_lateral )
{
int ret = SCANNER_ERR_OK ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
int len = desc - > size + 4 ;
char * buf = new char [ len ] ;
const char * lateral_swap = NULL ;
bool lateral = false ;
memset ( buf , 0 , len ) ;
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id , buf ) ;
2022-06-15 03:04:40 +00:00
lateral_swap = sane_opt_trans : : switch_paper_lateral ( buf ) ;
lateral = sane_opt_trans : : is_paper_lateral ( buf ) ;
if ( setv )
{
2023-01-28 07:20:51 +00:00
set_cur_and_def_value < bool > ( lateral , false , setv , data ) ;
2022-06-15 03:04:40 +00:00
}
else if ( lateral_swap )
{
SANE_Int after = 0 ;
if ( lateral ! = * ( bool * ) data )
{
strcpy ( buf , lateral_swap ) ;
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , buf , & after ) ;
2022-06-15 03:04:40 +00:00
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
}
else
2022-10-07 09:51:09 +00:00
{
SANE_Int after = 0 ;
if ( * ( bool * ) data )
{
// set to A4Lateral ...
2023-02-07 08:55:51 +00:00
strcpy ( buf , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_ZZCC_A4HX , true , nullptr ) ) ;
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , buf , & after ) ;
2022-10-07 09:51:09 +00:00
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
//ret = SCANNER_ERR_DEVICE_NOT_SUPPORT;
}
2022-06-15 03:04:40 +00:00
delete [ ] buf ;
return ret ;
}
EX_OPTION_HANDLER_IMPL ( auto_paper_size )
{
int ret = SCANNER_ERR_OK ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
int len = desc - > size + 4 ;
char * buf = new char [ len ] ;
memset ( buf , 0 , len ) ;
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id , buf ) ;
2022-06-15 03:04:40 +00:00
if ( setv )
{
2023-01-28 07:20:51 +00:00
char * init = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
2023-02-07 08:55:51 +00:00
bool yes = strcmp ( buf , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_ZZCC_PPYSCC , true , nullptr ) ) = = 0 ,
def = strcmp ( init , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_ZZCC_PPYSCC , true , nullptr ) ) = = 0 ;
2023-01-28 07:20:51 +00:00
local_utility : : free_memory ( init ) ;
set_cur_and_def_value < bool > ( yes , def , setv , data ) ;
2022-06-15 03:04:40 +00:00
}
else
{
SANE_Int after = 0 ;
2023-02-07 08:55:51 +00:00
strcpy ( buf , * ( bool * ) data ? local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_ZZCC_PPYSCC , true , nullptr ) : local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_ZZCC_A4 , true , nullptr ) ) ;
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , buf , & after ) ;
2022-06-15 03:04:40 +00:00
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
delete [ ] buf ;
return ret ;
}
EX_OPTION_HANDLER_IMPL ( auto_paper_crop )
{
int ret = SCANNER_ERR_OK ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
int len = desc - > size + 4 ;
char * buf = new char [ len ] ;
memset ( buf , 0 , len ) ;
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id , buf ) ;
2022-06-15 03:04:40 +00:00
if ( setv )
{
2023-01-28 07:20:51 +00:00
char * init = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
2023-02-07 08:55:51 +00:00
bool yes = strcmp ( buf , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_ZZCC_ZDSMCCZDCQ , true , nullptr ) ) = = 0 ,
2023-01-28 07:20:51 +00:00
def = strcmp ( init , OPTION_VALUE_ZZCC_ZDSMCCZDCQ ) = = 0 ;
local_utility : : free_memory ( init ) ;
set_cur_and_def_value < bool > ( yes , def , setv , data ) ;
2022-06-15 03:04:40 +00:00
}
else
{
SANE_Int after = 0 ;
2023-02-07 08:55:51 +00:00
strcpy ( buf , * ( bool * ) data ? local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_ZZCC_ZDSMCCZDCQ , true , nullptr ) : local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_ZZCC_ZDSMCC , true , nullptr ) ) ;
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , buf , & after ) ;
2022-06-15 03:04:40 +00:00
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
delete [ ] buf ;
return ret ;
}
EX_OPTION_HANDLER_IMPL ( text_direction )
{
int ret = SCANNER_ERR_OK ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
int len = desc - > size + 4 ;
char * buf = new char [ len ] ;
memset ( buf , 0 , len ) ;
if ( setv )
{
2023-01-28 07:20:51 +00:00
char * def = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
float now = .0f , init = sane_opt_trans : : text_direction_to_twain ( def ) , val = .0f ;
local_utility : : free_memory ( def ) ;
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id , buf ) ;
2022-06-15 03:04:40 +00:00
now = sane_opt_trans : : text_direction_to_twain ( buf ) ;
do
{
if ( desc - > constraint_type = = SANE_CONSTRAINT_STRING_LIST )
{
for ( int i = 0 ; desc - > constraint . string_list [ i ] ; + + i )
{
value_role role = VAL_ROLE_NONE ;
val = sane_opt_trans : : text_direction_to_twain ( desc - > constraint . string_list [ i ] ) ;
if ( IS_DOUBLE_EQUAL ( val , now ) )
role = VAL_ROLE_CURRENT ;
if ( IS_DOUBLE_EQUAL ( val , init ) )
role = value_role ( role | VAL_ROLE_DEFAULT ) ;
2023-01-28 07:20:51 +00:00
if ( ! setv ( & val , role , VAL_LIMIT_ENUM , data ) )
2022-06-15 03:04:40 +00:00
break ;
}
}
else
set_cur_and_def_value < float > ( now , init , setv , data ) ;
} while ( 0 ) ;
}
else
{
SANE_Int after = 0 ;
strcpy ( buf , sane_opt_trans : : text_direction_from_twain ( * ( float * ) data ) ) ;
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , buf , & after ) ;
2022-06-15 03:04:40 +00:00
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
delete [ ] buf ;
return ret ;
}
EX_OPTION_HANDLER_IMPL ( duplex )
{
int ret = SCANNER_ERR_OK ;
bool val = * ( bool * ) data ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
unsigned len = desc - > size + 4 ;
char * buf = new char [ len ] ;
memset ( buf , 0 , len ) ;
if ( setv )
{
2023-01-28 07:20:51 +00:00
char * init = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id , buf ) ;
2023-02-07 08:55:51 +00:00
set_cur_and_def_value < bool > ( strcmp ( buf , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMYM_SM , true , nullptr ) ) = = 0 , strcmp ( init , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMYM_SM , true , nullptr ) ) = = 0 , setv , data ) ;
2022-09-26 09:31:57 +00:00
local_utility : : free_memory ( init ) ;
2022-06-15 03:04:40 +00:00
}
else
{
2023-02-07 08:55:51 +00:00
strcpy ( buf , val ? local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMYM_SM , true , nullptr ) : local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMYM_DM , true , nullptr ) ) ;
2022-06-15 03:04:40 +00:00
SANE_Int after = 0 ;
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , buf , & after ) ;
2022-06-15 03:04:40 +00:00
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
delete [ ] buf ;
return ret ;
}
EX_OPTION_HANDLER_IMPL ( fill_background )
{
int ret = SCANNER_ERR_OK ;
bool val = * ( bool * ) data ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
unsigned len = desc - > size + 4 ;
char * buf = new char [ len ] ;
memset ( buf , 0 , len ) ;
if ( setv )
{
2023-01-28 07:20:51 +00:00
char * init = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id , buf ) ;
2023-02-07 08:55:51 +00:00
val = strcmp ( buf , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMYM_SM , true , nullptr ) ) = = 0 ;
set_cur_and_def_value < bool > ( strcmp ( buf , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_BJTCFS_TDBX , true , nullptr ) ) = = 0 , strcmp ( init , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_BJTCFS_TDBX , true , nullptr ) ) = = 0 , setv , data ) ;
2022-06-15 03:04:40 +00:00
local_utility : : free_memory ( init ) ;
}
else
{
2023-02-07 08:55:51 +00:00
strcpy ( buf , val ? local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_BJTCFS_TDBX , true , nullptr ) : local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_BJTCFS_ADBX , true , nullptr ) ) ;
2022-06-15 03:04:40 +00:00
SANE_Int after = 0 ;
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , buf , & after ) ;
2022-06-15 03:04:40 +00:00
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
delete [ ] buf ;
return ret ;
}
EX_OPTION_HANDLER_IMPL ( discard_blank_page )
{
int ret = SCANNER_ERR_OK ;
bool val = * ( bool * ) data ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
unsigned len = desc - > size + 4 ;
char * buf = new char [ len ] ;
memset ( buf , 0 , len ) ;
if ( setv )
{
2023-01-28 07:20:51 +00:00
char * init = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
2023-02-07 08:55:51 +00:00
bool def = strcmp ( init , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMYM_TGKBYTY , true , nullptr ) ) = = 0 ;
2023-01-28 07:20:51 +00:00
local_utility : : free_memory ( init ) ;
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id , buf ) ;
2023-02-07 08:55:51 +00:00
val = strcmp ( buf , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMYM_TGKBYTY , true , nullptr ) ) = = 0 ;
2023-01-28 07:20:51 +00:00
set_cur_and_def_value < bool > ( val , def , setv , data ) ;
2022-06-15 03:04:40 +00:00
}
else
{
if ( val )
2023-02-07 08:55:51 +00:00
strcpy ( buf , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMYM_TGKBYTY , true , nullptr ) ) ;
2022-06-15 03:04:40 +00:00
else
{
2023-01-28 07:20:51 +00:00
char * init = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
strcpy ( buf , init ) ;
local_utility : : free_memory ( init ) ;
}
SANE_Int after = 0 ;
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , buf , & after ) ;
2022-06-15 03:04:40 +00:00
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
delete [ ] buf ;
return ret ;
}
EX_OPTION_HANDLER_IMPL ( discard_blank_receipt )
{
int ret = SCANNER_ERR_OK ;
bool val = * ( bool * ) data ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
unsigned len = desc - > size + 4 ;
char * buf = new char [ len ] ;
memset ( buf , 0 , len ) ;
if ( setv )
{
2023-01-28 07:20:51 +00:00
char * init = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
2023-02-07 08:55:51 +00:00
bool def = strcmp ( init , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMYM_TGKBYFPZ , true , nullptr ) ) = = 0 ;
2023-01-28 07:20:51 +00:00
local_utility : : free_memory ( init ) ;
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id , buf ) ;
2023-02-07 08:55:51 +00:00
val = strcmp ( buf , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMYM_TGKBYFPZ , true , nullptr ) ) = = 0 ;
2023-01-28 07:20:51 +00:00
set_cur_and_def_value < bool > ( val , def , setv , data ) ;
2022-06-15 03:04:40 +00:00
}
else
{
if ( val )
2023-02-07 08:55:51 +00:00
strcpy ( buf , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMYM_TGKBYFPZ , true , nullptr ) ) ;
2022-06-15 03:04:40 +00:00
else
{
2023-01-28 07:20:51 +00:00
char * init = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
strcpy ( buf , init ) ;
local_utility : : free_memory ( init ) ;
}
SANE_Int after = 0 ;
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , buf , & after ) ;
2022-06-15 03:04:40 +00:00
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
delete [ ] buf ;
return ret ;
}
EX_OPTION_HANDLER_IMPL ( page_fold )
{
int ret = SCANNER_ERR_OK ;
bool val = * ( bool * ) data ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
unsigned len = desc - > size + 4 ;
char * buf = new char [ len ] ;
memset ( buf , 0 , len ) ;
if ( setv )
{
2023-01-28 07:20:51 +00:00
char * init = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
2023-02-07 08:55:51 +00:00
bool def = strcmp ( init , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMYM_DZ , true , nullptr ) ) = = 0 ;
2023-01-28 07:20:51 +00:00
local_utility : : free_memory ( init ) ;
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id , buf ) ;
2023-02-07 08:55:51 +00:00
val = strcmp ( buf , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMYM_DZ , true , nullptr ) ) = = 0 ;
2023-01-28 07:20:51 +00:00
set_cur_and_def_value < bool > ( val , def , setv , data ) ;
2022-06-15 03:04:40 +00:00
}
else
{
if ( val )
2023-02-07 08:55:51 +00:00
strcpy ( buf , local_trans : : lang_trans_between_hz936 ( OPTION_VALUE_SMYM_DZ , true , nullptr ) ) ;
2022-06-15 03:04:40 +00:00
else
{
2023-01-28 07:20:51 +00:00
char * init = ( char * ) hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
strcpy ( buf , init ) ;
local_utility : : free_memory ( init ) ;
}
SANE_Int after = 0 ;
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , buf , & after ) ;
2022-06-15 03:04:40 +00:00
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
delete [ ] buf ;
return ret ;
}
EX_OPTION_HANDLER_IMPL ( color_filter ) // int (filter_value)
{
int ret = SCANNER_ERR_DEVICE_NOT_SUPPORT ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
char * buf = NULL ;
unsigned int len = 0 ;
if ( desc )
{
len = desc - > size + 4 ;
buf = new char [ len ] ;
memset ( buf , 0 , len ) ;
if ( setv )
{
bool filter = false ;
int val = FILTER_NONE , now = FILTER_NONE ;
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id , buf ) ;
2022-06-15 03:04:40 +00:00
now = sane_opt_trans : : filter_enhance_value_to_twain ( buf , & filter ) ;
if ( ! filter )
now = val ;
do
{
if ( desc - > constraint_type = = SANE_CONSTRAINT_STRING_LIST )
{
for ( int i = 0 ; desc - > constraint . string_list [ i ] ; + + i )
{
value_role role = VAL_ROLE_NONE ;
int v = sane_opt_trans : : filter_enhance_value_to_twain ( desc - > constraint . string_list [ i ] , & filter ) ;
if ( ! filter & & v ! = FILTER_NONE )
continue ;
if ( v = = now )
role = VAL_ROLE_CURRENT ;
if ( v = = val )
role = value_role ( role | VAL_ROLE_DEFAULT ) ;
2023-01-28 07:20:51 +00:00
if ( ! setv ( & v , role , VAL_LIMIT_ENUM , data ) )
2022-06-15 03:04:40 +00:00
break ;
}
}
} while ( 0 ) ;
}
else
{
const char * val = sane_opt_trans : : filter_enhance_value_from_twain ( * ( ( int * ) data ) , true ) ;
SANE_Int after = 0 ;
strcpy ( buf , val ) ;
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , buf , & after ) ;
2022-06-15 03:04:40 +00:00
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
delete [ ] buf ;
}
return ret ;
}
EX_OPTION_HANDLER_IMPL ( color_enhance ) // int (enhance_value)
{
int ret = SCANNER_ERR_DEVICE_NOT_SUPPORT ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
2022-06-15 03:04:40 +00:00
char * buf = NULL ;
unsigned int len = 0 ;
if ( desc )
{
len = desc - > size + 4 ;
buf = new char [ len ] ;
memset ( buf , 0 , len ) ;
if ( setv )
{
bool filter = false ;
int val = ENHANCE_NONE , now = ENHANCE_NONE ;
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id , buf ) ;
2022-06-15 03:04:40 +00:00
now = sane_opt_trans : : filter_enhance_value_to_twain ( buf , & filter ) ;
if ( filter )
now = val ;
do
{
if ( desc - > constraint_type = = SANE_CONSTRAINT_STRING_LIST )
{
for ( int i = 0 ; desc - > constraint . string_list [ i ] ; + + i )
{
value_role role = VAL_ROLE_NONE ;
int v = sane_opt_trans : : filter_enhance_value_to_twain ( desc - > constraint . string_list [ i ] , & filter ) ;
if ( filter & & v ! = ENHANCE_NONE )
continue ;
if ( v = = now )
role = VAL_ROLE_CURRENT ;
if ( v = = val )
role = value_role ( role | VAL_ROLE_DEFAULT ) ;
2023-01-28 07:20:51 +00:00
if ( ! setv ( & v , role , VAL_LIMIT_ENUM , data ) )
2022-06-15 03:04:40 +00:00
break ;
}
}
} while ( 0 ) ;
}
else
{
const char * val = sane_opt_trans : : filter_enhance_value_from_twain ( * ( ( int * ) data ) , false ) ;
SANE_Int after = 0 ;
strcpy ( buf , val ) ;
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) base_id , SANE_ACTION_SET_VALUE , buf , & after ) ;
2022-06-15 03:04:40 +00:00
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
delete [ ] buf ;
}
return ret ;
}
EX_OPTION_HANDLER_IMPL ( final_compression )
{
int ret = SCANNER_ERR_OK ;
int * compression = ( int * ) data ;
unsigned int len = sizeof ( * compression ) ;
if ( setv )
{
int val = 0 ;
ret = hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_GET_FINAL_COMPRESSION , & val , & len ) ;
if ( ret = = SANE_STATUS_GOOD )
{
int i = SANE_COMPRESSION_FIRST ;
for ( ; i < SANE_COMPRESSION_LAST ; + + i )
{
value_role role = VAL_ROLE_NONE ;
if ( i = = val )
role = VAL_ROLE_CURRENT ;
if ( i = = SANE_COMPRESSION_NONE )
role = value_role ( role | VAL_ROLE_DEFAULT ) ;
int v = sane_opt_trans : : compression_to_twain ( i ) ;
2023-01-28 07:20:51 +00:00
if ( ! setv ( & v , role , VAL_LIMIT_ENUM , data ) )
2022-06-15 03:04:40 +00:00
break ;
}
}
}
else
{
int val = sane_opt_trans : : compression_from_twain ( * ( int * ) data ) ;
len = sizeof ( val ) ;
ret = hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_SET_FINAL_COMPRESSION , & val , & len ) ;
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
return ret ;
}
EX_OPTION_HANDLER_IMPL ( final_format )
{
int ret = SCANNER_ERR_OK ;
SANE_FinalImgFormat ff ;
unsigned int len = sizeof ( ff ) ;
if ( setv )
{
ret = hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_GET_FINAL_IMAGE_FORMAT , & ff , & len ) ;
if ( ret = = SANE_STATUS_GOOD )
{
int now = ff . img_format , init = SANE_IMAGE_TYPE_BMP ;
std : : vector < int > all ( sane_opt_trans : : support_image_types ( ) ) ;
2022-07-18 02:55:01 +00:00
for ( int i = 0 ; i < ( int ) all . size ( ) ; + + i )
2022-06-15 03:04:40 +00:00
{
value_role role = VAL_ROLE_NONE ;
ff . img_format = ( SANE_ImageType ) all [ i ] ;
if ( ff . img_format = = now )
role = VAL_ROLE_CURRENT ;
if ( ff . img_format = = init )
role = value_role ( role | VAL_ROLE_DEFAULT ) ;
2023-01-28 07:20:51 +00:00
if ( ! setv ( & ff , role , VAL_LIMIT_ENUM , data ) )
2022-06-15 03:04:40 +00:00
break ;
}
}
}
else
{
ret = hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_SET_FINAL_IMAGE_FORMAT , data , & len ) ;
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
return ret ;
}
EX_OPTION_HANDLER_IMPL ( serial )
{
int ret = SCANNER_ERR_INVALID_PARAMETER ;
if ( setv )
{
std : : string val ( " " ) ;
ret = control_read_string ( IO_CTRL_CODE_GET_SERIAL , val ) ;
if ( ret = = SANE_STATUS_GOOD )
2023-01-28 07:20:51 +00:00
setv ( & val , VAL_ROLE_CURRENT , VAL_LIMIT_NONE , data ) ;
2022-06-15 03:04:40 +00:00
}
return ret ;
}
EX_OPTION_HANDLER_IMPL ( to_be_scan )
{
int ret = SCANNER_ERR_OK ;
SANE_Bool wait_paper = SANE_FALSE ;
unsigned int len = sizeof ( wait_paper ) ;
if ( setv )
{
ret = hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_GET_SCAN_WHEN_PAPER_ON , & wait_paper , & len ) ;
if ( ret = = SANE_STATUS_GOOD )
{
bool val = wait_paper = = SANE_TRUE ;
2023-01-28 07:20:51 +00:00
set_cur_and_def_value < bool > ( val , false , setv , data ) ;
2022-06-15 03:04:40 +00:00
}
}
else
{
wait_paper = * ( ( bool * ) data ) ? SANE_TRUE : SANE_FALSE ;
ret = hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_SET_SCAN_WHEN_PAPER_ON , & wait_paper , & len ) ;
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
return ret ;
}
EX_OPTION_HANDLER_IMPL ( scan_with_hole )
{
int ret = SCANNER_ERR_OK ;
SANE_Bool with_hole = SANE_FALSE ;
unsigned int len = sizeof ( with_hole ) ;
if ( setv )
{
ret = hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_GET_SCAN_WITH_HOLE , & with_hole , & len ) ;
if ( ret = = SANE_STATUS_GOOD )
{
bool val = with_hole = = SANE_TRUE ;
2023-01-28 07:20:51 +00:00
set_cur_and_def_value < bool > ( val , false , setv , data ) ;
2022-06-15 03:04:40 +00:00
}
}
else
{
with_hole = * ( ( bool * ) data ) ? SANE_TRUE : SANE_FALSE ;
ret = hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_SET_SCAN_WITH_HOLE , & with_hole , & len ) ;
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
return ret ;
}
EX_OPTION_HANDLER_IMPL ( device_code )
{
int ret = SCANNER_ERR_INVALID_PARAMETER ;
if ( setv )
{
std : : string val ( " " ) ;
ret = control_read_string ( IO_CTRL_CODE_GET_DEVICE_CODE , val ) ;
if ( ret = = SANE_STATUS_GOOD )
2023-01-28 07:20:51 +00:00
setv ( & val , VAL_ROLE_CURRENT , VAL_LIMIT_NONE , data ) ;
2022-06-15 03:04:40 +00:00
}
return ret ;
}
EX_OPTION_HANDLER_IMPL ( power )
{
int ret = SCANNER_ERR_OK ;
if ( setv )
{
SANE_Power now = SANE_POWER_MINUTES_30 , init = SANE_POWER_MINUTES_30 ;
unsigned int len = sizeof ( now ) ;
hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_GET_POWER_LEVEL , & now , & len ) ;
for ( int i = SANE_POWER_FIRST ; i < SANE_POWER_LAST ; + + i )
{
value_role role = VAL_ROLE_NONE ;
if ( i = = now )
role = VAL_ROLE_CURRENT ;
if ( i = = init )
role = value_role ( role | VAL_ROLE_DEFAULT ) ;
SANE_Power power = ( SANE_Power ) i ;
2023-01-28 07:20:51 +00:00
if ( ! setv ( & power , role , VAL_LIMIT_ENUM , data ) )
2022-06-15 03:04:40 +00:00
break ;
}
}
else
{
SANE_Power power = * ( ( SANE_Power * ) data ) ;
unsigned int len = sizeof ( power ) ;
ret = hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_SET_POWER_LEVEL , & power , & len ) ;
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
return ret ;
}
EX_OPTION_HANDLER_IMPL ( hardware_version )
{
int ret = SCANNER_ERR_INVALID_PARAMETER ;
if ( setv )
{
std : : string val ( " " ) ;
ret = control_read_string ( IO_CTRL_CODE_GET_HARDWARE_VERSION , val ) ;
if ( ret = = SANE_STATUS_GOOD )
2023-01-28 07:20:51 +00:00
setv ( & val , VAL_ROLE_CURRENT , VAL_LIMIT_NONE , data ) ;
2022-06-15 03:04:40 +00:00
}
return ret ;
}
EX_OPTION_HANDLER_IMPL ( ip )
{
int ret = SCANNER_ERR_INVALID_PARAMETER ;
if ( setv )
{
std : : string val ( " " ) ;
ret = control_read_string ( IO_CTRL_CODE_GET_IP , val ) ;
if ( ret = = SANE_STATUS_GOOD )
2023-01-28 07:20:51 +00:00
setv ( & val , VAL_ROLE_CURRENT , VAL_LIMIT_NONE , data ) ;
2022-06-15 03:04:40 +00:00
}
return ret ;
}
2022-09-12 06:45:07 +00:00
EX_OPTION_HANDLER_IMPL ( erase_hole )
{
int ret = SCANNER_ERR_DEVICE_NOT_SUPPORT ;
if ( is_erase_hole_l_id_ ! = - 1 | | is_erase_hole_r_id_ ! = - 1 )
{
2023-01-28 07:20:51 +00:00
SANE_Bool yes = SANE_FALSE , def = SANE_FALSE ;
2022-09-12 06:45:07 +00:00
SANE_Int after = 0 ;
if ( setv )
{
if ( is_erase_hole_l_id_ ! = - 1 )
2023-01-28 07:20:51 +00:00
{
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) is_erase_hole_l_id_ , & yes ) ;
hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) is_erase_hole_l_id_ , & def ) ;
}
2022-09-12 06:45:07 +00:00
if ( ! yes & & is_erase_hole_r_id_ ! = - 1 )
2023-01-28 07:20:51 +00:00
{
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) is_erase_hole_r_id_ , & yes ) ;
hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) is_erase_hole_r_id_ , & def ) ;
}
2022-09-12 06:45:07 +00:00
2023-01-28 07:20:51 +00:00
set_cur_and_def_value < bool > ( yes = = SANE_TRUE , def = = SANE_TRUE , setv , data ) ;
2022-09-12 06:45:07 +00:00
ret = SCANNER_ERR_OK ;
}
else
{
yes = * ( bool * ) data ? SANE_TRUE : SANE_FALSE ;
if ( is_erase_hole_l_id_ ! = - 1 )
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) is_erase_hole_l_id_ , SANE_ACTION_SET_VALUE , & yes , & after ) ;
2022-09-12 06:45:07 +00:00
yes = * ( bool * ) data ? SANE_TRUE : SANE_FALSE ;
if ( is_erase_hole_r_id_ ! = - 1 )
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) is_erase_hole_r_id_ , SANE_ACTION_SET_VALUE , & yes , & after ) ;
2022-09-12 06:45:07 +00:00
}
}
return ret ;
}
EX_OPTION_HANDLER_IMPL ( search_hole_range )
{
int ret = SCANNER_ERR_DEVICE_NOT_SUPPORT ;
if ( search_hole_range_l_id_ ! = - 1 | | search_hole_range_r_id_ ! = - 1 )
{
SANE_Fixed val = 0 ;
SANE_Int after = 0 ;
2023-01-28 07:20:51 +00:00
double rv = .0f , def = .0f ;
2022-09-12 06:45:07 +00:00
if ( setv )
{
2023-01-28 07:20:51 +00:00
const SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) base_id ) ;
void * init = hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) base_id ) ,
* cur = hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) base_id ) ;
float n = SANE_UNFIX ( * ( SANE_Fixed * ) cur ) ,
d = SANE_UNFIX ( * ( SANE_Fixed * ) init ) ;
if ( desc - > constraint_type = = SANE_CONSTRAINT_RANGE )
2022-09-12 06:45:07 +00:00
{
2023-01-28 07:20:51 +00:00
float l = SANE_UNFIX ( desc - > constraint . range - > min ) ,
u = SANE_UNFIX ( desc - > constraint . range - > max ) ,
s = SANE_UNFIX ( desc - > constraint . range - > quant ) ;
set_value_range < SANE_Fixed , float > ( * ( SANE_Fixed * ) cur , * ( SANE_Fixed * ) init , desc - > constraint . range - > min , desc - > constraint . range - > max , desc - > constraint . range - > quant , setv , data , & scanner : : to_float ) ;
2022-09-12 06:45:07 +00:00
}
2023-01-28 07:20:51 +00:00
else
set_cur_and_def_value < float > ( n , d , setv , data ) ;
local_utility : : free_memory ( init ) ;
local_utility : : free_memory ( cur ) ;
2022-09-12 06:45:07 +00:00
ret = SCANNER_ERR_OK ;
}
else
{
2023-01-28 07:20:51 +00:00
rv = ( double ) * ( float * ) data ;
val = SANE_FIX ( rv ) ;
2022-09-12 06:45:07 +00:00
if ( search_hole_range_l_id_ ! = - 1 )
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) search_hole_range_l_id_ , SANE_ACTION_SET_VALUE , & val , & after ) ;
val = SANE_FIX ( rv ) ;
2022-09-12 06:45:07 +00:00
if ( search_hole_range_r_id_ ! = - 1 )
2023-01-28 07:20:51 +00:00
ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) search_hole_range_r_id_ , SANE_ACTION_SET_VALUE , & val , & after ) ;
2022-09-12 06:45:07 +00:00
}
}
return ret ;
}
2022-06-15 03:04:40 +00:00
// ISaneInvoker
2022-10-21 08:46:20 +00:00
COM_API_IMPLEMENT ( scanner , int , start ( void ) )
2022-06-15 03:04:40 +00:00
{
2022-06-18 08:48:41 +00:00
int ret = SANE_STATUS_GOOD ;
2023-03-28 07:02:24 +00:00
ev_cnt_ = 0 ;
2022-09-19 06:16:34 +00:00
events_ . clear ( ) ;
images_ . clear ( ) ;
2022-06-18 08:48:41 +00:00
scan_msg_ = " OK " ;
scan_err_ = false ;
2022-11-25 06:20:06 +00:00
user_cancel_ = false ;
2022-10-21 08:46:20 +00:00
app_wnd_ = setting_ . get ( ) ? setting_ - > hwnd ( ) : callback : : find_main_wnd ( ) ;
2022-07-02 09:27:21 +00:00
ret = hg_sane_middleware : : instance ( ) - > start ( handle_ , NULL ) ;
2022-06-15 03:04:40 +00:00
// the third-APPs in linux will call 'stop' after every start, but it not happens in windows-apps, so we handle this as following ...
if ( ret = = SANE_STATUS_NO_DOCS & & prev_start_result_ = = SANE_STATUS_GOOD )
ret = hg_sane_middleware : : instance ( ) - > start ( handle_ , NULL ) ;
2022-06-17 03:50:18 +00:00
if ( ret = = SANE_STATUS_GOOD )
{
2022-07-04 08:31:37 +00:00
if ( indicator_ . get ( ) & & ! IsWindowVisible ( indicator_ - > hwnd ( ) ) )
indicator_ - > show ( true ) ;
2022-06-17 03:50:18 +00:00
unsigned int l = sizeof ( img_fmt_ ) ;
2022-06-29 08:13:05 +00:00
SANE_CompressionType cmprsn = img_fmt_ . compress . compression ;
2022-06-17 03:50:18 +00:00
if ( hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_GET_FINAL_IMAGE_FORMAT , & img_fmt_ , & l ) )
img_fmt_ . img_format = SANE_IMAGE_TYPE_BMP ;
2022-06-29 08:13:05 +00:00
img_fmt_ . compress . compression = cmprsn ;
2022-06-17 03:50:18 +00:00
}
2022-09-22 08:25:03 +00:00
//else if (indicator_.get())
//{
// indicator_->notify_scan_over(hg_scanner_err_description(ret), true);
//}
else
2022-07-04 08:31:37 +00:00
{
2022-09-22 08:25:03 +00:00
std : : wstring msg ( local_trans : : a2u ( hg_scanner_err_description ( ret ) , CP_UTF8 ) ) ;
2022-10-21 08:46:20 +00:00
2022-09-22 08:25:03 +00:00
if ( indicator_ . get ( ) )
2022-09-28 12:01:14 +00:00
indicator_ - > show ( false ) ;
2022-10-21 08:46:20 +00:00
if ( ! IsWindow ( app_wnd_ ) )
2023-02-07 08:55:51 +00:00
callback : : bring_message_box_topmost ( local_trans : : lang_trans_between_hz936 ( CONST_STRING_START_FAILED ) . c_str ( ) ) ;
MessageBoxW ( app_wnd_ , msg . c_str ( ) , local_trans : : lang_trans_between_hz936 ( CONST_STRING_START_FAILED ) . c_str ( ) , MB_OK | MB_ICONERROR ) ;
2022-07-04 08:31:37 +00:00
}
2022-06-15 03:04:40 +00:00
prev_start_result_ = ret ;
2022-09-19 06:16:34 +00:00
is_scanning_ = ret = = SANE_STATUS_GOOD ;
2022-06-15 03:04:40 +00:00
2022-06-16 08:04:58 +00:00
return local_utility : : sane_statu_2_scanner_err ( ret ) ;
2022-06-15 03:04:40 +00:00
}
COM_API_IMPLEMENT ( scanner , int , stop ( void ) )
{
2022-11-25 06:20:06 +00:00
user_cancel_ = true ;
2022-06-15 03:04:40 +00:00
return hg_sane_middleware : : instance ( ) - > stop ( handle_ ) ;
}
2022-07-02 09:27:21 +00:00
COM_API_IMPLEMENT ( scanner , int , get_event ( void ) )
2022-06-15 03:04:40 +00:00
{
2022-07-02 09:27:21 +00:00
return events_ . take ( ) ;
2022-06-15 03:04:40 +00:00
}
2022-10-21 08:46:20 +00:00
COM_API_IMPLEMENT ( scanner , void , set_event_callback ( int ( __stdcall * handle_ev ) ( int , void * ) , void * para ) )
{
scanner_ev_handler_ = handle_ev ;
evh_param_ = para ;
}
2022-06-15 03:04:40 +00:00
COM_API_IMPLEMENT ( scanner , bool , wait_image ( DWORD milliseconds ) )
{
int count = get_scanned_images ( milliseconds ) ;
return count > 0 ;
}
COM_API_IMPLEMENT ( scanner , int , get_scanned_images ( DWORD milliseconds ) )
{
2022-06-18 00:54:01 +00:00
size_t count = images_ . count ( ) ;
2022-07-02 09:27:21 +00:00
DWORD elapse = 10 ;
2022-06-15 03:04:40 +00:00
2022-09-19 06:16:34 +00:00
is_ui_wait_img_ = true ;
while ( is_scanning_ & & count = = 0 & & milliseconds )
2022-06-15 03:04:40 +00:00
{
2022-06-18 08:48:41 +00:00
MSG msg = { 0 } ;
if ( PeekMessage ( & msg , NULL , 0 , 0 , PM_REMOVE ) )
{
TranslateMessage ( & msg ) ;
DispatchMessageW ( & msg ) ;
}
2022-11-07 08:49:24 +00:00
else
Sleep ( elapse ) ;
2022-07-02 09:27:21 +00:00
int ev = get_event ( ) ;
count = images_ . count ( ) ;
if ( ev = = SANE_EVENT_SCAN_FINISHED )
2022-06-18 08:48:41 +00:00
{
2022-07-02 09:27:21 +00:00
ui_hide ( ) ;
break ;
}
else if ( ev = = SANE_EVENT_UI_CLOSE_CANCEL )
{
stop ( ) ;
ui_hide ( ) ;
break ;
}
else if ( ev = = SANE_EVENT_UI_CLOSE_NORMAL )
{
ui_hide ( ) ;
break ;
2022-06-18 08:48:41 +00:00
}
2022-06-18 00:54:01 +00:00
if ( milliseconds ! = - 1 )
2022-06-15 03:04:40 +00:00
{
2022-07-02 09:27:21 +00:00
if ( milliseconds < = elapse )
2022-06-15 03:04:40 +00:00
break ;
2022-07-02 09:27:21 +00:00
milliseconds - = elapse ;
2022-06-15 03:04:40 +00:00
}
}
2022-09-19 06:16:34 +00:00
is_ui_wait_img_ = false ;
count = images_ . count ( ) ;
{
wchar_t msg [ 128 ] = { 0 } ;
swprintf_s ( msg , _countof ( msg ) - 1 , L " Wait image count = %d \r \n " , count ) ;
log_info ( msg , 0 ) ;
}
2022-06-15 03:04:40 +00:00
return count ;
}
2022-06-16 09:28:46 +00:00
COM_API_IMPLEMENT ( scanner , IScanImg * , take_first_image ( twain_xfer xfer ) )
2022-06-15 03:04:40 +00:00
{
2022-06-18 00:54:01 +00:00
scanned_img * img = images_ . take ( ) ;
2022-06-15 03:04:40 +00:00
return dynamic_cast < IScanImg * > ( img ) ;
}
2022-11-06 08:49:30 +00:00
COM_API_IMPLEMENT ( scanner , bool , get_first_image_header ( SANE_Parameters * header , size_t * bytes , int * dpi ) )
2022-06-15 03:04:40 +00:00
{
2022-11-06 08:49:30 +00:00
return images_ . get_header ( header , bytes , dpi ) ;
2022-06-15 03:04:40 +00:00
}
COM_API_IMPLEMENT ( scanner , bool , is_online ( void ) )
{
2022-10-09 03:59:45 +00:00
std : : string sn ( " " ) ;
return handle_ & & control_read_string ( IO_CTRL_CODE_GET_SERIAL , sn ) ! = SCANNER_ERR_DEVICE_NOT_FOUND ;
2022-06-15 03:04:40 +00:00
}
COM_API_IMPLEMENT ( scanner , bool , is_paper_on ( void ) )
{
SANE_Bool on = SANE_FALSE ;
unsigned int len = sizeof ( on ) ;
if ( hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_GET_PAPER_ON , & on , & len ) = = SANE_STATUS_GOOD )
return on = = SANE_TRUE ;
else
return false ;
}
2023-03-28 09:13:18 +00:00
COM_API_IMPLEMENT ( scanner , int , last_error ( void ) )
{
return err_ ;
}
2022-06-15 03:04:40 +00:00
COM_API_IMPLEMENT ( scanner , bool , get_option_info ( int sn , value_type * type , value_limit * limit , int * bytes ) )
{
2022-10-14 02:11:43 +00:00
EXAPIPOS ex = find_ex_api ( sn ) ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ex = = ex_opts_ . end ( ) ? ( void * ) sn : ( void * ) ex - > base_ind ) ;
2022-06-15 03:04:40 +00:00
bool ret = false ;
if ( desc )
{
if ( type )
* type = scanner : : from_sane_type ( desc - > type ) ;
if ( limit )
* limit = scanner : : from_sane_constraint ( desc - > constraint_type ) ;
if ( bytes )
* bytes = desc - > size ;
ret = true ;
}
return ret ;
}
COM_API_IMPLEMENT ( scanner , bool , get_value ( int sn , set_opt_value setval , void * param ) )
{
EXAPIPOS ex = find_ex_api ( sn ) ;
int ret = SANE_STATUS_INVAL ;
SANE_Int after = 0 ;
if ( ex = = ex_opts_ . end ( ) )
{
if ( get_option_value_with_parent ( sn , setval , param ) )
return true ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) sn ) ;
void * init = hg_sane_middleware : : instance ( ) - > get_def_value ( handle_ , ( void * ) sn ) ;
2022-06-15 03:04:40 +00:00
ret = SANE_STATUS_GOOD ;
if ( desc - > type = = SANE_TYPE_BOOL )
{
SANE_Bool v = SANE_FALSE ;
bool val = false ;
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) sn , & v ) ;
2022-06-15 03:04:40 +00:00
val = v = = SANE_TRUE ;
2023-01-28 07:20:51 +00:00
//set_cur_and_def_value<bool>(val, *(SANE_Bool*)init == SANE_TRUE, setval, param);
{
int role = VAL_ROLE_NONE ;
val = false ;
if ( * ( SANE_Bool * ) init = = SANE_FALSE )
role | = VAL_ROLE_DEFAULT ;
if ( v = = SANE_FALSE )
role | = VAL_ROLE_CURRENT ;
setval ( & val , ( value_role ) role , VAL_LIMIT_ENUM , param ) ;
val = true ;
role = VAL_ROLE_NONE ;
if ( * ( SANE_Bool * ) init = = SANE_TRUE )
role | = VAL_ROLE_DEFAULT ;
if ( v = = SANE_TRUE )
role | = VAL_ROLE_CURRENT ;
setval ( & val , ( value_role ) role , VAL_LIMIT_ENUM , param ) ;
}
2022-06-15 03:04:40 +00:00
}
else if ( desc - > type = = SANE_TYPE_INT )
{
SANE_Int cur = 0 , def = * ( SANE_Int * ) init ;
int val = 0 ;
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) sn , & cur ) ;
2022-06-15 03:04:40 +00:00
val = cur ;
2022-06-16 08:04:58 +00:00
if ( sn = = resolution_id_ )
dpi_ = cur ;
2022-06-15 03:04:40 +00:00
do
{
if ( desc - > constraint_type = = SANE_CONSTRAINT_RANGE )
{
set_value_range < SANE_Int , int > ( cur , def , desc - > constraint . range - > min , desc - > constraint . range - > max , desc - > constraint . range - > quant , setval , param , scanner : : to_int ) ;
}
else if ( desc - > constraint_type = = SANE_CONSTRAINT_WORD_LIST )
{
const SANE_Word * v = desc - > constraint . word_list ;
for ( int i = 0 ; i < v [ 0 ] ; + + i )
{
value_role role = VAL_ROLE_NONE ;
if ( v [ i + 1 ] = = cur )
role = value_role ( role | VAL_ROLE_CURRENT ) ;
if ( v [ i + 1 ] = = * ( SANE_Int * ) init )
role = value_role ( role | VAL_ROLE_DEFAULT ) ;
val = v [ i + 1 ] ;
2023-01-28 07:20:51 +00:00
if ( ! setval ( & val , role , VAL_LIMIT_ENUM , param ) )
2022-06-15 03:04:40 +00:00
break ;
}
}
else
set_cur_and_def_value < int > ( val , * ( SANE_Int * ) init , setval , param ) ;
} while ( 0 ) ;
}
else if ( desc - > type = = SANE_TYPE_FIXED )
{
SANE_Fixed cur = 0 , def = * ( SANE_Fixed * ) init ;
float val = .0f ;
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) sn , & cur ) ;
2022-06-16 08:04:58 +00:00
if ( sn = = resolution_id_ )
2022-07-18 02:55:01 +00:00
dpi_ = ( int ) ( SANE_UNFIX ( cur ) + .5f ) ;
2022-06-15 03:04:40 +00:00
do
{
if ( desc - > constraint_type = = SANE_CONSTRAINT_RANGE )
{
set_value_range < SANE_Fixed , float > ( cur , def , desc - > constraint . range - > min , desc - > constraint . range - > max , desc - > constraint . range - > quant , setval , param , scanner : : to_float ) ;
}
else if ( desc - > constraint_type = = SANE_CONSTRAINT_WORD_LIST )
{
const SANE_Word * v = desc - > constraint . word_list ;
for ( int i = 0 ; i < v [ 0 ] ; + + i )
{
value_role role = VAL_ROLE_NONE ;
if ( v [ i + 1 ] = = cur )
role = value_role ( role | VAL_ROLE_CURRENT ) ;
if ( v [ i + 1 ] = = def )
role = value_role ( role | VAL_ROLE_DEFAULT ) ;
2022-07-18 02:55:01 +00:00
val = ( float ) SANE_UNFIX ( v [ i + 1 ] ) ;
2023-01-28 07:20:51 +00:00
if ( ! setval ( & val , role , VAL_LIMIT_ENUM , param ) )
2022-06-15 03:04:40 +00:00
break ;
}
}
else
2022-07-18 02:55:01 +00:00
set_cur_and_def_value < float > ( val , ( float ) SANE_UNFIX ( * ( SANE_Fixed * ) init ) , setval , param ) ;
2022-06-15 03:04:40 +00:00
} while ( 0 ) ;
}
else if ( desc - > type = = SANE_TYPE_STRING )
{
char * buf = new char [ desc - > size + 4 ] ;
std : : string val ( " " ) , def ( ( char * ) init ) ;
memset ( buf , 0 , desc - > size + 4 ) ;
2023-01-28 07:20:51 +00:00
hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) sn , buf ) ;
2022-06-15 03:04:40 +00:00
val = buf ;
do
{
if ( desc - > constraint_type = = SANE_CONSTRAINT_STRING_LIST )
{
for ( int i = 0 ; desc - > constraint . string_list [ i ] ; + + i )
{
value_role role = VAL_ROLE_NONE ;
if ( strcmp ( desc - > constraint . string_list [ i ] , buf ) = = 0 )
role = value_role ( role | VAL_ROLE_CURRENT ) ;
if ( strcmp ( desc - > constraint . string_list [ i ] , ( char * ) init ) = = 0 )
role = value_role ( role | VAL_ROLE_DEFAULT ) ;
val = desc - > constraint . string_list [ i ] ;
2023-01-28 07:20:51 +00:00
if ( ! setval ( & val , role , VAL_LIMIT_ENUM , param ) )
2022-06-15 03:04:40 +00:00
break ;
}
}
else
set_cur_and_def_value < std : : string > ( val , def , setval , param ) ;
} while ( 0 ) ;
delete [ ] buf ;
}
else
{
ret = SANE_STATUS_INVAL ;
}
local_utility : : free_memory ( init ) ;
}
else
{
ret = ( this - > * ex - > ex_api ) ( ex - > base_ind , param , setval ) ;
}
return ret = = SANE_STATUS_GOOD ;
}
COM_API_IMPLEMENT ( scanner , int , set_value ( int sn , void * val ) )
{
EXAPIPOS ex = find_ex_api ( sn ) ;
int ret = SANE_STATUS_INVAL ;
SANE_Int after = 0 ;
2023-01-28 07:20:51 +00:00
SANE_Option_Descriptor * desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) sn ) ;
2022-06-15 03:04:40 +00:00
2022-09-23 08:47:00 +00:00
{
2022-11-19 00:48:39 +00:00
wchar_t msg [ 256 ] = { 0 } ;
2022-10-07 09:51:09 +00:00
if ( ex = = ex_opts_ . end ( ) )
2022-11-19 00:48:39 +00:00
swprintf_s ( msg , _countof ( msg ) - 1 , L " set_value of %s(%s) of ID %d \r \n " , local_trans : : a2u ( desc - > name , CP_UTF8 ) . c_str ( ) , local_trans : : a2u ( hg_sane_middleware : : option_value_2_string ( desc - > type , val ) . c_str ( ) , CP_UTF8 ) . c_str ( ) , sn ) ;
2023-01-28 07:20:51 +00:00
else if ( ex - > base_ind ! = - 1 )
2022-11-19 00:48:39 +00:00
{
2023-01-28 07:20:51 +00:00
desc = hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle_ , ( void * ) ex - > base_ind ) ;
2022-11-19 00:48:39 +00:00
swprintf_s ( msg , _countof ( msg ) - 1 , L " set_value of %s(0x%x) of ID %d, base id = %d) \r \n " , local_trans : : a2u ( desc - > name , CP_UTF8 ) . c_str ( ) , * ( unsigned * ) val , sn , ex - > base_ind ) ;
}
2022-09-23 08:47:00 +00:00
log_info ( msg , 0 ) ;
}
2023-03-08 06:45:50 +00:00
twain_set_ = true ;
2022-06-15 03:04:40 +00:00
if ( ex = = ex_opts_ . end ( ) )
{
if ( ! set_option_value_with_parent ( sn , val , & ret ) )
ret = set_option_value ( sn , desc - > type , desc - > size , val ) ;
ret = local_utility : : sane_statu_2_scanner_err ( ret ) ;
}
else
{
ret = ( this - > * ex - > ex_api ) ( ex - > base_ind , val , NULL ) ;
}
2022-06-16 08:04:58 +00:00
if ( sn = = resolution_id_ )
{
if ( desc - > type = = SANE_TYPE_FIXED )
2022-07-18 02:55:01 +00:00
dpi_ = ( int ) ( * ( float * ) val + .5f ) ;
2022-06-16 08:04:58 +00:00
else
dpi_ = * ( int * ) val ;
}
2022-06-15 03:04:40 +00:00
return ret ;
}
2022-06-28 09:17:10 +00:00
COM_API_IMPLEMENT ( scanner , int , convert_image ( SANE_ImageFormatConvert * conv ) )
{
return hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_CONVERT_IMAGE_FORMAT , conv , NULL ) ;
}
2022-06-29 08:13:05 +00:00
COM_API_IMPLEMENT ( scanner , void , free_buffer ( void * buf , int len ) )
{
hg_sane_middleware : : instance ( ) - > io_control ( handle_ , IO_CTRL_CODE_FREE_MEMORY , buf , ( unsigned int * ) & len ) ;
}
2022-06-15 03:04:40 +00:00
// SANE options ID ...
2023-02-24 09:44:47 +00:00
SANE_OPTION_ID_IMPLEMENT ( color_correction )
SANE_OPTION_ID_IMPLEMENT ( fold_type )
2022-06-15 03:04:40 +00:00
SANE_OPTION_ID_IMPLEMENT ( is_multiout )
SANE_OPTION_ID_IMPLEMENT ( multiout_type )
SANE_OPTION_ID_IMPLEMENT ( color_mode )
SANE_OPTION_ID_IMPLEMENT ( erase_color )
SANE_OPTION_ID_IMPLEMENT ( erase_multiout_red )
SANE_OPTION_ID_IMPLEMENT ( erase_paper_red )
SANE_OPTION_ID_IMPLEMENT ( is_erase_background )
SANE_OPTION_ID_IMPLEMENT ( background_color_range )
SANE_OPTION_ID_IMPLEMENT ( sharpen )
SANE_OPTION_ID_IMPLEMENT ( erase_morr )
SANE_OPTION_ID_IMPLEMENT ( erase_grids )
SANE_OPTION_ID_IMPLEMENT ( error_extend )
SANE_OPTION_ID_IMPLEMENT ( is_noise_modify )
SANE_OPTION_ID_IMPLEMENT ( noise_threshold )
SANE_OPTION_ID_IMPLEMENT ( paper )
SANE_OPTION_ID_IMPLEMENT ( is_custom_area )
SANE_OPTION_ID_IMPLEMENT ( curstom_area_l )
SANE_OPTION_ID_IMPLEMENT ( curstom_area_r )
SANE_OPTION_ID_IMPLEMENT ( curstom_area_t )
SANE_OPTION_ID_IMPLEMENT ( curstom_area_b )
SANE_OPTION_ID_IMPLEMENT ( is_size_check )
SANE_OPTION_ID_IMPLEMENT ( page )
SANE_OPTION_ID_IMPLEMENT ( blank_page_threshold )
SANE_OPTION_ID_IMPLEMENT ( resolution )
SANE_OPTION_ID_IMPLEMENT ( image_quality )
SANE_OPTION_ID_IMPLEMENT ( is_swap )
SANE_OPTION_ID_IMPLEMENT ( is_split )
SANE_OPTION_ID_IMPLEMENT ( is_auto_deskew )
SANE_OPTION_ID_IMPLEMENT ( is_custom_gamma )
SANE_OPTION_ID_IMPLEMENT ( bright )
SANE_OPTION_ID_IMPLEMENT ( contrast )
SANE_OPTION_ID_IMPLEMENT ( gamma )
SANE_OPTION_ID_IMPLEMENT ( is_erase_black_frame )
SANE_OPTION_ID_IMPLEMENT ( deep_sample )
SANE_OPTION_ID_IMPLEMENT ( threshold )
SANE_OPTION_ID_IMPLEMENT ( anti_noise )
SANE_OPTION_ID_IMPLEMENT ( margin )
SANE_OPTION_ID_IMPLEMENT ( fill_background )
SANE_OPTION_ID_IMPLEMENT ( is_anti_permeate )
SANE_OPTION_ID_IMPLEMENT ( anti_permeate_level )
SANE_OPTION_ID_IMPLEMENT ( is_erase_hole )
SANE_OPTION_ID_IMPLEMENT ( search_hole_range )
SANE_OPTION_ID_IMPLEMENT ( is_filling_color )
SANE_OPTION_ID_IMPLEMENT ( is_ultrasonic_check )
SANE_OPTION_ID_IMPLEMENT ( is_check_staple )
SANE_OPTION_ID_IMPLEMENT ( scan_mode )
SANE_OPTION_ID_IMPLEMENT ( scan_count )
SANE_OPTION_ID_IMPLEMENT ( text_direction )
SANE_OPTION_ID_IMPLEMENT ( is_rotate_bkg180 )
SANE_OPTION_ID_IMPLEMENT ( is_check_dogear )
SANE_OPTION_ID_IMPLEMENT ( dogear_size )
SANE_OPTION_ID_IMPLEMENT ( is_check_skew )
SANE_OPTION_ID_IMPLEMENT ( skew_range )
2022-06-28 09:17:10 +00:00
SANE_OPTION_ID_IMPLEMENT ( black_white_threshold )
2022-09-07 07:48:41 +00:00
SANE_OPTION_ID_IMPLEMENT ( is_photo_mode )
SANE_OPTION_ID_IMPLEMENT ( double_feed_handle )
SANE_OPTION_ID_IMPLEMENT ( scan_when_paper_on )
SANE_OPTION_ID_IMPLEMENT ( feed_strength )
SANE_OPTION_ID_IMPLEMENT ( power_scheme )
SANE_OPTION_ID_IMPLEMENT ( is_auto_strength )
SANE_OPTION_ID_IMPLEMENT ( feed_strength_value )
SANE_OPTION_ID_IMPLEMENT ( is_reverse_bw )
2022-09-10 02:09:37 +00:00
SANE_OPTION_ID_IMPLEMENT ( is_erase_hole_l )
SANE_OPTION_ID_IMPLEMENT ( search_hole_range_l )
SANE_OPTION_ID_IMPLEMENT ( is_erase_hole_r )
SANE_OPTION_ID_IMPLEMENT ( search_hole_range_r )
SANE_OPTION_ID_IMPLEMENT ( is_erase_hole_t )
SANE_OPTION_ID_IMPLEMENT ( search_hole_range_t )
SANE_OPTION_ID_IMPLEMENT ( is_erase_hole_b )
SANE_OPTION_ID_IMPLEMENT ( search_hole_range_b )
2022-10-24 08:58:09 +00:00
SANE_OPTION_ID_IMPLEMENT ( fold_direction )
2022-06-15 03:04:40 +00:00
// SANE-ex option ID:
SANE_OPTION_ID_IMPLEMENT ( ex_multiout_type )
SANE_OPTION_ID_IMPLEMENT ( ex_auto_color_type )
SANE_OPTION_ID_IMPLEMENT ( ex_color_mode )
SANE_OPTION_ID_IMPLEMENT ( ex_sharpen )
SANE_OPTION_ID_IMPLEMENT ( ex_paper )
SANE_OPTION_ID_IMPLEMENT ( ex_paper_lateral )
SANE_OPTION_ID_IMPLEMENT ( ex_auto_paper_size )
SANE_OPTION_ID_IMPLEMENT ( ex_is_paper_auto_crop )
SANE_OPTION_ID_IMPLEMENT ( ex_text_direction )
SANE_OPTION_ID_IMPLEMENT ( ex_duplex )
SANE_OPTION_ID_IMPLEMENT ( ex_fill_background )
SANE_OPTION_ID_IMPLEMENT ( ex_discard_blank_page )
SANE_OPTION_ID_IMPLEMENT ( ex_discard_blank_receipt )
SANE_OPTION_ID_IMPLEMENT ( ex_is_page_fold )
SANE_OPTION_ID_IMPLEMENT ( ex_color_filter )
SANE_OPTION_ID_IMPLEMENT ( ex_color_enhance )
SANE_OPTION_ID_IMPLEMENT ( ex_final_compression )
SANE_OPTION_ID_IMPLEMENT ( ex_final_format )
SANE_OPTION_ID_IMPLEMENT ( ex_serial )
SANE_OPTION_ID_IMPLEMENT ( ex_to_be_scan )
SANE_OPTION_ID_IMPLEMENT ( ex_scan_with_hole )
SANE_OPTION_ID_IMPLEMENT ( ex_device_code )
SANE_OPTION_ID_IMPLEMENT ( ex_power )
SANE_OPTION_ID_IMPLEMENT ( ex_hardware_version )
SANE_OPTION_ID_IMPLEMENT ( ex_ip )
2022-06-18 00:54:01 +00:00
COM_API_IMPLEMENT ( scanner , void , twain_set_transfer ( twain_xfer xfer ) )
2022-06-15 03:04:40 +00:00
{
2022-06-18 00:54:01 +00:00
xfer_ = xfer ;
2022-06-15 03:04:40 +00:00
}
2022-06-29 08:13:05 +00:00
COM_API_IMPLEMENT ( scanner , void , twain_set_compression ( SANE_CompressionType compression , void * detail ) )
{
img_fmt_ . compress . compression = compression ;
img_fmt_ . compress . detail = detail ;
}
2022-07-01 07:24:58 +00:00
COM_API_IMPLEMENT ( scanner , int , twain_get_config ( char * buf , size_t * len ) )
{
2023-04-04 05:50:10 +00:00
if ( cfg_ )
2022-07-01 07:24:58 +00:00
{
2023-04-04 05:50:10 +00:00
std : : string cont ( cfg_ - > to_text_stream ( ) ) ;
2022-07-01 07:24:58 +00:00
2023-04-04 05:50:10 +00:00
if ( * len < cont . length ( ) )
{
* len = cont . length ( ) + 4 ;
return SCANNER_ERR_INSUFFICIENT_MEMORY ;
}
strcpy ( buf , cont . c_str ( ) ) ;
2022-07-01 07:24:58 +00:00
}
return SCANNER_ERR_OK ;
}
COM_API_IMPLEMENT ( scanner , int , twain_set_config ( char * buf , size_t len ) )
{
2023-04-04 05:50:10 +00:00
if ( cfg_ & & cfg_ - > load_mem ( buf ) )
2022-07-01 07:24:58 +00:00
{
2022-10-08 06:13:09 +00:00
update_config ( ) ;
2022-07-01 07:24:58 +00:00
apply_config ( ) ;
return SCANNER_ERR_OK ;
}
return SCANNER_ERR_DATA_DAMAGED ;
}
2022-06-29 08:13:05 +00:00
2022-06-18 00:54:01 +00:00
// ui ...
COM_API_IMPLEMENT ( scanner , bool , ui_show_main ( HWND parent ) )
2022-06-15 03:04:40 +00:00
{
2022-06-18 00:54:01 +00:00
return false ;
2022-06-15 03:04:40 +00:00
}
2022-07-02 09:27:21 +00:00
COM_API_IMPLEMENT ( scanner , bool , ui_show_setting ( HWND parent , bool with_scan , bool indicator ) )
2022-06-15 03:04:40 +00:00
{
2023-04-04 05:50:10 +00:00
if ( callback : : show_setting_ui )
{
auto cb = [ & ] ( int ev )
{
on_ui_event ( ev , NULL ) ;
} ;
callback : : show_setting_ui ( handle_ , parent , & sane_api_ , with_scan , cb ) ;
}
else if ( cfg_ )
{
if ( with_scan )
{
events_ . clear ( ) ;
images_ . clear ( ) ;
scan_msg_ = " OK " ;
scan_err_ = false ;
}
size_t pid = scanner_name_ . find ( L " - " ) ;
if ( pid = = - 1 )
pid = scanner_name_ . length ( ) ;
setting_ . reset ( new dlg_setting ( parent , & sane_api_ , handle_ , with_scan , scanner_name_ . substr ( 0 , pid ) . c_str ( ) ) ) ;
setting_ - > set_ui_event_notify ( & scanner : : ui_callback , this ) ;
setting_ - > set_config ( cfg_ , ( cfg_path_ + scanner_name_ . substr ( 0 , pid ) + L " .cfg " ) . c_str ( ) , & scanner : : apply_scheme , this , & twain_set_ ) ;
indicator_ . reset ( ) ;
if ( indicator )
{
indicator_ . reset ( new dlg_indicator ( setting_ - > hwnd ( ) ) ) ;
indicator_ - > set_ui_event_notify ( & scanner : : ui_callback , this ) ;
}
setting_ - > show ( true ) ;
2022-06-27 01:38:12 +00:00
}
2022-06-18 08:48:41 +00:00
return true ;
2022-06-15 03:04:40 +00:00
}
2022-06-18 00:54:01 +00:00
COM_API_IMPLEMENT ( scanner , bool , ui_show_progress ( HWND parent ) )
2022-06-15 03:04:40 +00:00
{
2023-04-04 05:50:10 +00:00
if ( callback : : show_progress_ui )
{
}
else
{
if ( setting_ . get ( ) & & IsWindowVisible ( setting_ - > hwnd ( ) ) )
parent = setting_ - > hwnd ( ) ;
else if ( ! IsWindow ( parent ) )
parent = callback : : find_main_wnd ( ) ;
2022-07-28 01:57:26 +00:00
2023-04-04 05:50:10 +00:00
indicator_ . reset ( new dlg_indicator ( parent ) ) ;
indicator_ - > set_ui_event_notify ( & scanner : : ui_callback , this ) ;
indicator_ - > show ( true ) ;
}
2022-06-18 08:48:41 +00:00
return true ;
2022-06-15 03:04:40 +00:00
}
2022-06-18 00:54:01 +00:00
COM_API_IMPLEMENT ( scanner , void , ui_hide ( void ) )
2022-06-15 03:04:40 +00:00
{
2022-06-18 08:48:41 +00:00
if ( indicator_ . get ( ) )
indicator_ . reset ( ) ;
2022-06-20 07:17:55 +00:00
if ( setting_ . get ( ) )
setting_ . reset ( ) ;
2022-06-15 03:04:40 +00:00
}
COM_API_IMPLEMENT ( scanner , bool , ui_is_ok ( void ) )
{
2022-06-18 00:54:01 +00:00
return true ;
2022-06-15 03:04:40 +00:00
}
2022-06-18 00:54:01 +00:00
2022-07-01 07:24:58 +00:00
// called from device-layer ...
2022-07-02 09:27:21 +00:00
int scanner : : handle_device_event ( int ev_code , void * data , unsigned int * len )
2022-06-15 03:04:40 +00:00
{
2022-07-01 07:24:58 +00:00
if ( ev_code = = SANE_EVENT_WORKING )
{
if ( indicator_ . get ( ) )
indicator_ - > notify_working ( ) ;
2022-07-02 09:27:21 +00:00
else
2022-10-20 06:29:02 +00:00
on_ui_event ( ev_code , ( void * ) ev_code ) ;
2022-09-19 06:16:34 +00:00
log_info ( L " Scanning ... \r \n " , 0 ) ;
2022-07-01 07:24:58 +00:00
}
else if ( ev_code = = SANE_EVENT_IMAGE_OK )
2022-06-18 00:54:01 +00:00
{
SANE_Image * simg = ( SANE_Image * ) data ;
scanned_img * img = NULL ;
wchar_t name [ 40 ] = { 0 } ;
swprintf_s ( name , _countof ( name ) - 1 , L " img_%05u.bmp " , + + img_ind_ ) ;
2022-11-06 08:49:30 +00:00
img = new scanned_img ( handle_ , simg - > header , simg - > data , simg - > bytes , simg - > flag . dpi , ( tmp_path_ + name ) . c_str ( ) , xfer_ , & img_fmt_ ) ;
2022-06-29 08:13:05 +00:00
if ( img - > bytes ( ) /*>= simg->bytes*/ )
2022-06-18 00:54:01 +00:00
{
2022-11-25 06:20:06 +00:00
size_t bytes = 0 ;
int times = 0 ;
images_ . count ( & bytes ) ;
2022-09-20 10:14:27 +00:00
img - > set_image_status ( ( SANE_Image_Statu ) simg - > flag . statu ) ;
2022-11-25 06:20:06 +00:00
bytes / = 1024 * 1024 ;
while ( bytes > max_img_mem_ & & ! user_cancel_ & & times + + < 20 ) // memory control
{
std : : this_thread : : sleep_for ( std : : chrono : : milliseconds ( 5 ) ) ;
images_ . count ( & bytes ) ;
bytes / = 1024 * 1024 ;
if ( times = = 1 )
log_info ( L " Memory usage upto limit! wait up to 100 ms ... \r \n " , 0 ) ;
}
images_ . save ( img , img - > bytes ( ) ) ;
2022-06-18 00:54:01 +00:00
}
else
{
img - > release ( ) ;
}
2022-07-02 09:27:21 +00:00
if ( indicator_ . get ( ) )
2022-06-18 08:48:41 +00:00
indicator_ - > notify_data_arrived ( true ) ;
2022-09-19 06:16:34 +00:00
{
wchar_t msg [ 128 ] = { 0 } ;
swprintf_s ( msg , _countof ( msg ) - 1 , L " New image(%u) received with %u bytes \r \n " , img_ind_ , simg - > bytes ) ;
log_info ( msg , 0 ) ;
}
2022-06-18 08:48:41 +00:00
}
else if ( ev_code = = SANE_EVENT_USB_DATA_RECEIVED )
{
2022-07-02 09:27:21 +00:00
if ( indicator_ . get ( ) )
2022-06-18 08:48:41 +00:00
indicator_ - > notify_data_arrived ( false ) ;
2022-06-18 00:54:01 +00:00
}
else if ( ev_code = = SANE_EVENT_SCAN_FINISHED )
{
2022-10-21 08:46:20 +00:00
err_ = * len ;
2022-06-18 08:48:41 +00:00
if ( indicator_ . get ( ) )
2022-07-02 09:27:21 +00:00
indicator_ - > notify_scan_over ( ( char * ) data , * len ! = SCANNER_ERR_OK ) ;
else
2022-10-21 08:46:20 +00:00
{
if ( * len )
{
std : : wstring msg ( local_trans : : a2u ( ( char * ) data , CP_UTF8 ) ) ;
if ( ! IsWindow ( app_wnd_ ) )
2023-02-07 08:55:51 +00:00
callback : : bring_message_box_topmost ( local_trans : : lang_trans_between_hz936 ( CONST_STRING_ERROR ) . c_str ( ) ) ;
MessageBoxW ( app_wnd_ , msg . c_str ( ) , local_trans : : lang_trans_between_hz936 ( CONST_STRING_ERROR ) . c_str ( ) , MB_OK ) ;
2022-10-21 08:46:20 +00:00
}
on_ui_event ( ev_code , ( void * ) ev_code ) ;
}
2022-10-21 10:09:33 +00:00
// is_scanning_ = false;
2022-09-19 06:16:34 +00:00
{
wchar_t msg [ 128 ] = { 0 } ;
swprintf_s ( msg , _countof ( msg ) - 1 , L " Scan finished with error: %u \r \n " , * len ) ;
log_info ( msg , 0 ) ;
}
2022-06-18 00:54:01 +00:00
}
return 0 ;
2022-06-15 03:04:40 +00:00
}
2022-06-18 00:54:01 +00:00
2022-09-19 06:16:34 +00:00
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// log ...
# include <direct.h>
std : : mutex g_lock_ ;
2022-10-08 09:20:16 +00:00
std : : string g_path_file_ ( " " ) ;
2022-09-19 06:16:34 +00:00
FILE * g_file_ = NULL ;
void init_log ( void )
{
char * tmp = getenv ( " LOCALAPPDATA " ) ;
if ( tmp )
{
std : : string path ( tmp ) ;
char name [ MAX_PATH ] = { 0 } , * last = NULL ;
path + = std : : string ( " \\ " ) + PRODUCT_VENDOR + " Scan \\ Log \\ " ;
mkdir ( path . c_str ( ) ) ;
GetModuleFileNameA ( NULL , name , _countof ( name ) - 1 ) ;
last = strrchr ( name , ' \\ ' ) ;
if ( last + + = = NULL )
last = name ;
path + = last ;
path + = " _twain.log " ;
2022-10-08 09:20:16 +00:00
g_file_ = fopen ( path . c_str ( ) , " a+b " ) ;
g_path_file_ = path ;
2022-09-19 06:16:34 +00:00
}
else
{
char name [ MAX_PATH ] = { 0 } , * last = NULL ;
std : : string path ( " " ) ;
GetModuleFileNameA ( NULL , name , _countof ( name ) - 1 ) ;
path = std : : string ( name ) + " _twain.log " ;
2022-10-08 09:20:16 +00:00
g_file_ = fopen ( path . c_str ( ) , " a+b " ) ;
g_path_file_ = path ;
2022-09-19 06:16:34 +00:00
}
2022-09-27 04:35:37 +00:00
if ( g_file_ )
{
2022-10-08 09:20:16 +00:00
fseek ( g_file_ , 0 , SEEK_END ) ;
if ( ftell ( g_file_ ) )
{
2022-11-17 02:26:53 +00:00
std : : wstring sep ( L " \r \n \r \n \r \n ======================================================= \r \n " ) ;
2022-10-08 09:20:16 +00:00
fwrite ( sep . c_str ( ) , 2 , sep . length ( ) , g_file_ ) ;
}
else
{
unsigned short bom = 0x0feff ;
fwrite ( & bom , sizeof ( bom ) , 1 , g_file_ ) ;
}
2022-11-08 03:22:21 +00:00
wchar_t ts [ 128 ] = { 0 } , now [ 40 ] = { 0 } ;
2022-10-08 09:20:16 +00:00
2023-02-13 09:02:47 +00:00
hg_get_current_time_w ( now ) ;
2022-11-08 03:22:21 +00:00
swprintf_s ( ts , _countof ( ts ) - 1 , L " ==================%s================== \r \n " , now ) ;
2022-10-08 09:20:16 +00:00
fwrite ( ts , 2 , lstrlenW ( ts ) , g_file_ ) ;
2022-09-27 04:35:37 +00:00
}
2022-09-19 06:16:34 +00:00
}
void close_log ( void )
{
if ( g_file_ )
fclose ( g_file_ ) ;
g_file_ = NULL ;
}
void log ( const wchar_t * info )
{
if ( g_file_ )
{
std : : lock_guard < std : : mutex > lock ( g_lock_ ) ;
fwrite ( info , 2 , lstrlenW ( info ) , g_file_ ) ;
fflush ( g_file_ ) ;
if ( ftell ( g_file_ ) > 10 * 1024 * 1024 )
2022-10-08 09:20:16 +00:00
{
fclose ( g_file_ ) ;
remove ( g_path_file_ . c_str ( ) ) ;
g_file_ = fopen ( g_path_file_ . c_str ( ) , " a+b " ) ;
if ( g_file_ )
{
unsigned short bom = 0x0feff ;
2022-11-08 03:22:21 +00:00
wchar_t ts [ 128 ] = { 0 } , now [ 40 ] = { 0 } ;
2022-10-08 09:20:16 +00:00
2023-02-13 09:02:47 +00:00
hg_get_current_time_w ( now ) ;
2022-11-08 03:22:21 +00:00
swprintf_s ( ts , _countof ( ts ) - 1 , L " ==================%s (Truncated when size > 10MB) ================== \r \n " , now ) ;
2022-10-08 09:20:16 +00:00
fwrite ( & bom , sizeof ( bom ) , 1 , g_file_ ) ;
fwrite ( ts , 2 , lstrlenW ( ts ) , g_file_ ) ;
}
}
2022-09-19 06:16:34 +00:00
}
}
2022-06-15 03:04:40 +00:00
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// exports
2022-11-06 03:29:49 +00:00
extern " C "
{
2022-06-15 03:04:40 +00:00
# ifdef EXPORT_SANE_API
2022-11-06 03:29:49 +00:00
__declspec ( dllexport )
2022-06-15 03:04:40 +00:00
# else
2022-11-06 03:29:49 +00:00
__declspec ( dllimport )
2022-06-15 03:04:40 +00:00
# endif
2022-11-06 03:29:49 +00:00
int __stdcall initialize ( void * reserve )
{
init_log ( ) ;
2023-04-04 05:50:10 +00:00
callback : : init_ui ( ) ;
2022-11-06 03:29:49 +00:00
hg_sane_middleware : : set_callback ( callback : : sane_event_callback , NULL ) ;
2023-01-28 07:20:51 +00:00
if ( hg_sane_middleware : : instance ( ) - > is_ready ( ) )
return SANE_STATUS_GOOD ;
else
return SCANNER_ERR_LANG_PAK_LOST ;
2022-11-06 03:29:49 +00:00
}
2022-06-15 03:04:40 +00:00
# ifdef EXPORT_SANE_API
2022-11-06 03:29:49 +00:00
__declspec ( dllexport )
2022-06-15 03:04:40 +00:00
# else
2022-11-06 03:29:49 +00:00
__declspec ( dllimport )
2022-06-15 03:04:40 +00:00
# endif
2022-11-06 03:29:49 +00:00
int __stdcall open_scanner ( SCANNERID scanner_id , ISaneInvoker * * invoker )
{
if ( ! invoker )
return SCANNER_ERR_INVALID_PARAMETER ;
2022-06-15 03:04:40 +00:00
2022-11-06 03:29:49 +00:00
if ( ! is_scanner_online ( scanner_id ) )
return SCANNER_ERR_DEVICE_NOT_FOUND ;
2022-06-15 03:04:40 +00:00
2022-11-06 03:29:49 +00:00
scanner * scn = new scanner ( scanner_id ) ;
if ( scn - > last_error ( ) = = SCANNER_ERR_OK )
{
* invoker = dynamic_cast < ISaneInvoker * > ( scn ) ;
2022-06-15 03:04:40 +00:00
2022-11-06 03:29:49 +00:00
return 0 ;
}
else
{
int ret = scn - > last_error ( ) ;
2022-09-22 08:25:03 +00:00
2022-11-06 03:29:49 +00:00
scn - > release ( ) ;
* invoker = NULL ;
2022-09-22 08:25:03 +00:00
2022-11-06 03:29:49 +00:00
return ret ;
}
2022-09-22 08:25:03 +00:00
}
2022-06-15 03:04:40 +00:00
# ifdef EXPORT_SANE_API
2022-11-06 03:29:49 +00:00
__declspec ( dllexport )
2022-06-15 03:04:40 +00:00
# else
2022-11-06 03:29:49 +00:00
__declspec ( dllimport )
2022-06-15 03:04:40 +00:00
# endif
2022-11-06 03:29:49 +00:00
bool __stdcall is_scanner_online ( SCANNERID scanner_id )
{
std : : vector < std : : string > que ;
2022-10-09 03:59:45 +00:00
2022-11-06 03:29:49 +00:00
scanner : : get_scanner_name ( scanner_id , que ) ;
return ! que . empty ( ) ;
}
2022-06-15 03:04:40 +00:00
# ifdef EXPORT_SANE_API
2022-11-06 03:29:49 +00:00
__declspec ( dllexport )
2022-06-15 03:04:40 +00:00
# else
2022-11-06 03:29:49 +00:00
__declspec ( dllimport )
2022-06-15 03:04:40 +00:00
# endif
2022-11-06 03:29:49 +00:00
int __stdcall uninitialize ( void * reserve )
{
hg_sane_middleware : : set_callback ( NULL , NULL ) ;
hg_sane_middleware : : clear ( ) ;
close_log ( ) ;
2022-06-15 03:04:40 +00:00
2022-11-06 03:29:49 +00:00
return 0 ;
}
2022-09-19 06:16:34 +00:00
# ifdef EXPORT_SANE_API
2022-11-06 03:29:49 +00:00
__declspec ( dllexport )
2022-09-19 06:16:34 +00:00
# else
2022-11-06 03:29:49 +00:00
__declspec ( dllimport )
2022-09-19 06:16:34 +00:00
# endif
2022-11-06 03:29:49 +00:00
void __stdcall log_info ( const wchar_t * info , int level )
{
log ( info ) ;
}
2022-06-15 03:04:40 +00:00
2022-11-06 03:29:49 +00:00
}