2022-05-03 03:56:07 +00:00
# include "sane_hg_mdw.h"
2023-07-11 09:13:28 +00:00
2023-09-09 10:09:20 +00:00
# include "sane_opt/sane_opts.h"
2023-08-22 08:47:28 +00:00
2022-05-03 03:56:07 +00:00
# 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>
2023-07-11 09:13:28 +00:00
# include "../sdk/hginclude/utils.h"
2023-07-11 10:04:26 +00:00
# include <huagao/brand.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
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 ) ;
2023-06-02 03:10:17 +00:00
RETURN_MATCH_ERROR ( hgerr , SCANNER_ERR_OUT_OF_RANGE , SANE_STATUS_INVAL ) ;
2022-07-18 02:54:41 +00:00
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 ) ;
2023-06-02 03:10:17 +00:00
RETURN_MATCH_ERROR ( statu , SANE_STATUS_INVAL , SCANNER_ERR_OUT_OF_RANGE ) ;
2022-07-18 02:54:41 +00:00
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
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2023-08-22 08:47:28 +00:00
static sane_callback cb_ui_ = nullptr ;
static void * cb_ui_parm_ = nullptr ;
static SANE_Auth_Callback cb_auth_ = nullptr ;
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 )
{
2023-08-22 08:47:28 +00:00
sane_callback cb_ui = nullptr ;
void * cb_ui_parm = nullptr ;
SANE_Auth_Callback cb_auth = nullptr ;
2022-11-18 08:05:39 +00:00
{
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 ) ;
2023-08-22 08:47:28 +00:00
// utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, 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_ ) ;
2023-08-22 08:47:28 +00:00
cb_ui_ = nullptr ;
cb_ui_parm_ = nullptr ;
cb_auth_ = nullptr ;
2022-05-03 03:56:07 +00:00
}
2023-01-31 08:23:21 +00:00
2023-09-09 10:09:20 +00:00
static void dump_msg ( const char * msg )
{
utils : : to_log_with_api ( hg_scanner_log_is_enable , hg_scanner_log , LOG_LEVEL_DEBUG , msg ) ;
}
2022-05-03 03:56:07 +00:00
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2023-08-22 08:47:28 +00:00
hg_sane_middleware * hg_sane_middleware : : inst_ = nullptr ;
const SANE_Device * * hg_sane_middleware : : dev_list_ = nullptr ;
2022-05-03 03:56:07 +00:00
2023-09-18 03:21:14 +00:00
hg_sane_middleware : : hg_sane_middleware ( void ) : init_ok_ ( false ) , offline_ ( nullptr )
2022-05-03 03:56:07 +00:00
{
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 ) ;
2023-08-22 08:47:28 +00:00
# if defined(WIN32)
hg_scanner_set_sane_info ( " sane " , sane_ver ) ;
# else
2022-05-03 03:56:07 +00:00
signal ( SIGUSR1 , & hg_sane_middleware : : device_pnp ) ;
2023-08-22 08:47:28 +00:00
hg_scanner_set_sane_info ( GET_BACKEND_NAME , sane_ver ) ;
# endif
hg_scanner_initialize ( local_utility : : ui_cb , nullptr ) ;
2023-02-01 03:11:11 +00:00
2023-09-18 03:21:14 +00:00
// initialize offline options with scanner_handle nullptr:
2023-09-09 10:09:20 +00:00
{
2023-09-18 03:21:14 +00:00
offline_ = new DEVINST ;
offline_ - > opts = new device_opts ( ) ;
reload_options ( offline_ ) ;
2023-09-09 10:09:20 +00:00
}
2023-09-18 03:21:14 +00:00
2023-08-22 08:47:28 +00:00
std : : this_thread : : sleep_for ( std : : chrono : : milliseconds ( 500 ) ) ; // wait for device OK
2022-05-03 03:56:07 +00:00
}
hg_sane_middleware : : ~ hg_sane_middleware ( )
{
2023-09-09 10:09:20 +00:00
for ( auto & v : openning_ )
2022-05-03 03:56:07 +00:00
{
2023-09-09 10:09:20 +00:00
hg_sane_middleware : : free_device_instance ( v ) ;
2022-05-03 03:56:07 +00:00
}
2023-09-18 03:21:14 +00:00
hg_sane_middleware : : free_device_instance ( offline_ ) ;
offline_ = nullptr ;
2023-09-09 10:09:20 +00:00
openning_ . clear ( ) ;
2022-05-03 03:56:07 +00:00
hg_scanner_uninitialize ( ) ;
2023-09-09 10:09:20 +00:00
if ( hg_sane_middleware : : dev_list_ )
local_utility : : free_memory ( hg_sane_middleware : : dev_list_ ) ;
2023-01-19 07:43:59 +00:00
}
2023-09-09 10:09:20 +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
{
// 将多级指针安排在一个连续的内存空间存放
2023-08-22 08:47:28 +00:00
SANE_Device * * ret = nullptr , * dev = nullptr ;
SANE_String val = nullptr ;
2022-05-03 03:56:07 +00:00
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 )
2023-08-22 08:47:28 +00:00
return nullptr ;
2022-05-03 03:56:07 +00:00
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 ) ;
}
2023-08-22 08:47:28 +00:00
//utils::to_log_with_api(hg_scanner_log_is_enable, hg_scanner_log, 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 )
{
2023-08-22 08:47:28 +00:00
utils : : to_log_with_api ( hg_scanner_log_is_enable , hg_scanner_log , LOG_LEVEL_DEBUG , " 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 ) ;
}
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 ) ;
}
2023-09-09 10:09:20 +00:00
void hg_sane_middleware : : free_device_instance ( LPDEVINST inst )
2023-06-19 10:40:05 +00:00
{
2023-09-09 10:09:20 +00:00
if ( inst )
{
if ( inst - > dev )
hg_scanner_close ( inst - > dev , true ) ;
if ( inst - > opts )
delete inst - > opts ;
2023-06-19 10:40:05 +00:00
2023-09-09 10:09:20 +00:00
delete inst ;
}
}
2023-06-19 10:40:05 +00:00
2023-09-09 10:09:20 +00:00
hg_sane_middleware : : LPDEVINST hg_sane_middleware : : find_openning_device ( SANE_Handle h , bool rmv )
{
LPDEVINST ret = nullptr ;
scanner_handle handle = hg_sane_middleware : : sane_handle_to_scanner ( h ) ;
2023-06-19 10:40:05 +00:00
2023-09-09 10:09:20 +00:00
for ( int i = 0 ; i < openning_ . size ( ) ; + + i )
{
if ( openning_ [ i ] - > dev = = handle )
{
ret = openning_ [ i ] ;
if ( rmv )
openning_ . erase ( openning_ . begin ( ) + i ) ;
break ;
}
}
2023-06-19 10:40:05 +00:00
2023-09-09 10:09:20 +00:00
return ret ;
2023-06-19 10:40:05 +00:00
}
2023-09-09 10:09:20 +00:00
hg_sane_middleware : : LPDEVINST hg_sane_middleware : : find_openning_device ( const char * name , bool rmv )
2023-06-19 10:40:05 +00:00
{
2023-09-09 10:09:20 +00:00
LPDEVINST ret = nullptr ;
for ( int i = 0 ; i < openning_ . size ( ) ; + + i )
2023-06-19 10:40:05 +00:00
{
2023-09-09 10:09:20 +00:00
if ( openning_ [ i ] - > name = = name )
{
ret = openning_ [ i ] ;
if ( rmv )
openning_ . erase ( openning_ . begin ( ) + i ) ;
break ;
}
}
2023-06-19 10:40:05 +00:00
2023-09-09 10:09:20 +00:00
return ret ;
}
bool hg_sane_middleware : : reload_options ( LPDEVINST inst )
{
long len = 0 ;
char * buf = nullptr ;
scanner_err err = hg_scanner_get_option ( inst - > dev , PARAM_ALL , buf , & len , OPT_VAL_JSON ) ;
2023-06-19 10:40:05 +00:00
2023-09-09 10:09:20 +00:00
if ( err = = SCANNER_ERR_INSUFFICIENT_MEMORY )
{
buf = new char [ len + 4 ] ;
err = hg_scanner_get_option ( inst - > dev , PARAM_ALL , buf , & len , OPT_VAL_JSON ) ;
}
2023-06-19 10:40:05 +00:00
2023-09-09 10:09:20 +00:00
if ( err = = SCANNER_ERR_OK & & len )
{
if ( ! inst - > opts - > init_from ( buf , local_utility : : dump_msg ) )
err = SCANNER_ERR_DATA_DAMAGED ;
2023-06-19 10:40:05 +00:00
}
2023-09-09 10:09:20 +00:00
if ( buf )
delete [ ] buf ;
return err = = SCANNER_ERR_OK ;
2023-06-19 10:40:05 +00:00
}
2023-09-09 10:09:20 +00:00
scanner_err hg_sane_middleware : : read_value ( scanner_handle h , const char * name , SANE_Value_Type type , size_t len , void * value , bool to_default )
{
scanner_err err = SCANNER_ERR_INVALID_PARAMETER ;
2022-05-03 03:56:07 +00:00
2023-09-09 10:09:20 +00:00
if ( type = = SANE_TYPE_BOOL )
{
bool v = false ;
long len = sizeof ( v ) ;
err = hg_scanner_get_option ( h , name , ( char * ) & v , & len , to_default ? OPT_VAL_DEFAULT : OPT_VAL_CURRENT ) ;
if ( value )
* ( SANE_Bool * ) value = v ? SANE_TRUE : SANE_FALSE ;
}
else if ( type = = SANE_TYPE_INT )
{
int v = 0 ;
long len = sizeof ( v ) ;
err = hg_scanner_get_option ( h , name , ( char * ) & v , & len , to_default ? OPT_VAL_DEFAULT : OPT_VAL_CURRENT ) ;
if ( value )
* ( SANE_Int * ) value = v ;
}
else if ( type = = SANE_TYPE_FIXED )
{
double v = .0f ;
long len = sizeof ( v ) ;
err = hg_scanner_get_option ( h , name , ( char * ) & v , & len , to_default ? OPT_VAL_DEFAULT : OPT_VAL_CURRENT ) ;
if ( value )
* ( SANE_Fixed * ) value = hg_sane_middleware : : double_2_sane_fixed ( v ) ;
}
else
{
long l = len ;
err = hg_scanner_get_option ( h , name , ( char * ) value , & l , to_default ? OPT_VAL_DEFAULT : OPT_VAL_CURRENT ) ;
2022-05-03 03:56:07 +00:00
}
2023-09-09 10:09:20 +00:00
return err ;
2022-05-03 03:56:07 +00:00
}
2023-09-09 10:09:20 +00:00
scanner_err hg_sane_middleware : : write_value ( scanner_handle h , const char * name , SANE_Value_Type type , void * value , bool to_default , LPDEVINST optinst , SANE_Int * affect )
2022-05-03 03:56:07 +00:00
{
2023-09-09 10:09:20 +00:00
scanner_err err = SCANNER_ERR_INVALID_PARAMETER ;
if ( type = = SANE_TYPE_BOOL )
2022-05-03 03:56:07 +00:00
{
2023-09-09 10:09:20 +00:00
bool v = value ? * ( SANE_Bool * ) value = = SANE_TRUE : false ;
err = hg_scanner_set_option ( h , name , & v , to_default ) ;
if ( value )
* ( SANE_Bool * ) value = v ? SANE_TRUE : SANE_FALSE ;
}
else if ( type = = SANE_TYPE_INT )
{
int v = value ? * ( SANE_Int * ) value : 0 ;
err = hg_scanner_set_option ( h , name , & v , to_default ) ;
if ( value )
* ( SANE_Int * ) value = v ;
}
else if ( type = = SANE_TYPE_FIXED )
{
double v = value ? hg_sane_middleware : : sane_fixed_2_double ( * ( SANE_Fixed * ) value ) : .0f ;
err = hg_scanner_set_option ( h , name , & v , to_default ) ;
if ( value )
* ( SANE_Fixed * ) value = hg_sane_middleware : : double_2_sane_fixed ( v ) ;
}
else
{
err = hg_scanner_set_option ( h , name , value , to_default ) ;
}
2023-06-19 10:40:05 +00:00
2023-09-09 10:09:20 +00:00
if ( affect )
* affect = 0 ;
2022-05-03 03:56:07 +00:00
2023-09-09 10:09:20 +00:00
if ( err = = SCANNER_ERR_RELOAD_OPT_PARAM | | err = = SCANNER_ERR_CONFIGURATION_CHANGED )
{
if ( optinst )
reload_options ( optinst ) ;
if ( affect )
* affect = SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS ;
err = SCANNER_ERR_OK ;
}
else if ( err = = SCANNER_ERR_RELOAD_IMAGE_PARAM )
{
err = SCANNER_ERR_OK ;
if ( affect )
* affect = SANE_INFO_RELOAD_PARAMS ;
2022-05-03 03:56:07 +00:00
}
2023-09-09 10:09:20 +00:00
return err ;
2022-05-03 03:56:07 +00:00
}
2023-09-09 10:09:20 +00:00
SANE_Status hg_sane_middleware : : get_current_value ( LPDEVINST inst , const void * opt , void * value , bool default_val )
2022-05-03 03:56:07 +00:00
{
2023-09-09 10:09:20 +00:00
std : : string val ( " " ) ;
SANE_Option_Descriptor * desc = inst - > opts - > get_opt_descriptor ( opt ) ;
2022-05-03 03:56:07 +00:00
2023-09-18 03:21:14 +00:00
if ( ! desc & & inst ! = offline_ )
{
desc = offline_ - > opts - > get_opt_descriptor ( opt , nullptr , inst - > opts - > get_option_count ( ) ) ;
if ( desc )
inst = offline_ ;
else
return SANE_STATUS_INVAL ;
}
else if ( ! desc )
{
return SANE_STATUS_INVAL ;
}
2023-09-09 10:09:20 +00:00
if ( desc )
{
scanner_err err = read_value ( inst - > dev , desc - > name , desc - > type , desc - > size , value , default_val ) ;
2022-05-03 03:56:07 +00:00
2023-09-09 10:09:20 +00:00
return local_utility : : scanner_err_2_sane_statu ( err ) ;
}
else
2022-05-03 03:56:07 +00:00
{
2023-09-09 10:09:20 +00:00
return SANE_STATUS_INVAL ;
2022-05-03 03:56:07 +00:00
}
}
2023-09-09 10:09:20 +00:00
SANE_Status hg_sane_middleware : : set_value ( LPDEVINST inst , const void * opt , void * value , SANE_Int * affect , bool to_default )
2022-05-03 03:56:07 +00:00
{
2023-09-09 10:09:20 +00:00
bool empty_value = false ;
SANE_Option_Descriptor * desc = inst - > opts - > get_opt_descriptor ( opt ) ;
2022-05-03 03:56:07 +00:00
2023-09-18 03:21:14 +00:00
if ( ! desc & & inst ! = offline_ )
{
desc = offline_ - > opts - > get_opt_descriptor ( opt , nullptr , inst - > opts - > get_option_count ( ) ) ;
if ( desc )
inst = offline_ ;
else
return SANE_STATUS_INVAL ;
}
else if ( ! desc )
{
2023-09-09 10:09:20 +00:00
return SANE_STATUS_INVAL ;
2023-09-18 03:21:14 +00:00
}
if ( IS_CAP_READONLY ( desc - > cap ) )
return SANE_STATUS_UNSUPPORTED ;
if ( to_default & & ( desc - > cap & SANE_CAP_AUTOMATIC ) = = 0 )
return SANE_STATUS_UNSUPPORTED ;
2022-05-03 03:56:07 +00:00
2023-09-09 10:09:20 +00:00
scanner_err err = write_value ( inst - > dev , desc - > name , desc - > type , value , to_default , inst , affect ) ;
2022-05-03 03:56:07 +00:00
2023-09-09 10:09:20 +00:00
return local_utility : : scanner_err_2_sane_statu ( err ) ;
2022-05-03 03:56:07 +00:00
}
2023-09-09 10:09:20 +00:00
SANE_Status hg_sane_middleware : : get_option_fixed_id ( LPDEVINST inst , const void * opt , void * value )
2022-05-18 09:41:05 +00:00
{
2023-09-09 10:09:20 +00:00
int fix_id = 0 ;
2023-08-21 08:09:57 +00:00
2023-09-18 03:21:14 +00:00
if ( ! inst - > opts - > get_opt_descriptor ( opt , & fix_id ) & & inst ! = offline_ )
2022-05-18 09:41:05 +00:00
{
2023-09-18 03:21:14 +00:00
offline_ - > opts - > get_opt_descriptor ( opt , & fix_id , inst - > opts - > get_option_count ( ) ) ;
2023-08-21 08:09:57 +00:00
}
2023-09-18 03:21:14 +00:00
* ( SANE_Int * ) value = fix_id ;
return fix_id < = 0 ? SANE_STATUS_INVAL : SANE_STATUS_GOOD ;
2023-01-28 07:19:10 +00:00
}
2023-09-09 10:09:20 +00:00
2023-08-22 08:47:28 +00:00
void hg_sane_middleware : : set_app_callback ( void * cb , void * param , int type )
2023-01-28 07:19:10 +00:00
{
2023-08-22 08:47:28 +00:00
if ( type = = APP_CALLBACK_EX )
local_utility : : set_callback ( ( sane_callback ) cb , param ) ;
else
local_utility : : cb_auth_ = ( SANE_Auth_Callback ) cb ;
}
void hg_sane_middleware : : get_version ( SANE_Int * ver )
{
2023-09-09 10:09:20 +00:00
if ( ver )
* ver = 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 :)
2023-01-28 07:19:10 +00:00
}
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 : : 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_ ;
2023-08-22 08:47:28 +00:00
hg_sane_middleware : : inst_ = nullptr ;
2022-05-18 09:41:05 +00:00
}
}
2023-01-28 07:19:10 +00:00
2023-09-09 10:09:20 +00:00
SANE_Status hg_sane_middleware : : get_devices ( const SANE_Device * * * device_list , SANE_Bool local_only )
2023-06-17 06:59:57 +00:00
{
2023-09-09 10:09:20 +00:00
if ( ! device_list )
return SANE_STATUS_INVAL ;
ScannerInfo * dev = nullptr ;
long count = 0 ;
scanner_err hgerr = hg_scanner_enum ( dev , & count , local_only ) ;
SANE_Status ret = SANE_STATUS_GOOD ;
if ( hgerr = = SCANNER_ERR_INSUFFICIENT_MEMORY )
2023-06-17 06:59:57 +00:00
{
2023-09-09 10:09:20 +00:00
count + = 4 ;
dev = ( ScannerInfo * ) local_utility : : acquire_memory ( sizeof ( ScannerInfo ) * count , " hg_sane_middleware::get_devices " ) ;
hgerr = hg_scanner_enum ( dev , & count , local_only ) ;
}
2023-06-17 06:59:57 +00:00
2023-09-09 10:09:20 +00:00
if ( hgerr = = SCANNER_ERR_OK )
* device_list = hg_sane_middleware : : to_sane_device ( dev , count ) ;
else
ret = local_utility : : scanner_err_2_sane_statu ( hgerr ) ;
if ( dev )
local_utility : : free_memory ( dev ) ;
2023-06-19 10:40:05 +00:00
2023-09-09 10:09:20 +00:00
if ( hg_sane_middleware : : dev_list_ )
local_utility : : free_memory ( hg_sane_middleware : : dev_list_ ) ;
hg_sane_middleware : : dev_list_ = * device_list ;
return ret ;
}
SANE_Status hg_sane_middleware : : open_device ( SANE_String_Const devicename , SANE_Handle * handle )
{
if ( ! handle )
return SANE_STATUS_INVAL ;
char rsc [ 128 ] = { 0 } ;
scanner_handle h = nullptr ;
scanner_err se = hg_scanner_open ( & h , devicename , false , nullptr , nullptr , nullptr , rsc ) ;
if ( se = = SCANNER_ERR_ACCESS_DENIED & & rsc [ 0 ] )
{
SANEAUTH auth ;
memset ( & auth , 0 , sizeof ( auth ) ) ;
auth . resource = rsc ;
if ( local_utility : : ui_cb ( nullptr , SANE_EVENT_NEED_AUTH , ( void * ) & auth , nullptr , nullptr ) )
{
return SANE_STATUS_CANCELLED ;
2023-06-19 10:40:05 +00:00
}
2023-06-21 07:33:39 +00:00
2023-09-09 10:09:20 +00:00
se = hg_scanner_open ( & h , devicename , false , auth . name , auth . pwd , auth . method , rsc ) ;
}
if ( se = = SCANNER_ERR_OK )
{
// for depend item maybe later, we move the depend-logic-operation out of 'from_json'. to ensure the status, we get all options actively and do depend-logic operation after all options got - 2023-06-21
LPDEVINST inst = new DEVINST ;
inst - > dev = h ;
inst - > name = devicename ;
inst - > opts = new device_opts ( ) ;
if ( reload_options ( inst ) )
{
openning_ . push_back ( inst ) ;
* handle = hg_sane_middleware : : scanner_handle_to_sane ( h ) ;
}
else
2023-06-21 07:33:39 +00:00
{
2023-09-09 10:09:20 +00:00
hg_sane_middleware : : free_device_instance ( inst ) ;
* handle = nullptr ;
se = SCANNER_ERR_DATA_DAMAGED ;
2023-06-21 07:33:39 +00:00
}
}
2023-09-09 10:09:20 +00:00
return local_utility : : scanner_err_2_sane_statu ( se ) ;
2023-06-21 07:33:39 +00:00
}
2023-09-09 10:09:20 +00:00
SANE_Status hg_sane_middleware : : close_device ( SANE_Handle h )
2023-06-21 07:33:39 +00:00
{
2023-09-09 10:09:20 +00:00
LPDEVINST inst = find_openning_device ( h , true ) ;
SANE_Status err = SANE_STATUS_GOOD ;
if ( inst )
2023-06-21 07:33:39 +00:00
{
2023-09-09 10:09:20 +00:00
if ( inst - > dev )
err = local_utility : : scanner_err_2_sane_statu ( hg_scanner_close ( inst - > dev , true ) ) ;
inst - > dev = nullptr ;
hg_sane_middleware : : free_device_instance ( inst ) ;
2023-06-17 06:59:57 +00:00
}
2023-09-09 10:09:20 +00:00
return err ;
2023-06-17 06:59:57 +00:00
}
2023-09-09 10:09:20 +00:00
SANE_Status hg_sane_middleware : : get_image_parameters ( SANE_Handle handle , SANE_Parameters * params )
2022-05-03 03:56:07 +00:00
{
2023-09-09 10:09:20 +00:00
if ( ! params )
2022-05-03 03:56:07 +00:00
return SANE_STATUS_INVAL ;
2023-09-09 10:09:20 +00:00
LPDEVINST inst = find_openning_device ( handle ) ;
scanner_err err = SCANNER_ERR_NOT_START ;
2022-05-03 03:56:07 +00:00
2023-09-09 10:09:20 +00:00
if ( inst & & inst - > dev )
err = hg_scanner_get_img_info ( inst - > dev , params , sizeof ( * params ) ) ;
2022-05-03 03:56:07 +00:00
2023-09-09 10:09:20 +00:00
return local_utility : : scanner_err_2_sane_statu ( err ) ;
}
SANE_Status hg_sane_middleware : : start ( SANE_Handle h , void * async_event )
{
LPDEVINST dev = find_openning_device ( h ) ;
scanner_err err = SCANNER_ERR_INVALID_PARAMETER ;
if ( dev & & dev - > dev )
err = hg_scanner_start ( dev - > dev , async_event , - 1 ) ;
2022-05-23 03:52:53 +00:00
2023-09-09 10:09:20 +00:00
return local_utility : : scanner_err_2_sane_statu ( err ) ;
}
SANE_Status hg_sane_middleware : : read ( SANE_Handle h , void * buf , int * bytes )
{
LPDEVINST dev = find_openning_device ( h ) ;
scanner_err err = SCANNER_ERR_INVALID_PARAMETER ;
long r = bytes ? * bytes : 0 ;
if ( bytes )
2022-05-03 03:56:07 +00:00
{
2023-09-09 10:09:20 +00:00
if ( dev & & dev - > dev )
{
err = hg_scanner_read_img_data ( dev - > dev , ( unsigned char * ) buf , & r ) ;
* bytes = r ;
}
else
err = SCANNER_ERR_NOT_OPEN ;
2022-05-03 03:56:07 +00:00
}
2023-09-09 10:09:20 +00:00
return local_utility : : scanner_err_2_sane_statu ( err ) ;
2022-05-03 03:56:07 +00:00
}
2023-09-09 10:09:20 +00:00
SANE_Status hg_sane_middleware : : stop ( SANE_Handle h )
2022-05-03 03:56:07 +00:00
{
2023-09-09 10:09:20 +00:00
LPDEVINST dev = find_openning_device ( h ) ;
scanner_err err = SCANNER_ERR_OK ;
if ( dev & & dev - > dev )
err = hg_scanner_stop ( dev - > dev ) ;
2022-05-03 03:56:07 +00:00
2023-09-09 10:09:20 +00:00
return local_utility : : scanner_err_2_sane_statu ( err ) ;
}
SANE_Option_Descriptor * hg_sane_middleware : : get_option_descriptor ( SANE_Handle h , const void * option )
{
2023-08-22 08:47:28 +00:00
SANE_Option_Descriptor * ret = nullptr ;
2023-09-09 10:09:20 +00:00
LPDEVINST dev = find_openning_device ( h ) ;
2023-09-18 03:21:14 +00:00
int base_ind = 0 ;
2023-09-09 10:09:20 +00:00
if ( dev )
2023-09-18 03:21:14 +00:00
{
base_ind = dev - > opts - > get_option_count ( ) ;
2023-09-09 10:09:20 +00:00
ret = dev - > opts - > get_opt_descriptor ( option ) ;
2023-09-18 03:21:14 +00:00
}
if ( ! ret )
ret = offline_ - > opts - > get_opt_descriptor ( option , nullptr , base_ind ) ;
2022-05-03 03:56:07 +00:00
2023-09-09 10:09:20 +00:00
return ret ;
}
SANE_Status hg_sane_middleware : : control_option ( SANE_Handle h , const void * option , SANE_Action action , void * value , SANE_Int * after_do )
{
SANE_Status err = SANE_STATUS_INVAL ;
LPDEVINST inst = find_openning_device ( h ) ;
2022-05-03 03:56:07 +00:00
2023-09-09 10:09:20 +00:00
if ( ! inst )
{
2023-09-18 03:21:14 +00:00
if ( h )
return local_utility : : scanner_err_2_sane_statu ( SCANNER_ERR_NOT_OPEN ) ;
inst = offline_ ;
2022-05-03 03:56:07 +00:00
}
2023-09-18 03:21:14 +00:00
if ( action = = SANE_ACTION_GET_VALUE )
2022-05-03 03:56:07 +00:00
{
2023-09-09 10:09:20 +00:00
if ( ! option )
2022-05-03 03:56:07 +00:00
{
2023-09-18 03:21:14 +00:00
* ( SANE_Int * ) value = inst - > opts - > get_option_count ( ) + offline_ - > opts - > get_option_count ( ) ;
2023-09-09 10:09:20 +00:00
err = SANE_STATUS_GOOD ;
2022-05-03 03:56:07 +00:00
}
else
{
2023-09-09 10:09:20 +00:00
err = get_current_value ( inst , option , value , false ) ;
2022-05-03 03:56:07 +00:00
}
}
2023-09-09 10:09:20 +00:00
else if ( action = = SANE_ACTION_SET_VALUE | | action = = SANE_ACTION_SET_AUTO )
2022-05-03 03:56:07 +00:00
{
2023-09-09 10:09:20 +00:00
err = set_value ( inst , option , value , after_do , action = = SANE_ACTION_SET_AUTO ) ;
2022-05-03 03:56:07 +00:00
}
2023-09-09 10:09:20 +00:00
// extension ...
else if ( action = = SANE_ACTION_GET_DEFAULT_VALUE )
2022-05-03 03:56:07 +00:00
{
2023-09-09 10:09:20 +00:00
err = get_current_value ( inst , option , value , true ) ;
2022-05-03 03:56:07 +00:00
}
2023-09-09 10:09:20 +00:00
else if ( action = = SANE_ACTION_GET_FIX_ID )
2022-05-03 03:56:07 +00:00
{
2023-09-09 10:09:20 +00:00
err = get_option_fixed_id ( inst , option , value ) ;
2022-05-03 03:56:07 +00:00
}
2023-09-09 10:09:20 +00:00
return err ;
2022-06-15 03:05:36 +00:00
}
2023-09-18 03:21:14 +00:00
2023-09-09 10:09:20 +00:00
SANE_Status hg_sane_middleware : : ex_io_control ( SANE_Handle h , unsigned long code , void * data , unsigned * len )
2022-05-03 03:56:07 +00:00
{
2023-09-09 10:09:20 +00:00
LPDEVINST dev = find_openning_device ( h ) ;
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;
2023-09-09 10:09:20 +00:00
ret = hg_scanner_control ( dev - > dev , 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 ;
2023-08-22 08:47:28 +00:00
utils : : to_log_with_api ( hg_scanner_log_is_enable , hg_scanner_log , LOG_LEVEL_DEBUG , " the setting '0x%08x' affects other options value, RELOAD ... \n " , nc ) ;
2023-09-09 10:09:20 +00:00
reload_options ( 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