Publish curated LumaOps source from c85ee9ef8f1454f5c305398902afbb9e6738de40
Managed validation / full (push) Failing after 8s
Managed validation / full (push) Failing after 8s
This commit is contained in:
1 parent
91f8b3e3c1
commit
def7920856
2271 files changed
+501225
-501178
No files matched your search
+376
-376
@@ -1,376 +1,376 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LenovoUSBController_Gen7_8.cpp |
|
||||
| |
|
||||
| Driver for Lenovo Gen7 and Gen8 devices |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include "LenovoDevices.h"
|
||||
#include "LenovoUSBController_Gen7_8.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static void SetGen10PayloadLength(uint16_t pid, uint8_t* buffer, uint16_t payload_length)
|
||||
{
|
||||
if(pid != LEGION_7GEN10 && pid != LEGION_5GEN10)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
buffer[2] = payload_length & 0xFF;
|
||||
buffer[3] = (payload_length >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
static bool UsesGen10PacketFormat(uint16_t pid)
|
||||
{
|
||||
return pid == LEGION_7GEN10 || pid == LEGION_5GEN10;
|
||||
}
|
||||
|
||||
LenovoGen7And8USBController::LenovoGen7And8USBController(hid_device* dev_handle, const char* path, uint16_t in_pid, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
pid = in_pid;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LenovoGen7And8USBController::~LenovoGen7And8USBController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
uint16_t LenovoGen7And8USBController::getPid()
|
||||
{
|
||||
return pid;
|
||||
}
|
||||
|
||||
string LenovoGen7And8USBController::getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
string LenovoGen7And8USBController::getLocation()
|
||||
{
|
||||
return location;
|
||||
}
|
||||
|
||||
void LenovoGen7And8USBController::setLedsByGroup(uint8_t profile_id, vector<led_group> led_groups)
|
||||
{
|
||||
if(led_groups.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Some devices require many groups for per-key updates. |
|
||||
| Send as many groups as fit in one report, then continue |
|
||||
| in additional reports. |
|
||||
\*---------------------------------------------------------*/
|
||||
size_t group = 0;
|
||||
while(group < led_groups.size())
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE];
|
||||
memset(buffer, 0x00, PACKET_SIZE);
|
||||
|
||||
size_t i = 0;
|
||||
buffer[i++] = REPORT_ID;
|
||||
buffer[i++] = SAVE_PROFILE;
|
||||
buffer[i++] = 0xC0;
|
||||
buffer[i++] = 0x03;
|
||||
buffer[i++] = profile_id;
|
||||
buffer[i++] = 0x01;
|
||||
buffer[i++] = 0x01;
|
||||
|
||||
for(; group < led_groups.size() && i < PACKET_SIZE - 21; group++)
|
||||
{
|
||||
buffer[i++] = (uint8_t)group + 1; //Group index
|
||||
buffer[i++] = 0x06;
|
||||
buffer[i++] = 0x01;
|
||||
buffer[i++] = led_groups[group].mode;
|
||||
buffer[i++] = 0x02;
|
||||
buffer[i++] = led_groups[group].speed;
|
||||
buffer[i++] = 0x03;
|
||||
buffer[i++] = led_groups[group].spin;
|
||||
buffer[i++] = 0x04;
|
||||
buffer[i++] = led_groups[group].direction;
|
||||
buffer[i++] = 0x05;
|
||||
buffer[i++] = led_groups[group].color_mode;
|
||||
buffer[i++] = 0x06;
|
||||
buffer[i++] = 0x00;
|
||||
|
||||
buffer[i++] = (uint8_t)led_groups[group].colors.size();
|
||||
for(RGBColor c : led_groups[group].colors)
|
||||
{
|
||||
buffer[i++] = RGBGetRValue(c);
|
||||
buffer[i++] = RGBGetGValue(c);
|
||||
buffer[i++] = RGBGetBValue(c);
|
||||
}
|
||||
|
||||
vector<uint16_t> leds = led_groups[group].leds;
|
||||
size_t led_count = min(leds.size(), (PACKET_SIZE - i)/2);
|
||||
buffer[i++] = (uint8_t)led_count;
|
||||
uint8_t* byte_ptr = reinterpret_cast<uint8_t*>(leds.data());
|
||||
std::copy(byte_ptr, byte_ptr + led_count * sizeof(uint16_t), buffer + i);
|
||||
i+= led_count * sizeof(uint16_t);
|
||||
}
|
||||
|
||||
if(UsesGen10PacketFormat(pid))
|
||||
{
|
||||
SetGen10PayloadLength(pid, buffer, static_cast<uint16_t>(i - 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[2] = (uint8_t)i;
|
||||
}
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void LenovoGen7And8USBController::setLedsDirectOn(uint8_t profile_id)
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE];
|
||||
memset(buffer, 0x00, PACKET_SIZE);
|
||||
|
||||
size_t i = 0;
|
||||
buffer[i++] = REPORT_ID;
|
||||
buffer[i++] = SET_DIRECT_MODE;
|
||||
buffer[i++] = 0xC0;
|
||||
buffer[i++] = 0x03;
|
||||
buffer[i++] = 0x01;
|
||||
buffer[i++] = profile_id;
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, 2);
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LenovoGen7And8USBController::setLedsDirectOff(uint8_t profile_id)
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE];
|
||||
memset(buffer, 0x00, PACKET_SIZE);
|
||||
|
||||
size_t i = 0;
|
||||
buffer[i++] = REPORT_ID;
|
||||
buffer[i++] = SET_DIRECT_MODE;
|
||||
buffer[i++] = 0xC0;
|
||||
buffer[i++] = 0x03;
|
||||
buffer[i++] = 0x02;
|
||||
buffer[i++] = profile_id;
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, 2);
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LenovoGen7And8USBController::setLedsDirect(std::vector<led> &leds, std::vector<RGBColor> &colors)
|
||||
{
|
||||
if(UsesGen10PacketFormat(pid))
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Gen10 uses 0x07/A1 direct updates, with payload length |
|
||||
| stored in bytes 2-3. |
|
||||
\*---------------------------------------------------------*/
|
||||
uint8_t buffer[PACKET_SIZE];
|
||||
memset(buffer, 0x00, PACKET_SIZE);
|
||||
|
||||
size_t i = 0;
|
||||
buffer[i++] = REPORT_ID;
|
||||
buffer[i++] = DIRECT_MODE;
|
||||
buffer[i++] = 0x00;
|
||||
buffer[i++] = 0x00;
|
||||
|
||||
size_t count = 0;
|
||||
for(size_t index = 0; index < leds.size() && index < colors.size() && i + 5 <= PACKET_SIZE; index++)
|
||||
{
|
||||
buffer[i++] = leds[index].value & 0xFF;
|
||||
buffer[i++] = leds[index].value >> 8 & 0xFF;
|
||||
buffer[i++] = RGBGetRValue(colors[index]);
|
||||
buffer[i++] = RGBGetGValue(colors[index]);
|
||||
buffer[i++] = RGBGetBValue(colors[index]);
|
||||
count++;
|
||||
}
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, static_cast<uint16_t>(count * 5));
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t buffer[PACKET_SIZE];
|
||||
memset(buffer, 0x00, PACKET_SIZE);
|
||||
|
||||
size_t i = 0;
|
||||
buffer[i++] = REPORT_ID;
|
||||
buffer[i++] = DIRECT_MODE;
|
||||
buffer[i++] = 0xC0;
|
||||
buffer[i++] = 0x03;
|
||||
|
||||
for(size_t index = 0; index < leds.size() && i < PACKET_SIZE; index++)
|
||||
{
|
||||
buffer[i++] = leds[index].value & 0xFF;
|
||||
buffer[i++] = leds[index].value >> 8 & 0xFF;
|
||||
buffer[i++] = RGBGetRValue(colors[index]);
|
||||
buffer[i++] = RGBGetGValue(colors[index]);
|
||||
buffer[i++] = RGBGetBValue(colors[index]);
|
||||
}
|
||||
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LenovoGen7And8USBController::setLedsAllOff(uint8_t profile_id)
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE] = {REPORT_ID, SAVE_PROFILE, 0xC0, 0x03, profile_id, 0x01, 0x01};
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, 3);
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
}
|
||||
|
||||
uint8_t LenovoGen7And8USBController::getCurrentProfileId()
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE] = {REPORT_ID, GET_ACTIVE_PROFILE, 0xC0, 0x03};
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, 1);
|
||||
vector<uint8_t> response = getFeatureReport(buffer, PACKET_SIZE);
|
||||
|
||||
return response.size()>4?response[4]:0x01;
|
||||
}
|
||||
|
||||
uint8_t LenovoGen7And8USBController::getCurrentBrightness()
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE] = {REPORT_ID, GET_BRIGHTNESS, 0xC0, 0x03};
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, 1);
|
||||
vector<uint8_t> response = getFeatureReport(buffer, PACKET_SIZE);
|
||||
|
||||
return response.size()>4?response[4]:0x00;
|
||||
}
|
||||
|
||||
|
||||
void LenovoGen7And8USBController::setBrightness(uint8_t brightness)
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE] = {REPORT_ID, SET_BRIGHTNESS, 0xC0, 0x03, brightness};
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, 1);
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LenovoGen7And8USBController::switchProfileTo(uint8_t profile_id)
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE] = {REPORT_ID, SWITCH_PROFILE, 0xC0, 0x03, profile_id};
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, 1);
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
}
|
||||
|
||||
std::vector<led_group> LenovoGen7And8USBController::getProfileSettings(uint8_t profile_id)
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE] = {REPORT_ID, GET_PROFILE, 0xC0, 0x03, profile_id};
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, PACKET_SIZE - 4);
|
||||
vector<uint8_t> response = getFeatureReport(buffer, PACKET_SIZE);
|
||||
|
||||
vector<led_group> groups;
|
||||
|
||||
size_t i = 7;
|
||||
while(i < response.size() && response[i] != 0x00){
|
||||
i++;
|
||||
|
||||
led_group group;
|
||||
|
||||
/*-----------------*\
|
||||
|read group settings|
|
||||
\*-----------------*/
|
||||
|
||||
size_t cnt = response[i++];
|
||||
for(size_t j = 0; j < cnt && i < response.size(); j++, i+=2)
|
||||
{
|
||||
switch(response[i])
|
||||
{
|
||||
case 0x01:
|
||||
group.mode = response[i+1];
|
||||
break;
|
||||
case 0x02:
|
||||
group.speed = response[i+1];
|
||||
break;
|
||||
case 0x03:
|
||||
group.spin = response[i+1];
|
||||
break;
|
||||
case 0x04:
|
||||
group.direction = response[i+1];
|
||||
break;
|
||||
case 0x05:
|
||||
group.color_mode = response[i+1];
|
||||
break;
|
||||
case 0x06:
|
||||
//group.mode = response[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------*\
|
||||
|read group colors |
|
||||
\*-----------------*/
|
||||
|
||||
cnt = response[i++];
|
||||
for(size_t j = 0; j < cnt && i < response.size(); j++, i+=3)
|
||||
{
|
||||
group.colors.push_back(ToRGBColor(response[i],response[i+1],response[i+2]));
|
||||
}
|
||||
|
||||
/*-----------------*\
|
||||
|read group LEDs |
|
||||
\*-----------------*/
|
||||
|
||||
cnt = response[i++];
|
||||
for(size_t j = 0; j < cnt && i < response.size(); j++, i+=2)
|
||||
{
|
||||
group.leds.push_back(response[i] | response[i+1] << 8);
|
||||
}
|
||||
|
||||
groups.push_back(group);
|
||||
}
|
||||
|
||||
return groups;
|
||||
|
||||
}
|
||||
|
||||
void LenovoGen7And8USBController::sendFeatureReport(uint8_t packet[], size_t packet_size)
|
||||
{
|
||||
hid_send_feature_report(dev, packet, packet_size);
|
||||
LOG_TRACE("[Lenovo Gen 7 Controller] Buffer: %s", ConvertBytesToHex(packet, packet_size).c_str());
|
||||
}
|
||||
|
||||
std::vector<uint8_t> LenovoGen7And8USBController::getFeatureReport(uint8_t packet[], size_t packet_size)
|
||||
{
|
||||
sendFeatureReport(packet, packet_size);
|
||||
|
||||
uint8_t read_buffer[PACKET_SIZE] = {REPORT_ID};
|
||||
int num_bytes = 0;
|
||||
num_bytes = hid_get_feature_report(dev, read_buffer, sizeof(read_buffer));
|
||||
|
||||
vector<uint8_t> response = {};
|
||||
if(num_bytes > 0)
|
||||
{
|
||||
response.insert(response.begin(), read_buffer, read_buffer + num_bytes);
|
||||
}
|
||||
|
||||
LOG_TRACE("[Lenovo Gen 7 Controller] Read Buffer: %s", ConvertBytesToHex(response).c_str());
|
||||
return response;
|
||||
}
|
||||
|
||||
std::string LenovoGen7And8USBController::ConvertBytesToHex(uint8_t packet[], size_t packet_size)
|
||||
{
|
||||
return ConvertBytesToHex(std::vector<uint8_t>(packet, packet + packet_size));
|
||||
}
|
||||
|
||||
std::string LenovoGen7And8USBController::ConvertBytesToHex(const std::vector<uint8_t> &input)
|
||||
{
|
||||
std::ostringstream temp_stream;
|
||||
for(const uint8_t &oneInputByte : input)
|
||||
{
|
||||
temp_stream << (temp_stream.tellp()==0 ? "" : " ") << std::setw(2) << std::setfill('0') << std::hex << (int)oneInputByte;
|
||||
}
|
||||
return temp_stream.str();
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LenovoUSBController_Gen7_8.cpp |
|
||||
| |
|
||||
| Driver for Lenovo Gen7 and Gen8 devices |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include "LenovoDevices.h"
|
||||
#include "LenovoUSBController_Gen7_8.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
static void SetGen10PayloadLength(uint16_t pid, uint8_t* buffer, uint16_t payload_length)
|
||||
{
|
||||
if(pid != LEGION_7GEN10 && pid != LEGION_5GEN10)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
buffer[2] = payload_length & 0xFF;
|
||||
buffer[3] = (payload_length >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
static bool UsesGen10PacketFormat(uint16_t pid)
|
||||
{
|
||||
return pid == LEGION_7GEN10 || pid == LEGION_5GEN10;
|
||||
}
|
||||
|
||||
LenovoGen7And8USBController::LenovoGen7And8USBController(hid_device* dev_handle, const char* path, uint16_t in_pid, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
pid = in_pid;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LenovoGen7And8USBController::~LenovoGen7And8USBController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
uint16_t LenovoGen7And8USBController::getPid()
|
||||
{
|
||||
return pid;
|
||||
}
|
||||
|
||||
string LenovoGen7And8USBController::getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
string LenovoGen7And8USBController::getLocation()
|
||||
{
|
||||
return location;
|
||||
}
|
||||
|
||||
void LenovoGen7And8USBController::setLedsByGroup(uint8_t profile_id, vector<led_group> led_groups)
|
||||
{
|
||||
if(led_groups.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Some devices require many groups for per-key updates. |
|
||||
| Send as many groups as fit in one report, then continue |
|
||||
| in additional reports. |
|
||||
\*---------------------------------------------------------*/
|
||||
size_t group = 0;
|
||||
while(group < led_groups.size())
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE];
|
||||
memset(buffer, 0x00, PACKET_SIZE);
|
||||
|
||||
size_t i = 0;
|
||||
buffer[i++] = REPORT_ID;
|
||||
buffer[i++] = SAVE_PROFILE;
|
||||
buffer[i++] = 0xC0;
|
||||
buffer[i++] = 0x03;
|
||||
buffer[i++] = profile_id;
|
||||
buffer[i++] = 0x01;
|
||||
buffer[i++] = 0x01;
|
||||
|
||||
for(; group < led_groups.size() && i < PACKET_SIZE - 21; group++)
|
||||
{
|
||||
buffer[i++] = (uint8_t)group + 1; //Group index
|
||||
buffer[i++] = 0x06;
|
||||
buffer[i++] = 0x01;
|
||||
buffer[i++] = led_groups[group].mode;
|
||||
buffer[i++] = 0x02;
|
||||
buffer[i++] = led_groups[group].speed;
|
||||
buffer[i++] = 0x03;
|
||||
buffer[i++] = led_groups[group].spin;
|
||||
buffer[i++] = 0x04;
|
||||
buffer[i++] = led_groups[group].direction;
|
||||
buffer[i++] = 0x05;
|
||||
buffer[i++] = led_groups[group].color_mode;
|
||||
buffer[i++] = 0x06;
|
||||
buffer[i++] = 0x00;
|
||||
|
||||
buffer[i++] = (uint8_t)led_groups[group].colors.size();
|
||||
for(RGBColor c : led_groups[group].colors)
|
||||
{
|
||||
buffer[i++] = RGBGetRValue(c);
|
||||
buffer[i++] = RGBGetGValue(c);
|
||||
buffer[i++] = RGBGetBValue(c);
|
||||
}
|
||||
|
||||
vector<uint16_t> leds = led_groups[group].leds;
|
||||
size_t led_count = min(leds.size(), (PACKET_SIZE - i)/2);
|
||||
buffer[i++] = (uint8_t)led_count;
|
||||
uint8_t* byte_ptr = reinterpret_cast<uint8_t*>(leds.data());
|
||||
std::copy(byte_ptr, byte_ptr + led_count * sizeof(uint16_t), buffer + i);
|
||||
i+= led_count * sizeof(uint16_t);
|
||||
}
|
||||
|
||||
if(UsesGen10PacketFormat(pid))
|
||||
{
|
||||
SetGen10PayloadLength(pid, buffer, static_cast<uint16_t>(i - 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[2] = (uint8_t)i;
|
||||
}
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void LenovoGen7And8USBController::setLedsDirectOn(uint8_t profile_id)
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE];
|
||||
memset(buffer, 0x00, PACKET_SIZE);
|
||||
|
||||
size_t i = 0;
|
||||
buffer[i++] = REPORT_ID;
|
||||
buffer[i++] = SET_DIRECT_MODE;
|
||||
buffer[i++] = 0xC0;
|
||||
buffer[i++] = 0x03;
|
||||
buffer[i++] = 0x01;
|
||||
buffer[i++] = profile_id;
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, 2);
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LenovoGen7And8USBController::setLedsDirectOff(uint8_t profile_id)
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE];
|
||||
memset(buffer, 0x00, PACKET_SIZE);
|
||||
|
||||
size_t i = 0;
|
||||
buffer[i++] = REPORT_ID;
|
||||
buffer[i++] = SET_DIRECT_MODE;
|
||||
buffer[i++] = 0xC0;
|
||||
buffer[i++] = 0x03;
|
||||
buffer[i++] = 0x02;
|
||||
buffer[i++] = profile_id;
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, 2);
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LenovoGen7And8USBController::setLedsDirect(std::vector<led> &leds, std::vector<RGBColor> &colors)
|
||||
{
|
||||
if(UsesGen10PacketFormat(pid))
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Gen10 uses 0x07/A1 direct updates, with payload length |
|
||||
| stored in bytes 2-3. |
|
||||
\*---------------------------------------------------------*/
|
||||
uint8_t buffer[PACKET_SIZE];
|
||||
memset(buffer, 0x00, PACKET_SIZE);
|
||||
|
||||
size_t i = 0;
|
||||
buffer[i++] = REPORT_ID;
|
||||
buffer[i++] = DIRECT_MODE;
|
||||
buffer[i++] = 0x00;
|
||||
buffer[i++] = 0x00;
|
||||
|
||||
size_t count = 0;
|
||||
for(size_t index = 0; index < leds.size() && index < colors.size() && i + 5 <= PACKET_SIZE; index++)
|
||||
{
|
||||
buffer[i++] = leds[index].value & 0xFF;
|
||||
buffer[i++] = leds[index].value >> 8 & 0xFF;
|
||||
buffer[i++] = RGBGetRValue(colors[index]);
|
||||
buffer[i++] = RGBGetGValue(colors[index]);
|
||||
buffer[i++] = RGBGetBValue(colors[index]);
|
||||
count++;
|
||||
}
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, static_cast<uint16_t>(count * 5));
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t buffer[PACKET_SIZE];
|
||||
memset(buffer, 0x00, PACKET_SIZE);
|
||||
|
||||
size_t i = 0;
|
||||
buffer[i++] = REPORT_ID;
|
||||
buffer[i++] = DIRECT_MODE;
|
||||
buffer[i++] = 0xC0;
|
||||
buffer[i++] = 0x03;
|
||||
|
||||
for(size_t index = 0; index < leds.size() && i < PACKET_SIZE; index++)
|
||||
{
|
||||
buffer[i++] = leds[index].value & 0xFF;
|
||||
buffer[i++] = leds[index].value >> 8 & 0xFF;
|
||||
buffer[i++] = RGBGetRValue(colors[index]);
|
||||
buffer[i++] = RGBGetGValue(colors[index]);
|
||||
buffer[i++] = RGBGetBValue(colors[index]);
|
||||
}
|
||||
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LenovoGen7And8USBController::setLedsAllOff(uint8_t profile_id)
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE] = {REPORT_ID, SAVE_PROFILE, 0xC0, 0x03, profile_id, 0x01, 0x01};
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, 3);
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
}
|
||||
|
||||
uint8_t LenovoGen7And8USBController::getCurrentProfileId()
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE] = {REPORT_ID, GET_ACTIVE_PROFILE, 0xC0, 0x03};
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, 1);
|
||||
vector<uint8_t> response = getFeatureReport(buffer, PACKET_SIZE);
|
||||
|
||||
return response.size()>4?response[4]:0x01;
|
||||
}
|
||||
|
||||
uint8_t LenovoGen7And8USBController::getCurrentBrightness()
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE] = {REPORT_ID, GET_BRIGHTNESS, 0xC0, 0x03};
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, 1);
|
||||
vector<uint8_t> response = getFeatureReport(buffer, PACKET_SIZE);
|
||||
|
||||
return response.size()>4?response[4]:0x00;
|
||||
}
|
||||
|
||||
|
||||
void LenovoGen7And8USBController::setBrightness(uint8_t brightness)
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE] = {REPORT_ID, SET_BRIGHTNESS, 0xC0, 0x03, brightness};
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, 1);
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LenovoGen7And8USBController::switchProfileTo(uint8_t profile_id)
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE] = {REPORT_ID, SWITCH_PROFILE, 0xC0, 0x03, profile_id};
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, 1);
|
||||
sendFeatureReport(buffer, PACKET_SIZE);
|
||||
}
|
||||
|
||||
std::vector<led_group> LenovoGen7And8USBController::getProfileSettings(uint8_t profile_id)
|
||||
{
|
||||
uint8_t buffer[PACKET_SIZE] = {REPORT_ID, GET_PROFILE, 0xC0, 0x03, profile_id};
|
||||
|
||||
SetGen10PayloadLength(pid, buffer, PACKET_SIZE - 4);
|
||||
vector<uint8_t> response = getFeatureReport(buffer, PACKET_SIZE);
|
||||
|
||||
vector<led_group> groups;
|
||||
|
||||
size_t i = 7;
|
||||
while(i < response.size() && response[i] != 0x00){
|
||||
i++;
|
||||
|
||||
led_group group;
|
||||
|
||||
/*-----------------*\
|
||||
|read group settings|
|
||||
\*-----------------*/
|
||||
|
||||
size_t cnt = response[i++];
|
||||
for(size_t j = 0; j < cnt && i < response.size(); j++, i+=2)
|
||||
{
|
||||
switch(response[i])
|
||||
{
|
||||
case 0x01:
|
||||
group.mode = response[i+1];
|
||||
break;
|
||||
case 0x02:
|
||||
group.speed = response[i+1];
|
||||
break;
|
||||
case 0x03:
|
||||
group.spin = response[i+1];
|
||||
break;
|
||||
case 0x04:
|
||||
group.direction = response[i+1];
|
||||
break;
|
||||
case 0x05:
|
||||
group.color_mode = response[i+1];
|
||||
break;
|
||||
case 0x06:
|
||||
//group.mode = response[i+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------*\
|
||||
|read group colors |
|
||||
\*-----------------*/
|
||||
|
||||
cnt = response[i++];
|
||||
for(size_t j = 0; j < cnt && i < response.size(); j++, i+=3)
|
||||
{
|
||||
group.colors.push_back(ToRGBColor(response[i],response[i+1],response[i+2]));
|
||||
}
|
||||
|
||||
/*-----------------*\
|
||||
|read group LEDs |
|
||||
\*-----------------*/
|
||||
|
||||
cnt = response[i++];
|
||||
for(size_t j = 0; j < cnt && i < response.size(); j++, i+=2)
|
||||
{
|
||||
group.leds.push_back(response[i] | response[i+1] << 8);
|
||||
}
|
||||
|
||||
groups.push_back(group);
|
||||
}
|
||||
|
||||
return groups;
|
||||
|
||||
}
|
||||
|
||||
void LenovoGen7And8USBController::sendFeatureReport(uint8_t packet[], size_t packet_size)
|
||||
{
|
||||
hid_send_feature_report(dev, packet, packet_size);
|
||||
LOG_TRACE("[Lenovo Gen 7 Controller] Buffer: %s", ConvertBytesToHex(packet, packet_size).c_str());
|
||||
}
|
||||
|
||||
std::vector<uint8_t> LenovoGen7And8USBController::getFeatureReport(uint8_t packet[], size_t packet_size)
|
||||
{
|
||||
sendFeatureReport(packet, packet_size);
|
||||
|
||||
uint8_t read_buffer[PACKET_SIZE] = {REPORT_ID};
|
||||
int num_bytes = 0;
|
||||
num_bytes = hid_get_feature_report(dev, read_buffer, sizeof(read_buffer));
|
||||
|
||||
vector<uint8_t> response = {};
|
||||
if(num_bytes > 0)
|
||||
{
|
||||
response.insert(response.begin(), read_buffer, read_buffer + num_bytes);
|
||||
}
|
||||
|
||||
LOG_TRACE("[Lenovo Gen 7 Controller] Read Buffer: %s", ConvertBytesToHex(response).c_str());
|
||||
return response;
|
||||
}
|
||||
|
||||
std::string LenovoGen7And8USBController::ConvertBytesToHex(uint8_t packet[], size_t packet_size)
|
||||
{
|
||||
return ConvertBytesToHex(std::vector<uint8_t>(packet, packet + packet_size));
|
||||
}
|
||||
|
||||
std::string LenovoGen7And8USBController::ConvertBytesToHex(const std::vector<uint8_t> &input)
|
||||
{
|
||||
std::ostringstream temp_stream;
|
||||
for(const uint8_t &oneInputByte : input)
|
||||
{
|
||||
temp_stream << (temp_stream.tellp()==0 ? "" : " ") << std::setw(2) << std::setfill('0') << std::hex << (int)oneInputByte;
|
||||
}
|
||||
return temp_stream.str();
|
||||
}
|
||||
+92
-92
@@ -1,92 +1,92 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LenovoUSBController_Gen7_8.h |
|
||||
| |
|
||||
| Driver for Lenovo Gen7 and Gen8 devices |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
#ifndef HID_MAX_STR
|
||||
#define HID_MAX_STR 255
|
||||
#endif
|
||||
|
||||
#define PACKET_SIZE 960
|
||||
#define REPORT_ID 0x07
|
||||
#define DIRECT_MODE 0xA1
|
||||
#define SWITCH_PROFILE 0xC8
|
||||
#define GET_ACTIVE_PROFILE 0xCA
|
||||
#define SAVE_PROFILE 0xCB
|
||||
#define GET_PROFILE 0xCC
|
||||
#define GET_BRIGHTNESS 0xCD
|
||||
#define SET_BRIGHTNESS 0xCE
|
||||
#define SET_DIRECT_MODE 0xD0
|
||||
#define GET_DIRECT_MODE_PROFILE 0xD1
|
||||
|
||||
struct led_group
|
||||
{
|
||||
uint8_t mode;
|
||||
uint8_t speed;
|
||||
uint8_t spin;
|
||||
uint8_t direction;
|
||||
uint8_t color_mode;
|
||||
std::vector<RGBColor> colors;
|
||||
std::vector<uint16_t> leds;
|
||||
};
|
||||
|
||||
class LenovoGen7And8USBController
|
||||
{
|
||||
|
||||
public:
|
||||
/*--------------*\
|
||||
|ctor(s) and dtor|
|
||||
\*--------------*/
|
||||
LenovoGen7And8USBController(hid_device* dev_handle, const char* path, uint16_t in_pid, std::string dev_name);
|
||||
~LenovoGen7And8USBController();
|
||||
|
||||
/*--------------*\
|
||||
|device functions|
|
||||
\*--------------*/
|
||||
void setLedsByGroup(uint8_t profile_id, std::vector<led_group> led_groups);
|
||||
void setLedsDirect(std::vector<led> &leds, std::vector<RGBColor> &colors);
|
||||
void setLedsAllOff(uint8_t profile_id);
|
||||
void setLedsDirectOn(uint8_t profile_id);
|
||||
void setLedsDirectOff(uint8_t profile_id);
|
||||
uint16_t getPid();
|
||||
std::string getName();
|
||||
std::string getLocation();
|
||||
uint8_t getCurrentProfileId();
|
||||
uint8_t getCurrentBrightness();
|
||||
void setBrightness(uint8_t brightness);
|
||||
uint8_t getKeyboardId();
|
||||
void switchProfileTo(uint8_t profile_id);
|
||||
std::vector<led_group> getProfileSettings(uint8_t profile_id);
|
||||
|
||||
|
||||
private:
|
||||
/*--------------*\
|
||||
|data members |
|
||||
\*--------------*/
|
||||
std::string name;
|
||||
hid_device *dev;
|
||||
std::string location;
|
||||
uint16_t pid;
|
||||
|
||||
/*--------------*\
|
||||
|device functions|
|
||||
\*--------------*/
|
||||
void sendFeatureReport(uint8_t packet[], size_t packet_size);
|
||||
std::vector<uint8_t> getFeatureReport(uint8_t packet[], size_t packet_size);
|
||||
std::string ConvertBytesToHex(uint8_t packet[], size_t packet_size);
|
||||
std::string ConvertBytesToHex(const std::vector<uint8_t> &input);
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| LenovoUSBController_Gen7_8.h |
|
||||
| |
|
||||
| Driver for Lenovo Gen7 and Gen8 devices |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
#ifndef HID_MAX_STR
|
||||
#define HID_MAX_STR 255
|
||||
#endif
|
||||
|
||||
#define PACKET_SIZE 960
|
||||
#define REPORT_ID 0x07
|
||||
#define DIRECT_MODE 0xA1
|
||||
#define SWITCH_PROFILE 0xC8
|
||||
#define GET_ACTIVE_PROFILE 0xCA
|
||||
#define SAVE_PROFILE 0xCB
|
||||
#define GET_PROFILE 0xCC
|
||||
#define GET_BRIGHTNESS 0xCD
|
||||
#define SET_BRIGHTNESS 0xCE
|
||||
#define SET_DIRECT_MODE 0xD0
|
||||
#define GET_DIRECT_MODE_PROFILE 0xD1
|
||||
|
||||
struct led_group
|
||||
{
|
||||
uint8_t mode;
|
||||
uint8_t speed;
|
||||
uint8_t spin;
|
||||
uint8_t direction;
|
||||
uint8_t color_mode;
|
||||
std::vector<RGBColor> colors;
|
||||
std::vector<uint16_t> leds;
|
||||
};
|
||||
|
||||
class LenovoGen7And8USBController
|
||||
{
|
||||
|
||||
public:
|
||||
/*--------------*\
|
||||
|ctor(s) and dtor|
|
||||
\*--------------*/
|
||||
LenovoGen7And8USBController(hid_device* dev_handle, const char* path, uint16_t in_pid, std::string dev_name);
|
||||
~LenovoGen7And8USBController();
|
||||
|
||||
/*--------------*\
|
||||
|device functions|
|
||||
\*--------------*/
|
||||
void setLedsByGroup(uint8_t profile_id, std::vector<led_group> led_groups);
|
||||
void setLedsDirect(std::vector<led> &leds, std::vector<RGBColor> &colors);
|
||||
void setLedsAllOff(uint8_t profile_id);
|
||||
void setLedsDirectOn(uint8_t profile_id);
|
||||
void setLedsDirectOff(uint8_t profile_id);
|
||||
uint16_t getPid();
|
||||
std::string getName();
|
||||
std::string getLocation();
|
||||
uint8_t getCurrentProfileId();
|
||||
uint8_t getCurrentBrightness();
|
||||
void setBrightness(uint8_t brightness);
|
||||
uint8_t getKeyboardId();
|
||||
void switchProfileTo(uint8_t profile_id);
|
||||
std::vector<led_group> getProfileSettings(uint8_t profile_id);
|
||||
|
||||
|
||||
private:
|
||||
/*--------------*\
|
||||
|data members |
|
||||
\*--------------*/
|
||||
std::string name;
|
||||
hid_device *dev;
|
||||
std::string location;
|
||||
uint16_t pid;
|
||||
|
||||
/*--------------*\
|
||||
|device functions|
|
||||
\*--------------*/
|
||||
void sendFeatureReport(uint8_t packet[], size_t packet_size);
|
||||
std::vector<uint8_t> getFeatureReport(uint8_t packet[], size_t packet_size);
|
||||
std::string ConvertBytesToHex(uint8_t packet[], size_t packet_size);
|
||||
std::string ConvertBytesToHex(const std::vector<uint8_t> &input);
|
||||
};
|
||||
+820
-820
File diff suppressed because it is too large.
Load diff
+57
-57
@@ -1,57 +1,57 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_Lenovo_Gen7_8.h |
|
||||
| |
|
||||
| RGBController for Lenovo Gen7 and Gen8 devices |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LenovoUSBController_Gen7_8.h"
|
||||
|
||||
enum
|
||||
{
|
||||
LENOVO_LEGION_GEN7_8_MODE_SCREW_RAINBOW = 0x01,
|
||||
LENOVO_LEGION_GEN7_8_MODE_RAINBOW_WAVE = 0x02,
|
||||
LENOVO_LEGION_GEN7_8_MODE_COLOR_CHANGE = 0x03,
|
||||
LENOVO_LEGION_GEN7_8_MODE_COLOR_PULSE = 0x04,
|
||||
LENOVO_LEGION_GEN7_8_MODE_COLOR_WAVE = 0x05,
|
||||
LENOVO_LEGION_GEN7_8_MODE_SMOOTH = 0x06,
|
||||
LENOVO_LEGION_GEN7_8_MODE_RAIN = 0x07,
|
||||
LENOVO_LEGION_GEN7_8_MODE_RIPPLE = 0x08,
|
||||
LENOVO_LEGION_GEN7_8_MODE_AUDIO_BOUNCE = 0x09,
|
||||
LENOVO_LEGION_GEN7_8_MODE_AUDIO_RIPPLE = 0x0A,
|
||||
LENOVO_LEGION_GEN7_8_MODE_STATIC = 0x0B,
|
||||
LENOVO_LEGION_GEN7_8_MODE_TYPE = 0x0C,
|
||||
LENOVO_LEGION_GEN7_8_MODE_DIRECT = 0x0D,
|
||||
};
|
||||
|
||||
class LenovoRGBController_Gen7_8 : public RGBController
|
||||
{
|
||||
public:
|
||||
LenovoRGBController_Gen7_8(LenovoGen7And8USBController* controller_ptr);
|
||||
~LenovoRGBController_Gen7_8();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LenovoGen7And8USBController* controller;
|
||||
std::vector<led_group> GetLedGroups();
|
||||
void ReadDeviceSettings();
|
||||
std::unordered_map<unsigned int, size_t> led_id_to_index;
|
||||
int last_mode = 0;
|
||||
bool direct_enabled = false;
|
||||
uint8_t brightness = 0x00;
|
||||
uint8_t profile_id = 0x01;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_Lenovo_Gen7_8.h |
|
||||
| |
|
||||
| RGBController for Lenovo Gen7 and Gen8 devices |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LenovoUSBController_Gen7_8.h"
|
||||
|
||||
enum
|
||||
{
|
||||
LENOVO_LEGION_GEN7_8_MODE_SCREW_RAINBOW = 0x01,
|
||||
LENOVO_LEGION_GEN7_8_MODE_RAINBOW_WAVE = 0x02,
|
||||
LENOVO_LEGION_GEN7_8_MODE_COLOR_CHANGE = 0x03,
|
||||
LENOVO_LEGION_GEN7_8_MODE_COLOR_PULSE = 0x04,
|
||||
LENOVO_LEGION_GEN7_8_MODE_COLOR_WAVE = 0x05,
|
||||
LENOVO_LEGION_GEN7_8_MODE_SMOOTH = 0x06,
|
||||
LENOVO_LEGION_GEN7_8_MODE_RAIN = 0x07,
|
||||
LENOVO_LEGION_GEN7_8_MODE_RIPPLE = 0x08,
|
||||
LENOVO_LEGION_GEN7_8_MODE_AUDIO_BOUNCE = 0x09,
|
||||
LENOVO_LEGION_GEN7_8_MODE_AUDIO_RIPPLE = 0x0A,
|
||||
LENOVO_LEGION_GEN7_8_MODE_STATIC = 0x0B,
|
||||
LENOVO_LEGION_GEN7_8_MODE_TYPE = 0x0C,
|
||||
LENOVO_LEGION_GEN7_8_MODE_DIRECT = 0x0D,
|
||||
};
|
||||
|
||||
class LenovoRGBController_Gen7_8 : public RGBController
|
||||
{
|
||||
public:
|
||||
LenovoRGBController_Gen7_8(LenovoGen7And8USBController* controller_ptr);
|
||||
~LenovoRGBController_Gen7_8();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LenovoGen7And8USBController* controller;
|
||||
std::vector<led_group> GetLedGroups();
|
||||
void ReadDeviceSettings();
|
||||
std::unordered_map<unsigned int, size_t> led_id_to_index;
|
||||
int last_mode = 0;
|
||||
bool direct_enabled = false;
|
||||
uint8_t brightness = 0x00;
|
||||
uint8_t profile_id = 0x01;
|
||||
};
|
||||
Reference in new issue
Block a user