From c2c8f6b7ac89ebaf3710f4b53afa7969f2f468d6 Mon Sep 17 00:00:00 2001 From: MatMoul Date: Sat, 21 Jan 2017 09:15:18 +0100 Subject: [PATCH] Full refactor code --- .gitignore | 3 + INSTALL.md | 6 +- README.md | 14 +- makefile | 13 +- pictures/g410.png | Bin 59630 -> 0 bytes pictures/g610.png | Bin 57634 -> 0 bytes pictures/g810.jpg | Bin 43215 -> 0 bytes pictures/g910.jpg | Bin 21755 -> 0 bytes sample_profiles/all_blue_fxl_breathing_red | 2 +- sample_profiles/fx_breathing_red | 2 +- sample_profiles/fx_color_green | 2 +- sample_profiles/fx_cwave | 2 +- sample_profiles/fx_cycle | 2 + sample_profiles/fx_hwave | 2 +- sample_profiles/fx_vwave | 2 +- src/classes/Keyboard.cpp | 1441 ++++++-------------- src/classes/Keyboard.h | 238 +++- src/helpers/help.cpp | 187 +++ src/helpers/help.h | 15 + src/helpers/utils.cpp | 212 +++ src/helpers/utils.h | 21 + src/main.cpp | 687 +++------- 22 files changed, 1254 insertions(+), 1597 deletions(-) create mode 100644 .gitignore delete mode 100644 pictures/g410.png delete mode 100644 pictures/g610.png delete mode 100644 pictures/g810.jpg delete mode 100644 pictures/g910.jpg create mode 100644 sample_profiles/fx_cycle create mode 100644 src/helpers/help.cpp create mode 100644 src/helpers/help.h create mode 100644 src/helpers/utils.cpp create mode 100644 src/helpers/utils.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e31e806 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +g810-led.* +bin/* +. diff --git a/INSTALL.md b/INSTALL.md index e098e84..21bfb55 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -14,10 +14,8 @@ ArchLinux :
`sudo pacman -S git gcc make libusb`
Debian :
`sudo apt-get install git g++ make libusb-1.0-0-dev`
-OpenSUSE :
-`sudo zypper in git make gcc-c++ libstdc++-devel libusb-1_0-devel`
-CentOS :
-`sudo yum install git make gcc-c++ libstdc++-devel libusb-devel`
+Fedora :
+`sudo dnf install git make gcc-c++ libusb-devel`
## Installation :
`git clone https://github.com/MatMoul/g810-led.git`
diff --git a/README.md b/README.md index 3b196cc..fdea43b 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Linux LED controller for Logitech Led Keyboards.
- **G910 Orion Spectrum**
##Install and use :
-* https://github.com/MatMoul/g810-led/blob/master/INSTALL.md +* INSTALL.md ##Help :
`g410-led --help`
@@ -25,12 +25,12 @@ Linux LED controller for Logitech Led Keyboards.
`g810-led -a 00ff00 # Set color of all keys`
`g810-led -g fkeys ff00ff # Set color of a group of keys`
`g810-led -s color # Set keyboard power on effect`
-`g810-led -fx-color 00ff00 # Set fixed color effect`
-`g810-led -fx-breathing 00ff00 0a # Set breathing effect`
-`g810-led -fx-cycle 0a # Set color cycle effect`
-`g810-led -fx-hwave 0a # Set horizontal wave effect`
-`g810-led -fx-vwave 0a # Set vertical wave effect`
-`g810-led -fx-cwave 0a # Set center wave effect`
+`g810-led -fx color keys 00ff00 # Set fixed color effect`
+`g810-led -fx breathing logo 00ff00 0a # Set breathing effect`
+`g810-led -fx cycle all 0a # Set color cycle effect`
+`g810-led -fx hwave keys 0a # Set horizontal wave effect`
+`g810-led -fx vwave keys 0a # Set vertical wave effect`
+`g810-led -fx cwave keys 0a # Set center wave effect`
##Samples with no commit :
`g810-led -an 000000 # Set color of all key with no action`
diff --git a/makefile b/makefile index f393534..917f0bc 100644 --- a/makefile +++ b/makefile @@ -1,24 +1,23 @@ CC=g++ CFLAGS=-Wall -O2 -std=gnu++11 -LIBUSB_INC?=-I/usr/include/libusb-1.0 LDFLAGS=-lusb-1.0 PROGN=g810-led SYSTEMDDIR?=/usr/lib/systemd -.PHONY: all debug clean install uninstall +.PHONY: all debug clean all: bin/$(PROGN) -bin/$(PROGN): src/main.cpp src/classes/*.cpp src/classes/*.h +bin/$(PROGN): src/main.cpp src/helpers/*.cpp src/helpers/*.h src/classes/*.cpp src/classes/*.h @mkdir -p bin - $(CC) $(CFLAGS) $(LIBUSB_INC) -o $@ $^ $(LDFLAGS) - + $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) + debug: CFLAGS += -g -Wextra -pedantic debug: bin/$(PROGN) - + clean: @rm -rf bin - + install: @install -m 755 -d \ $(DESTDIR)/etc/$(PROGN)/samples \ diff --git a/pictures/g410.png b/pictures/g410.png deleted file mode 100644 index 6032224d1f62d29344cb46c027a825f9c80cd8a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59630 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�BFhD3>=O^qlFgRN!5V@C3*BNc9HsM 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≪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 diff --git a/sample_profiles/all_blue_fxl_breathing_red b/sample_profiles/all_blue_fxl_breathing_red index 0898d67..8e8ccf4 100644 --- a/sample_profiles/all_blue_fxl_breathing_red +++ b/sample_profiles/all_blue_fxl_breathing_red @@ -2,4 +2,4 @@ a 0000ff # Set all keys blue c # Commit changes -fxl-breathing ff0000 10 # Set breathing effect with red color and speed 10 +fx breathing logo ff0000 10 # Set breathing effect with red color and speed 10 diff --git a/sample_profiles/fx_breathing_red b/sample_profiles/fx_breathing_red index 1b0be0b..250349c 100644 --- a/sample_profiles/fx_breathing_red +++ b/sample_profiles/fx_breathing_red @@ -1,2 +1,2 @@ -fx-breathing ff0000 10 # Set breathing effect with red color and speed 10 +fx breathing all ff0000 20 # Set breathing effect with red color and speed 20 diff --git a/sample_profiles/fx_color_green b/sample_profiles/fx_color_green index 05f8232..97264a7 100644 --- a/sample_profiles/fx_color_green +++ b/sample_profiles/fx_color_green @@ -1,3 +1,3 @@ # Green Profile -fx-color 00ff00 # Set all keys green +fx color all 00ff00 # Set all keys green diff --git a/sample_profiles/fx_cwave b/sample_profiles/fx_cwave index 3405986..347a1bc 100644 --- a/sample_profiles/fx_cwave +++ b/sample_profiles/fx_cwave @@ -1,2 +1,2 @@ -fx-cwave 10 # Set center wave effect with speed 10 +fx cwave all 20 # Set center wave effect with speed 20 diff --git a/sample_profiles/fx_cycle b/sample_profiles/fx_cycle new file mode 100644 index 0000000..249adcb --- /dev/null +++ b/sample_profiles/fx_cycle @@ -0,0 +1,2 @@ + +fx cycle all 20 # Set color cycle effect with speed 20 diff --git a/sample_profiles/fx_hwave b/sample_profiles/fx_hwave index 5eb537c..cea0f8a 100644 --- a/sample_profiles/fx_hwave +++ b/sample_profiles/fx_hwave @@ -1,2 +1,2 @@ -fx-hwave 10 # Set horizontal wave effect with speed 10 +fx hwave all 20 # Set horizontal wave effect with speed 20 diff --git a/sample_profiles/fx_vwave b/sample_profiles/fx_vwave index 30ea410..a52aca2 100644 --- a/sample_profiles/fx_vwave +++ b/sample_profiles/fx_vwave @@ -1,2 +1,2 @@ -fx-vwave 10 # Set vertical wave effect with speed 10 +fx vwave all 20 # Set vertical wave effect with speed 20 diff --git a/src/classes/Keyboard.cpp b/src/classes/Keyboard.cpp index b52636c..1a37ca1 100644 --- a/src/classes/Keyboard.cpp +++ b/src/classes/Keyboard.cpp @@ -1,1101 +1,490 @@ #include "Keyboard.h" -#include + +#include #include -#include -#include "libusb.h" +#include + +#include "libusb-1.0/libusb.h" -bool Keyboard::isAttached() { - return m_isAttached; +using namespace std; + + + +LedKeyboard::~LedKeyboard() { + close(); } -bool Keyboard::attach() { - if (m_isAttached == true) return false; - int r; - r = libusb_init(&ctx); - if (r < 0) return false; + +bool LedKeyboard::listKeyboards() { + libusb_context *ctx = NULL; + if(libusb_init(&m_ctx) < 0) return false; libusb_device **devs; ssize_t cnt = libusb_get_device_list(ctx, &devs); - if(cnt < 0) return false; - int pid = 0; - for(ssize_t i = 0; i < cnt; i++) { - libusb_device *device = devs[i]; - libusb_device_descriptor desc = { - 0, // bLength - 0, // bDescriptorType - 0, // bcdUSB - 0, // bDeviceClass - 0, // bDeviceSubClass - 0, // bDeviceProtocol - 0, // bMaxPacketSize0 - 0, // idVendor - 0, // idProduct - 0, // bcdDevice - 0, // iManufacturer - 0, // iProduct - 0, // iSerialNumber - 0 // bNumConfigurations - }; - libusb_get_device_descriptor(device, &desc); - if (desc.idVendor == 0x046d) { - if (desc.idProduct == 0xc331) { pid = desc.idProduct; break; } // G810 spectrum - if (desc.idProduct == 0xc337) { pid = desc.idProduct; break; } // G810 spectrum - if (desc.idProduct == 0xc330) { pid = desc.idProduct; break; } // G410 spectrum - if (desc.idProduct == 0xc333) { pid = desc.idProduct; break; } // G610 spectrum - if (desc.idProduct == 0xc338) { pid = desc.idProduct; break; } // G610 spectrum - if (desc.idProduct == 0xc32b) { // G910 spark - pid = desc.idProduct; - kbdProtocol = KeyboardProtocol::g910; - break; - } - if (desc.idProduct == 0xc335) { // G910 spectrum - pid = desc.idProduct; - kbdProtocol = KeyboardProtocol::g910; - break; + if(cnt >= 0) { + for(ssize_t i = 0; i < cnt; i++) { + libusb_device *device = devs[i]; + libusb_device_descriptor desc = { + 0, // bLength + 0, // bDescriptorType + 0, // bcdUSB + 0, // bDeviceClass + 0, // bDeviceSubClass + 0, // bDeviceProtocol + 0, // bMaxPacketSize0 + 0, // idVendor + 0, // idProduct + 0, // bcdDevice + 0, // iManufacturer + 0, // iProduct + 0, // iSerialNumber + 0 // bNumConfigurations + }; + libusb_get_device_descriptor(device, &desc); + for (int i=0; i<(int)SuportedKeyboards.size(); i++) { + if (desc.idVendor == SuportedKeyboards[i][0]) { + if (desc.idProduct == SuportedKeyboards[i][1]) { + cout<<"0x"<= 0) { + for(ssize_t i = 0; i < cnt; i++) { + libusb_device *device = devs[i]; + libusb_device_descriptor desc = { + 0, // bLength + 0, // bDescriptorType + 0, // bcdUSB + 0, // bDeviceClass + 0, // bDeviceSubClass + 0, // bDeviceProtocol + 0, // bMaxPacketSize0 + 0, // idVendor + 0, // idProduct + 0, // bcdDevice + 0, // iManufacturer + 0, // iProduct + 0, // iSerialNumber + 0 // bNumConfigurations + }; + libusb_get_device_descriptor(device, &desc); + for (int i=0; i<(int)SuportedKeyboards.size(); i++) { + if (desc.idVendor == SuportedKeyboards[i][0]) { + if (desc.idProduct == SuportedKeyboards[i][1]) { + m_vendorID = desc.idVendor; + m_productID = desc.idProduct; + m_keyboardModel = (KeyboardModel)SuportedKeyboards[i][2]; + break; + } + } + } + + if (m_keyboardModel != KeyboardModel::unknown) break; + + } + libusb_free_device_list(devs, 1); + } } - libusb_free_device_list(devs, 1); - if (pid == 0) { - libusb_exit(ctx); - ctx = NULL; + + if (m_keyboardModel == KeyboardModel::unknown) { + cout<<"Keyboard not found"<> SortedKeys = { + {}, // Logo AddressGroup + {}, // Indicators AddressGroup + {}, // Multimedia AddressGroup + {}, // GKeys AddressGroup + {} // Keys AddressGroup + }; + + for (uint8_t i = 0; i < keyValues.size(); i++) { + switch(static_cast(static_cast(keyValues[i].key) >> 8 )) { + case LedKeyboard::KeyAddressGroup::logo: + if (SortedKeys[0].size() <= 2) SortedKeys[0].push_back(keyValues[i]); + break; + case LedKeyboard::KeyAddressGroup::indicators: + if (SortedKeys[1].size() <= 5) SortedKeys[1].push_back(keyValues[i]); + break; + case LedKeyboard::KeyAddressGroup::multimedia: + if (SortedKeys[2].size() <= 5) SortedKeys[2].push_back(keyValues[i]); + break; + case LedKeyboard::KeyAddressGroup::gkeys: + if (SortedKeys[3].size() <= 9) SortedKeys[3].push_back(keyValues[i]); + break; + case LedKeyboard::KeyAddressGroup::keys: + if (SortedKeys[4].size() <= 120) SortedKeys[4].push_back(keyValues[i]); + 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; + 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( + static_cast(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; + } + + } + } return retval; } -bool Keyboard::getKeyAddress(Key key, KeyAddress &keyAddress) { - switch (key) { - case Key::logo: - keyAddress.addressGroup = KeyAddressGroup::logo; - keyAddress.id = 0x01; +bool LedKeyboard::setGroupKeys(KeyGroup keyGroup, LedKeyboard::Color color) { + KeyValueArray keyValues; + + KeyArray keyArray; + + switch (keyGroup) { + case KeyGroup::logo: + keyArray = keyGroupLogo; break; - case Key::logo2: - keyAddress.addressGroup = KeyAddressGroup::logo; - keyAddress.id = 0x02; + case KeyGroup::indicators: + keyArray = keyGroupIndicators; break; - case Key::backlight: - keyAddress.addressGroup = KeyAddressGroup::indicators; - keyAddress.id = 0x01; + case KeyGroup::gkeys: + keyArray = keyGroupGKeys; break; - case Key::game: - keyAddress.addressGroup = KeyAddressGroup::indicators; - keyAddress.id = 0x02; + case KeyGroup::multimedia: + keyArray = keyGroupMultimedia; break; - case Key::caps: - keyAddress.addressGroup = KeyAddressGroup::indicators; - keyAddress.id = 0x03; + case KeyGroup::fkeys: + keyArray = keyGroupFKeys; break; - case Key::scroll: - keyAddress.addressGroup = KeyAddressGroup::indicators; - keyAddress.id = 0x04; + case KeyGroup::modifiers: + keyArray = keyGroupModifiers; break; - case Key::num: - keyAddress.addressGroup = KeyAddressGroup::indicators; - keyAddress.id = 0x05; + case KeyGroup::arrows: + keyArray = keyGroupArrows; break; - case Key::next: - keyAddress.addressGroup = KeyAddressGroup::multimedia; - keyAddress.id = 0xb5; + case KeyGroup::numeric: + keyArray = keyGroupNumeric; break; - case Key::prev: - keyAddress.addressGroup = KeyAddressGroup::multimedia; - keyAddress.id = 0xb6; + case KeyGroup::functions: + keyArray = keyGroupFunctions; break; - case Key::stop: - keyAddress.addressGroup = KeyAddressGroup::multimedia; - keyAddress.id = 0xb7; - break; - case Key::play: - keyAddress.addressGroup = KeyAddressGroup::multimedia; - keyAddress.id = 0xcd; - break; - case Key::mute: - keyAddress.addressGroup = KeyAddressGroup::multimedia; - keyAddress.id = 0xe2; - break; - case Key::g1: - keyAddress.addressGroup = KeyAddressGroup::gkeys; - keyAddress.id = 0x01; - break; - case Key::g2: - keyAddress.addressGroup = KeyAddressGroup::gkeys; - keyAddress.id = 0x02; - break; - case Key::g3: - keyAddress.addressGroup = KeyAddressGroup::gkeys; - keyAddress.id = 0x03; - break; - case Key::g4: - keyAddress.addressGroup = KeyAddressGroup::gkeys; - keyAddress.id = 0x04; - break; - case Key::g5: - keyAddress.addressGroup = KeyAddressGroup::gkeys; - keyAddress.id = 0x05; - break; - case Key::g6: - keyAddress.addressGroup = KeyAddressGroup::gkeys; - keyAddress.id = 0x06; - break; - case Key::g7: - keyAddress.addressGroup = KeyAddressGroup::gkeys; - keyAddress.id = 0x07; - break; - case Key::g8: - keyAddress.addressGroup = KeyAddressGroup::gkeys; - keyAddress.id = 0x08; - break; - case Key::g9: - keyAddress.addressGroup = KeyAddressGroup::gkeys; - keyAddress.id = 0x09; + case KeyGroup::keys: + keyArray = keyGroupKeys; break; default: - keyAddress.addressGroup = KeyAddressGroup::keys; - switch (key) { - case Key::a: keyAddress.id = 0x04; break; - case Key::b: keyAddress.id = 0x05; break; - case Key::c: keyAddress.id = 0x06; break; - case Key::d: keyAddress.id = 0x07; break; - case Key::e: keyAddress.id = 0x08; break; - case Key::f: keyAddress.id = 0x09; break; - case Key::g: keyAddress.id = 0x0a; break; - case Key::h: keyAddress.id = 0x0b; break; - case Key::i: keyAddress.id = 0x0c; break; - case Key::j: keyAddress.id = 0x0d; break; - case Key::k: keyAddress.id = 0x0e; break; - case Key::l: keyAddress.id = 0x0f; break; - case Key::m: keyAddress.id = 0x10; break; - case Key::n: keyAddress.id = 0x11; break; - case Key::o: keyAddress.id = 0x12; break; - case Key::p: keyAddress.id = 0x13; break; - case Key::q: keyAddress.id = 0x14; break; - case Key::r: keyAddress.id = 0x15; break; - case Key::s: keyAddress.id = 0x16; break; - case Key::t: keyAddress.id = 0x17; break; - case Key::u: keyAddress.id = 0x18; break; - case Key::v: keyAddress.id = 0x19; break; - case Key::w: keyAddress.id = 0x1a; break; - case Key::x: keyAddress.id = 0x1b; break; - case Key::y: keyAddress.id = 0x1c; break; - case Key::z: keyAddress.id = 0x1d; break; - case Key::n1: keyAddress.id = 0x1e; break; - case Key::n2: keyAddress.id = 0x1f; break; - case Key::n3: keyAddress.id = 0x20; break; - case Key::n4: keyAddress.id = 0x21; break; - case Key::n5: keyAddress.id = 0x22; break; - case Key::n6: keyAddress.id = 0x23; break; - case Key::n7: keyAddress.id = 0x24; break; - case Key::n8: keyAddress.id = 0x25; break; - case Key::n9: keyAddress.id = 0x26; break; - case Key::n0: keyAddress.id = 0x27; break; - case Key::enter: keyAddress.id = 0x28; break; - case Key::esc: keyAddress.id = 0x29; break; - case Key::backspace: keyAddress.id = 0x2a; break; - case Key::tab: keyAddress.id = 0x2b; break; - case Key::space: keyAddress.id = 0x2c; break; - case Key::minus: keyAddress.id = 0x2d; break; - case Key::equal: keyAddress.id = 0x2e; break; - case Key::open_bracket: keyAddress.id = 0x2f; break; - case Key::close_bracket: keyAddress.id = 0x30; break; - case Key::backslash: keyAddress.id = 0x31; break; - case Key::dollar: keyAddress.id = 0x32; break; - case Key::semicolon: keyAddress.id = 0x33; break; - case Key::quote: keyAddress.id = 0x34; break; - case Key::tilde: keyAddress.id = 0x35; break; - case Key::comma: keyAddress.id = 0x36; break; - case Key::period: keyAddress.id = 0x37; break; - case Key::slash: keyAddress.id = 0x38; break; - case Key::caps_lock: keyAddress.id = 0x39; break; - case Key::f1: keyAddress.id = 0x3a; break; - case Key::f2: keyAddress.id = 0x3b; break; - case Key::f3: keyAddress.id = 0x3c; break; - case Key::f4: keyAddress.id = 0x3d; break; - case Key::f5: keyAddress.id = 0x3e; break; - case Key::f6: keyAddress.id = 0x3f; break; - case Key::f7: keyAddress.id = 0x40; break; - case Key::f8: keyAddress.id = 0x41; break; - case Key::f9: keyAddress.id = 0x42; break; - case Key::f10: keyAddress.id = 0x43; break; - case Key::f11: keyAddress.id = 0x44; break; - case Key::f12: keyAddress.id = 0x45; break; - case Key::print_screen: keyAddress.id = 0x46; break; - case Key::scroll_lock: keyAddress.id = 0x47; break; - case Key::pause_break: keyAddress.id = 0x48; break; - case Key::insert: keyAddress.id = 0x49; break; - case Key::home: keyAddress.id = 0x4a; break; - case Key::page_up: keyAddress.id = 0x4b; break; - case Key::del: keyAddress.id = 0x4c; break; - case Key::end: keyAddress.id = 0x4d; break; - case Key::page_down: keyAddress.id = 0x4e; break; - case Key::arrow_right: keyAddress.id = 0x4f; break; - case Key::arrow_left: keyAddress.id = 0x50; break; - case Key::arrow_bottom: keyAddress.id = 0x51; break; - case Key::arrow_top: keyAddress.id = 0x52; break; - case Key::num_lock: keyAddress.id = 0x53; break; - case Key::num_slash: keyAddress.id = 0x54; break; - case Key::num_asterisk: keyAddress.id = 0x55; break; - case Key::num_minus: keyAddress.id = 0x56; break; - case Key::num_plus: keyAddress.id = 0x57; break; - case Key::num_enter: keyAddress.id = 0x58; break; - case Key::num_1: keyAddress.id = 0x59; break; - case Key::num_2: keyAddress.id = 0x5a; break; - case Key::num_3: keyAddress.id = 0x5b; break; - case Key::num_4: keyAddress.id = 0x5c; break; - case Key::num_5: keyAddress.id = 0x5d; break; - case Key::num_6: keyAddress.id = 0x5e; break; - case Key::num_7: keyAddress.id = 0x5f; break; - case Key::num_8: keyAddress.id = 0x60; break; - case Key::num_9: keyAddress.id = 0x61; break; - case Key::num_0: keyAddress.id = 0x62; break; - case Key::num_dot: keyAddress.id = 0x63; break; - case Key::intl_backslash: keyAddress.id = 0x64; break; - case Key::menu: keyAddress.id = 0x65; break; - case Key::ctrl_left: keyAddress.id = 0xe0; break; - case Key::shift_left: keyAddress.id = 0xe1; break; - case Key::alt_left: keyAddress.id = 0xe2; break; - case Key::win_left: keyAddress.id = 0xe3; break; - case Key::ctrl_right: keyAddress.id = 0xe4; break; - case Key::shift_right: keyAddress.id = 0xe5; break; - case Key::alt_right: keyAddress.id = 0xe6; break; - case Key::win_right: keyAddress.id = 0xe7; break; - default: break; - } break; } - return true; + + for (uint8_t i = 0; i < keyArray.size(); i++) keyValues.push_back({keyArray[i], color}); + + return setKeys(keyValues); } -bool Keyboard::parsePowerOnEffect(std::string effect, PowerOnEffect &powerOnEffect) { - if (effect == "rainbow") powerOnEffect = PowerOnEffect::rainbow; - else if (effect == "color") powerOnEffect = PowerOnEffect::color; - else return false; - return true; +bool LedKeyboard::setAllKeys(LedKeyboard::Color color) { + KeyValueArray keyValues; + for (uint8_t i = 0; i < keyGroupLogo.size(); i++) keyValues.push_back({keyGroupLogo[i], color}); + for (uint8_t i = 0; i < keyGroupIndicators.size(); i++) keyValues.push_back({keyGroupIndicators[i], color}); + for (uint8_t i = 0; i < keyGroupMultimedia.size(); i++) keyValues.push_back({keyGroupMultimedia[i], color}); + for (uint8_t i = 0; i < keyGroupGKeys.size(); i++) keyValues.push_back({keyGroupGKeys[i], color}); + for (uint8_t i = 0; i < keyGroupFKeys.size(); i++) keyValues.push_back({keyGroupFKeys[i], color}); + for (uint8_t i = 0; i < keyGroupFunctions.size(); i++) keyValues.push_back({keyGroupFunctions[i], color}); + for (uint8_t i = 0; i < keyGroupArrows.size(); i++) keyValues.push_back({keyGroupArrows[i], color}); + for (uint8_t i = 0; i < keyGroupNumeric.size(); i++) keyValues.push_back({keyGroupNumeric[i], color}); + for (uint8_t i = 0; i < keyGroupModifiers.size(); i++) keyValues.push_back({keyGroupModifiers[i], color}); + for (uint8_t i = 0; i < keyGroupKeys.size(); i++) keyValues.push_back({keyGroupKeys[i], color}); + return setKeys(keyValues); } -bool Keyboard::parseKey(std::string key, KeyAddress &keyAddress) { - std::transform(key.begin(), key.end(), key.begin(), ::tolower); - Key parsedKey; - if (key == "logo") parsedKey = Key::logo; - else if (key == "logo2") parsedKey = Key::logo2; - else if (key == "back_light" || key == "backlight" || key == "light") parsedKey = Key::backlight; - else if (key == "game_mode" || key == "gamemode" || key == "game") parsedKey = Key::game; - else if (key == "caps_indicator" || key == "capsindicator" || key == "caps") parsedKey = Key::caps; - else if (key == "scroll_indicator" || key == "scrollindicator" || key == "scroll") parsedKey = Key::scroll; - else if (key == "num_indicator" || key == "numindicator" || key == "num") parsedKey = Key::num; - else if (key == "next") parsedKey = Key::next; - else if (key == "prev" || key == "previous") parsedKey = Key::prev; - else if (key == "stop") parsedKey = Key::stop; - else if (key == "play_pause" || key == "playpause" || key == "play") parsedKey = Key::play; - else if (key == "mute") parsedKey = Key::mute; - else if (key == "a") parsedKey = Key::a; - else if (key == "b") parsedKey = Key::b; - else if (key == "c") parsedKey = Key::c; - else if (key == "d") parsedKey = Key::d; - else if (key == "e") parsedKey = Key::e; - else if (key == "f") parsedKey = Key::f; - else if (key == "g") parsedKey = Key::g; - else if (key == "h") parsedKey = Key::h; - else if (key == "i") parsedKey = Key::i; - else if (key == "j") parsedKey = Key::j; - else if (key == "k") parsedKey = Key::k; - else if (key == "l") parsedKey = Key::l; - else if (key == "m") parsedKey = Key::m; - else if (key == "n") parsedKey = Key::n; - else if (key == "o") parsedKey = Key::o; - else if (key == "p") parsedKey = Key::p; - else if (key == "q") parsedKey = Key::q; - else if (key == "r") parsedKey = Key::r; - else if (key == "s") parsedKey = Key::s; - else if (key == "t") parsedKey = Key::t; - else if (key == "u") parsedKey = Key::u; - else if (key == "v") parsedKey = Key::v; - else if (key == "w") parsedKey = Key::w; - else if (key == "x") parsedKey = Key::x; - else if (key == "z") parsedKey = Key::z; - else if (key == "y") parsedKey = Key::y; - else if (key == "1" || key == "one") parsedKey = Key::n1; - else if (key == "2" || key == "two") parsedKey = Key::n2; - else if (key == "3" || key == "three") parsedKey = Key::n3; - else if (key == "4" || key == "four") parsedKey = Key::n4; - else if (key == "5" || key == "five") parsedKey = Key::n5; - else if (key == "6" || key == "six") parsedKey = Key::n6; - else if (key == "7" || key == "seven") parsedKey = Key::n7; - else if (key == "8" || key == "eight") parsedKey = Key::n8; - else if (key == "9" || key == "nine") parsedKey = Key::n9; - else if (key == "0" || key == "zero") parsedKey = Key::n0; - else if (key == "enter") parsedKey = Key::enter; - else if (key == "esc" || key == "escape") parsedKey = Key::esc; - else if (key == "back" || key == "backspace") parsedKey = Key::backspace; - else if (key == "tab") parsedKey = Key::tab; - else if (key == "space") parsedKey = Key::space; - else if (key == "tilde" || key == "~") parsedKey = Key::tilde; - else if (key == "minus" || key == "-") parsedKey = Key::minus; - else if (key == "equal" || key == "=") parsedKey = Key::equal; - else if (key == "open_bracket" || key == "[") parsedKey = Key::open_bracket; - else if (key == "close_bracket" || key == "]") parsedKey = Key::close_bracket; - else if (key == "backslash" || key == "\\") parsedKey = Key::backslash; - else if (key == "semicolon" || key == ";") parsedKey = Key::semicolon; - else if (key == "quote" || key == "\"") parsedKey = Key::quote; - else if (key == "dollar" || key == "$") parsedKey = Key::dollar; - else if (key == "comma" || key == ",") parsedKey = Key::comma; - else if (key == "period" || key == ".") parsedKey = Key::period; - else if (key == "slash" || key == "/") parsedKey = Key::slash; - else if (key == "caps_lock" || key == "capslock") parsedKey = Key::caps_lock; - else if (key == "f1") parsedKey = Key::f1; - else if (key == "f2") parsedKey = Key::f2; - else if (key == "f3") parsedKey = Key::f3; - else if (key == "f4") parsedKey = Key::f4; - else if (key == "f5") parsedKey = Key::f5; - else if (key == "f6") parsedKey = Key::f6; - else if (key == "f7") parsedKey = Key::f7; - else if (key == "f8") parsedKey = Key::f8; - else if (key == "f9") parsedKey = Key::f9; - else if (key == "f10") parsedKey = Key::f10; - else if (key == "f11") parsedKey = Key::f11; - else if (key == "f12") parsedKey = Key::f12; - else if (key == "print_screen" || key == "printscreen" || key == "printscr" || key == "print") parsedKey = Key::print_screen; - else if (key == "scroll_lock" || key == "scrolllock") parsedKey = Key::scroll_lock; - else if (key == "pause_break" || key == "pausebreak" || key == "pause" || key == "break") parsedKey = Key::pause_break; - else if (key == "insert" || key == "ins") parsedKey = Key::insert; - else if (key == "home") parsedKey = Key::home; - else if (key == "page_up" || key == "pageup") parsedKey = Key::page_up; - else if (key == "delete" || key == "del") parsedKey = Key::del; - else if (key == "end") parsedKey = Key::end; - else if (key == "page_down" || key == "pagedown") parsedKey = Key::page_down; - else if (key == "arrow_right" || key == "arrowright" || key == "right") parsedKey = Key::arrow_right; - else if (key == "arrow_left" || key == "arrowleft" || key == "left") parsedKey = Key::arrow_left; - else if (key == "arrow_bottom" || key == "arrowbottom" || key == "bottom") parsedKey = Key::arrow_bottom; - else if (key == "arrow_top" || key == "arrowtop" || key == "top") parsedKey = Key::arrow_top; - else if (key == "num_lock" || key == "numlock") parsedKey = Key::num_lock; - else if (key == "num/" || key == "num_slash" || key == "numslash") parsedKey = Key::num_slash; - else if (key == "num*" || key == "num_asterisk" || key == "numasterisk") parsedKey = Key::num_asterisk; - else if (key == "num-" || key == "num_minus" || key == "numminus") parsedKey = Key::num_minus; - else if (key == "num+" || key == "num_plus" || key == "numplus") parsedKey = Key::num_plus; - else if (key == "numenter") parsedKey = Key::num_enter; - else if (key == "num1") parsedKey = Key::num_1; - else if (key == "num2") parsedKey = Key::num_2; - else if (key == "num3") parsedKey = Key::num_3; - else if (key == "num4") parsedKey = Key::num_4; - else if (key == "num5") parsedKey = Key::num_5; - else if (key == "num6") parsedKey = Key::num_6; - else if (key == "num7") parsedKey = Key::num_7; - else if (key == "num8") parsedKey = Key::num_8; - else if (key == "num9") parsedKey = Key::num_9; - else if (key == "num0") parsedKey = Key::num_0; - else if (key == "num." || key == "num_period" || key == "numperiod") parsedKey = Key::num_dot; - else if (key == "intl_backslash" || key == "<") parsedKey = Key::intl_backslash; - else if (key == "menu") parsedKey = Key::menu; - else if (key == "ctrl_left" || key == "ctrlleft" || key == "ctrll") parsedKey = Key::ctrl_left; - else if (key == "shift_left" || key == "shiftleft" || key == "shiftl") parsedKey = Key::shift_left; - else if (key == "alt_left" || key == "altleft" || key == "altl") parsedKey = Key::alt_left; - else if (key == "win_left" || key == "winleft" || key == "winl") parsedKey = Key::win_left; - else if (key == "meta_left" || key == "metaleft" || key == "metal") parsedKey = Key::win_left; - else if (key == "ctrl_right" || key == "ctrlright" || key == "ctrlr") parsedKey = Key::ctrl_right; - else if (key == "shift_right" || key == "shiftright" || key == "shiftr") parsedKey = Key::shift_right; - else if (key == "alt_right" || key == "altright" || key == "altr" || key == "altgr") parsedKey = Key::alt_right; - else if (key == "win_right" || key == "winright" || key == "winr") parsedKey = Key::win_right; - else if (key == "meta_right" || key == "metaright" || key == "metar") parsedKey = Key::win_right; - else if (key == "g1") parsedKey = Key::g1; - else if (key == "g2") parsedKey = Key::g2; - else if (key == "g3") parsedKey = Key::g3; - else if (key == "g4") parsedKey = Key::g4; - else if (key == "g5") parsedKey = Key::g5; - else if (key == "g6") parsedKey = Key::g6; - else if (key == "g7") parsedKey = Key::g7; - else if (key == "g8") parsedKey = Key::g8; - else if (key == "g9") parsedKey = Key::g9; - else return false; - return getKeyAddress(parsedKey, keyAddress); + +bool LedKeyboard::setStartupMode(StartupMode startupMode) { + byte_buffer_t data; + switch (m_keyboardModel) { + case KeyboardModel::g410: + case KeyboardModel::g610: + case KeyboardModel::g810: + data = { 0x11, 0xff, 0x0d, 0x5a, 0x00, 0x01 }; + break; + case KeyboardModel::g910: + data = { 0x11, 0xff, 0x10, 0x5e, 0x00, 0x01 }; + break; + default: + return false; + } + data.push_back((unsigned char)startupMode); + data.resize(20, 0x00); + return sendDataInternal(data); } -bool Keyboard::parseKeyGroup(std::string key, KeyGroup &keyGroup) { - if (key == "logo") keyGroup = KeyGroup::logo; - else if (key == "indicators") keyGroup = KeyGroup::indicators; - else if (key == "multimedia") keyGroup = KeyGroup::multimedia; - else if (key == "fkeys") keyGroup = KeyGroup::fkeys; - else if (key == "modifiers") keyGroup = KeyGroup::modifiers; - else if (key == "arrows") keyGroup = KeyGroup::arrows; - else if (key == "numeric") keyGroup = KeyGroup::numeric; - else if (key == "functions") keyGroup = KeyGroup::functions; - else if (key == "keys") keyGroup = KeyGroup::keys; - else if (key == "gkeys") keyGroup = KeyGroup::gkeys; - else return false; - return true; + +bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, uint8_t speed, Color color) { + byte_buffer_t data; + switch (effect) { + + case NativeEffect::color: + data = { 0x11, 0xff, 0x0d, 0x3c, (uint8_t)part, 0x01, color.red, color.green, color.blue, 0x02 }; + break; + case NativeEffect::breathing: + data = { + 0x11, 0xff, 0x0d, 0x3c, (uint8_t)part, 0x02, + color.red, color.green, color.blue, speed, + 0x10, 0x00, 0x64 + }; + break; + case NativeEffect::cycle: + data = { + 0x11, 0xff, 0x0d, 0x3c, (uint8_t)part, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, speed, 0x00, 0x00, 0x64 + }; + break; + case NativeEffect::hwave: + switch (part) { + case NativeEffectPart::logo: + setNativeEffect(NativeEffect::color, part, 0, Color({0x00, 0xff, 0xff})); + break; + default: + data = { + 0x11, 0xff, 0x0d, 0x3c, (uint8_t)part, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x64, speed + }; + break; + } + break; + case NativeEffect::vwave: + switch (part) { + case NativeEffectPart::logo: + setNativeEffect(NativeEffect::color, part, 0, Color({0x00, 0xff, 0xff})); + break; + default: + data = { + 0x11, 0xff, 0x0d, 0x3c, (uint8_t)part, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x02, 0x64, speed + }; + break; + } + break; + case NativeEffect::cwave: + switch (part) { + case NativeEffectPart::logo: + setNativeEffect(NativeEffect::color, part, 0, Color({0x00, 0xff, 0xff})); + break; + default: + data = { + 0x11, 0xff, 0x0d, 0x3c, (uint8_t)part, 0x04, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x03, 0x64, speed + }; + break; + } + break; + + default: + return false; + } + + data.resize(20, 0x00); + return sendDataInternal(data); } -bool Keyboard::parseColor(std::string color, KeyColors &colors) { - if (color.length() == 2) color = color + "0000"; // For G610 - if (color.length() != 6) return false; - colors.red = std::stoul("0x"+color.substr(0,2), nullptr, 16); - colors.green = std::stoul("0x"+color.substr(2,2), nullptr, 16); - colors.blue = std::stoul("0x"+color.substr(4,2), nullptr, 16); - return true; -} -bool Keyboard::parseSpeed(std::string speed, uint8_t &speedValue) { - if (speed.length() == 1) speed = speed + "0"; - if (speed.length() != 2) return false; - speedValue = std::stoul("0x"+speed, nullptr, 16); - return true; -} -bool Keyboard::sendDataInternal(unsigned char *data, uint16_t data_size) { - if (m_isAttached == false) return false; +bool LedKeyboard::sendDataInternal(const byte_buffer_t &data) { + if (! m_isOpen) return false; int r; - if (data_size > 20) r = libusb_control_transfer(dev_handle, 0x21, 0x09, 0x0212, 1, data, data_size, 2000); - else r = libusb_control_transfer(dev_handle, 0x21, 0x09, 0x0211, 1, data, data_size, 2000); + if (data.size() > 20) r = libusb_control_transfer(m_hidHandle, 0x21, 0x09, 0x0212, 1, const_cast(data.data()), data.size(), 2000); + else r = libusb_control_transfer(m_hidHandle, 0x21, 0x09, 0x0211, 1, const_cast(data.data()), data.size(), 2000); usleep(1000); if (r < 0) return false; unsigned char buffer[64]; int len = 0; - r = libusb_interrupt_transfer(dev_handle, 0x82, buffer, sizeof(buffer), &len, 1); + r = libusb_interrupt_transfer(m_hidHandle, 0x82, buffer, sizeof(buffer), &len, 1); return true; } -bool Keyboard::populateAddressGroupInternal(KeyAddressGroup addressGroup, unsigned char *data) { - switch (kbdProtocol) { - case KeyboardProtocol::generic: - switch (addressGroup) { - case KeyAddressGroup::logo: - data[0] = 0x11; // Base address - data[1] = 0xff; // Base address - data[2] = 0x0c; // Base address - data[3] = 0x3a; // Base address - data[4] = 0x00; // Base address - data[5] = 0x10; // Base address - data[6] = 0x00; // Base address - data[7] = 0x01; // Base address - break; - case KeyAddressGroup::indicators: - data[0] = 0x12; // Base address - data[1] = 0xff; // Base address - data[2] = 0x0c; // Base address - data[3] = 0x3a; // Base address - data[4] = 0x00; // Base address - data[5] = 0x40; // Base address - data[6] = 0x00; // Base address - data[7] = 0x05; // Base address - break; - case KeyAddressGroup::multimedia: - data[0] = 0x12; // Base address - data[1] = 0xff; // Base address - data[2] = 0x0c; // Base address - data[3] = 0x3a; // Base address - data[4] = 0x00; // Base address - data[5] = 0x02; // Base address - data[6] = 0x00; // Base address - data[7] = 0x05; // Base address - break; - case KeyAddressGroup::keys: - data[0] = 0x12; // Base address - data[1] = 0xff; // Base address - data[2] = 0x0c; // Base address - data[3] = 0x3a; // Base address - data[4] = 0x00; // Base address - data[5] = 0x01; // Base address - data[6] = 0x00; // Base address - data[7] = 0x0e; // Base address - break; - default: - return false; - break; +LedKeyboard::byte_buffer_t LedKeyboard::getKeyGroupAddress(LedKeyboard::KeyAddressGroup keyAddressGroup) { + switch (m_keyboardModel) { + case KeyboardModel::g410: + case KeyboardModel::g610: + case KeyboardModel::g810: + switch (keyAddressGroup) { + case LedKeyboard::KeyAddressGroup::logo: + return { 0x11, 0xff, 0x0c, 0x3a, 0x00, 0x10, 0x00, 0x01 }; + case LedKeyboard::KeyAddressGroup::indicators: + return { 0x12, 0xff, 0x0c, 0x3a, 0x00, 0x40, 0x00, 0x05 }; + case LedKeyboard::KeyAddressGroup::gkeys: + return {}; + case LedKeyboard::KeyAddressGroup::multimedia: + return { 0x12, 0xff, 0x0c, 0x3a, 0x00, 0x02, 0x00, 0x05 }; + case LedKeyboard::KeyAddressGroup::keys: + return { 0x12, 0xff, 0x0c, 0x3a, 0x00, 0x01, 0x00, 0x0e }; } break; - case KeyboardProtocol::g910: // gkeys and mkeys seem not changeable - switch (addressGroup) { - case KeyAddressGroup::logo: - data[0] = 0x11; // Base address - data[1] = 0xff; // Base address - data[2] = 0x0f; // Base address - data[3] = 0x3a; // Base address - data[4] = 0x00; // Base address - data[5] = 0x10; // Base address - data[6] = 0x00; // Base address - data[7] = 0x02; // Base address - break; - case KeyAddressGroup::indicators: - data[0] = 0x12; // Base address - data[1] = 0xff; // Base address - data[2] = 0x0c; // Base address - data[3] = 0x3a; // Base address - data[4] = 0x00; // Base address - data[5] = 0x40; // Base address - data[6] = 0x00; // Base address - data[7] = 0x05; // Base address - break; - case KeyAddressGroup::keys: - data[0] = 0x12; // Base address - data[1] = 0xff; // Base address - data[2] = 0x0f; // Base address - data[3] = 0x3d; // Base address - data[4] = 0x00; // Base address - data[5] = 0x01; // Base address - data[6] = 0x00; // Base address - data[7] = 0x0e; // Base address - break; - case KeyAddressGroup::gkeys: - data[0] = 0x12; // Base address - data[1] = 0xff; // Base address - data[2] = 0x0f; // Base address - data[3] = 0x3e; // Base address - data[4] = 0x00; // Base address - data[5] = 0x04; // Base address - data[6] = 0x00; // Base address - data[7] = 0x09; // Base address - break; - default: - return false; - break; + case KeyboardModel::g910: + switch (keyAddressGroup) { + case LedKeyboard::KeyAddressGroup::logo: + return { 0x11, 0xff, 0x0f, 0x3a, 0x00, 0x10, 0x00, 0x02 }; + case LedKeyboard::KeyAddressGroup::indicators: + return { 0x12, 0xff, 0x0c, 0x3a, 0x00, 0x40, 0x00, 0x05 }; + case LedKeyboard::KeyAddressGroup::gkeys: + return { 0x12, 0xff, 0x0f, 0x3e, 0x00, 0x04, 0x00, 0x09 }; + case LedKeyboard::KeyAddressGroup::multimedia: + return {}; + case LedKeyboard::KeyAddressGroup::keys: + return { 0x12, 0xff, 0x0f, 0x3d, 0x00, 0x01, 0x00, 0x0e }; } break; default: - return false; break; } - return true; -} - -bool Keyboard::populateFXAddressInternal(unsigned char *data) { - switch (kbdProtocol) { - case KeyboardProtocol::generic: - data[0] = 0x11; // Base address - data[1] = 0xff; // Base address - data[2] = 0x0d; // Base address - data[3] = 0x3c; // Base address - break; - case KeyboardProtocol::g910: - data[0] = 0x11; // Base address - data[1] = 0xff; // Base address - data[2] = 0x10; // Base address - data[3] = 0x3c; // Base address - break; - default: - return false; - break; - } - return true; -} - -bool Keyboard::setKeysInternal(KeyAddressGroup addressGroup, KeyValue keyValues[], size_t keyValueCount) { - bool retval = false; - int data_size; - if (addressGroup == KeyAddressGroup::logo) data_size = 20; - else data_size = 64; - unsigned char *data = new unsigned char[data_size]; - const size_t maxKeyValueCount = (data_size - 8) / 4; - populateAddressGroupInternal(addressGroup, data); - for(size_t i = 0; i < maxKeyValueCount; i++) { - if (i < keyValueCount) { - data[8 + i * 4 + 0] = keyValues[i].key.id; - data[8 + i * 4 + 1] = keyValues[i].colors.red; - data[8 + i * 4 + 2] = keyValues[i].colors.green; - data[8 + i * 4 + 3] = keyValues[i].colors.blue; - } else { - data[8 + i * 4 + 0] = 0x00; - data[8 + i * 4 + 1] = 0x00; - data[8 + i * 4 + 2] = 0x00; - data[8 + i * 4 + 3] = 0x00; - } - } - retval = sendDataInternal(data, data_size); - delete[] data; - return retval; -} - -bool Keyboard::setPowerOnEffect(PowerOnEffect powerOnEffect) { - bool retval = false; - int data_size = 20; - unsigned char *data = new unsigned char[data_size]; - switch (kbdProtocol) { - case KeyboardProtocol::generic: - data[0] = 0x11; // Base address - data[1] = 0xff; // Base address - data[2] = 0x0d; // Base address - data[3] = 0x5a; // Base address - data[4] = 0x00; // Base address - data[5] = 0x01; // Base address - case KeyboardProtocol::g910: - data[0] = 0x11; // Base address - data[1] = 0xff; // Base address - data[2] = 0x10; // Base address - data[3] = 0x5e; // Base address - data[4] = 0x00; // Base address - data[5] = 0x01; // Base address - } - switch (powerOnEffect) { - case PowerOnEffect::rainbow: - data[6] = 0x01; - break; - case PowerOnEffect::color: - data[6] = 0x02; - break; - } - for(int i = 7; i < data_size; i++) data[i] = 0x00; - retval = sendDataInternal(data, data_size); - delete[] data; - return retval; -} - -bool Keyboard::setKey(KeyValue keyValue) { - bool retval = false; - unsigned char *data; - int data_size; - if (keyValue.key.addressGroup == KeyAddressGroup::logo) { - data_size = 20; - data = new unsigned char[data_size]; - populateAddressGroupInternal(keyValue.key.addressGroup, data); - } else { - data_size = 64; - data = new unsigned char[data_size]; - populateAddressGroupInternal(keyValue.key.addressGroup, data); - } - data[8] = keyValue.key.id; - data[9] = keyValue.colors.red; - data[10] = keyValue.colors.green; - data[11] = keyValue.colors.blue; - for(int i = 12; i < data_size; i++) data[i] = 0x00; - retval = sendDataInternal(data, data_size); - delete[] data; - return retval; -} - -bool Keyboard::setKey(Key key, KeyColors colors) { - KeyValue keyValue; - getKeyAddress(key, keyValue.key); - keyValue.colors = colors; - return setKey(keyValue); -} - -bool Keyboard::setKeys(KeyValue keyValue[], size_t keyValueCount) { - const size_t maxLogoKeys = 5; - const size_t maxIndicatorsKeys = 25; - const size_t maxMultimediaKeys = 25; - const size_t maxKeys = 200; - const size_t maxGKeys = 25; - size_t logoCount = 0; - size_t indicatorsCount = 0; - size_t multimediaCount = 0; - size_t keysCount = 0; - size_t gkeysCount = 0; - KeyValue logo[maxLogoKeys]; - KeyValue indicators[maxIndicatorsKeys]; - KeyValue multimedia[maxMultimediaKeys]; - KeyValue keys[maxKeys]; - KeyValue gkeys[maxGKeys]; - - for (size_t i = 0; i < keyValueCount; i++) { - if(keyValue[i].key.addressGroup == KeyAddressGroup::logo && logoCount <= maxLogoKeys) { - logo[logoCount] = keyValue[i]; - logoCount++; - } else if(keyValue[i].key.addressGroup == KeyAddressGroup::indicators && indicatorsCount <= maxIndicatorsKeys) { - indicators[indicatorsCount] = keyValue[i]; - indicatorsCount++; - } else if(keyValue[i].key.addressGroup == KeyAddressGroup::multimedia && multimediaCount <= maxMultimediaKeys) { - multimedia[multimediaCount] = keyValue[i]; - multimediaCount++; - } else if(keyValue[i].key.addressGroup == KeyAddressGroup::keys && keysCount <= maxKeys) { - keys[keysCount] = keyValue[i]; - keysCount++; - } else if(keyValue[i].key.addressGroup == KeyAddressGroup::gkeys && gkeysCount <= maxGKeys) { - gkeys[gkeysCount] = keyValue[i]; - gkeysCount++; - } - } - - if (logoCount > 0) setKeysInternal(KeyAddressGroup::logo, logo, logoCount); - - if (indicatorsCount > 0) setKeysInternal(KeyAddressGroup::indicators, indicators, indicatorsCount); - - if (multimediaCount > 0) setKeysInternal(KeyAddressGroup::multimedia, multimedia, multimediaCount); - - if (keysCount > 0) { - const size_t maxKeyValueCount = 14; - for (size_t i = 0; i < keysCount; i = i + maxKeyValueCount) { - KeyValue keysBlock[maxKeyValueCount]; - size_t keysBlockCount = 0; - for (size_t j = 0; j < maxKeyValueCount; j++) { - if((i + j) < keysCount ) { - keysBlock[j] = keys[i + j]; - keysBlockCount++; - } - } - setKeysInternal(KeyAddressGroup::keys, keysBlock, keysBlockCount); - } - } - - if (gkeysCount > 0) setKeysInternal(KeyAddressGroup::gkeys, gkeys, gkeysCount); - - return true; -} - -bool Keyboard::setAllKeys(KeyColors colors) { - KeyValue keyValues[127]; - for (int i = 0; i < 127; i++) { - getKeyAddress((Key)i, keyValues[i].key); - keyValues[i].colors = colors; - } - setKeys(keyValues, 127); - return true; -} - -bool Keyboard::setGroupKeys(KeyGroup keyGroup, KeyColors colors) { - KeyValue keyValues[54]; - int keyValuesCount = 0; - switch (keyGroup) { - case KeyGroup::logo: - for (int i = 0; i < 2; i++) { - getKeyAddress((Key)i, keyValues[i].key); - keyValues[i].colors = colors; - keyValuesCount++; - } - setKeys(keyValues, keyValuesCount); - break; - case KeyGroup::indicators: - for (int i = 2; i < 7; i++) { - getKeyAddress((Key)i, keyValues[i - 2].key); - keyValues[i - 2].colors = colors; - keyValuesCount++; - } - setKeys(keyValues, keyValuesCount); - break; - case KeyGroup::multimedia: - for (int i = 7; i < 12; i++) { - getKeyAddress((Key)i, keyValues[i - 7].key); - keyValues[i - 7].colors = colors; - keyValuesCount++; - } - setKeys(keyValues, keyValuesCount); - break; - case KeyGroup::fkeys: - for (int i = 12; i < 24; i++) { - getKeyAddress((Key)i, keyValues[i - 12].key); - keyValues[i - 12].colors = colors; - keyValuesCount++; - } - setKeys(keyValues, keyValuesCount); - break; - case KeyGroup::modifiers: - for (int i = 24; i < 33; i++) { - getKeyAddress((Key)i, keyValues[i - 24].key); - keyValues[i - 24].colors = colors; - keyValuesCount++; - } - setKeys(keyValues, keyValuesCount); - break; - case KeyGroup::arrows: - for (int i = 33; i < 37; i++) { - getKeyAddress((Key)i, keyValues[i - 33].key); - keyValues[i - 33].colors = colors; - keyValuesCount++; - } - setKeys(keyValues, keyValuesCount); - break; - case KeyGroup::numeric: - for (int i = 37; i < 54; i++) { - getKeyAddress((Key)i, keyValues[i - 37].key); - keyValues[i - 37].colors = colors; - keyValuesCount++; - } - setKeys(keyValues, keyValuesCount); - break; - case KeyGroup::functions: - for (int i = 54; i < 64; i++) { - getKeyAddress((Key)i, keyValues[i - 54].key); - keyValues[i - 54].colors = colors; - keyValuesCount++; - } - setKeys(keyValues, keyValuesCount); - break; - case KeyGroup::keys: - for (int i = 64; i < 118; i++) { - getKeyAddress((Key)i, keyValues[i - 64].key); - keyValues[i - 64].colors = colors; - keyValuesCount++; - } - setKeys(keyValues, keyValuesCount); - break; - case KeyGroup::gkeys: - for (int i = 118; i < 127; i++) { - getKeyAddress((Key)i, keyValues[i - 118].key); - keyValues[i - 118].colors = colors; - keyValuesCount++; - } - setKeys(keyValues, keyValuesCount); - break; - } - return true; -} - -bool Keyboard::setFXColorKeys(KeyColors colors) { - bool retval = false; - int data_size = 20; - unsigned char *data = new unsigned char[data_size]; - - // Keys - populateFXAddressInternal(data); - data[4] = 0x00; // Keys - data[5] = 0x01; // Effect - data[6] = colors.red; - data[7] = colors.green; - data[8] = colors.blue; - data[9] = 0x02; - for(int i = 10; i < data_size; i++) data[i] = 0x00; - retval = sendDataInternal(data, data_size); - - delete[] data; - return retval; -} - -bool Keyboard::setFXColorLogo(KeyColors colors) { - bool retval = false; - int data_size = 20; - unsigned char *data = new unsigned char[data_size]; - - // Logo - populateFXAddressInternal(data); - data[4] = 0x01; // Logo - data[5] = 0x01; // Effect - data[6] = colors.red; - data[7] = colors.green; - data[8] = colors.blue; - data[9] = 0x02; - for(int i = 10; i < data_size; i++) data[i] = 0x00; - retval = sendDataInternal(data, data_size); - - delete[] data; - return retval; -} - -bool Keyboard::setFXBreathingKeys(KeyColors colors, uint8_t speed) { - bool retval = false; - int data_size = 20; - unsigned char *data = new unsigned char[data_size]; - - // Keys - populateFXAddressInternal(data); - data[4] = 0x00; // Keys - data[5] = 0x02; // Effect - data[6] = colors.red; - data[7] = colors.green; - data[8] = colors.blue; - data[9] = speed; // Speed - data[10] = 0x10; // ??? - data[11] = 0x00; - data[12] = 0x64; - for(int i = 13; i < data_size; i++) data[i] = 0x00; - retval = sendDataInternal(data, data_size); - - delete[] data; - return retval; -} - -bool Keyboard::setFXBreathingLogo(KeyColors colors, uint8_t speed) { - bool retval = false; - int data_size = 20; - unsigned char *data = new unsigned char[data_size]; - - // Logo - populateFXAddressInternal(data); - data[4] = 0x01; // Logo - data[5] = 0x02; // Effect - data[6] = colors.red; - data[7] = colors.green; - data[8] = colors.blue; - data[9] = speed; // Speed - data[10] = 0x10; // ??? - data[11] = 0x00; - data[12] = 0x64; - for(int i = 13; i < data_size; i++) data[i] = 0x00; - retval = sendDataInternal(data, data_size); - - delete[] data; - return retval; -} - -bool Keyboard::setFXColorCycleKeys(uint8_t speed) { - bool retval = false; - int data_size = 20; - unsigned char *data = new unsigned char[data_size]; - - // Keys - populateFXAddressInternal(data); - data[4] = 0x00; // Keys - data[5] = 0x03; // Effect - data[6] = 0x00; - data[7] = 0x00; - data[8] = 0x00; - data[9] = 0x00; - data[10] = 0x00; - data[11] = speed; // Speed - data[12] = 0x00; // ??? - data[13] = 0x00; - data[14] = 0x64; - for(int i = 15; i < data_size; i++) data[i] = 0x00; - retval = sendDataInternal(data, data_size); - - delete[] data; - return retval; -} - -bool Keyboard::setFXColorCycleLogo(uint8_t speed) { - bool retval = false; - int data_size = 20; - unsigned char *data = new unsigned char[data_size]; - - // Logo - populateFXAddressInternal(data); - data[4] = 0x01; // Logo - data[5] = 0x03; // Effect - data[6] = 0x00; - data[7] = 0x00; - data[8] = 0x00; - data[9] = 0x00; - data[10] = 0x00; - data[11] = speed; // Speed - data[12] = 0x00; // ??? - data[13] = 0x00; - data[14] = 0x64; - for(int i = 15; i < data_size; i++) data[i] = 0x00; - retval = sendDataInternal(data, data_size); - - delete[] data; - return retval; -} - -bool Keyboard::setFXHWaveKeys(uint8_t speed) { - bool retval = false; - int data_size = 20; - unsigned char *data = new unsigned char[data_size]; - - // Keys - populateFXAddressInternal(data); - data[4] = 0x00; // Keys - data[5] = 0x04; // Effect - data[6] = 0x00; - data[7] = 0x00; - data[8] = 0x00; - data[9] = 0x00; - data[10] = 0x00; - data[11] = 0x00; - data[12] = 0x88; - data[13] = 0x01; - data[14] = 0x64; - data[15] = speed; // Speed - for(int i = 16; i < data_size; i++) data[i] = 0x00; - retval = sendDataInternal(data, data_size); - - delete[] data; - return retval; -} - -bool Keyboard::setFXVWaveKeys(uint8_t speed) { - bool retval = false; - int data_size = 20; - unsigned char *data = new unsigned char[data_size]; - - // Keys - populateFXAddressInternal(data); - data[4] = 0x00; // Keys - data[5] = 0x04; // Effect - data[6] = 0x00; - data[7] = 0x00; - data[8] = 0x00; - data[9] = 0x00; - data[10] = 0x00; - data[11] = 0x00; - data[12] = 0x88; - data[13] = 0x02; - data[14] = 0x64; - data[15] = speed; // Speed - for(int i = 16; i < data_size; i++) data[i] = 0x00; - retval = sendDataInternal(data, data_size); - - delete[] data; - return retval; -} - -bool Keyboard::setFXCWaveKeys(uint8_t speed) { - bool retval = false; - int data_size = 20; - unsigned char *data = new unsigned char[data_size]; - - // Keys - populateFXAddressInternal(data); - data[4] = 0x00; // Keys - data[5] = 0x04; // Effect - data[6] = 0x00; - data[7] = 0x00; - data[8] = 0x00; - data[9] = 0x00; - data[10] = 0x00; - data[11] = 0x00; - data[12] = 0x88; - data[13] = 0x03; - data[14] = 0x64; - data[15] = speed; // Speed - for(int i = 16; i < data_size; i++) data[i] = 0x00; - retval = sendDataInternal(data, data_size); - - delete[] data; - return retval; + return {}; } diff --git a/src/classes/Keyboard.h b/src/classes/Keyboard.h index 5571e4e..86864cc 100644 --- a/src/classes/Keyboard.h +++ b/src/classes/Keyboard.h @@ -1,81 +1,195 @@ -#ifndef DEF_KEYBOARD -#define DEF_KEYBOARD +#ifndef KEYBOARD_CLASS +#define KEYBOARD_CLASS #include -#include +#include -class Keyboard { +#include "libusb-1.0/libusb.h" + + +class LedKeyboard { + + private: + + const std::vector> SuportedKeyboards = { + { 0x46d, 0xc330, (u_int16_t)KeyboardModel::g410 }, + { 0x46d, 0xc333, (u_int16_t)KeyboardModel::g610 }, + { 0x46d, 0xc338, (u_int16_t)KeyboardModel::g610 }, + { 0x46d, 0xc331, (u_int16_t)KeyboardModel::g810 }, + { 0x46d, 0xc337, (u_int16_t)KeyboardModel::g810 }, + { 0x46d, 0xc32b, (u_int16_t)KeyboardModel::g910 }, + { 0x46d, 0xc335, (u_int16_t)KeyboardModel::g910 } + }; + + + enum class KeyAddressGroup : uint8_t { + logo = 0x00, + indicators, + multimedia, + gkeys, + keys + }; + + public: - enum class KeyboardProtocol { generic, g910 }; - enum class PowerOnEffect { rainbow, color }; - enum class KeyAddressGroup { logo, indicators, multimedia, keys, gkeys }; - enum class Key { // 127 items - logo, logo2, - caps, num, scroll, game, backlight, - mute, play, stop, prev, next, - f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, - shift_left, ctrl_left, win_left, alt_left, alt_right, win_right, ctrl_right, shift_right, menu, - arrow_top, arrow_left, arrow_bottom, arrow_right, - num_1, num_2, num_3, num_4, num_5, num_6, num_7, num_8, num_9, num_0, num_dot, num_enter, num_plus, num_minus, num_asterisk, num_slash, num_lock, - esc, scroll_lock, - insert, del, home, end, page_up, page_down, print_screen, pause_break, - n1, n2, n3, n4, n5, n6, n7, n8, n9, n0, - tab, caps_lock, space, backspace, enter, - a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, - tilde, minus, equal, - open_bracket, close_bracket, backslash, - semicolon, quote, dollar, - intl_backslash, comma, period, slash, - g1, g2, g3, g4, g5, g6, g7, g8, g9 + enum class KeyboardModel : uint8_t { + unknown = 0x00, + g410, + g610, + g810, + g910 + }; + enum class StartupMode : uint8_t { + wave = 0x01, + color + }; + enum class NativeEffect : uint8_t { + color = 0x01, + breathing, + cycle, + hwave, + vwave, + cwave + }; + enum class NativeEffectPart : uint8_t { + all = 0xff, + keys = 0x00, + logo + }; + enum class KeyGroup : uint8_t { + logo = 0x00, + indicators, + multimedia, + gkeys, + fkeys, + modifiers, + functions, + arrows, + numeric, + keys + }; + enum class Key : uint16_t { // 127 items + + logo = static_cast(KeyAddressGroup::logo) << 8 | 0x01, + logo2, + + backlight = static_cast(KeyAddressGroup::indicators) << 8| 0x01, + game, caps, scroll, num, + + next = static_cast(KeyAddressGroup::multimedia) << 8 | 0xb5, + prev, stop, + play = static_cast(KeyAddressGroup::multimedia) << 8 | 0xcd, + mute = static_cast(KeyAddressGroup::multimedia) << 8 | 0xe2, + + g1 = static_cast(KeyAddressGroup::gkeys) << 8 | 0x01, + g2, g3, g4, g5, g6, g7, g8, g9, + + a = static_cast(KeyAddressGroup::keys) << 8 | 0x04, + b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, + n1, n2, n3, n4, n5, n6, n7, n8, n9, n0, + enter, esc, backspace, tab, space, minus, equal, open_bracket, close_bracket, + backslash, dollar, semicolon, quote, tilde, comma, period, slash, caps_lock, + f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, + print_screen, scroll_lock, pause_break, insert, home, page_up, del, end, page_down, + arrow_right, arrow_left, arrow_bottom, arrow_top, num_lock, num_slash, num_asterisk, + num_minus, num_plus, num_enter, + num_1, num_2, num_3, num_4, num_5, num_6, num_7, num_8, num_9, num_0, + num_dot, intl_backslash, menu, + + ctrl_left = static_cast(KeyAddressGroup::keys) << 8 | 0xe0, + shift_left, alt_left, win_left, + ctrl_right, shift_right, alt_right, win_right + }; - enum class KeyGroup { logo, indicators, multimedia, fkeys, modifiers, arrows, numeric, functions, keys, gkeys}; - struct KeyColors { uint8_t red; uint8_t green; uint8_t blue; }; - struct KeyAddress { KeyAddressGroup addressGroup; uint8_t id; }; - struct KeyValue { KeyAddress key; KeyColors colors; }; - bool isAttached(); - bool attach(); - bool detach(); + struct Color { + uint8_t red; + uint8_t green; + uint8_t blue; + }; + struct KeyValue { + LedKeyboard::Key key; + LedKeyboard::Color color; + }; + + typedef std::vector KeyValueArray; + + + ~LedKeyboard(); + + + bool listKeyboards(); + + bool isOpen(); + bool open(); + bool close(); + + KeyboardModel getKeyboardModel(); + bool commit(); - bool getKeyAddress(Key key, KeyAddress &keyAddress); - bool parsePowerOnEffect(std::string effect, PowerOnEffect &powerOnEffect); - bool parseKey(std::string key, KeyAddress &keyAddress); - bool parseKeyGroup(std::string key, KeyGroup &keyGroup); - bool parseColor(std::string color, KeyColors &colors); - bool parseSpeed(std::string speed, uint8_t &speedValue); - bool setPowerOnEffect(PowerOnEffect powerOnEffect); + bool setKey(KeyValue keyValue); - bool setKey(Key key, KeyColors colors); - bool setKeys(KeyValue keyValue[], size_t keyValueCount); - bool setAllKeys(KeyColors colors); - bool setGroupKeys(KeyGroup keyGroup, KeyColors colors); - bool setFXColorKeys(KeyColors colors); - bool setFXColorLogo(KeyColors colors); - bool setFXBreathingKeys(KeyColors colors, uint8_t speed); - bool setFXBreathingLogo(KeyColors colors, uint8_t speed); - bool setFXColorCycleKeys(uint8_t speed); - bool setFXColorCycleLogo(uint8_t speed); - bool setFXHWaveKeys(uint8_t speed); - bool setFXVWaveKeys(uint8_t speed); - bool setFXCWaveKeys(uint8_t speed); + bool setKeys(KeyValueArray keyValues); + bool setGroupKeys(KeyGroup keyGroup, Color color); + bool setAllKeys(Color color); + + bool setStartupMode(StartupMode startupMode); + + bool setNativeEffect(NativeEffect effect, NativeEffectPart part, uint8_t speed, Color color); + private: - bool m_isAttached = false; - bool m_isKernellDetached = false; - KeyboardProtocol kbdProtocol = KeyboardProtocol::generic; - libusb_device **devs; - libusb_device_handle *dev_handle; - libusb_context *ctx = NULL; + typedef std::vector byte_buffer_t; + typedef std::vector KeyArray; - bool populateAddressGroupInternal(KeyAddressGroup addressGroup, unsigned char *data); - bool populateFXAddressInternal(unsigned char *data); - bool sendDataInternal(unsigned char *data, uint16_t data_size); - bool setKeysInternal(KeyAddressGroup addressGroup, KeyValue keyValues[], size_t keyValueCount); + + const KeyArray keyGroupLogo = { Key::logo, Key::logo2 }; + const KeyArray keyGroupIndicators = { Key::caps, Key::num, Key::scroll, Key::game, Key::backlight }; + const KeyArray keyGroupMultimedia = { Key::next, Key::prev, Key::stop, Key::play, Key::mute }; + const KeyArray keyGroupGKeys = { Key::g1, Key::g2, Key::g3, Key::g4, Key::g5, Key::g6, Key::g7, Key::g8, Key::g9 }; + const KeyArray keyGroupFKeys = { + Key::f1, Key::f2, Key::f3, Key::f4, Key::f5, Key::f6, + Key::f7, Key::f8, Key::f9, Key::f10, Key::f11, Key::f12 + }; + const KeyArray keyGroupModifiers = { + Key::shift_left, Key::ctrl_left, Key::win_left, Key::alt_left, + Key::alt_right, Key::win_right, Key::ctrl_right, Key::shift_right, Key::menu }; + const KeyArray keyGroupFunctions = { + Key::esc, Key::print_screen, Key::scroll_lock, Key::pause_break, + Key::insert, Key::del, Key::home, Key::end, Key::page_up, Key::page_down + }; + const KeyArray keyGroupArrows = { Key::arrow_top, Key::arrow_left, Key::arrow_bottom, Key::arrow_right }; + const KeyArray keyGroupNumeric = { + Key::num_1, Key::num_2, Key::num_3, Key::num_4, Key::num_5, + Key::num_6, Key::num_7, Key::num_8, Key::num_9, Key::num_0, + Key::num_dot, Key::num_enter, Key::num_plus, Key::num_minus, + Key::num_asterisk, Key::num_slash, Key::num_lock + }; + const KeyArray keyGroupKeys = { + Key::a, Key::b, Key::c, Key::d, Key::e, Key::f, Key::g, Key::h, Key::i, Key::j, Key::k, Key::l, Key::m, + Key::n, Key::o, Key::p, Key::q, Key::r, Key::s, Key::t, Key::u, Key::v, Key::w, Key::x, Key::y, Key::z, + Key::n1, Key::n2, Key::n3, Key::n4, Key::n5, Key::n6, Key::n7, Key::n8, Key::n9, Key::n0, + Key::enter, Key::esc, Key::backspace, Key::tab, Key::space, Key::minus, Key::equal, + Key::open_bracket, Key::close_bracket, Key::backslash, Key::dollar, Key::semicolon, Key::quote, Key::tilde, + Key::comma, Key::period, Key::slash, Key::caps_lock, Key::intl_backslash + }; + + bool m_isOpen = false; + bool m_isKernellDetached = false; + uint16_t m_vendorID = 0; + uint16_t m_productID = 0; + KeyboardModel m_keyboardModel = KeyboardModel::unknown; + libusb_device_handle *m_hidHandle; + libusb_context *m_ctx = NULL; + + + bool sendDataInternal(const byte_buffer_t &data); + byte_buffer_t getKeyGroupAddress(KeyAddressGroup keyAddressGroup); }; diff --git a/src/helpers/help.cpp b/src/helpers/help.cpp new file mode 100644 index 0000000..3092f09 --- /dev/null +++ b/src/helpers/help.cpp @@ -0,0 +1,187 @@ +#include "help.h" + +#include +#include "utils.h" + + +using namespace std; + +namespace help { + + + void usage(char *arg0) { + string cmdName = utils::getCmdName(arg0); + cout< + +namespace help { + + void usage(char *arg0); + void keys(char *arg0); + void effects(char *arg0); + void samples(char *arg0); + +} + +#endif diff --git a/src/helpers/utils.cpp b/src/helpers/utils.cpp new file mode 100644 index 0000000..19ce07a --- /dev/null +++ b/src/helpers/utils.cpp @@ -0,0 +1,212 @@ +#include "utils.h" + +#include +#include + +#include "../classes/Keyboard.h" + + +namespace utils { + + 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 parseNativeEffect(std::string val, LedKeyboard::NativeEffect &nativeEffect) { + if (val == "color") nativeEffect = LedKeyboard::NativeEffect::color; + else if (val == "cycle") nativeEffect = LedKeyboard::NativeEffect::cycle; + else if (val == "breathing") nativeEffect = LedKeyboard::NativeEffect::breathing; + else if (val == "hwave") nativeEffect = LedKeyboard::NativeEffect::hwave; + else if (val == "vwave") nativeEffect = LedKeyboard::NativeEffect::vwave; + else if (val == "cwave") nativeEffect = LedKeyboard::NativeEffect::cwave; + else return false; + return true; + } + + bool parseNativeEffectPart(std::string val, LedKeyboard::NativeEffectPart &nativeEffectPart) { + if (val == "all") nativeEffectPart = LedKeyboard::NativeEffectPart::all; + else if (val == "keys") nativeEffectPart = LedKeyboard::NativeEffectPart::keys; + else if (val == "logo") nativeEffectPart = LedKeyboard::NativeEffectPart::logo; + else return false; + return true; + } + + bool parseKey(std::string val, LedKeyboard::Key &key) { + std::transform(val.begin(), val.end(), val.begin(), ::tolower); + if (val == "logo") key = LedKeyboard::Key::logo; + else if (val == "logo2") key = LedKeyboard::Key::logo2; + else if (val == "back_light" || val == "backlight" || val == "light") key = LedKeyboard::Key::backlight; + else if (val == "game_mode" || val == "gamemode" || val == "game") key = LedKeyboard::Key::game; + else if (val == "caps_indicator" || val == "capsindicator" || val == "caps") key = LedKeyboard::Key::caps; + else if (val == "scroll_indicator" || val == "scrollindicator" || val == "scroll") key = LedKeyboard::Key::scroll; + else if (val == "num_indicator" || val == "numindicator" || val == "num") key = LedKeyboard::Key::num; + else if (val == "next") key = LedKeyboard::Key::next; + else if (val == "prev" || val == "previous") key = LedKeyboard::Key::prev; + else if (val == "stop") key = LedKeyboard::Key::stop; + else if (val == "play_pause" || val == "playpause" || val == "play") key = LedKeyboard::Key::play; + else if (val == "mute") key = LedKeyboard::Key::mute; + else if (val == "a") key = LedKeyboard::Key::a; + else if (val == "b") key = LedKeyboard::Key::b; + else if (val == "c") key = LedKeyboard::Key::c; + else if (val == "d") key = LedKeyboard::Key::d; + else if (val == "e") key = LedKeyboard::Key::e; + else if (val == "f") key = LedKeyboard::Key::f; + else if (val == "g") key = LedKeyboard::Key::g; + else if (val == "h") key = LedKeyboard::Key::h; + else if (val == "i") key = LedKeyboard::Key::i; + else if (val == "j") key = LedKeyboard::Key::j; + else if (val == "k") key = LedKeyboard::Key::k; + else if (val == "l") key = LedKeyboard::Key::l; + else if (val == "m") key = LedKeyboard::Key::m; + else if (val == "n") key = LedKeyboard::Key::n; + else if (val == "o") key = LedKeyboard::Key::o; + else if (val == "p") key = LedKeyboard::Key::p; + else if (val == "q") key = LedKeyboard::Key::q; + else if (val == "r") key = LedKeyboard::Key::r; + else if (val == "s") key = LedKeyboard::Key::s; + else if (val == "t") key = LedKeyboard::Key::t; + else if (val == "u") key = LedKeyboard::Key::u; + else if (val == "v") key = LedKeyboard::Key::v; + else if (val == "w") key = LedKeyboard::Key::w; + else if (val == "x") key = LedKeyboard::Key::x; + else if (val == "z") key = LedKeyboard::Key::z; + else if (val == "y") key = LedKeyboard::Key::y; + else if (val == "1" || val == "one") key = LedKeyboard::Key::n1; + else if (val == "2" || val == "two") key = LedKeyboard::Key::n2; + else if (val == "3" || val == "three") key = LedKeyboard::Key::n3; + else if (val == "4" || val == "four") key = LedKeyboard::Key::n4; + else if (val == "5" || val == "five") key = LedKeyboard::Key::n5; + else if (val == "6" || val == "six") key = LedKeyboard::Key::n6; + else if (val == "7" || val == "seven") key = LedKeyboard::Key::n7; + else if (val == "8" || val == "eight") key = LedKeyboard::Key::n8; + else if (val == "9" || val == "nine") key = LedKeyboard::Key::n9; + else if (val == "0" || val == "zero") key = LedKeyboard::Key::n0; + else if (val == "enter") key = LedKeyboard::Key::enter; + else if (val == "esc" || val == "escape") key = LedKeyboard::Key::esc; + else if (val == "back" || val == "backspace") key = LedKeyboard::Key::backspace; + else if (val == "tab") key = LedKeyboard::Key::tab; + else if (val == "space") key = LedKeyboard::Key::space; + else if (val == "tilde" || val == "~") key = LedKeyboard::Key::tilde; + else if (val == "minus" || val == "-") key = LedKeyboard::Key::minus; + else if (val == "equal" || val == "=") key = LedKeyboard::Key::equal; + else if (val == "open_bracket" || val == "[") key = LedKeyboard::Key::open_bracket; + else if (val == "close_bracket" || val == "]") key = LedKeyboard::Key::close_bracket; + else if (val == "backslash" || val == "\\") key = LedKeyboard::Key::backslash; + else if (val == "semicolon" || val == ";") key = LedKeyboard::Key::semicolon; + else if (val == "quote" || val == "\"") key = LedKeyboard::Key::quote; + else if (val == "dollar" || val == "$") key = LedKeyboard::Key::dollar; + else if (val == "comma" || val == ",") key = LedKeyboard::Key::comma; + else if (val == "period" || val == ".") key = LedKeyboard::Key::period; + else if (val == "slash" || val == "/") key = LedKeyboard::Key::slash; + else if (val == "caps_lock" || val == "capslock") key = LedKeyboard::Key::caps_lock; + else if (val == "f1") key = LedKeyboard::Key::f1; + else if (val == "f2") key = LedKeyboard::Key::f2; + else if (val == "f3") key = LedKeyboard::Key::f3; + else if (val == "f4") key = LedKeyboard::Key::f4; + else if (val == "f5") key = LedKeyboard::Key::f5; + else if (val == "f6") key = LedKeyboard::Key::f6; + else if (val == "f7") key = LedKeyboard::Key::f7; + else if (val == "f8") key = LedKeyboard::Key::f8; + else if (val == "f9") key = LedKeyboard::Key::f9; + else if (val == "f10") key = LedKeyboard::Key::f10; + else if (val == "f11") key = LedKeyboard::Key::f11; + else if (val == "f12") key = LedKeyboard::Key::f12; + else if (val == "print_screen" || val == "printscreen" || val == "printscr" || val == "print") + key = LedKeyboard::Key::print_screen; + else if (val == "scroll_lock" || val == "scrolllock") key = LedKeyboard::Key::scroll_lock; + else if (val == "pause_break" || val == "pausebreak" || val == "pause" || val == "break") + key = LedKeyboard::Key::pause_break; + else if (val == "insert" || val == "ins") key = LedKeyboard::Key::insert; + else if (val == "home") key = LedKeyboard::Key::home; + else if (val == "page_up" || val == "pageup") key = LedKeyboard::Key::page_up; + else if (val == "delete" || val == "del") key = LedKeyboard::Key::del; + else if (val == "end") key = LedKeyboard::Key::end; + else if (val == "page_down" || val == "pagedown") key = LedKeyboard::Key::page_down; + else if (val == "arrow_right" || val == "arrowright" || val == "right") key = LedKeyboard::Key::arrow_right; + else if (val == "arrow_left" || val == "arrowleft" || val == "left") key = LedKeyboard::Key::arrow_left; + else if (val == "arrow_bottom" || val == "arrowbottom" || val == "bottom") key = LedKeyboard::Key::arrow_bottom; + else if (val == "arrow_top" || val == "arrowtop" || val == "top") key = LedKeyboard::Key::arrow_top; + else if (val == "num_lock" || val == "numlock") key = LedKeyboard::Key::num_lock; + else if (val == "num/" || val == "num_slash" || val == "numslash") key = LedKeyboard::Key::num_slash; + else if (val == "num*" || val == "num_asterisk" || val == "numasterisk") key = LedKeyboard::Key::num_asterisk; + else if (val == "num-" || val == "num_minus" || val == "numminus") key = LedKeyboard::Key::num_minus; + else if (val == "num+" || val == "num_plus" || val == "numplus") key = LedKeyboard::Key::num_plus; + else if (val == "numenter") key = LedKeyboard::Key::num_enter; + else if (val == "num1") key = LedKeyboard::Key::num_1; + else if (val == "num2") key = LedKeyboard::Key::num_2; + else if (val == "num3") key = LedKeyboard::Key::num_3; + else if (val == "num4") key = LedKeyboard::Key::num_4; + else if (val == "num5") key = LedKeyboard::Key::num_5; + else if (val == "num6") key = LedKeyboard::Key::num_6; + else if (val == "num7") key = LedKeyboard::Key::num_7; + else if (val == "num8") key = LedKeyboard::Key::num_8; + else if (val == "num9") key = LedKeyboard::Key::num_9; + else if (val == "num0") key = LedKeyboard::Key::num_0; + else if (val == "num." || val == "num_period" || val == "numperiod") key = LedKeyboard::Key::num_dot; + else if (val == "intl_backslash" || val == "<") key = LedKeyboard::Key::intl_backslash; + else if (val == "menu") key = LedKeyboard::Key::menu; + else if (val == "ctrl_left" || val == "ctrlleft" || val == "ctrll") key = LedKeyboard::Key::ctrl_left; + else if (val == "shift_left" || val == "shiftleft" || val == "shiftl") key = LedKeyboard::Key::shift_left; + else if (val == "alt_left" || val == "altleft" || val == "altl") key = LedKeyboard::Key::alt_left; + else if (val == "win_left" || val == "winleft" || val == "winl") key = LedKeyboard::Key::win_left; + else if (val == "meta_left" || val == "metaleft" || val == "metal") key = LedKeyboard::Key::win_left; + else if (val == "ctrl_right" || val == "ctrlright" || val == "ctrlr") key = LedKeyboard::Key::ctrl_right; + else if (val == "shift_right" || val == "shiftright" || val == "shiftr") key = LedKeyboard::Key::shift_right; + else if (val == "alt_right" || val == "altright" || val == "altr" || val == "altgr") + key = LedKeyboard::Key::alt_right; + else if (val == "win_right" || val == "winright" || val == "winr") key = LedKeyboard::Key::win_right; + else if (val == "meta_right" || val == "metaright" || val == "metar") key = LedKeyboard::Key::win_right; + else if (val == "g1") key = LedKeyboard::Key::g1; + else if (val == "g2") key = LedKeyboard::Key::g2; + else if (val == "g3") key = LedKeyboard::Key::g3; + else if (val == "g4") key = LedKeyboard::Key::g4; + else if (val == "g5") key = LedKeyboard::Key::g5; + else if (val == "g6") key = LedKeyboard::Key::g6; + else if (val == "g7") key = LedKeyboard::Key::g7; + else if (val == "g8") key = LedKeyboard::Key::g8; + else if (val == "g9") key = LedKeyboard::Key::g9; + else return false; + return true; + } + + bool parseKeyGroup(std::string val, LedKeyboard::KeyGroup &keyGroup) { + if (val == "logo") keyGroup = LedKeyboard::KeyGroup::logo; + else if (val == "indicators") keyGroup = LedKeyboard::KeyGroup::indicators; + else if (val == "multimedia") keyGroup = LedKeyboard::KeyGroup::multimedia; + else if (val == "fkeys") keyGroup = LedKeyboard::KeyGroup::fkeys; + else if (val == "modifiers") keyGroup = LedKeyboard::KeyGroup::modifiers; + else if (val == "arrows") keyGroup = LedKeyboard::KeyGroup::arrows; + else if (val == "numeric") keyGroup = LedKeyboard::KeyGroup::numeric; + else if (val == "functions") keyGroup = LedKeyboard::KeyGroup::functions; + else if (val == "keys") keyGroup = LedKeyboard::KeyGroup::keys; + else if (val == "gkeys") keyGroup = LedKeyboard::KeyGroup::gkeys; + else return false; + return true; + } + + bool parseColor(std::string val, LedKeyboard::Color &color) { + if (val.length() == 2) val = val + "0000"; // For G610 + if (val.length() != 6) return false; + color.red = std::stoul("0x"+val.substr(0,2), nullptr, 16); + color.green = std::stoul("0x"+val.substr(2,2), nullptr, 16); + color.blue = std::stoul("0x"+val.substr(4,2), nullptr, 16); + return true; + } + + bool parseSpeed(std::string val, uint8_t &speed) { + if (val.length() == 1) val = "0" + val; + if (val.length() != 2) return false; + speed = std::stoul("0x" + val, nullptr, 16); + return true; + } + +} diff --git a/src/helpers/utils.h b/src/helpers/utils.h new file mode 100644 index 0000000..1fb16f7 --- /dev/null +++ b/src/helpers/utils.h @@ -0,0 +1,21 @@ +#ifndef UTILS_HELPER +#define UTILS_HELPER + +#include +#include "../classes/Keyboard.h" + +namespace utils { + + std::string getCmdName(std::string cmd); + + bool parseStartupMode(std::string val, LedKeyboard::StartupMode &startupMode); + bool parseNativeEffect(std::string val, LedKeyboard::NativeEffect &nativeEffect); + bool parseNativeEffectPart(std::string val, LedKeyboard::NativeEffectPart &nativeEffectPart); + bool parseKey(std::string val, LedKeyboard::Key &key); + bool parseKeyGroup(std::string val, LedKeyboard::KeyGroup &keyGroup); + bool parseColor(std::string val, LedKeyboard::Color &color); + bool parseSpeed(std::string val, uint8_t &speed); + +} + +#endif diff --git a/src/main.cpp b/src/main.cpp index 4c2c8ee..c33047f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,511 +1,228 @@ -#include -#include -#include -#include +#include #include +#include +#include + +#include "helpers/help.h" +#include "helpers/utils.h" #include "classes/Keyboard.h" -using namespace std; -string appname = "g810-led"; - -void usage() { - cout< var; - vector keys; - - lg_kbd.attach(); - - while (!is.eof()) { - getline(is, line); - - if (line.substr(0, 3) == "var") { - line = line.substr(4); - ind = line.find(" "); - var[line.substr(0, ind)] = line.substr(ind + 1, 6); - } else if (line.substr(0, 1) == "a") { - line = line.substr(2); - if (line.substr(0, 1) == "$") { - ind = line.find(" "); - line = var[line.substr(1, ind - 1)]; - } else line = line.substr(0, 6); - if (lg_kbd.parseColor(line, colors) == true) { - keys.clear(); - lg_kbd.setAllKeys(colors); - } else cout<<"Error on line "< vars; + LedKeyboard::KeyValueArray keys = {}; + int retval = 0; + while (!stream.eof()) { + getline(stream, line); + if (line.size() > 0 && line.substr(0, 1) != "#") { + std::vector args = {}; + while (line.size() > 0) { + uint32_t ind = line.find(" "); + std::string argValue = line.substr(0, ind); + if (argValue.substr(0, 1) == "$") argValue = vars[argValue.substr(1)]; + args.push_back(argValue); + if (line.substr(0, ind) == line) line.clear(); + else line = line.substr(ind + 1); + } + if (args[0] == "var" && args.size() > 2) { + vars[args[1]] = args[2]; + } else if (args[0] == "c") { + if (kbd.open()) { + if (keys.size() > 0) { + if (! kbd.setKeys(keys)) retval = 1; + keys.clear(); + } + if(! kbd.commit()) retval = 1; + } else retval = 1; + } else if (args[0] == "a" && args.size() > 1) { + if (setAllKeys(kbd, args[1], false) == 1) retval = 1; + } else if (args[0] == "g" && args.size() > 2) { + if (setGroupKeys(kbd, args[1], args[2], false) == 1) retval = 1; + } else if (args[0] == "k" && args.size() > 2) { + LedKeyboard::Key key; + LedKeyboard::Color color; + if (utils::parseKey(args[1], key)) + if (utils::parseColor(args[2], color)) + keys.push_back({ key, color }); + } 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) { + if (setFX(kbd, args[1], args[2], args[3]) == 1) retval = 1; + } + } + } + return retval; +} + +int loadProfile(LedKeyboard &kbd, char *arg2) { + std::ifstream file; + file.open(arg2); if (file.is_open()) { - int retval = parseProfile(file); + int retval = 0; + retval = parseProfile(kbd, file); file.close(); return retval; } return 1; } -int pipeProfile() { +int pipeProfile(LedKeyboard &kbd) { if (isatty(fileno(stdin))) return 1; - return parseProfile(cin); + return parseProfile(kbd, std::cin); } -int main(int argc, char *argv[]) { - string str = argv[0]; - size_t split = str.find_last_of("/\\"); - str = str.substr(split + 1); - appname = str; + + +int main(int argc, char **argv) { + if (argc > 1) { - string argCmd = argv[1]; - if (argCmd == "-h" || argCmd == "--help") { usage(); return 0; } - else if (argCmd == "-lk" || argCmd == "--list-keys") { listkeys(); return 0; } - else if (argCmd == "-s" && argc == 3) return setStartupEffect(argv[2]); - else if (argCmd == "-a" && argc == 3) return setAllKeys(argv[2], true); - else if (argCmd == "-an" && argc == 3) return setAllKeys(argv[2], false); - else if (argCmd == "-g" && argc == 4) return setGroupKeys(argv[2], argv[3], true); - else if (argCmd == "-gn" && argc == 4) return setGroupKeys(argv[2], argv[3], false); - else if (argCmd == "-k" && argc == 4) return setKey(argv[2], argv[3], true); - else if (argCmd == "-kn" && argc == 4) return setKey(argv[2], argv[3], false); - else if (argCmd == "-c" && argc == 2) return commit(); - else if (argCmd == "-p" && argc == 3) return loadProfile(argv[2]); - else if (argCmd == "-pp" && argc == 2) return pipeProfile(); - else if (argCmd == "-fx-color" && argc == 3) return setFXColor(argv[2], true, true); - else if (argCmd == "-fx-breathing" && argc == 4) return setFXBreathing(argv[2], argv[3], true, true); - else if (argCmd == "-fx-cycle" && argc == 3) return setFXColorCycle(argv[2], true, true); - else if (argCmd == "-fx-hwave" && argc == 3) return setFXHWave(argv[2], true, true); - else if (argCmd == "-fx-vwave" && argc == 3) return setFXVWave(argv[2], true, true); - else if (argCmd == "-fx-cwave" && argc == 3) return setFXCWave(argv[2], true, true); - else if (argCmd == "-fxk-color" && argc == 3) return setFXColor(argv[2], true, false); - else if (argCmd == "-fxk-breathing" && argc == 4) return setFXBreathing(argv[2], argv[3], true, false); - else if (argCmd == "-fxk-cycle" && argc == 3) return setFXColorCycle(argv[2], true, false); - else if (argCmd == "-fxk-hwave" && argc == 3) return setFXHWave(argv[2], true, false); - else if (argCmd == "-fxk-vwave" && argc == 3) return setFXVWave(argv[2], true, false); - else if (argCmd == "-fxk-cwave" && argc == 3) return setFXCWave(argv[2], true, false); - else if (argCmd == "-fxl-color" && argc == 3) return setFXColor(argv[2], false, true); - else if (argCmd == "-fxl-breathing" && argc == 4) return setFXBreathing(argv[2], argv[3], false, true); - else if (argCmd == "-fxl-cycle" && argc == 3) return setFXColorCycle(argv[2], false, true); + + std::string arg = argv[1]; + + if (arg == "--help" || arg == "-h") help::usage(argv[0]); + else if (arg == "--help-keys") help::keys(argv[0]); + else if (arg == "--help-effects") help::effects(argv[0]); + else if (arg == "--help-samples") help::samples(argv[0]); + + else { + LedKeyboard kbd; + if (arg == "--list-keyboards") kbd.listKeyboards(); + else if (arg == "-c") return commit(kbd); + + else if (argc > 2 && arg == "-a") return setAllKeys(kbd, argv[2]); + else if (argc > 3 && arg == "-g") return setGroupKeys(kbd, argv[2], argv[3]); + else if (argc > 3 && arg == "-k") return setKey(kbd, argv[2], argv[3]); + else if (argc > 2 && arg == "-an") return setAllKeys(kbd, argv[2], false); + else if (argc > 3 && arg == "-gn") return setGroupKeys(kbd, argv[2], argv[3], false); + else if (argc > 3 && arg == "-kn") return setKey(kbd, argv[2], argv[3], false); + + else if (argc > 2 && arg == "-p") return loadProfile(kbd, argv[2]); + else if (argc > 1 && arg == "-pp") return pipeProfile(kbd); + + else if (argc > 5 && arg == "-fx") return setFX(kbd, argv[2], argv[3], argv[4], argv[5]); + else if (argc > 4 && arg == "-fx") return setFX(kbd, argv[2], argv[3], argv[4]); + + else if (argc > 2 && arg == "--startup-mode") return setStartupMode(kbd, argv[2]); + + else { help::usage(argv[0]); return 1; } + } + + return 0; + } - usage(); + + help::usage(argv[0]); return 1; }