From 8d2ae4c3c498b8c37c8c14e2838d384c2a003423 Mon Sep 17 00:00:00 2001 From: PixlOne <8843371+PixlOne@users.noreply.github.com> Date: Sat, 17 Aug 2019 19:58:00 -0400 Subject: [PATCH] Fixed bug where mouse would not reconfigure --- src/logid/Configuration.cpp | 6 +++ src/logid/Configuration.h | 1 + src/logid/Device.cpp | 93 ++++++++++++++++++++++++------------- src/logid/Device.h | 2 + src/logid/DeviceFinder.cpp | 33 ++----------- src/logid/DeviceFinder.h | 13 ------ src/logid/logid.cpp | 8 +++- 7 files changed, 80 insertions(+), 76 deletions(-) diff --git a/src/logid/Configuration.cpp b/src/logid/Configuration.cpp index 86a63cd..41a7a85 100644 --- a/src/logid/Configuration.cpp +++ b/src/logid/Configuration.cpp @@ -471,4 +471,10 @@ DeviceConfig::DeviceConfig() hiresscroll = nullptr; smartshift = nullptr; actions = {}; +} + +DeviceConfig::~DeviceConfig() +{ + for(auto it : this->actions) + delete(it.second); } \ No newline at end of file diff --git a/src/logid/Configuration.h b/src/logid/Configuration.h index e1b7e1d..8952424 100644 --- a/src/logid/Configuration.h +++ b/src/logid/Configuration.h @@ -14,6 +14,7 @@ class DeviceConfig { public: DeviceConfig(); + ~DeviceConfig(); DeviceConfig(DeviceConfig* dc, Device* dev); DeviceConfig(const libconfig::Setting& root); const int* dpi = nullptr; diff --git a/src/logid/Device.cpp b/src/logid/Device.cpp index 2b7d511..77310f8 100644 --- a/src/logid/Device.cpp +++ b/src/logid/Device.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -40,48 +41,80 @@ Device::Device(std::string p, const HIDPP::DeviceIndex i) : path(std::move(p)), else config = global_config->devices.find(name)->second; } +Device::~Device() +{ + if(!disconnected) + this->reset(); + if(!config->baseConfig) + delete(this->config); +} + void Device::configure() { if(config->baseConfig) config = new DeviceConfig(config, this); configuring = true; - usleep(50000); - if(disconnected) { - configuring = false; return; } + usleep(250000); - // Divert buttons - divert_buttons(); - if(disconnected) { - configuring = false; return; } + try + { + if(disconnected) { + configuring = false; return; } - // Set DPI if it is set - if(config->dpi != nullptr) - set_dpi(*config->dpi); - if(disconnected) { - configuring = false; return; } + // Divert buttons + divert_buttons(); + if(disconnected) { + configuring = false; return; } - // Set Smartshift if it is set - if(config->smartshift != nullptr) - set_smartshift(*config->smartshift); - if(disconnected) { - configuring = false; return; } + // Set DPI if it is set + if(config->dpi != nullptr) + set_dpi(*config->dpi); + if(disconnected) { + configuring = false; return; } - // Set Hires Scroll if it is set - if(config->hiresscroll != nullptr) - set_hiresscroll(*config->hiresscroll); + // Set Smartshift if it is set + if(config->smartshift != nullptr) + set_smartshift(*config->smartshift); + if(disconnected) { + configuring = false; return; } + + // Set Hires Scroll if it is set + if(config->hiresscroll != nullptr) + 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; } +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() { try { HIDPP20::IReprogControls irc = HIDPP20::IReprogControls::auto_version(hidpp_dev); + if(disconnected) return; int controlCount = irc.getControlCount(); for(int i = 0; i < controlCount; i++) { + if(disconnected) return; uint16_t cid = irc.getControlInfo(i).control_id; uint8_t flags = 0; flags |= HIDPP20::IReprogControls::ChangeTemporaryDivert; @@ -95,7 +128,7 @@ void Device::divert_buttons() if(action->second->type == Action::Gestures) flags |= HIDPP20::IReprogControls::RawXYDiverted; } - + if(disconnected) return; irc.setControlReporting(cid, flags, cid); } } @@ -113,7 +146,9 @@ void Device::set_smartshift(HIDPP20::ISmartShift::SmartshiftStatus ops) { try { + if(disconnected) return; HIDPP20::ISmartShift ss(hidpp_dev); + if(disconnected) return; ss.setStatus(ops); } catch (HIDPP20::UnsupportedFeature &e) @@ -130,7 +165,9 @@ void Device::set_hiresscroll(uint8_t ops) { try { + if(disconnected) return; HIDPP20::IHiresScroll hs(hidpp_dev); + if(disconnected) return; hs.setMode(ops); } catch (HIDPP20::UnsupportedFeature &e) @@ -145,8 +182,9 @@ void Device::set_hiresscroll(uint8_t ops) void Device::set_dpi(int dpi) { + if(disconnected) return; HIDPP20::IAdjustableDPI iad(hidpp_dev); - + if(disconnected) return; 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()); } } @@ -239,15 +277,7 @@ void ReceiverHandler::handleEvent(const HIDPP::Report &event) { log_printf(INFO, "Connection established to %s", dev->name.c_str()); dev->disconnected = false; - std::thread - { - [dev=this->dev] - { - while (dev->configuring) - if(dev->disconnected) return; - dev->configure(); - } - }.detach(); + dev->configure(); } break; } @@ -302,6 +332,7 @@ bool SimpleListener::event (EventHandler *handler, const HIDPP::Report &report) void Device::stop() { + disconnected = true; listener->stop(); } diff --git a/src/logid/Device.h b/src/logid/Device.h index 84a13fd..ad10ffd 100644 --- a/src/logid/Device.h +++ b/src/logid/Device.h @@ -18,10 +18,12 @@ class Device { public: Device(std::string p, const HIDPP::DeviceIndex i); + ~Device(); std::string name; void configure(); + void reset(); void press_button(uint16_t cid); void release_button(uint16_t cid); diff --git a/src/logid/DeviceFinder.cpp b/src/logid/DeviceFinder.cpp index 4d8de19..268c8f4 100644 --- a/src/logid/DeviceFinder.cpp +++ b/src/logid/DeviceFinder.cpp @@ -14,40 +14,15 @@ #include "util.h" #include "Device.h" -constexpr uint16_t DeviceFinder::UnifyingReceivers[]; - void DeviceFinder::addDevice(const char *path) { std::string string_path(path); // Asynchronously scan device 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 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 _devs; - const int max_tries = 5; - const int try_delay = 50000; + const int max_tries = 10; + const int try_delay = 250000; //Check if device is an HID++ device and handle it accordingly 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()); } for(auto dev : _devs) - { devices.insert({dev, std::thread{[dev]() { dev->start(); }}}); - devices[dev].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); it->first->stop(); it->second.join(); + delete(it->first); devices.erase(it); it++; } diff --git a/src/logid/DeviceFinder.h b/src/logid/DeviceFinder.h index a075479..e64d6c6 100644 --- a/src/logid/DeviceFinder.h +++ b/src/logid/DeviceFinder.h @@ -16,19 +16,6 @@ class DeviceFinder : public HID::DeviceMonitor { public: std::map 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: void addDevice(const char* path); void removeDevice(const char* path); diff --git a/src/logid/logid.cpp b/src/logid/logid.cpp index 9ddc773..d08e95b 100644 --- a/src/logid/logid.cpp +++ b/src/logid/logid.cpp @@ -35,12 +35,13 @@ enum class Option int main(int argc, char** argv) { std::string config_file = DEFAULT_CONFIG_FILE; + // Read command line options for(int i = 1; i < argc; i++) { 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 { @@ -76,7 +77,10 @@ int main(int argc, char** argv) catch (std::invalid_argument &e) { if (argv[i][0] == '-') + { global_verbosity = DEBUG; // Assume debug verbosity + i--; // Go back to last argument to continue loop. + } else { log_printf(WARN, e.what());