Added DPI IPC interface

This commit is contained in:
pixl 2023-04-29 15:52:49 -04:00
parent 7a4a7f0573
commit d13d1feb4b
No known key found for this signature in database
GPG Key ID: 1866C148CD593B6E
4 changed files with 153 additions and 33 deletions

View File

@ -19,6 +19,7 @@
#include <Device.h>
#include <algorithm>
#include <cmath>
#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<hidpp20::AdjustableDPI>
(&device->hidpp20());
} catch (hidpp20::UnsupportedFeature& e) {
throw UnsupportedFeature();
}
_ipc_interface = _device->ipcNode()->make_interface<IPC>(this);
}
void DPI::configure() {
std::shared_lock lock(_config_mutex);
if (_config.has_value()) {
const auto& config = _config.value();
if (std::holds_alternative<int>(config)) {
const auto& dpi = std::get<int>(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<std::list<int>>(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<std::vector<uint16_t>, 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<int>(_parent._config.value())) {
if (sensor == 0)
return std::get<int>(_parent._config.value());
else
return _parent.getDPI(sensor);
}
const auto& list = std::get<std::list<int>>(_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<int>());
if (std::holds_alternative<int>(_parent._config.value())) {
if (sensor == 0) {
_parent._config.value() = dpi;
} else {
auto list = std::list<int>(sensor + 1, 0);
*list.rbegin() = dpi;
*list.begin() = dpi;
_parent._config.value() = list;
}
} else {
auto& list = std::get<std::list<int>>(_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);
}

View File

@ -21,6 +21,8 @@
#include <backend/hidpp20/features/AdjustableDPI.h>
#include <features/DeviceFeature.h>
#include <config/schema.h>
#include <ipcgull/interface.h>
#include <shared_mutex>
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<std::vector<uint16_t>, 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::DPI>& _config;
std::shared_ptr<backend::hidpp20::AdjustableDPI> _adjustable_dpi;
mutable std::shared_mutex _dpi_list_mutex;
std::vector<backend::hidpp20::AdjustableDPI::SensorDPIList> _dpi_lists;
std::shared_ptr<IPC> _ipc_interface;
};
}

View File

@ -19,7 +19,7 @@
#include <actions/gesture/AxisGesture.h>
#include <Device.h>
#include <InputDevice.h>
#include "ipc_defs.h"
#include <ipc_defs.h>
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<hidpp20::HiresScroll>(&dev->hidpp20());
} catch (hidpp20::UnsupportedFeature& e) {
throw UnsupportedFeature();
}
if (_config.has_value()) {
if (std::holds_alternative<bool>(_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<hidpp20::HiresScroll>(&dev->hidpp20());
} catch (hidpp20::UnsupportedFeature& e) {
throw UnsupportedFeature();
}
_last_scroll = std::chrono::system_clock::now();
_ipc_interface = dev->ipcNode()->make_interface<IPC>(this);

View File

@ -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<hidpp20::ThumbWheel>(&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<hidpp20::ThumbWheel>(&dev->hidpp20());
} catch (hidpp20::UnsupportedFeature& e) {
throw UnsupportedFeature();
}
_wheel_info = _thumb_wheel->getInfo();
logPrintf(DEBUG, "Thumb wheel detected (0x2150), capabilities:");