diff --git a/Controllers/CorsairKeyboardController/CorsairKeyboardController.cpp b/Controllers/CorsairKeyboardController/CorsairKeyboardController.cpp index a91c43294..91672ecf3 100644 --- a/Controllers/CorsairKeyboardController/CorsairKeyboardController.cpp +++ b/Controllers/CorsairKeyboardController/CorsairKeyboardController.cpp @@ -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 colors) +device_type CorsairKeyboardController::GetDeviceType() +{ + return device_type; +} + +std::string CorsairKeyboardController::GetFirmwareString() +{ + return firmware_version; +} + +void CorsairKeyboardController::SetLEDs(std::vectorcolors) +{ + 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 colors) +{ + SubmitMouseColors(colors.size(), &colors[0]); +} + +void CorsairKeyboardController::SetLEDsLimited(std::vector 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 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 | \*-----------------------------------------------------*/ diff --git a/Controllers/CorsairKeyboardController/CorsairKeyboardController.h b/Controllers/CorsairKeyboardController/CorsairKeyboardController.h index 7e5c03d75..f89e3a81d 100644 --- a/Controllers/CorsairKeyboardController/CorsairKeyboardController.h +++ b/Controllers/CorsairKeyboardController/CorsairKeyboardController.h @@ -52,13 +52,22 @@ public: CorsairKeyboardController(hid_device* dev_handle); ~CorsairKeyboardController(); - void SetLEDsDirect(std::vector colors); - void SetLEDs(std::vector colors); + device_type GetDeviceType(); + std::string GetFirmwareString(); + + void SetLEDs(std::vector colors); + void SetLEDsKeyboard(std::vector colors); + void SetLEDsLimited(std::vector colors); + void SetLEDsMouse(std::vector 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 + ); }; diff --git a/Controllers/CorsairKeyboardController/CorsairKeyboardControllerDetect.cpp b/Controllers/CorsairKeyboardController/CorsairKeyboardControllerDetect.cpp index 34909e007..9d2bb852c 100644 --- a/Controllers/CorsairKeyboardController/CorsairKeyboardControllerDetect.cpp +++ b/Controllers/CorsairKeyboardController/CorsairKeyboardControllerDetect.cpp @@ -4,9 +4,62 @@ #include #include -#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& 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); - } } diff --git a/RGBController/RGBController_CorsairKeyboard.cpp b/RGBController/RGBController_CorsairKeyboard.cpp index 93f67c9ee..5d27e5c55 100644 --- a/RGBController/RGBController_CorsairKeyboard.cpp +++ b/RGBController/RGBController_CorsairKeyboard.cpp @@ -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); }