From 605ccdc07d96d4a88cdad5a5a19df306e97b0cea Mon Sep 17 00:00:00 2001 From: pixl Date: Mon, 14 Feb 2022 01:03:56 -0500 Subject: [PATCH] Add several IPC interfaces --- src/ipcgull | 2 +- src/logid/Configuration.cpp | 7 ++ src/logid/Configuration.h | 8 ++ src/logid/Device.cpp | 13 +- src/logid/Device.h | 6 +- src/logid/DeviceManager.cpp | 1 + src/logid/DeviceManager.h | 1 + src/logid/InputDevice.cpp | 25 ++++ src/logid/InputDevice.h | 4 + src/logid/actions/Action.cpp | 17 ++- src/logid/actions/Action.h | 7 +- src/logid/actions/ChangeDPI.cpp | 16 +-- src/logid/actions/ChangeDPI.h | 10 -- src/logid/actions/ChangeHostAction.cpp | 26 ++-- src/logid/actions/ChangeHostAction.h | 10 -- src/logid/actions/CycleDPI.cpp | 37 +++--- src/logid/actions/CycleDPI.h | 10 -- src/logid/actions/GestureAction.cpp | 56 +++++++-- src/logid/actions/GestureAction.h | 15 +-- src/logid/actions/KeypressAction.cpp | 98 ++++++++++----- src/logid/actions/KeypressAction.h | 14 +-- src/logid/actions/NullAction.cpp | 16 +-- src/logid/actions/NullAction.h | 6 - src/logid/actions/ToggleHiresScroll.cpp | 12 +- src/logid/actions/ToggleHiresScroll.h | 8 -- src/logid/actions/ToggleSmartShift.cpp | 12 +- src/logid/actions/ToggleSmartShift.h | 8 -- src/logid/actions/gesture/AxisGesture.cpp | 40 ++++--- src/logid/actions/gesture/AxisGesture.h | 7 +- src/logid/actions/gesture/Gesture.cpp | 49 ++++++-- src/logid/actions/gesture/Gesture.h | 18 +-- src/logid/actions/gesture/IntervalGesture.cpp | 16 ++- src/logid/actions/gesture/IntervalGesture.h | 17 ++- src/logid/actions/gesture/NullGesture.cpp | 7 +- src/logid/actions/gesture/NullGesture.h | 5 +- src/logid/actions/gesture/ReleaseGesture.cpp | 7 +- src/logid/actions/gesture/ReleaseGesture.h | 5 +- .../actions/gesture/ThresholdGesture.cpp | 11 +- src/logid/actions/gesture/ThresholdGesture.h | 5 +- src/logid/backend/raw/IOMonitor.cpp | 6 +- src/logid/config/group.h | 4 +- src/logid/config/map.h | 20 +++- src/logid/config/schema.h | 29 +++-- src/logid/config/types.h | 30 +++-- src/logid/features/HiresScroll.cpp | 2 +- src/logid/features/RemapButton.cpp | 113 +++++++++++++++--- src/logid/features/RemapButton.h | 38 +++++- src/logid/features/SmartShift.cpp | 94 ++++++++++++++- src/logid/features/SmartShift.h | 27 ++++- src/logid/features/ThumbWheel.cpp | 11 +- src/logid/features/ThumbWheel.h | 1 + 51 files changed, 672 insertions(+), 335 deletions(-) diff --git a/src/ipcgull b/src/ipcgull index e86f198..200df3c 160000 --- a/src/ipcgull +++ b/src/ipcgull @@ -1 +1 @@ -Subproject commit e86f1987bc40c840d3cef758619783e5bdec1c41 +Subproject commit 200df3c202739de5249b2fd7c43900fcb25c01cb diff --git a/src/logid/Configuration.cpp b/src/logid/Configuration.cpp index b87df91..63e8817 100644 --- a/src/logid/Configuration.cpp +++ b/src/logid/Configuration.cpp @@ -62,4 +62,11 @@ void Configuration::save() _config_file.c_str(), e.what()); throw; } +} + +Configuration::IPC::IPC(Configuration *config) : + ipcgull::interface("pizza.pixl.LogiOps.Config", { + {"Save", {config, &Configuration::save}} + }, {}, {}) +{ } \ No newline at end of file diff --git a/src/logid/Configuration.h b/src/logid/Configuration.h index 213d654..41cfbae 100644 --- a/src/logid/Configuration.h +++ b/src/logid/Configuration.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "config/schema.h" @@ -44,6 +45,13 @@ namespace logid // Reloading is not safe, references will be invalidated //void reload(); void save(); + + class IPC : public ipcgull::interface + { + public: + IPC(Configuration* config); + }; + private: std::string _config_file; libconfig::Config _config; diff --git a/src/logid/Device.cpp b/src/logid/Device.cpp index 07e005d..fd8ad71 100644 --- a/src/logid/Device.cpp +++ b/src/logid/Device.cpp @@ -67,7 +67,7 @@ std::shared_ptr Device::make( std::move(manager)); ret->_self = ret; ret->_ipc_node->manage(ret); - ret->_ipc_interface = ret->_ipc_node->make_interface(ret.get()); + ret->_ipc_interface = ret->_ipc_node->make_interface(ret.get()); return ret; } @@ -81,7 +81,7 @@ std::shared_ptr Device::make( std::move(manager)); ret->_self = ret; ret->_ipc_node->manage(ret); - ret->_ipc_interface = ret->_ipc_node->make_interface(ret.get()); + ret->_ipc_interface = ret->_ipc_node->make_interface(ret.get()); return ret; } @@ -92,7 +92,7 @@ std::shared_ptr Device::make( auto ret = std::make_shared<_Device>(receiver, index, std::move(manager)); ret->_self = ret; ret->_ipc_node->manage(ret); - ret->_ipc_interface = ret->_ipc_node->make_interface(ret.get()); + ret->_ipc_interface = ret->_ipc_node->make_interface(ret.get()); return ret; } @@ -265,7 +265,7 @@ void Device::_makeResetMechanism() } } -Device::DeviceIPC::DeviceIPC(Device* device) : +Device::IPC::IPC(Device* device) : ipcgull::interface( "pizza.pixl.LogiOps.Device", {}, @@ -274,7 +274,8 @@ Device::DeviceIPC::DeviceIPC(Device* device) : ipcgull::property_readable, device->name())}, {"ProductID", ipcgull::property( ipcgull::property_readable, device->pid())}, - {"Active", device->_awake} + {"Active", device->_awake}, + {"DefaultProfile", device->_config.default_profile} }, { {"StatusChanged", ipcgull::signal::make_signal({"active"})} @@ -282,7 +283,7 @@ Device::DeviceIPC::DeviceIPC(Device* device) : { } -void Device::DeviceIPC::notifyStatus() const +void Device::IPC::notifyStatus() const { emit_signal("StatusChanged", (bool)(_device._awake)); } diff --git a/src/logid/Device.h b/src/logid/Device.h index 503ab44..2af5397 100644 --- a/src/logid/Device.h +++ b/src/logid/Device.h @@ -142,17 +142,17 @@ namespace logid const DeviceNickname _nickname; std::shared_ptr _ipc_node; - class DeviceIPC : public ipcgull::interface { + class IPC : public ipcgull::interface { private: Device& _device; public: - DeviceIPC(Device* device); + IPC(Device* device); void notifyStatus() const; }; ipcgull::property _awake; std::mutex _state_lock; - std::shared_ptr _ipc_interface; + std::shared_ptr _ipc_interface; std::weak_ptr _self; }; diff --git a/src/logid/DeviceManager.cpp b/src/logid/DeviceManager.cpp index a6d0229..bb669f5 100644 --- a/src/logid/DeviceManager.cpp +++ b/src/logid/DeviceManager.cpp @@ -52,6 +52,7 @@ DeviceManager::DeviceManager(std::shared_ptr config, { _ipc_devices = _root_node->make_interface(this); _ipc_receivers = _root_node->make_interface(this); + _ipc_config = _root_node->make_interface(_config.get()); _device_node->add_server(_server); _receiver_node->add_server(_server); _root_node->add_server(_server); diff --git a/src/logid/DeviceManager.h b/src/logid/DeviceManager.h index aecc991..0c9f680 100644 --- a/src/logid/DeviceManager.h +++ b/src/logid/DeviceManager.h @@ -88,6 +88,7 @@ namespace logid std::shared_ptr _device_node; std::shared_ptr _receiver_node; + std::shared_ptr _ipc_config; std::shared_ptr _ipc_devices; std::shared_ptr _ipc_receivers; diff --git a/src/logid/InputDevice.cpp b/src/logid/InputDevice.cpp index 131514c..20646e2 100644 --- a/src/logid/InputDevice.cpp +++ b/src/logid/InputDevice.cpp @@ -33,6 +33,11 @@ InputDevice::InvalidEventCode::InvalidEventCode(const std::string& name) : { } +InputDevice::InvalidEventCode::InvalidEventCode(uint code) : + _what ("Invalid event code " + std::to_string(code)) +{ +} + const char* InputDevice::InvalidEventCode::what() const noexcept { return _what.c_str(); @@ -115,11 +120,21 @@ void InputDevice::releaseKey(uint code) _sendEvent(EV_KEY, code, 0); } +std::string InputDevice::toKeyName(uint code) +{ + return _toEventName(EV_KEY, code); +} + uint InputDevice::toKeyCode(const std::string& name) { return _toEventCode(EV_KEY, name); } +std::string InputDevice::toAxisName(uint code) +{ + return _toEventName(EV_REL, code); +} + uint InputDevice::toAxisCode(const std::string& name) { return _toEventCode(EV_REL, name); @@ -141,6 +156,16 @@ int InputDevice::getLowResAxis(const uint axis_code) return -1; } +std::string InputDevice::_toEventName(uint type, uint code) +{ + const char* ret = libevdev_event_code_get_name(type, code); + + if(!ret) + throw InvalidEventCode(code); + + return {ret}; +} + uint InputDevice::_toEventCode(uint type, const std::string& name) { int code = libevdev_event_code_from_name(type, name.c_str()); diff --git a/src/logid/InputDevice.h b/src/logid/InputDevice.h index 17e5045..9994787 100644 --- a/src/logid/InputDevice.h +++ b/src/logid/InputDevice.h @@ -37,6 +37,7 @@ namespace logid { public: explicit InvalidEventCode(const std::string& name); + explicit InvalidEventCode(uint code); const char* what() const noexcept override; private: const std::string _what; @@ -50,7 +51,9 @@ namespace logid void pressKey(uint code); void releaseKey(uint code); + static std::string toKeyName(uint code); static uint toKeyCode(const std::string& name); + static std::string toAxisName(uint code); static uint toAxisCode(const std::string& name); static int getLowResAxis(uint axis_code); @@ -58,6 +61,7 @@ namespace logid void _sendEvent(uint type, uint code, int value); void _enableEvent(uint type, uint name); + static std::string _toEventName(uint type, uint code); static uint _toEventCode(uint type, const std::string& name); bool registered_keys[KEY_CNT]; diff --git a/src/logid/actions/Action.cpp b/src/logid/actions/Action.cpp index 722b14c..26601d7 100644 --- a/src/logid/actions/Action.cpp +++ b/src/logid/actions/Action.cpp @@ -43,9 +43,11 @@ struct action_type : action_type { }; template std::shared_ptr _makeAction( - Device* device, T action, - const std::shared_ptr& parent) { - return std::make_shared::type>(device, action, parent); + Device* device, T& action, + const std::shared_ptr& parent) +{ + return parent->make_interface::type>( + device, std::forward(action), parent); } template @@ -75,7 +77,8 @@ std::shared_ptr _makeAction( } else if(name == ToggleSmartShift::interface_name) { config = config::ToggleHiresScroll(); return Action::makeAction(device, config.value(), parent); - } else if(name == "pizza.pixl.LogiOps.Action.Default") { + } else if(name == "Default") { + config.reset(); return nullptr; } @@ -127,3 +130,9 @@ std::shared_ptr Action::makeAction( }, action); return ret; } + +Action::Action(Device* device, const std::string& name, tables t) : + ipcgull::interface("pizza.pixl.LogiOps.Action." + name, std::move(t)), + _device (device), _pressed (false) +{ +} diff --git a/src/logid/actions/Action.h b/src/logid/actions/Action.h index d670906..240c4d8 100644 --- a/src/logid/actions/Action.h +++ b/src/logid/actions/Action.h @@ -45,7 +45,7 @@ namespace actions { std::string _action; }; - class Action + class Action : public ipcgull::interface { public: static std::shared_ptr makeAction( @@ -84,9 +84,8 @@ namespace actions { virtual ~Action() = default; protected: - explicit Action(Device* device) : _device (device), _pressed (false) - { - } + Action(Device* device, const std::string& name, tables t={}); + Device* _device; std::atomic _pressed; }; diff --git a/src/logid/actions/ChangeDPI.cpp b/src/logid/actions/ChangeDPI.cpp index 78f05d1..782f1de 100644 --- a/src/logid/actions/ChangeDPI.cpp +++ b/src/logid/actions/ChangeDPI.cpp @@ -24,13 +24,12 @@ using namespace logid::actions; -const char* ChangeDPI::interface_name = - "pizza.pixl.LogiOps.Action.ChangeDPI"; +const char* ChangeDPI::interface_name = "ChangeDPI"; ChangeDPI::ChangeDPI( Device *device, config::ChangeDPI& config, const std::shared_ptr& parent) : - Action(device), _config (config) + Action(device, interface_name), _config (config) { _dpi = _device->getFeature("dpi"); if(!_dpi) @@ -38,19 +37,17 @@ ChangeDPI::ChangeDPI( "ChangeDPI action.", _device->hidpp20().devicePath().c_str(), _device->hidpp20().deviceIndex()); - - _ipc = parent->make_interface(this); } void ChangeDPI::press() { _pressed = true; - if(_dpi) { + if(_dpi && _config.inc.has_value()) { spawn_task( [this]{ try { uint16_t last_dpi = _dpi->getDPI(_config.sensor.value_or(0)); - _dpi->setDPI(last_dpi + _config.inc, + _dpi->setDPI(last_dpi + _config.inc.value(), _config.sensor.value_or(0)); } catch (backend::hidpp20::Error& e) { if(e.code() == backend::hidpp20::Error::InvalidArgument) @@ -75,8 +72,3 @@ uint8_t ChangeDPI::reprogFlags() const { return backend::hidpp20::ReprogControls::TemporaryDiverted; } - -ChangeDPI::IPC::IPC(ChangeDPI *action) : - ipcgull::interface(interface_name, {}, {}, {}), _action (*action) -{ -} diff --git a/src/logid/actions/ChangeDPI.h b/src/logid/actions/ChangeDPI.h index d37dff9..4f83065 100644 --- a/src/logid/actions/ChangeDPI.h +++ b/src/logid/actions/ChangeDPI.h @@ -40,16 +40,6 @@ namespace logid { protected: config::ChangeDPI& _config; std::shared_ptr _dpi; - private: - class IPC : public ipcgull::interface - { - public: - IPC(ChangeDPI* action); - private: - ChangeDPI& _action; - }; - - std::shared_ptr _ipc; }; }} diff --git a/src/logid/actions/ChangeHostAction.cpp b/src/logid/actions/ChangeHostAction.cpp index c0fcc5f..9b34830 100644 --- a/src/logid/actions/ChangeHostAction.cpp +++ b/src/logid/actions/ChangeHostAction.cpp @@ -24,16 +24,15 @@ using namespace logid::actions; using namespace logid::backend; -const char* ChangeHostAction::interface_name = - "pizza.pixl.LogiOps.Action.ChangeHost"; +const char* ChangeHostAction::interface_name = "ChangeHost"; ChangeHostAction::ChangeHostAction( Device *device, config::ChangeHost& config, - const std::shared_ptr& parent) - : Action(device), _config (config) + [[maybe_unused]] const std::shared_ptr& parent) + : Action(device, interface_name), _config (config) { - if(std::holds_alternative(_config.host)) { - auto& host = std::get(_config.host); + if(std::holds_alternative(_config.host.value())) { + auto& host = std::get(_config.host.value()); std::transform(host.begin(), host.end(), host.begin(), ::tolower); } @@ -44,8 +43,6 @@ ChangeHostAction::ChangeHostAction( "ChangeHostAction will not work.", device->hidpp20() .devicePath().c_str(), device->hidpp20().deviceIndex()); } - - _ipc = parent->make_interface(this); } void ChangeHostAction::press() @@ -55,13 +52,13 @@ void ChangeHostAction::press() void ChangeHostAction::release() { - if(_change_host) { + if(_change_host && _config.host.has_value()) { spawn_task( [this] { auto host_info = _change_host->getHostInfo(); int next_host; - if(std::holds_alternative(_config.host)) { - const auto& host = std::get(_config.host); + if(std::holds_alternative(_config.host.value())) { + const auto& host = std::get(_config.host.value()); if(host == "next") next_host = host_info.currentHost + 1; else if(host == "prev" || host == "previous") @@ -69,7 +66,7 @@ void ChangeHostAction::release() else next_host = host_info.currentHost; } else { - next_host = std::get(_config.host)-1; + next_host = std::get(_config.host.value())-1; } next_host %= host_info.hostCount; if(next_host != host_info.currentHost) @@ -82,8 +79,3 @@ uint8_t ChangeHostAction::reprogFlags() const { return hidpp20::ReprogControls::TemporaryDiverted; } - -ChangeHostAction::IPC::IPC(ChangeHostAction *action) : - ipcgull::interface(interface_name, {}, {}, {}), _action (*action) -{ -} diff --git a/src/logid/actions/ChangeHostAction.h b/src/logid/actions/ChangeHostAction.h index e5ac8e8..1f26f04 100644 --- a/src/logid/actions/ChangeHostAction.h +++ b/src/logid/actions/ChangeHostAction.h @@ -41,16 +41,6 @@ namespace actions protected: std::shared_ptr _change_host; config::ChangeHost& _config; - private: - class IPC : public ipcgull::interface - { - public: - IPC(ChangeHostAction* action); - private: - ChangeHostAction& _action; - }; - - std::shared_ptr _ipc; }; }} diff --git a/src/logid/actions/CycleDPI.cpp b/src/logid/actions/CycleDPI.cpp index a169447..010a8e6 100644 --- a/src/logid/actions/CycleDPI.cpp +++ b/src/logid/actions/CycleDPI.cpp @@ -25,12 +25,12 @@ using namespace logid::actions; using namespace libconfig; -const char* CycleDPI::interface_name = - "pizza.pixl.LogiOps.Action.CycleDPI"; +const char* CycleDPI::interface_name = "CycleDPI"; CycleDPI::CycleDPI(Device* device, config::CycleDPI& config, const std::shared_ptr& parent) : - Action (device), _config (config), _current_dpi (_config.dpis.begin()) + Action (device, interface_name), + _config (config) { _dpi = _device->getFeature("dpi"); if(!_dpi) @@ -39,27 +39,29 @@ CycleDPI::CycleDPI(Device* device, config::CycleDPI& config, _device->hidpp20().devicePath().c_str(), _device->hidpp20().deviceIndex()); - _ipc = parent->make_interface(this); + if(_config.dpis.has_value()) { + _current_dpi = _config.dpis.value().begin(); + } } void CycleDPI::press() { _pressed = true; - if(_dpi && !_config.dpis.empty()) { - spawn_task( - [this](){ - std::lock_guard lock(_dpi_lock); - ++_current_dpi; - if(_current_dpi == _config.dpis.end()) - _current_dpi = _config.dpis.begin(); + std::lock_guard lock(_dpi_lock); + if(_dpi && _config.dpis.has_value() && _config.dpis.value().empty()) { + ++_current_dpi; + if(_current_dpi == _config.dpis.value().end()) + _current_dpi = _config.dpis.value().begin(); + + spawn_task([this, dpi=*_current_dpi]{ try { - _dpi->setDPI(*_current_dpi, _config.sensor.value_or(0)); + _dpi->setDPI(dpi, _config.sensor.value_or(0)); } catch (backend::hidpp20::Error& e) { if(e.code() == backend::hidpp20::Error::InvalidArgument) logPrintf(WARN, "%s:%d: Could not set DPI to %d for " - "sensor %d", _device->hidpp20().devicePath().c_str(), - _device->hidpp20().deviceIndex(), *_current_dpi, - _config.sensor.value_or(0)); + "sensor %d", _device->hidpp20().devicePath().c_str(), + _device->hidpp20().deviceIndex(), dpi, + _config.sensor.value_or(0)); else throw e; } @@ -76,8 +78,3 @@ uint8_t CycleDPI::reprogFlags() const { return backend::hidpp20::ReprogControls::TemporaryDiverted; } - -CycleDPI::IPC::IPC(CycleDPI *action) : - ipcgull::interface(interface_name, {}, {}, {}), _action (*action) -{ -} diff --git a/src/logid/actions/CycleDPI.h b/src/logid/actions/CycleDPI.h index d21c3bf..8f2cbfa 100644 --- a/src/logid/actions/CycleDPI.h +++ b/src/logid/actions/CycleDPI.h @@ -42,16 +42,6 @@ namespace actions { config::CycleDPI& _config; std::shared_ptr _dpi; std::list::const_iterator _current_dpi; - private: - class IPC : public ipcgull::interface - { - public: - IPC(CycleDPI* action); - private: - CycleDPI& _action; - }; - - std::shared_ptr _ipc; }; }} diff --git a/src/logid/actions/GestureAction.cpp b/src/logid/actions/GestureAction.cpp index d654d22..fd9afd4 100644 --- a/src/logid/actions/GestureAction.cpp +++ b/src/logid/actions/GestureAction.cpp @@ -24,8 +24,7 @@ using namespace logid::actions; using namespace logid; using namespace logid::backend; -const char* GestureAction::interface_name = - "pizza.pixl.LogiOps.Action.Gesture"; +const char* GestureAction::interface_name = "Gesture"; GestureAction::Direction GestureAction::toDirection(std::string direction) { @@ -78,7 +77,14 @@ GestureAction::Direction GestureAction::toDirection(int16_t x, int16_t y) GestureAction::GestureAction(Device* dev, config::GestureAction& config, const std::shared_ptr& parent) : - Action (dev), _config (config) + Action (dev, interface_name, + { + { + {"SetGesture", {this, &GestureAction::setGesture, + {"direction", "type"}}} + }, {}, {} + }), + _node (parent->make_child("gestures")), _config (config) { if(_config.gestures.has_value()) { auto& gestures = _config.gestures.value(); @@ -87,19 +93,20 @@ GestureAction::GestureAction(Device* dev, config::GestureAction& config, auto direction = toDirection(x.first); _gestures.emplace(direction, Gesture::makeGesture( - dev, x.second, parent, - fromDirection(direction))); + dev, x.second, + _node->make_child( + fromDirection(direction)))); } catch(std::invalid_argument& e) { logPrintf(WARN, "%s is not a direction", x.first.c_str()); } } } - - _ipc = parent->make_interface(this); } void GestureAction::press() { + std::lock_guard lock(_config_lock); + _pressed = true; _x = 0, _y = 0; for(auto& gesture : _gestures) @@ -108,6 +115,8 @@ void GestureAction::press() void GestureAction::release() { + std::lock_guard lock(_config_lock); + _pressed = false; bool threshold_met = false; @@ -147,6 +156,8 @@ void GestureAction::release() void GestureAction::move(int16_t x, int16_t y) { + std::lock_guard lock(_config_lock); + auto new_x = _x + x, new_y = _y + y; if(abs(x) > 0) { @@ -218,7 +229,34 @@ uint8_t GestureAction::reprogFlags() const hidpp20::ReprogControls::RawXYDiverted); } -GestureAction::IPC::IPC(GestureAction *action) : - ipcgull::interface(interface_name, {}, {}, {}), _action (*action) +void GestureAction::setGesture(const std::string &direction, + const std::string &type) { + std::lock_guard lock(_config_lock); + + Direction d = toDirection(direction); + + auto it = _gestures.find(d); + + if(it != _gestures.end()) { + if(pressed()) { + auto current = toDirection(_x, _y); + if(it->second) + it->second->release(current == d); + } + } + + auto dir_name = fromDirection(d); + + _gestures[d].reset(); + try { + _gestures[d] = Gesture::makeGesture( + _device, type, _config.gestures.value()[dir_name], + _node->make_child(dir_name)); + } catch (InvalidGesture& e) { + _gestures[d] = Gesture::makeGesture( + _device, _config.gestures.value()[dir_name], + _node->make_child(dir_name)); + throw std::invalid_argument("Invalid gesture type"); + } } diff --git a/src/logid/actions/GestureAction.h b/src/logid/actions/GestureAction.h index a66c732..2dfc603 100644 --- a/src/logid/actions/GestureAction.h +++ b/src/logid/actions/GestureAction.h @@ -51,21 +51,14 @@ namespace actions { virtual uint8_t reprogFlags() const; + void setGesture(const std::string& direction, + const std::string& type); protected: int16_t _x, _y; + std::shared_ptr _node; std::map> _gestures; config::GestureAction& _config; - - private: - class IPC : public ipcgull::interface - { - public: - explicit IPC(GestureAction* action); - private: - GestureAction& _action; - }; - - std::shared_ptr _ipc; + mutable std::mutex _config_lock; }; }} diff --git a/src/logid/actions/KeypressAction.cpp b/src/logid/actions/KeypressAction.cpp index ff6afac..909ed37 100644 --- a/src/logid/actions/KeypressAction.cpp +++ b/src/logid/actions/KeypressAction.cpp @@ -24,15 +24,48 @@ using namespace logid::actions; using namespace logid::backend; -const char* KeypressAction::interface_name = - "pizza.pixl.LogiOps.Action.Keypress"; +const char* KeypressAction::interface_name = "Keypress"; -KeypressAction::KeypressAction(Device *device, config::KeypressAction& config, - const std::shared_ptr& parent) : - Action(device), _config (config) +KeypressAction::KeypressAction( + Device *device, config::KeypressAction& config, + [[maybe_unused]] const std::shared_ptr& parent) : + Action(device, interface_name, { + { + {"GetKeys", {this, &KeypressAction::getKeys, {"keys"}}}, + {"SetKeys", {this, &KeypressAction::setKeys, {"keys"}}} + }, {}, {} + }), _config (config) { - if(std::holds_alternative(_config.keys)) { - const auto& key = std::get(_config.keys); + _setConfig(); +} + +void KeypressAction::press() +{ + std::lock_guard lock(_config_lock); + _pressed = true; + for(auto& key : _keys) + _device->virtualInput()->pressKey(key); +} + +void KeypressAction::release() +{ + std::lock_guard lock(_config_lock); + _pressed = false; + for(auto& key : _keys) + _device->virtualInput()->releaseKey(key); +} + +void KeypressAction::_setConfig() +{ + _keys.clear(); + + if(!_config.keys.has_value()) + return; + + auto& config = _config.keys.value(); + + if(std::holds_alternative(config)) { + const auto& key = std::get(config); try { auto code = _device->virtualInput()->toKeyCode(key); _device->virtualInput()->registerKey(code); @@ -40,14 +73,14 @@ KeypressAction::KeypressAction(Device *device, config::KeypressAction& config, } catch(InputDevice::InvalidEventCode& e) { logPrintf(WARN, "Invalid keycode %s, skipping.", key.c_str()); } - } else if(std::holds_alternative(_config.keys)) { - const auto& key = std::get(_config.keys); + } else if(std::holds_alternative(_config.keys.value())) { + const auto& key = std::get(config); _device->virtualInput()->registerKey(key); _keys.emplace_back(key); - } else if(std::holds_alternative>>(_config.keys)) { - const auto& keys = std::get>>( - _config.keys); + } else if(std::holds_alternative< + std::list>>(config)) { + const auto& keys = std::get< + std::list>>(config); for(const auto& key : keys) { if(std::holds_alternative(key)) { const auto& key_str = std::get(key); @@ -66,22 +99,6 @@ KeypressAction::KeypressAction(Device *device, config::KeypressAction& config, } } } - - _ipc = parent->make_interface(this); -} - -void KeypressAction::press() -{ - _pressed = true; - for(auto& key : _keys) - _device->virtualInput()->pressKey(key); -} - -void KeypressAction::release() -{ - _pressed = false; - for(auto& key : _keys) - _device->virtualInput()->releaseKey(key); } uint8_t KeypressAction::reprogFlags() const @@ -89,7 +106,26 @@ uint8_t KeypressAction::reprogFlags() const return hidpp20::ReprogControls::TemporaryDiverted; } -KeypressAction::IPC::IPC(KeypressAction *action) : ipcgull::interface( - interface_name, {}, {}, {}), _action (*action) +std::vector KeypressAction::getKeys() const { + std::lock_guard lock(_config_lock); + std::vector ret; + for(auto& x : _keys) + ret.push_back(InputDevice::toKeyName(x)); + + return ret; +} + +void KeypressAction::setKeys(const std::vector &keys) +{ + std::lock_guard lock(_config_lock); + if(_pressed) + for(auto& key : _keys) + _device->virtualInput()->releaseKey(key); + _config.keys = std::list>(); + auto& config = std::get>>( + _config.keys.value()); + for(auto& x : keys) + config.emplace_back(x); + _setConfig(); } diff --git a/src/logid/actions/KeypressAction.h b/src/logid/actions/KeypressAction.h index 8cde45d..e55fc62 100644 --- a/src/logid/actions/KeypressAction.h +++ b/src/logid/actions/KeypressAction.h @@ -36,20 +36,16 @@ namespace actions { virtual void press(); virtual void release(); + [[nodiscard]] std::vector getKeys() const; + void setKeys(const std::vector& keys); + virtual uint8_t reprogFlags() const; protected: + mutable std::mutex _config_lock; config::KeypressAction& _config; std::list _keys; - private: - class IPC : public ipcgull::interface - { - public: - explicit IPC(KeypressAction* action); - private: - KeypressAction& _action; - }; - std::shared_ptr _ipc; + void _setConfig(); }; }} diff --git a/src/logid/actions/NullAction.cpp b/src/logid/actions/NullAction.cpp index d81d60e..0fe6729 100644 --- a/src/logid/actions/NullAction.cpp +++ b/src/logid/actions/NullAction.cpp @@ -21,12 +21,12 @@ using namespace logid::actions; -const char* NullAction::interface_name = - "pizza.pixl.LogiOps.Action.None"; +const char* NullAction::interface_name = "None"; -NullAction::NullAction(Device* device, - const std::shared_ptr& parent) : - Action(device), _ipc (parent->make_interface()) +NullAction::NullAction( + Device* device, + [[maybe_unused]] const std::shared_ptr& parent) : + Action(device, interface_name) { } @@ -43,8 +43,4 @@ void NullAction::release() uint8_t NullAction::reprogFlags() const { return backend::hidpp20::ReprogControls::TemporaryDiverted; -} - -NullAction::IPC::IPC() : ipcgull::interface(interface_name, {}, {}, {}) -{ -} +} \ No newline at end of file diff --git a/src/logid/actions/NullAction.h b/src/logid/actions/NullAction.h index dd95f83..2262c30 100644 --- a/src/logid/actions/NullAction.h +++ b/src/logid/actions/NullAction.h @@ -38,12 +38,6 @@ namespace actions virtual void release(); virtual uint8_t reprogFlags() const; - private: - class IPC : public ipcgull::interface { - public: - IPC(); - }; - std::shared_ptr _ipc; }; }} diff --git a/src/logid/actions/ToggleHiresScroll.cpp b/src/logid/actions/ToggleHiresScroll.cpp index 40dfd0c..dfcb1c3 100644 --- a/src/logid/actions/ToggleHiresScroll.cpp +++ b/src/logid/actions/ToggleHiresScroll.cpp @@ -23,12 +23,12 @@ using namespace logid::actions; using namespace logid::backend; -const char* ToggleHiresScroll::interface_name = - "pizza.pixl.LogiOps.Action.ToggleHiresScroll"; +const char* ToggleHiresScroll::interface_name = "ToggleHiresScroll"; ToggleHiresScroll::ToggleHiresScroll( - Device *dev, const std::shared_ptr& parent) : - Action (dev), _ipc (parent->make_interface()) + Device *dev, + [[maybe_unused]] const std::shared_ptr& parent) : + Action (dev, interface_name) { _hires_scroll = _device->getFeature("hiresscroll"); if(!_hires_scroll) @@ -61,7 +61,3 @@ uint8_t ToggleHiresScroll::reprogFlags() const { return hidpp20::ReprogControls::TemporaryDiverted; } - -ToggleHiresScroll::IPC::IPC() : ipcgull::interface(interface_name, {}, {}, {}) -{ -} diff --git a/src/logid/actions/ToggleHiresScroll.h b/src/logid/actions/ToggleHiresScroll.h index 2c1f3b1..c79d846 100644 --- a/src/logid/actions/ToggleHiresScroll.h +++ b/src/logid/actions/ToggleHiresScroll.h @@ -41,14 +41,6 @@ namespace actions virtual uint8_t reprogFlags() const; protected: std::shared_ptr _hires_scroll; - private: - class IPC : public ipcgull::interface - { - public: - IPC(); - }; - - std::shared_ptr _ipc; }; }} diff --git a/src/logid/actions/ToggleSmartShift.cpp b/src/logid/actions/ToggleSmartShift.cpp index 6767138..efd3da6 100644 --- a/src/logid/actions/ToggleSmartShift.cpp +++ b/src/logid/actions/ToggleSmartShift.cpp @@ -23,12 +23,12 @@ using namespace logid::actions; using namespace logid::backend; -const char* ToggleSmartShift::interface_name = - "pizza.pixl.LogiOps.Action.ToggleSmartShift"; +const char* ToggleSmartShift::interface_name = "ToggleSmartShift"; ToggleSmartShift::ToggleSmartShift( - Device *dev, const std::shared_ptr& parent) : - Action (dev), _ipc (parent->make_interface()) + Device *dev, + [[maybe_unused]] const std::shared_ptr& parent) : + Action (dev, interface_name) { _smartshift = _device->getFeature("smartshift"); if(!_smartshift) @@ -61,7 +61,3 @@ uint8_t ToggleSmartShift::reprogFlags() const { return hidpp20::ReprogControls::TemporaryDiverted; } - -ToggleSmartShift::IPC::IPC() : ipcgull::interface(interface_name, {}, {}, {}) -{ -} diff --git a/src/logid/actions/ToggleSmartShift.h b/src/logid/actions/ToggleSmartShift.h index 7013c50..98c51a0 100644 --- a/src/logid/actions/ToggleSmartShift.h +++ b/src/logid/actions/ToggleSmartShift.h @@ -42,14 +42,6 @@ namespace actions { virtual uint8_t reprogFlags() const; protected: std::shared_ptr _smartshift; - private: - class IPC : public ipcgull::interface - { - public: - IPC(); - }; - - std::shared_ptr _ipc; }; }} diff --git a/src/logid/actions/gesture/AxisGesture.cpp b/src/logid/actions/gesture/AxisGesture.cpp index 9d8bd43..1338cf1 100644 --- a/src/logid/actions/gesture/AxisGesture.cpp +++ b/src/logid/actions/gesture/AxisGesture.cpp @@ -23,24 +23,29 @@ using namespace logid::actions; +const char* AxisGesture::interface_name = "Axis"; + AxisGesture::AxisGesture(Device *device, config::AxisGesture& config, - const std::shared_ptr& parent, - const std::string& direction) : - Gesture (device, parent, direction), _multiplier (1), _config (config) + const std::shared_ptr& parent) : + Gesture (device, parent, interface_name), _multiplier (1), _config (config) { - if(std::holds_alternative(_config.axis)) { - _input_axis = std::get(_config.axis); - } else { - const auto& axis = std::get(_config.axis); - try { - _input_axis = _device->virtualInput()->toAxisCode(axis); - _device->virtualInput()->registerAxis(_input_axis); - } catch(InputDevice::InvalidEventCode& e) { - logPrintf(WARN, "Invalid axis %s."); - throw InvalidGesture(); + if(_config.axis.has_value()) { + if(std::holds_alternative(_config.axis.value())) { + _input_axis = std::get(_config.axis.value()); + } else { + const auto& axis = std::get(_config.axis.value()); + try { + _input_axis = _device->virtualInput()->toAxisCode(axis); + _device->virtualInput()->registerAxis(_input_axis.value()); + } catch(InputDevice::InvalidEventCode& e) { + logPrintf(WARN, "Invalid axis %s."); + } } + } - _device->virtualInput()->registerAxis(_input_axis); + + if(_input_axis.has_value()) + _device->virtualInput()->registerAxis(_input_axis.value()); } void AxisGesture::press(bool init_threshold) @@ -59,6 +64,9 @@ void AxisGesture::release(bool primary) void AxisGesture::move(int16_t axis) { + if(!_input_axis.has_value()) + return; + const auto threshold = _config.threshold.value_or( defaults::gesture_threshold); int16_t new_axis = _axis+axis; @@ -90,7 +98,7 @@ void AxisGesture::move(int16_t axis) if(low_res_axis != -1) { int lowres_movement = 0, hires_movement = move_floor; - _device->virtualInput()->moveAxis(_input_axis, hires_movement); + _device->virtualInput()->moveAxis(_input_axis.value(), hires_movement); hires_remainder += hires_movement; if(abs(hires_remainder) >= 60) { lowres_movement = hires_remainder/120; @@ -102,7 +110,7 @@ void AxisGesture::move(int16_t axis) _hires_remainder = hires_remainder; } else { - _device->virtualInput()->moveAxis(_input_axis, move_floor); + _device->virtualInput()->moveAxis(_input_axis.value(), move_floor); } } _axis = new_axis; diff --git a/src/logid/actions/gesture/AxisGesture.h b/src/logid/actions/gesture/AxisGesture.h index 491c201..29d20bc 100644 --- a/src/logid/actions/gesture/AxisGesture.h +++ b/src/logid/actions/gesture/AxisGesture.h @@ -26,9 +26,10 @@ namespace logid { class AxisGesture : public Gesture { public: + static const char* interface_name; + AxisGesture(Device* device, config::AxisGesture& config, - const std::shared_ptr& parent, - const std::string& direction); + const std::shared_ptr& parent); virtual void press(bool init_threshold=false); virtual void release(bool primary=false); @@ -43,7 +44,7 @@ namespace logid { int16_t _axis; double _axis_remainder; int _hires_remainder; - uint _input_axis; + std::optional _input_axis; double _multiplier; config::AxisGesture& _config; }; diff --git a/src/logid/actions/gesture/Gesture.cpp b/src/logid/actions/gesture/Gesture.cpp index 9bc9dc2..85168ec 100644 --- a/src/logid/actions/gesture/Gesture.cpp +++ b/src/logid/actions/gesture/Gesture.cpp @@ -17,6 +17,7 @@ */ #include +#include #include "Gesture.h" #include "ReleaseGesture.h" #include "ThresholdGesture.h" @@ -28,9 +29,10 @@ using namespace logid; using namespace logid::actions; Gesture::Gesture(Device *device, - const std::shared_ptr& parent, - const std::string& direction) : _device (device), - _node (parent->make_child(direction)) + std::shared_ptr node, + const std::string& name, tables t) : + ipcgull::interface("pizza.pixl.LogiOps.Gesture." + name, std::move(t)), + _node (std::move(node)), _device (device) { } @@ -48,20 +50,41 @@ struct gesture_type : gesture_type { }; template std::shared_ptr _makeGesture( Device* device, T gesture, - const std::shared_ptr& parent, - const std::string& direction) { - return std::make_shared::type>( - device, gesture, parent, std::move(direction)); + const std::shared_ptr& parent) { + return parent->make_interface::type>( + device, gesture, parent); } std::shared_ptr Gesture::makeGesture( Device *device, config::Gesture& gesture, - const std::shared_ptr& parent, - const std::string& direction) + const std::shared_ptr& parent) { - std::shared_ptr ret; - std::visit([&device, &ret, &parent, &direction](auto&& x) { - ret = _makeGesture(device, x, parent, direction); + return std::visit([&device, &parent](auto&& x) { + return _makeGesture(device, x, parent); }, gesture); - return ret; +} + +std::shared_ptr Gesture::makeGesture( + Device *device, const std::string& type, + config::Gesture& config, + const std::shared_ptr &parent) +{ + if(type == AxisGesture::interface_name) { + config = config::AxisGesture(); + return makeGesture(device, config, parent); + } else if(type == IntervalGesture::interface_name) { + config = config::IntervalGesture(); + return makeGesture(device, config, parent); + } else if(type == ReleaseGesture::interface_name) { + config = config::IntervalGesture(); + return makeGesture(device, config, parent); + } else if(type == ThresholdGesture::interface_name) { + config = config::ThresholdGesture(); + return makeGesture(device, config, parent); + } else if(type == NullGesture::interface_name) { + config = config::NoGesture(); + return makeGesture(device, config, parent); + } + + throw InvalidGesture(); } diff --git a/src/logid/actions/gesture/Gesture.h b/src/logid/actions/gesture/Gesture.h index 6fc8816..b2e036b 100644 --- a/src/logid/actions/gesture/Gesture.h +++ b/src/logid/actions/gesture/Gesture.h @@ -39,7 +39,7 @@ namespace actions std::string _what; }; - class Gesture + class Gesture : public ipcgull::interface { public: virtual void press(bool init_threshold=false) = 0; @@ -53,15 +53,19 @@ namespace actions static std::shared_ptr makeGesture(Device* device, config::Gesture& gesture, - const std::shared_ptr& parent, - const std::string& direction); + const std::shared_ptr& parent); + + static std::shared_ptr makeGesture( + Device* device, const std::string& type, + config::Gesture& gesture, + const std::shared_ptr& parent); protected: - explicit Gesture(Device* device, - const std::shared_ptr& parent, - const std::string& direction); + Gesture(Device* device, + std::shared_ptr parent, + const std::string& name, tables t={}); + const std::shared_ptr _node; Device* _device; - std::shared_ptr _node; }; }} diff --git a/src/logid/actions/gesture/IntervalGesture.cpp b/src/logid/actions/gesture/IntervalGesture.cpp index 0acca9c..8ec68e0 100644 --- a/src/logid/actions/gesture/IntervalGesture.cpp +++ b/src/logid/actions/gesture/IntervalGesture.cpp @@ -21,10 +21,13 @@ using namespace logid::actions; -IntervalGesture::IntervalGesture(Device *device, config::IntervalGesture& config, - const std::shared_ptr& parent, - const std::string& direction) : - Gesture (device, parent, direction), _config (config) +const char* IntervalGesture::interface_name = "OnInterval"; + +IntervalGesture::IntervalGesture( + Device *device, config::IntervalGesture& config, + const std::shared_ptr& parent) : + Gesture (device, parent, interface_name), + _axis (0), _interval_pass_count (0), _config (config) { if(config.action) { try { @@ -50,6 +53,9 @@ void IntervalGesture::release(bool primary) void IntervalGesture::move(int16_t axis) { + if(!_config.interval.has_value()) + return; + const auto threshold = _config.threshold.value_or(defaults::gesture_threshold); _axis += axis; @@ -57,7 +63,7 @@ void IntervalGesture::move(int16_t axis) return; int16_t new_interval_count = (_axis - threshold)/ - _config.interval; + _config.interval.value(); if(new_interval_count > _interval_pass_count) { if(_action) { _action->press(); diff --git a/src/logid/actions/gesture/IntervalGesture.h b/src/logid/actions/gesture/IntervalGesture.h index 5ee4ecd..75356b6 100644 --- a/src/logid/actions/gesture/IntervalGesture.h +++ b/src/logid/actions/gesture/IntervalGesture.h @@ -26,9 +26,10 @@ namespace actions class IntervalGesture : public Gesture { public: + static const char* interface_name; + IntervalGesture(Device* device, config::IntervalGesture& config, - const std::shared_ptr& parent, - const std::string& direction); + const std::shared_ptr& parent); virtual void press(bool init_threshold=false); virtual void release(bool primary=false); @@ -42,6 +43,18 @@ namespace actions int16_t _interval_pass_count; std::shared_ptr _action; config::IntervalGesture& _config; + private: + class IPC : public ipcgull::interface + { + public: + IPC(IntervalGesture* parent); + + void setAction(const std::string& type); + void setInterval(int interval); + void setThreshold(int threshold); + private: + IntervalGesture& parent; + }; }; }} diff --git a/src/logid/actions/gesture/NullGesture.cpp b/src/logid/actions/gesture/NullGesture.cpp index 2b2c6ea..c8edbb1 100644 --- a/src/logid/actions/gesture/NullGesture.cpp +++ b/src/logid/actions/gesture/NullGesture.cpp @@ -20,11 +20,12 @@ using namespace logid::actions; +const char* NullGesture::interface_name = "None"; + NullGesture::NullGesture(Device *device, config::NoGesture& config, - const std::shared_ptr& parent, - const std::string& direction) : - Gesture (device, parent, direction), _config (config) + const std::shared_ptr& parent) : + Gesture (device, parent, interface_name), _config (config) { } diff --git a/src/logid/actions/gesture/NullGesture.h b/src/logid/actions/gesture/NullGesture.h index 9f08bab..9f8ce15 100644 --- a/src/logid/actions/gesture/NullGesture.h +++ b/src/logid/actions/gesture/NullGesture.h @@ -26,10 +26,11 @@ namespace actions class NullGesture : public Gesture { public: + static const char* interface_name; + NullGesture(Device* device, config::NoGesture& config, - const std::shared_ptr& parent, - const std::string& direction); + const std::shared_ptr& parent); virtual void press(bool init_threshold=false); virtual void release(bool primary=false); diff --git a/src/logid/actions/gesture/ReleaseGesture.cpp b/src/logid/actions/gesture/ReleaseGesture.cpp index ca663c1..2949965 100644 --- a/src/logid/actions/gesture/ReleaseGesture.cpp +++ b/src/logid/actions/gesture/ReleaseGesture.cpp @@ -20,10 +20,11 @@ using namespace logid::actions; +const char* ReleaseGesture::interface_name = "OnRelease"; + ReleaseGesture::ReleaseGesture(Device *device, config::ReleaseGesture& config, - const std::shared_ptr& parent, - const std::string& direction) : - Gesture (device, parent, direction), _config (config) + const std::shared_ptr& parent) : + Gesture (device, parent, interface_name), _config (config) { if(_config.action.has_value()) _action = Action::makeAction(device, _config.action.value(), _node); diff --git a/src/logid/actions/gesture/ReleaseGesture.h b/src/logid/actions/gesture/ReleaseGesture.h index f02c566..e0c9284 100644 --- a/src/logid/actions/gesture/ReleaseGesture.h +++ b/src/logid/actions/gesture/ReleaseGesture.h @@ -26,9 +26,10 @@ namespace actions class ReleaseGesture : public Gesture { public: + static const char* interface_name; + ReleaseGesture(Device* device, config::ReleaseGesture& config, - const std::shared_ptr& parent, - const std::string& direction); + const std::shared_ptr& parent); virtual void press(bool init_threshold=false); virtual void release(bool primary=false); diff --git a/src/logid/actions/gesture/ThresholdGesture.cpp b/src/logid/actions/gesture/ThresholdGesture.cpp index 3e79dd8..d29db07 100644 --- a/src/logid/actions/gesture/ThresholdGesture.cpp +++ b/src/logid/actions/gesture/ThresholdGesture.cpp @@ -20,11 +20,12 @@ using namespace logid::actions; -ThresholdGesture::ThresholdGesture(Device *device, - config::ThresholdGesture& config, - const std::shared_ptr& parent, - const std::string& direction) : - Gesture (device, parent, direction), _config (config) +const char* ThresholdGesture::interface_name = "OnRelease"; + +ThresholdGesture::ThresholdGesture( + Device *device, config::ThresholdGesture& config, + const std::shared_ptr& parent ) : + Gesture (device, parent, interface_name), _config (config) { if(config.action) { try { diff --git a/src/logid/actions/gesture/ThresholdGesture.h b/src/logid/actions/gesture/ThresholdGesture.h index 802cbb5..be071ee 100644 --- a/src/logid/actions/gesture/ThresholdGesture.h +++ b/src/logid/actions/gesture/ThresholdGesture.h @@ -26,9 +26,10 @@ namespace actions class ThresholdGesture : public Gesture { public: + static const char* interface_name; + ThresholdGesture(Device* device, config::ThresholdGesture& config, - const std::shared_ptr& parent, - const std::string& direction); + const std::shared_ptr& parent); virtual void press(bool init_threshold=false); virtual void release(bool primary=false); diff --git a/src/logid/backend/raw/IOMonitor.cpp b/src/logid/backend/raw/IOMonitor.cpp index 6114882..9cc23c2 100644 --- a/src/logid/backend/raw/IOMonitor.cpp +++ b/src/logid/backend/raw/IOMonitor.cpp @@ -85,9 +85,7 @@ IOMonitor::~IOMonitor() noexcept void IOMonitor::_listen() { - std::unique_lock run_lock(_run_lock, std::try_to_lock); - if(!run_lock.owns_lock()) - throw std::runtime_error("IOMonitor already listening"); + std::lock_guard run_lock(_run_lock); std::vector events; _is_running = true; @@ -130,7 +128,7 @@ void IOMonitor::_stop() noexcept bool IOMonitor::_running() const { std::unique_lock run_lock(_run_lock, std::try_to_lock); - return !run_lock.owns_lock(); + return !run_lock.owns_lock() || _is_running; } void IOMonitor::add(int fd, IOHandler handler) diff --git a/src/logid/config/group.h b/src/logid/config/group.h index 9c419ed..174e241 100644 --- a/src/logid/config/group.h +++ b/src/logid/config/group.h @@ -34,7 +34,7 @@ namespace logid::config { void set(libconfig::Setting& parent, const T& t); template - T get(const libconfig::Setting& parent, const std::string& name); + auto get(const libconfig::Setting& parent, const std::string& name); template void append(libconfig::Setting& list, const T& t); @@ -189,7 +189,7 @@ namespace logid::config { } void _save(libconfig::Setting& setting) const override { - set(setting, _signature, _sig_field); + set(setting, _sig_field, _signature); _setter(setting, this, _names); } diff --git a/src/logid/config/map.h b/src/logid/config/map.h index 8543bc3..9b309b8 100644 --- a/src/logid/config/map.h +++ b/src/logid/config/map.h @@ -33,13 +33,27 @@ namespace logid::config { char value[N]; }; + template + struct less_caseless { + constexpr bool operator()(const T& a, const T& b) const noexcept { + auto a_it = a.begin(), b_it = b.begin(); + for(; a_it != a.end() && b_it != b.end(); ++a_it, ++b_it) { + if(tolower(*a_it) != tolower(*b_it)) + return tolower(*a_it) < tolower(*b_it); + } + return b_it != b.end(); + } + }; + // Warning: map must be a variant of groups or a group - template - class map : public std::map { + template ::key_compare, + typename Allocator=typename std::map::allocator_type> + class map : public std::map { public: template map(Args... args) : - std::map(std::forward(args)...) { } + std::map(std::forward(args)...) { } }; } diff --git a/src/logid/config/schema.h b/src/logid/config/schema.h index 3fe3f52..da17f2d 100644 --- a/src/logid/config/schema.h +++ b/src/logid/config/schema.h @@ -46,11 +46,14 @@ namespace logid::config { struct KeypressAction : public signed_group { typedef actions::KeypressAction action; - std::variant>> keys; + std::optional< + std::variant>>> keys; KeypressAction() : signed_group( "type", "Keypress", - {"keys"}, &KeypressAction::keys) { } + {"keys"}, &KeypressAction::keys) + { + } }; struct ToggleSmartShift : public signed_group { @@ -67,7 +70,7 @@ namespace logid::config { struct CycleDPI : public signed_group { typedef actions::CycleDPI action; - std::list dpis; + std::optional> dpis; std::optional sensor; CycleDPI() : signed_group( "type", "CycleDPI", @@ -78,7 +81,7 @@ namespace logid::config { struct ChangeDPI : public signed_group { typedef actions::ChangeDPI action; - int inc; + std::optional inc; std::optional sensor; ChangeDPI() : signed_group( "type", "ChangeDPI", @@ -89,7 +92,7 @@ namespace logid::config { struct ChangeHost : public signed_group { typedef actions::ChangeHostAction action; - std::variant host; + std::optional> host; ChangeHost() : signed_group( "type", "ChangeHost", {"host"}, &ChangeHost::host) { } @@ -108,7 +111,7 @@ namespace logid::config { struct AxisGesture : public signed_group { typedef actions::AxisGesture gesture; std::optional threshold; - std::variant axis; + std::optional> axis; std::optional axis_multiplier; AxisGesture() : signed_group("mode", "Axis", @@ -122,7 +125,7 @@ namespace logid::config { typedef actions::IntervalGesture gesture; std::optional threshold; std::optional action; - int interval; + std::optional interval; protected: IntervalGesture(const std::string& name) : signed_group( "mode", name, @@ -180,7 +183,8 @@ namespace logid::config { struct GestureAction : public signed_group { typedef actions::GestureAction action; - std::optional> gestures; + std::optional>> gestures; GestureAction() : signed_group( "type", "Gestures", @@ -263,12 +267,15 @@ namespace logid::config { }; struct Device : public group { - std::string default_profile; + ipcgull::property default_profile; map profiles; Device() : group({"default_profile", "profiles"}, &Device::default_profile, - &Device::profiles) { } + &Device::profiles), + default_profile(ipcgull::property_full_permissions, "") + { + } }; struct Config : public group { diff --git a/src/logid/config/types.h b/src/logid/config/types.h index 1969045..955fb75 100644 --- a/src/logid/config/types.h +++ b/src/logid/config/types.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "group.h" #include "map.h" #include "../util/log.h" @@ -74,6 +75,9 @@ namespace logid::config { } }; + template + struct config_io> : public config_io { }; + template struct primitive_io { static T get(const libconfig::Setting& parent, @@ -328,11 +332,13 @@ namespace logid::config { } }; - template - struct config_io> { - static map get(const libconfig::Setting& setting) { + template + struct config_io> { + static map get( + const libconfig::Setting& setting) { const auto size = setting.getLength(); - map t; + map t; for(int i = 0; i < size; ++i) { auto& s = setting[i]; try { @@ -343,13 +349,13 @@ namespace logid::config { return t; } - static map get(const libconfig::Setting& parent, - const std::string& name) { + static map get( + const libconfig::Setting& parent, const std::string& name) { return get(parent.lookup(name)); } static void set(libconfig::Setting& setting, - const map& t) { + const map& t) { while(setting.getLength() != 0) setting.remove((int)0); for(auto& x : t) { @@ -361,7 +367,7 @@ namespace logid::config { static void set(libconfig::Setting& parent, const std::string& name, - const map& t) { + const map& t) { if (!parent.exists(name)) { parent.add(name, libconfig::Setting::TypeList); } else if(!parent.lookup(name).isArray()) { @@ -372,7 +378,7 @@ namespace logid::config { } static void append(libconfig::Setting& list, - const map& t) { + const map& t) { auto& s = list.add(libconfig::Setting::TypeList); set(s, t); } @@ -428,16 +434,16 @@ namespace logid::config { template void append(libconfig::Setting& list, const T& t) { - config_io::set(list, t); + config_io::append(list, t); } template - T get(const libconfig::Setting& setting) { + auto get(const libconfig::Setting& setting) { return config_io::get(setting); } template - T get(const libconfig::Setting& parent, const std::string& name) { + auto get(const libconfig::Setting& parent, const std::string& name) { return config_io::get(parent, name); } } diff --git a/src/logid/features/HiresScroll.cpp b/src/logid/features/HiresScroll.cpp index 15f2cae..bbfd7d4 100644 --- a/src/logid/features/HiresScroll.cpp +++ b/src/logid/features/HiresScroll.cpp @@ -116,7 +116,7 @@ void HiresScroll::_makeAction(std::shared_ptr &gesture, { if(config.has_value()) { gesture = actions::Gesture::makeGesture(_device, config.value(), - _node, direction); + _node->make_child(direction)); try { auto axis = std::dynamic_pointer_cast( gesture); diff --git a/src/logid/features/RemapButton.cpp b/src/logid/features/RemapButton.cpp index b485ac8..c8b5034 100644 --- a/src/logid/features/RemapButton.cpp +++ b/src/logid/features/RemapButton.cpp @@ -16,6 +16,7 @@ * */ #include +#include "../actions/GestureAction.h" #include "../Device.h" #include "RemapButton.h" #include "../backend/hidpp20/Error.h" @@ -67,14 +68,14 @@ RemapButton::RemapButton(Device *dev): DeviceFeature(dev), } _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])); + _buttons.emplace(control.second.controlID, + Button::make(control.second, i, + _device, func, _ipc_node, + _config.value()[control.first])); } + _ipc_interface = _device->ipcNode()->make_interface(this); + if(global_loglevel <= DEBUG) { #define FLAG(x) (control.second.flags & hidpp20::ReprogControls::x ? \ "YES" : "") @@ -104,7 +105,7 @@ RemapButton::~RemapButton() void RemapButton::configure() { for(const auto& button : _buttons) - button.second.configure(); + button.second->configure(); } void RemapButton::listen() @@ -127,8 +128,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); } }; @@ -149,7 +150,7 @@ void RemapButton::_buttonEvent(const std::set& new_state) } else { auto action = _buttons.find(i); if(action != _buttons.end()) - action->second.press(); + action->second->press(); } } @@ -157,12 +158,34 @@ void RemapButton::_buttonEvent(const std::set& 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; } +namespace logid::features { + class _Button : public Button { + public: + template + explicit _Button(Args&&... args) : Button(std::forward(args)...) + { + } + }; +} + +std::shared_ptr