From 9efd121387cffd1e5f3d0db5bb6ddebe55eeacb6 Mon Sep 17 00:00:00 2001 From: pixl Date: Thu, 27 Apr 2023 17:53:35 -0400 Subject: [PATCH] Code cleanup and reformatting --- src/logid/CMakeLists.txt | 12 +- src/logid/Configuration.cpp | 22 +- src/logid/Configuration.h | 13 +- src/logid/Device.cpp | 193 ++++++------ src/logid/Device.h | 52 ++-- src/logid/DeviceManager.cpp | 200 ++++++------- src/logid/DeviceManager.h | 27 +- src/logid/InputDevice.cpp | 81 ++--- src/logid/InputDevice.h | 30 +- src/logid/Receiver.cpp | 91 +++--- src/logid/Receiver.h | 25 +- src/logid/actions/Action.cpp | 121 ++++---- src/logid/actions/Action.h | 42 +-- src/logid/actions/ChangeDPI.cpp | 71 ++--- src/logid/actions/ChangeDPI.h | 36 +-- src/logid/actions/ChangeHostAction.cpp | 70 ++--- src/logid/actions/ChangeHostAction.h | 13 +- src/logid/actions/CycleDPI.cpp | 48 ++- src/logid/actions/CycleDPI.h | 11 +- src/logid/actions/GestureAction.cpp | 200 ++++++------- src/logid/actions/GestureAction.h | 29 +- src/logid/actions/KeypressAction.cpp | 66 ++-- src/logid/actions/KeypressAction.h | 17 +- src/logid/actions/NullAction.cpp | 12 +- src/logid/actions/NullAction.h | 19 +- src/logid/actions/ToggleHiresScroll.cpp | 29 +- src/logid/actions/ToggleHiresScroll.h | 20 +- src/logid/actions/ToggleSmartShift.cpp | 34 +-- src/logid/actions/ToggleSmartShift.h | 19 +- src/logid/actions/gesture/AxisGesture.cpp | 71 ++--- src/logid/actions/gesture/AxisGesture.h | 48 +-- src/logid/actions/gesture/Gesture.cpp | 57 ++-- src/logid/actions/gesture/Gesture.h | 42 +-- src/logid/actions/gesture/IntervalGesture.cpp | 49 ++- src/logid/actions/gesture/IntervalGesture.h | 34 ++- src/logid/actions/gesture/NullGesture.cpp | 22 +- src/logid/actions/gesture/NullGesture.h | 25 +- src/logid/actions/gesture/ReleaseGesture.cpp | 33 +- src/logid/actions/gesture/ReleaseGesture.h | 24 +- .../actions/gesture/ThresholdGesture.cpp | 37 +-- src/logid/actions/gesture/ThresholdGesture.h | 23 +- src/logid/backend/Error.cpp | 3 +- src/logid/backend/Error.h | 16 +- src/logid/backend/dj/Error.cpp | 23 +- src/logid/backend/dj/Error.h | 18 +- src/logid/backend/dj/Receiver.cpp | 214 ++++++------- src/logid/backend/dj/Receiver.h | 104 +++---- src/logid/backend/dj/ReceiverMonitor.cpp | 117 ++++---- src/logid/backend/dj/ReceiverMonitor.h | 20 +- src/logid/backend/dj/Report.cpp | 70 ++--- src/logid/backend/dj/Report.h | 26 +- src/logid/backend/dj/defs.h | 20 +- src/logid/backend/hidpp/Device.cpp | 218 +++++++------- src/logid/backend/hidpp/Device.h | 60 ++-- src/logid/backend/hidpp/Report.cpp | 283 ++++++++---------- src/logid/backend/hidpp/Report.h | 92 +++--- src/logid/backend/hidpp/defs.h | 24 +- src/logid/backend/hidpp10/Device.cpp | 64 ++-- src/logid/backend/hidpp10/Device.h | 26 +- src/logid/backend/hidpp10/Error.cpp | 67 ++--- src/logid/backend/hidpp10/Error.h | 18 +- src/logid/backend/hidpp10/defs.h | 10 +- src/logid/backend/hidpp20/Device.cpp | 85 +++--- src/logid/backend/hidpp20/Device.h | 26 +- src/logid/backend/hidpp20/Error.cpp | 59 ++-- src/logid/backend/hidpp20/Error.h | 16 +- .../backend/hidpp20/EssentialFeature.cpp | 21 +- src/logid/backend/hidpp20/EssentialFeature.h | 15 +- src/logid/backend/hidpp20/Feature.cpp | 30 +- src/logid/backend/hidpp20/Feature.h | 34 ++- src/logid/backend/hidpp20/feature_defs.h | 12 +- .../hidpp20/features/AdjustableDPI.cpp | 24 +- .../backend/hidpp20/features/AdjustableDPI.h | 20 +- .../backend/hidpp20/features/ChangeHost.cpp | 26 +- .../backend/hidpp20/features/ChangeHost.h | 28 +- .../backend/hidpp20/features/DeviceName.cpp | 69 ++--- .../backend/hidpp20/features/DeviceName.h | 35 +-- .../backend/hidpp20/features/FeatureSet.cpp | 16 +- .../backend/hidpp20/features/FeatureSet.h | 26 +- .../backend/hidpp20/features/HiresScroll.cpp | 28 +- .../backend/hidpp20/features/HiresScroll.h | 48 ++- .../hidpp20/features/ReprogControls.cpp | 114 ++++--- .../backend/hidpp20/features/ReprogControls.h | 111 +++---- src/logid/backend/hidpp20/features/Reset.cpp | 9 +- src/logid/backend/hidpp20/features/Reset.h | 21 +- src/logid/backend/hidpp20/features/Root.cpp | 85 ++---- src/logid/backend/hidpp20/features/Root.h | 43 +-- .../backend/hidpp20/features/SmartShift.cpp | 17 +- .../backend/hidpp20/features/SmartShift.h | 17 +- .../backend/hidpp20/features/ThumbWheel.cpp | 21 +- .../backend/hidpp20/features/ThumbWheel.h | 33 +- .../hidpp20/features/WirelessDeviceStatus.cpp | 6 +- .../hidpp20/features/WirelessDeviceStatus.h | 23 +- src/logid/backend/raw/DeviceMonitor.cpp | 80 +++-- src/logid/backend/raw/DeviceMonitor.h | 16 +- .../backend/raw/{defs.h => EventHandler.h} | 13 +- src/logid/backend/raw/IOMonitor.cpp | 92 +++--- src/logid/backend/raw/IOMonitor.h | 10 +- src/logid/backend/raw/RawDevice.cpp | 114 +++---- src/logid/backend/raw/RawDevice.h | 25 +- src/logid/config/group.h | 94 +++--- src/logid/config/map.h | 18 +- src/logid/config/schema.h | 100 ++++--- src/logid/config/types.h | 201 +++++++------ src/logid/features/DPI.cpp | 64 ++-- src/logid/features/DPI.h | 21 +- src/logid/features/DeviceFeature.h | 23 +- src/logid/features/DeviceStatus.cpp | 51 ++-- src/logid/features/DeviceStatus.h | 19 +- src/logid/features/HiresScroll.cpp | 121 ++++---- src/logid/features/HiresScroll.h | 23 +- src/logid/features/RemapButton.cpp | 253 ++++++++-------- src/logid/features/RemapButton.h | 45 +-- src/logid/features/SmartShift.cpp | 97 +++--- src/logid/features/SmartShift.h | 28 +- src/logid/features/ThumbWheel.cpp | 173 ++++++----- src/logid/features/ThumbWheel.h | 18 +- src/logid/logid.cpp | 132 ++++---- src/logid/util/ExceptionHandler.cpp | 19 +- src/logid/util/ExceptionHandler.h | 6 +- src/logid/util/log.cpp | 49 ++- src/logid/util/log.h | 12 +- src/logid/util/task.cpp | 7 +- src/logid/util/task.h | 3 +- 124 files changed, 3128 insertions(+), 3478 deletions(-) rename src/logid/backend/raw/{defs.h => EventHandler.h} (86%) diff --git a/src/logid/CMakeLists.txt b/src/logid/CMakeLists.txt index 89b0957..8bb3f03 100644 --- a/src/logid/CMakeLists.txt +++ b/src/logid/CMakeLists.txt @@ -76,7 +76,7 @@ pkg_check_modules(LIBCONFIG libconfig REQUIRED) pkg_check_modules(LIBUDEV libudev REQUIRED) find_path(EVDEV_INCLUDE_DIR libevdev/libevdev.h - HINTS ${PC_EVDEV_INCLUDE_DIRS} ${PC_EVDEV_INCLUDEDIR}) + HINTS ${PC_EVDEV_INCLUDE_DIRS} ${PC_EVDEV_INCLUDEDIR}) find_library(EVDEV_LIBRARY NAMES evdev libevdev) @@ -92,15 +92,15 @@ install(TARGETS logid DESTINATION bin) if (SYSTEMD_FOUND AND "${SYSTEMD_SERVICES_INSTALL_DIR}" STREQUAL "") execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} - --variable=systemdsystemunitdir systemd - OUTPUT_VARIABLE SYSTEMD_SERVICES_INSTALL_DIR) + --variable=systemdsystemunitdir systemd + OUTPUT_VARIABLE SYSTEMD_SERVICES_INSTALL_DIR) string(REGEX REPLACE "[ \t\n]+" "" SYSTEMD_SERVICES_INSTALL_DIR - "${SYSTEMD_SERVICES_INSTALL_DIR}") + "${SYSTEMD_SERVICES_INSTALL_DIR}") configure_file(logid.service.cmake ${CMAKE_BINARY_DIR}/logid.service) message(STATUS "systemd units will be installed at ${SYSTEMD_SERVICES_INSTALL_DIR}") install(FILES ${CMAKE_BINARY_DIR}/logid.service DESTINATION ${SYSTEMD_SERVICES_INSTALL_DIR} COMPONENT cp) -elseif(NOT SYSTEMD_FOUND AND SYSTEMD_SERVICES_INSTALL_DIR) +elseif (NOT SYSTEMD_FOUND AND SYSTEMD_SERVICES_INSTALL_DIR) message(FATAL_ERROR "systemd is not found w/ pkg-config but SYSTEMD_SERVICES_INSTALL_DIR is defined.") -endif() +endif () diff --git a/src/logid/Configuration.cpp b/src/logid/Configuration.cpp index ee3aad8..5ce66dc 100644 --- a/src/logid/Configuration.cpp +++ b/src/logid/Configuration.cpp @@ -18,7 +18,6 @@ #include #include -#include #include "Configuration.h" #include "util/log.h" @@ -28,15 +27,14 @@ using namespace libconfig; using namespace logid::config; Configuration::Configuration(std::string config_file) : - _config_file (std::move(config_file)) -{ + _config_file(std::move(config_file)) { try { _config.readFile(_config_file); - } catch(const FileIOException &e) { + } catch (const FileIOException& e) { logPrintf(ERROR, "I/O Error while reading %s: %s", _config_file.c_str(), e.what()); throw; - } catch(const ParseException &e) { + } catch (const ParseException& e) { logPrintf(ERROR, "Parse error in %s, line %d: %s", e.getFile(), e.getLine(), e.getError()); throw; @@ -44,29 +42,27 @@ Configuration::Configuration(std::string config_file) : Config::operator=(get(_config.getRoot())); - if(!devices.has_value()) + if (!devices.has_value()) devices = decltype(config::Config::devices)(); } -void Configuration::save() -{ +void Configuration::save() { config::set(_config.getRoot(), *this); try { _config.writeFile(_config_file); - } catch(const FileIOException &e) { + } catch (const FileIOException& e) { logPrintf(ERROR, "I/O Error while writing %s: %s", _config_file.c_str(), e.what()); throw; - } catch(const std::exception& e) { + } catch (const std::exception& e) { logPrintf(ERROR, "Error while writing %s: %s", _config_file.c_str(), e.what()); throw; } } -Configuration::IPC::IPC(Configuration *config) : +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 41e8b4b..5df76f3 100644 --- a/src/logid/Configuration.h +++ b/src/logid/Configuration.h @@ -28,28 +28,25 @@ #include "config/schema.h" -namespace logid -{ +namespace logid { namespace defaults { static constexpr double io_timeout = 500; static constexpr int gesture_threshold = 50; - static constexpr int worker_count = 4; } - class Configuration : public config::Config - { + class Configuration : public config::Config { public: explicit Configuration(std::string config_file); + Configuration() = default; // Reloading is not safe, references will be invalidated //void reload(); void save(); - class IPC : public ipcgull::interface - { + class IPC : public ipcgull::interface { public: - IPC(Configuration* config); + explicit IPC(Configuration* config); }; private: diff --git a/src/logid/Device.cpp b/src/logid/Device.cpp index fd8ad71..21aabf9 100644 --- a/src/logid/Device.cpp +++ b/src/logid/Device.cpp @@ -34,37 +34,34 @@ using namespace logid; using namespace logid::backend; DeviceNickname::DeviceNickname(const std::shared_ptr& manager) : - _nickname (manager->newDeviceNickname()), _manager (manager) -{ + _nickname(manager->newDeviceNickname()), _manager(manager) { } DeviceNickname::operator std::string() const { return std::to_string(_nickname); } -DeviceNickname::~DeviceNickname() -{ - if(auto manager = _manager.lock()) { +DeviceNickname::~DeviceNickname() { + if (auto manager = _manager.lock()) { std::lock_guard lock(manager->_nick_lock); manager->_device_nicknames.erase(_nickname); } } namespace logid { - class _Device : public Device { + class DeviceWrapper : public Device { public: - template - _Device(Args... args) : Device(std::forward(args)...) { } + template + explicit DeviceWrapper(Args... args) : Device(std::forward(args)...) {} }; } std::shared_ptr Device::make( std::string path, backend::hidpp::DeviceIndex index, - std::shared_ptr manager) -{ - auto ret = std::make_shared<_Device>(std::move(path), - index, - std::move(manager)); + std::shared_ptr manager) { + auto ret = std::make_shared(std::move(path), + index, + std::move(manager)); ret->_self = ret; ret->_ipc_node->manage(ret); ret->_ipc_interface = ret->_ipc_node->make_interface(ret.get()); @@ -74,11 +71,10 @@ std::shared_ptr Device::make( std::shared_ptr Device::make( std::shared_ptr raw_device, backend::hidpp::DeviceIndex index, - std::shared_ptr manager) -{ - auto ret = std::make_shared<_Device>(std::move(raw_device), - index, - std::move(manager)); + std::shared_ptr manager) { + auto ret = std::make_shared(std::move(raw_device), + index, + std::move(manager)); ret->_self = ret; ret->_ipc_node->manage(ret); ret->_ipc_interface = ret->_ipc_node->make_interface(ret.get()); @@ -87,9 +83,8 @@ std::shared_ptr Device::make( std::shared_ptr Device::make( Receiver* receiver, backend::hidpp::DeviceIndex index, - std::shared_ptr manager) -{ - auto ret = std::make_shared<_Device>(receiver, index, std::move(manager)); + std::shared_ptr manager) { + auto ret = std::make_shared(receiver, index, std::move(manager)); ret->_self = ret; ret->_ipc_node->manage(ret); ret->_ipc_interface = ret->_ipc_node->make_interface(ret.get()); @@ -97,59 +92,54 @@ std::shared_ptr Device::make( } Device::Device(std::string path, backend::hidpp::DeviceIndex index, - std::shared_ptr manager) : - _hidpp20 (path, index, manager, - manager->config()->io_timeout.value_or(defaults::io_timeout)), - _path (std::move(path)), _index (index), - _config (_getConfig(manager, _hidpp20.name())), - _receiver (nullptr), - _manager (manager), - _nickname (manager), - _ipc_node(manager->devicesNode()->make_child(_nickname)), - _awake (ipcgull::property_readable, true) -{ + const std::shared_ptr& manager) : + _hidpp20(path, index, manager, + manager->config()->io_timeout.value_or(defaults::io_timeout)), + _path(std::move(path)), _index(index), + _config(_getConfig(manager, _hidpp20.name())), + _receiver(nullptr), + _manager(manager), + _nickname(manager), + _ipc_node(manager->devicesNode()->make_child(_nickname)), + _awake(ipcgull::property_readable, true) { _init(); } Device::Device(std::shared_ptr raw_device, - hidpp::DeviceIndex index, - std::shared_ptr manager) : + hidpp::DeviceIndex index, const std::shared_ptr& manager) : _hidpp20(std::move(raw_device), index, manager->config()->io_timeout.value_or(defaults::io_timeout)), - _path (raw_device->rawPath()), _index (index), - _config (_getConfig(manager, _hidpp20.name())), - _receiver (nullptr), - _manager (manager), - _nickname (manager), - _ipc_node (manager->devicesNode()->make_child(_nickname)), - _awake (ipcgull::property_readable, true) -{ + _path(raw_device->rawPath()), _index(index), + _config(_getConfig(manager, _hidpp20.name())), + _receiver(nullptr), + _manager(manager), + _nickname(manager), + _ipc_node(manager->devicesNode()->make_child(_nickname)), + _awake(ipcgull::property_readable, true) { _init(); } Device::Device(Receiver* receiver, hidpp::DeviceIndex index, - std::shared_ptr manager) : - _hidpp20 (receiver->rawReceiver(), index, - manager->config()->io_timeout.value_or( - defaults::io_timeout)), - _path (receiver->path()), _index (index), - _config (_getConfig(manager, _hidpp20.name())), - _receiver (receiver), - _manager (manager), - _nickname (manager), - _ipc_node (manager->devicesNode()->make_child(_nickname)), - _awake (ipcgull::property_readable, true) -{ + const std::shared_ptr& manager) : + _hidpp20(receiver->rawReceiver(), index, + manager->config()->io_timeout.value_or( + defaults::io_timeout)), + _path(receiver->path()), _index(index), + _config(_getConfig(manager, _hidpp20.name())), + _receiver(receiver), + _manager(manager), + _nickname(manager), + _ipc_node(manager->devicesNode()->make_child(_nickname)), + _awake(ipcgull::property_readable, true) { _init(); } -void Device::_init() -{ +void Device::_init() { logPrintf(INFO, "Device found: %s on %s:%d", name().c_str(), - hidpp20().devicePath().c_str(), _index); + hidpp20().devicePath().c_str(), _index); _profile = _config.profiles.find(_config.default_profile); - if(_profile == _config.profiles.end()) + if (_profile == _config.profiles.end()) _profile = _config.profiles.insert({_config.default_profile, {}}).first; _addFeature("dpi"); @@ -162,61 +152,55 @@ void Device::_init() _makeResetMechanism(); reset(); - for(auto& feature: _features) { + for (auto& feature: _features) { feature.second->configure(); feature.second->listen(); } } -std::string Device::name() -{ +std::string Device::name() { return _hidpp20.name(); } -uint16_t Device::pid() -{ +uint16_t Device::pid() { return _hidpp20.pid(); } -void Device::sleep() -{ +void Device::sleep() { std::lock_guard lock(_state_lock); - if(_awake) { + if (_awake) { logPrintf(INFO, "%s:%d fell asleep.", _path.c_str(), _index); _awake = false; _ipc_interface->notifyStatus(); } } -void Device::wakeup() -{ +void Device::wakeup() { std::lock_guard lock(_state_lock); logPrintf(INFO, "%s:%d woke up.", _path.c_str(), _index); std::this_thread::sleep_for(std::chrono::milliseconds(100)); reset(); - for(auto& feature: _features) + for (auto& feature: _features) feature.second->configure(); - if(!_awake) { + if (!_awake) { _awake = true; _ipc_interface->notifyStatus(); } } -void Device::reset() -{ - if(_reset_mechanism) +void Device::reset() { + if (_reset_mechanism) (*_reset_mechanism)(); else logPrintf(DEBUG, "%s:%d tried to reset, but no reset mechanism was " "available.", _path.c_str(), _index); } -std::shared_ptr Device::virtualInput() const -{ - if(auto manager = _manager.lock()) { +std::shared_ptr Device::virtualInput() const { + if (auto manager = _manager.lock()) { return manager->virtualInput(); } else { logPrintf(ERROR, "Device manager lost"); @@ -227,8 +211,7 @@ std::shared_ptr Device::virtualInput() const } } -std::shared_ptr Device::ipcNode() const -{ +std::shared_ptr Device::ipcNode() const { return _ipc_node; } @@ -237,30 +220,27 @@ std::shared_ptr Device::ipcNode() const return _config; }*/ -config::Profile& Device::activeProfile() -{ - return _profile->second; -} -const config::Profile& Device::activeProfile() const -{ +config::Profile& Device::activeProfile() { return _profile->second; } -hidpp20::Device& Device::hidpp20() -{ +const config::Profile& Device::activeProfile() const { + return _profile->second; +} + +hidpp20::Device& Device::hidpp20() { return _hidpp20; } -void Device::_makeResetMechanism() -{ +void Device::_makeResetMechanism() { try { hidpp20::Reset reset(&_hidpp20); _reset_mechanism = std::make_unique>( - [dev=&this->_hidpp20]{ + [dev = &this->_hidpp20] { hidpp20::Reset reset(dev); - reset.reset(reset.getProfile()); + reset.reset(reset.getProfile()); }); - } catch(hidpp20::UnsupportedFeature& e) { + } catch (hidpp20::UnsupportedFeature& e) { // Reset unsupported, ignore. } } @@ -270,40 +250,37 @@ Device::IPC::IPC(Device* device) : "pizza.pixl.LogiOps.Device", {}, { - {"Name", ipcgull::property( - ipcgull::property_readable, device->name())}, - {"ProductID", ipcgull::property( - ipcgull::property_readable, device->pid())}, - {"Active", device->_awake}, - {"DefaultProfile", device->_config.default_profile} + {"Name", ipcgull::property( + ipcgull::property_readable, device->name())}, + {"ProductID", ipcgull::property( + ipcgull::property_readable, device->pid())}, + {"Active", device->_awake}, + {"DefaultProfile", device->_config.default_profile} }, { {"StatusChanged", ipcgull::signal::make_signal({"active"})} - }), _device (*device) -{ + }), _device(*device) { } -void Device::IPC::notifyStatus() const -{ - emit_signal("StatusChanged", (bool)(_device._awake)); +void Device::IPC::notifyStatus() const { + emit_signal("StatusChanged", (bool) (_device._awake)); } config::Device& Device::_getConfig( const std::shared_ptr& manager, - const std::string& name) -{ + const std::string& name) { static std::mutex config_mutex; std::lock_guard lock(config_mutex); auto& devices = manager->config()->devices; - if(!devices.has_value()) + if (!devices.has_value()) devices = decltype(config::Config::devices)(); - if(!devices.value().count(name)) { + if (!devices.value().count(name)) { devices.value().emplace(name, config::Device()); } auto& device = devices.value().at(name); - if(std::holds_alternative(device)) { + if (std::holds_alternative(device)) { config::Device d; d.profiles["default"] = std::get(device); d.default_profile = "default"; @@ -311,7 +288,7 @@ config::Device& Device::_getConfig( } auto& conf = std::get(device); - if(conf.profiles.empty()) { + if (conf.profiles.empty()) { conf.profiles["default"] = {}; conf.default_profile = "default"; } diff --git a/src/logid/Device.h b/src/logid/Device.h index 2af5397..7a54bbe 100644 --- a/src/logid/Device.h +++ b/src/logid/Device.h @@ -27,21 +27,27 @@ #include "Configuration.h" #include "util/log.h" -namespace logid -{ +namespace logid { class DeviceManager; + class Device; + class Receiver; + class InputDevice; class DeviceNickname { public: explicit DeviceNickname(const std::shared_ptr& manager); + DeviceNickname() = delete; + DeviceNickname(const DeviceNickname&) = delete; + ~DeviceNickname(); operator std::string() const; + private: const int _nickname; const std::weak_ptr _manager; @@ -51,63 +57,70 @@ namespace logid * Currently, the logid::Device class has a hardcoded requirement * for an HID++ 2.0 device. */ - class Device : public ipcgull::object - { - private: - class Config; + class Device : public ipcgull::object { public: std::string name(); + uint16_t pid(); //config::Device& config(); config::Profile& activeProfile(); - const config::Profile& activeProfile() const; + + [[nodiscard]] const config::Profile& activeProfile() const; + backend::hidpp20::Device& hidpp20(); static std::shared_ptr make( std::string path, backend::hidpp::DeviceIndex index, std::shared_ptr manager); + static std::shared_ptr make( std::shared_ptr raw_device, backend::hidpp::DeviceIndex index, std::shared_ptr manager); + static std::shared_ptr make( Receiver* receiver, backend::hidpp::DeviceIndex index, std::shared_ptr manager); void wakeup(); + void sleep(); void reset(); [[nodiscard]] std::shared_ptr virtualInput() const; + [[nodiscard]] std::shared_ptr ipcNode() const; template - std::shared_ptr getFeature(std::string name) { + std::shared_ptr getFeature(const std::string& name) { auto it = _features.find(name); - if(it == _features.end()) + if (it == _features.end()) return nullptr; try { return std::dynamic_pointer_cast(it->second); - } catch(std::bad_cast& e) { + } catch (std::bad_cast& e) { logPrintf(ERROR, "bad_cast while getting device feature %s: %s", - name.c_str(), e.what()); + name.c_str(), e.what()); return nullptr; } } private: - friend class _Device; + friend class DeviceWrapper; + Device(std::string path, backend::hidpp::DeviceIndex index, - std::shared_ptr manager); + const std::shared_ptr& manager); + Device(std::shared_ptr raw_device, backend::hidpp::DeviceIndex index, - std::shared_ptr manager); + const std::shared_ptr& manager); + Device(Receiver* receiver, backend::hidpp::DeviceIndex index, - std::shared_ptr manager); + const std::shared_ptr& manager); static config::Device& _getConfig( const std::shared_ptr& manager, @@ -117,8 +130,7 @@ namespace logid /* Adds a feature without calling an error if unsupported */ template - void _addFeature(std::string name) - { + void _addFeature(std::string name) { try { _features.emplace(name, std::make_shared(this)); } catch (features::UnsupportedFeature& e) { @@ -129,7 +141,7 @@ namespace logid std::string _path; backend::hidpp::DeviceIndex _index; std::map> - _features; + _features; config::Device& _config; std::map::iterator _profile; @@ -137,6 +149,7 @@ namespace logid const std::weak_ptr _manager; void _makeResetMechanism(); + std::unique_ptr> _reset_mechanism; const DeviceNickname _nickname; @@ -146,7 +159,8 @@ namespace logid private: Device& _device; public: - IPC(Device* device); + explicit IPC(Device* device); + void notifyStatus() const; }; diff --git a/src/logid/DeviceManager.cpp b/src/logid/DeviceManager.cpp index bb669f5..271c509 100644 --- a/src/logid/DeviceManager.cpp +++ b/src/logid/DeviceManager.cpp @@ -31,25 +31,23 @@ using namespace logid; using namespace logid::backend; namespace logid { - class _DeviceManager : public logid::DeviceManager - { + class DevManagerWrapper : public logid::DeviceManager { public: - template - explicit _DeviceManager(Args... args) : - DeviceManager(std::forward(args)...) { } + template + explicit DevManagerWrapper(Args... args) : + DeviceManager(std::forward(args)...) {} }; } DeviceManager::DeviceManager(std::shared_ptr config, std::shared_ptr virtual_input, std::shared_ptr server) : - backend::raw::DeviceMonitor(), - _server (std::move(server)), _config (std::move(config)), - _virtual_input (std::move(virtual_input)), - _root_node (ipcgull::node::make_root("")), - _device_node (ipcgull::node::make_root("devices")), - _receiver_node (ipcgull::node::make_root("receivers")) -{ + backend::raw::DeviceMonitor(), + _server(std::move(server)), _config(std::move(config)), + _virtual_input(std::move(virtual_input)), + _root_node(ipcgull::node::make_root("")), + _device_node(ipcgull::node::make_root("devices")), + _receiver_node(ipcgull::node::make_root("receivers")) { _ipc_devices = _root_node->make_interface(this); _ipc_receivers = _root_node->make_interface(this); _ipc_config = _root_node->make_interface(_config.get()); @@ -62,45 +60,39 @@ DeviceManager::DeviceManager(std::shared_ptr config, std::shared_ptr DeviceManager::make( const std::shared_ptr& config, const std::shared_ptr& virtual_input, - const std::shared_ptr& server) -{ - auto ret = std::make_shared<_DeviceManager>(config, virtual_input, server); + const std::shared_ptr& server) { + auto ret = std::make_shared(config, virtual_input, server); ret->_self = ret; return ret; } -std::shared_ptr DeviceManager::config() const -{ +std::shared_ptr DeviceManager::config() const { return _config; } -std::shared_ptr DeviceManager::virtualInput() const -{ +std::shared_ptr DeviceManager::virtualInput() const { return _virtual_input; } -std::shared_ptr DeviceManager::devicesNode() const -{ +std::shared_ptr DeviceManager::devicesNode() const { return _device_node; } -std::shared_ptr DeviceManager::receiversNode() const -{ +std::shared_ptr DeviceManager::receiversNode() const { return _receiver_node; } -void DeviceManager::addDevice(std::string path) -{ +void DeviceManager::addDevice(std::string path) { bool defaultExists = true; bool isReceiver = false; // Check if device is ignored before continuing { raw::RawDevice raw_dev(path, _self.lock()); - if(config()->ignore.has_value() && - config()->ignore.value().contains(raw_dev.productId())) { + if (config()->ignore.has_value() && + config()->ignore.value().contains(raw_dev.productId())) { logPrintf(DEBUG, "%s: Device 0x%04x ignored.", - path.c_str(), raw_dev.productId()); + path.c_str(), raw_dev.productId()); return; } } @@ -110,92 +102,88 @@ void DeviceManager::addDevice(std::string path) path, hidpp::DefaultDevice, _self.lock(), config()->io_timeout.value_or(defaults::io_timeout)); isReceiver = device.version() == std::make_tuple(1, 0); - } catch(hidpp10::Error &e) { - if(e.code() != hidpp10::Error::UnknownDevice) + } catch (hidpp10::Error& e) { + if (e.code() != hidpp10::Error::UnknownDevice) throw; - } catch(hidpp::Device::InvalidDevice &e) { - if(e.code() == hidpp::Device::InvalidDevice::VirtualNode) { + } catch (hidpp::Device::InvalidDevice& e) { + if (e.code() == hidpp::Device::InvalidDevice::VirtualNode) { logPrintf(DEBUG, "Ignoring virtual node on %s", path.c_str()); return; } defaultExists = false; - } catch(std::system_error &e) { + } catch (std::system_error& e) { logPrintf(WARN, "I/O error on %s: %s, skipping device.", - path.c_str(), e.what()); + path.c_str(), e.what()); return; - } catch (TimeoutError &e) { + } catch (TimeoutError& e) { logPrintf(WARN, "Device %s timed out.", path.c_str()); defaultExists = false; } - if(isReceiver) { + if (isReceiver) { logPrintf(INFO, "Detected receiver at %s", path.c_str()); auto receiver = Receiver::make(path, _self.lock()); std::lock_guard lock(_map_lock); _receivers.emplace(path, receiver); _ipc_receivers->receiverAdded(receiver); } else { - /* TODO: Can non-receivers only contain 1 device? - * If the device exists, it is guaranteed to be an HID++ 2.0 device */ - if(defaultExists) { + /* TODO: Can non-receivers only contain 1 device? + * If the device exists, it is guaranteed to be an HID++ 2.0 device */ + if (defaultExists) { auto device = Device::make(path, hidpp::DefaultDevice, _self.lock()); std::lock_guard lock(_map_lock); - _devices.emplace(path, device); + _devices.emplace(path, device); _ipc_devices->deviceAdded(device); } else { try { auto device = Device::make(path, - hidpp::CordedDevice, _self.lock()); + hidpp::CordedDevice, _self.lock()); std::lock_guard lock(_map_lock); _devices.emplace(path, device); _ipc_devices->deviceAdded(device); - } catch(hidpp10::Error &e) { - if(e.code() != hidpp10::Error::UnknownDevice) + } catch (hidpp10::Error& e) { + if (e.code() != hidpp10::Error::UnknownDevice) throw; else logPrintf(WARN, - "HID++ 1.0 error while trying to initialize %s:" - "%s", path.c_str(), e.what()); - } catch(hidpp::Device::InvalidDevice &e) { // Ignore - } catch(std::system_error &e) { + "HID++ 1.0 error while trying to initialize %s:" + "%s", path.c_str(), e.what()); + } catch (hidpp::Device::InvalidDevice& e) { // Ignore + } catch (std::system_error& e) { // This error should have been thrown previously logPrintf(WARN, "I/O error on %s: %s", path.c_str(), - e.what()); + e.what()); } } } } -void DeviceManager::addExternalDevice(const std::shared_ptr &d) -{ +void DeviceManager::addExternalDevice(const std::shared_ptr& d) { _ipc_devices->deviceAdded(d); } -void DeviceManager::removeExternalDevice(const std::shared_ptr &d) -{ +void DeviceManager::removeExternalDevice(const std::shared_ptr& d) { _ipc_devices->deviceRemoved(d); } -std::mutex& DeviceManager::mutex() const -{ +std::mutex& DeviceManager::mutex() const { return _map_lock; } -void DeviceManager::removeDevice(std::string path) -{ +void DeviceManager::removeDevice(std::string path) { std::lock_guard lock(_map_lock); auto receiver = _receivers.find(path); - if(receiver != _receivers.end()) { + if (receiver != _receivers.end()) { _ipc_receivers->receiverRemoved(receiver->second); _receivers.erase(receiver); logPrintf(INFO, "Receiver on %s disconnected", path.c_str()); } else { auto device = _devices.find(path); - if(device != _devices.end()) { + if (device != _devices.end()) { _ipc_devices->deviceRemoved(device->second); _devices.erase(device); logPrintf(INFO, "Device on %s disconnected", path.c_str()); @@ -204,42 +192,39 @@ void DeviceManager::removeDevice(std::string path) } DeviceManager::DevicesIPC::DevicesIPC(DeviceManager* manager) : -ipcgull::interface( - "pizza.pixl.LogiOps.Devices", - { - {"Enumerate",{manager, &DeviceManager::listDevices,{"devices"}}} - }, - {}, - { - {"DeviceAdded", - ipcgull::make_signal>( - {"device"})}, - {"DeviceRemoved", - ipcgull::make_signal>( - {"device"})} - }) -{ + ipcgull::interface( + "pizza.pixl.LogiOps.Devices", + { + {"Enumerate", {manager, &DeviceManager::listDevices, {"devices"}}} + }, + {}, + { + {"DeviceAdded", + ipcgull::make_signal>( + {"device"})}, + {"DeviceRemoved", + ipcgull::make_signal>( + {"device"})} + }) { } -std::vector> DeviceManager::listDevices() const -{ +std::vector> DeviceManager::listDevices() const { std::lock_guard lock(_map_lock); std::vector> devices; - for(auto& x : _devices) + for (auto& x: _devices) devices.emplace_back(x.second); - for(auto& x : _receivers) { - for(auto& d : x.second->devices()) + for (auto& x: _receivers) { + for (auto& d: x.second->devices()) devices.emplace_back(d.second); } return devices; } -std::vector> DeviceManager::listReceivers() const -{ +std::vector> DeviceManager::listReceivers() const { std::lock_guard lock(_map_lock); std::vector> receivers; - for(auto& x : _receivers) + for (auto& x: _receivers) receivers.emplace_back(x.second); return receivers; } @@ -255,22 +240,21 @@ void DeviceManager::DevicesIPC::deviceRemoved( } DeviceManager::ReceiversIPC::ReceiversIPC(DeviceManager* manager) : -ipcgull::interface( - "pizza.pixl.LogiOps.Receivers", - { - {"Enumerate",{manager, &DeviceManager::listReceivers, - {"receivers"}}} - }, - {}, - { - {"ReceiverAdded", - ipcgull::make_signal>( - {"receiver"})}, - {"ReceiverRemoved", - ipcgull::make_signal>( - {"receiver"})} - }) -{ + ipcgull::interface( + "pizza.pixl.LogiOps.Receivers", + { + {"Enumerate", {manager, &DeviceManager::listReceivers, + {"receivers"}}} + }, + {}, + { + {"ReceiverAdded", + ipcgull::make_signal>( + {"receiver"})}, + {"ReceiverRemoved", + ipcgull::make_signal>( + {"receiver"})} + }) { } void DeviceManager::ReceiversIPC::receiverAdded( @@ -283,13 +267,12 @@ void DeviceManager::ReceiversIPC::receiverRemoved( emit_signal("ReceiverRemoved", r); } -int DeviceManager::newDeviceNickname() -{ +int DeviceManager::newDeviceNickname() { std::lock_guard lock(_nick_lock); auto begin = _device_nicknames.begin(); - if(begin != _device_nicknames.end()) { - if(*begin != 0) { + if (begin != _device_nicknames.end()) { + if (*begin != 0) { _device_nicknames.insert(0); return 0; } @@ -300,9 +283,9 @@ int DeviceManager::newDeviceNickname() [](int l, int r) { return l + 1 < r; }); - if(i == _device_nicknames.end()) { + if (i == _device_nicknames.end()) { auto end = _device_nicknames.rbegin(); - if(end != _device_nicknames.rend()) { + if (end != _device_nicknames.rend()) { auto ret = *end + 1; assert(ret > 0); _device_nicknames.insert(ret); @@ -319,13 +302,12 @@ int DeviceManager::newDeviceNickname() return ret; } -int DeviceManager::newReceiverNickname() -{ +int DeviceManager::newReceiverNickname() { std::lock_guard lock(_nick_lock); auto begin = _receiver_nicknames.begin(); - if(begin != _receiver_nicknames.end()) { - if(*begin != 0) { + if (begin != _receiver_nicknames.end()) { + if (*begin != 0) { _receiver_nicknames.insert(0); return 0; } @@ -335,9 +317,9 @@ int DeviceManager::newReceiverNickname() _receiver_nicknames.end(), [](int l, int r) { return l + 1 < r; }); - if(i == _receiver_nicknames.end()) { + if (i == _receiver_nicknames.end()) { auto end = _receiver_nicknames.rbegin(); - if(end != _receiver_nicknames.rend()) { + if (end != _receiver_nicknames.rend()) { auto ret = *end + 1; assert(ret > 0); _receiver_nicknames.insert(ret); diff --git a/src/logid/DeviceManager.h b/src/logid/DeviceManager.h index 0c9f680..b17d26a 100644 --- a/src/logid/DeviceManager.h +++ b/src/logid/DeviceManager.h @@ -30,50 +30,63 @@ #include "Device.h" #include "Receiver.h" -namespace logid -{ +namespace logid { class InputDevice; - class DeviceManager : public backend::raw::DeviceMonitor - { + class DeviceManager : public backend::raw::DeviceMonitor { public: static std::shared_ptr make( const std::shared_ptr& config, const std::shared_ptr& virtual_input, const std::shared_ptr& server); + [[nodiscard]] std::shared_ptr config() const; + [[nodiscard]] std::shared_ptr virtualInput() const; + [[nodiscard]] std::shared_ptr devicesNode() const; + [[nodiscard]] std::shared_ptr - receiversNode() const; + receiversNode() const; void addExternalDevice(const std::shared_ptr& d); + void removeExternalDevice(const std::shared_ptr& d); std::mutex& mutex() const; + protected: void addDevice(std::string path) final; + void removeDevice(std::string path) final; + private: class DevicesIPC : public ipcgull::interface { public: explicit DevicesIPC(DeviceManager* manager); + void deviceAdded(const std::shared_ptr& d); + void deviceRemoved(const std::shared_ptr& d); }; + [[nodiscard]] std::vector> listDevices() const; class ReceiversIPC : public ipcgull::interface { public: explicit ReceiversIPC(DeviceManager* manager); + void receiverAdded(const std::shared_ptr& r); + void receiverRemoved(const std::shared_ptr& r); }; + [[nodiscard]] std::vector> listReceivers() const; - friend class _DeviceManager; + friend class DevManagerWrapper; + DeviceManager(std::shared_ptr config, std::shared_ptr virtual_input, std::shared_ptr server); @@ -98,9 +111,11 @@ namespace logid mutable std::mutex _map_lock; friend class DeviceNickname; + friend class ReceiverNickname; [[nodiscard]] int newDeviceNickname(); + [[nodiscard]] int newReceiverNickname(); std::mutex _nick_lock; diff --git a/src/logid/InputDevice.cpp b/src/logid/InputDevice.cpp index 20646e2..eafd0cb 100644 --- a/src/logid/InputDevice.cpp +++ b/src/logid/InputDevice.cpp @@ -29,22 +29,18 @@ extern "C" using namespace logid; InputDevice::InvalidEventCode::InvalidEventCode(const std::string& name) : - _what ("Invalid event code " + name) -{ + _what("Invalid event code " + name) { } InputDevice::InvalidEventCode::InvalidEventCode(uint code) : - _what ("Invalid event code " + std::to_string(code)) -{ + _what("Invalid event code " + std::to_string(code)) { } -const char* InputDevice::InvalidEventCode::what() const noexcept -{ +const char* InputDevice::InvalidEventCode::what() const noexcept { return _what.c_str(); } -InputDevice::InputDevice(const char* name) -{ +InputDevice::InputDevice(const char* name) { device = libevdev_new(); libevdev_set_name(device, name); @@ -61,30 +57,28 @@ InputDevice::InputDevice(const char* name) } } - for (unsigned int i = 0; i < REL_CNT; i++) - registered_axis[i] = false; + for (bool& axis: registered_axis) + axis = false; libevdev_enable_event_type(device, EV_REL); int err = libevdev_uinput_create_from_device(device, - LIBEVDEV_UINPUT_OPEN_MANAGED, &ui_device); + LIBEVDEV_UINPUT_OPEN_MANAGED, &ui_device); - if(err != 0) { + if (err != 0) { libevdev_free(device); throw std::system_error(-err, std::generic_category()); } } -InputDevice::~InputDevice() -{ +InputDevice::~InputDevice() { libevdev_uinput_destroy(ui_device); libevdev_free(device); } -void InputDevice::registerKey(uint code) -{ +void InputDevice::registerKey(uint code) { // TODO: Maybe print error message, if wrong code is passed? - if(code >= KEY_CNT || registered_keys[code]) { + if (code >= KEY_CNT || registered_keys[code]) { return; } @@ -93,10 +87,9 @@ void InputDevice::registerKey(uint code) registered_keys[code] = true; } -void InputDevice::registerAxis(uint axis) -{ +void InputDevice::registerAxis(uint axis) { // TODO: Maybe print error message, if wrong code is passed? - if(axis >= REL_CNT || registered_axis[axis]) { + if (axis >= REL_CNT || registered_axis[axis]) { return; } @@ -105,87 +98,76 @@ void InputDevice::registerAxis(uint axis) registered_axis[axis] = true; } -void InputDevice::moveAxis(uint axis, int movement) -{ +void InputDevice::moveAxis(uint axis, int movement) { _sendEvent(EV_REL, axis, movement); } -void InputDevice::pressKey(uint code) -{ +void InputDevice::pressKey(uint code) { _sendEvent(EV_KEY, code, 1); } -void InputDevice::releaseKey(uint code) -{ +void InputDevice::releaseKey(uint code) { _sendEvent(EV_KEY, code, 0); } -std::string InputDevice::toKeyName(uint code) -{ +std::string InputDevice::toKeyName(uint code) { return _toEventName(EV_KEY, code); } -uint InputDevice::toKeyCode(const std::string& name) -{ +uint InputDevice::toKeyCode(const std::string& name) { return _toEventCode(EV_KEY, name); } -std::string InputDevice::toAxisName(uint code) -{ +std::string InputDevice::toAxisName(uint code) { return _toEventName(EV_REL, code); } -uint InputDevice::toAxisCode(const std::string& name) -{ +uint InputDevice::toAxisCode(const std::string& name) { return _toEventCode(EV_REL, name); } /* Returns -1 if axis_code is not hi-res */ -int InputDevice::getLowResAxis(const uint axis_code) -{ +int InputDevice::getLowResAxis(const uint axis_code) { /* Some systems don't have these hi-res axes */ #ifdef REL_WHEEL_HI_RES - if(axis_code == REL_WHEEL_HI_RES) + if (axis_code == REL_WHEEL_HI_RES) return REL_WHEEL; #endif #ifdef REL_HWHEEL_HI_RES - if(axis_code == REL_HWHEEL_HI_RES) + if (axis_code == REL_HWHEEL_HI_RES) return REL_HWHEEL; #endif return -1; } -std::string InputDevice::_toEventName(uint type, uint code) -{ +std::string InputDevice::_toEventName(uint type, uint code) { const char* ret = libevdev_event_code_get_name(type, code); - if(!ret) + if (!ret) throw InvalidEventCode(code); return {ret}; } -uint InputDevice::_toEventCode(uint type, const std::string& name) -{ +uint InputDevice::_toEventCode(uint type, const std::string& name) { int code = libevdev_event_code_from_name(type, name.c_str()); - if(code == -1) + if (code == -1) throw InvalidEventCode(name); return code; } -void InputDevice::_enableEvent(const uint type, const uint code) -{ +void InputDevice::_enableEvent(const uint type, const uint code) { libevdev_uinput_destroy(ui_device); libevdev_enable_event_code(device, type, code, nullptr); int err = libevdev_uinput_create_from_device(device, - LIBEVDEV_UINPUT_OPEN_MANAGED, &ui_device); + LIBEVDEV_UINPUT_OPEN_MANAGED, &ui_device); - if(err != 0) { + if (err != 0) { libevdev_free(device); device = nullptr; ui_device = nullptr; @@ -193,8 +175,7 @@ void InputDevice::_enableEvent(const uint type, const uint code) } } -void InputDevice::_sendEvent(uint type, uint code, int value) -{ +void InputDevice::_sendEvent(uint type, uint code, int value) { libevdev_uinput_write_event(ui_device, type, code, value); libevdev_uinput_write_event(ui_device, EV_SYN, SYN_REPORT, 0); } diff --git a/src/logid/InputDevice.h b/src/logid/InputDevice.h index 9994787..d8c212f 100644 --- a/src/logid/InputDevice.h +++ b/src/logid/InputDevice.h @@ -28,44 +28,56 @@ extern "C" #include } -namespace logid -{ - class InputDevice - { +namespace logid { + class InputDevice { public: - class InvalidEventCode : public std::exception - { + class InvalidEventCode : public std::exception { public: explicit InvalidEventCode(const std::string& name); + explicit InvalidEventCode(uint code); + const char* what() const noexcept override; + private: const std::string _what; }; - explicit InputDevice(const char *name); + + explicit InputDevice(const char* name); + ~InputDevice(); void registerKey(uint code); + void registerAxis(uint axis); + void moveAxis(uint axis, int movement); + 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); private: 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]; - bool registered_axis[REL_CNT]; + bool registered_keys[KEY_CNT]{}; + bool registered_axis[REL_CNT]{}; libevdev* device; libevdev_uinput* ui_device{}; }; diff --git a/src/logid/Receiver.cpp b/src/logid/Receiver.cpp index ce4004c..44df3f0 100644 --- a/src/logid/Receiver.cpp +++ b/src/logid/Receiver.cpp @@ -28,34 +28,32 @@ using namespace logid::backend; ReceiverNickname::ReceiverNickname( const std::shared_ptr& manager) : - _nickname (manager->newReceiverNickname()), _manager (manager) -{ + _nickname(manager->newReceiverNickname()), _manager(manager) { } ReceiverNickname::operator std::string() const { return std::to_string(_nickname); } -ReceiverNickname::~ReceiverNickname() -{ - if(auto manager = _manager.lock()) { +ReceiverNickname::~ReceiverNickname() { + if (auto manager = _manager.lock()) { std::lock_guard lock(manager->_nick_lock); manager->_receiver_nicknames.erase(_nickname); } } namespace logid { - class _Receiver : public Receiver { + class ReceiverWrapper : public Receiver { public: - template - _Receiver(Args... args) : Receiver(std::forward(args)...) { } + template + explicit ReceiverWrapper(Args... args) : Receiver(std::forward(args)...) {} }; } std::shared_ptr Receiver::make( - const std::string &path, - const std::shared_ptr &manager) { - auto ret = std::make_shared<_Receiver>(path, manager); + const std::string& path, + const std::shared_ptr& manager) { + auto ret = std::make_shared(path, manager); ret->_self = ret; ret->_ipc_node->manage(ret); return ret; @@ -64,13 +62,12 @@ std::shared_ptr Receiver::make( Receiver::Receiver(const std::string& path, const std::shared_ptr& manager) : - dj::ReceiverMonitor(path, manager, - manager->config()->io_timeout.value_or( - defaults::io_timeout)), - _path (path), _manager (manager), _nickname (manager), - _ipc_node (manager->receiversNode()->make_child(_nickname)), - _ipc_interface (_ipc_node->make_interface(this)) -{ + dj::ReceiverMonitor(path, manager, + manager->config()->io_timeout.value_or( + defaults::io_timeout)), + _path(path), _manager(manager), _nickname(manager), + _ipc_node(manager->receiversNode()->make_child(_nickname)), + _ipc_interface(_ipc_node->make_interface(this)) { ready(); } @@ -78,20 +75,18 @@ const Receiver::DeviceList& Receiver::devices() const { return _devices; } -Receiver::~Receiver() -{ - if(auto manager = _manager.lock()) { - for(auto& d : _devices) +Receiver::~Receiver() noexcept { + if (auto manager = _manager.lock()) { + for (auto& d: _devices) manager->removeExternalDevice(d.second); } } -void Receiver::addDevice(hidpp::DeviceConnectionEvent event) -{ +void Receiver::addDevice(hidpp::DeviceConnectionEvent event) { std::unique_lock lock(_devices_change); auto manager = _manager.lock(); - if(!manager) { + if (!manager) { logPrintf(ERROR, "Orphan Receiver, missing DeviceManager"); logPrintf(ERROR, "Fatal error, file a bug report. Program will now exit."); @@ -100,7 +95,7 @@ void Receiver::addDevice(hidpp::DeviceConnectionEvent event) try { // Check if device is ignored before continuing - if(manager->config()->ignore.value_or( + if (manager->config()->ignore.value_or( std::set()).contains(event.pid)) { logPrintf(DEBUG, "%s:%d: Device 0x%04x ignored.", _path.c_str(), event.index, event.pid); @@ -108,15 +103,15 @@ void Receiver::addDevice(hidpp::DeviceConnectionEvent event) } auto dev = _devices.find(event.index); - if(dev != _devices.end()) { - if(event.linkEstablished) + if (dev != _devices.end()) { + if (event.linkEstablished) dev->second->wakeup(); else dev->second->sleep(); return; } - if(!event.linkEstablished) + if (!event.linkEstablished) return; hidpp::Device hidpp_device( @@ -125,9 +120,9 @@ void Receiver::addDevice(hidpp::DeviceConnectionEvent event) auto version = hidpp_device.version(); - if(std::get<0>(version) < 2) { + if (std::get<0>(version) < 2) { logPrintf(INFO, "Unsupported HID++ 1.0 device on %s:%d connected.", - _path.c_str(), event.index); + _path.c_str(), event.index); return; } @@ -136,46 +131,42 @@ void Receiver::addDevice(hidpp::DeviceConnectionEvent event) _devices.emplace(event.index, device); manager->addExternalDevice(device); - } catch(hidpp10::Error &e) { + } catch (hidpp10::Error& e) { logPrintf(ERROR, - "Caught HID++ 1.0 error while trying to initialize " - "%s:%d: %s", _path.c_str(), event.index, e.what()); - } catch(hidpp20::Error &e) { + "Caught HID++ 1.0 error while trying to initialize " + "%s:%d: %s", _path.c_str(), event.index, e.what()); + } catch (hidpp20::Error& e) { logPrintf(ERROR, "Caught HID++ 2.0 error while trying to initialize " - "%s:%d: %s", _path.c_str(), event.index, e.what()); - } catch(TimeoutError &e) { - if(!event.fromTimeoutCheck) + "%s:%d: %s", _path.c_str(), event.index, e.what()); + } catch (TimeoutError& e) { + if (!event.fromTimeoutCheck) logPrintf(DEBUG, "%s:%d timed out, waiting for input from device to" " initialize.", _path.c_str(), event.index); waitForDevice(event.index); } } -void Receiver::removeDevice(hidpp::DeviceIndex index) -{ +void Receiver::removeDevice(hidpp::DeviceIndex index) { std::unique_lock lock(_devices_change); std::unique_lock manager_lock; - if(auto manager = _manager.lock()) + if (auto manager = _manager.lock()) manager_lock = std::unique_lock(manager->mutex()); auto device = _devices.find(index); - if(device != _devices.end()) { - if(auto manager = _manager.lock()) + if (device != _devices.end()) { + if (auto manager = _manager.lock()) manager->removeExternalDevice(device->second); _devices.erase(device); } } -const std::string& Receiver::path() const -{ +const std::string& Receiver::path() const { return _path; } -std::shared_ptr Receiver::rawReceiver() -{ +std::shared_ptr Receiver::rawReceiver() { return receiver(); } -Receiver::ReceiverIPC::ReceiverIPC(Receiver *receiver) : - ipcgull::interface("pizza.pixl.LogiOps.Receiver", {}, {}, {}) -{ +Receiver::ReceiverIPC::ReceiverIPC(Receiver* receiver) : + ipcgull::interface("pizza.pixl.LogiOps.Receiver", {}, {}, {}) { } diff --git a/src/logid/Receiver.h b/src/logid/Receiver.h index 8022261..d2ebcba 100644 --- a/src/logid/Receiver.h +++ b/src/logid/Receiver.h @@ -23,42 +23,49 @@ #include "backend/dj/ReceiverMonitor.h" #include "Device.h" -namespace logid -{ +namespace logid { class ReceiverNickname { public: explicit ReceiverNickname(const std::shared_ptr& manager); + ReceiverNickname() = delete; + ReceiverNickname(const ReceiverNickname&) = delete; + ~ReceiverNickname(); operator std::string() const; + private: const int _nickname; const std::weak_ptr _manager; }; class Receiver : public backend::dj::ReceiverMonitor, - public ipcgull::object - { + public ipcgull::object { public: typedef std::map> - DeviceList; + DeviceList; - ~Receiver(); + ~Receiver() noexcept override; static std::shared_ptr make( const std::string& path, const std::shared_ptr& manager); - const std::string& path() const; + + [[nodiscard]] const std::string& path() const; + std::shared_ptr rawReceiver(); [[nodiscard]] const DeviceList& devices() const; + protected: void addDevice(backend::hidpp::DeviceConnectionEvent event) override; + void removeDevice(backend::hidpp::DeviceIndex index) override; + private: - friend class _Receiver; + friend class ReceiverWrapper; Receiver(const std::string& path, const std::shared_ptr& manager); @@ -73,7 +80,7 @@ namespace logid class ReceiverIPC : public ipcgull::interface { public: - ReceiverIPC(Receiver* receiver); + explicit ReceiverIPC(Receiver* receiver); }; std::shared_ptr _ipc_interface; diff --git a/src/logid/actions/Action.cpp b/src/logid/actions/Action.cpp index de0b935..950e3a6 100644 --- a/src/logid/actions/Action.cpp +++ b/src/logid/actions/Action.cpp @@ -30,73 +30,73 @@ using namespace logid; using namespace logid::actions; -template -struct action_type { - typedef typename T::action type; -}; +namespace logid::actions { + template + struct action_type { + typedef typename T::action type; + }; -template -struct action_type : action_type { }; + template + struct action_type : action_type { + }; -template -struct action_type : action_type { }; + template + struct action_type : action_type { + }; -template -std::shared_ptr _makeAction( - Device* device, T& action, - const std::shared_ptr& parent) -{ - return parent->make_interface::type>( - device, std::forward(action), parent); -} - -template -std::shared_ptr _makeAction( - Device *device, const std::string &name, - std::optional& config, - const std::shared_ptr& parent) -{ - if(name == ChangeDPI::interface_name) { - config = config::ChangeDPI(); - } else if(name == ChangeHostAction::interface_name) { - config = config::ChangeHost(); - } else if(name == CycleDPI::interface_name) { - config = config::CycleDPI(); - } else if(name == KeypressAction::interface_name) { - config = config::KeypressAction(); - } else if(name == NullAction::interface_name) { - config = config::NoAction(); - } else if(name == ChangeHostAction::interface_name) { - config = config::ChangeHost(); - } else if(name == ToggleHiresScroll::interface_name) { - config = config::ToggleHiresScroll(); - } else if(name == ToggleSmartShift::interface_name) { - config = config::ToggleHiresScroll(); - } else if(name == "Default") { - config.reset(); - return nullptr; + template + std::shared_ptr _makeAction( + Device* device, T& action, + const std::shared_ptr& parent) { + return parent->make_interface::type>( + device, std::forward(action), parent); } - return Action::makeAction(device, config.value(), parent); + template + std::shared_ptr _makeAction( + Device* device, const std::string& name, + std::optional& config, + const std::shared_ptr& parent) { + if (name == ChangeDPI::interface_name) { + config = config::ChangeDPI(); + } else if (name == CycleDPI::interface_name) { + config = config::CycleDPI(); + } else if (name == KeypressAction::interface_name) { + config = config::KeypressAction(); + } else if (name == NullAction::interface_name) { + config = config::NoAction(); + } else if (name == ChangeHostAction::interface_name) { + config = config::ChangeHost(); + } else if (name == ToggleHiresScroll::interface_name) { + config = config::ToggleHiresScroll(); + } else if (name == ToggleSmartShift::interface_name) { + config = config::ToggleSmartShift(); + } else if (name == "Default") { + config.reset(); + return nullptr; + } else { + throw InvalidAction(name); + } + + return Action::makeAction(device, config.value(), parent); + } } std::shared_ptr Action::makeAction( - Device *device, const std::string &name, - std::optional &config, - const std::shared_ptr& parent) -{ + Device* device, const std::string& name, + std::optional& config, + const std::shared_ptr& parent) { return _makeAction(device, name, config, parent); } std::shared_ptr Action::makeAction( - Device *device, const std::string &name, - std::optional &config, - const std::shared_ptr& parent) -{ + Device* device, const std::string& name, + std::optional& config, + const std::shared_ptr& parent) { try { return _makeAction(device, name, config, parent); - } catch(actions::InvalidAction& e) { - if(name == GestureAction::interface_name) { + } catch (actions::InvalidAction& e) { + if (name == GestureAction::interface_name) { config = config::GestureAction(); return makeAction(device, config.value(), parent); } @@ -105,9 +105,8 @@ std::shared_ptr Action::makeAction( } std::shared_ptr Action::makeAction( - Device *device, config::BasicAction& action, - const std::shared_ptr& parent) -{ + Device* device, config::BasicAction& action, + const std::shared_ptr& parent) { std::shared_ptr ret; std::visit([&device, &ret, &parent](auto&& x) { ret = _makeAction(device, x, parent); @@ -116,9 +115,8 @@ std::shared_ptr Action::makeAction( } std::shared_ptr Action::makeAction( - Device *device, config::Action& action, - const std::shared_ptr& parent) -{ + Device* device, config::Action& action, + const std::shared_ptr& parent) { std::shared_ptr ret; std::visit([&device, &ret, &parent](auto&& x) { ret = _makeAction(device, x, parent); @@ -127,7 +125,6 @@ std::shared_ptr Action::makeAction( } Action::Action(Device* device, const std::string& name, tables t) : - ipcgull::interface("pizza.pixl.LogiOps.Action." + name, std::move(t)), - _device (device), _pressed (false) -{ + 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 240c4d8..f037a60 100644 --- a/src/logid/actions/Action.h +++ b/src/logid/actions/Action.h @@ -21,32 +21,31 @@ #include #include #include +#include #include #include #include "../config/schema.h" namespace logid { class Device; -namespace actions { - class InvalidAction : public std::exception - { +} + +namespace logid::actions { + class InvalidAction : public std::exception { public: - InvalidAction() - { - } - explicit InvalidAction(std::string& action) : _action (action) - { - } - const char* what() const noexcept override - { + InvalidAction() = default; + + InvalidAction(std::string action) : _action(std::move(action)) {} + + [[nodiscard]] const char* what() const noexcept override { return _action.c_str(); } + private: std::string _action; }; - class Action : public ipcgull::interface - { + class Action : public ipcgull::interface { public: static std::shared_ptr makeAction( Device* device, const std::string& name, @@ -67,28 +66,29 @@ namespace actions { const std::shared_ptr& parent); virtual void press() = 0; + virtual void release() = 0; - virtual void move(int16_t x, int16_t y) - { + + virtual void move(int16_t x, int16_t y) { // Suppress unused warning - (void)x; (void)y; + (void) x; + (void) y; } - virtual bool pressed() - { + virtual bool pressed() { return _pressed; } - virtual uint8_t reprogFlags() const = 0; + [[nodiscard]] virtual uint8_t reprogFlags() const = 0; virtual ~Action() = default; protected: - Action(Device* device, const std::string& name, tables t={}); + Action(Device* device, const std::string& name, tables t = {}); Device* _device; std::atomic _pressed; }; -}} +} #endif //LOGID_ACTION_H diff --git a/src/logid/actions/ChangeDPI.cpp b/src/logid/actions/ChangeDPI.cpp index 3d4ee6f..f26a398 100644 --- a/src/logid/actions/ChangeDPI.cpp +++ b/src/logid/actions/ChangeDPI.cpp @@ -25,35 +25,33 @@ using namespace logid::actions; const char* ChangeDPI::interface_name = "ChangeDPI"; ChangeDPI::ChangeDPI( - Device *device, config::ChangeDPI& config, + Device* device, config::ChangeDPI& config, [[maybe_unused]] const std::shared_ptr& parent) : - Action(device, interface_name, { - { - {"GetConfig", {this, &ChangeDPI::getConfig, {"change", "sensor"}}}, - {"SetChange", {this, &ChangeDPI::setChange, {"change"}}}, - {"SetSensor", {this, &ChangeDPI::setSensor, {"sensor", "reset"}}}, - }, {}, {} }), _config (config) -{ + Action(device, interface_name, { + { + {"GetConfig", {this, &ChangeDPI::getConfig, {"change", "sensor"}}}, + {"SetChange", {this, &ChangeDPI::setChange, {"change"}}}, + {"SetSensor", {this, &ChangeDPI::setSensor, {"sensor", "reset"}}}, + }, + {}, + {}}), _config(config) { _dpi = _device->getFeature("dpi"); - if(!_dpi) + if (!_dpi) logPrintf(WARN, "%s:%d: DPI feature not found, cannot use " "ChangeDPI action.", _device->hidpp20().devicePath().c_str(), _device->hidpp20().deviceIndex()); } -std::tuple ChangeDPI::getConfig() const -{ +std::tuple ChangeDPI::getConfig() const { return {_config.inc.value_or(0), _config.sensor.value_or(0)}; } -void ChangeDPI::setChange(int16_t change) -{ +void ChangeDPI::setChange(int16_t change) { _config.inc = change; } -void ChangeDPI::setSensor(uint8_t sensor, bool reset) -{ +void ChangeDPI::setSensor(uint8_t sensor, bool reset) { if (reset) { _config.sensor.reset(); } else { @@ -61,36 +59,33 @@ void ChangeDPI::setSensor(uint8_t sensor, bool reset) } } -void ChangeDPI::press() -{ +void ChangeDPI::press() { _pressed = true; - if(_dpi && _config.inc.has_value()) { + 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.value(), - _config.sensor.value_or(0)); - } catch (backend::hidpp20::Error& e) { - if(e.code() == backend::hidpp20::Error::InvalidArgument) - logPrintf(WARN, "%s:%d: Could not get/set DPI for sensor " - "%d", - _device->hidpp20().devicePath().c_str(), - _device->hidpp20().deviceIndex(), - _config.sensor.value_or(0)); - else - throw e; - } - }); + [this] { + try { + uint16_t last_dpi = _dpi->getDPI(_config.sensor.value_or(0)); + _dpi->setDPI(last_dpi + _config.inc.value(), + _config.sensor.value_or(0)); + } catch (backend::hidpp20::Error& e) { + if (e.code() == backend::hidpp20::Error::InvalidArgument) + logPrintf(WARN, "%s:%d: Could not get/set DPI for sensor " + "%d", + _device->hidpp20().devicePath().c_str(), + _device->hidpp20().deviceIndex(), + _config.sensor.value_or(0)); + else + throw e; + } + }); } } -void ChangeDPI::release() -{ +void ChangeDPI::release() { _pressed = false; } -uint8_t ChangeDPI::reprogFlags() const -{ +uint8_t ChangeDPI::reprogFlags() const { return backend::hidpp20::ReprogControls::TemporaryDiverted; } diff --git a/src/logid/actions/ChangeDPI.h b/src/logid/actions/ChangeDPI.h index 1a0db62..0bf00e8 100644 --- a/src/logid/actions/ChangeDPI.h +++ b/src/logid/actions/ChangeDPI.h @@ -23,27 +23,29 @@ #include "../features/DPI.h" namespace logid::actions { - class ChangeDPI : public Action - { - public: - static const char* interface_name; + class ChangeDPI : public Action { + public: + static const char* interface_name; - ChangeDPI(Device* device, config::ChangeDPI& setting, - const std::shared_ptr& parent); + ChangeDPI(Device* device, config::ChangeDPI& setting, + const std::shared_ptr& parent); - virtual void press(); - virtual void release(); + void press() final; - [[nodiscard]] std::tuple getConfig() const; - void setChange(int16_t change); - void setSensor(uint8_t sensor, bool reset); + void release() final; - virtual uint8_t reprogFlags() const; + [[nodiscard]] std::tuple getConfig() const; - protected: - config::ChangeDPI& _config; - std::shared_ptr _dpi; - }; - } + void setChange(int16_t change); + + void setSensor(uint8_t sensor, bool reset); + + [[nodiscard]] uint8_t reprogFlags() const final; + + protected: + config::ChangeDPI& _config; + std::shared_ptr _dpi; + }; +} #endif //LOGID_ACTION_CHANGEDPI_H \ No newline at end of file diff --git a/src/logid/actions/ChangeHostAction.cpp b/src/logid/actions/ChangeHostAction.cpp index 8253d3a..8163f96 100644 --- a/src/logid/actions/ChangeHostAction.cpp +++ b/src/logid/actions/ChangeHostAction.cpp @@ -27,17 +27,18 @@ using namespace logid::backend; const char* ChangeHostAction::interface_name = "ChangeHost"; ChangeHostAction::ChangeHostAction( - Device *device, config::ChangeHost& config, + Device* device, config::ChangeHost& config, [[maybe_unused]] const std::shared_ptr& parent) - : Action(device, interface_name, { + : Action(device, interface_name, { { {"GetHost", {this, &ChangeHostAction::getHost, {"host"}}}, {"SetHost", {this, &ChangeHostAction::setHost, {"host"}}} - }, {}, {} - }), _config (config) -{ + }, + {}, + {} +}), _config(config) { if (_config.host.has_value()) { - if(std::holds_alternative(_config.host.value())) { + if (std::holds_alternative(_config.host.value())) { auto& host = std::get(_config.host.value()); std::transform(host.begin(), host.end(), host.begin(), ::tolower); @@ -48,13 +49,12 @@ ChangeHostAction::ChangeHostAction( } catch (hidpp20::UnsupportedFeature& e) { logPrintf(WARN, "%s:%d: ChangeHost feature not supported, " "ChangeHostAction will not work.", device->hidpp20() - .devicePath().c_str(), device->hidpp20().deviceIndex()); + .devicePath().c_str(), device->hidpp20().deviceIndex()); } } -std::string ChangeHostAction::getHost() const -{ - if(_config.host.has_value()) { +std::string ChangeHostAction::getHost() const { + if (_config.host.has_value()) { if (std::holds_alternative(_config.host.value())) return std::get(_config.host.value()); else @@ -64,8 +64,7 @@ std::string ChangeHostAction::getHost() const } } -void ChangeHostAction::setHost(std::string host) -{ +void ChangeHostAction::setHost(std::string host) { std::transform(host.begin(), host.end(), host.begin(), ::tolower); if (host == "next" || host == "prev" || host == "previous") { @@ -75,37 +74,34 @@ void ChangeHostAction::setHost(std::string host) } } -void ChangeHostAction::press() -{ +void ChangeHostAction::press() { // Do nothing, wait until release } -void ChangeHostAction::release() -{ - if(_change_host && _config.host.has_value()) { +void ChangeHostAction::release() { + 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.value())) { - const auto& host = std::get(_config.host.value()); - if(host == "next") - next_host = host_info.currentHost + 1; - else if(host == "prev" || host == "previous") - next_host = host_info.currentHost - 1; - else - next_host = host_info.currentHost; - } else { - next_host = std::get(_config.host.value())-1; - } - next_host %= host_info.hostCount; - if(next_host != host_info.currentHost) - _change_host->setHost(next_host); - }); + [this] { + auto host_info = _change_host->getHostInfo(); + int next_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") + next_host = host_info.currentHost - 1; + else + next_host = host_info.currentHost; + } else { + next_host = std::get(_config.host.value()) - 1; + } + next_host %= host_info.hostCount; + if (next_host != host_info.currentHost) + _change_host->setHost(next_host); + }); } } -uint8_t ChangeHostAction::reprogFlags() const -{ +uint8_t ChangeHostAction::reprogFlags() const { return hidpp20::ReprogControls::TemporaryDiverted; } diff --git a/src/logid/actions/ChangeHostAction.h b/src/logid/actions/ChangeHostAction.h index 1a5cdb9..6268a32 100644 --- a/src/logid/actions/ChangeHostAction.h +++ b/src/logid/actions/ChangeHostAction.h @@ -22,24 +22,23 @@ #include "Action.h" #include "../backend/hidpp20/features/ChangeHost.h" -namespace logid::actions -{ - class ChangeHostAction : public Action - { +namespace logid::actions { + class ChangeHostAction : public Action { public: static const char* interface_name; ChangeHostAction(Device* device, config::ChangeHost& config, const std::shared_ptr& parent); - virtual void press(); - virtual void release(); + void press() final; + void release() final; [[nodiscard]] std::string getHost() const; + void setHost(std::string host); - virtual uint8_t reprogFlags() const; + [[nodiscard]] uint8_t reprogFlags() const final; protected: std::shared_ptr _change_host; diff --git a/src/logid/actions/CycleDPI.cpp b/src/logid/actions/CycleDPI.cpp index 615291f..f29c640 100644 --- a/src/logid/actions/CycleDPI.cpp +++ b/src/logid/actions/CycleDPI.cpp @@ -18,8 +18,6 @@ #include "CycleDPI.h" #include "../Device.h" #include "../util/task.h" -#include "../util/log.h" -#include "../backend/hidpp20/Error.h" #include "../backend/hidpp20/features/ReprogControls.h" using namespace logid::actions; @@ -29,53 +27,51 @@ const char* CycleDPI::interface_name = "CycleDPI"; CycleDPI::CycleDPI(Device* device, config::CycleDPI& config, [[maybe_unused]] const std::shared_ptr& parent) : - Action (device, interface_name, { - { - {"GetDPIs", {this, &CycleDPI::getDPIs, {"dpis"}}}, - {"SetDPIs", {this, &CycleDPI::setDPIs, {"dpis"}}} - }, {}, {} - }), - _config (config) -{ + Action(device, interface_name, { + { + {"GetDPIs", {this, &CycleDPI::getDPIs, {"dpis"}}}, + {"SetDPIs", {this, &CycleDPI::setDPIs, {"dpis"}}} + }, + {}, + {} + }), + _config(config) { _dpi = _device->getFeature("dpi"); - if(!_dpi) + if (!_dpi) logPrintf(WARN, "%s:%d: DPI feature not found, cannot use " "CycleDPI action.", _device->hidpp20().devicePath().c_str(), _device->hidpp20().deviceIndex()); - if(_config.dpis.has_value()) { - _current_dpi = _config.dpis.value().begin(); + if (_config.dpis.has_value()) { + _current_dpi = _config.dpis.value().begin(); } } -std::vector CycleDPI::getDPIs() const -{ +std::vector CycleDPI::getDPIs() const { auto dpis = _config.dpis.value_or(std::list()); return {dpis.begin(), dpis.end()}; } -void CycleDPI::setDPIs(const std::vector& dpis) -{ +void CycleDPI::setDPIs(const std::vector& dpis) { std::lock_guard lock(_dpi_lock); _config.dpis.emplace(dpis.begin(), dpis.end()); _current_dpi = _config.dpis->cbegin(); } -void CycleDPI::press() -{ +void CycleDPI::press() { _pressed = true; std::lock_guard lock(_dpi_lock); - if(_dpi && _config.dpis.has_value() && _config.dpis.value().empty()) { + if (_dpi && _config.dpis.has_value() && _config.dpis.value().empty()) { ++_current_dpi; - if(_current_dpi == _config.dpis.value().end()) + if (_current_dpi == _config.dpis.value().end()) _current_dpi = _config.dpis.value().begin(); - spawn_task([this, dpi=*_current_dpi]{ + spawn_task([this, dpi = *_current_dpi] { try { _dpi->setDPI(dpi, _config.sensor.value_or(0)); } catch (backend::hidpp20::Error& e) { - if(e.code() == backend::hidpp20::Error::InvalidArgument) + 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(), dpi, @@ -87,12 +83,10 @@ void CycleDPI::press() } } -void CycleDPI::release() -{ +void CycleDPI::release() { _pressed = false; } -uint8_t CycleDPI::reprogFlags() const -{ +uint8_t CycleDPI::reprogFlags() const { return backend::hidpp20::ReprogControls::TemporaryDiverted; } diff --git a/src/logid/actions/CycleDPI.h b/src/logid/actions/CycleDPI.h index e1a66cd..a4347a7 100644 --- a/src/logid/actions/CycleDPI.h +++ b/src/logid/actions/CycleDPI.h @@ -23,21 +23,22 @@ #include "../features/DPI.h" namespace logid::actions { - class CycleDPI : public Action - { + class CycleDPI : public Action { public: static const char* interface_name; CycleDPI(Device* device, config::CycleDPI& setting, const std::shared_ptr& parent); - virtual void press(); - virtual void release(); + void press() final; + + void release() final; [[nodiscard]] std::vector getDPIs() const; + void setDPIs(const std::vector& dpis); - virtual uint8_t reprogFlags() const; + [[nodiscard]] uint8_t reprogFlags() const final; protected: std::mutex _dpi_lock; diff --git a/src/logid/actions/GestureAction.cpp b/src/logid/actions/GestureAction.cpp index fd9afd4..a7a32ca 100644 --- a/src/logid/actions/GestureAction.cpp +++ b/src/logid/actions/GestureAction.cpp @@ -26,50 +26,47 @@ using namespace logid::backend; const char* GestureAction::interface_name = "Gesture"; -GestureAction::Direction GestureAction::toDirection(std::string direction) -{ +GestureAction::Direction GestureAction::toDirection(std::string direction) { std::transform(direction.begin(), direction.end(), direction.begin(), - ::tolower); - if(direction == "up") + ::tolower); + if (direction == "up") return Up; - else if(direction == "down") + else if (direction == "down") return Down; - else if(direction == "left") + else if (direction == "left") return Left; - else if(direction == "right") + else if (direction == "right") return Right; - else if(direction == "none") + else if (direction == "none") return None; else throw std::invalid_argument("direction"); } -std::string GestureAction::fromDirection(Direction direction) -{ - switch(direction) { - case Up: - return "up"; - case Down: - return "down"; - case Left: - return "left"; - case Right: - return "right"; - case None: - return "none"; +std::string GestureAction::fromDirection(Direction direction) { + switch (direction) { + case Up: + return "up"; + case Down: + return "down"; + case Left: + return "left"; + case Right: + return "right"; + case None: + return "none"; } // This shouldn't happen throw InvalidGesture(); } -GestureAction::Direction GestureAction::toDirection(int16_t x, int16_t y) -{ - if(x >= 0 && y >= 0) +GestureAction::Direction GestureAction::toDirection(int32_t x, int32_t y) { + if (x >= 0 && y >= 0) return x >= y ? Right : Down; - else if(x < 0 && y >= 0) + else if (x < 0 && y >= 0) return -x <= y ? Down : Left; - else if(x <= 0 && y < 0) + else if (x <= 0 /* && y < 0 */) return x <= y ? Left : Up; else return x <= -y ? Up : Right; @@ -77,18 +74,19 @@ GestureAction::Direction GestureAction::toDirection(int16_t x, int16_t y) GestureAction::GestureAction(Device* dev, config::GestureAction& config, const std::shared_ptr& parent) : - Action (dev, interface_name, - { - { - {"SetGesture", {this, &GestureAction::setGesture, - {"direction", "type"}}} - }, {}, {} - }), - _node (parent->make_child("gestures")), _config (config) -{ - if(_config.gestures.has_value()) { + 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(); - for(auto& x : gestures) { + for (auto& x: gestures) { try { auto direction = toDirection(x.first); _gestures.emplace(direction, @@ -96,25 +94,23 @@ GestureAction::GestureAction(Device* dev, config::GestureAction& config, dev, x.second, _node->make_child( fromDirection(direction)))); - } catch(std::invalid_argument& e) { + } catch (std::invalid_argument& e) { logPrintf(WARN, "%s is not a direction", x.first.c_str()); } } } } -void GestureAction::press() -{ +void GestureAction::press() { std::lock_guard lock(_config_lock); _pressed = true; _x = 0, _y = 0; - for(auto& gesture : _gestures) - gesture.second->press(); + for (auto& gesture: _gestures) + gesture.second->press(false); } -void GestureAction::release() -{ +void GestureAction::release() { std::lock_guard lock(_config_lock); _pressed = false; @@ -122,16 +118,16 @@ void GestureAction::release() auto d = toDirection(_x, _y); auto primary_gesture = _gestures.find(d); - if(primary_gesture != _gestures.end()) { + if (primary_gesture != _gestures.end()) { threshold_met = primary_gesture->second->metThreshold(); primary_gesture->second->release(true); } - for(auto& gesture : _gestures) { - if(gesture.first == d) + for (auto& gesture: _gestures) { + if (gesture.first == d) continue; - if(!threshold_met) { - if(gesture.second->metThreshold()) { + if (!threshold_met) { + if (gesture.second->metThreshold()) { // If the primary gesture did not meet its threshold, use the // secondary one. threshold_met = true; @@ -143,105 +139,103 @@ void GestureAction::release() } } - if(!threshold_met) { + if (!threshold_met) { try { auto none = _gestures.at(None); - if(none) { - none->press(); - none->release(); + if (none) { + none->press(false); + none->release(false); } - } catch(std::out_of_range& e) { } + } catch (std::out_of_range& e) {} } } -void GestureAction::move(int16_t x, int16_t y) -{ +void GestureAction::move(int16_t x, int16_t y) { std::lock_guard lock(_config_lock); - auto new_x = _x + x, new_y = _y + y; + int32_t new_x = _x + x, new_y = _y + y; - if(abs(x) > 0) { - if(_x < 0 && new_x >= 0) { // Left -> Origin/Right + if (abs(x) > 0) { + if (_x < 0 && new_x >= 0) { // Left -> Origin/Right auto left = _gestures.find(Left); - if(left != _gestures.end() && left->second) - left->second->move(_x); - if(new_x) { // Ignore to origin + if (left != _gestures.end() && left->second) + left->second->move((int16_t) _x); + if (new_x) { // Ignore to origin auto right = _gestures.find(Right); - if(right != _gestures.end() && right->second) - right->second->move(new_x); + if (right != _gestures.end() && right->second) + right->second->move((int16_t) new_x); } - } else if(_x > 0 && new_x <= 0) { // Right -> Origin/Left + } else if (_x > 0 && new_x <= 0) { // Right -> Origin/Left auto right = _gestures.find(Right); - if(right != _gestures.end() && right->second) - right->second->move(-_x); - if(new_x) { // Ignore to origin + if (right != _gestures.end() && right->second) + right->second->move((int16_t) -_x); + if (new_x) { // Ignore to origin auto left = _gestures.find(Left); - if(left != _gestures.end() && left->second) - left->second->move(-new_x); + if (left != _gestures.end() && left->second) + left->second->move((int16_t) -new_x); } - } else if(new_x < 0) { // Origin/Left to Left + } else if (new_x < 0) { // Origin/Left to Left auto left = _gestures.find(Left); - if(left != _gestures.end() && left->second) - left->second->move(-x); - } else if(new_x > 0) { // Origin/Right to Right + if (left != _gestures.end() && left->second) + left->second->move((int16_t) -x); + } else if (new_x > 0) { // Origin/Right to Right auto right = _gestures.find(Right); - if(right != _gestures.end() && right->second) + if (right != _gestures.end() && right->second) right->second->move(x); } } - if(abs(y) > 0) { - if(_y > 0 && new_y <= 0) { // Up -> Origin/Down + if (abs(y) > 0) { + if (_y > 0 && new_y <= 0) { // Up -> Origin/Down auto up = _gestures.find(Up); - if(up != _gestures.end() && up->second) - up->second->move(_y); - if(new_y) { // Ignore to origin + if (up != _gestures.end() && up->second) + up->second->move((int16_t) _y); + if (new_y) { // Ignore to origin auto down = _gestures.find(Down); - if(down != _gestures.end() && down->second) - down->second->move(new_y); + if (down != _gestures.end() && down->second) + down->second->move((int16_t) new_y); } - } else if(_y < 0 && new_y >= 0) { // Down -> Origin/Up + } else if (_y < 0 && new_y >= 0) { // Down -> Origin/Up auto down = _gestures.find(Down); - if(down != _gestures.end() && down->second) - down->second->move(-_y); - if(new_y) { // Ignore to origin + if (down != _gestures.end() && down->second) + down->second->move((int16_t) -_y); + if (new_y) { // Ignore to origin auto up = _gestures.find(Up); - if(up != _gestures.end() && up->second) - up->second->move(-new_y); + if (up != _gestures.end() && up->second) + up->second->move((int16_t) -new_y); } - } else if(new_y < 0) { // Origin/Up to Up + } else if (new_y < 0) { // Origin/Up to Up auto up = _gestures.find(Up); - if(up != _gestures.end() && up->second) - up->second->move(-y); - } else if(new_y > 0) {// Origin/Down to Down + if (up != _gestures.end() && up->second) + up->second->move((int16_t) -y); + } else if (new_y > 0) {// Origin/Down to Down auto down = _gestures.find(Down); - if(down != _gestures.end() && down->second) + if (down != _gestures.end() && down->second) down->second->move(y); } } - _x = new_x; _y = new_y; + _x = new_x; + _y = new_y; } -uint8_t GestureAction::reprogFlags() const -{ +uint8_t GestureAction::reprogFlags() const { return (hidpp20::ReprogControls::TemporaryDiverted | - hidpp20::ReprogControls::RawXYDiverted); + hidpp20::ReprogControls::RawXYDiverted); } -void GestureAction::setGesture(const std::string &direction, - const std::string &type) -{ +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()) { + if (it != _gestures.end()) { + if (pressed()) { auto current = toDirection(_x, _y); - if(it->second) + if (it->second) it->second->release(current == d); } } diff --git a/src/logid/actions/GestureAction.h b/src/logid/actions/GestureAction.h index 2dfc603..45d9777 100644 --- a/src/logid/actions/GestureAction.h +++ b/src/logid/actions/GestureAction.h @@ -23,43 +23,46 @@ #include "Action.h" #include "gesture/Gesture.h" -namespace logid { -namespace actions { - class GestureAction : public Action - { +namespace logid::actions { + class GestureAction : public Action { public: static const char* interface_name; - enum Direction - { + enum Direction { None, Up, Down, Left, Right }; + static Direction toDirection(std::string direction); + static std::string fromDirection(Direction direction); - static Direction toDirection(int16_t x, int16_t y); + + static Direction toDirection(int32_t x, int32_t y); GestureAction(Device* dev, config::GestureAction& config, const std::shared_ptr& parent); - virtual void press(); - virtual void release(); - virtual void move(int16_t x, int16_t y); + void press() final; - virtual uint8_t reprogFlags() const; + void release() final; + + void move(int16_t x, int16_t y) final; + + uint8_t reprogFlags() const final; void setGesture(const std::string& direction, const std::string& type); + protected: - int16_t _x, _y; + int32_t _x{}, _y{}; std::shared_ptr _node; std::map> _gestures; config::GestureAction& _config; mutable std::mutex _config_lock; }; -}} +} #endif //LOGID_ACTION_GESTUREACTION_H diff --git a/src/logid/actions/KeypressAction.cpp b/src/logid/actions/KeypressAction.cpp index 909ed37..f5a4f62 100644 --- a/src/logid/actions/KeypressAction.cpp +++ b/src/logid/actions/KeypressAction.cpp @@ -17,7 +17,6 @@ */ #include "KeypressAction.h" #include "../Device.h" -#include "../util/log.h" #include "../InputDevice.h" #include "../backend/hidpp20/features/ReprogControls.h" @@ -27,72 +26,70 @@ using namespace logid::backend; const char* KeypressAction::interface_name = "Keypress"; KeypressAction::KeypressAction( - Device *device, config::KeypressAction& config, + 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) -{ + Action(device, interface_name, { + { + {"GetKeys", {this, &KeypressAction::getKeys, {"keys"}}}, + {"SetKeys", {this, &KeypressAction::setKeys, {"keys"}}} + }, + {}, + {} + }), _config(config) { _setConfig(); } -void KeypressAction::press() -{ +void KeypressAction::press() { std::lock_guard lock(_config_lock); _pressed = true; - for(auto& key : _keys) + for (auto& key: _keys) _device->virtualInput()->pressKey(key); } -void KeypressAction::release() -{ +void KeypressAction::release() { std::lock_guard lock(_config_lock); _pressed = false; - for(auto& key : _keys) + for (auto& key: _keys) _device->virtualInput()->releaseKey(key); } -void KeypressAction::_setConfig() -{ +void KeypressAction::_setConfig() { _keys.clear(); - if(!_config.keys.has_value()) + if (!_config.keys.has_value()) return; auto& config = _config.keys.value(); - if(std::holds_alternative(config)) { + if (std::holds_alternative(config)) { const auto& key = std::get(config); try { auto code = _device->virtualInput()->toKeyCode(key); _device->virtualInput()->registerKey(code); _keys.emplace_back(code); - } catch(InputDevice::InvalidEventCode& e) { + } catch (InputDevice::InvalidEventCode& e) { logPrintf(WARN, "Invalid keycode %s, skipping.", key.c_str()); } - } else if(std::holds_alternative(_config.keys.value())) { + } 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< + } 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)) { + for (const auto& key: keys) { + if (std::holds_alternative(key)) { const auto& key_str = std::get(key); try { auto code = _device->virtualInput()->toKeyCode(key_str); _device->virtualInput()->registerKey(code); _keys.emplace_back(code); - } catch(InputDevice::InvalidEventCode& e) { + } catch (InputDevice::InvalidEventCode& e) { logPrintf(WARN, "Invalid keycode %s, skipping.", key_str.c_str()); } - } else if(std::holds_alternative(key)) { + } else if (std::holds_alternative(key)) { auto& code = std::get(key); _device->virtualInput()->registerKey(code); _keys.emplace_back(code); @@ -101,31 +98,28 @@ void KeypressAction::_setConfig() } } -uint8_t KeypressAction::reprogFlags() const -{ +uint8_t KeypressAction::reprogFlags() const { return hidpp20::ReprogControls::TemporaryDiverted; } -std::vector KeypressAction::getKeys() const -{ +std::vector KeypressAction::getKeys() const { std::lock_guard lock(_config_lock); std::vector ret; - for(auto& x : _keys) + for (auto& x: _keys) ret.push_back(InputDevice::toKeyName(x)); return ret; } -void KeypressAction::setKeys(const std::vector &keys) -{ +void KeypressAction::setKeys(const std::vector& keys) { std::lock_guard lock(_config_lock); - if(_pressed) - for(auto& key : _keys) + 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) + for (auto& x: keys) config.emplace_back(x); _setConfig(); } diff --git a/src/logid/actions/KeypressAction.h b/src/logid/actions/KeypressAction.h index e55fc62..72bba6a 100644 --- a/src/logid/actions/KeypressAction.h +++ b/src/logid/actions/KeypressAction.h @@ -22,10 +22,8 @@ #include #include "Action.h" -namespace logid { -namespace actions { - class KeypressAction : public Action - { +namespace logid::actions { + class KeypressAction : public Action { public: static const char* interface_name; @@ -33,13 +31,16 @@ namespace actions { config::KeypressAction& config, const std::shared_ptr& parent); - virtual void press(); - virtual void release(); + void press() final; + + void release() final; [[nodiscard]] std::vector getKeys() const; + void setKeys(const std::vector& keys); - virtual uint8_t reprogFlags() const; + [[nodiscard]] uint8_t reprogFlags() const final; + protected: mutable std::mutex _config_lock; config::KeypressAction& _config; @@ -47,6 +48,6 @@ namespace actions { void _setConfig(); }; -}} +} #endif //LOGID_ACTION_KEYPRESS_H diff --git a/src/logid/actions/NullAction.cpp b/src/logid/actions/NullAction.cpp index 0fe6729..e38faa1 100644 --- a/src/logid/actions/NullAction.cpp +++ b/src/logid/actions/NullAction.cpp @@ -26,21 +26,17 @@ const char* NullAction::interface_name = "None"; NullAction::NullAction( Device* device, [[maybe_unused]] const std::shared_ptr& parent) : - Action(device, interface_name) -{ + Action(device, interface_name) { } -void NullAction::press() -{ +void NullAction::press() { _pressed = true; } -void NullAction::release() -{ +void NullAction::release() { _pressed = false; } -uint8_t NullAction::reprogFlags() const -{ +uint8_t NullAction::reprogFlags() const { return backend::hidpp20::ReprogControls::TemporaryDiverted; } \ No newline at end of file diff --git a/src/logid/actions/NullAction.h b/src/logid/actions/NullAction.h index 2262c30..9229b5b 100644 --- a/src/logid/actions/NullAction.h +++ b/src/logid/actions/NullAction.h @@ -20,26 +20,25 @@ #include "Action.h" -namespace logid { -namespace actions -{ - class NullAction : public Action - { +namespace logid::actions { + class NullAction : public Action { public: static const char* interface_name; NullAction(Device* device, const std::shared_ptr& parent); + NullAction(Device* device, [[maybe_unused]] config::NoAction& config, const std::shared_ptr& parent) : - NullAction(device, parent) { } + NullAction(device, parent) {} - virtual void press(); - virtual void release(); + void press() final; - virtual uint8_t reprogFlags() const; + void release() final; + + [[nodiscard]] uint8_t reprogFlags() const final; }; -}} +} #endif //LOGID_ACTION_NULL_H diff --git a/src/logid/actions/ToggleHiresScroll.cpp b/src/logid/actions/ToggleHiresScroll.cpp index dfcb1c3..bfe6262 100644 --- a/src/logid/actions/ToggleHiresScroll.cpp +++ b/src/logid/actions/ToggleHiresScroll.cpp @@ -26,38 +26,33 @@ using namespace logid::backend; const char* ToggleHiresScroll::interface_name = "ToggleHiresScroll"; ToggleHiresScroll::ToggleHiresScroll( - Device *dev, + Device* dev, [[maybe_unused]] const std::shared_ptr& parent) : - Action (dev, interface_name) -{ + Action(dev, interface_name) { _hires_scroll = _device->getFeature("hiresscroll"); - if(!_hires_scroll) + if (!_hires_scroll) logPrintf(WARN, "%s:%d: HiresScroll feature not found, cannot use " "ToggleHiresScroll action.", _device->hidpp20().devicePath().c_str(), _device->hidpp20().devicePath().c_str()); } -void ToggleHiresScroll::press() -{ +void ToggleHiresScroll::press() { _pressed = true; - if(_hires_scroll) - { + if (_hires_scroll) { spawn_task( - [hires=this->_hires_scroll](){ - auto mode = hires->getMode(); - mode ^= backend::hidpp20::HiresScroll::HiRes; - hires->setMode(mode); - }); + [hires = this->_hires_scroll]() { + auto mode = hires->getMode(); + mode ^= backend::hidpp20::HiresScroll::HiRes; + hires->setMode(mode); + }); } } -void ToggleHiresScroll::release() -{ +void ToggleHiresScroll::release() { _pressed = false; } -uint8_t ToggleHiresScroll::reprogFlags() const -{ +uint8_t ToggleHiresScroll::reprogFlags() const { return hidpp20::ReprogControls::TemporaryDiverted; } diff --git a/src/logid/actions/ToggleHiresScroll.h b/src/logid/actions/ToggleHiresScroll.h index c79d846..dd8cd92 100644 --- a/src/logid/actions/ToggleHiresScroll.h +++ b/src/logid/actions/ToggleHiresScroll.h @@ -21,27 +21,27 @@ #include "Action.h" #include "../features/HiresScroll.h" -namespace logid { -namespace actions -{ - class ToggleHiresScroll : public Action - { +namespace logid::actions { + class ToggleHiresScroll : public Action { public: static const char* interface_name; ToggleHiresScroll(Device* dev, const std::shared_ptr& parent); + ToggleHiresScroll(Device* device, [[maybe_unused]] config::ToggleHiresScroll& action, const std::shared_ptr& parent) : - ToggleHiresScroll(device, parent) { } + ToggleHiresScroll(device, parent) {} - virtual void press(); - virtual void release(); + void press() final; + + void release() final; + + [[nodiscard]] uint8_t reprogFlags() const final; - virtual uint8_t reprogFlags() const; protected: std::shared_ptr _hires_scroll; }; -}} +} #endif //LOGID_ACTION_TOGGLEHIRESSCROLL_H diff --git a/src/logid/actions/ToggleSmartShift.cpp b/src/logid/actions/ToggleSmartShift.cpp index efd3da6..7f4f09e 100644 --- a/src/logid/actions/ToggleSmartShift.cpp +++ b/src/logid/actions/ToggleSmartShift.cpp @@ -26,38 +26,34 @@ using namespace logid::backend; const char* ToggleSmartShift::interface_name = "ToggleSmartShift"; ToggleSmartShift::ToggleSmartShift( - Device *dev, + Device* dev, [[maybe_unused]] const std::shared_ptr& parent) : - Action (dev, interface_name) -{ + Action(dev, interface_name) { _smartshift = _device->getFeature("smartshift"); - if(!_smartshift) + if (!_smartshift) logPrintf(WARN, "%s:%d: SmartShift feature not found, cannot use " "ToggleSmartShift action.", - _device->hidpp20().devicePath().c_str(), - _device->hidpp20().deviceIndex()); + _device->hidpp20().devicePath().c_str(), + _device->hidpp20().deviceIndex()); } -void ToggleSmartShift::press() -{ +void ToggleSmartShift::press() { _pressed = true; - if(_smartshift) { + if (_smartshift) { spawn_task( - [ss=this->_smartshift](){ - auto status = ss->getStatus(); - status.setActive = true; - status.active = !status.active; - ss->setStatus(status); - }); + [ss = this->_smartshift]() { + auto status = ss->getStatus(); + status.setActive = true; + status.active = !status.active; + ss->setStatus(status); + }); } } -void ToggleSmartShift::release() -{ +void ToggleSmartShift::release() { _pressed = false; } -uint8_t ToggleSmartShift::reprogFlags() const -{ +uint8_t ToggleSmartShift::reprogFlags() const { return hidpp20::ReprogControls::TemporaryDiverted; } diff --git a/src/logid/actions/ToggleSmartShift.h b/src/logid/actions/ToggleSmartShift.h index 98c51a0..0b3546b 100644 --- a/src/logid/actions/ToggleSmartShift.h +++ b/src/logid/actions/ToggleSmartShift.h @@ -22,27 +22,28 @@ #include "Action.h" #include "../features/SmartShift.h" -namespace logid { -namespace actions { - class ToggleSmartShift : public Action - { +namespace logid::actions { + class ToggleSmartShift : public Action { public: static const char* interface_name; ToggleSmartShift(Device* dev, const std::shared_ptr& parent); + ToggleSmartShift(Device* device, [[maybe_unused]] config::ToggleSmartShift& action, const std::shared_ptr& parent) : - ToggleSmartShift(device, parent) { } + ToggleSmartShift(device, parent) {} - virtual void press(); - virtual void release(); + void press() final; + + void release() final; + + [[nodiscard]] uint8_t reprogFlags() const final; - virtual uint8_t reprogFlags() const; protected: std::shared_ptr _smartshift; }; -}} +} #endif //LOGID_ACTION_TOGGLESMARTSHIFT_H \ No newline at end of file diff --git a/src/logid/actions/gesture/AxisGesture.cpp b/src/logid/actions/gesture/AxisGesture.cpp index 1338cf1..879438c 100644 --- a/src/logid/actions/gesture/AxisGesture.cpp +++ b/src/logid/actions/gesture/AxisGesture.cpp @@ -19,66 +19,64 @@ #include "AxisGesture.h" #include "../../Device.h" #include "../../InputDevice.h" -#include "../../util/log.h" using namespace logid::actions; const char* AxisGesture::interface_name = "Axis"; -AxisGesture::AxisGesture(Device *device, config::AxisGesture& config, +AxisGesture::AxisGesture(Device* device, config::AxisGesture& config, const std::shared_ptr& parent) : - Gesture (device, parent, interface_name), _multiplier (1), _config (config) -{ - if(_config.axis.has_value()) { - if(std::holds_alternative(_config.axis.value())) { + Gesture(device, parent, interface_name), _multiplier(1), _config(config) { + 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) { + } catch (InputDevice::InvalidEventCode& e) { logPrintf(WARN, "Invalid axis %s."); } } } - if(_input_axis.has_value()) + if (_input_axis.has_value()) _device->virtualInput()->registerAxis(_input_axis.value()); } -void AxisGesture::press(bool init_threshold) -{ - _axis = init_threshold ? - _config.threshold.value_or(defaults::gesture_threshold) : 0; +void AxisGesture::press(bool init_threshold) { + if (init_threshold) { + _axis = (int32_t) (_config.threshold.value_or(defaults::gesture_threshold)); + } else { + _axis = 0; + } _axis_remainder = 0; _hires_remainder = 0; } -void AxisGesture::release(bool primary) -{ +void AxisGesture::release(bool primary) { // Do nothing - (void)primary; // Suppress unused warning + (void) primary; // Suppress unused warning } -void AxisGesture::move(int16_t axis) -{ - if(!_input_axis.has_value()) +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; + int32_t new_axis = _axis + axis; int low_res_axis = InputDevice::getLowResAxis(axis); int hires_remainder = _hires_remainder; - if(new_axis > threshold) { + if (new_axis > threshold) { double move = axis; - if(_axis < threshold) + if (_axis < threshold) move = new_axis - threshold; bool negative_multiplier = _config.axis_multiplier.value_or(1) < 0; - if(negative_multiplier) + if (negative_multiplier) move *= -_config.axis_multiplier.value_or(1); else move *= _config.axis_multiplier.value_or(1); @@ -87,48 +85,45 @@ void AxisGesture::move(int16_t axis) double move_floor = floor(move); _axis_remainder = move - move_floor; - if(_axis_remainder >= 1) { + if (_axis_remainder >= 1) { double int_remainder = floor(_axis_remainder); move_floor += int_remainder; _axis_remainder -= int_remainder; } - if(negative_multiplier) + if (negative_multiplier) move_floor = -move_floor; - if(low_res_axis != -1) { - int lowres_movement = 0, hires_movement = move_floor; + if (low_res_axis != -1) { + int lowres_movement, hires_movement = (int) move_floor; _device->virtualInput()->moveAxis(_input_axis.value(), hires_movement); hires_remainder += hires_movement; - if(abs(hires_remainder) >= 60) { - lowres_movement = hires_remainder/120; - if(lowres_movement == 0) + if (abs(hires_remainder) >= 60) { + lowres_movement = hires_remainder / 120; + if (lowres_movement == 0) lowres_movement = hires_remainder > 0 ? 1 : -1; - hires_remainder -= lowres_movement*120; + hires_remainder -= lowres_movement * 120; _device->virtualInput()->moveAxis(low_res_axis, lowres_movement); } _hires_remainder = hires_remainder; } else { - _device->virtualInput()->moveAxis(_input_axis.value(), move_floor); + _device->virtualInput()->moveAxis(_input_axis.value(), (int) move_floor); } } _axis = new_axis; } -bool AxisGesture::metThreshold() const -{ +bool AxisGesture::metThreshold() const { return _axis >= _config.threshold.value_or(defaults::gesture_threshold); } -bool AxisGesture::wheelCompatibility() const -{ +bool AxisGesture::wheelCompatibility() const { return true; } -void AxisGesture::setHiresMultiplier(double multiplier) -{ - if(InputDevice::getLowResAxis(_axis) != -1) { +void AxisGesture::setHiresMultiplier(double multiplier) { + if (InputDevice::getLowResAxis(_axis) != -1) { _multiplier = multiplier; } } diff --git a/src/logid/actions/gesture/AxisGesture.h b/src/logid/actions/gesture/AxisGesture.h index 29d20bc..2152f3b 100644 --- a/src/logid/actions/gesture/AxisGesture.h +++ b/src/logid/actions/gesture/AxisGesture.h @@ -20,34 +20,34 @@ #include "Gesture.h" -namespace logid { - namespace actions - { - class AxisGesture : public Gesture - { - public: - static const char* interface_name; +namespace logid::actions { + class AxisGesture : public Gesture { + public: + static const char* interface_name; - AxisGesture(Device* device, config::AxisGesture& config, - const std::shared_ptr& parent); + AxisGesture(Device* device, config::AxisGesture& config, + const std::shared_ptr& parent); - virtual void press(bool init_threshold=false); - virtual void release(bool primary=false); - virtual void move(int16_t axis); + void press(bool init_threshold) final; - virtual bool wheelCompatibility() const; - virtual bool metThreshold() const; + void release(bool primary) final; - void setHiresMultiplier(double multiplier); + void move(int16_t axis) final; - protected: - int16_t _axis; - double _axis_remainder; - int _hires_remainder; - std::optional _input_axis; - double _multiplier; - config::AxisGesture& _config; - }; - }} + [[nodiscard]] bool wheelCompatibility() const final; + + [[nodiscard]] bool metThreshold() const final; + + void setHiresMultiplier(double multiplier); + + protected: + int32_t _axis{}; + double _axis_remainder{}; + int _hires_remainder{}; + std::optional _input_axis; + double _multiplier; + config::AxisGesture& _config; + }; +} #endif //LOGID_ACTION_AXISGESTURE_H diff --git a/src/logid/actions/gesture/Gesture.cpp b/src/logid/actions/gesture/Gesture.cpp index deacfaa..45d3b47 100644 --- a/src/logid/actions/gesture/Gesture.cpp +++ b/src/logid/actions/gesture/Gesture.cpp @@ -27,56 +27,57 @@ using namespace logid; using namespace logid::actions; -Gesture::Gesture(Device *device, +Gesture::Gesture(Device* device, 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) -{ + _node(std::move(node)), _device(device) { } -template -struct gesture_type { - typedef typename T::gesture type; -}; +namespace { + template + struct gesture_type { + typedef typename T::gesture type; + }; -template -struct gesture_type : gesture_type { }; + template + struct gesture_type : gesture_type { + }; -template -struct gesture_type : gesture_type { }; + template + struct gesture_type : gesture_type { + }; -template -std::shared_ptr _makeGesture( - Device* device, T gesture, - const std::shared_ptr& parent) { - return parent->make_interface::type>( - device, gesture, parent); + template + std::shared_ptr _makeGesture( + Device* device, T gesture, + 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) -{ + Device* device, config::Gesture& gesture, + const std::shared_ptr& parent) { return std::visit([&device, &parent](auto&& x) { return _makeGesture(device, x, parent); }, gesture); } std::shared_ptr Gesture::makeGesture( - Device *device, const std::string& type, + Device* device, const std::string& type, config::Gesture& config, - const std::shared_ptr &parent) -{ - if(type == AxisGesture::interface_name) { + const std::shared_ptr& parent) { + if (type == AxisGesture::interface_name) { config = config::AxisGesture(); - } else if(type == IntervalGesture::interface_name) { + } else if (type == IntervalGesture::interface_name) { config = config::IntervalGesture(); - } else if(type == ReleaseGesture::interface_name) { + } else if (type == ReleaseGesture::interface_name) { config = config::ReleaseGesture(); - } else if(type == ThresholdGesture::interface_name) { + } else if (type == ThresholdGesture::interface_name) { config = config::ThresholdGesture(); - } else if(type == NullGesture::interface_name) { + } else if (type == NullGesture::interface_name) { config = config::NoGesture(); } else { throw InvalidGesture(); diff --git a/src/logid/actions/gesture/Gesture.h b/src/logid/actions/gesture/Gesture.h index b2e036b..03d5ce2 100644 --- a/src/logid/actions/gesture/Gesture.h +++ b/src/logid/actions/gesture/Gesture.h @@ -18,42 +18,41 @@ #ifndef LOGID_ACTION_GESTURE_H #define LOGID_ACTION_GESTURE_H +#include + #include "../Action.h" -#define LOGID_GESTURE_DEFAULT_THRESHOLD 50 - -namespace logid { -namespace actions -{ - class InvalidGesture : public std::exception - { +namespace logid::actions { + class InvalidGesture : public std::exception { public: - explicit InvalidGesture(std::string what="") : _what (what) - { + explicit InvalidGesture(std::string what = "") : _what(std::move(what)) { } - virtual const char* what() const noexcept - { + + [[nodiscard]] const char* what() const noexcept override { return _what.c_str(); } + private: std::string _what; }; - class Gesture : public ipcgull::interface - { + class Gesture : public ipcgull::interface { public: - virtual void press(bool init_threshold=false) = 0; - virtual void release(bool primary=false) = 0; + virtual void press(bool init_threshold) = 0; + + virtual void release(bool primary) = 0; + virtual void move(int16_t axis) = 0; - virtual bool wheelCompatibility() const = 0; - virtual bool metThreshold() const = 0; + [[nodiscard]] virtual bool wheelCompatibility() const = 0; + + [[nodiscard]] virtual bool metThreshold() const = 0; virtual ~Gesture() = default; static std::shared_ptr makeGesture(Device* device, - config::Gesture& gesture, - const std::shared_ptr& parent); + config::Gesture& gesture, + const std::shared_ptr& parent); static std::shared_ptr makeGesture( Device* device, const std::string& type, @@ -63,10 +62,11 @@ namespace actions protected: Gesture(Device* device, std::shared_ptr parent, - const std::string& name, tables t={}); + const std::string& name, tables t = {}); + const std::shared_ptr _node; Device* _device; }; -}} +} #endif //LOGID_ACTION_GESTURE_H diff --git a/src/logid/actions/gesture/IntervalGesture.cpp b/src/logid/actions/gesture/IntervalGesture.cpp index 8ec68e0..6d34899 100644 --- a/src/logid/actions/gesture/IntervalGesture.cpp +++ b/src/logid/actions/gesture/IntervalGesture.cpp @@ -16,7 +16,6 @@ * */ #include "IntervalGesture.h" -#include "../../util/log.h" #include "../../Configuration.h" using namespace logid::actions; @@ -24,48 +23,46 @@ using namespace logid::actions; const char* IntervalGesture::interface_name = "OnInterval"; IntervalGesture::IntervalGesture( - Device *device, config::IntervalGesture& config, + 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) { + Gesture(device, parent, interface_name), + _axis(0), _interval_pass_count(0), _config(config) { + if (config.action) { try { _action = Action::makeAction(device, config.action.value(), _node); - } catch(InvalidAction& e) { + } catch (InvalidAction& e) { logPrintf(WARN, "Mapping gesture to invalid action"); } } } -void IntervalGesture::press(bool init_threshold) -{ - _axis = init_threshold ? - _config.threshold.value_or(defaults::gesture_threshold) : 0; +void IntervalGesture::press(bool init_threshold) { + if (init_threshold) { + _axis = (int32_t) _config.threshold.value_or(defaults::gesture_threshold); + } else { + _axis = 0; + } _interval_pass_count = 0; } -void IntervalGesture::release(bool primary) -{ +void IntervalGesture::release(bool primary) { // Do nothing - (void)primary; // Suppress unused warning + (void) primary; // Suppress unused warning } -void IntervalGesture::move(int16_t axis) -{ - if(!_config.interval.has_value()) +void IntervalGesture::move(int16_t axis) { + if (!_config.interval.has_value()) return; const auto threshold = _config.threshold.value_or(defaults::gesture_threshold); _axis += axis; - if(_axis < threshold) + if (_axis < threshold) return; - int16_t new_interval_count = (_axis - threshold)/ - _config.interval.value(); - if(new_interval_count > _interval_pass_count) { - if(_action) { + int32_t new_interval_count = (_axis - threshold) / _config.interval.value(); + if (new_interval_count > _interval_pass_count) { + if (_action) { _action->press(); _action->release(); } @@ -73,12 +70,10 @@ void IntervalGesture::move(int16_t axis) _interval_pass_count = new_interval_count; } -bool IntervalGesture::wheelCompatibility() const -{ +bool IntervalGesture::wheelCompatibility() const { return true; } -bool IntervalGesture::metThreshold() const -{ - return _axis >= _config.threshold.value_or(defaults::gesture_threshold);; +bool IntervalGesture::metThreshold() const { + return _axis >= _config.threshold.value_or(defaults::gesture_threshold); } diff --git a/src/logid/actions/gesture/IntervalGesture.h b/src/logid/actions/gesture/IntervalGesture.h index 75356b6..e72967e 100644 --- a/src/logid/actions/gesture/IntervalGesture.h +++ b/src/logid/actions/gesture/IntervalGesture.h @@ -20,42 +20,44 @@ #include "Gesture.h" -namespace logid { -namespace actions -{ - class IntervalGesture : public Gesture - { +namespace logid::actions { + class IntervalGesture : public Gesture { public: static const char* interface_name; IntervalGesture(Device* device, config::IntervalGesture& config, const std::shared_ptr& parent); - virtual void press(bool init_threshold=false); - virtual void release(bool primary=false); - virtual void move(int16_t axis); + void press(bool init_threshold) final; - virtual bool wheelCompatibility() const; - virtual bool metThreshold() const; + void release(bool primary) final; + + void move(int16_t axis) final; + + [[nodiscard]] bool wheelCompatibility() const final; + + [[nodiscard]] bool metThreshold() const final; protected: - int16_t _axis; - int16_t _interval_pass_count; + int32_t _axis; + int32_t _interval_pass_count; std::shared_ptr _action; config::IntervalGesture& _config; private: - class IPC : public ipcgull::interface - { + class IPC : public ipcgull::interface { public: - IPC(IntervalGesture* parent); + explicit IPC(IntervalGesture* parent); void setAction(const std::string& type); + void setInterval(int interval); + void setThreshold(int threshold); + private: IntervalGesture& parent; }; }; -}} +} #endif //LOGID_ACTION_INTERVALGESTURE_H diff --git a/src/logid/actions/gesture/NullGesture.cpp b/src/logid/actions/gesture/NullGesture.cpp index c8edbb1..09793ad 100644 --- a/src/logid/actions/gesture/NullGesture.cpp +++ b/src/logid/actions/gesture/NullGesture.cpp @@ -22,36 +22,30 @@ using namespace logid::actions; const char* NullGesture::interface_name = "None"; -NullGesture::NullGesture(Device *device, +NullGesture::NullGesture(Device* device, config::NoGesture& config, const std::shared_ptr& parent) : - Gesture (device, parent, interface_name), _config (config) -{ + Gesture(device, parent, interface_name), _config(config) { } -void NullGesture::press(bool init_threshold) -{ +void NullGesture::press(bool init_threshold) { _axis = init_threshold ? _config.threshold.value_or( defaults::gesture_threshold) : 0; } -void NullGesture::release(bool primary) -{ +void NullGesture::release(bool primary) { // Do nothing - (void)primary; // Suppress unused warning + (void) primary; // Suppress unused warning } -void NullGesture::move(int16_t axis) -{ +void NullGesture::move(int16_t axis) { _axis += axis; } -bool NullGesture::wheelCompatibility() const -{ +bool NullGesture::wheelCompatibility() const { return true; } -bool NullGesture::metThreshold() const -{ +bool NullGesture::metThreshold() const { return _axis > _config.threshold.value_or(defaults::gesture_threshold); } \ No newline at end of file diff --git a/src/logid/actions/gesture/NullGesture.h b/src/logid/actions/gesture/NullGesture.h index 9f8ce15..e920b6d 100644 --- a/src/logid/actions/gesture/NullGesture.h +++ b/src/logid/actions/gesture/NullGesture.h @@ -20,11 +20,8 @@ #include "Gesture.h" -namespace logid { -namespace actions -{ - class NullGesture : public Gesture - { +namespace logid::actions { + class NullGesture : public Gesture { public: static const char* interface_name; @@ -32,16 +29,20 @@ namespace actions config::NoGesture& config, const std::shared_ptr& parent); - virtual void press(bool init_threshold=false); - virtual void release(bool primary=false); - virtual void move(int16_t axis); + void press(bool init_threshold) final; + + void release(bool primary) final; + + void move(int16_t axis) final; + + [[nodiscard]] bool wheelCompatibility() const final; + + [[nodiscard]] bool metThreshold() const final; - virtual bool wheelCompatibility() const; - virtual bool metThreshold() const; protected: - int16_t _axis; + int32_t _axis{}; config::NoGesture& _config; }; -}} +} #endif //LOGID_ACTION_NULLGESTURE_H diff --git a/src/logid/actions/gesture/ReleaseGesture.cpp b/src/logid/actions/gesture/ReleaseGesture.cpp index 2949965..e4e98ec 100644 --- a/src/logid/actions/gesture/ReleaseGesture.cpp +++ b/src/logid/actions/gesture/ReleaseGesture.cpp @@ -22,41 +22,38 @@ using namespace logid::actions; const char* ReleaseGesture::interface_name = "OnRelease"; -ReleaseGesture::ReleaseGesture(Device *device, config::ReleaseGesture& config, +ReleaseGesture::ReleaseGesture(Device* device, config::ReleaseGesture& config, const std::shared_ptr& parent) : - Gesture (device, parent, interface_name), _config (config) -{ - if(_config.action.has_value()) + Gesture(device, parent, interface_name), _config(config) { + if (_config.action.has_value()) _action = Action::makeAction(device, _config.action.value(), _node); } -void ReleaseGesture::press(bool init_threshold) -{ - _axis = init_threshold ? _config.threshold.value_or( - defaults::gesture_threshold) : 0; +void ReleaseGesture::press(bool init_threshold) { + if (init_threshold) { + _axis = (int32_t) (_config.threshold.value_or(defaults::gesture_threshold)); + } else { + _axis = 0; + } } -void ReleaseGesture::release(bool primary) -{ - if(metThreshold() && primary) { - if(_action) { +void ReleaseGesture::release(bool primary) { + if (metThreshold() && primary) { + if (_action) { _action->press(); _action->release(); } } } -void ReleaseGesture::move(int16_t axis) -{ +void ReleaseGesture::move(int16_t axis) { _axis += axis; } -bool ReleaseGesture::wheelCompatibility() const -{ +bool ReleaseGesture::wheelCompatibility() const { return false; } -bool ReleaseGesture::metThreshold() const -{ +bool ReleaseGesture::metThreshold() const { return _axis >= _config.threshold.value_or(defaults::gesture_threshold); } \ No newline at end of file diff --git a/src/logid/actions/gesture/ReleaseGesture.h b/src/logid/actions/gesture/ReleaseGesture.h index e0c9284..a9a111d 100644 --- a/src/logid/actions/gesture/ReleaseGesture.h +++ b/src/logid/actions/gesture/ReleaseGesture.h @@ -20,29 +20,29 @@ #include "Gesture.h" -namespace logid { -namespace actions -{ - class ReleaseGesture : public Gesture - { +namespace logid::actions { + class ReleaseGesture : public Gesture { public: static const char* interface_name; ReleaseGesture(Device* device, config::ReleaseGesture& config, const std::shared_ptr& parent); - virtual void press(bool init_threshold=false); - virtual void release(bool primary=false); - virtual void move(int16_t axis); + void press(bool init_threshold) final; - virtual bool wheelCompatibility() const; - virtual bool metThreshold() const; + void release(bool primary) final; + + void move(int16_t axis) final; + + [[nodiscard]] bool wheelCompatibility() const final; + + [[nodiscard]] bool metThreshold() const final; protected: - int16_t _axis; + int32_t _axis{}; std::shared_ptr _action; config::ReleaseGesture& _config; }; -}} +} #endif //LOGID_ACTION_RELEASEGESTURE_H diff --git a/src/logid/actions/gesture/ThresholdGesture.cpp b/src/logid/actions/gesture/ThresholdGesture.cpp index d29db07..7e14850 100644 --- a/src/logid/actions/gesture/ThresholdGesture.cpp +++ b/src/logid/actions/gesture/ThresholdGesture.cpp @@ -23,39 +23,34 @@ using namespace logid::actions; 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) { + Device* device, config::ThresholdGesture& config, + const std::shared_ptr& parent) : + Gesture(device, parent, interface_name), _config(config) { + if (config.action) { try { _action = Action::makeAction(device, config.action.value(), _node); - } catch(InvalidAction& e) { + } catch (InvalidAction& e) { logPrintf(WARN, "Mapping gesture to invalid action"); } } } -void ThresholdGesture::press(bool init_threshold) -{ - _axis = init_threshold ? - _config.threshold.value_or(defaults::gesture_threshold) : 0; +void ThresholdGesture::press(bool init_threshold) { + _axis = init_threshold ? (int32_t) _config.threshold.value_or(defaults::gesture_threshold) : 0; this->_executed = false; } -void ThresholdGesture::release(bool primary) -{ - (void)primary; // Suppress unused warning - +void ThresholdGesture::release(bool primary) { + (void) primary; // Suppress unused warning + this->_executed = false; } -void ThresholdGesture::move(int16_t axis) -{ +void ThresholdGesture::move(int16_t axis) { _axis += axis; - if(!this->_executed && metThreshold()) { - if(_action) { + if (!this->_executed && metThreshold()) { + if (_action) { _action->press(); _action->release(); } @@ -63,12 +58,10 @@ void ThresholdGesture::move(int16_t axis) } } -bool ThresholdGesture::metThreshold() const -{ +bool ThresholdGesture::metThreshold() const { return _axis >= _config.threshold.value_or(defaults::gesture_threshold); } -bool ThresholdGesture::wheelCompatibility() const -{ +bool ThresholdGesture::wheelCompatibility() const { return false; } \ No newline at end of file diff --git a/src/logid/actions/gesture/ThresholdGesture.h b/src/logid/actions/gesture/ThresholdGesture.h index be071ee..20317d2 100644 --- a/src/logid/actions/gesture/ThresholdGesture.h +++ b/src/logid/actions/gesture/ThresholdGesture.h @@ -20,33 +20,32 @@ #include "Gesture.h" -namespace logid { -namespace actions -{ - class ThresholdGesture : public Gesture - { +namespace logid::actions { + class ThresholdGesture : public Gesture { public: static const char* interface_name; ThresholdGesture(Device* device, config::ThresholdGesture& config, const std::shared_ptr& parent); - virtual void press(bool init_threshold=false); - virtual void release(bool primary=false); - virtual void move(int16_t axis); + void press(bool init_threshold) final; - virtual bool metThreshold() const; + void release(bool primary) final; - virtual bool wheelCompatibility() const; + void move(int16_t axis) final; + + [[nodiscard]] bool metThreshold() const final; + + [[nodiscard]] bool wheelCompatibility() const final; protected: - int16_t _axis; + int32_t _axis{}; std::shared_ptr _action; config::ThresholdGesture& _config; private: bool _executed = false; }; -}} +} #endif //LOGID_ACTION_THRESHOLDGESTURE_H diff --git a/src/logid/backend/Error.cpp b/src/logid/backend/Error.cpp index f15fc0e..cf9d2ea 100644 --- a/src/logid/backend/Error.cpp +++ b/src/logid/backend/Error.cpp @@ -18,7 +18,6 @@ #include "Error.h" -const char *logid::backend::TimeoutError::what() const noexcept -{ +const char* logid::backend::TimeoutError::what() const noexcept { return "Device timed out"; } diff --git a/src/logid/backend/Error.h b/src/logid/backend/Error.h index 8c391cf..fbf9f4c 100644 --- a/src/logid/backend/Error.h +++ b/src/logid/backend/Error.h @@ -21,15 +21,13 @@ #include -namespace logid { -namespace backend { -class TimeoutError: public std::exception -{ -public: - TimeoutError() = default; - const char* what() const noexcept override; -}; +namespace logid::backend { + class TimeoutError : public std::exception { + public: + TimeoutError() = default; -}} + [[nodiscard]] const char* what() const noexcept override; + }; +} #endif //LOGID_BACKEND_ERROR_H \ No newline at end of file diff --git a/src/logid/backend/dj/Error.cpp b/src/logid/backend/dj/Error.cpp index 4277cf6..26bce2c 100644 --- a/src/logid/backend/dj/Error.cpp +++ b/src/logid/backend/dj/Error.cpp @@ -20,23 +20,20 @@ using namespace logid::backend::dj; -Error::Error(uint8_t code) : _code (code) -{ +Error::Error(uint8_t code) : _code(code) { } -const char* Error::what() const noexcept -{ - switch(_code) { - case Unknown: - return "Unknown"; - case KeepAliveTimeout: - return "Keep-alive timeout"; - default: - return "Reserved"; +const char* Error::what() const noexcept { + switch (_code) { + case Unknown: + return "Unknown"; + case KeepAliveTimeout: + return "Keep-alive timeout"; + default: + return "Reserved"; } } -uint8_t Error::code() const noexcept -{ +uint8_t Error::code() const noexcept { return _code; } \ No newline at end of file diff --git a/src/logid/backend/dj/Error.h b/src/logid/backend/dj/Error.h index dc44067..a4e19e6 100644 --- a/src/logid/backend/dj/Error.h +++ b/src/logid/backend/dj/Error.h @@ -22,27 +22,23 @@ #include #include -namespace logid { -namespace backend { -namespace dj -{ - class Error : public std::exception - { +namespace logid::backend::dj { + class Error : public std::exception { public: - enum ErrorCode : uint8_t - { + enum ErrorCode : uint8_t { Unknown = 0x00, KeepAliveTimeout = 0x01 }; explicit Error(uint8_t code); - const char* what() const noexcept override; - uint8_t code() const noexcept; + [[nodiscard]] const char* what() const noexcept override; + + [[nodiscard]] uint8_t code() const noexcept; private: uint8_t _code; }; -}}} +} #endif //LOGID_BACKEND_DJ_ERROR_H \ No newline at end of file diff --git a/src/logid/backend/dj/Receiver.cpp b/src/logid/backend/dj/Receiver.cpp index fc19374..586bb98 100644 --- a/src/logid/backend/dj/Receiver.cpp +++ b/src/logid/backend/dj/Receiver.cpp @@ -24,74 +24,73 @@ using namespace logid::backend::dj; using namespace logid::backend; -InvalidReceiver::InvalidReceiver(Reason reason) : _reason (reason) -{ +InvalidReceiver::InvalidReceiver(Reason reason) : _reason(reason) { } -const char* InvalidReceiver::what() const noexcept -{ - switch(_reason) { - case NoDJReports: - return "No DJ reports"; - default: - return "Invalid receiver"; +const char* InvalidReceiver::what() const noexcept { + switch (_reason) { + case NoDJReports: + return "No DJ reports"; + default: + return "Invalid receiver"; } } -InvalidReceiver::Reason InvalidReceiver::code() const noexcept -{ +InvalidReceiver::Reason InvalidReceiver::code() const noexcept { return _reason; } Receiver::Receiver(std::string path, const std::shared_ptr& monitor, double timeout) : - _raw_device (std::make_shared(std::move(path), monitor)), - _hidpp10_device (_raw_device, hidpp::DefaultDevice, timeout) -{ - if(!supportsDjReports(_raw_device->reportDescriptor())) + _raw_device(std::make_shared(std::move(path), monitor)), + _hidpp10_device(_raw_device, hidpp::DefaultDevice, timeout) { + if (!supportsDjReports(_raw_device->reportDescriptor())) throw InvalidReceiver(InvalidReceiver::NoDJReports); // Pass all HID++ events on DefaultDevice to handleHidppEvent - _raw_hidpp_handler = _raw_device->addEventHandler({ - [](const std::vector& report)->bool { - return (report[hidpp::Offset::Type] == hidpp::Report::Type::Short || - report[hidpp::Offset::Type] == hidpp::Report::Type::Long); - }, - [this](const std::vector& report)->void { - hidpp::Report _report(report); - this->_handleHidppEvent(_report); - } - }); + _raw_hidpp_handler = _raw_device->addEventHandler( + { + [](const std::vector& report) -> bool { + return (report[hidpp::Offset::Type] == + hidpp::Report::Type::Short || + report[hidpp::Offset::Type] == + hidpp::Report::Type::Long); + }, + [this](const std::vector& report) -> void { + hidpp::Report _report(report); + this->_handleHidppEvent(_report); + } + }); // Pass all DJ events with device index to handleDjEvent - _raw_dj_handler = _raw_device->addEventHandler({ - [](const std::vector& report)->bool { - return (report[Offset::Type] == Report::Type::Short || - report[Offset::Type] == Report::Type::Long); - }, - [this](const std::vector& report)->void { - Report _report(report); - this->_handleDjEvent(_report); - } - }); + _raw_dj_handler = _raw_device->addEventHandler( + { + [](const std::vector& report) -> bool { + return (report[Offset::Type] == + Report::Type::Short || + report[Offset::Type] == + Report::Type::Long); + }, + [this](const std::vector& report) -> void { + Report _report(report); + this->_handleDjEvent(_report); + } + }); } -Receiver::~Receiver() -{ +Receiver::~Receiver() { _raw_device->removeEventHandler(_raw_dj_handler); _raw_device->removeEventHandler(_raw_hidpp_handler); } -void Receiver::enumerateDj() -{ - _sendDjRequest(hidpp::DefaultDevice, GetPairedDevices,{}); +void Receiver::enumerateDj() { + _sendDjRequest(hidpp::DefaultDevice, GetPairedDevices, {}); } -Receiver::NotificationFlags Receiver::getHidppNotifications() -{ +Receiver::NotificationFlags Receiver::getHidppNotifications() { auto response = _hidpp10_device.getRegister(EnableHidppNotifications, {}, - hidpp::ReportType::Short); + hidpp::ReportType::Short); NotificationFlags flags{}; flags.deviceBatteryStatus = response[0] & (1 << 4); @@ -101,41 +100,37 @@ Receiver::NotificationFlags Receiver::getHidppNotifications() return flags; } -void Receiver::enableHidppNotifications(NotificationFlags flags) -{ +void Receiver::enableHidppNotifications(NotificationFlags flags) { std::vector request(3); - if(flags.deviceBatteryStatus) + if (flags.deviceBatteryStatus) request[0] |= (1 << 4); - if(flags.receiverWirelessNotifications) + if (flags.receiverWirelessNotifications) request[1] |= 1; - if(flags.receiverSoftwarePresent) + if (flags.receiverSoftwarePresent) request[1] |= (1 << 3); _hidpp10_device.setRegister(EnableHidppNotifications, request, - hidpp::ReportType::Short); + hidpp::ReportType::Short); } -void Receiver::enumerateHidpp() -{ +void Receiver::enumerateHidpp() { /* This isn't in the documentation but this is how solaar does it * All I know is that when (p0 & 2), devices are enumerated */ _hidpp10_device.setRegister(ConnectionState, {2}, - hidpp::ReportType::Short); + hidpp::ReportType::Short); } ///TODO: Investigate usage -uint8_t Receiver::getConnectionState(hidpp::DeviceIndex index) -{ +uint8_t Receiver::getConnectionState(hidpp::DeviceIndex index) { auto response = _hidpp10_device.getRegister(ConnectionState, {index}, - hidpp::ReportType::Short); + hidpp::ReportType::Short); return response[0]; } -void Receiver::startPairing(uint8_t timeout) -{ +void Receiver::startPairing(uint8_t timeout) { ///TODO: Device number == Device index? std::vector request(3); @@ -144,11 +139,10 @@ void Receiver::startPairing(uint8_t timeout) request[2] = timeout; _hidpp10_device.setRegister(DevicePairing, request, - hidpp::ReportType::Short); + hidpp::ReportType::Short); } -void Receiver::stopPairing() -{ +void Receiver::stopPairing() { ///TODO: Device number == Device index? std::vector request(3); @@ -156,11 +150,10 @@ void Receiver::stopPairing() request[1] = hidpp::DefaultDevice; _hidpp10_device.setRegister(DevicePairing, request, - hidpp::ReportType::Short); + hidpp::ReportType::Short); } -void Receiver::disconnect(hidpp::DeviceIndex index) -{ +void Receiver::disconnect(hidpp::DeviceIndex index) { ///TODO: Device number == Device index? std::vector request(3); @@ -168,30 +161,28 @@ void Receiver::disconnect(hidpp::DeviceIndex index) request[1] = index; _hidpp10_device.setRegister(DevicePairing, request, - hidpp::ReportType::Short); + hidpp::ReportType::Short); } -std::map Receiver::getDeviceActivity() -{ +std::map Receiver::getDeviceActivity() { auto response = _hidpp10_device.getRegister(DeviceActivity, {}, - hidpp::ReportType::Long); + hidpp::ReportType::Long); std::map device_activity; - for(uint8_t i = hidpp::WirelessDevice1; i <= hidpp::WirelessDevice6; i++) + for (uint8_t i = hidpp::WirelessDevice1; i <= hidpp::WirelessDevice6; i++) device_activity[static_cast(i)] = response[i]; return device_activity; } struct Receiver::PairingInfo - Receiver::getPairingInfo(hidpp::DeviceIndex index) -{ +Receiver::getPairingInfo(hidpp::DeviceIndex index) { std::vector request(1); request[0] = index; request[0] += 0x1f; auto response = _hidpp10_device.getRegister(PairingInfo, request, - hidpp::ReportType::Long); + hidpp::ReportType::Long); struct PairingInfo info{}; info.destinationId = response[1]; @@ -204,26 +195,25 @@ struct Receiver::PairingInfo } struct Receiver::ExtendedPairingInfo - Receiver::getExtendedPairingInfo(hidpp::DeviceIndex index) -{ +Receiver::getExtendedPairingInfo(hidpp::DeviceIndex index) { std::vector request(1); request[0] = index; request[0] += 0x2f; auto response = _hidpp10_device.getRegister(PairingInfo, request, - hidpp::ReportType::Long); + hidpp::ReportType::Long); ExtendedPairingInfo info{}; info.serialNumber = 0; - for(uint8_t i = 0; i < 4; i++) - info.serialNumber |= (response[i+1] << 8*i); + for (uint8_t i = 0; i < 4; i++) + info.serialNumber |= (response[i + 1] << 8 * i); - for(uint8_t i = 0; i < 4; i++) + for (uint8_t i = 0; i < 4; i++) info.reportTypes[i] = response[i + 5]; uint8_t psl = response[8] & 0xf; - if(psl > 0xc) + if (psl > 0xc) info.powerSwitchLocation = PowerSwitchLocation::Reserved; else info.powerSwitchLocation = static_cast(psl); @@ -231,35 +221,32 @@ struct Receiver::ExtendedPairingInfo return info; } -std::string Receiver::getDeviceName(hidpp::DeviceIndex index) -{ +std::string Receiver::getDeviceName(hidpp::DeviceIndex index) { std::vector request(1); request[0] = index; request[0] += 0x3f; auto response = _hidpp10_device.getRegister(PairingInfo, request, - hidpp::ReportType::Long); + hidpp::ReportType::Long); uint8_t size = response[1]; assert(size <= 14); std::string name(size, ' '); - for(std::size_t i = 0; i < size; i++) - name[i] = response[i + 2]; + for (std::size_t i = 0; i < size; i++) + name[i] = (char) (response[i + 2]); return name; } hidpp::DeviceIndex Receiver::deviceDisconnectionEvent(const hidpp::Report& -report) -{ +report) { assert(report.subId() == DeviceDisconnection); return report.deviceIndex(); } hidpp::DeviceConnectionEvent Receiver::deviceConnectionEvent(const - hidpp::Report &report) -{ + hidpp::Report& report) { assert(report.subId() == DeviceConnection); hidpp::DeviceConnectionEvent event{}; @@ -269,75 +256,66 @@ hidpp::DeviceConnectionEvent Receiver::deviceConnectionEvent(const event.deviceType = static_cast( report.paramBegin()[0] & 0x0f); - event.softwarePresent = report.paramBegin()[0] & (1<<4); - event.encrypted = report.paramBegin()[0] & (1<<5); - event.linkEstablished = !(report.paramBegin()[0] & (1<<6)); - event.withPayload = report.paramBegin()[0] & (1<<7); + event.softwarePresent = report.paramBegin()[0] & (1 << 4); + event.encrypted = report.paramBegin()[0] & (1 << 5); + event.linkEstablished = !(report.paramBegin()[0] & (1 << 6)); + event.withPayload = report.paramBegin()[0] & (1 << 7); event.fromTimeoutCheck = false; - event.pid =(report.paramBegin()[2] << 8); + event.pid = (report.paramBegin()[2] << 8); event.pid |= report.paramBegin()[1]; return event; } -void Receiver::_handleDjEvent(Report& report) -{ - for(auto& handler : _dj_event_handlers) - if(handler.second->condition(report)) +void Receiver::_handleDjEvent(Report& report) { + for (auto& handler: _dj_event_handlers) + if (handler.second->condition(report)) handler.second->callback(report); } -void Receiver::_handleHidppEvent(hidpp::Report &report) -{ - for(auto& handler : _hidpp_event_handlers) - if(handler.second->condition(report)) +void Receiver::_handleHidppEvent(hidpp::Report& report) { + for (auto& handler: _hidpp_event_handlers) + if (handler.second->condition(report)) handler.second->callback(report); } void Receiver::addDjEventHandler(const std::string& nickname, - const std::shared_ptr& handler) -{ + const std::shared_ptr& handler) { assert(_dj_event_handlers.find(nickname) == _dj_event_handlers.end()); _dj_event_handlers.emplace(nickname, handler); } -void Receiver::removeDjEventHandler(const std::string &nickname) -{ +void Receiver::removeDjEventHandler(const std::string& nickname) { _dj_event_handlers.erase(nickname); } const std::map>& -Receiver::djEventHandlers() -{ +Receiver::djEventHandlers() { return _dj_event_handlers; } void Receiver::addHidppEventHandler(const std::string& nickname, - const std::shared_ptr& handler) -{ + const std::shared_ptr& handler) { assert(_hidpp_event_handlers.find(nickname) == _hidpp_event_handlers.end()); _hidpp_event_handlers.emplace(nickname, handler); } -void Receiver::removeHidppEventHandler(const std::string &nickname) -{ +void Receiver::removeHidppEventHandler(const std::string& nickname) { _hidpp_event_handlers.erase(nickname); } const std::map>& -Receiver::hidppEventHandlers() -{ +Receiver::hidppEventHandlers() { return _hidpp_event_handlers; } void Receiver::_sendDjRequest(hidpp::DeviceIndex index, uint8_t function, - const std::vector&& params) -{ + const std::vector&& params) { assert(params.size() <= LongParamLength); Report::Type type = params.size() <= ShortParamLength ? - ReportType::Short : ReportType::Long; + ReportType::Short : ReportType::Long; Report request(type, index, function); @@ -346,8 +324,7 @@ void Receiver::_sendDjRequest(hidpp::DeviceIndex index, uint8_t function, _raw_device->sendReport(request.rawData()); } -Receiver::ConnectionStatusEvent Receiver::connectionStatusEvent(Report& report) -{ +Receiver::ConnectionStatusEvent Receiver::connectionStatusEvent(Report& report) { assert(report.feature() == ConnectionStatus); ConnectionStatusEvent event{}; event.index = report.index(); @@ -355,7 +332,6 @@ Receiver::ConnectionStatusEvent Receiver::connectionStatusEvent(Report& report) return event; } -std::shared_ptr Receiver::rawDevice() const -{ +std::shared_ptr Receiver::rawDevice() const { return _raw_device; } \ No newline at end of file diff --git a/src/logid/backend/dj/Receiver.h b/src/logid/backend/dj/Receiver.h index 732c16b..09cd0fe 100644 --- a/src/logid/backend/dj/Receiver.h +++ b/src/logid/backend/dj/Receiver.h @@ -25,55 +25,51 @@ #include "../hidpp/Report.h" #include "../hidpp10/Device.h" -namespace logid { -namespace backend { -namespace dj -{ - struct EventHandler - { +namespace logid::backend::dj { + struct EventHandler { std::function condition; std::function callback; }; - class InvalidReceiver : public std::exception - { + class InvalidReceiver : public std::exception { public: - enum Reason - { + enum Reason { NoDJReports }; + explicit InvalidReceiver(Reason reason); - const char* what() const noexcept override; - Reason code() const noexcept; + + [[nodiscard]] const char* what() const noexcept override; + + [[nodiscard]] Reason code() const noexcept; + private: Reason _reason; }; - class Receiver final - { + class Receiver final { public: Receiver(std::string path, const std::shared_ptr& monitor, double timeout); + ~Receiver(); - enum DjEvents : uint8_t - { + enum DjEvents : uint8_t { DeviceDisconnection = 0x40, DeviceConnection = 0x41, ConnectionStatus = 0x42 }; - enum DjCommands : uint8_t - { - SwitchAndKeepAlive = 0x80, + enum DjCommands : uint8_t { + /* Kernel driver should handle this */ + SwitchAndKeepAlive [[maybe_unused]] = 0x80, GetPairedDevices = 0x81 }; void enumerateDj(); - struct ConnectionStatusEvent - { + struct ConnectionStatusEvent { hidpp::DeviceIndex index; bool linkLost; }; @@ -85,16 +81,14 @@ namespace dj * to have a separate hidpp10::Receiver class for these functions. */ - enum HidppEvents : uint8_t - { + enum HidppEvents : uint8_t { // These events are identical to their DJ counterparts // DeviceDisconnection = 0x40, // DeviceConnection = 0x41, LockingChange = 0x4a }; - enum HidppRegisters : uint8_t - { + enum HidppRegisters : uint8_t { EnableHidppNotifications = 0x00, ConnectionState = 0x02, DevicePairing = 0xb2, @@ -102,35 +96,36 @@ namespace dj PairingInfo = 0xb5 }; - struct NotificationFlags - { + struct NotificationFlags { bool deviceBatteryStatus; bool receiverWirelessNotifications; bool receiverSoftwarePresent; }; NotificationFlags getHidppNotifications(); + void enableHidppNotifications(NotificationFlags flags); void enumerateHidpp(); + uint8_t getConnectionState(hidpp::DeviceIndex index); void startPairing(uint8_t timeout = 0); + void stopPairing(); + void disconnect(hidpp::DeviceIndex index); std::map getDeviceActivity(); - struct PairingInfo - { + struct PairingInfo { uint8_t destinationId; uint8_t reportInterval; uint16_t pid; DeviceType::DeviceType deviceType; }; - enum class PowerSwitchLocation : uint8_t - { + enum class PowerSwitchLocation : uint8_t { Reserved = 0x0, Base = 0x1, TopCase = 0x2, @@ -146,42 +141,49 @@ namespace dj BottomEdge = 0xc }; - struct ExtendedPairingInfo - { + struct ExtendedPairingInfo { uint32_t serialNumber; uint8_t reportTypes[4]; PowerSwitchLocation powerSwitchLocation; }; struct PairingInfo getPairingInfo(hidpp::DeviceIndex index); + struct ExtendedPairingInfo getExtendedPairingInfo(hidpp::DeviceIndex - index); + index); std::string getDeviceName(hidpp::DeviceIndex index); static hidpp::DeviceIndex deviceDisconnectionEvent( const hidpp::Report& report); + static hidpp::DeviceConnectionEvent deviceConnectionEvent( const hidpp::Report& report); void addDjEventHandler(const std::string& nickname, - const std::shared_ptr& handler); + const std::shared_ptr& handler); + void removeDjEventHandler(const std::string& nickname); + const std::map>& djEventHandlers(); void addHidppEventHandler(const std::string& nickname, - const std::shared_ptr& handler); - void removeHidppEventHandler(const std::string& nickname); - const std::map>& - hidppEventHandlers(); + const std::shared_ptr& handler); + + void removeHidppEventHandler(const std::string& nickname); + + const std::map>& + hidppEventHandlers(); + + [[nodiscard]] std::shared_ptr rawDevice() const; - std::shared_ptr rawDevice() const; private: void _sendDjRequest(hidpp::DeviceIndex index, uint8_t function, - const std::vector&& params); + const std::vector&& params); void _handleDjEvent(dj::Report& report); + void _handleHidppEvent(hidpp::Report& report); raw::RawDevice::EvHandlerId _raw_hidpp_handler; @@ -197,20 +199,18 @@ namespace dj }; } -namespace hidpp -{ - struct DeviceConnectionEvent - { +namespace logid::backend::hidpp { + struct DeviceConnectionEvent { hidpp::DeviceIndex index; - uint16_t pid; + uint16_t pid{}; dj::DeviceType::DeviceType deviceType; - bool unifying; - bool softwarePresent; - bool encrypted; - bool linkEstablished; - bool withPayload; + bool unifying{}; + bool softwarePresent{}; + bool encrypted{}; + bool linkEstablished{}; + bool withPayload{}; bool fromTimeoutCheck = false; // Fake field }; -}}} +} #endif //LOGID_BACKEND_DJ_RECEIVER_H \ No newline at end of file diff --git a/src/logid/backend/dj/ReceiverMonitor.cpp b/src/logid/backend/dj/ReceiverMonitor.cpp index 96feea6..1cfd553 100644 --- a/src/logid/backend/dj/ReceiverMonitor.cpp +++ b/src/logid/backend/dj/ReceiverMonitor.cpp @@ -26,112 +26,111 @@ using namespace logid::backend::dj; ReceiverMonitor::ReceiverMonitor(std::string path, - std::shared_ptr monitor, - double timeout): - _receiver (std::make_shared( - std::move(path), std::move(monitor), timeout)) -{ - assert(_receiver->hidppEventHandlers().find("RECVMON") == - _receiver->hidppEventHandlers().end()); - assert(_receiver->djEventHandlers().find("RECVMON") == - _receiver->djEventHandlers().end()); + const std::shared_ptr& monitor, + double timeout) : + _receiver(std::make_shared( + std::move(path), monitor, timeout)) { + assert(!_receiver->hidppEventHandlers().contains(ev_handler_name)); + assert(!_receiver->djEventHandlers().contains(ev_handler_name)); Receiver::NotificationFlags notification_flags{ - true, - true, - true}; - _receiver->enableHidppNotifications(notification_flags); + true, + true, + true}; + _receiver->enableHidppNotifications(notification_flags); } -ReceiverMonitor::~ReceiverMonitor() -{ - _receiver->removeHidppEventHandler("RECVMON"); +ReceiverMonitor::~ReceiverMonitor() { + _receiver->removeHidppEventHandler(ev_handler_name); } -void ReceiverMonitor::ready() -{ - if(_receiver->hidppEventHandlers().find("RECVMON") == - _receiver->hidppEventHandlers().end()) { +void ReceiverMonitor::ready() { + if (!_receiver->hidppEventHandlers().contains(ev_handler_name)) { std::shared_ptr event_handler = std::make_shared(); - event_handler->condition = [](hidpp::Report &report) -> bool { + event_handler->condition = [](hidpp::Report& report) -> bool { return (report.subId() == Receiver::DeviceConnection || report.subId() == Receiver::DeviceDisconnection); }; - event_handler->callback = [this](hidpp::Report &report) -> void { + event_handler->callback = [this](hidpp::Report& report) -> void { /* Running in a new thread prevents deadlocks since the * receiver may be enumerating. */ spawn_task([this, report, - path= this->_receiver->rawDevice()->rawPath()]() { + path = this->_receiver->rawDevice()->rawPath()]() { if (report.subId() == Receiver::DeviceConnection) { try { this->addDevice(this->_receiver->deviceConnectionEvent (report)); - } catch(std::exception& e) { + } catch (std::exception& e) { logPrintf(ERROR, "Failed to add device %d to receiver " "on %s: %s", report.deviceIndex(), path.c_str(), e.what()); } - } - else if (report.subId() == Receiver::DeviceDisconnection) { + } else if (report.subId() == Receiver::DeviceDisconnection) { try { this->removeDevice(this->_receiver-> deviceDisconnectionEvent(report)); - } catch(std::exception& e) { + } catch (std::exception& e) { logPrintf(ERROR, "Failed to remove device %d from " "receiver on %s: %s", report.deviceIndex(), - path.c_str(), e.what()); + path.c_str(), e.what()); } } }); }; - _receiver->addHidppEventHandler("RECVMON", event_handler); + _receiver->addHidppEventHandler(ev_handler_name, event_handler); } enumerate(); } -void ReceiverMonitor::enumerate() -{ +void ReceiverMonitor::enumerate() { _receiver->enumerateHidpp(); } -void ReceiverMonitor::waitForDevice(hidpp::DeviceIndex index) -{ +void ReceiverMonitor::waitForDevice(hidpp::DeviceIndex index) { auto handler_id = std::make_shared(); - *handler_id = _receiver->rawDevice()->addEventHandler({ - [index](const std::vector& report)->bool { - return report[Offset::DeviceIndex] == index; - }, - [this, index, handler_id]( - [[maybe_unused]] const std::vector& report) { - hidpp::DeviceConnectionEvent event{}; - event.withPayload = false; - event.linkEstablished = true; - event.index = index; - event.fromTimeoutCheck = true; + *handler_id = _receiver->rawDevice()->addEventHandler( + { + [index](const std::vector& report) -> bool { + return report[Offset::DeviceIndex] == + index; + }, + [this, index, handler_id]( + [[maybe_unused]] const std::vector& report) { + hidpp::DeviceConnectionEvent event{}; + event.withPayload = false; + event.linkEstablished = true; + event.index = index; + event.fromTimeoutCheck = true; - spawn_task([this, event, handler_id]() { - assert(handler_id); - try { - _receiver->rawDevice()->removeEventHandler(*handler_id); - addDevice(event); - } catch(std::exception& e) { - logPrintf(ERROR, "Failed to add device %d to receiver " - "on %s: %s", event.index, - _receiver->rawDevice()->rawPath().c_str(), - e.what()); - } + spawn_task( + [this, event, handler_id]() { + assert(handler_id); + try { + _receiver->rawDevice()->removeEventHandler( + *handler_id); + addDevice( + event); + } catch ( + std::exception& e) { + logPrintf( + ERROR, + "Failed to add device %d to receiver " + "on %s: %s", + event.index, + _receiver->rawDevice()->rawPath().c_str(), + e.what()); + } + }); + } }); - } - }); } -std::shared_ptr ReceiverMonitor::receiver() const -{ +std::shared_ptr ReceiverMonitor::receiver() const { return _receiver; } \ No newline at end of file diff --git a/src/logid/backend/dj/ReceiverMonitor.h b/src/logid/backend/dj/ReceiverMonitor.h index 343d590..3acd377 100644 --- a/src/logid/backend/dj/ReceiverMonitor.h +++ b/src/logid/backend/dj/ReceiverMonitor.h @@ -24,38 +24,42 @@ #include "Receiver.h" #include "../hidpp/defs.h" -namespace logid { -namespace backend { -namespace dj -{ +namespace logid::backend::dj { // This class will run on the RawDevice thread, - class ReceiverMonitor - { + class ReceiverMonitor { public: ReceiverMonitor(std::string path, - std::shared_ptr monitor, + const std::shared_ptr& monitor, double timeout); + virtual ~ReceiverMonitor(); void enumerate(); + protected: void ready(); + virtual void addDevice(hidpp::DeviceConnectionEvent event) = 0; + virtual void removeDevice(hidpp::DeviceIndex index) = 0; void waitForDevice(hidpp::DeviceIndex index); // Internal methods for derived class void _pair(uint8_t timeout = 0); + void _stopPairing(); void _unpair(); [[nodiscard]] std::shared_ptr receiver() const; + private: + static constexpr const char* ev_handler_name = "receiver_monitor"; + std::shared_ptr _receiver; }; -}}} +} #endif //LOGID_BACKEND_DJ_RECEIVERMONITOR_H \ No newline at end of file diff --git a/src/logid/backend/dj/Report.cpp b/src/logid/backend/dj/Report.cpp index f2abac6..ec0b07a 100644 --- a/src/logid/backend/dj/Report.cpp +++ b/src/logid/backend/dj/Report.cpp @@ -66,41 +66,38 @@ static const std::array DJReportDesc2 = { 0xC0 // End Collection }; -bool dj::supportsDjReports(const std::vector& rdesc) -{ - auto it = std::search(rdesc.begin(), rdesc.end(), - DJReportDesc.begin(), DJReportDesc.end()); - if(it == rdesc.end()) - it = std::search(rdesc.begin(), rdesc.end(), +bool dj::supportsDjReports(const std::vector& report_desc) { + auto it = std::search(report_desc.begin(), report_desc.end(), + DJReportDesc.begin(), DJReportDesc.end()); + if (it == report_desc.end()) + it = std::search(report_desc.begin(), report_desc.end(), DJReportDesc2.begin(), DJReportDesc2.end()); - return it != rdesc.end(); + return it != report_desc.end(); } -Report::Report(const std::vector& data) : _data (data) -{ - switch(data[Offset::Type]) { - case ReportType::Short: - _data.resize(HeaderLength+ShortParamLength); - break; - case ReportType::Long: - _data.resize(HeaderLength+LongParamLength); - break; - default: - assert(false); +Report::Report(const std::vector& data) : _data(data) { + switch (data[Offset::Type]) { + case ReportType::Short: + _data.resize(HeaderLength + ShortParamLength); + break; + case ReportType::Long: + _data.resize(HeaderLength + LongParamLength); + break; + default: + assert(false); } } -Report::Report(Report::Type type, hidpp::DeviceIndex index, uint8_t feature) -{ - switch(type) { - case ReportType::Short: - _data.resize(HeaderLength+ShortParamLength); - break; - case ReportType::Long: - _data.resize(HeaderLength+LongParamLength); - break; - default: - assert(false); +Report::Report(Report::Type type, hidpp::DeviceIndex index, uint8_t feature) { + switch (type) { + case ReportType::Short: + _data.resize(HeaderLength + ShortParamLength); + break; + case ReportType::Long: + _data.resize(HeaderLength + LongParamLength); + break; + default: + assert(false); } _data[Offset::Type] = type; @@ -109,27 +106,22 @@ Report::Report(Report::Type type, hidpp::DeviceIndex index, uint8_t feature) } -Report::Type Report::type() const -{ +Report::Type Report::type() const { return static_cast(_data[Offset::Type]); } -hidpp::DeviceIndex Report::index() const -{ +hidpp::DeviceIndex Report::index() const { return static_cast(_data[Offset::DeviceIndex]); } -uint8_t Report::feature() const -{ +uint8_t Report::feature() const { return _data[Offset::Feature]; } -std::vector::iterator Report::paramBegin() -{ +std::vector::iterator Report::paramBegin() { return _data.begin() + Offset::Parameters; } -std::vector Report::rawData() const -{ +const std::vector& Report::rawData() const { return _data; } diff --git a/src/logid/backend/dj/Report.h b/src/logid/backend/dj/Report.h index 0a89d1d..11fd31a 100644 --- a/src/logid/backend/dj/Report.h +++ b/src/logid/backend/dj/Report.h @@ -24,30 +24,34 @@ #include "defs.h" #include "../hidpp/defs.h" -namespace logid::backend::dj -{ - namespace Offset - { +namespace logid::backend::dj { + namespace Offset { static constexpr uint8_t Type = 0; static constexpr uint8_t DeviceIndex = 1; static constexpr uint8_t Feature = 2; static constexpr uint8_t Parameters = 3; } - bool supportsDjReports(const std::vector& rdesc); - class Report - { + bool supportsDjReports(const std::vector& report_desc); + + class Report { public: typedef ReportType::ReportType Type; explicit Report(const std::vector& data); + Report(Type type, hidpp::DeviceIndex index, uint8_t feature); - Type type() const; - hidpp::DeviceIndex index() const; - uint8_t feature() const; + [[nodiscard]] Type type() const; + + [[nodiscard]] hidpp::DeviceIndex index() const; + + [[nodiscard]] uint8_t feature() const; + std::vector::iterator paramBegin(); - std::vector rawData() const; + + [[nodiscard]] const std::vector& rawData() const; + private: std::vector _data; }; diff --git a/src/logid/backend/dj/defs.h b/src/logid/backend/dj/defs.h index d527d9b..5030a1f 100644 --- a/src/logid/backend/dj/defs.h +++ b/src/logid/backend/dj/defs.h @@ -21,23 +21,16 @@ #include -namespace logid { -namespace backend { -namespace dj -{ - namespace ReportType - { - enum ReportType : uint8_t - { +namespace logid::backend::dj { + namespace ReportType { + enum ReportType : uint8_t { Short = 0x20, Long = 0x21 }; } - namespace DeviceType - { - enum DeviceType : uint8_t - { + namespace DeviceType { + enum DeviceType : uint8_t { Unknown = 0x00, Keyboard = 0x01, Mouse = 0x02, @@ -49,11 +42,12 @@ namespace dj }; } + [[maybe_unused]] static constexpr uint8_t ErrorFeature = 0x7f; static constexpr std::size_t HeaderLength = 3; static constexpr std::size_t ShortParamLength = 12; static constexpr std::size_t LongParamLength = 29; -}}} +} #endif //LOGID_BACKEND_DJ_DEFS_H \ No newline at end of file diff --git a/src/logid/backend/hidpp/Device.cpp b/src/logid/backend/hidpp/Device.cpp index 46822e6..8e4d6ce 100644 --- a/src/logid/backend/hidpp/Device.cpp +++ b/src/logid/backend/hidpp/Device.cpp @@ -22,7 +22,6 @@ #include "Report.h" #include "../hidpp20/features/Root.h" #include "../hidpp20/features/DeviceName.h" -#include "../hidpp20/Error.h" #include "../hidpp10/Error.h" #include "../Error.h" #include "../dj/Receiver.h" @@ -32,122 +31,115 @@ using namespace logid::backend::hidpp; using namespace std::chrono; -const char* Device::InvalidDevice::what() const noexcept -{ - switch(_reason) { - case NoHIDPPReport: - return "Invalid HID++ device"; - case InvalidRawDevice: - return "Invalid raw device"; - case Asleep: - return "Device asleep"; - case VirtualNode: - return "Virtual device"; - default: - return "Invalid device"; +const char* Device::InvalidDevice::what() const noexcept { + switch (_reason) { + case NoHIDPPReport: + return "Invalid HID++ device"; + case InvalidRawDevice: + return "Invalid raw device"; + case Asleep: + return "Device asleep"; + case VirtualNode: + return "Virtual device"; + default: + return "Invalid device"; } } -Device::InvalidDevice::Reason Device::InvalidDevice::code() const noexcept -{ +Device::InvalidDevice::Reason Device::InvalidDevice::code() const noexcept { return _reason; } Device::Device(const std::string& path, DeviceIndex index, - std::shared_ptr monitor, double timeout): - io_timeout (duration_cast( - duration(timeout))), - _raw_device (std::make_shared(path, std::move(monitor))), - _receiver (nullptr), _path (path), _index (index) -{ + std::shared_ptr monitor, double timeout) : + io_timeout(duration_cast( + duration(timeout))), + _raw_device(std::make_shared(path, std::move(monitor))), + _receiver(nullptr), _path(path), _index(index) { _init(); } Device::Device(std::shared_ptr raw_device, DeviceIndex index, double timeout) : - io_timeout (duration_cast( + io_timeout(duration_cast( duration(timeout))), - _raw_device (std::move(raw_device)), _receiver (nullptr), - _path (_raw_device->rawPath()), _index (index) -{ + _raw_device(std::move(raw_device)), _receiver(nullptr), + _path(_raw_device->rawPath()), _index(index) { _init(); } -Device::Device(std::shared_ptr receiver, - hidpp::DeviceConnectionEvent event, double timeout) : - io_timeout (duration_cast( +Device::Device(const std::shared_ptr& receiver, + hidpp::DeviceConnectionEvent event, double timeout) : + io_timeout(duration_cast( duration(timeout))), - _raw_device (receiver->rawDevice()), _receiver (receiver), - _path (receiver->rawDevice()->rawPath()), _index (event.index) -{ + _raw_device(receiver->rawDevice()), _receiver(receiver), + _path(receiver->rawDevice()->rawPath()), _index(event.index) { // Device will throw an error soon, just do it now - if(!event.linkEstablished) + if (!event.linkEstablished) throw InvalidDevice(InvalidDevice::Asleep); - if(!event.fromTimeoutCheck) + if (!event.fromTimeoutCheck) _pid = event.pid; else _pid = receiver->getPairingInfo(_index).pid; _init(); } -Device::Device(std::shared_ptr receiver, - DeviceIndex index, double timeout) : - io_timeout (duration_cast( +Device::Device(const std::shared_ptr& receiver, + DeviceIndex index, double timeout) : + io_timeout(duration_cast( duration(timeout))), - _raw_device (receiver->rawDevice()), - _receiver (receiver), _path (receiver->rawDevice()->rawPath()), - _index (index) -{ + _raw_device(receiver->rawDevice()), + _receiver(receiver), _path(receiver->rawDevice()->rawPath()), + _index(index) { _pid = receiver->getPairingInfo(_index).pid; _init(); } -std::string Device::devicePath() const -{ +const std::string& Device::devicePath() const { return _path; } -DeviceIndex Device::deviceIndex() const -{ +DeviceIndex Device::deviceIndex() const { return _index; } -std::tuple Device::version() const -{ +const std::tuple& Device::version() const { return _version; } -void Device::_init() -{ +void Device::_init() { supported_reports = getSupportedReports(_raw_device->reportDescriptor()); - if(!supported_reports) + if (!supported_reports) throw InvalidDevice(InvalidDevice::NoHIDPPReport); /* hid_logitech_dj creates virtual /dev/hidraw nodes for receiver * devices. We should ignore these devices. */ - if(_index == hidpp::DefaultDevice) { - _raw_handler = _raw_device->addEventHandler({ - [index=this->_index](const std::vector& report)->bool { - return (report[Offset::Type] == Report::Type::Short || - report[Offset::Type] == Report::Type::Long); - }, [this](const std::vector& report)->void { - Report _report(report); - this->handleEvent(_report); - } }); + if (_index == hidpp::DefaultDevice) { + _raw_handler = _raw_device->addEventHandler( + { + []( + const std::vector& report) -> bool { + return (report[Offset::Type] == Report::Type::Short || + report[Offset::Type] == Report::Type::Long); + }, + [this](const std::vector& report) -> void { + Report _report(report); + this->handleEvent(_report); + }}); try { auto rsp = sendReport( {ReportType::Short, _index, hidpp20::FeatureID::ROOT, hidpp20::Root::Ping, LOGID_HIDPP_SOFTWARE_ID}); - if(rsp.deviceIndex() != _index) { + if (rsp.deviceIndex() != _index) { throw InvalidDevice(InvalidDevice::VirtualNode); } - } catch(hidpp10::Error& e) { + } catch (hidpp10::Error& e) { // Ignore - } catch(std::exception& e) { + } catch (std::exception& e) { _raw_device->removeEventHandler(_raw_handler); throw; } @@ -155,90 +147,92 @@ void Device::_init() _raw_device->removeEventHandler(_raw_handler); } - _raw_handler = _raw_device->addEventHandler({ - [index=this->_index](const std::vector& report)->bool { - return (report[Offset::Type] == Report::Type::Short || - report[Offset::Type] == Report::Type::Long) && - (report[Offset::DeviceIndex] == index); - }, [this](const std::vector& report)->void { - Report _report(report); - this->handleEvent(_report); - } }); + _raw_handler = _raw_device->addEventHandler( + { + + [index = this->_index]( + const std::vector& report) -> bool { + return (report[Offset::Type] == + Report::Type::Short || + report[Offset::Type] == + Report::Type::Long) && + (report[Offset::DeviceIndex] == + index); + }, + [this](const std::vector& report) -> void { + Report _report(report); + this->handleEvent(_report); + }}); try { try { - hidpp20::EssentialRoot root(this); + hidpp20::Root root(this); _version = root.getVersion(); - } catch(hidpp10::Error &e) { + } catch (hidpp10::Error& e) { // Valid HID++ 1.0 devices should send an InvalidSubID error - if(e.code() != hidpp10::Error::InvalidSubID) + if (e.code() != hidpp10::Error::InvalidSubID) throw; // HID++ 2.0 is not supported, assume HID++ 1.0 _version = std::make_tuple(1, 0); } - if(!_receiver) { + if (!_receiver) { _pid = _raw_device->productId(); - if(std::get<0>(_version) >= 2) { + if (std::get<0>(_version) >= 2) { try { - hidpp20::EssentialDeviceName deviceName(this); + hidpp20::DeviceName deviceName(this); _name = deviceName.getName(); - } catch(hidpp20::UnsupportedFeature &e) { + } catch (hidpp20::UnsupportedFeature& e) { _name = _raw_device->name(); } } else { _name = _raw_device->name(); } } else { - if(std::get<0>(_version) >= 2) { + if (std::get<0>(_version) >= 2) { try { - hidpp20::EssentialDeviceName deviceName(this); + hidpp20::DeviceName deviceName(this); _name = deviceName.getName(); - } catch(hidpp20::UnsupportedFeature &e) { + } catch (hidpp20::UnsupportedFeature& e) { _name = _receiver->getDeviceName(_index); } } else { _name = _receiver->getDeviceName(_index); } } - } catch(std::exception& e) { + } catch (std::exception& e) { _raw_device->removeEventHandler(_raw_handler); throw; } } -Device::~Device() -{ +Device::~Device() { _raw_device->removeEventHandler(_raw_handler); } -Device::EvHandlerId Device::addEventHandler(EventHandler handler) -{ +Device::EvHandlerId Device::addEventHandler(EventHandler handler) { std::lock_guard lock(_event_handler_lock); _event_handlers.emplace_front(std::move(handler)); return _event_handlers.cbegin(); } -void Device::removeEventHandler(EvHandlerId id) -{ +void Device::removeEventHandler(EvHandlerId id) { std::lock_guard lock(_event_handler_lock); _event_handlers.erase(id); } -void Device::handleEvent(Report& report) -{ - if(responseReport(report)) +void Device::handleEvent(Report& report) { + if (responseReport(report)) return; std::lock_guard lock(_event_handler_lock); - for(auto& handler : _event_handlers) - if(handler.condition(report)) + for (auto& handler: _event_handlers) + if (handler.condition(report)) handler.callback(report); } -Report Device::sendReport(const Report &report) -{ +Report Device::sendReport(const Report& report) { std::lock_guard lock(_send_lock); { std::lock_guard sl(_slot_lock); @@ -247,39 +241,38 @@ Report Device::sendReport(const Report &report) sendReportNoResponse(report); std::unique_lock wait(_resp_wait_lock); bool valid = _resp_cv.wait_for( - wait, io_timeout, [this](){ + wait, io_timeout, [this]() { std::lock_guard sl(_slot_lock); return _report_slot.has_value(); }); - if(!valid) + if (!valid) throw TimeoutError(); std::lock_guard sl(_slot_lock); { Report::Hidpp10Error error{}; - if(_report_slot.value().isError10(&error)) + if (_report_slot.value().isError10(&error)) throw hidpp10::Error(error.error_code); } { Report::Hidpp20Error error{}; - if(_report_slot.value().isError20(&error)) + if (_report_slot.value().isError20(&error)) throw hidpp20::Error(error.error_code); } return _report_slot.value(); } -bool Device::responseReport(const Report &report) -{ - if(_send_lock.try_lock()) { +bool Device::responseReport(const Report& report) { + if (_send_lock.try_lock()) { _send_lock.unlock(); return false; } // Basic check to see if the report is a response - if( (report.swId() != LOGID_HIDPP_SOFTWARE_ID) - && report.subId() < 0x80) + if ((report.swId() != LOGID_HIDPP_SOFTWARE_ID) + && report.subId() < 0x80) return false; std::lock_guard lock(_slot_lock); @@ -288,18 +281,15 @@ bool Device::responseReport(const Report &report) return true; } -void Device::sendReportNoResponse(Report report) -{ +void Device::sendReportNoResponse(Report report) { reportFixup(report); _raw_device->sendReport(report.rawReport()); } -void Device::reportFixup(Report& report) -{ - switch(report.type()) - { +void Device::reportFixup(Report& report) const { + switch (report.type()) { case Report::Type::Short: - if(!(supported_reports & HIDPP_REPORT_SHORT_SUPPORTED)) + if (!(supported_reports & HIDPP_REPORT_SHORT_SUPPORTED)) report.setType(Report::Type::Long); break; case Report::Type::Long: @@ -308,12 +298,10 @@ void Device::reportFixup(Report& report) } } -std::string Device::name() const -{ +const std::string& Device::name() const { return _name; } -uint16_t Device::pid() const -{ +uint16_t Device::pid() const { return _pid; } diff --git a/src/logid/backend/hidpp/Device.h b/src/logid/backend/hidpp/Device.h index d8f1b6f..bf978f3 100644 --- a/src/logid/backend/hidpp/Device.h +++ b/src/logid/backend/hidpp/Device.h @@ -28,72 +28,80 @@ #include "Report.h" #include "defs.h" -namespace logid { -namespace backend { -namespace dj -{ +namespace logid::backend::dj { // Need to define here for a constructor class Receiver; } -namespace hidpp -{ + +namespace logid::backend::hidpp { struct DeviceConnectionEvent; - struct EventHandler - { + struct EventHandler { std::function condition; std::function callback; }; - class Device - { + + class Device { public: typedef std::list::const_iterator EvHandlerId; - class InvalidDevice : std::exception - { + class InvalidDevice : std::exception { public: - enum Reason - { + enum Reason { NoHIDPPReport, InvalidRawDevice, Asleep, VirtualNode }; - InvalidDevice(Reason reason) : _reason (reason) {} - virtual const char* what() const noexcept; - virtual Reason code() const noexcept; + + explicit InvalidDevice(Reason reason) : _reason(reason) {} + + [[nodiscard]] const char* what() const noexcept override; + + [[nodiscard]] virtual Reason code() const noexcept; + private: Reason _reason; }; Device(const std::string& path, DeviceIndex index, std::shared_ptr monitor, double timeout); + Device(std::shared_ptr raw_device, DeviceIndex index, double timeout); - Device(std::shared_ptr receiver, + + Device(const std::shared_ptr& receiver, hidpp::DeviceConnectionEvent event, double timeout); - Device(std::shared_ptr receiver, + + Device(const std::shared_ptr& receiver, DeviceIndex index, double timeout); + virtual ~Device(); - std::string devicePath() const; - DeviceIndex deviceIndex() const; - std::tuple version() const; + [[nodiscard]] const std::string& devicePath() const; - std::string name() const; - uint16_t pid() const; + [[nodiscard]] DeviceIndex deviceIndex() const; + + [[nodiscard]] const std::tuple& version() const; + + [[nodiscard]] const std::string& name() const; + + [[nodiscard]] uint16_t pid() const; EvHandlerId addEventHandler(EventHandler handler); + void removeEventHandler(EvHandlerId id); virtual Report sendReport(const Report& report); + void sendReportNoResponse(Report report); void handleEvent(Report& report); + protected: // Returns whether the report is a response virtual bool responseReport(const Report& report); - void reportFixup(Report& report); + void reportFixup(Report& report) const; const std::chrono::milliseconds io_timeout; uint8_t supported_reports; @@ -119,6 +127,6 @@ namespace hidpp std::mutex _event_handler_lock; std::list _event_handlers; }; -} } } +} #endif //LOGID_BACKEND_HIDPP_DEVICE_H \ No newline at end of file diff --git a/src/logid/backend/hidpp/Report.cpp b/src/logid/backend/hidpp/Report.cpp index 83bc19c..d46a1ce 100644 --- a/src/logid/backend/hidpp/Report.cpp +++ b/src/logid/backend/hidpp/Report.cpp @@ -28,107 +28,103 @@ using namespace logid::backend; /* Report descriptors were sourced from cvuchener/hidpp */ static const std::array ShortReportDesc = { - 0xA1, 0x01, // Collection (Application) - 0x85, 0x10, // Report ID (16) - 0x75, 0x08, // Report Size (8) - 0x95, 0x06, // Report Count (6) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x09, 0x01, // Usage (0001 - Vendor) - 0x81, 0x00, // Input (Data, Array, Absolute) - 0x09, 0x01, // Usage (0001 - Vendor) - 0x91, 0x00, // Output (Data, Array, Absolute) - 0xC0 // End Collection + 0xA1, 0x01, // Collection (Application) + 0x85, 0x10, // Report ID (16) + 0x75, 0x08, // Report Size (8) + 0x95, 0x06, // Report Count (6) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x09, 0x01, // Usage (0001 - Vendor) + 0x81, 0x00, // Input (Data, Array, Absolute) + 0x09, 0x01, // Usage (0001 - Vendor) + 0x91, 0x00, // Output (Data, Array, Absolute) + 0xC0 // End Collection }; static const std::array LongReportDesc = { - 0xA1, 0x01, // Collection (Application) - 0x85, 0x11, // Report ID (17) - 0x75, 0x08, // Report Size (8) - 0x95, 0x13, // Report Count (19) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x09, 0x02, // Usage (0002 - Vendor) - 0x81, 0x00, // Input (Data, Array, Absolute) - 0x09, 0x02, // Usage (0002 - Vendor) - 0x91, 0x00, // Output (Data, Array, Absolute) - 0xC0 // End Collection + 0xA1, 0x01, // Collection (Application) + 0x85, 0x11, // Report ID (17) + 0x75, 0x08, // Report Size (8) + 0x95, 0x13, // Report Count (19) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x09, 0x02, // Usage (0002 - Vendor) + 0x81, 0x00, // Input (Data, Array, Absolute) + 0x09, 0x02, // Usage (0002 - Vendor) + 0x91, 0x00, // Output (Data, Array, Absolute) + 0xC0 // End Collection }; /* Alternative versions from the G602 */ static const std::array ShortReportDesc2 = { - 0xA1, 0x01, // Collection (Application) - 0x85, 0x10, // Report ID (16) - 0x95, 0x06, // Report Count (6) - 0x75, 0x08, // Report Size (8) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x09, 0x01, // Usage (0001 - Vendor) - 0x81, 0x00, // Input (Data, Array, Absolute) - 0x09, 0x01, // Usage (0001 - Vendor) - 0x91, 0x00, // Output (Data, Array, Absolute) - 0xC0 // End Collection + 0xA1, 0x01, // Collection (Application) + 0x85, 0x10, // Report ID (16) + 0x95, 0x06, // Report Count (6) + 0x75, 0x08, // Report Size (8) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x09, 0x01, // Usage (0001 - Vendor) + 0x81, 0x00, // Input (Data, Array, Absolute) + 0x09, 0x01, // Usage (0001 - Vendor) + 0x91, 0x00, // Output (Data, Array, Absolute) + 0xC0 // End Collection }; static const std::array LongReportDesc2 = { - 0xA1, 0x01, // Collection (Application) - 0x85, 0x11, // Report ID (17) - 0x95, 0x13, // Report Count (19) - 0x75, 0x08, // Report Size (8) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x09, 0x02, // Usage (0002 - Vendor) - 0x81, 0x00, // Input (Data, Array, Absolute) - 0x09, 0x02, // Usage (0002 - Vendor) - 0x91, 0x00, // Output (Data, Array, Absolute) - 0xC0 // End Collection + 0xA1, 0x01, // Collection (Application) + 0x85, 0x11, // Report ID (17) + 0x95, 0x13, // Report Count (19) + 0x75, 0x08, // Report Size (8) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x09, 0x02, // Usage (0002 - Vendor) + 0x81, 0x00, // Input (Data, Array, Absolute) + 0x09, 0x02, // Usage (0002 - Vendor) + 0x91, 0x00, // Output (Data, Array, Absolute) + 0xC0 // End Collection }; -uint8_t hidpp::getSupportedReports(const std::vector& rdesc) -{ +uint8_t hidpp::getSupportedReports(const std::vector& report_desc) { uint8_t ret = 0; - auto it = std::search(rdesc.begin(), rdesc.end(), - ShortReportDesc.begin(), ShortReportDesc.end()); - if(it == rdesc.end()) - it = std::search(rdesc.begin(), rdesc.end(), - ShortReportDesc2.begin(), ShortReportDesc2.end()); - if(it != rdesc.end()) + auto it = std::search(report_desc.begin(), report_desc.end(), + ShortReportDesc.begin(), ShortReportDesc.end()); + if (it == report_desc.end()) + it = std::search(report_desc.begin(), report_desc.end(), + ShortReportDesc2.begin(), ShortReportDesc2.end()); + if (it != report_desc.end()) ret |= HIDPP_REPORT_SHORT_SUPPORTED; - it = std::search(rdesc.begin(), rdesc.end(), - LongReportDesc.begin(), LongReportDesc.end()); - if(it == rdesc.end()) - it = std::search(rdesc.begin(), rdesc.end(), - LongReportDesc2.begin(), LongReportDesc2.end()); - if(it != rdesc.end()) + it = std::search(report_desc.begin(), report_desc.end(), + LongReportDesc.begin(), LongReportDesc.end()); + if (it == report_desc.end()) + it = std::search(report_desc.begin(), report_desc.end(), + LongReportDesc2.begin(), LongReportDesc2.end()); + if (it != report_desc.end()) ret |= HIDPP_REPORT_LONG_SUPPORTED; return ret; } -const char *Report::InvalidReportID::what() const noexcept -{ +const char* Report::InvalidReportID::what() const noexcept { return "Invalid report ID"; } -const char *Report::InvalidReportLength::what() const noexcept -{ +const char* Report::InvalidReportLength::what() const noexcept { return "Invalid report length"; } Report::Report(Report::Type type, DeviceIndex device_index, - uint8_t sub_id, uint8_t address) -{ - switch(type) { - case Type::Short: - _data.resize(HeaderLength + ShortParamLength); - break; - case Type::Long: - _data.resize(HeaderLength + LongParamLength); - break; - default: - throw InvalidReportID(); + uint8_t sub_id, uint8_t address) { + switch (type) { + case Type::Short: + _data.resize(HeaderLength + ShortParamLength); + break; + case Type::Long: + _data.resize(HeaderLength + LongParamLength); + break; + default: + throw InvalidReportID(); } _data[Offset::Type] = type; @@ -138,163 +134,141 @@ Report::Report(Report::Type type, DeviceIndex device_index, } Report::Report(Report::Type type, DeviceIndex device_index, - uint8_t feature_index, uint8_t function, uint8_t sw_id) -{ + uint8_t feature_index, uint8_t function, uint8_t sw_id) { assert(function <= 0x0f); assert(sw_id <= 0x0f); - switch(type) { - case Type::Short: - _data.resize(HeaderLength + ShortParamLength); - break; - case Type::Long: - _data.resize(HeaderLength + LongParamLength); - break; - default: - throw InvalidReportID(); + switch (type) { + case Type::Short: + _data.resize(HeaderLength + ShortParamLength); + break; + case Type::Long: + _data.resize(HeaderLength + LongParamLength); + break; + default: + throw InvalidReportID(); } _data[Offset::Type] = type; _data[Offset::DeviceIndex] = device_index; _data[Offset::Feature] = feature_index; _data[Offset::Function] = (function & 0x0f) << 4 | - (sw_id & 0x0f); + (sw_id & 0x0f); } Report::Report(const std::vector& data) : - _data (data) -{ + _data(data) { _data.resize(HeaderLength + LongParamLength); // Truncating data is entirely valid here. - switch(_data[Offset::Type]) { - case Type::Short: - _data.resize(HeaderLength + ShortParamLength); - break; - case Type::Long: - _data.resize(HeaderLength + LongParamLength); - break; - default: - throw InvalidReportID(); + switch (_data[Offset::Type]) { + case Type::Short: + _data.resize(HeaderLength + ShortParamLength); + break; + case Type::Long: + _data.resize(HeaderLength + LongParamLength); + break; + default: + throw InvalidReportID(); } } -Report::Type Report::type() const -{ +Report::Type Report::type() const { return static_cast(_data[Offset::Type]); } -void Report::setType(Report::Type type) -{ - switch(type) { - case Type::Short: - _data.resize(HeaderLength + ShortParamLength); - break; - case Type::Long: - _data.resize(HeaderLength + LongParamLength); - break; - default: - throw InvalidReportID(); +void Report::setType(Report::Type type) { + switch (type) { + case Type::Short: + _data.resize(HeaderLength + ShortParamLength); + break; + case Type::Long: + _data.resize(HeaderLength + LongParamLength); + break; + default: + throw InvalidReportID(); } _data[Offset::Type] = type; } -hidpp::DeviceIndex Report::deviceIndex() const -{ +hidpp::DeviceIndex Report::deviceIndex() const { return static_cast(_data[Offset::DeviceIndex]); } -void Report::setDeviceIndex(hidpp::DeviceIndex index) -{ +[[maybe_unused]] void Report::setDeviceIndex(hidpp::DeviceIndex index) { _data[Offset::DeviceIndex] = index; } -uint8_t Report::feature() const -{ +uint8_t Report::feature() const { return _data[Offset::Feature]; } -void Report::setFeature(uint8_t feature) -{ +[[maybe_unused]] void Report::setFeature(uint8_t feature) { _data[Offset::Parameters] = feature; } -uint8_t Report::subId() const -{ +uint8_t Report::subId() const { return _data[Offset::SubID]; } -void Report::setSubId(uint8_t sub_id) -{ +[[maybe_unused]] void Report::setSubId(uint8_t sub_id) { _data[Offset::SubID] = sub_id; } -uint8_t Report::function() const -{ +uint8_t Report::function() const { return (_data[Offset::Function] >> 4) & 0x0f; } -void Report::setFunction(uint8_t function) -{ +[[maybe_unused]] void Report::setFunction(uint8_t function) { _data[Offset::Function] &= 0x0f; _data[Offset::Function] |= (function & 0x0f) << 4; } -uint8_t Report::swId() const -{ +uint8_t Report::swId() const { return _data[Offset::Function] & 0x0f; } -void Report::setSwId(uint8_t sw_id) -{ +void Report::setSwId(uint8_t sw_id) { _data[Offset::Function] &= 0xf0; _data[Offset::Function] |= sw_id & 0x0f; } -uint8_t Report::address() const -{ +uint8_t Report::address() const { return _data[Offset::Address]; } -void Report::setAddress(uint8_t address) -{ +[[maybe_unused]] void Report::setAddress(uint8_t address) { _data[Offset::Address] = address; } -std::vector::iterator Report::paramBegin() -{ +std::vector::iterator Report::paramBegin() { return _data.begin() + Offset::Parameters; } -std::vector::iterator Report::paramEnd() -{ +std::vector::iterator Report::paramEnd() { return _data.end(); } -std::vector::const_iterator Report::paramBegin() const -{ +std::vector::const_iterator Report::paramBegin() const { return _data.begin() + Offset::Parameters; } -std::vector::const_iterator Report::paramEnd() const -{ +std::vector::const_iterator Report::paramEnd() const { return _data.end(); } -void Report::setParams(const std::vector& _params) -{ - assert(_params.size() <= _data.size()-HeaderLength); +void Report::setParams(const std::vector& _params) { + assert(_params.size() <= _data.size() - HeaderLength); - for(std::size_t i = 0; i < _params.size(); i++) + for (std::size_t i = 0; i < _params.size(); i++) _data[Offset::Parameters + i] = _params[i]; } -bool Report::isError10(Report::Hidpp10Error *error) const -{ +bool Report::isError10(Report::Hidpp10Error* error) const { assert(error != nullptr); - if(_data[Offset::Type] != Type::Short || + if (_data[Offset::Type] != Type::Short || _data[Offset::SubID] != hidpp10::ErrorID) return false; @@ -305,18 +279,21 @@ bool Report::isError10(Report::Hidpp10Error *error) const return true; } -bool Report::isError20(Report::Hidpp20Error* error) const -{ +bool Report::isError20(Report::Hidpp20Error* error) const { assert(error != nullptr); - if(_data[Offset::Type] != Type::Long || + if (_data[Offset::Type] != Type::Long || _data[Offset::Feature] != hidpp20::ErrorID) return false; - error->feature_index= _data[3]; + error->feature_index = _data[3]; error->function = (_data[4] >> 4) & 0x0f; error->software_id = _data[4] & 0x0f; error->error_code = _data[5]; return true; -} \ No newline at end of file +} + +const std::vector& Report::rawReport() const { + return _data; +} diff --git a/src/logid/backend/hidpp/Report.h b/src/logid/backend/hidpp/Report.h index 41b4839..6bb70af 100644 --- a/src/logid/backend/hidpp/Report.h +++ b/src/logid/backend/hidpp/Report.h @@ -25,17 +25,13 @@ /* Some devices only support a subset of these reports */ #define HIDPP_REPORT_SHORT_SUPPORTED 1U -#define HIDPP_REPORT_LONG_SUPPORTED 1U<<1U +#define HIDPP_REPORT_LONG_SUPPORTED 1U<<1U /* Very long reports exist, however they have not been encountered so far */ -namespace logid { -namespace backend { -namespace hidpp -{ - uint8_t getSupportedReports(const std::vector& rdesc); +namespace logid::backend::hidpp { + uint8_t getSupportedReports(const std::vector& report_desc); - namespace Offset - { + namespace Offset { static constexpr uint8_t Type = 0; static constexpr uint8_t DeviceIndex = 1; static constexpr uint8_t SubID = 2; @@ -45,23 +41,22 @@ namespace hidpp static constexpr uint8_t Parameters = 4; } - class Report - { + class Report { public: typedef ReportType::ReportType Type; - class InvalidReportID: public std::exception - { + class InvalidReportID : public std::exception { public: InvalidReportID() = default; - const char* what() const noexcept override; + + [[nodiscard]] const char* what() const noexcept override; }; - class InvalidReportLength: public std::exception - { + class InvalidReportLength : public std::exception { public: - InvalidReportLength() = default;; - const char* what() const noexcept override; + InvalidReportLength() = default; + + [[nodiscard]] const char* what() const noexcept override; }; static constexpr std::size_t MaxDataLength = 20; @@ -69,57 +64,70 @@ namespace hidpp Report(Report::Type type, DeviceIndex device_index, uint8_t sub_id, uint8_t address); + Report(Report::Type type, DeviceIndex device_index, - uint8_t feature_index, - uint8_t function, - uint8_t sw_id); + uint8_t feature_index, + uint8_t function, + uint8_t sw_id); + explicit Report(const std::vector& data); - Report::Type type() const; + [[nodiscard]] Report::Type type() const; + void setType(Report::Type type); - DeviceIndex deviceIndex() const; - void setDeviceIndex(DeviceIndex index); + [[nodiscard]] DeviceIndex deviceIndex() const; - uint8_t feature() const; - void setFeature(uint8_t feature); + [[maybe_unused]] void setDeviceIndex(DeviceIndex index); - uint8_t subId() const; - void setSubId(uint8_t sub_id); + [[nodiscard]] uint8_t feature() const; - uint8_t function() const; - void setFunction(uint8_t function); + [[maybe_unused]] void setFeature(uint8_t feature); + + [[nodiscard]] uint8_t subId() const; + + [[maybe_unused]] void setSubId(uint8_t sub_id); + + [[nodiscard]] uint8_t function() const; + + [[maybe_unused]] void setFunction(uint8_t function); + + [[nodiscard]] uint8_t swId() const; - uint8_t swId() const; void setSwId(uint8_t sw_id); - uint8_t address() const; - void setAddress(uint8_t address); + [[nodiscard]] uint8_t address() const; + + [[maybe_unused]] void setAddress(uint8_t address); + + [[nodiscard]] std::vector::iterator paramBegin(); + + [[nodiscard]] std::vector::iterator paramEnd(); + + [[nodiscard]] std::vector::const_iterator paramBegin() const; + + [[nodiscard]] std::vector::const_iterator paramEnd() const; - std::vector::iterator paramBegin(); - std::vector::iterator paramEnd(); - std::vector::const_iterator paramBegin() const; - std::vector::const_iterator paramEnd() const; void setParams(const std::vector& _params); - struct Hidpp10Error - { + struct Hidpp10Error { uint8_t sub_id, address, error_code; }; + bool isError10(Hidpp10Error* error) const; - struct Hidpp20Error - { + struct Hidpp20Error { uint8_t feature_index, function, software_id, error_code; }; + bool isError20(Hidpp20Error* error) const; - std::vector rawReport() const { return _data; } + [[nodiscard]] const std::vector& rawReport() const; static constexpr std::size_t HeaderLength = 4; private: std::vector _data; }; -}}} +} #endif //LOGID_BACKEND_HIDPP_REPORT_H \ No newline at end of file diff --git a/src/logid/backend/hidpp/defs.h b/src/logid/backend/hidpp/defs.h index 4696006..a2e5c88 100644 --- a/src/logid/backend/hidpp/defs.h +++ b/src/logid/backend/hidpp/defs.h @@ -23,33 +23,27 @@ #include -namespace logid { -namespace backend { -namespace hidpp -{ - namespace ReportType - { - enum ReportType : uint8_t - { +namespace logid::backend::hidpp { + namespace ReportType { + enum ReportType : uint8_t { Short = 0x10, Long = 0x11 }; } - enum DeviceIndex: uint8_t - { + enum DeviceIndex : uint8_t { DefaultDevice = 0xff, CordedDevice = 0, WirelessDevice1 = 1, - WirelessDevice2 = 2, - WirelessDevice3 = 3, - WirelessDevice4 = 4, - WirelessDevice5 = 5, + WirelessDevice2 [[maybe_unused]] = 2, + WirelessDevice3 [[maybe_unused]] = 3, + WirelessDevice4 [[maybe_unused]] = 4, + WirelessDevice5 [[maybe_unused]] = 5, WirelessDevice6 = 6, }; static constexpr std::size_t ShortParamLength = 3; static constexpr std::size_t LongParamLength = 16; -} } } +} #endif //LOGID_BACKEND_HIDPP_DEFS_H \ No newline at end of file diff --git a/src/logid/backend/hidpp10/Device.cpp b/src/logid/backend/hidpp10/Device.cpp index 2596669..b294b02 100644 --- a/src/logid/backend/hidpp10/Device.cpp +++ b/src/logid/backend/hidpp10/Device.cpp @@ -25,44 +25,40 @@ using namespace logid::backend; using namespace logid::backend::hidpp10; -Device::Device(const std::string &path, +Device::Device(const std::string& path, hidpp::DeviceIndex index, std::shared_ptr monitor, double timeout) : - hidpp::Device(path, index, std::move(monitor), timeout) -{ + hidpp::Device(path, index, std::move(monitor), timeout) { assert(version() == std::make_tuple(1, 0)); } Device::Device(std::shared_ptr raw_dev, - hidpp::DeviceIndex index, - double timeout) : hidpp::Device(std::move(raw_dev), index, timeout) -{ + hidpp::DeviceIndex index, + double timeout) : hidpp::Device(std::move(raw_dev), index, timeout) { assert(version() == std::make_tuple(1, 0)); } -Device::Device(std::shared_ptr receiver, +Device::Device(const std::shared_ptr& receiver, hidpp::DeviceIndex index, double timeout) - : hidpp::Device(std::move(receiver), index, timeout) -{ + : hidpp::Device(receiver, index, timeout) { assert(version() == std::make_tuple(1, 0)); } -hidpp::Report Device::sendReport(const hidpp::Report& report) -{ +hidpp::Report Device::sendReport(const hidpp::Report& report) { decltype(_responses)::iterator response_slot; - while(true) { + while (true) { { std::lock_guard lock(_response_lock); response_slot = _responses.find(report.subId()); - if(response_slot == _responses.end()) { + if (response_slot == _responses.end()) { response_slot = _responses.emplace( report.subId(), std::optional()).first; break; } } std::unique_lock lock(_response_wait_lock); - _response_cv.wait(lock, [this, sub_id=report.subId()](){ + _response_cv.wait(lock, [this, sub_id = report.subId()]() { std::lock_guard lock(_response_lock); return _responses.find(sub_id) != _responses.end(); }); @@ -70,13 +66,14 @@ hidpp::Report Device::sendReport(const hidpp::Report& report) sendReportNoResponse(report); std::unique_lock wait(_response_wait_lock); - bool valid = _response_cv.wait_for(wait, io_timeout, - [this, &response_slot]() { - std::lock_guard lock(_response_lock); - return response_slot->second.has_value(); - }); + bool valid = _response_cv.wait_for( + wait, io_timeout, + [this, &response_slot]() { + std::lock_guard lock(_response_lock); + return response_slot->second.has_value(); + }); - if(!valid) { + if (!valid) { std::lock_guard lock(_response_lock); _responses.erase(response_slot); throw TimeoutError(); @@ -86,20 +83,19 @@ hidpp::Report Device::sendReport(const hidpp::Report& report) assert(response_slot->second.has_value()); auto response = response_slot->second.value(); _responses.erase(response_slot); - if(std::holds_alternative(response)) + if (std::holds_alternative(response)) return std::get(response); else // if(std::holds_alternative(response)) throw Error(std::get(response)); } -bool Device::responseReport(const hidpp::Report& report) -{ +bool Device::responseReport(const hidpp::Report& report) { std::lock_guard lock(_response_lock); uint8_t sub_id; bool is_error = false; - hidpp::Report::Hidpp10Error hidpp10_error {}; - if(report.isError10(&hidpp10_error)) { + hidpp::Report::Hidpp10Error hidpp10_error{}; + if (report.isError10(&hidpp10_error)) { sub_id = hidpp10_error.sub_id; is_error = true; } else { @@ -107,10 +103,10 @@ bool Device::responseReport(const hidpp::Report& report) } auto response_slot = _responses.find(sub_id); - if(response_slot == _responses.end()) + if (response_slot == _responses.end()) return false; - if(is_error) { + if (is_error) { response_slot->second = static_cast( hidpp10_error.error_code); } else { @@ -122,20 +118,19 @@ bool Device::responseReport(const hidpp::Report& report) } std::vector Device::getRegister(uint8_t address, - const std::vector& params, hidpp::Report::Type type) -{ + const std::vector& params, + hidpp::Report::Type type) { assert(params.size() <= hidpp::LongParamLength); uint8_t sub_id = type == hidpp::Report::Type::Short ? - GetRegisterShort : GetRegisterLong; + GetRegisterShort : GetRegisterLong; return accessRegister(sub_id, address, params); } std::vector Device::setRegister(uint8_t address, const std::vector& params, - hidpp::Report::Type type) -{ + hidpp::Report::Type type) { assert(params.size() <= hidpp::LongParamLength); uint8_t sub_id = type == hidpp::Report::Type::Short ? @@ -145,10 +140,9 @@ std::vector Device::setRegister(uint8_t address, } std::vector Device::accessRegister(uint8_t sub_id, uint8_t address, - const std::vector ¶ms) -{ + const std::vector& params) { hidpp::Report::Type type = params.size() <= hidpp::ShortParamLength ? - hidpp::Report::Type::Short : hidpp::Report::Type::Long; + hidpp::Report::Type::Short : hidpp::Report::Type::Long; hidpp::Report request(type, deviceIndex(), sub_id, address); std::copy(params.begin(), params.end(), request.paramBegin()); diff --git a/src/logid/backend/hidpp10/Device.h b/src/logid/backend/hidpp10/Device.h index 659abbb..abc0332 100644 --- a/src/logid/backend/hidpp10/Device.h +++ b/src/logid/backend/hidpp10/Device.h @@ -25,29 +25,31 @@ #include "../hidpp/Device.h" #include "Error.h" -namespace logid { -namespace backend { -namespace hidpp10 -{ - class Device : public hidpp::Device - { +namespace logid::backend::hidpp10 { + class Device : public hidpp::Device { public: Device(const std::string& path, hidpp::DeviceIndex index, std::shared_ptr monitor, double timeout); + Device(std::shared_ptr raw_dev, - hidpp::DeviceIndex index, double timeout); - Device(std::shared_ptr receiver, + hidpp::DeviceIndex index, double timeout); + + Device(const std::shared_ptr& receiver, hidpp::DeviceIndex index, double timeout); hidpp::Report sendReport(const hidpp::Report& report) final; std::vector getRegister(uint8_t address, - const std::vector& params, hidpp::Report::Type type); + const std::vector& params, + hidpp::Report::Type type); std::vector setRegister(uint8_t address, - const std::vector& params, hidpp::Report::Type type); + const std::vector& params, + hidpp::Report::Type type); + protected: bool responseReport(const hidpp::Report& report) final; + private: std::mutex _response_lock; std::mutex _response_wait_lock; @@ -57,8 +59,8 @@ namespace hidpp10 std::map> _responses; std::vector accessRegister(uint8_t sub_id, - uint8_t address, const std::vector& params); + uint8_t address, const std::vector& params); }; -}}} +} #endif //LOGID_BACKEND_HIDPP10_DEVICE_H \ No newline at end of file diff --git a/src/logid/backend/hidpp10/Error.cpp b/src/logid/backend/hidpp10/Error.cpp index 76c8415..8c208f7 100644 --- a/src/logid/backend/hidpp10/Error.cpp +++ b/src/logid/backend/hidpp10/Error.cpp @@ -22,46 +22,43 @@ using namespace logid::backend::hidpp10; -Error::Error(uint8_t code): _code(code) -{ +Error::Error(uint8_t code) : _code(code) { assert(code != Success); } -const char* Error::what() const noexcept -{ - switch(_code) { - case Success: - return "Success"; - case InvalidSubID: - return "Invalid sub ID"; - case InvalidAddress: - return "Invalid address"; - case InvalidValue: - return "Invalid value"; - case ConnectFail: - return "Connection failure"; - case TooManyDevices: - return "Too many devices"; - case AlreadyExists: - return "Already exists"; - case Busy: - return "Busy"; - case UnknownDevice: - return "Unknown device"; - case ResourceError: - return "Resource error"; - case RequestUnavailable: - return "Request unavailable"; - case InvalidParameterValue: - return "Invalid parameter value"; - case WrongPINCode: - return "Wrong PIN code"; - default: - return "Unknown error code"; +const char* Error::what() const noexcept { + switch (_code) { + case Success: + return "Success"; + case InvalidSubID: + return "Invalid sub ID"; + case InvalidAddress: + return "Invalid address"; + case InvalidValue: + return "Invalid value"; + case ConnectFail: + return "Connection failure"; + case TooManyDevices: + return "Too many devices"; + case AlreadyExists: + return "Already exists"; + case Busy: + return "Busy"; + case UnknownDevice: + return "Unknown device"; + case ResourceError: + return "Resource error"; + case RequestUnavailable: + return "Request unavailable"; + case InvalidParameterValue: + return "Invalid parameter value"; + case WrongPINCode: + return "Wrong PIN code"; + default: + return "Unknown error code"; } } -uint8_t Error::code() const noexcept -{ +uint8_t Error::code() const noexcept { return _code; } \ No newline at end of file diff --git a/src/logid/backend/hidpp10/Error.h b/src/logid/backend/hidpp10/Error.h index f5fffae..2e1b2c6 100644 --- a/src/logid/backend/hidpp10/Error.h +++ b/src/logid/backend/hidpp10/Error.h @@ -20,17 +20,14 @@ #define LOGID_BACKEND_HIDPP10_ERROR_H #include +#include -namespace logid { -namespace backend { -namespace hidpp10 { +namespace logid::backend::hidpp10 { static constexpr uint8_t ErrorID = 0x8f; - class Error: public std::exception - { + class Error : public std::exception { public: - enum ErrorCode: uint8_t - { + enum ErrorCode : uint8_t { Success = 0x00, InvalidSubID = 0x01, InvalidAddress = 0x02, @@ -48,12 +45,13 @@ namespace hidpp10 { explicit Error(uint8_t code); - const char* what() const noexcept override; - uint8_t code() const noexcept; + [[nodiscard]] const char* what() const noexcept override; + + [[nodiscard]] uint8_t code() const noexcept; private: uint8_t _code; }; -}}} +} #endif //LOGID_BACKEND_HIDPP10_ERROR_H \ No newline at end of file diff --git a/src/logid/backend/hidpp10/defs.h b/src/logid/backend/hidpp10/defs.h index d3c06b8..25fba27 100644 --- a/src/logid/backend/hidpp10/defs.h +++ b/src/logid/backend/hidpp10/defs.h @@ -19,17 +19,13 @@ #ifndef LOGID_BACKEND_HIDPP10_DEFS_H #define LOGID_BACKEND_HIDPP10_DEFS_H -namespace logid { -namespace backend { -namespace hidpp10 -{ - enum SubID: uint8_t - { +namespace logid::backend::hidpp10 { + enum SubID : uint8_t { SetRegisterShort = 0x80, GetRegisterShort = 0x81, SetRegisterLong = 0x82, GetRegisterLong = 0x83 }; -}}} +} #endif //LOGID_BACKEND_HIDPP10_DEFS_H \ No newline at end of file diff --git a/src/logid/backend/hidpp20/Device.cpp b/src/logid/backend/hidpp20/Device.cpp index bf7e46d..bade382 100644 --- a/src/logid/backend/hidpp20/Device.cpp +++ b/src/logid/backend/hidpp20/Device.cpp @@ -19,7 +19,6 @@ #include #include "Device.h" -#include "../hidpp/defs.h" #include "../Error.h" #include "../dj/Receiver.h" @@ -28,68 +27,62 @@ using namespace logid::backend::hidpp20; Device::Device(const std::string& path, hidpp::DeviceIndex index, std::shared_ptr monitor, double timeout) : - hidpp::Device(path, index, - std::move(monitor), timeout) -{ + hidpp::Device(path, index, + std::move(monitor), timeout) { // TODO: Fix version check - if(std::get<0>(version()) < 2) + if (std::get<0>(version()) < 2) throw std::runtime_error("Invalid HID++ version"); } Device::Device(std::shared_ptr raw_device, hidpp::DeviceIndex index, double timeout) : - hidpp::Device(std::move(raw_device), index, timeout) -{ - if(std::get<0>(version()) < 2) + hidpp::Device(std::move(raw_device), index, timeout) { + if (std::get<0>(version()) < 2) throw std::runtime_error("Invalid HID++ version"); } -Device::Device(std::shared_ptr receiver, +Device::Device(const std::shared_ptr& receiver, hidpp::DeviceConnectionEvent event, double timeout) : - hidpp::Device(std::move(receiver), event, timeout) -{ - if(std::get<0>(version()) < 2) + hidpp::Device(receiver, event, timeout) { + if (std::get<0>(version()) < 2) throw std::runtime_error("Invalid HID++ version"); } -Device::Device(std::shared_ptr receiver, +Device::Device(const std::shared_ptr& receiver, hidpp::DeviceIndex index, double timeout) - : hidpp::Device(std::move(receiver), index, timeout) -{ - if(std::get<0>(version()) < 2) + : hidpp::Device(receiver, index, timeout) { + if (std::get<0>(version()) < 2) throw std::runtime_error("Invalid HID++ version"); } std::vector Device::callFunction(uint8_t feature_index, - uint8_t function, std::vector& params) -{ + uint8_t function, std::vector& params) { hidpp::Report::Type type; assert(params.size() <= hidpp::LongParamLength); - if(params.size() <= hidpp::ShortParamLength) + if (params.size() <= hidpp::ShortParamLength) type = hidpp::Report::Type::Short; - else if(params.size() <= hidpp::LongParamLength) + else if (params.size() <= hidpp::LongParamLength) type = hidpp::Report::Type::Long; else throw hidpp::Report::InvalidReportID(); hidpp::Report request(type, deviceIndex(), feature_index, function, - LOGID_HIDPP_SOFTWARE_ID); + LOGID_HIDPP_SOFTWARE_ID); std::copy(params.begin(), params.end(), request.paramBegin()); auto response = this->sendReport(request); - return std::vector(response.paramBegin(), response.paramEnd()); + return {response.paramBegin(), response.paramEnd()}; } void Device::callFunctionNoResponse(uint8_t feature_index, uint8_t function, - std::vector ¶ms) -{ + std::vector& params) { hidpp::Report::Type type; assert(params.size() <= hidpp::LongParamLength); - if(params.size() <= hidpp::ShortParamLength) + if (params.size() <= hidpp::ShortParamLength) type = hidpp::Report::Type::Short; - else if(params.size() <= hidpp::LongParamLength) + else if (params.size() <= hidpp::LongParamLength) type = hidpp::Report::Type::Long; else throw hidpp::Report::InvalidReportID(); @@ -101,21 +94,20 @@ void Device::callFunctionNoResponse(uint8_t feature_index, uint8_t function, this->sendReportNoResponse(request); } -hidpp::Report Device::sendReport(const hidpp::Report& report) -{ +hidpp::Report Device::sendReport(const hidpp::Report& report) { decltype(_responses)::iterator response_slot; - while(true) { + while (true) { { std::lock_guard lock(_response_lock); - if(_responses.empty()) { + if (_responses.empty()) { response_slot = _responses.emplace( 2, std::optional()).first; break; - } else if(_responses.size() < response_slots) { + } else if (_responses.size() < response_slots) { uint8_t i = 0; - for(auto& x : _responses) { - if(x.first != i + 1) { + for (auto& x: _responses) { + if (x.first != i + 1) { ++i; break; } @@ -130,7 +122,7 @@ hidpp::Report Device::sendReport(const hidpp::Report& report) } std::unique_lock lock(_response_wait_lock); - _response_cv.wait(lock, [this, sub_id=report.subId()](){ + _response_cv.wait(lock, [this, sub_id = report.subId()]() { std::lock_guard lock(_response_lock); return _responses.size() < response_slots; }); @@ -138,19 +130,19 @@ hidpp::Report Device::sendReport(const hidpp::Report& report) { std::lock_guard lock(_response_lock); - hidpp::Report mod_report {report}; + hidpp::Report mod_report{report}; mod_report.setSwId(response_slot->first); sendReportNoResponse(std::move(mod_report)); } std::unique_lock wait(_response_wait_lock); bool valid = _response_cv.wait_for(wait, io_timeout, - [this, &response_slot]() { - std::lock_guard lock(_response_lock); - return response_slot->second.has_value(); - }); + [this, &response_slot]() { + std::lock_guard lock(_response_lock); + return response_slot->second.has_value(); + }); - if(!valid) { + if (!valid) { std::lock_guard lock(_response_lock); _responses.erase(response_slot); throw TimeoutError(); @@ -160,20 +152,19 @@ hidpp::Report Device::sendReport(const hidpp::Report& report) assert(response_slot->second.has_value()); auto response = response_slot->second.value(); _responses.erase(response_slot); - if(std::holds_alternative(response)) + if (std::holds_alternative(response)) return std::get(response); else // if(std::holds_alternative(response)) throw Error(std::get(response)); } -bool Device::responseReport(const hidpp::Report& report) -{ +bool Device::responseReport(const hidpp::Report& report) { std::lock_guard lock(_response_lock); uint8_t sw_id; bool is_error = false; - hidpp::Report::Hidpp20Error hidpp20_error {}; - if(report.isError20(&hidpp20_error)) { + hidpp::Report::Hidpp20Error hidpp20_error{}; + if (report.isError20(&hidpp20_error)) { is_error = true; sw_id = hidpp20_error.software_id; } else { @@ -181,10 +172,10 @@ bool Device::responseReport(const hidpp::Report& report) } auto response_slot = _responses.find(sw_id); - if(response_slot == _responses.end()) + if (response_slot == _responses.end()) return false; - if(is_error) { + if (is_error) { response_slot->second = static_cast( hidpp20_error.error_code); } else { diff --git a/src/logid/backend/hidpp20/Device.h b/src/logid/backend/hidpp20/Device.h index 0813cd5..051df68 100644 --- a/src/logid/backend/hidpp20/Device.h +++ b/src/logid/backend/hidpp20/Device.h @@ -26,32 +26,34 @@ #include "../hidpp/Device.h" #include "Error.h" -namespace logid { -namespace backend { -namespace hidpp20 { - class Device : public hidpp::Device - { +namespace logid::backend::hidpp20 { + class Device : public hidpp::Device { public: Device(const std::string& path, hidpp::DeviceIndex index, std::shared_ptr monitor, double timeout); + Device(std::shared_ptr raw_device, hidpp::DeviceIndex index, double timeout); - Device(std::shared_ptr receiver, + + Device(const std::shared_ptr& receiver, hidpp::DeviceConnectionEvent event, double timeout); - Device(std::shared_ptr receiver, + + Device(const std::shared_ptr& receiver, hidpp::DeviceIndex index, double timeout); std::vector callFunction(uint8_t feature_index, - uint8_t function, - std::vector& params); + uint8_t function, + std::vector& params); void callFunctionNoResponse(uint8_t feature_index, - uint8_t function, - std::vector& params); + uint8_t function, + std::vector& params); hidpp::Report sendReport(const hidpp::Report& report) final; + protected: bool responseReport(const hidpp::Report& report) final; + private: std::mutex _response_lock; std::mutex _response_wait_lock; @@ -61,6 +63,6 @@ namespace hidpp20 { typedef std::variant Response; std::map> _responses; }; -}}} +} #endif //LOGID_BACKEND_HIDPP20_DEVICE_H \ No newline at end of file diff --git a/src/logid/backend/hidpp20/Error.cpp b/src/logid/backend/hidpp20/Error.cpp index eea11a9..799034f 100644 --- a/src/logid/backend/hidpp20/Error.cpp +++ b/src/logid/backend/hidpp20/Error.cpp @@ -21,42 +21,39 @@ using namespace logid::backend::hidpp20; -Error::Error(uint8_t code) : _code (code) -{ +Error::Error(uint8_t code) : _code(code) { assert(_code != NoError); } -const char* Error::what() const noexcept -{ - switch(_code) { - case NoError: - return "No error"; - case Unknown: - return "Unknown"; - case InvalidArgument: - return "Invalid argument"; - case OutOfRange: - return "Out of range"; - case HardwareError: - return "Hardware error"; - case LogitechInternal: - return "Logitech internal feature"; - case InvalidFeatureIndex: - return "Invalid feature index"; - case InvalidFunctionID: - return "Invalid function ID"; - case Busy: - return "Busy"; - case Unsupported: - return "Unsupported"; - case UnknownDevice: - return "Unknown device"; - default: - return "Unknown error code"; +const char* Error::what() const noexcept { + switch (_code) { + case NoError: + return "No error"; + case Unknown: + return "Unknown"; + case InvalidArgument: + return "Invalid argument"; + case OutOfRange: + return "Out of range"; + case HardwareError: + return "Hardware error"; + case LogitechInternal: + return "Logitech internal feature"; + case InvalidFeatureIndex: + return "Invalid feature index"; + case InvalidFunctionID: + return "Invalid function ID"; + case Busy: + return "Busy"; + case Unsupported: + return "Unsupported"; + case UnknownDevice: + return "Unknown device"; + default: + return "Unknown error code"; } } -uint8_t Error::code() const noexcept -{ +uint8_t Error::code() const noexcept { return _code; } \ No newline at end of file diff --git a/src/logid/backend/hidpp20/Error.h b/src/logid/backend/hidpp20/Error.h index 06b5132..782e0d8 100644 --- a/src/logid/backend/hidpp20/Error.h +++ b/src/logid/backend/hidpp20/Error.h @@ -22,15 +22,12 @@ #include #include -namespace logid { -namespace backend { -namespace hidpp20 { +namespace logid::backend::hidpp20 { static constexpr uint8_t ErrorID = 0xFF; - class Error: public std::exception - { + class Error : public std::exception { public: - enum ErrorCode: uint8_t { + enum ErrorCode : uint8_t { NoError = 0, Unknown = 1, InvalidArgument = 2, @@ -46,12 +43,13 @@ namespace hidpp20 { explicit Error(uint8_t code); - const char* what() const noexcept override; - uint8_t code() const noexcept; + [[nodiscard]] const char* what() const noexcept override; + + [[nodiscard]] uint8_t code() const noexcept; private: uint8_t _code; }; -}}} +} #endif //LOGID_BACKEND_HIDPP20_ERROR_H \ No newline at end of file diff --git a/src/logid/backend/hidpp20/EssentialFeature.cpp b/src/logid/backend/hidpp20/EssentialFeature.cpp index ffd2442..2a749b2 100644 --- a/src/logid/backend/hidpp20/EssentialFeature.cpp +++ b/src/logid/backend/hidpp20/EssentialFeature.cpp @@ -25,14 +25,13 @@ using namespace logid::backend::hidpp20; std::vector EssentialFeature::callFunction(uint8_t function_id, - std::vector& params) -{ + std::vector& params) { hidpp::Report::Type type; assert(params.size() <= hidpp::LongParamLength); - if(params.size() <= hidpp::ShortParamLength) + if (params.size() <= hidpp::ShortParamLength) type = hidpp::Report::Type::Short; - else if(params.size() <= hidpp::LongParamLength) + else if (params.size() <= hidpp::LongParamLength) type = hidpp::Report::Type::Long; else throw hidpp::Report::InvalidReportID(); @@ -46,25 +45,23 @@ std::vector EssentialFeature::callFunction(uint8_t function_id, } EssentialFeature::EssentialFeature(hidpp::Device* dev, uint16_t _id) : - _device (dev) -{ + _device(dev) { _index = hidpp20::FeatureID::ROOT; - if(_id) - { + if (_id) { std::vector getFunc_req(2); getFunc_req[0] = (_id >> 8) & 0xff; getFunc_req[1] = _id & 0xff; try { - _index = this->callFunction(Root::GetFeature,getFunc_req).at(0); - } catch(Error& e) { - if(e.code() == Error::InvalidFeatureIndex) + _index = this->callFunction(Root::GetFeature, getFunc_req).at(0); + } catch (Error& e) { + if (e.code() == Error::InvalidFeatureIndex) throw UnsupportedFeature(_id); throw e; } // 0 if not found - if(!_index) + if (!_index) throw UnsupportedFeature(_id); } } diff --git a/src/logid/backend/hidpp20/EssentialFeature.h b/src/logid/backend/hidpp20/EssentialFeature.h index bfc578f..c1b69b6 100644 --- a/src/logid/backend/hidpp20/EssentialFeature.h +++ b/src/logid/backend/hidpp20/EssentialFeature.h @@ -27,24 +27,23 @@ #include "Device.h" -namespace logid { -namespace backend { -namespace hidpp20 -{ - class EssentialFeature - { +namespace logid::backend::hidpp20 { + class EssentialFeature { public: static const uint16_t ID; + virtual uint16_t getID() = 0; protected: EssentialFeature(hidpp::Device* dev, uint16_t _id); + std::vector callFunction(uint8_t function_id, - std::vector& params); + std::vector& params); + private: hidpp::Device* _device; uint8_t _index; }; -}}} +} #endif //LOGID_BACKEND_HIDPP20_ESSENTIAL_FEATURE_H \ No newline at end of file diff --git a/src/logid/backend/hidpp20/Feature.cpp b/src/logid/backend/hidpp20/Feature.cpp index 1fc62b5..2cdb412 100644 --- a/src/logid/backend/hidpp20/Feature.cpp +++ b/src/logid/backend/hidpp20/Feature.cpp @@ -23,55 +23,47 @@ using namespace logid::backend::hidpp20; -const char* UnsupportedFeature::what() const noexcept -{ +const char* UnsupportedFeature::what() const noexcept { return "Unsupported feature"; } -uint16_t UnsupportedFeature::code() const noexcept -{ +uint16_t UnsupportedFeature::code() const noexcept { return _f_id; } std::vector Feature::callFunction(uint8_t function_id, - std::vector& params) -{ + std::vector& params) { return _device->callFunction(_index, function_id, params); } void Feature::callFunctionNoResponse(uint8_t function_id, - std::vector& params) -{ + std::vector& params) { _device->callFunctionNoResponse(_index, function_id, params); } -Feature::Feature(Device* dev, uint16_t _id) : _device (dev) -{ +Feature::Feature(Device* dev, uint16_t _id) : _device(dev) { _index = hidpp20::FeatureID::ROOT; - if(_id) - { + if (_id) { std::vector getFunc_req(2); getFunc_req[0] = (_id >> 8) & 0xff; getFunc_req[1] = _id & 0xff; try { - auto getFunc_resp = this->callFunction(Root::GetFeature, - getFunc_req); + auto getFunc_resp = this->callFunction(Root::GetFeature, getFunc_req); _index = getFunc_resp[0]; - } catch(Error& e) { - if(e.code() == Error::InvalidFeatureIndex) + } catch (Error& e) { + if (e.code() == Error::InvalidFeatureIndex) throw UnsupportedFeature(_id); throw e; } // 0 if not found - if(!_index) + if (!_index) throw UnsupportedFeature(_id); } } -uint8_t Feature::featureIndex() -{ +uint8_t Feature::featureIndex() { return _index; } \ No newline at end of file diff --git a/src/logid/backend/hidpp20/Feature.h b/src/logid/backend/hidpp20/Feature.h index 3469ce6..e045011 100644 --- a/src/logid/backend/hidpp20/Feature.h +++ b/src/logid/backend/hidpp20/Feature.h @@ -22,36 +22,40 @@ #include #include "Device.h" -namespace logid { -namespace backend { -namespace hidpp20 { - class UnsupportedFeature : public std::exception - { +namespace logid::backend::hidpp20 { + class UnsupportedFeature : public std::exception { public: - explicit UnsupportedFeature(uint16_t ID) : _f_id (ID) {} - const char* what() const noexcept override; - uint16_t code() const noexcept; + explicit UnsupportedFeature(uint16_t ID) : _f_id(ID) {} + + [[nodiscard]] const char* what() const noexcept override; + + [[nodiscard]] uint16_t code() const noexcept; + private: uint16_t _f_id; }; - class Feature - { + class Feature { public: static const uint16_t ID; + virtual uint16_t getID() = 0; + uint8_t featureIndex(); + virtual ~Feature() = default; + protected: explicit Feature(Device* dev, uint16_t _id); - std::vector callFunction(uint8_t function_id, - std::vector& params); - void callFunctionNoResponse(uint8_t function_id, - std::vector& params); + + std::vector callFunction(uint8_t function_id, std::vector& params); + + void callFunctionNoResponse(uint8_t function_id, std::vector& params); + private: Device* _device; uint8_t _index; }; -}}} +} #endif //LOGID_BACKEND_HIDPP20_FEATURE_H \ No newline at end of file diff --git a/src/logid/backend/hidpp20/feature_defs.h b/src/logid/backend/hidpp20/feature_defs.h index 687dcc4..6d6ccbd 100644 --- a/src/logid/backend/hidpp20/feature_defs.h +++ b/src/logid/backend/hidpp20/feature_defs.h @@ -21,9 +21,7 @@ #include -namespace logid { -namespace backend { -namespace hidpp20 { +namespace logid::backend::hidpp20 { struct feature_info { uint16_t feature_id; bool obsolete; @@ -31,10 +29,8 @@ namespace hidpp20 { bool hidden; }; - namespace FeatureID - { - enum FeatureID : uint16_t - { + namespace FeatureID { + enum FeatureID : uint16_t { ROOT = 0x0000, FEATURE_SET = 0x0001, FEATURE_INFO = 0x0002, @@ -127,6 +123,6 @@ namespace hidpp20 { }; } -}}} +} #endif //LOGID_BACKEND_HIDPP20_FEATUREDEFS \ No newline at end of file diff --git a/src/logid/backend/hidpp20/features/AdjustableDPI.cpp b/src/logid/backend/hidpp20/features/AdjustableDPI.cpp index 722d6cb..e34f99a 100644 --- a/src/logid/backend/hidpp20/features/AdjustableDPI.cpp +++ b/src/logid/backend/hidpp20/features/AdjustableDPI.cpp @@ -19,31 +19,28 @@ using namespace logid::backend::hidpp20; -AdjustableDPI::AdjustableDPI(Device* dev) : Feature(dev, ID) -{ +AdjustableDPI::AdjustableDPI(Device* dev) : Feature(dev, ID) { } -uint8_t AdjustableDPI::getSensorCount() -{ +uint8_t AdjustableDPI::getSensorCount() { std::vector params(0); auto response = callFunction(GetSensorCount, params); return response[0]; } -AdjustableDPI::SensorDPIList AdjustableDPI::getSensorDPIList(uint8_t sensor) -{ +AdjustableDPI::SensorDPIList AdjustableDPI::getSensorDPIList(uint8_t sensor) { SensorDPIList dpi_list{}; std::vector params(1); params[0] = sensor; auto response = callFunction(GetSensorDPIList, params); dpi_list.dpiStep = false; - for(std::size_t i = 1; i < response.size(); i+=2) { + for (std::size_t i = 1; i < response.size(); i += 2) { uint16_t dpi = response[i + 1]; dpi |= (response[i] << 8); - if(!dpi) + if (!dpi) break; - if(dpi >= 0xe000) { + if (dpi >= 0xe000) { dpi_list.isRange = true; dpi_list.dpiStep = dpi - 0xe000; } else { @@ -54,8 +51,7 @@ AdjustableDPI::SensorDPIList AdjustableDPI::getSensorDPIList(uint8_t sensor) return dpi_list; } -uint16_t AdjustableDPI::getDefaultSensorDPI(uint8_t sensor) -{ +uint16_t AdjustableDPI::getDefaultSensorDPI(uint8_t sensor) { std::vector params(1); params[0] = sensor; auto response = callFunction(GetSensorDPI, params); @@ -66,8 +62,7 @@ uint16_t AdjustableDPI::getDefaultSensorDPI(uint8_t sensor) return default_dpi; } -uint16_t AdjustableDPI::getSensorDPI(uint8_t sensor) -{ +uint16_t AdjustableDPI::getSensorDPI(uint8_t sensor) { std::vector params(1); params[0] = sensor; auto response = callFunction(GetSensorDPI, params); @@ -78,8 +73,7 @@ uint16_t AdjustableDPI::getSensorDPI(uint8_t sensor) return dpi; } -void AdjustableDPI::setSensorDPI(uint8_t sensor, uint16_t dpi) -{ +void AdjustableDPI::setSensorDPI(uint8_t sensor, uint16_t dpi) { std::vector params(3); params[0] = sensor; params[1] = (dpi >> 8); diff --git a/src/logid/backend/hidpp20/features/AdjustableDPI.h b/src/logid/backend/hidpp20/features/AdjustableDPI.h index 9a76d0f..92a4194 100644 --- a/src/logid/backend/hidpp20/features/AdjustableDPI.h +++ b/src/logid/backend/hidpp20/features/AdjustableDPI.h @@ -21,15 +21,12 @@ #include "../feature_defs.h" #include "../Feature.h" -namespace logid { -namespace backend { -namespace hidpp20 -{ - class AdjustableDPI : public Feature - { +namespace logid::backend::hidpp20 { + class AdjustableDPI : public Feature { public: static const uint16_t ID = FeatureID::ADJUSTABLE_DPI; - virtual uint16_t getID() { return ID; } + + [[nodiscard]] uint16_t getID() final { return ID; } enum Function { GetSensorCount = 0, @@ -38,23 +35,24 @@ namespace hidpp20 SetSensorDPI = 3 }; - AdjustableDPI(Device* dev); + explicit AdjustableDPI(Device* dev); uint8_t getSensorCount(); - struct SensorDPIList - { + struct SensorDPIList { std::vector dpis; bool isRange; uint16_t dpiStep; }; + SensorDPIList getSensorDPIList(uint8_t sensor); uint16_t getDefaultSensorDPI(uint8_t sensor); + uint16_t getSensorDPI(uint8_t sensor); void setSensorDPI(uint8_t sensor, uint16_t dpi); }; -}}} +} #endif //LOGID_BACKEND_HIDPP20_FEATURE_ADJUSTABLEDPI_H diff --git a/src/logid/backend/hidpp20/features/ChangeHost.cpp b/src/logid/backend/hidpp20/features/ChangeHost.cpp index 3083718..f88e60b 100644 --- a/src/logid/backend/hidpp20/features/ChangeHost.cpp +++ b/src/logid/backend/hidpp20/features/ChangeHost.cpp @@ -16,16 +16,13 @@ * */ #include "ChangeHost.h" -#include "../Error.h" using namespace logid::backend::hidpp20; -ChangeHost::ChangeHost(Device *dev) : Feature(dev, ID), _host_count (0) -{ +ChangeHost::ChangeHost(Device* dev) : Feature(dev, ID), _host_count(0) { } -ChangeHost::HostInfo ChangeHost::getHostInfo() -{ +ChangeHost::HostInfo ChangeHost::getHostInfo() { std::vector params(0); auto response = callFunction(GetHostInfo, params); @@ -34,23 +31,22 @@ ChangeHost::HostInfo ChangeHost::getHostInfo() info.currentHost = response[1]; info.enhancedHostSwitch = response[2] & 1; - if(!_host_count) + if (!_host_count) _host_count = info.hostCount; return info; } -void ChangeHost::setHost(uint8_t host) -{ +void ChangeHost::setHost(uint8_t host) { /* Expect connection to be severed here, send without response * * Since there is no response, we have to emulate any kind of * error that may be returned (i.e. InvalidArgument as per the docs) */ - if(!_host_count) + if (!_host_count) getHostInfo(); - if(host >= _host_count) + if (host >= _host_count) throw hidpp20::Error(hidpp20::Error::InvalidArgument); std::vector params = {host}; @@ -58,9 +54,9 @@ void ChangeHost::setHost(uint8_t host) callFunctionNoResponse(SetCurrentHost, params); } -std::vector ChangeHost::getCookies() -{ - if(!_host_count) +[[maybe_unused]] +std::vector ChangeHost::getCookies() { + if (!_host_count) getHostInfo(); std::vector params(0); @@ -71,8 +67,8 @@ std::vector ChangeHost::getCookies() return response; } -void ChangeHost::setCookie(uint8_t host, uint8_t cookie) -{ +[[maybe_unused]] +void ChangeHost::setCookie(uint8_t host, uint8_t cookie) { std::vector params = {host, cookie}; callFunction(SetCookie, params); } \ No newline at end of file diff --git a/src/logid/backend/hidpp20/features/ChangeHost.h b/src/logid/backend/hidpp20/features/ChangeHost.h index 094cfb1..9e1f5af 100644 --- a/src/logid/backend/hidpp20/features/ChangeHost.h +++ b/src/logid/backend/hidpp20/features/ChangeHost.h @@ -21,17 +21,14 @@ #include "../feature_defs.h" #include "../Feature.h" -namespace logid { -namespace backend { -namespace hidpp20 -{ - class ChangeHost : public Feature - { +namespace logid::backend::hidpp20 { + class ChangeHost : public Feature { public: static const uint16_t ID = FeatureID::CHANGE_HOST; - virtual uint16_t getID() { return ID; } - ChangeHost(Device* dev); + [[nodiscard]] uint16_t getID() final { return ID; } + + explicit ChangeHost(Device* dev); enum Function { GetHostInfo = 0, @@ -40,22 +37,23 @@ namespace hidpp20 SetCookie = 3 }; - struct HostInfo - { + struct HostInfo { uint8_t hostCount; uint8_t currentHost; - bool enhancedHostSwitch; + [[maybe_unused]] bool enhancedHostSwitch; }; HostInfo getHostInfo(); + void setHost(uint8_t host); - std::vector getCookies(); - void setCookie(uint8_t host, uint8_t cookie); + [[maybe_unused]] [[maybe_unused]] std::vector getCookies(); + + [[maybe_unused]] [[maybe_unused]] void setCookie(uint8_t host, uint8_t cookie); + private: uint8_t _host_count; }; -}}} - +} #endif //LOGID_BACKEND_HIDPP20_FEATURE_CHANGEHOST_H diff --git a/src/logid/backend/hidpp20/features/DeviceName.cpp b/src/logid/backend/hidpp20/features/DeviceName.cpp index deed409..5522b4e 100644 --- a/src/logid/backend/hidpp20/features/DeviceName.cpp +++ b/src/logid/backend/hidpp20/features/DeviceName.cpp @@ -16,61 +16,39 @@ * */ -#include #include "DeviceName.h" using namespace logid::backend; using namespace logid::backend::hidpp20; -DeviceName::DeviceName(Device* dev) : Feature(dev, ID) -{ -} +namespace { + std::string _getName(uint8_t length, + const std::function(std::vector)>& fcall) { + uint8_t function_calls = length / hidpp::LongParamLength; + if (length % hidpp::LongParamLength) + function_calls++; + std::vector params(1); + std::string name; -uint8_t DeviceName::getNameLength() -{ - std::vector params(0); - - auto response = this->callFunction(Function::GetLength, params); - return response[0]; -} - -std::string _getName(uint8_t length, - const std::function(std::vector)>& fcall) -{ - uint8_t function_calls = length/hidpp::LongParamLength; - if(length % hidpp::LongParamLength) - function_calls++; - std::vector params(1); - std::string name; - - for(uint8_t i = 0; i < function_calls; i++) { - params[0] = i*hidpp::LongParamLength; - auto name_section = fcall(params); - for(std::size_t j = 0; j < hidpp::LongParamLength; j++) { - if(params[0] + j >= length) - return name; - name += name_section[j]; + for (uint8_t i = 0; i < function_calls; i++) { + params[0] = i * hidpp::LongParamLength; + auto name_section = fcall(params); + for (std::size_t j = 0; j < hidpp::LongParamLength; j++) { + if (params[0] + j >= length) + return name; + name += (char) name_section[j]; + } } + + return name; } - - return name; } -std::string DeviceName::getName() -{ - return _getName(getNameLength(), [this] - (std::vector params)->std::vector { - return this->callFunction(Function::GetDeviceName, params); - }); +DeviceName::DeviceName(hidpp::Device* dev) : + EssentialFeature(dev, ID) { } -EssentialDeviceName::EssentialDeviceName(hidpp::Device* dev) : - EssentialFeature(dev, ID) -{ -} - -uint8_t EssentialDeviceName::getNameLength() -{ +uint8_t DeviceName::getNameLength() { std::vector params(0); auto response = this->callFunction(DeviceName::Function::GetLength, params); @@ -78,10 +56,9 @@ uint8_t EssentialDeviceName::getNameLength() return response[0]; } -std::string EssentialDeviceName::getName() -{ +std::string DeviceName::getName() { return _getName(getNameLength(), [this] - (std::vector params)->std::vector { + (std::vector params) -> std::vector { return this->callFunction(DeviceName::Function::GetDeviceName, params); }); } \ No newline at end of file diff --git a/src/logid/backend/hidpp20/features/DeviceName.h b/src/logid/backend/hidpp20/features/DeviceName.h index e21fe27..e326c65 100644 --- a/src/logid/backend/hidpp20/features/DeviceName.h +++ b/src/logid/backend/hidpp20/features/DeviceName.h @@ -23,39 +23,24 @@ #include "../feature_defs.h" #include "../EssentialFeature.h" -namespace logid { -namespace backend { -namespace hidpp20 -{ - class DeviceName : public Feature - { +namespace logid::backend::hidpp20 { + class DeviceName : public EssentialFeature { public: static const uint16_t ID = FeatureID::DEVICE_NAME; - virtual uint16_t getID() { return ID; } - enum Function : uint8_t - { + enum Function : uint8_t { GetLength = 0, GetDeviceName = 1 }; - explicit DeviceName(Device* device); + [[nodiscard]] uint16_t getID() final { return ID; } - uint8_t getNameLength(); - std::string getName(); + explicit DeviceName(hidpp::Device* device); + + [[nodiscard]] uint8_t getNameLength(); + + [[nodiscard]] std::string getName(); }; - - class EssentialDeviceName : public EssentialFeature - { - public: - static const uint16_t ID = FeatureID::DEVICE_NAME; - virtual uint16_t getID() { return ID; } - - explicit EssentialDeviceName(hidpp::Device* device); - - uint8_t getNameLength(); - std::string getName(); - }; -}}} +} #endif //LOGID_BACKEND_HIDPP20_FEATURE_DEVICENAME_H \ No newline at end of file diff --git a/src/logid/backend/hidpp20/features/FeatureSet.cpp b/src/logid/backend/hidpp20/features/FeatureSet.cpp index 092b809..3c4772b 100644 --- a/src/logid/backend/hidpp20/features/FeatureSet.cpp +++ b/src/logid/backend/hidpp20/features/FeatureSet.cpp @@ -19,19 +19,17 @@ using namespace logid::backend::hidpp20; -FeatureSet::FeatureSet(Device *device) : Feature(device, ID) -{ +[[maybe_unused]] +FeatureSet::FeatureSet(Device* device) : Feature(device, ID) { } -uint8_t FeatureSet::getFeatureCount() -{ +uint8_t FeatureSet::getFeatureCount() { std::vector params(0); auto response = callFunction(GetFeatureCount, params); return response[0]; } -uint16_t FeatureSet::getFeature(uint8_t feature_index) -{ +uint16_t FeatureSet::getFeature(uint8_t feature_index) { std::vector params(1); params[0] = feature_index; auto response = callFunction(GetFeature, params); @@ -41,11 +39,11 @@ uint16_t FeatureSet::getFeature(uint8_t feature_index) return feature_id; } -std::map FeatureSet::getFeatures() -{ +[[maybe_unused]] +std::map FeatureSet::getFeatures() { uint8_t feature_count = getFeatureCount(); std::map features; - for(uint8_t i = 0; i < feature_count; i++) + for (uint8_t i = 0; i < feature_count; i++) features[i] = getFeature(i); return features; } \ No newline at end of file diff --git a/src/logid/backend/hidpp20/features/FeatureSet.h b/src/logid/backend/hidpp20/features/FeatureSet.h index 27a814e..b115a74 100644 --- a/src/logid/backend/hidpp20/features/FeatureSet.h +++ b/src/logid/backend/hidpp20/features/FeatureSet.h @@ -21,28 +21,28 @@ #include "../Feature.h" #include "../feature_defs.h" -namespace logid { -namespace backend { -namespace hidpp20 -{ - class FeatureSet : public Feature - { +namespace logid::backend::hidpp20 { + class FeatureSet : public Feature { public: static const uint16_t ID = FeatureID::FEATURE_SET; - virtual uint16_t getID() { return ID; } - enum Function : uint8_t - { + [[nodiscard]] uint16_t getID() final { return ID; } + + enum Function : uint8_t { GetFeatureCount = 0, GetFeature = 1 }; + [[maybe_unused]] [[maybe_unused]] explicit FeatureSet(Device* device); - uint8_t getFeatureCount(); - uint16_t getFeature(uint8_t feature_index); - std::map getFeatures(); + [[nodiscard]] uint8_t getFeatureCount(); + + [[nodiscard]] uint16_t getFeature(uint8_t feature_index); + + [[maybe_unused]] + [[nodiscard]] std::map getFeatures(); }; -}}} +} #endif //LOGID_BACKEND_HIDPP20_FEATURE_FEATURESET_H diff --git a/src/logid/backend/hidpp20/features/HiresScroll.cpp b/src/logid/backend/hidpp20/features/HiresScroll.cpp index d8f64e8..a20e489 100644 --- a/src/logid/backend/hidpp20/features/HiresScroll.cpp +++ b/src/logid/backend/hidpp20/features/HiresScroll.cpp @@ -20,12 +20,10 @@ using namespace logid::backend::hidpp20; -HiresScroll::HiresScroll(Device *device) : Feature(device, ID) -{ +HiresScroll::HiresScroll(Device* device) : Feature(device, ID) { } -HiresScroll::Capabilities HiresScroll::getCapabilities() -{ +HiresScroll::Capabilities HiresScroll::getCapabilities() { std::vector params(0); auto response = callFunction(GetCapabilities, params); @@ -35,41 +33,35 @@ HiresScroll::Capabilities HiresScroll::getCapabilities() return capabilities; } -uint8_t HiresScroll::getMode() -{ +uint8_t HiresScroll::getMode() { std::vector params(0); auto response = callFunction(GetMode, params); return response[0]; } -void HiresScroll::setMode(uint8_t mode) -{ +void HiresScroll::setMode(uint8_t mode) { std::vector params(1); params[0] = mode; callFunction(SetMode, params); } -bool HiresScroll::getRatchetState() -{ +[[maybe_unused]] bool HiresScroll::getRatchetState() { std::vector params(0); auto response = callFunction(GetRatchetState, params); return params[0]; } -HiresScroll::WheelStatus HiresScroll::wheelMovementEvent(const hidpp::Report - &report) -{ +HiresScroll::WheelStatus HiresScroll::wheelMovementEvent(const hidpp::Report& report) { assert(report.function() == WheelMovement); WheelStatus status{}; - status.hiRes = report.paramBegin()[0] & 1<<4; + status.hiRes = report.paramBegin()[0] & 1 << 4; status.periods = report.paramBegin()[0] & 0x0F; - status.deltaV = report.paramBegin()[1] << 8 | report.paramBegin()[2]; + status.deltaV = (int16_t) (report.paramBegin()[1] << 8 | report.paramBegin()[2]); return status; } -HiresScroll::RatchetState HiresScroll::ratchetSwitchEvent(const hidpp::Report - &report) -{ +[[maybe_unused]] +HiresScroll::RatchetState HiresScroll::ratchetSwitchEvent(const hidpp::Report& report) { assert(report.function() == RatchetSwitch); // Possible bad cast return static_cast(report.paramBegin()[0]); diff --git a/src/logid/backend/hidpp20/features/HiresScroll.h b/src/logid/backend/hidpp20/features/HiresScroll.h index e580f82..6822930 100644 --- a/src/logid/backend/hidpp20/features/HiresScroll.h +++ b/src/logid/backend/hidpp20/features/HiresScroll.h @@ -21,58 +21,48 @@ #include "../Feature.h" #include "../feature_defs.h" -namespace logid { -namespace backend { -namespace hidpp20 -{ - class HiresScroll : public Feature - { +namespace logid::backend::hidpp20 { + class HiresScroll : public Feature { public: ///TODO: Hires scroll V1? static const uint16_t ID = FeatureID::HIRES_SCROLLING_V2; - virtual uint16_t getID() { return ID; } - enum Function : uint8_t - { + uint16_t getID() final { return ID; } + + enum Function : uint8_t { GetCapabilities = 0, GetMode = 1, SetMode = 2, GetRatchetState = 3 }; - enum Event : uint8_t - { + enum Event : uint8_t { WheelMovement = 0, RatchetSwitch = 1, }; - enum Capability : uint8_t - { - Invertable = 1<<3, - HasRatchet = 1<<2 + enum Capability : uint8_t { + Invertible = 1 << 3, + HasRatchet = 1 << 2 }; - enum Mode : uint8_t - { - Inverted = 1<<2, - HiRes = 1<<1, + enum Mode : uint8_t { + Inverted = 1 << 2, + HiRes = 1 << 1, Target = 1 }; - enum RatchetState : uint8_t - { + enum RatchetState : uint8_t { FreeWheel = 0, Ratchet = 1 }; - struct Capabilities - { + struct Capabilities { uint8_t multiplier; uint8_t flags; }; - struct WheelStatus - { + struct WheelStatus { bool hiRes; uint8_t periods; int16_t deltaV; @@ -81,13 +71,19 @@ namespace hidpp20 explicit HiresScroll(Device* device); Capabilities getCapabilities(); + uint8_t getMode(); + void setMode(uint8_t mode); + + [[maybe_unused]] bool getRatchetState(); static WheelStatus wheelMovementEvent(const hidpp::Report& report); + + [[maybe_unused]] static RatchetState ratchetSwitchEvent(const hidpp::Report& report); }; -}}} +} #endif //LOGID_BACKEND_HIDPP20_FEATURE_HIRESSCROLL_H diff --git a/src/logid/backend/hidpp20/features/ReprogControls.cpp b/src/logid/backend/hidpp20/features/ReprogControls.cpp index ce10bb0..eb2814b 100644 --- a/src/logid/backend/hidpp20/features/ReprogControls.cpp +++ b/src/logid/backend/hidpp20/features/ReprogControls.cpp @@ -21,47 +21,51 @@ using namespace logid::backend::hidpp20; -#define DEFINE_REPROG(x, base) \ -x::x(Device* dev) : base(dev, ID) \ -{ \ -} \ -x::x(Device* dev, uint16_t _id) : base(dev, _id) \ -{ \ -} +// Define all the ReprogControls versions +#define DEFINE_REPROG(T, Base) \ + T::T(Device* dev, uint16_t _id) : Base(dev, _id) { } \ + T::T(Device* dev) : T(dev, ID) { } -#define MAKE_REPROG(x, dev) \ -try { \ - return std::make_shared(dev); \ -} catch(UnsupportedFeature &e) {\ -} - -// Define all of the ReprogControls versions DEFINE_REPROG(ReprogControls, Feature) + DEFINE_REPROG(ReprogControlsV2, ReprogControls) + DEFINE_REPROG(ReprogControlsV2_2, ReprogControlsV2) + DEFINE_REPROG(ReprogControlsV3, ReprogControlsV2_2) + DEFINE_REPROG(ReprogControlsV4, ReprogControlsV3) -std::shared_ptr ReprogControls::autoVersion(Device *dev) -{ - MAKE_REPROG(ReprogControlsV4, dev) - MAKE_REPROG(ReprogControlsV3, dev) - MAKE_REPROG(ReprogControlsV2_2, dev) - MAKE_REPROG(ReprogControlsV2, dev) +template +std::shared_ptr make_reprog(Device* dev) { + try { + return std::make_shared(dev); + } catch (UnsupportedFeature& e) { + return {}; + } +} + +std::shared_ptr ReprogControls::autoVersion(Device* dev) { + if (auto v4 = make_reprog(dev)) { + return v4; + } else if (auto v3 = make_reprog(dev)) { + return v3; + } else if (auto v2_2 = make_reprog(dev)) { + return v2_2; + } else if (auto v2 = make_reprog(dev)) { + return v2; + } - // If base version cannot be made, throw error return std::make_shared(dev); } -uint8_t ReprogControls::getControlCount() -{ +uint8_t ReprogControls::getControlCount() { std::vector params(0); auto response = callFunction(GetControlCount, params); return response[0]; } -ReprogControls::ControlInfo ReprogControls::getControlInfo(uint8_t index) -{ +ReprogControls::ControlInfo ReprogControls::getControlInfo(uint8_t index) { std::vector params(1); ControlInfo info{}; params[0] = index; @@ -79,13 +83,12 @@ ReprogControls::ControlInfo ReprogControls::getControlInfo(uint8_t index) return info; } -void ReprogControls::initCidMap() -{ +void ReprogControls::initCidMap() { std::unique_lock lock(_cids_populating); - if(_cids_initialized) + if (_cids_initialized) return; uint8_t controls = getControlCount(); - for(uint8_t i = 0; i < controls; i++) { + for (uint8_t i = 0; i < controls; i++) { auto info = getControlInfo(i); _cids.emplace(info.controlID, info); } @@ -93,57 +96,53 @@ void ReprogControls::initCidMap() } const std::map& - ReprogControls::getControls() const -{ +ReprogControls::getControls() const { return _cids; } -ReprogControls::ControlInfo ReprogControls::getControlIdInfo(uint16_t cid) -{ - if(!_cids_initialized) +ReprogControls::ControlInfo ReprogControls::getControlIdInfo(uint16_t cid) { + if (!_cids_initialized) initCidMap(); auto it = _cids.find(cid); - if(it == _cids.end()) + if (it == _cids.end()) throw Error(Error::InvalidArgument); else return it->second; } -ReprogControls::ControlInfo ReprogControls::getControlReporting(uint16_t cid) -{ +[[maybe_unused]] ReprogControls::ControlInfo ReprogControls::getControlReporting(uint16_t cid) { // Emulate this function, only Reprog controls v4 supports this auto info = getControlIdInfo(cid); ControlInfo report{}; report.controlID = cid; report.flags = 0; - if(info.flags & TemporaryDivertable) + if (info.flags & TemporaryDivertable) report.flags |= TemporaryDiverted; - if(info.flags & PersisentlyDivertable) + if (info.flags & PersistentlyDivertable) report.flags |= PersistentlyDiverted; - if(info.additionalFlags & RawXY) + if (info.additionalFlags & RawXY) report.flags |= RawXYDiverted; return report; } -void ReprogControls::setControlReporting(uint8_t cid, ControlInfo info) -{ +void ReprogControls::setControlReporting(uint8_t cid, ControlInfo info) { // This function does not exist pre-v4 and cannot be emulated, ignore. - (void)cid; (void)info; // Suppress unused warnings + (void) cid; + (void) info; // Suppress unused warnings } std::set ReprogControls::divertedButtonEvent( - const hidpp::Report& report) -{ + const hidpp::Report& report) { assert(report.function() == DivertedButtonEvent); std::set buttons; - uint8_t cids = std::distance(report.paramBegin(), report.paramEnd())/2; - for(uint8_t i = 0; i < cids; i++) { - uint16_t cid = report.paramBegin()[2*i + 1]; - cid |= report.paramBegin()[2*i] << 8; - if(cid) + uint8_t cids = std::distance(report.paramBegin(), report.paramEnd()) / 2; + for (uint8_t i = 0; i < cids; i++) { + uint16_t cid = report.paramBegin()[2 * i + 1]; + cid |= report.paramBegin()[2 * i] << 8; + if (cid) buttons.insert(cid); else break; @@ -152,19 +151,15 @@ std::set ReprogControls::divertedButtonEvent( } ReprogControls::Move ReprogControls::divertedRawXYEvent(const hidpp::Report - &report) -{ + & report) { assert(report.function() == DivertedRawXYEvent); Move move{}; - move.x = report.paramBegin()[1]; - move.x |= report.paramBegin()[0] << 8; - move.y = report.paramBegin()[3]; - move.y |= report.paramBegin()[2] << 8; + move.x = (int16_t) ((report.paramBegin()[0] << 8) | report.paramBegin()[1]); + move.y = (int16_t) ((report.paramBegin()[2] << 8) | report.paramBegin()[3]); return move; } -ReprogControls::ControlInfo ReprogControlsV4::getControlReporting(uint16_t cid) -{ +ReprogControls::ControlInfo ReprogControlsV4::getControlReporting(uint16_t cid) { std::vector params(2); ControlInfo info{}; params[0] = (cid >> 8) & 0xff; @@ -177,8 +172,7 @@ ReprogControls::ControlInfo ReprogControlsV4::getControlReporting(uint16_t cid) return info; } -void ReprogControlsV4::setControlReporting(uint8_t cid, ControlInfo info) -{ +void ReprogControlsV4::setControlReporting(uint8_t cid, ControlInfo info) { std::vector params(5); params[0] = (cid >> 8) & 0xff; params[1] = cid & 0xff; diff --git a/src/logid/backend/hidpp20/features/ReprogControls.h b/src/logid/backend/hidpp20/features/ReprogControls.h index 9f0d4d5..c76e1f2 100644 --- a/src/logid/backend/hidpp20/features/ReprogControls.h +++ b/src/logid/backend/hidpp20/features/ReprogControls.h @@ -23,12 +23,8 @@ #include "../feature_defs.h" #include "../Feature.h" -namespace logid { -namespace backend { -namespace hidpp20 -{ - class ReprogControls : public Feature - { +namespace logid::backend::hidpp20 { + class ReprogControls : public Feature { public: enum Function { GetControlCount = 0, @@ -41,8 +37,7 @@ namespace hidpp20 DivertedRawXYEvent = 1 }; - struct ControlInfo - { + struct ControlInfo { uint16_t controlID; uint16_t taskID; uint8_t flags; @@ -52,121 +47,127 @@ namespace hidpp20 uint8_t additionalFlags; }; - enum ControlInfoFlags: uint8_t - { + enum ControlInfoFlags : uint8_t { MouseButton = 1, //Mouse button - FKey = 1<<1, //Fx key - Hotkey = 1<<2, - FnToggle = 1<<3, - ReprogHint = 1<<4, - TemporaryDivertable = 1<<5, - PersisentlyDivertable = 1<<6, - Virtual = 1<<7 + FKey = 1 << 1, //Fx key + Hotkey = 1 << 2, + FnToggle = 1 << 3, + ReprogHint = 1 << 4, + TemporaryDivertable = 1 << 5, + PersistentlyDivertable = 1 << 6, + Virtual = 1 << 7 }; - enum ControlInfoAdditionalFlags: uint8_t { - RawXY = 1<<0 + enum ControlInfoAdditionalFlags : uint8_t { + RawXY = 1 << 0 }; - enum ControlReportingFlags: uint8_t { - TemporaryDiverted = 1<<0, - ChangeTemporaryDivert = 1<<1, - PersistentlyDiverted = 1<<2, - ChangePersistentDivert = 1<<3, - RawXYDiverted = 1<<4, - ChangeRawXYDivert = 1<<5 + enum ControlReportingFlags : uint8_t { + TemporaryDiverted = 1 << 0, + ChangeTemporaryDivert = 1 << 1, + PersistentlyDiverted = 1 << 2, + ChangePersistentDivert [[maybe_unused]] = 1 << 3, + RawXYDiverted = 1 << 4, + ChangeRawXYDivert = 1 << 5 }; - struct Move - { + struct Move { int16_t x; int16_t y; }; static const uint16_t ID = FeatureID::REPROG_CONTROLS; - virtual uint16_t getID() { return ID; } - virtual bool supportsRawXY() { return false; } + [[nodiscard]] uint16_t getID() override { return ID; } + + [[nodiscard]] virtual bool supportsRawXY() { return false; } explicit ReprogControls(Device* dev); - virtual uint8_t getControlCount(); + [[nodiscard]] virtual uint8_t getControlCount(); - virtual ControlInfo getControlInfo(uint8_t cid); + [[nodiscard]] virtual ControlInfo getControlInfo(uint8_t cid); - virtual ControlInfo getControlIdInfo(uint16_t cid); + [[nodiscard]] virtual ControlInfo getControlIdInfo(uint16_t cid); virtual void initCidMap(); - const std::map& getControls() const; + [[nodiscard]] const std::map& getControls() const; - // Onlu controlId and flags will be set - virtual ControlInfo getControlReporting(uint16_t cid); + // Only controlId and flags will be set + [[maybe_unused]] + [[nodiscard]] virtual ControlInfo getControlReporting(uint16_t cid); // Only controlId (for remap) and flags will be read virtual void setControlReporting(uint8_t cid, ControlInfo info); - static std::set divertedButtonEvent(const hidpp::Report& - report); + [[nodiscard]] static std::set divertedButtonEvent(const hidpp::Report& report); - static Move divertedRawXYEvent(const hidpp::Report& report); + [[nodiscard]] static Move divertedRawXYEvent(const hidpp::Report& report); + + [[nodiscard]] static std::shared_ptr autoVersion(Device* dev); - static std::shared_ptr autoVersion(Device *dev); protected: ReprogControls(Device* dev, uint16_t _id); + std::map _cids; bool _cids_initialized = false; std::mutex _cids_populating; }; - class ReprogControlsV2 : public ReprogControls - { + class ReprogControlsV2 : public ReprogControls { public: static const uint16_t ID = FeatureID::REPROG_CONTROLS_V2; - virtual uint16_t getID() override { return ID; } + + [[nodiscard]] uint16_t getID() override { return ID; } explicit ReprogControlsV2(Device* dev); + protected: ReprogControlsV2(Device* dev, uint16_t _id); }; - class ReprogControlsV2_2 : public ReprogControlsV2 - { + class ReprogControlsV2_2 : public ReprogControlsV2 { public: static const uint16_t ID = FeatureID::REPROG_CONTROLS_V2_2; - virtual uint16_t getID() override { return ID; } + + [[nodiscard]] uint16_t getID() override { return ID; } explicit ReprogControlsV2_2(Device* dev); + protected: ReprogControlsV2_2(Device* dev, uint16_t _id); }; - class ReprogControlsV3 : public ReprogControlsV2_2 - { + class ReprogControlsV3 : public ReprogControlsV2_2 { public: static const uint16_t ID = FeatureID::REPROG_CONTROLS_V3; - virtual uint16_t getID() override { return ID; } + + [[nodiscard]] uint16_t getID() override { return ID; } explicit ReprogControlsV3(Device* dev); + protected: ReprogControlsV3(Device* dev, uint16_t _id); }; - class ReprogControlsV4 : public ReprogControlsV3 - { + class ReprogControlsV4 : public ReprogControlsV3 { public: static const uint16_t ID = FeatureID::REPROG_CONTROLS_V4; - virtual uint16_t getID() override { return ID; } - bool supportsRawXY() override { return true; } + [[nodiscard]] uint16_t getID() final { return ID; } - ControlInfo getControlReporting(uint16_t cid) override; + [[nodiscard]] bool supportsRawXY() override { return true; } + + [[nodiscard]] ControlInfo getControlReporting(uint16_t cid) override; void setControlReporting(uint8_t cid, ControlInfo info) override; explicit ReprogControlsV4(Device* dev); + protected: + [[maybe_unused]] ReprogControlsV4(Device* dev, uint16_t _id); }; -}}} +} #endif //LOGID_BACKEND_HIDPP20_FEATURE_REPROGCONTROLS_H diff --git a/src/logid/backend/hidpp20/features/Reset.cpp b/src/logid/backend/hidpp20/features/Reset.cpp index 3512055..e04b4ba 100644 --- a/src/logid/backend/hidpp20/features/Reset.cpp +++ b/src/logid/backend/hidpp20/features/Reset.cpp @@ -19,12 +19,10 @@ using namespace logid::backend::hidpp20; -Reset::Reset(Device *device) : Feature(device, ID) -{ +Reset::Reset(Device* device) : Feature(device, ID) { } -uint16_t Reset::getProfile() -{ +uint16_t Reset::getProfile() { std::vector params(0); auto results = callFunction(GetProfile, params); @@ -33,8 +31,7 @@ uint16_t Reset::getProfile() return profile; } -void Reset::reset(uint16_t profile) -{ +void Reset::reset(uint16_t profile) { std::vector params(2); params[0] = (profile >> 8) & 0xff; params[1] = profile & 0xff; diff --git a/src/logid/backend/hidpp20/features/Reset.h b/src/logid/backend/hidpp20/features/Reset.h index a3b6e14..13c1cca 100644 --- a/src/logid/backend/hidpp20/features/Reset.h +++ b/src/logid/backend/hidpp20/features/Reset.h @@ -21,27 +21,24 @@ #include "../Feature.h" #include "../feature_defs.h" -namespace logid { -namespace backend { -namespace hidpp20 -{ - class Reset : public Feature - { +namespace logid::backend::hidpp20 { + class Reset : public Feature { public: static const uint16_t ID = FeatureID::RESET; - virtual uint16_t getID() { return ID; } - enum Function : uint8_t - { - GetProfile = 0, - ResetToProfile = 1 + [[nodiscard]] uint16_t getID() final { return ID; } + + enum Function : uint8_t { + GetProfile = 0, + ResetToProfile = 1 }; explicit Reset(Device* device); uint16_t getProfile(); + void reset(uint16_t profile = 0); }; -}}} +} #endif //LOGID_BACKEND_HIDPP20_FEATURE_RESET_H diff --git a/src/logid/backend/hidpp20/features/Root.cpp b/src/logid/backend/hidpp20/features/Root.cpp index ad97da0..f1258f9 100644 --- a/src/logid/backend/hidpp20/features/Root.cpp +++ b/src/logid/backend/hidpp20/features/Root.cpp @@ -17,82 +17,53 @@ */ #include "Root.h" -#include "../Error.h" using namespace logid::backend::hidpp20; -Root::Root(Device* dev) : Feature(dev, ID) -{ +namespace { + std::vector _genGetFeatureParams(uint16_t feature_id) { + std::vector params(2); + params[0] = feature_id & 0xff; + params[1] = (feature_id >> 8) & 0xff; + return params; + } + + feature_info _genGetFeatureInfo(uint16_t feature_id, + std::vector response) { + feature_info info{}; + info.feature_id = response[0]; + + if (!info.feature_id) + throw UnsupportedFeature(feature_id); + + info.hidden = response[1] & Root::FeatureFlag::Hidden; + info.obsolete = response[1] & Root::FeatureFlag::Obsolete; + info.internal = response[1] & Root::FeatureFlag::Internal; + + return info; + } } -std::vector _genGetFeatureParams(uint16_t feature_id) -{ - std::vector params(2); - params[0] = feature_id & 0xff; - params[1] = (feature_id >> 8) & 0xff; - return params; +Root::Root(hidpp::Device* dev) : EssentialFeature(dev, ID) { } -feature_info _genGetFeatureInfo(uint16_t feature_id, - std::vector response) -{ - feature_info info{}; - info.feature_id = response[0]; - - if(!info.feature_id) - throw UnsupportedFeature(feature_id); - - info.hidden = response[1] & Root::FeatureFlag::Hidden; - info.obsolete = response[1] & Root::FeatureFlag::Obsolete; - info.internal = response[1] & Root::FeatureFlag::Internal; - - return info; -} - -feature_info Root::getFeature(uint16_t feature_id) -{ +feature_info Root::getFeature(uint16_t feature_id) { auto params = _genGetFeatureParams(feature_id); try { auto response = this->callFunction(Root::Function::GetFeature, params); return _genGetFeatureInfo(feature_id, response); - } catch(Error& e) { - if(e.code() == Error::InvalidFeatureIndex) + } catch (Error& e) { + if (e.code() == Error::InvalidFeatureIndex) throw UnsupportedFeature(feature_id); throw e; } } -std::tuple Root::getVersion() -{ - std::vector params(0); - auto response = this->callFunction(Function::Ping, params); - - return std::make_tuple(response[0], response[1]); -} - -EssentialRoot::EssentialRoot(hidpp::Device* dev) : EssentialFeature(dev, ID) -{ -} - -feature_info EssentialRoot::getFeature(uint16_t feature_id) -{ - auto params = _genGetFeatureParams(feature_id); - try { - auto response = this->callFunction(Root::Function::GetFeature, params); - return _genGetFeatureInfo(feature_id, response); - } catch(Error& e) { - if(e.code() == Error::InvalidFeatureIndex) - throw UnsupportedFeature(feature_id); - throw e; - } -} - -std::tuple EssentialRoot::getVersion() -{ +std::tuple Root::getVersion() { std::vector params(0); auto response = this->callFunction(Root::Function::Ping, params); - if(response[0] == 0x11) + if (response[0] == 0x11) return std::make_tuple(1, 0); return std::make_tuple(response[0], response[1]); diff --git a/src/logid/backend/hidpp20/features/Root.h b/src/logid/backend/hidpp20/features/Root.h index 6d699aa..2558b28 100644 --- a/src/logid/backend/hidpp20/features/Root.h +++ b/src/logid/backend/hidpp20/features/Root.h @@ -23,46 +23,31 @@ #include "../EssentialFeature.h" #include "../feature_defs.h" -namespace logid { -namespace backend { -namespace hidpp20 -{ - class Root : public Feature - { +namespace logid::backend::hidpp20 { + + class Root : public EssentialFeature { public: static const uint16_t ID = FeatureID::ROOT; - virtual uint16_t getID() { return ID; } - enum Function : uint8_t - { + uint16_t getID() final { return ID; } + + explicit Root(hidpp::Device* device); + + enum Function : uint8_t { GetFeature = 0, Ping = 1 }; - explicit Root(Device* device); + feature_info getFeature(uint16_t feature_id); - feature_info getFeature (uint16_t feature_id); std::tuple getVersion(); - enum FeatureFlag : uint8_t - { - Obsolete = 1<<7, - Hidden = 1<<6, - Internal = 1<<5 + enum FeatureFlag : uint8_t { + Obsolete = 1 << 7, + Hidden = 1 << 6, + Internal = 1 << 5 }; }; - - class EssentialRoot : public EssentialFeature - { - public: - static const uint16_t ID = FeatureID::ROOT; - virtual uint16_t getID() { return ID; } - - explicit EssentialRoot(hidpp::Device* device); - - feature_info getFeature(uint16_t feature_id); - std::tuple getVersion(); - }; -}}} +} #endif //LOGID_BACKEND_HIDPP20_FEATURE_ROOT_H \ No newline at end of file diff --git a/src/logid/backend/hidpp20/features/SmartShift.cpp b/src/logid/backend/hidpp20/features/SmartShift.cpp index 2170f10..9f7ab67 100644 --- a/src/logid/backend/hidpp20/features/SmartShift.cpp +++ b/src/logid/backend/hidpp20/features/SmartShift.cpp @@ -19,29 +19,26 @@ using namespace logid::backend::hidpp20; -SmartShift::SmartShift(Device* dev) : Feature(dev, ID) -{ +SmartShift::SmartShift(Device* dev) : Feature(dev, ID) { } -SmartShift::SmartshiftStatus SmartShift::getStatus() -{ +SmartShift::SmartshiftStatus SmartShift::getStatus() { std::vector params(0); SmartshiftStatus status{}; auto response = callFunction(GetStatus, params); - status.active = response[0]-1; + status.active = response[0] - 1; status.autoDisengage = response[1]; status.defaultAutoDisengage = response[2]; return status; } -void SmartShift::setStatus(SmartshiftStatus status) -{ +void SmartShift::setStatus(SmartshiftStatus status) { std::vector params(3); - if(status.setActive) + if (status.setActive) params[0] = status.active + 1; - if(status.setAutoDisengage) + if (status.setAutoDisengage) params[1] = status.autoDisengage; - if(status.setDefaultAutoDisengage) + if (status.setDefaultAutoDisengage) params[2] = status.defaultAutoDisengage; callFunction(SetStatus, params); } \ No newline at end of file diff --git a/src/logid/backend/hidpp20/features/SmartShift.h b/src/logid/backend/hidpp20/features/SmartShift.h index 92f4fb1..c06b38b 100644 --- a/src/logid/backend/hidpp20/features/SmartShift.h +++ b/src/logid/backend/hidpp20/features/SmartShift.h @@ -21,15 +21,12 @@ #include "../feature_defs.h" #include "../Feature.h" -namespace logid { -namespace backend { -namespace hidpp20 -{ - class SmartShift : public Feature - { +namespace logid::backend::hidpp20 { + class SmartShift : public Feature { public: static const uint16_t ID = FeatureID::SMART_SHIFT; - virtual uint16_t getID() { return ID; } + + uint16_t getID() final { return ID; } enum Function { GetStatus = 0, @@ -38,8 +35,7 @@ namespace hidpp20 explicit SmartShift(Device* dev); - struct SmartshiftStatus - { + struct SmartshiftStatus { bool active; uint8_t autoDisengage; uint8_t defaultAutoDisengage; @@ -47,8 +43,9 @@ namespace hidpp20 }; SmartshiftStatus getStatus(); + void setStatus(SmartshiftStatus status); }; -}}} +} #endif //LOGID_BACKEND_HIDPP20_FEATURE_SMARTSHIFT_H diff --git a/src/logid/backend/hidpp20/features/ThumbWheel.cpp b/src/logid/backend/hidpp20/features/ThumbWheel.cpp index a4262ea..261726f 100644 --- a/src/logid/backend/hidpp20/features/ThumbWheel.cpp +++ b/src/logid/backend/hidpp20/features/ThumbWheel.cpp @@ -21,12 +21,10 @@ using namespace logid::backend::hidpp20; -ThumbWheel::ThumbWheel(Device *dev) : Feature(dev, ID) -{ +ThumbWheel::ThumbWheel(Device* dev) : Feature(dev, ID) { } -ThumbWheel::ThumbwheelInfo ThumbWheel::getInfo() -{ +ThumbWheel::ThumbwheelInfo ThumbWheel::getInfo() { std::vector params(0), response; ThumbwheelInfo info{}; response = callFunction(GetInfo, params); @@ -43,20 +41,20 @@ ThumbWheel::ThumbwheelInfo ThumbWheel::getInfo() return info; } -ThumbWheel::ThumbwheelStatus ThumbWheel::getStatus() -{ +ThumbWheel::ThumbwheelStatus ThumbWheel::getStatus() { std::vector params(0), response; ThumbwheelStatus status{}; response = callFunction(GetStatus, params); status.diverted = response[0]; status.inverted = response[1] & 1; + status.touch = response[1] & (1 << 1); + status.proxy = response[1] & (1 << 2); return status; } -ThumbWheel::ThumbwheelStatus ThumbWheel::setStatus(bool divert, bool invert) -{ +ThumbWheel::ThumbwheelStatus ThumbWheel::setStatus(bool divert, bool invert) { std::vector params(2), response; ThumbwheelStatus status{}; params[0] = divert; @@ -69,13 +67,10 @@ ThumbWheel::ThumbwheelStatus ThumbWheel::setStatus(bool divert, bool invert) return status; } -ThumbWheel::ThumbwheelEvent ThumbWheel::thumbwheelEvent( - const hidpp::Report& report) -{ +ThumbWheel::ThumbwheelEvent ThumbWheel::thumbwheelEvent(const hidpp::Report& report) { assert(report.function() == Event); ThumbwheelEvent event{}; - event.rotation = report.paramBegin()[1]; - event.rotation |= report.paramBegin()[0] << 8; + event.rotation = (int16_t) ((report.paramBegin()[0] << 8) | report.paramBegin()[1]); event.timestamp = report.paramBegin()[3]; event.timestamp |= report.paramBegin()[2] << 8; event.rotationStatus = static_cast(report.paramBegin()[4]); diff --git a/src/logid/backend/hidpp20/features/ThumbWheel.h b/src/logid/backend/hidpp20/features/ThumbWheel.h index b66dc2a..43adf76 100644 --- a/src/logid/backend/hidpp20/features/ThumbWheel.h +++ b/src/logid/backend/hidpp20/features/ThumbWheel.h @@ -21,15 +21,12 @@ #include "../feature_defs.h" #include "../Feature.h" -namespace logid { -namespace backend { -namespace hidpp20 -{ - class ThumbWheel : public Feature - { +namespace logid::backend::hidpp20 { + class ThumbWheel : public Feature { public: static const uint16_t ID = FeatureID::THUMB_WHEEL; - virtual uint16_t getID() { return ID; } + + uint16_t getID() final { return ID; } enum Function { GetInfo = 0, @@ -43,12 +40,11 @@ namespace hidpp20 explicit ThumbWheel(Device* dev); - enum Capabilities : uint8_t - { + enum Capabilities : uint8_t { Timestamp = 1, - Touch = 1<<1, - Proxy = 1<<2, - SingleTap = 1<<3 + Touch = 1 << 1, + Proxy = 1 << 2, + SingleTap = 1 << 3 }; struct ThumbwheelInfo { @@ -66,8 +62,7 @@ namespace hidpp20 bool proxy; }; - enum RotationStatus : uint8_t - { + enum RotationStatus : uint8_t { Inactive = 0, Start = 1, Active = 2, @@ -81,14 +76,14 @@ namespace hidpp20 uint8_t flags; }; - ThumbwheelInfo getInfo(); - ThumbwheelStatus getStatus(); + [[nodiscard]] ThumbwheelInfo getInfo(); + + [[nodiscard]] ThumbwheelStatus getStatus(); ThumbwheelStatus setStatus(bool divert, bool invert); - [[nodiscard]] ThumbwheelEvent thumbwheelEvent( - const hidpp::Report& report); + [[nodiscard]] static ThumbwheelEvent thumbwheelEvent(const hidpp::Report& report); }; -}}} +} #endif //LOGID_BACKEND_HIDPP20_FEATURE_THUMBWHEEL_H diff --git a/src/logid/backend/hidpp20/features/WirelessDeviceStatus.cpp b/src/logid/backend/hidpp20/features/WirelessDeviceStatus.cpp index d8c526b..7c26362 100644 --- a/src/logid/backend/hidpp20/features/WirelessDeviceStatus.cpp +++ b/src/logid/backend/hidpp20/features/WirelessDeviceStatus.cpp @@ -20,13 +20,11 @@ using namespace logid::backend::hidpp20; -WirelessDeviceStatus::WirelessDeviceStatus(Device* dev) : Feature(dev, ID) -{ +WirelessDeviceStatus::WirelessDeviceStatus(Device* dev) : Feature(dev, ID) { } WirelessDeviceStatus::Status WirelessDeviceStatus::statusBroadcastEvent( - const hidpp::Report &report) -{ + const hidpp::Report& report) { assert(report.function() == StatusBroadcast); Status status = {}; auto params = report.paramBegin(); diff --git a/src/logid/backend/hidpp20/features/WirelessDeviceStatus.h b/src/logid/backend/hidpp20/features/WirelessDeviceStatus.h index 77d6f15..4871dea 100644 --- a/src/logid/backend/hidpp20/features/WirelessDeviceStatus.h +++ b/src/logid/backend/hidpp20/features/WirelessDeviceStatus.h @@ -21,32 +21,27 @@ #include "../Feature.h" #include "../feature_defs.h" -namespace logid { -namespace backend { -namespace hidpp20 -{ - class WirelessDeviceStatus : public Feature - { +namespace logid::backend::hidpp20 { + class WirelessDeviceStatus : public Feature { public: static constexpr uint16_t ID = FeatureID::WIRELESS_DEVICE_STATUS; - virtual uint16_t getID() { return ID; } - WirelessDeviceStatus(Device* dev); + [[nodiscard]] uint16_t getID() final { return ID; } - enum Event : uint8_t - { + explicit WirelessDeviceStatus(Device* dev); + + enum Event : uint8_t { StatusBroadcast = 0 }; - struct Status - { + struct Status { bool reconnection; bool reconfNeeded; bool powerSwitch; }; - static Status statusBroadcastEvent(const hidpp::Report &report); + static Status statusBroadcastEvent(const hidpp::Report& report); }; -}}} +} #endif //LOGID_BACKEND_HIDPP20_FEATURE_WIRELESSDEVICESTATUS_H diff --git a/src/logid/backend/raw/DeviceMonitor.cpp b/src/logid/backend/raw/DeviceMonitor.cpp index 145d37a..9a85da2 100644 --- a/src/logid/backend/raw/DeviceMonitor.cpp +++ b/src/logid/backend/raw/DeviceMonitor.cpp @@ -26,35 +26,33 @@ extern "C" { -#include #include } using namespace logid; using namespace logid::backend::raw; -DeviceMonitor::DeviceMonitor() : _io_monitor (std::make_shared()), - _ready (false) -{ +DeviceMonitor::DeviceMonitor() : _io_monitor(std::make_shared()), + _ready(false) { int ret; _udev_context = udev_new(); - if(!_udev_context) + if (!_udev_context) throw std::runtime_error("udev_new failed"); _udev_monitor = udev_monitor_new_from_netlink(_udev_context, "udev"); - if(!_udev_monitor) { - if(_udev_context) + if (!_udev_monitor) { + if (_udev_context) udev_unref(_udev_context); throw std::runtime_error("udev_monitor_new_from_netlink failed"); } ret = udev_monitor_filter_add_match_subsystem_devtype( _udev_monitor, "hidraw", nullptr); - if(0 != ret) { - if(_udev_monitor) + if (0 != ret) { + if (_udev_monitor) udev_monitor_unref(_udev_monitor); - if(_udev_context) + if (_udev_context) udev_unref(_udev_context); throw std::system_error( -ret, std::system_category(), @@ -62,10 +60,10 @@ DeviceMonitor::DeviceMonitor() : _io_monitor (std::make_shared()), } ret = udev_monitor_enable_receiving(_udev_monitor); - if(0 != ret) { - if(_udev_monitor) + if (0 != ret) { + if (_udev_monitor) udev_monitor_unref(_udev_monitor); - if(_udev_context) + if (_udev_context) udev_unref(_udev_context); throw std::system_error(-ret, std::system_category(), "udev_monitor_enable_receiving"); @@ -74,34 +72,32 @@ DeviceMonitor::DeviceMonitor() : _io_monitor (std::make_shared()), _fd = udev_monitor_get_fd(_udev_monitor); } -DeviceMonitor::~DeviceMonitor() -{ - if(_ready) +DeviceMonitor::~DeviceMonitor() { + if (_ready) _io_monitor->remove(_fd); - if(_udev_monitor) + if (_udev_monitor) udev_monitor_unref(_udev_monitor); - if(_udev_context) + if (_udev_context) udev_unref(_udev_context); } -void DeviceMonitor::ready() -{ - if(_ready) +void DeviceMonitor::ready() { + if (_ready) return; _ready = true; _io_monitor->add(_fd, { [this]() { - struct udev_device *device = udev_monitor_receive_device( + struct udev_device* device = udev_monitor_receive_device( _udev_monitor); std::string action = udev_device_get_action(device); - std::string devnode = udev_device_get_devnode(device); + std::string dev_node = udev_device_get_devnode(device); if (action == "add") - spawn_task([this, devnode]() { _addHandler(devnode); }); + spawn_task([this, dev_node]() { _addHandler(dev_node); }); else if (action == "remove") - spawn_task([this, devnode]() { _removeHandler(devnode); }); + spawn_task([this, dev_node]() { _removeHandler(dev_node); }); udev_device_unref(device); }, @@ -114,66 +110,62 @@ void DeviceMonitor::ready() }); } -void DeviceMonitor::enumerate() -{ +void DeviceMonitor::enumerate() { int ret; struct udev_enumerate* udev_enum = udev_enumerate_new(_udev_context); ret = udev_enumerate_add_match_subsystem(udev_enum, "hidraw"); - if(0 != ret) + if (0 != ret) throw std::system_error(-ret, std::system_category(), - "udev_enumerate_add_match_subsystem"); + "udev_enumerate_add_match_subsystem"); ret = udev_enumerate_scan_devices(udev_enum); - if(0 != ret) + if (0 != ret) throw std::system_error(-ret, std::system_category(), "udev_enumerate_scan_devices"); struct udev_list_entry* udev_enum_entry; udev_list_entry_foreach(udev_enum_entry, - udev_enumerate_get_list_entry(udev_enum)) { + udev_enumerate_get_list_entry(udev_enum)) { const char* name = udev_list_entry_get_name(udev_enum_entry); struct udev_device* device = udev_device_new_from_syspath(_udev_context, - name); - if(!device) + name); + if (!device) throw std::runtime_error("udev_device_new_from_syspath failed"); - std::string devnode = udev_device_get_devnode(device); + std::string dev_node = udev_device_get_devnode(device); udev_device_unref(device); - _addHandler(devnode); + _addHandler(dev_node); } udev_enumerate_unref(udev_enum); } -void DeviceMonitor::_addHandler(const std::string& device) -{ +void DeviceMonitor::_addHandler(const std::string& device) { try { auto supported_reports = backend::hidpp::getSupportedReports( RawDevice::getReportDescriptor(device)); - if(supported_reports) + if (supported_reports) this->addDevice(device); else logPrintf(DEBUG, "Unsupported device %s ignored", device.c_str()); - } catch(std::exception& e) { + } catch (std::exception& e) { logPrintf(WARN, "Error adding device %s: %s", device.c_str(), e.what()); } } -void DeviceMonitor::_removeHandler(const std::string& device) -{ +void DeviceMonitor::_removeHandler(const std::string& device) { try { this->removeDevice(device); - } catch(std::exception& e) { + } catch (std::exception& e) { logPrintf(WARN, "Error removing device %s: %s", device.c_str(), e.what()); } } -std::shared_ptr DeviceMonitor::ioMonitor() const -{ +std::shared_ptr DeviceMonitor::ioMonitor() const { return _io_monitor; } diff --git a/src/logid/backend/raw/DeviceMonitor.h b/src/logid/backend/raw/DeviceMonitor.h index 80abf00..ef7cbc7 100644 --- a/src/logid/backend/raw/DeviceMonitor.h +++ b/src/logid/backend/raw/DeviceMonitor.h @@ -27,28 +27,32 @@ extern "C" { - struct udev; - struct udev_monitor; +struct udev; +struct udev_monitor; } -namespace logid::backend::raw -{ - class DeviceMonitor - { +namespace logid::backend::raw { + class DeviceMonitor { public: virtual ~DeviceMonitor(); void enumerate(); + [[nodiscard]] std::shared_ptr ioMonitor() const; protected: DeviceMonitor(); + // This should be run once the derived class is ready void ready(); + virtual void addDevice(std::string device) = 0; + virtual void removeDevice(std::string device) = 0; + private: void _addHandler(const std::string& device); + void _removeHandler(const std::string& device); std::shared_ptr _io_monitor; diff --git a/src/logid/backend/raw/defs.h b/src/logid/backend/raw/EventHandler.h similarity index 86% rename from src/logid/backend/raw/defs.h rename to src/logid/backend/raw/EventHandler.h index 53f9848..b845e23 100644 --- a/src/logid/backend/raw/defs.h +++ b/src/logid/backend/raw/EventHandler.h @@ -23,21 +23,16 @@ #include #include -namespace logid { -namespace backend { -namespace raw -{ - struct RawEventHandler - { +namespace logid::backend::raw { + struct RawEventHandler { std::function&)> condition; std::function&)> callback; RawEventHandler(std::function&)> cond, std::function&)> call) : - condition (std::move(cond)), callback (std::move(call)) - { + condition(std::move(cond)), callback(std::move(call)) { } }; -}}} +} #endif //LOGID_BACKEND_RAW_DEFS_H \ No newline at end of file diff --git a/src/logid/backend/raw/IOMonitor.cpp b/src/logid/backend/raw/IOMonitor.cpp index 9cc23c2..e89fa00 100644 --- a/src/logid/backend/raw/IOMonitor.cpp +++ b/src/logid/backend/raw/IOMonitor.cpp @@ -30,24 +30,21 @@ using namespace logid::backend::raw; IOHandler::IOHandler(std::function r, std::function hup, std::function err) : - read (std::move(r)), - hangup (std::move(hup)), - error (std::move(err)) -{ + read(std::move(r)), + hangup(std::move(hup)), + error(std::move(err)) { } -IOMonitor::IOMonitor() : _epoll_fd (epoll_create1(0)), - _event_fd(eventfd(0, EFD_NONBLOCK)) -{ - if(_epoll_fd < 0) { - if(_event_fd >= 0) +IOMonitor::IOMonitor() : _epoll_fd(epoll_create1(0)), + _event_fd(eventfd(0, EFD_NONBLOCK)) { + if (_epoll_fd < 0) { + if (_event_fd >= 0) close(_event_fd); throw std::runtime_error("failed to create epoll fd"); } - if(_event_fd < 0) { - if(_epoll_fd >= 0) - close(_epoll_fd); + if (_event_fd < 0) { + close(_epoll_fd); throw std::runtime_error("failed to create event fd"); } @@ -55,84 +52,80 @@ IOMonitor::IOMonitor() : _epoll_fd (epoll_create1(0)), event.events = EPOLLIN; event.data.fd = _event_fd; - if(::epoll_ctl(_epoll_fd, EPOLL_CTL_ADD, _event_fd, &event)) { + if (::epoll_ctl(_epoll_fd, EPOLL_CTL_ADD, _event_fd, &event)) { throw std::system_error(errno, std::generic_category()); } - _fds.emplace(std::piecewise_construct,std::forward_as_tuple(_event_fd), - std::forward_as_tuple([]() { },[]() { - throw std::runtime_error("eventfd hangup"); - },[]() { - throw std::runtime_error("eventfd error"); - })); + _fds.emplace(std::piecewise_construct, std::forward_as_tuple(_event_fd), + std::forward_as_tuple([]() {}, []() { + throw std::runtime_error("event_fd hangup"); + }, []() { + throw std::runtime_error("event_fd error"); + })); - _io_thread = std::make_unique([this](){ + _io_thread = std::make_unique([this]() { _listen(); }); } -IOMonitor::~IOMonitor() noexcept -{ +IOMonitor::~IOMonitor() noexcept { std::lock_guard ctl_lock(_ctl_lock); _stop(); - if(_event_fd >= 0) + if (_event_fd >= 0) close(_event_fd); - if(_epoll_fd >= 0) + if (_epoll_fd >= 0) close(_epoll_fd); } -void IOMonitor::_listen() -{ +void IOMonitor::_listen() { std::lock_guard run_lock(_run_lock); std::vector events; _is_running = true; - while(_is_running) { + while (_is_running) { { std::unique_lock lock(_interrupt_lock); - _interrupt_cv.wait(lock, [this](){ - return !(bool)_interrupting; + _interrupt_cv.wait(lock, [this]() { + return !(bool) _interrupting; }); - if(!_is_running) + if (!_is_running) break; } std::lock_guard io_lock(_io_lock); - if(events.size() != _fds.size()) + if (events.size() != _fds.size()) events.resize(_fds.size()); - int eventc = ::epoll_wait(_epoll_fd, events.data(), events.size(), -1); - for(int i = 0; i < eventc; ++i) { + int ev_count = ::epoll_wait(_epoll_fd, events.data(), (int) events.size(), -1); + for (int i = 0; i < ev_count; ++i) { const auto& handler = _fds.at(events[i].data.fd); - if(events[i].events & EPOLLIN) + if (events[i].events & EPOLLIN) handler.read(); - if(events[i].events & EPOLLHUP) + if (events[i].events & EPOLLHUP) handler.hangup(); - if(events[i].events & EPOLLERR) + if (events[i].events & EPOLLERR) handler.error(); } } } -void IOMonitor::_stop() noexcept -{ +void IOMonitor::_stop() noexcept { _interrupt(); _is_running = false; _continue(); _io_thread->join(); } -bool IOMonitor::_running() const -{ +[[maybe_unused]] +bool IOMonitor::_running() const { std::unique_lock run_lock(_run_lock, std::try_to_lock); return !run_lock.owns_lock() || _is_running; } -void IOMonitor::add(int fd, IOHandler handler) -{ +void IOMonitor::add(int fd, IOHandler handler) { std::lock_guard lock(_ctl_lock); _interrupt(); @@ -141,12 +134,12 @@ void IOMonitor::add(int fd, IOHandler handler) event.data.fd = fd; // TODO: EPOLL_CTL_MOD - if(_fds.contains(fd)) { + if (_fds.contains(fd)) { _continue(); throw std::runtime_error("duplicate io fd"); } - if(::epoll_ctl(_epoll_fd, EPOLL_CTL_ADD, fd, &event)) { + if (::epoll_ctl(_epoll_fd, EPOLL_CTL_ADD, fd, &event)) { _continue(); throw std::system_error(errno, std::generic_category()); } @@ -155,8 +148,7 @@ void IOMonitor::add(int fd, IOHandler handler) _continue(); } -void IOMonitor::remove(int fd) noexcept -{ +void IOMonitor::remove(int fd) noexcept { std::lock_guard lock(_ctl_lock); _interrupt(); std::lock_guard io_lock(_io_lock); @@ -167,8 +159,7 @@ void IOMonitor::remove(int fd) noexcept _continue(); } -void IOMonitor::_interrupt() noexcept -{ +void IOMonitor::_interrupt() noexcept { std::unique_lock run_lock(_run_lock, std::try_to_lock); _interrupting = true; @@ -182,8 +173,7 @@ void IOMonitor::_interrupt() noexcept } -void IOMonitor::_continue() noexcept -{ +void IOMonitor::_continue() noexcept { std::unique_lock run_lock(_run_lock, std::try_to_lock); uint64_t counter; @@ -191,7 +181,7 @@ void IOMonitor::_continue() noexcept assert(ret != -1); - if(counter == 1) { + if (counter == 1) { _interrupting = false; _interrupt_cv.notify_all(); } diff --git a/src/logid/backend/raw/IOMonitor.h b/src/logid/backend/raw/IOMonitor.h index 36ec1d0..9453dc9 100644 --- a/src/logid/backend/raw/IOMonitor.h +++ b/src/logid/backend/raw/IOMonitor.h @@ -35,21 +35,25 @@ namespace logid::backend::raw { std::function err); }; - class IOMonitor - { + class IOMonitor { public: IOMonitor(); + ~IOMonitor() noexcept; void add(int fd, IOHandler handler); + void remove(int fd) noexcept; + private: void _listen(); // This is a blocking call void _stop() noexcept; - bool _running() const; + [[maybe_unused]] + [[nodiscard]] bool _running() const; void _interrupt() noexcept; + void _continue() noexcept; std::unique_ptr _io_thread; diff --git a/src/logid/backend/raw/RawDevice.cpp b/src/logid/backend/raw/RawDevice.cpp index 86fcaf0..a754e7a 100644 --- a/src/logid/backend/raw/RawDevice.cpp +++ b/src/logid/backend/raw/RawDevice.cpp @@ -19,7 +19,6 @@ #include "RawDevice.h" #include "DeviceMonitor.h" #include "IOMonitor.h" -#include "../Error.h" #include "../../util/log.h" #include @@ -39,31 +38,28 @@ using namespace logid::backend::raw; using namespace logid::backend; using namespace std::chrono; -int get_fd(const std::string& path) -{ +int get_fd(const std::string& path) { int fd = ::open(path.c_str(), O_RDWR | O_NONBLOCK); - if(fd == -1) + if (fd == -1) throw std::system_error(errno, std::system_category(), "RawDevice open failed"); return fd; } -RawDevice::dev_info get_devinfo(int fd) -{ - hidraw_devinfo devinfo{}; - if (-1 == ::ioctl(fd, HIDIOCGRAWINFO, &devinfo)) { +RawDevice::dev_info get_dev_info(int fd) { + hidraw_devinfo dev_info{}; + if (-1 == ::ioctl(fd, HIDIOCGRAWINFO, &dev_info)) { int err = errno; ::close(fd); throw std::system_error(err, std::system_category(), "RawDevice HIDIOCGRAWINFO failed"); } - return {devinfo.vendor, devinfo.product}; + return {dev_info.vendor, dev_info.product}; } -std::string get_name(int fd) -{ +std::string get_name(int fd) { ssize_t len; char name_buf[256]; if (-1 == (len = ::ioctl(fd, HIDIOCGRAWNAME(sizeof(name_buf)), name_buf))) { @@ -75,128 +71,111 @@ std::string get_name(int fd) return {name_buf, static_cast(len)}; } -RawDevice::RawDevice(std::string path, - std::shared_ptr monitor) : - _valid (true), - _path (std::move(path)), - _fd (get_fd(_path)), - _devinfo (get_devinfo(_fd)), - _name (get_name(_fd)), - _rdesc (getReportDescriptor(_fd)), - _io_monitor (monitor->ioMonitor()) -{ +RawDevice::RawDevice(std::string path, const std::shared_ptr& monitor) : + _valid(true), _path(std::move(path)), _fd(get_fd(_path)), + _dev_info(get_dev_info(_fd)), _name(get_name(_fd)), + _report_desc(getReportDescriptor(_fd)), _io_monitor(monitor->ioMonitor()) { _io_monitor->add(_fd, { - [this]() { _readReports(); }, - [this]() { _valid = false; }, - [this]() { _valid = false; } + [this]() { _readReports(); }, + [this]() { _valid = false; }, + [this]() { _valid = false; } }); } -RawDevice::~RawDevice() noexcept -{ +RawDevice::~RawDevice() noexcept { _io_monitor->remove(_fd); ::close(_fd); } -const std::string& RawDevice::rawPath() const -{ +const std::string& RawDevice::rawPath() const { return _path; } -const std::string& RawDevice::name() const -{ +const std::string& RawDevice::name() const { return _name; } -int16_t RawDevice::vendorId() const -{ - return _devinfo.vid; +[[maybe_unused]] +int16_t RawDevice::vendorId() const { + return _dev_info.vid; } -int16_t RawDevice::productId() const -{ - return _devinfo.pid; +int16_t RawDevice::productId() const { + return _dev_info.pid; } -std::vector RawDevice::getReportDescriptor(std::string path) -{ +std::vector RawDevice::getReportDescriptor(const std::string& path) { int fd = ::open(path.c_str(), O_RDWR | O_NONBLOCK); if (fd == -1) throw std::system_error(errno, std::system_category(), "open failed"); - auto rdesc = getReportDescriptor(fd); + auto report_desc = getReportDescriptor(fd); ::close(fd); - return rdesc; + return report_desc; } -std::vector RawDevice::getReportDescriptor(int fd) -{ - hidraw_report_descriptor rdesc{}; - if (-1 == ::ioctl(fd, HIDIOCGRDESCSIZE, &rdesc.size)) { +std::vector RawDevice::getReportDescriptor(int fd) { + hidraw_report_descriptor report_desc{}; + if (-1 == ::ioctl(fd, HIDIOCGRDESCSIZE, &report_desc.size)) { int err = errno; ::close(fd); throw std::system_error(err, std::system_category(), "RawDevice HIDIOCGRDESCSIZE failed"); } - if (-1 == ::ioctl(fd, HIDIOCGRDESC, &rdesc)) { + if (-1 == ::ioctl(fd, HIDIOCGRDESC, &report_desc)) { int err = errno; ::close(fd); throw std::system_error(err, std::system_category(), "RawDevice HIDIOCGRDESC failed"); } - return std::vector(rdesc.value, rdesc.value + rdesc.size); + return {report_desc.value, report_desc.value + report_desc.size}; } -const std::vector& RawDevice::reportDescriptor() const -{ - return _rdesc; +const std::vector& RawDevice::reportDescriptor() const { + return _report_desc; } -void RawDevice::sendReport(const std::vector& report) -{ - if(!_valid) { +void RawDevice::sendReport(const std::vector& report) { + if (!_valid) { // We could throw an error here, but this will likely be closed soon. return; } - if(logid::global_loglevel <= LogLevel::RAWREPORT) { + if (logid::global_loglevel <= LogLevel::RAWREPORT) { printf("[RAWREPORT] %s OUT: ", _path.c_str()); - for(auto &i : report) + for (auto& i: report) printf("%02x ", i); printf("\n"); } - if(write(_fd, report.data(), report.size()) == -1) + if (write(_fd, report.data(), report.size()) == -1) throw std::system_error(errno, std::system_category(), "sendReport write failed"); } -RawDevice::EvHandlerId RawDevice::addEventHandler(RawEventHandler handler) -{ +RawDevice::EvHandlerId RawDevice::addEventHandler(RawEventHandler handler) { std::lock_guard lock(_event_handler_lock); _event_handlers.emplace_front(std::move(handler)); return _event_handlers.cbegin(); } -void RawDevice::removeEventHandler(RawDevice::EvHandlerId id) -{ +void RawDevice::removeEventHandler(RawDevice::EvHandlerId id) { std::lock_guard lock(_event_handler_lock); _event_handlers.erase(id); } -void RawDevice::_readReports() -{ +void RawDevice::_readReports() { uint8_t buf[max_data_length]; ssize_t len; - while(-1 != (len = ::read(_fd, buf, max_data_length))) { + while (-1 != (len = ::read(_fd, buf, max_data_length))) { assert(len <= max_data_length); std::vector report(buf, buf + len); - if(logid::global_loglevel <= LogLevel::RAWREPORT) { + if (logid::global_loglevel <= LogLevel::RAWREPORT) { printf("[RAWREPORT] %s IN: ", _path.c_str()); - for(auto &i : report) + for (auto& i: report) printf("%02x ", i); printf("\n"); } @@ -205,10 +184,9 @@ void RawDevice::_readReports() } } -void RawDevice::_handleEvent(const std::vector& report) -{ +void RawDevice::_handleEvent(const std::vector& report) { std::unique_lock lock(_event_handler_lock); - for(auto& handler : _event_handlers) - if(handler.condition(report)) + for (auto& handler: _event_handlers) + if (handler.condition(report)) handler.callback(report); } diff --git a/src/logid/backend/raw/RawDevice.h b/src/logid/backend/raw/RawDevice.h index fabfd30..5b8b7f0 100644 --- a/src/logid/backend/raw/RawDevice.h +++ b/src/logid/backend/raw/RawDevice.h @@ -28,15 +28,14 @@ #include #include -#include "defs.h" +#include "EventHandler.h" -namespace logid::backend::raw -{ +namespace logid::backend::raw { class DeviceMonitor; + class IOMonitor; - class RawDevice - { + class RawDevice { public: static constexpr int max_data_length = 32; typedef std::list::const_iterator EvHandlerId; @@ -47,22 +46,29 @@ namespace logid::backend::raw }; RawDevice(std::string path, - std::shared_ptr monitor); + const std::shared_ptr& monitor); + ~RawDevice() noexcept; [[nodiscard]] const std::string& rawPath() const; [[nodiscard]] const std::string& name() const; + + [[maybe_unused]] [[nodiscard]] int16_t vendorId() const; + [[nodiscard]] int16_t productId() const; - static std::vector getReportDescriptor(std::string path); + static std::vector getReportDescriptor(const std::string& path); + static std::vector getReportDescriptor(int fd); + [[nodiscard]] const std::vector& reportDescriptor() const; void sendReport(const std::vector& report); EvHandlerId addEventHandler(RawEventHandler handler); + void removeEventHandler(EvHandlerId id); private: @@ -72,14 +78,15 @@ namespace logid::backend::raw const std::string _path; const int _fd; - const dev_info _devinfo; + const dev_info _dev_info; const std::string _name; - const std::vector _rdesc; + const std::vector _report_desc; std::shared_ptr _io_monitor; std::list _event_handlers; std::mutex _event_handler_lock; + void _handleEvent(const std::vector& report); }; } diff --git a/src/logid/config/group.h b/src/logid/config/group.h index 4bcfa3f..d6b9b9d 100644 --- a/src/logid/config/group.h +++ b/src/logid/config/group.h @@ -25,53 +25,55 @@ #include "../util/log.h" namespace logid::config { - template + template void set(libconfig::Setting& parent, const std::string& name, const T& t); - template + template void set(libconfig::Setting& parent, const T& t); - template + template auto get(const libconfig::Setting& parent, const std::string& name); - template + template void append(libconfig::Setting& list, const T& t); namespace { - template - struct group_io { }; + template + struct group_io { + }; - template + template struct group_io { static inline void get( [[maybe_unused]] const libconfig::Setting& s, [[maybe_unused]] T* t, [[maybe_unused]] const std::vector& names, - [[maybe_unused]] const std::size_t index) { } + [[maybe_unused]] const std::size_t index) {} + static inline void set( [[maybe_unused]] libconfig::Setting& s, [[maybe_unused]] const T* t, [[maybe_unused]] const std::vector& names, - [[maybe_unused]] const std::size_t index) { } + [[maybe_unused]] const std::size_t index) {} }; - template + template struct group_io { static inline void get( const libconfig::Setting& s, T* t, const std::vector& names, const std::size_t index, A T::* arg, M T::*... rest) { auto& x = t->*(arg); - A old {x}; + A old{x}; try { x = config::get(s, names[index]); - group_io::get(s, t, names, index+1, rest...); - } catch(libconfig::SettingTypeException& e) { + group_io::get(s, t, names, index + 1, rest...); + } catch (libconfig::SettingTypeException& e) { x = old; throw; - } catch(libconfig::SettingException& e) { + } catch (libconfig::SettingException& e) { x = old; throw libconfig::SettingTypeException(s); } @@ -82,12 +84,12 @@ namespace logid::config { const std::vector& names, const std::size_t index, A T::* arg, M T::*... rest) { config::set(s, names[index], t->*(arg)); - group_io::set(s, t, names, index+1, rest...); + group_io::set(s, t, names, index + 1, rest...); } }; } - template + template struct signed_group; struct group { @@ -96,39 +98,43 @@ namespace logid::config { const std::function&)> _getter; const std::function&)> _setter; + const std::vector&)> _setter; - template - friend struct signed_group; + template + friend + struct signed_group; protected: - template + template explicit group(const std::array& names, - M T::*... args) : - _names (names.begin(), names.end()), - _getter ([args...](const libconfig::Setting& s, group* g, - const std::vector& names) { + M T::*... args) : + _names(names.begin(), names.end()), + _getter([args...](const libconfig::Setting& s, group* g, + const std::vector& names) { T* t = dynamic_cast(g); group_io::get(s, t, names, 0, args...); }), - _setter ([args...](libconfig::Setting& s, const group* g, - const std::vector& names) { - const T* t = dynamic_cast(g);; + _setter([args...](libconfig::Setting& s, const group* g, + const std::vector& names) { + const T* t = dynamic_cast(g); group_io::set(s, t, names, 0, args...); }) { static_assert(std::is_base_of::value); } - group() : _getter ([](const libconfig::Setting&, group*, - const std::vector&) { }), - _setter ([](libconfig::Setting&, const group*, - const std::vector&) { }) { } + group() : _getter([](const libconfig::Setting&, group*, + const std::vector&) {}), + _setter([](libconfig::Setting&, const group*, + const std::vector&) {}) {} public: group(const group& o) = default; + group(group&& o) noexcept = default; + group& operator=(const group&) { return *this; } + group& operator=(group&&) noexcept { return *this; } @@ -145,12 +151,12 @@ namespace logid::config { }; namespace { - template + template struct normalize_signature { static inline const T& make(const T& ret) { return ret; } }; - template <> + template<> struct normalize_signature { static inline std::string make(const std::string& data) { std::string ret = data; @@ -161,29 +167,33 @@ namespace logid::config { }; } - template + template struct signed_group : public group { private: const std::string _sig_field; const Sign _signature; protected: - signed_group(std::string sign_name, const Sign& sign_data) : - group(), _sig_field (std::move(sign_name)), - _signature (normalize_signature::make(sign_data)) { } + signed_group(std::string sign_name, const Sign& sign_data) : + group(), _sig_field(std::move(sign_name)), + _signature(normalize_signature::make(sign_data)) {} - template + template signed_group( std::string sign_name, const Sign& sign_data, const std::array& names, M T::*... args) : group(names, args...), - _sig_field (std::move(sign_name)), - _signature (normalize_signature::make(sign_data)) { } + _sig_field(std::move(sign_name)), + _signature(normalize_signature::make(sign_data)) {} + public: signed_group(const signed_group& o) = default; + signed_group(signed_group&& o) noexcept = default; + signed_group& operator=(const signed_group&) { return *this; } + signed_group& operator=(signed_group&&) noexcept { return *this; } @@ -194,8 +204,8 @@ namespace logid::config { } void _load(const libconfig::Setting& setting) override { - if(normalize_signature::make(get(setting, _sig_field)) - != _signature) + if (normalize_signature::make(get(setting, _sig_field)) + != _signature) throw libconfig::SettingTypeException(setting); _getter(setting, this, _names); } diff --git a/src/logid/config/map.h b/src/logid/config/map.h index 9b309b8..05a5891 100644 --- a/src/logid/config/map.h +++ b/src/logid/config/map.h @@ -26,19 +26,19 @@ namespace logid::config { template struct string_literal { - constexpr string_literal(const char (&str)[N]) { + constexpr string_literal(const char (& str)[N]) { std::copy_n(str, N, value); } - char value[N]; + char value[N]{}; }; - template + 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)) + 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(); @@ -46,14 +46,14 @@ namespace logid::config { }; // Warning: map must be a variant of groups or a group - 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)...) { } + template + explicit map(Args... args) : + std::map(std::forward(args)...) {} }; } diff --git a/src/logid/config/schema.h b/src/logid/config/schema.h index da17f2d..45f41e4 100644 --- a/src/logid/config/schema.h +++ b/src/logid/config/schema.h @@ -22,18 +22,29 @@ namespace logid::actions { class ChangeDPI; + class ChangeHostAction; + class CycleDPI; + class GestureAction; + class KeypressAction; + class NullAction; + class ToggleHiresScroll; + class ToggleSmartShift; class AxisGesture; + class IntervalGesture; + class NullGesture; + class ReleaseGesture; + class ThresholdGesture; } @@ -41,61 +52,67 @@ namespace logid::config { struct NoAction : public signed_group { typedef actions::NullAction action; - NoAction() : signed_group("type", "None") { } + + NoAction() : signed_group("type", "None") {} }; struct KeypressAction : public signed_group { typedef actions::KeypressAction action; std::optional< std::variant>>> keys; + std::list>>> keys; + KeypressAction() : signed_group( "type", "Keypress", - {"keys"}, &KeypressAction::keys) - { + {"keys"}, &KeypressAction::keys) { } }; struct ToggleSmartShift : public signed_group { typedef actions::ToggleSmartShift action; + ToggleSmartShift() : - signed_group("type", "ToggleSmartShift") { } + signed_group("type", "ToggleSmartShift") {} }; struct ToggleHiresScroll : public signed_group { typedef actions::ToggleHiresScroll action; + ToggleHiresScroll() : - signed_group("type", "ToggleHiresScroll") { } + signed_group("type", "ToggleHiresScroll") {} }; struct CycleDPI : public signed_group { typedef actions::CycleDPI action; std::optional> dpis; std::optional sensor; + CycleDPI() : signed_group( "type", "CycleDPI", {"dpis", "sensor"}, &CycleDPI::dpis, - &CycleDPI::sensor) { } + &CycleDPI::sensor) {} }; struct ChangeDPI : public signed_group { typedef actions::ChangeDPI action; std::optional inc; std::optional sensor; + ChangeDPI() : signed_group( "type", "ChangeDPI", {"inc", "sensor"}, &ChangeDPI::inc, - &ChangeDPI::sensor) { } + &ChangeDPI::sensor) {} }; struct ChangeHost : public signed_group { typedef actions::ChangeHostAction action; std::optional> host; + ChangeHost() : signed_group( "type", "ChangeHost", - {"host"}, &ChangeHost::host) { } + {"host"}, &ChangeHost::host) {} }; typedef std::variant< @@ -118,7 +135,7 @@ namespace logid::config { {"threshold", "axis", "axis_multiplier"}, &AxisGesture::threshold, &AxisGesture::axis, - &AxisGesture::axis_multiplier) { } + &AxisGesture::axis_multiplier) {} }; struct IntervalGesture : public signed_group { @@ -127,18 +144,19 @@ namespace logid::config { std::optional action; std::optional interval; protected: - IntervalGesture(const std::string& name) : signed_group( + explicit IntervalGesture(const std::string& name) : signed_group( "mode", name, {"threshold", "action", "interval"}, &IntervalGesture::threshold, &IntervalGesture::action, - &IntervalGesture::interval) { } + &IntervalGesture::interval) {} + public: - IntervalGesture() : IntervalGesture("OnInterval") { } + IntervalGesture() : IntervalGesture("OnInterval") {} }; struct FewPixelsGesture : public IntervalGesture { - FewPixelsGesture() : IntervalGesture("OnFewPixels") { } + FewPixelsGesture() : IntervalGesture("OnFewPixels") {} }; struct ReleaseGesture : public signed_group { @@ -149,7 +167,7 @@ namespace logid::config { ReleaseGesture() : signed_group("mode", "OnRelease", {"threshold", "action"}, &ReleaseGesture::threshold, - &ReleaseGesture::action) { } + &ReleaseGesture::action) {} }; struct ThresholdGesture : public signed_group { @@ -160,15 +178,16 @@ namespace logid::config { ThresholdGesture() : signed_group("mode", "OnThreshold", {"threshold", "action"}, &ThresholdGesture::threshold, - &ThresholdGesture::action) { } + &ThresholdGesture::action) {} }; struct NoGesture : public signed_group { typedef actions::NullGesture gesture; std::optional threshold; + NoGesture() : signed_group("mode", "NoPress", {"threshold"}, - &NoGesture::threshold) { } + &NoGesture::threshold) {} }; typedef std::variant< @@ -184,36 +203,38 @@ namespace logid::config { struct GestureAction : public signed_group { typedef actions::GestureAction action; std::optional>> gestures; + less_caseless>> gestures; GestureAction() : signed_group( "type", "Gestures", {"gestures"}, - &GestureAction::gestures) { } + &GestureAction::gestures) {} }; typedef std::variant< - NoAction, - KeypressAction, - ToggleSmartShift, - ToggleHiresScroll, - CycleDPI, - ChangeDPI, - ChangeHost, - GestureAction + NoAction, + KeypressAction, + ToggleSmartShift, + ToggleHiresScroll, + CycleDPI, + ChangeDPI, + ChangeHost, + GestureAction > Action; struct Button : public group { std::optional action; + Button() : group({"action"}, - &Button::action) { } + &Button::action) {} }; struct SmartShift : public group { std::optional on; std::optional threshold; + SmartShift() : group({"on", "threshold"}, - &SmartShift::on, &SmartShift::threshold) { } + &SmartShift::on, &SmartShift::threshold) {} }; @@ -223,12 +244,13 @@ namespace logid::config { std::optional target; std::optional up; std::optional down; + HiresScroll() : group({"hires", "invert", "target", "up", "down"}, &HiresScroll::hires, &HiresScroll::invert, &HiresScroll::target, &HiresScroll::up, - &HiresScroll::down) { } + &HiresScroll::down) {} }; typedef std::variant> DPI; @@ -243,11 +265,11 @@ namespace logid::config { std::optional tap; ThumbWheel() : group({"divert", "invert", "left", "right", - "proxy", "touch", "tap" }, + "proxy", "touch", "tap"}, &ThumbWheel::divert, &ThumbWheel::invert, &ThumbWheel::left, &ThumbWheel::right, &ThumbWheel::proxy, &ThumbWheel::touch, - &ThumbWheel::tap) { } + &ThumbWheel::tap) {} }; typedef map RemapButton; @@ -263,7 +285,7 @@ namespace logid::config { "buttons", "thumbwheel"}, &Profile::dpi, &Profile::smartshift, &Profile::hiresscroll, &Profile::buttons, - &Profile::thumbwheel) { } + &Profile::thumbwheel) {} }; struct Device : public group { @@ -271,22 +293,22 @@ namespace logid::config { map profiles; Device() : group({"default_profile", "profiles"}, - &Device::default_profile, - &Device::profiles), - default_profile(ipcgull::property_full_permissions, "") - { + &Device::default_profile, + &Device::profiles), + default_profile(ipcgull::property_full_permissions, "") { } }; struct Config : public group { std::optional, "name">> devices; + std::variant, "name">> devices; std::optional> ignore; std::optional io_timeout; + Config() : group({"devices", "ignore", "io_timeout"}, &Config::devices, &Config::ignore, - &Config::io_timeout) { } + &Config::io_timeout) {} }; } diff --git a/src/logid/config/types.h b/src/logid/config/types.h index 4973f3e..b74a161 100644 --- a/src/logid/config/types.h +++ b/src/logid/config/types.h @@ -35,30 +35,30 @@ namespace logid::config { namespace { - template + template struct config_io { static_assert(std::is_base_of::value); static inline T get(const libconfig::Setting& parent, - const std::string& name) { - T t {}; + const std::string& name) { + T t{}; t._load(parent.lookup(name)); return t; } static inline T get(const libconfig::Setting& setting) { - T t {}; + T t{}; t._load(setting); return t; } static inline void set(libconfig::Setting& parent, - const std::string& name, - const T& t) { - if(!parent.exists(name)) { + const std::string& name, + const T& t) { + if (!parent.exists(name)) { parent.add(name, libconfig::Setting::TypeGroup); - } else if(parent.lookup(name).getType() - != libconfig::Setting::TypeGroup) { + } else if (parent.lookup(name).getType() + != libconfig::Setting::TypeGroup) { parent.remove(name); parent.add(name, libconfig::Setting::TypeGroup); } @@ -75,13 +75,14 @@ namespace logid::config { } }; - template - struct config_io> : public config_io { }; + template + struct config_io> : public config_io { + }; - template + template struct primitive_io { static inline T get(const libconfig::Setting& parent, - const std::string& name) { + const std::string& name) { return parent.lookup(name); } @@ -90,11 +91,11 @@ namespace logid::config { } static inline void set(libconfig::Setting& parent, - const std::string& name, - const T& t) { - if(!parent.exists(name)) { + const std::string& name, + const T& t) { + if (!parent.exists(name)) { parent.add(name, TypeEnum); - } else if(parent.lookup(name).getType() != TypeEnum) { + } else if (parent.lookup(name).getType() != TypeEnum) { parent.remove(name); parent.add(name, TypeEnum); } @@ -111,10 +112,10 @@ namespace logid::config { } }; - template + template struct reinterpret_io { static inline T get(const libconfig::Setting& parent, - const std::string& name) { + const std::string& name) { return static_cast(primitive_io::get(parent, name)); } @@ -123,8 +124,8 @@ namespace logid::config { } static inline void set(libconfig::Setting& parent, - const std::string& name, - const T& t) { + const std::string& name, + const T& t) { primitive_io::set(parent, name, static_cast(t)); } @@ -134,74 +135,90 @@ namespace logid::config { static_cast(t)); } + [[maybe_unused]] static inline void append(libconfig::Setting& list, const T& t) { primitive_io::append(list, static_cast(t)); } }; - template <> + template<> struct config_io : public primitive_io { }; - template <> + libconfig::Setting::TypeBoolean> { + }; + template<> struct config_io : public reinterpret_io { }; - template <> + libconfig::Setting::TypeInt> { + }; + template<> struct config_io : public reinterpret_io { }; - template <> + libconfig::Setting::TypeInt> { + }; + template<> struct config_io : public reinterpret_io { }; - template <> + libconfig::Setting::TypeInt> { + }; + template<> struct config_io : public reinterpret_io { }; - template <> + int, libconfig::Setting::TypeInt> { + }; + template<> struct config_io : public primitive_io { }; - template <> + libconfig::Setting::TypeInt> { + }; + template<> struct config_io : public reinterpret_io { }; - template <> + int, libconfig::Setting::TypeInt> { + }; + template<> struct config_io : public reinterpret_io { }; - template <> + libconfig::Setting::TypeInt64> { + }; + template<> struct config_io : public reinterpret_io { }; - template <> + long long, libconfig::Setting::TypeInt64> { + }; + template<> struct config_io : public primitive_io { }; - template <> + libconfig::Setting::TypeInt64> { + }; + template<> struct config_io : public reinterpret_io { }; - template <> + libconfig::Setting::TypeInt64> { + }; + template<> struct config_io : public primitive_io { }; - template <> + libconfig::Setting::TypeFloat> { + }; + template<> struct config_io : public primitive_io { }; - template <> + libconfig::Setting::TypeFloat> { + }; + template<> struct config_io : public primitive_io { }; + libconfig::Setting::TypeString> { + }; - template + template struct config_io> { private: - template + template static inline std::variant try_each( const libconfig::Setting& setting) { return config_io::get(setting); } - template + template static inline std::variant try_each( const libconfig::Setting& setting) { try { return config_io::get(setting); - } catch(libconfig::SettingException& e) { + } catch (libconfig::SettingException& e) { return try_each(setting); } } + public: static inline std::variant get( const libconfig::Setting& setting) { @@ -216,7 +233,7 @@ namespace logid::config { static inline void set(libconfig::Setting& setting, const std::variant& t) { - std::visit([&setting](auto&& arg){ + std::visit([&setting](auto&& arg) { config::set(setting, arg); }, t); } @@ -224,42 +241,43 @@ namespace logid::config { static inline void set(libconfig::Setting& parent, const std::string& name, const std::variant& t) { - std::visit([&parent, &name](auto&& arg){ + std::visit([&parent, &name](auto&& arg) { config::set(parent, name, arg); }, t); } + [[maybe_unused]] static inline void append(libconfig::Setting& list, const std::variant& t) { - std::visit([&list](auto&& arg){ + std::visit([&list](auto&& arg) { config::append(list, arg); }, t); } }; - template + template struct config_io> { static inline std::list get(const libconfig::Setting& setting) { const auto size = setting.getLength(); - std::list t {}; - for(int i = 0; i < size; ++i) { + std::list t{}; + for (int i = 0; i < size; ++i) { try { t.emplace_back(config_io::get(setting[i])); - } catch(libconfig::SettingException& e) { } + } catch (libconfig::SettingException& e) {} } return t; } static inline std::list get(const libconfig::Setting& parent, - const std::string& name) { + const std::string& name) { return get(parent.lookup(name)); } static inline void set(libconfig::Setting& setting, const std::list& t) { - while(setting.getLength() != 0) - setting.remove((int)0); - for(auto& x : t) { + while (setting.getLength() != 0) + setting.remove((int) 0); + for (auto& x: t) { config_io::append(setting, x); } } @@ -269,13 +287,14 @@ namespace logid::config { const std::list& t) { if (!parent.exists(name)) { parent.add(name, libconfig::Setting::TypeList); - } else if(!parent.lookup(name).isList()) { + } else if (!parent.lookup(name).isList()) { parent.remove(name); parent.add(name, libconfig::Setting::TypeList); } set(parent.lookup(name), t); } + [[maybe_unused]] static inline void append(libconfig::Setting& list, const std::list& t) { auto& s = list.add(libconfig::Setting::TypeList); @@ -283,15 +302,15 @@ namespace logid::config { } }; - template + template struct config_io> { static inline std::set get(const libconfig::Setting& setting) { const auto size = setting.getLength(); std::set t; - for(int i = 0; i < size; ++i) { + for (int i = 0; i < size; ++i) { try { t.emplace(config_io::get(setting[i])); - } catch(libconfig::SettingException& e) { } + } catch (libconfig::SettingException& e) {} } return t; } @@ -303,9 +322,9 @@ namespace logid::config { static inline void set(libconfig::Setting& setting, const std::set& t) { - while(setting.getLength() != 0) - setting.remove((int)0); - for(auto& x : t) { + while (setting.getLength() != 0) + setting.remove((int) 0); + for (auto& x: t) { auto& s = setting.add(libconfig::Setting::TypeGroup); config_io::set(s, x); } @@ -316,13 +335,14 @@ namespace logid::config { const std::set& t) { if (!parent.exists(name)) { parent.add(name, libconfig::Setting::TypeList); - } else if(!parent.lookup(name).isArray()) { + } else if (!parent.lookup(name).isArray()) { parent.remove(name); parent.add(name, libconfig::Setting::TypeList); } set(parent.lookup(name), t); } + [[maybe_unused]] static inline void append(libconfig::Setting& list, const std::set& t) { auto& s = list.add(libconfig::Setting::TypeList); @@ -330,19 +350,19 @@ namespace logid::config { } }; - template + template struct config_io> { static inline map get( const libconfig::Setting& setting) { const auto size = setting.getLength(); map t; - for(int i = 0; i < size; ++i) { + for (int i = 0; i < size; ++i) { auto& s = setting[i]; try { t.emplace(config_io::get(s.lookup(KeyName.value)), config_io::get(s)); - } catch(libconfig::SettingException& e) { } + } catch (libconfig::SettingException& e) {} } return t; } @@ -354,9 +374,9 @@ namespace logid::config { static inline void set(libconfig::Setting& setting, const map& t) { - while(setting.getLength() != 0) - setting.remove((int)0); - for(auto& x : t) { + while (setting.getLength() != 0) + setting.remove((int) 0); + for (auto& x: t) { auto& s = setting.add(libconfig::Setting::TypeGroup); config_io::set(s, x.second); config_io::set(s, KeyName.value, x.first); @@ -368,13 +388,14 @@ namespace logid::config { const map& t) { if (!parent.exists(name)) { parent.add(name, libconfig::Setting::TypeList); - } else if(!parent.lookup(name).isArray()) { + } else if (!parent.lookup(name).isArray()) { parent.remove(name); parent.add(name, libconfig::Setting::TypeList); } set(parent.lookup(name), t); } + [[maybe_unused]] static inline void append(libconfig::Setting& list, const map& t) { auto& s = list.add(libconfig::Setting::TypeList); @@ -382,11 +403,11 @@ namespace logid::config { } }; - template + template struct config_io> { static inline std::optional get(const libconfig::Setting& parent, const std::string& name) { - if(parent.exists(name)) + if (parent.exists(name)) return config_io::get(parent.lookup(name)); else return {}; @@ -401,46 +422,46 @@ namespace logid::config { }; // Optionals may not appear as part of a list or array - template + template struct config_io, Rest...>> { static_assert(!sizeof(std::optional), "Invalid type"); }; - template + template struct config_io>> { static_assert(!sizeof(std::optional), "Invalid type"); }; - template + template struct config_io>> { static_assert(!sizeof(std::optional), "Invalid type"); }; } - template + template void set(libconfig::Setting& parent, const std::string& name, const T& t) { config_io::set(parent, name, t); } - template + template void set(libconfig::Setting& setting, const T& t) { config_io::set(setting, t); } - template + template void append(libconfig::Setting& list, const T& t) { config_io::append(list, t); } - template + template auto get(const libconfig::Setting& setting) { return config_io::get(setting); } - template + template auto get(const libconfig::Setting& parent, const std::string& name) { return config_io::get(parent, name); } diff --git a/src/logid/features/DPI.cpp b/src/logid/features/DPI.cpp index 1fd856c..eb9e62c 100644 --- a/src/logid/features/DPI.cpp +++ b/src/logid/features/DPI.cpp @@ -24,32 +24,29 @@ using namespace logid::features; using namespace logid::backend; uint16_t getClosestDPI(const hidpp20::AdjustableDPI::SensorDPIList& dpi_list, - uint16_t dpi) -{ - if(dpi_list.isRange) { - const uint16_t min = *std::min_element(dpi_list.dpis.begin(), - dpi_list.dpis.end()); - const uint16_t max = *std::max_element(dpi_list.dpis.begin(), - dpi_list.dpis.end()); - if(!((dpi-min) % dpi_list.dpiStep) && dpi >= min && dpi <= max) + uint16_t dpi) { + if (dpi_list.isRange) { + const uint16_t min = *std::min_element(dpi_list.dpis.begin(), dpi_list.dpis.end()); + const uint16_t max = *std::max_element(dpi_list.dpis.begin(), dpi_list.dpis.end()); + if (!((dpi - min) % dpi_list.dpiStep) && dpi >= min && dpi <= max) return dpi; - else if(dpi > max) + else if (dpi > max) return max; - else if(dpi < min) + else if (dpi < min) return min; else - return min + round((double)(dpi-min)/dpi_list.dpiStep)*dpi_list - .dpiStep; + return (uint16_t) (min + round((double) (dpi - min) / dpi_list.dpiStep) * + dpi_list.dpiStep); } else { - if(std::find(dpi_list.dpis.begin(), dpi_list.dpis.end(), dpi) - != dpi_list.dpis.end()) + if (std::find(dpi_list.dpis.begin(), dpi_list.dpis.end(), dpi) + != dpi_list.dpis.end()) return dpi; else { - auto it = std::min_element(dpi_list.dpis.begin(), dpi_list.dpis - .end(), [dpi](uint16_t a, uint16_t b) { - return (dpi - a) < (dpi - b); - }); - if(it == dpi_list.dpis.end()) + auto it = std::min_element(dpi_list.dpis.begin(), dpi_list.dpis.end(), + [dpi](uint16_t a, uint16_t b) { + return (dpi - a) < (dpi - b); + }); + if (it == dpi_list.dpis.end()) return 0; else return *it; @@ -58,8 +55,7 @@ uint16_t getClosestDPI(const hidpp20::AdjustableDPI::SensorDPIList& dpi_list, } DPI::DPI(Device* device) : DeviceFeature(device), - _config (device->activeProfile().dpi) -{ + _config(device->activeProfile().dpi) { try { _adjustable_dpi = std::make_shared (&device->hidpp20()); @@ -68,45 +64,41 @@ DPI::DPI(Device* device) : DeviceFeature(device), } } -void DPI::configure() -{ - if(_config.has_value()) { +void DPI::configure() { + if (_config.has_value()) { const auto& config = _config.value(); - if(std::holds_alternative(config)) { + if (std::holds_alternative(config)) { const auto& dpi = std::get(config); _adjustable_dpi->setSensorDPI( 0, getClosestDPI(_adjustable_dpi->getSensorDPIList(0), - dpi) ); + dpi)); } else { const auto& dpis = std::get>(config); int i = 0; - for(const auto& dpi : dpis) { + for (const auto& dpi: dpis) { _adjustable_dpi->setSensorDPI( i, getClosestDPI(_adjustable_dpi->getSensorDPIList(i), - dpi) ); + dpi)); ++i; } } } } -void DPI::listen() -{ +void DPI::listen() { } -uint16_t DPI::getDPI(uint8_t sensor) -{ +uint16_t DPI::getDPI(uint8_t sensor) { return _adjustable_dpi->getSensorDPI(sensor); } -void DPI::setDPI(uint16_t dpi, uint8_t sensor) -{ +void DPI::setDPI(uint16_t dpi, uint8_t sensor) { hidpp20::AdjustableDPI::SensorDPIList dpi_list; - if(_dpi_lists.size() <= sensor) { + if (_dpi_lists.size() <= sensor) { dpi_list = _adjustable_dpi->getSensorDPIList(sensor); - for(std::size_t i = _dpi_lists.size(); i < sensor; i++) { + for (std::size_t i = _dpi_lists.size(); i < sensor; i++) { _dpi_lists.push_back(_adjustable_dpi->getSensorDPIList(i)); } _dpi_lists.push_back(dpi_list); diff --git a/src/logid/features/DPI.h b/src/logid/features/DPI.h index de804b8..38738f4 100644 --- a/src/logid/features/DPI.h +++ b/src/logid/features/DPI.h @@ -22,23 +22,24 @@ #include "DeviceFeature.h" #include "../config/schema.h" -namespace logid { -namespace features -{ - class DPI : public DeviceFeature - { +namespace logid::features { + class DPI : public DeviceFeature { public: explicit DPI(Device* dev); - virtual void configure(); - virtual void listen(); - uint16_t getDPI(uint8_t sensor=0); - void setDPI(uint16_t dpi, uint8_t sensor=0); + void configure() final; + + void listen() final; + + uint16_t getDPI(uint8_t sensor = 0); + + void setDPI(uint16_t dpi, uint8_t sensor = 0); + private: std::optional& _config; std::shared_ptr _adjustable_dpi; std::vector _dpi_lists; }; - }} +} #endif //LOGID_FEATURE_DPI_H diff --git a/src/logid/features/DeviceFeature.h b/src/logid/features/DeviceFeature.h index 7b7ed4a..a11f6ca 100644 --- a/src/logid/features/DeviceFeature.h +++ b/src/logid/features/DeviceFeature.h @@ -23,31 +23,32 @@ namespace logid { class Device; -namespace features -{ - class UnsupportedFeature : public std::exception - { +} + +namespace logid::features { + class UnsupportedFeature : public std::exception { public: UnsupportedFeature() = default; - virtual const char* what() const noexcept - { + + [[nodiscard]] const char* what() const noexcept override { return "Unsupported feature"; } }; - class DeviceFeature - { + class DeviceFeature { public: - explicit DeviceFeature(Device* dev) : _device (dev) - { + explicit DeviceFeature(Device* dev) : _device(dev) { } + virtual void configure() = 0; + virtual void listen() = 0; + virtual ~DeviceFeature() = default; protected: Device* _device; }; -}} +} #endif //LOGID_FEATURES_DEVICEFEATURE_H diff --git a/src/logid/features/DeviceStatus.cpp b/src/logid/features/DeviceStatus.cpp index 08dc093..7ce6d72 100644 --- a/src/logid/features/DeviceStatus.cpp +++ b/src/logid/features/DeviceStatus.cpp @@ -21,50 +21,49 @@ using namespace logid::features; using namespace logid::backend; -DeviceStatus::DeviceStatus(logid::Device *dev) : DeviceFeature(dev) -{ +DeviceStatus::DeviceStatus(logid::Device* dev) : DeviceFeature(dev) { /* This feature is redundant on receivers since the receiver * handles wakeup/sleep events. If the device is connected on a * receiver, pretend this feature is unsupported. */ - if(dev->hidpp20().deviceIndex() >= hidpp::WirelessDevice1 && - dev->hidpp20().deviceIndex() <= hidpp::WirelessDevice6) + if (dev->hidpp20().deviceIndex() >= hidpp::WirelessDevice1 && + dev->hidpp20().deviceIndex() <= hidpp::WirelessDevice6) throw UnsupportedFeature(); try { _wireless_device_status = std::make_shared< hidpp20::WirelessDeviceStatus>(&dev->hidpp20()); - } catch(hidpp20::UnsupportedFeature& e) { + } catch (hidpp20::UnsupportedFeature& e) { throw UnsupportedFeature(); } } -DeviceStatus::~DeviceStatus() noexcept -{ - if(_ev_handler.has_value()) +DeviceStatus::~DeviceStatus() noexcept { + if (_ev_handler.has_value()) _device->hidpp20().removeEventHandler(_ev_handler.value()); } -void DeviceStatus::configure() -{ +void DeviceStatus::configure() { // Do nothing } -void DeviceStatus::listen() -{ - if(!_ev_handler.has_value()) { - _ev_handler = _device->hidpp20().addEventHandler({ - [index=_wireless_device_status->featureIndex()]( - const hidpp::Report& report)->bool { - return report.feature() == index && report.function() == - hidpp20::WirelessDeviceStatus::StatusBroadcast; - }, - [dev=this->_device](const hidpp::Report& report) { - auto event = - hidpp20::WirelessDeviceStatus::statusBroadcastEvent(report); - if(event.reconfNeeded) - spawn_task( [dev](){ dev->wakeup(); }); - } - }); +void DeviceStatus::listen() { + if (!_ev_handler.has_value()) { + _ev_handler = _device->hidpp20().addEventHandler( + { + [index = _wireless_device_status->featureIndex()]( + const hidpp::Report& report) -> bool { + return report.feature() == index && + report.function() == + hidpp20::WirelessDeviceStatus::StatusBroadcast; + }, + [dev = this->_device]( + const hidpp::Report& report) { + auto event = + hidpp20::WirelessDeviceStatus::statusBroadcastEvent(report); + if (event.reconfNeeded) + spawn_task([dev]() { dev->wakeup(); }); + } + }); } } \ No newline at end of file diff --git a/src/logid/features/DeviceStatus.h b/src/logid/features/DeviceStatus.h index abe23b6..9ebcb03 100644 --- a/src/logid/features/DeviceStatus.h +++ b/src/logid/features/DeviceStatus.h @@ -23,21 +23,22 @@ #include "../Device.h" #include "../backend/hidpp20/features/WirelessDeviceStatus.h" -namespace logid { -namespace features -{ - class DeviceStatus : public DeviceFeature - { +namespace logid::features { + class DeviceStatus : public DeviceFeature { public: explicit DeviceStatus(Device* dev); - ~DeviceStatus(); - virtual void configure(); - virtual void listen(); + + ~DeviceStatus() noexcept override; + + void configure() final; + + void listen() final; + private: std::optional _ev_handler; std::shared_ptr _wireless_device_status; }; -}} +} #endif //LOGID_FEATURE_DEVICESTATUS_H diff --git a/src/logid/features/HiresScroll.cpp b/src/logid/features/HiresScroll.cpp index 1a9ca47..fa321c2 100644 --- a/src/logid/features/HiresScroll.cpp +++ b/src/logid/features/HiresScroll.cpp @@ -23,15 +23,13 @@ using namespace logid::features; using namespace logid::backend; -#define MOVE_EVENTHANDLER_NAME "HIRES_SCROLL" - -HiresScroll::HiresScroll(Device *dev) : DeviceFeature(dev), - _config (dev->activeProfile().hiresscroll), _mode (0), _mask (0), - _node (dev->ipcNode()->make_child("hires")) -{ - if(_config.has_value()) { - if(std::holds_alternative(_config.value())) { - config::HiresScroll conf {}; +HiresScroll::HiresScroll(Device* dev) : DeviceFeature(dev), + _config(dev->activeProfile().hiresscroll), _mode(0), + _mask(0), + _node(dev->ipcNode()->make_child("hires")) { + if (_config.has_value()) { + if (std::holds_alternative(_config.value())) { + config::HiresScroll conf{}; conf.hires = std::get(_config.value()); conf.invert = false; conf.target = false; @@ -39,19 +37,19 @@ HiresScroll::HiresScroll(Device *dev) : DeviceFeature(dev), _config.value() = conf; } auto& conf = std::get(_config.value()); - if(conf.hires.has_value()) { + if (conf.hires.has_value()) { _mask |= hidpp20::HiresScroll::Mode::HiRes; - if(conf.hires.value()) + if (conf.hires.value()) _mode |= hidpp20::HiresScroll::Mode::HiRes; } - if(conf.invert.has_value()) { + if (conf.invert.has_value()) { _mask |= hidpp20::HiresScroll::Mode::Inverted; - if(conf.invert.value()) + if (conf.invert.value()) _mode |= hidpp20::HiresScroll::Mode::Inverted; } - if(conf.target.has_value()) { + if (conf.target.has_value()) { _mask |= hidpp20::HiresScroll::Mode::Target; - if(conf.target.value()) + if (conf.target.value()) _mode |= hidpp20::HiresScroll::Mode::Target; } @@ -61,110 +59,107 @@ HiresScroll::HiresScroll(Device *dev) : DeviceFeature(dev), try { _hires_scroll = std::make_shared(&dev->hidpp20()); - } catch(hidpp20::UnsupportedFeature& e) { + } catch (hidpp20::UnsupportedFeature& e) { throw UnsupportedFeature(); } _last_scroll = std::chrono::system_clock::now(); } -HiresScroll::~HiresScroll() -{ - if(_ev_handler.has_value()) +HiresScroll::~HiresScroll() noexcept { + if (_ev_handler.has_value()) _device->hidpp20().removeEventHandler(_ev_handler.value()); } -void HiresScroll::configure() -{ +void HiresScroll::configure() { auto mode = _hires_scroll->getMode(); mode &= ~_mask; mode |= (_mode & _mask); _hires_scroll->setMode(mode); } -void HiresScroll::listen() -{ - if(!_ev_handler.has_value()) { +void HiresScroll::listen() { + if (!_ev_handler.has_value()) { _ev_handler = _device->hidpp20().addEventHandler({ - [index=_hires_scroll->featureIndex()]( - const hidpp::Report& report)->bool { - return (report.feature() == index) && (report.function() == - hidpp20::HiresScroll::WheelMovement); - }, - [this](const hidpp::Report& report) { - _handleScroll(_hires_scroll->wheelMovementEvent(report)); - } - }); + [index = _hires_scroll->featureIndex()]( + const hidpp::Report& report) -> bool { + return (report.feature() == + index) && + (report.function() == + hidpp20::HiresScroll::WheelMovement); + }, + [this](const hidpp::Report& report) { + _handleScroll( + _hires_scroll->wheelMovementEvent( + report)); + } + }); } } -uint8_t HiresScroll::getMode() -{ +uint8_t HiresScroll::getMode() { return _hires_scroll->getMode(); } -void HiresScroll::setMode(uint8_t mode) -{ +void HiresScroll::setMode(uint8_t mode) { _hires_scroll->setMode(mode); } -void HiresScroll::_makeAction(std::shared_ptr &gesture, - std::optional &config, - const std::string& direction) -{ - if(config.has_value()) { +void HiresScroll::_makeAction(std::shared_ptr& gesture, + std::optional& config, + const std::string& direction) { + if (config.has_value()) { gesture = actions::Gesture::makeGesture(_device, config.value(), _node->make_child(direction)); try { auto axis = std::dynamic_pointer_cast( gesture); - if(axis) + if (axis) axis->setHiresMultiplier( _hires_scroll->getCapabilities().multiplier); - } catch(std::bad_cast& e) { } - if(gesture) + } catch (std::bad_cast& e) {} + if (gesture) gesture->press(true); } else { gesture.reset(); } } -void HiresScroll::_handleScroll(hidpp20::HiresScroll::WheelStatus event) -{ +void HiresScroll::_handleScroll(hidpp20::HiresScroll::WheelStatus event) { auto now = std::chrono::system_clock::now(); - if(std::chrono::duration_cast( + if (std::chrono::duration_cast( now - _last_scroll).count() >= 1) { - if(_up_action) { - _up_action->release(); + if (_up_action) { + _up_action->release(false); _up_action->press(true); } - if(_down_action) { - _down_action->release(); + if (_down_action) { + _down_action->release(false); _down_action->press(true); } _last_direction = 0; } - if(event.deltaV > 0) { - if(_last_direction == -1) { - if(_down_action){ - _down_action->release(); + if (event.deltaV > 0) { + if (_last_direction == -1) { + if (_down_action) { + _down_action->release(false); _down_action->press(true); } } - if(_up_action) + if (_up_action) _up_action->move(event.deltaV); _last_direction = 1; - } else if(event.deltaV < 0) { - if(_last_direction == 1) { - if(_up_action){ - _up_action->release(); + } else if (event.deltaV < 0) { + if (_last_direction == 1) { + if (_up_action) { + _up_action->release(false); _up_action->press(true); } } - if(_down_action) - _down_action->move(-event.deltaV); + if (_down_action) + _down_action->move((int16_t) -event.deltaV); _last_direction = -1; } diff --git a/src/logid/features/HiresScroll.h b/src/logid/features/HiresScroll.h index 15312b3..01195a1 100644 --- a/src/logid/features/HiresScroll.h +++ b/src/logid/features/HiresScroll.h @@ -22,19 +22,21 @@ #include "DeviceFeature.h" #include "../actions/gesture/Gesture.h" -namespace logid { -namespace features -{ - class HiresScroll : public DeviceFeature - { +namespace logid::features { + class HiresScroll : public DeviceFeature { public: explicit HiresScroll(Device* dev); - ~HiresScroll(); - virtual void configure(); - virtual void listen(); - uint8_t getMode(); + ~HiresScroll() noexcept override; + + void configure() final; + + void listen() final; + + [[nodiscard]] uint8_t getMode(); + void setMode(uint8_t mode); + private: std::optional _ev_handler; @@ -43,6 +45,7 @@ namespace features const std::string& direction); void _handleScroll(backend::hidpp20::HiresScroll::WheelStatus event); + std::shared_ptr _hires_scroll; std::chrono::time_point _last_scroll; int16_t _last_direction = 0; @@ -57,6 +60,6 @@ namespace features std::shared_ptr _node; }; -}} +} #endif //LOGID_FEATURE_HIRESSCROLL_H diff --git a/src/logid/features/RemapButton.cpp b/src/logid/features/RemapButton.cpp index 5ac58ef..121f171 100644 --- a/src/logid/features/RemapButton.cpp +++ b/src/logid/features/RemapButton.cpp @@ -19,7 +19,6 @@ #include "../actions/GestureAction.h" #include "../Device.h" #include "RemapButton.h" -#include "../backend/hidpp20/Error.h" using namespace logid::features; using namespace logid::backend; @@ -28,35 +27,34 @@ using namespace logid::actions; #define HIDPP20_REPROG_REBIND (hidpp20::ReprogControls::ChangeTemporaryDivert \ | hidpp20::ReprogControls::ChangeRawXYDivert) -RemapButton::RemapButton(Device *dev): DeviceFeature(dev), - _config (dev->activeProfile().buttons), - _ipc_node (dev->ipcNode()->make_child("buttons")) -{ +RemapButton::RemapButton(Device* dev) : DeviceFeature(dev), + _config(dev->activeProfile().buttons), + _ipc_node(dev->ipcNode()->make_child("buttons")) { try { _reprog_controls = hidpp20::ReprogControls::autoVersion( &dev->hidpp20()); - } catch(hidpp20::UnsupportedFeature& e) { + } catch (hidpp20::UnsupportedFeature& e) { throw UnsupportedFeature(); } _reprog_controls->initCidMap(); - if(!_config.has_value()) + if (!_config.has_value()) _config = config::RemapButton(); - for(const auto& control : _reprog_controls->getControls()) { + for (const auto& control: _reprog_controls->getControls()) { const auto i = _buttons.size(); - Button::ConfigFunction func = [this, info=control.second]( - std::shared_ptr action) { + Button::ConfigFunction func = [this, info = control.second]( + const std::shared_ptr& 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) )) + 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(), @@ -67,101 +65,106 @@ RemapButton::RemapButton(Device *dev): DeviceFeature(dev), _reprog_controls->setControlReporting(info.controlID, report); }; _buttons.emplace(control.second.controlID, - Button::make(control.second, i, + Button::make(control.second, (int) 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 ? \ + if (global_loglevel <= DEBUG) { +#define FLAG(x) (control.second.flags & hidpp20::ReprogControls::x ? \ "YES" : "") - #define ADDITIONAL_FLAG(x) (control.second.additionalFlags & \ +#define ADDITIONAL_FLAG(x) (control.second.additionalFlags & \ hidpp20::ReprogControls::x ? "YES" : "") // Print CIDs, originally by zv0n - logPrintf(DEBUG, "%s:%d remappable buttons:", - dev->hidpp20().devicePath().c_str(), - dev->hidpp20().deviceIndex()); + logPrintf(DEBUG, "%s:%d remappable buttons:", + dev->hidpp20().devicePath().c_str(), + dev->hidpp20().deviceIndex()); logPrintf(DEBUG, "CID | reprog? | fn key? | mouse key? | " "gesture support?"); - for(const auto & control : _reprog_controls->getControls()) - logPrintf(DEBUG, "0x%02x | %-7s | %-7s | %-10s | %s", - control.first, FLAG(TemporaryDivertable), FLAG(FKey), - FLAG(MouseButton), ADDITIONAL_FLAG(RawXY)); - #undef ADDITIONAL_FLAG - #undef FLAG + for (const auto& control: _reprog_controls->getControls()) + logPrintf(DEBUG, "0x%02x | %-7s | %-7s | %-10s | %s", + control.first, FLAG(TemporaryDivertable), FLAG(FKey), + FLAG(MouseButton), ADDITIONAL_FLAG(RawXY)); +#undef ADDITIONAL_FLAG +#undef FLAG } } -RemapButton::~RemapButton() -{ - if(_ev_handler.has_value()) +RemapButton::~RemapButton() noexcept { + if (_ev_handler.has_value()) _device->hidpp20().removeEventHandler(_ev_handler.value()); } -void RemapButton::configure() -{ - for(const auto& button : _buttons) +void RemapButton::configure() { + for (const auto& button: _buttons) button.second->configure(); } -void RemapButton::listen() -{ - if(!_ev_handler.has_value()) { - _ev_handler = _device->hidpp20().addEventHandler({ - [index=_reprog_controls->featureIndex()](const hidpp::Report& report)->bool { - if(report.feature() == index) { - switch(report.function()) { - case hidpp20::ReprogControls::DivertedButtonEvent: - return true; - case hidpp20::ReprogControls::DivertedRawXYEvent: return true; - default: return false; - } - } - return false; - }, - [this](const hidpp::Report& report)->void { - switch(report.function()) { - case hidpp20::ReprogControls::DivertedButtonEvent: - this->_buttonEvent(_reprog_controls->divertedButtonEvent(report)); - break; - case hidpp20::ReprogControls::DivertedRawXYEvent: { - auto divertedXY = _reprog_controls->divertedRawXYEvent(report); - for(const auto& button : this->_buttons) - if(button.second->pressed()) - button.second->move(divertedXY.x, divertedXY.y); - break; - } - default: break; - } - } - }); +void RemapButton::listen() { + if (!_ev_handler.has_value()) { + _ev_handler = _device->hidpp20().addEventHandler( + { + [index = _reprog_controls->featureIndex()]( + const hidpp::Report& report) -> bool { + if (report.feature() == index) { + switch (report.function()) { + case hidpp20::ReprogControls::DivertedButtonEvent: + case hidpp20::ReprogControls::DivertedRawXYEvent: + return true; + default: + return false; + } + } + return false; + }, + [this](const hidpp::Report& report) -> void { + switch (report.function()) { + case hidpp20::ReprogControls::DivertedButtonEvent: + this->_buttonEvent( + _reprog_controls->divertedButtonEvent( + report)); + break; + case hidpp20::ReprogControls::DivertedRawXYEvent: { + auto divertedXY = _reprog_controls->divertedRawXYEvent( + report); + for (const auto& button: this->_buttons) + if (button.second->pressed()) + button.second->move( + divertedXY.x, + divertedXY.y); + break; + } + default: + break; + } + } + }); } } -void RemapButton::_buttonEvent(const std::set& new_state) -{ +void RemapButton::_buttonEvent(const std::set& new_state) { // Ensure I/O doesn't occur while updating button state std::lock_guard lock(_button_lock); // Press all added buttons - for(const auto& i : new_state) { + for (const auto& i: new_state) { auto old_i = _pressed_buttons.find(i); - if(old_i != _pressed_buttons.end()) { + if (old_i != _pressed_buttons.end()) { _pressed_buttons.erase(old_i); } else { auto action = _buttons.find(i); - if(action != _buttons.end()) + if (action != _buttons.end()) action->second->press(); } } // Release all removed buttons - for(auto& i : _pressed_buttons) { + for (auto& i: _pressed_buttons) { auto action = _buttons.find(i); - if(action != _buttons.end()) + if (action != _buttons.end()) action->second->release(); } @@ -169,21 +172,19 @@ void RemapButton::_buttonEvent(const std::set& new_state) } namespace logid::features { - class _Button : public Button { + class ButtonWrapper : public Button { public: - template - explicit _Button(Args&&... args) : Button(std::forward(args)...) - { + template + explicit ButtonWrapper(Args&& ... args) : Button(std::forward(args)...) { } }; } std::shared_ptr