diff --git a/Controllers/CorsairPeripheralController/CorsairK55RGBPROXTController.cpp b/Controllers/CorsairPeripheralController/CorsairK55RGBPROXTController.cpp new file mode 100644 index 00000000..4102294c --- /dev/null +++ b/Controllers/CorsairPeripheralController/CorsairK55RGBPROXTController.cpp @@ -0,0 +1,287 @@ +/*--------------------------------------------*\ +| CorsairK55RGBPROXTController.cpp | +| | +| Driver for Corsair K55 RGB PRO XT Keyboard | +\*--------------------------------------------*/ + +#include "CorsairK55RGBPROXTController.h" +#include "LogManager.h" + + +#define COLOR_BANK_SIZE 137 +#define HID_PACKET_LENGTH 65 +#define HID_PAYLOAD_SIZE1 (HID_PACKET_LENGTH - 12) +#define HID_PAYLOAD_SIZE2 (HID_PACKET_LENGTH - 4) + + +static const unsigned int keys[] = + { 127, 128, 129, 130, 131, 132, 37, 49, 39, 53, 102, 101, 26, 96, 104, 54, 27, 16, 0, 25, + 103, 55, 28, 22, 18, 23, 56, 29, 4, 3, 2, 57, 30, 17, 5, 21, 31, 58, 32, 19, + 6, 1, 40, 59, 33, 24, 7, 60, 34, 20, 9, 13, 61, 35, 8, 10, 12, 14, 11, 50, + 62, 41, 15, 47, 51, 107, 63, 42, 43, 48, 52, 118, 64, 38, 44, 46, 106, 97, 65, 36, + 105, 66, 69, 72, 76, 67, 70, 73, 78, 77, 68, 71, 74, 75, 79, 91, 88, 85, 94, 80, + 92, 89, 86, 81, 93, 90, 87, 95, 82, 83, 84 }; + + +static unsigned char color_bank[3][COLOR_BANK_SIZE]; + +static const unsigned char filler[] = + { 0x70, 0x6E, 0x4E, 0x4D, 0x4C, 0x65, 0x6F, 0x2C, 0x4B, 0x4A, 0x49, 0x48, 0x47, 0x46, 0x45, 0x05, + 0x19, 0x06, 0x1B, 0x1D, 0x64, 0x6A, 0x34, 0x6B, 0x6C, 0x69, 0x38, 0x37, 0x36, 0x10, 0x11, 0x16, + 0x04, 0x39, 0x2F, 0x13, 0x12, 0x0C, 0x18, 0x33, 0x0F, 0x0E, 0x0D, 0x0B, 0x0A, 0x09, 0x07, 0x27, + 0x7A, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1C, 0x17, 0x15, 0x08, 0x1A, 0x14, 0x2B, 0x2D, + 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x29, 0x1F, 0x1E, 0x35, 0x44, 0x43, 0x42, 0x41, 0x40, 0x62, + 0x00, 0x5B, 0x5A, 0x59, 0x5E, 0x5D, 0x5C, 0x88, 0x87, 0x86, 0x85, 0x84, 0x83, 0x63, 0x53, 0x4F, + 0x61, 0x60, 0x5F, 0x58, 0x57, 0x56, 0x55, 0x54, 0x2A, 0x2E, 0x28, 0x32, 0x30, 0x51, 0x50, 0x52, + 0x6D }; + + +CorsairK55RGBPROXTController::CorsairK55RGBPROXTController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; + + LightingControl(); +} + +CorsairK55RGBPROXTController::~CorsairK55RGBPROXTController() +{ + hid_close(dev); +} + +std::string CorsairK55RGBPROXTController::GetDeviceLocation() +{ + return("HID: " + location); +} + +std::string CorsairK55RGBPROXTController::GetFirmwareString() +{ + return ""; +} + +std::string CorsairK55RGBPROXTController::GetSerialString() +{ + wchar_t serial_string[128]; + int ret = hid_get_serial_number_string(dev, serial_string, 128); + + if(ret != 0) + { + return(""); + } + + std::wstring return_wstring = serial_string; + std::string return_string(return_wstring.begin(), return_wstring.end()); + + return(return_string); +} + +void CorsairK55RGBPROXTController::LightingControl() +{ + unsigned char usb_buf[HID_PACKET_LENGTH]; + + memset(usb_buf, 0x00, sizeof(usb_buf)); + usb_buf[0x01] = 0x08; + usb_buf[0x02] = 0x01; + usb_buf[0x03] = 0x03; + usb_buf[0x05] = 0x02; + hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH); + + memset(usb_buf, 0x00, sizeof(usb_buf)); + usb_buf[0x01] = 0x08; + usb_buf[0x02] = 0x02; + usb_buf[0x03] = 0x5F; + hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH); + + memset(usb_buf, 0x00, sizeof(usb_buf)); + usb_buf[0x01] = 0x08; + usb_buf[0x02] = 0x0D; + usb_buf[0x04] = 0x01; + hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH); +} + +void CorsairK55RGBPROXTController::SetLEDs(std::vectorcolors) +{ + for(std::size_t color_idx = 0; color_idx < colors.size(); ++color_idx) + { + RGBColor color = colors[color_idx]; + color_bank[0][keys[color_idx]] = RGBGetRValue(color); + color_bank[1][keys[color_idx]] = RGBGetGValue(color); + color_bank[2][keys[color_idx]] = RGBGetBValue(color); + } + + unsigned char* color_ptr = &color_bank[0][0]; + unsigned char usb_buf[HID_PACKET_LENGTH]; + memset(usb_buf, 0x00, sizeof(usb_buf)); + + usb_buf[0x01] = 0x08; + usb_buf[0x02] = 0x06; + usb_buf[0x04] = 0x9B; + usb_buf[0x05] = 0x01; + + memcpy(&usb_buf[12], color_ptr, HID_PAYLOAD_SIZE1); + color_ptr += HID_PAYLOAD_SIZE1; + hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH); + + usb_buf[0x02] = 0x07; + + for(std::size_t i = 0; i < 6; ++i) + { + memcpy(&usb_buf[4], color_ptr, HID_PAYLOAD_SIZE2); + color_ptr += HID_PAYLOAD_SIZE2; + hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH); + } +} + +void CorsairK55RGBPROXTController::SetHardwareMode + ( + int mode_value, + unsigned int color_mode, + std::vector colors, + unsigned int speed, + unsigned int direction + ) +{ + LightingControl(); + + unsigned char usb_buf[HID_PACKET_LENGTH]; + memset(usb_buf, 0x00, sizeof(usb_buf)); + usb_buf[0x01] = 0x08; + usb_buf[0x02] = 0x0D; + usb_buf[0x03] = 0x01; + usb_buf[0x04] = 0x61; + usb_buf[0x05] = 0x6D; + hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH); + + memset(usb_buf, 0x00, sizeof(usb_buf)); + usb_buf[0x01] = 0x08; + usb_buf[0x02] = 0x09; + usb_buf[0x03] = 0x01; + hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH); + + memset(usb_buf, 0x00, sizeof(usb_buf)); + usb_buf[0x01] = 0x08; + usb_buf[0x02] = 0x06; + usb_buf[0x03] = 0x01; + usb_buf[0x04] = 0x78; + usb_buf[0x08] = mode_value & 0x00FF; + usb_buf[0x09] = mode_value >> 8; + + if(color_mode != MODE_COLORS_NONE) + { + usb_buf[0x0A] = color_mode == MODE_COLORS_RANDOM ? CORSAIR_HW_MODE_COLOR_RANDOM : CORSAIR_HW_MODE_COLOR_PREDEF; + } + + if(mode_value == CORSAIR_HW_MODE_WATER_COLOR_VALUE) + { + usb_buf[0x0A] = CORSAIR_HW_MODE_COLOR_UNKNOWN; + } + + usb_buf[0x0B] = speed; + + if((mode_value == CORSAIR_HW_MODE_COLOR_WAVE_VALUE) || + (mode_value == CORSAIR_HW_MODE_RAINBOW_WAVE_VALUE) || + (mode_value == CORSAIR_HW_MODE_RAIN_VALUE) || + (mode_value == CORSAIR_HW_MODE_SPIRAL_VALUE) || + (mode_value == CORSAIR_HW_MODE_VISOR_VALUE)) + { + switch(direction) + { + case MODE_DIRECTION_LEFT: + if(mode_value == CORSAIR_HW_MODE_SPIRAL_VALUE) + { + usb_buf[0x0C] = CORSAIE_HW_MODE_DIR_COUNTER_CLOCK_WISE; + } + else + { + usb_buf[0x0C] = CORSAIR_HW_MODE_DIR_LEFT; + } + break; + + case MODE_DIRECTION_RIGHT: + if(mode_value == CORSAIR_HW_MODE_SPIRAL_VALUE) + { + usb_buf[0x0C] = CORSAIR_HW_MODE_DIR_CLOCK_WISE; + } + else + { + usb_buf[0x0C] = CORSAIR_HW_MODE_DIR_RIGHT; + } + break; + + case MODE_DIRECTION_UP: + usb_buf[0x0C] = CORSAIR_HW_MODE_DIR_UP; + break; + + case MODE_DIRECTION_DOWN: + usb_buf[0x0C] = CORSAIR_HW_MODE_DIR_DOWN; + break; + + default: + usb_buf[0x0C] = CORSAIR_HW_MODE_DIR_NONE; + break; + } + } + + int fill_dest_index = 0x0F; + int fill_src_index = 0x00; + + if(usb_buf[0x0A] != CORSAIR_HW_MODE_COLOR_RANDOM) + { + usb_buf[0x0E] = (unsigned char)colors.size(); + + for(size_t i = 0; i < colors.size(); ++i) + { + usb_buf[0x0F + i * 4] = 0xFF; + usb_buf[0x10 + i * 4] = RGBGetBValue(colors[i]); + usb_buf[0x11 + i * 4] = RGBGetGValue(colors[i]); + usb_buf[0x12 + i * 4] = RGBGetRValue(colors[i]); + usb_buf[4] += 4; + fill_dest_index += 4; + } + } + + memcpy(&usb_buf[fill_dest_index], &filler[fill_src_index], HID_PACKET_LENGTH - fill_dest_index); + fill_src_index += (HID_PACKET_LENGTH - fill_dest_index); + hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH); + + memset(usb_buf, 0x00, sizeof(usb_buf)); + usb_buf[0x01] = 0x08; + usb_buf[0x02] = 0x07; + usb_buf[0x03] = 0x01; + memcpy(&usb_buf[4], &filler[fill_src_index], HID_PACKET_LENGTH - 4); + fill_src_index += (HID_PACKET_LENGTH - 4); + hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH); + + memset(usb_buf, 0x00, sizeof(usb_buf)); + usb_buf[0x01] = 0x08; + usb_buf[0x02] = 0x07; + usb_buf[0x03] = 0x01; + memcpy(&usb_buf[4], &filler[fill_src_index], sizeof(filler) - fill_src_index); + hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH); + + memset(usb_buf, 0x00, sizeof(usb_buf)); + usb_buf[0x01] = 0x08; + usb_buf[0x02] = 0x05; + usb_buf[0x03] = 0x01; + usb_buf[0x04] = 0x01; + hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH); +} + +void CorsairK55RGBPROXTController::SwitchMode(bool software) +{ + if(software) + { + LightingControl(); + } + else + { + unsigned char usb_buf[HID_PACKET_LENGTH]; + + memset(usb_buf, 0x00, sizeof(usb_buf)); + usb_buf[0x01] = 0x00; + usb_buf[0x02] = 0x01; + usb_buf[0x03] = 0x03; + usb_buf[0x05] = 0x01; + hid_write(dev, (unsigned char *)usb_buf, HID_PACKET_LENGTH); + } +} diff --git a/Controllers/CorsairPeripheralController/CorsairK55RGBPROXTController.h b/Controllers/CorsairPeripheralController/CorsairK55RGBPROXTController.h new file mode 100644 index 00000000..c7920a3f --- /dev/null +++ b/Controllers/CorsairPeripheralController/CorsairK55RGBPROXTController.h @@ -0,0 +1,90 @@ +/*--------------------------------------------*\ +| CorsairK55RGBPROXTController.h | +| | +| Driver for Corsair K55 RGB PRO XT Keyboard | +\*--------------------------------------------*/ + +#ifndef CORSAIRK55RGBPROXTCONTROLLER_H +#define CORSAIRK55RGBPROXTCONTROLLER_H + +#include "RGBController.h" + +#include +#include + + +class CorsairK55RGBPROXTController +{ +public: + CorsairK55RGBPROXTController(hid_device* dev_handle, const char* path); + ~CorsairK55RGBPROXTController(); + std::string GetDeviceLocation(); + std::string GetFirmwareString(); + std::string GetSerialString(); + + void SetLEDs(std::vector colors); + void SetHardwareMode + ( + int mode_value, + unsigned int color_mode, + std::vector colors, + unsigned int speed, + unsigned int direction + ); + void SwitchMode(bool software); + + + enum + { + CORSAIR_MODE_DIRECT_VALUE = 0xFFFF, + CORSAIR_HW_MODE_STATIC_VALUE = 0x207E, + CORSAIR_HW_MODE_COLOR_PULSE_VALUE = 0xAD4F, + CORSAIR_HW_MODE_COLOR_SHIFT_VALUE = 0xA5FA, + CORSAIR_HW_MODE_COLOR_WAVE_VALUE = 0x7BFF, + CORSAIR_HW_MODE_RAINBOW_WAVE_VALUE = 0xB94C, + CORSAIR_HW_MODE_RAIN_VALUE = 0xA07E, + CORSAIR_HW_MODE_SPIRAL_VALUE = 0xAB87, + CORSAIR_HW_MODE_WATER_COLOR_VALUE = 0x0022, + CORSAIR_HW_MODE_TYPE_KEY_VALUE = 0xB1F9, + CORSAIR_HW_MODE_TYPE_RIPPLE_VALUE = 0x09A2, + CORSAIR_HW_MODE_VISOR_VALUE = 0x90c0 + }; + + enum + { + CORSAIR_HW_MODE_COLOR_NONE = 0x00, + CORSAIR_HW_MODE_COLOR_PREDEF = 0x01, + CORSAIR_HW_MODE_COLOR_RANDOM = 0x02, + CORSAIR_HW_MODE_COLOR_UNKNOWN = 0x03 + }; + + enum + { + CORSAIR_HW_MODE_SPEED_NONE = 0x00, + CORSAIR_HW_MODE_SPEED_MIN = 0x03, + CORSAIR_HW_MODE_SPEED_MED = 0x04, + CORSAIR_HW_MODE_SPEED_MAX = 0x05 + }; + + enum + { + CORSAIR_HW_MODE_DIR_NONE = 0x00, + CORSAIR_HW_MODE_DIR_DOWN = 0x01, + CORSAIR_HW_MODE_DIR_UP = 0x02, + CORSAIR_HW_MODE_DIR_RIGHT = 0x04, + CORSAIR_HW_MODE_DIR_LEFT = 0x05, + CORSAIR_HW_MODE_DIR_CLOCK_WISE = 0x06, + CORSAIE_HW_MODE_DIR_COUNTER_CLOCK_WISE = 0x07 + }; + +private: + hid_device* dev; + + std::string firmware_version; + std::string location; + device_type type; + + void LightingControl(); +}; + +#endif // CORSAIRK55RGBPROXTCONTROLLER_H diff --git a/Controllers/CorsairPeripheralController/CorsairPeripheralControllerDetect.cpp b/Controllers/CorsairPeripheralController/CorsairPeripheralControllerDetect.cpp index 7afdab61..9ad0c06c 100644 --- a/Controllers/CorsairPeripheralController/CorsairPeripheralControllerDetect.cpp +++ b/Controllers/CorsairPeripheralController/CorsairPeripheralControllerDetect.cpp @@ -3,6 +3,7 @@ \*-----------------------------------------------------*/ #include #include "Detector.h" +#include "CorsairK55RGBPROXTController.h" #include "LogManager.h" #include "RGBController.h" @@ -11,6 +12,7 @@ \*-----------------------------------------------------*/ #include "RGBController_CorsairPeripheral.h" #include "RGBController_CorsairK100.h" +#include "RGBController_CorsairK55RGBPROXT.h" #include "RGBController_CorsairK65Mini.h" #include "RGBController_CorsairK95PlatinumXT.h" @@ -84,6 +86,12 @@ \*-----------------------------------------------------*/ #define CORSAIR_K100_PID 0x1B7C +/*-----------------------------------------------------*\ +| Corsair K55 RGB PRO XT Keyboard product ID | +| This keyboard uses a separate driver | +\*-----------------------------------------------------*/ +#define CORSAIR_K55_RGB_PRO_XT_PID 0x1BA1 + /*-----------------------------------------------------*\ | Corsair K65 Mini Keyboard product ID | | This keyboard uses a separate driver | @@ -117,6 +125,19 @@ void DetectCorsairK100Controllers(hid_device_info* info, const std::string& name } } /* DetectCorsairPeripheralControllers() */ +void DetectCorsairK55RGBPROXTControllers(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + + if(dev) + { + CorsairK55RGBPROXTController* controller = new CorsairK55RGBPROXTController(dev, info->path); + RGBController_CorsairK55RGBPROXT* rgb_controller = new RGBController_CorsairK55RGBPROXT(controller); + rgb_controller->name = name; + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} /* DetectCorsairK55RGBPROXTControllers() */ + void DetectCorsairK65MiniControllers(hid_device_info* info, const std::string& name) { hid_device* dev = hid_open_path(info->path); @@ -241,6 +262,12 @@ REGISTER_HID_DETECTOR_IP("Corsair K100", DetectCorsairK100Con \*-----------------------------------------------------------------------------------------------------*/ REGISTER_HID_DETECTOR_I("Corsair K65 Mini", DetectCorsairK65MiniControllers, CORSAIR_VID, CORSAIR_K65_MINI_PID, 1); +/*-----------------------------------------------------------------------------------------------------*\ +| Corsair K55 RGB PRO XT Keyboard | +\*-----------------------------------------------------------------------------------------------------*/ +REGISTER_HID_DETECTOR_IP("Corsair K55 RGB PRO XT", DetectCorsairK55RGBPROXTControllers, CORSAIR_VID, CORSAIR_K55_RGB_PRO_XT_PID, 1, 0xFF42); + + /*-----------------------------------------------------------------------------------------------------*\ | Corsair K95 Platinum XT Keyboard | \*-----------------------------------------------------------------------------------------------------*/ diff --git a/Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPROXT.cpp b/Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPROXT.cpp new file mode 100644 index 00000000..572d6c33 --- /dev/null +++ b/Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPROXT.cpp @@ -0,0 +1,443 @@ +/*--------------------------------------------*\ +| RGBController_CorsairK55RGBPROXT.cpp | +| | +| Driver for Corsair K55 RGB PRO XT Keyboard | +\*--------------------------------------------*/ + +#include "RGBController_CorsairK55RGBPROXT.h" +#include "RGBControllerKeyNames.h" +#include "LogManager.h" + +using namespace std::chrono_literals; + +#define NA 0xFFFFFFFF +#define WIDTH 24 +#define HEIGHT 6 + +static unsigned int matrix_map[HEIGHT][WIDTH] = + { { 0, 6, NA, 15, 21, 26, 31, NA, 37, 43, 47, 52, NA, 60, 66, 72, 78, 81, 85, 90, NA, NA, NA, NA }, + { 1, 7, 12, 16, 22, 27, 32, 36, 38, 44, 48, 53, NA, 61, 67, 73, NA, 82, 86, 91, 94, 99, 103, 108 }, + { 2, 8, NA, 17, 23, 28, 33, NA, 39, 45, 49, 54, 57, 62, 68, 74, 79, 83, 87, 92, 95, 100, 104, 109 }, + { 3, 9, NA, 18, 24, 29, 34, NA, 40, 46, 50, 55, 58, 63, 69, 75, NA, NA, NA, NA, 96, 101, 105, NA }, + { 4, 10, 13, 19, 25, 30, 35, NA, 41, NA, 51, 56, 59, 64, 70, 76, NA, NA, 88, NA, 97, 102, 106, 110 }, + { 5, 11, 14, 20, NA, NA, NA, NA, 42, NA, NA, NA, NA, 65, 71, 77, 80, 84, 89, 93, 98, NA, 107, NA } }; + +std::vector key_names = +{ + // col 0 + "Key: G1", + "Key: G2", + "Key: G3", + "Key: G4", + "Key: G5", + "Key: G6", + + // col 1 + KEY_EN_ESCAPE, + KEY_EN_BACK_TICK, + KEY_EN_TAB, + KEY_EN_CAPS_LOCK, + KEY_EN_LEFT_SHIFT, + KEY_EN_LEFT_CONTROL, + + // col 2 + KEY_EN_1, + KEY_EN_ISO_BACK_SLASH, + KEY_EN_LEFT_WINDOWS, + + // col 3 + KEY_EN_F1, + KEY_EN_2, + KEY_EN_Q, + KEY_EN_A, + KEY_EN_Z, + KEY_EN_LEFT_ALT, + + // col 4 + KEY_EN_F2, + KEY_EN_3, + KEY_EN_W, + KEY_EN_S, + KEY_EN_X, + + // col 5 + KEY_EN_F3, + KEY_EN_4, + KEY_EN_E, + KEY_EN_D, + KEY_EN_C, + + // col 6 + KEY_EN_F4, + KEY_EN_5, + KEY_EN_R, + KEY_EN_F, + KEY_EN_V, + + // col 7 + KEY_EN_6, + + // col 8 + KEY_EN_F5, + KEY_EN_7, + KEY_EN_T, + KEY_EN_G, + KEY_EN_B, + KEY_EN_SPACE, + + // col 9 + KEY_EN_F6, + KEY_EN_8, + KEY_EN_Y, + KEY_EN_H, + + // col 10 + KEY_EN_F7, + KEY_EN_9, + KEY_EN_U, + KEY_EN_J, + KEY_EN_N, + + // col 11 + KEY_EN_F8, + KEY_EN_0, + KEY_EN_I, + KEY_EN_K, + KEY_EN_M, + + // col 12 + KEY_EN_O, + KEY_EN_L, + KEY_EN_COMMA, + + // col 13 + KEY_EN_F9, + KEY_EN_MINUS, + KEY_EN_P, + KEY_EN_SEMICOLON, + KEY_EN_PERIOD, + KEY_EN_RIGHT_ALT, + + // col 14 + KEY_EN_F10, + KEY_EN_EQUALS, + KEY_EN_LEFT_BRACKET, + KEY_EN_QUOTE, + KEY_EN_FORWARD_SLASH, + KEY_EN_RIGHT_FUNCTION, + + // col 15 + KEY_EN_F11, + KEY_EN_BACKSPACE, + KEY_EN_RIGHT_BRACKET, + KEY_EN_POUND, + KEY_EN_RIGHT_SHIFT, + KEY_EN_MENU, + + // col 16 + KEY_EN_F12, + KEY_EN_ANSI_ENTER, + KEY_EN_RIGHT_CONTROL, + + // col 17 + KEY_EN_PRINT_SCREEN, + KEY_EN_INSERT, + KEY_EN_DELETE, + KEY_EN_LEFT_ARROW, + + // col 18 + KEY_EN_SCROLL_LOCK, + KEY_EN_HOME, + KEY_EN_END, + KEY_EN_UP_ARROW, + KEY_EN_DOWN_ARROW, + + // col 19 + KEY_EN_PAUSE_BREAK, + KEY_EN_PAGE_UP, + KEY_EN_PAGE_DOWN, + KEY_EN_RIGHT_ARROW, + + // col 20 + KEY_EN_NUMPAD_LOCK, + KEY_EN_NUMPAD_7, + KEY_EN_NUMPAD_4, + KEY_EN_NUMPAD_1, + KEY_EN_NUMPAD_0, + + // col 21 + KEY_EN_NUMPAD_DIVIDE, + KEY_EN_NUMPAD_8, + KEY_EN_NUMPAD_5, + KEY_EN_NUMPAD_2, + + // col 22 + KEY_EN_NUMPAD_TIMES, + KEY_EN_NUMPAD_9, + KEY_EN_NUMPAD_6, + KEY_EN_NUMPAD_3, + KEY_EN_NUMPAD_PERIOD, + + // col 23 + KEY_EN_NUMPAD_MINUS, + KEY_EN_NUMPAD_PLUS, + KEY_EN_NUMPAD_ENTER +}; + + +/**------------------------------------------------------------------*\ + @name Corsair K55 RGB Pro XT + @category Keyboard + @type USB + @save :x: + @direct :white_check_mark: + @effects :white_check_mark: + @detectors DetectCorsairK55RGBPROXTControllers + @comment +\*-------------------------------------------------------------------*/ + + +RGBController_CorsairK55RGBPROXT::RGBController_CorsairK55RGBPROXT(CorsairK55RGBPROXTController* controller_ptr) +{ + controller = controller_ptr; + + vendor = "Corsair"; + description = "Corsair K55 RGB PRO XT Keyboard Device"; + type = DEVICE_TYPE_KEYBOARD; + version = controller->GetFirmwareString(); + location = controller->GetDeviceLocation(); + serial = controller->GetSerialString(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = CorsairK55RGBPROXTController::CORSAIR_MODE_DIRECT_VALUE; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + mode Static; + Static.name = "Static"; + Static.value = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_STATIC_VALUE; + Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + Static.color_mode = MODE_COLORS_MODE_SPECIFIC; + Static.colors.resize(1); + modes.push_back(Static); + + mode ColorPulse; + ColorPulse.name = "ColorPulse"; + ColorPulse.value = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_COLOR_PULSE_VALUE; + ColorPulse.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + ColorPulse.color_mode = MODE_COLORS_RANDOM; + ColorPulse.speed = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MED; + ColorPulse.speed_min = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MIN; + ColorPulse.speed_max = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MAX; + ColorPulse.colors.resize(2); + modes.push_back(ColorPulse); + + mode ColorShift; + ColorShift.name = "ColorShift"; + ColorShift.value = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_COLOR_SHIFT_VALUE; + ColorShift.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + ColorShift.color_mode = MODE_COLORS_RANDOM; + ColorShift.speed = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MED; + ColorShift.speed_min = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MIN; + ColorShift.speed_max = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MAX; + ColorShift.colors.resize(2); + modes.push_back(ColorShift); + + mode ColorWave; + ColorWave.name = "ColorWave"; + ColorWave.value = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_COLOR_WAVE_VALUE; + ColorWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD; + ColorWave.color_mode = MODE_COLORS_RANDOM; + ColorWave.direction = MODE_DIRECTION_RIGHT; + ColorWave.speed = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MED; + ColorWave.speed_min = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MIN; + ColorWave.speed_max = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MAX; + ColorWave.colors.resize(2); + modes.push_back(ColorWave); + + mode RainbowWave; + RainbowWave.name = "RainbowWave"; + RainbowWave.value = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_RAINBOW_WAVE_VALUE; + RainbowWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD; + RainbowWave.color_mode = MODE_COLORS_NONE; + RainbowWave.direction = MODE_DIRECTION_RIGHT; + RainbowWave.speed = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MED; + RainbowWave.speed_min = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MIN; + RainbowWave.speed_max = CorsairK55RGBPROXTController:: CORSAIR_HW_MODE_SPEED_MAX; + modes.push_back(RainbowWave); + + mode Rain; + Rain.name = "Rain"; + Rain.value = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_RAIN_VALUE; + Rain.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + Rain.color_mode = MODE_COLORS_RANDOM; + Rain.direction = MODE_DIRECTION_DOWN; + Rain.speed = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MED; + Rain.speed_min = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MIN; + Rain.speed_max = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MAX; + Rain.colors.resize(2); + modes.push_back(Rain); + + mode Spiral; + Spiral.name = "Spiral"; + Spiral.value = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPIRAL_VALUE; + Spiral.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR; + Spiral.color_mode = MODE_COLORS_NONE; + Spiral.direction = MODE_DIRECTION_RIGHT; + Spiral.speed = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MED; + Spiral.speed_min = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MIN; + Spiral.speed_max = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MAX; + modes.push_back(Spiral); + + mode WaterColor; + WaterColor.name = "WaterColor"; + WaterColor.value = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_WATER_COLOR_VALUE; + WaterColor.flags = MODE_FLAG_HAS_SPEED; + WaterColor.color_mode = MODE_COLORS_NONE; + WaterColor.speed = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MED; + WaterColor.speed_min = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MIN; + WaterColor.speed_max = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MAX; + WaterColor.colors.resize(1); + WaterColor.colors[0] = 0x00FFFFFF; + modes.push_back(WaterColor); + + mode TypeKey; + TypeKey.name = "TypeKey"; + TypeKey.value = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_TYPE_KEY_VALUE; + TypeKey.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + TypeKey.color_mode = MODE_COLORS_RANDOM; + TypeKey.speed = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MED; + TypeKey.speed_min = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MIN; + TypeKey.speed_max = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MAX; + TypeKey.colors.resize(2); + modes.push_back(TypeKey); + + mode TypeRipple; + TypeRipple.name = "TypeRipple"; + TypeRipple.value = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_TYPE_RIPPLE_VALUE; + TypeRipple.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + TypeRipple.color_mode = MODE_COLORS_RANDOM; + TypeRipple.speed = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MED; + TypeRipple.speed_min = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MIN; + TypeRipple.speed_max = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MAX; + TypeRipple.colors.resize(2); + modes.push_back(TypeRipple); + + mode Visor; + Visor.name = "Visor"; + Visor.value = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_VISOR_VALUE; + Visor.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR; + Visor.color_mode = MODE_COLORS_RANDOM; + Visor.direction = MODE_DIRECTION_RIGHT; + Visor.speed = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MED; + Visor.speed_min = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MIN; + Visor.speed_max = CorsairK55RGBPROXTController::CORSAIR_HW_MODE_SPEED_MAX; + Visor.colors.resize(2); + modes.push_back(Visor); + + SetupZones(); + /*-----------------------------------------------------*\ + | The Corsair K55 RGB PRO XT requires a packet within | + | 1 minutes of sending the lighting change in order | + | to not revert back into rainbow mode. Start a thread | + | to continuously send a keepalive packet every 50 sec | + \*-----------------------------------------------------*/ + keepalive_thread_run = true; + keepalive_thread = new std::thread(&RGBController_CorsairK55RGBPROXT::KeepaliveThread, this); +} + +RGBController_CorsairK55RGBPROXT::~RGBController_CorsairK55RGBPROXT() +{ + /*-----------------------------------------------------*\ + | Close keepalive thread | + \*-----------------------------------------------------*/ + keepalive_thread_run = false; + keepalive_thread->join(); + delete keepalive_thread; + delete[] zones[0].matrix_map->map; + + delete controller; +} + +void RGBController_CorsairK55RGBPROXT::SetupZones() +{ + zone keyboard_zone; + keyboard_zone.name = "Keyboard"; + keyboard_zone.type = ZONE_TYPE_MATRIX; + + keyboard_zone.matrix_map = new matrix_map_type; + keyboard_zone.matrix_map->map = (unsigned int *)&matrix_map; + keyboard_zone.matrix_map->height = HEIGHT; + keyboard_zone.matrix_map->width = WIDTH; + + for(size_t led_index = 0; led_index < key_names.size(); ++led_index) + { + led new_led; + new_led.name = key_names[led_index]; + leds.push_back(new_led); + } + + keyboard_zone.leds_min = (unsigned int)leds.size(); + keyboard_zone.leds_max = (unsigned int)leds.size(); + keyboard_zone.leds_count = (unsigned int)leds.size(); + + zones.push_back(keyboard_zone); + + SetupColors(); +} + +void RGBController_CorsairK55RGBPROXT::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_CorsairK55RGBPROXT::DeviceUpdateLEDs() +{ + last_update_time = std::chrono::steady_clock::now(); + + controller->SetLEDs(colors); +} + +void RGBController_CorsairK55RGBPROXT::UpdateZoneLEDs(int /*zone*/) +{ + controller->SetLEDs(colors); +} + +void RGBController_CorsairK55RGBPROXT::UpdateSingleLED(int /*led*/) +{ + controller->SetLEDs(colors); +} + +void RGBController_CorsairK55RGBPROXT::DeviceUpdateMode() +{ + if(modes[active_mode].value == CorsairK55RGBPROXTController::CORSAIR_MODE_DIRECT_VALUE) + { + controller->SwitchMode(true); + } + else + { + const mode& active = modes[active_mode]; + + controller->SetHardwareMode(active.value, active.color_mode, active.colors, active.speed, active.direction); + controller->SwitchMode(false); + } +} + +void RGBController_CorsairK55RGBPROXT::KeepaliveThread() +{ + while(keepalive_thread_run.load()) + { + if(active_mode == 0) + { + if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(50000)) + { + DeviceUpdateLEDs(); + } + } + std::this_thread::sleep_for(3000ms); + } +} diff --git a/Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPROXT.h b/Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPROXT.h new file mode 100644 index 00000000..bafb7a33 --- /dev/null +++ b/Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPROXT.h @@ -0,0 +1,37 @@ +/*--------------------------------------------*\ +| RGBController_CorsairK55RGBPROXT.cpp | +| | +| Driver for Corsair K55 RGB PRO XT Keyboard | +\*--------------------------------------------*/ + +#ifndef RGBCONTROLLER_CORSAIRK55RGBPROXT_H +#define RGBCONTROLLER_CORSAIRK55RGBPROXT_H + +#include "RGBController.h" +#include "CorsairK55RGBPROXTController.h" + +class RGBController_CorsairK55RGBPROXT : public RGBController +{ +public: + RGBController_CorsairK55RGBPROXT(CorsairK55RGBPROXTController* controller_ptr); + ~RGBController_CorsairK55RGBPROXT(); + + void SetupZones(); + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + void KeepaliveThread(); + +private: + CorsairK55RGBPROXTController* controller; + + std::thread* keepalive_thread; + std::atomic keepalive_thread_run; + std::chrono::time_point last_update_time; +}; + +#endif // RGBCONTROLLER_CORSAIRK55RGBPROXT_H diff --git a/OpenRGB.pro b/OpenRGB.pro index cca8484a..98914914 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -319,10 +319,12 @@ HEADERS += Controllers/CorsairLightingNodeController/RGBController_CorsairLightingNode.h \ Controllers/CorsairPeripheralController/CorsairPeripheralController.h \ Controllers/CorsairPeripheralController/CorsairK100Controller.h \ + Controllers/CorsairPeripheralController/CorsairK55RGBPROXTController.h \ Controllers/CorsairPeripheralController/CorsairK65MiniController.h \ Controllers/CorsairPeripheralController/CorsairK95PlatinumXTController.h \ Controllers/CorsairPeripheralController/RGBController_CorsairPeripheral.h \ Controllers/CorsairPeripheralController/RGBController_CorsairK100.h \ + Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPROXT.h \ Controllers/CorsairPeripheralController/RGBController_CorsairK65Mini.h \ Controllers/CorsairPeripheralController/RGBController_CorsairK95PlatinumXT.h \ Controllers/CorsairPeripheralV2Controller/CorsairPeripheralV2Controller.h \ @@ -810,10 +812,12 @@ SOURCES += Controllers/CorsairPeripheralController/CorsairPeripheralController.cpp \ Controllers/CorsairPeripheralController/CorsairPeripheralControllerDetect.cpp \ Controllers/CorsairPeripheralController/CorsairK100Controller.cpp \ + Controllers/CorsairPeripheralController/CorsairK55RGBPROXTController.cpp \ Controllers/CorsairPeripheralController/CorsairK65MiniController.cpp \ Controllers/CorsairPeripheralController/CorsairK95PlatinumXTController.cpp \ Controllers/CorsairPeripheralController/RGBController_CorsairPeripheral.cpp \ Controllers/CorsairPeripheralController/RGBController_CorsairK100.cpp \ + Controllers/CorsairPeripheralController/RGBController_CorsairK55RGBPROXT.cpp \ Controllers/CorsairPeripheralController/RGBController_CorsairK65Mini.cpp \ Controllers/CorsairPeripheralController/RGBController_CorsairK95PlatinumXT.cpp \ Controllers/CorsairPeripheralV2Controller/CorsairPeripheralV2Controller.cpp \