mirror of
https://github.com/MatMoul/g810-led.git
synced 2024-12-23 01:06:11 +00:00
Merge branch 'develop' into master
This commit is contained in:
commit
b61655fe59
@ -65,11 +65,4 @@ Gentoo :<br/>
|
|||||||
Same as install, but your profile and reboot files are preserved.</br>
|
Same as install, but your profile and reboot files are preserved.</br>
|
||||||
|
|
||||||
## Uninstall :</br>
|
## Uninstall :</br>
|
||||||
`sudo make uninstall`</br>
|
`sudo make uninstall`</br>
|
||||||
|
|
||||||
## Boot profiles :</br>
|
|
||||||
On boot, the keyboard is set with the udev file /etc/udev/rules.d/g810-led.rules</br>
|
|
||||||
This file launches the profile stored in /etc/g810-led/profile</br>
|
|
||||||
To prevent your keyboard flashing 3 times when you reboot use the systemd unit (g810-led-reboot).</br>
|
|
||||||
|
|
||||||
Samples can be found in /etc/g810-led/samples.</br>
|
|
16
PROFILES.md
Normal file
16
PROFILES.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Profiles for your keyboard
|
||||||
|
|
||||||
|
## Boot profiles :</br>
|
||||||
|
On boot, the keyboard is set with the udev file `/etc/udev/rules.d/g810-led.rules`</br>
|
||||||
|
This file launches the profile stored in `/etc/g810-led/profile`</br>
|
||||||
|
To prevent your keyboard flashing 3 times when you reboot use the systemd unit (g810-led-reboot).</br>
|
||||||
|
|
||||||
|
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)</br>
|
@ -21,6 +21,10 @@ Linux led controller for Logitech G213, G410, G413, G512, G513, G610, G810, G910
|
|||||||
## Install :</br>
|
## Install :</br>
|
||||||
* [INSTALL.md](https://github.com/MatMoul/g810-led/blob/master/INSTALL.md)
|
* [INSTALL.md](https://github.com/MatMoul/g810-led/blob/master/INSTALL.md)
|
||||||
|
|
||||||
|
## Profiles :<br>
|
||||||
|
You can load predefined configurations on startup!
|
||||||
|
* [PROFILES.md](https://github.com/MatMoul/g810-led/blob/master/PROFILES.md)
|
||||||
|
|
||||||
## Help :</br>
|
## Help :</br>
|
||||||
`g213-led --help`</br>
|
`g213-led --help`</br>
|
||||||
`g410-led --help`</br>
|
`g410-led --help`</br>
|
||||||
|
@ -374,10 +374,11 @@ bool LedKeyboard::commit() {
|
|||||||
case KeyboardModel::g413:
|
case KeyboardModel::g413:
|
||||||
return true; // Keyboard is non-transactional
|
return true; // Keyboard is non-transactional
|
||||||
case KeyboardModel::g410:
|
case KeyboardModel::g410:
|
||||||
case KeyboardModel::g512:
|
case KeyboardModel::g512:
|
||||||
case KeyboardModel::g513:
|
case KeyboardModel::g513:
|
||||||
case KeyboardModel::g610:
|
case KeyboardModel::g610:
|
||||||
case KeyboardModel::g810:
|
case KeyboardModel::g810:
|
||||||
|
case KeyboardModel::g815:
|
||||||
case KeyboardModel::gpro:
|
case KeyboardModel::gpro:
|
||||||
data = { 0x11, 0xff, 0x0c, 0x5a };
|
data = { 0x11, 0xff, 0x0c, 0x5a };
|
||||||
break;
|
break;
|
||||||
@ -543,7 +544,12 @@ bool LedKeyboard::setGroupKeys(KeyGroup keyGroup, LedKeyboard::Color color) {
|
|||||||
keyArray = keyGroupLogo;
|
keyArray = keyGroupLogo;
|
||||||
break;
|
break;
|
||||||
case KeyGroup::indicators:
|
case KeyGroup::indicators:
|
||||||
keyArray = keyGroupIndicators;
|
switch (currentDevice.model) {
|
||||||
|
case KeyboardModel::g815:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
keyArray = keyGroupIndicators;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case KeyGroup::gkeys:
|
case KeyGroup::gkeys:
|
||||||
keyArray = keyGroupGKeys;
|
keyArray = keyGroupGKeys;
|
||||||
@ -720,7 +726,7 @@ bool LedKeyboard::setStartupMode(StartupMode startupMode) {
|
|||||||
bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part,
|
bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part,
|
||||||
std::chrono::duration<uint16_t, std::milli> period, Color color,
|
std::chrono::duration<uint16_t, std::milli> period, Color color,
|
||||||
NativeEffectStorage storage) {
|
NativeEffectStorage storage) {
|
||||||
uint8_t protocolByte = 0;
|
uint8_t protocolBytes[2] = {0x00, 0x00};
|
||||||
NativeEffectGroup effectGroup = static_cast<NativeEffectGroup>(static_cast<uint16_t>(effect) >> 8);
|
NativeEffectGroup effectGroup = static_cast<NativeEffectGroup>(static_cast<uint16_t>(effect) >> 8);
|
||||||
|
|
||||||
// NativeEffectPart::all is not in the device protocol, but an alias for both keys and logo, plus indicators
|
// 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;
|
break;
|
||||||
case NativeEffectGroup::cycle:
|
case NativeEffectGroup::cycle:
|
||||||
case NativeEffectGroup::waves:
|
case NativeEffectGroup::waves:
|
||||||
|
case NativeEffectGroup::ripple:
|
||||||
if (! setGroupKeys(
|
if (! setGroupKeys(
|
||||||
LedKeyboard::KeyGroup::indicators,
|
LedKeyboard::KeyGroup::indicators,
|
||||||
LedKeyboard::Color({0xff, 0xff, 0xff}))
|
LedKeyboard::Color({0xff, 0xff, 0xff}))
|
||||||
) return false;
|
) return false;
|
||||||
if (! commit()) return false;
|
if (! commit()) return false;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
setNativeEffect(effect, LedKeyboard::NativeEffectPart::keys, period, color, storage) &&
|
setNativeEffect(effect, LedKeyboard::NativeEffectPart::keys, period, color, storage) &&
|
||||||
@ -751,30 +760,33 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part,
|
|||||||
switch (currentDevice.model) {
|
switch (currentDevice.model) {
|
||||||
case KeyboardModel::g213:
|
case KeyboardModel::g213:
|
||||||
case KeyboardModel::g413:
|
case KeyboardModel::g413:
|
||||||
protocolByte = 0x0c;
|
protocolBytes[0] = 0x0c;
|
||||||
|
protocolBytes[1] = 0x3c;
|
||||||
if (part == NativeEffectPart::logo) return true; //Does not have logo component
|
if (part == NativeEffectPart::logo) return true; //Does not have logo component
|
||||||
break;
|
break;
|
||||||
case KeyboardModel::g410:
|
case KeyboardModel::g410:
|
||||||
case KeyboardModel::g512:
|
case KeyboardModel::g512:
|
||||||
case KeyboardModel::g513:
|
case KeyboardModel::g513:
|
||||||
case KeyboardModel::g610: // Unconfirmed
|
case KeyboardModel::g610: // Unconfirmed
|
||||||
case KeyboardModel::g810:
|
case KeyboardModel::g810:
|
||||||
case KeyboardModel::gpro:
|
case KeyboardModel::gpro:
|
||||||
protocolByte = 0x0d;
|
protocolBytes[0] = 0x0d;
|
||||||
|
protocolBytes[1] = 0x3c;
|
||||||
|
break;
|
||||||
|
case KeyboardModel::g815:
|
||||||
|
protocolBytes[0] = 0x0f;
|
||||||
|
protocolBytes[1] = 0x1c;
|
||||||
break;
|
break;
|
||||||
case KeyboardModel::g910:
|
case KeyboardModel::g910:
|
||||||
protocolByte = 0x10;
|
protocolBytes[0] = 0x10;
|
||||||
|
protocolBytes[1] = 0x3c;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return false;
|
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 = {
|
byte_buffer_t data = {
|
||||||
0x11, 0xff, protocolByte, 0x3c,
|
0x11, 0xff, protocolBytes[0], protocolBytes[1],
|
||||||
(uint8_t)part, static_cast<uint8_t>(effectGroup),
|
(uint8_t)part, static_cast<uint8_t>(effectGroup),
|
||||||
// color of static-color and breathing effects
|
// color of static-color and breathing effects
|
||||||
color.red, color.green, color.blue,
|
color.red, color.green, color.blue,
|
||||||
@ -791,7 +803,71 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part,
|
|||||||
0, // unused?
|
0, // unused?
|
||||||
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 (data.size() > 0) {
|
||||||
#if defined(hidapi)
|
#if defined(hidapi)
|
||||||
if (! open(currentDevice.vendorID, currentDevice.productID, currentDevice.serialNumber)) return false;
|
if (! open(currentDevice.vendorID, currentDevice.productID, currentDevice.serialNumber)) return false;
|
||||||
data.insert(data.begin(), 0x00);
|
|
||||||
if (hid_write(m_hidHandle, const_cast<unsigned char*>(data.data()), data.size()) < 0) {
|
if (hid_write(m_hidHandle, const_cast<unsigned char*>(data.data()), data.size()) < 0) {
|
||||||
std::cout<<"Error: Can not write to hidraw, try with the libusb version"<<std::endl;
|
std::cout<<"Error: Can not write to hidraw, try with the libusb version"<<std::endl;
|
||||||
return false;
|
return false;
|
||||||
|
@ -54,6 +54,7 @@ class LedKeyboard {
|
|||||||
{ 0x46d, 0xc338, (uint16_t)KeyboardModel::g610 },
|
{ 0x46d, 0xc338, (uint16_t)KeyboardModel::g610 },
|
||||||
{ 0x46d, 0xc331, (uint16_t)KeyboardModel::g810 },
|
{ 0x46d, 0xc331, (uint16_t)KeyboardModel::g810 },
|
||||||
{ 0x46d, 0xc337, (uint16_t)KeyboardModel::g810 },
|
{ 0x46d, 0xc337, (uint16_t)KeyboardModel::g810 },
|
||||||
|
{ 0x46d, 0xc33f, (uint16_t)KeyboardModel::g815 },
|
||||||
{ 0x46d, 0xc32b, (uint16_t)KeyboardModel::g910 },
|
{ 0x46d, 0xc32b, (uint16_t)KeyboardModel::g910 },
|
||||||
{ 0x46d, 0xc335, (uint16_t)KeyboardModel::g910 },
|
{ 0x46d, 0xc335, (uint16_t)KeyboardModel::g910 },
|
||||||
{ 0x46d, 0xc339, (uint16_t)KeyboardModel::gpro }
|
{ 0x46d, 0xc339, (uint16_t)KeyboardModel::gpro }
|
||||||
@ -68,6 +69,7 @@ class LedKeyboard {
|
|||||||
g513,
|
g513,
|
||||||
g610,
|
g610,
|
||||||
g810,
|
g810,
|
||||||
|
g815,
|
||||||
g910,
|
g910,
|
||||||
gpro
|
gpro
|
||||||
};
|
};
|
||||||
@ -79,19 +81,23 @@ class LedKeyboard {
|
|||||||
color
|
color
|
||||||
};
|
};
|
||||||
enum class NativeEffectGroup : uint8_t {
|
enum class NativeEffectGroup : uint8_t {
|
||||||
color = 0x01,
|
off,
|
||||||
|
color,
|
||||||
breathing,
|
breathing,
|
||||||
cycle,
|
cycle,
|
||||||
waves
|
waves,
|
||||||
|
ripple
|
||||||
};
|
};
|
||||||
enum class NativeEffect : uint16_t {
|
enum class NativeEffect : uint16_t {
|
||||||
|
off,
|
||||||
color = static_cast<uint16_t>(NativeEffectGroup::color) << 8,
|
color = static_cast<uint16_t>(NativeEffectGroup::color) << 8,
|
||||||
breathing = static_cast<uint16_t>(NativeEffectGroup::breathing) << 8,
|
breathing = static_cast<uint16_t>(NativeEffectGroup::breathing) << 8,
|
||||||
cycle = static_cast<uint16_t>(NativeEffectGroup::cycle) << 8,
|
cycle = static_cast<uint16_t>(NativeEffectGroup::cycle) << 8,
|
||||||
waves = static_cast<uint16_t>(NativeEffectGroup::waves) << 8,
|
waves = static_cast<uint16_t>(NativeEffectGroup::waves) << 8,
|
||||||
hwave,
|
hwave,
|
||||||
vwave,
|
vwave,
|
||||||
cwave
|
cwave,
|
||||||
|
ripple = static_cast<uint16_t>(NativeEffectGroup::ripple) << 8
|
||||||
};
|
};
|
||||||
enum class NativeEffectPart : uint8_t {
|
enum class NativeEffectPart : uint8_t {
|
||||||
all = 0xff,
|
all = 0xff,
|
||||||
|
Loading…
Reference in New Issue
Block a user