code_app/app/scanner/sane_device.cpp

190 lines
4.3 KiB
C++
Raw Normal View History

2022-05-03 10:25:52 +00:00
#include "sane_device.h"
sane_dev::sane_dev() : hdev_(nullptr), offline_(true), name_(""), cfg_name_("")
{}
sane_dev::~sane_dev()
{
close();
}
bool sane_dev::apply(OPTSCHEME* schm)
{
SANE_Int count = 0,
afterdo = 0;
bool ret = false;
if(sane_control_option(hdev_, 0, SANE_ACTION_GET_VALUE, &count, &afterdo) == SANE_STATUS_GOOD)
{
int applied = 0;
for(int i = 1; i < count; ++i)
{
const SANE_Option_Descriptor* desc = sane_get_option_descriptor(hdev_, i);
2022-05-03 10:25:52 +00:00
if(!desc)
continue;
if(desc->type == SANE_TYPE_GROUP ||
desc->type == SANE_TYPE_BUTTON)
continue;
act_result result = apply(desc, i, schm->opts);
2022-05-03 10:25:52 +00:00
if(result == ACT_RESULT_NO_NEED)
continue;
if(result == ACT_RESULT_SUCCESS)
applied++;
2022-05-03 10:25:52 +00:00
else
break;
}
ret = schm->opts.size() == applied;
2022-05-03 10:25:52 +00:00
}
if(ret)
2022-10-18 10:51:24 +00:00
cfg_name_ = schm->m_schemeTitle;
2022-05-03 10:25:52 +00:00
return ret;
}
sane_dev::act_result sane_dev::apply(const SANE_Option_Descriptor* desc, int opt, const std::vector<OPTVAL>& vals)
2022-05-03 10:25:52 +00:00
{
act_result result = ACT_RESULT_NO_NEED;
const OPTVAL *cfg = nullptr;
for(size_t i = 0; i < vals.size(); ++i)
{
2022-10-12 09:42:55 +00:00
if(vals[i].name == desc->name)
2022-05-03 10:25:52 +00:00
{
cfg = &vals[i];
break;
}
}
if(cfg)
{
SANE_Int afterdo = 0;
void *data = nullptr, *str = nullptr;
SANE_Int nv = 0;
SANE_Bool bv = false;
SANE_Fixed fv = 0;
result = ACT_RESULT_FAILED;
if(desc->type == SANE_TYPE_INT)
{
nv = atoi(cfg->val.c_str());
data = &nv;
}
else if(desc->type == SANE_TYPE_BOOL)
{
bv = cfg->val == "true";
data = &bv;
}
else if(desc->type == SANE_TYPE_FIXED)
{
fv = SANE_FIX(atof(cfg->val.c_str()));
data = &fv;
}
else if(desc->type == SANE_TYPE_STRING)
{
int len = (int)cfg->val.length() > desc->size * 4 ? cfg->val.length() : desc->size * 4;
str = new char[len + 4];
if(str)
{
memset(str, 0, len + 4);
strcpy((char*)str, cfg->val.c_str());
data = str;
}
}
if(data)
result = sane_control_option(hdev_, opt, SANE_ACTION_SET_VALUE, data, &afterdo) == SANE_STATUS_GOOD ? ACT_RESULT_SUCCESS : result;
if(str)
delete[] str;
2022-10-13 07:14:20 +00:00
if(cfg->name == SANE_STD_OPT_NAME_IS_CUSTOM_GAMMA && cfg->val == "true")
{
SANE_Gamma gamma = {0};
unsigned int l = 0;
if(config::load_custom_gamma(cfg->extra.c_str(), &gamma))
sane_io_control(hdev_, IO_CTRL_CODE_SET_CUSTOM_GAMMA, &gamma, &l);
}
2022-05-03 10:25:52 +00:00
}
return result;
}
std::string sane_dev::name(void)
{
return name_;
}
std::string sane_dev::current_configuration_name(void)
{
return cfg_name_;
}
bool sane_dev::is_online(void)
{
return !offline_;
}
SANE_Handle sane_dev::handle(void)
{
return hdev_;
}
bool sane_dev::open(const std::string& name)
{
if(name_ == name)
return true;
close();
SANE_Status statu = sane_open(name.c_str(), &hdev_);
if(statu == SANE_STATUS_GOOD)
{
DEVCFG first;
name_ = name;
offline_ = false;
if(first.schemes.size())
2022-10-18 10:51:24 +00:00
cfg_name_ = first.schemes[0].m_schemeTitle;
2022-05-03 10:25:52 +00:00
}
return statu == SANE_STATUS_GOOD;
}
bool sane_dev::apply_setting(OPTSCHEME* schm)
{
bool ret = false;
if(hdev_)
{
if(sane_io_control(hdev_, IO_CTRL_CODE_RESTORE_SETTINGS, nullptr, nullptr) == SANE_STATUS_GOOD)
{
DEVCFG first;
if(first.schemes.size())
2022-10-18 10:51:24 +00:00
cfg_name_ = first.schemes[0].m_schemeTitle;
2022-05-03 10:25:52 +00:00
if(schm)
{
ret = apply(schm);
}
else
{
ret = true;
}
}
}
return ret;
}
void sane_dev::set_online(bool online)
{
offline_ = !online;
}
void sane_dev::close(void)
{
if(hdev_)
{
sane_close(hdev_);
hdev_ = nullptr;
}
offline_ = true;
name_ = "";
cfg_name_ = "";
}