2023-08-04 07:42:59 +00:00
2023-04-23 14:23:02 +00:00
# include "scanner.h"
2022-06-15 03:04:40 +00:00
# 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>
2023-04-23 14:23:02 +00:00
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>
2023-04-23 14:23:02 +00:00
# include "DlgIndicator.h"
2023-08-12 02:10:28 +00:00
# include <twainui/twainui.h>
2022-10-08 09:20:16 +00:00
# pragma comment(lib, "Shlwapi.lib")
2023-05-29 01:11:09 +00:00
# define START_SCAN_IN_THREAD
2022-06-15 03:04:40 +00:00
static IMPLEMENT_OPTION_STRING_COMPARE ( compare_sane_opt ) ;
2023-05-13 08:27:44 +00:00
# define SET_SANE_OPT_ID(id, id_name, name, val, extension) \
if ( strcmp ( SANE_STD_OPT_NAME_ # # name , val ) = = 0 ) \
{ \
id_name # # _id_ = id ; \
sane_ids_ [ ( sane_option_id ) SANE_OPT_ID_ # # name ] = id ; \
extension ( id ) ; \
2022-06-15 03:04:40 +00:00
}
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 ;
2023-11-16 09:29:37 +00:00
int sane_event_callback ( // 婵炲鍔岄崬浠嬪炊閻愬墎娈堕柣銊ュ椤曨喚鎸掗埥鍛闂傚洠鍋撻悷鏇氭缁绘氨鎷犳担绛嬪殙闁搞儳鍋犻惃鐔煎及椤栨凹妯嬬紒鎹愭硶閳昏偐鈧懓顦崣蹇涙<E8B987> <E6B699> ?
SANE_Handle hdev // 濞存籂鍛櫢濞存粌顑勫▎銏ゆ儍閸曨噮鍟庡璺烘搐瑜扮偤寮?
, int code // 闁搞儳鍋犻惃鐔哥鐎b晜顐藉ù鐙呯悼閻?
, void * data // 闁搞儳鍋犻惃鐔哥鐎b 晜顐介柡浣哄瀹撲線鏁嶇仦鍓у 闁硅鍠曠花銊︾閺堥潧鏁╅柣顔荤劍濠€渚€骞嶉埀顒佺▔瀹ュ懏鍊遍柨娑樿嫰瀵剟鎮¤閸欐寧鎷呴幘鑼殤濞寸姾娉涢悾鐐<E99090> <EE8482> ?
, unsigned int * len // 闁轰胶澧楀畵渚€姊归崹顔碱唺闁挎稑鐗嗛悺褔鎳為崒锔剧闁挎稑鏈崹銊╂嚀閸楁仸ent_data闁汇劌瀚槐锕傚礃閹绘帒闅橀梻鈧崹顔碱唺闁挎稑鐭侀娑氱磼閸℃凹鍤為柣顏勵儑濞村鎯旈弮鍌涚暠濞存粌顑勫▎銏$ 閿濆洨<E6BF86> <E6B4A8> ?
, void * param // 闁活潿鍔嶉崺娑㈡嚊椤忓嫮鏆板☉鏂款槹閺嗙喖骞戦鍡欑濞戞挸姘﹂惃鐔兼偨閳虹棏ne_init_ex濞磋偐濮撮崣鍡涘籍閸撲焦鐣卞ǎ鍥ㄧ箖鐎垫梹绋夐埀顒勬<E9A192> <E58BAC> ?
) // 閺夆晜鏌ㄥú鏍磹闂傚璐╁☉鎾崇Т閹捇鎯冮崟顏嗙殤濞寸姵婀归崬顒勬儘娴hВ鍋撶仦鐣屾毎闁挎稑鐭傞埀顒佽壘閻栬埖绋夌悰鈾€鍋?<3F> <> ?
2022-06-18 00:54:01 +00:00
{
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 ) ;
2023-05-20 04:02:26 +00:00
log_info ( msg , 1 ) ;
2022-09-21 08:44:41 +00:00
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 }
2023-08-16 07:32:13 +00:00
, { SANE_STD_OPT_NAME_DISCARDBLANK , OPTION_TITLE_TGKBY }
2022-10-08 06:13:09 +00:00
} ,
2023-11-16 09:29:37 +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 " } // 濮掓稒鍨瑰▍褔宕堕幆褍鍓奸柛娆忕Х 婢瑰﹥娼忛幘鍐叉瘔闁挎稑鐗婇婊呮暜閹间緡鏉归柤纭呭紦鐠愮喖<E684AE> <E59696> ?-濮掓稒鍨兼竟濠囨<E6BFA0> <E59BA8> ?-闁谎冣偓鐔奉棌闁?
, { 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 " } // " 闁瑰吋鎸鹃悞濠囨⒓閸績<EE82A3> <E7B8BE> ?
2022-10-08 06:13:09 +00:00
} ;
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
2023-11-23 06:58:28 +00:00
static bool check_wnd_thread_id = false ;
2022-10-21 08:46:20 +00:00
static BOOL CALLBACK main_wnd ( HWND hwnd , LPARAM param )
{
2023-11-23 06:58:28 +00:00
DWORD pid = 0 ,
tid = GetWindowThreadProcessId ( hwnd , & pid ) ;
2022-10-21 08:46:20 +00:00
if ( pid ! = GetCurrentProcessId ( ) )
return TRUE ;
2023-11-23 06:58:28 +00:00
if ( check_wnd_thread_id & & tid ! = GetCurrentThreadId ( ) )
return TRUE ;
2022-10-21 08:46:20 +00:00
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 ) ;
2023-11-23 06:58:28 +00:00
{
wchar_t mw [ 128 ] = { 0 } ;
swprintf_s ( mw , _countof ( mw ) - 1 , L " find_main_wnd of thread %u = 0x%x \r \n " , GetCurrentThreadId ( ) , wnd [ 0 ] ) ;
log_info ( mw , 1 ) ;
}
2022-10-21 08:46:20 +00:00
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
2023-05-20 04:02:26 +00:00
static HMODULE hui = NULL ;
2023-04-23 14:23:02 +00:00
int ( * choose_scanner ) ( const std : : vector < DEVQUEUI > & devs ) = NULL ; // blocked. return selected DEVQUE::id or -1 if user cancelled
2023-11-16 09:29:37 +00:00
char * ( * apply_current_config ) ( const char * dev_name , SANE_Handle device , LPSANEAPI api ) = NULL ; // 閹煎瓨姊婚弫銈囨媼閹屾У闁汇劌瀚紞瀣礈瀹ュ甯抽柨?
2023-11-29 06:41:06 +00:00
int ( * show_setting_ui ) ( SANE_Handle device , HWND parent , LPSANEAPI api , const char * devname , bool with_scan , std : : function < void ( ui_result ) > callback , std : : function < void ( int , void * , int ) > * notify ) = NULL ;
2023-04-25 08:54:57 +00:00
int ( * show_progress_ui ) ( HWND parent , std : : function < void ( ui_result ) > callback , std : : function < void ( int /*event*/ , void */ * msg */ , int /*flag*/ ) > * notify ) = NULL ;
2023-05-04 10:18:01 +00:00
int ( * show_messagebox_ui ) ( HWND parent , int event , void * msg , int flag ) = NULL ;
2023-05-19 07:03:38 +00:00
int ( * close_ui ) ( int ) = NULL ;
2023-11-16 09:29:37 +00:00
int ( * apply_given_config ) ( const char * content , SANE_Handle device , LPSANEAPI api ) = NULL ; // 閹煎瓨姊婚弫銈夊箰閸パ呮毎闁汇劌瀚伴崢銈囩磾椤曞棛绀塩ontent濞戞挻妞介崢銈囩磾椤旇姤娈堕柟璇″枟<E280B3> <E69E9F> ?
2023-06-30 08:58:57 +00:00
char * ( * get_config_content ) ( const char * dev_name , const char * name ) = NULL ;
2023-05-26 02:08:32 +00:00
void ( * twain_ui_free ) ( void * buf ) = NULL ;
2023-10-07 04:41:24 +00:00
void ( * pump_ui_message ) ( void * reserved ) = NULL ;
int ( * abnormal_image ) ( SANE_Image * img ) = NULL ; // return SANE_Abnormal_Image_Treat
2023-05-04 10:18:01 +00:00
2023-04-23 14:23:02 +00:00
2023-08-08 08:48:50 +00:00
static int load_dll ( const char * path_dll , HMODULE * dll )
{
HMODULE h = LoadLibraryA ( path_dll ) ;
int ret = GetLastError ( ) ;
char info [ 128 ] = { 0 } ;
sprintf_s ( info , _countof ( info ) - 1 , " = %d \r \n " , ret ) ;
OutputDebugStringA ( ( " [TWAIN]Load: " + std : : string ( path_dll ) + info ) . c_str ( ) ) ;
if ( ! h & & ( ret = = ERROR_MOD_NOT_FOUND | | ret = = ERROR_BAD_EXE_FORMAT | | ret = = 0 ) )
{
std : : string dir ( path_dll ) ;
size_t pos = dir . rfind ( L ' \\ ' ) ;
wchar_t path [ MAX_PATH ] = { 0 } ;
GetDllDirectoryW ( _countof ( path ) - 1 , path ) ;
if ( pos ! = std : : wstring : : npos )
dir . erase ( pos ) ;
OutputDebugStringA ( ( " [TWAIN]Load: try change directory to " + dir + " \r \n " ) . c_str ( ) ) ;
SetDllDirectoryA ( dir . c_str ( ) ) ;
h = LoadLibraryA ( path_dll ) ;
// h = LoadLibraryExW(path_dll, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
ret = GetLastError ( ) ;
sprintf_s ( info , _countof ( info ) - 1 , " = %d \r \n " , ret ) ;
OutputDebugStringA ( ( " [TWAIN]Load: " + std : : string ( path_dll ) + info ) . c_str ( ) ) ;
OutputDebugStringW ( ( L " [TWAIN]Load: restore directory to " + std : : wstring ( path ) + L " \r \n " ) . c_str ( ) ) ;
SetDllDirectoryW ( path ) ;
}
if ( dll )
* dll = h ;
return ret ;
}
2023-04-04 05:50:10 +00:00
static void init_ui ( void )
{
std : : string root ( hg_sane_middleware : : sane_path ( ) ) ;
2023-08-08 08:25:45 +00:00
if ( hui )
FreeLibrary ( hui ) ;
2023-08-08 08:48:50 +00:00
hui = NULL ;
2023-08-08 08:25:45 +00:00
2023-06-02 02:54:48 +00:00
root + = OEM_SHORT_NAME_E ;
root + = " TwainUI.dll " ;
2023-08-08 08:25:45 +00:00
// hui = LoadLibraryExA(root.c_str(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
2023-08-08 08:48:50 +00:00
//hui = LoadLibraryA(root.c_str());
load_dll ( root . c_str ( ) , & hui ) ;
2023-05-20 04:02:26 +00:00
if ( ! hui )
2023-04-04 05:50:10 +00:00
{
std : : wstring info ( L " Load ' " + local_trans : : a2u ( root . c_str ( ) , CP_UTF8 ) ) ;
info + = L " ' failed: " + std : : to_wstring ( GetLastError ( ) ) + L " \r \n " ;
2023-05-20 04:02:26 +00:00
log_info ( info . c_str ( ) , 1 ) ;
2023-04-04 05:50:10 +00:00
}
else
{
# define GET_API(api) \
proc = ( FARPROC * ) & api ; \
2023-05-20 04:02:26 +00:00
* proc = GetProcAddress ( hui , # api ) ;
2023-04-04 05:50:10 +00:00
FARPROC * proc = NULL ;
GET_API ( choose_scanner ) ;
GET_API ( apply_current_config ) ;
GET_API ( show_setting_ui ) ;
GET_API ( show_progress_ui ) ;
2023-05-04 02:36:55 +00:00
GET_API ( show_messagebox_ui ) ;
2023-05-19 07:03:38 +00:00
GET_API ( close_ui ) ;
2023-05-26 02:08:32 +00:00
GET_API ( twain_ui_free ) ;
2023-06-30 08:58:57 +00:00
GET_API ( apply_given_config ) ;
GET_API ( get_config_content ) ;
2023-10-07 04:41:24 +00:00
GET_API ( pump_ui_message ) ;
GET_API ( abnormal_image ) ;
2023-04-04 05:50:10 +00:00
}
}
2023-05-20 04:02:26 +00:00
static void unint_ui ( void )
{
2023-05-23 08:10:40 +00:00
if ( close_ui )
2023-05-24 00:44:59 +00:00
close_ui ( UI_UNLOAD_MODULE ) ;
2023-05-20 04:02:26 +00:00
choose_scanner = NULL ;
apply_current_config = NULL ;
show_setting_ui = NULL ;
show_progress_ui = NULL ;
show_messagebox_ui = NULL ;
close_ui = NULL ;
2023-05-26 02:08:32 +00:00
twain_ui_free = NULL ;
2023-06-30 08:58:57 +00:00
apply_given_config = NULL ;
get_config_content = NULL ;
2023-10-07 04:41:24 +00:00
pump_ui_message = NULL ;
abnormal_image = NULL ;
2023-05-20 04:02:26 +00:00
if ( hui )
{
FreeLibrary ( hui ) ;
hui = NULL ;
}
}
2023-05-26 02:08:32 +00:00
// check thread whether has window
static BOOL WINAPI check_window ( HWND hwnd , LPARAM lp )
{
LPDWORD id = ( LPDWORD ) lp ;
if ( GetWindowThreadProcessId ( hwnd , NULL ) = = id [ 0 ] )
{
id [ 1 ] = 1 ;
return FALSE ;
}
return TRUE ;
}
static bool is_thread_has_window ( DWORD thread_id = - 1 )
{
if ( thread_id = = - 1 )
thread_id = GetCurrentThreadId ( ) ;
DWORD param [ ] = { thread_id , 0 } ;
EnumWindows ( check_window , ( LPARAM ) param ) ;
return param [ 1 ] ;
}
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-11-07 09:02:10 +00:00
, max_img_mem_ ( 400 ) , wait_fetch_ ( 60 * 1000 ) , twain_set_ ( false ) , ev_cnt_ ( 0 ) , is_bIndicator ( false ) , is_show_setting_ ( false ) , is_in_working_thread_ ( false )
2022-06-15 03:04:40 +00:00
{
2023-05-13 10:33:36 +00:00
ui_notify = std : : function < void ( int , void * , int ) > ( ) ;
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
}
2023-09-12 07:47:00 +00:00
mem_limit = GetPrivateProfileIntW ( L " mem " , L " wait " , 0 , ( cfg_path_ + L " debug.cfg " ) . c_str ( ) ) ;
if ( mem_limit > 0 )
{
wait_fetch_ = mem_limit * 1000 ; // second to millisecond
}
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 ( ) ;
2023-05-29 01:11:09 +00:00
if ( thread_starting_ . get ( ) & & thread_starting_ - > joinable ( ) )
thread_starting_ - > join ( ) ;
thread_starting_ . reset ( ) ;
2023-10-28 08:32:35 +00:00
if ( start_after_keep_ . get ( ) & & start_after_keep_ - > joinable ( ) )
start_after_keep_ - > join ( ) ;
start_after_keep_ . reset ( ) ;
2022-07-01 07:24:58 +00:00
if ( cfg_ )
2022-10-25 08:41:09 +00:00
{
2023-08-09 08:43:29 +00:00
cfg_ - > remove_all_schemes ( ) ; // schemes would add_ref on cfg_, so we clear them first. NOTE: do not call save after this !!!
2022-10-25 08:41:09 +00:00
cfg_ - > release ( ) ;
cfg_ = NULL ;
2023-10-23 03:14:25 +00:00
while ( ! dlg_base : : is_message_thread_exited ( ) )
{
MSG msg = { 0 } ;
PeekMessageW ( & msg , NULL , 0 , 0 , PM_NOREMOVE ) ;
}
2022-10-25 08:41:09 +00:00
}
2022-06-18 00:54:01 +00:00
}
2022-06-15 03:04:40 +00:00
2023-09-26 06:15:56 +00:00
std : : string scanner : : getDeviceType ( )
{
std : : string cfgPath ( " " ) ;
std : : string env ( " LOCALAPPDATA " ) ;
cfgPath = getenv ( env . c_str ( ) ) ;
cfgPath + = " \\ " ;
# ifdef OEM_HANWANG
cfgPath + = " HanvonScan " ;
# elif defined(OEM_LISICHENG)
cfgPath + = " LanxumScan " ;
# elif defined(OEM_CANGTIAN)
cfgPath + = " CumTennScan " ;
# elif defined(OEM_ZHONGJING)
cfgPath + = " MicrotekScan " ;
# elif defined(OEM_ZIGUANG)
cfgPath + = " UniScan " ;
# elif defined(OEM_DELI)
cfgPath + = " DeliScan " ;
# elif defined(OEM_NEUTRAL)
cfgPath + = " NeuScan " ;
# else
cfgPath + = " HuaGoScan " ;
# endif
char devType [ 256 ] = { 0 } ;
cfgPath + = " \\ config \\ debug.cfg " ;
GetPrivateProfileStringA ( " devs_name " , " name " , NULL , devType , 256 , cfgPath . c_str ( ) ) ;
return devType ;
}
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 )
{
2023-10-21 01:48:01 +00:00
return pid = = 0x300 | | pid = = 0x302 | | pid = = 0x339 | | pid = = 0x306 ;
2022-10-09 03:59:45 +00:00
}
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 )
{
2023-09-26 06:15:56 +00:00
std : : string devType = getDeviceType ( ) ;
int devPid = 0x200 ;
if ( ! devType . empty ( ) )
{
if ( devType = = " G300 " )
devPid = 0x300 ;
else if ( devType = = " G400 " )
devPid = 0x400 ;
}
int a = GET_SCANNER_VID ( serial ) ;
return pid = = 0x7823 & & GET_SCANNER_VID ( serial ) = = PRODUCT_VENDOR_HG & & ( GET_SCANNER_PID ( serial ) = = devPid ) ;
2022-10-09 03:59:45 +00:00
}
else if ( vid = = PRODUCT_VENDOR_HW )
{
return GET_SCANNER_VID ( serial ) = = vid & & GET_SCANNER_PID ( serial ) = = pid ;
}
else if ( vid = = PRODUCT_VENDOR_LSC )
{
2023-09-11 10:09:45 +00:00
# if defined (LISICHENG_SPECIAL)
return GET_SCANNER_VID ( serial ) = = vid & & GET_SCANNER_PID ( serial ) = = pid ;
# else
2022-10-09 03:59:45 +00:00
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-09-11 10:09:45 +00:00
# endif
2023-01-13 09:46:27 +00:00
return false ;
2022-10-09 03:59:45 +00:00
}
2023-07-20 01:21:31 +00:00
else if ( vid = = PRODUCT_VENDOR_DL )
{
2023-08-10 06:34:44 +00:00
if ( GET_SCANNER_PID ( serial ) = = 0x401C )
2023-07-20 01:21:31 +00:00
{
2023-08-10 06:34:44 +00:00
return pid = = 0x401C | | pid = = 0x4020 ;
}
else
{
return GET_SCANNER_VID ( serial ) = = vid & & GET_SCANNER_PID ( serial ) = = pid ;
2023-07-20 01:21:31 +00:00
}
}
2023-09-09 01:49:01 +00:00
else if ( vid = = PRODUCT_VENDOR_ZG )
{
return GET_SCANNER_VID ( serial ) = = vid & & GET_SCANNER_PID ( serial ) = = pid ;
}
2023-11-16 09:28:19 +00:00
else if ( vid = = PRODUCT_VENDOR_CTS )
{
return GET_SCANNER_VID ( serial ) = = vid & & GET_SCANNER_PID ( serial ) = = pid ;
}
2023-07-20 01:21:31 +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
2023-10-11 05:54:17 +00:00
void scanner : : scan_done ( void )
{
std : : string msg ( scan_msg_ ) ;
2023-11-30 01:16:13 +00:00
// avoid APP do not fetch image ... - 2023-11-30
if ( err_ ! = SCANNER_ERR_USER_CANCELED )
{
int cnt = images_ . count ( ) ,
wait_total = 1000 ,
wait_unit = 5 ,
wait = 0 ;
while ( cnt )
{
std : : this_thread : : sleep_for ( std : : chrono : : milliseconds ( wait_unit ) ) ;
wait + + ;
if ( wait > = wait_total / wait_unit )
break ;
else if ( cnt ! = images_ . count ( ) )
wait = 0 ;
cnt = images_ . count ( ) ;
}
}
2023-10-11 05:54:17 +00:00
2023-10-23 03:14:25 +00:00
if ( indicator_ )
2023-10-11 05:54:17 +00:00
indicator_ - > notify_scan_over ( & msg [ 0 ] , err_ ! = SCANNER_ERR_OK ) ;
else if ( ui_notify )
ui_notify ( SANE_EVENT_SCAN_FINISHED , & msg [ 0 ] , err_ ) ;
else
2023-11-21 09:49:07 +00:00
{
if ( err_ )
{
if ( callback : : show_messagebox_ui )
{
callback : : show_messagebox_ui ( app_wnd_ , SANE_EVENT_SCAN_FINISHED , ( void * ) & msg [ 0 ] , 0 ) ;
}
else // windows message box ...
{
std : : wstring text ( local_trans : : a2u ( msg . c_str ( ) , CP_UTF8 ) ) ;
if ( ! IsWindow ( app_wnd_ ) )
callback : : bring_message_box_topmost ( local_trans : : lang_trans_between_hz936 ( CONST_STRING_ERROR ) . c_str ( ) ) ;
MessageBoxW ( app_wnd_ , text . c_str ( ) , local_trans : : lang_trans_between_hz936 ( CONST_STRING_ERROR ) . c_str ( ) , MB_OK ) ;
}
}
on_ui_event ( SANE_EVENT_SCAN_FINISHED , ( void * ) SANE_EVENT_SCAN_FINISHED ) ;
}
2023-11-16 08:43:43 +00:00
is_in_working_thread_ = false ;
2023-10-11 05:54:17 +00:00
}
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 ( ) ;
}
2023-05-13 08:27:44 +00:00
int scanner : : transfer_id ( int id )
{
if ( id > SANE_OPT_ID_BASE )
{
if ( sane_ids_ . count ( ( sane_option_id ) id ) = = 0 )
id = - 1 ;
else
id = sane_ids_ [ ( sane_option_id ) id ] ;
}
return id ;
}
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 ( ) ) )
{
2023-05-20 04:02:26 +00:00
log_info ( ( L " Rename config file ' " + old + L " ' to ' " + scanner_name_ . substr ( 0 , pos ) + L " ' \r \n " ) . c_str ( ) , 1 ) ;
2022-10-08 09:20:16 +00:00
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 )
2023-05-26 02:08:32 +00:00
{
char * cfg = callback : : apply_current_config ( local_trans : : u2a ( scanner_name_ . c_str ( ) , CP_UTF8 ) . c_str ( ) , handle_ , & sane_api_ ) ;
if ( cfg & & callback : : twain_ui_free )
callback : : twain_ui_free ( cfg ) ;
}
2023-04-04 05:50:10 +00:00
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
{
2023-05-18 02:40:35 +00:00
if ( uev = = SANE_EVENT_UI_CLOSE_SETTING )
2022-10-21 10:09:33 +00:00
{
2023-05-18 02:40:35 +00:00
// setting UI closed ...
is_scanning_ = is_show_setting_ = false ;
2023-10-23 03:14:25 +00:00
if ( setting_ )
setting_ - > close ( ) ;
setting_ = NULL ;
2022-10-21 10:09:33 +00:00
}
2023-05-18 02:40:35 +00:00
else if ( uev = = SANE_EVENT_UI_CLOSE_NORMAL )
2023-05-16 07:25:19 +00:00
{
2023-05-18 02:40:35 +00:00
// scan complete
2023-10-23 03:14:25 +00:00
if ( indicator_ )
indicator_ - > close ( ) ;
indicator_ = NULL ;
2023-05-18 02:40:35 +00:00
2023-05-30 01:12:53 +00:00
// FIX on 2023-05-30: restore scan finished status, whether close UI is up to APP
//is_scanning_ = is_show_setting_;
is_scanning_ = false ;
2023-05-29 06:50:17 +00:00
ui_notify = std : : function < void ( int , void * , int ) > ( ) ;
2023-05-16 07:25:19 +00:00
}
2023-05-18 02:40:35 +00:00
else if ( uev = = SANE_EVENT_UI_CLOSE_CANCEL )
{
// scan cancelled
2023-10-23 03:14:25 +00:00
//if (indicator_)
// indicator_->close();
//indicator_ = NULL;
2023-05-18 02:40:35 +00:00
stop ( ) ; // nothing to do, the finishing work do in SANE_EVENT_SCAN_FINISHED
}
else if ( uev = = SANE_EVENT_SCAN_FINISHED )
{
2023-05-30 01:12:53 +00:00
// FIX on 2023-05-30: restore scan finished status, whether close UI is up to APP
//is_scanning_ = is_show_setting_;
is_scanning_ = false ;
2023-05-29 06:50:17 +00:00
ui_notify = std : : function < void ( int , void * , int ) > ( ) ;
2023-05-18 02:40:35 +00:00
}
int ( __stdcall * h ) ( int , void * ) = scanner_ev_handler_ ;
if ( h )
2023-05-16 07:25:19 +00:00
{
h ( uev , evh_param_ ) ;
}
return ;
2022-10-21 10:09:33 +00:00
2023-05-08 07:31:24 +00:00
events_ . save ( uev , sizeof ( uev ) ) ;
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-23 14:23:02 +00:00
std : : vector < DEVQUEUI > 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
{
2023-04-23 14:23:02 +00:00
DEVQUEUI dev ;
2023-04-04 05:50:10 +00:00
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
{
2023-04-23 14:23:02 +00:00
//dlg_choose_dev dlg(NULL, devs);
//dlg.show(true, true);
//sel = dlg.get_selected_device();
2022-10-09 03:59:45 +00:00
}
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 ( ) ;
2023-06-13 04:28:56 +00:00
// check roller life ...
SANE_Int cnt = 0 , life = 0 ;
if ( hg_sane_middleware : : instance ( ) - > get_cur_value ( handle_ , ( void * ) SANE_OPT_ID_ROLLER_COUNT , & cnt ) & &
2023-06-15 02:09:40 +00:00
hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) SANE_OPT_ID_ROLLER_LIFE , SANE_ACTION_GET_VALUE , & life , NULL ) = = SANE_STATUS_GOOD )
//hg_sane_middleware::instance()->get_cur_value(handle_, (void*)SANE_OPT_ID_ROLLER_LIFE, &life))
2023-06-13 04:28:56 +00:00
{
2023-06-21 07:51:43 +00:00
if ( cnt > = life / 100 * 99 ) // 99%
2023-06-13 04:28:56 +00:00
{
if ( callback : : show_messagebox_ui )
{
2023-11-16 09:29:37 +00:00
// 缂佺偓鐡曢悿鍡涘箹閹惧墎鍓ㄦ繛鍡忓墲閺嗙喎顔忛懠鍓佇㈤弶鈺佹穿椤旀洜鎷嬮垾鎻掆枏闁活潿鍔忕€垫牠宕舵潏鍓х 闁规鍋呭鎸庢交閸モ斁鏌ゅ☉鎿冨幗閹紕鐥粙瑁や杭閻犳劑鍎埀顑跨劍椤掞綁寮┃搴撳亾娴h 鍋傚鑸佃壘缁卞墎绮垫径濠勭= 閻㈩垱鎮傞。璺衡枎閳ュ啿璁查柤铏灊缁变即寮版惔銏♀枖濠⒀呭仜椤﹀潡鏁嶅畝鍐惧殲婵炲鍔嶉崜浼村矗婵犲啯顦ф繛鎾虫噺绾俱儵濡存担姝屽珯闁艰鲸姊婚柈瀵告媼閹屾У 濞撴碍绋戠花鏌ュ疮閸℃艾鏋犲☉鏃傚濞存盯骞戦姀銏㈠墾閺夌儐鍣<E98DA3> <EE889C> ?
2023-06-14 01:33:05 +00:00
std : : wstring roller_msgw ( local_trans : : lang_trans_between_hz936 ( L " \u7EB8 \u8F6E \u6413 \u7EB8 \u6B21 \u6570 \u5DF2 \u8D85 \u8FC7 \u8BBE \u8BA1 \u4F7F \u7528 \u8303 \u56F4 \uFF0C \u626B \u63CF \u8FC7 \u7A0B \u4E2D \u6413 \u7EB8 \u5931 \u8D25 \u3001 \u6B6A \u659C \u3001 \u6413 \u591A \u5F20 \u7B49 \u5F02 \u5E38 \u9891 \u6B21 \u53EF \u80FD \u4F1A \u660E \u663E \u589E \u591A \uFF0C \u8BF7 \u6CE8 \u610F \u53CA \u65F6 \u6E05 \u6D01 \u3001 \u5E76 \u8054 \u7CFB \u8BBE \u5907 \u4F9B \u5E94 \u5546 \u8D2D \u4E70 \u66FF \u6362 \u7EB8 \u8F6E \uFF01 " ) ) ;
std : : string roller_msg ( local_trans : : u2a ( roller_msgw . c_str ( ) , CP_UTF8 ) ) ;
2023-06-13 04:28:56 +00:00
app_wnd_ = callback : : find_main_wnd ( ) ;
callback : : show_messagebox_ui ( app_wnd_ , ret , ( void * ) & roller_msg [ 0 ] , 0 ) ;
}
}
}
2022-06-15 03:04:40 +00:00
}
2022-09-22 08:25:03 +00:00
else
{
2023-05-04 02:36:55 +00:00
if ( callback : : show_messagebox_ui )
{
2023-06-13 04:28:56 +00:00
app_wnd_ = callback : : find_main_wnd ( ) ;
2023-05-04 02:36:55 +00:00
callback : : show_messagebox_ui ( app_wnd_ , ret , ( void * ) hg_scanner_err_description ( ret ) , 0 ) ;
}
else
{
std : : wstring msg ( local_trans : : a2u ( hg_scanner_err_description ( ret ) , CP_UTF8 ) ) ;
2022-10-21 08:46:20 +00:00
2023-05-04 02:36:55 +00:00
//if (indicator_.get())
// indicator_->show(false);
if ( ! IsWindow ( app_wnd_ ) )
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-09-22 08:25:03 +00:00
}
2022-06-15 03:04:40 +00:00
return ret ;
}
int scanner : : close ( void )
{
2023-10-11 05:54:17 +00:00
images_ . clear ( ) ;
if ( done_ . get ( ) & & done_ - > joinable ( ) )
done_ - > join ( ) ;
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-05-13 08:27:44 +00:00
# define INIT_FIXED_IDS(id) \
2023-06-13 04:28:56 +00:00
sane_ids_ [ SANE_OPT_ID_ # # id ] = SANE_OPT_ID_ # # id ;
INIT_FIXED_IDS ( HISTORY_COUNT ) ;
INIT_FIXED_IDS ( DRIVER_VERSION ) ;
INIT_FIXED_IDS ( MANUFACTURER ) ;
INIT_FIXED_IDS ( COPYRIGHT ) ;
INIT_FIXED_IDS ( CO_URL ) ;
INIT_FIXED_IDS ( CO_TEL ) ;
INIT_FIXED_IDS ( CO_ADDR ) ;
INIT_FIXED_IDS ( CO_GPS ) ;
INIT_FIXED_IDS ( HELP ) ;
INIT_FIXED_IDS ( VID ) ;
INIT_FIXED_IDS ( PID ) ;
INIT_FIXED_IDS ( DEV_NAME ) ;
INIT_FIXED_IDS ( DEV_FAMILY ) ;
INIT_FIXED_IDS ( LOGIN ) ;
INIT_FIXED_IDS ( LOGOUT ) ;
INIT_FIXED_IDS ( ROLLER_COUNT ) ;
INIT_FIXED_IDS ( DRIVER_LOG ) ;
INIT_FIXED_IDS ( DEVICE_LOG ) ;
INIT_FIXED_IDS ( ROLLER_LIFE ) ;
2023-06-15 02:09:40 +00:00
INIT_FIXED_IDS ( DEVICE_MAC_ADDR ) ;
INIT_FIXED_IDS ( CUSTOM_GAMMA ) ;
2023-06-17 05:29:39 +00:00
INIT_FIXED_IDS ( MOTOR_VER ) ;
2023-08-16 06:14:58 +00:00
INIT_FIXED_IDS ( INITIAL_BOOT_TIME ) ;
2023-05-13 08:27:44 +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 ( color_correction , COLOR_CORRECTION , extension_none )
2023-06-15 02:09:40 +00:00
else SET_OPT_ID ( language , LANGUAGE , extension_none )
2023-08-16 07:32:13 +00:00
else SET_OPT_ID ( discardblank , DISCARDBLANK , 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 )
{
2023-11-16 09:29:37 +00:00
// 闁稿繒鍘ч鎰版嚀娴g儤鐣遍梻鍕╁€曢悺鐔虹不濡や胶銆?
2022-09-12 06:45:07 +00:00
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
2023-05-29 01:11:09 +00:00
int scanner : : thread_start ( void )
{
2023-11-07 09:02:10 +00:00
is_in_working_thread_ = false ;
2023-10-11 05:54:17 +00:00
scan_over_ = false ;
2023-10-17 09:52:13 +00:00
double_handle_ = DOUBLE_FEED_NEED_UI ;
2023-10-11 05:54:17 +00:00
2023-10-28 08:46:34 +00:00
unsigned int l = sizeof ( img_fmt_ ) ;
SANE_CompressionType cmprsn = img_fmt_ . compress . compression ;
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 ;
img_fmt_ . compress . compression = cmprsn ;
2023-05-29 01:11:09 +00:00
int ret = hg_sane_middleware : : instance ( ) - > start ( handle_ , NULL ) ;
// the third-APPs in linux will call 'stop' after every start, but it not happens in windows-apps, so we handle this as following ...
2023-10-28 08:46:34 +00:00
//if (ret == SANE_STATUS_NO_DOCS && prev_start_result_ == SANE_STATUS_GOOD)
// ret = hg_sane_middleware::instance()->start(handle_, NULL);
2023-05-29 01:11:09 +00:00
2023-10-28 08:46:34 +00:00
if ( ret = = SANE_STATUS_GOOD | | ret = = SCANNER_ERR_DEVICE_DOUBLE_FEEDING )
2023-05-29 01:11:09 +00:00
{
/*if (indicator_.get() && !IsWindowVisible(indicator_->hwnd()))
indicator_ - > show ( true ) ; */
}
//else if (indicator_.get())
//{
// indicator_->notify_scan_over(hg_scanner_err_description(ret), true);
//}
else
{
// display error message on progress UI, may be closed immediately by APP, so we hide progress UI and call message_box ...
//
2023-10-25 03:23:23 +00:00
err_ = ret ;
2023-05-29 06:44:47 +00:00
# ifdef START_SCAN_IN_THREAD
2023-11-07 09:02:10 +00:00
if ( callback : : show_progress_ui & & is_bIndicator & & ui_notify & & ! is_in_working_thread_ )
2023-05-29 06:44:47 +00:00
{
int ev = SANE_EVENT_WORKING ;
ui_notify ( SANE_EVENT_SCAN_FINISHED , ( void * ) hg_scanner_err_description ( ret ) , ret ) ;
}
2023-11-16 08:43:43 +00:00
else if ( ! is_in_working_thread_ )
2023-05-29 06:44:47 +00:00
# endif
2023-05-29 01:11:09 +00:00
{
2023-10-11 05:54:17 +00:00
scan_over_ = true ;
2023-05-29 01:11:09 +00:00
if ( callback : : close_ui )
callback : : close_ui ( UI_INDICATOR ) ;
if ( callback : : show_messagebox_ui )
{
callback : : show_messagebox_ui ( app_wnd_ , ret , ( void * ) hg_scanner_err_description ( ret ) , 0 ) ;
}
else
{
std : : wstring msg ( local_trans : : a2u ( hg_scanner_err_description ( ret ) , CP_UTF8 ) ) ;
//if (indicator_.get())
// indicator_->show(false);
if ( ! IsWindow ( app_wnd_ ) )
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 ) ;
}
2023-05-29 06:44:47 +00:00
is_scanning_ = false ;
2023-05-29 01:11:09 +00:00
}
}
prev_start_result_ = ret ;
return ret ;
}
2023-10-28 08:32:35 +00:00
int scanner : : thread_start_after_keep ( )
{
2023-11-07 09:02:10 +00:00
is_in_working_thread_ = false ;
2023-10-28 08:32:35 +00:00
int ret = hg_sane_middleware : : instance ( ) - > start ( handle_ , NULL ) ;
2023-11-07 09:02:10 +00:00
if ( ret ! = SANE_STATUS_GOOD & & ret ! = SCANNER_ERR_DEVICE_DOUBLE_FEEDING )
{
if ( callback : : show_progress_ui & & is_bIndicator & & ui_notify )
{
int ev = ret ;
if ( ! is_in_working_thread_ )
ui_notify ( SANE_EVENT_SCAN_FINISHED , ( void * ) hg_scanner_err_description ( ret ) , ret ) ;
}
else
{
scan_over_ = true ;
if ( callback : : close_ui )
callback : : close_ui ( UI_INDICATOR ) ;
if ( callback : : show_messagebox_ui )
{
callback : : show_messagebox_ui ( app_wnd_ , ret , ( void * ) hg_scanner_err_description ( ret ) , 0 ) ;
}
else
{
std : : wstring msg ( local_trans : : a2u ( hg_scanner_err_description ( ret ) , CP_UTF8 ) ) ;
if ( ! IsWindow ( app_wnd_ ) )
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 ) ;
}
is_scanning_ = false ;
}
}
2023-10-28 08:32:35 +00:00
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 ) ) ;
2023-05-20 04:02:26 +00:00
log_info ( info , 1 ) ;
2023-02-07 08:55:51 +00:00
}
}
}
}
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 ;
2023-07-01 13:18:44 +00:00
//if (in && strcmp(in, "\346\227\240"))
//{
// ret = set_is_multiout(true);
// if (ret == SANE_STATUS_GOOD)
// {
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 ) ;
2023-07-01 13:18:44 +00:00
// }
//}
//else
//{
// // 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 ;
2023-10-19 03:35:06 +00:00
std : : vector < int > exists ;
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 ] ) ;
2023-10-19 03:35:06 +00:00
if ( val = = - 1 | | std : : find ( exists . begin ( ) , exists . end ( ) , val ) ! = exists . end ( ) )
2022-06-15 03:04:40 +00:00
continue ;
2023-10-19 03:35:06 +00:00
exists . push_back ( val ) ;
2022-06-15 03:04:40 +00:00
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 ;
2023-05-26 07:17:15 +00:00
fetch_imgs_ = 0 ;
2023-05-29 01:11:09 +00:00
is_scanning_ = true ;
2023-11-21 09:49:07 +00:00
err_ = SANE_STATUS_GOOD ;
2023-10-23 03:14:25 +00:00
app_wnd_ = setting_ ? setting_ - > hwnd ( ) : callback : : find_main_wnd ( ) ;
2023-05-04 02:36:55 +00:00
2023-05-29 01:11:09 +00:00
if ( thread_starting_ . get ( ) & & thread_starting_ - > joinable ( ) )
thread_starting_ - > join ( ) ;
# ifdef START_SCAN_IN_THREAD
thread_starting_ . reset ( new std : : thread ( & scanner : : thread_start , this ) ) ;
2023-12-02 09:54:16 +00:00
ret = get_scanned_images ( - 1 ) ; // block until image arrived or scan finished
ret = ret > 0 ? 0 : err_ ; // received images, ensure return success. BUG-809
2023-05-29 01:11:09 +00:00
# else
ret = thread_start ( ) ;
# endif
2022-06-15 03:04:40 +00:00
2023-05-29 01:11:09 +00:00
return 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 ( ) ;
2023-05-13 10:33:36 +00:00
DWORD elapse = 2 ;
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
2023-04-26 10:07:59 +00:00
count = images_ . count ( ) ;
2023-04-25 08:54:57 +00:00
//int ev = get_event();
//
2023-04-26 10:07:59 +00:00
2023-04-25 08:54:57 +00:00
//if (ev == SANE_EVENT_SCAN_FINISHED)
//{
// 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 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 ) ;
2023-05-20 04:02:26 +00:00
log_info ( msg , 1 ) ;
2022-09-19 06:16:34 +00:00
}
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
{
2023-08-04 05:03:22 +00:00
scanned_img * img = images_ . take ( false ) ;
2022-06-15 03:04:40 +00:00
2023-08-03 01:47:58 +00:00
if ( img )
{
2023-08-04 09:38:26 +00:00
img - > prepare_data_for_transfer ( xfer ) ;
2023-08-04 05:03:22 +00:00
img - > add_ref ( ) ;
2023-08-03 01:47:58 +00:00
wchar_t msg [ 128 ] = { 0 } ;
swprintf_s ( msg , _countof ( msg ) - 1 , L " Begin transferring image %d of %p \r \n " , fetch_imgs_ + 1 , img ) ;
log_info ( msg , 1 ) ;
}
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
}
2023-08-04 05:03:22 +00:00
COM_API_IMPLEMENT ( scanner , bool , discard_first_image ( void ) )
{
scanned_img * img = images_ . take ( ) ;
if ( img )
{
img - > release ( ) ;
return true ;
}
else
{
return false ;
}
}
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_ ;
}
2023-05-26 07:17:15 +00:00
COM_API_IMPLEMENT ( scanner , int , image_fetched ( IScanImg * tx ) )
{
fetch_imgs_ + + ;
if ( ui_notify )
ui_notify ( SANE_EVENT_IMG_UPLOADED , NULL , fetch_imgs_ ) ;
2023-10-23 03:14:25 +00:00
else if ( indicator_ )
2023-05-26 07:17:15 +00:00
indicator_ - > notify_data_arrived ( false ) ;
2023-08-03 01:47:58 +00:00
{
wchar_t msg [ 128 ] = { 0 } ;
swprintf_s ( msg , _countof ( msg ) - 1 , L " Transferring image %d of %p finished. \r \n " , fetch_imgs_ , tx ) ;
log_info ( msg , 1 ) ;
}
2023-05-26 07:17:15 +00:00
return 0 ;
}
2023-03-28 09:13:18 +00:00
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 ) )
{
2023-06-15 02:09:40 +00:00
# define SIMPLE_STR_INFO(id, rdo) \
2023-05-13 08:27:44 +00:00
if ( sn = = id ) \
{ \
if ( type ) \
* type = VAL_TYPE_STR ; \
if ( limit ) \
2023-06-15 02:09:40 +00:00
* limit = rdo ? VAL_LIMIT_READONLY : VAL_LIMIT_NONE ; \
2023-05-13 08:27:44 +00:00
if ( bytes ) \
* bytes = 255 ; \
\
return true ; \
}
2023-06-15 02:09:40 +00:00
# define SIMPLE_INT_INFO(id, rdo) \
2023-05-13 08:27:44 +00:00
if ( sn = = id ) \
{ \
if ( type ) \
* type = VAL_TYPE_INT ; \
if ( limit ) \
2023-06-15 02:09:40 +00:00
* limit = rdo ? VAL_LIMIT_READONLY : VAL_LIMIT_NONE ; \
2023-05-13 08:27:44 +00:00
if ( bytes ) \
* bytes = sizeof ( int ) ; \
\
return true ; \
}
2023-11-02 07:31:32 +00:00
# define SIMPLE_BOOL_INFO(id, rdo) \
if ( sn = = id ) \
{ \
if ( type ) \
* type = VAL_TYPE_BOOL ; \
if ( limit ) \
* limit = rdo ? VAL_LIMIT_READONLY : VAL_LIMIT_NONE ; \
if ( bytes ) \
* bytes = sizeof ( int ) ; \
\
return true ; \
}
2023-05-13 08:27:44 +00:00
2023-06-15 02:09:40 +00:00
SIMPLE_STR_INFO ( SANE_OPT_ID_DRIVER_VERSION , true ) ;
SIMPLE_STR_INFO ( SANE_OPT_ID_MANUFACTURER , true ) ;
SIMPLE_STR_INFO ( SANE_OPT_ID_COPYRIGHT , true ) ;
SIMPLE_STR_INFO ( SANE_OPT_ID_CO_URL , true ) ;
SIMPLE_STR_INFO ( SANE_OPT_ID_CO_TEL , true ) ;
SIMPLE_STR_INFO ( SANE_OPT_ID_CO_ADDR , true ) ;
SIMPLE_STR_INFO ( SANE_OPT_ID_CO_GPS , true ) ;
SIMPLE_STR_INFO ( SANE_OPT_ID_DEV_NAME , true ) ;
SIMPLE_STR_INFO ( SANE_OPT_ID_DEV_FAMILY , true ) ;
SIMPLE_STR_INFO ( SANE_OPT_ID_LOGIN , false ) ;
SIMPLE_STR_INFO ( SANE_OPT_ID_LOGOUT , false ) ;
SIMPLE_STR_INFO ( SANE_OPT_ID_DRIVER_LOG , false ) ;
SIMPLE_STR_INFO ( SANE_OPT_ID_DEVICE_LOG , false ) ;
SIMPLE_STR_INFO ( SANE_OPT_ID_DEVICE_MAC_ADDR , true ) ;
2023-06-17 05:29:39 +00:00
SIMPLE_STR_INFO ( SANE_OPT_ID_MOTOR_VER , true ) ;
2023-06-15 02:09:40 +00:00
SIMPLE_INT_INFO ( SANE_OPT_ID_HELP , false ) ;
SIMPLE_INT_INFO ( SANE_OPT_ID_HISTORY_COUNT , true ) ;
SIMPLE_INT_INFO ( SANE_OPT_ID_ROLLER_COUNT , false ) ;
SIMPLE_INT_INFO ( SANE_OPT_ID_VID , true ) ;
SIMPLE_INT_INFO ( SANE_OPT_ID_PID , true ) ;
SIMPLE_INT_INFO ( SANE_OPT_ID_ROLLER_LIFE , true ) ;
2023-08-16 06:14:58 +00:00
SIMPLE_STR_INFO ( SANE_OPT_ID_INITIAL_BOOT_TIME , true ) ;
2023-11-02 07:31:32 +00:00
SIMPLE_BOOL_INFO ( SANE_OPT_ID_LENS_DIRTY , false ) ;
2023-05-13 08:27:44 +00:00
sn = transfer_id ( sn ) ;
if ( sn = = - 1 )
return false ;
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 )
2023-06-15 02:09:40 +00:00
{
int lmt = scanner : : from_sane_constraint ( desc - > constraint_type ) ;
if ( IS_CAP_READONLY ( desc - > cap ) )
lmt | = VAL_LIMIT_READONLY ;
* limit = ( value_limit ) lmt ;
}
2022-06-15 03:04:40 +00:00
if ( bytes )
* bytes = desc - > size ;
ret = true ;
}
return ret ;
}
COM_API_IMPLEMENT ( scanner , bool , get_value ( int sn , set_opt_value setval , void * param ) )
{
2023-05-13 08:27:44 +00:00
if ( sane_ids_ . count ( ( sane_option_id ) sn ) & &
sane_ids_ [ ( sane_option_id ) sn ] = = sn )
{
char buf [ 256 ] = { 0 } ;
value_type type = VAL_TYPE_NONE ;
int ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) sn , SANE_ACTION_GET_VALUE , buf , NULL ) ;
if ( ret = = SANE_STATUS_GOOD )
{
get_option_info ( sn , & type , NULL , NULL ) ;
if ( type = = VAL_TYPE_STR )
{
std : : string str ( buf ) ;
setval ( & str , VAL_ROLE_CURRENT , VAL_LIMIT_NONE , param ) ;
}
else
setval ( buf , VAL_ROLE_CURRENT , VAL_LIMIT_NONE , param ) ;
return true ;
}
return false ;
}
2023-06-15 02:09:40 +00:00
int org_id = sn ;
if ( sn = = 0x102c ) // CapType::Language
sn = transfer_id ( SANE_OPT_ID_LANGUAGE ) ;
else
sn = transfer_id ( sn ) ;
2023-05-13 08:27:44 +00:00
if ( sn = = - 1 )
return false ;
2022-06-15 03:04:40 +00:00
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-06-15 02:09:40 +00:00
if ( org_id = = 0x102c )
{
// const char* hz = local_trans::lang_trans_between_hz936(val.c_str(), false, NULL);
int lid = sane_opt_trans : : language_to_twain ( val . c_str ( ) ) ;
if ( ! setval ( & lid , role , VAL_LIMIT_ENUM , param ) )
break ;
}
else 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 ;
}
2023-05-13 08:27:44 +00:00
COM_API_IMPLEMENT ( scanner , bool , get_value ( int sn , void * data , int * len ) )
{
if ( sn ! = SANE_OPT_ID_DRIVER_LOG & & sn ! = SANE_OPT_ID_DEVICE_LOG )
return false ;
2023-06-30 01:49:05 +00:00
SANE_Status ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( const void * ) sn , SANE_ACTION_GET_VALUE , data , NULL ) ;
wchar_t msg [ 128 ] = { 0 } ;
swprintf_s ( msg , _countof ( msg ) - 1 , L " get log of(%x) = 0x%x \r \n " , sn , ret ) ;
log_info ( msg , 1 ) ;
2023-06-30 08:58:57 +00:00
return ret = = SANE_STATUS_GOOD ;
2023-05-13 08:27:44 +00:00
}
2022-06-15 03:04:40 +00:00
COM_API_IMPLEMENT ( scanner , int , set_value ( int sn , void * val ) )
{
2023-05-13 08:27:44 +00:00
if ( sane_ids_ . count ( ( sane_option_id ) sn ) & &
sane_ids_ [ ( sane_option_id ) sn ] = = sn )
{
int ret = hg_sane_middleware : : instance ( ) - > set_option ( handle_ , ( void * ) sn , SANE_ACTION_SET_VALUE , val , NULL ) ;
2023-05-16 07:38:54 +00:00
return ret ;
2023-05-13 08:27:44 +00:00
}
2023-06-15 02:09:40 +00:00
int org_id = sn ;
if ( sn = = 0x102c ) // CapType::Language
sn = transfer_id ( SANE_OPT_ID_LANGUAGE ) ;
else
sn = transfer_id ( sn ) ;
2023-05-13 08:27:44 +00:00
if ( sn = = - 1 )
return SANE_STATUS_UNSUPPORTED ;
2022-06-15 03:04:40 +00:00
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 ( ) )
{
2023-06-15 02:09:40 +00:00
std : : string strv ( " " ) ;
void * w = val ;
if ( org_id = = 0x102c )
{
2023-06-15 03:47:00 +00:00
// const char* str = sane_opt_trans::language_from_twain(*(int*)val);
strv = sane_opt_trans : : language_from_twain ( * ( int * ) val ) ;
2023-06-15 02:09:40 +00:00
w = & strv ;
}
if ( ! set_option_value_with_parent ( sn , w , & ret ) )
ret = set_option_value ( sn , desc - > type , desc - > size , w ) ;
2022-06-15 03:04:40 +00:00
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 ) ;
}
2023-06-15 02:09:40 +00:00
COM_API_IMPLEMENT ( scanner , int , get_fixed_ids ( bool ( __stdcall * cb ) ( uint32_t id , void * param ) , void * param ) )
{
for ( auto & v : sane_ids_ )
{
if ( ! cb ( v . first , param ) )
break ;
}
return 0 ;
}
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 )
2023-08-16 07:32:13 +00:00
SANE_OPTION_ID_IMPLEMENT ( discardblank )
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-06-30 08:58:57 +00:00
int ret = SCANNER_ERR_NO_DATA ;
if ( callback : : get_config_content )
2022-07-01 07:24:58 +00:00
{
2023-06-30 08:58:57 +00:00
char * cont = callback : : get_config_content ( local_trans : : u2a ( scanner_name_ . c_str ( ) , CP_UTF8 ) . c_str ( ) , NULL ) ;
if ( cont )
2023-04-04 05:50:10 +00:00
{
2023-06-30 08:58:57 +00:00
if ( * len < = strlen ( cont ) )
{
* len = strlen ( cont ) + 4 ;
2023-04-04 05:50:10 +00:00
2023-06-30 08:58:57 +00:00
ret = SCANNER_ERR_INSUFFICIENT_MEMORY ;
}
else
{
strcpy ( buf , cont ) ;
ret = SCANNER_ERR_OK ;
* len = strlen ( cont ) ;
}
if ( callback : : twain_ui_free )
callback : : twain_ui_free ( cont ) ;
2023-04-04 05:50:10 +00:00
}
2022-07-01 07:24:58 +00:00
}
2023-06-30 08:58:57 +00:00
return ret ;
2022-07-01 07:24:58 +00:00
}
COM_API_IMPLEMENT ( scanner , int , twain_set_config ( char * buf , size_t len ) )
{
2023-06-30 08:58:57 +00:00
if ( callback : : apply_given_config )
2022-07-01 07:24:58 +00:00
{
2023-06-30 08:58:57 +00:00
if ( callback : : apply_given_config ( buf , handle_ , & sane_api_ ) = = 0 )
return SCANNER_ERR_OK ;
2022-07-01 07:24:58 +00:00
}
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-05-08 07:31:24 +00:00
is_show_ui_ = with_scan ;
2023-05-13 10:33:36 +00:00
is_show_setting_ = true ;
2023-05-11 06:25:09 +00:00
events_ . clear ( ) ;
2023-11-29 06:41:06 +00:00
ui_notify = std : : function < void ( int , void * , int ) > ( ) ;
2023-04-04 05:50:10 +00:00
if ( callback : : show_setting_ui )
{
2023-05-08 14:29:50 +00:00
if ( with_scan )
{
images_ . clear ( ) ;
scan_msg_ = " OK " ;
scan_err_ = false ;
}
2023-05-05 09:53:46 +00:00
auto ui = [ this ] ( ui_result res )
2023-04-04 05:50:10 +00:00
{
2023-05-05 09:53:46 +00:00
int uev = SANE_EVENT_SCAN_FINISHED ;
switch ( res )
{
case UI_RESULT_FAILED :
break ;
case UI_RESULT_OK :
2023-04-25 08:54:57 +00:00
2023-05-05 09:53:46 +00:00
break ;
case UI_RESULT_CLOSE_NORMAL :
2023-05-18 09:00:35 +00:00
is_show_ui_ = false ;
uev = SANE_EVENT_UI_CLOSE_NORMAL ;
on_ui_event ( uev , ( void * ) uev ) ;
break ;
2023-05-05 09:53:46 +00:00
case UI_RESULT_CLOSE_CANCEL :
2023-05-08 07:31:24 +00:00
is_show_ui_ = false ;
2023-05-18 09:00:35 +00:00
uev = SANE_EVENT_UI_CLOSE_CANCEL ;
on_ui_event ( uev , ( void * ) uev ) ;
break ;
case UI_RESULT_CLOSE_SETTING :
is_show_setting_ = false ;
2023-05-17 01:44:19 +00:00
uev = SANE_EVENT_UI_CLOSE_SETTING ;
on_ui_event ( uev , ( void * ) uev ) ;
2023-05-05 09:53:46 +00:00
break ;
case UI_RESULT_START_SCAN :
on_ui_event ( SANE_EVENT_UI_SCAN_COMMAND , NULL ) ;
break ;
default :
break ;
}
} ;
2023-11-29 06:41:06 +00:00
int res = callback : : show_setting_ui ( handle_ , parent , & sane_api_ , local_trans : : u2a ( scanner_name_ . c_str ( ) , CP_UTF8 ) . c_str ( ) , with_scan , ui , & ui_notify ) ;
2023-05-05 09:53:46 +00:00
//if (res == ui_result::UI_RESULT_CLOSE_NORMAL)
2023-04-25 08:54:57 +00:00
//{
2023-05-05 09:53:46 +00:00
// int ev = SANE_EVENT_UI_CLOSE_NORMAL;
// on_ui_event(ev, (void*)ev);
//}
//else if (res == ui_result::UI_RESULT_START_SCAN)
//{
// //callback::show_progress_ui(parent, ui_process, &ui_notify);
// //start();
// on_ui_event(SANE_EVENT_UI_SCAN_COMMAND, NULL);
//}
//else if (res == UI_RESULT_CLOSE_CANCEL)
//{
// int ev = SANE_EVENT_UI_CLOSE_CANCEL;
// on_ui_event(ev, (void*)ev);
//}
2023-04-25 08:54:57 +00:00
//on_ui_event(ev, NULL);
2023-04-04 05:50:10 +00:00
}
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 ( ) ;
2023-10-23 03:14:25 +00:00
if ( setting_ )
setting_ - > close ( ) ;
setting_ = new dlg_setting ( parent , & sane_api_ , handle_ , with_scan , scanner_name_ . substr ( 0 , pid ) . c_str ( ) , true ) ;
2023-04-04 05:50:10 +00:00
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_ ) ;
2023-10-23 03:14:25 +00:00
//if (indicator)
//{
// indicator_.reset(new dlg_indicator(setting_->hwnd(), false));
// indicator_->set_ui_event_notify(&scanner::ui_callback, this);
//}
2023-04-04 05:50:10 +00:00
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
}
2023-04-24 09:23:43 +00:00
2023-05-03 09:09:05 +00:00
COM_API_IMPLEMENT ( scanner , bool , ui_show_progress ( HWND parent , bool bIndicator ) )
2022-06-15 03:04:40 +00:00
{
2023-05-03 09:09:05 +00:00
is_bIndicator = bIndicator ;
2023-11-29 06:41:06 +00:00
if ( is_bIndicator )
ui_notify = std : : function < void ( int , void * , int ) > ( ) ;
2023-05-04 02:36:55 +00:00
auto ui_process = [ this ] ( ui_result res )
{
int uev = SANE_EVENT_SCAN_FINISHED ;
switch ( res )
{
case UI_RESULT_CLOSE_NORMAL :
uev = SANE_EVENT_UI_CLOSE_NORMAL ;
2023-05-17 01:44:19 +00:00
//if (!is_show_ui_)
2023-05-08 07:31:24 +00:00
{
on_ui_event ( uev , ( void * ) uev ) ;
}
2023-05-04 02:36:55 +00:00
break ;
case UI_RESULT_CLOSE_CANCEL :
uev = SANE_EVENT_UI_CLOSE_CANCEL ;
2023-05-17 01:44:19 +00:00
//if (!is_show_ui_)
2023-05-11 13:07:00 +00:00
{
on_ui_event ( uev , ( void * ) uev ) ;
}
2023-05-17 01:44:19 +00:00
//else
// stop();
2023-05-04 02:36:55 +00:00
break ;
default :
break ;
}
} ;
2023-05-03 09:09:05 +00:00
if ( callback : : show_progress_ui & & bIndicator )
2023-04-04 05:50:10 +00:00
{
2023-04-23 14:23:02 +00:00
callback : : show_progress_ui ( parent , ui_process , & ui_notify ) ;
2023-04-04 05:50:10 +00:00
}
2023-05-16 07:25:19 +00:00
else if ( bIndicator )
2023-04-04 05:50:10 +00:00
{
2023-10-23 03:14:25 +00:00
bool sole_thread = true ;
if ( setting_ & & IsWindowVisible ( setting_ - > hwnd ( ) ) )
{
2023-04-04 05:50:10 +00:00
parent = setting_ - > hwnd ( ) ;
2023-10-23 03:14:25 +00:00
sole_thread = false ;
}
2023-04-04 05:50:10 +00:00
else if ( ! IsWindow ( parent ) )
parent = callback : : find_main_wnd ( ) ;
2022-07-28 01:57:26 +00:00
2023-10-23 03:14:25 +00:00
if ( indicator_ )
indicator_ - > close ( ) ;
indicator_ = new dlg_indicator ( parent , sole_thread ) ;
2023-04-04 05:50:10 +00:00
indicator_ - > set_ui_event_notify ( & scanner : : ui_callback , this ) ;
2023-05-13 10:33:36 +00:00
indicator_ - > show ( true ) ;
2023-04-04 05:50:10 +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 , void , ui_hide ( void ) )
2022-06-15 03:04:40 +00:00
{
2023-10-23 03:14:25 +00:00
if ( indicator_ )
indicator_ - > close ( ) ;
indicator_ = NULL ;
if ( setting_ )
setting_ - > close ( ) ;
setting_ = NULL ;
2023-05-19 07:03:38 +00:00
if ( callback : : close_ui )
2023-05-23 08:16:30 +00:00
callback : : close_ui ( UI_INDICATOR | UI_SETTING | UI_MSG_BOX ) ;
2023-05-26 08:21:33 +00:00
is_show_setting_ = false ;
2023-05-29 06:50:17 +00:00
ui_notify = std : : function < void ( int , void * , int ) > ( ) ;
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
{
2023-10-23 03:14:25 +00:00
dlg_indicator * prog = indicator_ ;
2022-07-01 07:24:58 +00:00
if ( ev_code = = SANE_EVENT_WORKING )
{
2023-11-07 09:02:10 +00:00
is_in_working_thread_ = true ;
2023-05-17 03:49:30 +00:00
img_ind_ = 0 ;
2023-11-29 06:41:06 +00:00
2023-10-23 03:14:25 +00:00
if ( prog )
prog - > notify_working ( ) ;
2023-10-28 08:46:34 +00:00
else if ( callback : : show_progress_ui & & is_bIndicator & & ui_notify )
2023-05-04 10:18:01 +00:00
ui_notify ( ev_code , data , * len ) ;
2023-11-29 06:41:06 +00:00
else if ( callback : : show_setting_ui & & ui_notify )
ui_notify ( ev_code , data , * len ) ;
2023-05-13 10:33:36 +00:00
on_ui_event ( ev_code , ( void * ) ev_code ) ;
2023-05-20 04:02:26 +00:00
log_info ( L " Scanning ... \r \n " , 1 ) ;
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 } ;
2023-10-07 04:41:24 +00:00
if ( simg - > flag . statu & & callback : : abnormal_image )
{
2023-10-17 09:52:13 +00:00
if ( double_handle_ = = DOUBLE_FEED_NEED_UI )
2023-10-07 04:41:24 +00:00
{
2023-10-17 09:52:13 +00:00
if ( callback : : abnormal_image ( simg ) = = SANE_Abnormal_Image_Discard )
{
wchar_t info [ 128 ] = { 0 } ;
2023-10-07 04:41:24 +00:00
2023-10-17 09:52:13 +00:00
swprintf_s ( info , _countof ( info ) - 1 , L " Discard image %d for the status is: %d \r \n " , simg - > src_id , simg - > flag . statu ) ;
log_info ( info , LOG_LEVEL_DEBUG_INFO ) ;
2023-10-07 04:41:24 +00:00
2023-10-17 09:52:13 +00:00
double_handle_ = DOUBLE_FEED_DISCARD ;
}
else
double_handle_ = DOUBLE_FEED_KEEP ;
2023-10-07 04:41:24 +00:00
}
2023-10-17 09:52:13 +00:00
if ( double_handle_ = = DOUBLE_FEED_DISCARD )
return 0 ;
2023-10-07 04:41:24 +00:00
}
2023-10-28 08:32:35 +00:00
else
{
double_handle_ = DOUBLE_FEED_NEED_UI ;
}
2023-10-07 04:41:24 +00:00
2022-06-18 00:54:01 +00:00
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 ;
2023-09-12 07:47:00 +00:00
int times = 0 , cnt0 = images_ . count ( & bytes ) , cnt = cnt0 ,
gap = 5 , max_wait = wait_fetch_ / gap ;
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 ;
2023-09-12 07:47:00 +00:00
while ( bytes > max_img_mem_ & & ! user_cancel_ & & times + + < max_wait & & cnt > = cnt0 ) // memory control
2022-11-25 06:20:06 +00:00
{
2023-09-12 07:47:00 +00:00
std : : this_thread : : sleep_for ( std : : chrono : : milliseconds ( gap ) ) ;
cnt = images_ . count ( & bytes ) ;
2022-11-25 06:20:06 +00:00
bytes / = 1024 * 1024 ;
if ( times = = 1 )
2023-09-27 01:55:37 +00:00
{
wchar_t tips [ 128 ] = { 0 } ;
swprintf_s ( tips , _countof ( tips ) - 1 , L " Memory usage upto limit! wait up to %u ms ... \r \n " , wait_fetch_ ) ;
log_info ( tips , 1 ) ;
}
2022-11-25 06:20:06 +00:00
}
images_ . save ( img , img - > bytes ( ) ) ;
2022-06-18 00:54:01 +00:00
}
else
{
img - > release ( ) ;
}
2023-10-23 03:14:25 +00:00
if ( prog )
prog - > notify_data_arrived ( true ) ;
2023-05-13 10:33:36 +00:00
else if ( ui_notify )
2023-05-29 02:54:44 +00:00
ui_notify ( ev_code , data , img_ind_ ) ;
2022-09-19 06:16:34 +00:00
2023-11-16 09:29:37 +00:00
// notifyXferReady <20> <> Ϊ<EFBFBD> <CEAA> ͼƬ<CDBC> <C6AC> ֪ͨ<CDA8> <D6AA> <EFBFBD> <EFBFBD> ֹ<EFBFBD> <D6B9> <EFBFBD> <EFBFBD> APP<50> <50> imgGetInfo<66> з<EFBFBD> <D0B7> ش<EFBFBD> <D8B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ˳<EFBFBD> <CBB3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> - 22023-10-25
2023-10-25 03:23:23 +00:00
if ( img_ind_ = = 1 )
on_ui_event ( SANE_EVENT_TWAIN_XFER_READY , nullptr ) ;
2022-09-19 06:16:34 +00:00
{
wchar_t msg [ 128 ] = { 0 } ;
2023-10-28 08:46:34 +00:00
swprintf_s ( msg , _countof ( msg ) - 1 , L " New image(%u) received with %u bytes (status: %d) \r \n " , img_ind_ , simg - > bytes , simg - > flag . statu ) ;
2023-05-20 04:02:26 +00:00
log_info ( msg , 1 ) ;
2022-09-19 06:16:34 +00:00
}
2022-06-18 08:48:41 +00:00
}
else if ( ev_code = = SANE_EVENT_USB_DATA_RECEIVED )
{
2023-10-23 03:14:25 +00:00
//if (prog)
// prog->notify_data_arrived(false);
2023-05-26 07:17:15 +00:00
//else if (ui_notify)
// ui_notify(ev_code, data, 0);
2022-06-18 00:54:01 +00:00
}
else if ( ev_code = = SANE_EVENT_SCAN_FINISHED )
{
2023-10-28 08:32:35 +00:00
if ( double_handle_ = = DOUBLE_FEED_KEEP )
{
2023-10-30 03:29:29 +00:00
double_handle_ = DOUBLE_FEED_NEED_UI ;
2023-10-28 08:32:35 +00:00
if ( start_after_keep_ . get ( ) & & start_after_keep_ - > joinable ( ) )
start_after_keep_ - > join ( ) ;
start_after_keep_ . reset ( new std : : thread ( & scanner : : thread_start_after_keep , this ) ) ;
}
else
{
2023-11-16 08:43:43 +00:00
//is_in_working_thread_ = false;
2023-10-28 08:32:35 +00:00
err_ = * len ;
scan_over_ = true ;
scan_msg_ = data ? ( char * ) data : " OK " ;
2023-10-11 05:54:17 +00:00
2023-10-28 08:32:35 +00:00
if ( double_handle_ = = DOUBLE_FEED_DISCARD )
{
scan_msg_ = " OK " ;
err_ = 0 ;
}
if ( done_ . get ( ) & & done_ - > joinable ( ) )
done_ - > join ( ) ;
done_ . reset ( new std : : thread ( & scanner : : scan_done , this ) ) ;
// scan_done(); // invoking move to the last image fetched
2023-04-23 14:23:02 +00:00
2023-10-28 08:32:35 +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 , 1 ) ;
}
2022-09-19 06:16:34 +00:00
}
2022-06-18 00:54:01 +00:00
}
2023-11-16 09:29:37 +00:00
//else if (ev_code == SANE_EVENT_ERROR) // 閻忕偛绻楅弬鈧柨娑樿嫰濠€顏堝磻濠婂嫷鍓鹃柟娈垮亝瀵潡寮捄铏规綌缂佲偓鏉為绻嗛柟?- 2023-05-30
2023-05-30 02:12:31 +00:00
//{
// if (callback::show_messagebox_ui && *len)
// {
// callback::show_messagebox_ui(app_wnd_, ev_code, (void*)data, 0);
// }
2023-11-16 09:29:37 +00:00
// else if (*len) //闂佹寧鐟ㄩ銈咁嚕閻熸澘<E786B8> <E6BE98> ?
2023-05-30 02:12:31 +00:00
// {
// std::wstring msg(local_trans::a2u((char*)data, CP_UTF8));
// if (!IsWindow(app_wnd_))
// 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);
// }
//// on_ui_event(ev_code, (void*)ev_code);
//}
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 ;
2023-05-20 04:02:26 +00:00
static int g_log_level = 1 ;
2023-11-23 06:58:28 +00:00
static int get_log_level ( const char * log_file , std : : wstring * firstmsg = NULL )
2023-05-20 04:02:26 +00:00
{
std : : string cfg ( log_file ) ;
size_t pos = cfg . rfind ( ' \\ ' ) ;
2022-09-19 06:16:34 +00:00
2023-11-23 06:58:28 +00:00
if ( firstmsg )
* firstmsg = L " " ;
2023-05-20 04:02:26 +00:00
cfg . erase ( pos ) ;
pos = cfg . rfind ( ' \\ ' ) ;
if ( pos ! = std : : string : : npos )
{
if ( stricmp ( cfg . substr ( pos ) . c_str ( ) , " \\ log " ) = = 0 )
{
cfg . erase ( pos ) ;
cfg + = " \\ config " ;
}
}
cfg + = " \\ debug.cfg " ;
2023-11-23 06:58:28 +00:00
// A+ -> XYBscanner.exe
callback : : check_wnd_thread_id = GetPrivateProfileIntA ( " twain-app " , " check-main-wnd-thread-id " , 0 , cfg . c_str ( ) ) = = 1 ;
if ( ! callback : : check_wnd_thread_id )
{
wchar_t pe [ MAX_PATH ] = { 0 } , * name = NULL ;
GetModuleFileNameW ( NULL , pe , _countof ( pe ) - 1 ) ;
name = wcsrchr ( pe , L ' \\ ' ) ;
if ( name + + = = NULL )
name = pe ;
if ( wcsicmp ( name , L " XYBscanner.exe " ) = = 0 )
{
callback : : check_wnd_thread_id = true ;
if ( firstmsg )
* firstmsg = std : : wstring ( L " check window thread while PE is: ' " ) + pe + L " ' \r \n " ;
}
}
2023-05-20 04:09:29 +00:00
return GetPrivateProfileIntA ( " log " , " twain-level " , 1 , cfg . c_str ( ) ) ;
2023-05-20 04:02:26 +00:00
}
2022-09-19 06:16:34 +00:00
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 } ;
2023-11-23 06:58:28 +00:00
std : : wstring msg1 ( L " " ) ;
2022-10-08 09:20:16 +00:00
2023-02-13 09:02:47 +00:00
hg_get_current_time_w ( now ) ;
2023-11-23 06:58:28 +00:00
g_log_level = get_log_level ( g_path_file_ . c_str ( ) , & msg1 ) ;
2023-05-25 07:37:29 +00:00
swprintf_s ( ts , _countof ( ts ) - 1 , L " ==================%s - %d, Proc %d================== \r \n " , now , g_log_level , GetCurrentProcessId ( ) ) ;
2022-10-08 09:20:16 +00:00
fwrite ( ts , 2 , lstrlenW ( ts ) , g_file_ ) ;
2023-11-23 06:58:28 +00:00
if ( msg1 . length ( ) )
fwrite ( msg1 . c_str ( ) , 2 , msg1 . length ( ) , 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 )
{
2023-10-28 08:46:34 +00:00
wchar_t clock [ 40 ] = { 0 } ;
hg_get_current_time_w ( clock ) ;
2022-09-19 06:16:34 +00:00
if ( g_file_ )
{
std : : lock_guard < std : : mutex > lock ( g_lock_ ) ;
2023-10-28 08:46:34 +00:00
std : : wstring text ( clock ) ;
2022-09-19 06:16:34 +00:00
2023-10-28 08:46:34 +00:00
text + = info ;
fwrite ( text . c_str ( ) , 2 , text . length ( ) , g_file_ ) ;
2022-09-19 06:16:34 +00:00
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 ( ) ) ;
2023-05-16 08:41:42 +00:00
g_file_ = fopen ( g_path_file_ . c_str ( ) , " wb " ) ;
2022-10-08 09:20:16 +00:00
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
2023-05-20 03:05:06 +00:00
int __stdcall open_scanner ( SCANNERID scanner_id , ISaneInvoker * * invoker , bool last_try )
2022-11-06 03:29:49 +00:00
{
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 ) )
2023-05-20 03:05:06 +00:00
{
if ( last_try )
{
HWND parent = callback : : find_main_wnd ( ) ;
std : : string msg ( callback : : language_trans ( " \xE6 \xB2 \xA1 \xE6 \x9C \x89 \xE6 \x89 \xBE \xE5 \x88 \xB0 \xE6 \x89 \xAB \xE6 \x8F \x8F \xE4 \xBB \xAA \xEF \xBC \x81 " , true , NULL ) ) ,
title ( callback : : language_trans ( " \xE9 \x94 \x99 \xE8 \xAF \xAF " , true , NULL ) ) ;
if ( callback : : show_messagebox_ui )
callback : : show_messagebox_ui ( parent , 0 , & msg [ 0 ] , SCANNER_ERR_DEVICE_NOT_FOUND ) ;
else
MessageBoxW ( parent , local_trans : : a2u ( msg . c_str ( ) , CP_UTF8 ) . c_str ( ) , local_trans : : a2u ( title . c_str ( ) , CP_UTF8 ) . c_str ( ) , MB_OK ) ;
}
2022-11-06 03:29:49 +00:00
return SCANNER_ERR_DEVICE_NOT_FOUND ;
2023-05-20 03:05:06 +00:00
}
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
{
2023-05-20 03:05:06 +00:00
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 ;
2023-05-20 03:05:06 +00:00
if ( last_try )
{
HWND parent = callback : : find_main_wnd ( ) ;
std : : string msg ( callback : : language_trans ( " \xE6 \x89 \x93 \xE5 \xBC \x80 \xE6 \x89 \xAB \xE6 \x8F \x8F \xE4 \xBB \xAA \xE5 \xA4 \xB1 \xE8 \xB4 \xA5 \xE3 \x80 \x82 " , true , NULL ) ) ,
title ( callback : : language_trans ( " \xE9 \x94 \x99 \xE8 \xAF \xAF " , true , NULL ) ) ;
if ( callback : : show_messagebox_ui )
callback : : show_messagebox_ui ( parent , 0 , & msg [ 0 ] , ret ) ;
else
MessageBoxW ( parent , local_trans : : a2u ( msg . c_str ( ) , CP_UTF8 ) . c_str ( ) , local_trans : : a2u ( title . c_str ( ) , CP_UTF8 ) . c_str ( ) , MB_OK ) ;
}
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 ( ) ;
2023-05-20 04:02:26 +00:00
callback : : unint_ui ( ) ;
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 )
{
2023-05-20 04:02:26 +00:00
if ( level > = g_log_level )
log ( info ) ;
2022-11-06 03:29:49 +00:00
}
2022-06-15 03:04:40 +00:00
2022-11-06 03:29:49 +00:00
}