Support for Corsair K55 RGB PRO XT (fixes issue #2555)

This commit is contained in:
Thomas Boos 2022-08-27 19:13:42 +00:00 committed by Adam Honse
parent 38dd53b945
commit 6d1f8967a0
6 changed files with 888 additions and 0 deletions

View file

@ -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::vector<RGBColor>colors)
{
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<RGBColor> 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);
}
}

View file

@ -0,0 +1,90 @@
/*--------------------------------------------*\
| CorsairK55RGBPROXTController.h |
| |
| Driver for Corsair K55 RGB PRO XT Keyboard |
\*--------------------------------------------*/
#ifndef CORSAIRK55RGBPROXTCONTROLLER_H
#define CORSAIRK55RGBPROXTCONTROLLER_H
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
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<RGBColor> colors);
void SetHardwareMode
(
int mode_value,
unsigned int color_mode,
std::vector<RGBColor> 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

View file

@ -3,6 +3,7 @@
\*-----------------------------------------------------*/
#include <hidapi/hidapi.h>
#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 |
\*-----------------------------------------------------------------------------------------------------*/

View file

@ -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<std::string> 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);
}
}

View file

@ -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<bool> keepalive_thread_run;
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
};
#endif // RGBCONTROLLER_CORSAIRK55RGBPROXT_H

View file

@ -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 \