Initial code for MSI/SteelSeries 3-Zone laptop keyboards

This commit is contained in:
Adam Honse
2019-12-25 03:08:37 -06:00
parent eac739fdb4
commit eef95f50dd
8 changed files with 284 additions and 1 deletions

View File

@@ -0,0 +1,78 @@
/*-----------------------------------------*\
| MSI3ZoneController.cpp |
| |
| Driver for MSI/Steelseries 3-Zone |
| Keyboard lighting controller |
| |
| Adam Honse (CalcProgrammer1) 12/25/2019 |
\*-----------------------------------------*/
#include "MSI3ZoneController.h"
MSI3ZoneController::MSI3ZoneController(libusb_device_handle* dev_handle)
{
dev = dev_handle;
strcpy(device_name, "MSI 3-Zone Keyboard");
}
MSI3ZoneController::~MSI3ZoneController()
{
}
char* MSI3ZoneController::GetDeviceName()
{
return device_name;
}
void MSI3ZoneController::SetLEDs(std::vector<RGBColor> colors)
{
//Shout out to bparker06 for reverse engineering the MSI keyboard USB protocol!
// https://github.com/bparker06/msi-keyboard/blob/master/keyboard.cpp for original implementation
unsigned char buf[8] = { 0 };
buf[0] = 1;
buf[1] = 2;
buf[2] = 64;
buf[3] = 1;
buf[4] = RGBGetRValue(colors[0]);
buf[5] = RGBGetGValue(colors[0]);
buf[6] = RGBGetBValue(colors[0]);
buf[7] = 236;
libusb_control_transfer(dev, LIBUSB_DT_HID, LIBUSB_REQUEST_SET_CONFIGURATION, 0x0300, 0x03, buf, 8, 0);
buf[3] = 2;
buf[4] = RGBGetRValue(colors[1]);
buf[5] = RGBGetGValue(colors[1]);
buf[6] = RGBGetBValue(colors[1]);
libusb_control_transfer(dev, LIBUSB_DT_HID, LIBUSB_REQUEST_SET_CONFIGURATION, 0x0300, 0x03, buf, 8, 0);
buf[3] = 3;
buf[4] = RGBGetRValue(colors[2]);
buf[5] = RGBGetGValue(colors[2]);
buf[6] = RGBGetBValue(colors[2]);
libusb_control_transfer(dev, LIBUSB_DT_HID, LIBUSB_REQUEST_SET_CONFIGURATION, 0x0300, 0x03, buf, 8, 0);
buf[3] = 4;
buf[4] = RGBGetRValue(colors[3]);
buf[5] = RGBGetGValue(colors[3]);
buf[6] = RGBGetBValue(colors[3]);
libusb_control_transfer(dev, LIBUSB_DT_HID, LIBUSB_REQUEST_SET_CONFIGURATION, 0x0300, 0x03, buf, 8, 0);
buf[3] = 5;
libusb_control_transfer(dev, LIBUSB_DT_HID, LIBUSB_REQUEST_SET_CONFIGURATION, 0x0300, 0x03, buf, 8, 0);
buf[3] = 6;
libusb_control_transfer(dev, LIBUSB_DT_HID, LIBUSB_REQUEST_SET_CONFIGURATION, 0x0300, 0x03, buf, 8, 0);
buf[3] = 7;
libusb_control_transfer(dev, LIBUSB_DT_HID, LIBUSB_REQUEST_SET_CONFIGURATION, 0x0300, 0x03, buf, 8, 0);
}

View File

@@ -0,0 +1,30 @@
/*-----------------------------------------*\
| MSI3ZoneController.h |
| |
| Definitions and types for MSI/Steelseries|
| 3-Zone Keyboard lighting controller |
| |
| Adam Honse (CalcProgrammer1) 12/25/2019 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <libusb-1.0/libusb.h>
#pragma once
class MSI3ZoneController
{
public:
MSI3ZoneController(libusb_device_handle* dev_handle);
~MSI3ZoneController();
char* GetDeviceName();
void SetLEDs(std::vector<RGBColor> colors);
private:
char device_name[32];
libusb_device_handle* dev;
};

View File

@@ -0,0 +1,38 @@
#include "MSI3ZoneController.h"
#include "RGBController.h"
#include "RGBController_MSI3Zone.h"
#include <vector>
#include <libusb-1.0/libusb.h>
#define MSI_3_ZONE_KEYBOARD_VID 0x1770
#define MSI_3_ZONE_KEYBOARD_PID 0xFF00
/******************************************************************************************\
* *
* DetectMSI3ZoneControllers *
* *
* Tests the USB address to see if an MSI/SteelSeries 3-zone Keyboard controller *
* exists there. *
* *
\******************************************************************************************/
void DetectMSI3ZoneControllers(std::vector<RGBController*>& rgb_controllers)
{
libusb_context * ctx;
libusb_init(&ctx);
//Look for MSI/Steelseries 3-zone Keyboard
libusb_device_handle * dev = libusb_open_device_with_vid_pid(ctx, MSI_3_ZONE_KEYBOARD_VID, MSI_3_ZONE_KEYBOARD_PID);
if( dev )
{
libusb_detach_kernel_driver(dev, 1);
libusb_claim_interface(dev, 1);
MSI3ZoneController* controller = new MSI3ZoneController(dev);
RGBController_MSI3Zone* rgb_controller = new RGBController_MSI3Zone(controller);
rgb_controllers.push_back(rgb_controller);
}
}