VulcanoLE/src/VulcanoLE/Keyboards/Vulcan121.cpp

243 lines
9.7 KiB
C++

#include <cstring>
#include <execution>
#include <VulcanoLE/Keyboards/Vulcan121.h>
#include <VUtils/Logging.h>
Vulcan121::Vulcan121(HIDHelper *helper)
: m_helper(helper) {}
int Vulcan121::send_led_map(led_map *src, bool deleteMap) {
int i, k;
rgba rgb;
unsigned char hwmap[444]{};
unsigned char workbuf[65];
memset(hwmap, 0, sizeof(hwmap));
for (k = 0; k < NUM_KEYS; k++) {
rgb = rv_fixed[ k ] ? *(rv_fixed[ k ]) : (src ? src->key[ k ] : rv_color_off);
rgb.r = (rgb.r > 255) ? 255 : (rgb.r < 0) ? 0 : rgb.r;
rgb.g = (rgb.g > 255) ? 255 : (rgb.g < 0) ? 0 : rgb.g;
rgb.b = (rgb.b > 255) ? 255 : (rgb.b < 0) ? 0 : rgb.b;
rgb.a = (rgb.a > 255) ? 255 : (rgb.a < 0) ? 0 : rgb.a;
double factor = rgb.a / 255.0;
rgb.r *= factor;
rgb.g *= factor;
rgb.b *= factor;
int offset = ((k / 12) * 36) + (k % 12);
hwmap[ offset + 0 ] = (unsigned char) rgb.r;
hwmap[ offset + 12 ] = (unsigned char) rgb.g;
hwmap[ offset + 24 ] = (unsigned char) rgb.b;
}
// First chunk comes with header
workbuf[ 0 ] = 0x00;
workbuf[ 1 ] = 0xa1;
workbuf[ 2 ] = 0x01;
workbuf[ 3 ] = 0x01;
workbuf[ 4 ] = 0xb4;
memcpy(&workbuf[ 5 ], hwmap, 60);
if (hid_write(m_helper->m_ledDevice, workbuf, 65) != 65) {
if (deleteMap) {
delete src;
}
return 0;
}
// Six more chunks
for (i = 1; i < 7; i++) {
workbuf[ 0 ] = 0x00;
memcpy(&workbuf[ 1 ], &hwmap[ (i * 64) - 4 ], 64);
if (hid_write(m_helper->m_ledDevice, workbuf, 65) != 65) {
if (deleteMap) {
delete src;
}
return 0;
}
}
if (deleteMap) {
delete src;
}
return 1;
}
int Vulcan121::send_led_to(rgba rgb) {
auto *map = new led_map();
for (auto &i : map->key) {
i = rgb;
}
int st = send_led_map(map, true);
return st;
}
led_map *Vulcan121::createEmptyLEDMap() {
return new led_map();
}
bool Vulcan121::send_init_sequence() {
LOG("Sending device init sequence...")
unsigned char a[9] = { 0x15, 0x05, 0x07, 0x0a, 0x0b, 0x06, 0x09, 0x0d, 0x13 };
if (!query_ctrl_report(0x0f))
return false;
for (auto i : a) {
if (!send_ctrl_report(i) || !wait_for_ctrl_dev()) {
return false;
}
}
m_helper->close_ctrl_device();
return true;
}
bool Vulcan121::query_ctrl_report(unsigned char id) {
if (id != 0x0f) return false;
unsigned char buffer[8] = {};
int length = 8;
buffer[ 0 ] = id;
int res = m_helper->get_feature_report(buffer, length);
if (res) {
return true;
}
ERR("query_ctrl_report(%02hhx) failed", id);
return false;
}
bool Vulcan121::send_ctrl_report(unsigned char id) {
unsigned char *buffer;
int length;
switch (id) {
case 0x15:
buffer = (unsigned char *) "\x15\x00\x01";
length = 3;
break;
case 0x05:
buffer = (unsigned char *) "\x05\x04\x00\x04";
length = 4;
break;
case 0x07:
buffer = (unsigned char *) "\x07\x5f\x00\x3a\x00\x00\x3b\x00\x00\x3c\x00\x00\x3d\x00\x00\x3e" \
"\x00\x00\x3f\x00\x00\x40\x00\x00\x41\x00\x00\x42\x00\x00\x43\x00" \
"\x00\x44\x00\x00\x45\x00\x00\x46\x00\x00\x47\x00\x00\x48\x00\x00" \
"\xb3\x00\x00\xb4\x00\x00\xb5\x00\x00\xb6\x00\x00\xc2\x00\x00\xc3" \
"\x00\x00\xc0\x00\x00\xc1\x00\x00\xce\x00\x00\xcf\x00\x00\xcc\x00" \
"\x00\xcd\x00\x00\x46\x00\x00\xfc\x00\x00\x48\x00\x00\xcd\x0e";
length = 95;
break;
case 0x0a:
buffer = (unsigned char *) "\x0a\x08\x00\xff\xf1\x00\x02\x02";
length = 8;
break;
case 0x0b:
buffer = (unsigned char *) "\x0b\x41\x00\x1e\x00\x00\x1f\x00\x00\x20\x00\x00\x21\x00\x00\x22" \
"\x00\x00\x14\x00\x00\x1a\x00\x00\x08\x00\x00\x15\x00\x00\x17\x00" \
"\x00\x04\x00\x00\x16\x00\x00\x07\x00\x00\x09\x00\x00\x0a\x00\x00" \
"\x1d\x00\x00\x1b\x00\x00\x06\x00\x00\x19\x00\x00\x05\x00\x00\xde\x01";
length = 65;
break;
case 0x06:
buffer = (unsigned char *) "\x06\x85\x00\x3a\x29\x35\x1e\x2b\x39\xe1\xe0\x3b\x1f\x14\x1a\x04" \
"\x64\x00\x00\x3d\x3c\x20\x21\x08\x16\x1d\xe2\x3e\x23\x22\x15\x07" \
"\x1b\x06\x8b\x3f\x24\x00\x17\x0a\x09\x19\x91\x40\x41\x00\x1c\x18" \
"\x0b\x05\x2c\x42\x26\x25\x0c\x0d\x0e\x10\x11\x43\x2a\x27\x2d\x12" \
"\x0f\x36\x8a\x44\x45\x89\x2e\x13\x33\x37\x90\x46\x49\x4c\x2f\x30" \
"\x34\x38\x88\x47\x4a\x4d\x31\x32\x00\x87\xe6\x48\x4b\x4e\x28\x52" \
"\x50\xe5\xe7\xd2\x53\x5f\x5c\x59\x51\x00\xf1\xd1\x54\x60\x5d\x5a" \
"\x4f\x8e\x65\xd0\x55\x61\x5e\x5b\x62\xa4\xe4\xfc\x56\x57\x85\x58" \
"\x63\x00\x00\xc2\x24";
length = 133;
break;
case 0x09:
buffer = (unsigned char *) "\x09\x2b\x00\x49\x00\x00\x4a\x00\x00\x4b\x00\x00\x4c\x00\x00\x4d" \
"\x00\x00\x4e\x00\x00\xa4\x00\x00\x8e\x00\x00\xd0\x00\x00\xd1\x00" \
"\x00\x00\x00\x00\x01\x00\x00\x00\x00\xcd\x04";
length = 43;
break;
case 0x0d:
length = 443;
buffer = (unsigned char *) "\x0d\xbb\x01\x00\x06\x0b\x05\x45\x83\xca\xca\xca\xca\xca\xca\xce" \
"\xce\xd2\xce\xce\xd2\x19\x19\x19\x19\x19\x19\x23\x23\x2d\x23\x23" \
"\x2d\xe0\xe0\xe0\xe0\xe0\xe0\xe3\xe3\xe6\xe3\xe3\xe6\xd2\xd2\xd5" \
"\xd2\xd2\xd5\xd5\xd5\xd9\xd5\x00\xd9\x2d\x2d\x36\x2d\x2d\x36\x36" \
"\x36\x40\x36\x00\x40\xe6\xe6\xe9\xe6\xe6\xe9\xe9\xe9\xec\xe9\x00" \
"\xec\xd9\xd9\xdd\xd9\xdd\xdd\xe0\xe0\xdd\xe0\xe4\xe4\x40\x40\x4a" \
"\x40\x4a\x4a\x53\x53\x4a\x53\x5d\x5d\xec\xec\xef\xec\xef\xef\xf2" \
"\xf2\xef\xf2\xf5\xf5\xe4\xe4\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
"\x00\x5d\x5d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf5\xf5\x00" \
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe4\xe4\xe8\xe8\xe8\xe8\xe8" \
"\xeb\xeb\xeb\x00\xeb\x5d\x5d\x67\x67\x67\x67\x67\x70\x70\x70\x00" \
"\x70\xf5\xf5\xf8\xf8\xf8\xf8\xf8\xfb\xfb\xfb\x00\xfb\xeb\xef\xef" \
"\xef\x00\xef\xf0\xf0\xed\xf0\xf0\x00\x70\x7a\x7a\x7a\x00\x7a\x7a" \
"\x7a\x6f\x7a\x7a\x00\xfb\xfd\xfd\xfd\x00\xfd\xf8\xf8\xea\xf8\xf8" \
"\x00\xed\xed\xea\xed\xed\x00\xed\xea\xea\xf6\xe7\xea\x6f\x6f\x65" \
"\x6f\x6f\x00\x6f\x65\x65\x66\x5a\x65\xea\xea\xdc\xea\xea\x00\xea" \
"\xdc\xdc\x00\xce\xdc\xea\xe7\xe5\xe7\xe5\xe5\x00\x00\x00\x00\x00" \
"\x00\x65\x5a\x50\x5a\x50\x50\x00\x00\x00\x00\x00\x00\xdc\xce\xc0" \
"\xce\xc0\xc0\x00\x00\x00\x00\x00\x00\xe7\x00\x00\xe2\xe2\xe2\xe2" \
"\xdf\xdf\xdf\xdf\xdf\x5a\x00\x00\x45\x45\x45\x45\x3b\x3b\x3b\x3b" \
"\x3b\xce\x00\x00\xb2\xb2\xb2\xb2\xa4\xa4\xa4\xa4\xa4\xdc\xdc\xdc" \
"\xdc\x00\xda\xda\xda\xda\xda\x00\xd7\x30\x30\x30\x30\x00\x26\x26" \
"\x26\x26\x26\x00\x1c\x96\x96\x96\x96\x00\x88\x88\x88\x88\x88\x00" \
"\x7a\xd7\xd7\xd7\x00\xd4\xd4\xd4\xd4\xd4\xd1\xd1\xd1\x1c\x1c\x1c" \
"\x00\x11\x11\x11\x11\x11\x06\x06\x06\x7a\x7a\x7a\x00\x6c\x6c\x6c" \
"\x6c\x6c\x5e\x5e\x5e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x24\xcf";
break;
case 0x13:
buffer = (unsigned char *) "\x13\x08\x01\x00\x00\x00\x00\x00";
length = 8;
break;
default: ERR("UNKNOWN BUFFER OPTION")
return false;
}
int res = m_helper->send_feature_report(buffer, length);
if (res == length) return true;
ERR("send_ctrl_report(%02hhx) failed", id)
return false;
}
bool Vulcan121::wait_for_ctrl_dev() {
unsigned char buffer[] = { 0x04, 0x00, 0x00, 0x00 };
int res;
while (true) {
// 150ms is the magic number here, should suffice on first try.
usleep(10000);
res = m_helper->get_feature_report(buffer, sizeof(buffer));
if (res) {
if (buffer[ 1 ] == 0x01) break;
} else {
ERR("rv_wait_for_ctrl_device() failed");
return false;
}
}
return true;
}
int Vulcan121::getColumnsForRow(int row) {
if (row > 5) {
WARN("Try to Access out of Bound %d max %d", row, 5)
return 0;
}
return keyMapRow[row]->count;
}
// @Todo Add Columngs
int Vulcan121::getRowsForColumns(int col) {
if (col > 5) {
WARN("Try to Access out of Bound %d max %d", col, 5)
return 0;
}
return keyMapCols[col]->count;
}
int Vulcan121::getIndex(int row, int col) {
if (row > 5) {
WARN("Try to Access out of Bound %d max %d", row, 5)
return 0;
}
if (col > keyMapRow[ row ]->count) {
WARN("Try to Access out of Bound %d max %d", col, keyMapRow[row]->count)
return 0;
}
return keyMapRow[row]->index[col];
}