mirror of
https://github.com/PixlOne/logiops.git
synced 2025-07-14 13:22:33 +08:00
Add full profile support
This commit is contained in:
parent
c0e532b1de
commit
27b6a2fd8f
@ -25,6 +25,7 @@
|
|||||||
#include <features/DeviceStatus.h>
|
#include <features/DeviceStatus.h>
|
||||||
#include <features/ThumbWheel.h>
|
#include <features/ThumbWheel.h>
|
||||||
#include <backend/hidpp20/features/Reset.h>
|
#include <backend/hidpp20/features/Reset.h>
|
||||||
|
#include <util/task.h>
|
||||||
#include <util/log.h>
|
#include <util/log.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -94,9 +95,11 @@ std::shared_ptr<Device> Device::make(
|
|||||||
Device::Device(std::string path, backend::hidpp::DeviceIndex index,
|
Device::Device(std::string path, backend::hidpp::DeviceIndex index,
|
||||||
const std::shared_ptr<DeviceManager>& manager) :
|
const std::shared_ptr<DeviceManager>& manager) :
|
||||||
_hidpp20(hidpp20::Device::make(path, index, manager,
|
_hidpp20(hidpp20::Device::make(path, index, manager,
|
||||||
manager->config()->io_timeout.value_or(defaults::io_timeout))),
|
manager->config()->io_timeout.value_or(
|
||||||
|
defaults::io_timeout))),
|
||||||
_path(std::move(path)), _index(index),
|
_path(std::move(path)), _index(index),
|
||||||
_config(_getConfig(manager, _hidpp20->name())),
|
_config(_getConfig(manager, _hidpp20->name())),
|
||||||
|
_profile_name(ipcgull::property_readable, ""),
|
||||||
_receiver(nullptr),
|
_receiver(nullptr),
|
||||||
_manager(manager),
|
_manager(manager),
|
||||||
_nickname(manager),
|
_nickname(manager),
|
||||||
@ -112,6 +115,7 @@ Device::Device(std::shared_ptr<backend::raw::RawDevice> raw_device,
|
|||||||
manager->config()->io_timeout.value_or(defaults::io_timeout))),
|
manager->config()->io_timeout.value_or(defaults::io_timeout))),
|
||||||
_path(raw_device->rawPath()), _index(index),
|
_path(raw_device->rawPath()), _index(index),
|
||||||
_config(_getConfig(manager, _hidpp20->name())),
|
_config(_getConfig(manager, _hidpp20->name())),
|
||||||
|
_profile_name(ipcgull::property_readable, ""),
|
||||||
_receiver(nullptr),
|
_receiver(nullptr),
|
||||||
_manager(manager),
|
_manager(manager),
|
||||||
_nickname(manager),
|
_nickname(manager),
|
||||||
@ -127,6 +131,7 @@ Device::Device(Receiver* receiver, hidpp::DeviceIndex index,
|
|||||||
manager->config()->io_timeout.value_or(defaults::io_timeout))),
|
manager->config()->io_timeout.value_or(defaults::io_timeout))),
|
||||||
_path(receiver->path()), _index(index),
|
_path(receiver->path()), _index(index),
|
||||||
_config(_getConfig(manager, _hidpp20->name())),
|
_config(_getConfig(manager, _hidpp20->name())),
|
||||||
|
_profile_name(ipcgull::property_readable, ""),
|
||||||
_receiver(receiver),
|
_receiver(receiver),
|
||||||
_manager(manager),
|
_manager(manager),
|
||||||
_nickname(manager),
|
_nickname(manager),
|
||||||
@ -139,9 +144,13 @@ void Device::_init() {
|
|||||||
logPrintf(INFO, "Device found: %s on %s:%d", name().c_str(),
|
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())
|
std::unique_lock lock(_profile_mutex);
|
||||||
_profile = _config.profiles.insert({_config.default_profile, {}}).first;
|
_profile = _config.profiles.find(_config.default_profile);
|
||||||
|
if (_profile == _config.profiles.end())
|
||||||
|
_profile = _config.profiles.insert({_config.default_profile, {}}).first;
|
||||||
|
_profile_name = _config.default_profile;
|
||||||
|
}
|
||||||
|
|
||||||
_addFeature<features::DPI>("dpi");
|
_addFeature<features::DPI>("dpi");
|
||||||
_addFeature<features::SmartShift>("smartshift");
|
_addFeature<features::SmartShift>("smartshift");
|
||||||
@ -180,10 +189,7 @@ void Device::wakeup() {
|
|||||||
std::lock_guard<std::mutex> lock(_state_lock);
|
std::lock_guard<std::mutex> lock(_state_lock);
|
||||||
logPrintf(INFO, "%s:%d woke up.", _path.c_str(), _index);
|
logPrintf(INFO, "%s:%d woke up.", _path.c_str(), _index);
|
||||||
|
|
||||||
reset();
|
reconfigure();
|
||||||
|
|
||||||
for (auto& feature: _features)
|
|
||||||
feature.second->configure();
|
|
||||||
|
|
||||||
if (!_awake) {
|
if (!_awake) {
|
||||||
_awake = true;
|
_awake = true;
|
||||||
@ -191,6 +197,13 @@ void Device::wakeup() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Device::reconfigure() {
|
||||||
|
reset();
|
||||||
|
|
||||||
|
for (auto& feature: _features)
|
||||||
|
feature.second->configure();
|
||||||
|
}
|
||||||
|
|
||||||
void Device::reset() {
|
void Device::reset() {
|
||||||
if (_reset_mechanism)
|
if (_reset_mechanism)
|
||||||
(*_reset_mechanism)();
|
(*_reset_mechanism)();
|
||||||
@ -215,11 +228,71 @@ std::shared_ptr<ipcgull::node> Device::ipcNode() const {
|
|||||||
return _ipc_node;
|
return _ipc_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
config::Profile& Device::activeProfile() {
|
std::vector<std::string> Device::getProfiles() const {
|
||||||
return _profile->second;
|
std::shared_lock lock(_profile_mutex);
|
||||||
|
|
||||||
|
std::vector<std::string> ret;
|
||||||
|
for (auto& profile : _config.profiles) {
|
||||||
|
ret.push_back(profile.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const config::Profile& Device::activeProfile() const {
|
void Device::setProfile(const std::string& profile) {
|
||||||
|
std::unique_lock lock(_profile_mutex);
|
||||||
|
|
||||||
|
_profile = _config.profiles.find(profile);
|
||||||
|
if (_profile == _config.profiles.end())
|
||||||
|
_profile = _config.profiles.insert({profile, {}}).first;
|
||||||
|
_profile_name = profile;
|
||||||
|
|
||||||
|
for (auto& feature : _features)
|
||||||
|
feature.second->setProfile(_profile->second);
|
||||||
|
|
||||||
|
reconfigure();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::setProfileDelayed(const std::string& profile) {
|
||||||
|
run_task([self_weak = _self, profile](){
|
||||||
|
if (auto self = self_weak.lock())
|
||||||
|
self->setProfile(profile);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::removeProfile(const std::string& profile) {
|
||||||
|
std::unique_lock lock(_profile_mutex);
|
||||||
|
|
||||||
|
if (profile == (std::string)_profile_name)
|
||||||
|
throw std::invalid_argument("cannot remove active profile");
|
||||||
|
else if (profile == (std::string)_config.default_profile)
|
||||||
|
throw std::invalid_argument("cannot remove default profile");
|
||||||
|
|
||||||
|
_config.profiles.erase(profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::clearProfile(const std::string& profile) {
|
||||||
|
std::unique_lock lock(_profile_mutex);
|
||||||
|
|
||||||
|
if (profile == (std::string)_profile_name) {
|
||||||
|
_profile->second = config::Profile();
|
||||||
|
|
||||||
|
for (auto& feature : _features)
|
||||||
|
feature.second->setProfile(_profile->second);
|
||||||
|
|
||||||
|
reconfigure();
|
||||||
|
} else {
|
||||||
|
auto it = _config.profiles.find(profile);
|
||||||
|
if (it != _config.profiles.end()) {
|
||||||
|
it->second = config::Profile();
|
||||||
|
} else {
|
||||||
|
throw std::invalid_argument("unknown profile");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config::Profile& Device::activeProfile() {
|
||||||
|
std::shared_lock lock(_profile_mutex);
|
||||||
return _profile->second;
|
return _profile->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,17 +316,22 @@ void Device::_makeResetMechanism() {
|
|||||||
Device::IPC::IPC(Device* device) :
|
Device::IPC::IPC(Device* device) :
|
||||||
ipcgull::interface(
|
ipcgull::interface(
|
||||||
SERVICE_ROOT_NAME ".Device",
|
SERVICE_ROOT_NAME ".Device",
|
||||||
{},
|
{
|
||||||
|
{"GetProfiles", {device, &Device::getProfiles, {"profiles"}}},
|
||||||
|
{"SetProfile", {device, &Device::setProfile, {"profile"}}},
|
||||||
|
{"RemoveProfile", {device, &Device::removeProfile, {"profile"}}},
|
||||||
|
{"ClearProfile", {device, &Device::clearProfile, {"profile"}}}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
{"Name", ipcgull::property<std::string>(
|
{"Name", ipcgull::property<std::string>(
|
||||||
ipcgull::property_readable, device->name())},
|
ipcgull::property_readable, device->name())},
|
||||||
{"ProductID", ipcgull::property<uint16_t>(
|
{"ProductID", ipcgull::property<uint16_t>(
|
||||||
ipcgull::property_readable, device->pid())},
|
ipcgull::property_readable, device->pid())},
|
||||||
{"Active", device->_awake},
|
{"Active", device->_awake},
|
||||||
{"DefaultProfile", device->_config.default_profile}
|
{"DefaultProfile", device->_config.default_profile},
|
||||||
|
{"ActiveProfile", device->_profile_name}
|
||||||
}, {
|
}, {
|
||||||
{"StatusChanged",
|
{"StatusChanged", ipcgull::signal::make_signal<bool>({"active"})}
|
||||||
ipcgull::signal::make_signal<bool>({"active"})}
|
|
||||||
}), _device(*device) {
|
}), _device(*device) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,10 +62,17 @@ namespace logid {
|
|||||||
|
|
||||||
uint16_t pid();
|
uint16_t pid();
|
||||||
|
|
||||||
//config::Device& config();
|
[[nodiscard]] config::Profile& activeProfile();
|
||||||
config::Profile& activeProfile();
|
|
||||||
|
|
||||||
[[nodiscard]] const config::Profile& activeProfile() const;
|
[[nodiscard]] std::vector<std::string> getProfiles() const;
|
||||||
|
|
||||||
|
void setProfile(const std::string& profile);
|
||||||
|
|
||||||
|
void setProfileDelayed(const std::string& profile);
|
||||||
|
|
||||||
|
void removeProfile(const std::string& profile);
|
||||||
|
|
||||||
|
void clearProfile(const std::string& profile);
|
||||||
|
|
||||||
backend::hidpp20::Device& hidpp20();
|
backend::hidpp20::Device& hidpp20();
|
||||||
|
|
||||||
@ -88,6 +95,8 @@ namespace logid {
|
|||||||
|
|
||||||
void sleep();
|
void sleep();
|
||||||
|
|
||||||
|
void reconfigure();
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
[[nodiscard]] std::shared_ptr<InputDevice> virtualInput() const;
|
[[nodiscard]] std::shared_ptr<InputDevice> virtualInput() const;
|
||||||
@ -107,7 +116,9 @@ namespace logid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Device(const Device&) = delete;
|
Device(const Device&) = delete;
|
||||||
|
|
||||||
Device(Device&&) = delete;
|
Device(Device&&) = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class DeviceWrapper;
|
friend class DeviceWrapper;
|
||||||
|
|
||||||
@ -139,9 +150,11 @@ namespace logid {
|
|||||||
std::shared_ptr<backend::hidpp20::Device> _hidpp20;
|
std::shared_ptr<backend::hidpp20::Device> _hidpp20;
|
||||||
std::string _path;
|
std::string _path;
|
||||||
backend::hidpp::DeviceIndex _index;
|
backend::hidpp::DeviceIndex _index;
|
||||||
std::map<std::string, std::shared_ptr<features::DeviceFeature>>
|
std::map<std::string, std::shared_ptr<features::DeviceFeature>> _features;
|
||||||
_features;
|
|
||||||
config::Device& _config;
|
config::Device& _config;
|
||||||
|
mutable std::shared_mutex _profile_mutex;
|
||||||
|
ipcgull::property<std::string> _profile_name;
|
||||||
std::map<std::string, config::Profile>::iterator _profile;
|
std::map<std::string, config::Profile>::iterator _profile;
|
||||||
|
|
||||||
Receiver* _receiver;
|
Receiver* _receiver;
|
||||||
|
@ -69,11 +69,7 @@ namespace logid::actions {
|
|||||||
|
|
||||||
virtual void release() = 0;
|
virtual void release() = 0;
|
||||||
|
|
||||||
virtual void move(int16_t x, int16_t y) {
|
virtual void move([[maybe_unused]] int16_t x, [[maybe_unused]] int16_t y) { }
|
||||||
// Suppress unused warning
|
|
||||||
(void) x;
|
|
||||||
(void) y;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool pressed() {
|
virtual bool pressed() {
|
||||||
return _pressed;
|
return _pressed;
|
||||||
|
@ -69,8 +69,8 @@ DPI::DPI(Device* device) : DeviceFeature(device), _config(device->activeProfile(
|
|||||||
void DPI::configure() {
|
void DPI::configure() {
|
||||||
std::shared_lock lock(_config_mutex);
|
std::shared_lock lock(_config_mutex);
|
||||||
|
|
||||||
if (_config.has_value()) {
|
if (_config.get().has_value()) {
|
||||||
const auto& config = _config.value();
|
const auto& config = _config.get().value();
|
||||||
if (std::holds_alternative<int>(config)) {
|
if (std::holds_alternative<int>(config)) {
|
||||||
const auto& dpi = std::get<int>(config);
|
const auto& dpi = std::get<int>(config);
|
||||||
_fillDPILists(0);
|
_fillDPILists(0);
|
||||||
@ -96,6 +96,11 @@ void DPI::configure() {
|
|||||||
void DPI::listen() {
|
void DPI::listen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DPI::setProfile(config::Profile& profile) {
|
||||||
|
std::unique_lock lock(_config_mutex);
|
||||||
|
_config = profile.dpi;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t DPI::getDPI(uint8_t sensor) {
|
uint16_t DPI::getDPI(uint8_t sensor) {
|
||||||
return _adjustable_dpi->getSensorDPI(sensor);
|
return _adjustable_dpi->getSensorDPI(sensor);
|
||||||
}
|
}
|
||||||
@ -145,17 +150,19 @@ std::tuple<std::vector<uint16_t>, uint16_t, bool> DPI::IPC::getDPIs(uint8_t sens
|
|||||||
|
|
||||||
uint16_t DPI::IPC::getDPI(uint8_t sensor) const {
|
uint16_t DPI::IPC::getDPI(uint8_t sensor) const {
|
||||||
std::shared_lock lock(_parent._config_mutex);
|
std::shared_lock lock(_parent._config_mutex);
|
||||||
if (!_parent._config.has_value())
|
auto& config = _parent._config.get();
|
||||||
|
|
||||||
|
if (!config.has_value())
|
||||||
return _parent.getDPI(sensor);
|
return _parent.getDPI(sensor);
|
||||||
|
|
||||||
if (std::holds_alternative<int>(_parent._config.value())) {
|
if (std::holds_alternative<int>(config.value())) {
|
||||||
if (sensor == 0)
|
if (sensor == 0)
|
||||||
return std::get<int>(_parent._config.value());
|
return std::get<int>(config.value());
|
||||||
else
|
else
|
||||||
return _parent.getDPI(sensor);
|
return _parent.getDPI(sensor);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& list = std::get<std::list<int>>(_parent._config.value());
|
const auto& list = std::get<std::list<int>>(config.value());
|
||||||
|
|
||||||
if (list.size() > sensor) {
|
if (list.size() > sensor) {
|
||||||
auto it = list.begin();
|
auto it = list.begin();
|
||||||
@ -168,21 +175,22 @@ uint16_t DPI::IPC::getDPI(uint8_t sensor) const {
|
|||||||
|
|
||||||
void DPI::IPC::setDPI(uint16_t dpi, uint8_t sensor) {
|
void DPI::IPC::setDPI(uint16_t dpi, uint8_t sensor) {
|
||||||
std::unique_lock lock(_parent._config_mutex);
|
std::unique_lock lock(_parent._config_mutex);
|
||||||
|
auto& config = _parent._config.get();
|
||||||
|
|
||||||
if (!_parent._config.has_value())
|
if (!config.has_value())
|
||||||
_parent._config.emplace(std::list<int>());
|
config.emplace(std::list<int>());
|
||||||
|
|
||||||
if (std::holds_alternative<int>(_parent._config.value())) {
|
if (std::holds_alternative<int>(config.value())) {
|
||||||
if (sensor == 0) {
|
if (sensor == 0) {
|
||||||
_parent._config.value() = dpi;
|
config.value() = dpi;
|
||||||
} else {
|
} else {
|
||||||
auto list = std::list<int>(sensor + 1, 0);
|
auto list = std::list<int>(sensor + 1, 0);
|
||||||
*list.rbegin() = dpi;
|
*list.rbegin() = dpi;
|
||||||
*list.begin() = dpi;
|
*list.begin() = dpi;
|
||||||
_parent._config.value() = list;
|
config.value() = list;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto& list = std::get<std::list<int>>(_parent._config.value());
|
auto& list = std::get<std::list<int>>(config.value());
|
||||||
|
|
||||||
while (list.size() <= sensor) {
|
while (list.size() <= sensor) {
|
||||||
list.emplace_back(0);
|
list.emplace_back(0);
|
||||||
|
@ -31,6 +31,8 @@ namespace logid::features {
|
|||||||
|
|
||||||
void listen() final;
|
void listen() final;
|
||||||
|
|
||||||
|
void setProfile(config::Profile& profile) final;
|
||||||
|
|
||||||
uint16_t getDPI(uint8_t sensor = 0);
|
uint16_t getDPI(uint8_t sensor = 0);
|
||||||
|
|
||||||
void setDPI(uint16_t dpi, uint8_t sensor = 0);
|
void setDPI(uint16_t dpi, uint8_t sensor = 0);
|
||||||
@ -59,7 +61,7 @@ namespace logid::features {
|
|||||||
};
|
};
|
||||||
|
|
||||||
mutable std::shared_mutex _config_mutex;
|
mutable std::shared_mutex _config_mutex;
|
||||||
std::optional<config::DPI>& _config;
|
std::reference_wrapper<std::optional<config::DPI>> _config;
|
||||||
std::shared_ptr<backend::hidpp20::AdjustableDPI> _adjustable_dpi;
|
std::shared_ptr<backend::hidpp20::AdjustableDPI> _adjustable_dpi;
|
||||||
mutable std::shared_mutex _dpi_list_mutex;
|
mutable std::shared_mutex _dpi_list_mutex;
|
||||||
std::vector<backend::hidpp20::AdjustableDPI::SensorDPIList> _dpi_lists;
|
std::vector<backend::hidpp20::AdjustableDPI::SensorDPIList> _dpi_lists;
|
||||||
|
@ -26,6 +26,10 @@ namespace logid {
|
|||||||
class Device;
|
class Device;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace logid::config {
|
||||||
|
struct Profile;
|
||||||
|
}
|
||||||
|
|
||||||
namespace logid::features {
|
namespace logid::features {
|
||||||
class UnsupportedFeature : public std::exception {
|
class UnsupportedFeature : public std::exception {
|
||||||
public:
|
public:
|
||||||
@ -59,6 +63,8 @@ namespace logid::features {
|
|||||||
|
|
||||||
virtual void listen() = 0;
|
virtual void listen() = 0;
|
||||||
|
|
||||||
|
virtual void setProfile(config::Profile& profile) = 0;
|
||||||
|
|
||||||
virtual ~DeviceFeature() = default;
|
virtual ~DeviceFeature() = default;
|
||||||
|
|
||||||
DeviceFeature(const DeviceFeature&) = delete;
|
DeviceFeature(const DeviceFeature&) = delete;
|
||||||
|
@ -61,4 +61,7 @@ void DeviceStatus::listen() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceStatus::setProfile(config::Profile&) {
|
||||||
|
}
|
||||||
|
@ -30,6 +30,8 @@ namespace logid::features {
|
|||||||
|
|
||||||
void listen() final;
|
void listen() final;
|
||||||
|
|
||||||
|
void setProfile(config::Profile& profile) final;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit DeviceStatus(Device* dev);
|
explicit DeviceStatus(Device* dev);
|
||||||
|
|
||||||
|
@ -39,16 +39,28 @@ HiresScroll::HiresScroll(Device* dev) :
|
|||||||
throw UnsupportedFeature();
|
throw UnsupportedFeature();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_config.has_value()) {
|
_makeConfig();
|
||||||
if (std::holds_alternative<bool>(_config.value())) {
|
|
||||||
|
_last_scroll = std::chrono::system_clock::now();
|
||||||
|
|
||||||
|
_ipc_interface = dev->ipcNode()->make_interface<IPC>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HiresScroll::_makeConfig() {
|
||||||
|
auto& config = _config.get();
|
||||||
|
_mode = 0;
|
||||||
|
_mask = 0;
|
||||||
|
|
||||||
|
if (config.has_value()) {
|
||||||
|
if (std::holds_alternative<bool>(config.value())) {
|
||||||
config::HiresScroll conf{};
|
config::HiresScroll conf{};
|
||||||
conf.hires = std::get<bool>(_config.value());
|
conf.hires = std::get<bool>(config.value());
|
||||||
conf.invert = false;
|
conf.invert = false;
|
||||||
conf.target = false;
|
conf.target = false;
|
||||||
_mask |= hidpp20::HiresScroll::Mode::HiRes;
|
_mask |= hidpp20::HiresScroll::Mode::HiRes;
|
||||||
_config.value() = conf;
|
config.value() = conf;
|
||||||
}
|
}
|
||||||
auto& conf = std::get<config::HiresScroll>(_config.value());
|
auto& conf = std::get<config::HiresScroll>(config.value());
|
||||||
if (conf.hires.has_value()) {
|
if (conf.hires.has_value()) {
|
||||||
_mask |= hidpp20::HiresScroll::Mode::HiRes;
|
_mask |= hidpp20::HiresScroll::Mode::HiRes;
|
||||||
if (conf.hires.value())
|
if (conf.hires.value())
|
||||||
@ -68,10 +80,6 @@ HiresScroll::HiresScroll(Device* dev) :
|
|||||||
_makeGesture(_up_gesture, conf.up, "up");
|
_makeGesture(_up_gesture, conf.up, "up");
|
||||||
_makeGesture(_down_gesture, conf.down, "down");
|
_makeGesture(_down_gesture, conf.down, "down");
|
||||||
}
|
}
|
||||||
|
|
||||||
_last_scroll = std::chrono::system_clock::now();
|
|
||||||
|
|
||||||
_ipc_interface = dev->ipcNode()->make_interface<IPC>(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HiresScroll::configure() {
|
void HiresScroll::configure() {
|
||||||
@ -103,6 +111,15 @@ void HiresScroll::listen() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HiresScroll::setProfile(config::Profile& profile) {
|
||||||
|
std::unique_lock lock(_config_mutex);
|
||||||
|
|
||||||
|
_up_gesture.reset();
|
||||||
|
_down_gesture.reset();
|
||||||
|
_config = profile.hiresscroll;
|
||||||
|
_makeConfig();
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t HiresScroll::getMode() {
|
uint8_t HiresScroll::getMode() {
|
||||||
return _hires_scroll->getMode();
|
return _hires_scroll->getMode();
|
||||||
}
|
}
|
||||||
@ -189,15 +206,17 @@ HiresScroll::IPC::IPC(HiresScroll* parent) : ipcgull::interface(
|
|||||||
std::tuple<bool, bool, bool> HiresScroll::IPC::getConfig() const {
|
std::tuple<bool, bool, bool> HiresScroll::IPC::getConfig() const {
|
||||||
std::shared_lock lock(_parent._config_mutex);
|
std::shared_lock lock(_parent._config_mutex);
|
||||||
|
|
||||||
if (_parent._config.has_value()) {
|
auto& config = _parent._config.get();
|
||||||
if (std::holds_alternative<bool>(_parent._config.value())) {
|
|
||||||
return {std::get<bool>(_parent._config.value()), false, false};
|
if (config.has_value()) {
|
||||||
|
if (std::holds_alternative<bool>(config.value())) {
|
||||||
|
return {std::get<bool>(config.value()), false, false};
|
||||||
} else {
|
} else {
|
||||||
const auto& config = std::get<config::HiresScroll>(_parent._config.value());
|
const auto& config_obj = std::get<config::HiresScroll>(config.value());
|
||||||
return {
|
return {
|
||||||
config.hires.value_or(true),
|
config_obj.hires.value_or(true),
|
||||||
config.invert.value_or(false),
|
config_obj.invert.value_or(false),
|
||||||
config.target.value_or(false)
|
config_obj.target.value_or(false)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -206,16 +225,17 @@ std::tuple<bool, bool, bool> HiresScroll::IPC::getConfig() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
config::HiresScroll& HiresScroll::IPC::_parentConfig() {
|
config::HiresScroll& HiresScroll::IPC::_parentConfig() {
|
||||||
if (!_parent._config.has_value()) {
|
auto& config = _parent._config.get();
|
||||||
_parent._config = config::HiresScroll();
|
if (!config.has_value()) {
|
||||||
} else if (std::holds_alternative<bool>(_parent._config.value())) {
|
config = config::HiresScroll();
|
||||||
bool hires = std::get<bool>(_parent._config.value());
|
} else if (std::holds_alternative<bool>(config.value())) {
|
||||||
auto config = config::HiresScroll();
|
bool hires = std::get<bool>(config.value());
|
||||||
config.hires = hires;
|
auto new_config = config::HiresScroll();
|
||||||
_parent._config = hires;
|
new_config.hires = hires;
|
||||||
|
config = new_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::get<config::HiresScroll>(_parent._config.value());
|
return std::get<config::HiresScroll>(config.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HiresScroll::IPC::setHires(bool hires) {
|
void HiresScroll::IPC::setHires(bool hires) {
|
||||||
|
@ -34,6 +34,8 @@ namespace logid::features {
|
|||||||
|
|
||||||
void listen() final;
|
void listen() final;
|
||||||
|
|
||||||
|
void setProfile(config::Profile& profile) final;
|
||||||
|
|
||||||
[[nodiscard]] uint8_t getMode();
|
[[nodiscard]] uint8_t getMode();
|
||||||
|
|
||||||
void setMode(uint8_t mode);
|
void setMode(uint8_t mode);
|
||||||
@ -42,6 +44,8 @@ namespace logid::features {
|
|||||||
explicit HiresScroll(Device* dev);
|
explicit HiresScroll(Device* dev);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void _makeConfig();
|
||||||
|
|
||||||
EventHandlerLock<backend::hidpp::Device> _ev_handler;
|
EventHandlerLock<backend::hidpp::Device> _ev_handler;
|
||||||
|
|
||||||
void _makeGesture(std::shared_ptr<actions::Gesture>& gesture,
|
void _makeGesture(std::shared_ptr<actions::Gesture>& gesture,
|
||||||
@ -81,7 +85,7 @@ namespace logid::features {
|
|||||||
int16_t _last_direction = 0;
|
int16_t _last_direction = 0;
|
||||||
|
|
||||||
mutable std::shared_mutex _config_mutex;
|
mutable std::shared_mutex _config_mutex;
|
||||||
std::optional<std::variant<bool, config::HiresScroll>>& _config;
|
std::reference_wrapper<std::optional<std::variant<bool, config::HiresScroll>>> _config;
|
||||||
|
|
||||||
uint8_t _mode;
|
uint8_t _mode;
|
||||||
uint8_t _mask;
|
uint8_t _mask;
|
||||||
|
@ -46,8 +46,10 @@ RemapButton::RemapButton(Device* dev) : DeviceFeature(dev),
|
|||||||
|
|
||||||
_reprog_controls->initCidMap();
|
_reprog_controls->initCidMap();
|
||||||
|
|
||||||
if (!_config.has_value())
|
auto& config = _config.get();
|
||||||
_config = config::RemapButton();
|
|
||||||
|
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();
|
const auto i = _buttons.size();
|
||||||
@ -58,8 +60,7 @@ RemapButton::RemapButton(Device* dev) : DeviceFeature(dev),
|
|||||||
report.flags = hidpp20_reprog_rebind;
|
report.flags = hidpp20_reprog_rebind;
|
||||||
|
|
||||||
if (action) {
|
if (action) {
|
||||||
if ((action->reprogFlags() &
|
if ((action->reprogFlags() & hidpp20::ReprogControls::RawXYDiverted) &&
|
||||||
hidpp20::ReprogControls::RawXYDiverted) &&
|
|
||||||
(!_reprog_controls->supportsRawXY() ||
|
(!_reprog_controls->supportsRawXY() ||
|
||||||
!(info.additionalFlags & hidpp20::ReprogControls::RawXY)))
|
!(info.additionalFlags & hidpp20::ReprogControls::RawXY)))
|
||||||
logPrintf(WARN, "%s: Cannot divert raw XY movements for CID 0x%02x",
|
logPrintf(WARN, "%s: Cannot divert raw XY movements for CID 0x%02x",
|
||||||
@ -72,7 +73,7 @@ RemapButton::RemapButton(Device* dev) : DeviceFeature(dev),
|
|||||||
_buttons.emplace(control.second.controlID,
|
_buttons.emplace(control.second.controlID,
|
||||||
Button::make(control.second, (int) i,
|
Button::make(control.second, (int) i,
|
||||||
_device, func, _ipc_node,
|
_device, func, _ipc_node,
|
||||||
_config.value()[control.first]));
|
config.value()[control.first]));
|
||||||
}
|
}
|
||||||
|
|
||||||
_ipc_interface = _device->ipcNode()->make_interface<IPC>(this);
|
_ipc_interface = _device->ipcNode()->make_interface<IPC>(this);
|
||||||
@ -137,6 +138,18 @@ void RemapButton::listen() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemapButton::setProfile(config::Profile& profile) {
|
||||||
|
std::lock_guard<std::mutex> lock(_button_lock);
|
||||||
|
|
||||||
|
_config = profile.buttons;
|
||||||
|
if (!_config.get().has_value())
|
||||||
|
_config.get().emplace();
|
||||||
|
auto& config = _config.get().value();
|
||||||
|
|
||||||
|
for(auto& button : _buttons)
|
||||||
|
button.second->setProfile(config[button.first]);
|
||||||
|
}
|
||||||
|
|
||||||
void RemapButton::_buttonEvent(const std::set<uint16_t>& new_state) {
|
void RemapButton::_buttonEvent(const std::set<uint16_t>& new_state) {
|
||||||
// Ensure I/O doesn't occur while updating button state
|
// Ensure I/O doesn't occur while updating button state
|
||||||
std::lock_guard<std::mutex> lock(_button_lock);
|
std::lock_guard<std::mutex> lock(_button_lock);
|
||||||
@ -191,48 +204,59 @@ Button::Button(Info info, int index,
|
|||||||
_device(device), _conf_func(std::move(conf_func)),
|
_device(device), _conf_func(std::move(conf_func)),
|
||||||
_config(config),
|
_config(config),
|
||||||
_info(info) {
|
_info(info) {
|
||||||
if (_config.action.has_value()) {
|
_makeConfig();
|
||||||
try {
|
|
||||||
_action = Action::makeAction(_device, _config.action.value(), _node);
|
|
||||||
} catch (std::exception& e) {
|
|
||||||
logPrintf(WARN, "Error creating button action: %s",
|
|
||||||
e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ipc_interface = _node->make_interface<IPC>(this, _info);
|
_ipc_interface = _node->make_interface<IPC>(this, _info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Button::_makeConfig() {
|
||||||
|
auto& config = _config.get();
|
||||||
|
if (config.action.has_value()) {
|
||||||
|
try {
|
||||||
|
_action = Action::makeAction(_device, config.action.value(), _node);
|
||||||
|
} catch (std::exception& e) {
|
||||||
|
logPrintf(WARN, "Error creating button action: %s", e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Button::press() const {
|
void Button::press() const {
|
||||||
std::lock_guard<std::mutex> lock(_action_lock);
|
std::shared_lock lock(_action_lock);
|
||||||
if (_action)
|
if (_action)
|
||||||
_action->press();
|
_action->press();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::release() const {
|
void Button::release() const {
|
||||||
std::lock_guard<std::mutex> lock(_action_lock);
|
std::shared_lock lock(_action_lock);
|
||||||
if (_action)
|
if (_action)
|
||||||
_action->release();
|
_action->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::move(int16_t x, int16_t y) const {
|
void Button::move(int16_t x, int16_t y) const {
|
||||||
std::lock_guard<std::mutex> lock(_action_lock);
|
std::shared_lock lock(_action_lock);
|
||||||
if (_action)
|
if (_action)
|
||||||
_action->move(x, y);
|
_action->move(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Button::pressed() const {
|
bool Button::pressed() const {
|
||||||
std::lock_guard<std::mutex> lock(_action_lock);
|
std::shared_lock lock(_action_lock);
|
||||||
if (_action)
|
if (_action)
|
||||||
return _action->pressed();
|
return _action->pressed();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Button::configure() const {
|
void Button::configure() const {
|
||||||
std::lock_guard<std::mutex> lock(_action_lock);
|
std::shared_lock lock(_action_lock);
|
||||||
_conf_func(_action);
|
_conf_func(_action);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Button::setProfile(config::Button& config) {
|
||||||
|
std::unique_lock lock(_action_lock);
|
||||||
|
_config = config;
|
||||||
|
_action.reset();
|
||||||
|
_makeConfig();
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<ipcgull::node> Button::node() const {
|
std::shared_ptr<ipcgull::node> Button::node() const {
|
||||||
return _node;
|
return _node;
|
||||||
}
|
}
|
||||||
@ -265,11 +289,11 @@ void Button::IPC::setAction(const std::string& type) {
|
|||||||
throw std::invalid_argument("No gesture support");
|
throw std::invalid_argument("No gesture support");
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(_button._action_lock);
|
std::unique_lock lock(_button._action_lock);
|
||||||
_button._action.reset();
|
_button._action.reset();
|
||||||
_button._action = Action::makeAction(
|
_button._action = Action::makeAction(
|
||||||
_button._device, type,
|
_button._device, type,
|
||||||
_button._config.action, _button._node);
|
_button._config.get().action, _button._node);
|
||||||
}
|
}
|
||||||
_button.configure();
|
_button.configure();
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,8 @@ namespace logid::features {
|
|||||||
|
|
||||||
void move(int16_t x, int16_t y) const;
|
void move(int16_t x, int16_t y) const;
|
||||||
|
|
||||||
|
void setProfile(config::Button& config);
|
||||||
|
|
||||||
[[nodiscard]] std::shared_ptr<ipcgull::node> node() const;
|
[[nodiscard]] std::shared_ptr<ipcgull::node> node() const;
|
||||||
|
|
||||||
void configure() const;
|
void configure() const;
|
||||||
@ -51,6 +53,8 @@ namespace logid::features {
|
|||||||
private:
|
private:
|
||||||
friend class ButtonWrapper;
|
friend class ButtonWrapper;
|
||||||
|
|
||||||
|
void _makeConfig();
|
||||||
|
|
||||||
Button(Info info, int index,
|
Button(Info info, int index,
|
||||||
Device* device, ConfigFunction conf_func,
|
Device* device, ConfigFunction conf_func,
|
||||||
const std::shared_ptr<ipcgull::node>& root,
|
const std::shared_ptr<ipcgull::node>& root,
|
||||||
@ -72,9 +76,9 @@ namespace logid::features {
|
|||||||
Device* _device;
|
Device* _device;
|
||||||
const ConfigFunction _conf_func;
|
const ConfigFunction _conf_func;
|
||||||
|
|
||||||
config::Button& _config;
|
std::reference_wrapper<config::Button> _config;
|
||||||
|
|
||||||
mutable std::mutex _action_lock;
|
mutable std::shared_mutex _action_lock;
|
||||||
std::shared_ptr<actions::Action> _action;
|
std::shared_ptr<actions::Action> _action;
|
||||||
const Info _info;
|
const Info _info;
|
||||||
|
|
||||||
@ -89,6 +93,8 @@ namespace logid::features {
|
|||||||
|
|
||||||
void listen() final;
|
void listen() final;
|
||||||
|
|
||||||
|
void setProfile(config::Profile& profile) final;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit RemapButton(Device* dev);
|
explicit RemapButton(Device* dev);
|
||||||
|
|
||||||
@ -99,7 +105,7 @@ namespace logid::features {
|
|||||||
std::set<uint16_t> _pressed_buttons;
|
std::set<uint16_t> _pressed_buttons;
|
||||||
std::mutex _button_lock;
|
std::mutex _button_lock;
|
||||||
|
|
||||||
std::optional<config::RemapButton>& _config;
|
std::reference_wrapper<std::optional<config::RemapButton>> _config;
|
||||||
std::map<uint16_t, std::shared_ptr<Button>> _buttons;
|
std::map<uint16_t, std::shared_ptr<Button>> _buttons;
|
||||||
|
|
||||||
std::shared_ptr<ipcgull::node> _ipc_node;
|
std::shared_ptr<ipcgull::node> _ipc_node;
|
||||||
|
@ -34,8 +34,10 @@ SmartShift::SmartShift(Device* device) : DeviceFeature(device),
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SmartShift::configure() {
|
void SmartShift::configure() {
|
||||||
if (_config.has_value()) {
|
std::shared_lock lock(_config_mutex);
|
||||||
const auto& conf = _config.value();
|
auto& config = _config.get();
|
||||||
|
if (config.has_value()) {
|
||||||
|
const auto& conf = config.value();
|
||||||
Status settings{};
|
Status settings{};
|
||||||
settings.setActive = conf.on.has_value();
|
settings.setActive = conf.on.has_value();
|
||||||
if (settings.setActive)
|
if (settings.setActive)
|
||||||
@ -51,6 +53,11 @@ void SmartShift::configure() {
|
|||||||
void SmartShift::listen() {
|
void SmartShift::listen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SmartShift::setProfile(config::Profile& profile) {
|
||||||
|
std::unique_lock lock(_config_mutex);
|
||||||
|
_config = profile.smartshift;
|
||||||
|
}
|
||||||
|
|
||||||
SmartShift::Status SmartShift::getStatus() const {
|
SmartShift::Status SmartShift::getStatus() const {
|
||||||
return _smartshift->getStatus();
|
return _smartshift->getStatus();
|
||||||
}
|
}
|
||||||
@ -94,39 +101,51 @@ void SmartShift::IPC::setThreshold(uint8_t threshold) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<bool, bool, bool, uint8_t> SmartShift::IPC::getDefault() const {
|
std::tuple<bool, bool, bool, uint8_t> SmartShift::IPC::getDefault() const {
|
||||||
if (!_parent._config.has_value())
|
std::shared_lock lock(_parent._config_mutex);
|
||||||
|
|
||||||
|
auto& config = _parent._config.get();
|
||||||
|
|
||||||
|
if (!config.has_value())
|
||||||
return {false, false, false, 0};
|
return {false, false, false, 0};
|
||||||
|
|
||||||
std::tuple<bool, bool, bool, uint8_t> ret;
|
std::tuple<bool, bool, bool, uint8_t> ret;
|
||||||
std::get<0>(ret) = _parent._config.value().on.has_value();
|
std::get<0>(ret) = config.value().on.has_value();
|
||||||
if (std::get<0>(ret))
|
if (std::get<0>(ret))
|
||||||
std::get<1>(ret) = _parent._config.value().on.value();
|
std::get<1>(ret) = config.value().on.value();
|
||||||
std::get<2>(ret) = _parent._config.value().threshold.has_value();
|
std::get<2>(ret) = config.value().threshold.has_value();
|
||||||
if (std::get<2>(ret))
|
if (std::get<2>(ret))
|
||||||
std::get<3>(ret) = _parent._config.value().threshold.value();
|
std::get<3>(ret) = config.value().threshold.value();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmartShift::IPC::clearDefaultActive() {
|
void SmartShift::IPC::clearDefaultActive() {
|
||||||
if (_parent._config.has_value())
|
std::unique_lock lock(_parent._config_mutex);
|
||||||
_parent._config.value().on.reset();
|
auto& config = _parent._config.get();
|
||||||
|
if (config.has_value())
|
||||||
|
config.value().on.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmartShift::IPC::setDefaultActive(bool active) {
|
void SmartShift::IPC::setDefaultActive(bool active) {
|
||||||
if (!_parent._config.has_value())
|
std::unique_lock lock(_parent._config_mutex);
|
||||||
_parent._config = config::SmartShift{};
|
auto& config = _parent._config.get();
|
||||||
_parent._config.value().on = active;
|
if (!config.has_value())
|
||||||
|
config = config::SmartShift{};
|
||||||
|
config.value().on = active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SmartShift::IPC::clearDefaultThreshold() {
|
void SmartShift::IPC::clearDefaultThreshold() {
|
||||||
if (_parent._config.has_value())
|
std::unique_lock lock(_parent._config_mutex);
|
||||||
_parent._config.value().threshold.reset();
|
auto& config = _parent._config.get();
|
||||||
|
if (config.has_value())
|
||||||
|
config.value().threshold.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SmartShift::IPC::setDefaultThreshold(uint8_t threshold) {
|
void SmartShift::IPC::setDefaultThreshold(uint8_t threshold) {
|
||||||
if (!_parent._config.has_value())
|
std::unique_lock lock(_parent._config_mutex);
|
||||||
_parent._config = config::SmartShift{};
|
auto& config = _parent._config.get();
|
||||||
_parent._config.value().threshold = threshold;
|
if (!config.has_value())
|
||||||
|
config = config::SmartShift{};
|
||||||
|
config.value().threshold = threshold;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <backend/hidpp20/features/SmartShift.h>
|
#include <backend/hidpp20/features/SmartShift.h>
|
||||||
#include <ipcgull/interface.h>
|
#include <ipcgull/interface.h>
|
||||||
#include <config/schema.h>
|
#include <config/schema.h>
|
||||||
|
#include <shared_mutex>
|
||||||
|
|
||||||
namespace logid::features {
|
namespace logid::features {
|
||||||
class SmartShift : public DeviceFeature {
|
class SmartShift : public DeviceFeature {
|
||||||
@ -31,6 +32,8 @@ namespace logid::features {
|
|||||||
|
|
||||||
void listen() final;
|
void listen() final;
|
||||||
|
|
||||||
|
void setProfile(config::Profile& profile) final;
|
||||||
|
|
||||||
typedef backend::hidpp20::SmartShift::SmartshiftStatus Status;
|
typedef backend::hidpp20::SmartShift::SmartshiftStatus Status;
|
||||||
|
|
||||||
[[nodiscard]] Status getStatus() const;
|
[[nodiscard]] Status getStatus() const;
|
||||||
@ -41,7 +44,8 @@ namespace logid::features {
|
|||||||
explicit SmartShift(Device* dev);
|
explicit SmartShift(Device* dev);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<config::SmartShift>& _config;
|
mutable std::shared_mutex _config_mutex;
|
||||||
|
std::reference_wrapper<std::optional<config::SmartShift>> _config;
|
||||||
std::shared_ptr<backend::hidpp20::SmartShift> _smartshift;
|
std::shared_ptr<backend::hidpp20::SmartShift> _smartshift;
|
||||||
|
|
||||||
class IPC : public ipcgull::interface {
|
class IPC : public ipcgull::interface {
|
||||||
|
@ -80,14 +80,7 @@ ThumbWheel::ThumbWheel(Device* dev) : DeviceFeature(dev), _wheel_info(),
|
|||||||
throw UnsupportedFeature();
|
throw UnsupportedFeature();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_config.has_value()) {
|
_makeConfig();
|
||||||
auto& conf = _config.value();
|
|
||||||
_left_gesture = _genGesture(dev, conf.left, _left_node, "left");
|
|
||||||
_right_gesture = _genGesture(dev, conf.right, _right_node, "right");
|
|
||||||
_touch_action = _genAction(dev, conf.touch, _touch_node);
|
|
||||||
_tap_action = _genAction(dev, conf.tap, _tap_node);
|
|
||||||
_proxy_action = _genAction(dev, conf.proxy, _proxy_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
_wheel_info = _thumb_wheel->getInfo();
|
_wheel_info = _thumb_wheel->getInfo();
|
||||||
|
|
||||||
@ -109,12 +102,24 @@ ThumbWheel::ThumbWheel(Device* dev) : DeviceFeature(dev), _wheel_info(),
|
|||||||
_ipc_interface = dev->ipcNode()->make_interface<IPC>(this);
|
_ipc_interface = dev->ipcNode()->make_interface<IPC>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThumbWheel::_makeConfig() {
|
||||||
|
if (_config.get().has_value()) {
|
||||||
|
auto& conf = _config.get().value();
|
||||||
|
_left_gesture = _genGesture(_device, conf.left, _left_node, "left");
|
||||||
|
_right_gesture = _genGesture(_device, conf.right, _right_node, "right");
|
||||||
|
_touch_action = _genAction(_device, conf.touch, _touch_node);
|
||||||
|
_tap_action = _genAction(_device, conf.tap, _tap_node);
|
||||||
|
_proxy_action = _genAction(_device, conf.proxy, _proxy_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ThumbWheel::configure() {
|
void ThumbWheel::configure() {
|
||||||
std::shared_lock lock(_config_mutex);
|
std::shared_lock lock(_config_mutex);
|
||||||
if (_config.has_value()) {
|
auto& config = _config.get();
|
||||||
const auto& config = _config.value();
|
if (config.has_value()) {
|
||||||
_thumb_wheel->setStatus(config.divert.value_or(false),
|
const auto& value = config.value();
|
||||||
config.invert.value_or(false));
|
_thumb_wheel->setStatus(value.divert.value_or(false),
|
||||||
|
value.invert.value_or(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,10 +128,8 @@ void ThumbWheel::listen() {
|
|||||||
_ev_handler = _device->hidpp20().addEventHandler(
|
_ev_handler = _device->hidpp20().addEventHandler(
|
||||||
{[index = _thumb_wheel->featureIndex()]
|
{[index = _thumb_wheel->featureIndex()]
|
||||||
(const hidpp::Report& report) -> bool {
|
(const hidpp::Report& report) -> bool {
|
||||||
return (report.feature() ==
|
return (report.feature() == index) &&
|
||||||
index) &&
|
(report.function() == hidpp20::ThumbWheel::Event);
|
||||||
(report.function() ==
|
|
||||||
hidpp20::ThumbWheel::Event);
|
|
||||||
},
|
},
|
||||||
[self_weak = self<ThumbWheel>()](const hidpp::Report& report) -> void {
|
[self_weak = self<ThumbWheel>()](const hidpp::Report& report) -> void {
|
||||||
if (auto self = self_weak.lock())
|
if (auto self = self_weak.lock())
|
||||||
@ -136,6 +139,17 @@ void ThumbWheel::listen() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ThumbWheel::setProfile(config::Profile& profile) {
|
||||||
|
std::unique_lock lock(_config_mutex);
|
||||||
|
_config = profile.thumbwheel;
|
||||||
|
_left_gesture.reset();
|
||||||
|
_right_gesture.reset();
|
||||||
|
_touch_action.reset();
|
||||||
|
_tap_action.reset();
|
||||||
|
_proxy_action.reset();
|
||||||
|
_makeConfig();
|
||||||
|
}
|
||||||
|
|
||||||
void ThumbWheel::_handleEvent(hidpp20::ThumbWheel::ThumbwheelEvent event) {
|
void ThumbWheel::_handleEvent(hidpp20::ThumbWheel::ThumbwheelEvent event) {
|
||||||
std::shared_lock lock(_config_mutex);
|
std::shared_lock lock(_config_mutex);
|
||||||
if (event.flags & hidpp20::ThumbWheel::SingleTap) {
|
if (event.flags & hidpp20::ThumbWheel::SingleTap) {
|
||||||
@ -227,22 +241,24 @@ ThumbWheel::IPC::IPC(ThumbWheel* parent) : ipcgull::interface(
|
|||||||
}
|
}
|
||||||
|
|
||||||
config::ThumbWheel& ThumbWheel::IPC::_parentConfig() {
|
config::ThumbWheel& ThumbWheel::IPC::_parentConfig() {
|
||||||
if (!_parent._config.has_value()) {
|
auto& config = _parent._config.get();
|
||||||
_parent._config.emplace();
|
if (!config.has_value()) {
|
||||||
|
config.emplace();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _parent._config.value();
|
return config.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<bool, bool> ThumbWheel::IPC::getConfig() const {
|
std::tuple<bool, bool> ThumbWheel::IPC::getConfig() const {
|
||||||
std::shared_lock lock(_parent._config_mutex);
|
std::shared_lock lock(_parent._config_mutex);
|
||||||
|
|
||||||
if (!_parent._config.has_value()) {
|
auto& config = _parent._config.get();
|
||||||
|
if (!config.has_value()) {
|
||||||
return {false, false};
|
return {false, false};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {_parent._config.value().divert.value_or(false),
|
return {config.value().divert.value_or(false),
|
||||||
_parent._config.value().invert.value_or(false)};
|
config.value().invert.value_or(false)};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThumbWheel::IPC::setDivert(bool divert) {
|
void ThumbWheel::IPC::setDivert(bool divert) {
|
||||||
|
@ -32,7 +32,11 @@ namespace logid::features {
|
|||||||
|
|
||||||
void listen() final;
|
void listen() final;
|
||||||
|
|
||||||
|
void setProfile(config::Profile& profile) final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void _makeConfig();
|
||||||
|
|
||||||
void _handleEvent(backend::hidpp20::ThumbWheel::ThumbwheelEvent event);
|
void _handleEvent(backend::hidpp20::ThumbWheel::ThumbwheelEvent event);
|
||||||
|
|
||||||
void _fixGesture(const std::shared_ptr<actions::Gesture>& gesture) const;
|
void _fixGesture(const std::shared_ptr<actions::Gesture>& gesture) const;
|
||||||
@ -59,6 +63,7 @@ namespace logid::features {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
config::ThumbWheel& _parentConfig();
|
config::ThumbWheel& _parentConfig();
|
||||||
|
|
||||||
ThumbWheel& _parent;
|
ThumbWheel& _parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -82,7 +87,7 @@ namespace logid::features {
|
|||||||
bool _last_touch = false;
|
bool _last_touch = false;
|
||||||
|
|
||||||
mutable std::shared_mutex _config_mutex;
|
mutable std::shared_mutex _config_mutex;
|
||||||
std::optional<config::ThumbWheel>& _config;
|
std::reference_wrapper<std::optional<config::ThumbWheel>> _config;
|
||||||
|
|
||||||
EventHandlerLock<backend::hidpp::Device> _ev_handler;
|
EventHandlerLock<backend::hidpp::Device> _ev_handler;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user