Hello community, here is the log from the commit of package g810-led for openSUSE:Leap:15.2 checked in at 2020-05-28 20:09:31 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/g810-led (Old) and /work/SRC/openSUSE:Leap:15.2/.g810-led.new.3606 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "g810-led" Thu May 28 20:09:31 2020 rev:2 rq:809116 version:0.4.2 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/g810-led/g810-led.changes 2020-02-09 11:26:47.535345853 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.g810-led.new.3606/g810-led.changes 2020-05-28 20:09:33.866893323 +0200 @@ -1,0 +2,6 @@ +Wed May 20 12:21:52 UTC 2020 - Olav Reinert <[email protected]> + +- Update to version 0.4.2: + * add support for G815 + +------------------------------------------------------------------- Old: ---- g810-led-0.3.9.tar.gz New: ---- g810-led-0.4.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ g810-led.spec ++++++ --- /var/tmp/diff_new_pack.hCHQGj/_old 2020-05-28 20:09:34.434895014 +0200 +++ /var/tmp/diff_new_pack.hCHQGj/_new 2020-05-28 20:09:34.434895014 +0200 @@ -1,7 +1,7 @@ # # spec file for package g810-led # -# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: g810-led -Version: 0.3.9 +Version: 0.4.2 Release: 0 Summary: Controller for Logitech LED keyboards License: GPL-3.0-only @@ -47,7 +47,7 @@ %setup -q %build -make %{?_smp_mflags} +%make_build %install install -D -m 644 -t %{buildroot}%{_sysconfdir}/%{name}/samples/ sample_profiles/* ++++++ g810-led-0.3.9.tar.gz -> g810-led-0.4.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/g810-led-0.3.9/INSTALL.md new/g810-led-0.4.2/INSTALL.md --- old/g810-led-0.3.9/INSTALL.md 2019-09-21 00:44:32.000000000 +0200 +++ new/g810-led-0.4.2/INSTALL.md 2020-05-19 23:44:50.000000000 +0200 @@ -65,11 +65,4 @@ Same as install, but your profile and reboot files are preserved.</br> ## 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> +`sudo make uninstall`</br> \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/g810-led-0.3.9/PROFILES.md new/g810-led-0.4.2/PROFILES.md --- old/g810-led-0.3.9/PROFILES.md 1970-01-01 01:00:00.000000000 +0100 +++ new/g810-led-0.4.2/PROFILES.md 2020-05-19 23:44:50.000000000 +0200 @@ -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> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/g810-led-0.3.9/README.md new/g810-led-0.4.2/README.md --- old/g810-led-0.3.9/README.md 2019-09-21 00:44:32.000000000 +0200 +++ new/g810-led-0.4.2/README.md 2020-05-19 23:44:50.000000000 +0200 @@ -1,6 +1,6 @@ # g810-led</br> -Linux led controller for Logitech G213, G410, G413, G512, G513, G610, G810, G910 and GPRO Keyboards.</br> +Linux led controller for Logitech G213, G410, G413, G512, G513, G610, G810, G815, G910 and GPRO Keyboards.</br> ## Compatible keyboards :</br> - **G213 Prodigy**</br> @@ -11,6 +11,7 @@ - **G610 Orion Brown**</br> - **G610 Orion Red**</br> - **G810 Orion Spectrum**</br> +- **G815 LIGHTSYNC**</br> - **G910 Orion Spark**</br> - **G910 Orion Spectrum**</br> - **GPRO**</br> @@ -21,6 +22,10 @@ ## Install :</br> * [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> `g213-led --help`</br> `g410-led --help`</br> @@ -29,6 +34,7 @@ `g513-led --help`</br> `g610-led --help`</br> `g810-led --help`</br> +`g815-led --help`</br> `g910-led --help`</br> `gpro-led --help`</br> @@ -76,12 +82,14 @@ `lsusb`</br> Sample return :<br> `Bus 001 Device 001: ID 046d:c331 Logitech, Inc.`</br> -In this sample VendorID is 046d and ProductID is c331. Now test your keyboard with all supported protocol :</br> +In this sample VendorID is 046d and ProductID is c331. Now test your keyboard with all supported protocol (for 2019 keyboard start with -tuk 4):</br> `g810-led -dv 046d -dp c331 -tuk 1 -a 000000`</br> If your keyboard set all key to off you have found the protocol (1), if not continue.</br> `g810-led -dv 046d -dp c331 -tuk 2 -a 000000`</br> If your keyboard set all key to off you have found the protocol (2), if not continue.</br> `g810-led -dv 046d -dp c331 -tuk 3 -a 000000`</br> +If your keyboard set all key to off you have found the protocol (2), if not continue.</br> +`g810-led -dv 046d -dp c331 -tuk 4 -a 000000`</br> If your keyboard set all key to off you have found the protocol (3), if not, need new dump.</br> ## Building and linking against the libg810-led library :</br> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/g810-led-0.3.9/makefile new/g810-led-0.4.2/makefile --- old/g810-led-0.3.9/makefile 2019-09-21 00:44:32.000000000 +0200 +++ new/g810-led-0.4.2/makefile 2020-05-19 23:44:50.000000000 +0200 @@ -17,8 +17,8 @@ # Program & versioning information PROGN=g810-led MAJOR=0 -MINOR=3 -MICRO=9 +MINOR=4 +MICRO=2 CXXFLAGS+=-std=gnu++11 -DVERSION=\"$(MAJOR).$(MINOR).$(MICRO)\" APPSRCS=src/main.cpp src/helpers/*.cpp @@ -64,6 +64,7 @@ @test -s $(DESTDIR)/usr/bin/g512-led || ln -s /usr/bin/$(PROGN) $(DESTDIR)/usr/bin/g512-led @test -s $(DESTDIR)/usr/bin/g513-led || ln -s /usr/bin/$(PROGN) $(DESTDIR)/usr/bin/g513-led @test -s $(DESTDIR)/usr/bin/g610-led || ln -s /usr/bin/$(PROGN) $(DESTDIR)/usr/bin/g610-led + @test -s $(DESTDIR)/usr/bin/g815-led || ln -s /usr/bin/$(PROGN) $(DESTDIR)/usr/bin/g815-led @test -s $(DESTDIR)/usr/bin/g910-led || ln -s /usr/bin/$(PROGN) $(DESTDIR)/usr/bin/g910-led @test -s $(DESTDIR)/usr/bin/gpro-led || ln -s /usr/bin/$(PROGN) $(DESTDIR)/usr/bin/gpro-led @cp sample_profiles/* $(DESTDIR)/etc/$(PROGN)/samples @@ -111,6 +112,7 @@ @rm /usr/bin/g512-led @rm /usr/bin/g513-led @rm /usr/bin/g610-led + @rm /usr/bin/g815-led @rm /usr/bin/g910-led @rm /usr/bin/gpro-led @rm /usr/bin/$(PROGN) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/g810-led-0.3.9/src/classes/Keyboard.cpp new/g810-led-0.4.2/src/classes/Keyboard.cpp --- old/g810-led-0.3.9/src/classes/Keyboard.cpp 2019-09-21 00:44:32.000000000 +0200 +++ new/g810-led-0.4.2/src/classes/Keyboard.cpp 2020-05-19 23:44:50.000000000 +0200 @@ -19,6 +19,7 @@ #include <iostream> #include <unistd.h> #include <vector> +#include <map> #if defined(hidapi) #include <locale> @@ -374,12 +375,16 @@ case KeyboardModel::g413: return true; // Keyboard is non-transactional case KeyboardModel::g410: - case KeyboardModel::g513: + case KeyboardModel::g512: + case KeyboardModel::g513: case KeyboardModel::g610: case KeyboardModel::g810: case KeyboardModel::gpro: data = { 0x11, 0xff, 0x0c, 0x5a }; break; + case KeyboardModel::g815: + data = { 0x11, 0xff, 0x10, 0x7f }; + break; case KeyboardModel::g910: data = { 0x11, 0xff, 0x0f, 0x5d }; break; @@ -399,135 +404,229 @@ bool retval = true; - vector<vector<KeyValue>> SortedKeys = { - {}, // Logo AddressGroup - {}, // Indicators AddressGroup - {}, // Multimedia AddressGroup - {}, // GKeys AddressGroup - {} // Keys AddressGroup - }; + vector<vector<KeyValue>> SortedKeys; + map<int32_t, vector<KeyValue>> KeyByColors; + map<int32_t, vector<KeyValue>>::iterator KeyByColorsIterator; + const uint8_t maxKeyPerColor = 13; - for (uint8_t i = 0; i < keyValues.size(); i++) { - switch(static_cast<LedKeyboard::KeyAddressGroup>(static_cast<uint16_t>(keyValues[i].key) >> 8 )) { - case LedKeyboard::KeyAddressGroup::logo: - switch (currentDevice.model) { - case LedKeyboard::KeyboardModel::g610: - case LedKeyboard::KeyboardModel::g810: - case LedKeyboard::KeyboardModel::gpro: - if (SortedKeys[0].size() <= 1 && keyValues[i].key == LedKeyboard::Key::logo) - SortedKeys[0].push_back(keyValues[i]); - break; - case LedKeyboard::KeyboardModel::g910: - if (SortedKeys[0].size() <= 2) SortedKeys[0].push_back(keyValues[i]); - break; - default: - break; - } - break; - case LedKeyboard::KeyAddressGroup::indicators: - if (SortedKeys[1].size() <= 5) SortedKeys[1].push_back(keyValues[i]); - break; - case LedKeyboard::KeyAddressGroup::multimedia: - switch (currentDevice.model) { - case LedKeyboard::KeyboardModel::g610: - case LedKeyboard::KeyboardModel::g810: - case LedKeyboard::KeyboardModel::gpro: - if (SortedKeys[2].size() <= 5) SortedKeys[2].push_back(keyValues[i]); - break; - default: - break; - } - break; - case LedKeyboard::KeyAddressGroup::gkeys: - switch (currentDevice.model) { - case LedKeyboard::KeyboardModel::g910: - if (SortedKeys[3].size() <= 9) SortedKeys[3].push_back(keyValues[i]); - break; - default: - break; - } - break; - case LedKeyboard::KeyAddressGroup::keys: - switch (currentDevice.model) { - case LedKeyboard::KeyboardModel::g513: - case LedKeyboard::KeyboardModel::g610: - case LedKeyboard::KeyboardModel::g810: - case LedKeyboard::KeyboardModel::g910: - case LedKeyboard::KeyboardModel::gpro: - if (SortedKeys[4].size() <= 120) SortedKeys[4].push_back(keyValues[i]); - break; - case LedKeyboard::KeyboardModel::g410: - if (SortedKeys[4].size() <= 120) - if (keyValues[i].key < LedKeyboard::Key::num_lock || - keyValues[i].key > LedKeyboard::Key::num_dot) - SortedKeys[4].push_back(keyValues[i]); - break; - default: - break; + switch (currentDevice.model) { + case KeyboardModel::g815: + for (uint8_t i = 0; i < keyValues.size(); i++) { + uint32_t colorkey = static_cast<uint32_t>(keyValues[i].color.red | keyValues[i].color.green << 8 | keyValues[i].color.blue << 16 ); + if (KeyByColors.count(colorkey) == 0) KeyByColors.insert(pair<uint32_t, vector<KeyValue>>(colorkey, {})); + KeyByColors[colorkey].push_back(keyValues[i]); + } + + for (auto& x: KeyByColors) { + if (x.second.size() > 0) { + uint8_t gi = 0; + while (gi < x.second.size()) { + size_t data_size = 20; + byte_buffer_t data = { 0x11, 0xff, 0x10, 0x6c }; + data.push_back(x.second[0].color.red); + data.push_back(x.second[0].color.green); + data.push_back(x.second[0].color.blue); + for (uint8_t i = 0; i < maxKeyPerColor; i++) { + if (gi + i < x.second.size()) { + switch (x.second[gi+i].key) { + case Key::logo2: + case Key::game: + case Key::caps: + case Key::scroll: + case Key::num: + case Key::stop: + case Key::g6: + case Key::g7: + case Key::g8: + case Key::g9: + break; + case Key::play: + data.push_back(0x9b); + break; + case Key::mute: + data.push_back(0x9c); + break; + case Key::next: + data.push_back(0x9d); + break; + case Key::prev: + data.push_back(0x9e); + break; + case Key::ctrl_left: + case Key::shift_left: + case Key::alt_left: + case Key::win_left: + case Key::ctrl_right: + case Key::shift_right: + case Key::alt_right: + case Key::win_right: + data.push_back((static_cast<uint8_t>(x.second[gi+i].key) & 0x00ff) - 0x78); + break; + default: + switch (static_cast<KeyAddressGroup>((static_cast<uint16_t>(x.second[gi+i].key) & 0xff00) / 0xff)) { + case KeyAddressGroup::logo: + data.push_back((static_cast<uint8_t>(x.second[gi+i].key) & 0x00ff) + 0xd1); + break; + case KeyAddressGroup::indicators: + data.push_back((static_cast<uint8_t>(x.second[gi+i].key) & 0x00ff) + 0x98); + break; + case KeyAddressGroup::gkeys: + data.push_back((static_cast<uint8_t>(x.second[gi+i].key) & 0x00ff) + 0xb3); + break; + case KeyAddressGroup::keys: + data.push_back((static_cast<uint8_t>(x.second[gi+i].key) & 0x00ff) - 0x03); + break; + default: + break; + } + } + } + } + + if (data.size() < data_size) data.push_back(0xff); + data.resize(data_size, 0x00); + if (retval) retval = sendDataInternal(data); + else sendDataInternal(data); + + gi = gi + maxKeyPerColor; + } } - break; - } - } - - for (uint8_t kag = 0; kag < 5; kag++) { - - if (SortedKeys[kag].size() > 0) { + } - uint8_t gi = 0; - while (gi < SortedKeys[kag].size()) { - - size_t data_size = 0; - byte_buffer_t data = {}; - - switch (kag) { - case 0: - data_size = 20; - data = getKeyGroupAddress(LedKeyboard::KeyAddressGroup::logo); + break; + default: + SortedKeys = { + {}, // Logo AddressGroup + {}, // Indicators AddressGroup + {}, // Multimedia AddressGroup + {}, // GKeys AddressGroup + {} // Keys AddressGroup + }; + + for (uint8_t i = 0; i < keyValues.size(); i++) { + switch(static_cast<LedKeyboard::KeyAddressGroup>(static_cast<uint16_t>(keyValues[i].key) >> 8 )) { + case LedKeyboard::KeyAddressGroup::logo: + switch (currentDevice.model) { + case LedKeyboard::KeyboardModel::g610: + case LedKeyboard::KeyboardModel::g810: + case LedKeyboard::KeyboardModel::gpro: + if (SortedKeys[0].size() <= 1 && keyValues[i].key == LedKeyboard::Key::logo) + SortedKeys[0].push_back(keyValues[i]); + break; + case LedKeyboard::KeyboardModel::g910: + if (SortedKeys[0].size() <= 2) SortedKeys[0].push_back(keyValues[i]); + break; + default: + break; + } break; - case 1: - data_size = 64; - data = getKeyGroupAddress(LedKeyboard::KeyAddressGroup::indicators); + case LedKeyboard::KeyAddressGroup::indicators: + if (SortedKeys[1].size() <= 5) SortedKeys[1].push_back(keyValues[i]); break; - case 2: - data_size = 64; - data = getKeyGroupAddress(LedKeyboard::KeyAddressGroup::multimedia); + case LedKeyboard::KeyAddressGroup::multimedia: + switch (currentDevice.model) { + case LedKeyboard::KeyboardModel::g610: + case LedKeyboard::KeyboardModel::g810: + case LedKeyboard::KeyboardModel::gpro: + if (SortedKeys[2].size() <= 5) SortedKeys[2].push_back(keyValues[i]); + break; + default: + break; + } break; - case 3: - data_size = 64; - data = getKeyGroupAddress(LedKeyboard::KeyAddressGroup::gkeys); + case LedKeyboard::KeyAddressGroup::gkeys: + switch (currentDevice.model) { + case LedKeyboard::KeyboardModel::g910: + if (SortedKeys[3].size() <= 9) SortedKeys[3].push_back(keyValues[i]); + break; + default: + break; + } break; - case 4: - data_size = 64; - data = getKeyGroupAddress(LedKeyboard::KeyAddressGroup::keys); + case LedKeyboard::KeyAddressGroup::keys: + switch (currentDevice.model) { + case LedKeyboard::KeyboardModel::g512: + case LedKeyboard::KeyboardModel::g513: + case LedKeyboard::KeyboardModel::g610: + case LedKeyboard::KeyboardModel::g810: + case LedKeyboard::KeyboardModel::g910: + case LedKeyboard::KeyboardModel::gpro: + if (SortedKeys[4].size() <= 120) SortedKeys[4].push_back(keyValues[i]); + break; + case LedKeyboard::KeyboardModel::g410: + if (SortedKeys[4].size() <= 120) + if (keyValues[i].key < LedKeyboard::Key::num_lock || + keyValues[i].key > LedKeyboard::Key::num_dot) + SortedKeys[4].push_back(keyValues[i]); + break; + default: + break; + } break; } + } + + for (uint8_t kag = 0; kag < 5; kag++) { - const uint8_t maxKeyCount = (data_size - 8) / 4; - - if (data.size() > 0) { + if (SortedKeys[kag].size() > 0) { - for (uint8_t i = 0; i < maxKeyCount; i++) { - if (gi + i < SortedKeys[kag].size()) { - data.push_back(static_cast<uint8_t>( - static_cast<uint16_t>(SortedKeys[kag][gi+i].key) & 0x00ff)); - data.push_back(SortedKeys[kag][gi+i].color.red); - data.push_back(SortedKeys[kag][gi+i].color.green); - data.push_back(SortedKeys[kag][gi+i].color.blue); + uint8_t gi = 0; + while (gi < SortedKeys[kag].size()) { + + size_t data_size = 0; + byte_buffer_t data = {}; + + switch (kag) { + case 0: + data_size = 20; + data = getKeyGroupAddress(LedKeyboard::KeyAddressGroup::logo); + break; + case 1: + data_size = 64; + data = getKeyGroupAddress(LedKeyboard::KeyAddressGroup::indicators); + break; + case 2: + data_size = 64; + data = getKeyGroupAddress(LedKeyboard::KeyAddressGroup::multimedia); + break; + case 3: + data_size = 64; + data = getKeyGroupAddress(LedKeyboard::KeyAddressGroup::gkeys); + break; + case 4: + data_size = 64; + data = getKeyGroupAddress(LedKeyboard::KeyAddressGroup::keys); + break; + } + + const uint8_t maxKeyCount = (data_size - 8) / 4; + + if (data.size() > 0) { + + for (uint8_t i = 0; i < maxKeyCount; i++) { + if (gi + i < SortedKeys[kag].size()) { + data.push_back(static_cast<uint8_t>( + static_cast<uint16_t>(SortedKeys[kag][gi+i].key) & 0x00ff)); + data.push_back(SortedKeys[kag][gi+i].color.red); + data.push_back(SortedKeys[kag][gi+i].color.green); + data.push_back(SortedKeys[kag][gi+i].color.blue); + } + } + + data.resize(data_size, 0x00); + + if (retval) retval = sendDataInternal(data); + else sendDataInternal(data); + } + + gi = gi + maxKeyCount; } - data.resize(data_size, 0x00); - - if (retval) retval = sendDataInternal(data); - else sendDataInternal(data); - } - - gi = gi + maxKeyCount; } - - } } + return retval; } @@ -588,9 +687,11 @@ NativeEffectStorage::none); return true; case KeyboardModel::g410: - case KeyboardModel::g513: + case KeyboardModel::g512: + case KeyboardModel::g513: case KeyboardModel::g610: case KeyboardModel::g810: + case KeyboardModel::g815: case KeyboardModel::g910: case KeyboardModel::gpro: for (uint8_t i = 0; i < keyGroupLogo.size(); i++) keyValues.push_back({keyGroupLogo[i], color}); @@ -614,6 +715,17 @@ bool LedKeyboard::setMRKey(uint8_t value) { LedKeyboard::byte_buffer_t data; switch (currentDevice.model) { + case KeyboardModel::g815: + switch (value) { + case 0x00: + case 0x01: + data = { 0x11, 0xff, 0x0c, 0x0c, value }; + data.resize(20, 0x00); + return sendDataInternal(data); + default: + break; + } + break; case KeyboardModel::g910: switch (value) { case 0x00: @@ -634,6 +746,24 @@ bool LedKeyboard::setMNKey(uint8_t value) { LedKeyboard::byte_buffer_t data; switch (currentDevice.model) { + case KeyboardModel::g815: + switch (value) { + case 0x01: + data = { 0x11, 0xff, 0x0b, 0x1c, 0x01 }; + data.resize(20, 0x00); + return sendDataInternal(data); + case 0x02: + data = { 0x11, 0xff, 0x0b, 0x1c, 0x02 }; + data.resize(20, 0x00); + return sendDataInternal(data); + case 0x03: + data = { 0x11, 0xff, 0x0b, 0x1c, 0x04 }; + data.resize(20, 0x00); + return sendDataInternal(data); + default: + break; + } + break; case KeyboardModel::g910: switch (value) { case 0x00: @@ -660,6 +790,17 @@ bool LedKeyboard::setGKeysMode(uint8_t value) { LedKeyboard::byte_buffer_t data; switch (currentDevice.model) { + case KeyboardModel::g815: + switch (value) { + case 0x00: + case 0x01: + data = { 0x11, 0xff, 0x0a, 0x2b, value }; + data.resize(20, 0x00); + return sendDataInternal(data); + default: + break; + } + break; case KeyboardModel::g910: switch (value) { case 0x00: @@ -713,11 +854,22 @@ return sendDataInternal(data); } +bool LedKeyboard::setOnBoardMode(OnBoardMode onBoardMode) { + byte_buffer_t data; + switch (currentDevice.model) { + case KeyboardModel::g815: + data = { 0x11, 0xff, 0x11, 0x1a, static_cast<uint8_t>(onBoardMode) }; + data.resize(20, 0x00); + return sendDataInternal(data); + default: + return false; + } +} bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, std::chrono::duration<uint16_t, std::milli> period, Color color, NativeEffectStorage storage) { - uint8_t protocolByte = 0; + uint8_t protocolBytes[2] = {0x00, 0x00}; 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 @@ -733,12 +885,15 @@ 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) && @@ -748,29 +903,33 @@ 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::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<uint8_t>(effectGroup), // color of static-color and breathing effects color.red, color.green, color.blue, @@ -787,7 +946,71 @@ 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; } @@ -795,7 +1018,6 @@ 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<unsigned char*>(data.data()), data.size()) < 0) { std::cout<<"Error: Can not write to hidraw, try with the libusb version"<<std::endl; return false; @@ -835,6 +1057,7 @@ case KeyboardModel::g413: return {}; // Device doesn't support per-key setting case KeyboardModel::g410: + case KeyboardModel::g512: case KeyboardModel::g513: case KeyboardModel::gpro: switch (keyAddressGroup) { @@ -865,6 +1088,20 @@ return { 0x12, 0xff, 0x0c, 0x3a, 0x00, 0x01, 0x00, 0x0e }; } break; + case KeyboardModel::g815: + switch (keyAddressGroup) { + case LedKeyboard::KeyAddressGroup::logo: + return { 0x11, 0xff, 0x10, 0x1c }; + case LedKeyboard::KeyAddressGroup::indicators: + return { 0x11, 0xff, 0x10, 0x1c }; + case LedKeyboard::KeyAddressGroup::gkeys: + return { 0x11, 0xff, 0x10, 0x1c }; + case LedKeyboard::KeyAddressGroup::multimedia: + return { 0x11, 0xff, 0x10, 0x1c }; + case LedKeyboard::KeyAddressGroup::keys: + return { 0x11, 0xff, 0x10, 0x1c }; + } + break; case KeyboardModel::g910: switch (keyAddressGroup) { case LedKeyboard::KeyAddressGroup::logo: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/g810-led-0.3.9/src/classes/Keyboard.h new/g810-led-0.4.2/src/classes/Keyboard.h --- old/g810-led-0.3.9/src/classes/Keyboard.h 2019-09-21 00:44:32.000000000 +0200 +++ new/g810-led-0.4.2/src/classes/Keyboard.h 2020-05-19 23:44:50.000000000 +0200 @@ -48,11 +48,13 @@ { 0x46d, 0xc336, (uint16_t)KeyboardModel::g213 }, { 0x46d, 0xc330, (uint16_t)KeyboardModel::g410 }, { 0x46d, 0xc33a, (uint16_t)KeyboardModel::g413 }, + { 0x46d, 0xc342, (uint16_t)KeyboardModel::g512 }, { 0x46d, 0xc33c, (uint16_t)KeyboardModel::g513 }, { 0x46d, 0xc333, (uint16_t)KeyboardModel::g610 }, { 0x46d, 0xc338, (uint16_t)KeyboardModel::g610 }, { 0x46d, 0xc331, (uint16_t)KeyboardModel::g810 }, { 0x46d, 0xc337, (uint16_t)KeyboardModel::g810 }, + { 0x46d, 0xc33f, (uint16_t)KeyboardModel::g815 }, { 0x46d, 0xc32b, (uint16_t)KeyboardModel::g910 }, { 0x46d, 0xc335, (uint16_t)KeyboardModel::g910 }, { 0x46d, 0xc339, (uint16_t)KeyboardModel::gpro } @@ -63,9 +65,11 @@ g213, g410, g413, - g513, + g512, + g513, g610, g810, + g815, g910, gpro }; @@ -76,20 +80,28 @@ wave = 0x01, color }; + enum class OnBoardMode : uint8_t { + board = 0x01, + software + }; enum class NativeEffectGroup : uint8_t { - color = 0x01, + off, + color, breathing, cycle, - waves + waves, + ripple }; enum class NativeEffect : uint16_t { + off, color = static_cast<uint16_t>(NativeEffectGroup::color) << 8, breathing = static_cast<uint16_t>(NativeEffectGroup::breathing) << 8, cycle = static_cast<uint16_t>(NativeEffectGroup::cycle) << 8, waves = static_cast<uint16_t>(NativeEffectGroup::waves) << 8, hwave, vwave, - cwave + cwave, + ripple = static_cast<uint16_t>(NativeEffectGroup::ripple) << 8 }; enum class NativeEffectPart : uint8_t { all = 0xff, @@ -195,6 +207,7 @@ bool setRegion(uint8_t region, Color color); bool setStartupMode(StartupMode startupMode); + bool setOnBoardMode(OnBoardMode onBoardMode); bool setNativeEffect(NativeEffect effect, NativeEffectPart part, std::chrono::duration<uint16_t, std::milli> period, Color color, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/g810-led-0.3.9/src/helpers/help.cpp new/g810-led-0.4.2/src/helpers/help.cpp --- old/g810-led-0.3.9/src/helpers/help.cpp 2019-09-21 00:44:32.000000000 +0200 +++ new/g810-led-0.4.2/src/helpers/help.cpp 2020-05-19 23:44:50.000000000 +0200 @@ -32,9 +32,11 @@ if(cmdName == "g213-led") return KeyboardFeatures::g213; else if(cmdName == "g410-led") return KeyboardFeatures::g410; else if(cmdName == "g413-led") return KeyboardFeatures::g413; + else if(cmdName == "g512-led") return KeyboardFeatures::g512; else if(cmdName == "g513-led") return KeyboardFeatures::g513; else if(cmdName == "g610-led") return KeyboardFeatures::g610; else if(cmdName == "g810-led") return KeyboardFeatures::g810; + else if(cmdName == "g815-led") return KeyboardFeatures::g815; else if(cmdName == "g910-led") return KeyboardFeatures::g910; else if(cmdName == "gpro-led") return KeyboardFeatures::gpro; return KeyboardFeatures::all; @@ -89,6 +91,10 @@ cout<<" --startup-mode {startup mode}\t\tSet startup mode"<<endl; cout<<endl; } + if((features | KeyboardFeatures::onboardmode) == features) { + cout<<" --on-board-mode {on-board mode}\t\tSet on-board mode"<<endl; + cout<<endl; + } cout<<" --list-keyboards \t\t\tList connected keyboards"<<endl; cout<<" --print-device\t\t\tPrint device information for the keyboard"<<endl; cout<<endl; @@ -119,6 +125,7 @@ if((features | KeyboardFeatures::setgroup) == features) cout<<" group values :\t\t\tlogo, indicators, fkeys, ... (use --help-keys for more detail)"<<endl; cout<<" startup mode :\t\t\twave, color"<<endl; + cout<<" on-board mode :\t\t\tboard, software"<<endl; cout<<endl; } @@ -323,6 +330,9 @@ if((features | KeyboardFeatures::poweronfx) == features) cout<<cmdName<<" --startup-mode color # Set keyboard power on effect"<<endl; cout<<endl; + if((features | KeyboardFeatures::onboardmode) == features) + cout<<cmdName<<" --on-board-mode color # Set keyboard power on effect"<<endl; + cout<<endl; if((features | KeyboardFeatures::commit) == features) { cout<<"Samples with no commit :"<<endl; if((features | KeyboardFeatures::setall) == features) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/g810-led-0.3.9/src/helpers/help.h new/g810-led-0.4.2/src/helpers/help.h --- old/g810-led-0.3.9/src/helpers/help.h 2019-09-21 00:44:32.000000000 +0200 +++ new/g810-led-0.4.2/src/helpers/help.h 2020-05-19 23:44:50.000000000 +0200 @@ -39,17 +39,20 @@ poweronfx = 8192, // "user-stored lighting" can be recalled with backlight+7 on the G Pro userstoredlighting = 16384, + onboardmode = 32768, // fx features all = rgb | intensity | commit | logo1 | logo2 | numpad | multimedia | gkeys | - setall | setgroup | setkey | setregion | setindicators | poweronfx | userstoredlighting, + setall | setgroup | setkey | setregion | setindicators | poweronfx | userstoredlighting | onboardmode, g213 = rgb | logo1 | numpad | multimedia | setall | setregion | setindicators | poweronfx | userstoredlighting, g410 = rgb | commit | setall | setgroup | setkey | poweronfx | userstoredlighting, g413 = intensity | setall | userstoredlighting, + g512 = rgb | commit | numpad | setall | setgroup | setkey | setindicators | poweronfx | userstoredlighting, g513 = rgb | commit | numpad | setall | setgroup | setkey | setindicators | poweronfx | userstoredlighting, g610 = intensity | commit | logo1 | numpad | multimedia | setall | setgroup | setkey | setindicators | poweronfx | userstoredlighting, g810 = rgb | commit | logo1 | numpad | multimedia | setall | setgroup | setkey | setindicators | poweronfx, + g815 = rgb | commit | logo1 | numpad | multimedia | gkeys | setall | setgroup | setkey | setindicators | onboardmode, g910 = rgb | commit | logo1 | logo2 | numpad | multimedia | gkeys | setall | setgroup | setkey | setindicators | poweronfx | userstoredlighting, gpro = rgb | commit | logo1 | setall | setgroup | setkey | setindicators | poweronfx | userstoredlighting }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/g810-led-0.3.9/src/helpers/utils.cpp new/g810-led-0.4.2/src/helpers/utils.cpp --- old/g810-led-0.3.9/src/helpers/utils.cpp 2019-09-21 00:44:32.000000000 +0200 +++ new/g810-led-0.4.2/src/helpers/utils.cpp 2020-05-19 23:44:50.000000000 +0200 @@ -27,15 +27,22 @@ std::string getCmdName(std::string cmd) { return cmd.substr(cmd.find_last_of("/\\") + 1); } - - - + + + bool parseStartupMode(std::string val, LedKeyboard::StartupMode &startupMode) { if (val == "wave") startupMode = LedKeyboard::StartupMode::wave; else if (val == "color") startupMode = LedKeyboard::StartupMode::color; else return false; return true; } + + bool parseOnBoardMode(std::string val, LedKeyboard::OnBoardMode &onBoardMode) { + if (val == "software") onBoardMode = LedKeyboard::OnBoardMode ::software; + else if (val == "board") onBoardMode = LedKeyboard::OnBoardMode::board; + else return false; + return true; + } bool parseNativeEffect(std::string val, LedKeyboard::NativeEffect &nativeEffect) { if (val == "color") nativeEffect = LedKeyboard::NativeEffect::color; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/g810-led-0.3.9/src/helpers/utils.h new/g810-led-0.4.2/src/helpers/utils.h --- old/g810-led-0.3.9/src/helpers/utils.h 2019-09-21 00:44:32.000000000 +0200 +++ new/g810-led-0.4.2/src/helpers/utils.h 2020-05-19 23:44:50.000000000 +0200 @@ -24,8 +24,9 @@ namespace utils { std::string getCmdName(std::string cmd); - + bool parseStartupMode(std::string val, LedKeyboard::StartupMode &startupMode); + bool parseOnBoardMode(std::string val, LedKeyboard::OnBoardMode &onBoardMode); bool parseNativeEffect(std::string val, LedKeyboard::NativeEffect &nativeEffect); bool parseNativeEffectPart(std::string val, LedKeyboard::NativeEffectPart &nativeEffectPart); bool parseKey(std::string val, LedKeyboard::Key &key); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/g810-led-0.3.9/src/main.cpp new/g810-led-0.4.2/src/main.cpp --- old/g810-led-0.3.9/src/main.cpp 2019-09-21 00:44:32.000000000 +0200 +++ new/g810-led-0.4.2/src/main.cpp 2020-05-19 23:44:50.000000000 +0200 @@ -129,6 +129,9 @@ if (! utils::parseNativeEffectPart(arg3, effectPart)) return 1; switch (effect) { + case LedKeyboard::NativeEffect::off: + case LedKeyboard::NativeEffect::ripple: + break; case LedKeyboard::NativeEffect::color: if (! utils::parseColor(arg4, color)) return 1; break; @@ -171,6 +174,14 @@ return 1; } +int setOnBoardMode(LedKeyboard &kbd, std::string arg2) { + LedKeyboard::OnBoardMode onBoardMode; + if (! utils::parseOnBoardMode(arg2, onBoardMode)) return 1; + if (! kbd.open()) return 1; + if (kbd.setOnBoardMode(onBoardMode)) return 0; + return 1; +} + int parseProfile(LedKeyboard &kbd, std::istream &stream) { std::string line; @@ -217,6 +228,10 @@ if (setMNKey(kbd, args[1]) == 1) retval = 1; } else if (args[0] == "gkm" && args.size() > 1) { if (setGKeysMode(kbd, args[1]) == 1) retval = 1; + } else if (args[0] == "sm" && args.size() > 1) { + if (setStartupMode(kbd, args[1]) == 1) retval = 1; + } else if (args[0] == "obm" && args.size() > 1) { + if (setOnBoardMode(kbd, args[1]) == 1) retval = 1; } else if (args[0] == "fx" && args.size() > 4) { if (setFX(kbd, args[1], args[2], args[3], args[4]) == 1) retval = 1; } else if (args[0] == "fx" && args.size() > 3) { @@ -288,6 +303,9 @@ case 3: kbd.SupportedKeyboards = { { vendorID, productID, (uint16_t)LedKeyboard::KeyboardModel::g213 } }; break; + case 4: + kbd.SupportedKeyboards = { { vendorID, productID, (uint16_t)LedKeyboard::KeyboardModel::g815 } }; + break; default: break; } @@ -334,6 +352,7 @@ else if (argc > (argIndex + 3) && arg == "-fx-store") return storeFX(kbd, argv[argIndex + 1], argv[argIndex + 2], argv[argIndex + 3]); else if (argc > (argIndex + 1) && arg == "--startup-mode") return setStartupMode(kbd, argv[argIndex + 1]); + else if (argc > (argIndex + 1) && arg == "--on-board-mode") return setOnBoardMode(kbd, argv[argIndex + 1]); else { help::usage(argv[0]); return 1; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/g810-led-0.3.9/udev/g810-led.rules new/g810-led-0.4.2/udev/g810-led.rules --- old/g810-led-0.3.9/udev/g810-led.rules 2019-09-21 00:44:32.000000000 +0200 +++ new/g810-led-0.4.2/udev/g810-led.rules 2020-05-19 23:44:50.000000000 +0200 @@ -1,17 +1,20 @@ ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c336", MODE="666" RUN+="/usr/bin/g213-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c330", MODE="666" RUN+="/usr/bin/g410-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c33a", MODE="666" RUN+="/usr/bin/g413-led -p /etc/g810-led/profile" +ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c342", MODE="666" RUN+="/usr/bin/g512-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c33c", MODE="666" RUN+="/usr/bin/g513-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c333", MODE="666" RUN+="/usr/bin/g610-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c338", MODE="666" RUN+="/usr/bin/g610-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c331", MODE="666" RUN+="/usr/bin/g810-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c337", MODE="666" RUN+="/usr/bin/g810-led -p /etc/g810-led/profile" +ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c33f", MODE="666" RUN+="/usr/bin/g815-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c32b", MODE="666" RUN+="/usr/bin/g910-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c335", MODE="666" RUN+="/usr/bin/g910-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c339", MODE="666" RUN+="/usr/bin/gpro-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c336", MODE="666" RUN+="/usr/bin/g213-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c330", MODE="666" RUN+="/usr/bin/g410-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c33a", MODE="666" RUN+="/usr/bin/g413-led -p /etc/g810-led/profile" +ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c342", MODE="666" RUN+="/usr/bin/g512-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c33c", MODE="666" RUN+="/usr/bin/g513-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c333", MODE="666" RUN+="/usr/bin/g610-led -p /etc/g810-led/profile" ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c338", MODE="666" RUN+="/usr/bin/g610-led -p /etc/g810-led/profile"
