/*---------------------------------------------------------*\ | RedSquareKeyroxTKLClassicController.cpp | | | | Driver for Red Square Keyrox TKL Classic | | | | vlack 03 May 2023 | | | | This file is part of the OpenRGB project | | SPDX-License-Identifier: GPL-2.0-only | \*---------------------------------------------------------*/ #include "LogManager.h" #include "RedSquareKeyroxTKLClassicController.h" using namespace std::chrono_literals; RedSquareKeyroxTKLClassicController::RedSquareKeyroxTKLClassicController(hid_device *dev_handle, const hid_device_info &info) { dev = dev_handle; location = info.path; } RedSquareKeyroxTKLClassicController::~RedSquareKeyroxTKLClassicController() { hid_close(dev); } std::string RedSquareKeyroxTKLClassicController::GetDeviceLocation() { return("HID: " + location); } std::string RedSquareKeyroxTKLClassicController::GetSerialString() { wchar_t serial_wchar[128]; hid_get_serial_number_string(dev, serial_wchar, 128); std::wstring serial_wstring(serial_wchar); std::string serial_string; std::transform(serial_wstring.begin(), serial_wstring.end(), std::back_inserter(serial_string), [] (wchar_t i) { return (char)i; }); return serial_string; } int RedSquareKeyroxTKLClassicController::GetDirection(int direction) { switch(direction) { case MODE_DIRECTION_LEFT: return 0x00; case MODE_DIRECTION_RIGHT: return 0x01; case MODE_DIRECTION_UP: return 0x02; case MODE_DIRECTION_DOWN: return 0x03; case MODE_DIRECTION_HORIZONTAL: // actually direction out return 0x04; case MODE_DIRECTION_VERTICAL: // actually direction in return 0x05; default: return 0x00; } } int RedSquareKeyroxTKLClassicController::GetDirectionRound(int direction) { switch(direction) { case MODE_DIRECTION_LEFT: // actually anticlockwise return 0x07; case MODE_DIRECTION_RIGHT: // actually clockwise return 0x06; default: return 0x00; } } void RedSquareKeyroxTKLClassicController::SetMode(mode m) { /*---------------------------------------------*\ | Mode set command | \*---------------------------------------------*/ unsigned char usb_buf[CLASSIC_PACKET_DATA_LENGTH]; memset(usb_buf, 0x00, CLASSIC_PACKET_DATA_LENGTH); usb_buf[0] = 0x01; usb_buf[1] = 0x07; usb_buf[6] = m.value; usb_buf[7] = m.brightness; // brightness usb_buf[8] = m.speed; // speed if(m.colors_max == 1 || m.colors_max == 2) { usb_buf[9] = RGBGetRValue(m.colors[0]); // front R usb_buf[10] = RGBGetGValue(m.colors[0]); // front G usb_buf[11] = RGBGetBValue(m.colors[0]); // front B } if(m.colors_max == 2 && m.color_mode != MODE_COLORS_RANDOM) { usb_buf[12] = RGBGetRValue(m.colors[1]); // back R usb_buf[13] = RGBGetGValue(m.colors[1]); // back G usb_buf[14] = RGBGetBValue(m.colors[1]); // back B } if(m.value == CLASSIC_RADAR_MODE_VALUE || m.value == CLASSIC_RUNNING_LINE_MODE_VALUE) { usb_buf[15] = GetDirectionRound(m.direction); } else { usb_buf[15] = GetDirection(m.direction); } usb_buf[16] = m.color_mode == MODE_COLORS_RANDOM; hid_write(dev, usb_buf, CLASSIC_PACKET_DATA_LENGTH); // sleep is necessary std::this_thread::sleep_for(10ms); } void RedSquareKeyroxTKLClassicController::SetLEDsData(std::vector colors, std::vector leds) { /*---------------------------------------------*\ | LEDs data set command | \*---------------------------------------------*/ unsigned char usb_buf[CLASSIC_PACKET_DATA_LENGTH * 8]; memset(usb_buf, 0x00, CLASSIC_PACKET_DATA_LENGTH * 8); for(unsigned int i = 0; i < colors.size(); i++) { int offset = leds[i].value; usb_buf[offset - 1] = RGBGetRValue(colors[i]); usb_buf[offset] = RGBGetGValue(colors[i]); usb_buf[offset + 1] = RGBGetBValue(colors[i]); } for(unsigned int i = 0; i < 8; i++) { unsigned char packet[CLASSIC_PACKET_DATA_LENGTH]; memset(packet, 0x00, CLASSIC_PACKET_DATA_LENGTH); packet[0] = 0x01; packet[1] = 0x0F; packet[4] = i; // package number packet[5] = i == 7 ? 0x12 : 0x36; // package size for (int x = 6; x < CLASSIC_PACKET_DATA_LENGTH; x++) { packet[x] = usb_buf[CLASSIC_PACKET_DATA_LENGTH * i + x]; } hid_write(dev, packet, CLASSIC_PACKET_DATA_LENGTH); } // sleep is necessary std::this_thread::sleep_for(10ms); }