1412 lines
40 KiB
C++
1412 lines
40 KiB
C++
#include "HGSaneImpl.hpp"
|
|
#include "../base/HGInc.h"
|
|
#include "../base/HGUtility.h"
|
|
#include "huagao/hgscanner_error.h"
|
|
|
|
HGSaneManagerImpl::HGSaneManagerImpl()
|
|
{
|
|
|
|
}
|
|
|
|
HGSaneManagerImpl::~HGSaneManagerImpl()
|
|
{
|
|
|
|
}
|
|
|
|
HGResult HGSaneManagerImpl::Create()
|
|
{
|
|
std::string archName;
|
|
FILE *file = popen("arch", "r");
|
|
if (NULL != file)
|
|
{
|
|
char str[256] = {0};
|
|
if (NULL != fgets(str, 256, file))
|
|
{
|
|
char *p = str;
|
|
while (0 != *p && '\n' != *p)
|
|
{
|
|
archName.push_back(*p);
|
|
++p;
|
|
}
|
|
}
|
|
|
|
pclose(file);
|
|
}
|
|
|
|
std::string osName;
|
|
FILE* fp = popen("cat /etc/issue | cut -d\' \' -f1", "r");
|
|
if (NULL != fp)
|
|
{
|
|
char buff[1024] = { 0 };
|
|
fread(buff, 1024, 1, fp);
|
|
|
|
int len = (int)strlen(buff);
|
|
for (int i = 0; i < len; ++i)
|
|
{
|
|
if (buff[i] == '\n')
|
|
buff[i] = '\0';
|
|
}
|
|
|
|
osName = buff;
|
|
pclose(fp);
|
|
}
|
|
|
|
if (archName.empty() || osName.empty())
|
|
{
|
|
return HGBASE_ERR_FAIL;
|
|
}
|
|
|
|
if (archName == "mips64")
|
|
archName += "el";
|
|
|
|
char manuPath[] = "/etc/sane.d/dll.d";
|
|
|
|
DIR* dir = opendir(manuPath);
|
|
if (NULL != dir)
|
|
{
|
|
struct dirent* dire = NULL;
|
|
while (dire = readdir(dir))
|
|
{
|
|
if (0 == strcmp(dire->d_name, ".") || 0 == strcmp(dire->d_name, ".."))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
char fileName[256];
|
|
sprintf(fileName, "%s/%s", manuPath, dire->d_name);
|
|
|
|
struct stat filebuf;
|
|
lstat(fileName, &filebuf);
|
|
if (S_ISDIR(filebuf.st_mode))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
std::string manuName;
|
|
FILE *file = fopen(fileName, "r");
|
|
if (NULL != file)
|
|
{
|
|
char str[256] = {0};
|
|
while (NULL != fgets(str, 256, file))
|
|
{
|
|
if ('#' == str[0] || '\n' == str[0])
|
|
{
|
|
continue;
|
|
}
|
|
|
|
char *p = str;
|
|
while (0 != *p && '\n' != *p)
|
|
{
|
|
manuName.push_back(*p);
|
|
++p;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
fclose(file);
|
|
}
|
|
|
|
if (manuName.empty())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
std::pair<std::string, std::string> pr;
|
|
pr.first = manuName;
|
|
|
|
char sanePath[256];
|
|
if (osName == "NeoKylin")
|
|
{
|
|
sprintf(sanePath, "/usr/lib64/sane/libsane-%s.so.1", manuName.c_str());
|
|
}
|
|
else
|
|
{
|
|
sprintf(sanePath, "/usr/lib/%s-linux-gnu/sane/libsane-%s.so.1", archName.c_str(), manuName.c_str());
|
|
}
|
|
pr.second = sanePath;
|
|
|
|
if(!filterDeviceSource(pr.first.c_str()))
|
|
m_vSource.push_back(pr);
|
|
}
|
|
|
|
closedir(dir);
|
|
}
|
|
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneManagerImpl::Destroy()
|
|
{
|
|
if (!m_listSourceImpl.empty())
|
|
{
|
|
return HGBASE_ERR_FAIL;
|
|
}
|
|
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneManagerImpl::GetSourceCount(HGUInt *count)
|
|
{
|
|
if (NULL == count)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
*count = (HGUInt)m_vSource.size();
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneManagerImpl::GetSourceName(HGUInt index, HGChar* name, HGUInt maxLen)
|
|
{
|
|
if (index >= (HGUInt)m_vSource.size() || NULL == name || 0 == maxLen)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
if (maxLen < m_vSource[index].first.size() + 1)
|
|
return HGBASE_ERR_FAIL;
|
|
strcpy(name, m_vSource[index].first.c_str());
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneManagerImpl::OpenSource(HGUInt index, class HGSaneSourceImpl **sourceImpl)
|
|
{
|
|
if (index >= (HGUInt)m_vSource.size() || NULL == sourceImpl)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
HGSaneSourceImpl *newSourceImpl = new HGSaneSourceImpl(this);
|
|
HGResult ret = newSourceImpl->Open(m_vSource[index].first.c_str(), m_vSource[index].second.c_str());
|
|
if (HGBASE_ERR_OK != ret)
|
|
{
|
|
delete newSourceImpl;
|
|
return ret;
|
|
}
|
|
|
|
m_listSourceImpl.push_back(newSourceImpl);
|
|
*sourceImpl = newSourceImpl;
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneManagerImpl::OpenDefaultSource(HGSaneSourceImpl **sourceImpl)
|
|
{
|
|
if (m_vSource.empty() || NULL == sourceImpl)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
HGSaneSourceImpl *newSourceImpl = new HGSaneSourceImpl(this);
|
|
HGResult ret = newSourceImpl->Open(m_vSource[0].first.c_str(), m_vSource[0].second.c_str());
|
|
if (HGBASE_ERR_OK != ret)
|
|
{
|
|
delete newSourceImpl;
|
|
return ret;
|
|
}
|
|
|
|
m_listSourceImpl.push_back(newSourceImpl);
|
|
*sourceImpl = newSourceImpl;
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneManagerImpl::OpenSelectedSource(HGWindow parent, class HGSaneSourceImpl **sourceImpl)
|
|
{
|
|
if (NULL == sourceImpl)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
const char **manuNames = new const char *[m_vSource.size() + 1];
|
|
const char **sanePaths = new const char *[m_vSource.size() + 1];
|
|
for (int i = 0; i < (int)m_vSource.size(); ++i)
|
|
{
|
|
manuNames[i] = m_vSource[i].first.c_str();
|
|
sanePaths[i] = m_vSource[i].second.c_str();
|
|
}
|
|
manuNames[m_vSource.size()] = NULL;
|
|
sanePaths[m_vSource.size()] = NULL;
|
|
|
|
HGDll dll = NULL;
|
|
SANEAPI saneAPI;
|
|
char manuName[256];
|
|
if (-2 == show_srclist_ui(manuNames, sanePaths, parent, &dll, &saneAPI, manuName, 256))
|
|
{
|
|
delete [] sanePaths;
|
|
delete [] manuNames;
|
|
return HGBASE_ERR_NOTSUPPORT;
|
|
}
|
|
|
|
delete [] sanePaths;
|
|
delete [] manuNames;
|
|
|
|
if (NULL == dll)
|
|
{
|
|
return HGSANE_ERR_FAIL;
|
|
}
|
|
|
|
HGSaneSourceImpl* newSourceImpl = new HGSaneSourceImpl(this);
|
|
HGResult ret = newSourceImpl->Init(manuName, dll, &saneAPI);
|
|
if (HGBASE_ERR_OK != ret)
|
|
{
|
|
delete newSourceImpl;
|
|
HGBase_DestroyDll(dll);
|
|
return ret;
|
|
}
|
|
|
|
m_listSourceImpl.push_back(newSourceImpl);
|
|
*sourceImpl = newSourceImpl;
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
void HGSaneManagerImpl::RemoveSource(class HGSaneSourceImpl* sourceImpl)
|
|
{
|
|
std::list<class HGSaneSourceImpl*>::iterator iter;
|
|
for (iter = m_listSourceImpl.begin(); iter != m_listSourceImpl.end(); ++iter)
|
|
{
|
|
if (*iter == sourceImpl)
|
|
{
|
|
m_listSourceImpl.erase(iter);
|
|
delete sourceImpl;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool HGSaneManagerImpl::filterDeviceSource(const char *sourceName)
|
|
{
|
|
#if !defined(OEM_HANWANG) && !defined(OEM_LISICHENG) && !defined(OEM_CANGTIAN) && !defined(OEM_ZHONGJING) && !defined(OEM_ZIGUANG) && !defined(OEM_NEUTRAL) && !defined(OEM_DELI)
|
|
std::string oemIden = "hgsane";
|
|
#elif defined(OEM_HANWANG)
|
|
std::string oemIden = "hwsane";
|
|
#elif defined(OEM_LISICHENG)
|
|
std::string oemIden = "lscsane";
|
|
#elif defined(OEM_CANGTIAN)
|
|
std::string oemIden = "ctssane";
|
|
#elif defined(OEM_ZHONGJING)
|
|
std::string oemIden = "zjsane";
|
|
#elif defined(OEM_ZIGUANG)
|
|
std::string oemIden = "zgsane";
|
|
#elif defined(OEM_DELI)
|
|
std::string oemIden = "dlsane";
|
|
#elif defined(OEM_NEUTRAL)
|
|
std::string oemIden = "neusane";
|
|
#endif
|
|
|
|
if (sourceName != strstr(sourceName, oemIden.c_str()))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
HGSaneSourceImpl::HGSaneSourceImpl(HGSaneManagerImpl *managerImpl)
|
|
{
|
|
m_managerImpl = managerImpl;
|
|
m_manuName.clear();
|
|
m_dll = NULL;
|
|
memset(&m_saneApi, 0, sizeof(SANEAPI));
|
|
}
|
|
|
|
HGSaneSourceImpl::~HGSaneSourceImpl()
|
|
{
|
|
|
|
}
|
|
|
|
HGResult HGSaneSourceImpl::Init(const HGChar* saneManu, HGDll dll, const SANEAPI *saneAPI)
|
|
{
|
|
assert(NULL == m_dll);
|
|
|
|
if (NULL == saneManu || 0 == *saneManu || NULL == dll || NULL == saneAPI)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
if (NULL == saneAPI->sane_open_api || NULL == saneAPI->sane_close_api
|
|
|| NULL == saneAPI->sane_start_api || NULL == saneAPI->sane_read_api
|
|
|| NULL == saneAPI->sane_cancel_api || NULL == saneAPI->sane_get_devices_api
|
|
|| NULL == saneAPI->sane_get_option_descriptor_api || NULL == saneAPI->sane_control_option_api
|
|
|| NULL == saneAPI->sane_get_parameters_api || NULL == saneAPI->sane_set_io_mode_api
|
|
|| NULL == saneAPI->sane_strstatus_api
|
|
|| NULL == saneAPI->sane_init_api || NULL == saneAPI->sane_exit_api)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
if (SANE_STATUS_GOOD != saneAPI->sane_init_api(NULL, NULL))
|
|
{
|
|
return HGSANE_ERR_FAIL;
|
|
}
|
|
|
|
m_manuName = saneManu;
|
|
m_dll = dll;
|
|
memcpy(&m_saneApi, saneAPI, sizeof(SANEAPI));
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneSourceImpl::Open(const HGChar* saneManu, const HGChar* sanePath)
|
|
{
|
|
assert(NULL == m_dll);
|
|
|
|
if (NULL == saneManu || 0 == *saneManu || NULL == sanePath || 0 == *sanePath)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
HGChar fileName[260];
|
|
HGBase_GetFileName(sanePath, fileName, 260);
|
|
|
|
HGDll dll = NULL;
|
|
HGResult ret = HGBase_CreateDll(fileName, &dll);
|
|
if (HGBASE_ERR_OK != ret)
|
|
{
|
|
ret = HGBase_CreateDll(sanePath, &dll);
|
|
if (HGBASE_ERR_OK != ret)
|
|
{
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
SANEAPI saneAPI;
|
|
ret = FindFunctions(dll, saneManu, &saneAPI);
|
|
if (HGBASE_ERR_OK != ret)
|
|
{
|
|
HGBase_DestroyDll(dll);
|
|
dll = NULL;
|
|
return ret;
|
|
}
|
|
|
|
if (SANE_STATUS_GOOD != saneAPI.sane_init_api(NULL, NULL))
|
|
{
|
|
HGBase_DestroyDll(m_dll);
|
|
m_dll = NULL;
|
|
return HGSANE_ERR_FAIL;
|
|
}
|
|
|
|
m_manuName = saneManu;
|
|
m_dll = dll;
|
|
memcpy(&m_saneApi, &saneAPI, sizeof(SANEAPI));
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneSourceImpl::Close()
|
|
{
|
|
assert(NULL != m_dll);
|
|
|
|
if (!m_listDeviceImpl.empty())
|
|
{
|
|
return HGBASE_ERR_FAIL;
|
|
}
|
|
|
|
m_saneApi.sane_exit_api();
|
|
HGBase_DestroyDll(m_dll);
|
|
m_dll = NULL;
|
|
m_managerImpl->RemoveSource(this);
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneSourceImpl::GetName(HGChar* name, HGUInt maxLen)
|
|
{
|
|
if (NULL == name || 0 == maxLen)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
if (maxLen < m_manuName.size() + 1)
|
|
return HGBASE_ERR_FAIL;
|
|
strcpy(name, m_manuName.c_str());
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneSourceImpl::GetDeviceCount(HGUInt* count)
|
|
{
|
|
if (NULL == count)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
const SANE_Device** device_list;
|
|
if (SANE_STATUS_GOOD != m_saneApi.sane_get_devices_api(&device_list, SANE_TRUE))
|
|
{
|
|
return HGSANE_ERR_FAIL;
|
|
}
|
|
|
|
*count = 0;
|
|
const SANE_Device** p;
|
|
for (p = device_list; *p != NULL; ++p)
|
|
++(*count);
|
|
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneSourceImpl::GetDeviceName(HGUInt index, HGChar* name, HGUInt maxLen)
|
|
{
|
|
if (NULL == name || 0 == maxLen)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
const SANE_Device** device_list;
|
|
if (SANE_STATUS_GOOD != m_saneApi.sane_get_devices_api(&device_list, SANE_TRUE))
|
|
{
|
|
return HGSANE_ERR_FAIL;
|
|
}
|
|
|
|
HGUInt count = 0;
|
|
const SANE_Device** p;
|
|
for (p = device_list; *p != NULL; ++p)
|
|
++count;
|
|
|
|
if (index >= count)
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
if (NULL == device_list[index]->name)
|
|
return HGBASE_ERR_FAIL;
|
|
if (maxLen < strlen(device_list[index]->name) + 1)
|
|
return HGBASE_ERR_FAIL;
|
|
strcpy(name, device_list[index]->name);
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneSourceImpl::OpenDevice(HGUInt index, HGSaneDeviceImpl** deviceImpl, HGChar* errInfo, HGUInt errInfoLen)
|
|
{
|
|
if (NULL == deviceImpl)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
const SANE_Device** device_list;
|
|
if (SANE_STATUS_GOOD != m_saneApi.sane_get_devices_api(&device_list, SANE_TRUE))
|
|
{
|
|
return HGSANE_ERR_FAIL;
|
|
}
|
|
|
|
HGUInt count = 0;
|
|
const SANE_Device** p;
|
|
for (p = device_list; *p != NULL; ++p)
|
|
++count;
|
|
|
|
if (index >= count)
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
HGSaneDeviceImpl* newDeviceImpl = new HGSaneDeviceImpl(this);
|
|
HGResult ret = newDeviceImpl->Open(device_list[index]->name, errInfo, errInfoLen);
|
|
if (HGBASE_ERR_OK != ret)
|
|
{
|
|
delete newDeviceImpl;
|
|
return ret;
|
|
}
|
|
|
|
m_listDeviceImpl.push_back(newDeviceImpl);
|
|
*deviceImpl = newDeviceImpl;
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneSourceImpl::OpenSelectedDevice(HGWindow parent, class HGSaneDeviceImpl** deviceImpl)
|
|
{
|
|
if (NULL == deviceImpl)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
std::vector<DEVQUEUI> devs;
|
|
|
|
HGUInt count = 0;
|
|
GetDeviceCount(&count);
|
|
for (HGUInt i = 0; i < count; ++i)
|
|
{
|
|
HGChar name[256] = {0};
|
|
GetDeviceName(i, name, 256);
|
|
|
|
SANE_Handle handle = NULL;
|
|
m_saneApi.sane_open_api(name, &handle);
|
|
if (NULL != handle)
|
|
{
|
|
HGChar sn[256] = {0};
|
|
m_saneApi.sane_control_option_api(handle, (SANE_Int)0x8856, SANE_ACTION_GET_VALUE, sn, NULL);
|
|
|
|
DEVQUEUI dev;
|
|
dev.id = i + 1;
|
|
dev.name = name;
|
|
dev.sn = sn;
|
|
devs.push_back(dev);
|
|
|
|
m_saneApi.sane_close_api(handle);
|
|
}
|
|
}
|
|
|
|
int id = choose_scanner(devs);
|
|
if (-1 == id)
|
|
{
|
|
return HGSANE_ERR_FAIL;
|
|
}
|
|
|
|
SANE_Handle handle = NULL;
|
|
char devName[256] = {0};
|
|
for (int i = 0; i < devs.size(); ++i)
|
|
{
|
|
if (devs[i].id == id)
|
|
{
|
|
strcpy(devName, devs[i].name.c_str());
|
|
m_saneApi.sane_open_api(devs[i].name.c_str(), &handle);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (NULL == handle)
|
|
{
|
|
return HGSANE_ERR_FAIL;
|
|
}
|
|
|
|
HGSaneDeviceImpl* newDeviceImpl = new HGSaneDeviceImpl(this);
|
|
HGResult ret = newDeviceImpl->Init(devName, handle);
|
|
if (HGBASE_ERR_OK != ret)
|
|
{
|
|
delete newDeviceImpl;
|
|
m_saneApi.sane_close_api(handle);
|
|
return ret;
|
|
}
|
|
|
|
m_listDeviceImpl.push_back(newDeviceImpl);
|
|
*deviceImpl = newDeviceImpl;
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneSourceImpl::FindFunctions(HGDll dll, const HGChar* saneManu, SANEAPI *saneAPI)
|
|
{
|
|
HGResult ret = HGBASE_ERR_OK;
|
|
|
|
do
|
|
{
|
|
HGChar funcName[256];
|
|
|
|
sprintf(funcName, "sane_%s_init", saneManu);
|
|
ret = HGBase_GetDllProcAddress(dll, funcName, (HGPointer*)&saneAPI->sane_init_api);
|
|
if (HGBASE_ERR_OK != ret)
|
|
break;
|
|
|
|
sprintf(funcName, "sane_%s_exit", saneManu);
|
|
ret = HGBase_GetDllProcAddress(dll, funcName, (HGPointer*)&saneAPI->sane_exit_api);
|
|
if (HGBASE_ERR_OK != ret)
|
|
break;
|
|
|
|
sprintf(funcName, "sane_%s_get_devices", saneManu);
|
|
ret = HGBase_GetDllProcAddress(dll, funcName, (HGPointer*)&saneAPI->sane_get_devices_api);
|
|
if (HGBASE_ERR_OK != ret)
|
|
break;
|
|
|
|
sprintf(funcName, "sane_%s_open", saneManu);
|
|
ret = HGBase_GetDllProcAddress(dll, funcName, (HGPointer*)&saneAPI->sane_open_api);
|
|
if (HGBASE_ERR_OK != ret)
|
|
break;
|
|
|
|
sprintf(funcName, "sane_%s_close", saneManu);
|
|
ret = HGBase_GetDllProcAddress(dll, funcName, (HGPointer*)&saneAPI->sane_close_api);
|
|
if (HGBASE_ERR_OK != ret)
|
|
break;
|
|
|
|
sprintf(funcName, "sane_%s_start", saneManu);
|
|
ret = HGBase_GetDllProcAddress(dll, funcName, (HGPointer*)&saneAPI->sane_start_api);
|
|
if (HGBASE_ERR_OK != ret)
|
|
break;
|
|
|
|
sprintf(funcName, "sane_%s_read", saneManu);
|
|
ret = HGBase_GetDllProcAddress(dll, funcName, (HGPointer*)&saneAPI->sane_read_api);
|
|
if (HGBASE_ERR_OK != ret)
|
|
break;
|
|
|
|
sprintf(funcName, "sane_%s_cancel", saneManu);
|
|
ret = HGBase_GetDllProcAddress(dll, funcName, (HGPointer*)&saneAPI->sane_cancel_api);
|
|
if (HGBASE_ERR_OK != ret)
|
|
break;
|
|
|
|
sprintf(funcName, "sane_%s_set_io_mode", saneManu);
|
|
ret = HGBase_GetDllProcAddress(dll, funcName, (HGPointer*)&saneAPI->sane_set_io_mode_api);
|
|
if (HGBASE_ERR_OK != ret)
|
|
break;
|
|
|
|
sprintf(funcName, "sane_%s_strstatus", saneManu);
|
|
ret = HGBase_GetDllProcAddress(dll, funcName, (HGPointer*)&saneAPI->sane_strstatus_api);
|
|
if (HGBASE_ERR_OK != ret)
|
|
break;
|
|
|
|
sprintf(funcName, "sane_%s_get_parameters", saneManu);
|
|
ret = HGBase_GetDllProcAddress(dll, funcName, (HGPointer*)&saneAPI->sane_get_parameters_api);
|
|
if (HGBASE_ERR_OK != ret)
|
|
break;
|
|
|
|
sprintf(funcName, "sane_%s_get_option_descriptor", saneManu);
|
|
ret = HGBase_GetDllProcAddress(dll, funcName, (HGPointer*)&saneAPI->sane_get_option_descriptor_api);
|
|
if (HGBASE_ERR_OK != ret)
|
|
break;
|
|
|
|
sprintf(funcName, "sane_%s_control_option", saneManu);
|
|
ret = HGBase_GetDllProcAddress(dll, funcName, (HGPointer*)&saneAPI->sane_control_option_api);
|
|
if (HGBASE_ERR_OK != ret)
|
|
break;
|
|
|
|
} while (0);
|
|
|
|
return ret;
|
|
}
|
|
|
|
void HGSaneSourceImpl::RemoveDevice(class HGSaneDeviceImpl* deviceImpl)
|
|
{
|
|
std::list<class HGSaneDeviceImpl*>::iterator iter;
|
|
for (iter = m_listDeviceImpl.begin(); iter != m_listDeviceImpl.end(); ++iter)
|
|
{
|
|
if (*iter == deviceImpl)
|
|
{
|
|
m_listDeviceImpl.erase(iter);
|
|
delete deviceImpl;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
HGSaneDeviceImpl *HGSaneDeviceImpl::m_curDevice = NULL;
|
|
|
|
HGSaneDeviceImpl::HGSaneDeviceImpl(HGSaneSourceImpl* sourceImpl)
|
|
{
|
|
m_sourceImpl = sourceImpl;
|
|
m_devName.clear();
|
|
m_devHandle = NULL;
|
|
m_scanNotify = NULL;
|
|
m_dpi = 0;
|
|
m_eventFunc = NULL;
|
|
m_eventParam = NULL;
|
|
m_imageFunc = NULL;
|
|
m_imageParam = NULL;
|
|
m_stopThread = HGFALSE;
|
|
m_thread = NULL;
|
|
m_cancelScan = false;
|
|
}
|
|
|
|
HGSaneDeviceImpl::~HGSaneDeviceImpl()
|
|
{
|
|
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::Init(const HGChar* devName, SANE_Handle handle)
|
|
{
|
|
assert(NULL == m_devHandle);
|
|
|
|
if (NULL == devName || NULL == handle)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
m_devName = devName;
|
|
m_sourceImpl->m_saneApi.sane_set_io_mode_api(handle, SANE_FALSE);
|
|
m_devHandle = handle;
|
|
char* cfg = apply_current_config(m_devName.c_str(), m_devHandle, &m_sourceImpl->m_saneApi);
|
|
twain_ui_free(cfg);
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::Open(const HGChar* devName, HGChar* errInfo, HGUInt errInfoLen)
|
|
{
|
|
assert(NULL == m_devHandle);
|
|
|
|
if (NULL == devName)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
SANE_Handle handle = NULL;
|
|
SANE_Status stat = m_sourceImpl->m_saneApi.sane_open_api(devName, &handle);
|
|
if (SANE_STATUS_GOOD != stat)
|
|
{
|
|
if (NULL != errInfo)
|
|
{
|
|
const char* err = m_sourceImpl->m_saneApi.sane_strstatus_api(stat);
|
|
if (NULL != err && errInfoLen >= strlen(err) + 1)
|
|
{
|
|
strcpy(errInfo, err);
|
|
}
|
|
}
|
|
|
|
return HGSANE_ERR_FAIL;
|
|
}
|
|
|
|
m_devName = devName;
|
|
m_sourceImpl->m_saneApi.sane_set_io_mode_api(handle, SANE_FALSE);
|
|
m_devHandle = handle;
|
|
char* cfg = apply_current_config(m_devName.c_str(), m_devHandle, &m_sourceImpl->m_saneApi);
|
|
twain_ui_free(cfg);
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::Close()
|
|
{
|
|
assert(NULL != m_devHandle);
|
|
|
|
m_sourceImpl->m_saneApi.sane_close_api(m_devHandle);
|
|
m_devHandle = NULL;
|
|
m_devName.clear();
|
|
m_sourceImpl->RemoveDevice(this);
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::GetName(HGChar* name, HGUInt maxLen)
|
|
{
|
|
if (NULL == name || 0 == maxLen)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
if (maxLen < m_devName.size() + 1)
|
|
return HGBASE_ERR_FAIL;
|
|
strcpy(name, m_devName.c_str());
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::GetCustomInfo(HGSaneDeviceCustomInfo *info)
|
|
{
|
|
if (NULL == info)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
memset(info, 0, sizeof(HGSaneDeviceCustomInfo));
|
|
|
|
GetValueInt32(0x8852, &info->vid);
|
|
GetValueInt32(0x8853, &info->pid);
|
|
GetValueStr256(0x8856, info->sn, sizeof(info->sn));
|
|
GetValueStr256(0x8855, info->type, sizeof(info->type));
|
|
GetValueStr256(0x8857, info->fwVer, sizeof(info->fwVer));
|
|
GetValueStr256(0x8858, info->ip, sizeof(info->ip));
|
|
GetValueStr256(0x8859, info->mac, sizeof(info->mac));
|
|
GetValueStr256(0x884A, info->driverVer, sizeof(info->driverVer));
|
|
GetValueStr256(0x884B, info->vendor, sizeof(info->vendor));
|
|
GetValueStr256(0x884C, info->copyright, sizeof(info->copyright));
|
|
GetValueStr256(0x884D, info->comUrl, sizeof(info->comUrl));
|
|
GetValueStr256(0x884E, info->comTel, sizeof(info->comTel));
|
|
GetValueStr256(0x884F, info->comAddr, sizeof(info->comAddr));
|
|
GetValueStr256(0x8850, info->comGps, sizeof(info->comGps));
|
|
GetValueInt32(0x9902, &info->rollerCount);
|
|
GetValueInt32(0x8849, &info->totalCount);
|
|
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::Login(const HGChar *user, const HGChar *pwd)
|
|
{
|
|
if (NULL == user || strlen(user) >= 32
|
|
|| NULL == pwd || strlen(pwd) >= 32)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
HGChar value[256] = {0};
|
|
strcpy(value, user);
|
|
strcpy(value + 32, pwd);
|
|
return SetValueStr256(0x9900, value);
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::Logout()
|
|
{
|
|
HGChar value[256] = {0};
|
|
return SetValueStr256(0x9901, value);
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::ClearRollerCount()
|
|
{
|
|
return SetValueInt32(0x9902, 0);
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::GetRollerLife(HGInt *rollerLife)
|
|
{
|
|
return GetValueInt32(0x885B, rollerLife);
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::GetDriverLog(const HGChar *fileName)
|
|
{
|
|
if (NULL == fileName || strlen(fileName) >= 256)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
char v[256];
|
|
strcpy(v, fileName);
|
|
SANE_Status status = m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, (SANE_Int)0x9903, SANE_ACTION_GET_VALUE, (void*)v, NULL);
|
|
return (SANE_STATUS_GOOD == status) ? HGBASE_ERR_OK : HGBASE_ERR_FAIL;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::ClearDriverLog()
|
|
{
|
|
HGChar value[256] = {0};
|
|
return SetValueStr256(0x9903, value);
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::GetDeviceLog(const HGChar *fileName)
|
|
{
|
|
if (NULL == fileName || strlen(fileName) >= 256)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
char v[256];
|
|
strcpy(v, fileName);
|
|
SANE_Status status = m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, (SANE_Int)0x9904, SANE_ACTION_GET_VALUE, (void*)v, NULL);
|
|
return (SANE_STATUS_GOOD == status) ? HGBASE_ERR_OK : HGBASE_ERR_FAIL;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::ClearDeviceLog()
|
|
{
|
|
HGChar value[256] = {0};
|
|
return SetValueStr256(0x9904, value);
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::ShowSettingDlg(HGWindow parent)
|
|
{
|
|
int pid = 0;
|
|
if (SANE_STATUS_GOOD != m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, (SANE_Int)0x8853,
|
|
SANE_ACTION_GET_VALUE, &pid, NULL))
|
|
{
|
|
return HGSANE_ERR_DEVICEOFFLINE;
|
|
}
|
|
|
|
m_curDevice = this;
|
|
int ret = show_setting_ui(m_devHandle, parent, &m_sourceImpl->m_saneApi, m_devName.c_str(), false, UIResultCallback, nullptr);
|
|
if (0 != ret)
|
|
{
|
|
return HGSANE_ERR_FAIL;
|
|
}
|
|
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::Start(HGWindow parent, HGSane_DeviceEventFunc eventFunc, HGPointer eventParam,
|
|
HGSane_DeviceImageFunc imageFunc, HGPointer imageParam)
|
|
{
|
|
if (NULL != m_thread)
|
|
{
|
|
return HGSANE_ERR_FAIL;
|
|
}
|
|
|
|
int pid = 0;
|
|
if (SANE_STATUS_GOOD != m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, (SANE_Int)0x8853,
|
|
SANE_ACTION_GET_VALUE, &pid, NULL))
|
|
{
|
|
return HGSANE_ERR_DEVICEOFFLINE;
|
|
}
|
|
|
|
m_curDevice = this;
|
|
int ret = show_progress_ui(parent, UIResultCallback, &m_scanNotify);
|
|
if (0 != ret)
|
|
{
|
|
return HGSANE_ERR_FAIL;
|
|
}
|
|
|
|
GetDpi(&m_dpi);
|
|
m_eventFunc = eventFunc;
|
|
m_eventParam = eventParam;
|
|
m_imageFunc = imageFunc;
|
|
m_imageParam = imageParam;
|
|
|
|
GetScanMode(m_oldScanMode, 256);
|
|
GetScanCount(&m_oldScanCount);
|
|
|
|
m_stopThread = HGFALSE;
|
|
m_cancelScan = false;
|
|
HGBase_OpenThread(ThreadFunc, this, &m_thread);
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::StartWithSingleScan(HGWindow parent, HGSane_DeviceEventFunc eventFunc, HGPointer eventParam,
|
|
HGSane_DeviceImageFunc imageFunc, HGPointer imageParam)
|
|
{
|
|
if (NULL != m_thread)
|
|
{
|
|
return HGSANE_ERR_FAIL;
|
|
}
|
|
|
|
int pid = 0;
|
|
if (SANE_STATUS_GOOD != m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, (SANE_Int)0x8853,
|
|
SANE_ACTION_GET_VALUE, &pid, NULL))
|
|
{
|
|
return HGSANE_ERR_DEVICEOFFLINE;
|
|
}
|
|
|
|
m_curDevice = this;
|
|
int ret = show_progress_ui(parent, UIResultCallback, &m_scanNotify);
|
|
if (0 != ret)
|
|
{
|
|
return HGSANE_ERR_FAIL;
|
|
}
|
|
|
|
GetDpi(&m_dpi);
|
|
m_eventFunc = eventFunc;
|
|
m_eventParam = eventParam;
|
|
m_imageFunc = imageFunc;
|
|
m_imageParam = imageParam;
|
|
|
|
GetScanMode(m_oldScanMode, 256);
|
|
GetScanCount(&m_oldScanCount);
|
|
|
|
HGChar newScanMode[256] = {0};
|
|
strcpy(newScanMode, OPTION_VALUE_SMZS_SMZDZS);
|
|
SetScanMode(newScanMode);
|
|
SetScanCount(1);
|
|
|
|
m_stopThread = HGFALSE;
|
|
m_cancelScan = false;
|
|
HGBase_OpenThread(ThreadFunc, this, &m_thread);
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
void HGSaneDeviceImpl::UIResultCallback(ui_result result)
|
|
{
|
|
assert(NULL != m_curDevice);
|
|
assert(result != UI_RESULT_START_SCAN);
|
|
|
|
if (result == UI_RESULT_CLOSE_NORMAL)
|
|
{
|
|
if (NULL != m_curDevice->m_thread)
|
|
{
|
|
m_curDevice->m_stopThread = HGTRUE;
|
|
m_curDevice->m_sourceImpl->m_saneApi.sane_cancel_api(m_curDevice->m_devHandle);
|
|
HGBase_CloseThread(m_curDevice->m_thread);
|
|
m_curDevice->m_thread = NULL;
|
|
|
|
if (NULL != m_curDevice->m_eventFunc)
|
|
m_curDevice->m_eventFunc((HGSaneDevice)m_curDevice, HGSANE_EVENT_TYPE_SCANFINISHED, m_curDevice->m_eventParam);
|
|
|
|
m_curDevice->SetScanMode(m_curDevice->m_oldScanMode);
|
|
m_curDevice->SetScanCount(m_curDevice->m_oldScanCount);
|
|
}
|
|
|
|
close_ui(UI_INDICATOR);
|
|
}
|
|
else if (result == UI_RESULT_CLOSE_CANCEL)
|
|
{
|
|
if (NULL != m_curDevice->m_thread)
|
|
{
|
|
m_curDevice->m_cancelScan = true;
|
|
m_curDevice->m_sourceImpl->m_saneApi.sane_cancel_api(m_curDevice->m_devHandle);
|
|
}
|
|
}
|
|
else if (result == UI_RESULT_CLOSE_SETTING)
|
|
{
|
|
close_ui(UI_SETTING);
|
|
}
|
|
}
|
|
|
|
void HGAPI HGSaneDeviceImpl::ThreadFunc(HGThread thread, HGPointer param)
|
|
{
|
|
(void)thread;
|
|
HGSaneDeviceImpl *p = (HGSaneDeviceImpl *)param;
|
|
|
|
SANEAPI &saneAPI = m_curDevice->m_sourceImpl->m_saneApi;
|
|
|
|
if (NULL != p->m_eventFunc)
|
|
p->m_eventFunc((HGSaneDevice)p, HGSANE_EVENT_TYPE_WORKING, p->m_eventParam);
|
|
|
|
if (NULL != p->m_scanNotify)
|
|
p->m_scanNotify((int)SANE_EVENT_WORKING, NULL, 0);
|
|
|
|
SANE_Status stat = saneAPI.sane_start_api(p->m_devHandle);
|
|
|
|
// 获取设置界面选择的双张处理方式
|
|
HGUInt doubleImgStat = HGBASE_ERR_OK;
|
|
p->GetDoubleImgStatus(&doubleImgStat);
|
|
|
|
if (SANE_STATUS_GOOD != stat)
|
|
{
|
|
if ((SCANNER_ERR_DEVICE_DOUBLE_FEEDING == stat && HGSANE_ERR_UI_RESERVE_CHECK != doubleImgStat))
|
|
{
|
|
if (NULL != p->m_scanNotify)
|
|
p->m_scanNotify((int)SANE_EVENT_SCAN_FINISHED, (void*)saneAPI.sane_strstatus_api(stat), (int)stat);
|
|
|
|
if (HGSANE_ERR_UI_DISCARD_STOP == doubleImgStat)
|
|
return;
|
|
}
|
|
else if (SCANNER_ERR_DEVICE_DOUBLE_FEEDING != stat)
|
|
{
|
|
if (NULL != p->m_scanNotify)
|
|
p->m_scanNotify((int)SANE_EVENT_SCAN_FINISHED, (void*)saneAPI.sane_strstatus_api(stat), (int)stat);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 双张图像处理的返回值
|
|
HGUInt doubleImgRet = HGBASE_ERR_OK;
|
|
bool clickedReserveImg = false;
|
|
|
|
while (!p->m_stopThread)
|
|
{
|
|
SANE_Parameters params;
|
|
memset(¶ms, 0, sizeof(SANE_Parameters));
|
|
SANE_Status stat1 = saneAPI.sane_get_parameters_api(p->m_devHandle, ¶ms);
|
|
if (SANE_STATUS_GOOD != stat1 && SCANNER_ERR_DEVICE_DOUBLE_FEEDING != stat1)
|
|
{
|
|
if (NULL != p->m_scanNotify)
|
|
p->m_scanNotify((int)SANE_EVENT_SCAN_FINISHED, (void*)saneAPI.sane_strstatus_api(stat1), (int)stat1);
|
|
break;
|
|
}
|
|
|
|
HGUInt bufferSize = params.bytes_per_line * params.lines;
|
|
HGByte *buffer = (HGByte *)malloc(bufferSize);
|
|
if (NULL == buffer)
|
|
{
|
|
if (NULL != p->m_scanNotify)
|
|
p->m_scanNotify((int)SANE_EVENT_SCAN_FINISHED, (void*)saneAPI.sane_strstatus_api(SANE_STATUS_NO_MEM), (int)SANE_STATUS_NO_MEM);
|
|
break;
|
|
}
|
|
|
|
SANE_Int readSize = 0;
|
|
SANE_Status stat2 = SANE_STATUS_GOOD;
|
|
while (readSize < bufferSize)
|
|
{
|
|
SANE_Int len = 0;
|
|
stat2 = saneAPI.sane_read_api(p->m_devHandle, buffer + readSize, bufferSize - readSize, &len);
|
|
readSize += len;
|
|
if (SANE_STATUS_GOOD != stat2)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (SANE_STATUS_GOOD == stat2)
|
|
{
|
|
// bufferSize空间不够
|
|
free(buffer);
|
|
if (NULL != p->m_scanNotify)
|
|
p->m_scanNotify((int)SANE_EVENT_SCAN_FINISHED, (void*)saneAPI.sane_strstatus_api(SANE_STATUS_NO_MEM), (int)SANE_STATUS_NO_MEM);
|
|
break;
|
|
}
|
|
else if (SANE_STATUS_EOF == stat2)
|
|
{
|
|
if (0 == readSize)
|
|
{
|
|
free(buffer);
|
|
if (p->m_cancelScan)
|
|
{
|
|
if (NULL != p->m_scanNotify)
|
|
p->m_scanNotify((int)SANE_EVENT_SCAN_FINISHED, (void*)saneAPI.sane_strstatus_api(SANE_STATUS_CANCELLED), (int)SANE_STATUS_CANCELLED);
|
|
}
|
|
else
|
|
{
|
|
if (NULL != p->m_scanNotify)
|
|
p->m_scanNotify((int)SANE_EVENT_SCAN_FINISHED, NULL, 0);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if (readSize != params.bytes_per_line * params.lines)
|
|
{
|
|
free(buffer);
|
|
if (NULL != p->m_scanNotify)
|
|
p->m_scanNotify((int)SANE_EVENT_SCAN_FINISHED, (void*)saneAPI.sane_strstatus_api(SANE_STATUS_IO_ERROR), (int)SANE_STATUS_IO_ERROR);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
free(buffer);
|
|
if (NULL != p->m_scanNotify)
|
|
p->m_scanNotify((int)SANE_EVENT_SCAN_FINISHED, (void*)saneAPI.sane_strstatus_api(stat2), (int)stat2);
|
|
break;
|
|
}
|
|
|
|
if (NULL != p->m_scanNotify)
|
|
p->m_scanNotify((int)SANE_EVENT_IMAGE_OK, NULL, 0);
|
|
|
|
if (nullptr != p->m_imageFunc)
|
|
{
|
|
HGUInt imgType = 0;
|
|
if (params.format == SANE_FRAME_GRAY)
|
|
{
|
|
if (1 == params.depth)
|
|
imgType = HGBASE_IMGTYPE_BINARY;
|
|
else if (8 == params.depth)
|
|
imgType = HGBASE_IMGTYPE_GRAY;
|
|
}
|
|
else if (params.format == SANE_FRAME_RGB)
|
|
{
|
|
imgType = HGBASE_IMGTYPE_RGB;
|
|
}
|
|
|
|
HGImageInfo imgInfo = { (HGUInt)params.pixels_per_line, (HGUInt)params.lines,
|
|
imgType, (HGUInt)params.bytes_per_line, HGBASE_IMGORIGIN_TOP };
|
|
HGImage img = NULL;
|
|
HGBase_CreateImageWithData(buffer, &imgInfo, &img);
|
|
if (NULL != img)
|
|
{
|
|
HGBase_SetImageDpi(img, p->m_dpi, p->m_dpi);
|
|
if (HGBASE_ERR_OK == doubleImgRet && SCANNER_ERR_DEVICE_DOUBLE_FEEDING == stat
|
|
&& HGSANE_ERR_UI_RESERVE_CHECK == doubleImgStat)
|
|
{
|
|
// 第一个双张图片
|
|
doubleImgRet = p->m_imageFunc((HGSaneDevice)p, img, HGSANE_IMAGE_TYPE_DOUBLE, p->m_imageParam);
|
|
|
|
if (HGSANE_ERR_IMAGE_RESERVE == doubleImgRet)
|
|
clickedReserveImg = true;
|
|
}
|
|
else
|
|
{
|
|
// 普通图片或第二个双张图片
|
|
p->m_imageFunc((HGSaneDevice)p, img, HGSANE_IMAGE_TYPE_NORMAL, p->m_imageParam);
|
|
doubleImgRet = HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGBase_DestroyImage(img);
|
|
}
|
|
}
|
|
|
|
free(buffer);
|
|
buffer = NULL;
|
|
bufferSize = 0;
|
|
|
|
if (HGSANE_ERR_IMAGE_DISCARD == doubleImgRet)
|
|
{
|
|
saneAPI.sane_cancel_api(p->m_devHandle);
|
|
if (NULL != p->m_scanNotify)
|
|
p->m_scanNotify((int)SANE_EVENT_SCAN_FINISHED, NULL, 0);
|
|
break;
|
|
}
|
|
|
|
if (!p->m_cancelScan)
|
|
{
|
|
stat = saneAPI.sane_start_api(p->m_devHandle);
|
|
if (SANE_STATUS_NO_DOCS == stat)
|
|
{
|
|
if (NULL != p->m_scanNotify)
|
|
{
|
|
if (clickedReserveImg)
|
|
p->m_scanNotify((int)SANE_EVENT_SCAN_FINISHED, (void*)saneAPI.sane_strstatus_api(stat), (int)stat);
|
|
else
|
|
p->m_scanNotify((int)SANE_EVENT_SCAN_FINISHED, NULL, 0);
|
|
}
|
|
|
|
break;
|
|
}
|
|
else if (SANE_STATUS_GOOD != stat && HGSANE_ERR_UI_RESERVE_CHECK != doubleImgStat)
|
|
{
|
|
if (NULL != p->m_scanNotify)
|
|
p->m_scanNotify((int)SANE_EVENT_SCAN_FINISHED, (void*)saneAPI.sane_strstatus_api(stat), (int)stat);
|
|
break;
|
|
}
|
|
|
|
if (SANE_STATUS_GOOD == stat)
|
|
{
|
|
doubleImgRet = HGBASE_ERR_OK;
|
|
clickedReserveImg = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::SetValueInt32(HGUInt optionId, HGInt value)
|
|
{
|
|
SANE_Int v = (SANE_Int)value;
|
|
SANE_Status status = m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, (SANE_Int)optionId, SANE_ACTION_SET_VALUE, &v, NULL);
|
|
return (SANE_STATUS_GOOD == status) ? HGBASE_ERR_OK : HGBASE_ERR_FAIL;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::GetValueInt32(HGUInt optionId, HGInt *value)
|
|
{
|
|
SANE_Int v = 0;
|
|
SANE_Status status = m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, (SANE_Int)optionId, SANE_ACTION_GET_VALUE, &v, NULL);
|
|
if (SANE_STATUS_GOOD != status)
|
|
{
|
|
return HGBASE_ERR_FAIL;
|
|
}
|
|
|
|
*value = (HGInt)v;
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::SetValueStr256(HGUInt optionId, const HGChar *value)
|
|
{
|
|
if (NULL == value || strlen(value) >= 256)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
const char *v = value;
|
|
SANE_Status status = m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, (SANE_Int)optionId, SANE_ACTION_SET_VALUE, (void*)v, NULL);
|
|
return (SANE_STATUS_GOOD == status) ? HGBASE_ERR_OK : HGBASE_ERR_FAIL;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::GetValueStr256(HGUInt optionId, HGChar *value, HGUInt maxLen)
|
|
{
|
|
if (NULL == value || 0 == maxLen)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
char v[256] = {0};
|
|
SANE_Status status = m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, (SANE_Int)optionId, SANE_ACTION_GET_VALUE, v, NULL);
|
|
if (SANE_STATUS_GOOD != status)
|
|
{
|
|
return HGBASE_ERR_FAIL;
|
|
}
|
|
|
|
if (maxLen <= strlen(v))
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
strcpy(value, v);
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::GetDpi(HGInt *dpi)
|
|
{
|
|
SANE_Int dev_options = 0;
|
|
SANE_Int method = 0;
|
|
m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, 0, SANE_ACTION_GET_VALUE, &dev_options, nullptr);
|
|
for (int i = 1; i < dev_options; ++i)
|
|
{
|
|
const SANE_Option_Descriptor* opt = m_sourceImpl->m_saneApi.sane_get_option_descriptor_api(m_devHandle, i);
|
|
if (strcmp(opt->name, SANE_STD_OPT_NAME_RESOLUTION) == 0)
|
|
{
|
|
SANE_Int value = 0;
|
|
SANE_Status ret = m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, &method);
|
|
if (ret == SANE_STATUS_GOOD)
|
|
{
|
|
*dpi = (HGInt)value;
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::GetScanMode(HGChar *scanMode, HGUInt maxLen)
|
|
{
|
|
if (NULL == scanMode || 0 == maxLen)
|
|
{
|
|
return HGBASE_ERR_INVALIDARG;
|
|
}
|
|
|
|
SANE_Int dev_options = 0;
|
|
SANE_Int method = 0;
|
|
m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, 0, SANE_ACTION_GET_VALUE, &dev_options, nullptr);
|
|
for (int i = 1; i < dev_options; ++i)
|
|
{
|
|
const SANE_Option_Descriptor* opt = m_sourceImpl->m_saneApi.sane_get_option_descriptor_api(m_devHandle, i);
|
|
HGChar *value = (char*)malloc(opt->size * 2 + 4);
|
|
if (strcmp(opt->name, SANE_STD_OPT_NAME_SCAN_MODE) == 0)
|
|
{
|
|
SANE_Status ret = m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, i, SANE_ACTION_GET_VALUE, value, &method);
|
|
if (ret == SANE_STATUS_GOOD)
|
|
{
|
|
strcpy(scanMode, value);
|
|
free(value);
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
}
|
|
free(value);
|
|
}
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::GetScanCount(HGInt *scanCount)
|
|
{
|
|
SANE_Int dev_options = 0;
|
|
SANE_Int method = 0;
|
|
m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, 0, SANE_ACTION_GET_VALUE, &dev_options, nullptr);
|
|
for (int i = 1; i < dev_options; ++i)
|
|
{
|
|
const SANE_Option_Descriptor* opt = m_sourceImpl->m_saneApi.sane_get_option_descriptor_api(m_devHandle, i);
|
|
if (strcmp(opt->name, SANE_STD_OPT_NAME_SCAN_COUNT) == 0)
|
|
{
|
|
SANE_Int value = 0;
|
|
SANE_Status ret = m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, &method);
|
|
if (ret == SANE_STATUS_GOOD)
|
|
{
|
|
*scanCount = (HGInt)value;
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::SetScanMode(const HGChar *scanMode)
|
|
{
|
|
SANE_Int dev_options = 0;
|
|
SANE_Int method = 0;
|
|
SANE_String value = nullptr;
|
|
m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, 0, SANE_ACTION_GET_VALUE, &dev_options, nullptr);
|
|
for (int i = 1; i < dev_options; ++i)
|
|
{
|
|
const SANE_Option_Descriptor* opt = m_sourceImpl->m_saneApi.sane_get_option_descriptor_api(m_devHandle, i);
|
|
SANE_String value = (SANE_String)malloc(opt->size * 2 + 4);
|
|
strcpy(value, scanMode);
|
|
if (strcmp(opt->name, SANE_STD_OPT_NAME_SCAN_MODE) == 0)
|
|
{
|
|
SANE_Status ret = m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, i, SANE_ACTION_SET_VALUE, value, &method);
|
|
if (ret == SANE_STATUS_GOOD)
|
|
{
|
|
free(value);
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
}
|
|
free(value);
|
|
}
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::SetScanCount(HGInt scanCount)
|
|
{
|
|
SANE_Int dev_options = 0;
|
|
SANE_Int method = 0;
|
|
m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, 0, SANE_ACTION_GET_VALUE, &dev_options, nullptr);
|
|
for (int i = 1; i < dev_options; ++i)
|
|
{
|
|
const SANE_Option_Descriptor* opt = m_sourceImpl->m_saneApi.sane_get_option_descriptor_api(m_devHandle, i);
|
|
SANE_Int value = (SANE_Int)scanCount;
|
|
if (strcmp(opt->name, SANE_STD_OPT_NAME_SCAN_COUNT) == 0)
|
|
{
|
|
SANE_Status ret = m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, i, SANE_ACTION_SET_VALUE, &value, &method);
|
|
if (ret == SANE_STATUS_GOOD)
|
|
{
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
}
|
|
|
|
HGResult HGSaneDeviceImpl::GetDoubleImgStatus(HGUInt *status)
|
|
{
|
|
SANE_Int dev_options = 0;
|
|
SANE_Int method = 0;
|
|
m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, 0, SANE_ACTION_GET_VALUE, &dev_options, nullptr);
|
|
for (int i = 1; i < dev_options; ++i)
|
|
{
|
|
const SANE_Option_Descriptor* opt = m_sourceImpl->m_saneApi.sane_get_option_descriptor_api(m_devHandle, i);
|
|
if (strcmp(opt->name, SANE_STD_OPT_NAME_DOUBLE_FEED_HANDLE) == 0)
|
|
{
|
|
char *value = (char*)malloc(opt->size * 2 + 4);
|
|
SANE_Status ret = m_sourceImpl->m_saneApi.sane_control_option_api(m_devHandle, i, SANE_ACTION_GET_VALUE, value, &method);
|
|
if (ret == SANE_STATUS_GOOD)
|
|
{
|
|
if (0 == strcmp(value, OPTION_VALUE_SZTPCL_SCTXBJY))
|
|
*status = HGSANE_ERR_UI_RESERVE_CHECK;
|
|
else if (0 == strcmp(value, OPTION_VALUE_SZTPCL_SCTXBTZSM))
|
|
*status = HGSANE_ERR_UI_RESERVE_STOP;
|
|
else
|
|
*status = HGSANE_ERR_UI_DISCARD_STOP;
|
|
|
|
free(value);
|
|
return HGBASE_ERR_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
}
|