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,