2022-05-03 10:25:52 +00:00
|
|
|
|
#include "HGSaneImpl.hpp"
|
|
|
|
|
#include "../base/HGInc.h"
|
|
|
|
|
|
|
|
|
|
HGSaneManagerImpl::HGSaneManagerImpl()
|
|
|
|
|
{
|
|
|
|
|
m_dll = NULL;
|
|
|
|
|
m_f_sane_init = NULL;
|
|
|
|
|
m_f_sane_exit = NULL;
|
|
|
|
|
m_f_sane_get_devices = NULL;
|
|
|
|
|
m_f_sane_open = NULL;
|
|
|
|
|
m_f_sane_close = NULL;
|
|
|
|
|
m_f_sane_start = NULL;
|
|
|
|
|
m_f_sane_read = NULL;
|
|
|
|
|
m_f_sane_cancel = NULL;
|
|
|
|
|
m_f_sane_set_io_mode = NULL;
|
|
|
|
|
m_f_sane_strstatus = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGSaneManagerImpl::~HGSaneManagerImpl()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGSaneManagerImpl::Create(const HGChar* sanePath)
|
|
|
|
|
{
|
|
|
|
|
if (NULL != m_dll)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult ret = HGBase_CreateDll(sanePath, &m_dll);
|
|
|
|
|
if (HGBASE_ERR_OK != ret)
|
|
|
|
|
{
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = FindFunctions();
|
|
|
|
|
if (HGBASE_ERR_OK != ret)
|
|
|
|
|
{
|
|
|
|
|
HGBase_DestroyDll(m_dll);
|
|
|
|
|
m_dll = NULL;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (SANE_STATUS_GOOD != m_f_sane_init(NULL, NULL))
|
|
|
|
|
{
|
|
|
|
|
HGBase_DestroyDll(m_dll);
|
|
|
|
|
m_dll = NULL;
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGSaneManagerImpl::Destroy()
|
|
|
|
|
{
|
|
|
|
|
if (!m_devList.empty())
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NULL != m_dll)
|
|
|
|
|
{
|
|
|
|
|
m_f_sane_exit();
|
|
|
|
|
HGBase_DestroyDll(m_dll);
|
|
|
|
|
m_dll = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGSaneManagerImpl::GetDeviceCount(HGUInt* count)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == count)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const SANE_Device **device_list;
|
|
|
|
|
if (SANE_STATUS_GOOD != m_f_sane_get_devices(&device_list, SANE_TRUE))
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*count = 0;
|
|
|
|
|
const SANE_Device** p;
|
|
|
|
|
for (p = device_list; *p != NULL; ++p)
|
|
|
|
|
++(*count);
|
|
|
|
|
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGSaneManagerImpl::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_f_sane_get_devices(&device_list, SANE_TRUE))
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_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 HGSaneManagerImpl::OpenDevice(HGUInt index, HGSaneDeviceImpl** device)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == device)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const SANE_Device** device_list;
|
|
|
|
|
if (SANE_STATUS_GOOD != m_f_sane_get_devices(&device_list, SANE_TRUE))
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGUInt count = 0;
|
|
|
|
|
const SANE_Device** p;
|
|
|
|
|
for (p = device_list; *p != NULL; ++p)
|
|
|
|
|
++count;
|
|
|
|
|
|
|
|
|
|
if (index >= count)
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
|
|
|
|
|
SANE_Handle handle = NULL;
|
|
|
|
|
if (SANE_STATUS_GOOD != m_f_sane_open(device_list[index]->name, &handle))
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_f_sane_set_io_mode(handle, SANE_FALSE);
|
|
|
|
|
|
|
|
|
|
HGSaneDeviceImpl* saneDeviceImpl = new HGSaneDeviceImpl(this);
|
|
|
|
|
saneDeviceImpl->devHandle = handle;
|
|
|
|
|
m_devList.push_back(saneDeviceImpl);
|
|
|
|
|
*device = saneDeviceImpl;
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGSaneManagerImpl::CloseDevice(HGSaneDeviceImpl* device)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == device)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult ret = HGBASE_ERR_FAIL;
|
|
|
|
|
std::list<HGSaneDeviceImpl*>::iterator iter;
|
|
|
|
|
for (iter = m_devList.begin(); iter != m_devList.end(); ++iter)
|
|
|
|
|
{
|
|
|
|
|
if (device == *iter)
|
|
|
|
|
{
|
|
|
|
|
StopDevice(device);
|
|
|
|
|
|
|
|
|
|
m_f_sane_close(device->devHandle);
|
|
|
|
|
delete device;
|
|
|
|
|
m_devList.erase(iter);
|
|
|
|
|
ret = HGBASE_ERR_OK;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGSaneManagerImpl::StartDevice(HGSaneDeviceImpl* device, HGSane_DeviceEventCallback func, HGPointer param)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == device || NULL == func)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NULL != device->thread)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (SANE_STATUS_GOOD != m_f_sane_start(device->devHandle))
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
device->func = func;
|
|
|
|
|
device->param = param;
|
|
|
|
|
device->stopThread = HGFALSE;
|
|
|
|
|
HGBase_OpenThread(ThreadFunc, device, &device->thread);
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGSaneManagerImpl::StopDevice(HGSaneDeviceImpl* device)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == device)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
device->stopThread = HGTRUE;
|
|
|
|
|
// 该函数应该打断m_f_sane_read
|
|
|
|
|
m_f_sane_cancel(device->devHandle);
|
|
|
|
|
|
|
|
|
|
HGBase_CloseThread(device->thread);
|
|
|
|
|
device->thread = NULL;
|
|
|
|
|
device->func = NULL;
|
|
|
|
|
device->param = NULL;
|
|
|
|
|
device->recvData.clear();
|
|
|
|
|
device->imgReady = HGFALSE;
|
|
|
|
|
return HGBASE_ERR_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGSaneManagerImpl::GetImage(HGSaneDeviceImpl* device, HGUInt type, HGUInt origin, HGImage* image)
|
|
|
|
|
{
|
|
|
|
|
if (NULL == device)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_INVALIDARG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGBase_EnterLock(device->lock);
|
|
|
|
|
HGBool imgReady = device->imgReady;
|
|
|
|
|
HGBase_LeaveLock(device->lock);
|
|
|
|
|
if (!imgReady)
|
|
|
|
|
{
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 从m_recvData中加载
|
|
|
|
|
return HGBASE_ERR_FAIL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-12 03:35:09 +00:00
|
|
|
|
void HGAPI HGSaneManagerImpl::ThreadFunc(HGThread thread, HGPointer param)
|
2022-05-03 10:25:52 +00:00
|
|
|
|
{
|
|
|
|
|
HGSaneDeviceImpl* p = (HGSaneDeviceImpl*)param;
|
|
|
|
|
|
|
|
|
|
while (!p->stopThread)
|
|
|
|
|
{
|
|
|
|
|
SANE_Byte data[2048];
|
|
|
|
|
|
|
|
|
|
SANE_Int len = 0;
|
|
|
|
|
SANE_Status stat = p->mgrImpl->m_f_sane_read(p->devHandle, data, 5000, &len);
|
|
|
|
|
if (SANE_STATUS_GOOD == stat)
|
|
|
|
|
{
|
|
|
|
|
HGBase_EnterLock(p->lock);
|
|
|
|
|
for (SANE_Int i = 0; i < len; ++i)
|
|
|
|
|
{
|
|
|
|
|
p->recvData.push_back(data[i]);
|
|
|
|
|
}
|
|
|
|
|
HGBase_LeaveLock(p->lock);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
assert(NULL != p->func);
|
|
|
|
|
|
|
|
|
|
if (SANE_STATUS_EOF == stat)
|
|
|
|
|
{
|
|
|
|
|
HGBase_EnterLock(p->lock);
|
|
|
|
|
p->imgReady = HGTRUE;
|
|
|
|
|
HGBase_LeaveLock(p->lock);
|
|
|
|
|
|
|
|
|
|
p->func((HGSaneDevice)p, HGSANE_DEVEVENT_IMGREADY, p->param);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
p->func((HGSaneDevice)p, HGSANE_DEVEVENT_ERROR, p->param);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HGResult HGSaneManagerImpl::FindFunctions()
|
|
|
|
|
{
|
|
|
|
|
HGResult ret = HGBASE_ERR_OK;
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
ret = HGBase_GetDllProcAddress(m_dll, "sane_init", (HGPointer*)&m_f_sane_init);
|
|
|
|
|
if (HGBASE_ERR_OK != ret)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ret = HGBase_GetDllProcAddress(m_dll, "sane_exit", (HGPointer*)&m_f_sane_exit);
|
|
|
|
|
if (HGBASE_ERR_OK != ret)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ret = HGBase_GetDllProcAddress(m_dll, "sane_get_devices", (HGPointer*)&m_f_sane_get_devices);
|
|
|
|
|
if (HGBASE_ERR_OK != ret)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ret = HGBase_GetDllProcAddress(m_dll, "sane_open", (HGPointer*)&m_f_sane_open);
|
|
|
|
|
if (HGBASE_ERR_OK != ret)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ret = HGBase_GetDllProcAddress(m_dll, "sane_close", (HGPointer*)&m_f_sane_close);
|
|
|
|
|
if (HGBASE_ERR_OK != ret)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ret = HGBase_GetDllProcAddress(m_dll, "sane_start", (HGPointer*)&m_f_sane_start);
|
|
|
|
|
if (HGBASE_ERR_OK != ret)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ret = HGBase_GetDllProcAddress(m_dll, "sane_read", (HGPointer*)&m_f_sane_read);
|
|
|
|
|
if (HGBASE_ERR_OK != ret)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ret = HGBase_GetDllProcAddress(m_dll, "sane_cancel", (HGPointer*)&m_f_sane_cancel);
|
|
|
|
|
if (HGBASE_ERR_OK != ret)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ret = HGBase_GetDllProcAddress(m_dll, "sane_set_io_mode", (HGPointer*)&m_f_sane_set_io_mode);
|
|
|
|
|
if (HGBASE_ERR_OK != ret)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
ret = HGBase_GetDllProcAddress(m_dll, "sane_strstatus", (HGPointer*)&m_f_sane_strstatus);
|
|
|
|
|
if (HGBASE_ERR_OK != ret)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
} while (0);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|