From d13d1feb4bb0d479badab568ba4ea4e392a100ca Mon Sep 17 00:00:00 2001 From: pixl Date: Sat, 29 Apr 2023 15:52:49 -0400 Subject: [PATCH] Added DPI IPC interface --- src/logid/features/DPI.cpp | 133 ++++++++++++++++++++++++----- src/logid/features/DPI.h | 25 ++++++ src/logid/features/HiresScroll.cpp | 15 ++-- src/logid/features/ThumbWheel.cpp | 13 +-- 4 files changed, 153 insertions(+), 33 deletions(-) diff --git a/src/logid/features/DPI.cpp b/src/logid/features/DPI.cpp index c6986cb..a4b39d1 100644 --- a/src/logid/features/DPI.cpp +++ b/src/logid/features/DPI.cpp @@ -19,6 +19,7 @@ #include #include #include +#include "ipc_defs.h" using namespace logid::features; using namespace logid::backend; @@ -54,34 +55,39 @@ uint16_t getClosestDPI(const hidpp20::AdjustableDPI::SensorDPIList& dpi_list, } } -DPI::DPI(Device* device) : DeviceFeature(device), - _config(device->activeProfile().dpi) { +DPI::DPI(Device* device) : DeviceFeature(device), _config(device->activeProfile().dpi) { try { _adjustable_dpi = std::make_shared (&device->hidpp20()); } catch (hidpp20::UnsupportedFeature& e) { throw UnsupportedFeature(); } + + _ipc_interface = _device->ipcNode()->make_interface(this); } void DPI::configure() { + std::shared_lock lock(_config_mutex); + if (_config.has_value()) { const auto& config = _config.value(); if (std::holds_alternative(config)) { const auto& dpi = std::get(config); - _adjustable_dpi->setSensorDPI( - 0, - getClosestDPI(_adjustable_dpi->getSensorDPIList(0), - dpi)); + _fillDPILists(0); + std::shared_lock dpi_lock(_dpi_list_mutex); + if (dpi != 0) { + _adjustable_dpi->setSensorDPI(0, getClosestDPI(_dpi_lists.at(0), dpi)); + } } else { const auto& dpis = std::get>(config); int i = 0; + _fillDPILists(dpis.size() - 1); + std::shared_lock dpi_lock(_dpi_list_mutex); for (const auto& dpi: dpis) { - _adjustable_dpi->setSensorDPI( - i, - getClosestDPI(_adjustable_dpi->getSensorDPIList(i), - dpi)); - ++i; + if (dpi != 0) { + _adjustable_dpi->setSensorDPI(i, getClosestDPI(_dpi_lists.at(i), dpi)); + ++i; + } } } } @@ -95,14 +101,101 @@ uint16_t DPI::getDPI(uint8_t sensor) { } void DPI::setDPI(uint16_t dpi, uint8_t sensor) { - hidpp20::AdjustableDPI::SensorDPIList dpi_list; - if (_dpi_lists.size() <= sensor) { - dpi_list = _adjustable_dpi->getSensorDPIList(sensor); - 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); - } - dpi_list = _dpi_lists[sensor]; + if (dpi == 0) + return; + _fillDPILists(sensor); + std::shared_lock lock(_dpi_list_mutex); + auto dpi_list = _dpi_lists.at(sensor); _adjustable_dpi->setSensorDPI(sensor, getClosestDPI(dpi_list, dpi)); } + +void DPI::_fillDPILists(uint8_t sensor) { + bool needs_fill; + { + std::shared_lock lock(_dpi_list_mutex); + needs_fill = _dpi_lists.size() <= sensor; + } + if (needs_fill) { + std::unique_lock lock(_dpi_list_mutex); + for (std::size_t i = _dpi_lists.size(); i <= sensor; i++) { + _dpi_lists.push_back(_adjustable_dpi->getSensorDPIList(i)); + } + } +} + +DPI::IPC::IPC(DPI* parent) : ipcgull::interface( + SERVICE_ROOT_NAME ".DPI", { + {"GetSensors", {this, &IPC::getSensors, {"sensors"}}}, + {"GetDPIs", {this, &IPC::getDPIs, {"sensor"}, {"dpis", "dpiStep", "range"}}}, + {"GetDPI", {this, &IPC::getDPI, {"sensor"}, {"dpi"}}}, + {"SetDPI", {this, &IPC::setDPI, {"dpi", "sensor"}}} + }, {}, {}), _parent(*parent) { +} + +uint8_t DPI::IPC::getSensors() const { + return _parent._dpi_lists.size(); +} + +std::tuple, uint16_t, bool> DPI::IPC::getDPIs(uint8_t sensor) const { + _parent._fillDPILists(sensor); + std::shared_lock lock(_parent._dpi_list_mutex); + auto& dpi_list = _parent._dpi_lists.at(sensor); + return {dpi_list.dpis, dpi_list.dpiStep, dpi_list.isRange}; +} + +uint16_t DPI::IPC::getDPI(uint8_t sensor) const { + std::shared_lock lock(_parent._config_mutex); + if (!_parent._config.has_value()) + return _parent.getDPI(sensor); + + if (std::holds_alternative(_parent._config.value())) { + if (sensor == 0) + return std::get(_parent._config.value()); + else + return _parent.getDPI(sensor); + } + + const auto& list = std::get>(_parent._config.value()); + + if (list.size() > sensor) { + auto it = list.begin(); + std::advance(it, sensor); + return *it; + } else { + return _parent.getDPI(sensor); + } +} + +void DPI::IPC::setDPI(uint16_t dpi, uint8_t sensor) { + std::unique_lock lock(_parent._config_mutex); + + if (!_parent._config.has_value()) + _parent._config.emplace(std::list()); + + if (std::holds_alternative(_parent._config.value())) { + if (sensor == 0) { + _parent._config.value() = dpi; + } else { + auto list = std::list(sensor + 1, 0); + *list.rbegin() = dpi; + *list.begin() = dpi; + _parent._config.value() = list; + } + } else { + auto& list = std::get>(_parent._config.value()); + + while (list.size() <= sensor) { + list.emplace_back(0); + } + + if (list.size() == (size_t) (sensor + 1)) { + *list.rbegin() = dpi; + } else { + auto it = list.begin(); + std::advance(it, sensor); + *it = dpi; + } + } + + _parent.setDPI(dpi, sensor); +} diff --git a/src/logid/features/DPI.h b/src/logid/features/DPI.h index 101981b..a77a432 100644 --- a/src/logid/features/DPI.h +++ b/src/logid/features/DPI.h @@ -21,6 +21,8 @@ #include #include #include +#include +#include namespace logid::features { class DPI : public DeviceFeature { @@ -36,9 +38,32 @@ namespace logid::features { void setDPI(uint16_t dpi, uint8_t sensor = 0); private: + void _fillDPILists(uint8_t sensor); + + class IPC : public ipcgull::interface { + public: + explicit IPC(DPI* parent); + + [[nodiscard]] uint8_t getSensors() const; + + [[nodiscard]] std::tuple, uint16_t, bool> getDPIs(uint8_t + sensor) const; + + [[nodiscard]] uint16_t getDPI(uint8_t sensor) const; + + void setDPI(uint16_t dpi, uint8_t sensor); + + private: + DPI& _parent; + }; + + mutable std::shared_mutex _config_mutex; std::optional& _config; std::shared_ptr _adjustable_dpi; + mutable std::shared_mutex _dpi_list_mutex; std::vector _dpi_lists; + + std::shared_ptr _ipc_interface; }; } diff --git a/src/logid/features/HiresScroll.cpp b/src/logid/features/HiresScroll.cpp index c40c4ea..4afd281 100644 --- a/src/logid/features/HiresScroll.cpp +++ b/src/logid/features/HiresScroll.cpp @@ -19,7 +19,7 @@ #include #include #include -#include "ipc_defs.h" +#include using namespace logid; using namespace logid::features; @@ -32,6 +32,13 @@ HiresScroll::HiresScroll(Device* dev) : _node(dev->ipcNode()->make_child("hires_scroll")), _up_node(_node->make_child("up")), _down_node(_node->make_child("down")) { + + try { + _hires_scroll = std::make_shared(&dev->hidpp20()); + } catch (hidpp20::UnsupportedFeature& e) { + throw UnsupportedFeature(); + } + if (_config.has_value()) { if (std::holds_alternative(_config.value())) { config::HiresScroll conf{}; @@ -62,12 +69,6 @@ HiresScroll::HiresScroll(Device* dev) : _makeGesture(_down_gesture, conf.down, "down"); } - try { - _hires_scroll = std::make_shared(&dev->hidpp20()); - } catch (hidpp20::UnsupportedFeature& e) { - throw UnsupportedFeature(); - } - _last_scroll = std::chrono::system_clock::now(); _ipc_interface = dev->ipcNode()->make_interface(this); diff --git a/src/logid/features/ThumbWheel.cpp b/src/logid/features/ThumbWheel.cpp index 1382a6e..6b83fad 100644 --- a/src/logid/features/ThumbWheel.cpp +++ b/src/logid/features/ThumbWheel.cpp @@ -73,6 +73,13 @@ ThumbWheel::ThumbWheel(Device* dev) : DeviceFeature(dev), _wheel_info(), _tap_node(_node->make_child("tap")), _touch_node(_node->make_child("touch")), _config(dev->activeProfile().thumbwheel) { + + try { + _thumb_wheel = std::make_shared(&dev->hidpp20()); + } catch (hidpp20::UnsupportedFeature& e) { + throw UnsupportedFeature(); + } + if (_config.has_value()) { auto& conf = _config.value(); _left_gesture = _genGesture(dev, conf.left, _left_node, "left"); @@ -82,12 +89,6 @@ ThumbWheel::ThumbWheel(Device* dev) : DeviceFeature(dev), _wheel_info(), _proxy_action = _genAction(dev, conf.proxy, _proxy_node); } - try { - _thumb_wheel = std::make_shared(&dev->hidpp20()); - } catch (hidpp20::UnsupportedFeature& e) { - throw UnsupportedFeature(); - } - _wheel_info = _thumb_wheel->getInfo(); logPrintf(DEBUG, "Thumb wheel detected (0x2150), capabilities:");