Add support for Corsair Polaris MM800 mousemat using CorsairKeyboardController driver

This commit is contained in:
Adam Honse committed 2020-03-09 20:39:55 -05:00
1 parent a7ed250c4e
commit f1e1c41d68
4 files changed
+308 -40

No files matched your search

@@ -50,6 +50,9 @@ CorsairKeyboardController::CorsairKeyboardController(hid_device* dev_handle)
char data_pkt[64] = { 0 };
ReadFirmwareInfo();
SpecialFunctionControl();
LightingControl();
}
@@ -58,7 +61,39 @@ CorsairKeyboardController::~CorsairKeyboardController()
}
void CorsairKeyboardController::SetLEDs(std::vector<RGBColor> colors)
device_type CorsairKeyboardController::GetDeviceType()
{
return device_type;
}
std::string CorsairKeyboardController::GetFirmwareString()
{
return firmware_version;
}
void CorsairKeyboardController::SetLEDs(std::vector<RGBColor>colors)
{
switch(device_type)
{
case DEVICE_TYPE_KEYBOARD:
SetLEDsLimited(colors);
break;
case DEVICE_TYPE_MOUSE:
break;
case DEVICE_TYPE_MOUSEMAT:
SetLEDsMouse(colors);
break;
}
}
void CorsairKeyboardController::SetLEDsMouse(std::vector<RGBColor> colors)
{
SubmitMouseColors(colors.size(), &colors[0]);
}
void CorsairKeyboardController::SetLEDsLimited(std::vector<RGBColor> colors)
{
unsigned char data_pkt[216];
unsigned char red_val[144];
@@ -141,11 +176,52 @@ void CorsairKeyboardController::LightingControl()
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_LIGHTING_CONTROL;
usb_buf[0x02] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
usb_buf[0x04] = 0x03;
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_LIGHTING_CONTROL;
usb_buf[0x02] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
/*-----------------------------------------------------*\
| Lighting control byte needs to be 3 for keyboards, 1 |
| for mice and mousepads |
\*-----------------------------------------------------*/
switch(device_type)
{
default:
case DEVICE_TYPE_KEYBOARD:
usb_buf[0x04] = 0x03;
break;
case DEVICE_TYPE_MOUSE:
usb_buf[0x04] = 0x01;
break;
case DEVICE_TYPE_MOUSEMAT:
usb_buf[0x04] = 0x04;
break;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf);
}
void CorsairKeyboardController::SpecialFunctionControl()
{
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_SPECIAL_FUNCTION;
usb_buf[0x02] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
@@ -172,6 +248,39 @@ void CorsairKeyboardController::ReadFirmwareInfo()
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf);
get_usb_msg(dev, usb_buf);
/*-----------------------------------------------------*\
| Get device type |
| 0xC0 Device is a keyboard |
| 0xC1 Device is a mouse |
| 0xC2 Device is a mousepad |
\*-----------------------------------------------------*/
switch((unsigned char)usb_buf[0x14])
{
case 0xC0:
device_type = DEVICE_TYPE_KEYBOARD;
break;
case 0xC1:
device_type = DEVICE_TYPE_MOUSE;
break;
case 0xC2:
device_type = DEVICE_TYPE_MOUSEMAT;
break;
default:
device_type = DEVICE_TYPE_UNKNOWN;
break;
}
/*-----------------------------------------------------*\
| Format firmware version string if device type is valid|
\*-----------------------------------------------------*/
if(device_type != DEVICE_TYPE_UNKNOWN)
{
firmware_version = std::to_string(usb_buf[0x09]) + "." + std::to_string(usb_buf[0x08]);
}
}
void CorsairKeyboardController::StreamPacket
@@ -246,6 +355,44 @@ void CorsairKeyboardController::SubmitLimitedColors
usb_buf[0x01] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_9;
usb_buf[0x04] = byte_count;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
send_usb_msg(dev, usb_buf);
}
void CorsairKeyboardController::SubmitMouseColors
(
unsigned char num_zones,
RGBColor * color_data
)
{
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
usb_buf[0x01] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
usb_buf[0x02] = num_zones;
usb_buf[0x03] = 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) + 4] = zone_idx;
usb_buf[(zone_idx * 3) + 4] = RGBGetRValue(color_data[zone_idx]);
usb_buf[(zone_idx * 3) + 5] = RGBGetGValue(color_data[zone_idx]);
usb_buf[(zone_idx * 3) + 6] = RGBGetBValue(color_data[zone_idx]);
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
@@ -52,13 +52,22 @@ public:
CorsairKeyboardController(hid_device* dev_handle);
~CorsairKeyboardController();
void SetLEDsDirect(std::vector<RGBColor> colors);
void SetLEDs(std::vector<RGBColor> colors);
device_type GetDeviceType();
std::string GetFirmwareString();
void SetLEDs(std::vector<RGBColor> colors);
void SetLEDsKeyboard(std::vector<RGBColor> colors);
void SetLEDsLimited(std::vector<RGBColor> colors);
void SetLEDsMouse(std::vector<RGBColor> colors);
private:
hid_device* dev;
std::string firmware_version;
device_type device_type;
void LightingControl();
void SpecialFunctionControl();
void ReadFirmwareInfo();
@@ -75,4 +84,10 @@ private:
(
unsigned char byte_count
);
void SubmitMouseColors
(
unsigned char num_zones,
RGBColor * color_data
);
};
@@ -4,9 +4,62 @@
#include <vector>
#include <hidapi/hidapi.h>
#define CORSAIR_RGB_KEYBOARD_VID 0x1B1C
#define CORSAIR_RGB_KEYBOARD_K70_PID 0x1B13
#define CORSAIR_RGB_KEYBOARD_K95_PID 0x1B11
/*-----------------------------------------------------*\
| 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 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 0x1B38
#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_STRAFE_PID 0x1B20
#define CORSAIR_STRAFE_MK2_PID 0x1B48
/*-----------------------------------------------------*\
| Mouse product IDs |
| List taken from ckb-next |
\*-----------------------------------------------------*/
/*-----------------------------------------------------*\
| Mousepad product IDs |
| List taken from ckb-next |
\*-----------------------------------------------------*/
#define CORSAIR_MM800_RGB_POLARIS_PID 0x1B3B
typedef struct
{
unsigned short usb_vid;
unsigned short usb_pid;
unsigned char usb_interface;
const char * name;
} corsair_node_device;
static const corsair_node_device device_list[3] =
{
{ CORSAIR_VID, CORSAIR_K70_RGB_PID, 1, "Corsair K70 RGB" },
{ CORSAIR_VID, CORSAIR_K95_RGB_PID, 1, "Corsair K95 RGB" },
{ CORSAIR_VID, CORSAIR_MM800_RGB_POLARIS_PID, 0, "Corsair MM800 RGB Polaris" }
};
/******************************************************************************************\
* *
@@ -19,34 +72,44 @@
void DetectCorsairKeyboardControllers(std::vector<RGBController*>& rgb_controllers)
{
hid_device_info* info;
hid_device* dev = NULL;
hid_device* dev;
hid_init();
info = hid_enumerate(CORSAIR_RGB_KEYBOARD_VID, CORSAIR_RGB_KEYBOARD_K70_PID);
//Look for Corsair RGB Keyboard, interface 1
while(info)
for(int device_idx = 0; device_idx < 3; device_idx++)
{
if((info->vendor_id == CORSAIR_RGB_KEYBOARD_VID)
&&(info->product_id == CORSAIR_RGB_KEYBOARD_K70_PID)
&&(info->interface_number == 1))
dev = NULL;
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for Corsair RGB Keyboard, interface 1
while(info)
{
dev = hid_open_path(info->path);
break;
if((info->vendor_id == device_list[device_idx].usb_vid)
&&(info->product_id == device_list[device_idx].usb_pid)
&&(info->interface_number == device_list[device_idx].usb_interface))
{
dev = hid_open_path(info->path);
break;
}
else
{
info = info->next;
}
}
else
if( dev )
{
info = info->next;
CorsairKeyboardController* controller = new CorsairKeyboardController(dev);
if(controller->GetDeviceType() != DEVICE_TYPE_UNKNOWN)
{
RGBController_CorsairKeyboard* rgb_controller = new RGBController_CorsairKeyboard(controller);
rgb_controller->name = device_list[device_idx].name;
rgb_controllers.push_back(rgb_controller);
}
}
}
if( dev )
{
CorsairKeyboardController* controller = new CorsairKeyboardController(dev);
RGBController_CorsairKeyboard* rgb_controller = new RGBController_CorsairKeyboard(controller);
rgb_controllers.push_back(rgb_controller);
}
}
@@ -141,8 +141,9 @@ RGBController_CorsairKeyboard::RGBController_CorsairKeyboard(CorsairKeyboardCont
{
corsair = corsair_ptr;
name = "Corsair RGB Keyboard";
type = DEVICE_TYPE_KEYBOARD;
name = "Corsair RGB Keyboard";
type = corsair->GetDeviceType();
version = corsair->GetFirmwareString();
mode Direct;
Direct.name = "Direct";
@@ -161,26 +162,68 @@ RGBController_CorsairKeyboard::~RGBController_CorsairKeyboard()
void RGBController_CorsairKeyboard::SetupZones()
{
/*---------------------------------------------------------*\
| Determine number of zones |
| For now, keyboard has 2 zones and mousemat has 1 |
\*---------------------------------------------------------*/
unsigned int num_zones = 0;
switch(type)
{
case DEVICE_TYPE_KEYBOARD:
num_zones = 2;
break;
case DEVICE_TYPE_MOUSEMAT:
num_zones = 1;
break;
}
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
unsigned int total_led_count = 0;
for(unsigned int zone_idx = 0; zone_idx < 2; zone_idx++)
for(unsigned int zone_idx = 0; zone_idx < num_zones; zone_idx++)
{
zone new_zone;
new_zone.name = zone_names[zone_idx];
new_zone.leds_min = zone_sizes[zone_idx];
new_zone.leds_max = zone_sizes[zone_idx];
new_zone.leds_count = zone_sizes[zone_idx];
switch(type)
{
case DEVICE_TYPE_KEYBOARD:
new_zone.name = zone_names[zone_idx];
new_zone.leds_min = zone_sizes[zone_idx];
new_zone.leds_max = zone_sizes[zone_idx];
new_zone.leds_count = zone_sizes[zone_idx];
break;
case DEVICE_TYPE_MOUSEMAT:
new_zone.name = "Mousemat Zone";
new_zone.leds_min = 15;
new_zone.leds_max = 15;
new_zone.leds_count = 15;
break;
}
zones.push_back(new_zone);
total_led_count += zone_sizes[zone_idx];
total_led_count += new_zone.leds_count;
}
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
{
led new_led;
new_led.name = led_names[led_idx];
switch(type)
{
case DEVICE_TYPE_KEYBOARD:
new_led.name = led_names[led_idx];
break;
case DEVICE_TYPE_MOUSEMAT:
new_led.name = "Mousemat LED ";
new_led.name.append(std::to_string(led_idx + 1));
break;
}
leds.push_back(new_led);
}