mirror of
https://github.com/PixlOne/logiops.git
synced 2025-07-14 05:12:34 +08:00
Move Buttons into their own class
This commit is contained in:
parent
6614702929
commit
1dd6dbfe02
@ -45,7 +45,7 @@ KeypressAction::KeypressAction(Device *device, config::KeypressAction& config) :
|
||||
const auto& keys = std::get<std::list<std::variant<uint, std::string>>>(
|
||||
_config.keys);
|
||||
for(const auto& key : keys) {
|
||||
if(std::holds_alternative<std::string>(_config.keys)) {
|
||||
if(std::holds_alternative<std::string>(key)) {
|
||||
const auto& key_str = std::get<std::string>(key);
|
||||
try {
|
||||
auto code = _device->virtualInput()->toKeyCode(key_str);
|
||||
@ -55,8 +55,8 @@ KeypressAction::KeypressAction(Device *device, config::KeypressAction& config) :
|
||||
logPrintf(WARN, "Invalid keycode %s, skipping.",
|
||||
key_str.c_str());
|
||||
}
|
||||
} else if(std::holds_alternative<uint>(_config.keys)) {
|
||||
auto& code = std::get<uint>(_config.keys);
|
||||
} else if(std::holds_alternative<uint>(key)) {
|
||||
auto& code = std::get<uint>(key);
|
||||
_device->virtualInput()->registerKey(code);
|
||||
_keys.emplace_back(code);
|
||||
}
|
||||
|
@ -31,8 +31,8 @@ AxisGesture::AxisGesture(Device *device, config::AxisGesture& config) :
|
||||
} else {
|
||||
const auto& axis = std::get<std::string>(_config.axis);
|
||||
try {
|
||||
_axis = _device->virtualInput()->toAxisCode(axis);
|
||||
_device->virtualInput()->registerAxis(_axis);
|
||||
_input_axis = _device->virtualInput()->toAxisCode(axis);
|
||||
_device->virtualInput()->registerAxis(_input_axis);
|
||||
} catch(InputDevice::InvalidEventCode& e) {
|
||||
logPrintf(WARN, "Invalid axis %s.");
|
||||
throw InvalidGesture();
|
||||
|
@ -33,22 +33,6 @@ RemapButton::RemapButton(Device *dev): DeviceFeature(dev),
|
||||
_config (dev->activeProfile().buttons),
|
||||
_ipc_node (dev->ipcNode()->make_child("buttons"))
|
||||
{
|
||||
if(_config.has_value()) {
|
||||
for(auto& button : _config.value()) {
|
||||
if(button.second.action.has_value()) {
|
||||
try {
|
||||
_buttons.emplace(
|
||||
button.first,
|
||||
Action::makeAction(
|
||||
dev,button.second.action.value()));
|
||||
} catch(std::exception& e) {
|
||||
logPrintf(WARN, "Error creating button action: %s",
|
||||
e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
_reprog_controls = hidpp20::ReprogControls::autoVersion(
|
||||
&dev->hidpp20());
|
||||
@ -58,6 +42,39 @@ RemapButton::RemapButton(Device *dev): DeviceFeature(dev),
|
||||
|
||||
_reprog_controls->initCidMap();
|
||||
|
||||
if(!_config.has_value())
|
||||
_config = config::RemapButton();
|
||||
|
||||
for(const auto& control : _reprog_controls->getControls()) {
|
||||
const auto i = _buttons.size();
|
||||
Button::ConfigFunction func = [this, info=control.second](
|
||||
std::shared_ptr<actions::Action> action) {
|
||||
hidpp20::ReprogControls::ControlInfo report{};
|
||||
report.controlID = info.controlID;
|
||||
report.flags = HIDPP20_REPROG_REBIND;
|
||||
|
||||
if(action) {
|
||||
if(( action->reprogFlags() &
|
||||
hidpp20::ReprogControls::RawXYDiverted ) &&
|
||||
( !_reprog_controls->supportsRawXY() ||
|
||||
!(info.additionalFlags & hidpp20::ReprogControls::RawXY) ))
|
||||
logPrintf(WARN,
|
||||
"%s: Cannot divert raw XY movements for CID "
|
||||
"0x%02x", _device->name().c_str(),
|
||||
info.controlID);
|
||||
|
||||
report.flags |= action->reprogFlags();
|
||||
}
|
||||
_reprog_controls->setControlReporting(info.controlID, report);
|
||||
};
|
||||
_buttons.emplace(std::piecewise_construct,
|
||||
std::forward_as_tuple(control.second.controlID),
|
||||
std::forward_as_tuple(control.second, i,
|
||||
_device, func,
|
||||
_ipc_node,
|
||||
_config.value()[control.first]));
|
||||
}
|
||||
|
||||
if(global_loglevel <= DEBUG) {
|
||||
#define FLAG(x) (control.second.flags & hidpp20::ReprogControls::x ? \
|
||||
"YES" : "")
|
||||
@ -77,14 +94,6 @@ RemapButton::RemapButton(Device *dev): DeviceFeature(dev),
|
||||
#undef ADDITIONAL_FLAG
|
||||
#undef FLAG
|
||||
}
|
||||
|
||||
for(const auto& control : _reprog_controls->getControls()) {
|
||||
auto i = std::to_string(_button_ipcs.size());
|
||||
auto node = _ipc_node->make_child(i);
|
||||
auto iface = node->make_interface<ButtonIPC>(this,
|
||||
control.second);
|
||||
_button_ipcs.emplace_back(node, iface);
|
||||
}
|
||||
}
|
||||
|
||||
RemapButton::~RemapButton()
|
||||
@ -94,32 +103,8 @@ RemapButton::~RemapButton()
|
||||
|
||||
void RemapButton::configure()
|
||||
{
|
||||
///TODO: DJ reporting trickery if cannot be remapped
|
||||
for(const auto& i : _buttons) {
|
||||
hidpp20::ReprogControls::ControlInfo info{};
|
||||
try {
|
||||
info = _reprog_controls->getControlIdInfo(i.first);
|
||||
} catch(hidpp20::Error& e) {
|
||||
if(e.code() == hidpp20::Error::InvalidArgument) {
|
||||
logPrintf(WARN, "%s: CID 0x%02x does not exist.",
|
||||
_device->name().c_str(), i.first);
|
||||
continue;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
if((i.second->reprogFlags() & hidpp20::ReprogControls::RawXYDiverted) &&
|
||||
(!_reprog_controls->supportsRawXY() || !(info.additionalFlags &
|
||||
hidpp20::ReprogControls::RawXY)))
|
||||
logPrintf(WARN, "%s: Cannot divert raw XY movements for CID "
|
||||
"0x%02x", _device->name().c_str(), i.first);
|
||||
|
||||
hidpp20::ReprogControls::ControlInfo report{};
|
||||
report.controlID = i.first;
|
||||
report.flags = HIDPP20_REPROG_REBIND;
|
||||
report.flags |= i.second->reprogFlags();
|
||||
_reprog_controls->setControlReporting(i.first, report);
|
||||
}
|
||||
for(const auto& button : _buttons)
|
||||
button.second.configure();
|
||||
}
|
||||
|
||||
void RemapButton::listen()
|
||||
@ -142,8 +127,8 @@ void RemapButton::listen()
|
||||
else { // RawXY
|
||||
auto divertedXY = _reprog_controls->divertedRawXYEvent(report);
|
||||
for(const auto& button : this->_buttons)
|
||||
if(button.second->pressed())
|
||||
button.second->move(divertedXY.x, divertedXY.y);
|
||||
if(button.second.pressed())
|
||||
button.second.move(divertedXY.x, divertedXY.y);
|
||||
}
|
||||
};
|
||||
|
||||
@ -164,7 +149,7 @@ void RemapButton::_buttonEvent(const std::set<uint16_t>& new_state)
|
||||
} else {
|
||||
auto action = _buttons.find(i);
|
||||
if(action != _buttons.end())
|
||||
action->second->press();
|
||||
action->second.press();
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,22 +157,66 @@ void RemapButton::_buttonEvent(const std::set<uint16_t>& new_state)
|
||||
for(auto& i : _pressed_buttons) {
|
||||
auto action = _buttons.find(i);
|
||||
if(action != _buttons.end())
|
||||
action->second->release();
|
||||
action->second.release();
|
||||
}
|
||||
|
||||
_pressed_buttons = new_state;
|
||||
}
|
||||
|
||||
RemapButton::ButtonIPC::ButtonIPC(
|
||||
RemapButton *parent,
|
||||
backend::hidpp20::ReprogControls::ControlInfo info) :
|
||||
Button::Button(Info info, int index,
|
||||
Device *device, ConfigFunction conf_func,
|
||||
std::shared_ptr<ipcgull::node> root,
|
||||
config::Button &config) :
|
||||
_node (root->make_child(std::to_string(index))),
|
||||
_interface (_node->make_interface<IPC>(this, info)),
|
||||
_device (device), _conf_func (std::move(conf_func)),
|
||||
_config (config),
|
||||
_info (info)
|
||||
{
|
||||
if(_config.action.has_value()) {
|
||||
try {
|
||||
_action = Action::makeAction(_device, _config.action.value());
|
||||
} catch(std::exception& e) {
|
||||
logPrintf(WARN, "Error creating button action: %s",
|
||||
e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Button::press() const {
|
||||
if(_action)
|
||||
_action->press();
|
||||
}
|
||||
|
||||
void Button::release() const {
|
||||
if(_action)
|
||||
_action->release();
|
||||
}
|
||||
|
||||
void Button::move(int16_t x, int16_t y) const {
|
||||
if(_action)
|
||||
_action->move(x, y);
|
||||
}
|
||||
|
||||
bool Button::pressed() const {
|
||||
if(_action)
|
||||
return _action->pressed();
|
||||
return false;
|
||||
}
|
||||
|
||||
void Button::configure() const {
|
||||
_conf_func(_action);
|
||||
}
|
||||
|
||||
Button::IPC::IPC(Button* parent,
|
||||
const Info& info) :
|
||||
ipcgull::interface("pizza.pixl.LogiOps.Device.Button", {}, {
|
||||
{"ControlID", ipcgull::property<uint16_t>(
|
||||
ipcgull::property_readable, info.controlID)},
|
||||
{"Remappable", ipcgull::property<bool>(
|
||||
{"Remappable", ipcgull::property<const bool>(
|
||||
ipcgull::property_readable,
|
||||
info.flags & hidpp20::ReprogControls::TemporaryDivertable)},
|
||||
{"GestureSupport", ipcgull::property<bool>(
|
||||
{"GestureSupport", ipcgull::property<const bool>(
|
||||
ipcgull::property_readable,
|
||||
(info.additionalFlags & hidpp20::ReprogControls::RawXY)
|
||||
)}
|
||||
|
@ -25,6 +25,45 @@
|
||||
namespace logid {
|
||||
namespace features
|
||||
{
|
||||
class RemapButton;
|
||||
|
||||
class Button
|
||||
{
|
||||
public:
|
||||
typedef backend::hidpp20::ReprogControls::ControlInfo Info;
|
||||
typedef std::function<void(std::shared_ptr<actions::Action>)>
|
||||
ConfigFunction;
|
||||
|
||||
Button(Info info, int index,
|
||||
Device* device, ConfigFunction conf_func,
|
||||
std::shared_ptr<ipcgull::node> root,
|
||||
config::Button& config);
|
||||
void press() const;
|
||||
void release() const;
|
||||
void move(int16_t x, int16_t y) const;
|
||||
|
||||
void configure() const;
|
||||
|
||||
bool pressed() const;
|
||||
private:
|
||||
class IPC : public ipcgull::interface
|
||||
{
|
||||
public:
|
||||
IPC(Button* parent,
|
||||
const Info& info);
|
||||
};
|
||||
|
||||
std::shared_ptr<ipcgull::node> _node;
|
||||
std::shared_ptr<IPC> _interface;
|
||||
Device* _device;
|
||||
const ConfigFunction _conf_func;
|
||||
|
||||
config::Button& _config;
|
||||
|
||||
std::shared_ptr<actions::Action> _action;
|
||||
const Info _info;
|
||||
};
|
||||
|
||||
class RemapButton : public DeviceFeature
|
||||
{
|
||||
public:
|
||||
@ -34,25 +73,15 @@ namespace features
|
||||
virtual void listen();
|
||||
|
||||
private:
|
||||
class ButtonIPC : public ipcgull::interface
|
||||
{
|
||||
public:
|
||||
ButtonIPC(RemapButton* parent,
|
||||
backend::hidpp20::ReprogControls::ControlInfo info);
|
||||
};
|
||||
|
||||
void _buttonEvent(const std::set<uint16_t>& new_state);
|
||||
std::shared_ptr<backend::hidpp20::ReprogControls> _reprog_controls;
|
||||
std::set<uint16_t> _pressed_buttons;
|
||||
std::mutex _button_lock;
|
||||
|
||||
std::optional<config::RemapButton>& _config;
|
||||
std::map<uint16_t, std::shared_ptr<actions::Action>> _buttons;
|
||||
std::map<uint16_t, Button> _buttons;
|
||||
|
||||
std::shared_ptr<ipcgull::node> _ipc_node;
|
||||
typedef std::pair<std::shared_ptr<ipcgull::node>,
|
||||
std::shared_ptr<ButtonIPC>> ButtonIPCPair;
|
||||
std::vector<ButtonIPCPair> _button_ipcs;
|
||||
};
|
||||
}}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user