Publish LumaOps source

This commit is contained in:
LumaOps release export
2026-09-03 01:18:36 +02:00
commit 7f1c0e5f71
2363 changed files with 501543 additions and 0 deletions
@@ -0,0 +1,287 @@
/*---------------------------------------------------------*\
| CorsairK55RGBPROXTController.cpp |
| |
| Driver for Corsair K55 RGB PRO XT keyboard |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "CorsairK55RGBPROXTController.h"
#include "LogManager.h"
#include "StringUtils.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, std::string dev_name)
{
dev = dev_handle;
location = path;
name = dev_name;
LightingControl();
}
CorsairK55RGBPROXTController::~CorsairK55RGBPROXTController()
{
hid_close(dev);
}
std::string CorsairK55RGBPROXTController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string CorsairK55RGBPROXTController::GetNameString()
{
return(name);
}
std::string CorsairK55RGBPROXTController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
return(StringUtils::wstring_to_string(serial_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);
}
}
@@ -0,0 +1,87 @@
/*---------------------------------------------------------*\
| CorsairK55RGBPROXTController.h |
| |
| Driver for Corsair K55 RGB PRO XT keyboard |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <string>
#include <hidapi.h>
#include "RGBController.h"
class CorsairK55RGBPROXTController
{
public:
CorsairK55RGBPROXTController(hid_device* dev_handle, const char* path, std::string dev_name);
~CorsairK55RGBPROXTController();
std::string GetDeviceLocation();
std::string GetNameString();
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 location;
std::string name;
void LightingControl();
};
@@ -0,0 +1,111 @@
/*---------------------------------------------------------*\
| CorsairK65MiniController.cpp |
| |
| Driver for Corsair K65 Mini keyboard |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "CorsairK65MiniController.h"
#include "LogManager.h"
#include "StringUtils.h"
CorsairK65MiniController::CorsairK65MiniController(hid_device* dev_handle, const char* path, std::string dev_name)
{
dev = dev_handle;
location = path;
name = dev_name;
LightingControl();
}
CorsairK65MiniController::~CorsairK65MiniController()
{
hid_close(dev);
}
std::string CorsairK65MiniController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string CorsairK65MiniController::GetName()
{
return(name);
}
std::string CorsairK65MiniController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
return(StringUtils::wstring_to_string(serial_string));
}
void CorsairK65MiniController::LightingControl()
{
/*-----------------------------------------*\
| A few init packets have to be sent to |
| enabled software control |
\*-----------------------------------------*/
unsigned char usb_buf[PACKET_LENGTH];
memset(usb_buf, 0x00, PACKET_LENGTH);
usb_buf[0x01] = K65_WRITE_COMMAND;
usb_buf[0x02] = 0x01;
usb_buf[0x03] = 0x03;
usb_buf[0x05] = 0x02;
hid_write(dev, usb_buf, PACKET_LENGTH);
memset(usb_buf, 0x00, PACKET_LENGTH);
usb_buf[0x01] = K65_WRITE_COMMAND;
usb_buf[0x02] = 0x02;
usb_buf[0x03] = 0x6E;
hid_write(dev, usb_buf, PACKET_LENGTH);
memset(usb_buf, 0x00, PACKET_LENGTH);
usb_buf[0x01] = K65_WRITE_COMMAND;
usb_buf[0x02] = 0x0D;
usb_buf[0x03] = 0x01;
usb_buf[0x04] = 0x22;
hid_write(dev, usb_buf, PACKET_LENGTH);
}
void CorsairK65MiniController::SetLEDs(std::vector<RGBColor>colors, std::vector<unsigned int> positions)
{
unsigned char usb_buf[PACKET_LENGTH];
memset(usb_buf, 0x00, PACKET_LENGTH);
/*-----------------------------------------*\
| Direct mode pattern |
| 08 06 01 73 01 00 00 12 00 RR GG BB ... |
\*-----------------------------------------*/
usb_buf[0x01] = K65_WRITE_COMMAND;
usb_buf[0x02] = 0x06;
usb_buf[0x03] = 0x01;
usb_buf[0x04] = 0x73;
usb_buf[0x05] = 0x01;
usb_buf[0x08] = 0x12;
for(unsigned int i = 0 ; i < colors.size(); i++)
{
unsigned int position = positions[i];
usb_buf[0x0A + position * 3] = RGBGetRValue(colors[i]);
usb_buf[0x0A + position * 3 + 1] = RGBGetGValue(colors[i]);
usb_buf[0x0A + position * 3 + 2] = RGBGetBValue(colors[i]);
}
hid_write(dev, usb_buf, PACKET_LENGTH);
}
@@ -0,0 +1,37 @@
/*---------------------------------------------------------*\
| CorsairK65MiniController.cpp |
| |
| Driver for Corsair K65 Mini keyboard |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <string>
#include <hidapi.h>
#include "RGBController.h"
#define PACKET_LENGTH 1025
#define K65_WRITE_COMMAND 0x08
class CorsairK65MiniController
{
public:
CorsairK65MiniController(hid_device* dev_handle, const char* path, std::string dev_name);
~CorsairK65MiniController();
std::string GetDeviceLocation();
std::string GetName();
std::string GetSerialString();
void SetLEDs(std::vector<RGBColor> colors, std::vector<unsigned int> positions);
private:
hid_device* dev;
std::string location;
std::string name;
void LightingControl();
};
@@ -0,0 +1,983 @@
/*---------------------------------------------------------*\
| CorsairPeripheralController.cpp |
| |
| Driver for Corsair peripherals |
| |
| Adam Honse (CalcProgrammer1) 09 Jan 2020 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <cstring>
#include "CorsairPeripheralController.h"
#include "LogManager.h"
#include "StringUtils.h"
using namespace std::chrono_literals;
static unsigned int keys[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12,
0x14, 0x15, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x24, 0x25, 0x26,
0x27, 0x28, 0x2A, 0x2B, 0x2C, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x42, 0x43, 0x44, 0x45, 0x48, 73, 74, 75, 76, 78,
79, 80, 81, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 96, 97,
98, 99, 100, 101, 102, 103, 104, 105, 108, 109, 110, 111, 112, 113, 115,
116, 117, 120, 121, 122, 123, 124, 126, 127, 128, 129, 132, 133, 134, 135,
136, 137, 139, 140, 141, 0x10, 114};
static unsigned int keys_k70_mk2[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12,
0x14, 0x15, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x24, 0x25, 0x26,
0x27, 0x28, 0x2A, 0x2B, 0x2C, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x42, 0x43, 0x44, 0x45, 0x48, 73, 74, 75, 76, 78,
79, 80, 81, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 96, 97,
98, 99, 100, 101, 102, 103, 104, 105, 108, 109, 110, 111, 112, 113, 115,
116, 117, 120, 121, 122, 123, 124, 126, 127, 128, 129, 132, 133, 134, 135,
136, 137, 139, 140, 141, 16, 114, 47, 59, 125 };
static unsigned int keys_k95_plat[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12,
0x14, 0x15, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x24, 0x25, 0x26,
0x27, 0x28, 0x2A, 0x2B, 0x2C, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x42, 0x43, 0x44, 0x45, 0x48, 73, 74, 75, 76, 78,
79, 80, 81, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 96, 97,
98, 99, 100, 101, 102, 103, 104, 105, 108, 109, 110, 111, 112, 113, 115,
116, 117, 120, 121, 122, 123, 124, 126, 127, 128, 129, 132, 133, 134, 135,
136, 137, 139, 140, 141,
0x10, 114, 0x0a, 0x16, 0x22, 0x2e, 0x3a, 0x46, 125,
144, 145, 146, 158, 160, 147, 148, 149, 150, 151, 152, 153,
154, 155, 159, 162, 161, 156, 157};
static unsigned int keys_k95[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12,
0x14, 0x15, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x24, 0x25, 0x26,
0x27, 0x28, 0x2A, 0x2B, 0x2C, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x42, 0x43, 0x44, 0x45, 0x48, 73, 74, 75, 76, 78,
79, 80, 81, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 96, 97,
98, 99, 100, 101, 102, 103, 104, 105, 108, 109, 110, 111, 112, 113, 115,
116, 117, 120, 121, 122, 123, 124, 126, 127, 128, 129, 132, 133, 134, 135,
136, 137, 139, 140, 141,
0x10, 114, 0x0a, 0x16, 0x22, 0x2e, 0x3a, 0x46, 0x52, 0x5e, 0x6a, 0x76, 0x3b, 0x47, 0x53,
0x5f, 0x6b, 0x77, 0x83, 0x8f, 0x0b, 0x17, 0x23, 0x2f};
static unsigned int st100[] = { 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x04 };
static unsigned int key_mapping_k95_plat_ansi[] = { 0x31, 0x3f, 0x41, 0x42, 0x51, 0x53, 0x55, 0x6f, 0x7e, 0x7f, 0x80, 0x81 };
static unsigned int key_mapping_k95_plat_iso[] = { 0x3f, 0x41, 0x42, 0x50, 0x53, 0x55, 0x6f, 0x78, 0x7e, 0x7f, 0x80, 0x81 };
static unsigned int key_mapping_k70_mk2_plat_iso[] = { 0x3f, 0x41, 0x42, 0x50, 0x53, 0x55, 0x6f, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81 };
#define CORSAIR_PERIPHERAL_CONTROLLER_NAME "Corsair peripheral"
CorsairPeripheralController::CorsairPeripheralController(hid_device* dev_handle, const char* path, std::string dev_name)
{
dev = dev_handle;
location = path;
name = dev_name;
ReadFirmwareInfo();
/*-----------------------------------------------------*\
| K55 and K95 Platinum require additional steps |
\*-----------------------------------------------------*/
if (logical_layout == CORSAIR_TYPE_K55 || logical_layout == CORSAIR_TYPE_K95_PLAT || logical_layout == CORSAIR_TYPE_K70_MK2 || logical_layout == CORSAIR_TYPE_K68)
{
SpecialFunctionControl();
}
LightingControl();
if (logical_layout == CORSAIR_TYPE_K55 || logical_layout == CORSAIR_TYPE_K95_PLAT || logical_layout == CORSAIR_TYPE_K70_MK2 || logical_layout == CORSAIR_TYPE_K68)
{
SetupK55AndK95LightingControl();
}
}
CorsairPeripheralController::~CorsairPeripheralController()
{
hid_close(dev);
}
device_type CorsairPeripheralController::GetDeviceType()
{
return type;
}
std::string CorsairPeripheralController::GetDeviceLocation()
{
return("HID: " + location);
}
int CorsairPeripheralController::GetPhysicalLayout()
{
return physical_layout;
}
int CorsairPeripheralController::GetLogicalLayout()
{
return logical_layout;
}
std::string CorsairPeripheralController::GetFirmwareString()
{
return firmware_version;
}
std::string CorsairPeripheralController::GetName()
{
return name;
}
std::string CorsairPeripheralController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
return(StringUtils::wstring_to_string(serial_string));
}
void CorsairPeripheralController::SetLEDs(std::vector<RGBColor>colors)
{
switch(type)
{
case DEVICE_TYPE_KEYBOARD:
if (logical_layout == CORSAIR_TYPE_K55)
{
SubmitKeyboardZonesColors(colors[0], colors[1], colors[2]);
}
else
{
SetLEDsKeyboardFull(colors);
}
break;
case DEVICE_TYPE_MOUSE:
SetLEDsMouse(colors);
break;
case DEVICE_TYPE_MOUSEMAT:
SetLEDsMousemat(colors);
break;
case DEVICE_TYPE_HEADSET_STAND:
/*-----------------------------------------------------*\
| The logo zone of the ST100 is in the middle of the |
| base LED strip, so remap the colors so that the logo |
| is the last LED in the sequence. |
\*-----------------------------------------------------*/
std::vector<RGBColor> remap_colors;
remap_colors.resize(colors.size());
for(int i = 0; i < 9; i++)
{
remap_colors[st100[i]] = colors[i];
}
/*-----------------------------------------------------*\
| The ST100 uses the mousemat protocol |
\*-----------------------------------------------------*/
SetLEDsMousemat(remap_colors);
break;
}
}
void CorsairPeripheralController::SetLEDsKeyboardFull(std::vector<RGBColor> colors)
{
unsigned char red_val[168];
unsigned char grn_val[168];
unsigned char blu_val[168];
unsigned char data_sz = 24;
/*-----------------------------------------------------*\
| Zero out buffers |
\*-----------------------------------------------------*/
memset(red_val, 0x00, sizeof( red_val ));
memset(grn_val, 0x00, sizeof( grn_val ));
memset(blu_val, 0x00, sizeof( blu_val ));
/*-----------------------------------------------------*\
| Copy red, green, and blue components into buffers |
\*-----------------------------------------------------*/
for(std::size_t color_idx = 0; color_idx < colors.size(); color_idx++)
{
RGBColor color = colors[color_idx];
if (logical_layout == CORSAIR_TYPE_K95_PLAT)
{
red_val[keys_k95_plat[color_idx]] = RGBGetRValue(color);
grn_val[keys_k95_plat[color_idx]] = RGBGetGValue(color);
blu_val[keys_k95_plat[color_idx]] = RGBGetBValue(color);
data_sz = 48;
}
else if (logical_layout == CORSAIR_TYPE_K95)
{
red_val[keys_k95[color_idx]] = RGBGetRValue(color);
grn_val[keys_k95[color_idx]] = RGBGetGValue(color);
blu_val[keys_k95[color_idx]] = RGBGetBValue(color);
data_sz = 48; //untested
}
else if (logical_layout == CORSAIR_TYPE_K70_MK2)
{
red_val[keys_k70_mk2[color_idx]] = RGBGetRValue(color);
grn_val[keys_k70_mk2[color_idx]] = RGBGetGValue(color);
blu_val[keys_k70_mk2[color_idx]] = RGBGetBValue(color);
}
else
{
red_val[keys[color_idx]] = RGBGetRValue(color);
grn_val[keys[color_idx]] = RGBGetGValue(color);
blu_val[keys[color_idx]] = RGBGetBValue(color);
}
}
/*-----------------------------------------------------*\
| Send red bytes |
\*-----------------------------------------------------*/
StreamPacket(1, 60, &red_val[0]);
StreamPacket(2, 60, &red_val[60]);
StreamPacket(3, data_sz, &red_val[120]);
SubmitKeyboardFullColors(1, 3, 1);
/*-----------------------------------------------------*\
| Send green bytes |
\*-----------------------------------------------------*/
StreamPacket(1, 60, &grn_val[0]);
StreamPacket(2, 60, &grn_val[60]);
StreamPacket(3, data_sz, &grn_val[120]);
SubmitKeyboardFullColors(2, 3, 1);
/*-----------------------------------------------------*\
| Send blue bytes |
\*-----------------------------------------------------*/
StreamPacket(1, 60, &blu_val[0]);
StreamPacket(2, 60, &blu_val[60]);
StreamPacket(3, data_sz, &blu_val[120]);
SubmitKeyboardFullColors(3, 3, 2);
}
void CorsairPeripheralController::SetLEDsMouse(std::vector<RGBColor> colors)
{
SubmitMouseColors((unsigned char)colors.size(), &colors[0]);
}
void CorsairPeripheralController::SetLEDsMousemat(std::vector<RGBColor> colors)
{
SubmitMousematColors((unsigned char)colors.size(), &colors[0]);
}
void CorsairPeripheralController::SetLEDsKeyboardLimited(std::vector<RGBColor> colors)
{
unsigned char data_pkt[216];
unsigned char red_val[144];
unsigned char grn_val[144];
unsigned char blu_val[144];
/*-----------------------------------------------------*\
| Zero out buffers |
\*-----------------------------------------------------*/
memset(data_pkt, 0x00, sizeof( data_pkt ));
memset(red_val, 0x00, sizeof( red_val ));
memset(grn_val, 0x00, sizeof( grn_val ));
memset(blu_val, 0x00, sizeof( blu_val ));
/*-----------------------------------------------------*\
| Scale color values to 9-bit |
\*-----------------------------------------------------*/
for(std::size_t color_idx = 0; color_idx < colors.size(); color_idx++)
{
RGBColor color = colors[color_idx];
unsigned char red = RGBGetRValue(color);
unsigned char grn = RGBGetGValue(color);
unsigned char blu = RGBGetBValue(color);
if( red > 7 ) red = 7;
if( grn > 7 ) grn = 7;
if( blu > 7 ) blu = 7;
red = 7 - red;
grn = 7 - grn;
blu = 7 - blu;
red_val[keys[color_idx]] = red;
grn_val[keys[color_idx]] = grn;
blu_val[keys[color_idx]] = blu;
}
/*-----------------------------------------------------*\
| Pack the color values, 2 values per byte |
\*-----------------------------------------------------*/
for(int red_idx = 0; red_idx < 72; red_idx++)
{
data_pkt[red_idx] = red_val[(red_idx * 2) + 1] << 4 | red_val[red_idx * 2];
}
for(int grn_idx = 0; grn_idx < 72; grn_idx++)
{
data_pkt[grn_idx + 72] = grn_val[(grn_idx * 2) + 1] << 4 | grn_val[grn_idx * 2];
}
for(int blu_idx = 0; blu_idx < 72; blu_idx++)
{
data_pkt[blu_idx + 144] = blu_val[(blu_idx * 2) + 1] << 4 | blu_val[blu_idx * 2];
}
/*-----------------------------------------------------*\
| Send the packets |
\*-----------------------------------------------------*/
StreamPacket(1, 60, &data_pkt[0]);
StreamPacket(2, 60, &data_pkt[60]);
StreamPacket(3, 60, &data_pkt[120]);
StreamPacket(4, 36, &data_pkt[180]);
SubmitKeyboardLimitedColors(216);
}
void CorsairPeripheralController::SwitchMode(bool software)
{
if(software)
{
if (logical_layout == CORSAIR_TYPE_K55 || logical_layout == CORSAIR_TYPE_K95_PLAT || logical_layout == CORSAIR_TYPE_K70_MK2 || logical_layout == CORSAIR_TYPE_K68)
{
SpecialFunctionControl();
}
LightingControl();
if (logical_layout == CORSAIR_TYPE_K55 || logical_layout == CORSAIR_TYPE_K95_PLAT || logical_layout == CORSAIR_TYPE_K70_MK2 || logical_layout == CORSAIR_TYPE_K68)
{
SetupK55AndK95LightingControl();
}
}
else
{
unsigned char usb_buf[CORSAIR_PERIPHERAL_PACKET_LENGTH];
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
usb_buf[1] = CORSAIR_COMMAND_WRITE;
usb_buf[2] = CORSAIR_PROPERTY_SPECIAL_FUNCTION;
usb_buf[3] = CORSAIR_LIGHTING_CONTROL_HARDWARE;
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
}
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void CorsairPeripheralController::LightingControl()
{
unsigned char usb_buf[CORSAIR_PERIPHERAL_PACKET_LENGTH];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_LIGHTING_CONTROL;
usb_buf[0x03] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
/*-----------------------------------------------------*\
| Lighting control byte needs to be 3 for keyboards and |
| headset stand, 1 for mice and mousepads |
\*-----------------------------------------------------*/
switch(type)
{
default:
case DEVICE_TYPE_KEYBOARD:
usb_buf[0x05] = 0x03; // On K95 Platinum, this controls keyboard brightness
break;
case DEVICE_TYPE_MOUSE:
usb_buf[0x05] = 0x01;
break;
case DEVICE_TYPE_MOUSEMAT:
usb_buf[0x05] = 0x04;
break;
case DEVICE_TYPE_HEADSET_STAND:
usb_buf[0x05] = 0x03;
break;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
}
/*-----------------------------------------------------*\
| Probably a key mapping packet? |
\*-----------------------------------------------------*/
void CorsairPeripheralController::SetupK55AndK95LightingControl()
{
unsigned char usb_buf[CORSAIR_PERIPHERAL_PACKET_LENGTH];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
/*-----------------------------------------------------*\
| Set up a packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_LIGHTING_CONTROL;
usb_buf[0x03] = 0x08;
usb_buf[0x05] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
unsigned int* skipped_identifiers = key_mapping_k95_plat_ansi;
int skipped_identifiers_count = sizeof(key_mapping_k95_plat_ansi) / sizeof(key_mapping_k95_plat_ansi[0]);
if (physical_layout == CORSAIR_LAYOUT_ISO)
{
if(logical_layout == CORSAIR_TYPE_K70_MK2)
{
skipped_identifiers = key_mapping_k70_mk2_plat_iso;
skipped_identifiers_count = sizeof(key_mapping_k70_mk2_plat_iso) / sizeof(key_mapping_k70_mk2_plat_iso[0]);
}
else
{
skipped_identifiers = key_mapping_k95_plat_iso;
skipped_identifiers_count = sizeof(key_mapping_k95_plat_iso) / sizeof(key_mapping_k95_plat_iso[0]);
}
}
unsigned int identifier = 0;
for (int i = 0; i < 4; i++)
{
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
/*-----------------------------------------------------*\
| Set up a packet - a sequence of 120 ids |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = 0x40;
usb_buf[0x03] = 0x1E;
for (int j = 0; j < 30; j++)
{
for (int j = 0; j < skipped_identifiers_count; j++)
{
if (identifier == skipped_identifiers[j])
{
identifier++;
}
}
usb_buf[5 + 2 * j] = identifier++;
usb_buf[5 + 2 * j + 1] = 0xC0;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
}
}
void CorsairPeripheralController::SpecialFunctionControl()
{
unsigned char usb_buf[CORSAIR_PERIPHERAL_PACKET_LENGTH];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SPECIAL_FUNCTION;
usb_buf[0x03] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
}
void CorsairPeripheralController::ReadFirmwareInfo()
{
int actual;
unsigned char usb_buf[CORSAIR_PERIPHERAL_PACKET_LENGTH];
char offset = 0;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
/*-----------------------------------------------------*\
| Set up Read Firmware Info packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_READ;
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
/*-----------------------------------------------------*\
| Send packet and try reading it using an HID read |
| If that fails, repeat the send and read the reply as |
| a feature report. |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
actual = hid_read_timeout(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH, 1000);
if(actual == 0)
{
/*-------------------------------------------------*\
| Zero out buffer |
\*-------------------------------------------------*/
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
/*-------------------------------------------------*\
| Set up Read Firmware Info packet |
\*-------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_READ;
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
hid_send_feature_report(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
actual = hid_get_feature_report(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
offset = 1;
}
/*-----------------------------------------------------*\
| Get device type |
| 0xC0 Device is a keyboard |
| 0xC1 Device is a mouse |
| 0xC2 Device is a mousepad or headset stand |
\*-----------------------------------------------------*/
LOG_DEBUG("[%s] Device type %02X", CORSAIR_PERIPHERAL_CONTROLLER_NAME, usb_buf[0x14 + offset]);
switch(usb_buf[0x14 + offset])
{
case 0xC0:
{
unsigned short pid = (unsigned short)(usb_buf[0x0E] << 8) + (unsigned short)(usb_buf[0x0F]);
/*-----------------------------------------------------*\
| Get the correct Keyboard Type |
\*-----------------------------------------------------*/
switch(pid)
{
case 0x1B2D:
logical_layout = CORSAIR_TYPE_K95_PLAT;
break;
case 0x1B11:
logical_layout = CORSAIR_TYPE_K95;
break;
case 0x1B3D:
logical_layout = CORSAIR_TYPE_K55;
break;
case 0x1B38:
case 0x1B49:
case 0x1B6B:
case 0x1B55:
logical_layout = CORSAIR_TYPE_K70_MK2;
break;
case 0x1B4F:
logical_layout = CORSAIR_TYPE_K68;
break;
default:
logical_layout = CORSAIR_TYPE_NORMAL;
}
/*-----------------------------------------------------*\
| Get the correct Keyboard Layout. |
| Currently unused but can be implemented in the future.|
\*-----------------------------------------------------*/
switch(usb_buf[0x17 + offset])
{
case CORSAIR_LAYOUT_ANSI:
physical_layout = CORSAIR_LAYOUT_ANSI;
break;
case CORSAIR_LAYOUT_ISO:
physical_layout = CORSAIR_LAYOUT_ISO;
break;
case CORSAIR_LAYOUT_ABNT:
physical_layout = CORSAIR_LAYOUT_ABNT;
break;
case CORSAIR_LAYOUT_JIS:
physical_layout = CORSAIR_LAYOUT_JIS;
break;
case CORSAIR_LAYOUT_DUBEOLSIK:
physical_layout = CORSAIR_LAYOUT_DUBEOLSIK;
break;
default:
physical_layout = CORSAIR_LAYOUT_ANSI;
}
}
type = DEVICE_TYPE_KEYBOARD;
break;
case 0xC1:
type = DEVICE_TYPE_MOUSE;
SpecialFunctionControl();
break;
case 0xC2:
{
unsigned short pid = (unsigned short)(usb_buf[0x0F] << 8) + (unsigned short)(usb_buf[0x0E]);
switch(pid)
{
case 0x0A34:
type = DEVICE_TYPE_HEADSET_STAND;
SpecialFunctionControl();
break;
default:
type = DEVICE_TYPE_MOUSEMAT;
SpecialFunctionControl();
break;
}
}
break;
default:
type = DEVICE_TYPE_UNKNOWN;
break;
}
/*-----------------------------------------------------*\
| Format firmware version string if device type is valid|
\*-----------------------------------------------------*/
if(type != DEVICE_TYPE_UNKNOWN)
{
firmware_version = std::to_string(usb_buf[0x09 + offset]) + "." + std::to_string(usb_buf[0x08 + offset]);
}
}
void CorsairPeripheralController::StreamPacket
(
unsigned char packet_id,
unsigned char data_sz,
unsigned char* data_ptr
)
{
unsigned char usb_buf[CORSAIR_PERIPHERAL_PACKET_LENGTH];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
/*-----------------------------------------------------*\
| Set up Stream packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_STREAM;
usb_buf[0x02] = packet_id;
usb_buf[0x03] = data_sz;
/*-----------------------------------------------------*\
| Copy in data bytes |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x05], data_ptr, data_sz);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
}
void CorsairPeripheralController::SetHardwareMode
(
int mode_value,
unsigned int color_mode,
std::vector<RGBColor> colors,
unsigned int speed,
unsigned int direction,
unsigned char brightness
)
{
unsigned char usb_buf[CORSAIR_PERIPHERAL_PACKET_LENGTH];
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
/*-----------------------------------------------------*\
| Set the brightness |
\*-----------------------------------------------------*/
usb_buf[1] = CORSAIR_COMMAND_WRITE;
usb_buf[2] = 0x05;
usb_buf[3] = 0x02;
usb_buf[5] = brightness;
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
/*-----------------------------------------------------*\
| Send "lght_00.d" |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
usb_buf[1] = CORSAIR_COMMAND_WRITE;
usb_buf[2] = 0x17;
usb_buf[3] = 0x05;
usb_buf[5] = 0x6c;
usb_buf[6] = 0x67;
usb_buf[7] = 0x68;
usb_buf[8] = 0x74;
usb_buf[9] = 0x5F;
usb_buf[10] = 0x30;
usb_buf[11] = 0x30;
usb_buf[12] = 0x2E;
usb_buf[13] = 0x64;
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
/*-----------------------------------------------------*\
| Stream the mode data |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
usb_buf[1] = CORSAIR_COMMAND_STREAM;
usb_buf[2] = 0x01;
usb_buf[3] = 0x0D;
usb_buf[5] = mode_value;
usb_buf[8] = direction;
if(mode_value == CORSAIR_HW_MODE_TYPE_KEY_VALUE)
{
usb_buf[9] = speed;
}
else
{
usb_buf[6] = speed;
}
if(color_mode == MODE_COLORS_RANDOM)
{
usb_buf[7] = 0x01;
}
else if (color_mode == MODE_COLORS_MODE_SPECIFIC)
{
usb_buf[7] = 0x03;
usb_buf[10] = RGBGetRValue(colors[0]);
usb_buf[11] = RGBGetGValue(colors[0]);
usb_buf[12] = RGBGetBValue(colors[0]);
usb_buf[13] = 0xFF;
usb_buf[14] = RGBGetRValue(colors[1]);
usb_buf[15] = RGBGetGValue(colors[1]);
usb_buf[16] = RGBGetBValue(colors[1]);
usb_buf[17] = 0xFF;
}
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
/*-----------------------------------------------------*\
| Stop stream and commit |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
usb_buf[1] = CORSAIR_COMMAND_WRITE;
usb_buf[2] = 0x17;
usb_buf[3] = 0x09;
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
usb_buf[3] = 0x08;
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
}
void CorsairPeripheralController::SubmitKeyboardFullColors
(
unsigned char color_channel,
unsigned char packet_count,
unsigned char finish_val
)
{
unsigned char usb_buf[CORSAIR_PERIPHERAL_PACKET_LENGTH];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
/*-----------------------------------------------------*\
| Set up Submit Keyboard 24-Bit Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_24;
usb_buf[0x03] = color_channel;
usb_buf[0x04] = packet_count;
usb_buf[0x05] = finish_val;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
}
void CorsairPeripheralController::SubmitKeyboardZonesColors
(
RGBColor left,
RGBColor mid,
RGBColor right
)
{
unsigned char usb_buf[CORSAIR_PERIPHERAL_PACKET_LENGTH];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Keyboard 24-Bit Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_KBZONES_COLOR_24;
usb_buf[0x03] = 0x00;
usb_buf[0x04] = 0x00;
usb_buf[0x05] = RGBGetRValue(left);
usb_buf[0x06] = RGBGetGValue(left);
usb_buf[0x07] = RGBGetBValue(left);
usb_buf[0x08] = RGBGetRValue(mid);
usb_buf[0x09] = RGBGetGValue(mid);
usb_buf[0x0A] = RGBGetBValue(mid);
usb_buf[0x0B] = RGBGetRValue(right);
usb_buf[0x0C] = RGBGetGValue(right);
usb_buf[0x0D] = RGBGetBValue(right);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
}
void CorsairPeripheralController::SubmitKeyboardLimitedColors
(
unsigned char byte_count
)
{
unsigned char usb_buf[CORSAIR_PERIPHERAL_PACKET_LENGTH];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Keyboard 9-Bit Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_9;
usb_buf[0x05] = byte_count;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
}
void CorsairPeripheralController::SubmitMouseColors
(
unsigned char num_zones,
RGBColor * color_data
)
{
unsigned char usb_buf[CORSAIR_PERIPHERAL_PACKET_LENGTH];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
usb_buf[0x03] = num_zones;
usb_buf[0x04] = 0x00;
/*-----------------------------------------------------*\
| Copy in colors in <ZONE> <RED> <GREEN> <BLUE> order |
\*-----------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < num_zones; zone_idx++)
{
usb_buf[(zone_idx * 4) + 5] = zone_idx;
usb_buf[(zone_idx * 4) + 6] = RGBGetRValue(color_data[zone_idx]);
usb_buf[(zone_idx * 4) + 7] = RGBGetGValue(color_data[zone_idx]);
usb_buf[(zone_idx * 4) + 8] = RGBGetBValue(color_data[zone_idx]);
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
}
void CorsairPeripheralController::SubmitMousematColors
(
unsigned char num_zones,
RGBColor * color_data
)
{
unsigned char usb_buf[CORSAIR_PERIPHERAL_PACKET_LENGTH];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
usb_buf[0x03] = num_zones;
usb_buf[0x04] = 0x00;
/*-----------------------------------------------------*\
| Copy in colors in <RED> <GREEN> <BLUE> order |
\*-----------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < num_zones; zone_idx++)
{
usb_buf[(zone_idx * 3) + 5] = RGBGetRValue(color_data[zone_idx]);
usb_buf[(zone_idx * 3) + 6] = RGBGetGValue(color_data[zone_idx]);
usb_buf[(zone_idx * 3) + 7] = RGBGetBValue(color_data[zone_idx]);
}
/*-----------------------------------------------------*\
| Send packet using feature reports, as headset stand |
| seems to not update completely using HID writes |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
}
@@ -0,0 +1,180 @@
/*---------------------------------------------------------*\
| CorsairPeripheralController.h |
| |
| Driver for Corsair peripherals |
| |
| Adam Honse (CalcProgrammer1) 09 Jan 2020 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include <string>
#include <hidapi.h>
#include "RGBController.h"
#define CORSAIR_PERIPHERAL_PACKET_LENGTH 65
enum
{
CORSAIR_COMMAND_WRITE = 0x07,
CORSAIR_COMMAND_READ = 0x0E,
CORSAIR_COMMAND_STREAM = 0x7F
};
enum
{
CORSAIR_PROPERTY_FIRMWARE_INFO = 0x01,
CORSAIR_PROPERTY_RESET = 0x02,
CORSAIR_PROPERTY_SPECIAL_FUNCTION = 0x04,
CORSAIR_PROPERTY_LIGHTING_CONTROL = 0x05,
CORSAIR_PROPERTY_HARDWARE_PROFILE = 0x13,
CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR = 0x22,
CORSAIR_PROPERTY_SUBMIT_KBZONES_COLOR_24 = 0x25,
CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_9 = 0x27,
CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_24 = 0x28,
};
enum
{
CORSAIR_LIGHTING_CONTROL_HARDWARE = 0x01,
CORSAIR_LIGHTING_CONTROL_SOFTWARE = 0x02
};
enum
{
CORSAIR_COLOR_CHANNEL_RED = 0x01,
CORSAIR_COLOR_CHANNEL_GREEN = 0x02,
CORSAIR_COLOR_CHANNEL_BLUE = 0x03
};
enum
{
CORSAIR_LAYOUT_ANSI = 0x00,
CORSAIR_LAYOUT_ISO = 0x01,
CORSAIR_LAYOUT_ABNT = 0x02,
CORSAIR_LAYOUT_JIS = 0x03,
CORSAIR_LAYOUT_DUBEOLSIK = 0x04
};
enum
{
CORSAIR_TYPE_NORMAL = 0,
CORSAIR_TYPE_K95_PLAT = 1,
CORSAIR_TYPE_K95 = 2,
CORSAIR_TYPE_K55 = 3,
CORSAIR_TYPE_K70_MK2 = 4,
CORSAIR_TYPE_K68 = 5
};
enum
{
CORSAIR_MODE_DIRECT_VALUE = 0xFF,
CORSAIR_HW_MODE_COLOR_PULSE_VALUE = 0x01,
CORSAIR_HW_MODE_COLOR_SHIFT_VALUE = 0x00,
CORSAIR_HW_MODE_COLOR_WAVE_VALUE = 0x04,
CORSAIR_HW_MODE_RAINBOW_WAVE_VALUE = 0x03,
CORSAIR_HW_MODE_RAIN_VALUE = 0x06,
CORSAIR_HW_MODE_SPIRAL_VALUE = 0x02,
CORSAIR_HW_MODE_TYPE_KEY_VALUE = 0x08,
CORSAIR_HW_MODE_TYPE_RIPPLE_VALUE = 0x09,
CORSAIR_HW_MODE_VISOR_VALUE = 0x05
};
enum
{
CORSAIR_HW_MODE_SPEED_MIN = 0x01,
CORSAIR_HW_MODE_SPEED_MAX = 0x03,
CORSAIR_HW_MODE_BRIGHTNESS_MIN = 0x00,
CORSAIR_HW_MODE_BRIGHTNESS_MAX = 0x03
};
class CorsairPeripheralController
{
public:
CorsairPeripheralController(hid_device* dev_handle, const char* path, std::string dev_name);
~CorsairPeripheralController();
int GetLogicalLayout();
int GetPhysicalLayout();
device_type GetDeviceType();
std::string GetDeviceLocation();
std::string GetFirmwareString();
std::string GetName();
std::string GetSerialString();
void SetLEDs(std::vector<RGBColor> colors);
void SetLEDsKeyboardFull(std::vector<RGBColor> colors);
void SetLEDsKeyboardLimited(std::vector<RGBColor> colors);
void SetLEDsMouse(std::vector<RGBColor> colors);
void SetLEDsMousemat(std::vector<RGBColor> colors);
void SetHardwareMode
(
int mode_value,
unsigned int color_mode,
std::vector<RGBColor> colors,
unsigned int speed,
unsigned int direction,
unsigned char brightness
);
void SwitchMode(bool software);
private:
hid_device* dev;
std::string firmware_version;
std::string location;
std::string name;
device_type type;
int physical_layout; //ANSI, ISO, etc.
int logical_layout; //Normal, K95 or K95 Platinum
void LightingControl();
void SetupK55AndK95LightingControl();
void SpecialFunctionControl();
void ReadFirmwareInfo();
void StreamPacket
(
unsigned char packet_id,
unsigned char data_sz,
unsigned char* data_ptr
);
void SubmitKeyboardFullColors
(
unsigned char color_channel,
unsigned char packet_count,
unsigned char finish_val
);
void SubmitKeyboardZonesColors
(
RGBColor left,
RGBColor mid,
RGBColor right
);
void SubmitKeyboardLimitedColors
(
unsigned char byte_count
);
void SubmitMouseColors
(
unsigned char num_zones,
RGBColor * color_data
);
void SubmitMousematColors
(
unsigned char num_zones,
RGBColor * color_data
);
};
@@ -0,0 +1,234 @@
/*---------------------------------------------------------*\
| CorsairPeripheralControllerDetect.cpp |
| |
| Driver for Corsair peripherals |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
/*-----------------------------------------------------*\
| OpenRGB includes |
\*-----------------------------------------------------*/
#include <hidapi.h>
#include "Detector.h"
#include "LogManager.h"
#include "RGBController.h"
/*-----------------------------------------------------*\
| Corsair Peripheral specific includes |
\*-----------------------------------------------------*/
#include "RGBController_CorsairPeripheral.h"
#include "RGBController_CorsairK55RGBPROXT.h"
#include "RGBController_CorsairK65Mini.h"
#define CORSAIR_PERIPHERAL_CONTROLLER_NAME "Corsair peripheral"
/*-----------------------------------------------------*\
| Corsair vendor ID |
\*-----------------------------------------------------*/
#define CORSAIR_VID 0x1B1C
/*-----------------------------------------------------*\
| Keyboard product IDs |
| List taken from ckb-next |
| Non-RGB keyboards were omitted from this list |
\*-----------------------------------------------------*/
#define CORSAIR_K55_RGB_PID 0x1B3D
#define CORSAIR_K65_RGB_PID 0x1B17
#define CORSAIR_K65_LUX_RGB_PID 0x1B37
#define CORSAIR_K65_RGB_RAPIDFIRE_PID 0x1B39
#define CORSAIR_K68_RGB_PID 0x1B4F
#define CORSAIR_K70_RGB_PID 0x1B13
#define CORSAIR_K70_LUX_RGB_PID 0x1B33
#define CORSAIR_K70_RGB_RAPIDFIRE_PID 0x1B38
#define CORSAIR_K70_RGB_MK2_PID 0x1B49
#define CORSAIR_K70_RGB_MK2_SE_PID 0x1B6B
#define CORSAIR_K70_RGB_MK2_LP_PID 0x1B55
#define CORSAIR_K95_RGB_PID 0x1B11
#define CORSAIR_K95_PLATINUM_PID 0x1B2D
#define CORSAIR_K95_PLATINUM_SE_PID 0x1B82
#define CORSAIR_STRAFE_PID 0x1B20
#define CORSAIR_STRAFE_RED_PID 0x1B44
#define CORSAIR_STRAFE_MK2_PID 0x1B48
/*-----------------------------------------------------*\
| Non-RGB Keyboard product IDs |
\*-----------------------------------------------------*/
#define CORSAIR_K70_LUX_PID 0x1B36
#define CORSAIR_K68_RED_PID 0x1B3F
#define CORSAIR_K68_RED_SHADOW_PID 0x1BA5
/*-----------------------------------------------------*\
| Mouse product IDs |
| List taken from ckb-next |
\*-----------------------------------------------------*/
#define CORSAIR_GLAIVE_RGB_PID 0x1B34
#define CORSAIR_GLAIVE_RGB_PRO_PID 0x1B74
#define CORSAIR_HARPOON_RGB_PID 0x1B3C
#define CORSAIR_HARPOON_RGB_PRO_PID 0x1B75
#define CORSAIR_IRONCLAW_RGB_PID 0x1B5D
#define CORSAIR_M65_PID 0x1B12
#define CORSAIR_M65_PRO_PID 0x1B2E
#define CORSAIR_M65_RGB_ELITE_PID 0x1B5A
#define CORSAIR_NIGHTSWORD_PID 0x1B5C
#define CORSAIR_SCIMITAR_RGB_PID 0x1B1E
#define CORSAIR_SCIMITAR_PRO_RGB_PID 0x1B3E
#define CORSAIR_SCIMITAR_ELITE_RGB_PID 0x1B8B
#define CORSAIR_SABRE_RGB_PID 0x1B2F
/*-----------------------------------------------------*\
| Mousepad product IDs |
| List taken from ckb-next |
\*-----------------------------------------------------*/
#define CORSAIR_MM800_RGB_POLARIS_PID 0x1B3B
/*-----------------------------------------------------*\
| Headset Stand product IDs |
| List taken from ckb-next |
\*-----------------------------------------------------*/
#define CORSAIR_ST100_PID 0x0A34
/*-----------------------------------------------------*\
| 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 |
\*-----------------------------------------------------*/
#define CORSAIR_K65_MINI_PID 0x1BAF
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, name);
RGBController_CorsairK55RGBPROXT* rgb_controller = new RGBController_CorsairK55RGBPROXT(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
} /* DetectCorsairK55RGBPROXTControllers() */
void DetectCorsairK65MiniControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CorsairK65MiniController* controller = new CorsairK65MiniController(dev, info->path, name);
RGBController_CorsairK65Mini* rgb_controller = new RGBController_CorsairK65Mini(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
} /* DetectCorsairK65MiniControllers() */
/******************************************************************************************\
* *
* DetectCorsairPeripheralControllers *
* *
* Tests the USB address to see if a Corsair RGB Keyboard controller exists there. *
* *
\******************************************************************************************/
void DetectCorsairPeripheralControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LOG_DEBUG("[%s] Device opened. VID/PID %02X:%02X", CORSAIR_PERIPHERAL_CONTROLLER_NAME, info->vendor_id , info->product_id);
CorsairPeripheralController* controller = new CorsairPeripheralController(dev, info->path, name);
if(controller->GetDeviceType() != DEVICE_TYPE_UNKNOWN)
{
bool supports_hardware_modes =
(info->product_id == CORSAIR_K70_RGB_MK2_PID) ||
(info->product_id == CORSAIR_K70_RGB_MK2_LP_PID);
RGBController_CorsairPeripheral* rgb_controller = new RGBController_CorsairPeripheral(controller, supports_hardware_modes);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
else
{
LOG_DEBUG("[%s] Device type is unknown", CORSAIR_PERIPHERAL_CONTROLLER_NAME);
delete controller;
}
}
} /* DetectCorsairPeripheralControllers() */
/*-----------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("Corsair K55 RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K55_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K65 RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K65_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K65 LUX RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K65_LUX_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K65 RGB RAPIDFIRE", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K65_RGB_RAPIDFIRE_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K68 RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K68_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K68 RED", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K68_RED_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K68 RED SHADOW", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K68_RED_SHADOW_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K70_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K70 LUX", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K70_LUX_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K70 LUX RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K70_LUX_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB RAPIDFIRE", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K70_RGB_RAPIDFIRE_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB MK.2", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K70_RGB_MK2_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB MK.2 SE", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K70_RGB_MK2_SE_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB MK.2 Low Profile",DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K70_RGB_MK2_LP_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K95 RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K95_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K95 RGB PLATINUM", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K95_PLATINUM_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K95 RGB PLATINUM SE", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K95_PLATINUM_SE_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair Strafe", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_STRAFE_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair Strafe Red", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_STRAFE_RED_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair Strafe MK.2", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_STRAFE_MK2_PID, 1, 0xFFC2);
/*-----------------------------------------------------------------------------------------------------*\
| Mice |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("Corsair Glaive RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_GLAIVE_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair Glaive RGB PRO", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_GLAIVE_RGB_PRO_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair Harpoon RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_HARPOON_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair Harpoon RGB PRO", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_HARPOON_RGB_PRO_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair Ironclaw RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_IRONCLAW_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair M65", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_M65_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair M65 PRO", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_M65_PRO_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair M65 RGB Elite", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_M65_RGB_ELITE_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair Nightsword", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_NIGHTSWORD_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair Scimitar RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_SCIMITAR_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair Scimitar PRO RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_SCIMITAR_PRO_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair Scimitar Elite RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_SCIMITAR_ELITE_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair Sabre RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_SABRE_RGB_PID, 1, 0xFFC2);
/*-----------------------------------------------------------------------------------------------------*\
| Mousemats |
\*-----------------------------------------------------------------------------------------------------*/
#ifdef USE_HID_USAGE
REGISTER_HID_DETECTOR_P("Corsair MM800 RGB Polaris", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_MM800_RGB_POLARIS_PID, 0xFFC2);
#else
REGISTER_HID_DETECTOR_I("Corsair MM800 RGB Polaris", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_MM800_RGB_POLARIS_PID, 0);
#endif
/*-----------------------------------------------------------------------------------------------------*\
| Headset Stands |
\*-----------------------------------------------------------------------------------------------------*/
#ifdef USE_HID_USAGE
REGISTER_HID_DETECTOR_P("Corsair ST100 RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_ST100_PID, 0xFFC2);
#else
REGISTER_HID_DETECTOR_I("Corsair ST100 RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_ST100_PID, 0);
#endif
/*-----------------------------------------------------------------------------------------------------*\
| Corsair K65 Mini Keyboard |
\*-----------------------------------------------------------------------------------------------------*/
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);
@@ -0,0 +1,446 @@
/*---------------------------------------------------------*\
| RGBController_CorsairK55RGBPROXT.cpp |
| |
| RGBController for Corsair K55 RGB PRO XT keyboard |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#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;
name = controller->GetNameString();
vendor = "Corsair";
description = "Corsair K55 RGB PRO XT Keyboard Device";
type = DEVICE_TYPE_KEYBOARD;
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;
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);
}
}
@@ -0,0 +1,37 @@
/*---------------------------------------------------------*\
| CorsairK55RGBPROXTController.h |
| |
| Driver for Corsair K55 RGB PRO XT keyboard |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#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;
};
@@ -0,0 +1,259 @@
/*---------------------------------------------------------*\
| RGBController_CorsairK65Mini.cpp |
| |
| RGBController for Corsair K65 Mini keyboard |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "RGBController_CorsairK65Mini.h"
#include "LogManager.h"
#include "RGBControllerKeyNames.h"
using namespace std::chrono_literals;
#define NA 0xFFFFFFFF
#define WIDTH 15
#define HEIGHT 5
unsigned int matrix_map[HEIGHT][WIDTH] =
{
{ 0, 5, 8, 13, 17, 22, 26, 31, 35, 40, 44, 49, 54, NA, 60},
{ 1, NA, 9, 14, 18, 23, 27, 32, 36, 41, 45, 50, 55, 58, NA},
{ 2, NA, 10, 15, 19, 24, 28, 33, 37, 42, 46, 51, 56, 59, 61},
{ 3, 6, 11, 16, 20, 25, 29, 34, 38, 43, 47, 52, NA, NA, 62},
{ 4, 7, 12, NA, 21, NA, 30, NA, 39, NA, 48, 53, 57, NA, 63}
};
std::vector<std::tuple<unsigned int, std::string>> keys =
{
// col 1
{41, KEY_EN_ESCAPE},
{43, KEY_EN_TAB},
{57, KEY_EN_CAPS_LOCK},
{106, KEY_EN_LEFT_SHIFT},
{105, KEY_EN_LEFT_CONTROL},
// col 2
{30, KEY_EN_1},
{100, KEY_EN_ISO_BACK_SLASH},
{108, KEY_EN_LEFT_WINDOWS},
// col 3
{31, KEY_EN_2},
{20, KEY_EN_Q},
{4, KEY_EN_A},
{29, KEY_EN_Z},
{107, KEY_EN_LEFT_ALT},
// col 4
{32, KEY_EN_3},
{26, KEY_EN_W},
{22, KEY_EN_S},
{27, KEY_EN_X},
// col 5
{33, KEY_EN_4},
{8, KEY_EN_E},
{7, KEY_EN_D},
{6, KEY_EN_C},
{0, ""}, // space bar, left LED
// col 6
{34, KEY_EN_5},
{21, KEY_EN_R},
{9, KEY_EN_F},
{25, KEY_EN_V},
// col 7
{35, KEY_EN_6},
{23, KEY_EN_T},
{10, KEY_EN_G},
{5, KEY_EN_B},
{44, KEY_EN_SPACE},
// col 8
{36, KEY_EN_7},
{28, KEY_EN_Y},
{11, KEY_EN_H},
{17, KEY_EN_N},
// col 9
{37, KEY_EN_8},
{24, KEY_EN_U},
{13, KEY_EN_J},
{16, KEY_EN_M},
{1, ""}, // space bar, right LED
// col 10
{38, KEY_EN_9},
{12, KEY_EN_I},
{14, KEY_EN_K},
{54, KEY_EN_COMMA},
// col 11
{39, KEY_EN_0},
{18, KEY_EN_O},
{15, KEY_EN_L},
{55, KEY_EN_PERIOD},
{111, KEY_EN_RIGHT_ALT},
// col 12
{45, KEY_EN_MINUS},
{19, KEY_EN_P},
{51, KEY_EN_SEMICOLON},
{56, KEY_EN_FORWARD_SLASH},
{122, KEY_EN_RIGHT_FUNCTION},
// col 13
{46, KEY_EN_EQUALS},
{47, KEY_EN_LEFT_BRACKET},
{52, KEY_EN_QUOTE},
{101, KEY_EN_MENU},
// col 14
{48, KEY_EN_RIGHT_BRACKET},
{50, KEY_EN_POUND},
// col 15
{42, KEY_EN_BACKSPACE},
{40, KEY_EN_ISO_ENTER},
{110, KEY_EN_RIGHT_SHIFT},
{109, KEY_EN_RIGHT_CONTROL}
};
/**------------------------------------------------------------------*\
@name Corsair K65 Mini
@category Keyboard
@type USB
@save :x:
@direct :white_check_mark:
@effects :x:
@detectors DetectCorsairK65MiniControllers
@comment
\*-------------------------------------------------------------------*/
RGBController_CorsairK65Mini::RGBController_CorsairK65Mini(CorsairK65MiniController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetName();
vendor = "Corsair";
description = "Corsair K65 Mini Keyboard Device";
type = DEVICE_TYPE_KEYBOARD;
location = controller->GetDeviceLocation();
serial = controller->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = 0;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
SetupZones();
/*-----------------------------------------------------*\
| The Corsair K65 Mini 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_CorsairK65Mini::KeepaliveThread, this);
}
RGBController_CorsairK65Mini::~RGBController_CorsairK65Mini()
{
/*-----------------------------------------------------*\
| Close keepalive thread |
\*-----------------------------------------------------*/
keepalive_thread_run = false;
keepalive_thread->join();
delete keepalive_thread;
delete controller;
}
void RGBController_CorsairK65Mini::SetupZones()
{
unsigned int zone_size = 0;
zone keyboard_zone;
keyboard_zone.name = ZONE_EN_KEYBOARD;
keyboard_zone.type = ZONE_TYPE_MATRIX;
keyboard_zone.matrix_map = new matrix_map_type;
keyboard_zone.matrix_map->height = HEIGHT;
keyboard_zone.matrix_map->width = WIDTH;
keyboard_zone.matrix_map->map = new unsigned int[HEIGHT * WIDTH];
for(unsigned int w = 0; w < WIDTH; w++)
{
for(unsigned int h = 0; h < HEIGHT; h++)
{
unsigned int key = matrix_map[h][w];
keyboard_zone.matrix_map->map[h * WIDTH + w] = key;
if(key != NA)
{
led new_led;
new_led.name = std::get<1>(keys[key]);
leds.push_back(new_led);
zone_size++;
led_positions.push_back(std::get<0>(keys[key]));
}
}
}
keyboard_zone.leds_min = zone_size;
keyboard_zone.leds_max = zone_size;
keyboard_zone.leds_count = zone_size;
zones.push_back(keyboard_zone);
SetupColors();
}
void RGBController_CorsairK65Mini::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_CorsairK65Mini::DeviceUpdateLEDs()
{
last_update_time = std::chrono::steady_clock::now();
controller->SetLEDs(colors, led_positions);
}
void RGBController_CorsairK65Mini::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_CorsairK65Mini::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_CorsairK65Mini::DeviceUpdateMode()
{
}
void RGBController_CorsairK65Mini::KeepaliveThread()
{
while(keepalive_thread_run.load())
{
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(50000))
{
DeviceUpdateLEDs();
}
std::this_thread::sleep_for(3000ms);
}
}
@@ -0,0 +1,39 @@
/*---------------------------------------------------------*\
| RGBController_CorsairK65Mini.h |
| |
| RGBController for Corsair K65 Mini keyboard |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CorsairK65MiniController.h"
class RGBController_CorsairK65Mini : public RGBController
{
public:
RGBController_CorsairK65Mini(CorsairK65MiniController* controller_ptr);
~RGBController_CorsairK65Mini();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
void KeepaliveThread();
private:
CorsairK65MiniController* controller;
std::thread* keepalive_thread;
std::atomic<bool> keepalive_thread_run;
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
std::vector<unsigned int> led_positions;
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,38 @@
/*---------------------------------------------------------*\
| RGBController_CorsairPeripheral.h |
| |
| RGBController for Corsair peripherals |
| |
| Adam Honse (CalcProgrammer1) 09 Jan 2020 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CorsairPeripheralController.h"
class RGBController_CorsairPeripheral : public RGBController
{
public:
RGBController_CorsairPeripheral(CorsairPeripheralController* controller_ptr, bool supports_hardware_modes);
~RGBController_CorsairPeripheral();
int physical_layout;
int logical_layout;
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
private:
CorsairPeripheralController* controller;
};