mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2025-12-25 00:07:49 -05:00
443 lines
15 KiB
C++
443 lines
15 KiB
C++
/*-----------------------------------------*\
|
|
| AlienwareAW510KController.cpp |
|
|
| |
|
|
| Driver for Alienware AW510K |
|
|
| keyboard light controller |
|
|
| |
|
|
| Mohamad Sallal - msallal 05/22/2021 |
|
|
\*-----------------------------------------*/
|
|
|
|
#include "AlienwareAW510KController.h"
|
|
#include <cstring>
|
|
|
|
AlienwareAW510KController::AlienwareAW510KController(hid_device* dev_handle, const char* path)
|
|
{
|
|
dev = dev_handle;
|
|
location = path;
|
|
|
|
SendCommit();
|
|
}
|
|
|
|
AlienwareAW510KController::~AlienwareAW510KController()
|
|
{
|
|
hid_close(dev);
|
|
}
|
|
|
|
std::string AlienwareAW510KController::GetDeviceLocation()
|
|
{
|
|
return("HID: " + location);
|
|
}
|
|
|
|
std::string AlienwareAW510KController::GetSerialString()
|
|
{
|
|
wchar_t serial_string[128];
|
|
hid_get_serial_number_string(dev, serial_string, 128);
|
|
|
|
std::wstring return_wstring = serial_string;
|
|
std::string return_string(return_wstring.begin(), return_wstring.end());
|
|
|
|
return(return_string);
|
|
}
|
|
|
|
void AlienwareAW510KController::SendCommit()
|
|
{
|
|
char usb_buf[65];
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Zero out buffer |
|
|
\*-----------------------------------------------------*/
|
|
memset(usb_buf, 0x00, sizeof(usb_buf));
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Set up Commit packet |
|
|
\*-----------------------------------------------------*/
|
|
usb_buf[0x00] = 0x00;
|
|
usb_buf[0x01] = 0x05;
|
|
usb_buf[0x02] = 0x01;
|
|
usb_buf[0x0A] = 0x10;
|
|
usb_buf[0x0B] = 0x0A;
|
|
usb_buf[0x0C] = 0x01;
|
|
usb_buf[0x0D] = 0x02;
|
|
usb_buf[0x0E] = 0x01;
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Send packet |
|
|
\*-----------------------------------------------------*/
|
|
hid_write(dev, (unsigned char *)usb_buf, 65);
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Delay 20 milliseconds |
|
|
\*-----------------------------------------------------*/
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
|
}
|
|
|
|
|
|
void AlienwareAW510KController::SendfeatureReport
|
|
(
|
|
unsigned char first_byte,
|
|
unsigned char second_byte,
|
|
unsigned char third_byte,
|
|
unsigned char forth_byte
|
|
)
|
|
{
|
|
char usb_buf[65];
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Zero out buffer |
|
|
\*-----------------------------------------------------*/
|
|
memset(usb_buf, 0x00, sizeof(usb_buf));
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Set up Feature report packet |
|
|
\*-----------------------------------------------------*/
|
|
usb_buf[0x00] = 0x00;
|
|
usb_buf[0x01] = first_byte;
|
|
usb_buf[0x02] = second_byte;
|
|
usb_buf[0x03] = third_byte;
|
|
usb_buf[0x04] = forth_byte;
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Send Feature report packet |
|
|
\*-----------------------------------------------------*/
|
|
hid_send_feature_report(dev, (unsigned char *)usb_buf, 65);
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Delay 10 milliseconds |
|
|
\*-----------------------------------------------------*/
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
|
}
|
|
|
|
void AlienwareAW510KController::SendEdit()
|
|
{
|
|
char usb_buf[65];
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Zero out buffer |
|
|
\*-----------------------------------------------------*/
|
|
memset(usb_buf, 0x00, sizeof(usb_buf));
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Set up Edit packet |
|
|
\*-----------------------------------------------------*/
|
|
usb_buf[0x00] = 0x00;
|
|
usb_buf[0x01] = 0x01;
|
|
usb_buf[0x02] = 0x00;
|
|
usb_buf[0x03] = 0x01;
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Send packet |
|
|
\*-----------------------------------------------------*/
|
|
hid_write(dev, (unsigned char *)usb_buf, 65);
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Delay 2 milliseconds |
|
|
\*-----------------------------------------------------*/
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
|
}
|
|
|
|
void AlienwareAW510KController::SendInitialize()
|
|
{
|
|
char usb_buf[65];
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Zero out buffer |
|
|
\*-----------------------------------------------------*/
|
|
memset(usb_buf, 0x00, sizeof(usb_buf));
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Set up Commit packet |
|
|
\*-----------------------------------------------------*/
|
|
usb_buf[0x00] = 0x00;
|
|
usb_buf[0x01] = 0x0E;
|
|
usb_buf[0x02] = 0x01;
|
|
usb_buf[0x03] = 0x00;
|
|
usb_buf[0x04] = 0x01;
|
|
usb_buf[0x05] = 0xAD;
|
|
usb_buf[0x06] = 0x80;
|
|
usb_buf[0x07] = 0x10;
|
|
usb_buf[0x08] = 0xA5;
|
|
usb_buf[0x0A] = 0x0A;
|
|
usb_buf[0x12] = 0x01;
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Send packet |
|
|
\*-----------------------------------------------------*/
|
|
hid_write(dev, (unsigned char *)usb_buf, 65);
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Delay 2 milliseconds |
|
|
\*-----------------------------------------------------*/
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
|
}
|
|
|
|
void AlienwareAW510KController::SetDirect
|
|
(
|
|
unsigned char zone,
|
|
unsigned char r,
|
|
unsigned char g,
|
|
unsigned char b
|
|
)
|
|
{
|
|
unsigned char usb_buf[65];
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Zero out buffer |
|
|
\*-----------------------------------------------------*/
|
|
memset(usb_buf, 0x00, sizeof(usb_buf));
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Set up Lighting Control packet |
|
|
\*-----------------------------------------------------*/
|
|
|
|
usb_buf[0x00] = 0x00;
|
|
usb_buf[0x01] = 0x05;
|
|
usb_buf[0x02] = 0x01;
|
|
usb_buf[0x03] = 0x01;
|
|
usb_buf[0x04] = r;
|
|
usb_buf[0x05] = g;
|
|
usb_buf[0x06] = b;
|
|
usb_buf[0x0B] = 0x0A;
|
|
usb_buf[0x0D] = 0x01;
|
|
usb_buf[0x0E] = 0x01;
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Send packet |
|
|
\*-----------------------------------------------------*/
|
|
hid_write(dev, (unsigned char *)usb_buf, 65);
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Delay 2 milliseconds |
|
|
\*-----------------------------------------------------*/
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
|
}
|
|
|
|
void AlienwareAW510KController::SendDirectOn
|
|
(
|
|
std::vector<SelectedKeys> &frame_data
|
|
)
|
|
{
|
|
SendfeatureReport(0x0E, frame_data.size(), 0x00, 0x01);
|
|
|
|
/*-----------------------------------------------*\
|
|
| To Guarantee the data are always %4 =0 append |
|
|
| zeros at end of last packet |
|
|
\*-----------------------------------------------*/
|
|
for(int i = 0; i < (frame_data.size() % 4); i++)
|
|
{
|
|
SelectedKeys key;
|
|
key.idx = 0x00;
|
|
key.red = 0x00;
|
|
key.green = 0x00;
|
|
key.blue = 0x00;
|
|
|
|
frame_data.push_back(key);
|
|
}
|
|
|
|
unsigned char usb_buf[65];
|
|
unsigned int frame_idx = 0;
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Zero out buffer |
|
|
\*-----------------------------------------------------*/
|
|
memset(usb_buf, 0x00, 65);
|
|
|
|
for(unsigned int packet_idx = 0; packet_idx < frame_data.size(); packet_idx++)
|
|
{
|
|
usb_buf[0x00] = 0x00;
|
|
usb_buf[0x01] = 0x0E;
|
|
usb_buf[0x02] = 0x01;
|
|
usb_buf[0x03] = 0x00;
|
|
usb_buf[0x04] = ++frame_idx;
|
|
usb_buf[0x05] = frame_data[packet_idx].idx;
|
|
usb_buf[0x06] = 0x81;
|
|
usb_buf[0x07] = 0x00;
|
|
usb_buf[0x08] = 0xA5;
|
|
usb_buf[0x0A] = 0x0A;
|
|
usb_buf[0x0B] = frame_data[packet_idx].red;
|
|
usb_buf[0x0C] = frame_data[packet_idx].green;
|
|
usb_buf[0x0D] = frame_data[packet_idx].blue;
|
|
usb_buf[0x12] = 0x01;
|
|
|
|
usb_buf[0x14] = frame_data[++packet_idx].idx;
|
|
usb_buf[0x15] = 0x81;
|
|
usb_buf[0x16] = 0x00;
|
|
usb_buf[0x17] = 0xA5;
|
|
usb_buf[0x19] = 0x0A;
|
|
usb_buf[0x1A] = frame_data[packet_idx].red;
|
|
usb_buf[0x1B] = frame_data[packet_idx].green;
|
|
usb_buf[0x1C] = frame_data[packet_idx].blue;
|
|
usb_buf[0x21] = 0x01;
|
|
|
|
usb_buf[0x23] = frame_data[++packet_idx].idx;
|
|
usb_buf[0x24] = 0x81;
|
|
usb_buf[0x25] = 0x00;
|
|
usb_buf[0x26] = 0xA5;
|
|
usb_buf[0x28] = 0x0A;
|
|
usb_buf[0x29] = frame_data[packet_idx].red;
|
|
usb_buf[0x2A] = frame_data[packet_idx].green;
|
|
usb_buf[0x2B] = frame_data[packet_idx].blue;
|
|
usb_buf[0x30] = 0x01;
|
|
|
|
usb_buf[0x32] = frame_data[++packet_idx].idx;
|
|
usb_buf[0x33] = 0x81;
|
|
usb_buf[0x34] = 0x00;
|
|
usb_buf[0x35] = 0xA5;
|
|
usb_buf[0x37] = 0x0A;
|
|
usb_buf[0x38] = frame_data[packet_idx].red;
|
|
usb_buf[0x39] = frame_data[packet_idx].green;
|
|
usb_buf[0x3A] = frame_data[packet_idx].blue;
|
|
usb_buf[0x3F] = 0x01;
|
|
|
|
hid_write(dev, (unsigned char *)usb_buf, 65);
|
|
}
|
|
}
|
|
|
|
|
|
void AlienwareAW510KController::SetMode
|
|
(
|
|
unsigned char mode,
|
|
unsigned short speed,
|
|
unsigned char direction,
|
|
unsigned char colorMode,
|
|
unsigned char red,
|
|
unsigned char green,
|
|
unsigned char blue
|
|
)
|
|
{
|
|
SendMode(ALIENWARE_AW510K_ZONE_MODE_KEYBOARD, mode, speed, direction, colorMode, red, green, blue);
|
|
SendCommit();
|
|
}
|
|
|
|
void AlienwareAW510KController::UpdateSingleLED
|
|
(
|
|
unsigned char led,
|
|
unsigned char red,
|
|
unsigned char green,
|
|
unsigned char blue
|
|
)
|
|
{
|
|
SendfeatureReport(0x0E, 0x01, 0x00, 0x01);
|
|
|
|
char usb_buf[65];
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Zero out buffer |
|
|
\*-----------------------------------------------------*/
|
|
memset(usb_buf, 0x00, sizeof(usb_buf));
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Set up Single LED packet |
|
|
\*-----------------------------------------------------*/
|
|
|
|
usb_buf[0x00] = 0x00;
|
|
usb_buf[0x01] = 0x0E;
|
|
usb_buf[0x02] = 0x01;
|
|
usb_buf[0x03] = 0x00;
|
|
usb_buf[0x04] = 0x01;
|
|
usb_buf[0x05] = led;
|
|
usb_buf[0x06] = 0x81;
|
|
usb_buf[0x07] = 0x00;
|
|
usb_buf[0x08] = 0xA5;
|
|
usb_buf[0x09] = 0x00;
|
|
usb_buf[0x0A] = 0x0A;
|
|
usb_buf[0x0B] = red;
|
|
usb_buf[0x0C] = green;
|
|
usb_buf[0x0D] = blue;
|
|
usb_buf[0x12] = 0x01;
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Send packet |
|
|
\*-----------------------------------------------------*/
|
|
hid_write(dev, (unsigned char *)usb_buf, 65);
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Delay 20 milliseconds |
|
|
\*-----------------------------------------------------*/
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
|
|
|
}
|
|
void AlienwareAW510KController::SendMode
|
|
(
|
|
unsigned char zone,
|
|
unsigned char mode,
|
|
unsigned short speed,
|
|
unsigned char direction,
|
|
unsigned char colorMode,
|
|
unsigned char red,
|
|
unsigned char green,
|
|
unsigned char blue
|
|
)
|
|
{
|
|
char usb_buf[65];
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Zero out buffer |
|
|
\*-----------------------------------------------------*/
|
|
memset(usb_buf, 0x00, sizeof(usb_buf));
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Set up Mode Control packet |
|
|
\*-----------------------------------------------------*/
|
|
usb_buf[0x00] = 0x00;
|
|
usb_buf[0x01] = 0x05;
|
|
usb_buf[0x02] = 0x01;
|
|
usb_buf[0x03] = mode;
|
|
usb_buf[0x04] = red;
|
|
usb_buf[0x05] = green;
|
|
usb_buf[0x06] = blue;
|
|
usb_buf[0x0A] = speed;
|
|
usb_buf[0x0B] = 0x0A;
|
|
usb_buf[0x0D] = 0x01;
|
|
usb_buf[0x0E] = colorMode;
|
|
usb_buf[0x0F] = direction;
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Send packet |
|
|
\*-----------------------------------------------------*/
|
|
hid_write(dev, (unsigned char *)usb_buf, 65);
|
|
}
|
|
|
|
void AlienwareAW510KController::SetMorphMode
|
|
(
|
|
unsigned char mode,
|
|
unsigned short speed,
|
|
unsigned char red1,
|
|
unsigned char green1,
|
|
unsigned char blue1,
|
|
unsigned char red2,
|
|
unsigned char green2,
|
|
unsigned char blue2
|
|
)
|
|
{
|
|
char usb_buf[65];
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Zero out buffer |
|
|
\*-----------------------------------------------------*/
|
|
memset(usb_buf, 0x00, sizeof(usb_buf));
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Set up Morph Mode packet |
|
|
\*-----------------------------------------------------*/
|
|
usb_buf[0x00] = 0x00;
|
|
usb_buf[0x01] = 0x05;
|
|
usb_buf[0x02] = 0x01;
|
|
usb_buf[0x03] = mode;
|
|
usb_buf[0x04] = red1;
|
|
usb_buf[0x05] = green1;
|
|
usb_buf[0x06] = blue1;
|
|
usb_buf[0x07] = red2;
|
|
usb_buf[0x08] = green2;
|
|
usb_buf[0x09] = blue2;
|
|
usb_buf[0x0E] = 0x02;
|
|
usb_buf[0x0A] = speed;
|
|
usb_buf[0x0B] = 0x0A;
|
|
usb_buf[0x0D] = 0x01;
|
|
usb_buf[0x0E] = ALIENWARE_AW510K_TWO_USER_DEFINED_COLOR_MODE;
|
|
|
|
/*-----------------------------------------------------*\
|
|
| Send packet |
|
|
\*-----------------------------------------------------*/
|
|
hid_write(dev, (unsigned char *)usb_buf, 65);
|
|
}
|