diff --git a/logiconf-gui/Page1.qml b/logiconf-gui/Page1.qml index dbf6f02..b868ba5 100755 --- a/logiconf-gui/Page1.qml +++ b/logiconf-gui/Page1.qml @@ -1,51 +1,52 @@ import QtQuick 2.7 +import dslul.devicecomm 1.0 Page1Form { property bool settingsLoaded: false switchDpiLed.onCheckedChanged: { if(settingsLoaded === true) - devcomm.toggleDPILed() + DevCom.toggleDPILed() } checkBoxGlow.onCheckedChanged: { if(settingsLoaded === true) { if(checkBoxGlow.checked === true) { sliderGlow.enabled = true - devcomm.setLogoGlow(sliderGlow.value) + DevCom.setLogoGlow(sliderGlow.value) } else { sliderGlow.enabled = false - devcomm.disableGlow() + DevCom.disableGlow() } } } sliderBrightness.onValueChanged: { if(settingsLoaded === true) - devcomm.setLogoBrightness(sliderBrightness.value) + DevCom.setLogoBrightness(sliderBrightness.value) } sliderGlow.onValueChanged: { if(settingsLoaded === true) - devcomm.setLogoGlow(sliderGlow.value) + DevCom.setLogoGlow(sliderGlow.value) } Component.onCompleted: { - if(devcomm.isDPILedOn()) + if(DevCom.isDPILedOn()) switchDpiLed.checked = true else switchDpiLed.checked = false - if(devcomm.isBreathingEnabled()) { + if(DevCom.isBreathingEnabled()) { checkBoxGlow.checked = true sliderGlow.enabled = true } else { checkBoxGlow.checked = false sliderGlow.enabled = false } - sliderBrightness.value = devcomm.getBreathingIntensity() - sliderGlow.value = devcomm.getBreathingRate() + sliderBrightness.value = DevCom.getBreathingIntensity() + sliderGlow.value = DevCom.getBreathingRate() settingsLoaded = true } } diff --git a/logiconf-gui/Page2.qml b/logiconf-gui/Page2.qml index 21ee34a..1dee302 100755 --- a/logiconf-gui/Page2.qml +++ b/logiconf-gui/Page2.qml @@ -1,4 +1,5 @@ import QtQuick 2.7 +import dslul.devicecomm 1.0 Page2Form { property int resNum: resNumSpinBox.value diff --git a/logiconf-gui/devicecommunicator.cpp b/logiconf-gui/devicecommunicator.cpp index 93f1a64..16ce661 100755 --- a/logiconf-gui/devicecommunicator.cpp +++ b/logiconf-gui/devicecommunicator.cpp @@ -6,16 +6,55 @@ #include #include -#include +#include +#include #include +#include +#include +#include #include "devicecommunicator.h" +#include "devicemanager.h" DeviceCommunicator::DeviceCommunicator(QObject *parent) - : QObject(parent), dev("/dev/hidraw1", HIDPP::DefaultDevice), + : QObject(parent), dev(nullptr), profiles(nullptr), profile(nullptr), + dpi(nullptr), profileformat(nullptr), breathingIntensity(200), breathingRate(10000), oldBreathingRate(10000) { + DeviceManager devmanager; + devmanager.enumerate(); + + HIDPP::Dispatcher *dispatcher = new HIDPP::SimpleDispatcher(devmanager.getDevicePath().c_str()); + dev = new HIDPP20::Device(dispatcher, HIDPP::DefaultDevice); + profiles = new HIDPP20::IOnboardProfiles(dev); + profile = new HIDPP::Profile(); + dpi = new HIDPP20::IAdjustableDPI(dev); + profileformat = new HIDPP20::ProfileFormat(profiles->getDescription()); + + + HIDPP::Address dir_address; + dir_address = HIDPP::Address { HIDPP20::IOnboardProfiles::Writeable, 0, 0 }; + std::unique_ptr profdir_format; + profdir_format = HIDPP20::getProfileDirectoryFormat(dev); + std::unique_ptr memory; + memory.reset(new HIDPP20::MemoryMapping(dev)); + + auto profdir_it = memory->getReadOnlyIterator(dir_address); + HIDPP::ProfileDirectory profdir = profdir_format->read (profdir_it); + for (const auto &entry: profdir.entries) { + auto it = memory->getReadOnlyIterator(entry.profile_address); + *profile = profileformat->read(it); + } + //std::cout << profile->settings.at("angle_snapping").toString() << "\n"; + //for(auto elem : profile->settings) + // std::cout << elem.first << " - " << "\n"; + + + //profile.setCurrentDPIIndex(4); + //profile.setCurrentProfile(HIDPP20::IOnboardProfiles::MemoryType::Writeable, 1); + //std::cout << profile->settings << std::endl; + QFile savefile(savefilePath); std::cout << savefilePath.toStdString() << std::endl; if(savefile.exists() == false) { @@ -51,17 +90,32 @@ DeviceCommunicator::DeviceCommunicator(QObject *parent) savefile.close(); } +void DeviceCommunicator::setDPIIndex(int level) +{ + return profiles->setCurrentDPIIndex(level); +} + +int DeviceCommunicator::getDPIIndex() +{ + return profiles->getCurrentDPIIndex(); +} + +int DeviceCommunicator::getcurrentDPI() +{ + return std::get<0>(dpi->getSensorDPI(0)); +} + void DeviceCommunicator::toggleDPILed() { if(isDPILedOn()) - dev.callFunction(5, 7, {0,4,0}); + dev->callFunction(5, 7, {0,4,0}); else - dev.callFunction(5, 7, {0,2,0}); + dev->callFunction(5, 7, {0,2,0}); } bool DeviceCommunicator::isDPILedOn() { - std::vector result = dev.callFunction(5, 6, {0,0,0}); + std::vector result = dev->callFunction(5, 6, {0,0,0}); if(result.at(1) == 0x04) { return false; } else if(result.at(1) == 0x02) { @@ -97,16 +151,16 @@ void DeviceCommunicator::setLogoGlow(quint16 value) void DeviceCommunicator::setBackLlight(quint16 intensity, quint16 rate) { - dev.callFunction(5, 3, {1,0,0}); - dev.callFunction(5, 5, {1,0,0x80,0,(uint8_t)intensity, + dev->callFunction(5, 3, {1,0,0}); + dev->callFunction(5, 5, {1,0,0x80,0,(uint8_t)intensity, (uint8_t)(rate>>8),(uint8_t)(rate&0x00ff),0,0,0,0,0,0,0,0,0}); - dev.callFunction(5, 3, {0,0,0}); + dev->callFunction(5, 3, {0,0,0}); saveSettings(); } QString DeviceCommunicator::getDeviceName() { - return QString::fromStdString(dev.name()); + return QString::fromStdString(dev->name()); } void DeviceCommunicator::saveSettings() diff --git a/logiconf-gui/devicecommunicator.h b/logiconf-gui/devicecommunicator.h index f2d9b64..ad1b080 100755 --- a/logiconf-gui/devicecommunicator.h +++ b/logiconf-gui/devicecommunicator.h @@ -4,12 +4,18 @@ #include #include #include +#include +#include +#include class DeviceCommunicator : public QObject { Q_OBJECT public: explicit DeviceCommunicator(QObject *parent = 0); + Q_INVOKABLE void setDPIIndex(int level); + Q_INVOKABLE int getDPIIndex(); + Q_INVOKABLE int getcurrentDPI(); Q_INVOKABLE void toggleDPILed(); Q_INVOKABLE bool isDPILedOn(); Q_INVOKABLE void setLogoBrightness(quint16 value); @@ -21,7 +27,11 @@ class DeviceCommunicator : public QObject Q_INVOKABLE quint16 getBreathingRate(); Q_INVOKABLE bool isBreathingEnabled(); private: - HIDPP20::Device dev; + HIDPP20::Device *dev; + HIDPP20::IOnboardProfiles *profiles; + HIDPP::Profile *profile; + HIDPP20::IAdjustableDPI *dpi; + HIDPP20::ProfileFormat *profileformat; quint16 breathingIntensity; quint16 breathingRate; quint16 oldBreathingRate; diff --git a/logiconf-gui/devicemanager.cpp b/logiconf-gui/devicemanager.cpp index b4b4340..b15a3f9 100644 --- a/logiconf-gui/devicemanager.cpp +++ b/logiconf-gui/devicemanager.cpp @@ -1,6 +1,78 @@ +#include + +#include +#include +#include +#include +#include + #include "devicemanager.h" +/* +DeviceManager::DeviceManager(): + dev(nullptr) +{ +}*/ -DeviceManager::DeviceManager() + +std::string DeviceManager::getDevicePath() { + return pathdev; +} + + + +void DeviceManager::addDevice(const char *path) { + try { + HIDPP::SimpleDispatcher dispatcher(path); + bool has_receiver_index = false; + for(HIDPP::DeviceIndex index: { + HIDPP::DefaultDevice, + HIDPP::CordedDevice, + HIDPP::WirelessDevice1, + HIDPP::WirelessDevice2, + HIDPP::WirelessDevice3, + HIDPP::WirelessDevice4, + HIDPP::WirelessDevice5, + HIDPP::WirelessDevice6 }) { + // Skip wireless devices, if the default index(used by the receiver) already failed. + if(!has_receiver_index && index == HIDPP::WirelessDevice1) + break; + try { + HIDPP::Device dev(&dispatcher, index); + auto version = dev.protocolVersion(); + std::cout << path << std::endl; + pathdev = path; + if(index == HIDPP::DefaultDevice && version == std::make_tuple(1, 0)) + has_receiver_index = true; + //TODO: implement a list of compatible devices + break; + } + catch(HIDPP10::Error e) { + if(e.errorCode() != HIDPP10::Error::UnknownDevice && e.errorCode() != HIDPP10::Error::InvalidSubID) { + Log::error().printf("Error while querying %s wireless device %d: %s\n", + path, index, e.what()); + } + } + catch(HIDPP20::Error e) { + if(e.errorCode() != HIDPP20::Error::UnknownDevice) { + Log::error().printf("Error while querying %s device %d: %s\n", + path, index, e.what()); + } + } + catch(HIDPP::Dispatcher::TimeoutError e) { + Log::warning().printf("Device %s(index %d) timed out\n", + path, index); + } + } + + } + catch(HIDPP::Dispatcher::NoHIDPPReportException e) { + } + catch(std::system_error e) { + Log::warning().printf("Failed to open %s: %s\n", path, e.what()); + } +} +void DeviceManager::removeDevice(const char *path) { + return; } diff --git a/logiconf-gui/devicemanager.h b/logiconf-gui/devicemanager.h index fb15b50..c453ffa 100644 --- a/logiconf-gui/devicemanager.h +++ b/logiconf-gui/devicemanager.h @@ -1,17 +1,25 @@ #ifndef DEVICEMANAGER_H #define DEVICEMANAGER_H -#include +#include +#include -class DeviceManager : public QQuickItem +class DeviceManager : public HID::DeviceMonitor { - Q_OBJECT public: - DeviceManager(); + std::string getDevicePath(); + //DeviceManager(); -signals: +private: + std::string pathdev; -public slots: + + + + +protected: + void addDevice(const char *path); + void removeDevice(const char *path); }; -#endif // DEVICEMANAGER_H \ No newline at end of file +#endif // DEVICEMANAGER_H diff --git a/logiconf-gui/logiconf-gui.pro b/logiconf-gui/logiconf-gui.pro index 1d6d5a8..7b1db09 100755 --- a/logiconf-gui/logiconf-gui.pro +++ b/logiconf-gui/logiconf-gui.pro @@ -1,10 +1,10 @@ QT += qml quick -CONFIG += c++11 +CONFIG += c++14 SOURCES += main.cpp \ devicecommunicator.cpp \ - ProfileManager.cpp + devicemanager.cpp RESOURCES += qml.qrc @@ -32,11 +32,19 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin HEADERS += \ devicecommunicator.h \ - ProfileManager.h + devicemanager.h unix:!macx: LIBS += -L$$OUT_PWD/../hidpp/ -lhidpp INCLUDEPATH += $$PWD/../hidpp DEPENDPATH += $$PWD/../hidpp +unix { + packagesExist(libudev) { + CONFIG += link_pkgconfig + DEFINES += LINK_LIBUDEV + PKGCONFIG += libudev + } +} + unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../hidpp/libhidpp.a diff --git a/logiconf-gui/main.cpp b/logiconf-gui/main.cpp index 681e626..978a497 100755 --- a/logiconf-gui/main.cpp +++ b/logiconf-gui/main.cpp @@ -1,18 +1,26 @@ +#include + #include #include #include #include #include +#include +#include #include "devicecommunicator.h" -#include "ProfileManager.h" int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); - qmlRegisterType("dslul.devicecomm", 1,0, "DevCom"); - qmlRegisterType("dslul.ProfileManager", 1,0, "ProfileManager"); + + qmlRegisterSingletonType("dslul.devicecomm", 1,0, "DevCom", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * { + Q_UNUSED(engine) + Q_UNUSED(scriptEngine) + DeviceCommunicator *devcomm = new DeviceCommunicator(); + return devcomm; + }); QQmlApplicationEngine engine; engine.load(QUrl(QLatin1String("qrc:/main.qml"))); diff --git a/logiconf-gui/main.qml b/logiconf-gui/main.qml index d878bd4..6bc5582 100755 --- a/logiconf-gui/main.qml +++ b/logiconf-gui/main.qml @@ -25,10 +25,6 @@ ApplicationWindow { } } - DevCom { - id: devcomm - } - SwipeView { id: swipeView anchors.fill: parent @@ -42,7 +38,7 @@ ApplicationWindow { Page { Label { - text: devcomm.getDeviceName() + text: DevCom.getDeviceName() anchors.centerIn: parent } diff --git a/logiconf.pro b/logiconf.pro index 4479dae..cdd5995 100755 --- a/logiconf.pro +++ b/logiconf.pro @@ -3,4 +3,5 @@ TEMPLATE = subdirs CONFIG += ordered CONFIG += static + SUBDIRS = hidpp logiconf-gui