mirror of
https://github.com/MatMoul/g810-led.git
synced 2024-12-23 09:16:11 +00:00
First commit
This commit is contained in:
commit
fdc8220e70
165
LICENSE
Normal file
165
LICENSE
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
|
||||||
|
This version of the GNU Lesser General Public License incorporates
|
||||||
|
the terms and conditions of version 3 of the GNU General Public
|
||||||
|
License, supplemented by the additional permissions listed below.
|
||||||
|
|
||||||
|
0. Additional Definitions.
|
||||||
|
|
||||||
|
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||||
|
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||||
|
General Public License.
|
||||||
|
|
||||||
|
"The Library" refers to a covered work governed by this License,
|
||||||
|
other than an Application or a Combined Work as defined below.
|
||||||
|
|
||||||
|
An "Application" is any work that makes use of an interface provided
|
||||||
|
by the Library, but which is not otherwise based on the Library.
|
||||||
|
Defining a subclass of a class defined by the Library is deemed a mode
|
||||||
|
of using an interface provided by the Library.
|
||||||
|
|
||||||
|
A "Combined Work" is a work produced by combining or linking an
|
||||||
|
Application with the Library. The particular version of the Library
|
||||||
|
with which the Combined Work was made is also called the "Linked
|
||||||
|
Version".
|
||||||
|
|
||||||
|
The "Minimal Corresponding Source" for a Combined Work means the
|
||||||
|
Corresponding Source for the Combined Work, excluding any source code
|
||||||
|
for portions of the Combined Work that, considered in isolation, are
|
||||||
|
based on the Application, and not on the Linked Version.
|
||||||
|
|
||||||
|
The "Corresponding Application Code" for a Combined Work means the
|
||||||
|
object code and/or source code for the Application, including any data
|
||||||
|
and utility programs needed for reproducing the Combined Work from the
|
||||||
|
Application, but excluding the System Libraries of the Combined Work.
|
||||||
|
|
||||||
|
1. Exception to Section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
You may convey a covered work under sections 3 and 4 of this License
|
||||||
|
without being bound by section 3 of the GNU GPL.
|
||||||
|
|
||||||
|
2. Conveying Modified Versions.
|
||||||
|
|
||||||
|
If you modify a copy of the Library, and, in your modifications, a
|
||||||
|
facility refers to a function or data to be supplied by an Application
|
||||||
|
that uses the facility (other than as an argument passed when the
|
||||||
|
facility is invoked), then you may convey a copy of the modified
|
||||||
|
version:
|
||||||
|
|
||||||
|
a) under this License, provided that you make a good faith effort to
|
||||||
|
ensure that, in the event an Application does not supply the
|
||||||
|
function or data, the facility still operates, and performs
|
||||||
|
whatever part of its purpose remains meaningful, or
|
||||||
|
|
||||||
|
b) under the GNU GPL, with none of the additional permissions of
|
||||||
|
this License applicable to that copy.
|
||||||
|
|
||||||
|
3. Object Code Incorporating Material from Library Header Files.
|
||||||
|
|
||||||
|
The object code form of an Application may incorporate material from
|
||||||
|
a header file that is part of the Library. You may convey such object
|
||||||
|
code under terms of your choice, provided that, if the incorporated
|
||||||
|
material is not limited to numerical parameters, data structure
|
||||||
|
layouts and accessors, or small macros, inline functions and templates
|
||||||
|
(ten or fewer lines in length), you do both of the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the object code that the
|
||||||
|
Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
4. Combined Works.
|
||||||
|
|
||||||
|
You may convey a Combined Work under terms of your choice that,
|
||||||
|
taken together, effectively do not restrict modification of the
|
||||||
|
portions of the Library contained in the Combined Work and reverse
|
||||||
|
engineering for debugging such modifications, if you also do each of
|
||||||
|
the following:
|
||||||
|
|
||||||
|
a) Give prominent notice with each copy of the Combined Work that
|
||||||
|
the Library is used in it and that the Library and its use are
|
||||||
|
covered by this License.
|
||||||
|
|
||||||
|
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||||
|
document.
|
||||||
|
|
||||||
|
c) For a Combined Work that displays copyright notices during
|
||||||
|
execution, include the copyright notice for the Library among
|
||||||
|
these notices, as well as a reference directing the user to the
|
||||||
|
copies of the GNU GPL and this license document.
|
||||||
|
|
||||||
|
d) Do one of the following:
|
||||||
|
|
||||||
|
0) Convey the Minimal Corresponding Source under the terms of this
|
||||||
|
License, and the Corresponding Application Code in a form
|
||||||
|
suitable for, and under terms that permit, the user to
|
||||||
|
recombine or relink the Application with a modified version of
|
||||||
|
the Linked Version to produce a modified Combined Work, in the
|
||||||
|
manner specified by section 6 of the GNU GPL for conveying
|
||||||
|
Corresponding Source.
|
||||||
|
|
||||||
|
1) Use a suitable shared library mechanism for linking with the
|
||||||
|
Library. A suitable mechanism is one that (a) uses at run time
|
||||||
|
a copy of the Library already present on the user's computer
|
||||||
|
system, and (b) will operate properly with a modified version
|
||||||
|
of the Library that is interface-compatible with the Linked
|
||||||
|
Version.
|
||||||
|
|
||||||
|
e) Provide Installation Information, but only if you would otherwise
|
||||||
|
be required to provide such information under section 6 of the
|
||||||
|
GNU GPL, and only to the extent that such information is
|
||||||
|
necessary to install and execute a modified version of the
|
||||||
|
Combined Work produced by recombining or relinking the
|
||||||
|
Application with a modified version of the Linked Version. (If
|
||||||
|
you use option 4d0, the Installation Information must accompany
|
||||||
|
the Minimal Corresponding Source and Corresponding Application
|
||||||
|
Code. If you use option 4d1, you must provide the Installation
|
||||||
|
Information in the manner specified by section 6 of the GNU GPL
|
||||||
|
for conveying Corresponding Source.)
|
||||||
|
|
||||||
|
5. Combined Libraries.
|
||||||
|
|
||||||
|
You may place library facilities that are a work based on the
|
||||||
|
Library side by side in a single library together with other library
|
||||||
|
facilities that are not Applications and are not covered by this
|
||||||
|
License, and convey such a combined library under terms of your
|
||||||
|
choice, if you do both of the following:
|
||||||
|
|
||||||
|
a) Accompany the combined library with a copy of the same work based
|
||||||
|
on the Library, uncombined with any other library facilities,
|
||||||
|
conveyed under the terms of this License.
|
||||||
|
|
||||||
|
b) Give prominent notice with the combined library that part of it
|
||||||
|
is a work based on the Library, and explaining where to find the
|
||||||
|
accompanying uncombined form of the same work.
|
||||||
|
|
||||||
|
6. Revised Versions of the GNU Lesser General Public License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the GNU Lesser General Public License from time to time. Such new
|
||||||
|
versions will be similar in spirit to the present version, but may
|
||||||
|
differ in detail to address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Library as you received it specifies that a certain numbered version
|
||||||
|
of the GNU Lesser General Public License "or any later version"
|
||||||
|
applies to it, you have the option of following the terms and
|
||||||
|
conditions either of that published version or of any later version
|
||||||
|
published by the Free Software Foundation. If the Library as you
|
||||||
|
received it does not specify a version number of the GNU Lesser
|
||||||
|
General Public License, you may choose any version of the GNU Lesser
|
||||||
|
General Public License ever published by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Library as you received it specifies that a proxy can decide
|
||||||
|
whether future versions of the GNU Lesser General Public License shall
|
||||||
|
apply, that proxy's public statement of acceptance of any version is
|
||||||
|
permanent authorization for you to choose that version for the
|
||||||
|
Library.
|
8
README.md
Normal file
8
README.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# g810-led
|
||||||
|
|
||||||
|
Linux led controller for the Logitech G810 Keyboard
|
||||||
|
|
||||||
|
(The old python project have moded to https://github.com/MatMoul/g810-led-python/)
|
||||||
|
|
||||||
|
Dependencies :</br>
|
||||||
|
- lib-usb
|
15
makefile
Normal file
15
makefile
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
CC=g++
|
||||||
|
CFLAGS=
|
||||||
|
LDFLAGS=-lusb-1.0
|
||||||
|
|
||||||
|
|
||||||
|
all: bin/g810-led
|
||||||
|
|
||||||
|
bin/g810-led: src/main.cpp src/classes/*
|
||||||
|
$(CC) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf *.o
|
||||||
|
|
||||||
|
mrproper: clean
|
||||||
|
rm -rf $(EXEC)
|
5
sample_profiles/all_blue
Normal file
5
sample_profiles/all_blue
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Blue Profile
|
||||||
|
|
||||||
|
a 0000ff # Set all keys blue
|
||||||
|
|
||||||
|
c # Commit changes
|
5
sample_profiles/all_green
Normal file
5
sample_profiles/all_green
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Green Profile
|
||||||
|
|
||||||
|
a 00ff00 # Set all keys green
|
||||||
|
|
||||||
|
c # Commit changes
|
5
sample_profiles/all_off
Normal file
5
sample_profiles/all_off
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Off Profile
|
||||||
|
|
||||||
|
a 000000 # Set all keys off
|
||||||
|
|
||||||
|
c # Commit changes
|
5
sample_profiles/all_red
Normal file
5
sample_profiles/all_red
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Red Profile
|
||||||
|
|
||||||
|
a ff0000 # Set all keys red
|
||||||
|
|
||||||
|
c # Commit changes
|
13
sample_profiles/group_keys
Normal file
13
sample_profiles/group_keys
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Sample profile by groups keys
|
||||||
|
|
||||||
|
g logo 000096
|
||||||
|
g indicators 00ffff
|
||||||
|
g multimedia 009600
|
||||||
|
g fkeys ff00ff
|
||||||
|
g modifiers ff0000
|
||||||
|
g arrows ffff00
|
||||||
|
g numeric 00ffff
|
||||||
|
g functions ffffff
|
||||||
|
g keys 009696
|
||||||
|
|
||||||
|
c # Commit changes
|
129
sample_profiles/keys_v_gradiant
Normal file
129
sample_profiles/keys_v_gradiant
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
# Sample profile vertical gradiant with vars and keys
|
||||||
|
|
||||||
|
# Vars :
|
||||||
|
var raw0 00ffff
|
||||||
|
var raw1 960096
|
||||||
|
var raw2 600096
|
||||||
|
var raw3 300096
|
||||||
|
var raw4 000096
|
||||||
|
var raw5 003096
|
||||||
|
var raw6 006096
|
||||||
|
|
||||||
|
|
||||||
|
# Raw 0 :
|
||||||
|
g logo $raw0
|
||||||
|
g indicators $raw0
|
||||||
|
k mute $raw0
|
||||||
|
|
||||||
|
# Raw 1 :
|
||||||
|
k esc $raw1
|
||||||
|
g fkeys $raw1
|
||||||
|
k printscreen $raw1
|
||||||
|
k scrolllock $raw1
|
||||||
|
k pausebreak $raw1
|
||||||
|
k play $raw1
|
||||||
|
k stop $raw1
|
||||||
|
k prev $raw1
|
||||||
|
k next $raw1
|
||||||
|
|
||||||
|
# Raw 2 :
|
||||||
|
k ° $raw2
|
||||||
|
k 1 $raw2
|
||||||
|
k 2 $raw2
|
||||||
|
k 3 $raw2
|
||||||
|
k 4 $raw2
|
||||||
|
k 5 $raw2
|
||||||
|
k 6 $raw2
|
||||||
|
k 7 $raw2
|
||||||
|
k 8 $raw2
|
||||||
|
k 9 $raw2
|
||||||
|
k 0 $raw2
|
||||||
|
k ? $raw2
|
||||||
|
k tidle $raw2
|
||||||
|
k backspace $raw2
|
||||||
|
k insert $raw2
|
||||||
|
k home $raw2
|
||||||
|
k pageup $raw2
|
||||||
|
k numlock $raw2
|
||||||
|
k numslash $raw2
|
||||||
|
k numasterisk $raw2
|
||||||
|
k numminus $raw2
|
||||||
|
|
||||||
|
# Raw 3 :
|
||||||
|
k tab $raw3
|
||||||
|
k q $raw3
|
||||||
|
k w $raw3
|
||||||
|
k e $raw3
|
||||||
|
k r $raw3
|
||||||
|
k t $raw3
|
||||||
|
k z $raw3
|
||||||
|
k u $raw3
|
||||||
|
k i $raw3
|
||||||
|
k o $raw3
|
||||||
|
k p $raw3
|
||||||
|
k è $raw3
|
||||||
|
k ¨ $raw3
|
||||||
|
k delete $raw3
|
||||||
|
k end $raw3
|
||||||
|
k pagedown $raw3
|
||||||
|
k num7 $raw3
|
||||||
|
k num8 $raw3
|
||||||
|
k num9 $raw3
|
||||||
|
|
||||||
|
# Raw 4 :
|
||||||
|
k capslock $raw4
|
||||||
|
k a $raw4
|
||||||
|
k s $raw4
|
||||||
|
k d $raw4
|
||||||
|
k f $raw4
|
||||||
|
k g $raw4
|
||||||
|
k h $raw4
|
||||||
|
k j $raw4
|
||||||
|
k k $raw4
|
||||||
|
k l $raw4
|
||||||
|
k é $raw4
|
||||||
|
k à $raw4
|
||||||
|
k $ $raw4
|
||||||
|
k enter $raw4
|
||||||
|
k num4 $raw4
|
||||||
|
k num5 $raw4
|
||||||
|
k num6 $raw4
|
||||||
|
k num+ $raw4
|
||||||
|
|
||||||
|
# Raw 5 :
|
||||||
|
k shiftl $raw5
|
||||||
|
k < $raw5
|
||||||
|
k y $raw5
|
||||||
|
k x $raw5
|
||||||
|
k c $raw5
|
||||||
|
k v $raw5
|
||||||
|
k b $raw5
|
||||||
|
k n $raw5
|
||||||
|
k m $raw5
|
||||||
|
k , $raw5
|
||||||
|
k . $raw5
|
||||||
|
k - $raw5
|
||||||
|
k shiftr $raw5
|
||||||
|
k top $raw5
|
||||||
|
k num1 $raw5
|
||||||
|
k num2 $raw5
|
||||||
|
k num3 $raw5
|
||||||
|
|
||||||
|
# Raw 6 :
|
||||||
|
k ctrll $raw6
|
||||||
|
k winl $raw6
|
||||||
|
k altl $raw6
|
||||||
|
k space $raw6
|
||||||
|
k altr $raw6
|
||||||
|
k winr $raw6
|
||||||
|
k menu $raw6
|
||||||
|
k ctrlr $raw6
|
||||||
|
k left $raw6
|
||||||
|
k bottom $raw6
|
||||||
|
k right $raw6
|
||||||
|
k num0 $raw6
|
||||||
|
k num. $raw6
|
||||||
|
k numenter $raw6
|
||||||
|
|
||||||
|
# Commit
|
||||||
|
c
|
968
src/classes/Keyboard.cpp
Normal file
968
src/classes/Keyboard.cpp
Normal file
@ -0,0 +1,968 @@
|
|||||||
|
#include "Keyboard.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "/usr/include/libusb-1.0/libusb.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
bool Keyboard::isAttached() {
|
||||||
|
return m_isAttached;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Keyboard::attach() {
|
||||||
|
if (m_isAttached == true) return false;
|
||||||
|
int r;
|
||||||
|
r = libusb_init(&ctx);
|
||||||
|
if (r < 0) return false;
|
||||||
|
dev_handle = libusb_open_device_with_vid_pid(ctx, 0x046d, 0xc331);
|
||||||
|
if (dev_handle == NULL) {
|
||||||
|
libusb_exit(ctx);
|
||||||
|
ctx = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(libusb_kernel_driver_active(dev_handle, 1) == 1) {
|
||||||
|
libusb_detach_kernel_driver(dev_handle, 1);
|
||||||
|
m_isKernellDetached = true;
|
||||||
|
}
|
||||||
|
r = libusb_claim_interface(dev_handle, 1);
|
||||||
|
if(r < 0) return false;
|
||||||
|
m_isAttached = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Keyboard::detach() {
|
||||||
|
if (m_isAttached == false) return false;
|
||||||
|
int r;
|
||||||
|
r = libusb_release_interface(dev_handle, 1);
|
||||||
|
if(r!=0) return false;
|
||||||
|
if(m_isKernellDetached==true) {
|
||||||
|
libusb_attach_kernel_driver(dev_handle, 1);
|
||||||
|
m_isKernellDetached = false;
|
||||||
|
}
|
||||||
|
libusb_close(dev_handle);
|
||||||
|
dev_handle = NULL;
|
||||||
|
libusb_exit(ctx);
|
||||||
|
ctx = NULL;
|
||||||
|
m_isAttached = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Keyboard::commit() {
|
||||||
|
if (m_isAttached == false) return false;
|
||||||
|
unsigned char *data = new unsigned char[20-1];
|
||||||
|
data[0] = 0x11;
|
||||||
|
data[1] = 0xff;
|
||||||
|
data[2] = 0x0c;
|
||||||
|
data[3] = 0x5a;
|
||||||
|
return sendDataInternal(data, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Keyboard::getKeyAddress(Key key, KeyAddress &keyAddress) {
|
||||||
|
switch (key) {
|
||||||
|
case Key::logo:
|
||||||
|
keyAddress.addressGroup = KeyAddressGroup::logo;
|
||||||
|
keyAddress.id = 0x01;
|
||||||
|
break;
|
||||||
|
case Key::backlight:
|
||||||
|
keyAddress.addressGroup = KeyAddressGroup::indicators;
|
||||||
|
keyAddress.id = 0x01;
|
||||||
|
break;
|
||||||
|
case Key::game:
|
||||||
|
keyAddress.addressGroup = KeyAddressGroup::indicators;
|
||||||
|
keyAddress.id = 0x02;
|
||||||
|
break;
|
||||||
|
case Key::caps:
|
||||||
|
keyAddress.addressGroup = KeyAddressGroup::indicators;
|
||||||
|
keyAddress.id = 0x03;
|
||||||
|
break;
|
||||||
|
case Key::scroll:
|
||||||
|
keyAddress.addressGroup = KeyAddressGroup::indicators;
|
||||||
|
keyAddress.id = 0x04;
|
||||||
|
break;
|
||||||
|
case Key::num:
|
||||||
|
keyAddress.addressGroup = KeyAddressGroup::indicators;
|
||||||
|
keyAddress.id = 0x05;
|
||||||
|
break;
|
||||||
|
case Key::next:
|
||||||
|
keyAddress.addressGroup = KeyAddressGroup::multimedia;
|
||||||
|
keyAddress.id = 0xb5;
|
||||||
|
break;
|
||||||
|
case Key::prev:
|
||||||
|
keyAddress.addressGroup = KeyAddressGroup::multimedia;
|
||||||
|
keyAddress.id = 0xb6;
|
||||||
|
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;
|
||||||
|
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::z: keyAddress.id = 0x1c; break;
|
||||||
|
case Key::y: 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::apostrophe: keyAddress.id = 0x2d; break; // *
|
||||||
|
case Key::tidle: keyAddress.id = 0x2e; break;
|
||||||
|
case Key::open_bracket: keyAddress.id = 0x2f; break;
|
||||||
|
case Key::close_bracket: keyAddress.id = 0x30; break;
|
||||||
|
case Key::unknown: keyAddress.id = 0x31; break; // *
|
||||||
|
case Key::dollar: keyAddress.id = 0x32; break; // *
|
||||||
|
case Key::eaigu: keyAddress.id = 0x33; break; // *
|
||||||
|
case Key::agrave: keyAddress.id = 0x34; break; // *
|
||||||
|
case Key::degree: keyAddress.id = 0x35; break; // *
|
||||||
|
case Key::comma: keyAddress.id = 0x36; break;
|
||||||
|
case Key::dot: keyAddress.id = 0x37; break;
|
||||||
|
case Key::minus: 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::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;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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 == "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 == "'" || key == "?") parsedKey = Key::apostrophe;
|
||||||
|
else if (key == "tidle" || key == "^" || key == "~") parsedKey = Key::tidle;
|
||||||
|
else if (key == "open_bracket" || key == "openbracket" || key == "è" || key == "ü") parsedKey = Key::open_bracket;
|
||||||
|
else if (key == "close_bracket" || key == "closebracket" || key == "¨" || key == "!") parsedKey = Key::close_bracket;
|
||||||
|
else if (key == "unknown") parsedKey = Key::unknown; // Not on my keyboard
|
||||||
|
else if (key == "$" || key == "dollar") parsedKey = Key::dollar;
|
||||||
|
else if (key == "é" || key == "ö") parsedKey = Key::eaigu;
|
||||||
|
else if (key == "à" || key == "ä") parsedKey = Key::agrave;
|
||||||
|
else if (key == "§" || key == "°") parsedKey = Key::degree;
|
||||||
|
else if (key == "," || key == "comma") parsedKey = Key::comma;
|
||||||
|
else if (key == "." || key == "dot") parsedKey = Key::dot;
|
||||||
|
else if (key == "-" || key == "minus") parsedKey = Key::minus;
|
||||||
|
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_dot" || key == "numdot") parsedKey = Key::num_dot;
|
||||||
|
else if (key == "<" || key == ">" || key == "\\" || key == "backslash") parsedKey = Key::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 return false;
|
||||||
|
return getKeyAddress(parsedKey, keyAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 == "raw0") keyGroup = KeyGroup::raw0;
|
||||||
|
else if (key == "raw1") keyGroup = KeyGroup::raw1;
|
||||||
|
else if (key == "raw2") keyGroup = KeyGroup::raw2;
|
||||||
|
else if (key == "raw3") keyGroup = KeyGroup::raw3;
|
||||||
|
else if (key == "raw4") keyGroup = KeyGroup::raw4;
|
||||||
|
else if (key == "raw5") keyGroup = KeyGroup::raw5;
|
||||||
|
else if (key == "raw6") keyGroup = KeyGroup::raw6;
|
||||||
|
else return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Keyboard::parseColor(std::string color, KeyColors &colors) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Need work arround sleep and/or updatekeys ????
|
||||||
|
bool Keyboard::sendDataInternal(unsigned char *data, int data_size) {
|
||||||
|
if (m_isAttached == false) return false;
|
||||||
|
int r;
|
||||||
|
r = libusb_control_transfer(dev_handle, 0x21, 0x09, 0x0211, 1, data, data_size, 0);
|
||||||
|
//sleep(0.01);
|
||||||
|
//sleep(0.5);
|
||||||
|
if (r < 0) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Keyboard::populateAddressGroupInternal(KeyAddressGroup addressGroup, unsigned char *data) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Possible Bug
|
||||||
|
bool Keyboard::setKeysInternal(KeyAddressGroup addressGroup, KeyValue keyValues[], int keyValueCount) {
|
||||||
|
unsigned char *data;
|
||||||
|
int data_size;
|
||||||
|
if (addressGroup == KeyAddressGroup::logo) {
|
||||||
|
data_size = 20;
|
||||||
|
data = new unsigned char[data_size - 1];
|
||||||
|
populateAddressGroupInternal(addressGroup, data);
|
||||||
|
data[8] = keyValues[0].key.id;
|
||||||
|
data[9] = keyValues[0].colors.red;
|
||||||
|
data[10] = keyValues[0].colors.green;
|
||||||
|
data[11] = keyValues[0].colors.blue;
|
||||||
|
for(int i = 12; i < data_size; i++) data[i] = 0x00;
|
||||||
|
} else {
|
||||||
|
data_size = 108;
|
||||||
|
data = new unsigned char[data_size - 1];
|
||||||
|
populateAddressGroupInternal(addressGroup, data);
|
||||||
|
int maxKeyValueCount = (data_size - 8) / 4;
|
||||||
|
if (keyValueCount > maxKeyValueCount) keyValueCount = maxKeyValueCount;
|
||||||
|
for(int 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sendDataInternal(data, data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Keyboard::setPowerOnEffect(PowerOnEffect powerOnEffect) {
|
||||||
|
int data_size = 20;
|
||||||
|
unsigned char *data = new unsigned char[data_size - 1];
|
||||||
|
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
|
||||||
|
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;
|
||||||
|
return sendDataInternal(data, data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Keyboard::setKey(KeyValue keyValue) {
|
||||||
|
unsigned char *data;
|
||||||
|
int data_size;
|
||||||
|
if (keyValue.key.addressGroup == KeyAddressGroup::logo) {
|
||||||
|
data_size = 20;
|
||||||
|
data = new unsigned char[data_size - 1];
|
||||||
|
populateAddressGroupInternal(keyValue.key.addressGroup, data);
|
||||||
|
} else {
|
||||||
|
data_size = 108;
|
||||||
|
data = new unsigned char[data_size - 1];
|
||||||
|
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;
|
||||||
|
return sendDataInternal(data, data_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Keyboard::setKey(Key key, KeyColors colors) {
|
||||||
|
KeyValue keyValue;
|
||||||
|
getKeyAddress(key, keyValue.key);
|
||||||
|
keyValue.colors = colors;
|
||||||
|
return setKey(keyValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: maxKeyValueCount = 12 or 13, Why ?
|
||||||
|
bool Keyboard::setKeys(KeyValue keyValue[], int keyValueCount) {
|
||||||
|
KeyValue logo[5];
|
||||||
|
int logoCount = 0;
|
||||||
|
KeyValue indicators[25];
|
||||||
|
int indicatorsCount = 0;
|
||||||
|
KeyValue multimedia[25];
|
||||||
|
int multimediaCount = 0;
|
||||||
|
KeyValue keys[200];
|
||||||
|
int keysCount = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < keyValueCount; i++) {
|
||||||
|
if(keyValue[i].key.addressGroup == KeyAddressGroup::logo) {
|
||||||
|
logo[logoCount] = keyValue[i];
|
||||||
|
logoCount++;
|
||||||
|
} else if(keyValue[i].key.addressGroup == KeyAddressGroup::indicators) {
|
||||||
|
indicators[indicatorsCount] = keyValue[i];
|
||||||
|
indicatorsCount++;
|
||||||
|
} else if(keyValue[i].key.addressGroup == KeyAddressGroup::multimedia) {
|
||||||
|
multimedia[multimediaCount] = keyValue[i];
|
||||||
|
multimediaCount++;
|
||||||
|
} else if(keyValue[i].key.addressGroup == KeyAddressGroup::keys) {
|
||||||
|
keys[keysCount] = keyValue[i];
|
||||||
|
keysCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logoCount > 0) setKey(logo[logoCount - 1]);
|
||||||
|
if (indicatorsCount > 0) {
|
||||||
|
for (int i = 0; i < indicatorsCount; i++) {
|
||||||
|
setKeysInternal(KeyAddressGroup::indicators, indicators, indicatorsCount);
|
||||||
|
commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (multimediaCount > 0) {
|
||||||
|
for (int i = 0; i < multimediaCount; i++) {
|
||||||
|
setKeysInternal(KeyAddressGroup::multimedia, multimedia, multimediaCount);
|
||||||
|
commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (keysCount > 0) {
|
||||||
|
int maxKeyValueCount = 2;
|
||||||
|
//int maxKeyValueCount = 4;
|
||||||
|
//int maxKeyValueCount = 10;
|
||||||
|
//int maxKeyValueCount = 12;
|
||||||
|
//int maxKeyValueCount = 13;
|
||||||
|
//int maxKeyValueCount = 14; Don't work
|
||||||
|
//int maxKeyValueCount = 20;
|
||||||
|
for (int i = 0; i < keysCount; i = i + maxKeyValueCount - 1) {
|
||||||
|
KeyValue keysBlock[maxKeyValueCount];
|
||||||
|
int keysBlockCount = 0;
|
||||||
|
for (int j = 0; j < maxKeyValueCount; j++) {
|
||||||
|
keysBlock[j] = keys[i + j];
|
||||||
|
keysBlockCount++;
|
||||||
|
}
|
||||||
|
setKeysInternal(KeyAddressGroup::keys, keysBlock, keysBlockCount);
|
||||||
|
commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Keyboard::setAllKeys(KeyColors colors) {
|
||||||
|
KeyValue keyValues[118];
|
||||||
|
for (int i = 0; i < 118; i++) {
|
||||||
|
getKeyAddress((Key)i, keyValues[i].key);
|
||||||
|
keyValues[i].colors = colors;
|
||||||
|
}
|
||||||
|
setKeys(keyValues, 118);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Keyboard::setGroupKeys(KeyGroup keyGroup, KeyColors colors) {
|
||||||
|
KeyValue keyValues[118];
|
||||||
|
int keyValuesCount = 0;
|
||||||
|
switch (keyGroup) {
|
||||||
|
case KeyGroup::logo:
|
||||||
|
setKey(Key::logo, colors);
|
||||||
|
break;
|
||||||
|
case KeyGroup::indicators:
|
||||||
|
for (int i = 1; i < 6; i++) {
|
||||||
|
getKeyAddress((Key)i, keyValues[i - 1].key);
|
||||||
|
keyValues[i - 1].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
}
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
case KeyGroup::multimedia:
|
||||||
|
for (int i = 6; i < 11; i++) {
|
||||||
|
getKeyAddress((Key)i, keyValues[i - 6].key);
|
||||||
|
keyValues[i - 6].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
}
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
case KeyGroup::fkeys:
|
||||||
|
for (int i = 11; i < 23; i++) {
|
||||||
|
getKeyAddress((Key)i, keyValues[i - 11].key);
|
||||||
|
keyValues[i - 11].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
}
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
case KeyGroup::modifiers:
|
||||||
|
for (int i = 23; i < 32; i++) {
|
||||||
|
getKeyAddress((Key)i, keyValues[i - 23].key);
|
||||||
|
keyValues[i - 23].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
}
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
case KeyGroup::arrows:
|
||||||
|
for (int i = 32; i < 36; i++) {
|
||||||
|
getKeyAddress((Key)i, keyValues[i - 32].key);
|
||||||
|
keyValues[i - 32].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
}
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
case KeyGroup::numeric:
|
||||||
|
for (int i = 36; i < 53; i++) {
|
||||||
|
getKeyAddress((Key)i, keyValues[i - 36].key);
|
||||||
|
keyValues[i - 36].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
}
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
case KeyGroup::functions:
|
||||||
|
for (int i = 53; i < 63; i++) {
|
||||||
|
getKeyAddress((Key)i, keyValues[i - 53].key);
|
||||||
|
keyValues[i - 53].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
}
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
case KeyGroup::keys:
|
||||||
|
for (int i = 63; i < 118; i++) {
|
||||||
|
getKeyAddress((Key)i, keyValues[i - 63].key);
|
||||||
|
keyValues[i - 63].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
}
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
case KeyGroup::raw0:
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
getKeyAddress((Key)i, keyValues[i].key);
|
||||||
|
keyValues[i].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
}
|
||||||
|
getKeyAddress(Key::mute, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
case KeyGroup::raw1:
|
||||||
|
getKeyAddress(Key::esc, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
for (int i = 11; i < 23; i++) {
|
||||||
|
getKeyAddress((Key)i, keyValues[i - 11 + 1].key);
|
||||||
|
keyValues[i - 11 + 1].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
}
|
||||||
|
getKeyAddress(Key::print_screen, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::scroll_lock, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::pause_break, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
for (int i = 7; i < 11; i++) {
|
||||||
|
getKeyAddress((Key)i, keyValues[i - 7 + 16].key);
|
||||||
|
keyValues[i - 7 + 16].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
}
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
case KeyGroup::raw2:
|
||||||
|
getKeyAddress(Key::degree, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
for (int i = 63; i < 73; i++) {
|
||||||
|
getKeyAddress((Key)i, keyValues[i - 63 + 1].key);
|
||||||
|
keyValues[i - 63 + 1].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
}
|
||||||
|
getKeyAddress(Key::apostrophe, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::tidle, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::backspace, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::insert, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::home, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::page_up, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_lock, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_slash, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_asterisk, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_minus, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
case KeyGroup::raw3:
|
||||||
|
getKeyAddress(Key::tab, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::q, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::w, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::e, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::r, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::t, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::z, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::u, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::i, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::o, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::p, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::open_bracket, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::close_bracket, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::del, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::end, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::page_down, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_7, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_8, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_9, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
case KeyGroup::raw4:
|
||||||
|
getKeyAddress(Key::caps_lock, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::a, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::s, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::d, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::f, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::g, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::h, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::j, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::k, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::l, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::eaigu, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::agrave, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::dollar, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::enter, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_4, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_5, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_6, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_plus, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
case KeyGroup::raw5:
|
||||||
|
getKeyAddress(Key::shift_left, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::backslash, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::y, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::x, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::c, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::v, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::b, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::n, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::m, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::comma, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::dot, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::minus, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::shift_right, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::arrow_top, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_1, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_2, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_3, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
case KeyGroup::raw6:
|
||||||
|
getKeyAddress(Key::ctrl_left, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::win_left, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::alt_left, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::space, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::alt_right, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::win_right, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::menu, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::ctrl_right, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::arrow_left, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::arrow_bottom, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::arrow_right, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_0, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_dot, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
getKeyAddress(Key::num_enter, keyValues[keyValuesCount].key);
|
||||||
|
keyValues[keyValuesCount].colors = colors;
|
||||||
|
keyValuesCount++;
|
||||||
|
setKeys(keyValues, keyValuesCount);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
66
src/classes/Keyboard.h
Normal file
66
src/classes/Keyboard.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#ifndef DEF_KEYBOARD
|
||||||
|
#define DEF_KEYBOARD
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include "/usr/include/libusb-1.0/libusb.h"
|
||||||
|
|
||||||
|
class Keyboard {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum class PowerOnEffect { rainbow, color };
|
||||||
|
enum class KeyAddressGroup { logo, indicators, multimedia, keys };
|
||||||
|
enum class Key { // 118 items
|
||||||
|
logo,
|
||||||
|
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,
|
||||||
|
unknown, egrave, eaigu, agrave, dollar, apostrophe, degree, backslash, // Need best names
|
||||||
|
comma, dot, minus, open_bracket, close_bracket, tidle
|
||||||
|
};
|
||||||
|
enum class KeyGroup { logo, indicators, multimedia, fkeys, modifiers, arrows, numeric, functions, keys, raw0, raw1, raw2, raw3, raw4, raw5, raw6 };
|
||||||
|
|
||||||
|
struct KeyColors { char red; char green; char blue; };
|
||||||
|
struct KeyAddress { KeyAddressGroup addressGroup; char id; };
|
||||||
|
struct KeyValue { KeyAddress key; KeyColors colors; };
|
||||||
|
|
||||||
|
bool isAttached();
|
||||||
|
bool attach();
|
||||||
|
bool detach();
|
||||||
|
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 setPowerOnEffect(PowerOnEffect powerOnEffect);
|
||||||
|
bool setKey(KeyValue keyValue);
|
||||||
|
bool setKey(Key key, KeyColors colors);
|
||||||
|
bool setKeys(KeyValue keyValue[], int keyValueCount);
|
||||||
|
bool setAllKeys(KeyColors colors);
|
||||||
|
bool setGroupKeys(KeyGroup keyGroup, KeyColors colors);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool m_isAttached = false;
|
||||||
|
bool m_isKernellDetached = false;
|
||||||
|
libusb_device **devs;
|
||||||
|
libusb_device_handle *dev_handle;
|
||||||
|
libusb_context *ctx = NULL;
|
||||||
|
|
||||||
|
bool populateAddressGroupInternal(KeyAddressGroup addressGroup, unsigned char *data);
|
||||||
|
bool sendDataInternal(unsigned char *data, int data_size);
|
||||||
|
bool setKeysInternal(KeyAddressGroup addressGroup, KeyValue keyValues[], int keyValueCount);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
225
src/main.cpp
Normal file
225
src/main.cpp
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
//#include <stdlib.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <fstream>
|
||||||
|
#include "classes/Keyboard.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
void usage() {
|
||||||
|
cout<<"g810-led Usages :\n";
|
||||||
|
cout<<"-----------------\n";
|
||||||
|
cout<<"\n";
|
||||||
|
cout<<" -s effect :\t\tSet keyboard startup effect\n";
|
||||||
|
cout<<"\n";
|
||||||
|
cout<<" -a color :\t\tSet all keys\n";
|
||||||
|
cout<<" -g group, color :\tSet a group of keys\n";
|
||||||
|
cout<<" -k key, color :\tSet a key\n";
|
||||||
|
cout<<"\n";
|
||||||
|
cout<<" -an color :\t\tSet all keys without commit\n";
|
||||||
|
cout<<" -gn group, color :\tSet a group of keys without commit\n";
|
||||||
|
cout<<" -kn key, color :\tSet a key without commit\n";
|
||||||
|
cout<<"\n";
|
||||||
|
cout<<" -c :\t\t\tCommit changes\n";
|
||||||
|
cout<<"\n";
|
||||||
|
cout<<" -p porfilefile :\tLoad a profile\n";
|
||||||
|
cout<<"\n";
|
||||||
|
cout<<" -h | --help :\t\tthis help message\n";
|
||||||
|
cout<<"\n";
|
||||||
|
cout<<"color formats :\t\tRRGGBB (hex value for red, green and blue)\n";
|
||||||
|
cout<<"\n";
|
||||||
|
cout<<"effect values :\t\trainbow, color\n";
|
||||||
|
cout<<"key values :\t\tabc... 123... and other\n";
|
||||||
|
cout<<"group values :\t\tlogo, indicators, fkeys, modifiers, multimedia, arrows, numeric, functions, keys\n";
|
||||||
|
cout<<"\t\t\traw0, raw1, raw2, raw3, raw4, raw5, raw6\n";
|
||||||
|
cout<<"\n";
|
||||||
|
cout<<"sample :\n";
|
||||||
|
cout<<"g810-led -k logo ff0000\n";
|
||||||
|
cout<<"g810-led -a 00ff00\n";
|
||||||
|
cout<<"g810-led -g fkeys ff00ff\n";
|
||||||
|
cout<<"g810-led -s color\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
int commit() {
|
||||||
|
Keyboard g810;
|
||||||
|
g810.attach();
|
||||||
|
g810.commit();
|
||||||
|
g810.detach();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int setStartupEffect(string effect) {
|
||||||
|
Keyboard g810;
|
||||||
|
Keyboard::PowerOnEffect powerOnEffect;
|
||||||
|
if (g810.parsePowerOnEffect(effect, powerOnEffect) == true) {
|
||||||
|
g810.attach();
|
||||||
|
g810.setPowerOnEffect(powerOnEffect);
|
||||||
|
g810.commit();
|
||||||
|
g810.detach();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int setKey(string key, string color, bool commit) {
|
||||||
|
Keyboard g810;
|
||||||
|
Keyboard::KeyAddress keyAddress;
|
||||||
|
if (g810.parseKey(key, keyAddress) == true) {
|
||||||
|
Keyboard::KeyColors colors;
|
||||||
|
if (g810.parseColor(color, colors) == true) {
|
||||||
|
Keyboard::KeyValue keyValue;
|
||||||
|
keyValue.key = keyAddress;
|
||||||
|
keyValue.colors = colors;
|
||||||
|
g810.attach();
|
||||||
|
g810.setKey(keyValue);
|
||||||
|
if (commit == true) g810.commit();
|
||||||
|
g810.detach();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int setAllKeys(string color, bool commit) {
|
||||||
|
Keyboard g810;
|
||||||
|
Keyboard::KeyColors colors;
|
||||||
|
if (g810.parseColor(color, colors) == true) {
|
||||||
|
g810.attach();
|
||||||
|
g810.setAllKeys(colors);
|
||||||
|
if (commit == true) g810.commit();
|
||||||
|
g810.detach();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int setGroupKeys(string groupKeys, string color, bool commit) {
|
||||||
|
Keyboard g810;
|
||||||
|
Keyboard::KeyGroup keyGroup;
|
||||||
|
if (g810.parseKeyGroup(groupKeys, keyGroup) == true) {
|
||||||
|
Keyboard::KeyColors colors;
|
||||||
|
if (g810.parseColor(color, colors) == true) {
|
||||||
|
g810.attach();
|
||||||
|
g810.setGroupKeys(keyGroup, colors);
|
||||||
|
if (commit == true) g810.commit();
|
||||||
|
g810.detach();
|
||||||
|
//delete [] g810;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int loadProfile(string profileFile) {
|
||||||
|
ifstream file;
|
||||||
|
|
||||||
|
file.open(profileFile);
|
||||||
|
if (file.is_open()) {
|
||||||
|
|
||||||
|
string line;
|
||||||
|
int lineCount = 1;
|
||||||
|
int ind;
|
||||||
|
bool commit;
|
||||||
|
|
||||||
|
Keyboard g810;
|
||||||
|
Keyboard::KeyGroup keyGroup;
|
||||||
|
Keyboard::KeyAddress keyAddress;
|
||||||
|
Keyboard::KeyValue keyValue;
|
||||||
|
Keyboard::KeyColors colors;
|
||||||
|
|
||||||
|
map<string, string> var;
|
||||||
|
vector<Keyboard::KeyValue> keys;
|
||||||
|
|
||||||
|
g810.attach();
|
||||||
|
|
||||||
|
while (!file.eof()) {
|
||||||
|
getline(file, 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 (g810.parseColor(line, colors) == true) {
|
||||||
|
keys.clear();
|
||||||
|
g810.setAllKeys(colors);
|
||||||
|
} else cout<<"Error on line "<<lineCount<<" : "<<line<<"\n";
|
||||||
|
} else if (line.substr(0,1) == "g") {
|
||||||
|
line = line.substr(2);
|
||||||
|
ind = line.find(" ");
|
||||||
|
if (g810.parseKeyGroup(line.substr(0, ind), keyGroup) == true) {
|
||||||
|
line = line.substr(ind + 1);
|
||||||
|
if (line.substr(0, 1) == "$") {
|
||||||
|
ind = line.find(" ");
|
||||||
|
line = var[line.substr(1, ind - 1)];
|
||||||
|
};
|
||||||
|
if (g810.parseColor(line.substr(0, 6), colors) == true) {
|
||||||
|
g810.setGroupKeys(keyGroup, colors);
|
||||||
|
} else cout<<"Error on line "<<lineCount<<" : "<<line<<"\n";
|
||||||
|
} else cout<<"Error on line "<<lineCount<<" : "<<line<<"\n";
|
||||||
|
} else if (line.substr(0,1) == "k") {
|
||||||
|
line = line.substr(2);
|
||||||
|
ind = line.find(" ");
|
||||||
|
if (g810.parseKey(line.substr(0, ind), keyAddress) == true) {
|
||||||
|
line = line.substr(ind + 1);
|
||||||
|
if (line.substr(0, 1) == "$") {
|
||||||
|
ind = line.find(" ");
|
||||||
|
line = var[line.substr(1, ind - 1)];
|
||||||
|
}
|
||||||
|
if (g810.parseColor(line.substr(0, 6), colors) == true) {
|
||||||
|
keyValue.key = keyAddress;
|
||||||
|
keyValue.colors = colors;
|
||||||
|
keys.push_back(keyValue);
|
||||||
|
} else cout<<"Error on line "<<lineCount<<" : "<<line<<"\n";
|
||||||
|
} else cout<<"Error on line "<<lineCount<<" : "<<line<<"\n";
|
||||||
|
} else if (line.substr(0,1) == "c") {
|
||||||
|
g810.commit();
|
||||||
|
g810.setKeys(&keys[0], keys.size());
|
||||||
|
keys.clear();
|
||||||
|
g810.commit();
|
||||||
|
} else if ((line.substr(0, 1) != "#") && (line.substr(0, 1) != "")) {
|
||||||
|
cout<<"Error on line "<<lineCount<<" : "<<line<<"\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
lineCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
g810.detach();
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc > 1) {
|
||||||
|
string argCmd = argv[1];
|
||||||
|
if (argCmd == "-h" || argCmd == "--help") { usage(); 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]);
|
||||||
|
}
|
||||||
|
usage();
|
||||||
|
return 1;
|
||||||
|
}
|
BIN
wireshark_dumps/set_boot_color.pcapng
Normal file
BIN
wireshark_dumps/set_boot_color.pcapng
Normal file
Binary file not shown.
BIN
wireshark_dumps/set_boot_rainbow.pcapng
Normal file
BIN
wireshark_dumps/set_boot_rainbow.pcapng
Normal file
Binary file not shown.
BIN
wireshark_dumps/set_keys_colors.pcapng
Normal file
BIN
wireshark_dumps/set_keys_colors.pcapng
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user