/*---------------------------------------------*\ | RedSquareKeyroxController.cpp | | | | Driver for Red Square Keyrox USB Controller | | | | cafeed28 3 Nov 2022 | \*---------------------------------------------*/ #include "LogManager.h" #include "RedSquareKeyroxController.h" #include using namespace std::chrono_literals; RedSquareKeyroxController::RedSquareKeyroxController(hid_device *dev_handle, const hid_device_info &info, int variant) { dev = dev_handle; location = info.path; this->variant = variant; } RedSquareKeyroxController::~RedSquareKeyroxController() { hid_close(dev); } int RedSquareKeyroxController::GetVariant() { return variant; } std::string RedSquareKeyroxController::GetDeviceLocation() { return("HID: " + location); } std::string RedSquareKeyroxController::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 RedSquareKeyroxController::GetDirectionLRUD(int direction) { switch(direction) { case MODE_DIRECTION_LEFT: return 0x10; case MODE_DIRECTION_RIGHT: return 0x00; case MODE_DIRECTION_UP: return 0x20; case MODE_DIRECTION_DOWN: return 0x30; default: return 0x00; } } int RedSquareKeyroxController::GetDirectionUD(int direction) { switch(direction) { case MODE_DIRECTION_UP: return 0xA0; case MODE_DIRECTION_DOWN: return 0xB0; default: return 0xA0; } } void RedSquareKeyroxController::SetLedSequencePositions(std::vector positions) { led_sequence_positions = positions; } void RedSquareKeyroxController::SetMode(std::vector modes, int active_mode) { /*---------------------------------------------*\ | Mode set command | \*---------------------------------------------*/ mode m = modes[active_mode]; unsigned char usb_buf[PACKET_DATA_LENGTH]; memset(usb_buf, 0x00, PACKET_DATA_LENGTH); usb_buf[4] = 0x01; usb_buf[6] = 0x04; usb_buf[8] = m.value; Send(usb_buf); } void RedSquareKeyroxController::SetModeData(std::vector modes, int active_mode) { /*---------------------------------------------*\ | Mode specific data set command | \*---------------------------------------------*/ mode m = modes[active_mode]; if(m.value == CUSTOM_MODE_VALUE) { return; } unsigned char usb_buf[PACKET_DATA_LENGTH]; memset(usb_buf, 0x00, PACKET_DATA_LENGTH); usb_buf[4] = 0x09; usb_buf[6] = 0x05; usb_buf[7] = m.value; usb_buf[8] = m.brightness; usb_buf[9] = 0xFF; if(m.flags & MODE_FLAG_HAS_SPEED) { usb_buf[10] = m.speed; usb_buf[11] = 0xFF; if(m.value == SPECTRUM_MODE_VALUE) { usb_buf[10] += 0x80; } } if(m.flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR) { if(m.flags & MODE_FLAG_HAS_RANDOM_COLOR && m.color_mode == MODE_COLORS_RANDOM) { usb_buf[10] += 0x80; } else { usb_buf[11] = RGBGetRValue(m.colors[0]); usb_buf[12] = RGBGetGValue(m.colors[0]); usb_buf[13] = RGBGetBValue(m.colors[0]); } } if((m.flags & MODE_FLAG_HAS_DIRECTION_LR) && (m.flags & MODE_FLAG_HAS_DIRECTION_UD)) { usb_buf[10] += GetDirectionLRUD(m.direction); } else if((m.flags & MODE_FLAG_HAS_DIRECTION_UD) && !(m.flags & MODE_FLAG_HAS_DIRECTION_LR)) { usb_buf[10] += GetDirectionUD(m.direction); } Send(usb_buf); } void RedSquareKeyroxController::SetLEDsData(std::vector modes, int active_mode, std::vector colors) { /*---------------------------------------------*\ | LEDs data set command | \*---------------------------------------------*/ mode m = modes[active_mode]; if(m.value != CUSTOM_MODE_VALUE) { return; } unsigned char usb_buf[PACKET_DATA_LENGTH]; memset(usb_buf, 0x00, PACKET_DATA_LENGTH); usb_buf[4] = 0xB0; usb_buf[5] = 0x01; usb_buf[6] = 0x07; for(unsigned int i = 0; i < colors.size(); i++) { int offset = 7 + led_sequence_positions[i] * 4; usb_buf[offset + 1] = RGBGetRValue(colors[i]); usb_buf[offset + 2] = RGBGetGValue(colors[i]); usb_buf[offset + 3] = RGBGetBValue(colors[i]); usb_buf[offset + 4] = m.brightness; } Send(usb_buf); } void RedSquareKeyroxController::Send(unsigned char data[PACKET_DATA_LENGTH]) { unsigned char usb_buf[PACKET_DATA_LENGTH + 1]; usb_buf[0] = 0x00; // Report ID for(int x = 0; x < PACKET_DATA_LENGTH; x++) { usb_buf[x + 1] = data[x]; } hid_send_feature_report(dev, usb_buf, PACKET_DATA_LENGTH + 1); std::this_thread::sleep_for(10ms); }