mirror of
https://github.com/CalcProgrammer1/OpenRGB.git
synced 2025-12-25 08:17:53 -05:00
133 lines
4.6 KiB
C++
133 lines
4.6 KiB
C++
/*-------------------------------------------------------------------*\
|
|
| LenovoUSBController.cpp |
|
|
| |
|
|
| Driver for various Lenovo Devices |
|
|
| |
|
|
| Cooper Hall (geobot19) 17 Apr 2022 |
|
|
| |
|
|
\*-------------------------------------------------------------------*/
|
|
|
|
#include "LenovoUSBController.h"
|
|
#include "LogManager.h"
|
|
|
|
using namespace std;
|
|
|
|
LenovoUSBController::LenovoUSBController(hid_device* dev_handle, const char* path, uint16_t in_pid)
|
|
{
|
|
const uint8_t sz = HID_MAX_STR;
|
|
wchar_t tmp[sz];
|
|
|
|
dev = dev_handle;
|
|
location = path;
|
|
pid = in_pid;
|
|
|
|
hid_get_manufacturer_string(dev, tmp, sz);
|
|
std::wstring w_tmp = wstring(tmp);
|
|
name = string(w_tmp.begin(), w_tmp.end());
|
|
|
|
hid_get_product_string(dev, tmp, sz);
|
|
w_tmp = wstring(tmp);
|
|
name.append(" ").append(string(w_tmp.begin(), w_tmp.end()));
|
|
|
|
setDeviceSoftwareMode();
|
|
}
|
|
|
|
LenovoUSBController::~LenovoUSBController()
|
|
{
|
|
hid_close(dev);
|
|
}
|
|
|
|
uint16_t LenovoUSBController::getPid()
|
|
{
|
|
return pid;
|
|
}
|
|
|
|
string LenovoUSBController::getName()
|
|
{
|
|
return name;
|
|
}
|
|
|
|
string LenovoUSBController::getLocation()
|
|
{
|
|
return location;
|
|
}
|
|
|
|
void LenovoUSBController::setZoneLeds(uint8_t zone_num, vector<pair<uint8_t, RGBColor>> &led_colors)
|
|
{
|
|
for(size_t curr = 0; curr < led_colors.size();)
|
|
{
|
|
uint8_t buffer[LENOVO_HID_PACKET_SIZE] = {LENOVO_INSTRUCTION_START, (uint8_t) (LENOVO_ZONE_ID_0+zone_num), 0, 0};
|
|
|
|
/*---------------------------------------------------------*\
|
|
| Set the colour bytes in the packet |
|
|
| buffer[2] is required to know the amount of leds in packet|
|
|
| so it is set here as well |
|
|
\*---------------------------------------------------------*/
|
|
for(; buffer[2] < LENOVO_MAX_LEDS_PER_PACKET && curr < led_colors.size(); ++buffer[2])
|
|
{
|
|
uint8_t offset = (buffer[2] * 4) + 4;
|
|
|
|
/*------------------*\
|
|
|write the led number|
|
|
\*------------------*/
|
|
buffer[offset] = led_colors[curr].first;
|
|
/*--------------*\
|
|
|write the colors|
|
|
\*--------------*/
|
|
buffer[offset + 1] = RGBGetRValue(led_colors[curr].second);
|
|
buffer[offset + 2] = RGBGetGValue(led_colors[curr].second);
|
|
buffer[offset + 3] = RGBGetBValue(led_colors[curr].second);
|
|
|
|
++curr;
|
|
}
|
|
|
|
hid_send_feature_report(dev, buffer, LENOVO_HID_PACKET_SIZE);
|
|
}
|
|
}
|
|
|
|
void LenovoUSBController::setSingleLED(uint8_t zone_num, uint8_t led_num, RGBColor color)
|
|
{
|
|
uint8_t buffer[LENOVO_HID_PACKET_SIZE] = {LENOVO_INSTRUCTION_START, (uint8_t) (LENOVO_ZONE_ID_0+zone_num), 1, 0, led_num, (uint8_t) (RGBGetRValue(color)), (uint8_t) (RGBGetGValue(color)), (uint8_t) (RGBGetBValue(color))};
|
|
hid_send_feature_report(dev, buffer, LENOVO_HID_PACKET_SIZE);
|
|
}
|
|
|
|
void LenovoUSBController::sendBasicInstruction(uint8_t instruction)
|
|
{
|
|
uint8_t buffer[LENOVO_HID_PACKET_SIZE] = {LENOVO_INSTRUCTION_START, instruction};
|
|
hid_send_feature_report(dev, buffer, LENOVO_HID_PACKET_SIZE);
|
|
}
|
|
|
|
vector<uint8_t> LenovoUSBController::getInformation(uint8_t information_id)
|
|
{
|
|
uint8_t buffer[LENOVO_HID_PACKET_SIZE] = {LENOVO_INSTRUCTION_START, information_id};
|
|
hid_send_feature_report(dev, buffer, LENOVO_HID_PACKET_SIZE);
|
|
uint8_t read_buffer[LENOVO_HID_PACKET_SIZE] = {LENOVO_INSTRUCTION_START};
|
|
int num_bytes = hid_get_feature_report(dev, read_buffer, LENOVO_HID_PACKET_SIZE);
|
|
if(num_bytes > 0)
|
|
{
|
|
vector<uint8_t> response(&read_buffer[0], &read_buffer[num_bytes]);
|
|
return response;
|
|
}
|
|
return vector<uint8_t>();
|
|
}
|
|
|
|
void LenovoUSBController::setDeviceSoftwareMode()
|
|
{
|
|
/*---------------------------------------*\
|
|
| this is required for the device listen |
|
|
| to the software protocol |
|
|
\*---------------------------------------*/
|
|
sendBasicInstruction(0xB2);
|
|
}
|
|
|
|
void LenovoUSBController::setDeviceHardwareMode()
|
|
{
|
|
/*---------------------------------------*\
|
|
|releases the device from sofware mode so |
|
|
|that onboard controlls can be used |
|
|
|this has not been shown to happen between|
|
|
|reboots |
|
|
\*---------------------------------------*/
|
|
sendBasicInstruction(0xB1);
|
|
}
|