Compare commits
24
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f888b1ddbc | ||
|
|
f03b3472ea | ||
|
|
3e53302613 | ||
|
|
30043e3835 | ||
|
|
ce3ee27d8e | ||
|
|
0873907793 | ||
|
|
5303e29628 | ||
|
|
ffcf003c37 | ||
|
|
f7e0e3d77b | ||
|
|
cb0052c761 | ||
|
|
e075870853 | ||
|
|
4cf5fe9346 | ||
|
|
eb5d88537d | ||
|
|
d5e0c94fdc | ||
|
|
cd44e41d46 | ||
|
|
0129e58f53 | ||
|
|
0adfde971b | ||
|
|
27a93edec5 | ||
|
|
65e04a5332 | ||
|
|
ec5ff26eda | ||
|
|
51398fd6c5 | ||
|
|
9a6cfaf021 | ||
|
|
0a201edbc1 | ||
|
|
83ea112603 |
+2
-2
@@ -186,8 +186,8 @@ void ASRockGPUSMBusController::SetChannelColor(uint8_t channel_idx, uint8_t red,
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
0x80, // Brightness
|
||||
0xFF, // Effect speed
|
||||
0x80, // Effect speed
|
||||
0xFF, // Brightness
|
||||
0x00, // Effect direction
|
||||
0x1A // Unknown constant
|
||||
};
|
||||
|
||||
+1
@@ -42,5 +42,6 @@ DetectedControllers DetectASRockGPUSMBusControllers(i2c_smbus_interface* bus, ui
|
||||
}
|
||||
|
||||
REGISTER_I2C_PCI_DETECTOR("ASRock Radeon RX 9070 XT Steel Legend", DetectASRockGPUSMBusControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, ASROCK_SUB_VEN, 0x5403, ASROCK_GPU_SMBUS_ADDRESS);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASRock Radeon RX 9070 XT Steel Legend Dark", DetectASRockGPUSMBusControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, ASROCK_SUB_VEN, 0x5414, ASROCK_GPU_SMBUS_ADDRESS);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASRock Radeon RX 9070 XT Taichi 16GB OC", DetectASRockGPUSMBusControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, ASROCK_SUB_VEN, 0x5401, ASROCK_GPU_SMBUS_ADDRESS);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASRock Radeon RX 9060 XT Steel Legend", DetectASRockGPUSMBusControllers, AMD_GPU_VEN, AMD_NAVI44_DEV, ASROCK_SUB_VEN, 0x5407, ASROCK_GPU_SMBUS_ADDRESS);
|
||||
|
||||
+2
@@ -44,6 +44,8 @@ RGBController_ASRockGPUSMBus::RGBController_ASRockGPUSMBus(ASRockGPUSMBusControl
|
||||
|
||||
RGBController_ASRockGPUSMBus::~RGBController_ASRockGPUSMBus()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,18 @@ CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_han
|
||||
| If the PID is in the know wireless receivers list |
|
||||
| switch the write_cmd to talk to the device and retry |
|
||||
\*---------------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| Establish the packet size before talking to the device. |
|
||||
\*---------------------------------------------------------*/
|
||||
uint16_t report_size = GetOutputReportSize();
|
||||
|
||||
if(report_size >= CORSAIR_V2_WRITE_SIZE && report_size <= CORSAIR_V2_PACKET_SIZE)
|
||||
{
|
||||
pkt_sze = report_size;
|
||||
}
|
||||
|
||||
LOG_DEBUG("[%s] Packet length set to %d", device_name.c_str(), pkt_sze);
|
||||
|
||||
unsigned int pid = GetAddressRetry(0x12);
|
||||
|
||||
switch(pid)
|
||||
@@ -64,14 +76,12 @@ CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_han
|
||||
| the device being set up. |
|
||||
\*---------------------------------------------------------*/
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
memset(buffer, 0, pkt_sze);
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_GET;
|
||||
buffer[3] = 0x11;
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
uint16_t result = hid_read_timeout(dev, buffer, CORSAIR_V2_PACKET_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
result++;
|
||||
pkt_sze = std::max(result, (uint16_t)CORSAIR_V2_WRITE_SIZE);
|
||||
LOG_DEBUG("[%s] Packet length set to %d", device_name.c_str(), pkt_sze);
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| NB: If the device is not found in the device list |
|
||||
@@ -108,22 +118,115 @@ CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_han
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Check lighting control endpoints |
|
||||
| If lighting control endpoint 2 is unavailable |
|
||||
| then use endpoint 1. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(light_ctrl == CORSAIR_V2_LIGHT_CTRL2)
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Check lighting control endpoints |
|
||||
| If lighting control endpoint 2 is unavailable |
|
||||
| then use endpoint 1. |
|
||||
\*---------------------------------------------------------*/
|
||||
uint16_t CorsairPeripheralV2Controller::GetOutputReportSize()
|
||||
{
|
||||
unsigned char descriptor[HID_API_MAX_REPORT_DESCRIPTOR_SIZE];
|
||||
int length = hid_get_report_descriptor(dev, descriptor, sizeof(descriptor));
|
||||
|
||||
if(length <= 0)
|
||||
{
|
||||
result = StartTransaction(0);
|
||||
if(result > 0)
|
||||
{
|
||||
light_ctrl = CORSAIR_V2_LIGHT_CTRL1;
|
||||
StartTransaction(0);
|
||||
}
|
||||
StopTransaction(0);
|
||||
LOG_DEBUG("[%s] Lighting Endpoint set to %02X", device_name.c_str(), light_ctrl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int report_size = 0;
|
||||
unsigned int report_count = 0;
|
||||
int index = 0;
|
||||
|
||||
while(index < length)
|
||||
{
|
||||
unsigned char item = descriptor[index];
|
||||
unsigned char tag = item & 0xFC;
|
||||
unsigned char item_size = item & 0x03;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| A size field of 3 means four data bytes follow. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(item_size == 3)
|
||||
{
|
||||
item_size = 4;
|
||||
}
|
||||
|
||||
if(index + 1 + item_size > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned int value = 0;
|
||||
|
||||
for(unsigned char byte = 0; byte < item_size; byte++)
|
||||
{
|
||||
value |= (unsigned int)descriptor[index + 1 + byte] << (8 * byte);
|
||||
}
|
||||
|
||||
switch(tag)
|
||||
{
|
||||
case 0x74: /* Report Size */
|
||||
report_size = value;
|
||||
break;
|
||||
|
||||
case 0x94: /* Report Count */
|
||||
report_count = value;
|
||||
break;
|
||||
|
||||
case 0x90: /* Output */
|
||||
if(report_size > 0 && report_count > 0)
|
||||
{
|
||||
return (uint16_t)(((report_size * report_count) / 8) + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
index += 1 + item_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2Controller::DetectLightingEndpoint()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| A device that cannot be read from cannot be probed; those |
|
||||
| carry the endpoint they need already set. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(skip_reads)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Lighting control 1 is the plain lighting resource and |
|
||||
| takes colour block data. A device that answers |
|
||||
| invalid or unsupported for it wants the alternate |
|
||||
| lighting resource, which takes RGB triplets. |
|
||||
\*---------------------------------------------------------*/
|
||||
light_ctrl = CORSAIR_V2_LIGHT_CTRL1;
|
||||
unsigned char result = StartTransaction(0);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| A handle left open by an earlier session answers failed; |
|
||||
| close it and open it again. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(result == CORSAIR_V2_ERR_FAILED)
|
||||
{
|
||||
StopTransaction(0);
|
||||
result = StartTransaction(0);
|
||||
}
|
||||
|
||||
if(result == CORSAIR_V2_ERR_INVALID || result == CORSAIR_V2_ERR_NOT_SUPPORTED)
|
||||
{
|
||||
light_ctrl = CORSAIR_V2_LIGHT_CTRL2;
|
||||
StartTransaction(0);
|
||||
}
|
||||
|
||||
StopTransaction(0);
|
||||
LOG_DEBUG("[%s] Lighting Endpoint set to %02X", device_name.c_str(), light_ctrl);
|
||||
}
|
||||
|
||||
CorsairPeripheralV2Controller::~CorsairPeripheralV2Controller()
|
||||
@@ -191,9 +294,9 @@ std::string CorsairPeripheralV2Controller::GetSerialString()
|
||||
|
||||
void CorsairPeripheralV2Controller::SetRenderMode(corsair_v2_device_mode mode)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
memset(buffer, 0, pkt_sze);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set Mode |
|
||||
@@ -203,19 +306,19 @@ void CorsairPeripheralV2Controller::SetRenderMode(corsair_v2_device_mode mode)
|
||||
buffer[3] = CORSAIR_V2_VALUE_MODE;
|
||||
buffer[5] = mode;
|
||||
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2Controller::LightingControl(uint8_t opt1)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
memset(buffer, 0, pkt_sze);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| The Corsair command is the same for each initialisation |
|
||||
@@ -227,11 +330,11 @@ void CorsairPeripheralV2Controller::LightingControl(uint8_t opt1)
|
||||
buffer[3] = opt1;
|
||||
buffer[5] = 0x00;
|
||||
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,18 +373,18 @@ unsigned int CorsairPeripheralV2Controller::GetAddressRetry(uint8_t address)
|
||||
|
||||
unsigned int CorsairPeripheralV2Controller::GetAddress(uint8_t address)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
uint8_t read[CORSAIR_V2_WRITE_SIZE];
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
uint8_t read[CORSAIR_V2_PACKET_SIZE];
|
||||
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
memset(read, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
memset(buffer, 0, pkt_sze);
|
||||
memset(read, 0, pkt_sze);
|
||||
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_GET;
|
||||
buffer[3] = address;
|
||||
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_read_timeout(dev, read, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
hid_read_timeout(dev, read, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
|
||||
unsigned int temp = (unsigned int)(read[6] << 24 | read[5] << 16 | read[4] << 8 | read[3]);
|
||||
LOG_DEBUG("[%s] GetAddress %02X - %02X %02X - %02X %02X %02X %02X %02X %02X %02X %02X", device_name.c_str(),
|
||||
@@ -299,20 +402,20 @@ unsigned int CorsairPeripheralV2Controller::GetAddress(uint8_t address)
|
||||
|
||||
unsigned char CorsairPeripheralV2Controller::StartTransaction(uint8_t opt1)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
memset(buffer, 0, pkt_sze);
|
||||
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_START_TX;
|
||||
buffer[3] = opt1;
|
||||
buffer[4] = light_ctrl;
|
||||
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
|
||||
return buffer[2];
|
||||
@@ -320,20 +423,20 @@ unsigned char CorsairPeripheralV2Controller::StartTransaction(uint8_t opt1)
|
||||
|
||||
void CorsairPeripheralV2Controller::StopTransaction(uint8_t opt1)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
memset(buffer, 0, pkt_sze);
|
||||
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_STOP_TX;
|
||||
buffer[3] = 0x01;
|
||||
buffer[4] = opt1;
|
||||
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,6 +450,11 @@ void CorsairPeripheralV2Controller::ClearPacketBuffer()
|
||||
uint8_t result = 0;
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Draining expects to find nothing, so the last read here |
|
||||
| always waits out the timeout. Keep it short: this runs |
|
||||
| before every LED update. |
|
||||
\*---------------------------------------------------------*/
|
||||
do
|
||||
{
|
||||
result = hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
|
||||
@@ -356,6 +464,8 @@ void CorsairPeripheralV2Controller::ClearPacketBuffer()
|
||||
|
||||
void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(device_mutex);
|
||||
|
||||
const uint8_t offset1 = 8;
|
||||
const uint8_t offset2 = 4;
|
||||
uint16_t remaining = data_size;
|
||||
@@ -389,7 +499,7 @@ void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
|
||||
remaining -= copy_bytes;
|
||||
@@ -414,7 +524,7 @@ void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
|
||||
remaining -= copy_bytes;
|
||||
@@ -426,6 +536,8 @@ void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
|
||||
void CorsairPeripheralV2Controller::UpdateHWMode(uint16_t mode, corsair_v2_color /*color_mode*/, uint8_t /*speed*/,
|
||||
uint8_t /*direction*/, uint8_t /*brightness*/, std::vector<RGBColor> /*colors*/)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(device_mutex);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| If we are switching to `Direct` mode |
|
||||
| set device in software mode |
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "LogManager.h"
|
||||
@@ -21,13 +22,33 @@
|
||||
#define NA 0xFFFFFFFF
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
#define CORSAIR_V2_TIMEOUT 50
|
||||
/*---------------------------------------------------------*\
|
||||
| A jumbo packet device answers a 1KB command in well over |
|
||||
| 50ms. Missing the reply leaves it queued and the next |
|
||||
| write to the device then fails outright, so this has to |
|
||||
| be generous. A reply that does arrive is returned as |
|
||||
| soon as it lands, so this only costs time on failure. |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CORSAIR_V2_TIMEOUT 500
|
||||
#define CORSAIR_V2_TIMEOUT_SHORT 3
|
||||
#define CORSAIR_V2_VALUE_MODE 3
|
||||
#define CORSAIR_V2_WRITE_WIRED_ID 8
|
||||
#define CORSAIR_V2_WRITE_WIRELESS_ID 9
|
||||
#define CORSAIR_V2_WRITE_SIZE 65
|
||||
#define CORSAIR_V2_PACKET_SIZE 1024
|
||||
/*---------------------------------------------------------*\
|
||||
| Largest packet the protocol uses: 1024 payload bytes |
|
||||
| plus the leading report ID. pkt_sze is measured |
|
||||
| against this, and every stack buffer handed to hidapi |
|
||||
| with pkt_sze is this size, so the two must agree. |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CORSAIR_V2_PACKET_SIZE 1025
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Error codes the device returns in byte 2 of a reply. |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CORSAIR_V2_ERR_INVALID 0x01
|
||||
#define CORSAIR_V2_ERR_FAILED 0x03
|
||||
#define CORSAIR_V2_ERR_NOT_SUPPORTED 0x06
|
||||
|
||||
#define CORSAIR_V2_LIGHT_CTRL1 1
|
||||
#define CORSAIR_V2_LIGHT_CTRL2 34 /* 0x22 */
|
||||
@@ -113,6 +134,27 @@ protected:
|
||||
std::string device_name;
|
||||
uint8_t light_ctrl = CORSAIR_V2_LIGHT_CTRL2;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Works out which lighting control endpoint the device |
|
||||
| accepts. Must be called only once the device has been |
|
||||
| put into software render mode: endpoint 2 rejects the |
|
||||
| transaction while the device is still driving its own |
|
||||
| lighting, which would pick endpoint 1 for a device that |
|
||||
| does not support it. |
|
||||
\*---------------------------------------------------------*/
|
||||
void DetectLightingEndpoint();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Size of one output report, plus the leading report ID. |
|
||||
| Read from the HID report descriptor before anything is |
|
||||
| sent: these devices come in a 64 byte and a 1024 byte |
|
||||
| flavour, and sending a short packet to a 1024 byte |
|
||||
| endpoint wedges it until the device is reset, so the |
|
||||
| size has to be known before the first write rather than |
|
||||
| inferred from a reply. Returns 0 if it cannot be read. |
|
||||
\*---------------------------------------------------------*/
|
||||
uint16_t GetOutputReportSize();
|
||||
|
||||
private:
|
||||
void ClearPacketBuffer();
|
||||
unsigned int GetAddress(uint8_t address);
|
||||
@@ -122,6 +164,16 @@ private:
|
||||
|
||||
hid_device* dev;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Serialises device transactions. |
|
||||
| The RGB controllers run a keepalive thread that writes |
|
||||
| LEDs independently of the caller, and a Corsair block |
|
||||
| write spans several packets. Letting two of those |
|
||||
| interleave on one HID handle corrupts the transaction |
|
||||
| and leaves the device unresponsive until it is reset. |
|
||||
\*---------------------------------------------------------*/
|
||||
std::mutex device_mutex;
|
||||
|
||||
uint8_t write_cmd = CORSAIR_V2_WRITE_WIRED_ID;
|
||||
uint16_t pkt_sze = CORSAIR_V2_WRITE_SIZE;
|
||||
bool skip_reads = false;
|
||||
|
||||
@@ -92,6 +92,7 @@ DetectedControllers DetectCorsairV2SoftwareControllers(hid_device_info* info, co
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K55 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K55_RGB_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K57 RGB (Wired)", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K57_RGB_WIRED_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO SE", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_SE_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO Low Profile", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_LP_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO TKL Black", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_TKL_B_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO TKL White", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_TKL_W_PID, 1, 0xFF42);
|
||||
|
||||
@@ -901,7 +901,7 @@ static const corsair_v2_device k57_rgb_wired_device =
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 6 Rows, 21 Columns |
|
||||
| 7 Rows, 22 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone k60_rgb_pro_zone =
|
||||
{
|
||||
@@ -928,12 +928,34 @@ static const corsair_v2_device k60_rgb_pro_device =
|
||||
&corsair_K60_layout
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Corsair K60 RGB Pro SE 1B1C:1B8D |
|
||||
| |
|
||||
| Initial implementation reuses K60 RGB Pro zone/layout |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_device k60_rgb_pro_se_device =
|
||||
{
|
||||
CORSAIR_K60_RGB_PRO_SE_PID,
|
||||
DEVICE_TYPE_KEYBOARD,
|
||||
6,
|
||||
21,
|
||||
{
|
||||
&k60_rgb_pro_zone,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
},
|
||||
&corsair_K60_layout
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Corsair K60 RGB Pro Low Profile 1B1C:1BAD |
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 6 Rows, 21 Columns |
|
||||
| 7 Rows, 22 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone k60_rgb_pro_lp_zone =
|
||||
{
|
||||
@@ -966,7 +988,7 @@ static const corsair_v2_device k60_rgb_pro_lp_device =
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 6 Rows, 21 Columns |
|
||||
| 7 Rows, 22 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone k60_rgb_pro_tkl_zone =
|
||||
{
|
||||
@@ -1016,7 +1038,7 @@ static const corsair_v2_device k60_rgb_pro_tkl_device_w =
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 6 Rows, 21 Columns |
|
||||
| 7 Rows, 22 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone k70_core_rgb_zone =
|
||||
{
|
||||
@@ -1145,14 +1167,14 @@ static const corsair_v2_device k70_rgb_tkl_cs_device =
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 6 Rows, 21 Columns |
|
||||
| 7 Rows, 22 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone k70_rgb_pro_zone =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
ZONE_TYPE_MATRIX,
|
||||
7,
|
||||
21
|
||||
22
|
||||
};
|
||||
|
||||
static const corsair_v2_device k70_rgb_pro_device =
|
||||
@@ -1160,7 +1182,7 @@ static const corsair_v2_device k70_rgb_pro_device =
|
||||
CORSAIR_K70_RGB_PRO_PID,
|
||||
DEVICE_TYPE_KEYBOARD,
|
||||
7,
|
||||
21,
|
||||
22,
|
||||
{
|
||||
&k70_rgb_pro_zone,
|
||||
nullptr,
|
||||
@@ -1177,14 +1199,14 @@ static const corsair_v2_device k70_rgb_pro_device =
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 6 Rows, 21 Columns |
|
||||
| 7 Rows, 22 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_device k70_rgb_pro_v2_device =
|
||||
{
|
||||
CORSAIR_K70_RGB_PRO_V2_PID,
|
||||
DEVICE_TYPE_KEYBOARD,
|
||||
7,
|
||||
21,
|
||||
22,
|
||||
{
|
||||
&k70_rgb_pro_zone,
|
||||
nullptr,
|
||||
@@ -1193,7 +1215,8 @@ static const corsair_v2_device k70_rgb_pro_v2_device =
|
||||
nullptr,
|
||||
nullptr
|
||||
},
|
||||
&corsair_k70_pro_layout
|
||||
&corsair_k70_pro_layout,
|
||||
193
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
@@ -1625,6 +1648,7 @@ const corsair_v2_device* corsair_v2_device_list_data[] =
|
||||
&k55_rgb_pro_device,
|
||||
&k57_rgb_wired_device,
|
||||
&k60_rgb_pro_device,
|
||||
&k60_rgb_pro_se_device,
|
||||
&k60_rgb_pro_lp_device,
|
||||
&k60_rgb_pro_tkl_device_b,
|
||||
&k60_rgb_pro_tkl_device_w,
|
||||
|
||||
@@ -63,6 +63,15 @@ typedef struct
|
||||
uint8_t cols;
|
||||
const corsair_v2_zone* zones[CORSAIR_ZONES_MAX];
|
||||
keyboard_keymap_overlay_values* layout_new;
|
||||
/*-------------------------------------------------------*\
|
||||
| Number of LED slots the device expects in a direct |
|
||||
| lighting write. The keymap only covers the keys that |
|
||||
| exist, but the device wants its full slot count and |
|
||||
| ignores a short write, so the buffer map is padded up |
|
||||
| to this. Left 0 where the count is not known, which |
|
||||
| keeps the keymap derived size. |
|
||||
\*-------------------------------------------------------*/
|
||||
uint16_t hw_led_count;
|
||||
} corsair_v2_device;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
@@ -72,6 +81,7 @@ typedef struct
|
||||
#define CORSAIR_K57_RGB_WIRED_PID 0x1B6E
|
||||
#define CORSAIR_K57_RGB_WIRELESS_PID 0x1B62
|
||||
#define CORSAIR_K60_RGB_PRO_PID 0x1BA0
|
||||
#define CORSAIR_K60_RGB_PRO_SE_PID 0x1B8D
|
||||
#define CORSAIR_K60_RGB_PRO_LP_PID 0x1BAD
|
||||
#define CORSAIR_K60_RGB_PRO_TKL_B_PID 0x1BC7
|
||||
#define CORSAIR_K60_RGB_PRO_TKL_W_PID 0x1BED
|
||||
|
||||
@@ -16,6 +16,12 @@ CorsairPeripheralV2HWController::CorsairPeripheralV2HWController(hid_device* dev
|
||||
{
|
||||
SetRenderMode(CORSAIR_V2_MODE_SW);
|
||||
LightingControl(0x5F);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Only now that the device is in software render mode can |
|
||||
| its lighting control endpoint be probed reliably. |
|
||||
\*---------------------------------------------------------*/
|
||||
DetectLightingEndpoint();
|
||||
}
|
||||
|
||||
CorsairPeripheralV2HWController::~CorsairPeripheralV2HWController()
|
||||
|
||||
@@ -16,6 +16,12 @@ CorsairPeripheralV2SWController::CorsairPeripheralV2SWController(hid_device* dev
|
||||
{
|
||||
SetRenderMode(CORSAIR_V2_MODE_SW);
|
||||
LightingControl(0x5F);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Only now that the device is in software render mode can |
|
||||
| its lighting control endpoint be probed reliably. |
|
||||
\*---------------------------------------------------------*/
|
||||
DetectLightingEndpoint();
|
||||
}
|
||||
|
||||
CorsairPeripheralV2SWController::~CorsairPeripheralV2SWController()
|
||||
|
||||
@@ -66,21 +66,32 @@ RGBController_CorsairV2HW::RGBController_CorsairV2HW(CorsairPeripheralV2Controll
|
||||
| to not revert back into rainbow mode. Start a thread |
|
||||
| to continuously send a keepalive packet every 50 sec |
|
||||
\*-----------------------------------------------------*/
|
||||
/*-----------------------------------------------------*\
|
||||
| Start the keepalive clock before the thread runs. |
|
||||
| A default constructed time_point sits at the clock |
|
||||
| epoch, which is always older than the update |
|
||||
| period, so the thread would otherwise fire a write |
|
||||
| on its first pass - during detection, racing |
|
||||
| whatever the caller is doing. |
|
||||
\*-----------------------------------------------------*/
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
|
||||
keepalive_thread_run = true;
|
||||
keepalive_thread = new std::thread(&RGBController_CorsairV2HW::KeepaliveThread, this);
|
||||
}
|
||||
|
||||
RGBController_CorsairV2HW::~RGBController_CorsairV2HW()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Close keepalive thread |
|
||||
| Close keepalive thread first, so that it cannot issue |
|
||||
| a write while the device is being shut down. |
|
||||
\*-----------------------------------------------------*/
|
||||
keepalive_thread_run = false;
|
||||
keepalive_thread->join();
|
||||
delete keepalive_thread;
|
||||
|
||||
Shutdown();
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
@@ -198,6 +209,15 @@ void RGBController_CorsairV2HW::SetupZones()
|
||||
|
||||
SetupColors();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Pad out to the slot count the device expects. A write |
|
||||
| that is short of it is ignored by the hardware. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(corsair->hw_led_count > max_led_value)
|
||||
{
|
||||
max_led_value = corsair->hw_led_count;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create a buffer map of pointers which contains the |
|
||||
| layout order of colors the device expects. |
|
||||
|
||||
@@ -53,21 +53,32 @@ RGBController_CorsairV2SW::RGBController_CorsairV2SW(CorsairPeripheralV2Controll
|
||||
| to not revert back into rainbow mode. Start a thread |
|
||||
| to continuously send a keepalive packet every 50 sec |
|
||||
\*-----------------------------------------------------*/
|
||||
/*-----------------------------------------------------*\
|
||||
| Start the keepalive clock before the thread runs. |
|
||||
| A default constructed time_point sits at the clock |
|
||||
| epoch, which is always older than the update |
|
||||
| period, so the thread would otherwise fire a write |
|
||||
| on its first pass - during detection, racing |
|
||||
| whatever the caller is doing. |
|
||||
\*-----------------------------------------------------*/
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
|
||||
keepalive_thread_run = true;
|
||||
keepalive_thread = new std::thread(&RGBController_CorsairV2SW::KeepaliveThread, this);
|
||||
}
|
||||
|
||||
RGBController_CorsairV2SW::~RGBController_CorsairV2SW()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Close keepalive thread |
|
||||
| Close keepalive thread first, so that it cannot issue |
|
||||
| a write while the device is being shut down. |
|
||||
\*-----------------------------------------------------*/
|
||||
keepalive_thread_run = false;
|
||||
keepalive_thread->join();
|
||||
delete keepalive_thread;
|
||||
|
||||
Shutdown();
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
@@ -185,6 +196,15 @@ void RGBController_CorsairV2SW::SetupZones()
|
||||
|
||||
SetupColors();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Pad out to the slot count the device expects. A write |
|
||||
| that is short of it is ignored by the hardware. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(corsair->hw_led_count > max_led_value)
|
||||
{
|
||||
max_led_value = corsair->hw_led_count;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create a buffer map of pointers which contains the |
|
||||
| layout order of colors the device expects. |
|
||||
|
||||
+2
-1
@@ -144,7 +144,8 @@ REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 GAMING OC",
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Geforce RTX 4070 Aero OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070_AERO_OC_12G_SUB_DEV, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 SUPER GAMING OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070S_GAMING_OC_12G, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 SUPER Aero OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070S_AERO_OC_12G, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 SUPER Eagle OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070S_EAGLE_OC_ICE_12G, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 SUPER Eagle OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070S_EAGLE_OC_12G, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 SUPER Eagle OC ICE", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070S_EAGLE_OC_ICE_12G, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 Ti GAMING", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070TI_GAMING_12G, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 Ti GAMING OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070TI_GAMING_OC_12G, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 Ti GAMING OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070TI_GAMING_OC_12G_SUB_DEV2, 0x71);
|
||||
|
||||
+8
-7
@@ -7559,7 +7559,8 @@ void LogitechHIDPP20Controller::ReadActiveProfileSector()
|
||||
}
|
||||
|
||||
constexpr uint16_t SECTOR_SIZE = 0x63; // 99 bytes
|
||||
constexpr uint16_t PAGE_SIZE = 16;
|
||||
constexpr uint16_t SIZE_OF_PAGE = 16;
|
||||
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Step 1: load the sector into the device's read buffer |
|
||||
@@ -7585,7 +7586,7 @@ void LogitechHIDPP20Controller::ReadActiveProfileSector()
|
||||
\*-----------------------------------------------------*/
|
||||
uint8_t sector_buf[SECTOR_SIZE] = {};
|
||||
|
||||
for(uint16_t offset = 0; offset < SECTOR_SIZE; offset += PAGE_SIZE)
|
||||
for(uint16_t offset = 0; offset < SECTOR_SIZE; offset += SIZE_OF_PAGE)
|
||||
{
|
||||
uint8_t read_req[3] = {
|
||||
(uint8_t)((offset >> 8) & 0xFF),
|
||||
@@ -7605,9 +7606,9 @@ void LogitechHIDPP20Controller::ReadActiveProfileSector()
|
||||
return;
|
||||
}
|
||||
|
||||
size_t copy_len = (offset + PAGE_SIZE > SECTOR_SIZE)
|
||||
size_t copy_len = (offset + SIZE_OF_PAGE > SECTOR_SIZE)
|
||||
? (size_t)(SECTOR_SIZE - offset)
|
||||
: PAGE_SIZE;
|
||||
: SIZE_OF_PAGE;
|
||||
memcpy(sector_buf + offset, page_resp, copy_len);
|
||||
}
|
||||
|
||||
@@ -7617,11 +7618,11 @@ void LogitechHIDPP20Controller::ReadActiveProfileSector()
|
||||
LOG_DEBUG("%s ProfileSector partition=NVS sector=1 size=%u bytes:",
|
||||
LOG_TAG, (unsigned)SECTOR_SIZE);
|
||||
|
||||
for(uint16_t row = 0; row < SECTOR_SIZE; row += PAGE_SIZE)
|
||||
for(uint16_t row = 0; row < SECTOR_SIZE; row += SIZE_OF_PAGE)
|
||||
{
|
||||
size_t row_len = (row + PAGE_SIZE > SECTOR_SIZE)
|
||||
size_t row_len = (row + SIZE_OF_PAGE > SECTOR_SIZE)
|
||||
? (size_t)(SECTOR_SIZE - row)
|
||||
: PAGE_SIZE;
|
||||
: SIZE_OF_PAGE;
|
||||
|
||||
char hex[64] = {};
|
||||
char* p = hex;
|
||||
|
||||
+22
-22
@@ -423,37 +423,37 @@ MSIMotherboard185Controller::MSIMotherboard185Controller(hid_device* handle, con
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| If the firmware version is below the minimum, set |
|
||||
| invalid version flag and return |
|
||||
\*-----------------------------------------------------*/
|
||||
if(version_APROM_val < board_config->minimum_firmware_version)
|
||||
{
|
||||
version_invalid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in the number of each zone type based on the |
|
||||
| board configuration |
|
||||
\*-----------------------------------------------------*/
|
||||
if(board_config != nullptr)
|
||||
{
|
||||
numof_onboard_leds = board_config->numof_onboard_leds;
|
||||
numof_pipe1_leds = board_config->numof_pipe1_leds;
|
||||
numof_pipe2_leds = board_config->numof_pipe2_leds;
|
||||
numof_JRGBs = board_config->numof_JRGBs;
|
||||
supported_zones = board_config->supported_zones;
|
||||
per_led_mode = board_config->per_led_mode;
|
||||
/*-------------------------------------------------*\
|
||||
| If the firmware version is below the minimum, set |
|
||||
| invalid version flag and return |
|
||||
\*-------------------------------------------------*/
|
||||
if(version_APROM_val < board_config->minimum_firmware_version)
|
||||
{
|
||||
version_invalid = true;
|
||||
return;
|
||||
}
|
||||
|
||||
numof_onboard_leds = board_config->numof_onboard_leds;
|
||||
numof_pipe1_leds = board_config->numof_pipe1_leds;
|
||||
numof_pipe2_leds = board_config->numof_pipe2_leds;
|
||||
numof_JRGBs = board_config->numof_JRGBs;
|
||||
supported_zones = board_config->supported_zones;
|
||||
per_led_mode = board_config->per_led_mode;
|
||||
}
|
||||
else
|
||||
{
|
||||
numof_onboard_leds = 6;
|
||||
numof_pipe1_leds = 1;
|
||||
numof_pipe2_leds = 1;
|
||||
numof_JRGBs = 2;
|
||||
supported_zones = &all_zones;
|
||||
per_led_mode = DIRECT_MODE_DISABLED;
|
||||
numof_onboard_leds = 6;
|
||||
numof_pipe1_leds = 1;
|
||||
numof_pipe2_leds = 1;
|
||||
numof_JRGBs = 2;
|
||||
supported_zones = &all_zones;
|
||||
per_led_mode = DIRECT_MODE_DISABLED;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
|
||||
+5
-1
@@ -78,7 +78,9 @@ static const std::string board_names[] =
|
||||
"MSI MAG X870E TOMAHAWK MAX WIFI PZ (MS-7E84)",
|
||||
"MSI PRO B850M-A WIFI PZ (MS-7E78)",
|
||||
"MSI B850MPOWER (MS-7E83)",
|
||||
"MSI B840M GAMING WIFI6E (MS-7E76)"
|
||||
"MSI B840M GAMING WIFI6E (MS-7E76)",
|
||||
"MSI PRO B850M-A WIFI (MS-7E66)",
|
||||
"MSI PRO B850-S WIFI6E (MS-7E80)"
|
||||
};
|
||||
|
||||
static const mystic_light_761_config board_configs[] =
|
||||
@@ -115,6 +117,8 @@ static const mystic_light_761_config board_configs[] =
|
||||
{ &(board_names[29]), 0, 0, 0, 1, &zone_set1, MSIMotherboard761Controller::DIRECT_MODE_ZONE_BASED }, // MSI PRO B850M-A WIFI PZ (MS-7E78)
|
||||
{ &(board_names[30]), 0, 0, 0, 1, &zone_set1, MSIMotherboard761Controller::DIRECT_MODE_ZONE_BASED }, // MSI B850MPOWER (MS-7E83)
|
||||
{ &(board_names[31]), 0, 0, 0, 1, &zone_set1, MSIMotherboard761Controller::DIRECT_MODE_ZONE_BASED }, // MSI B840M GAMING WIFI6E (MS-7E76)
|
||||
{ &(board_names[32]), 0, 0, 0, 1, &zone_set1, MSIMotherboard761Controller::DIRECT_MODE_ZONE_BASED }, // MSI PRO B850M-A WIFI (MS-7E66)
|
||||
{ &(board_names[33]), 0, 0, 0, 1, &zone_set1, MSIMotherboard761Controller::DIRECT_MODE_ZONE_BASED }, // MSI PRO B850-S WIFI6E (MS-7E80)
|
||||
};
|
||||
|
||||
enum MSI_ZONE setup_map [] =
|
||||
|
||||
@@ -236,6 +236,7 @@ REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7E34", DetectMSIMotherboardCont
|
||||
REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7E32", DetectMSIMotherboardControllers, MSI_USB_VID, 0x7E32, 0x0001, 0x00);
|
||||
REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7E20", DetectMSIMotherboardControllers, MSI_USB_VID, 0x7E20, 0x0001, 0x00);
|
||||
REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7E76", DetectMSIMotherboardControllers, MSI_USB_VID, 0x7E76, 0x0001, 0x00);
|
||||
REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7E66", DetectMSIMotherboardControllers, MSI_USB_VID, 0x7E66, 0x0001, 0x00);
|
||||
// Detector for the set of common boards
|
||||
REGISTER_HID_DETECTOR_PU("MSI Mystic Light Common", DetectMSIMotherboardControllers, MSI_USB_VID_COMMON, MSI_USB_PID_COMMON, 0x0001, 0x00);
|
||||
REGISTER_HID_DETECTOR_PU("MSI Mystic Light X870", DetectMSIMotherboardControllers, MSI_USB_VID_COMMON, MSI_USB_PID_COMMON, 0xFF00, 0x01);
|
||||
|
||||
@@ -47,9 +47,10 @@ DetectedControllers DetectPNYARGBEpicXGPULargeControllers(i2c_smbus_interface* b
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_I2C_PCI_DETECTOR("PNY GeForce RTX 5060Ti ARGB Epic-X OC", DetectPNYARGBEpicXGPUSmallControllers, NVIDIA_VEN, NVIDIA_RTX5060TI_DEV, PNY_SUB_VEN, PNY_RTX_5060TI_ARGB_EPIC_X_OC_SUB_DEV, 0x60);
|
||||
REGISTER_I2C_PCI_DETECTOR("PNY GeForce RTX 5070 ARGB Epic-X OC", DetectPNYARGBEpicXGPUSmallControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, PNY_SUB_VEN, PNY_RTX_5070_ARGB_EPIC_X_OC_SUB_DEV, 0x60);
|
||||
REGISTER_I2C_PCI_DETECTOR("PNY GeForce RTX 5070Ti ARGB Epic-X", DetectPNYARGBEpicXGPUSmallControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, PNY_SUB_VEN, PNY_RTX_5070TI_ARGB_EPIC_X_SUB_DEV, 0x60);
|
||||
REGISTER_I2C_PCI_DETECTOR("PNY GeForce RTX 5070Ti ARGB Epic-X OC", DetectPNYARGBEpicXGPUSmallControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, PNY_SUB_VEN, PNY_RTX_5070TI_ARGB_EPIC_X_OC_SUB_DEV, 0x60);
|
||||
REGISTER_I2C_PCI_DETECTOR("PNY GeForce RTX 5080 ARGB Epic-X OC", DetectPNYARGBEpicXGPULargeControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, PNY_SUB_VEN, PNY_RTX_5080_ARGB_EPIC_X_OC_SUB_DEV, 0x60);
|
||||
REGISTER_I2C_PCI_DETECTOR("PNY GeForce RTX 5090 ARGB Epic-X OC", DetectPNYARGBEpicXGPULargeControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, PNY_SUB_VEN, PNY_RTX_5090_ARGB_EPIC_X_OC_SUB_DEV, 0x60);
|
||||
REGISTER_I2C_PCI_DETECTOR("PNY GeForce RTX 5060Ti ARGB Epic-X OC", DetectPNYARGBEpicXGPUSmallControllers, NVIDIA_VEN, NVIDIA_RTX5060TI_DEV, PNY_SUB_VEN, PNY_RTX_5060TI_ARGB_EPIC_X_OC_SUB_DEV, 0x60);
|
||||
REGISTER_I2C_PCI_DETECTOR("PNY GeForce RTX 5070 ARGB Epic-X OC", DetectPNYARGBEpicXGPUSmallControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, PNY_SUB_VEN, PNY_RTX_5070_ARGB_EPIC_X_OC_SUB_DEV, 0x60);
|
||||
REGISTER_I2C_PCI_DETECTOR("PNY GeForce RTX 5070Ti ARGB Epic-X", DetectPNYARGBEpicXGPUSmallControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, PNY_SUB_VEN, PNY_RTX_5070TI_ARGB_EPIC_X_SUB_DEV, 0x60);
|
||||
REGISTER_I2C_PCI_DETECTOR("PNY GeForce RTX 5070Ti ARGB Epic-X OC", DetectPNYARGBEpicXGPUSmallControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, PNY_SUB_VEN, PNY_RTX_5070TI_ARGB_EPIC_X_OC_SUB_DEV, 0x60);
|
||||
REGISTER_I2C_PCI_DETECTOR("PNY GeForce RTX 5070Ti ARGB Epic-X OC", DetectPNYARGBEpicXGPUSmallControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, PNY_SUB_VEN, PNY_RTX_5070TI_ARGB_EPIC_X_OC_SUB_DEV2, 0x60);
|
||||
REGISTER_I2C_PCI_DETECTOR("PNY GeForce RTX 5080 ARGB Epic-X OC", DetectPNYARGBEpicXGPULargeControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, PNY_SUB_VEN, PNY_RTX_5080_ARGB_EPIC_X_OC_SUB_DEV, 0x60);
|
||||
REGISTER_I2C_PCI_DETECTOR("PNY GeForce RTX 5090 ARGB Epic-X OC", DetectPNYARGBEpicXGPULargeControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, PNY_SUB_VEN, PNY_RTX_5090_ARGB_EPIC_X_OC_SUB_DEV, 0x60);
|
||||
|
||||
@@ -26,11 +26,43 @@ bool TestForPalitGPUv1Controller(i2c_smbus_interface* bus, uint8_t i2c_addr)
|
||||
{
|
||||
bool pass = false;
|
||||
|
||||
switch(i2c_addr)
|
||||
if(bus->info.port_id == 1)
|
||||
{
|
||||
case 0x08:
|
||||
pass = bus->i2c_smbus_write_quick(i2c_addr, I2C_SMBUS_WRITE);
|
||||
break;
|
||||
/*-------------------------------------------------*\
|
||||
| Check for PALIT string, which is known to work |
|
||||
| for Palit variants |
|
||||
\*-------------------------------------------------*/
|
||||
const uint8_t palit[] = {'P', 'A', 'L', 'I', 'T'};
|
||||
bool match = true;
|
||||
|
||||
for(size_t i = 0; i < sizeof(palit); i++)
|
||||
{
|
||||
int32_t letter = bus->i2c_smbus_read_byte_data(i2c_addr, 0x07 + (u8)i);
|
||||
|
||||
if(palit[i] != letter)
|
||||
{
|
||||
match = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| If PALIT string fails, try a quick write to the |
|
||||
| target address, which is known to work for |
|
||||
| Gainward variants |
|
||||
\*-------------------------------------------------*/
|
||||
if(match)
|
||||
{
|
||||
pass = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(i2c_addr)
|
||||
{
|
||||
case 0x08:
|
||||
pass = bus->i2c_smbus_write_quick(i2c_addr, I2C_SMBUS_WRITE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(pass);
|
||||
@@ -40,13 +72,16 @@ bool TestForPalitGPUv2Controller(i2c_smbus_interface* bus, uint8_t i2c_addr)
|
||||
{
|
||||
bool pass = false;
|
||||
|
||||
switch(i2c_addr)
|
||||
if(bus->info.port_id == 1)
|
||||
{
|
||||
case 0x49:
|
||||
s32 data = bus->i2c_smbus_read_byte_data(i2c_addr, 0x0);
|
||||
s32 mode_data = bus->i2c_smbus_read_byte_data(i2c_addr, 0xe0);
|
||||
pass = (data == 0x0) && (mode_data < 0x5);
|
||||
break;
|
||||
switch(i2c_addr)
|
||||
{
|
||||
case 0x49:
|
||||
s32 data = bus->i2c_smbus_read_byte_data(i2c_addr, 0x0);
|
||||
s32 mode_data = bus->i2c_smbus_read_byte_data(i2c_addr, 0xe0);
|
||||
pass = (data == 0x0) && (mode_data < 0x5);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(pass);
|
||||
|
||||
@@ -127,6 +127,8 @@ RazerController::RazerController(hid_device* dev_handle, hid_device* dev_argb_ha
|
||||
case RAZER_NAGA_LEFT_HANDED_PID:
|
||||
case RAZER_NAGA_PRO_V2_WIRED_PID:
|
||||
case RAZER_NAGA_PRO_V2_WIRELESS_PID:
|
||||
case RAZER_NAGA_PRO_V3_WIRED_PID:
|
||||
case RAZER_NAGA_PRO_V3_WIRELESS_PID:
|
||||
case RAZER_O11_DYNAMIC_PID:
|
||||
case RAZER_STRIDER_CHROMA_PID:
|
||||
case RAZER_TARTARUS_PRO_PID:
|
||||
|
||||
@@ -366,6 +366,8 @@ REGISTER_HID_DETECTOR_IPU("Razer Naga Pro (Wired)", Det
|
||||
REGISTER_HID_DETECTOR_IPU("Razer Naga Pro (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_NAGA_PRO_WIRELESS_PID, 0x00, 0x01, 0x02);
|
||||
REGISTER_HID_DETECTOR_IPU("Razer Naga Pro V2 (Wired)", DetectRazerControllers, RAZER_VID, RAZER_NAGA_PRO_V2_WIRED_PID, 0x00, 0x01, 0x02);
|
||||
REGISTER_HID_DETECTOR_IPU("Razer Naga Pro V2 (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_NAGA_PRO_V2_WIRELESS_PID, 0x00, 0x01, 0x02);
|
||||
REGISTER_HID_DETECTOR_PU("Razer Naga Pro V3 (Wired)", DetectRazerControllers, RAZER_VID, RAZER_NAGA_PRO_V3_WIRED_PID, 0x01, 0x03);
|
||||
REGISTER_HID_DETECTOR_PU("Razer Naga Pro V3 (Wireless)", DetectRazerControllers, RAZER_VID, RAZER_NAGA_PRO_V3_WIRELESS_PID, 0x01, 0x03);
|
||||
REGISTER_HID_DETECTOR_IPU("Razer Viper", DetectRazerControllers, RAZER_VID, RAZER_VIPER_PID, 0x00, 0x01, 0x02);
|
||||
REGISTER_HID_DETECTOR_IPU("Razer Viper 8kHz", DetectRazerControllers, RAZER_VID, RAZER_VIPER_8KHZ_PID, 0x00, 0x01, 0x02);
|
||||
REGISTER_HID_DETECTOR_IPU("Razer Viper Mini", DetectRazerControllers, RAZER_VID, RAZER_VIPER_MINI_PID, 0x00, 0x01, 0x02);
|
||||
|
||||
@@ -7222,6 +7222,81 @@ static const razer_device naga_pro_v2_wireless_device =
|
||||
NULL
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Razer Naga Pro V3 1532:00E7 (wired) 1532:00E8 (wireless) |
|
||||
| |
|
||||
| Zone "Logo" |
|
||||
| Single |
|
||||
| 1 LED |
|
||||
| |
|
||||
| Zone "Numpad" |
|
||||
| Single |
|
||||
| 1 LED |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const razer_zone naga_pro_v3_scroll_wheel_zone =
|
||||
{
|
||||
"Scroll Wheel",
|
||||
ZONE_TYPE_SINGLE,
|
||||
1,
|
||||
1
|
||||
};
|
||||
|
||||
static const razer_zone naga_pro_v3_logo_zone =
|
||||
{
|
||||
"Logo",
|
||||
ZONE_TYPE_SINGLE,
|
||||
1,
|
||||
1
|
||||
};
|
||||
|
||||
static const razer_zone naga_pro_v3_numpad_zone =
|
||||
{
|
||||
"Numpad",
|
||||
ZONE_TYPE_SINGLE,
|
||||
1,
|
||||
1
|
||||
};
|
||||
|
||||
static const razer_device naga_pro_v3_wired_device =
|
||||
{
|
||||
"Razer Naga Pro V3 (Wired)",
|
||||
RAZER_NAGA_PRO_V3_WIRED_PID,
|
||||
DEVICE_TYPE_MOUSE,
|
||||
RAZER_MATRIX_TYPE_EXTENDED,
|
||||
0x1F,
|
||||
1,
|
||||
3,
|
||||
{
|
||||
&naga_pro_v3_logo_zone,
|
||||
&naga_pro_v3_scroll_wheel_zone,
|
||||
&naga_pro_v3_numpad_zone,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
NULL
|
||||
};
|
||||
|
||||
static const razer_device naga_pro_v3_wireless_device =
|
||||
{
|
||||
"Razer Naga Pro V3 (Wireless)",
|
||||
RAZER_NAGA_PRO_V3_WIRELESS_PID,
|
||||
DEVICE_TYPE_MOUSE,
|
||||
RAZER_MATRIX_TYPE_EXTENDED,
|
||||
0x1F,
|
||||
1,
|
||||
3,
|
||||
{
|
||||
&naga_pro_v3_logo_zone,
|
||||
&naga_pro_v3_scroll_wheel_zone,
|
||||
&naga_pro_v3_numpad_zone,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
},
|
||||
NULL
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Razer Viper 8kHz 1532:0091 |
|
||||
| |
|
||||
@@ -9590,6 +9665,8 @@ const razer_device* razer_device_list[] =
|
||||
&naga_pro_wireless_device,
|
||||
&naga_pro_v2_wired_device,
|
||||
&naga_pro_v2_wireless_device,
|
||||
&naga_pro_v3_wired_device,
|
||||
&naga_pro_v3_wireless_device,
|
||||
&viper_8khz_device,
|
||||
&viper_mini_device,
|
||||
&viper_ultimate_wired_device,
|
||||
|
||||
@@ -213,6 +213,8 @@
|
||||
#define RAZER_NAGA_PRO_WIRELESS_PID 0x0090
|
||||
#define RAZER_NAGA_PRO_V2_WIRED_PID 0x00A7
|
||||
#define RAZER_NAGA_PRO_V2_WIRELESS_PID 0x00A8
|
||||
#define RAZER_NAGA_PRO_V3_WIRED_PID 0x00E7
|
||||
#define RAZER_NAGA_PRO_V3_WIRELESS_PID 0x00E8
|
||||
#define RAZER_OROCHI_2011_PID 0x0013
|
||||
#define RAZER_OROCHI_2013_PID 0x0039
|
||||
#define RAZER_OROCHI_CHROMA_PID 0x0048
|
||||
|
||||
+5
-4
@@ -3793,19 +3793,20 @@ void NetworkServer::SendReply_ServerString(NetworkClientInfo* client_info)
|
||||
|
||||
void NetworkServer::SendReply_PluginList(NetworkClientInfo* client_info)
|
||||
{
|
||||
unsigned int data_size = 0;
|
||||
unsigned int data_ptr = 0;
|
||||
unsigned int data_ptr = 0;
|
||||
unsigned int data_size = 0;
|
||||
unsigned short num_plugins = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Calculate data size |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned short num_plugins = (unsigned short)plugin_manager->GetPluginCount();
|
||||
|
||||
data_size += sizeof(data_size);
|
||||
data_size += sizeof(num_plugins);
|
||||
|
||||
if(plugin_manager)
|
||||
{
|
||||
num_plugins = (unsigned short)plugin_manager->GetPluginCount();
|
||||
|
||||
for(unsigned int i = 0; i < num_plugins; i++)
|
||||
{
|
||||
data_size += sizeof(unsigned short) * 3;
|
||||
|
||||
+38
-5
@@ -163,6 +163,21 @@ ProfileManager::~ProfileManager()
|
||||
|
||||
}
|
||||
|
||||
void ProfileManager::ApplyActiveProfilePluginData()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| The server only sends profile data to the clients |
|
||||
| connected at the time it loads, and plugins only |
|
||||
| exist in the GUI, so read it back here |
|
||||
\*-----------------------------------------------------*/
|
||||
if(!active_profile.empty() && ResourceManager::get()->IsLocalClient() && (ResourceManager::get()->GetLocalClient()->GetSupportsProfileManagerAPI()))
|
||||
{
|
||||
LOG_DEBUG("[%s] Reading active profile for plugin data: %s", PROFILEMANAGER, active_profile.c_str());
|
||||
|
||||
OnProfileLoaded(ResourceManager::get()->GetLocalClient()->ProfileManager_DownloadProfile(active_profile));
|
||||
}
|
||||
}
|
||||
|
||||
void ProfileManager::ClearActiveProfile()
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
@@ -903,6 +918,8 @@ bool ProfileManager::SaveConfiguration()
|
||||
\*-----------------------------------------------------*/
|
||||
std::vector<RGBController *> controllers = ResourceManager::get()->GetRGBControllers();
|
||||
|
||||
configuration_save_mutex.lock();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Open an output file in the profile directory |
|
||||
\*-----------------------------------------------------*/
|
||||
@@ -1005,6 +1022,8 @@ bool ProfileManager::SaveConfiguration()
|
||||
\*-----------------------------------------------------*/
|
||||
controller_file.close();
|
||||
|
||||
configuration_save_mutex.unlock();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Reinitialize manually configured controllers list |
|
||||
\*-----------------------------------------------------*/
|
||||
@@ -1274,6 +1293,8 @@ bool ProfileManager::LoadAutoProfile(std::string setting_name)
|
||||
\*-----------------------------------------------------*/
|
||||
if(!profile_name.empty())
|
||||
{
|
||||
LOG_INFO("[%s] Loading %s: %s", PROFILEMANAGER, setting_name.c_str(), profile_name.c_str());
|
||||
|
||||
return(LoadProfile(profile_name));
|
||||
}
|
||||
else
|
||||
@@ -1548,6 +1569,23 @@ bool ProfileManager::LoadProfileWithOptions
|
||||
bool load_state
|
||||
)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Get JSON data for given profile name |
|
||||
\*-------------------------------------------------*/
|
||||
nlohmann::json profile_json = ReadProfileJSON(profile_name);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Stop here if the profile could not be read. |
|
||||
| Carrying on would clear the active profile and |
|
||||
| send an empty profile to connected clients. |
|
||||
\*-------------------------------------------------*/
|
||||
if(profile_json.empty())
|
||||
{
|
||||
LOG_WARNING("[%s] Profile not found or empty, nothing to load: %s", PROFILEMANAGER, profile_name.c_str());
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Clear stored active profile data |
|
||||
\*-------------------------------------------------*/
|
||||
@@ -1562,11 +1600,6 @@ bool ProfileManager::LoadProfileWithOptions
|
||||
delete active_rgb_controllers_copy[controller_idx];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Get JSON data for given profile name |
|
||||
\*-------------------------------------------------*/
|
||||
nlohmann::json profile_json = ReadProfileJSON(profile_name);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Load the controller state data for this profile |
|
||||
| into the active profile data |
|
||||
|
||||
@@ -78,6 +78,8 @@ public:
|
||||
ProfileManager(const filesystem::path& config_dir);
|
||||
~ProfileManager();
|
||||
|
||||
void ApplyActiveProfilePluginData();
|
||||
|
||||
void ClearActiveProfile();
|
||||
|
||||
void DeleteProfile(std::string profile_name);
|
||||
@@ -156,6 +158,8 @@ private:
|
||||
filesystem::path configuration_directory;
|
||||
filesystem::path profile_directory;
|
||||
|
||||
std::mutex configuration_save_mutex;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| ProfileManager Callbacks |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
@@ -280,6 +280,12 @@ ResourceManager::ResourceManager()
|
||||
logmanager_settings_schema["file_count_limit"]["default"] = 10;
|
||||
logmanager_settings_schema["file_count_limit"]["minimum"] = 0;
|
||||
|
||||
logmanager_settings_schema["dialog_no_show_hashes"]["title"] = QT_TRANSLATE_NOOP("Settings", "Dialog No-Show Hashes");
|
||||
logmanager_settings_schema["dialog_no_show_hashes"]["type"] = "array";
|
||||
logmanager_settings_schema["dialog_no_show_hashes"]["description"] = QT_TRANSLATE_NOOP("Settings", "A list of hashes of dialog text that should not be shown. Selecting \"Do Not Show Again\" on a dialog adds it to this list.");
|
||||
logmanager_settings_schema["dialog_no_show_hashes"]["items"]["type"] = "integer";
|
||||
logmanager_settings_schema["dialog_no_show_hashes"]["visible"] = false;
|
||||
|
||||
settings_manager->RegisterSettingsSchema("LogManager", QT_TRANSLATE_NOOP("Settings", "Log Manager"), logmanager_settings_schema);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
|
||||
@@ -175,18 +175,38 @@ bool i2c_smbus_linux_detect()
|
||||
path[sizeof(path) - 1] = '\0';
|
||||
free(ptr);
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Truncate at last '/' to get the parent PCI device directory. |
|
||||
| For AMDGPU i2c buses the realpath resolves to something like: |
|
||||
| /sys/devices/pci.../0000:03:00.0/i2c-4 |
|
||||
| The parent (0000:03:00.0) contains vendor/device/subsystem |
|
||||
| files. Using /..' traversal is unreliable in sysfs; directly |
|
||||
| truncating the path is correct and portable. |
|
||||
\*-------------------------------------------------------------*/
|
||||
char* last_slash = strrchr(path, '/');
|
||||
if(last_slash == NULL || last_slash == path)
|
||||
/*-----------------------------------------------------*\
|
||||
| Walk up sysfs to the nearest PCI device. |
|
||||
| Some I2C adapters sit below an intermediate device. |
|
||||
\*-----------------------------------------------------*/
|
||||
while(true)
|
||||
{
|
||||
char pci_vendor_path[PATH_MAX];
|
||||
char pci_device_path[PATH_MAX];
|
||||
|
||||
snprintf(pci_vendor_path, sizeof(pci_vendor_path), "%s/vendor", path);
|
||||
snprintf(pci_device_path, sizeof(pci_device_path), "%s/device", path);
|
||||
|
||||
if(access(pci_vendor_path, R_OK) == 0 && access(pci_device_path, R_OK) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
char* last_slash = strrchr(path, '/');
|
||||
|
||||
if(last_slash == NULL || last_slash == path)
|
||||
{
|
||||
path[0] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
*last_slash = '\0';
|
||||
}
|
||||
|
||||
if(path[0] == '\0')
|
||||
{
|
||||
continue;
|
||||
*last_slash = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| i2c_intel_gpu.h |
|
||||
| |
|
||||
| Bits specific to Intel GPUs to reliably detect |
|
||||
| the I2C bus that has RGB control |
|
||||
| |
|
||||
| Jan Dvořák 13 Sep 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "i2c_smbus.h"
|
||||
#include "pci_ids.h"
|
||||
|
||||
inline constexpr const char * RECOGNIZED_INTEL_I2C_BUS_NAMES[] =
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Linux Intel discrete GPU internal I2C controller |
|
||||
\*-----------------------------------------------------*/
|
||||
"Synopsys DesignWare I2C adapter",
|
||||
nullptr
|
||||
};
|
||||
|
||||
inline bool is_intel_gpu_i2c_bus(const i2c_smbus_interface *bus)
|
||||
{
|
||||
if(bus->info.pci_vendor != INTEL_VEN)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *name;
|
||||
size_t idx = 0;
|
||||
|
||||
while((name = RECOGNIZED_INTEL_I2C_BUS_NAMES[idx++]) != nullptr)
|
||||
{
|
||||
const char *pos = std::strstr(bus->info.device_name, name);
|
||||
|
||||
if(pos == bus->info.device_name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -707,6 +707,7 @@
|
||||
#define GIGABYTE_RTX4070_AERO_OC_12G_SUB_DEV 0x40E6
|
||||
#define GIGABYTE_RTX4070S_GAMING_OC_12G 0x4138
|
||||
#define GIGABYTE_RTX4070S_AERO_OC_12G 0x4139
|
||||
#define GIGABYTE_RTX4070S_EAGLE_OC_12G 0x413A
|
||||
#define GIGABYTE_RTX4070S_EAGLE_OC_ICE_12G 0x4148
|
||||
#define GIGABYTE_RTX4070TI_GAMING_12G 0x40DF
|
||||
#define GIGABYTE_RTX4070TI_GAMING_OC_12G 0x40C6
|
||||
@@ -912,6 +913,7 @@
|
||||
#define PNY_RTX_5070_ARGB_EPIC_X_OC_SUB_DEV 0x1439
|
||||
#define PNY_RTX_5070TI_ARGB_EPIC_X_SUB_DEV 0x143B
|
||||
#define PNY_RTX_5070TI_ARGB_EPIC_X_OC_SUB_DEV 0x143A
|
||||
#define PNY_RTX_5070TI_ARGB_EPIC_X_OC_SUB_DEV2 0x144A
|
||||
#define PNY_RTX_5060TI_ARGB_EPIC_X_OC_SUB_DEV 0x143E
|
||||
#define PNY_RTX_5080_ARGB_EPIC_X_OC_SUB_DEV 0x1435
|
||||
#define PNY_RTX_5090_ARGB_EPIC_X_OC_SUB_DEV 0x1446
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "JsonUtils.h"
|
||||
#include "OpenRGBDynamicSettingsWidget.h"
|
||||
#include "OpenRGBDeviceEditorDialog.h"
|
||||
#include "ProfileManager.h"
|
||||
@@ -125,6 +126,11 @@ OpenRGBDeviceEditorDialog::OpenRGBDeviceEditorDialog(RGBController *dev, QWidget
|
||||
\*-----------------------------------------------------*/
|
||||
for(std::size_t configuration_idx = 0; configuration_idx < configuration_entries.size(); configuration_idx++)
|
||||
{
|
||||
if(JsonUtils::JsonGetBool(configuration_entries[configuration_idx].value, "visible", true) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
OpenRGBDynamicSettingsWidget* item_widget = new OpenRGBDynamicSettingsWidget(configuration_entries[configuration_idx].key, configuration_entries[configuration_idx].value, configuration_value);
|
||||
|
||||
item_widget->SetCallback(Callback, this);
|
||||
|
||||
@@ -1629,11 +1629,6 @@ void OpenRGBDevicePage::UpdateModeUi()
|
||||
ui->PerLEDCheck->setEnabled(enable_controls);
|
||||
ui->PerLEDCheck->setChecked(per_led);
|
||||
ui->PerLEDCheck->blockSignals(false);
|
||||
|
||||
if(DeviceViewShowing)
|
||||
{
|
||||
ui->DeviceViewBoxFrame->show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1647,6 +1642,22 @@ void OpenRGBDevicePage::UpdateModeUi()
|
||||
ui->DeviceViewBoxFrame->hide();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Show the device view if the selected mode is a per- |
|
||||
| LED mode or if the selected zone mode is following |
|
||||
| entire device and the device mode is per-LED. |
|
||||
\*-----------------------------------------------------*/
|
||||
if((per_led)
|
||||
|| ((selected_zone_mode)
|
||||
&& (selected_mode == -1)
|
||||
&& (device->GetModeColorMode(device->GetActiveMode()) == MODE_COLORS_PER_LED)))
|
||||
{
|
||||
if(DeviceViewShowing)
|
||||
{
|
||||
ui->DeviceViewBoxFrame->show();
|
||||
}
|
||||
}
|
||||
|
||||
if(supports_mode_specific)
|
||||
{
|
||||
ui->ModeSpecificCheck->blockSignals(true);
|
||||
|
||||
@@ -54,8 +54,7 @@ static void OpenRGBDialogLogManagerCallback(void * this_ptr, unsigned int update
|
||||
switch(update_reason)
|
||||
{
|
||||
case LOGMANAGER_UPDATE_REASON_SHOW_DIALOG:
|
||||
this_obj->SetDialogMessage(message);
|
||||
QMetaObject::invokeMethod(this_obj, "onShowDialogMessage", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(this_obj, "onShowDialogMessage", Qt::QueuedConnection, Q_ARG(QString, QString::fromStdString(message->text)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -133,6 +132,11 @@ static void DeletePluginCallback(void * this_ptr, OpenRGBPluginEntry* plugin)
|
||||
this_obj->RemovePlugin(plugin);
|
||||
}
|
||||
|
||||
static bool AutoProfileIsSet(json& profilemanager_settings, std::string key)
|
||||
{
|
||||
return(profilemanager_settings.contains(key) && (JsonUtils::JsonGetString(profilemanager_settings[key], "name") != ""));
|
||||
}
|
||||
|
||||
bool OpenRGBDialog::IsMinimizeOnClose()
|
||||
{
|
||||
json ui_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("UserInterface");
|
||||
@@ -279,6 +283,7 @@ OpenRGBDialog::OpenRGBDialog(QWidget *parent) : QMainWindow(parent), ui(new Ui::
|
||||
#if defined(_WIN32)
|
||||
drivers_settings_schema["shared_smbus_acces"]["title"] = QT_TRANSLATE_NOOP("Settings", "Shared SMBus Access (restart required)");
|
||||
drivers_settings_schema["shared_smbus_acces"]["type"] = "bool";
|
||||
drivers_settings_schema["shared_smbus_access"]["default"] = true;
|
||||
|
||||
drivers_settings_schema["smbus_sleep_mode"]["title"] = QT_TRANSLATE_NOOP("Settings", "SMBus Sleep Mode (restart required)");
|
||||
drivers_settings_schema["smbus_sleep_mode"]["type"] = "integer";
|
||||
@@ -288,6 +293,7 @@ OpenRGBDialog::OpenRGBDialog(QWidget *parent) : QMainWindow(parent), ui(new Ui::
|
||||
drivers_settings_schema["smbus_sleep_mode"]["enumNames"][1] = "Short Busy";
|
||||
drivers_settings_schema["smbus_sleep_mode"]["enum"][2] = 2;
|
||||
drivers_settings_schema["smbus_sleep_mode"]["enumNames"][2] = "Always Sleep";
|
||||
drivers_settings_schema["smbus_sleep_mode"]["default"] = 2;
|
||||
#else
|
||||
drivers_settings_schema["amd_smbus_reduce_cpu"]["title"] = QT_TRANSLATE_NOOP("Settings", "AMD SMBus: Reduce CPU Usage (restart required)");
|
||||
drivers_settings_schema["amd_smbus_reduce_cpu"]["type"] = "bool";
|
||||
@@ -296,6 +302,11 @@ OpenRGBDialog::OpenRGBDialog(QWidget *parent) : QMainWindow(parent), ui(new Ui::
|
||||
ResourceManager::get()->GetSettingsManager()->RegisterSettingsSchema("Drivers", QT_TRANSLATE_NOOP("Settings", "Drivers"), drivers_settings_schema);
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Migrate settings from pre-1.0 versions |
|
||||
\*-----------------------------------------------------*/
|
||||
MigrateLegacySettings();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Register resource manager callbacks |
|
||||
\*-----------------------------------------------------*/
|
||||
@@ -1403,11 +1414,6 @@ void OpenRGBDialog::UpdateDevicesList()
|
||||
}
|
||||
}
|
||||
|
||||
void OpenRGBDialog::SetDialogMessage(PLogMessage msg)
|
||||
{
|
||||
dialog_message = QString::fromStdString(msg->text);
|
||||
}
|
||||
|
||||
void OpenRGBDialog::SetLanguage(std::string locale)
|
||||
{
|
||||
QApplication* app = static_cast<QApplication *>(QApplication::instance());
|
||||
@@ -1627,10 +1633,13 @@ void OpenRGBDialog::onDetectionEnded()
|
||||
| Load plugins after the first detection (ONLY the |
|
||||
| first) |
|
||||
\*-----------------------------------------------------*/
|
||||
bool plugins_just_loaded = false;
|
||||
|
||||
if(!plugins_loaded)
|
||||
{
|
||||
plugin_manager->ScanAndLoadPlugins();
|
||||
plugins_loaded = true;
|
||||
plugins_just_loaded = true;
|
||||
PluginsPage->RefreshList();
|
||||
}
|
||||
|
||||
@@ -1642,7 +1651,173 @@ void OpenRGBDialog::onDetectionEnded()
|
||||
/*-----------------------------------------------------*\
|
||||
| Load the on open automatic profile |
|
||||
\*-----------------------------------------------------*/
|
||||
ResourceManager::get()->GetProfileManager()->LoadAutoProfileOpen();
|
||||
bool open_profile_loaded = ResourceManager::get()->GetProfileManager()->LoadAutoProfileOpen();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| With no profile to open, the plugins that were just |
|
||||
| loaded still need the active profile's plugin data |
|
||||
\*-----------------------------------------------------*/
|
||||
if(plugins_just_loaded && !open_profile_loaded)
|
||||
{
|
||||
ResourceManager::get()->GetProfileManager()->ApplyActiveProfilePluginData();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenRGBDialog::MigrateLegacySettings()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Legacy AutoStart argument flags and value keys |
|
||||
\*-----------------------------------------------------*/
|
||||
static const char* legacy_arguments[][3] =
|
||||
{
|
||||
{ "setserver", "--server", "" },
|
||||
{ "setserverhost", "--server-host", "host" },
|
||||
{ "setserverport", "--server-port", "port" },
|
||||
{ "setclient", "--client", "client" },
|
||||
{ "setcustom", "", "custom" },
|
||||
};
|
||||
|
||||
static const char* legacy_profiles[] =
|
||||
{
|
||||
"exit_profile",
|
||||
"resume_profile",
|
||||
"suspend_profile",
|
||||
};
|
||||
|
||||
SettingsManager* settings_manager = ResourceManager::get()->GetSettingsManager();
|
||||
json autostart_settings = settings_manager->GetSettings("AutoStart");
|
||||
json ui_settings = settings_manager->GetSettings("UserInterface");
|
||||
json profilemanager_settings = settings_manager->GetSettings("ProfileManager");
|
||||
bool settings_migrated = false;
|
||||
bool ui_migrated = false;
|
||||
bool profiles_migrated = false;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Migrate pre-1.0 AutoStart keys |
|
||||
\*-----------------------------------------------------*/
|
||||
if(autostart_settings.contains("setminimized"))
|
||||
{
|
||||
std::string arguments;
|
||||
std::string profile_name = JsonUtils::JsonGetString(autostart_settings, "profile");
|
||||
|
||||
for(unsigned int arg_idx = 0; arg_idx < (sizeof(legacy_arguments) / sizeof(legacy_arguments[0])); arg_idx++)
|
||||
{
|
||||
if(JsonUtils::JsonGetBool(autostart_settings, legacy_arguments[arg_idx][0]))
|
||||
{
|
||||
std::string argument = legacy_arguments[arg_idx][1];
|
||||
std::string value = JsonUtils::JsonGetString(autostart_settings, legacy_arguments[arg_idx][2]);
|
||||
|
||||
if(value != "")
|
||||
{
|
||||
if(argument != "")
|
||||
{
|
||||
argument += " ";
|
||||
}
|
||||
|
||||
argument += value;
|
||||
}
|
||||
|
||||
if(argument != "")
|
||||
{
|
||||
if(arguments != "")
|
||||
{
|
||||
arguments += " ";
|
||||
}
|
||||
|
||||
arguments += argument;
|
||||
}
|
||||
}
|
||||
|
||||
autostart_settings.erase(legacy_arguments[arg_idx][0]);
|
||||
autostart_settings.erase(legacy_arguments[arg_idx][2]);
|
||||
}
|
||||
|
||||
if(!autostart_settings.contains("start_minimized"))
|
||||
{
|
||||
autostart_settings["start_minimized"] = JsonUtils::JsonGetBool(autostart_settings, "setminimized");
|
||||
}
|
||||
|
||||
if(!autostart_settings.contains("custom_arguments"))
|
||||
{
|
||||
autostart_settings["custom_arguments"] = arguments;
|
||||
}
|
||||
|
||||
if(JsonUtils::JsonGetBool(autostart_settings, "setprofile") && (profile_name != ""))
|
||||
{
|
||||
if(!AutoProfileIsSet(profilemanager_settings, "open_profile"))
|
||||
{
|
||||
profilemanager_settings["open_profile"]["enabled"] = true;
|
||||
profilemanager_settings["open_profile"]["name"] = profile_name;
|
||||
profiles_migrated = true;
|
||||
}
|
||||
|
||||
if(!AutoProfileIsSet(profilemanager_settings, "service_startup_profile"))
|
||||
{
|
||||
profilemanager_settings["service_startup_profile"]["enabled"] = true;
|
||||
profilemanager_settings["service_startup_profile"]["name"] = profile_name;
|
||||
profiles_migrated = true;
|
||||
}
|
||||
}
|
||||
|
||||
autostart_settings.erase("setminimized");
|
||||
autostart_settings.erase("setprofile");
|
||||
autostart_settings.erase("profile");
|
||||
|
||||
settings_manager->SetSettings("AutoStart", autostart_settings);
|
||||
settings_migrated = true;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Migrate pre-1.0 tray icon and autoload profile keys |
|
||||
\*-----------------------------------------------------*/
|
||||
if(ui_settings.contains("greyscale_tray_icon"))
|
||||
{
|
||||
if(!ui_settings.contains("monochrome_tray_icon"))
|
||||
{
|
||||
ui_settings["monochrome_tray_icon"] = JsonUtils::JsonGetBool(ui_settings, "greyscale_tray_icon");
|
||||
}
|
||||
|
||||
ui_settings.erase("greyscale_tray_icon");
|
||||
ui_migrated = true;
|
||||
}
|
||||
|
||||
if(ui_settings.contains("autoload_profiles"))
|
||||
{
|
||||
for(unsigned int profile_idx = 0; profile_idx < (sizeof(legacy_profiles) / sizeof(legacy_profiles[0])); profile_idx++)
|
||||
{
|
||||
std::string key = legacy_profiles[profile_idx];
|
||||
|
||||
if(ui_settings["autoload_profiles"].contains(key) && !AutoProfileIsSet(profilemanager_settings, key))
|
||||
{
|
||||
json legacy_profile = ui_settings["autoload_profiles"][key];
|
||||
|
||||
profilemanager_settings[key]["enabled"] = JsonUtils::JsonGetBool(legacy_profile, "enabled");
|
||||
profilemanager_settings[key]["name"] = JsonUtils::JsonGetString(legacy_profile, "name");
|
||||
profiles_migrated = true;
|
||||
}
|
||||
}
|
||||
|
||||
ui_settings.erase("autoload_profiles");
|
||||
ui_migrated = true;
|
||||
}
|
||||
|
||||
if(ui_migrated)
|
||||
{
|
||||
settings_manager->SetSettings("UserInterface", ui_settings);
|
||||
settings_migrated = true;
|
||||
}
|
||||
|
||||
if(settings_migrated)
|
||||
{
|
||||
if(profiles_migrated)
|
||||
{
|
||||
settings_manager->SetSettings("ProfileManager", profilemanager_settings);
|
||||
}
|
||||
|
||||
settings_manager->SaveSettings();
|
||||
|
||||
LOG_INFO("[OpenRGBDialog] Migrated legacy AutoStart and profile settings");
|
||||
}
|
||||
}
|
||||
|
||||
void OpenRGBDialog::onSettingsUpdated()
|
||||
@@ -1819,9 +1994,9 @@ void OpenRGBDialog::on_ShowHide()
|
||||
}
|
||||
}
|
||||
|
||||
void OpenRGBDialog::onShowDialogMessage()
|
||||
void OpenRGBDialog::onShowDialogMessage(QString message)
|
||||
{
|
||||
std::size_t hash = std::hash<std::string>{}(dialog_message.toStdString());
|
||||
std::size_t hash = std::hash<std::string>{}(message.toStdString());
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Load the LogManager settings and check if the hash of |
|
||||
@@ -1843,7 +2018,6 @@ void OpenRGBDialog::onShowDialogMessage()
|
||||
{
|
||||
if(log_manager_settings["dialog_no_show_hashes"][list_idx] == hash)
|
||||
{
|
||||
dialog_message.clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1851,21 +2025,21 @@ void OpenRGBDialog::onShowDialogMessage()
|
||||
|
||||
QMessageBox box;
|
||||
|
||||
box.setInformativeText(QCoreApplication::translate("ResourceManager", dialog_message.toUtf8()));
|
||||
box.setInformativeText(QCoreApplication::translate("ResourceManager", message.toUtf8()));
|
||||
|
||||
QCheckBox* CheckBox_DontShowAgain = new QCheckBox("Don't show this message again");
|
||||
|
||||
DontShowAgain = false;
|
||||
bool DontShowAgain = false;
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
|
||||
QObject::connect(CheckBox_DontShowAgain, &QCheckBox::checkStateChanged, [this](Qt::CheckState state)
|
||||
QObject::connect(CheckBox_DontShowAgain, &QCheckBox::checkStateChanged, [&DontShowAgain](Qt::CheckState state)
|
||||
#else
|
||||
QObject::connect(CheckBox_DontShowAgain, &QCheckBox::stateChanged, [this](int state)
|
||||
QObject::connect(CheckBox_DontShowAgain, &QCheckBox::stateChanged, [&DontShowAgain](int state)
|
||||
#endif
|
||||
{
|
||||
if(static_cast<Qt::CheckState>(state) == Qt::CheckState::Checked)
|
||||
{
|
||||
this->DontShowAgain = true;
|
||||
DontShowAgain = true;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1888,8 +2062,6 @@ void OpenRGBDialog::onShowDialogMessage()
|
||||
}
|
||||
|
||||
DontShowAgain = false;
|
||||
|
||||
dialog_message.clear();
|
||||
}
|
||||
|
||||
void OpenRGBDialog::on_ReShow(QSystemTrayIcon::ActivationReason reason)
|
||||
|
||||
@@ -59,11 +59,8 @@ public:
|
||||
|
||||
static bool IsMinimizeOnClose();
|
||||
|
||||
void SetDialogMessage(PLogMessage msg);
|
||||
void SetLanguage(std::string locale);
|
||||
|
||||
bool DontShowAgain;
|
||||
|
||||
signals:
|
||||
void ProfileListChanged();
|
||||
|
||||
@@ -126,8 +123,6 @@ private:
|
||||
QAction * trayActionRescan;
|
||||
QAction * trayActionExit;
|
||||
|
||||
QString dialog_message;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| User interface |
|
||||
\*-----------------------------------------------------*/
|
||||
@@ -151,6 +146,7 @@ private:
|
||||
void ShowHideDevicesList();
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
bool SelectConfigProfile(const std::string name);
|
||||
void MigrateLegacySettings();
|
||||
|
||||
void SetDetectionViewState(bool detection_showing);
|
||||
void SaveProfile();
|
||||
@@ -185,7 +181,7 @@ private slots:
|
||||
void onSettingsUpdated();
|
||||
void on_SetAllDevices(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void on_ShowHide();
|
||||
void onShowDialogMessage();
|
||||
void onShowDialogMessage(QString message);
|
||||
void on_ReShow(QSystemTrayIcon::ActivationReason reason);
|
||||
void on_ProfileSelected();
|
||||
void on_ProfileBox_currentIndexChanged(int index);
|
||||
|
||||
@@ -146,6 +146,11 @@ OpenRGBDynamicSettingsWidget::OpenRGBDynamicSettingsWidget(std::string key, nloh
|
||||
\*---------------------------------------------*/
|
||||
for(std::size_t setting_idx = 0; setting_idx < setting_entries.size(); setting_idx++)
|
||||
{
|
||||
if(JsonUtils::JsonGetBool(setting_entries[setting_idx].value, "visible", true) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
OpenRGBDynamicSettingsWidget* item_widget = new OpenRGBDynamicSettingsWidget(setting_entries[setting_idx].key, setting_entries[setting_idx].value, settings_json);
|
||||
|
||||
item_widget->SetCallback(&OpenRGBDynamicSettingsWidget::NestedCallback, this);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <QLayoutItem>
|
||||
#include <QSpacerItem>
|
||||
#include <QVBoxLayout>
|
||||
#include "JsonUtils.h"
|
||||
#include "OpenRGBDynamicSettingsWidget.h"
|
||||
#include "OpenRGBSettingsPage.h"
|
||||
#include "ResourceManager.h"
|
||||
@@ -139,6 +140,11 @@ void OpenRGBSettingsPage::UpdateInterface()
|
||||
\*-----------------------------------------------------*/
|
||||
for(std::size_t setting_idx = 0; setting_idx < setting_entries.size(); setting_idx++)
|
||||
{
|
||||
if(JsonUtils::JsonGetBool(setting_entries[setting_idx].value, "visible", true) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
nlohmann::json setting_value;
|
||||
setting_value[setting_entries[setting_idx].key] = ResourceManager::get()->GetSettingsManager()->GetSettings(setting_entries[setting_idx].key);
|
||||
OpenRGBDynamicSettingsWidget* item_widget = new OpenRGBDynamicSettingsWidget(setting_entries[setting_idx].key, setting_entries[setting_idx].value, setting_value);
|
||||
|
||||
Reference in New Issue
Block a user