diff --git a/INSTALL.md b/INSTALL.md index d3432fb..4589e43 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -65,11 +65,4 @@ Gentoo :
Same as install, but your profile and reboot files are preserved.
## Uninstall :
-`sudo make uninstall`
- -## Boot profiles :
-On boot, the keyboard is set with the udev file /etc/udev/rules.d/g810-led.rules
-This file launches the profile stored in /etc/g810-led/profile
-To prevent your keyboard flashing 3 times when you reboot use the systemd unit (g810-led-reboot).
- -Samples can be found in /etc/g810-led/samples.
+`sudo make uninstall`
\ No newline at end of file diff --git a/PROFILES.md b/PROFILES.md new file mode 100644 index 0000000..eaac74d --- /dev/null +++ b/PROFILES.md @@ -0,0 +1,16 @@ +# Profiles for your keyboard + +## Boot profiles :
+On boot, the keyboard is set with the udev file `/etc/udev/rules.d/g810-led.rules`
+This file launches the profile stored in `/etc/g810-led/profile`
+To prevent your keyboard flashing 3 times when you reboot use the systemd unit (g810-led-reboot).
+ +A profile looks like this: +``` +# G810-LED Profile (turn all keys on) + +a ffffff # Set all keys on + +c # Commit changes +``` +More samples can be found in [/etc/g810-led/samples.](https://github.com/MatMoul/g810-led/tree/master/sample_profiles)
diff --git a/README.md b/README.md index f178a92..960fe64 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,10 @@ Linux led controller for Logitech G213, G410, G413, G512, G513, G610, G810, G910 ## Install :
* [INSTALL.md](https://github.com/MatMoul/g810-led/blob/master/INSTALL.md) +## Profiles :
+You can load predefined configurations on startup! +* [PROFILES.md](https://github.com/MatMoul/g810-led/blob/master/PROFILES.md) + ## Help :
`g213-led --help`
`g410-led --help`
diff --git a/src/classes/Keyboard.cpp b/src/classes/Keyboard.cpp index 8b1adc3..c5acf2c 100644 --- a/src/classes/Keyboard.cpp +++ b/src/classes/Keyboard.cpp @@ -374,10 +374,11 @@ bool LedKeyboard::commit() { case KeyboardModel::g413: return true; // Keyboard is non-transactional case KeyboardModel::g410: - case KeyboardModel::g512: - case KeyboardModel::g513: + case KeyboardModel::g512: + case KeyboardModel::g513: case KeyboardModel::g610: case KeyboardModel::g810: + case KeyboardModel::g815: case KeyboardModel::gpro: data = { 0x11, 0xff, 0x0c, 0x5a }; break; @@ -543,7 +544,12 @@ bool LedKeyboard::setGroupKeys(KeyGroup keyGroup, LedKeyboard::Color color) { keyArray = keyGroupLogo; break; case KeyGroup::indicators: - keyArray = keyGroupIndicators; + switch (currentDevice.model) { + case KeyboardModel::g815: + return true; + default: + keyArray = keyGroupIndicators; + } break; case KeyGroup::gkeys: keyArray = keyGroupGKeys; @@ -720,7 +726,7 @@ bool LedKeyboard::setStartupMode(StartupMode startupMode) { bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, std::chrono::duration period, Color color, NativeEffectStorage storage) { - uint8_t protocolByte = 0; + uint8_t protocolBytes[2] = {0x00, 0x00}; NativeEffectGroup effectGroup = static_cast(static_cast(effect) >> 8); // NativeEffectPart::all is not in the device protocol, but an alias for both keys and logo, plus indicators @@ -736,12 +742,15 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, break; case NativeEffectGroup::cycle: case NativeEffectGroup::waves: + case NativeEffectGroup::ripple: if (! setGroupKeys( LedKeyboard::KeyGroup::indicators, LedKeyboard::Color({0xff, 0xff, 0xff})) ) return false; if (! commit()) return false; break; + default: + break; } return ( setNativeEffect(effect, LedKeyboard::NativeEffectPart::keys, period, color, storage) && @@ -751,30 +760,33 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, switch (currentDevice.model) { case KeyboardModel::g213: case KeyboardModel::g413: - protocolByte = 0x0c; + protocolBytes[0] = 0x0c; + protocolBytes[1] = 0x3c; if (part == NativeEffectPart::logo) return true; //Does not have logo component break; case KeyboardModel::g410: - case KeyboardModel::g512: - case KeyboardModel::g513: + case KeyboardModel::g512: + case KeyboardModel::g513: case KeyboardModel::g610: // Unconfirmed case KeyboardModel::g810: case KeyboardModel::gpro: - protocolByte = 0x0d; + protocolBytes[0] = 0x0d; + protocolBytes[1] = 0x3c; + break; + case KeyboardModel::g815: + protocolBytes[0] = 0x0f; + protocolBytes[1] = 0x1c; break; case KeyboardModel::g910: - protocolByte = 0x10; + protocolBytes[0] = 0x10; + protocolBytes[1] = 0x3c; break; default: return false; } - if ((effectGroup == NativeEffectGroup::waves) && (part == NativeEffectPart::logo)) { - return setNativeEffect(NativeEffect::color, part, std::chrono::seconds(0), Color({0x00, 0xff, 0xff}), storage); - } - byte_buffer_t data = { - 0x11, 0xff, protocolByte, 0x3c, + 0x11, 0xff, protocolBytes[0], protocolBytes[1], (uint8_t)part, static_cast(effectGroup), // color of static-color and breathing effects color.red, color.green, color.blue, @@ -791,7 +803,71 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, 0, // unused? 0, // unused? }; - return sendDataInternal(data); + + byte_buffer_t setupData; + bool retval; + switch (currentDevice.model) { + case KeyboardModel::g815: + setupData = { 0x11, 0xff, 0x0f, 0x5c, 0x01, 0x03, 0x03 }; + setupData.resize(20, 0x00); + retval = sendDataInternal(setupData); + + data[16] = 0x01; + + switch (part) { + case NativeEffectPart::keys: + data[4] = 0x01; + + //Seems to conflict with a star-like effect on G410 and G810 + switch (effect) { + case NativeEffect::ripple: + //Adjust periodicity + data[9]=0x00; + data[10]=period.count() >> 8 & 0xff;; + data[11]=period.count() & 0xff; + data[12]=0x00; + break; + default: + break; + } + break; + case NativeEffectPart::logo: + data[4] = 0x00; + switch (effect) { + case NativeEffect::breathing: + data[5]=0x03; + break; + case NativeEffect::cwave: + case NativeEffect::vwave: + case NativeEffect::hwave: + data[5]=0x02; + data[13]=0x64; + break; + case NativeEffect::waves: + case NativeEffect::cycle: + data[5]=0x02; + break; + case NativeEffect::ripple: + case NativeEffect::off: + data[5]=0x00; + break; + default: + data[5]=0x01; + break; + } + break; + default: + break; + } + break; + default: //Many devices may not support logo coloring for wave? + if ((effectGroup == NativeEffectGroup::waves) && (part == NativeEffectPart::logo)) { + return setNativeEffect(NativeEffect::color, part, std::chrono::seconds(0), Color({0x00, 0xff, 0xff}), storage); + } + break; + } + retval = sendDataInternal(data); + return retval; } @@ -799,7 +875,6 @@ bool LedKeyboard::sendDataInternal(byte_buffer_t &data) { if (data.size() > 0) { #if defined(hidapi) if (! open(currentDevice.vendorID, currentDevice.productID, currentDevice.serialNumber)) return false; - data.insert(data.begin(), 0x00); if (hid_write(m_hidHandle, const_cast(data.data()), data.size()) < 0) { std::cout<<"Error: Can not write to hidraw, try with the libusb version"<(NativeEffectGroup::color) << 8, breathing = static_cast(NativeEffectGroup::breathing) << 8, cycle = static_cast(NativeEffectGroup::cycle) << 8, waves = static_cast(NativeEffectGroup::waves) << 8, hwave, vwave, - cwave + cwave, + ripple = static_cast(NativeEffectGroup::ripple) << 8 }; enum class NativeEffectPart : uint8_t { all = 0xff,