1355 lines
35 KiB
C++
1355 lines
35 KiB
C++
#include "HGLibDeviceImpl.hpp"
|
|
#include "base/HGInc.h"
|
|
#include "base/HGInfo.h"
|
|
#include "base/HGImage.h"
|
|
#include "HGString.h"
|
|
|
|
const char* GROUP_NAME[] = {
|
|
NULL,
|
|
"grp-1",
|
|
"grp-2",
|
|
"grp-3",
|
|
"grp-4"
|
|
};
|
|
|
|
const char* OPTION_NAME[] = {
|
|
NULL,
|
|
SANE_STD_OPT_NAME_IS_MULTI_OUT,
|
|
SANE_STD_OPT_NAME_MULTI_OUT_TYPE,
|
|
SANE_STD_OPT_NAME_COLOR_MODE,
|
|
SANE_STD_OPT_NAME_BINARY_THRESHOLD,
|
|
SANE_STD_OPT_NAME_FILTER,
|
|
SANE_STD_OPT_NAME_RID_MULTIOUT_RED,
|
|
SANE_STD_OPT_NAME_RID_ANSWER_SHEET_RED,
|
|
SANE_STD_OPT_NAME_ERASE_BACKGROUND,
|
|
SANE_STD_OPT_NAME_BKG_COLOR_RANGE,
|
|
SANE_STD_OPT_NAME_SHARPEN,
|
|
SANE_STD_OPT_NAME_RID_MORR,
|
|
SANE_STD_OPT_NAME_RID_GRID,
|
|
SANE_STD_OPT_NAME_ERROR_EXTENSION,
|
|
SANE_STD_OPT_NAME_NOISE_OPTIMIZE,
|
|
SANE_STD_OPT_NAME_NOISE_SIZE,
|
|
SANE_STD_OPT_NAME_PAPER,
|
|
SANE_STD_OPT_NAME_CUSTOM_AREA,
|
|
SANE_STD_OPT_NAME_CUSTOM_AREA_LEFT,
|
|
SANE_STD_OPT_NAME_CUSTOM_AREA_RIGHT,
|
|
SANE_STD_OPT_NAME_CUSTOM_AREA_TOP,
|
|
SANE_STD_OPT_NAME_CUSTOM_AREA_BOTTOM,
|
|
SANE_STD_OPT_NAME_SIZE_CHECK,
|
|
SANE_STD_OPT_NAME_PAGE,
|
|
SANE_STD_OPT_NAME_DISCARD_BLANK_SENS,
|
|
SANE_STD_OPT_NAME_FEED_STRENGTH,
|
|
SANE_STD_OPT_NAME_TIME_TO_SLEEP,
|
|
SANE_STD_OPT_NAME_RESOLUTION,
|
|
SANE_STD_OPT_NAME_IMAGE_QUALITY,
|
|
SANE_STD_OPT_NAME_EXCHANGE,
|
|
SANE_STD_OPT_NAME_SPLIT,
|
|
SANE_STD_OPT_NAME_ANTI_SKEW,
|
|
SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA,
|
|
SANE_STD_OPT_NAME_BRIGHTNESS,
|
|
SANE_STD_OPT_NAME_CONTRAST,
|
|
SANE_STD_OPT_NAME_GAMMA,
|
|
SANE_STD_OPT_NAME_IS_PHOTO_MODE,
|
|
SANE_STD_OPT_NAME_ERASE_BLACK_FRAME,
|
|
SANE_STD_OPT_NAME_DARK_SAMPLE,
|
|
SANE_STD_OPT_NAME_THRESHOLD,
|
|
SANE_STD_OPT_NAME_ANTI_NOISE_LEVEL,
|
|
SANE_STD_OPT_NAME_MARGIN,
|
|
SANE_STD_OPT_NAME_FILL_BKG_MODE,
|
|
SANE_STD_OPT_NAME_IS_ANTI_PERMEATE,
|
|
SANE_STD_OPT_NAME_ANTI_PERMEATE_LEVEL,
|
|
SANE_STD_OPT_NAME_RID_HOLE_L,
|
|
SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_L,
|
|
SANE_STD_OPT_NAME_RID_HOLE_R,
|
|
SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_R,
|
|
SANE_STD_OPT_NAME_RID_HOLE_T,
|
|
SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_T,
|
|
SANE_STD_OPT_NAME_RID_HOLE_B,
|
|
SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE_B,
|
|
SANE_STD_OPT_NAME_IS_FILL_COLOR,
|
|
SANE_STD_OPT_NAME_IS_ULTROSONIC_CHECK,
|
|
SANE_STD_OPT_NAME_DOUBLE_FEED_HANDLE,
|
|
SANE_STD_OPT_NAME_IS_CHECK_STAPLE,
|
|
SANE_STD_OPT_NAME_SCAN_MODE,
|
|
SANE_STD_OPT_NAME_SCAN_COUNT,
|
|
SANE_STD_OPT_NAME_TEXT_DIRECTION,
|
|
SANE_STD_OPT_NAME_IS_ROTATE_BKG_180,
|
|
SANE_STD_OPT_NAME_IS_CHECK_DOG_EAR,
|
|
SANE_STD_OPT_NAME_DOG_EAR_SIZE,
|
|
SANE_STD_OPT_NAME_IS_CHECK_ASKEW,
|
|
SANE_STD_OPT_NAME_ASKEW_RANGE,
|
|
SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH,
|
|
SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE,
|
|
SANE_STD_OPT_NAME_WAIT_TO_SCAN,
|
|
SANE_STD_OPT_NAME_REVERSE_01,
|
|
SANE_STD_OPT_NAME_FOLD_TYPE,
|
|
SANE_STD_OPT_NAME_COLOR_CORRECTION,
|
|
SANE_STD_OPT_NAME_WAIT_SCAN_EXIT,
|
|
SANE_STD_OPT_NAME_DISCARDBLANK,
|
|
SANE_STD_OPT_NAME_LENS_DIRTY,
|
|
SANE_STD_OPT_NAME_RID_HOLE,
|
|
SANE_STD_OPT_NAME_SEARCH_HOLE_RANGE
|
|
};
|
|
|
|
const char* OPTION_ENUMVALUE[] = {
|
|
NULL,
|
|
OPTION_VALUE_DLSCLX_W,
|
|
OPTION_VALUE_DLSCLX_CS_HD_HB,
|
|
OPTION_VALUE_DLSCLX_CS_HD,
|
|
OPTION_VALUE_DLSCLX_CS_HB,
|
|
OPTION_VALUE_DLSCLX_HD_HB,
|
|
OPTION_VALUE_YSMS_24WCS,
|
|
OPTION_VALUE_YSMS_256JHD,
|
|
OPTION_VALUE_YSMS_HB,
|
|
OPTION_VALUE_YSMS_YSZDSB,
|
|
OPTION_VALUE_HDHHBTX_CSYZQ_BCS,
|
|
OPTION_VALUE_HDHHBTX_CSYZQ_CHS,
|
|
OPTION_VALUE_HDHHBTX_CSYZQ_CLS,
|
|
OPTION_VALUE_HDHHBTX_CSYZQ_CHULANSE,
|
|
OPTION_VALUE_HDHHBTX_CSYZQ_HSZQ,
|
|
OPTION_VALUE_HDHHBTX_CSYZQ_LSZQ,
|
|
OPTION_VALUE_HDHHBTX_CSYZQ_LANSEZENGQIANG,
|
|
OPTION_VALUE_RHYMH_W,
|
|
OPTION_VALUE_RHYMH_RH,
|
|
OPTION_VALUE_RHYMH_JYBRH,
|
|
OPTION_VALUE_RHYMH_MH,
|
|
OPTION_VALUE_RHYMH_JYBMH,
|
|
OPTION_VALUE_ZZCC_A3,
|
|
OPTION_VALUE_ZZCC_8K,
|
|
OPTION_VALUE_ZZCC_A4,
|
|
OPTION_VALUE_ZZCC_A4HX,
|
|
OPTION_VALUE_ZZCC_16K,
|
|
OPTION_VALUE_ZZCC_16KHX,
|
|
OPTION_VALUE_ZZCC_A5,
|
|
OPTION_VALUE_ZZCC_A5HX,
|
|
OPTION_VALUE_ZZCC_A6,
|
|
OPTION_VALUE_ZZCC_A6HX,
|
|
OPTION_VALUE_ZZCC_B4,
|
|
OPTION_VALUE_ZZCC_B5,
|
|
OPTION_VALUE_ZZCC_B5HX,
|
|
OPTION_VALUE_ZZCC_B6,
|
|
OPTION_VALUE_ZZCC_B6HX,
|
|
OPTION_VALUE_ZZCC_Letter,
|
|
OPTION_VALUE_ZZCC_LetterHX,
|
|
OPTION_VALUE_ZZCC_DoubleLetter,
|
|
OPTION_VALUE_ZZCC_LEGAL,
|
|
OPTION_VALUE_ZZCC_PPYSCC,
|
|
OPTION_VALUE_ZZCC_ZDSMCCZDCQ,
|
|
OPTION_VALUE_ZZCC_ZDSMCC,
|
|
OPTION_VALUE_ZZCC_SLSJ,
|
|
OPTION_VALUE_SMYM_DM,
|
|
OPTION_VALUE_SMYM_SM,
|
|
OPTION_VALUE_SMYM_TGKBYTY,
|
|
OPTION_VALUE_SMYM_TGKBYFPZ,
|
|
OPTION_VALUE_SMYM_DZ,
|
|
OPTION_VALUE_HZ_W,
|
|
OPTION_VALUE_HZ_SDYX,
|
|
OPTION_VALUE_HZ_HZYX,
|
|
OPTION_VALUE_BJTCFS_TDBX,
|
|
OPTION_VALUE_BJTCFS_ADBX,
|
|
OPTION_VALUE_FZSTDJ_R,
|
|
OPTION_VALUE_FZSTDJ_JR,
|
|
OPTION_VALUE_FZSTDJ_YB,
|
|
OPTION_VALUE_FZSTDJ_JQ,
|
|
OPTION_VALUE_FZSTDJ_Q,
|
|
OPTION_VALUE_SZTPCL_DQTXBTZSM,
|
|
OPTION_VALUE_SZTPCL_DQTXBJXSM,
|
|
OPTION_VALUE_SZTPCL_SCTXBTZSM,
|
|
OPTION_VALUE_SZTPCL_SCTXBJXSM,
|
|
OPTION_VALUE_SMZS_LXSM,
|
|
OPTION_VALUE_SMZS_SMZDZS,
|
|
OPTION_VALUE_WGFX_0,
|
|
OPTION_VALUE_WGFX_90,
|
|
OPTION_VALUE_WGFX_180,
|
|
OPTION_VALUE_WGFX__90,
|
|
OPTION_VALUE_WGFX_ZDWBFXSB,
|
|
OPTION_VALUE_FZQD_R,
|
|
OPTION_VALUE_FZQD_YB,
|
|
OPTION_VALUE_FZQD_Q,
|
|
OPTION_VALUE_XMSJ_BXM,
|
|
OPTION_VALUE_XMSJ_WFZ,
|
|
OPTION_VALUE_XMSJ_SFZ,
|
|
OPTION_VALUE_XMSJ_BXS,
|
|
OPTION_VALUE_XMSJ_YXS,
|
|
OPTION_VALUE_XMSJ_LXS,
|
|
OPTION_VALUE_XMSJ_SXS,
|
|
OPTION_VALUE_ZYDZ,
|
|
OPTION_VALUE_SXDZ,
|
|
OPTION_VALUE_ZDDZ,
|
|
"15s",
|
|
"30s",
|
|
"60s",
|
|
"2min",
|
|
"4min",
|
|
"8min",
|
|
OPTION_VALUE_SMYM_TGKBYJYWJDX,
|
|
OPTION_VALUE_SZTPCL_SCTXBJY
|
|
};
|
|
|
|
struct DeviceParam
|
|
{
|
|
DeviceParam()
|
|
{
|
|
valueType = 0;
|
|
intValue = 0;
|
|
doubleValue = 0;
|
|
boolValue = false;
|
|
|
|
rangeType = 0;
|
|
intValueMin = 0;
|
|
intValueMax = 0;
|
|
doubleValueMin = 0;
|
|
doubleValueMax = 0;
|
|
}
|
|
|
|
// 配置名
|
|
std::string option;
|
|
|
|
int valueType;
|
|
std::string stringValue;
|
|
int intValue;
|
|
double doubleValue;
|
|
bool boolValue;
|
|
|
|
int rangeType;
|
|
std::vector<std::string> stringValueList;
|
|
std::vector<int> intValueList;
|
|
std::vector<double> doubleValueList;
|
|
int intValueMin;
|
|
int intValueMax;
|
|
double doubleValueMin;
|
|
double doubleValueMax;
|
|
};
|
|
|
|
struct DeviceParamsGroup
|
|
{
|
|
std::string groupName;
|
|
std::vector<DeviceParam> devParams;
|
|
};
|
|
|
|
HGLibDeviceHotPlugEventFunc HGLibDeviceImpl::m_hotPlugEventFunc = NULL;
|
|
HGPointer HGLibDeviceImpl::m_hotPlugEventParam = NULL;
|
|
HGBool HGLibDeviceImpl::m_init = HGFALSE;
|
|
std::map<SANE_Handle, HGLibDeviceImpl*> HGLibDeviceImpl::m_deviceList;
|
|
|
|
HGLibDeviceImpl::HGLibDeviceImpl()
|
|
{
|
|
m_lock = NULL;
|
|
HGBase_CreateLock(&m_lock);
|
|
m_devHandle = NULL;
|
|
m_devName.clear();
|
|
m_dpi = 0;
|
|
m_scanning = HGFALSE;
|
|
m_eventFunc = NULL;
|
|
m_eventParam = NULL;
|
|
m_imageFunc = NULL;
|
|
m_imageParam = NULL;
|
|
m_statusCode = SANE_STATUS_GOOD;
|
|
}
|
|
|
|
HGLibDeviceImpl::~HGLibDeviceImpl()
|
|
{
|
|
HGBase_DestroyLock(m_lock);
|
|
m_lock = NULL;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::Init(HGLibDeviceHotPlugEventFunc func, HGPointer param)
|
|
{
|
|
if (m_init)
|
|
{
|
|
return HGFALSE;
|
|
}
|
|
|
|
assert(NULL == m_hotPlugEventFunc);
|
|
m_hotPlugEventFunc = func;
|
|
m_hotPlugEventParam = param;
|
|
|
|
SANE_Int version_code = 0;
|
|
if (SANE_STATUS_GOOD != sane_init_ex(&version_code, sane_ex_callback, NULL))
|
|
{
|
|
m_hotPlugEventFunc = NULL;
|
|
m_hotPlugEventParam = NULL;
|
|
return HGFALSE;
|
|
}
|
|
|
|
m_init = HGTRUE;
|
|
return HGTRUE;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::Deinit()
|
|
{
|
|
if (!m_init)
|
|
{
|
|
return HGFALSE;
|
|
}
|
|
|
|
if (!m_deviceList.empty())
|
|
{
|
|
return HGFALSE;
|
|
}
|
|
|
|
sane_exit();
|
|
m_hotPlugEventFunc = NULL;
|
|
m_hotPlugEventParam = NULL;
|
|
m_init = HGFALSE;
|
|
return HGTRUE;
|
|
}
|
|
|
|
HGChar** HGLibDeviceImpl::GetNameList()
|
|
{
|
|
const SANE_Device **device = NULL;
|
|
sane_get_devices(&device, SANE_TRUE);
|
|
if (NULL == device)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
std::vector<std::string> devNameList;
|
|
|
|
const SANE_Device** p = device;
|
|
while (NULL != *p)
|
|
{
|
|
devNameList.push_back((*p)->name);
|
|
++p;
|
|
}
|
|
|
|
if (devNameList.empty())
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
HGChar** nameList = (HGChar **)malloc((devNameList.size() + 1) * sizeof(HGChar *));
|
|
if (NULL != nameList)
|
|
{
|
|
nameList[devNameList.size()] = NULL;
|
|
for (int i = 0; i < (int)devNameList.size(); ++i)
|
|
{
|
|
nameList[i] = (HGChar *)malloc(devNameList[i].size() + 1);
|
|
if (NULL != nameList[i])
|
|
strcpy(nameList[i], devNameList[i].c_str());
|
|
}
|
|
}
|
|
|
|
return nameList;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::ReleaseNameList(HGChar** deviceName)
|
|
{
|
|
if (NULL == deviceName)
|
|
{
|
|
return HGFALSE;
|
|
}
|
|
|
|
HGChar** p = deviceName;
|
|
while (0 != *p)
|
|
{
|
|
free(*p);
|
|
++p;
|
|
}
|
|
|
|
free(deviceName);
|
|
return HGTRUE;
|
|
}
|
|
|
|
HGLibDeviceImpl* HGLibDeviceImpl::Open(const HGChar* deviceName)
|
|
{
|
|
SANE_Handle devHandle = NULL;
|
|
sane_open(deviceName, &devHandle);
|
|
if (NULL == devHandle)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
HGLibDeviceImpl* deviceImpl = new HGLibDeviceImpl;
|
|
deviceImpl->m_devHandle = devHandle;
|
|
deviceImpl->m_devName = deviceName;
|
|
m_deviceList[devHandle] = deviceImpl;
|
|
return deviceImpl;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::Close()
|
|
{
|
|
assert(NULL != m_devHandle);
|
|
assert(!m_devName.empty());
|
|
|
|
StopScan();
|
|
sane_close(m_devHandle);
|
|
m_devHandle = NULL;
|
|
m_devName.clear();
|
|
|
|
std::map<SANE_Handle, HGLibDeviceImpl*>::iterator iter;
|
|
for (iter = m_deviceList.begin(); iter != m_deviceList.end(); ++iter)
|
|
{
|
|
if (iter->second == this)
|
|
{
|
|
m_deviceList.erase(iter);
|
|
break;
|
|
}
|
|
}
|
|
|
|
delete this;
|
|
return HGTRUE;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::GetType(HGChar *type, HGUInt maxLen)
|
|
{
|
|
assert(NULL != m_devHandle);
|
|
return GetValueStr256(0x8855, type, maxLen);
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::GetSN(HGChar* sn, HGUInt maxLen)
|
|
{
|
|
assert(NULL != m_devHandle);
|
|
return GetValueStr256(0x8856, sn, maxLen);
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::GetFWVersion(HGChar* fwVersion, HGUInt maxLen)
|
|
{
|
|
assert(NULL != m_devHandle);
|
|
return GetValueStr256(0x8857, fwVersion, maxLen);
|
|
}
|
|
|
|
HGInt HGLibDeviceImpl::GetRollerCount()
|
|
{
|
|
assert(NULL != m_devHandle);
|
|
HGInt ret = -1;
|
|
GetValueInt32(0x9902, &ret);
|
|
return ret;
|
|
}
|
|
|
|
HGInt HGLibDeviceImpl::GetTotalCount()
|
|
{
|
|
assert(NULL != m_devHandle);
|
|
HGInt ret = -1;
|
|
GetValueInt32(0x8849, &ret);
|
|
return ret;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::ClearRollerCount()
|
|
{
|
|
assert(NULL != m_devHandle);
|
|
|
|
std::string userName = "user";
|
|
std::string password;
|
|
|
|
#if defined(OEM_HANWANG)
|
|
password = "hanvonscan";
|
|
#elif defined(OEM_LISICHENG)
|
|
password = "lanxum";
|
|
#elif defined(OEM_CANGTIAN)
|
|
password = "cumtenn";
|
|
#elif defined(OEM_ZHONGJING)
|
|
password = "microtek";
|
|
#elif defined(OEM_ZIGUANG)
|
|
password = "uniscan";
|
|
#elif defined(OEM_NEUTRAL)
|
|
password = "scan";
|
|
#elif defined(OEM_DELI)
|
|
password = "deliscan";
|
|
#else
|
|
password = "huagoscan";
|
|
#endif
|
|
|
|
HGBool ret = Login(userName.c_str(), password.c_str());
|
|
if (ret)
|
|
{
|
|
ret = SetValueInt32(0x9902, 0);
|
|
Logout();
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::SetParam(HGUInt option, const HGVoid* data)
|
|
{
|
|
assert(NULL != m_devHandle);
|
|
if (NULL == data)
|
|
return HGFALSE;
|
|
|
|
const char *optionName = GetOptionName(option);
|
|
if (NULL == optionName)
|
|
return HGFALSE;
|
|
|
|
HGBool ret = HGFALSE;
|
|
SANE_Int num_dev_options = 0;
|
|
m_statusCode = sane_control_option(m_devHandle, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL);
|
|
for (int i = 1; i < num_dev_options; ++i)
|
|
{
|
|
const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, i);
|
|
if (NULL == desp)
|
|
continue;
|
|
|
|
const char* name = desp->name;
|
|
while (' ' == *name)
|
|
++name;
|
|
|
|
if (0 == strcmp(optionName, name))
|
|
{
|
|
if (SANE_TYPE_STRING == desp->type)
|
|
{
|
|
SANE_Char* value = (SANE_Char*)GetOptionEnumValue(*(HGUInt*)data);
|
|
if (NULL != value)
|
|
{
|
|
m_statusCode = sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, value, NULL);
|
|
if (SANE_STATUS_GOOD == m_statusCode)
|
|
ret = HGTRUE;
|
|
}
|
|
}
|
|
else if (SANE_TYPE_INT == desp->type)
|
|
{
|
|
SANE_Int value = (SANE_Int)(*(HGInt*)data);
|
|
m_statusCode = sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, &value, NULL);
|
|
if (SANE_STATUS_GOOD == m_statusCode)
|
|
ret = HGTRUE;
|
|
}
|
|
else if (SANE_TYPE_FIXED == desp->type)
|
|
{
|
|
SANE_Fixed value = SANE_FIX(*(HGDouble*)data);
|
|
m_statusCode = sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, &value, NULL);
|
|
if (SANE_STATUS_GOOD == m_statusCode)
|
|
ret = HGTRUE;
|
|
}
|
|
else if (SANE_TYPE_BOOL == desp->type)
|
|
{
|
|
SANE_Bool value = (SANE_Bool)(*(HGBool*)data);
|
|
m_statusCode = sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, &value, NULL);
|
|
if (SANE_STATUS_GOOD == m_statusCode)
|
|
ret = HGTRUE;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
HGLibDeviceParamGroup* HGLibDeviceImpl::GetParamGroupList(HGUInt* count)
|
|
{
|
|
assert(NULL != m_devHandle);
|
|
if (NULL == count)
|
|
return NULL;
|
|
|
|
std::vector<DeviceParamsGroup> devParams;
|
|
|
|
SANE_Int num_dev_options = 0;
|
|
m_statusCode = sane_control_option(m_devHandle, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL);
|
|
for (int i = 1; i < num_dev_options; ++i)
|
|
{
|
|
const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, i);
|
|
if (NULL == desp)
|
|
continue;
|
|
|
|
const char* name = desp->name;
|
|
while (' ' == *name)
|
|
++name;
|
|
|
|
if (SANE_TYPE_GROUP == desp->type)
|
|
{
|
|
DeviceParamsGroup group;
|
|
group.groupName = name;
|
|
devParams.push_back(group);
|
|
}
|
|
else if (SANE_TYPE_STRING == desp->type)
|
|
{
|
|
char value[256] = { 0 };
|
|
m_statusCode = sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, value, NULL);
|
|
|
|
DeviceParam devParam;
|
|
devParam.option = name;
|
|
devParam.valueType = HGLIB_OPTION_VALUETYPE_ENUM;
|
|
devParam.stringValue = value;
|
|
|
|
assert(SANE_CONSTRAINT_STRING_LIST == desp->constraint_type);
|
|
|
|
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_ENUMLIST;
|
|
const SANE_String_Const* p = desp->constraint.string_list;
|
|
while (NULL != *p)
|
|
{
|
|
devParam.stringValueList.push_back(*p);
|
|
++p;
|
|
}
|
|
|
|
assert(!devParams.empty());
|
|
devParams[devParams.size() - 1].devParams.push_back(devParam);
|
|
}
|
|
else if (SANE_TYPE_INT == desp->type)
|
|
{
|
|
SANE_Int value = 0;
|
|
m_statusCode = sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL);
|
|
|
|
DeviceParam devParam;
|
|
devParam.option = name;
|
|
devParam.valueType = HGLIB_OPTION_VALUETYPE_INT;
|
|
devParam.intValue = (int)value;
|
|
|
|
if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type)
|
|
{
|
|
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_INTLIST;
|
|
const SANE_Word* p = desp->constraint.word_list;
|
|
for (SANE_Int i = 0; i < p[0]; ++i)
|
|
{
|
|
devParam.intValueList.push_back(p[i + 1]);
|
|
}
|
|
}
|
|
else if (SANE_CONSTRAINT_RANGE == desp->constraint_type)
|
|
{
|
|
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_INTRANGE;
|
|
devParam.intValueMin = desp->constraint.range->min;
|
|
devParam.intValueMax = desp->constraint.range->max;
|
|
}
|
|
|
|
assert(!devParams.empty());
|
|
devParams[devParams.size() - 1].devParams.push_back(devParam);
|
|
}
|
|
else if (SANE_TYPE_FIXED == desp->type)
|
|
{
|
|
SANE_Word value = 0;
|
|
m_statusCode = sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL);
|
|
|
|
DeviceParam devParam;
|
|
devParam.option = name;
|
|
devParam.valueType = HGLIB_OPTION_VALUETYPE_DOUBLE;
|
|
devParam.doubleValue = SANE_UNFIX(value);
|
|
|
|
if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type)
|
|
{
|
|
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_DOUBLELIST;
|
|
const SANE_Word* p = desp->constraint.word_list;
|
|
for (SANE_Int i = 0; i < p[0]; ++i)
|
|
{
|
|
devParam.doubleValueList.push_back(SANE_UNFIX(p[i + 1]));
|
|
}
|
|
}
|
|
else if (SANE_CONSTRAINT_RANGE == desp->constraint_type)
|
|
{
|
|
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_DOUBLERANGE;
|
|
devParam.doubleValueMin = SANE_UNFIX(desp->constraint.range->min);
|
|
devParam.doubleValueMax = SANE_UNFIX(desp->constraint.range->max);
|
|
}
|
|
|
|
assert(!devParams.empty());
|
|
devParams[devParams.size() - 1].devParams.push_back(devParam);
|
|
}
|
|
else if (SANE_TYPE_BOOL == desp->type)
|
|
{
|
|
SANE_Bool value = 0;
|
|
m_statusCode = sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL);
|
|
|
|
DeviceParam devParam;
|
|
devParam.option = name;
|
|
devParam.valueType = HGLIB_OPTION_VALUETYPE_BOOL;
|
|
devParam.boolValue = (bool)value;
|
|
|
|
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_NULL;
|
|
|
|
assert(!devParams.empty());
|
|
devParams[devParams.size() - 1].devParams.push_back(devParam);
|
|
}
|
|
}
|
|
|
|
*count = (HGUInt)devParams.size();
|
|
HGLibDeviceParamGroup* paramGroup = (HGLibDeviceParamGroup*)malloc((*count) * sizeof(HGLibDeviceParamGroup));
|
|
if (NULL != paramGroup)
|
|
{
|
|
for (int i = 0; i < (int)devParams.size(); ++i)
|
|
{
|
|
paramGroup[i].group = GetGroupName(devParams[i].groupName.c_str());
|
|
paramGroup[i].paramCount = (HGUInt)devParams[i].devParams.size();
|
|
paramGroup[i].param = (HGLibDeviceParam*)malloc(paramGroup[i].paramCount * sizeof(HGLibDeviceParam));
|
|
if (NULL != paramGroup[i].param)
|
|
{
|
|
for (int j = 0; j < (int)devParams[i].devParams.size(); ++j)
|
|
{
|
|
HGLibDeviceParam& dest = paramGroup[i].param[j];
|
|
DeviceParam& src = devParams[i].devParams[j];
|
|
|
|
dest.option = GetOptionName(src.option.c_str());
|
|
dest.type = src.valueType;
|
|
if (HGLIB_OPTION_VALUETYPE_INT == dest.type)
|
|
dest.intValue = src.intValue;
|
|
else if (HGLIB_OPTION_VALUETYPE_DOUBLE == dest.type)
|
|
dest.doubleValue = src.doubleValue;
|
|
else if (HGLIB_OPTION_VALUETYPE_BOOL == dest.type)
|
|
dest.boolValue = (HGBool)src.boolValue;
|
|
else if (HGLIB_OPTION_VALUETYPE_ENUM == dest.type)
|
|
dest.enumValue = GetOptionEnumValue(src.stringValue.c_str());
|
|
|
|
dest.rangeType = src.rangeType;
|
|
if (HGLIB_OPTION_VALUERANGETYPE_INTLIST == dest.rangeType)
|
|
{
|
|
dest.intValueList.count = (HGUInt)src.intValueList.size();
|
|
dest.intValueList.value = (HGInt *)malloc(dest.intValueList.count * sizeof(HGInt));
|
|
if (NULL != dest.intValueList.value)
|
|
{
|
|
for (int k = 0; k < (int)src.intValueList.size(); ++k)
|
|
{
|
|
dest.intValueList.value[k] = src.intValueList[k];
|
|
}
|
|
}
|
|
}
|
|
else if (HGLIB_OPTION_VALUERANGETYPE_DOUBLELIST == dest.rangeType)
|
|
{
|
|
dest.doubleValueList.count = (HGUInt)src.doubleValueList.size();
|
|
dest.doubleValueList.value = (HGDouble*)malloc(dest.doubleValueList.count * sizeof(HGDouble));
|
|
if (NULL != dest.doubleValueList.value)
|
|
{
|
|
for (int k = 0; k < (int)src.doubleValueList.size(); ++k)
|
|
{
|
|
dest.doubleValueList.value[k] = src.doubleValueList[k];
|
|
}
|
|
}
|
|
}
|
|
else if (HGLIB_OPTION_VALUERANGETYPE_INTRANGE == dest.rangeType)
|
|
{
|
|
dest.intValueRange.minValue = src.intValueMin;
|
|
dest.intValueRange.maxValue = src.intValueMax;
|
|
}
|
|
else if (HGLIB_OPTION_VALUERANGETYPE_DOUBLERANGE == dest.rangeType)
|
|
{
|
|
dest.doubleValueRange.minValue = src.doubleValueMin;
|
|
dest.doubleValueRange.maxValue = src.doubleValueMax;
|
|
}
|
|
else if (HGLIB_OPTION_VALUERANGETYPE_ENUMLIST == dest.rangeType)
|
|
{
|
|
dest.enumValueList.count = (HGUInt)src.stringValueList.size();
|
|
dest.enumValueList.value = (HGUInt*)malloc(dest.enumValueList.count * sizeof(HGUInt));
|
|
if (NULL != dest.enumValueList.value)
|
|
{
|
|
for (int k = 0; k < (int)src.stringValueList.size(); ++k)
|
|
{
|
|
dest.enumValueList.value[k] = GetOptionEnumValue(src.stringValueList[k].c_str());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return paramGroup;
|
|
}
|
|
|
|
HGLibDeviceParam* HGLibDeviceImpl::GetParam(HGUInt option)
|
|
{
|
|
assert(NULL != m_devHandle);
|
|
const char* optionName = GetOptionName(option);
|
|
if (NULL == optionName)
|
|
return NULL;
|
|
|
|
HGLibDeviceParam* param = NULL;
|
|
SANE_Int num_dev_options = 0;
|
|
m_statusCode = sane_control_option(m_devHandle, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL);
|
|
for (int i = 1; i < num_dev_options; ++i)
|
|
{
|
|
const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, i);
|
|
if (NULL == desp)
|
|
continue;
|
|
|
|
const char* name = desp->name;
|
|
while (' ' == *name)
|
|
++name;
|
|
|
|
if (0 == strcmp(optionName, name))
|
|
{
|
|
DeviceParam devParam;
|
|
devParam.option = name;
|
|
|
|
if (SANE_TYPE_STRING == desp->type)
|
|
{
|
|
char value[256] = { 0 };
|
|
m_statusCode = sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, value, NULL);
|
|
|
|
devParam.valueType = HGLIB_OPTION_VALUETYPE_ENUM;
|
|
devParam.stringValue = value;
|
|
|
|
assert(SANE_CONSTRAINT_STRING_LIST == desp->constraint_type);
|
|
|
|
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_ENUMLIST;
|
|
const SANE_String_Const* p = desp->constraint.string_list;
|
|
while (NULL != *p)
|
|
{
|
|
devParam.stringValueList.push_back(*p);
|
|
++p;
|
|
}
|
|
}
|
|
else if (SANE_TYPE_INT == desp->type)
|
|
{
|
|
SANE_Int value = 0;
|
|
m_statusCode = sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL);
|
|
|
|
devParam.valueType = HGLIB_OPTION_VALUETYPE_INT;
|
|
devParam.intValue = (int)value;
|
|
|
|
if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type)
|
|
{
|
|
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_INTLIST;
|
|
const SANE_Word* p = desp->constraint.word_list;
|
|
for (SANE_Int i = 0; i < p[0]; ++i)
|
|
{
|
|
devParam.intValueList.push_back(p[i + 1]);
|
|
}
|
|
}
|
|
else if (SANE_CONSTRAINT_RANGE == desp->constraint_type)
|
|
{
|
|
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_INTRANGE;
|
|
devParam.intValueMin = desp->constraint.range->min;
|
|
devParam.intValueMax = desp->constraint.range->max;
|
|
}
|
|
}
|
|
else if (SANE_TYPE_FIXED == desp->type)
|
|
{
|
|
SANE_Word value = 0;
|
|
m_statusCode = sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL);
|
|
|
|
devParam.valueType = HGLIB_OPTION_VALUETYPE_DOUBLE;
|
|
devParam.doubleValue = SANE_UNFIX(value);
|
|
|
|
if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type)
|
|
{
|
|
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_DOUBLELIST;
|
|
const SANE_Word* p = desp->constraint.word_list;
|
|
for (SANE_Int i = 0; i < p[0]; ++i)
|
|
{
|
|
devParam.doubleValueList.push_back(SANE_UNFIX(p[i + 1]));
|
|
}
|
|
}
|
|
else if (SANE_CONSTRAINT_RANGE == desp->constraint_type)
|
|
{
|
|
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_DOUBLERANGE;
|
|
devParam.doubleValueMin = SANE_UNFIX(desp->constraint.range->min);
|
|
devParam.doubleValueMax = SANE_UNFIX(desp->constraint.range->max);
|
|
}
|
|
}
|
|
else if (SANE_TYPE_BOOL == desp->type)
|
|
{
|
|
SANE_Bool value = 0;
|
|
m_statusCode = sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL);
|
|
|
|
devParam.valueType = HGLIB_OPTION_VALUETYPE_BOOL;
|
|
devParam.boolValue = (bool)value;
|
|
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_NULL;
|
|
}
|
|
|
|
assert(0 != devParam.valueType);
|
|
param = (HGLibDeviceParam*)malloc(sizeof(HGLibDeviceParam));
|
|
if (NULL != param)
|
|
{
|
|
param->option = GetOptionName(devParam.option.c_str());
|
|
param->type = devParam.valueType;
|
|
if (HGLIB_OPTION_VALUETYPE_INT == param->type)
|
|
param->intValue = devParam.intValue;
|
|
else if (HGLIB_OPTION_VALUETYPE_DOUBLE == param->type)
|
|
param->doubleValue = devParam.doubleValue;
|
|
else if (HGLIB_OPTION_VALUETYPE_BOOL == param->type)
|
|
param->boolValue = (HGBool)devParam.boolValue;
|
|
else if (HGLIB_OPTION_VALUETYPE_ENUM == param->type)
|
|
param->enumValue = GetOptionEnumValue(devParam.stringValue.c_str());
|
|
|
|
param->rangeType = devParam.rangeType;
|
|
if (HGLIB_OPTION_VALUERANGETYPE_INTLIST == param->rangeType)
|
|
{
|
|
param->intValueList.count = (HGUInt)devParam.intValueList.size();
|
|
param->intValueList.value = (HGInt*)malloc(param->intValueList.count * sizeof(HGInt));
|
|
if (NULL != param->intValueList.value)
|
|
{
|
|
for (int k = 0; k < (int)devParam.intValueList.size(); ++k)
|
|
{
|
|
param->intValueList.value[k] = devParam.intValueList[k];
|
|
}
|
|
}
|
|
}
|
|
else if (HGLIB_OPTION_VALUERANGETYPE_DOUBLELIST == param->rangeType)
|
|
{
|
|
param->doubleValueList.count = (HGUInt)devParam.doubleValueList.size();
|
|
param->doubleValueList.value = (HGDouble*)malloc(param->doubleValueList.count * sizeof(HGDouble));
|
|
if (NULL != param->doubleValueList.value)
|
|
{
|
|
for (int k = 0; k < (int)devParam.doubleValueList.size(); ++k)
|
|
{
|
|
param->doubleValueList.value[k] = devParam.doubleValueList[k];
|
|
}
|
|
}
|
|
}
|
|
else if (HGLIB_OPTION_VALUERANGETYPE_INTRANGE == param->rangeType)
|
|
{
|
|
param->intValueRange.minValue = devParam.intValueMin;
|
|
param->intValueRange.maxValue = devParam.intValueMax;
|
|
}
|
|
else if (HGLIB_OPTION_VALUERANGETYPE_DOUBLERANGE == param->rangeType)
|
|
{
|
|
param->doubleValueRange.minValue = devParam.doubleValueMin;
|
|
param->doubleValueRange.maxValue = devParam.doubleValueMax;
|
|
}
|
|
else if (HGLIB_OPTION_VALUERANGETYPE_ENUMLIST == param->rangeType)
|
|
{
|
|
param->enumValueList.count = (HGUInt)devParam.stringValueList.size();
|
|
param->enumValueList.value = (HGUInt*)malloc(param->enumValueList.count * sizeof(HGUInt));
|
|
if (NULL != param->enumValueList.value)
|
|
{
|
|
for (int k = 0; k < (int)devParam.stringValueList.size(); ++k)
|
|
{
|
|
param->enumValueList.value[k] = GetOptionEnumValue(devParam.stringValueList[k].c_str());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return param;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::ReleaseParamGroupList(HGLibDeviceParamGroup* paramGroup, HGUInt count)
|
|
{
|
|
if (NULL == paramGroup || 0 == count)
|
|
{
|
|
return HGFALSE;
|
|
}
|
|
|
|
for (HGUInt i = 0; i < count; ++i)
|
|
{
|
|
for (HGUInt j = 0; j < paramGroup[i].paramCount; ++j)
|
|
{
|
|
if (HGLIB_OPTION_VALUERANGETYPE_INTLIST == paramGroup[i].param[j].rangeType)
|
|
free(paramGroup[i].param[j].intValueList.value);
|
|
else if (HGLIB_OPTION_VALUERANGETYPE_DOUBLELIST == paramGroup[i].param[j].rangeType)
|
|
free(paramGroup[i].param[j].doubleValueList.value);
|
|
else if (HGLIB_OPTION_VALUERANGETYPE_ENUMLIST == paramGroup[i].param[j].rangeType)
|
|
free(paramGroup[i].param[j].enumValueList.value);
|
|
}
|
|
|
|
free(paramGroup[i].param);
|
|
}
|
|
|
|
free(paramGroup);
|
|
return HGTRUE;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::ReleaseParam(HGLibDeviceParam* param)
|
|
{
|
|
if (NULL == param)
|
|
{
|
|
return HGFALSE;
|
|
}
|
|
|
|
if (HGLIB_OPTION_VALUERANGETYPE_INTLIST == param->rangeType)
|
|
free(param->intValueList.value);
|
|
else if (HGLIB_OPTION_VALUERANGETYPE_DOUBLELIST == param->rangeType)
|
|
free(param->doubleValueList.value);
|
|
else if (HGLIB_OPTION_VALUERANGETYPE_ENUMLIST == param->rangeType)
|
|
free(param->enumValueList.value);
|
|
|
|
free(param);
|
|
return HGTRUE;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::ResetParam()
|
|
{
|
|
assert(NULL != m_devHandle);
|
|
|
|
HGBool ret = HGFALSE;
|
|
|
|
SANE_Int num_dev_options = 0;
|
|
m_statusCode = sane_control_option(m_devHandle, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL);
|
|
for (int i = 1; i < num_dev_options; ++i)
|
|
{
|
|
const SANE_Option_Descriptor* desp = sane_get_option_descriptor(m_devHandle, i);
|
|
if (NULL == desp)
|
|
continue;
|
|
|
|
const char* name = desp->name;
|
|
while (' ' == *name)
|
|
++name;
|
|
|
|
if (0 == strcmp(SANE_STD_OPT_NAME_RESTORE, name) && SANE_TYPE_BUTTON == desp->type)
|
|
{
|
|
m_statusCode = sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, NULL, NULL);
|
|
if (SANE_STATUS_GOOD == m_statusCode)
|
|
ret = HGTRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::IsPaperOn()
|
|
{
|
|
SANE_Bool isOn = SANE_FALSE;
|
|
unsigned int len = sizeof(SANE_Bool);
|
|
m_statusCode = sane_io_control(m_devHandle, IO_CTRL_CODE_GET_PAPER_ON, &isOn, &len);
|
|
if (SANE_STATUS_GOOD == m_statusCode && isOn)
|
|
return HGTRUE;
|
|
return HGFALSE;
|
|
}
|
|
|
|
HGInt HGLibDeviceImpl::GetStatus()
|
|
{
|
|
SANE_Bool isOn = SANE_FALSE;
|
|
unsigned int len = sizeof(SANE_Bool);
|
|
m_statusCode = sane_io_control(m_devHandle, IO_CTRL_CODE_GET_PAPER_ON, &isOn, &len);
|
|
if (SANE_STATUS_GOOD == m_statusCode)
|
|
return isOn ? 1 : 0;
|
|
return -1;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::Restart()
|
|
{
|
|
SANE_Power stat = SANE_POWER_RESTART;
|
|
unsigned int len = sizeof(SANE_Power);
|
|
m_statusCode = sane_io_control(m_devHandle, IO_CTRL_CODE_SET_POWER_LEVEL, &stat, &len);
|
|
if (SANE_STATUS_GOOD == m_statusCode)
|
|
return HGTRUE;
|
|
return HGFALSE;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::ShutDown()
|
|
{
|
|
SANE_Power stat = SANE_POWER_SHUTDOWN;
|
|
unsigned int len = sizeof(SANE_Power);
|
|
m_statusCode = sane_io_control(m_devHandle, IO_CTRL_CODE_SET_POWER_LEVEL, &stat, &len);
|
|
if (SANE_STATUS_GOOD == m_statusCode)
|
|
return HGTRUE;
|
|
return HGFALSE;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::StartScan(HGLibDeviceScanEventFunc eventFunc, HGPointer eventParam,
|
|
HGLibDeviceScanImageFunc imageFunc, HGPointer imageParam)
|
|
{
|
|
HGBool ret = HGFALSE;
|
|
|
|
HGBase_EnterLock(m_lock);
|
|
if (!m_scanning)
|
|
{
|
|
HGLibDeviceParam* devParam = GetParam(HGLIB_OPTION_NAME_FBL);
|
|
if (NULL != devParam && devParam->type == HGLIB_OPTION_VALUETYPE_INT)
|
|
{
|
|
m_dpi = devParam->intValue;
|
|
ReleaseParam(devParam);
|
|
}
|
|
|
|
m_eventFunc = eventFunc;
|
|
m_eventParam = eventParam;
|
|
m_imageFunc = imageFunc;
|
|
m_imageParam = imageParam;
|
|
m_scanning = HGTRUE;
|
|
|
|
m_statusCode = sane_start(m_devHandle);
|
|
if (SANE_STATUS_GOOD != m_statusCode)
|
|
{
|
|
m_scanning = HGFALSE;
|
|
m_eventFunc = NULL;
|
|
m_eventParam = NULL;
|
|
m_imageFunc = NULL;
|
|
m_imageParam = NULL;
|
|
m_dpi = 0;
|
|
}
|
|
else
|
|
{
|
|
ret = HGTRUE;
|
|
}
|
|
}
|
|
HGBase_LeaveLock(m_lock);
|
|
|
|
return ret;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::StopScan()
|
|
{
|
|
HGBool ret = HGFALSE;
|
|
|
|
sane_cancel(m_devHandle);
|
|
HGBase_EnterLock(m_lock);
|
|
if (m_scanning)
|
|
{
|
|
m_eventFunc = NULL;
|
|
m_eventParam = NULL;
|
|
m_imageFunc = NULL;
|
|
m_imageParam = NULL;
|
|
m_scanning = HGFALSE;
|
|
m_dpi = 0;
|
|
ret = HGTRUE;
|
|
}
|
|
HGBase_LeaveLock(m_lock);
|
|
|
|
return ret;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::StopScanAsyn()
|
|
{
|
|
return StopScan();
|
|
}
|
|
|
|
HGInt HGLibDeviceImpl::GetOperateCode()
|
|
{
|
|
return m_statusCode;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::Login(const HGChar *user, const HGChar *pwd)
|
|
{
|
|
if (NULL == user || strlen(user) >= 32
|
|
|| NULL == pwd || strlen(pwd) >= 32)
|
|
{
|
|
return HGFALSE;
|
|
}
|
|
|
|
HGChar value[256] = {0};
|
|
strcpy(value, user);
|
|
strcpy(value + 32, pwd);
|
|
return SetValueStr256(0x9900, value);
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::Logout()
|
|
{
|
|
HGChar value[256] = {0};
|
|
return SetValueStr256(0x9901, value);
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::SetValueInt32(HGUInt optionId, HGInt value)
|
|
{
|
|
SANE_Int v = (SANE_Int)value;
|
|
m_statusCode = sane_control_option(m_devHandle, (SANE_Int)optionId, SANE_ACTION_SET_VALUE, &v, NULL);
|
|
return (SANE_STATUS_GOOD == m_statusCode) ? HGTRUE : HGFALSE;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::GetValueInt32(HGUInt optionId, HGInt *value)
|
|
{
|
|
SANE_Int v = 0;
|
|
m_statusCode = sane_control_option(m_devHandle, (SANE_Int)optionId, SANE_ACTION_GET_VALUE, &v, NULL);
|
|
if (SANE_STATUS_GOOD != m_statusCode)
|
|
{
|
|
return HGFALSE;
|
|
}
|
|
|
|
*value = (HGInt)v;
|
|
return HGTRUE;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::SetValueStr256(HGUInt optionId, const HGChar *value)
|
|
{
|
|
if (NULL == value || strlen(value) >= 256)
|
|
{
|
|
return HGFALSE;
|
|
}
|
|
|
|
const char *v = value;
|
|
m_statusCode = sane_control_option(m_devHandle, (SANE_Int)optionId, SANE_ACTION_SET_VALUE, (void*)v, NULL);
|
|
return (SANE_STATUS_GOOD == m_statusCode) ? HGTRUE : HGFALSE;
|
|
}
|
|
|
|
HGBool HGLibDeviceImpl::GetValueStr256(HGUInt optionId, HGChar *value, HGUInt maxLen)
|
|
{
|
|
if (NULL == value || 0 == maxLen)
|
|
{
|
|
return HGFALSE;
|
|
}
|
|
|
|
char v[256] = {0};
|
|
m_statusCode = sane_control_option(m_devHandle, (SANE_Int)optionId, SANE_ACTION_GET_VALUE, v, NULL);
|
|
if (SANE_STATUS_GOOD != m_statusCode)
|
|
{
|
|
return HGFALSE;
|
|
}
|
|
|
|
if (maxLen <= strlen(v))
|
|
{
|
|
return HGFALSE;
|
|
}
|
|
|
|
strcpy(value, v);
|
|
return HGTRUE;
|
|
}
|
|
|
|
const char* HGLibDeviceImpl::GetGroupName(HGUInt group)
|
|
{
|
|
if (group > HGLIB_GROUP_NAME_PAPERFEEDING)
|
|
return NULL;
|
|
return GROUP_NAME[group];
|
|
}
|
|
|
|
HGUInt HGLibDeviceImpl::GetGroupName(const char* group)
|
|
{
|
|
if (NULL == group)
|
|
return 0;
|
|
|
|
HGUInt ret = 0;
|
|
for (int i = 1; i < sizeof(GROUP_NAME) / sizeof(const char*); ++i)
|
|
{
|
|
if (0 == strcmp(group, GROUP_NAME[i]))
|
|
{
|
|
ret = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
const char* HGLibDeviceImpl::GetOptionName(HGUInt option)
|
|
{
|
|
if (option > HGLIB_OPTION_NAME_CKSSFWZFMBL)
|
|
return NULL;
|
|
return OPTION_NAME[option];
|
|
}
|
|
|
|
HGUInt HGLibDeviceImpl::GetOptionName(const char* option)
|
|
{
|
|
if (NULL == option)
|
|
return 0;
|
|
|
|
HGUInt ret = 0;
|
|
for (int i = 1; i < sizeof(OPTION_NAME) / sizeof(const char*); ++i)
|
|
{
|
|
if (0 == strcmp(option, OPTION_NAME[i]))
|
|
{
|
|
ret = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
const char* HGLibDeviceImpl::GetOptionEnumValue(HGUInt enumValue)
|
|
{
|
|
if (enumValue > HGLIB_OPTION_ENUMVALUE_SZTPCL_SCTXBJY)
|
|
return NULL;
|
|
return OPTION_ENUMVALUE[enumValue];
|
|
}
|
|
|
|
HGUInt HGLibDeviceImpl::GetOptionEnumValue(const char* enumValue)
|
|
{
|
|
if (NULL == enumValue)
|
|
return 0;
|
|
|
|
HGUInt ret = 0;
|
|
for (int i = 1; i < sizeof(OPTION_ENUMVALUE) / sizeof(const char*); ++i)
|
|
{
|
|
if (0 == strcmp(enumValue, OPTION_ENUMVALUE[i]))
|
|
{
|
|
ret = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int HGLibDeviceImpl::sane_ex_callback(SANE_Handle hdev, int code, void* data, unsigned int* len, void* param)
|
|
{
|
|
(void)param;
|
|
|
|
switch (code)
|
|
{
|
|
case SANE_EVENT_DEVICE_ARRIVED:
|
|
{
|
|
SANE_Device* sane_dev = (SANE_Device*)data;
|
|
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_DEVICE_ARRIVED, name=%s", Utf8ToStdString(sane_dev->name).c_str());
|
|
|
|
if (NULL != m_hotPlugEventFunc)
|
|
m_hotPlugEventFunc(HGLIB_DEVHOTPLUG_EVENT_ARRIVE, sane_dev->name, m_hotPlugEventParam);
|
|
}
|
|
break;
|
|
case SANE_EVENT_DEVICE_LEFT:
|
|
{
|
|
SANE_Device* sane_dev = (SANE_Device*)data;
|
|
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_DEVICE_LEFT, name=%s", Utf8ToStdString(sane_dev->name).c_str());
|
|
|
|
if (NULL != m_hotPlugEventFunc)
|
|
m_hotPlugEventFunc(HGLIB_DEVHOTPLUG_EVENT_REMOVE, sane_dev->name, m_hotPlugEventParam);
|
|
}
|
|
break;
|
|
case SANE_EVENT_WORKING:
|
|
{
|
|
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_WORKING, msg=%s", Utf8ToStdString((char*)data).c_str());
|
|
|
|
HGLibDeviceImpl* deviceImpl = m_deviceList[hdev];
|
|
if (NULL != deviceImpl->m_eventFunc)
|
|
{
|
|
deviceImpl->m_eventFunc((HGLibDevice)deviceImpl, HGLIB_DEVSCAN_EVENT_BEGIN,
|
|
0, NULL, deviceImpl->m_eventParam);
|
|
deviceImpl->m_eventFunc((HGLibDevice)deviceImpl, HGLIB_DEVSCAN_EVENT_INFO,
|
|
0, (const char*)data, deviceImpl->m_eventParam);
|
|
}
|
|
}
|
|
break;
|
|
case SANE_EVENT_SCAN_FINISHED:
|
|
{
|
|
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_SCAN_FINISHED, msg=%s", Utf8ToStdString((char*)data).c_str());
|
|
|
|
HGLibDeviceImpl* deviceImpl = m_deviceList[hdev];
|
|
if (NULL != deviceImpl->m_eventFunc)
|
|
{
|
|
deviceImpl->m_eventFunc((HGLibDevice)deviceImpl, HGLIB_DEVSCAN_EVENT_INFO,
|
|
(HGInt)(*len), (const char*)data, deviceImpl->m_eventParam);
|
|
}
|
|
|
|
if (NULL != deviceImpl->m_eventFunc)
|
|
{
|
|
deviceImpl->m_eventFunc((HGLibDevice)deviceImpl, HGLIB_DEVSCAN_EVENT_END,
|
|
0, NULL, deviceImpl->m_eventParam);
|
|
}
|
|
|
|
HGBase_EnterLock(deviceImpl->m_lock);
|
|
deviceImpl->m_eventFunc = NULL;
|
|
deviceImpl->m_eventParam = NULL;
|
|
deviceImpl->m_imageFunc = NULL;
|
|
deviceImpl->m_imageParam = NULL;
|
|
deviceImpl->m_scanning = HGFALSE;
|
|
deviceImpl->m_dpi = 0;
|
|
HGBase_LeaveLock(deviceImpl->m_lock);
|
|
}
|
|
break;
|
|
case SANE_EVENT_STATUS:
|
|
{
|
|
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_STATUS, msg=%s", Utf8ToStdString((char*)data).c_str());
|
|
}
|
|
break;
|
|
case SANE_EVENT_ERROR:
|
|
{
|
|
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_ERROR, msg=%s", Utf8ToStdString((char*)data).c_str());
|
|
}
|
|
break;
|
|
case SANE_EVENT_IMAGE_OK:
|
|
{
|
|
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_IMAGE_OK");
|
|
|
|
SANE_Image* sane_img = (SANE_Image*)data;
|
|
|
|
HGLibDeviceImpl* deviceImpl = m_deviceList[hdev];
|
|
if (NULL != deviceImpl->m_imageFunc)
|
|
{
|
|
HGUInt imgType = 0;
|
|
if (sane_img->header.format == SANE_FRAME_GRAY)
|
|
{
|
|
if (1 == sane_img->header.depth)
|
|
imgType = HGBASE_IMGTYPE_BINARY;
|
|
else if (8 == sane_img->header.depth)
|
|
imgType = HGBASE_IMGTYPE_GRAY;
|
|
}
|
|
else if (sane_img->header.format == SANE_FRAME_RGB)
|
|
imgType = HGBASE_IMGTYPE_RGB;
|
|
|
|
HGByte* data = sane_img->data;
|
|
HGImageInfo imgInfo = { (HGUInt)sane_img->header.pixels_per_line, (HGUInt)sane_img->header.lines,
|
|
imgType, (HGUInt)sane_img->header.bytes_per_line, HGBASE_IMGORIGIN_TOP };
|
|
|
|
HGImage img = NULL;
|
|
HGBase_CreateImageFromData(data, &imgInfo, NULL, 0, HGBASE_IMGORIGIN_TOP, &img);
|
|
if (NULL != img)
|
|
{
|
|
HGBase_SetImageDpi(img, deviceImpl->m_dpi, deviceImpl->m_dpi);
|
|
deviceImpl->m_imageFunc((HGLibDevice)deviceImpl, (HGLibImage)img, deviceImpl->m_imageParam);
|
|
HGBase_DestroyImage(img);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|