2022-05-03 03:56:07 +00:00
# include "sane_hg_mdw.h"
# include "json.h"
# include <stdarg.h>
# include <time.h>
# include <fcntl.h>
# include <sys/stat.h>
2022-05-09 06:48:42 +00:00
# include <mutex>
2022-10-14 01:00:57 +00:00
# include <thread>
2022-07-18 08:56:03 +00:00
# if defined(WIN32) || defined(_WIN64)
2022-05-03 03:56:07 +00:00
# include <windows.h>
# include <direct.h>
# define pthread_t DWORD
# define pthread_self GetCurrentThreadId
# define MKDIR(a, b) mkdir(a)
# else
# define MKDIR(a, b) mkdir(a, b)
# include <pthread.h>
# endif
2022-05-20 06:46:25 +00:00
# include "../../sdk/include/sane/sane_option_definitions.h"
2022-05-23 03:52:53 +00:00
# include "sane_option.h"
2023-01-19 07:43:59 +00:00
# include <lang/app_language.h>
2022-05-20 06:46:25 +00:00
2022-05-03 03:56:07 +00:00
# ifndef SIGUSR1
# define SIGUSR1 10
# endif
// copy to /usr/lib/x86_64-linux-gnu/sane
// export SANE_DEBUG_DLL=5
# ifndef iconv_t
# define iconv_t void*
# endif
2022-07-15 08:47:26 +00:00
static std : : string g_sane_path ( " " ) ;
static std : : string g_sane_name ( GET_BACKEND_NAME ) ;
2022-06-01 03:04:10 +00:00
2022-05-03 03:56:07 +00:00
namespace local_utility
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2022-07-18 02:54:41 +00:00
# define RETURN_MATCH_ERROR(err, from, to) \
if ( err = = from ) \
return to ;
2022-05-17 07:04:55 +00:00
SANE_Status scanner_err_2_sane_statu ( int hgerr )
2022-05-03 03:56:07 +00:00
{
2022-07-18 02:54:41 +00:00
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_OK , SANE_STATUS_GOOD ) ;
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_INVALID_PARAMETER , SANE_STATUS_INVAL ) ;
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_INSUFFICIENT_MEMORY , SANE_STATUS_NO_MEM ) ;
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_ACCESS_DENIED , SANE_STATUS_ACCESS_DENIED ) ;
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_IO_PENDING , SANE_STATUS_GOOD ) ;
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_NOT_EXACT , SANE_STATUS_GOOD ) ;
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_CONFIGURATION_CHANGED , SANE_STATUS_GOOD ) ;
2023-02-18 02:26:38 +00:00
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_RELOAD_IMAGE_PARAM , SANE_STATUS_GOOD ) ;
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_RELOAD_OPT_PARAM , SANE_STATUS_GOOD ) ;
2022-08-02 10:20:34 +00:00
//RETURN_MATCH_ERROR(hgerr, SCANNER_ERR_NOT_OPEN, SANE_STATUS_NO_DOCS);
//RETURN_MATCH_ERROR(hgerr, SCANNER_ERR_NOT_START, SANE_STATUS_NO_DOCS);
2022-07-18 02:54:41 +00:00
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_NO_DATA , SANE_STATUS_EOF ) ;
2022-08-06 12:43:07 +00:00
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_IO , SANE_STATUS_IO_ERROR ) ;
2022-07-18 02:54:41 +00:00
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_OUT_OF_RANGE , SANE_STATUS_NO_MEM ) ;
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_IO , SANE_STATUS_IO_ERROR ) ;
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_TIMEOUT , SANE_STATUS_IO_ERROR ) ;
// RETURN_MATCH_ERROR(hgerr, SCANNER_ERR_DEVICE_NOT_FOUND, SANE_STATUS_NO_DOCS);
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_DEVICE_NOT_SUPPORT , SANE_STATUS_UNSUPPORTED ) ;
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_DEVICE_BUSY , SANE_STATUS_DEVICE_BUSY ) ;
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_DEVICE_COVER_OPENNED , SANE_STATUS_COVER_OPEN ) ;
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_DEVICE_NO_PAPER , SANE_STATUS_NO_DOCS ) ;
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_DEVICE_PAPER_JAMMED , SANE_STATUS_JAMMED ) ;
2022-05-03 03:56:07 +00:00
return ( SANE_Status ) hgerr ;
}
2022-06-15 03:05:36 +00:00
int sane_statu_2_scanner_err ( int statu )
{
2022-07-18 02:54:41 +00:00
RETURN_MATCH_ERROR ( statu , SANE_STATUS_GOOD , SCANNER_ERR_OK ) ;
RETURN_MATCH_ERROR ( statu , SANE_STATUS_INVAL , SCANNER_ERR_INVALID_PARAMETER ) ;
RETURN_MATCH_ERROR ( statu , SANE_STATUS_NO_MEM , SCANNER_ERR_INSUFFICIENT_MEMORY ) ;
RETURN_MATCH_ERROR ( statu , SANE_STATUS_ACCESS_DENIED , SCANNER_ERR_ACCESS_DENIED ) ;
RETURN_MATCH_ERROR ( statu , SANE_STATUS_GOOD , SCANNER_ERR_IO_PENDING ) ;
RETURN_MATCH_ERROR ( statu , SANE_STATUS_GOOD , SCANNER_ERR_NOT_EXACT ) ;
RETURN_MATCH_ERROR ( statu , SANE_STATUS_GOOD , SCANNER_ERR_CONFIGURATION_CHANGED ) ;
2023-02-18 02:26:38 +00:00
RETURN_MATCH_ERROR ( statu , SANE_STATUS_GOOD , SCANNER_ERR_RELOAD_IMAGE_PARAM ) ;
RETURN_MATCH_ERROR ( statu , SANE_STATUS_GOOD , SCANNER_ERR_RELOAD_OPT_PARAM ) ;
2022-08-02 10:20:34 +00:00
//RETURN_MATCH_ERROR(statu, SANE_STATUS_NO_DOCS, SCANNER_ERR_NOT_OPEN);
//RETURN_MATCH_ERROR(statu, SANE_STATUS_NO_DOCS, SCANNER_ERR_NOT_START);
2022-07-18 02:54:41 +00:00
RETURN_MATCH_ERROR ( statu , SANE_STATUS_EOF , SCANNER_ERR_NO_DATA ) ;
2022-08-06 12:43:07 +00:00
RETURN_MATCH_ERROR ( statu , SANE_STATUS_IO_ERROR , SCANNER_ERR_IO ) ;
2022-07-18 02:54:41 +00:00
RETURN_MATCH_ERROR ( statu , SANE_STATUS_NO_MEM , SCANNER_ERR_OUT_OF_RANGE ) ;
RETURN_MATCH_ERROR ( statu , SANE_STATUS_IO_ERROR , SCANNER_ERR_IO ) ;
RETURN_MATCH_ERROR ( statu , SANE_STATUS_IO_ERROR , SCANNER_ERR_TIMEOUT ) ;
2022-08-02 10:20:34 +00:00
//RETURN_MATCH_ERROR(statu, SANE_STATUS_NO_DOCS, SCANNER_ERR_DEVICE_NOT_FOUND);
2022-07-18 02:54:41 +00:00
RETURN_MATCH_ERROR ( statu , SANE_STATUS_UNSUPPORTED , SCANNER_ERR_DEVICE_NOT_SUPPORT ) ;
RETURN_MATCH_ERROR ( statu , SANE_STATUS_DEVICE_BUSY , SCANNER_ERR_DEVICE_BUSY ) ;
RETURN_MATCH_ERROR ( statu , SANE_STATUS_COVER_OPEN , SCANNER_ERR_DEVICE_COVER_OPENNED ) ;
RETURN_MATCH_ERROR ( statu , SANE_STATUS_NO_DOCS , SCANNER_ERR_DEVICE_NO_PAPER ) ;
RETURN_MATCH_ERROR ( statu , SANE_STATUS_JAMMED , SCANNER_ERR_DEVICE_PAPER_JAMMED ) ;
2022-06-15 03:05:36 +00:00
return statu ;
}
2022-05-03 03:56:07 +00:00
void * acquire_memory ( size_t bytes , const char * info )
{
//if (!info)
// info = "";
//hg_sane_middleware::log(strlen(info) + 80, "allocate memory with %u bytes from %s\n", bytes, info);
2022-09-23 06:15:44 +00:00
void * buf = malloc ( bytes ) ;
if ( buf )
memset ( buf , 0 , bytes ) ;
return buf ;
2022-05-03 03:56:07 +00:00
}
2022-05-18 09:41:05 +00:00
void free_memory ( void * m )
{
if ( m )
free ( m ) ;
}
2022-05-03 03:56:07 +00:00
2022-05-30 03:04:26 +00:00
2022-05-03 03:56:07 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2022-05-30 03:04:26 +00:00
// json parser ...
2022-05-03 03:56:07 +00:00
bool is_space ( char ch )
{
return ch = = ' ' | | ch = = ' \t ' ;
}
bool is_digital ( char ch )
{
return ch > = ' 0 ' & & ch < = ' 9 ' ;
}
bool is_hex_num ( char ch )
{
if ( is_digital ( ch ) )
return true ;
return ( ch > = ' a ' & & ch < = ' f ' ) | | ( ch > = ' A ' & & ch < = ' F ' ) ;
}
bool to_num ( char ch , int & v , bool hex )
{
if ( is_digital ( ch ) )
{
v = ch - ' 0 ' ;
return true ;
}
if ( hex )
{
if ( ch > = ' a ' & & ch < = ' f ' )
{
v = ch - ' a ' + 10 ;
}
else if ( ch > = ' A ' & & ch < = ' F ' )
{
v = ch - ' A ' + 10 ;
}
else
{
hex = false ;
}
}
return hex ;
}
bool skip_space ( const char * & str )
{
const char * bgn = str ;
while ( is_space ( * str ) )
str + + ;
return str > bgn ;
}
2023-05-13 08:26:43 +00:00
// 暂不支持科学计数<E8AEA1> <E695B0> ?1.2e+10
2022-05-03 03:56:07 +00:00
bool get_number ( const char * & str , double & val )
{
const char * bgn = str ;
double val_race = 10.0f ,
val_sign = 1.0f ,
digit_race = 1.0f ,
digit_race_race = 1.0f ;
val = .0f ;
if ( * str = = ' - ' )
{
str + + ;
val_sign = - 1.0f ;
}
if ( * str = = ' . ' )
{
str + + ;
digit_race = digit_race_race = .1f ;
val_race = 1.0f ;
}
bgn = str ;
while ( * str & & is_digital ( * str ) )
{
int v = 0 ;
val * = val_race ;
to_num ( * str + + , v , false ) ;
val + = v * digit_race ;
digit_race * = digit_race_race ;
}
if ( * str = = ' . ' )
{
if ( digit_race_race < 1.0f )
return false ;
digit_race = digit_race_race = .1f ;
val_race = 1.0f ;
while ( * str & & is_digital ( * str ) )
{
int v = 0 ;
val * = val_race ;
to_num ( * str + + , v , false ) ;
val + = v * digit_race ;
digit_race * = digit_race_race ;
}
}
return str > bgn ;
}
bool get_limit ( const char * & str , std : : string & l , std : : string & r )
{
// set l = "a", r = "b" in text "[a, b]"
bool ret = * str = = ' [ ' ;
if ( ret )
{
str + + ;
skip_space ( str ) ;
l = str ;
size_t pos = l . find ( " ] " ) ;
if ( pos = = - 1 )
return false ;
l . erase ( pos ) ;
pos = l . find ( " , " ) ;
if ( pos = = - 1 )
return false ;
r = l . substr ( pos + 1 ) ;
l . erase ( pos ) ;
}
return ret ;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2023-05-13 08:26:43 +00:00
// fixed id map
static void init_fixed_id ( const char * name , int id , std : : map < sane_option_id , int > & mapid )
{
# define TRY_MATCH(n, m) \
if ( strcmp ( SANE_STD_OPT_NAME_ # # n , name ) = = 0 ) \
{ \
mapid [ SANE_OPT_ID_ # # n ] = id ; \
return ; \
}
TRY_MATCH ( IS_MULTI_OUT ) ;
TRY_MATCH ( MULTI_OUT_TYPE ) ;
TRY_MATCH ( COLOR_MODE ) ;
TRY_MATCH ( FILTER ) ;
TRY_MATCH ( RID_MULTIOUT_RED ) ;
TRY_MATCH ( RID_ANSWER_SHEET_RED ) ;
TRY_MATCH ( ERASE_BACKGROUND ) ;
TRY_MATCH ( BKG_COLOR_RANGE ) ;
TRY_MATCH ( SHARPEN ) ;
TRY_MATCH ( RID_MORR ) ;
TRY_MATCH ( RID_GRID ) ;
TRY_MATCH ( ERROR_EXTENSION ) ;
TRY_MATCH ( NOISE_OPTIMIZE ) ;
TRY_MATCH ( NOISE_SIZE ) ;
TRY_MATCH ( PAPER ) ;
TRY_MATCH ( CUSTOM_AREA ) ;
TRY_MATCH ( CUSTOM_AREA_LEFT ) ;
TRY_MATCH ( CUSTOM_AREA_RIGHT ) ;
TRY_MATCH ( CUSTOM_AREA_TOP ) ;
TRY_MATCH ( CUSTOM_AREA_BOTTOM ) ;
TRY_MATCH ( SIZE_CHECK ) ;
TRY_MATCH ( PAGE ) ;
TRY_MATCH ( DISCARD_BLANK_SENS ) ;
TRY_MATCH ( RESOLUTION ) ;
TRY_MATCH ( IMAGE_QUALITY ) ;
TRY_MATCH ( EXCHANGE ) ;
TRY_MATCH ( SPLIT ) ;
TRY_MATCH ( ANTI_SKEW ) ;
TRY_MATCH ( IS_CUSTOM_GAMMA ) ;
TRY_MATCH ( BRIGHTNESS ) ;
TRY_MATCH ( CONTRAST ) ;
TRY_MATCH ( GAMMA ) ;
TRY_MATCH ( ERASE_BLACK_FRAME ) ;
TRY_MATCH ( DARK_SAMPLE ) ;
TRY_MATCH ( THRESHOLD ) ;
TRY_MATCH ( ANTI_NOISE_LEVEL ) ;
TRY_MATCH ( MARGIN ) ;
TRY_MATCH ( FILL_BKG_MODE ) ;
TRY_MATCH ( IS_ANTI_PERMEATE ) ;
TRY_MATCH ( ANTI_PERMEATE_LEVEL ) ;
TRY_MATCH ( RID_HOLE ) ;
TRY_MATCH ( SEARCH_HOLE_RANGE ) ;
TRY_MATCH ( IS_FILL_COLOR ) ;
TRY_MATCH ( IS_ULTROSONIC_CHECK ) ;
TRY_MATCH ( IS_CHECK_STAPLE ) ;
TRY_MATCH ( SCAN_MODE ) ;
TRY_MATCH ( SCAN_COUNT ) ;
TRY_MATCH ( TEXT_DIRECTION ) ;
TRY_MATCH ( IS_ROTATE_BKG_180 ) ;
TRY_MATCH ( IS_CHECK_DOG_EAR ) ;
TRY_MATCH ( DOG_EAR_SIZE ) ;
TRY_MATCH ( IS_CHECK_ASKEW ) ;
TRY_MATCH ( ASKEW_RANGE ) ;
TRY_MATCH ( BINARY_THRESHOLD ) ;
TRY_MATCH ( IS_PHOTO_MODE ) ;
TRY_MATCH ( DOUBLE_FEED_HANDLE ) ;
TRY_MATCH ( WAIT_TO_SCAN ) ;
TRY_MATCH ( FEED_STRENGTH ) ;
TRY_MATCH ( TIME_TO_SLEEP ) ;
TRY_MATCH ( IS_AUTO_FEED_STRENGTH ) ;
TRY_MATCH ( FEED_STRENGTH_VALUE ) ;
TRY_MATCH ( REVERSE_01 ) ;
TRY_MATCH ( RID_HOLE_L ) ;
TRY_MATCH ( SEARCH_HOLE_RANGE_L ) ;
TRY_MATCH ( RID_HOLE_R ) ;
TRY_MATCH ( SEARCH_HOLE_RANGE_R ) ;
TRY_MATCH ( RID_HOLE_T ) ;
TRY_MATCH ( SEARCH_HOLE_RANGE_T ) ;
TRY_MATCH ( RID_HOLE_B ) ;
TRY_MATCH ( SEARCH_HOLE_RANGE_B ) ;
TRY_MATCH ( FOLD_TYPE ) ;
TRY_MATCH ( COLOR_CORRECTION ) ;
//TRY_MATCH(HISTORY_COUNT);
//TRY_MATCH(DRIVER_VERSION);
//TRY_MATCH(MANUFACTURER);
//TRY_MATCH(COPYRIGHT);
//TRY_MATCH(CO_URL);
//TRY_MATCH(CO_TEL);
//TRY_MATCH(CO_ADDR);
//TRY_MATCH(CO_GPS);
//TRY_MATCH(HELP);
//TRY_MATCH(VID);
//TRY_MATCH(PID);
//TRY_MATCH(DEV_NAME);
//TRY_MATCH(DEV_FAMILY);
//TRY_MATCH(LOGIN);
//TRY_MATCH(LOGOUT);
//TRY_MATCH(ROLLER_COUNT);
//TRY_MATCH(DRIVER_LOG);
//TRY_MATCH(DEVICE_LOG);
}
static std : : string un_json_option_name ( int id )
{
# define FIX_ID_TO_NAME(fid) \
if ( id = = SANE_OPT_ID_ # # fid ) \
return SANE_STD_OPT_NAME_ # # fid ;
FIX_ID_TO_NAME ( HISTORY_COUNT ) ;
FIX_ID_TO_NAME ( DRIVER_VERSION ) ;
FIX_ID_TO_NAME ( MANUFACTURER ) ;
FIX_ID_TO_NAME ( COPYRIGHT ) ;
FIX_ID_TO_NAME ( CO_URL ) ;
FIX_ID_TO_NAME ( CO_TEL ) ;
FIX_ID_TO_NAME ( CO_ADDR ) ;
FIX_ID_TO_NAME ( CO_GPS ) ;
FIX_ID_TO_NAME ( VID ) ;
FIX_ID_TO_NAME ( PID ) ;
FIX_ID_TO_NAME ( DEV_NAME ) ;
FIX_ID_TO_NAME ( DEV_FAMILY ) ;
FIX_ID_TO_NAME ( ROLLER_COUNT ) ;
FIX_ID_TO_NAME ( HELP ) ;
2023-05-16 08:42:07 +00:00
FIX_ID_TO_NAME ( LOGIN ) ;
FIX_ID_TO_NAME ( LOGOUT ) ;
FIX_ID_TO_NAME ( DRIVER_LOG ) ;
FIX_ID_TO_NAME ( DEVICE_LOG ) ;
2023-05-13 08:26:43 +00:00
2023-05-16 03:44:48 +00:00
FIX_ID_TO_NAME ( DEVICE_SERIAL_NO ) ;
FIX_ID_TO_NAME ( FIRMWARE_VERSION ) ;
FIX_ID_TO_NAME ( DEVICE_IP_ADDR ) ;
FIX_ID_TO_NAME ( DEVICE_MAC_ADDR ) ;
2023-05-13 08:26:43 +00:00
return " " ;
}
2022-05-03 03:56:07 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static sane_callback cb_ui_ = NULL ;
static void * cb_ui_parm_ = NULL ;
static SANE_Auth_Callback cb_auth_ = NULL ;
2022-05-09 06:48:42 +00:00
static std : : mutex cb_lock_ ;
2022-05-03 03:56:07 +00:00
static std : : string sane_event ( SANE_Event ev )
{
RETURN_IF ( ev , SANE_EVENT_NONE ) ;
RETURN_IF ( ev , SANE_EVENT_SUPPORT_ASYNC_IO ) ;
RETURN_IF ( ev , SANE_EVENT_IS_MEMORY_ENOUGH ) ;
RETURN_IF ( ev , SANE_EVENT_NEED_AUTH ) ;
RETURN_IF ( ev , SANE_EVENT_DEVICE_ARRIVED ) ;
RETURN_IF ( ev , SANE_EVENT_DEVICE_LEFT ) ;
RETURN_IF ( ev , SANE_EVENT_STATUS ) ;
RETURN_IF ( ev , SANE_EVENT_ERROR ) ;
RETURN_IF ( ev , SANE_EVENT_WORKING ) ;
RETURN_IF ( ev , SANE_EVENT_IMAGE_OK ) ;
RETURN_IF ( ev , SANE_EVENT_SCAN_FINISHED ) ;
RETURN_IF ( ev , SANE_EVENT_ABOUT_INFORMATION ) ;
RETURN_IF ( ev , SANE_EVENT_SCANNER_CLOSED ) ;
char unk [ 20 ] ;
sprintf ( unk , " %d " , ev ) ;
return unk ;
}
int ui_cb ( scanner_handle dev , int code , void * data , unsigned int * len , void * unused )
{
2022-11-18 08:05:39 +00:00
sane_callback cb_ui = NULL ;
void * cb_ui_parm = NULL ;
SANE_Auth_Callback cb_auth = NULL ;
{
std : : lock_guard < std : : mutex > lck ( cb_lock_ ) ;
cb_ui = cb_ui_ ;
cb_ui_parm = cb_ui_parm_ ;
cb_auth_ = cb_auth ;
}
2022-05-09 06:48:42 +00:00
2022-05-03 03:56:07 +00:00
if ( SANE_EVENT_SUPPORT_ASYNC_IO = = code )
2022-05-17 07:04:55 +00:00
return cb_ui_ ? SCANNER_ERR_OK : SCANNER_ERR_DEVICE_NOT_SUPPORT ;
2022-05-03 03:56:07 +00:00
SANE_Handle h = hg_sane_middleware : : scanner_handle_to_sane ( dev ) ;
2022-11-10 02:02:52 +00:00
// VLOG_MINI_1(LOG_LEVEL_ALL, "sane callback invoked of event %s\n", sane_event((SANE_Event)code).c_str());
2022-05-03 03:56:07 +00:00
2022-11-18 08:05:39 +00:00
if ( cb_ui )
2022-05-03 03:56:07 +00:00
{
2022-11-18 08:05:39 +00:00
return cb_ui ( h , code , data , len , cb_ui_parm ) ;
2022-05-03 03:56:07 +00:00
}
2022-11-18 08:05:39 +00:00
else if ( cb_auth & & code = = SANE_EVENT_NEED_AUTH )
2022-05-03 03:56:07 +00:00
{
SANEAUTH * auth = ( SANEAUTH * ) data ;
2022-11-18 08:05:39 +00:00
cb_auth ( auth - > resource , auth - > name , auth - > pwd ) ;
2022-05-03 03:56:07 +00:00
}
return 0 ;
}
void get_version ( SANE_Int * version_code )
{
if ( version_code )
* version_code = SANE_VERSION_CODE ( SANE_CURRENT_MAJOR , SANE_CURRENT_MINOR , VERSION_BUILD ) ; // leading-char '1' is used for avoid compiler considering '0118' as an octal number :)
}
2022-06-18 00:55:15 +00:00
void set_callback ( sane_callback cb , void * param )
{
std : : lock_guard < std : : mutex > lck ( cb_lock_ ) ;
cb_ui_ = cb ;
cb_ui_parm_ = param ;
}
2022-05-03 03:56:07 +00:00
void stop_work ( void )
{
2022-05-09 06:48:42 +00:00
std : : lock_guard < std : : mutex > lck ( cb_lock_ ) ;
2022-05-03 03:56:07 +00:00
cb_ui_ = NULL ;
cb_ui_parm_ = NULL ;
cb_auth_ = NULL ;
}
2023-01-31 08:23:21 +00:00
static void trans_language_if_was_word_id ( std : : string & val )
{
size_t pos = val . find ( " . " ) ;
if ( pos ! = std : : string : : npos )
{
bool num = true ;
for ( size_t i = pos + 1 ; i < val . length ( ) ; + + i )
{
if ( val [ i ] ! = ' 0 ' )
{
num = false ;
break ;
}
}
if ( num & & std : : to_string ( atoi ( val . c_str ( ) ) ) = = val . substr ( 0 , pos ) )
{
val = lang_load_string ( atoi ( val . c_str ( ) ) , nullptr ) ;
}
}
}
2022-05-03 03:56:07 +00:00
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
hg_sane_middleware * hg_sane_middleware : : inst_ = NULL ;
const SANE_Device * * hg_sane_middleware : : dev_list_ = NULL ;
2023-01-28 07:19:10 +00:00
hg_sane_middleware : : hg_sane_middleware ( void ) : opt_0_ ( nullptr ) , init_ok_ ( false )
2022-05-03 03:56:07 +00:00
{
2023-01-19 07:43:59 +00:00
if ( lang_initialize ( ) = = - 1 )
{
return ;
}
2022-05-30 03:04:26 +00:00
char sane_ver [ 40 ] = { 0 } ;
2023-01-19 07:43:59 +00:00
init_ok_ = true ;
2022-05-30 03:04:26 +00:00
sprintf ( sane_ver , " %u.%u.%u " , SANE_CURRENT_MAJOR , SANE_CURRENT_MINOR , VERSION_BUILD ) ;
2022-05-03 03:56:07 +00:00
signal ( SIGUSR1 , & hg_sane_middleware : : device_pnp ) ;
2022-07-15 08:47:26 +00:00
hg_scanner_set_sane_info ( g_sane_name . c_str ( ) , sane_ver ) ;
2022-05-03 03:56:07 +00:00
hg_scanner_initialize ( local_utility : : ui_cb , NULL ) ;
2022-05-30 09:36:42 +00:00
2023-02-01 03:11:11 +00:00
if ( lang_get_cur_code_page ( ) ! = DEFAULT_CODE_PAGE )
lang_refresh_language ( ) ;
register_language_changed_notify ( & hg_sane_middleware : : language_changed , true ) ;
2022-07-19 01:40:30 +00:00
# if !defined(WIN32) && !defined(_WIN64)
2022-05-30 09:36:42 +00:00
char path [ 512 ] = { 0 } ;
size_t pos = 0 ;
2022-06-01 03:04:10 +00:00
g_sane_path = get_file_path ( ( std : : string ( GET_BACKEND_NAME ) + " .so " ) . c_str ( ) , path ) ;
pos = g_sane_path . rfind ( ' / ' ) ;
2022-05-30 09:36:42 +00:00
if ( pos + + ! = std : : string : : npos )
2022-06-01 03:04:10 +00:00
g_sane_path . erase ( pos ) ;
2022-05-30 09:36:42 +00:00
# endif
2022-05-03 03:56:07 +00:00
}
hg_sane_middleware : : ~ hg_sane_middleware ( )
{
2023-01-19 07:43:59 +00:00
register_language_changed_notify ( & hg_sane_middleware : : language_changed , false ) ;
2023-01-28 07:19:10 +00:00
for ( size_t i = 0 ; i < openning_ . size ( ) ; + + i )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
hg_scanner_close ( openning_ [ i ] - > dev , true ) ;
hg_sane_middleware : : free_device_inst ( openning_ [ i ] ) ;
2022-05-03 03:56:07 +00:00
}
hg_scanner_uninitialize ( ) ;
2022-05-20 06:46:25 +00:00
if ( opt_0_ )
local_utility : : free_memory ( opt_0_ ) ;
2022-05-03 03:56:07 +00:00
}
2023-01-19 07:43:59 +00:00
void hg_sane_middleware : : language_changed ( int cp , void * param )
{
2023-01-29 07:01:38 +00:00
for ( auto & v : hg_sane_middleware : : instance ( ) - > openning_ )
hg_sane_middleware : : free_device_inst ( v , false ) ;
2023-01-19 07:43:59 +00:00
}
2022-05-17 07:04:55 +00:00
const SANE_Device * * hg_sane_middleware : : to_sane_device ( ScannerInfo * hgscanner , int count )
2022-05-03 03:56:07 +00:00
{
// 将多级指针安排在一个连续的内存空间存放
SANE_Device * * ret = NULL , * dev = NULL ;
SANE_String val = NULL ;
unsigned long bytes = ( count + 1 ) * ( sizeof ( SANE_Device ) + sizeof ( SANE_Device * ) ) , total = 0 ;
// calculate space ...
for ( int i = 0 ; i < count ; + + i )
{
bytes + = ALIGN_INT ( strlen ( hgscanner [ i ] . name ) + 1 ) ;
bytes + = ALIGN_INT ( strlen ( hgscanner [ i ] . vendor ) + 1 ) ;
bytes + = ALIGN_INT ( strlen ( hgscanner [ i ] . model ) + 1 ) ;
bytes + = ALIGN_INT ( strlen ( hgscanner [ i ] . type ) + 1 ) ;
}
bytes = ALIGN_INT ( bytes + 16 ) ;
dev = ( SANE_Device * ) local_utility : : acquire_memory ( bytes , " hg_sane_middleware::to_sane_device " ) ;
total = bytes ;
if ( ! dev )
return NULL ;
memset ( dev , 0 , bytes ) ;
ret = ( SANE_Device * * ) dev ;
dev = ( SANE_Device * ) ( ( SANE_Device * * ) dev + count + 1 ) ;
val = ( SANE_String ) ( dev + count ) ;
# define COPY_DEVICE_MEMBER(m) \
dev - > m = val ; \
strcpy ( val , hgscanner [ i ] . m ) ; \
bytes = ALIGN_INT ( strlen ( val ) + 1 ) ; \
val + = bytes ;
for ( int i = 0 ; i < count ; + + i , + + dev )
{
ret [ i ] = dev ;
COPY_DEVICE_MEMBER ( name ) ;
COPY_DEVICE_MEMBER ( vendor ) ;
COPY_DEVICE_MEMBER ( model ) ;
COPY_DEVICE_MEMBER ( type ) ;
}
2022-05-30 03:04:26 +00:00
//VLOG_MINI_2(LOG_LEVEL_ALL, "Memory usage: %u / %u\n", val - (char*)ret, total);
2022-05-03 03:56:07 +00:00
return ( const SANE_Device * * ) ret ;
}
void hg_sane_middleware : : free_sane_device ( SANE_Device * * dev )
{
char * mem = ( char * ) dev ;
if ( mem )
{
free ( mem ) ;
}
}
void hg_sane_middleware : : device_pnp ( int sig )
{
2022-05-30 03:04:26 +00:00
VLOG_MINI_1 ( LOG_LEVEL_DEBUG_INFO , " Device list changed (%d)... " , sig ) ;
2022-05-03 03:56:07 +00:00
}
SANE_Fixed hg_sane_middleware : : double_2_sane_fixed ( double v )
{
return SANE_FIX ( v ) ;
}
double hg_sane_middleware : : sane_fixed_2_double ( SANE_Fixed v )
{
return SANE_UNFIX ( v ) ;
}
2023-01-28 07:19:10 +00:00
void hg_sane_middleware : : set_value_to_var ( void * val , size_t bytes , void * param )
{
memcpy ( param , val , bytes ) ;
}
void hg_sane_middleware : : set_value_to_new ( void * val , size_t bytes , void * param )
{
void * * addr = ( void * * ) param ;
* addr = local_utility : : acquire_memory ( bytes , " set_value_to_new " ) ;
memcpy ( * addr , val , bytes ) ;
}
2022-05-03 03:56:07 +00:00
std : : string hg_sane_middleware : : option_value_2_string ( SANE_Value_Type type , void * val )
{
std : : string ret ( " unknown " ) ;
char buf [ 40 ] ;
switch ( type )
{
case SANE_TYPE_BOOL :
ret = * ( SANE_Bool * ) val ? " true " : " false " ;
break ;
case SANE_TYPE_INT :
2022-05-09 06:48:42 +00:00
sprintf ( buf , " %d " , * ( SANE_Word * ) val ) ;
2022-05-03 03:56:07 +00:00
ret = buf ;
break ;
case SANE_TYPE_FIXED :
2022-05-09 06:48:42 +00:00
sprintf ( buf , " %f " , hg_sane_middleware : : sane_fixed_2_double ( * ( SANE_Word * ) val ) ) ;
2022-05-03 03:56:07 +00:00
ret = buf ;
break ;
case SANE_TYPE_STRING :
ret = ( char * ) val ;
break ;
case SANE_TYPE_BUTTON :
ret = " Button " ;
break ;
case SANE_TYPE_GROUP :
ret = " Group " ;
break ;
default :
break ;
}
return ret ;
}
scanner_handle hg_sane_middleware : : sane_handle_to_scanner ( SANE_Handle h )
{
2023-01-28 07:19:10 +00:00
if ( ! h )
return nullptr ;
2022-05-03 03:56:07 +00:00
int bits = sizeof ( h ) / 2 * 8 ;
2023-01-28 07:19:10 +00:00
uint64_t v = ( uint64_t ) h ;
2022-05-03 03:56:07 +00:00
v ^ = v > > bits ;
return ( scanner_handle ) ( v ) ;
}
SANE_Handle hg_sane_middleware : : scanner_handle_to_sane ( scanner_handle h )
{
2023-01-28 07:19:10 +00:00
if ( ! h )
return nullptr ;
2022-05-03 03:56:07 +00:00
int bits = sizeof ( h ) / 2 * 8 ;
2023-01-28 07:19:10 +00:00
uint64_t v = ( uint64_t ) h ;
2022-05-03 03:56:07 +00:00
v ^ = v > > bits ;
return ( SANE_Handle ) ( v ) ;
}
SANE_Option_Descriptor * hg_sane_middleware : : string_option_to_SANE_descriptor ( const char * name , const char * title , const char * desc
, const std : : vector < std : : string > & values )
{
int bytes = sizeof ( SANE_Option_Descriptor ) + sizeof ( char * ) ;
SANE_Option_Descriptor * sod = NULL ;
char * str = NULL , * * str_arr = NULL ;
bytes + = ALIGN_INT ( strlen ( name ) + 1 ) ;
bytes + = ALIGN_INT ( strlen ( title ) + 1 ) ;
bytes + = ALIGN_INT ( strlen ( desc ) + 1 ) ;
bytes + = sizeof ( SANE_Option_Descriptor ) ;
bytes + = sizeof ( char * ) ;
for ( size_t i = 0 ; i < values . size ( ) ; + + i )
bytes + = ALIGN_INT ( values [ i ] . length ( ) + 1 ) ;
bytes + = sizeof ( char * ) * ( values . size ( ) + 1 ) ;
sod = ( SANE_Option_Descriptor * ) local_utility : : acquire_memory ( bytes , " hg_sane_middleware::string_option_to_SANE_descriptor " ) ;
bzero ( sod , bytes ) ;
str = ( char * ) sod ;
str + = sizeof ( SANE_Option_Descriptor ) ;
sod - > name = str ;
strcpy ( str , name ) ;
str + = ALIGN_INT ( strlen ( str ) + 1 ) ;
sod - > title = str ;
strcpy ( str , title ) ;
str + = ALIGN_INT ( strlen ( str ) + 1 ) ;
sod - > desc = str ;
strcpy ( str , desc ) ;
str + = ALIGN_INT ( strlen ( str ) + 1 ) ;
sod - > type = SANE_TYPE_STRING ;
sod - > unit = SANE_UNIT_NONE ;
sod - > size = values . size ( ) ;
sod - > cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT // 软件可设置选项
2023-02-18 02:26:38 +00:00
| SANE_CAP_AUTOMATIC ; // 硬件可设置默认<E9BB98> ?
2022-05-03 03:56:07 +00:00
if ( values . size ( ) )
{
sod - > constraint_type = SANE_CONSTRAINT_STRING_LIST ;
sod - > constraint . string_list = ( char * * ) str ;
str_arr = ( char * * ) str ;
str + = ( values . size ( ) + 1 ) * sizeof ( char * ) ;
for ( size_t i = 0 ; i < values . size ( ) ; + + i )
{
str_arr [ i ] = str ;
strcpy ( str , values [ i ] . c_str ( ) ) ;
str + = ALIGN_INT ( values [ i ] . length ( ) + 1 ) ;
}
}
2022-05-30 03:04:26 +00:00
//VLOG_MINI_2(LOG_LEVEL_ALL, "Memory usage: %u/%u\n", str - (char*)sod, bytes);
2022-05-03 03:56:07 +00:00
return sod ;
}
SANE_Option_Descriptor * hg_sane_middleware : : number_option_to_SANE_descriptor ( const char * name , const char * title , const char * desc
2022-12-31 07:44:47 +00:00
, bool double_val , double * lower , double * upper , double * step )
2022-05-03 03:56:07 +00:00
{
int bytes = sizeof ( SANE_Option_Descriptor ) + sizeof ( SANE_Range ) ;
SANE_Option_Descriptor * sod = NULL ;
char * str = NULL ;
bytes + = ALIGN_INT ( strlen ( name ) + 1 ) ;
bytes + = ALIGN_INT ( strlen ( title ) + 1 ) ;
bytes + = ALIGN_INT ( strlen ( desc ) + 1 ) ;
bytes + = sizeof ( SANE_Option_Descriptor ) ;
bytes + = sizeof ( SANE_Range * ) + sizeof ( SANE_Range ) ;
sod = ( SANE_Option_Descriptor * ) local_utility : : acquire_memory ( bytes , " hg_sane_middleware::number_option_to_SANE_descriptor " ) ;
bzero ( sod , bytes ) ;
str = ( char * ) sod ;
str + = sizeof ( SANE_Option_Descriptor ) ;
sod - > name = str ;
strcpy ( str , name ) ;
str + = ALIGN_INT ( strlen ( str ) + 1 ) ;
sod - > title = str ;
strcpy ( str , title ) ;
str + = ALIGN_INT ( strlen ( str ) + 1 ) ;
sod - > desc = str ;
strcpy ( str , desc ) ;
str + = ALIGN_INT ( strlen ( str ) + 1 ) ;
sod - > type = double_val ? SANE_TYPE_FIXED : SANE_TYPE_INT ;
sod - > unit = SANE_UNIT_NONE ;
sod - > size = sizeof ( SANE_Word ) ;
2022-07-18 02:54:41 +00:00
sod - > cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT
2023-05-13 08:26:43 +00:00
| SANE_CAP_AUTOMATIC ;
2022-05-03 03:56:07 +00:00
if ( lower | | upper )
{
sod - > size = sizeof ( SANE_Range ) ;
sod - > constraint_type = SANE_CONSTRAINT_RANGE ;
sod - > constraint . range = ( SANE_Range * ) str ;
if ( lower )
{
if ( double_val )
( * ( SANE_Range * ) str ) . min = hg_sane_middleware : : double_2_sane_fixed ( * lower ) ;
else
2022-07-18 02:54:41 +00:00
( * ( SANE_Range * ) str ) . min = ( SANE_Word ) * lower ;
2022-05-03 03:56:07 +00:00
}
if ( upper )
{
if ( double_val )
( * ( SANE_Range * ) str ) . max = hg_sane_middleware : : double_2_sane_fixed ( * upper ) ;
else
2022-07-18 02:54:41 +00:00
( * ( SANE_Range * ) str ) . max = ( SANE_Word ) * upper ;
2022-05-03 03:56:07 +00:00
}
( * ( SANE_Range * ) str ) . quant = 0 ;
2022-12-31 07:44:47 +00:00
if ( step )
{
if ( double_val )
( * ( SANE_Range * ) str ) . quant = hg_sane_middleware : : double_2_sane_fixed ( * step ) ;
else
( * ( SANE_Range * ) str ) . quant = ( SANE_Word ) ( * step ) ;
}
2022-05-03 03:56:07 +00:00
str = ( char * ) ( ( SANE_Range * ) str + 1 ) ;
}
2022-05-30 03:04:26 +00:00
//VLOG_MINI_2(LOG_LEVEL_ALL, "Memory usage: %u/%u\n", str - (char*)sod, bytes);
2022-05-03 03:56:07 +00:00
return sod ;
}
SANE_Option_Descriptor * hg_sane_middleware : : number_option_to_SANE_descriptor ( const char * name , const char * title , const char * desc
, const std : : vector < int > & values )
{
int bytes = sizeof ( SANE_Option_Descriptor ) + sizeof ( SANE_Range ) ;
SANE_Option_Descriptor * sod = NULL ;
char * str = NULL ;
bytes + = ALIGN_INT ( strlen ( name ) + 1 ) ;
bytes + = ALIGN_INT ( strlen ( title ) + 1 ) ;
bytes + = ALIGN_INT ( strlen ( desc ) + 1 ) ;
bytes + = sizeof ( SANE_Option_Descriptor ) ;
bytes + = sizeof ( SANE_Word * ) + sizeof ( SANE_Word ) * ( values . size ( ) + 1 ) ;
sod = ( SANE_Option_Descriptor * ) local_utility : : acquire_memory ( bytes , " hg_sane_middleware::number_option_to_SANE_descriptor " ) ;
bzero ( sod , bytes ) ;
str = ( char * ) sod ;
str + = sizeof ( SANE_Option_Descriptor ) ;
sod - > name = str ;
strcpy ( str , name ) ;
str + = ALIGN_INT ( strlen ( str ) + 1 ) ;
sod - > title = str ;
strcpy ( str , title ) ;
str + = ALIGN_INT ( strlen ( str ) + 1 ) ;
sod - > desc = str ;
strcpy ( str , desc ) ;
str + = ALIGN_INT ( strlen ( str ) + 1 ) ;
sod - > type = SANE_TYPE_INT ;
sod - > unit = SANE_UNIT_NONE ;
sod - > size = sizeof ( SANE_Word ) ;
sod - > cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT // 软件可设置选项
2023-05-13 08:26:43 +00:00
| SANE_CAP_AUTOMATIC ; // 硬件可设置默认<E9BB98> ?
2022-05-03 03:56:07 +00:00
if ( values . size ( ) )
{
SANE_Word * val = ( SANE_Word * ) str ;
sod - > constraint . word_list = val ;
sod - > constraint_type = SANE_CONSTRAINT_WORD_LIST ;
* val + + = values . size ( ) ;
for ( size_t i = 0 ; i < values . size ( ) ; + + i )
val [ i ] = values [ i ] ;
str = ( char * ) ( val + values . size ( ) ) ;
}
2022-05-30 03:04:26 +00:00
//VLOG_MINI_2(LOG_LEVEL_ALL, "Memory usage: %u/%u\n", str - (char*)sod, bytes);
2022-05-03 03:56:07 +00:00
return sod ;
}
SANE_Option_Descriptor * hg_sane_middleware : : number_option_to_SANE_descriptor ( const char * name , const char * title , const char * desc
, const std : : vector < double > & values )
{
int bytes = sizeof ( SANE_Option_Descriptor ) + sizeof ( SANE_Range ) ;
SANE_Option_Descriptor * sod = NULL ;
char * str = NULL ;
bytes + = ALIGN_INT ( strlen ( name ) + 1 ) ;
bytes + = ALIGN_INT ( strlen ( title ) + 1 ) ;
bytes + = ALIGN_INT ( strlen ( desc ) + 1 ) ;
bytes + = sizeof ( SANE_Option_Descriptor ) ;
bytes + = sizeof ( SANE_Word * ) + sizeof ( SANE_Word ) * ( values . size ( ) + 1 ) ;
sod = ( SANE_Option_Descriptor * ) local_utility : : acquire_memory ( bytes , " hg_sane_middleware::number_option_to_SANE_descriptor " ) ;
bzero ( sod , bytes ) ;
str = ( char * ) sod ;
str + = sizeof ( SANE_Option_Descriptor ) ;
sod - > name = str ;
strcpy ( str , name ) ;
str + = ALIGN_INT ( strlen ( str ) + 1 ) ;
sod - > title = str ;
strcpy ( str , title ) ;
str + = ALIGN_INT ( strlen ( str ) + 1 ) ;
sod - > desc = str ;
strcpy ( str , desc ) ;
str + = ALIGN_INT ( strlen ( str ) + 1 ) ;
sod - > type = SANE_TYPE_FIXED ;
sod - > unit = SANE_UNIT_NONE ;
sod - > size = sizeof ( SANE_Word ) ;
sod - > cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT // 软件可设置选项
2023-05-13 08:26:43 +00:00
| SANE_CAP_AUTOMATIC ; // 硬件可设置默认<E9BB98> ?
2022-05-03 03:56:07 +00:00
if ( values . size ( ) )
{
SANE_Word * val = ( SANE_Word * ) str ;
sod - > constraint . word_list = val ;
sod - > constraint_type = SANE_CONSTRAINT_WORD_LIST ;
* val + + = values . size ( ) ;
for ( size_t i = 0 ; i < values . size ( ) ; + + i )
val [ i ] = hg_sane_middleware : : double_2_sane_fixed ( values [ i ] ) ;
str = ( char * ) ( val + values . size ( ) ) ;
}
2022-05-30 03:04:26 +00:00
//VLOG_MINI_2(LOG_LEVEL_ALL, "Memory usage: %u/%u\n", str - (char*)sod, bytes);
2022-05-03 03:56:07 +00:00
return sod ;
}
2023-01-28 07:19:10 +00:00
std : : string hg_sane_middleware : : get_string_in_json ( json * jsn , const char * key )
2022-05-18 09:41:05 +00:00
{
2023-01-28 07:19:10 +00:00
std : : string str ( " " ) ;
int id = - 1 ;
if ( jsn - > get_value ( key , id ) & & id ! = - 1 )
2022-05-18 09:41:05 +00:00
{
2023-01-28 07:19:10 +00:00
str = lang_load_string ( id , & id ) ;
2022-05-18 09:41:05 +00:00
}
2023-01-28 07:19:10 +00:00
else
jsn - > get_value ( key , str ) ;
return std : : move ( str ) ;
}
std : : string hg_sane_middleware : : sane_path ( void )
{
return g_sane_path ;
}
hg_sane_middleware * hg_sane_middleware : : instance ( void )
{
if ( ! hg_sane_middleware : : inst_ )
hg_sane_middleware : : inst_ = new hg_sane_middleware ( ) ;
return hg_sane_middleware : : inst_ ;
}
void hg_sane_middleware : : set_callback ( sane_callback cb , void * param )
{
local_utility : : set_callback ( cb , param ) ;
}
void hg_sane_middleware : : clear ( void )
{
local_utility : : stop_work ( ) ;
if ( hg_sane_middleware : : inst_ )
2022-05-18 09:41:05 +00:00
{
2023-01-28 07:19:10 +00:00
delete hg_sane_middleware : : inst_ ;
hg_sane_middleware : : inst_ = NULL ;
2022-05-18 09:41:05 +00:00
}
}
2023-01-28 07:19:10 +00:00
2022-05-03 03:56:07 +00:00
SANE_Status hg_sane_middleware : : open ( SANE_String_Const devicename , SANE_Handle * handle , const char * name , const char * pwd , const char * method , char * rsc )
{
scanner_handle h = NULL ;
2022-05-17 07:04:55 +00:00
scanner_err err = SCANNER_ERR_OK ;
2022-05-03 03:56:07 +00:00
if ( handle = = NULL )
return SANE_STATUS_INVAL ;
err = hg_scanner_open ( & h , devicename , false , NULL , NULL , NULL , rsc ) ;
2022-05-17 07:04:55 +00:00
if ( err = = SCANNER_ERR_OK )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
LPDEVINST inst = new DEVINST ;
2022-05-03 03:56:07 +00:00
2023-01-28 07:19:10 +00:00
inst - > name = devicename ;
inst - > dev = h ;
openning_ . push_back ( inst ) ;
2022-05-03 03:56:07 +00:00
* handle = hg_sane_middleware : : scanner_handle_to_sane ( h ) ;
2022-05-23 03:52:53 +00:00
if ( ! local_utility : : cb_ui_ )
{
long count = 0 ;
hg_scanner_get_parameter ( h , 0 , NULL , & count ) ;
2023-01-28 07:19:10 +00:00
inst - > std_opt = new sane_std_opts ( count ) ;
2022-05-23 03:52:53 +00:00
}
2022-05-03 03:56:07 +00:00
return SANE_STATUS_GOOD ;
}
2022-05-17 07:04:55 +00:00
else if ( err = = SCANNER_ERR_ACCESS_DENIED )
2022-05-03 03:56:07 +00:00
{
return SANE_STATUS_ACCESS_DENIED ;
}
else
2022-09-22 08:23:16 +00:00
return ( SANE_Status ) err ; // SANE_STATUS_UNSUPPORTED;
2022-05-03 03:56:07 +00:00
}
2023-01-28 07:19:10 +00:00
SANE_Option_Descriptor * hg_sane_middleware : : from_json ( scanner_handle h , const std : : string & name , json * jsn )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
std : : string title ( hg_sane_middleware : : get_string_in_json ( jsn , " title " ) ) ,
desc ( hg_sane_middleware : : get_string_in_json ( jsn , " desc " ) ) ,
val ( " " ) ;
2022-05-03 03:56:07 +00:00
std : : vector < std : : string > constraints ;
2022-12-31 07:44:47 +00:00
double lower = .0f , upper = .0f , step = .0f ;
2022-05-03 03:56:07 +00:00
bool db_val = false ;
if ( ! jsn - > get_value ( " type " , val ) )
return NULL ;
SANE_Option_Descriptor * ret = NULL ;
if ( val = = " string " )
{
json * range = NULL ;
std : : vector < std : : string > constraints ;
jsn - > get_value ( " range " , range ) ;
if ( range )
{
if ( range - > first_child ( val ) )
{
2023-01-28 07:19:10 +00:00
size_t pos = val . find ( " . " ) ;
if ( pos ! = std : : string : : npos )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
for ( size_t i = val . length ( ) - 1 ; i > pos ; - - i )
{
if ( val [ i ] ! = ' 0 ' )
{
pos = i + 1 ;
break ;
}
}
val . erase ( pos ) ;
}
if ( std : : to_string ( atoi ( val . c_str ( ) ) ) = = val )
constraints . push_back ( lang_load_string ( atoi ( val . c_str ( ) ) , ( int * ) & lower ) ) ;
else
2022-05-30 03:04:26 +00:00
constraints . push_back ( val ) ;
2023-01-28 07:19:10 +00:00
while ( range - > next_child ( val ) )
{
2023-01-31 08:23:21 +00:00
local_utility : : trans_language_if_was_word_id ( val ) ;
constraints . push_back ( val ) ;
2022-05-03 03:56:07 +00:00
}
}
delete range ;
}
ret = hg_sane_middleware : : string_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
, constraints ) ;
}
else if ( val = = " int " | | val = = " float " )
{
json * range = NULL ;
jsn - > get_value ( " range " , range ) ;
if ( range )
{
if ( val = = " int " )
{
int l = 0 ;
if ( range - > get_value ( " min " , l ) )
{
2022-12-31 07:44:47 +00:00
int u = 0 , s = 1 ;
2022-05-03 03:56:07 +00:00
range - > get_value ( " max " , u ) ;
2022-12-31 07:44:47 +00:00
range - > get_value ( " step " , s ) ;
2022-05-03 03:56:07 +00:00
lower = l ;
upper = u ;
2022-12-31 07:44:47 +00:00
step = s ;
2023-01-28 07:19:10 +00:00
VLOG_MINI_4 ( LOG_LEVEL_DEBUG_INFO , " %s range: [%d, +%d, %d] \n " , name . c_str ( ) , l , s , u ) ;
2022-05-03 03:56:07 +00:00
ret = hg_sane_middleware : : number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
2022-12-31 07:44:47 +00:00
, false , & lower , & upper , & step ) ;
2022-05-03 03:56:07 +00:00
}
else
{
std : : vector < int > constraints ;
if ( range - > first_child ( val ) )
{
constraints . push_back ( atoi ( val . c_str ( ) ) ) ;
while ( range - > next_child ( val ) )
{
constraints . push_back ( atoi ( val . c_str ( ) ) ) ;
}
}
ret = hg_sane_middleware : : number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
, constraints ) ;
}
}
else
{
if ( range - > get_value ( " min " , lower ) )
{
range - > get_value ( " max " , upper ) ;
2022-12-31 07:44:47 +00:00
step = ( upper - lower ) / 10.0f ;
range - > get_value ( " step " , step ) ;
2023-01-28 07:19:10 +00:00
VLOG_MINI_4 ( LOG_LEVEL_DEBUG_INFO , " %s range: (%f, +%f, %f) \n " , name . c_str ( ) , lower , step , upper ) ;
2022-05-03 03:56:07 +00:00
ret = hg_sane_middleware : : number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
2022-12-31 07:44:47 +00:00
, true , & lower , & upper , & step ) ;
2022-05-03 03:56:07 +00:00
}
else
{
std : : vector < double > constraints ;
if ( range - > first_child ( val ) )
{
constraints . push_back ( atof ( val . c_str ( ) ) ) ;
while ( range - > next_child ( val ) )
{
constraints . push_back ( atof ( val . c_str ( ) ) ) ;
}
}
ret = hg_sane_middleware : : number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
, constraints ) ;
}
}
delete range ;
}
else
{
ret = hg_sane_middleware : : number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
2022-12-31 07:44:47 +00:00
, false , NULL , NULL , NULL ) ;
2022-05-03 03:56:07 +00:00
}
}
else if ( val = = " bool " )
{
ret = hg_sane_middleware : : number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
2022-12-31 07:44:47 +00:00
, false , NULL , NULL , NULL ) ;
2022-05-03 03:56:07 +00:00
ret - > type = SANE_TYPE_BOOL ;
}
else if ( val = = " button " )
{
ret = hg_sane_middleware : : number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
2022-12-31 07:44:47 +00:00
, false , NULL , NULL , NULL ) ;
2022-05-03 03:56:07 +00:00
ret - > type = SANE_TYPE_BUTTON ;
}
else if ( val = = " group " )
{
ret = hg_sane_middleware : : number_option_to_SANE_descriptor ( name . c_str ( ) , title . c_str ( ) , desc . c_str ( )
2022-12-31 07:44:47 +00:00
, false , NULL , NULL , NULL ) ;
2022-05-03 03:56:07 +00:00
ret - > type = SANE_TYPE_GROUP ;
}
// fill the 'size' field, for SANE_ACTION_GET action ...
if ( ret )
{
int bytes = 0 ;
2023-05-13 08:26:43 +00:00
bool bv = false ;
2022-05-03 03:56:07 +00:00
jsn - > get_value ( " size " , bytes ) ;
ret - > size = bytes ;
2023-05-13 08:26:43 +00:00
if ( jsn - > get_value ( " readonly " , bv ) & & bv )
SET_CAP_READONLY ( ret - > cap )
2022-05-03 03:56:07 +00:00
val = " " ;
2023-05-13 08:26:43 +00:00
jsn - > get_value ( " cat " , val ) ;
2022-05-03 03:56:07 +00:00
if ( val = = " advanced " )
{
ret - > cap | = SANE_CAP_ADVANCED ;
}
2022-11-10 02:02:52 +00:00
if ( strcmp ( ret - > name , SANE_STD_OPT_NAME_RESOLUTION ) = = 0 )
2022-05-03 03:56:07 +00:00
{
ret - > unit = SANE_UNIT_DPI ;
}
2022-05-23 03:52:53 +00:00
else if ( strcmp ( ret - > name , SANE_STD_OPT_NAME_CUSTOM_AREA_LEFT ) = = 0 | |
strcmp ( ret - > name , SANE_STD_OPT_NAME_CUSTOM_AREA_RIGHT ) = = 0 | |
strcmp ( ret - > name , SANE_STD_OPT_NAME_CUSTOM_AREA_TOP ) = = 0 | |
strcmp ( ret - > name , SANE_STD_OPT_NAME_CUSTOM_AREA_BOTTOM ) = = 0 )
2022-05-06 05:37:14 +00:00
ret - > unit = SANE_UNIT_MM ;
2022-05-03 03:56:07 +00:00
//bool enabled = true;
//if (jsn->get_value("enable", enabled) && !enabled)
// ret->cap |= SANE_CAP_INACTIVE;
2023-05-13 08:26:43 +00:00
// 关联<E585B3> <E88194> ?
2022-05-03 03:56:07 +00:00
json * depend = NULL ;
SLAVEOP so ;
if ( jsn - > get_value ( " depend_or " , depend ) )
{
so . is_enable = & hg_sane_middleware : : is_enable_or ;
}
else if ( jsn - > get_value ( " depend_and " , depend ) )
{
so . is_enable = & hg_sane_middleware : : is_enable_and ;
}
if ( depend )
{
2023-01-28 07:19:10 +00:00
std : : vector < LPDEVINST > : : iterator it = find_openning_device_in_que ( h ) ;
2023-01-29 07:01:38 +00:00
if ( it ! = openning_ . end ( ) & & parse_depends ( h , depend , so , ( * it ) - > masters ) )
2022-05-03 03:56:07 +00:00
{
so . enable_now = ( ret - > cap & SANE_CAP_INACTIVE ) ! = SANE_CAP_INACTIVE ;
2022-11-10 02:02:52 +00:00
so . name = name ;
2022-05-03 03:56:07 +00:00
// initializing status ...
if ( so . master . size ( ) )
{
2023-01-31 08:23:21 +00:00
//std::string master(get_option_json(h, (void *)so.master[0].name.c_str()));
//json* m = new json();
//if (m->attach_text(&master[0]))
//{
// bool integer = false, str = false;
// master = "";
// m->get_value("type", master);
// integer = master == "int";
// str = master == "string";
// master = "";
// m->get_value_as_string("cur", master, integer);
// local_utility::trans_language_if_was_word_id(val);
2023-01-28 07:19:10 +00:00
so . enable_now = so . is_enable ( so . master , ( * it ) - > cur_vals ) ;
2022-05-03 03:56:07 +00:00
if ( ! so . enable_now )
ret - > cap | = SANE_CAP_INACTIVE ;
2023-01-31 08:23:21 +00:00
//}
//delete m;
2022-05-03 03:56:07 +00:00
}
2023-01-28 07:19:10 +00:00
( * it ) - > slaves . push_back ( so ) ;
2022-05-03 03:56:07 +00:00
}
delete depend ;
}
}
return ret ;
}
2023-01-29 07:01:38 +00:00
void hg_sane_middleware : : free_device_inst ( LPDEVINST dev , bool del )
2023-01-28 07:19:10 +00:00
{
if ( dev - > std_opt )
delete dev - > std_opt ;
for ( auto & v : dev - > opts )
local_utility : : free_memory ( v . desc ) ;
2023-01-29 07:01:38 +00:00
if ( del )
delete dev ;
else
{
dev - > opts . clear ( ) ;
dev - > cur_vals . clear ( ) ;
dev - > slaves . clear ( ) ;
dev - > masters . clear ( ) ;
}
2023-01-28 07:19:10 +00:00
}
scanner_handle hg_sane_middleware : : find_openning_device ( SANE_Handle h , bool rmv , LPDEVINST * dev )
2022-05-03 03:56:07 +00:00
{
scanner_handle handle = hg_sane_middleware : : sane_handle_to_scanner ( h ) ;
2023-01-28 07:19:10 +00:00
std : : vector < LPDEVINST > : : iterator it = find_openning_device_in_que ( handle ) ;
2022-05-03 03:56:07 +00:00
if ( it = = openning_ . end ( ) )
handle = NULL ;
else
{
if ( dev )
* dev = * it ;
if ( rmv )
2023-01-28 07:19:10 +00:00
{
if ( ! dev )
hg_sane_middleware : : free_device_inst ( * it ) ;
2022-05-03 03:56:07 +00:00
openning_ . erase ( it ) ;
2023-01-28 07:19:10 +00:00
}
2022-05-03 03:56:07 +00:00
}
return handle ;
}
2023-01-28 07:19:10 +00:00
std : : string hg_sane_middleware : : get_option_json ( scanner_handle handle , void * opt , std : : string * key , SANE_Int * id )
2022-05-03 03:56:07 +00:00
{
char * json_txt = NULL ;
long length = 0 ;
2022-11-10 02:02:52 +00:00
scanner_err err = hg_scanner_get_parameter ( handle , ( const char * ) opt , json_txt , & length ) ;
2022-05-03 03:56:07 +00:00
std : : string ret ( " " ) ;
2022-05-17 07:04:55 +00:00
if ( err = = SCANNER_ERR_INSUFFICIENT_MEMORY )
2022-05-03 03:56:07 +00:00
{
json_txt = ( char * ) local_utility : : acquire_memory ( ALIGN_INT ( length + 4 ) , " hg_sane_middleware::get_option_json " ) ;
bzero ( json_txt , length + 4 ) ;
2023-01-28 07:19:10 +00:00
err = hg_scanner_get_parameter ( handle , ( const char * ) opt , json_txt , & length , id ) ;
2022-05-17 07:04:55 +00:00
if ( err = = SCANNER_ERR_OK )
2022-05-03 03:56:07 +00:00
{
2022-11-10 02:02:52 +00:00
const char * head = json_txt ;
local_utility : : skip_space ( head ) ;
if ( * head = = ' \" ' )
{
head + + ;
while ( * head ! = ' \" ' & & * head )
ret . append ( 1 , * head + + ) ;
if ( * head )
{
head + + ;
local_utility : : skip_space ( head ) ;
if ( * head = = ' : ' )
{
head + + ;
local_utility : : skip_space ( head ) ;
}
}
}
if ( key )
* key = ret ;
ret = head ;
2022-05-03 03:56:07 +00:00
}
free ( json_txt ) ;
}
return ret ;
}
2023-01-28 07:19:10 +00:00
SANE_Option_Descriptor * hg_sane_middleware : : find_stored_descriptor ( scanner_handle handle , const void * option , SANE_Int * id )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
std : : vector < LPDEVINST > : : iterator it = find_openning_device_in_que ( handle ) ;
if ( it ! = openning_ . end ( ) )
2022-11-10 02:02:52 +00:00
{
2023-01-28 07:19:10 +00:00
if ( IS_PTR_NUMBER ( option ) )
2022-11-10 02:02:52 +00:00
{
2023-01-28 07:19:10 +00:00
if ( id )
2023-01-29 07:25:24 +00:00
* id = ( SANE_Int ) ( long long ) option ;
2023-01-28 07:19:10 +00:00
for ( const auto & v : ( * it ) - > opts )
{
2023-01-29 07:25:24 +00:00
if ( v . option_no = = ( SANE_Int ) ( long long ) option )
2023-01-28 07:19:10 +00:00
return v . desc ;
}
2022-11-10 02:02:52 +00:00
}
2023-01-28 07:19:10 +00:00
else
2022-11-10 02:02:52 +00:00
{
2023-01-28 07:19:10 +00:00
for ( const auto & v : ( * it ) - > opts )
{
if ( v . opt_name = = ( const char * ) option )
{
if ( id )
* id = v . option_no ;
return v . desc ;
}
}
2022-11-10 02:02:52 +00:00
}
2022-05-03 03:56:07 +00:00
}
return NULL ;
}
2022-11-10 02:02:52 +00:00
void hg_sane_middleware : : reload_current_value ( scanner_handle handle , std : : vector < std : : string > * changed )
2022-06-15 03:05:36 +00:00
{
long count = 0 ;
2023-01-28 07:19:10 +00:00
std : : vector < LPDEVINST > : : iterator it = find_openning_device_in_que ( handle ) ;
2022-06-15 03:05:36 +00:00
if ( changed )
changed - > clear ( ) ;
hg_scanner_get_parameter ( handle , 0 , NULL , & count ) ;
for ( int i = 1 ; i < count ; + + i )
{
2022-11-10 02:02:52 +00:00
std : : string key ( " " ) ,
2022-11-11 09:59:08 +00:00
val ( get_option_json ( handle , ( void * ) i , & key ) ) ;
2022-06-15 03:05:36 +00:00
json * jsn = new json ( ) ;
if ( jsn - > attach_text ( & val [ 0 ] ) & &
jsn - > get_value ( " type " , val ) )
{
2023-01-28 07:19:10 +00:00
if ( refresh_current_value ( * it , key . c_str ( ) , jsn ) )
2022-11-10 02:02:52 +00:00
changed - > push_back ( key ) ;
2022-06-15 03:05:36 +00:00
}
delete jsn ;
}
}
2023-01-28 07:19:10 +00:00
bool hg_sane_middleware : : get_current_value ( scanner_handle handle , const void * option , void ( * setv ) ( void * , size_t , void * ) , void * value , SANE_Value_Type * type )
2022-05-03 03:56:07 +00:00
{
2023-05-13 08:26:43 +00:00
if ( IS_PTR_NUMBER ( option ) )
{
int id = ( int ) ( uint64_t ) option ;
std : : string name ( local_utility : : un_json_option_name ( id ) ) ;
if ( ! name . empty ( ) )
{
char buf [ 256 ] = { 0 } ;
long len = sizeof ( buf ) - 1 ;
if ( hg_scanner_get_parameter ( handle , name . c_str ( ) , buf , & len ) = = SCANNER_ERR_OK )
{
setv ( buf , len , value ) ;
return true ;
}
return false ;
}
}
2022-11-10 02:02:52 +00:00
std : : string name ( " " ) ,
2022-11-11 09:59:08 +00:00
val ( get_option_json ( handle , ( void * ) option , & name ) ) ;
2022-06-15 03:05:36 +00:00
json * jsn = new json ( ) ;
2022-05-03 03:56:07 +00:00
int estimate = 20 ;
bool ret = false ;
if ( jsn - > attach_text ( & val [ 0 ] ) & &
jsn - > get_value ( " type " , val ) )
{
SANE_Value_Type t = SANE_TYPE_STRING ;
ret = true ;
2022-05-23 03:52:53 +00:00
if ( val = = " int " )
2022-05-03 03:56:07 +00:00
{
int v = 0 ;
jsn - > get_value ( " cur " , v ) ;
2023-01-28 07:19:10 +00:00
// *((SANE_Int*)value) = v;
setv ( & v , sizeof ( v ) , value ) ;
2022-05-03 03:56:07 +00:00
t = SANE_TYPE_INT ;
}
else if ( val = = " bool " )
{
2023-01-28 07:19:10 +00:00
bool bv = false ;
SANE_Bool v = SANE_FALSE ;
jsn - > get_value ( " cur " , bv ) ;
// *(SANE_Bool*)value = v;
v = bv ;
setv ( & v , sizeof ( v ) , value ) ;
2022-05-03 03:56:07 +00:00
t = SANE_TYPE_BOOL ;
}
else if ( val = = " float " )
{
2023-01-28 07:19:10 +00:00
double dv = .0f ;
SANE_Fixed v = 0 ;
jsn - > get_value ( " cur " , dv ) ;
v = hg_sane_middleware : : double_2_sane_fixed ( dv ) ;
setv ( & v , sizeof ( v ) , value ) ;
2022-05-03 03:56:07 +00:00
t = SANE_TYPE_FIXED ;
}
else
{
2023-01-28 07:19:10 +00:00
int size = 0 ;
jsn - > get_value ( " size " , size ) ;
val = hg_sane_middleware : : get_string_in_json ( jsn , " cur " ) ;
if ( size < = val . length ( ) )
size = val . length ( ) + 1 ;
//strcpy((char*)value, val.c_str());
setv ( & val [ 0 ] , size , value ) ;
2022-05-03 03:56:07 +00:00
estimate + = val . length ( ) ;
}
if ( type )
* type = t ;
2023-01-28 07:19:10 +00:00
std : : vector < LPDEVINST > : : iterator it = find_openning_device_in_que ( handle ) ;
refresh_current_value ( * it , name . c_str ( ) , jsn ) ;
2022-05-03 03:56:07 +00:00
2023-01-29 07:01:38 +00:00
val = hg_sane_middleware : : get_string_in_json ( jsn , " title " ) ;
2022-05-03 03:56:07 +00:00
2023-01-28 07:19:10 +00:00
if ( setv = = & hg_sane_middleware : : set_value_to_new )
value = * ( void * * ) value ;
2022-06-18 00:55:15 +00:00
VLOG_MINI_3 ( LOG_LEVEL_ALL , " <--Get option(%d - %s) value: %s \n " , option , val . c_str ( ) , hg_sane_middleware : : option_value_2_string ( t , value ) . c_str ( ) ) ;
2022-05-03 03:56:07 +00:00
}
delete jsn ;
return ret ;
}
2023-01-28 07:19:10 +00:00
void * hg_sane_middleware : : get_default_value ( scanner_handle handle , const void * option , int * bytes , bool log )
2022-05-20 06:46:25 +00:00
{
2022-11-11 09:59:08 +00:00
std : : string val ( get_option_json ( handle , ( void * ) option ) ) ;
2022-06-15 03:05:36 +00:00
void * data = nullptr ;
json * jsn = new json ( ) ;
2022-05-20 06:46:25 +00:00
if ( jsn - > attach_text ( & val [ 0 ] ) & &
jsn - > get_value ( " type " , val ) )
{
2023-01-29 07:01:38 +00:00
std : : string title ( hg_sane_middleware : : get_string_in_json ( jsn , " title " ) ) ;
2022-05-20 06:46:25 +00:00
if ( val = = " bool " )
{
bool v = false ;
jsn - > get_value ( " default " , v ) ;
2022-10-28 02:47:57 +00:00
data = local_utility : : acquire_memory ( sizeof ( SANE_Bool ) , " " ) ;
2022-05-20 06:46:25 +00:00
memcpy ( data , & v , sizeof ( v ) ) ;
2022-10-28 02:47:57 +00:00
if ( bytes )
* bytes = sizeof ( SANE_Bool ) ;
2022-11-10 03:09:16 +00:00
if ( log )
{
VLOG_MINI_3 ( LOG_LEVEL_DEBUG_INFO , " option %d(%s) default value is: %s \n " , option , title . c_str ( ) , v ? " true " : " false " ) ;
}
2022-05-20 06:46:25 +00:00
}
else if ( val = = " int " )
{
int v = 0 ;
jsn - > get_value ( " default " , v ) ;
data = local_utility : : acquire_memory ( sizeof ( v ) , " " ) ;
memcpy ( data , & v , sizeof ( v ) ) ;
2022-10-28 02:47:57 +00:00
if ( bytes )
* bytes = sizeof ( v ) ;
2022-11-10 03:09:16 +00:00
if ( log )
{
VLOG_MINI_3 ( LOG_LEVEL_DEBUG_INFO , " option %d(%s) default value is: %d \n " , option , title . c_str ( ) , v ) ;
}
2022-05-20 06:46:25 +00:00
}
else if ( val = = " float " )
{
double v = .0f ;
jsn - > get_value ( " default " , v ) ;
2022-09-26 09:30:44 +00:00
SANE_Fixed sd = hg_sane_middleware : : double_2_sane_fixed ( v ) ;
data = local_utility : : acquire_memory ( sizeof ( sd ) , " " ) ;
2022-10-28 02:47:57 +00:00
if ( bytes )
* bytes = sizeof ( sd ) ;
2022-09-26 09:30:44 +00:00
memcpy ( data , & sd , sizeof ( sd ) ) ;
2022-11-10 03:09:16 +00:00
if ( log )
{
VLOG_MINI_3 ( LOG_LEVEL_DEBUG_INFO , " option %d(%s) default value is: %f \n " , option , title . c_str ( ) , v ) ;
}
2022-05-20 06:46:25 +00:00
}
else if ( val = = " string " )
{
int size = 0 ;
jsn - > get_value ( " size " , size ) ;
2023-01-28 07:19:10 +00:00
val = hg_sane_middleware : : get_string_in_json ( jsn , " default " ) ;
2022-05-20 06:46:25 +00:00
2022-07-18 02:54:41 +00:00
if ( size < ( int ) val . length ( ) )
2022-05-20 06:46:25 +00:00
size = val . length ( ) ;
data = local_utility : : acquire_memory ( size + 4 , " " ) ;
strcpy ( ( char * ) data , val . c_str ( ) ) ;
2022-10-28 02:47:57 +00:00
if ( bytes )
* bytes = val . length ( ) ;
2022-11-10 03:09:16 +00:00
if ( log )
{
VLOG_MINI_3 ( LOG_LEVEL_DEBUG_INFO , " option %d(%s) default value is: %s \n " , option , title . c_str ( ) , ( char * ) data ) ;
}
2022-05-20 06:46:25 +00:00
}
else
{
2022-11-10 02:02:52 +00:00
VLOG_MINI_3 ( LOG_LEVEL_DEBUG_INFO , " option %d(%s) is '%s' and no value action. \n " , option , title . c_str ( ) , val . c_str ( ) ) ;
2022-05-20 06:46:25 +00:00
}
}
delete jsn ;
2022-05-03 03:56:07 +00:00
2023-01-28 07:19:10 +00:00
if ( ! data )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
std : : vector < LPDEVINST > : : iterator it = find_openning_device_in_que ( handle ) ;
if ( it ! = openning_ . end ( ) & & ( * it ) - > std_opt )
{
SANE_Int id = - 1 ;
find_stored_descriptor ( handle , option , & id ) ;
data = ( * it ) - > std_opt - > get_default_value ( handle , id ) ;
}
2022-05-03 03:56:07 +00:00
}
2022-06-15 03:05:36 +00:00
return data ;
2022-05-03 03:56:07 +00:00
}
SANE_Status hg_sane_middleware : : get_devices ( const SANE_Device * * * device_list , SANE_Bool local_only )
{
if ( ! device_list )
return SANE_STATUS_INVAL ;
2022-05-17 07:04:55 +00:00
ScannerInfo * dev = NULL ;
2022-05-03 03:56:07 +00:00
long count = 0 ;
2022-05-17 07:04:55 +00:00
scanner_err hgerr = hg_scanner_enum ( dev , & count , local_only ) ;
2022-05-03 03:56:07 +00:00
SANE_Status ret = SANE_STATUS_GOOD ;
2022-05-17 07:04:55 +00:00
if ( hgerr = = SCANNER_ERR_INSUFFICIENT_MEMORY )
2022-05-03 03:56:07 +00:00
{
2023-05-13 08:26:43 +00:00
count + = 4 ; // 为两次hg_scanner_enum间隙可能新增的设备预留空<E79599> <E7A9BA> ?
2022-05-17 07:04:55 +00:00
dev = ( ScannerInfo * ) local_utility : : acquire_memory ( sizeof ( ScannerInfo ) * count , " hg_sane_middleware::get_devices " ) ;
2022-05-03 03:56:07 +00:00
hgerr = hg_scanner_enum ( dev , & count , local_only ) ;
2022-05-17 07:04:55 +00:00
if ( hgerr ! = SCANNER_ERR_OK )
2022-05-03 03:56:07 +00:00
{
2022-10-08 09:18:17 +00:00
local_utility : : free_memory ( dev ) ;
2022-05-03 03:56:07 +00:00
dev = NULL ;
}
}
2022-05-17 07:04:55 +00:00
if ( hgerr = = SCANNER_ERR_OK )
2022-05-03 03:56:07 +00:00
{
* device_list = hg_sane_middleware : : to_sane_device ( dev , count ) ;
if ( dev )
2022-10-08 09:18:17 +00:00
local_utility : : free_memory ( dev ) ;
2022-05-03 03:56:07 +00:00
}
else
2022-05-17 07:04:55 +00:00
ret = local_utility : : scanner_err_2_sane_statu ( hgerr ) ;
2022-05-03 03:56:07 +00:00
if ( hg_sane_middleware : : dev_list_ )
2022-10-08 09:18:17 +00:00
local_utility : : free_memory ( hg_sane_middleware : : dev_list_ ) ;
2022-05-03 03:56:07 +00:00
hg_sane_middleware : : dev_list_ = * device_list ;
return ret ;
}
SANE_Status hg_sane_middleware : : open_device ( SANE_String_Const devicename , SANE_Handle * handle )
{
char rsc [ 128 ] ;
SANE_Status ret = SANE_STATUS_GOOD ;
bzero ( rsc , sizeof ( rsc ) ) ;
ret = open ( devicename , handle , NULL , NULL , NULL , rsc ) ;
if ( ret = = SANE_STATUS_ACCESS_DENIED & & rsc [ 0 ] )
{
SANEAUTH auth ;
bzero ( & auth , sizeof ( auth ) ) ;
auth . resource = rsc ;
if ( local_utility : : ui_cb ( NULL , SANE_EVENT_NEED_AUTH , ( void * ) & auth , NULL , NULL ) )
{
return SANE_STATUS_CANCELLED ;
}
ret = open ( devicename , handle , auth . name , auth . pwd , auth . method , rsc ) ;
}
return ret ;
}
SANE_Status hg_sane_middleware : : close_device ( SANE_Handle h )
{
scanner_handle hs = find_openning_device ( h , true ) ;
SANE_Status err = SANE_STATUS_GOOD ;
if ( hs )
2022-05-17 07:04:55 +00:00
err = local_utility : : scanner_err_2_sane_statu ( hg_scanner_close ( hs , true ) ) ;
2022-05-03 03:56:07 +00:00
return err ;
}
SANE_Status hg_sane_middleware : : get_image_parameters ( SANE_Handle handle , SANE_Parameters * params )
{
scanner_handle h = find_openning_device ( handle ) ;
2022-05-17 07:04:55 +00:00
scanner_err err = SCANNER_ERR_NOT_START ;
2022-05-03 03:56:07 +00:00
if ( ! params )
return SANE_STATUS_INVAL ;
err = hg_scanner_get_img_info ( h , params , sizeof ( * params ) ) ;
2022-05-17 07:04:55 +00:00
return local_utility : : scanner_err_2_sane_statu ( err ) ;
2022-05-03 03:56:07 +00:00
}
SANE_Status hg_sane_middleware : : start ( SANE_Handle h , void * async_event )
{
2023-01-28 07:19:10 +00:00
LPDEVINST dev ;
scanner_handle hs = find_openning_device ( h ) ;
scanner_err err = SCANNER_ERR_INVALID_PARAMETER ;
2022-05-03 03:56:07 +00:00
if ( hs )
2023-01-28 07:19:10 +00:00
err = hg_scanner_start ( hs , async_event , - 1 ) ;
2022-05-03 03:56:07 +00:00
2022-05-17 07:04:55 +00:00
return local_utility : : scanner_err_2_sane_statu ( err ) ;
2022-05-03 03:56:07 +00:00
}
SANE_Status hg_sane_middleware : : read ( SANE_Handle h , void * buf , int * bytes )
{
scanner_handle hs = find_openning_device ( h ) ;
2022-05-17 07:04:55 +00:00
scanner_err err = SCANNER_ERR_INVALID_PARAMETER ;
2022-05-03 03:56:07 +00:00
long r = bytes ? * bytes : 0 ;
if ( bytes & & hs )
{
err = hg_scanner_read_img_data ( hs , ( unsigned char * ) buf , & r ) ;
* bytes = r ;
}
2022-05-17 07:04:55 +00:00
return local_utility : : scanner_err_2_sane_statu ( err ) ;
2022-05-03 03:56:07 +00:00
}
SANE_Status hg_sane_middleware : : stop ( SANE_Handle h )
{
scanner_handle hs = find_openning_device ( h ) ;
if ( hs )
hg_scanner_stop ( hs ) ;
return SANE_STATUS_GOOD ;
}
2023-01-28 07:19:10 +00:00
SANE_Option_Descriptor * hg_sane_middleware : : get_option_descriptor ( SANE_Handle h , const void * option )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
SANE_Option_Descriptor * ret = nullptr ;
scanner_handle handle = hg_sane_middleware : : sane_handle_to_scanner ( h ) ;
std : : vector < LPDEVINST > : : iterator it = find_openning_device_in_que ( handle ) ;
SANE_Int id = - 1 ;
2022-05-03 03:56:07 +00:00
2023-01-28 07:19:10 +00:00
if ( ! handle | | it = = openning_ . end ( ) )
return nullptr ;
else if ( option = = 0 )
2022-05-20 06:46:25 +00:00
{
if ( ! opt_0_ )
{
opt_0_ = ( SANE_Option_Descriptor * ) local_utility : : acquire_memory ( sizeof ( SANE_Option_Descriptor ) , " " ) ;
opt_0_ - > cap = SANE_CAP_SOFT_DETECT ;
opt_0_ - > name = " option-count " ;
opt_0_ - > title = " " ;
opt_0_ - > desc = " Number of options " ;
opt_0_ - > type = SANE_TYPE_INT ;
opt_0_ - > size = sizeof ( SANE_TYPE_INT ) ;
}
2022-05-30 03:04:26 +00:00
LOG_INFO ( LOG_LEVEL_DEBUG_INFO , " get_option_descriptor(0) \n " ) ;
2022-05-20 06:46:25 +00:00
return opt_0_ ;
}
2023-01-28 07:19:10 +00:00
ret = find_stored_descriptor ( handle , option , & id ) ;
2022-05-03 03:56:07 +00:00
if ( ! ret )
{
2022-11-10 02:02:52 +00:00
std : : string key ( " " ) ,
2023-01-28 07:19:10 +00:00
json_txt ( get_option_json ( handle , ( void * ) option , & key , & id ) ) ;
2022-05-03 03:56:07 +00:00
if ( json_txt . length ( ) )
{
json * jsn = new json ( ) ;
if ( jsn - > attach_text ( & json_txt [ 0 ] ) )
{
2023-01-28 07:19:10 +00:00
ret = from_json ( handle , key , jsn ) ;
2022-05-03 03:56:07 +00:00
if ( ret )
{
DEVOPT devopt ;
2023-01-28 07:19:10 +00:00
devopt . option_no = id ;
2022-05-03 03:56:07 +00:00
devopt . desc = ret ;
2023-05-13 08:26:43 +00:00
local_utility : : init_fixed_id ( key . c_str ( ) , id , ( * it ) - > fixed_id ) ;
2023-01-28 07:19:10 +00:00
devopt . opt_name = std : : move ( key ) ;
( * it ) - > opts . push_back ( std : : move ( devopt ) ) ;
2022-05-03 03:56:07 +00:00
2023-05-13 08:26:43 +00:00
if ( ( * it ) - > std_opt )
( * it ) - > std_opt - > init_known_opt ( id , ret ) ;
2023-01-28 07:19:10 +00:00
refresh_current_value ( * it , ret - > name , jsn ) ;
2022-05-03 03:56:07 +00:00
}
}
delete jsn ;
}
2023-05-13 08:26:43 +00:00
if ( ! ret & & ( * it ) - > std_opt )
ret = ( * it ) - > std_opt - > get_option ( id ) ;
2022-05-03 03:56:07 +00:00
}
return ret ;
}
2023-01-28 07:19:10 +00:00
SANE_Status hg_sane_middleware : : set_option ( SANE_Handle h , const void * option , SANE_Action action , void * value , SANE_Int * after_do )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
LPDEVINST dev = nullptr ;
2022-05-03 03:56:07 +00:00
scanner_handle handle = find_openning_device ( h , false , & dev ) ;
if ( ! handle | | ( action = = SANE_ACTION_GET_VALUE & & ! value ) )
return SANE_STATUS_INVAL ;
if ( action = = SANE_ACTION_GET_VALUE )
{
if ( after_do )
* after_do = 0 ;
SANE_Status ret = SANE_STATUS_IO_ERROR ;
if ( option = = 0 )
{
long count = 0 ;
2022-11-10 02:02:52 +00:00
hg_scanner_get_parameter ( handle , ( const char * ) option , NULL , & count ) ;
2022-05-03 03:56:07 +00:00
* ( ( SANE_Int * ) value ) = count ;
ret = SANE_STATUS_GOOD ;
2022-05-30 03:04:26 +00:00
VLOG_MINI_1 ( LOG_LEVEL_WARNING , " get option count = %d. \n " , count ) ;
2022-05-03 03:56:07 +00:00
}
else
{
2023-01-28 07:19:10 +00:00
SANE_Int id = - 1 ;
find_stored_descriptor ( handle , option , & id ) ;
if ( dev - > std_opt & & dev - > std_opt - > is_known_option ( id ) )
2022-05-23 03:52:53 +00:00
{
2023-01-28 07:19:10 +00:00
dev - > std_opt - > get_value ( h , id , value ) ;
2022-05-23 03:52:53 +00:00
ret = SANE_STATUS_GOOD ;
}
2023-01-28 07:19:10 +00:00
else if ( get_current_value ( handle , option , & hg_sane_middleware : : set_value_to_var , value ) )
2022-05-03 03:56:07 +00:00
ret = SANE_STATUS_GOOD ;
}
return ret ;
}
else
{
2023-01-28 07:19:10 +00:00
SANE_Int id = - 1 ;
SANE_Option_Descriptor * desc = find_stored_descriptor ( handle , option , & id ) ;
2022-05-20 06:46:25 +00:00
bool release_value = false ;
2022-05-23 03:52:53 +00:00
scanner_err err = SCANNER_ERR_OK ;
SANE_Status status = SANE_STATUS_GOOD ;
std : : string prev ( " " ) , v ( " " ) ;
2022-05-03 03:56:07 +00:00
2023-05-13 08:26:43 +00:00
if ( action = = SANE_ACTION_SET_AUTO & & desc & & desc - > type ! = SANE_TYPE_BUTTON & & desc - > type ! = SANE_TYPE_GROUP ) // we assume the driver can set the option properbly, and no work to do
{
VLOG_MINI_2 ( LOG_LEVEL_WARNING , " Option %d(%s) call SANE_ACTION_SET_AUTO, we set default value. \n " , option , desc - > title ) ;
value = get_default_value ( handle , option ) ;
if ( ! value )
return SANE_STATUS_UNSUPPORTED ;
release_value = true ;
}
2023-01-28 07:19:10 +00:00
if ( dev - > std_opt & & dev - > std_opt - > is_known_option ( id , & desc ) )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
SANE_Option_Descriptor * known = dev - > std_opt - > get_option ( id ) ;
2022-11-10 02:02:52 +00:00
unsigned char * cont = ( unsigned char * ) value ;
2022-05-23 03:52:53 +00:00
prev = hg_sane_middleware : : option_value_2_string ( known - > type , value ) ;
2022-11-10 02:02:52 +00:00
VLOG_MINI_5 ( LOG_LEVEL_DEBUG_INFO , " $First 4-bytes of origin value for option %d is: %02X%02X%02X%02X \n " , option , cont [ 0 ] , cont [ 1 ] , cont [ 2 ] , cont [ 3 ] ) ;
2023-01-28 07:19:10 +00:00
err = dev - > std_opt - > set_value ( handle , id , value ) ;
2022-05-23 03:52:53 +00:00
v = hg_sane_middleware : : option_value_2_string ( known - > type , value ) ;
2022-05-03 03:56:07 +00:00
}
2022-05-23 03:52:53 +00:00
else
2022-05-03 03:56:07 +00:00
{
2022-05-23 03:52:53 +00:00
if ( ! desc )
2022-05-20 06:46:25 +00:00
{
2023-05-13 08:26:43 +00:00
if ( IS_PTR_NUMBER ( option ) )
{
int id = ( int ) ( uint64_t ) option ;
std : : string name ( local_utility : : un_json_option_name ( id ) ) ;
if ( ! name . empty ( ) )
return local_utility : : scanner_err_2_sane_statu ( hg_scanner_set_parameter ( handle , name . c_str ( ) , value , 0 ) ) ;
}
2022-05-30 03:04:26 +00:00
VLOG_MINI_1 ( LOG_LEVEL_FATAL , " Option descriptor %d not found. \n " , option ) ;
2022-05-23 03:52:53 +00:00
return SANE_STATUS_UNSUPPORTED ;
2022-05-20 06:46:25 +00:00
}
2022-05-23 03:52:53 +00:00
else if ( ! value & & desc - > type ! = SANE_TYPE_BUTTON )
2022-05-20 06:46:25 +00:00
{
2023-05-13 08:26:43 +00:00
//if (action == SANE_ACTION_SET_AUTO) // we assume the driver can set the option properbly, and no work to do
//{
// VLOG_MINI_2(LOG_LEVEL_WARNING, "Option %d(%s) call SANE_ACTION_SET_AUTO, we set default value.\n", option, desc->title);
//
// value = get_default_value(handle, option);
// if (!value)
// return SANE_STATUS_GOOD;
// release_value = true;
//}
//else
2022-05-23 03:52:53 +00:00
{
2022-05-30 03:04:26 +00:00
VLOG_MINI_2 ( LOG_LEVEL_WARNING , " Option descriptor %d(%s) need a value!. \n " , option , desc - > title ) ;
2022-05-20 06:46:25 +00:00
2022-05-23 03:52:53 +00:00
return SANE_STATUS_INVAL ;
}
}
2022-05-03 03:56:07 +00:00
2022-05-23 03:52:53 +00:00
void * pass = value ;
double dv = .0f ;
bool bv = false ;
2023-05-16 03:06:07 +00:00
long size = desc - > size ;
2022-05-03 03:56:07 +00:00
2022-05-23 03:52:53 +00:00
prev = hg_sane_middleware : : option_value_2_string ( desc - > type , value ) ;
if ( desc - > type = = SANE_TYPE_BOOL )
{
bv = * ( ( SANE_Bool * ) value ) = = SANE_TRUE ;
pass = & bv ;
size = sizeof ( bv ) ;
}
else if ( desc - > type = = SANE_TYPE_FIXED )
{
dv = hg_sane_middleware : : sane_fixed_2_double ( * ( ( SANE_Fixed * ) value ) ) ;
pass = & dv ;
size = sizeof ( dv ) ;
}
2022-05-03 03:56:07 +00:00
2023-05-16 03:06:07 +00:00
err = hg_scanner_set_parameter ( handle , ( const char * ) option , pass , & size ) ;
2022-05-03 03:56:07 +00:00
2022-05-23 03:52:53 +00:00
if ( desc - > type = = SANE_TYPE_BOOL )
{
* ( ( SANE_Bool * ) value ) = bv ? SANE_TRUE : SANE_FALSE ;
}
else if ( desc - > type = = SANE_TYPE_FIXED )
{
* ( ( SANE_Fixed * ) value ) = hg_sane_middleware : : double_2_sane_fixed ( dv ) ;
}
v = hg_sane_middleware : : option_value_2_string ( desc - > type , value ) ;
2022-05-03 03:56:07 +00:00
}
if ( prev = = v )
{
2022-06-18 00:55:15 +00:00
VLOG_MINI_3 ( LOG_LEVEL_ALL , " -->Set option(%d - %s) value: %s \n " , option , desc - > title , v . c_str ( ) ) ;
2022-05-03 03:56:07 +00:00
}
else
{
2022-06-18 00:55:15 +00:00
VLOG_4 ( LOG_LEVEL_ALL , 512 , " -->Set option(%d - %s) value: %s(Applied: %s) \n " , option , desc - > title , prev . c_str ( ) , v . c_str ( ) ) ;
2022-05-03 03:56:07 +00:00
}
2022-05-17 07:04:55 +00:00
if ( err = = SCANNER_ERR_OK )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
err = ( scanner_err ) something_after_do ( dev , desc - > name , v . c_str ( ) ) ;
2022-05-03 03:56:07 +00:00
}
2022-05-17 07:04:55 +00:00
else if ( err = = SCANNER_ERR_NOT_EXACT )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
err = ( scanner_err ) ( something_after_do ( dev , desc - > name , v . c_str ( ) ) | SANE_INFO_INEXACT ) ;
2022-05-03 03:56:07 +00:00
}
2022-05-17 07:04:55 +00:00
else if ( err = = SCANNER_ERR_CONFIGURATION_CHANGED )
2022-05-03 03:56:07 +00:00
{
2022-05-30 03:04:26 +00:00
VLOG_MINI_1 ( LOG_LEVEL_DEBUG_INFO , " the setting '%s' affects other options value, RELOAD ... \n " , desc - > title ) ;
2023-01-28 07:19:10 +00:00
on_SCANNER_ERR_CONFIGURATION_CHANGED ( dev ) ;
2022-05-17 07:04:55 +00:00
err = ( scanner_err ) SANE_INFO_RELOAD_OPTIONS ;
2022-05-03 03:56:07 +00:00
}
2023-02-18 02:26:38 +00:00
else if ( err = = SCANNER_ERR_RELOAD_IMAGE_PARAM )
{
VLOG_MINI_1 ( LOG_LEVEL_DEBUG_INFO , " the setting '%s' affects image parameter, APP should re-get ... \n " , desc - > title ) ;
err = ( scanner_err ) SANE_INFO_RELOAD_PARAMS ;
}
else if ( err = = SCANNER_ERR_RELOAD_OPT_PARAM )
{
VLOG_MINI_1 ( LOG_LEVEL_DEBUG_INFO , " the setting '%s' affects image parameter and options, APP should re-get image info and reload options... \n " , desc - > title ) ;
on_SCANNER_ERR_CONFIGURATION_CHANGED ( dev ) ;
err = ( scanner_err ) ( SANE_INFO_RELOAD_PARAMS | SANE_INFO_RELOAD_OPTIONS ) ;
}
2022-05-17 07:04:55 +00:00
else if ( err = = SCANNER_ERR_ACCESS_DENIED )
2022-10-13 07:34:01 +00:00
{
2022-05-03 03:56:07 +00:00
status = SANE_STATUS_ACCESS_DENIED ;
2022-10-13 07:34:01 +00:00
err = ( scanner_err ) 0 ;
}
2022-05-03 03:56:07 +00:00
else
2022-10-13 07:34:01 +00:00
{
2022-05-03 03:56:07 +00:00
status = SANE_STATUS_INVAL ;
2022-10-13 07:34:01 +00:00
err = ( scanner_err ) 0 ;
}
2022-05-03 03:56:07 +00:00
if ( after_do )
* after_do = err ;
2022-05-20 06:46:25 +00:00
if ( release_value )
local_utility : : free_memory ( value ) ;
2022-05-03 03:56:07 +00:00
return status ;
}
}
2023-01-28 07:19:10 +00:00
bool hg_sane_middleware : : get_cur_value ( SANE_Handle handle , void * option , void * value , SANE_Value_Type * type )
2022-06-15 03:05:36 +00:00
{
scanner_handle h = find_openning_device ( handle ) ;
if ( ! h )
return false ;
2023-01-28 07:19:10 +00:00
return get_current_value ( h , option , & hg_sane_middleware : : set_value_to_var , value , type ) ;
2022-06-15 03:05:36 +00:00
}
2023-01-28 07:19:10 +00:00
void * hg_sane_middleware : : get_cur_value ( SANE_Handle handle , void * option , SANE_Value_Type * type )
{
scanner_handle h = find_openning_device ( handle ) ;
void * buf = nullptr ;
if ( ! h )
return NULL ;
get_current_value ( h , option , & hg_sane_middleware : : set_value_to_new , & buf , type ) ;
return buf ;
}
void * hg_sane_middleware : : get_def_value ( SANE_Handle handle , void * option , int * bytes , bool log )
2022-06-15 03:05:36 +00:00
{
scanner_handle h = find_openning_device ( handle ) ;
if ( ! h )
return NULL ;
2022-11-10 03:09:16 +00:00
return get_default_value ( h , option , bytes , log ) ;
2022-06-15 03:05:36 +00:00
}
2022-05-03 03:56:07 +00:00
SANE_Status hg_sane_middleware : : io_control ( SANE_Handle h , unsigned long code , void * data , unsigned * len )
{
2023-01-28 07:19:10 +00:00
LPDEVINST dev ;
scanner_handle handle = find_openning_device ( h , false , & dev ) ;
2022-10-28 02:47:57 +00:00
int ret = SANE_STATUS_GOOD ;
2022-05-03 03:56:07 +00:00
// commented at 2022-03-23 for getting app about info before open any device
//
//if (!handle)
// return SANE_STATUS_INVAL;
2022-10-28 02:47:57 +00:00
ret = hg_scanner_control ( handle , code , data , len ) ;
2022-05-17 07:04:55 +00:00
if ( ret = = SCANNER_ERR_CONFIGURATION_CHANGED )
2022-05-03 03:56:07 +00:00
{
int nc = code ;
2022-05-30 03:04:26 +00:00
VLOG_MINI_1 ( LOG_LEVEL_DEBUG_INFO , " the setting '0x%08x' affects other options value, RELOAD ... \n " , nc ) ;
2023-01-28 07:19:10 +00:00
on_SCANNER_ERR_CONFIGURATION_CHANGED ( dev ) ;
2022-05-03 03:56:07 +00:00
}
2022-05-17 07:04:55 +00:00
return local_utility : : scanner_err_2_sane_statu ( ret ) ;
2022-05-03 03:56:07 +00:00
}
2023-01-19 07:43:59 +00:00
bool hg_sane_middleware : : is_ready ( void )
{
return init_ok_ ;
}
2022-05-03 03:56:07 +00:00
/// <summary>
2023-05-13 08:26:43 +00:00
/// 关联项处<E9A1B9> <E5A484> ?
2022-05-03 03:56:07 +00:00
bool hg_sane_middleware : : compare_val_equal ( const char * cur_val , const char * limit_l , const char * limit_r )
{
return strcmp ( cur_val , limit_l ) = = 0 ;
}
bool hg_sane_middleware : : compare_val_not_equal ( const char * cur_val , const char * limit_l , const char * limit_r )
{
return ! hg_sane_middleware : : compare_val_equal ( cur_val , limit_l , limit_r ) ;
}
bool hg_sane_middleware : : compare_val_great ( const char * cur_val , const char * limit_l , const char * limit_r )
{
return atof ( cur_val ) > atof ( limit_l ) ;
}
bool hg_sane_middleware : : compare_val_not_less ( const char * cur_val , const char * limit_l , const char * limit_r )
{
return ! hg_sane_middleware : : compare_val_less ( cur_val , limit_l , limit_r ) ;
}
bool hg_sane_middleware : : compare_val_less ( const char * cur_val , const char * limit_l , const char * limit_r )
{
return atof ( cur_val ) < atof ( limit_l ) ;
}
bool hg_sane_middleware : : compare_val_not_great ( const char * cur_val , const char * limit_l , const char * limit_r )
{
return ! hg_sane_middleware : : compare_val_great ( cur_val , limit_l , limit_r ) ;
}
bool hg_sane_middleware : : compare_val_between ( const char * cur_val , const char * limit_l , const char * limit_r )
{
return atof ( limit_l ) < atof ( cur_val ) & & atof ( cur_val ) < atof ( limit_r ) ;
}
bool hg_sane_middleware : : compare_val_not_between ( const char * cur_val , const char * limit_l , const char * limit_r )
{
return ! hg_sane_middleware : : compare_val_between ( cur_val , limit_l , limit_r ) ;
}
bool hg_sane_middleware : : is_enable_and ( const std : : vector < MASTEROP > & master , std : : vector < CURVAL > & curvals )
{
// NOTE: logical operator '&&' should get all master's value to check, here we only consider ONE master !!!!
bool enabled = true ;
for ( size_t i = 0 ; enabled & & i < master . size ( ) ; + + i )
{
2022-11-10 02:02:52 +00:00
std : : vector < CURVAL > : : iterator it = std : : find ( curvals . begin ( ) , curvals . end ( ) , master [ i ] . name ) ;
2022-05-03 03:56:07 +00:00
if ( it = = curvals . end ( ) )
{
2022-11-10 02:02:52 +00:00
VLOG_MINI_1 ( LOG_LEVEL_WARNING , " option %s's current value is not found, other options depend it maybe in wrong status. \n " , master [ i ] . name . c_str ( ) ) ;
2022-05-03 03:56:07 +00:00
continue ;
}
enabled & = master [ i ] . compare_val ( it - > val . c_str ( ) , master [ i ] . limit_l . c_str ( ) , master [ i ] . limit_r . c_str ( ) ) ;
}
return enabled ;
}
bool hg_sane_middleware : : is_enable_or ( const std : : vector < MASTEROP > & master , std : : vector < CURVAL > & curvals )
{
bool enabled = false ;
for ( size_t i = 0 ; ! enabled & & i < master . size ( ) ; + + i )
{
2022-11-10 02:02:52 +00:00
std : : vector < CURVAL > : : iterator it = std : : find ( curvals . begin ( ) , curvals . end ( ) , master [ i ] . name ) ;
2022-05-03 03:56:07 +00:00
if ( it = = curvals . end ( ) )
{
2022-11-10 02:02:52 +00:00
VLOG_MINI_1 ( LOG_LEVEL_WARNING , " option %s's current value is not found, other options depend it maybe in wrong status. \n " , master [ i ] . name . c_str ( ) ) ;
2022-05-03 03:56:07 +00:00
continue ;
}
enabled | = master [ i ] . compare_val ( it - > val . c_str ( ) , master [ i ] . limit_l . c_str ( ) , master [ i ] . limit_r . c_str ( ) ) ;
}
return enabled ;
}
bool hg_sane_middleware : : parse_master_option ( const char * depend_str , MASTEROP & mo )
{
bool ret = true ;
double num = .0f ;
2022-11-10 02:02:52 +00:00
std : : string v ( " " ) ;
2022-05-03 03:56:07 +00:00
mo . compare_val = & hg_sane_middleware : : compare_val_equal ;
mo . limit_l = mo . limit_r = " " ;
local_utility : : skip_space ( depend_str ) ;
2022-11-10 02:02:52 +00:00
while ( ( * depend_str > = ' a ' & & * depend_str < = ' z ' ) | | * depend_str = = ' - ' )
v . push_back ( * depend_str + + ) ;
if ( ! v . empty ( ) )
mo . name = v ;
2022-05-03 03:56:07 +00:00
if ( ret )
{
local_utility : : skip_space ( depend_str ) ;
if ( * depend_str = = ' = ' )
{
depend_str + + ;
if ( * depend_str = = ' = ' )
{
depend_str + + ;
if ( * depend_str = = ' [ ' )
{
ret = local_utility : : get_limit ( depend_str , mo . limit_l , mo . limit_r ) ;
mo . compare_val = & hg_sane_middleware : : compare_val_between ;
}
else
{
mo . compare_val = & hg_sane_middleware : : compare_val_equal ;
mo . limit_l = depend_str ;
}
}
else
{
ret = false ;
}
}
else if ( * depend_str = = ' > ' )
{
depend_str + + ;
if ( * depend_str = = ' = ' )
{
depend_str + + ;
mo . compare_val = & hg_sane_middleware : : compare_val_not_less ;
}
else
{
mo . compare_val = & hg_sane_middleware : : compare_val_great ;
}
mo . limit_l = depend_str ;
}
else if ( * depend_str = = ' < ' )
{
depend_str + + ;
if ( * depend_str = = ' = ' )
{
depend_str + + ;
mo . compare_val = & hg_sane_middleware : : compare_val_not_great ;
}
else
{
mo . compare_val = & hg_sane_middleware : : compare_val_less ;
}
mo . limit_l = depend_str ;
}
else if ( * depend_str = = ' ! ' )
{
depend_str + + ;
if ( * depend_str = = ' = ' )
{
depend_str + + ;
if ( * depend_str = = ' [ ' )
{
ret = local_utility : : get_limit ( depend_str , mo . limit_l , mo . limit_r ) ;
mo . compare_val = & hg_sane_middleware : : compare_val_not_between ;
}
else
{
mo . compare_val = & hg_sane_middleware : : compare_val_not_equal ;
mo . limit_l = depend_str ;
}
}
else
{
ret = false ;
}
}
else
{
ret = false ;
}
}
return ret ;
}
2023-01-29 07:01:38 +00:00
bool hg_sane_middleware : : parse_depends ( scanner_handle h , json * jsn , SLAVEOP & so , std : : vector < std : : string > & master )
2022-05-03 03:56:07 +00:00
{
2022-11-10 02:02:52 +00:00
std : : string val ( " " ) , mn ( " " ) ;
2022-05-03 03:56:07 +00:00
bool ret = jsn - > first_child ( val ) ;
while ( ret )
{
MASTEROP mo ;
ret = parse_master_option ( val . c_str ( ) , mo ) ;
if ( ! ret )
break ;
2022-11-10 02:02:52 +00:00
if ( mo . name . empty ( ) )
mo . name = mn ;
else
mn = mo . name ;
2023-01-29 07:01:38 +00:00
SANE_Option_Descriptor * m = find_stored_descriptor ( h , mo . name . c_str ( ) ) ;
if ( m & & m - > type = = SANE_TYPE_STRING )
mo . limit_l = from_default_language ( mo . limit_l . c_str ( ) , nullptr ) ;
2022-05-03 03:56:07 +00:00
so . master . push_back ( mo ) ;
2023-01-28 07:19:10 +00:00
if ( std : : find ( master . begin ( ) , master . end ( ) , mo . name ) = = master . end ( ) )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
master . push_back ( mo . name ) ;
std : : sort ( master . begin ( ) , master . end ( ) ) ;
2022-05-03 03:56:07 +00:00
}
ret = jsn - > next_child ( val ) ;
}
return so . master . size ( ) > 0 ;
}
2022-11-10 02:02:52 +00:00
bool hg_sane_middleware : : is_associatived ( const SLAVEOP & slave , const char * master_name )
2022-05-03 03:56:07 +00:00
{
bool result = false ;
2022-11-10 02:02:52 +00:00
for ( const auto & v : slave . master )
2022-05-03 03:56:07 +00:00
{
2022-11-10 02:02:52 +00:00
if ( v . name = = master_name )
2022-05-03 03:56:07 +00:00
{
result = true ;
break ;
}
}
return result ;
}
2023-01-28 07:19:10 +00:00
bool hg_sane_middleware : : set_stored_option_enabled ( scanner_handle h , const void * option , bool enable , int * size )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
SANE_Option_Descriptor * opt = find_stored_descriptor ( h , option ) ;
2022-05-03 03:56:07 +00:00
bool ret = false ;
if ( opt )
{
if ( size )
* size = opt - > size ;
ret = true ;
if ( enable )
opt - > cap & = ~ SANE_CAP_INACTIVE ;
else
opt - > cap | = SANE_CAP_INACTIVE ;
}
return ret ;
}
2023-01-28 07:19:10 +00:00
int hg_sane_middleware : : something_after_do ( LPDEVINST dev , const char * master_name , const char * cur_val )
2022-05-03 03:56:07 +00:00
{
int after = 0 ;
OPTENABLE oe ;
std : : vector < OPTENABLE > changed_options ;
2023-01-28 07:19:10 +00:00
refresh_current_value ( dev , master_name , cur_val ) ;
if ( std : : find ( dev - > masters . begin ( ) , dev - > masters . end ( ) , master_name ) = = dev - > masters . end ( ) )
2022-05-03 03:56:07 +00:00
{
return after ;
}
2022-11-10 02:02:52 +00:00
oe . name = master_name ;
2022-05-03 03:56:07 +00:00
oe . enable = true ;
changed_options . push_back ( oe ) ;
for ( size_t i = 0 ; i < changed_options . size ( ) ; + + i )
{
2023-01-28 07:19:10 +00:00
for ( size_t slave = 0 ; slave < dev - > slaves . size ( ) ; + + slave )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
if ( dev - > slaves [ slave ] . name = = changed_options [ i ] . name | |
! is_associatived ( dev - > slaves [ slave ] , changed_options [ i ] . name . c_str ( ) ) )
2022-05-03 03:56:07 +00:00
continue ;
bool enable = changed_options [ i ] . enable ;
int bytes = 0 ;
2022-09-15 14:26:51 +00:00
// if (enable)
2023-01-28 07:19:10 +00:00
enable = dev - > slaves [ slave ] . is_enable ( dev - > slaves [ slave ] . master , dev - > cur_vals ) ;
if ( enable = = dev - > slaves [ slave ] . enable_now )
2022-05-03 03:56:07 +00:00
continue ;
2023-01-28 07:19:10 +00:00
dev - > slaves [ slave ] . enable_now = enable ;
if ( ! set_stored_option_enabled ( dev - > dev , dev - > slaves [ slave ] . name . c_str ( ) , enable , & bytes ) )
2022-05-03 03:56:07 +00:00
continue ;
2023-01-28 07:19:10 +00:00
OPTEN * op = get_control_enalbe_data ( dev , dev - > slaves [ slave ] ) ;
hg_scanner_control ( dev - > dev , HG_CONTROL_CODE_OPTION_ENABLE , op , NULL ) ;
2022-05-03 03:56:07 +00:00
free_control_enable_data ( op ) ;
2023-01-28 07:19:10 +00:00
if ( std : : find ( changed_options . begin ( ) , changed_options . end ( ) , dev - > slaves [ slave ] . name ) ! = changed_options . end ( ) )
2022-05-03 03:56:07 +00:00
continue ;
2023-01-28 07:19:10 +00:00
oe . name = dev - > slaves [ slave ] . name ;
oe . enable = dev - > slaves [ slave ] . enable_now ;
2022-05-03 03:56:07 +00:00
changed_options . push_back ( oe ) ;
}
}
if ( changed_options . size ( ) > 1 )
after = SANE_INFO_RELOAD_OPTIONS ;
return after ;
}
2023-01-28 07:19:10 +00:00
bool hg_sane_middleware : : refresh_current_value ( LPDEVINST dev , const char * name , json * jsn )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
std : : vector < CURVAL > : : iterator it = std : : find ( dev - > cur_vals . begin ( ) , dev - > cur_vals . end ( ) , name ) ;
if ( it = = dev - > cur_vals . end ( ) )
2022-05-03 03:56:07 +00:00
{
CURVAL cv ;
jsn - > get_value ( " type " , cv . type ) ;
2022-11-10 02:02:52 +00:00
cv . name = name ;
2022-05-03 03:56:07 +00:00
jsn - > get_value_as_string ( " cur " , cv . val , cv . type = = " int " ) ;
2023-01-31 08:23:21 +00:00
if ( cv . type = = " string " )
local_utility : : trans_language_if_was_word_id ( cv . val ) ;
2023-01-28 07:19:10 +00:00
dev - > cur_vals . push_back ( cv ) ;
2022-05-03 03:56:07 +00:00
return false ;
}
else
{
std : : string old ( it - > val ) ;
jsn - > get_value_as_string ( " cur " , it - > val , it - > type = = " int " ) ;
2023-01-31 08:29:40 +00:00
if ( it - > type = = " string " )
2023-01-31 08:23:21 +00:00
local_utility : : trans_language_if_was_word_id ( it - > val ) ;
2022-05-03 03:56:07 +00:00
return old ! = it - > val ;
}
}
2023-01-28 07:19:10 +00:00
bool hg_sane_middleware : : refresh_current_value ( LPDEVINST dev , const char * name , const char * val )
2022-05-03 03:56:07 +00:00
{
2023-01-28 07:19:10 +00:00
std : : vector < CURVAL > : : iterator it = std : : find ( dev - > cur_vals . begin ( ) , dev - > cur_vals . end ( ) , name ) ;
if ( it ! = dev - > cur_vals . end ( ) )
2022-05-03 03:56:07 +00:00
{
bool ret = strcmp ( it - > val . c_str ( ) , val ) = = 0 ;
it - > val = val ;
return ret ;
}
return false ;
}
2023-01-28 07:19:10 +00:00
OPTEN * hg_sane_middleware : : get_control_enalbe_data ( LPDEVINST dev , const SLAVEOP & slave )
2022-05-03 03:56:07 +00:00
{
2022-11-10 02:02:52 +00:00
std : : vector < std : : string > master ;
2022-05-03 03:56:07 +00:00
OPTEN * opt = NULL ;
size_t size = sizeof ( OPTEN ) ;
for ( size_t i = 0 ; i < slave . master . size ( ) ; + + i )
{
2022-11-10 02:02:52 +00:00
if ( std : : find ( master . begin ( ) , master . end ( ) , slave . master [ i ] . name ) = = master . end ( ) )
master . push_back ( slave . master [ i ] . name ) ;
2022-05-03 03:56:07 +00:00
}
size + = master . size ( ) * sizeof ( OPTVAL ) ;
opt = ( OPTEN * ) malloc ( size ) ;
bzero ( opt , size ) ;
opt - > enabled = slave . enable_now ;
2022-11-10 02:02:52 +00:00
opt - > name = slave . name ;
2022-05-03 03:56:07 +00:00
opt - > master_count = 0 ;
for ( size_t i = 0 ; i < master . size ( ) ; + + i )
{
2023-01-28 07:19:10 +00:00
std : : vector < CURVAL > : : iterator m = std : : find ( dev - > cur_vals . begin ( ) , dev - > cur_vals . end ( ) , master [ i ] ) ;
if ( m = = dev - > cur_vals . end ( ) )
2022-05-03 03:56:07 +00:00
continue ;
2022-11-10 02:02:52 +00:00
opt - > master [ opt - > master_count ] . name = master [ i ] ;
2022-05-03 03:56:07 +00:00
if ( m - > type = = " string " )
{
opt - > master [ opt - > master_count ] . data = malloc ( m - > val . length ( ) + 4 ) ;
strcpy ( ( char * ) opt - > master [ opt - > master_count ] . data , m - > val . c_str ( ) ) ;
}
else
{
opt - > master [ opt - > master_count ] . data = malloc ( sizeof ( double ) ) ;
if ( m - > type = = " bool " )
* ( ( bool * ) opt - > master [ opt - > master_count ] . data ) = ( m - > val = = " true " ) ;
else if ( m - > type = = " int " )
* ( ( int * ) opt - > master [ opt - > master_count ] . data ) = atoi ( m - > val . c_str ( ) ) ;
else
* ( ( double * ) opt - > master [ opt - > master_count ] . data ) = atof ( m - > val . c_str ( ) ) ;
opt - > master_count + + ;
}
}
return opt ;
}
void hg_sane_middleware : : free_control_enable_data ( OPTEN * opt )
{
if ( opt )
{
for ( int i = 0 ; i < opt - > master_count ; + + i )
{
if ( opt - > master [ i ] . data )
free ( opt - > master [ i ] . data ) ;
}
free ( opt ) ;
}
}
2023-01-28 07:19:10 +00:00
void hg_sane_middleware : : on_SCANNER_ERR_CONFIGURATION_CHANGED ( LPDEVINST dev )
2022-05-03 03:56:07 +00:00
{
2022-11-10 02:02:52 +00:00
std : : vector < std : : string > changed ;
2023-01-28 07:19:10 +00:00
reload_current_value ( dev - > dev , & changed ) ;
2022-05-03 03:56:07 +00:00
if ( changed . size ( ) )
{
for ( size_t i = 0 ; i < changed . size ( ) ; + + i )
{
2023-01-28 07:19:10 +00:00
std : : vector < CURVAL > : : iterator it = std : : find ( dev - > cur_vals . begin ( ) , dev - > cur_vals . end ( ) , changed [ i ] ) ;
if ( it ! = dev - > cur_vals . end ( ) )
something_after_do ( dev , it - > name . c_str ( ) , it - > val . c_str ( ) ) ;
2022-05-03 03:56:07 +00:00
}
}
}
2023-01-28 07:19:10 +00:00
std : : vector < LPDEVINST > : : iterator hg_sane_middleware : : find_openning_device_in_que ( scanner_handle h )
{
for ( size_t i = 0 ; i < openning_ . size ( ) ; + + i )
{
if ( openning_ [ i ] - > dev = = h )
return openning_ . begin ( ) + i ;
}
return openning_ . end ( ) ;
}
std : : vector < LPDEVINST > : : iterator hg_sane_middleware : : find_openning_device_in_que ( const char * name )
{
for ( size_t i = 0 ; i < openning_ . size ( ) ; + + i )
{
if ( openning_ [ i ] - > name = = name )
return openning_ . begin ( ) + i ;
}
return openning_ . end ( ) ;
}
2022-05-03 03:56:07 +00:00
/// </summary>
/// <summary>
/// 导出接口
/// </summary>
extern " C " { // avoid compiler exporting name in C++ style !!!
SANE_Status inner_sane_init ( SANE_Int * version_code , SANE_Auth_Callback authorize )
{
local_utility : : cb_auth_ = authorize ;
2023-01-19 07:43:59 +00:00
if ( ! hg_sane_middleware : : instance ( ) - > is_ready ( ) )
return ( SANE_Status ) SCANNER_ERR_LANG_PAK_LOST ;
2022-05-03 03:56:07 +00:00
local_utility : : get_version ( version_code ) ;
2022-10-14 01:00:57 +00:00
std : : this_thread : : sleep_for ( std : : chrono : : milliseconds ( 500 ) ) ;
2022-05-03 03:56:07 +00:00
return SANE_STATUS_GOOD ;
}
void inner_sane_exit ( void )
{
hg_sane_middleware : : clear ( ) ;
}
SANE_Status inner_sane_get_devices ( const SANE_Device * * * device_list , SANE_Bool local_only )
{
SANE_Status code = hg_sane_middleware : : instance ( ) - > get_devices ( device_list , local_only ) ;
return code ;
}
SANE_Status inner_sane_open ( SANE_String_Const devicename , SANE_Handle * handle )
{
return hg_sane_middleware : : instance ( ) - > open_device ( devicename , handle ) ;
}
void inner_sane_close ( SANE_Handle handle )
{
hg_sane_middleware : : instance ( ) - > close_device ( handle ) ;
}
const SANE_Option_Descriptor *
2023-01-28 07:19:10 +00:00
inner_sane_get_option_descriptor ( SANE_Handle handle , const void * option )
2022-05-03 03:56:07 +00:00
{
return hg_sane_middleware : : instance ( ) - > get_option_descriptor ( handle , option ) ;
}
2023-01-28 07:19:10 +00:00
SANE_Status inner_sane_control_option ( SANE_Handle handle , const void * option , SANE_Action action , void * value , SANE_Int * info )
2022-05-03 03:56:07 +00:00
{
return hg_sane_middleware : : instance ( ) - > set_option ( handle , option , action , value , info ) ;
}
SANE_Status inner_sane_get_parameters ( SANE_Handle handle , SANE_Parameters * params )
{
return hg_sane_middleware : : instance ( ) - > get_image_parameters ( handle , params ) ;
}
SANE_Status inner_sane_start ( SANE_Handle handle )
{
2022-05-30 03:04:26 +00:00
LOG_INFO ( LOG_LEVEL_ALL , " sane_start \n " ) ;
2022-05-03 03:56:07 +00:00
return hg_sane_middleware : : instance ( ) - > start ( handle , NULL ) ;
}
SANE_Status inner_sane_read ( SANE_Handle handle , SANE_Byte * data , SANE_Int max_length , SANE_Int * length )
{
if ( ! length )
length = & max_length ;
else
* length = max_length ;
return hg_sane_middleware : : instance ( ) - > read ( handle , data , length ) ;
}
void inner_sane_cancel ( SANE_Handle handle )
{
2022-08-20 02:36:34 +00:00
LOG_INFO ( LOG_LEVEL_ALL , " sane_cancel \n " ) ;
2022-05-03 03:56:07 +00:00
hg_sane_middleware : : instance ( ) - > stop ( handle ) ;
}
SANE_Status inner_sane_set_io_mode ( SANE_Handle handle , SANE_Bool non_blocking )
{
2022-05-30 03:04:26 +00:00
LOG_INFO ( LOG_LEVEL_ALL , " sane_set_io_mode \n " ) ;
2022-05-03 03:56:07 +00:00
return non_blocking ? SANE_STATUS_UNSUPPORTED : SANE_STATUS_GOOD ;
}
SANE_Status inner_sane_get_select_fd ( SANE_Handle handle , SANE_Int * fd )
{
return SANE_STATUS_UNSUPPORTED ;
}
SANE_String_Const inner_sane_strstatus ( SANE_Status status )
{
2022-05-30 03:04:26 +00:00
return hg_scanner_err_name ( status ) ;
2022-05-03 03:56:07 +00:00
}
SANE_Status inner_sane_init_ex ( SANE_Int * version_code , sane_callback cb , void * param )
{
2022-06-18 00:55:15 +00:00
local_utility : : set_callback ( cb , param ) ;
2023-01-19 07:43:59 +00:00
if ( ! hg_sane_middleware : : instance ( ) - > is_ready ( ) )
return ( SANE_Status ) SCANNER_ERR_LANG_PAK_LOST ;
2022-05-03 03:56:07 +00:00
local_utility : : get_version ( version_code ) ;
return SANE_STATUS_GOOD ;
}
SANE_Status inner_sane_io_control ( SANE_Handle h , unsigned long code , void * data , unsigned * len )
{
return hg_sane_middleware : : instance ( ) - > io_control ( h , code , data , len ) ;
}
2022-08-02 09:32:22 +00:00
const char * inner_sane_err_desc ( SANE_Status err )
{
return hg_scanner_err_description ( local_utility : : sane_statu_2_scanner_err ( err ) ) ;
}
2023-01-28 07:19:10 +00:00
SANE_Status inner_sane_read_ext ( SANE_Img_Ext_Info * ext_info , SANE_Int * len )
{
return SANE_STATUS_UNSUPPORTED ;
}
2022-05-03 03:56:07 +00:00
void sanei_debug_msg ( int level , int max_level , const char * be , const char * fmt , va_list ap )
{
}
}
2022-07-18 08:56:03 +00:00
# if defined(WIN32) || defined(_WIN64)
2022-06-18 08:47:21 +00:00
HMODULE g_my_inst = NULL ;
2022-05-27 01:24:28 +00:00
BOOL WINAPI DllMain ( HINSTANCE inst , DWORD reason , LPVOID reserved )
{
if ( reason = = DLL_PROCESS_ATTACH )
{
2022-06-18 08:47:21 +00:00
g_my_inst = inst ;
2022-06-01 03:04:10 +00:00
if ( g_sane_path . empty ( ) )
2022-05-27 01:24:28 +00:00
{
char path [ MAX_PATH ] = { 0 } ;
GetModuleFileNameA ( inst , path , _countof ( path ) - 1 ) ;
if ( strrchr ( path , ' \\ ' ) )
{
2022-07-15 08:47:26 +00:00
g_sane_name = strrchr ( path , ' \\ ' ) + 1 ;
2022-05-27 01:24:28 +00:00
strrchr ( path , ' \\ ' ) [ 1 ] = 0 ;
2022-06-01 03:04:10 +00:00
g_sane_path = path ;
2022-07-15 08:47:26 +00:00
if ( g_sane_name . rfind ( ' . ' ) ! = std : : string : : npos )
g_sane_name . erase ( g_sane_name . rfind ( ' . ' ) ) ;
2022-05-27 01:24:28 +00:00
}
}
}
2022-06-15 03:05:36 +00:00
else if ( reason = = DLL_PROCESS_DETACH )
{
inner_sane_exit ( ) ;
}
2022-05-27 01:24:28 +00:00
return TRUE ;
}
# endif