mirror of
https://github.com/MatMoul/g810-led.git
synced 2024-12-23 01:06:11 +00:00
Merge pull request #73 from pearsonk/SpecDevice
Support specifying a specific device for executing commands
This commit is contained in:
commit
cbb416527b
@ -5,6 +5,7 @@
|
||||
#include <vector>
|
||||
|
||||
#if defined(hidapi)
|
||||
#include <locale>
|
||||
#include "hidapi/hidapi.h"
|
||||
#elif defined(libusb)
|
||||
#include "libusb-1.0/libusb.h"
|
||||
@ -20,38 +21,57 @@ LedKeyboard::~LedKeyboard() {
|
||||
}
|
||||
|
||||
|
||||
bool LedKeyboard::listKeyboards() {
|
||||
vector<LedKeyboard::DeviceInfo> LedKeyboard::listKeyboards() {
|
||||
vector<LedKeyboard::DeviceInfo> deviceList;
|
||||
|
||||
#if defined(hidapi)
|
||||
if (hid_init() < 0) return false;
|
||||
if (hid_init() < 0) return deviceList;
|
||||
|
||||
struct hid_device_info *devs, *dev;
|
||||
devs = hid_enumerate(0x0, 0x0);
|
||||
dev = devs;
|
||||
while (dev) {
|
||||
for (int i=0; i<(int)SupportedKeyboards.size(); i++) {
|
||||
for (size_t i=0; i<SupportedKeyboards.size(); i++) {
|
||||
if (dev->vendor_id == SupportedKeyboards[i][0]) {
|
||||
if (dev->product_id == SupportedKeyboards[i][1]) {
|
||||
cout<<"0x"<<std::hex<<dev->vendor_id \
|
||||
<<" 0x"<<std::hex<<dev->product_id \
|
||||
<<" "<<dev->serial_number \
|
||||
<<" "<<dev->path<<" ";
|
||||
DeviceInfo deviceInfo;
|
||||
deviceInfo.vendorID=dev->vendor_id;
|
||||
deviceInfo.productID=dev->product_id;
|
||||
|
||||
if (dev->serial_number != NULL) {
|
||||
char buf[256];
|
||||
wcstombs(buf,dev->serial_number,256);
|
||||
deviceInfo.serialNumber = string(buf);
|
||||
}
|
||||
|
||||
if (dev->manufacturer_string != NULL)
|
||||
{
|
||||
char buf[256];
|
||||
wcstombs(buf,dev->manufacturer_string,256);
|
||||
deviceInfo.manufacturer = string(buf);
|
||||
}
|
||||
|
||||
if (dev->product_string != NULL)
|
||||
{
|
||||
char buf[256];
|
||||
wcstombs(buf,dev->product_string,256);
|
||||
deviceInfo.product = string(buf);
|
||||
}
|
||||
|
||||
deviceList.push_back(deviceInfo);
|
||||
dev = dev->next;
|
||||
cout<<dev->serial_number<<" "<<dev->path<<endl;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dev = dev->next;
|
||||
if (dev != NULL) dev = dev->next;
|
||||
}
|
||||
hid_free_enumeration(devs);
|
||||
|
||||
hid_exit();
|
||||
return true;
|
||||
|
||||
#elif defined(libusb)
|
||||
libusb_context *ctx = NULL;
|
||||
if(libusb_init(&m_ctx) < 0) return false;
|
||||
if(libusb_init(&m_ctx) < 0) return deviceList;
|
||||
|
||||
libusb_device **devs;
|
||||
ssize_t cnt = libusb_get_device_list(ctx, &devs);
|
||||
@ -62,20 +82,37 @@ bool LedKeyboard::listKeyboards() {
|
||||
for (int i=0; i<(int)SupportedKeyboards.size(); i++) {
|
||||
if (desc.idVendor == SupportedKeyboards[i][0]) {
|
||||
if (desc.idProduct == SupportedKeyboards[i][1]) {
|
||||
cout<<"0x"<<std::hex<<desc.idVendor \
|
||||
<<" 0x"<<std::hex<<desc.idProduct<<endl;
|
||||
unsigned char buf[256];
|
||||
DeviceInfo deviceInfo;
|
||||
deviceInfo.vendorID=desc.idVendor;
|
||||
deviceInfo.productID=desc.idProduct;
|
||||
|
||||
if (libusb_open(device, &m_hidHandle) != 0) continue;
|
||||
|
||||
if (libusb_get_string_descriptor_ascii(m_hidHandle, desc.iSerialNumber, buf, 256) >= 1) deviceInfo.serialNumber = string((char*)buf);
|
||||
if (libusb_get_string_descriptor_ascii(m_hidHandle, desc.iManufacturer, buf, 256) >= 1) deviceInfo.manufacturer = string((char*)buf);
|
||||
if (libusb_get_string_descriptor_ascii(m_hidHandle, desc.iProduct, buf, 256) >= 1) deviceInfo.product = string((char*)buf);
|
||||
|
||||
deviceList.push_back(deviceInfo);
|
||||
libusb_close(m_hidHandle);
|
||||
m_hidHandle = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
libusb_free_device_list(devs, 1);
|
||||
|
||||
if (m_hidHandle != NULL) {
|
||||
libusb_close(m_hidHandle);
|
||||
m_hidHandle = NULL;
|
||||
}
|
||||
|
||||
libusb_exit(m_ctx);
|
||||
return true;
|
||||
m_ctx = NULL;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
|
||||
@ -86,114 +123,204 @@ bool LedKeyboard::isOpen() {
|
||||
bool LedKeyboard::open() {
|
||||
if (m_isOpen) return true;
|
||||
|
||||
return open(0x0,0x0,"");
|
||||
}
|
||||
|
||||
bool LedKeyboard::open(uint16_t vendorID, uint16_t productID, string serial) {
|
||||
if (m_isOpen && ! close()) return false;
|
||||
currentDevice.model = KeyboardModel::unknown;
|
||||
|
||||
#if defined(hidapi)
|
||||
if (hid_init() < 0) return false;
|
||||
|
||||
if (m_keyboardModel == KeyboardModel::unknown) {
|
||||
struct hid_device_info *devs, *dev;
|
||||
devs = hid_enumerate(0x0, 0x0);
|
||||
dev = devs;
|
||||
m_keyboardModel = KeyboardModel::unknown;
|
||||
while (dev) {
|
||||
for (int i=0; i<(int)SupportedKeyboards.size(); i++) {
|
||||
if (dev->vendor_id == SupportedKeyboards[i][0]) {
|
||||
if (dev->product_id == SupportedKeyboards[i][1]) {
|
||||
m_vendorID = dev->vendor_id;
|
||||
m_productID = dev->product_id;
|
||||
m_keyboardModel = (KeyboardModel)SupportedKeyboards[i][2];
|
||||
break;
|
||||
}
|
||||
if (hid_init() < 0) return false;
|
||||
|
||||
struct hid_device_info *devs, *dev;
|
||||
devs = hid_enumerate(vendorID, productID);
|
||||
dev = devs;
|
||||
wstring wideSerial;
|
||||
|
||||
if (!serial.empty()) {
|
||||
wchar_t tempSerial[256];
|
||||
if (mbstowcs(tempSerial, serial.c_str(), 256) < 1) return false;
|
||||
wideSerial = wstring(tempSerial);
|
||||
}
|
||||
|
||||
while (dev) {
|
||||
for (int i=0; i<(int)SupportedKeyboards.size(); i++) {
|
||||
if (dev->vendor_id == SupportedKeyboards[i][0]) {
|
||||
if (dev->product_id == SupportedKeyboards[i][1]) {
|
||||
if (!serial.empty() && dev->serial_number != NULL && wideSerial.compare(dev->serial_number) != 0) break; //Serial didn't match
|
||||
|
||||
if (dev->serial_number != NULL) {
|
||||
char buf[256];
|
||||
wcstombs(buf,dev->serial_number,256);
|
||||
currentDevice.serialNumber=string(buf);
|
||||
}
|
||||
|
||||
if (dev->manufacturer_string != NULL)
|
||||
{
|
||||
char buf[256];
|
||||
wcstombs(buf,dev->manufacturer_string,256);
|
||||
currentDevice.manufacturer = string(buf);
|
||||
}
|
||||
|
||||
if (dev->product_string != NULL)
|
||||
{
|
||||
char buf[256];
|
||||
wcstombs(buf,dev->product_string,256);
|
||||
currentDevice.product = string(buf);
|
||||
}
|
||||
|
||||
currentDevice.vendorID = dev->vendor_id;
|
||||
currentDevice.productID = dev->product_id;
|
||||
currentDevice.model = (KeyboardModel)SupportedKeyboards[i][2];
|
||||
break;
|
||||
}
|
||||
if (m_keyboardModel != KeyboardModel::unknown) break;
|
||||
dev = dev->next;
|
||||
}
|
||||
hid_free_enumeration(devs);
|
||||
|
||||
if (! dev) {
|
||||
cout<<"Keyboard not found"<<endl;
|
||||
m_keyboardModel = KeyboardModel::unknown;
|
||||
hid_exit();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_hidHandle = hid_open(m_vendorID, m_productID, NULL);
|
||||
|
||||
if(m_hidHandle == 0) {
|
||||
hid_exit();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_isOpen = true;
|
||||
return true;
|
||||
|
||||
if (currentDevice.model != KeyboardModel::unknown) break;
|
||||
dev = dev->next;
|
||||
}
|
||||
|
||||
hid_free_enumeration(devs);
|
||||
|
||||
if (! dev) {
|
||||
currentDevice.model = KeyboardModel::unknown;
|
||||
hid_exit();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wideSerial.empty()) m_hidHandle = hid_open(currentDevice.vendorID, currentDevice.productID, NULL);
|
||||
else m_hidHandle = hid_open(currentDevice.vendorID, currentDevice.productID, wideSerial.c_str());
|
||||
|
||||
if(m_hidHandle == 0) {
|
||||
hid_exit();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_isOpen = true;
|
||||
return true;
|
||||
|
||||
#elif defined(libusb)
|
||||
if(libusb_init(&m_ctx) < 0) return false;
|
||||
if (libusb_init(&m_ctx) < 0) return false;
|
||||
|
||||
if (m_keyboardModel == KeyboardModel::unknown) {
|
||||
libusb_device **devs;
|
||||
ssize_t cnt = libusb_get_device_list(m_ctx, &devs);
|
||||
if(cnt >= 0) {
|
||||
for(ssize_t i = 0; i < cnt; i++) {
|
||||
libusb_device *device = devs[i];
|
||||
libusb_device_descriptor desc;
|
||||
libusb_get_device_descriptor(device, &desc);
|
||||
libusb_device **devs;
|
||||
libusb_device *dev = NULL;
|
||||
ssize_t cnt = libusb_get_device_list(m_ctx, &devs);
|
||||
if(cnt >= 0) {
|
||||
for(ssize_t i = 0; i < cnt; i++) {
|
||||
libusb_device *device = devs[i];
|
||||
libusb_device_descriptor desc;
|
||||
libusb_get_device_descriptor(device, &desc);
|
||||
|
||||
if (vendorID != 0x0 && desc.idVendor != vendorID) continue;
|
||||
else if (productID != 0x0 && desc.idProduct != productID) continue;
|
||||
else if (! serial.empty()) {
|
||||
if (desc.iSerialNumber <= 0) continue; //Device does not populate serial number
|
||||
|
||||
unsigned char buf[256];
|
||||
if (libusb_open(device, &m_hidHandle) != 0){
|
||||
m_hidHandle = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (libusb_get_string_descriptor_ascii(m_hidHandle, desc.iSerialNumber, buf, 256) >= 1 && serial.compare((char*)buf) == 0) {
|
||||
//Make sure entry is a supported keyboard and get model
|
||||
for (int i=0; i<(int)SupportedKeyboards.size(); i++) {
|
||||
if (desc.idVendor == SupportedKeyboards[i][0]) {
|
||||
if (desc.idProduct == SupportedKeyboards[i][1]) {
|
||||
m_vendorID = desc.idVendor;
|
||||
m_productID = desc.idProduct;
|
||||
m_keyboardModel = (KeyboardModel)SupportedKeyboards[i][2];
|
||||
if (libusb_get_string_descriptor_ascii(m_hidHandle, desc.iManufacturer, buf, 256) >= 1) currentDevice.manufacturer = string((char*)buf);
|
||||
if (libusb_get_string_descriptor_ascii(m_hidHandle, desc.iProduct, buf, 256) >= 1) currentDevice.product = string((char*)buf);
|
||||
currentDevice.serialNumber = serial;
|
||||
currentDevice.vendorID = desc.idVendor;
|
||||
currentDevice.productID = desc.idProduct;
|
||||
currentDevice.model = (KeyboardModel)SupportedKeyboards[i][2];
|
||||
|
||||
dev = device;
|
||||
libusb_close(m_hidHandle);
|
||||
m_hidHandle = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_keyboardModel != KeyboardModel::unknown) break;
|
||||
}
|
||||
libusb_free_device_list(devs, 1);
|
||||
else {
|
||||
libusb_close(m_hidHandle);
|
||||
m_hidHandle = NULL;
|
||||
continue; //Serial number set but doesn't match
|
||||
}
|
||||
}
|
||||
|
||||
//For the case where serial is not specified, find first supported device
|
||||
for (int i=0; i<(int)SupportedKeyboards.size(); i++) {
|
||||
if (desc.idVendor == SupportedKeyboards[i][0]) {
|
||||
if (desc.idProduct == SupportedKeyboards[i][1]) {
|
||||
unsigned char buf[256];
|
||||
if (libusb_open(device, &m_hidHandle) != 0){
|
||||
m_hidHandle = NULL;
|
||||
continue;
|
||||
}
|
||||
currentDevice.vendorID = desc.idVendor;
|
||||
currentDevice.productID = desc.idProduct;
|
||||
currentDevice.model = (KeyboardModel)SupportedKeyboards[i][2];
|
||||
if (libusb_get_string_descriptor_ascii(m_hidHandle, desc.iManufacturer, buf, 256) >= 1) currentDevice.manufacturer = string((char*)buf);
|
||||
if (libusb_get_string_descriptor_ascii(m_hidHandle, desc.iProduct, buf, 256) >= 1) currentDevice.product = string((char*)buf);
|
||||
if (libusb_get_string_descriptor_ascii(m_hidHandle, desc.iSerialNumber, buf, 256) >= 1) currentDevice.serialNumber = string((char*)buf);
|
||||
|
||||
libusb_close(m_hidHandle);
|
||||
m_hidHandle=NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentDevice.model != KeyboardModel::unknown) break;
|
||||
}
|
||||
libusb_free_device_list(devs, 1);
|
||||
}
|
||||
|
||||
if (currentDevice.model == KeyboardModel::unknown) {
|
||||
libusb_exit(m_ctx);
|
||||
m_ctx = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_keyboardModel == KeyboardModel::unknown) {
|
||||
cout<<"Keyboard not found"<<endl;
|
||||
if (dev == NULL) m_hidHandle = libusb_open_device_with_vid_pid(m_ctx, currentDevice.vendorID, currentDevice.productID);
|
||||
else libusb_open(dev, &m_hidHandle);
|
||||
|
||||
if(m_hidHandle == NULL) {
|
||||
libusb_exit(m_ctx);
|
||||
m_ctx = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(libusb_kernel_driver_active(m_hidHandle, 1) == 1) {
|
||||
if(libusb_detach_kernel_driver(m_hidHandle, 1) != 0) {
|
||||
libusb_exit(m_ctx);
|
||||
m_ctx = NULL;
|
||||
return false;
|
||||
}
|
||||
m_isKernellDetached = true;
|
||||
}
|
||||
|
||||
m_hidHandle = libusb_open_device_with_vid_pid(m_ctx, m_vendorID, m_productID);
|
||||
if(m_hidHandle == 0) {
|
||||
libusb_exit(m_ctx);
|
||||
m_ctx = NULL;
|
||||
return false;
|
||||
if(libusb_claim_interface(m_hidHandle, 1) < 0) {
|
||||
if(m_isKernellDetached==true) {
|
||||
libusb_attach_kernel_driver(m_hidHandle, 1);
|
||||
m_isKernellDetached = false;
|
||||
}
|
||||
libusb_exit(m_ctx);
|
||||
m_ctx = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(libusb_kernel_driver_active(m_hidHandle, 1) == 1) {
|
||||
if(libusb_detach_kernel_driver(m_hidHandle, 1) != 0) {
|
||||
libusb_exit(m_ctx);
|
||||
m_ctx = NULL;
|
||||
return false;
|
||||
}
|
||||
m_isKernellDetached = true;
|
||||
}
|
||||
|
||||
if(libusb_claim_interface(m_hidHandle, 1) < 0) {
|
||||
if(m_isKernellDetached==true) {
|
||||
libusb_attach_kernel_driver(m_hidHandle, 1);
|
||||
m_isKernellDetached = false;
|
||||
}
|
||||
libusb_exit(m_ctx);
|
||||
m_ctx = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_isOpen = true;
|
||||
return true;
|
||||
|
||||
m_isOpen = true;
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
|
||||
return false; //In case neither is defined
|
||||
}
|
||||
|
||||
LedKeyboard::DeviceInfo LedKeyboard::getCurrentDevice()
|
||||
{
|
||||
return currentDevice;
|
||||
}
|
||||
|
||||
bool LedKeyboard::close() {
|
||||
@ -202,11 +329,12 @@ bool LedKeyboard::close() {
|
||||
|
||||
#if defined(hidapi)
|
||||
hid_close(m_hidHandle);
|
||||
m_hidHandle = 0;
|
||||
m_hidHandle = NULL;
|
||||
hid_exit();
|
||||
return true;
|
||||
|
||||
#elif defined(libusb)
|
||||
if (m_hidHandle == NULL) return true;
|
||||
if(libusb_release_interface(m_hidHandle, 1) != 0) return false;
|
||||
if(m_isKernellDetached==true) {
|
||||
libusb_attach_kernel_driver(m_hidHandle, 1);
|
||||
@ -224,13 +352,12 @@ bool LedKeyboard::close() {
|
||||
|
||||
|
||||
LedKeyboard::KeyboardModel LedKeyboard::getKeyboardModel() {
|
||||
return m_keyboardModel;
|
||||
return currentDevice.model;
|
||||
}
|
||||
|
||||
|
||||
bool LedKeyboard::commit() {
|
||||
byte_buffer_t data;
|
||||
switch (m_keyboardModel) {
|
||||
switch (currentDevice.model) {
|
||||
case KeyboardModel::g213:
|
||||
break; // Keyboard is non-transactional
|
||||
case KeyboardModel::g410:
|
||||
@ -268,7 +395,7 @@ bool LedKeyboard::setKeys(KeyValueArray keyValues) {
|
||||
for (uint8_t i = 0; i < keyValues.size(); i++) {
|
||||
switch(static_cast<LedKeyboard::KeyAddressGroup>(static_cast<uint16_t>(keyValues[i].key) >> 8 )) {
|
||||
case LedKeyboard::KeyAddressGroup::logo:
|
||||
switch (m_keyboardModel) {
|
||||
switch (currentDevice.model) {
|
||||
case LedKeyboard::KeyboardModel::g610:
|
||||
case LedKeyboard::KeyboardModel::g810:
|
||||
if (SortedKeys[0].size() <= 1 && keyValues[i].key == LedKeyboard::Key::logo)
|
||||
@ -285,7 +412,7 @@ bool LedKeyboard::setKeys(KeyValueArray keyValues) {
|
||||
if (SortedKeys[1].size() <= 5) SortedKeys[1].push_back(keyValues[i]);
|
||||
break;
|
||||
case LedKeyboard::KeyAddressGroup::multimedia:
|
||||
switch (m_keyboardModel) {
|
||||
switch (currentDevice.model) {
|
||||
case LedKeyboard::KeyboardModel::g610:
|
||||
case LedKeyboard::KeyboardModel::g810:
|
||||
if (SortedKeys[2].size() <= 5) SortedKeys[2].push_back(keyValues[i]);
|
||||
@ -295,7 +422,7 @@ bool LedKeyboard::setKeys(KeyValueArray keyValues) {
|
||||
}
|
||||
break;
|
||||
case LedKeyboard::KeyAddressGroup::gkeys:
|
||||
switch (m_keyboardModel) {
|
||||
switch (currentDevice.model) {
|
||||
case LedKeyboard::KeyboardModel::g910:
|
||||
if (SortedKeys[3].size() <= 9) SortedKeys[3].push_back(keyValues[i]);
|
||||
break;
|
||||
@ -304,7 +431,7 @@ bool LedKeyboard::setKeys(KeyValueArray keyValues) {
|
||||
}
|
||||
break;
|
||||
case LedKeyboard::KeyAddressGroup::keys:
|
||||
switch (m_keyboardModel) {
|
||||
switch (currentDevice.model) {
|
||||
case LedKeyboard::KeyboardModel::g610:
|
||||
case LedKeyboard::KeyboardModel::g810:
|
||||
case LedKeyboard::KeyboardModel::g910:
|
||||
@ -433,7 +560,7 @@ bool LedKeyboard::setGroupKeys(KeyGroup keyGroup, LedKeyboard::Color color) {
|
||||
bool LedKeyboard::setAllKeys(LedKeyboard::Color color) {
|
||||
KeyValueArray keyValues;
|
||||
|
||||
switch (m_keyboardModel) {
|
||||
switch (currentDevice.model) {
|
||||
case KeyboardModel::g213:
|
||||
for (uint8_t rIndex=0x01; rIndex <= 0x05; rIndex++) if (! setRegion(rIndex, color)) return false;
|
||||
return true;
|
||||
@ -461,7 +588,7 @@ bool LedKeyboard::setAllKeys(LedKeyboard::Color color) {
|
||||
|
||||
bool LedKeyboard::setMRKey(uint8_t value) {
|
||||
LedKeyboard::byte_buffer_t data;
|
||||
switch (m_keyboardModel) {
|
||||
switch (currentDevice.model) {
|
||||
case KeyboardModel::g910:
|
||||
switch (value) {
|
||||
case 0x00:
|
||||
@ -481,7 +608,7 @@ bool LedKeyboard::setMRKey(uint8_t value) {
|
||||
|
||||
bool LedKeyboard::setMNKey(uint8_t value) {
|
||||
LedKeyboard::byte_buffer_t data;
|
||||
switch (m_keyboardModel) {
|
||||
switch (currentDevice.model) {
|
||||
case KeyboardModel::g910:
|
||||
switch (value) {
|
||||
case 0x00:
|
||||
@ -507,7 +634,7 @@ bool LedKeyboard::setMNKey(uint8_t value) {
|
||||
|
||||
bool LedKeyboard::setGKeysMode(uint8_t value) {
|
||||
LedKeyboard::byte_buffer_t data;
|
||||
switch (m_keyboardModel) {
|
||||
switch (currentDevice.model) {
|
||||
case KeyboardModel::g910:
|
||||
switch (value) {
|
||||
case 0x00:
|
||||
@ -527,7 +654,7 @@ bool LedKeyboard::setGKeysMode(uint8_t value) {
|
||||
|
||||
bool LedKeyboard::setRegion(uint8_t region, LedKeyboard::Color color) {
|
||||
LedKeyboard::byte_buffer_t data;
|
||||
switch (m_keyboardModel) {
|
||||
switch (currentDevice.model) {
|
||||
case KeyboardModel::g213:
|
||||
data = { 0x11, 0xff, 0x0c, 0x3a, region, 0x01, color.red, color.green, color.blue };
|
||||
data.resize(20,0x00);
|
||||
@ -542,7 +669,7 @@ bool LedKeyboard::setRegion(uint8_t region, LedKeyboard::Color color) {
|
||||
|
||||
bool LedKeyboard::setStartupMode(StartupMode startupMode) {
|
||||
byte_buffer_t data;
|
||||
switch (m_keyboardModel) {
|
||||
switch (currentDevice.model) {
|
||||
case KeyboardModel::g213:
|
||||
case KeyboardModel::g410:
|
||||
case KeyboardModel::g610:
|
||||
@ -564,7 +691,7 @@ bool LedKeyboard::setStartupMode(StartupMode startupMode) {
|
||||
bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, uint8_t speed, Color color) {
|
||||
uint8_t protocolByte = 0;
|
||||
|
||||
switch (m_keyboardModel) {
|
||||
switch (currentDevice.model) {
|
||||
case KeyboardModel::g213:
|
||||
protocolByte = 0x0c;
|
||||
if (part == NativeEffectPart::logo) return false; //Does not have logo component
|
||||
@ -686,7 +813,7 @@ bool LedKeyboard::sendDataInternal(byte_buffer_t &data) {
|
||||
}
|
||||
|
||||
LedKeyboard::byte_buffer_t LedKeyboard::getKeyGroupAddress(LedKeyboard::KeyAddressGroup keyAddressGroup) {
|
||||
switch (m_keyboardModel) {
|
||||
switch (currentDevice.model) {
|
||||
case KeyboardModel::g213:
|
||||
return {}; // Device doesn't support per-key setting
|
||||
case KeyboardModel::g410:
|
||||
|
@ -109,7 +109,15 @@ class LedKeyboard {
|
||||
ctrl_right, shift_right, alt_right, win_right
|
||||
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16_t vendorID = 0x0;
|
||||
uint16_t productID = 0x0;
|
||||
std::string manufacturer = "";
|
||||
std::string product = "";
|
||||
std::string serialNumber = "";
|
||||
KeyboardModel model;
|
||||
} DeviceInfo;
|
||||
|
||||
struct Color {
|
||||
uint8_t red;
|
||||
@ -127,10 +135,12 @@ class LedKeyboard {
|
||||
~LedKeyboard();
|
||||
|
||||
|
||||
bool listKeyboards();
|
||||
std::vector<DeviceInfo> listKeyboards();
|
||||
|
||||
bool isOpen();
|
||||
bool open();
|
||||
bool open(uint16_t vendorID, uint16_t productID, std::string serial);
|
||||
DeviceInfo getCurrentDevice();
|
||||
bool close();
|
||||
|
||||
KeyboardModel getKeyboardModel();
|
||||
@ -152,7 +162,6 @@ class LedKeyboard {
|
||||
bool setNativeEffect(NativeEffect effect, NativeEffectPart part, uint8_t speed, Color color);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
typedef std::vector<unsigned char> byte_buffer_t;
|
||||
@ -191,9 +200,7 @@ class LedKeyboard {
|
||||
};
|
||||
|
||||
bool m_isOpen = false;
|
||||
uint16_t m_vendorID = 0;
|
||||
uint16_t m_productID = 0;
|
||||
KeyboardModel m_keyboardModel = KeyboardModel::unknown;
|
||||
DeviceInfo currentDevice;
|
||||
|
||||
#if defined(hidapi)
|
||||
hid_device *m_hidHandle;
|
||||
|
@ -14,6 +14,8 @@ namespace help {
|
||||
cout<<"--------"<<endl;
|
||||
cout<<"Version : "<<VERSION<<endl;
|
||||
cout<<endl;
|
||||
cout<<"Usage: "<<cmdName<<" [OPTIONS...] [command] (command arguments)"<<endl;
|
||||
cout<<"Commands:"<<endl;
|
||||
cout<<" -a {color}\t\t\t\tSet all keys color"<<endl;
|
||||
cout<<" -g {keygroup} {color}\t\t\tSet key group color"<<endl;
|
||||
cout<<" -k {key} {color}\t\t\tSet key color"<<endl;
|
||||
@ -40,13 +42,18 @@ namespace help {
|
||||
cout<<" --startup-mode {startup mode}\t\tSet startup mode"<<endl;
|
||||
cout<<endl;
|
||||
cout<<" --list-keyboards \t\t\tList connected keyboards"<<endl;
|
||||
cout<<" --print-device\t\t\tPrint device information for the keyboard"<<endl;
|
||||
cout<<endl;
|
||||
cout<<" --help\t\t\t\tThis help"<<endl;
|
||||
cout<<" --help-keys\t\t\t\tHelp for keys in groups"<<endl;
|
||||
cout<<" --help-effects\t\t\tHelp for native effects"<<endl;
|
||||
cout<<" --help-samples\t\t\tUsage samples"<<endl;
|
||||
cout<<""<<endl;
|
||||
cout<<""<<endl;
|
||||
cout<<endl;
|
||||
cout<<"Options:"<<endl;
|
||||
cout<<" -dv\t\t\t\t\tDevice vendor ID, such as 046d for Logitech. Can be omitted to match any vendor ID"<<endl;
|
||||
cout<<" -dp\t\t\t\t\tDevice product ID, such as c337 for Logitech G810. Can be omitted to match any product ID"<<endl;
|
||||
cout<<" -ds\t\t\t\t\tDevice serial number, Can be omitted to match the first device found"<<endl;
|
||||
cout<<"--------"<<endl;
|
||||
if (cmdName == "g610-led")
|
||||
cout<<"color formats :\t\t\t\tII (hex value for intensity)"<<endl;
|
||||
else
|
||||
@ -59,7 +66,7 @@ namespace help {
|
||||
cout<<"key values :\t\t\t\tabc... 123... and other (use --help-keys for more detail)"<<endl;
|
||||
cout<<"group values :\t\t\t\tlogo, indicators, fkeys, ... (use --help-keys for more detail)"<<endl;
|
||||
cout<<"startup mode :\t\t\t\twave, color"<<endl;
|
||||
cout<<""<<endl;
|
||||
cout<<endl;
|
||||
}
|
||||
|
||||
void keys(char *arg0) {
|
||||
|
@ -216,4 +216,12 @@ namespace utils {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseUInt16(std::string val, uint16_t &uint16) {
|
||||
if (val.length() == 1) val = "0" + val;
|
||||
if (val.length() == 2) val = "0" + val;
|
||||
if (val.length() == 3) val = "0" + val;
|
||||
if (val.length() != 4) return false;
|
||||
uint16 = std::stoul("0x" + val, nullptr, 16);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ namespace utils {
|
||||
bool parseColor(std::string val, LedKeyboard::Color &color);
|
||||
bool parseSpeed(std::string val, uint8_t &speed);
|
||||
bool parseUInt8(std::string val, uint8_t &uint8);
|
||||
bool parseUInt16(std::string val, uint16_t &uint16);
|
||||
|
||||
}
|
||||
|
||||
|
130
src/main.cpp
130
src/main.cpp
@ -1,3 +1,4 @@
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <fstream>
|
||||
@ -14,6 +15,27 @@ int commit(LedKeyboard &kbd) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void printDeviceInfo(LedKeyboard::DeviceInfo device)
|
||||
{
|
||||
std::cout<<"Device: "<<device.manufacturer<<" - "<<device.product<<std::endl;
|
||||
std::cout<<"\tVendor ID: "<<std::hex<<std::setw(4)<<std::setfill('0')<<device.vendorID<<std::endl;
|
||||
std::cout<<"\tProduct ID: "<<std::hex<<std::setw(4)<<std::setfill('0')<<device.productID<<std::endl;
|
||||
std::cout<<"\tSerial Number: "<<device.serialNumber<<std::endl;
|
||||
}
|
||||
|
||||
int listKeyboards(LedKeyboard &kbd) {
|
||||
std::vector<LedKeyboard::DeviceInfo> deviceList = kbd.listKeyboards();
|
||||
if (deviceList.empty()) return 1;
|
||||
|
||||
std::vector<LedKeyboard::DeviceInfo>::iterator iterator;
|
||||
for (iterator = deviceList.begin(); iterator != deviceList.end(); iterator++) {
|
||||
LedKeyboard::DeviceInfo device = *iterator;
|
||||
printDeviceInfo(device);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int setAllKeys(LedKeyboard &kbd, std::string arg2, bool commit = true) {
|
||||
LedKeyboard::Color color;
|
||||
if (! utils::parseColor(arg2, color)) return 1;
|
||||
@ -226,47 +248,71 @@ int pipeProfile(LedKeyboard &kbd) {
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc > 1) {
|
||||
|
||||
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 == "-mr") return setMRKey(kbd, argv[2]);
|
||||
else if (argc > 2 && arg == "-mn") return setMNKey(kbd, argv[2]);
|
||||
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 > 3 && arg == "-r") return setRegion(kbd, argv[2], argv[3]);
|
||||
|
||||
else if (argc > 2 && arg == "-gkm") return setGKeysMode(kbd, argv[2]);
|
||||
|
||||
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;
|
||||
|
||||
if (argc < 2) {
|
||||
help::usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
help::usage(argv[0]);
|
||||
return 1;
|
||||
|
||||
LedKeyboard kbd;
|
||||
std::string serial;
|
||||
uint16_t vendorID = 0x0;
|
||||
uint16_t productID = 0x0;
|
||||
|
||||
int argIndex = 1;
|
||||
while (argIndex < argc)
|
||||
{
|
||||
std::string arg = argv[argIndex];
|
||||
|
||||
// Non-Command arguments
|
||||
if (argc > (argIndex + 1) && arg == "-ds") {
|
||||
serial = argv[argIndex + 1];
|
||||
argIndex += 2;
|
||||
continue;
|
||||
}
|
||||
else if (argc > (argIndex + 1) && arg == "-dv"){
|
||||
if (! utils::parseUInt16(argv[argIndex + 1], vendorID)) return 1;
|
||||
argIndex += 2;
|
||||
continue;
|
||||
}
|
||||
else if (argc > (argIndex + 1) && arg == "-dp"){
|
||||
if (! utils::parseUInt16(argv[argIndex + 1], productID)) return 1;
|
||||
argIndex += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
//Commands that do not need to initialize a specific device
|
||||
if (arg == "--help" || arg == "-h") {help::usage(argv[0]); return 0;}
|
||||
else if (arg == "--list-keyboards") return listKeyboards(kbd);
|
||||
else if (arg == "--help-keys") {help::keys(argv[0]); return 0;}
|
||||
else if (arg == "--help-effects") {help::effects(argv[0]); return 0;}
|
||||
else if (arg == "--help-samples") {help::samples(argv[0]); return 0;}
|
||||
|
||||
//Initialize the device for use
|
||||
if (!kbd.open(vendorID, productID, serial)) {
|
||||
std::cout << "Matching or compatible device not found" << std::endl;
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Command arguments, these will cause parsing to ignore anything beyond the command and its arguments
|
||||
if (arg == "-c") return commit(kbd);
|
||||
else if (arg == "--print-device") {printDeviceInfo(kbd.getCurrentDevice()); return 0;}
|
||||
else if (argc > (argIndex + 1) && arg == "-a") return setAllKeys(kbd, argv[argIndex + 1]);
|
||||
else if (argc > (argIndex + 2) && arg == "-g") return setGroupKeys(kbd, argv[argIndex + 1], argv[argIndex + 2]);
|
||||
else if (argc > (argIndex + 2) && arg == "-k") return setKey(kbd, argv[argIndex + 1], argv[argIndex + 2]);
|
||||
else if (argc > (argIndex + 1) && arg == "-mr") return setMRKey(kbd, argv[argIndex + 1]);
|
||||
else if (argc > (argIndex + 1) && arg == "-mn") return setMNKey(kbd, argv[argIndex + 1]);
|
||||
else if (argc > (argIndex + 1) && arg == "-an") return setAllKeys(kbd, argv[argIndex + 1], false);
|
||||
else if (argc > (argIndex + 2) && arg == "-gn") return setGroupKeys(kbd, argv[argIndex + 1], argv[argIndex + 2], false);
|
||||
else if (argc > (argIndex + 2) && arg == "-kn") return setKey(kbd, argv[argIndex + 1], argv[argIndex + 2], false);
|
||||
else if (argc > (argIndex + 2) && arg == "-r") return setRegion(kbd, argv[argIndex + 1], argv[argIndex + 2]);
|
||||
else if (argc > (argIndex + 1) && arg == "-gkm") return setGKeysMode(kbd, argv[argIndex + 1]);
|
||||
else if (argc > (argIndex + 1) && arg == "-p") return loadProfile(kbd, argv[argIndex + 1]);
|
||||
else if (arg == "-pp") return pipeProfile(kbd);
|
||||
else if (argc > (argIndex + 4) && arg == "-fx") return setFX(kbd, argv[argIndex + 1], argv[argIndex + 2], argv[argIndex + 3], argv[argIndex + 4]);
|
||||
else if (argc > (argIndex + 3) && arg == "-fx") return setFX(kbd, argv[argIndex + 1], argv[argIndex + 2], argv[argIndex + 3]);
|
||||
else if (argc > (argIndex + 1) && arg == "--startup-mode") return setStartupMode(kbd, argv[argIndex + 1]);
|
||||
else { help::usage(argv[0]); return 1; }
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user