mirror of
https://github.com/PixlOne/logiops.git
synced 2025-07-13 21:02:43 +08:00
Add Device and Receiver signals to DeviceManager
This commit is contained in:
parent
daa8c37c7d
commit
918ea63755
@ -1 +1 @@
|
||||
Subproject commit 89c6103af33705320494043da86c4709cc938b32
|
||||
Subproject commit 0d53465fe70ab07e07f9f9d853413a6cc82704c6
|
@ -32,37 +32,106 @@
|
||||
using namespace logid;
|
||||
using namespace logid::backend;
|
||||
|
||||
DeviceNickname::DeviceNickname(const std::shared_ptr<DeviceManager>& manager) :
|
||||
_nickname (manager->newDeviceNickname()), _manager (manager)
|
||||
{
|
||||
}
|
||||
|
||||
DeviceNickname::operator std::string() const {
|
||||
return std::to_string(_nickname);
|
||||
}
|
||||
|
||||
DeviceNickname::~DeviceNickname()
|
||||
{
|
||||
if(auto manager = _manager.lock()) {
|
||||
std::lock_guard<std::mutex> lock(manager->_nick_lock);
|
||||
manager->_device_nicknames.erase(_nickname);
|
||||
}
|
||||
}
|
||||
|
||||
namespace logid {
|
||||
class _Device : public Device {
|
||||
public:
|
||||
template <typename... Args>
|
||||
_Device(Args... args) : Device(std::forward<Args>(args)...) { }
|
||||
};
|
||||
}
|
||||
|
||||
std::shared_ptr<Device> Device::make(
|
||||
std::string path, backend::hidpp::DeviceIndex index,
|
||||
std::shared_ptr<DeviceManager> manager)
|
||||
{
|
||||
auto ret = std::make_shared<_Device>(std::move(path),
|
||||
index,
|
||||
std::move(manager));
|
||||
ret->_self = ret;
|
||||
ret->_ipc_node->manage(ret);
|
||||
ret->_ipc_interface = ret->_ipc_node->make_interface<DeviceIPC>(ret.get());
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::shared_ptr<Device> Device::make(
|
||||
std::shared_ptr<backend::raw::RawDevice> raw_device,
|
||||
backend::hidpp::DeviceIndex index,
|
||||
std::shared_ptr<DeviceManager> manager)
|
||||
{
|
||||
auto ret = std::make_shared<_Device>(std::move(raw_device),
|
||||
index,
|
||||
std::move(manager));
|
||||
ret->_self = ret;
|
||||
ret->_ipc_node->manage(ret);
|
||||
ret->_ipc_interface = ret->_ipc_node->make_interface<DeviceIPC>(ret.get());
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::shared_ptr<Device> Device::make(
|
||||
Receiver* receiver, backend::hidpp::DeviceIndex index,
|
||||
std::shared_ptr<DeviceManager> manager)
|
||||
{
|
||||
auto ret = std::make_shared<_Device>(receiver, index, std::move(manager));
|
||||
ret->_self = ret;
|
||||
ret->_ipc_node->manage(ret);
|
||||
ret->_ipc_interface = ret->_ipc_node->make_interface<DeviceIPC>(ret.get());
|
||||
return ret;
|
||||
}
|
||||
|
||||
Device::Device(std::string path, backend::hidpp::DeviceIndex index,
|
||||
const std::shared_ptr<DeviceManager>& manager) :
|
||||
std::shared_ptr<DeviceManager> manager) :
|
||||
_hidpp20 (path, index,
|
||||
manager->config()->ioTimeout(), manager->workQueue()),
|
||||
_path (std::move(path)), _index (index),
|
||||
_config (manager->config(), this),
|
||||
_receiver (nullptr),
|
||||
_manager (manager)
|
||||
_manager (manager),
|
||||
_nickname (manager),
|
||||
_ipc_node(manager->devicesNode()->make_child(_nickname))
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
Device::Device(const std::shared_ptr<backend::raw::RawDevice>& raw_device,
|
||||
Device::Device(std::shared_ptr<backend::raw::RawDevice> raw_device,
|
||||
hidpp::DeviceIndex index,
|
||||
const std::shared_ptr<DeviceManager>& manager) :
|
||||
std::shared_ptr<DeviceManager> manager) :
|
||||
_hidpp20(raw_device, index),
|
||||
_path (raw_device->hidrawPath()), _index (index),
|
||||
_config (manager->config(), this),
|
||||
_receiver (nullptr),
|
||||
_manager (manager)
|
||||
_manager (manager),
|
||||
_nickname (manager),
|
||||
_ipc_node (manager->devicesNode()->make_child(_nickname))
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
Device::Device(Receiver* receiver, hidpp::DeviceIndex index,
|
||||
const std::shared_ptr<DeviceManager>& manager) :
|
||||
std::shared_ptr<DeviceManager> manager) :
|
||||
_hidpp20 (receiver->rawReceiver(), index),
|
||||
_path (receiver->path()), _index (index),
|
||||
_config (manager->config(), this),
|
||||
_receiver (receiver),
|
||||
_manager (manager)
|
||||
_manager (manager),
|
||||
_nickname (manager),
|
||||
_ipc_node (manager->devicesNode()->make_child(_nickname))
|
||||
{
|
||||
_init();
|
||||
}
|
||||
@ -173,6 +242,12 @@ void Device::_makeResetMechanism()
|
||||
}
|
||||
}
|
||||
|
||||
Device::DeviceIPC::DeviceIPC(Device* device) :
|
||||
ipcgull::interface("pizza.pixl.LogiOps.Device", {}, {}, {})
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
DeviceConfig::DeviceConfig(const std::shared_ptr<Configuration>& config, Device*
|
||||
device) : _device (device), _config (config)
|
||||
{
|
||||
|
@ -19,6 +19,8 @@
|
||||
#ifndef LOGID_DEVICE_H
|
||||
#define LOGID_DEVICE_H
|
||||
|
||||
#include <ipcgull/node.h>
|
||||
#include <ipcgull/interface.h>
|
||||
#include "backend/hidpp/defs.h"
|
||||
#include "backend/hidpp20/Device.h"
|
||||
#include "features/DeviceFeature.h"
|
||||
@ -32,6 +34,19 @@ namespace logid
|
||||
class Receiver;
|
||||
class InputDevice;
|
||||
|
||||
class DeviceNickname {
|
||||
public:
|
||||
explicit DeviceNickname(const std::shared_ptr<DeviceManager>& manager);
|
||||
DeviceNickname() = delete;
|
||||
DeviceNickname(const DeviceNickname&) = delete;
|
||||
~DeviceNickname();
|
||||
|
||||
operator std::string() const;
|
||||
private:
|
||||
const int _nickname;
|
||||
const std::weak_ptr<DeviceManager> _manager;
|
||||
};
|
||||
|
||||
class DeviceConfig
|
||||
{
|
||||
public:
|
||||
@ -48,23 +63,28 @@ namespace logid
|
||||
* Currently, the logid::Device class has a hardcoded requirement
|
||||
* for an HID++ 2.0 device.
|
||||
*/
|
||||
class Device
|
||||
class Device : public ipcgull::object
|
||||
{
|
||||
public:
|
||||
Device(std::string path, backend::hidpp::DeviceIndex index,
|
||||
const std::shared_ptr<DeviceManager>& manager);
|
||||
Device(const std::shared_ptr<backend::raw::RawDevice>& raw_device,
|
||||
backend::hidpp::DeviceIndex index,
|
||||
const std::shared_ptr<DeviceManager>& manager);
|
||||
Device(Receiver* receiver, backend::hidpp::DeviceIndex index,
|
||||
const std::shared_ptr<DeviceManager>& manager);
|
||||
|
||||
std::string name();
|
||||
uint16_t pid();
|
||||
|
||||
DeviceConfig& config();
|
||||
backend::hidpp20::Device& hidpp20();
|
||||
|
||||
static std::shared_ptr<Device> make(
|
||||
std::string path,
|
||||
backend::hidpp::DeviceIndex index,
|
||||
std::shared_ptr<DeviceManager> manager);
|
||||
static std::shared_ptr<Device> make(
|
||||
std::shared_ptr<backend::raw::RawDevice> raw_device,
|
||||
backend::hidpp::DeviceIndex index,
|
||||
std::shared_ptr<DeviceManager> manager);
|
||||
static std::shared_ptr<Device> make(
|
||||
Receiver* receiver,
|
||||
backend::hidpp::DeviceIndex index,
|
||||
std::shared_ptr<DeviceManager> manager);
|
||||
|
||||
void wakeup();
|
||||
void sleep();
|
||||
|
||||
@ -89,6 +109,15 @@ namespace logid
|
||||
}
|
||||
|
||||
private:
|
||||
friend class _Device;
|
||||
Device(std::string path, backend::hidpp::DeviceIndex index,
|
||||
std::shared_ptr<DeviceManager> manager);
|
||||
Device(std::shared_ptr<backend::raw::RawDevice> raw_device,
|
||||
backend::hidpp::DeviceIndex index,
|
||||
std::shared_ptr<DeviceManager> manager);
|
||||
Device(Receiver* receiver, backend::hidpp::DeviceIndex index,
|
||||
std::shared_ptr<DeviceManager> manager);
|
||||
|
||||
void _init();
|
||||
|
||||
/* Adds a feature without calling an error if unsupported */
|
||||
@ -113,6 +142,18 @@ namespace logid
|
||||
|
||||
void _makeResetMechanism();
|
||||
std::unique_ptr<std::function<void()>> _reset_mechanism;
|
||||
|
||||
const DeviceNickname _nickname;
|
||||
std::shared_ptr<ipcgull::node> _ipc_node;
|
||||
|
||||
class DeviceIPC : public ipcgull::interface {
|
||||
public:
|
||||
DeviceIPC(Device* device);
|
||||
};
|
||||
|
||||
std::shared_ptr<ipcgull::interface> _ipc_interface;
|
||||
|
||||
std::weak_ptr<Device> _self;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -41,18 +41,28 @@ namespace logid {
|
||||
}
|
||||
|
||||
DeviceManager::DeviceManager(std::shared_ptr<Configuration> config,
|
||||
std::shared_ptr<InputDevice> virtual_input) :
|
||||
std::shared_ptr<InputDevice> virtual_input,
|
||||
std::shared_ptr<ipcgull::server> server) :
|
||||
backend::raw::DeviceMonitor(config->workerCount()),
|
||||
_config (std::move(config)),
|
||||
_virtual_input (std::move(virtual_input))
|
||||
_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<DevicesIPC>();
|
||||
_ipc_receivers = _root_node->make_interface<ReceiversIPC>();
|
||||
_device_node->add_server(_server);
|
||||
_receiver_node->add_server(_server);
|
||||
_root_node->add_server(_server);
|
||||
}
|
||||
|
||||
std::shared_ptr<DeviceManager> DeviceManager::make(
|
||||
const std::shared_ptr<Configuration>& config,
|
||||
const std::shared_ptr<InputDevice>& virtual_input)
|
||||
const std::shared_ptr<InputDevice>& virtual_input,
|
||||
const std::shared_ptr<ipcgull::server>& server)
|
||||
{
|
||||
auto ret = std::make_shared<_DeviceManager>(config, virtual_input);
|
||||
auto ret = std::make_shared<_DeviceManager>(config, virtual_input, server);
|
||||
ret->_self = ret;
|
||||
return ret;
|
||||
}
|
||||
@ -67,6 +77,16 @@ std::shared_ptr<InputDevice> DeviceManager::virtualInput() const
|
||||
return _virtual_input;
|
||||
}
|
||||
|
||||
std::shared_ptr<const ipcgull::node> DeviceManager::devicesNode() const
|
||||
{
|
||||
return _device_node;
|
||||
}
|
||||
|
||||
std::shared_ptr<const ipcgull::node> DeviceManager::receiversNode() const
|
||||
{
|
||||
return _receiver_node;
|
||||
}
|
||||
|
||||
void DeviceManager::addDevice(std::string path)
|
||||
{
|
||||
bool defaultExists = true;
|
||||
@ -102,21 +122,24 @@ void DeviceManager::addDevice(std::string path)
|
||||
|
||||
if(isReceiver) {
|
||||
logPrintf(INFO, "Detected receiver at %s", path.c_str());
|
||||
auto receiver = std::make_shared<Receiver>(path, _self.lock());
|
||||
auto receiver = Receiver::make(path, _self.lock());
|
||||
receiver->run();
|
||||
_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) {
|
||||
auto device = std::make_shared<Device>(path, hidpp::DefaultDevice,
|
||||
_self.lock());
|
||||
auto device = Device::make(path, hidpp::DefaultDevice,
|
||||
_self.lock());
|
||||
_devices.emplace(path, device);
|
||||
_ipc_devices->deviceAdded(device);
|
||||
} else {
|
||||
try {
|
||||
auto device = std::make_shared<Device>(path,
|
||||
auto device = Device::make(path,
|
||||
hidpp::CordedDevice, _self.lock());
|
||||
_devices.emplace(path, device);
|
||||
_ipc_devices->deviceAdded(device);
|
||||
} catch(hidpp10::Error &e) {
|
||||
if(e.code() != hidpp10::Error::UnknownDevice)
|
||||
throw;
|
||||
@ -134,18 +157,152 @@ void DeviceManager::addDevice(std::string path)
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceManager::addExternalDevice(const std::shared_ptr<Device> &d)
|
||||
{
|
||||
_ipc_devices->deviceAdded(d);
|
||||
}
|
||||
|
||||
void DeviceManager::removeExternalDevice(const std::shared_ptr<Device> &d)
|
||||
{
|
||||
_ipc_devices->deviceRemoved(d);
|
||||
}
|
||||
|
||||
void DeviceManager::removeDevice(std::string path)
|
||||
{
|
||||
auto receiver = _receivers.find(path);
|
||||
|
||||
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()) {
|
||||
_ipc_devices->deviceRemoved(device->second);
|
||||
_devices.erase(device);
|
||||
logPrintf(INFO, "Device on %s disconnected", path.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeviceManager::DevicesIPC::DevicesIPC() : ipcgull::interface(
|
||||
"pizza.pixl.LogiOps.Devices",
|
||||
{},
|
||||
{},
|
||||
{
|
||||
{"deviceAdded",
|
||||
ipcgull::make_signal<std::shared_ptr<Device>>(
|
||||
{"device"})},
|
||||
{"deviceRemoved",
|
||||
ipcgull::make_signal<std::shared_ptr<Device>>(
|
||||
{"device"})}
|
||||
}
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
void DeviceManager::DevicesIPC::deviceAdded(
|
||||
const std::shared_ptr<Device>& d) {
|
||||
emit_signal("deviceAdded", d);
|
||||
}
|
||||
|
||||
void DeviceManager::DevicesIPC::deviceRemoved(
|
||||
const std::shared_ptr<Device>& d) {
|
||||
emit_signal("deviceRemoved", d);
|
||||
}
|
||||
|
||||
DeviceManager::ReceiversIPC::ReceiversIPC() : ipcgull::interface(
|
||||
"pizza.pixl.LogiOps.Receivers",
|
||||
{},
|
||||
{},
|
||||
{
|
||||
{"receiverAdded",
|
||||
ipcgull::make_signal<std::shared_ptr<Receiver>>(
|
||||
{"device"})},
|
||||
{"receiverRemoved",
|
||||
ipcgull::make_signal<std::shared_ptr<Receiver>>(
|
||||
{"device"})}
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
void DeviceManager::ReceiversIPC::receiverAdded(
|
||||
const std::shared_ptr<Receiver>& r) {
|
||||
emit_signal("receiverAdded", r);
|
||||
}
|
||||
|
||||
void DeviceManager::ReceiversIPC::receiverRemoved(
|
||||
const std::shared_ptr<Receiver>& r) {
|
||||
emit_signal("receiverRemoved", r);
|
||||
}
|
||||
|
||||
int DeviceManager::newDeviceNickname()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_nick_lock);
|
||||
|
||||
auto begin = _device_nicknames.begin();
|
||||
if(begin != _device_nicknames.end()) {
|
||||
if(*begin != 0) {
|
||||
_device_nicknames.insert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const auto i = std::adjacent_find(_device_nicknames.begin(),
|
||||
_device_nicknames.end(),
|
||||
[](int l, int r) { return l + 1 < r; });
|
||||
|
||||
|
||||
if(i == _device_nicknames.end()) {
|
||||
auto end = _device_nicknames.rbegin();
|
||||
if(end != _device_nicknames.rend()) {
|
||||
auto ret = *end + 1;
|
||||
assert(ret > 0);
|
||||
_device_nicknames.insert(ret);
|
||||
return ret;
|
||||
} else {
|
||||
_device_nicknames.insert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
auto ret = *i + 1;
|
||||
assert(ret > 0);
|
||||
_device_nicknames.insert(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DeviceManager::newReceiverNickname()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(_nick_lock);
|
||||
|
||||
auto begin = _receiver_nicknames.begin();
|
||||
if(begin != _receiver_nicknames.end()) {
|
||||
if(*begin != 0) {
|
||||
_receiver_nicknames.insert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const auto i = std::adjacent_find(_receiver_nicknames.begin(),
|
||||
_receiver_nicknames.end(),
|
||||
[](int l, int r) { return l + 1 < r; });
|
||||
|
||||
if(i == _receiver_nicknames.end()) {
|
||||
auto end = _receiver_nicknames.rbegin();
|
||||
if(end != _receiver_nicknames.rend()) {
|
||||
auto ret = *end + 1;
|
||||
assert(ret > 0);
|
||||
_receiver_nicknames.insert(ret);
|
||||
return ret;
|
||||
} else {
|
||||
_receiver_nicknames.insert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
auto ret = *i + 1;
|
||||
assert(ret > 0);
|
||||
_receiver_nicknames.insert(ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <map>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <ipcgull/node.h>
|
||||
#include <ipcgull/interface.h>
|
||||
|
||||
#include "backend/raw/DeviceMonitor.h"
|
||||
#include "backend/hidpp/Device.h"
|
||||
@ -38,23 +40,66 @@ namespace logid
|
||||
public:
|
||||
static std::shared_ptr<DeviceManager> make(
|
||||
const std::shared_ptr<Configuration>& config,
|
||||
const std::shared_ptr<InputDevice>& virtual_input);
|
||||
const std::shared_ptr<InputDevice>& virtual_input,
|
||||
const std::shared_ptr<ipcgull::server>& server);
|
||||
[[nodiscard]] std::shared_ptr<Configuration> config() const;
|
||||
[[nodiscard]] std::shared_ptr<InputDevice> virtualInput() const;
|
||||
[[nodiscard]] std::shared_ptr<const ipcgull::node> devicesNode() const;
|
||||
[[nodiscard]] std::shared_ptr<const ipcgull::node>
|
||||
receiversNode() const;
|
||||
|
||||
void addExternalDevice(const std::shared_ptr<Device>& d);
|
||||
void removeExternalDevice(const std::shared_ptr<Device>& d);
|
||||
protected:
|
||||
void addDevice(std::string path) final;
|
||||
void removeDevice(std::string path) final;
|
||||
private:
|
||||
class DevicesIPC : public ipcgull::interface {
|
||||
public:
|
||||
DevicesIPC();
|
||||
void deviceAdded(const std::shared_ptr<Device>& d);
|
||||
void deviceRemoved(const std::shared_ptr<Device>& d);
|
||||
};
|
||||
|
||||
class ReceiversIPC : public ipcgull::interface {
|
||||
public:
|
||||
ReceiversIPC();
|
||||
void receiverAdded(const std::shared_ptr<Receiver>& r);
|
||||
void receiverRemoved(const std::shared_ptr<Receiver>& r);
|
||||
};
|
||||
|
||||
friend class _DeviceManager;
|
||||
DeviceManager(std::shared_ptr<Configuration> config,
|
||||
std::shared_ptr<InputDevice> virtual_input);
|
||||
std::shared_ptr<InputDevice> virtual_input,
|
||||
std::shared_ptr<ipcgull::server> server);
|
||||
|
||||
std::weak_ptr<DeviceManager> _self;
|
||||
std::shared_ptr<ipcgull::server> _server;
|
||||
std::shared_ptr<Configuration> _config;
|
||||
std::shared_ptr<InputDevice> _virtual_input;
|
||||
|
||||
std::shared_ptr<ipcgull::node> _root_node;
|
||||
|
||||
std::shared_ptr<ipcgull::node> _device_node;
|
||||
std::shared_ptr<ipcgull::node> _receiver_node;
|
||||
|
||||
std::shared_ptr<DevicesIPC> _ipc_devices;
|
||||
std::shared_ptr<ReceiversIPC> _ipc_receivers;
|
||||
|
||||
std::map<std::string, std::shared_ptr<Device>> _devices;
|
||||
std::map<std::string, std::shared_ptr<Receiver>> _receivers;
|
||||
|
||||
friend class DeviceNickname;
|
||||
friend class ReceiverNickname;
|
||||
|
||||
[[nodiscard]] int newDeviceNickname();
|
||||
[[nodiscard]] int newReceiverNickname();
|
||||
|
||||
std::mutex _nick_lock;
|
||||
std::set<int> _device_nicknames;
|
||||
std::set<int> _receiver_nicknames;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //LOGID_DEVICEMANAGER_H
|
||||
#endif //LOGID_DEVICEMANAGER_H
|
||||
|
@ -56,6 +56,9 @@ InputDevice::InputDevice(const char* name)
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < REL_CNT; i++)
|
||||
registered_axis[i] = false;
|
||||
|
||||
libevdev_enable_event_type(device, EV_REL);
|
||||
|
||||
int err = libevdev_uinput_create_from_device(device,
|
||||
@ -76,7 +79,7 @@ InputDevice::~InputDevice()
|
||||
void InputDevice::registerKey(uint code)
|
||||
{
|
||||
// TODO: Maybe print error message, if wrong code is passed?
|
||||
if(registered_keys[code] || code > KEY_CNT) {
|
||||
if(code >= KEY_CNT || registered_keys[code]) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -88,7 +91,7 @@ void InputDevice::registerKey(uint code)
|
||||
void InputDevice::registerAxis(uint axis)
|
||||
{
|
||||
// TODO: Maybe print error message, if wrong code is passed?
|
||||
if(registered_axis[axis] || axis > REL_CNT) {
|
||||
if(axis >= REL_CNT || registered_axis[axis]) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -26,15 +26,61 @@
|
||||
using namespace logid;
|
||||
using namespace logid::backend;
|
||||
|
||||
ReceiverNickname::ReceiverNickname(
|
||||
const std::shared_ptr<DeviceManager>& manager) :
|
||||
_nickname (manager->newReceiverNickname()), _manager (manager)
|
||||
{
|
||||
}
|
||||
|
||||
ReceiverNickname::operator std::string() const {
|
||||
return std::to_string(_nickname);
|
||||
}
|
||||
|
||||
ReceiverNickname::~ReceiverNickname()
|
||||
{
|
||||
if(auto manager = _manager.lock()) {
|
||||
std::lock_guard<std::mutex> lock(manager->_nick_lock);
|
||||
manager->_receiver_nicknames.erase(_nickname);
|
||||
}
|
||||
}
|
||||
|
||||
namespace logid {
|
||||
class _Receiver : public Receiver {
|
||||
public:
|
||||
template <typename... Args>
|
||||
_Receiver(Args... args) : Receiver(std::forward<Args>(args)...) { }
|
||||
};
|
||||
}
|
||||
|
||||
std::shared_ptr<Receiver> Receiver::make(
|
||||
const std::string &path,
|
||||
const std::shared_ptr<DeviceManager> &manager) {
|
||||
auto ret = std::make_shared<_Receiver>(path, manager);
|
||||
ret->_self = ret;
|
||||
ret->_ipc_node->manage(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Receiver::Receiver(const std::string& path,
|
||||
const std::shared_ptr<DeviceManager>& manager) :
|
||||
dj::ReceiverMonitor(path,
|
||||
manager->config()->ioTimeout(),
|
||||
manager->workQueue()),
|
||||
_path (path), _manager (manager)
|
||||
_path (path), _manager (manager), _nickname (manager),
|
||||
_ipc_node (manager->receiversNode()->make_child(_nickname)),
|
||||
_ipc_interface (_ipc_node->make_interface<ReceiverIPC>(this))
|
||||
{
|
||||
}
|
||||
|
||||
Receiver::~Receiver()
|
||||
{
|
||||
if(auto manager = _manager.lock()) {
|
||||
for(auto& d : _devices)
|
||||
manager->removeExternalDevice(d.second);
|
||||
}
|
||||
}
|
||||
|
||||
void Receiver::addDevice(hidpp::DeviceConnectionEvent event)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_devices_change);
|
||||
@ -77,10 +123,9 @@ void Receiver::addDevice(hidpp::DeviceConnectionEvent event)
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<Device> device = std::make_shared<Device>(this,
|
||||
event.index, manager);
|
||||
|
||||
auto device = Device::make(this, event.index, manager);
|
||||
_devices.emplace(event.index, device);
|
||||
manager->addExternalDevice(device);
|
||||
|
||||
} catch(hidpp10::Error &e) {
|
||||
logPrintf(ERROR,
|
||||
@ -100,7 +145,12 @@ void Receiver::addDevice(hidpp::DeviceConnectionEvent event)
|
||||
void Receiver::removeDevice(hidpp::DeviceIndex index)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(_devices_change);
|
||||
_devices.erase(index);
|
||||
auto device = _devices.find(index);
|
||||
if(device != _devices.end()) {
|
||||
if(auto manager = _manager.lock())
|
||||
manager->removeExternalDevice(device->second);
|
||||
_devices.erase(device);
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& Receiver::path() const
|
||||
@ -111,4 +161,9 @@ const std::string& Receiver::path() const
|
||||
std::shared_ptr<dj::Receiver> Receiver::rawReceiver()
|
||||
{
|
||||
return receiver();
|
||||
}
|
||||
}
|
||||
|
||||
Receiver::ReceiverIPC::ReceiverIPC(Receiver *receiver) :
|
||||
ipcgull::interface("pizza.pixl.LogiOps.Receiver", {}, {}, {})
|
||||
{
|
||||
}
|
||||
|
@ -25,21 +25,55 @@
|
||||
|
||||
namespace logid
|
||||
{
|
||||
class Receiver : public backend::dj::ReceiverMonitor
|
||||
class ReceiverNickname {
|
||||
public:
|
||||
explicit ReceiverNickname(const std::shared_ptr<DeviceManager>& manager);
|
||||
ReceiverNickname() = delete;
|
||||
ReceiverNickname(const ReceiverNickname&) = delete;
|
||||
~ReceiverNickname();
|
||||
|
||||
operator std::string() const;
|
||||
private:
|
||||
const int _nickname;
|
||||
const std::weak_ptr<DeviceManager> _manager;
|
||||
};
|
||||
|
||||
class Receiver : public backend::dj::ReceiverMonitor,
|
||||
public ipcgull::object
|
||||
{
|
||||
public:
|
||||
explicit Receiver(const std::string& path,
|
||||
const std::shared_ptr<DeviceManager>& manager);
|
||||
~Receiver();
|
||||
|
||||
static std::shared_ptr<Receiver> make(
|
||||
const std::string& path,
|
||||
const std::shared_ptr<DeviceManager>& manager);
|
||||
const std::string& path() const;
|
||||
std::shared_ptr<backend::dj::Receiver> rawReceiver();
|
||||
protected:
|
||||
void addDevice(backend::hidpp::DeviceConnectionEvent event) override;
|
||||
void removeDevice(backend::hidpp::DeviceIndex index) override;
|
||||
private:
|
||||
friend class _Receiver;
|
||||
|
||||
Receiver(const std::string& path,
|
||||
const std::shared_ptr<DeviceManager>& manager);
|
||||
|
||||
std::mutex _devices_change;
|
||||
std::map<backend::hidpp::DeviceIndex, std::shared_ptr<Device>> _devices;
|
||||
std::string _path;
|
||||
std::weak_ptr<DeviceManager> _manager;
|
||||
|
||||
const ReceiverNickname _nickname;
|
||||
std::shared_ptr<ipcgull::node> _ipc_node;
|
||||
|
||||
class ReceiverIPC : public ipcgull::interface {
|
||||
public:
|
||||
ReceiverIPC(Receiver* receiver);
|
||||
};
|
||||
|
||||
std::shared_ptr<ipcgull::interface> _ipc_interface;
|
||||
|
||||
std::weak_ptr<Receiver> _self;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <mutex>
|
||||
#include <ipcgull/exception.h>
|
||||
|
||||
#include "util/log.h"
|
||||
#include "DeviceManager.h"
|
||||
@ -157,6 +158,19 @@ int main(int argc, char** argv)
|
||||
std::shared_ptr<Configuration> config;
|
||||
std::shared_ptr<InputDevice> virtual_input;
|
||||
|
||||
auto server = ipcgull::make_server("pizza.pixl.LogiOps",
|
||||
"/pizza/pixl/logiops",
|
||||
ipcgull::IPCGULL_USER);
|
||||
|
||||
std::thread( [server]() {
|
||||
try {
|
||||
server->start();
|
||||
} catch(ipcgull::connection_failed& e) {
|
||||
logPrintf(ERROR, "Lost IPC connection, terminating.");
|
||||
std::terminate();
|
||||
}
|
||||
} ).detach();
|
||||
|
||||
// Read config
|
||||
try {
|
||||
config = std::make_shared<Configuration>(options.config_file);
|
||||
@ -174,9 +188,11 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
// Scan devices, create listeners, handlers, etc.
|
||||
auto device_manager = DeviceManager::make(config, virtual_input);
|
||||
auto device_manager = DeviceManager::make(config, virtual_input, server);
|
||||
|
||||
device_manager->run();
|
||||
|
||||
server->stop_sync();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user