Fixed bug where mouse would not reconfigure
This commit is contained in:
parent
b55db6777e
commit
8d2ae4c3c4
|
@ -472,3 +472,9 @@ DeviceConfig::DeviceConfig()
|
||||||
smartshift = nullptr;
|
smartshift = nullptr;
|
||||||
actions = {};
|
actions = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeviceConfig::~DeviceConfig()
|
||||||
|
{
|
||||||
|
for(auto it : this->actions)
|
||||||
|
delete(it.second);
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ class DeviceConfig
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DeviceConfig();
|
DeviceConfig();
|
||||||
|
~DeviceConfig();
|
||||||
DeviceConfig(DeviceConfig* dc, Device* dev);
|
DeviceConfig(DeviceConfig* dc, Device* dev);
|
||||||
DeviceConfig(const libconfig::Setting& root);
|
DeviceConfig(const libconfig::Setting& root);
|
||||||
const int* dpi = nullptr;
|
const int* dpi = nullptr;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <hidpp20/IFeatureSet.h>
|
#include <hidpp20/IFeatureSet.h>
|
||||||
#include <hidpp20/Error.h>
|
#include <hidpp20/Error.h>
|
||||||
#include <hidpp20/IReprogControls.h>
|
#include <hidpp20/IReprogControls.h>
|
||||||
|
#include <hidpp20/IReset.h>
|
||||||
#include <hidpp20/ISmartShift.h>
|
#include <hidpp20/ISmartShift.h>
|
||||||
#include <hidpp20/Device.h>
|
#include <hidpp20/Device.h>
|
||||||
#include <hidpp10/Error.h>
|
#include <hidpp10/Error.h>
|
||||||
|
@ -40,13 +41,24 @@ Device::Device(std::string p, const HIDPP::DeviceIndex i) : path(std::move(p)),
|
||||||
else config = global_config->devices.find(name)->second;
|
else config = global_config->devices.find(name)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Device::~Device()
|
||||||
|
{
|
||||||
|
if(!disconnected)
|
||||||
|
this->reset();
|
||||||
|
if(!config->baseConfig)
|
||||||
|
delete(this->config);
|
||||||
|
}
|
||||||
|
|
||||||
void Device::configure()
|
void Device::configure()
|
||||||
{
|
{
|
||||||
if(config->baseConfig)
|
if(config->baseConfig)
|
||||||
config = new DeviceConfig(config, this);
|
config = new DeviceConfig(config, this);
|
||||||
|
|
||||||
configuring = true;
|
configuring = true;
|
||||||
usleep(50000);
|
usleep(250000);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
if(disconnected) {
|
if(disconnected) {
|
||||||
configuring = false; return; }
|
configuring = false; return; }
|
||||||
|
|
||||||
|
@ -70,18 +82,39 @@ void Device::configure()
|
||||||
// Set Hires Scroll if it is set
|
// Set Hires Scroll if it is set
|
||||||
if(config->hiresscroll != nullptr)
|
if(config->hiresscroll != nullptr)
|
||||||
set_hiresscroll(*config->hiresscroll);
|
set_hiresscroll(*config->hiresscroll);
|
||||||
|
}
|
||||||
|
catch(HIDPP10::Error &e)
|
||||||
|
{
|
||||||
|
log_printf(ERROR, "HID++ 1.0 Error whjle configuring %s: %s", name.c_str(), e.what());
|
||||||
|
}
|
||||||
|
|
||||||
configuring = false;
|
configuring = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Device::reset()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
HIDPP20::IReset iReset(hidpp_dev);
|
||||||
|
iReset.reset();
|
||||||
|
}
|
||||||
|
catch(HIDPP20::UnsupportedFeature &e) { }
|
||||||
|
catch(HIDPP10::Error &e)
|
||||||
|
{
|
||||||
|
log_printf(ERROR, "Failed to reset %s: %s", name.c_str(), e.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Device::divert_buttons()
|
void Device::divert_buttons()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
HIDPP20::IReprogControls irc = HIDPP20::IReprogControls::auto_version(hidpp_dev);
|
HIDPP20::IReprogControls irc = HIDPP20::IReprogControls::auto_version(hidpp_dev);
|
||||||
|
if(disconnected) return;
|
||||||
int controlCount = irc.getControlCount();
|
int controlCount = irc.getControlCount();
|
||||||
for(int i = 0; i < controlCount; i++)
|
for(int i = 0; i < controlCount; i++)
|
||||||
{
|
{
|
||||||
|
if(disconnected) return;
|
||||||
uint16_t cid = irc.getControlInfo(i).control_id;
|
uint16_t cid = irc.getControlInfo(i).control_id;
|
||||||
uint8_t flags = 0;
|
uint8_t flags = 0;
|
||||||
flags |= HIDPP20::IReprogControls::ChangeTemporaryDivert;
|
flags |= HIDPP20::IReprogControls::ChangeTemporaryDivert;
|
||||||
|
@ -95,7 +128,7 @@ void Device::divert_buttons()
|
||||||
if(action->second->type == Action::Gestures)
|
if(action->second->type == Action::Gestures)
|
||||||
flags |= HIDPP20::IReprogControls::RawXYDiverted;
|
flags |= HIDPP20::IReprogControls::RawXYDiverted;
|
||||||
}
|
}
|
||||||
|
if(disconnected) return;
|
||||||
irc.setControlReporting(cid, flags, cid);
|
irc.setControlReporting(cid, flags, cid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,7 +146,9 @@ void Device::set_smartshift(HIDPP20::ISmartShift::SmartshiftStatus ops)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if(disconnected) return;
|
||||||
HIDPP20::ISmartShift ss(hidpp_dev);
|
HIDPP20::ISmartShift ss(hidpp_dev);
|
||||||
|
if(disconnected) return;
|
||||||
ss.setStatus(ops);
|
ss.setStatus(ops);
|
||||||
}
|
}
|
||||||
catch (HIDPP20::UnsupportedFeature &e)
|
catch (HIDPP20::UnsupportedFeature &e)
|
||||||
|
@ -130,7 +165,9 @@ void Device::set_hiresscroll(uint8_t ops)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if(disconnected) return;
|
||||||
HIDPP20::IHiresScroll hs(hidpp_dev);
|
HIDPP20::IHiresScroll hs(hidpp_dev);
|
||||||
|
if(disconnected) return;
|
||||||
hs.setMode(ops);
|
hs.setMode(ops);
|
||||||
}
|
}
|
||||||
catch (HIDPP20::UnsupportedFeature &e)
|
catch (HIDPP20::UnsupportedFeature &e)
|
||||||
|
@ -145,8 +182,9 @@ void Device::set_hiresscroll(uint8_t ops)
|
||||||
|
|
||||||
void Device::set_dpi(int dpi)
|
void Device::set_dpi(int dpi)
|
||||||
{
|
{
|
||||||
|
if(disconnected) return;
|
||||||
HIDPP20::IAdjustableDPI iad(hidpp_dev);
|
HIDPP20::IAdjustableDPI iad(hidpp_dev);
|
||||||
|
if(disconnected) return;
|
||||||
try { for(unsigned int i = 0; i < iad.getSensorCount(); i++) iad.setSensorDPI(i, dpi); }
|
try { for(unsigned int i = 0; i < iad.getSensorCount(); i++) iad.setSensorDPI(i, dpi); }
|
||||||
catch (HIDPP20::Error &e) { log_printf(ERROR, "Error while setting DPI: %s", e.what()); }
|
catch (HIDPP20::Error &e) { log_printf(ERROR, "Error while setting DPI: %s", e.what()); }
|
||||||
}
|
}
|
||||||
|
@ -239,16 +277,8 @@ void ReceiverHandler::handleEvent(const HIDPP::Report &event)
|
||||||
{
|
{
|
||||||
log_printf(INFO, "Connection established to %s", dev->name.c_str());
|
log_printf(INFO, "Connection established to %s", dev->name.c_str());
|
||||||
dev->disconnected = false;
|
dev->disconnected = false;
|
||||||
std::thread
|
|
||||||
{
|
|
||||||
[dev=this->dev]
|
|
||||||
{
|
|
||||||
while (dev->configuring)
|
|
||||||
if(dev->disconnected) return;
|
|
||||||
dev->configure();
|
dev->configure();
|
||||||
}
|
}
|
||||||
}.detach();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -302,6 +332,7 @@ bool SimpleListener::event (EventHandler *handler, const HIDPP::Report &report)
|
||||||
|
|
||||||
void Device::stop()
|
void Device::stop()
|
||||||
{
|
{
|
||||||
|
disconnected = true;
|
||||||
listener->stop();
|
listener->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,12 @@ class Device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Device(std::string p, const HIDPP::DeviceIndex i);
|
Device(std::string p, const HIDPP::DeviceIndex i);
|
||||||
|
~Device();
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
||||||
void configure();
|
void configure();
|
||||||
|
void reset();
|
||||||
|
|
||||||
void press_button(uint16_t cid);
|
void press_button(uint16_t cid);
|
||||||
void release_button(uint16_t cid);
|
void release_button(uint16_t cid);
|
||||||
|
|
|
@ -14,40 +14,15 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "Device.h"
|
#include "Device.h"
|
||||||
|
|
||||||
constexpr uint16_t DeviceFinder::UnifyingReceivers[];
|
|
||||||
|
|
||||||
void DeviceFinder::addDevice(const char *path)
|
void DeviceFinder::addDevice(const char *path)
|
||||||
{
|
{
|
||||||
std::string string_path(path);
|
std::string string_path(path);
|
||||||
// Asynchronously scan device
|
// Asynchronously scan device
|
||||||
std::thread{[=]()
|
std::thread{[=]()
|
||||||
{
|
{
|
||||||
// Check /sys/class/hidraw/hidrawX/device/uevent for device details.
|
|
||||||
// Continue if HID_NAME contains 'Logitech' or is non-existent
|
|
||||||
// Otherwise, skip.
|
|
||||||
std::string hidraw_name;
|
|
||||||
std::size_t spos = string_path.rfind('/');
|
|
||||||
if(spos != std::string::npos) hidraw_name = string_path.substr(spos+1, string_path.size()-1);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
log_printf(ERROR, "Expected file but got directory: %s", path);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::ifstream info_file("/sys/class/hidraw/" + hidraw_name + "/device/uevent");
|
|
||||||
std::map<std::string, std::string> hidraw_info;
|
|
||||||
std::string line;
|
|
||||||
while(std::getline(info_file, line))
|
|
||||||
{
|
|
||||||
if(line.find('=') == std::string::npos) continue;
|
|
||||||
hidraw_info.insert({line.substr(0, line.find('=')), line.substr(line.find('=') + 1, line.size()-1)});
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hidraw_info.find("HID_NAME") != hidraw_info.end())
|
|
||||||
if (hidraw_info.find("HID_NAME")->second.find("Logitech") == std::string::npos) return;
|
|
||||||
|
|
||||||
std::vector<Device*> _devs;
|
std::vector<Device*> _devs;
|
||||||
const int max_tries = 5;
|
const int max_tries = 10;
|
||||||
const int try_delay = 50000;
|
const int try_delay = 250000;
|
||||||
|
|
||||||
//Check if device is an HID++ device and handle it accordingly
|
//Check if device is an HID++ device and handle it accordingly
|
||||||
try
|
try
|
||||||
|
@ -119,10 +94,7 @@ void DeviceFinder::addDevice(const char *path)
|
||||||
catch(std::system_error &e) { log_printf(WARN, "Failed to open %s: %s", string_path.c_str(), e.what()); }
|
catch(std::system_error &e) { log_printf(WARN, "Failed to open %s: %s", string_path.c_str(), e.what()); }
|
||||||
|
|
||||||
for(auto dev : _devs)
|
for(auto dev : _devs)
|
||||||
{
|
|
||||||
devices.insert({dev, std::thread{[dev]() { dev->start(); }}});
|
devices.insert({dev, std::thread{[dev]() { dev->start(); }}});
|
||||||
devices[dev].detach();
|
|
||||||
}
|
|
||||||
|
|
||||||
}}.detach();
|
}}.detach();
|
||||||
}
|
}
|
||||||
|
@ -138,6 +110,7 @@ void DeviceFinder::removeDevice(const char* path)
|
||||||
log_printf(INFO, "%s on %s disconnected.", it->first->name.c_str(), path);
|
log_printf(INFO, "%s on %s disconnected.", it->first->name.c_str(), path);
|
||||||
it->first->stop();
|
it->first->stop();
|
||||||
it->second.join();
|
it->second.join();
|
||||||
|
delete(it->first);
|
||||||
devices.erase(it);
|
devices.erase(it);
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,19 +16,6 @@ class DeviceFinder : public HID::DeviceMonitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::map<Device*, std::thread> devices;
|
std::map<Device*, std::thread> devices;
|
||||||
static constexpr uint16_t UnifyingReceivers[] =
|
|
||||||
{
|
|
||||||
0xc52b, 0xc532, // Official Unifying receivers
|
|
||||||
0xc52f, 0xc526, // Nano receivers
|
|
||||||
0xc52e, 0xc51b,
|
|
||||||
0xc531, 0xc517,
|
|
||||||
0xc518, 0xc51a,
|
|
||||||
0xc521, 0xc525,
|
|
||||||
0xc534,
|
|
||||||
0xc539, 0xc53a, // Lightspeed receivers
|
|
||||||
0xc53f,
|
|
||||||
0x17ef, // Lenovo nano receivers
|
|
||||||
};
|
|
||||||
protected:
|
protected:
|
||||||
void addDevice(const char* path);
|
void addDevice(const char* path);
|
||||||
void removeDevice(const char* path);
|
void removeDevice(const char* path);
|
||||||
|
|
|
@ -35,12 +35,13 @@ enum class Option
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
std::string config_file = DEFAULT_CONFIG_FILE;
|
std::string config_file = DEFAULT_CONFIG_FILE;
|
||||||
|
// Read command line options
|
||||||
for(int i = 1; i < argc; i++)
|
for(int i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
Option option = Option::None;
|
Option option = Option::None;
|
||||||
if(argv[i][0] == '-') // Option
|
if(argv[i][0] == '-') // This argument is an option
|
||||||
{
|
{
|
||||||
switch(argv[i][1])
|
switch(argv[i][1]) // Set option
|
||||||
{
|
{
|
||||||
case '-': // Full option name
|
case '-': // Full option name
|
||||||
{
|
{
|
||||||
|
@ -76,7 +77,10 @@ int main(int argc, char** argv)
|
||||||
catch (std::invalid_argument &e)
|
catch (std::invalid_argument &e)
|
||||||
{
|
{
|
||||||
if (argv[i][0] == '-')
|
if (argv[i][0] == '-')
|
||||||
|
{
|
||||||
global_verbosity = DEBUG; // Assume debug verbosity
|
global_verbosity = DEBUG; // Assume debug verbosity
|
||||||
|
i--; // Go back to last argument to continue loop.
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_printf(WARN, e.what());
|
log_printf(WARN, e.what());
|
||||||
|
|
Loading…
Reference in New Issue
Block a user