Compare commits
96
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfaef77719 | ||
|
|
02d0e16a72 | ||
|
|
6ebf3573af | ||
|
|
5aef451e81 | ||
|
|
1880961afa | ||
|
|
fb5a723193 | ||
|
|
88002a4abf | ||
|
|
289dbc675a | ||
|
|
bcfaa7e8a7 | ||
|
|
bf62ead713 | ||
|
|
8a7cda7495 | ||
|
|
84cf974d70 | ||
|
|
afc54314b5 | ||
|
|
bd8db75106 | ||
|
|
9da692b12f | ||
|
|
4ee39b0dc8 | ||
|
|
286514b509 | ||
|
|
c7140baa33 | ||
|
|
2a9889b194 | ||
|
|
2afbd64c8e | ||
|
|
8be6aba43a | ||
|
|
565f1dad74 | ||
|
|
67a81f219d | ||
|
|
ccd103a29f | ||
|
|
c5d088b69d | ||
|
|
6362054368 | ||
|
|
2dab17f5dc | ||
|
|
c545305825 | ||
|
|
578c81784b | ||
|
|
1cd9b63c3e | ||
|
|
7b1817a0b8 | ||
|
|
fb0e4f3ad9 | ||
|
|
09a5b414b6 | ||
|
|
e5dc869c9b | ||
|
|
2687ff57aa | ||
|
|
52138b4cbd | ||
|
|
b3a2cccfed | ||
|
|
15a8abf2c9 | ||
|
|
d16b474aa8 | ||
|
|
760758230a | ||
|
|
358fc7b007 | ||
|
|
069eeccb60 | ||
|
|
da77b63bea | ||
|
|
791d8820d6 | ||
|
|
05fbe381dd | ||
|
|
3b2466ba10 | ||
|
|
acc7fa6754 | ||
|
|
394a5c8eb0 | ||
|
|
ac6d89b611 | ||
|
|
46cdd6fbe1 | ||
|
|
14d543b9e4 | ||
|
|
8a831cef04 | ||
|
|
9fd79b1ad2 | ||
|
|
c9c37a4576 | ||
|
|
fe53d90664 | ||
|
|
8e8a9c8e05 | ||
|
|
dafc6e9cbc | ||
|
|
68b113bf86 | ||
|
|
eb5d8b579c | ||
|
|
56df76dbfc | ||
|
|
878f32fccf | ||
|
|
63828313bd | ||
|
|
31992acad1 | ||
|
|
bd41ba3b5c | ||
|
|
b9309c61e1 | ||
|
|
7fc8aea930 | ||
|
|
b35e119325 | ||
|
|
8fb790358f | ||
|
|
39c6dbf361 | ||
|
|
9d189d5b9b | ||
|
|
9e5c63cc64 | ||
|
|
b664f35e17 | ||
|
|
381e3ac70c | ||
|
|
e3225d93c4 | ||
|
|
1b3480bf8a | ||
|
|
a6bea17df2 | ||
|
|
28d73d74bc | ||
|
|
cf383cacdd | ||
|
|
d9b0995b44 | ||
|
|
79eb758a52 | ||
|
|
75463b8772 | ||
|
|
5da92fca4e | ||
|
|
d11be2aa0b | ||
|
|
285a7bce4e | ||
|
|
21009cdc45 | ||
|
|
a0cee2ce2b | ||
|
|
ba33ff0c35 | ||
|
|
795616e62d | ||
|
|
baa033ff7f | ||
|
|
33ec03d129 | ||
|
|
a0d5a985f0 | ||
|
|
1275fe816b | ||
|
|
d4e1ed5245 | ||
|
|
b833a43490 | ||
|
|
94295c52ba | ||
|
|
f32aa29ecd |
@@ -119,6 +119,21 @@ bool AutoStart::IsAutoStartEnabled()
|
||||
|
||||
std::string AutoStart::GetExePath()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| When running from an AppImage, the AppImage runtime |
|
||||
| sets the APPIMAGE environment variable to the path of |
|
||||
| the AppImage file itself. /proc/self/exe would |
|
||||
| instead point at the extracted binary inside the |
|
||||
| temporary squashfs mount, which disappears once the |
|
||||
| AppImage is closed, so prefer APPIMAGE when it is set |
|
||||
\*-----------------------------------------------------*/
|
||||
const char* appimage_path = getenv("APPIMAGE");
|
||||
|
||||
if(appimage_path != NULL)
|
||||
{
|
||||
return(std::string(appimage_path));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Create the OpenRGB executable path |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| A4TechDetector.cpp |
|
||||
| |
|
||||
| Detector for A4Tech Devices |
|
||||
| |
|
||||
| Chris M (Dr_No) 30 Jun 2022 |
|
||||
| Mohammed Julfikar Ali Mahbub (o-julfikar) 01 Apr 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "BloodyB820RController.h"
|
||||
#include "BloodyMouseController.h"
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_BloodyB820R.h"
|
||||
#include "RGBController_BloodyMouse.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| A4 Tech USB vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define A4_TECH_VID 0x09DA
|
||||
|
||||
DetectedControllers DetectA4TechMouseControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
BloodyMouseController* controller = new BloodyMouseController(dev, info->path, info->product_id, name);
|
||||
RGBController_BloodyMouse* rgb_controller = new RGBController_BloodyMouse(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectBloodyB820R(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
BloodyB820RController* controller = new BloodyB820RController(dev, info->path, name);
|
||||
RGBController_BloodyB820R* rgb_controller = new RGBController_BloodyB820R(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W60 Pro", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_W60_PRO_PID, 2, 0xFF33, 0x0529);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W70 Max", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_W70_MAX_PID, 2, 0xFF33, 0x0518);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W90 Max", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_W90_MAX_PID, 2, 0xFF33, 0x053D);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W90 Pro", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_W90_PRO_PID, 2, 0xFF33, 0x054D);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody MP 50RS", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_MP_50RS_PID, 2, 0xFFF2, 0x6009);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody B820R", DetectBloodyB820R, A4_TECH_VID, BLOODY_B820R_PID, 2, 0xFF52, 0x0210);
|
||||
@@ -0,0 +1,40 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| BloodyB820RControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Bloody B820R Devices |
|
||||
| |
|
||||
| Mohammed Julfikar Ali Mahbub (o-julfikar) 01 Apr 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "BloodyB820RController.h"
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_BloodyB820R.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| A4 Tech USB vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define A4_TECH_VID 0x09DA
|
||||
|
||||
DetectedControllers DetectBloodyB820R(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
BloodyB820RController* controller = new BloodyB820RController(dev, info->path, name);
|
||||
RGBController_BloodyB820R* rgb_controller = new RGBController_BloodyB820R(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody B820R", DetectBloodyB820R, A4_TECH_VID, BLOODY_B820R_PID, 2, 0xFF52, 0x0210);
|
||||
@@ -0,0 +1,44 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| BloodyMouseControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Bloody Mouse Devices |
|
||||
| |
|
||||
| Chris M (Dr_No) 30 Jun 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "BloodyMouseController.h"
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_BloodyMouse.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| A4 Tech USB vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define A4_TECH_VID 0x09DA
|
||||
|
||||
DetectedControllers DetectBloodyMouseControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
BloodyMouseController* controller = new BloodyMouseController(dev, info->path, info->product_id, name);
|
||||
RGBController_BloodyMouse* rgb_controller = new RGBController_BloodyMouse(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W60 Pro", DetectBloodyMouseControllers, A4_TECH_VID, BLOODY_W60_PRO_PID, 2, 0xFF33, 0x0529);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W70 Max", DetectBloodyMouseControllers, A4_TECH_VID, BLOODY_W70_MAX_PID, 2, 0xFF33, 0x0518);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W90 Max", DetectBloodyMouseControllers, A4_TECH_VID, BLOODY_W90_MAX_PID, 2, 0xFF33, 0x053D);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W90 Pro", DetectBloodyMouseControllers, A4_TECH_VID, BLOODY_W90_PRO_PID, 2, 0xFF33, 0x054D);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody MP 50RS", DetectBloodyMouseControllers, A4_TECH_VID, BLOODY_MP_50RS_PID, 2, 0xFFF2, 0x6009);
|
||||
@@ -334,9 +334,14 @@ void RGBController_PolychromeUSB::DeviceUpdateLEDs()
|
||||
}
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
if(zones[zone_idx].leds_count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned char set_mode = zones_info[zone_idx].mode;
|
||||
|
||||
if (set_mode>modes.size())
|
||||
if(set_mode>modes.size())
|
||||
{
|
||||
set_mode = active_mode;
|
||||
}
|
||||
@@ -347,6 +352,11 @@ void RGBController_PolychromeUSB::DeviceUpdateLEDs()
|
||||
|
||||
void RGBController_PolychromeUSB::DeviceUpdateZoneLEDs(int zone)
|
||||
{
|
||||
if(zones[zone].leds_count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char set_mode=zones_info[zone].mode;
|
||||
|
||||
if(set_mode > modes.size())
|
||||
@@ -354,7 +364,7 @@ void RGBController_PolychromeUSB::DeviceUpdateZoneLEDs(int zone)
|
||||
set_mode = active_mode;
|
||||
}
|
||||
|
||||
controller->WriteZone(zone, set_mode, zones_info[zone].speed, zones[zone].colors[0], false);
|
||||
controller->WriteZone((unsigned char)zone, set_mode, zones_info[zone].speed, zones[zone].colors[0], false);
|
||||
}
|
||||
|
||||
void RGBController_PolychromeUSB::DeviceUpdateSingleLED(int led)
|
||||
@@ -362,12 +372,17 @@ void RGBController_PolychromeUSB::DeviceUpdateSingleLED(int led)
|
||||
unsigned int channel = leds[led].value;
|
||||
unsigned char set_mode = zones_info[channel].mode;
|
||||
|
||||
if(zones[channel].leds_count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(set_mode > modes.size())
|
||||
{
|
||||
set_mode = active_mode;
|
||||
}
|
||||
|
||||
controller->WriteZone(channel, set_mode, zones_info[channel].speed, zones[channel].colors[0], false);
|
||||
controller->WriteZone((unsigned char)channel, set_mode, zones_info[channel].speed, zones[channel].colors[0], false);
|
||||
}
|
||||
|
||||
unsigned char RGBController_PolychromeUSB::GetDeviceMode(unsigned char zone)
|
||||
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ASRockGPUSMBusController.cpp |
|
||||
| |
|
||||
| Driver for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| Based on SignalRGB ASRock GPU.js plugin |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "ASRockGPUSMBusController.h"
|
||||
#include "LogManager.h"
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
ASRockGPUSMBusController::ASRockGPUSMBusController(i2c_smbus_interface* bus, asrock_gpu_dev_id dev, std::string name)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
this->device_name = name;
|
||||
this->num_channels = 0;
|
||||
|
||||
memset(enabled_channels, 0, sizeof(enabled_channels));
|
||||
memset(led_counts, 0, sizeof(led_counts));
|
||||
}
|
||||
|
||||
ASRockGPUSMBusController::~ASRockGPUSMBusController()
|
||||
{
|
||||
}
|
||||
|
||||
std::string ASRockGPUSMBusController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->info.device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return("I2C: " + return_string);
|
||||
}
|
||||
|
||||
std::string ASRockGPUSMBusController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
bool ASRockGPUSMBusController::WriteBlock(uint8_t command, uint8_t subcommand, const uint8_t* data, uint8_t len)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| SignalRGB packet format |
|
||||
| [command, 0, subcommand, data...] |
|
||||
| Uses pure I2C rather than SMBus |
|
||||
\*-----------------------------------------------------*/
|
||||
uint8_t packet[12];
|
||||
memset(packet, 0, sizeof(packet));
|
||||
|
||||
packet[0] = command;
|
||||
packet[1] = 0x00;
|
||||
packet[2] = subcommand;
|
||||
|
||||
if(data != nullptr && len > 0)
|
||||
{
|
||||
uint8_t copy_len = (len > 9) ? 9 : len;
|
||||
memcpy(&packet[3], data, copy_len);
|
||||
}
|
||||
|
||||
int size = 12;
|
||||
int result = bus->i2c_write_block(dev, size, packet);
|
||||
|
||||
if(result < 0)
|
||||
{
|
||||
LOG_DEBUG("[ASRock GPU] Write block failed: %d", result);
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool ASRockGPUSMBusController::ReadBlock(uint8_t* response, uint8_t len)
|
||||
{
|
||||
memset(response, 0, len);
|
||||
int size = len;
|
||||
int result = bus->i2c_read_block(dev, &size, response);
|
||||
|
||||
if(result < 0)
|
||||
{
|
||||
LOG_DEBUG("[ASRock GPU] Read block failed: %d", result);
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool ASRockGPUSMBusController::DetectChannels()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Get enabled channels |
|
||||
| Command 0x14, subcommand 0x01 |
|
||||
\*-----------------------------------------------------*/
|
||||
if(!WriteBlock(0x14, 0x01, nullptr, 0))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to request enabled channels");
|
||||
return(false);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(20ms);
|
||||
|
||||
uint8_t response[I2C_SMBUS_BLOCK_MAX];
|
||||
if(!ReadBlock(response, sizeof(response)))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to read enabled channels");
|
||||
return(false);
|
||||
}
|
||||
|
||||
LOG_TRACE("[ASRock GPU] Enabled channels response: %02X %02X %02X %02X %02X %02X", response[0], response[1], response[2], response[3], response[4], response[5]);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Response format |
|
||||
| Bytes 4-5 contain the channel bitmap |
|
||||
\*-----------------------------------------------------*/
|
||||
uint16_t channel_bits = response[4] | (response[5] << 8);
|
||||
LOG_TRACE("[ASRock GPU] Channel bits: 0x%04X", channel_bits);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get LED counts |
|
||||
| Command 0x14, subcommand 0x02 |
|
||||
\*-----------------------------------------------------*/
|
||||
if(!WriteBlock(0x14, 0x02, nullptr, 0))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to request LED counts");
|
||||
return(false);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(20ms);
|
||||
|
||||
if(!ReadBlock(response, sizeof(response)))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to read LED counts");
|
||||
return(false);
|
||||
}
|
||||
|
||||
num_channels = 0;
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
if(channel_bits & (1 << i))
|
||||
{
|
||||
enabled_channels[num_channels] = i;
|
||||
led_counts[num_channels] = response[4 + i];
|
||||
|
||||
const char* name = "Unknown";
|
||||
if(i == ASROCK_GPU_CHANNEL_ARGB_HEADER)
|
||||
{
|
||||
name = "ARGB Header";
|
||||
}
|
||||
else if(i == ASROCK_GPU_CHANNEL_TOP_SIDE)
|
||||
{
|
||||
name = "Top Side";
|
||||
}
|
||||
else if(i == ASROCK_GPU_CHANNEL_FAN)
|
||||
{
|
||||
name = "Fan";
|
||||
}
|
||||
|
||||
LOG_DEBUG("[ASRock GPU] Channel %d (%s) active with %d LEDs", i, name, response[4 + i]);
|
||||
num_channels++;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("[ASRock GPU] Found %d active channels", num_channels);
|
||||
return(num_channels > 0);
|
||||
}
|
||||
|
||||
void ASRockGPUSMBusController::SetChannelColor(uint8_t channel_idx, uint8_t red, uint8_t green, uint8_t blue)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| SignalRGB color packet |
|
||||
| Command 0x10, subcommand is the channel index |
|
||||
\*-----------------------------------------------------*/
|
||||
uint8_t data[8] =
|
||||
{
|
||||
0x01, // Mode: direct/static
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
0x80, // Brightness
|
||||
0xFF, // Effect speed
|
||||
0x00, // Effect direction
|
||||
0x1A // Unknown constant
|
||||
};
|
||||
|
||||
if(!WriteBlock(0x10, channel_idx, data, sizeof(data)))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to set color for channel %d", channel_idx);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ASRockGPUSMBusController.h |
|
||||
| |
|
||||
| Driver for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| Based on SignalRGB ASRock GPU.js plugin |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
typedef uint8_t asrock_gpu_dev_id;
|
||||
|
||||
#define ASROCK_GPU_CONTROLLER_NAME "ASRock GPU SMBus Controller"
|
||||
#define ASROCK_GPU_SMBUS_ADDRESS 0x36
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| ASRock GPU Channel Names (from SignalRGB) |
|
||||
\*-----------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
ASROCK_GPU_CHANNEL_ARGB_HEADER = 3,
|
||||
ASROCK_GPU_CHANNEL_TOP_SIDE = 6,
|
||||
ASROCK_GPU_CHANNEL_FAN = 7,
|
||||
};
|
||||
|
||||
class ASRockGPUSMBusController
|
||||
{
|
||||
public:
|
||||
ASRockGPUSMBusController(i2c_smbus_interface* bus, asrock_gpu_dev_id dev, std::string name);
|
||||
~ASRockGPUSMBusController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
|
||||
void SetChannelColor(uint8_t channel_idx, uint8_t red, uint8_t green, uint8_t blue);
|
||||
bool DetectChannels();
|
||||
|
||||
uint8_t enabled_channels[16];
|
||||
uint8_t led_counts[16];
|
||||
uint8_t num_channels;
|
||||
|
||||
private:
|
||||
i2c_smbus_interface* bus;
|
||||
asrock_gpu_dev_id dev;
|
||||
std::string device_name;
|
||||
|
||||
bool WriteBlock(uint8_t command, uint8_t subcommand, const uint8_t* data, uint8_t len);
|
||||
bool ReadBlock(uint8_t* response, uint8_t len);
|
||||
};
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ASRockGPUSMBusControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "DetectionManager.h"
|
||||
#include "ASRockGPUSMBusController.h"
|
||||
#include "LogManager.h"
|
||||
#include "RGBController_ASRockGPUSMBus.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include "pci_ids.h"
|
||||
|
||||
DetectedControllers DetectASRockGPUSMBusControllers(i2c_smbus_interface* bus, uint8_t address, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
|
||||
LOG_DEBUG("[ASRock GPU] Checking GPU I2C bus for RGB controller at 0x%02X", address);
|
||||
|
||||
if(bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE) < 0)
|
||||
{
|
||||
LOG_DEBUG("[ASRock GPU] No response at address 0x%02X", address);
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
LOG_DEBUG("[ASRock GPU] Device responded at 0x%02X, creating controller", address);
|
||||
|
||||
ASRockGPUSMBusController* controller = new ASRockGPUSMBusController(bus, address, name);
|
||||
|
||||
if(controller->DetectChannels())
|
||||
{
|
||||
detected_controllers.push_back(new RGBController_ASRockGPUSMBus(controller));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] No active channels found, device not registered");
|
||||
delete controller;
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
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);
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_ASRockGPUSMBus.cpp |
|
||||
| |
|
||||
| RGBController for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| Based on SignalRGB ASRock GPU.js plugin |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_ASRockGPUSMBus.h"
|
||||
|
||||
RGBController_ASRockGPUSMBus::RGBController_ASRockGPUSMBus(ASRockGPUSMBusController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "ASRock";
|
||||
type = DEVICE_TYPE_GPU;
|
||||
description = "ASRock GPU RGB Controller";
|
||||
location = controller->GetDeviceLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_ASRockGPUSMBus::~RGBController_ASRockGPUSMBus()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::SetupZones()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up zones - one zone per channel |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < controller->num_channels; i++)
|
||||
{
|
||||
uint8_t channel_idx = controller->enabled_channels[i];
|
||||
|
||||
zone new_zone;
|
||||
new_zone.type = ZONE_TYPE_SINGLE;
|
||||
new_zone.leds_min = 1;
|
||||
new_zone.leds_max = 1;
|
||||
new_zone.leds_count = 1;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Channel names from SignalRGB |
|
||||
\*-----------------------------------------------------*/
|
||||
if(channel_idx == ASROCK_GPU_CHANNEL_ARGB_HEADER)
|
||||
{
|
||||
new_zone.name = "ARGB Header";
|
||||
}
|
||||
else if(channel_idx == ASROCK_GPU_CHANNEL_TOP_SIDE)
|
||||
{
|
||||
new_zone.name = "Top Side";
|
||||
}
|
||||
else if(channel_idx == ASROCK_GPU_CHANNEL_FAN)
|
||||
{
|
||||
new_zone.name = "Fan";
|
||||
}
|
||||
else
|
||||
{
|
||||
new_zone.name = "Channel " + std::to_string(channel_idx);
|
||||
}
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up LED for this zone |
|
||||
\*-----------------------------------------------------*/
|
||||
led new_led;
|
||||
new_led.name = new_zone.name;
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*-----------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::DeviceUpdateLEDs()
|
||||
{
|
||||
for(unsigned int i = 0; i < controller->num_channels; i++)
|
||||
{
|
||||
uint8_t channel_idx = controller->enabled_channels[i];
|
||||
RGBColor color = colors[i];
|
||||
|
||||
controller->SetChannelColor(channel_idx,
|
||||
RGBGetRValue(color),
|
||||
RGBGetGValue(color),
|
||||
RGBGetBValue(color));
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
uint8_t channel_idx = controller->enabled_channels[zone];
|
||||
RGBColor color = colors[zone];
|
||||
|
||||
controller->SetChannelColor(channel_idx,
|
||||
RGBGetRValue(color),
|
||||
RGBGetGValue(color),
|
||||
RGBGetBValue(color));
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::UpdateSingleLED(int led)
|
||||
{
|
||||
UpdateZoneLEDs(led);
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_ASRockGPUSMBus.h |
|
||||
| |
|
||||
| RGBController for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| Based on SignalRGB ASRock GPU.js plugin |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "ASRockGPUSMBusController.h"
|
||||
|
||||
class RGBController_ASRockGPUSMBus : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_ASRockGPUSMBus(ASRockGPUSMBusController* controller_ptr);
|
||||
~RGBController_ASRockGPUSMBus();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
ASRockGPUSMBusController* controller;
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| Detector for Acer Nitro HID Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <vector>
|
||||
#include "DetectionManager.h"
|
||||
#include "AcerNitroHidKeyboardController.h"
|
||||
#include "RGBController_AcerNitroHidKeyboard.h"
|
||||
#include "RGBController_AcerNitroHidLed.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HID vendor and product IDs for ENEK EC in Acer Nitro |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#define ACER_ENEC_VID 0x0CF2
|
||||
#define ACER_ENEC_PID 0x5130
|
||||
#define ACER_ENEC_USAGE_PAGE 0xFF5A
|
||||
#define ACER_ENEC_USAGE 0x01
|
||||
|
||||
DetectedControllers DetectAcerHIDControllers(hid_device_info* info, const std::string&)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
if(dev)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Controller is shared between keyboard and onboard |
|
||||
| led |
|
||||
\*-------------------------------------------------*/
|
||||
std::shared_ptr<AcerNitroHidKeyboardController> controller = std::make_shared<AcerNitroHidKeyboardController>(dev, info->path);
|
||||
RGBController_AcerNitroHidKeyboard* rgb_kb_controller = new RGBController_AcerNitroHidKeyboard(controller);
|
||||
RGBController_AcerNitroHidLed* rgb_led_controller = new RGBController_AcerNitroHidLed(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_kb_controller);
|
||||
detected_controllers.push_back(rgb_led_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_PU("AcerNitroHidKeyboardController", DetectAcerHIDControllers, ACER_ENEC_VID, ACER_ENEC_PID, ACER_ENEC_USAGE_PAGE, ACER_ENEC_USAGE);
|
||||
@@ -0,0 +1,80 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| Driver for Acer Nitro Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "AcerNitroHidKeyboardController.h"
|
||||
|
||||
AcerNitroHidKeyboardController::AcerNitroHidKeyboardController(hid_device *dev_handle, const char *path)
|
||||
{
|
||||
this->location = path;
|
||||
this->dev = dev_handle;
|
||||
|
||||
device_name = "Acer Nitro HID Keyboard";
|
||||
}
|
||||
|
||||
AcerNitroHidKeyboardController::~AcerNitroHidKeyboardController()
|
||||
{
|
||||
if(dev)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
}
|
||||
|
||||
std::string AcerNitroHidKeyboardController::GetLocation() const
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string AcerNitroHidKeyboardController::GetDeviceName() const
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
void AcerNitroHidKeyboardController::SetLEDs(const std::vector<RGBColor>& colors, unsigned char brightness, unsigned char device_id)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(device_mutex);
|
||||
|
||||
for(unsigned int led_idx = 0; (led_idx < colors.size()) && (led_idx < ACER_HID_NUM_ZONES); led_idx++)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Convert colors to RGB format |
|
||||
\*-------------------------------------------------*/
|
||||
unsigned char r = RGBGetRValue(colors[led_idx]);
|
||||
unsigned char g = RGBGetGValue(colors[led_idx]);
|
||||
unsigned char b = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-------------------------------------------------*/
|
||||
unsigned char zone_select = (unsigned char)(1<<led_idx);
|
||||
unsigned char packet[ACER_HID_PACKET_SIZE] = {0xA4, device_id, ACER_HID_MODE_STATIC, brightness, 0, 1, r, g, b, zone_select, 0};
|
||||
hid_send_feature_report(dev, packet, ACER_HID_PACKET_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void AcerNitroHidKeyboardController::SetAllLEDs(const RGBColor &color, unsigned char brightness, unsigned char speed, unsigned char direction, unsigned char mode, unsigned char device_id)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(device_mutex);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Convert color to RGB format |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char r = RGBGetRValue(color);
|
||||
unsigned char g = RGBGetGValue(color);
|
||||
unsigned char b = RGBGetBValue(color);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
| Zone select = All zones |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char zone_select = 0x0F;
|
||||
unsigned char packet[ACER_HID_PACKET_SIZE] = {0xA4, device_id, mode, brightness, speed, direction, r, g, b, zone_select, 0};
|
||||
hid_send_feature_report(dev, packet, ACER_HID_PACKET_SIZE);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| Driver for Acer Nitro Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
ACER_HID_MODE_DIRECT = 1,
|
||||
ACER_HID_MODE_STATIC = 2,
|
||||
ACER_HID_MODE_BREATHING = 4,
|
||||
ACER_HID_MODE_NEON = 5,
|
||||
ACER_HID_MODE_OPMODE = 6,
|
||||
ACER_HID_MODE_WAVE = 7,
|
||||
ACER_HID_MODE_SHIFTING = 8,
|
||||
ACER_HID_MODE_ZOOM = 9,
|
||||
ACER_HID_MODE_METEOR = 10,
|
||||
ACER_HID_MODE_TWINKLING = 11,
|
||||
};
|
||||
|
||||
#define ACER_HID_NAME_BUFFER_SIZE 255
|
||||
#define ACER_HID_NUM_ZONES 4
|
||||
#define ACER_HID_PACKET_SIZE 11
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "RGBControllerInterface.h"
|
||||
|
||||
class AcerNitroHidKeyboardController
|
||||
{
|
||||
public:
|
||||
AcerNitroHidKeyboardController(hid_device *dev_handle, const char *path);
|
||||
~AcerNitroHidKeyboardController();
|
||||
|
||||
std::string GetDeviceName() const;
|
||||
std::string GetSerial() const;
|
||||
std::string GetLocation() const;
|
||||
|
||||
void SetLEDs(const std::vector<RGBColor> &colors, unsigned char brightness, unsigned char device_id);
|
||||
void SetAllLEDs(const RGBColor &color, unsigned char brightness, unsigned char speed, unsigned char direction, unsigned char mode, unsigned char device_id);
|
||||
|
||||
private:
|
||||
hid_device *dev;
|
||||
std::string device_name;
|
||||
std::string location;
|
||||
std::mutex device_mutex;
|
||||
};
|
||||
@@ -0,0 +1,231 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| RGBController for Acer Nitro HID Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_AcerNitroHidKeyboard.h"
|
||||
|
||||
// /**------------------------------------------------------------------*\
|
||||
// @name Acer Nitro HID Keyboard
|
||||
// @category Laptop
|
||||
// @type HID
|
||||
// @save :x:
|
||||
// @direct :white_check_mark:
|
||||
// @effects :white_check_mark:
|
||||
// @detectors DetectAcerHIDControllers
|
||||
// @comment
|
||||
// \*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_AcerNitroHidKeyboard::RGBController_AcerNitroHidKeyboard(std::shared_ptr<AcerNitroHidKeyboardController> controller)
|
||||
{
|
||||
this->controller = controller;
|
||||
device_id = 0x21;
|
||||
|
||||
name = "Acer Nitro HID Keyboard";
|
||||
vendor = "Acer";
|
||||
type = DEVICE_TYPE_LAPTOP;
|
||||
description = "Acer Nitro HID Keyboard Device";
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = ACER_HID_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS ;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
Direct.brightness_min = 0;
|
||||
Direct.brightness_max = 100;
|
||||
Direct.brightness = 100;
|
||||
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = ACER_HID_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.brightness_min = 0;
|
||||
Static.brightness_max = 100;
|
||||
Static.brightness = 100;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(1);
|
||||
Static.speed = 0;
|
||||
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = ACER_HID_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = 100;
|
||||
Breathing.brightness = 100;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.speed_min = 1;
|
||||
Breathing.speed_max = 9;
|
||||
Breathing.speed = 4;
|
||||
Breathing.colors.resize(1);
|
||||
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Neon;
|
||||
Neon.name = "Neon";
|
||||
Neon.value = ACER_HID_MODE_NEON;
|
||||
Neon.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Neon.color_mode = MODE_COLORS_NONE;
|
||||
Neon.brightness_min = 0;
|
||||
Neon.brightness_max = 100;
|
||||
Neon.brightness = 100;
|
||||
Neon.speed_min = 1;
|
||||
Neon.speed_max = 9;
|
||||
Neon.speed = 4;
|
||||
|
||||
modes.push_back(Neon);
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = ACER_HID_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR;
|
||||
Wave.color_mode = MODE_COLORS_NONE;
|
||||
Wave.brightness_min = 0;
|
||||
Wave.brightness_max = 100;
|
||||
Wave.brightness = 100;
|
||||
Wave.speed_min = 1;
|
||||
Wave.speed_max = 9;
|
||||
Wave.speed = 4;
|
||||
Wave.direction = 0;
|
||||
|
||||
modes.push_back(Wave);
|
||||
|
||||
mode Shifting;
|
||||
Shifting.name = "Shifting";
|
||||
Shifting.value = ACER_HID_MODE_SHIFTING;
|
||||
Shifting.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Shifting.color_mode = MODE_COLORS_NONE;
|
||||
Shifting.brightness_min = 0;
|
||||
Shifting.brightness_max = 100;
|
||||
Shifting.brightness = 100;
|
||||
Shifting.speed_min = 1;
|
||||
Shifting.speed_max = 9;
|
||||
Shifting.speed = 4;
|
||||
|
||||
modes.push_back(Shifting);
|
||||
|
||||
mode Zoom;
|
||||
Zoom.name = "Zoom";
|
||||
Zoom.value = ACER_HID_MODE_ZOOM;
|
||||
Zoom.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Zoom.color_mode = MODE_COLORS_NONE;
|
||||
Zoom.brightness_min = 0;
|
||||
Zoom.brightness_max = 100;
|
||||
Zoom.brightness = 100;
|
||||
Zoom.speed_min = 1;
|
||||
Zoom.speed_max = 9;
|
||||
Zoom.speed = 4;
|
||||
|
||||
modes.push_back(Zoom);
|
||||
|
||||
mode Meteor;
|
||||
Meteor.name = "Meteor";
|
||||
Meteor.value = ACER_HID_MODE_METEOR;
|
||||
Meteor.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Meteor.color_mode = MODE_COLORS_NONE;
|
||||
Meteor.brightness_min = 0;
|
||||
Meteor.brightness_max = 100;
|
||||
Meteor.brightness = 100;
|
||||
Meteor.speed_min = 1;
|
||||
Meteor.speed_max = 9;
|
||||
Meteor.speed = 4;
|
||||
|
||||
modes.push_back(Meteor);
|
||||
|
||||
mode Twinkling;
|
||||
Twinkling.name = "Twinkling";
|
||||
Twinkling.value = ACER_HID_MODE_TWINKLING;
|
||||
Twinkling.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Twinkling.color_mode = MODE_COLORS_NONE;
|
||||
Twinkling.brightness_min = 0;
|
||||
Twinkling.brightness_max = 100;
|
||||
Twinkling.brightness = 100;
|
||||
Twinkling.colors_min = 1;
|
||||
Twinkling.colors_max = 1;
|
||||
Twinkling.speed_min = 1;
|
||||
Twinkling.speed_max = 9;
|
||||
Twinkling.speed = 4;
|
||||
|
||||
modes.push_back(Twinkling);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_AcerNitroHidKeyboard::~RGBController_AcerNitroHidKeyboard()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::SetupZones()
|
||||
{
|
||||
zone* new_zone = new zone;
|
||||
|
||||
new_zone->name = "Keyboard Backlight Zone";
|
||||
new_zone->type = ZONE_TYPE_LINEAR;
|
||||
new_zone->leds_min = 4;
|
||||
new_zone->leds_max = 4;
|
||||
new_zone->leds_count = 4;
|
||||
|
||||
zones.push_back(*new_zone);
|
||||
|
||||
for(std::size_t zone_idx = 0; zone_idx < ACER_HID_NUM_ZONES; zone_idx++)
|
||||
{
|
||||
led* new_led = new led();
|
||||
new_led->name = "Keyboard Backlight Zone ";
|
||||
new_led->name.append(std::to_string(zone_idx + 1));
|
||||
new_led->value = (unsigned int)leds.size();
|
||||
|
||||
leds.push_back(*new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::DeviceUpdateLEDs()
|
||||
{
|
||||
mode& current_mode = modes[active_mode];
|
||||
if(current_mode.value == ACER_HID_MODE_DIRECT)
|
||||
{
|
||||
controller->SetLEDs(colors, current_mode.brightness, device_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
RGBColor color = current_mode.colors.size()==0? (RGBColor)0 : current_mode.colors[0];
|
||||
unsigned char direction = 1;
|
||||
if((modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR) && modes[active_mode].direction)
|
||||
{
|
||||
direction = 2;
|
||||
}
|
||||
controller->SetAllLEDs(color, current_mode.brightness, current_mode.speed, direction, current_mode.value, device_id);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::DeviceUpdateZoneLEDs(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::DeviceUpdateSingleLED(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| RGBController for Acer Nitro HID Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "AcerNitroHidKeyboardController.h"
|
||||
|
||||
class RGBController_AcerNitroHidKeyboard : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_AcerNitroHidKeyboard(std::shared_ptr<AcerNitroHidKeyboardController> controller);
|
||||
~RGBController_AcerNitroHidKeyboard();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
std::shared_ptr<AcerNitroHidKeyboardController> controller;
|
||||
unsigned int device_id;
|
||||
};
|
||||
@@ -0,0 +1,152 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidLed.cpp |
|
||||
| |
|
||||
| RGBController for Acer Nitro HID LED |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_AcerNitroHidLed.h"
|
||||
|
||||
// /**------------------------------------------------------------------*\
|
||||
// @name Acer Nitro HID Led
|
||||
// @category Laptop
|
||||
// @type HID
|
||||
// @save :x:
|
||||
// @direct :white_check_mark:
|
||||
// @effects :white_check_mark:
|
||||
// @detectors DetectAcerHIDControllers
|
||||
// @comment
|
||||
// \*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_AcerNitroHidLed::RGBController_AcerNitroHidLed(std::shared_ptr<AcerNitroHidKeyboardController> controller)
|
||||
{
|
||||
this->controller = controller;
|
||||
device_id = 0x65;
|
||||
|
||||
name = "Acer Nitro HID LED Device";
|
||||
vendor = "Acer";
|
||||
type = DEVICE_TYPE_LIGHT;
|
||||
description = "Acer Nitro HID LED Device";
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = ACER_HID_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS ;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
Direct.brightness_min = 0;
|
||||
Direct.brightness_max = 100;
|
||||
Direct.brightness = 100;
|
||||
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = ACER_HID_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.brightness_min = 0;
|
||||
Static.brightness_max = 100;
|
||||
Static.brightness = 100;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(1);
|
||||
Static.speed = 0;
|
||||
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = ACER_HID_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = 100;
|
||||
Breathing.brightness = 100;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.speed_min = 1;
|
||||
Breathing.speed_max = 5;
|
||||
Breathing.speed = 4;
|
||||
Breathing.colors.resize(1);
|
||||
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Neon;
|
||||
Neon.name = "Neon";
|
||||
Neon.value = ACER_HID_MODE_NEON;
|
||||
Neon.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Neon.color_mode = MODE_COLORS_NONE;
|
||||
Neon.brightness_min = 0;
|
||||
Neon.brightness_max = 100;
|
||||
Neon.brightness = 100;
|
||||
Neon.speed_min = 1;
|
||||
Neon.speed_max = 5;
|
||||
Neon.speed = 4;
|
||||
|
||||
modes.push_back(Neon);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_AcerNitroHidLed::~RGBController_AcerNitroHidLed()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::SetupZones()
|
||||
{
|
||||
zone* new_zone = new zone;
|
||||
|
||||
new_zone->name = "LED";
|
||||
new_zone->type = ZONE_TYPE_LINEAR;
|
||||
new_zone->leds_min = 1;
|
||||
new_zone->leds_max = 1;
|
||||
new_zone->leds_count = 1;
|
||||
zones.push_back(*new_zone);
|
||||
|
||||
led* new_led = new led();
|
||||
new_led->name = "LED";
|
||||
new_led->value = (unsigned int)leds.size();
|
||||
leds.push_back(*new_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::DeviceUpdateLEDs()
|
||||
{
|
||||
mode& current_mode = modes[active_mode];
|
||||
if(current_mode.value == ACER_HID_MODE_DIRECT)
|
||||
{
|
||||
controller->SetLEDs(colors, current_mode.brightness, device_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
RGBColor color = current_mode.colors.size()==0? (RGBColor)0 : current_mode.colors[0];
|
||||
unsigned char direction = 1;
|
||||
if((modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR) && modes[active_mode].direction)
|
||||
{
|
||||
direction = 2;
|
||||
}
|
||||
controller->SetAllLEDs(color, current_mode.brightness, current_mode.speed, direction, current_mode.value, device_id);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::DeviceUpdateZoneLEDs(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::DeviceUpdateSingleLED(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidLed.cpp |
|
||||
| |
|
||||
| RGBController for Acer Nitro HID LED |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "AcerNitroHidKeyboardController.h"
|
||||
#include "RGBController_AcerNitroHidKeyboard.h"
|
||||
|
||||
class RGBController_AcerNitroHidLed : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_AcerNitroHidLed(std::shared_ptr<AcerNitroHidKeyboardController> controller);
|
||||
~RGBController_AcerNitroHidLed();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
std::shared_ptr<AcerNitroHidKeyboardController> controller;
|
||||
unsigned int device_id;
|
||||
};
|
||||
+4
-26
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| AlienwareKeyboardControllerDetect.cpp |
|
||||
| AlienwareAW410KControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Alienware Keyboard |
|
||||
| Detector for Alienware AW410K Keyboard |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -10,38 +10,17 @@
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "AlienwareAW410KController.h"
|
||||
#include "AlienwareAW510KController.h"
|
||||
#include "RGBController_AlienwareAW410K.h"
|
||||
#include "RGBController_AlienwareAW510K.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Alienware vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ALIENWARE_VID 0x04F2
|
||||
#define ALIENWARE_VID 0x04F2
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ALIENWARE_AW510K_PID 0x1830
|
||||
#define ALIENWARE_AW410K_PID 0x1968
|
||||
|
||||
DetectedControllers DetectAlienwareAW510KControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
AlienwareAW510KController* controller = new AlienwareAW510KController(dev, info->path, name);
|
||||
RGBController_AlienwareAW510K* rgb_controller = new RGBController_AlienwareAW510K(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
#define ALIENWARE_AW410K_PID 0x1968
|
||||
|
||||
DetectedControllers DetectAlienwareAW410KControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
@@ -61,5 +40,4 @@ DetectedControllers DetectAlienwareAW410KControllers(hid_device_info* info, cons
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Alienware AW510K", DetectAlienwareAW510KControllers, ALIENWARE_VID, ALIENWARE_AW510K_PID, 0x02, 0xFF00, 0x01);
|
||||
REGISTER_HID_DETECTOR_IPU("Alienware AW410K", DetectAlienwareAW410KControllers, ALIENWARE_VID, ALIENWARE_AW410K_PID, 0x02, 0xFF00, 0x01);
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| AlienwareAW510KControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Alienware AW510K Keyboard |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "AlienwareAW510KController.h"
|
||||
#include "RGBController_AlienwareAW510K.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Alienware vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ALIENWARE_VID 0x04F2
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ALIENWARE_AW510K_PID 0x1830
|
||||
|
||||
DetectedControllers DetectAlienwareAW510KControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
AlienwareAW510KController* controller = new AlienwareAW510KController(dev, info->path, name);
|
||||
RGBController_AlienwareAW510K* rgb_controller = new RGBController_AlienwareAW510K(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Alienware AW510K", DetectAlienwareAW510KControllers, ALIENWARE_VID, ALIENWARE_AW510K_PID, 0x02, 0xFF00, 0x01);
|
||||
@@ -1,22 +1,25 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardController.cpp |
|
||||
| |
|
||||
| Driver for Clevo laptop per-key RGB keyboard (ITE 8291) |
|
||||
| Protocol based on tuxedo-drivers ite_8291 module |
|
||||
| Driver for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| |
|
||||
| Kyle Cascade ([email protected]) 16 Jan 2026 |
|
||||
| Valentin Lobstein ([email protected]) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include "ClevoKeyboardController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
ClevoKeyboardController::ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info)
|
||||
ClevoKeyboardController::ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info, clevo_keyboard_type kb_type)
|
||||
{
|
||||
dev = dev_handle;
|
||||
type = kb_type;
|
||||
location = info.path;
|
||||
version = info.release_number;
|
||||
}
|
||||
@@ -26,6 +29,31 @@ ClevoKeyboardController::~ClevoKeyboardController()
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
clevo_keyboard_type ClevoKeyboardController::GetType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
int ClevoKeyboardController::GetNumRows()
|
||||
{
|
||||
return(type == CLEVO_KB_ITE829X) ? CLEVO_829X_NUM_ROWS : CLEVO_8291_NUM_ROWS;
|
||||
}
|
||||
|
||||
int ClevoKeyboardController::GetNumCols()
|
||||
{
|
||||
return(type == CLEVO_KB_ITE829X) ? CLEVO_829X_NUM_COLS : CLEVO_8291_NUM_COLS;
|
||||
}
|
||||
|
||||
int ClevoKeyboardController::GetNumLEDs()
|
||||
{
|
||||
return GetNumRows() * GetNumCols();
|
||||
}
|
||||
|
||||
unsigned char ClevoKeyboardController::GetBrightnessMax()
|
||||
{
|
||||
return(type == CLEVO_KB_ITE829X) ? CLEVO_829X_BRIGHTNESS_MAX : CLEVO_8291_BRIGHTNESS_MAX;
|
||||
}
|
||||
|
||||
std::string ClevoKeyboardController::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
@@ -51,147 +79,355 @@ std::string ClevoKeyboardController::GetFirmwareVersion()
|
||||
return(version_string);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::WriteControl(unsigned char* data)
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291: 8-byte feature report, no report ID |
|
||||
\*---------------------------------------------------------*/
|
||||
void ClevoKeyboardController::WriteControl8291(unsigned char* data)
|
||||
{
|
||||
hid_send_feature_report(dev, data, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
hid_send_feature_report(dev, data, CLEVO_8291_REPORT_SIZE);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::WriteRowData(unsigned char* data)
|
||||
{
|
||||
hid_write(dev, data, CLEVO_KEYBOARD_ROW_DATA_SIZE);
|
||||
hid_write(dev, data, CLEVO_8291_ROW_DATA_SIZE);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x: 6-byte feature report with report ID 0xCC |
|
||||
\*---------------------------------------------------------*/
|
||||
void ClevoKeyboardController::SendCommand829x(unsigned char cmd, unsigned char d0, unsigned char d1, unsigned char d2, unsigned char d3)
|
||||
{
|
||||
unsigned char buf[CLEVO_829X_REPORT_SIZE];
|
||||
|
||||
buf[0] = CLEVO_829X_REPORT_ID;
|
||||
buf[1] = cmd;
|
||||
buf[2] = d0;
|
||||
buf[3] = d1;
|
||||
buf[4] = d2;
|
||||
buf[5] = d3;
|
||||
|
||||
hid_send_feature_report(dev, buf, CLEVO_829X_REPORT_SIZE);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::TurnOff()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Turn off: 08 01 00 00 00 00 00 00 |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char buf[CLEVO_KEYBOARD_REPORT_SIZE];
|
||||
if(type == CLEVO_KB_ITE829X)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_BRIGHTNESS);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
buf[0] = 0x08;
|
||||
buf[1] = 0x01;
|
||||
|
||||
WriteControl(buf);
|
||||
unsigned char buf[CLEVO_8291_REPORT_SIZE];
|
||||
memset(buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
buf[0] = CLEVO_8291_CMD_MODE;
|
||||
buf[1] = CLEVO_8291_POWER_OFF;
|
||||
WriteControl8291(buf);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SetMode(unsigned char mode, unsigned char brightness, unsigned char speed, unsigned char behaviour)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set params: 08 [power] [mode] [speed] [brightness] 08 |
|
||||
| [behaviour] 00 |
|
||||
| power: 01=off, 02=on |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char buf[CLEVO_KEYBOARD_REPORT_SIZE];
|
||||
if(type == CLEVO_KB_ITE829X)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_BRIGHTNESS, brightness, speed);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
buf[0] = 0x08;
|
||||
buf[1] = 0x02; // Power on
|
||||
unsigned char buf[CLEVO_8291_REPORT_SIZE];
|
||||
memset(buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
buf[0] = CLEVO_8291_CMD_MODE;
|
||||
buf[1] = CLEVO_8291_POWER_ON;
|
||||
buf[2] = mode;
|
||||
buf[3] = speed;
|
||||
buf[4] = brightness;
|
||||
buf[5] = 0x08;
|
||||
buf[5] = CLEVO_8291_MODE_FLAG;
|
||||
buf[6] = behaviour;
|
||||
|
||||
WriteControl(buf);
|
||||
WriteControl8291(buf);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SetModeColor(unsigned char color_idx, unsigned char red, unsigned char green, unsigned char blue)
|
||||
void ClevoKeyboardController::SetModeColor(unsigned char color_idx, RGBColor color)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set color define: 14 00 [index] R G B 00 00 |
|
||||
| index: 1-7 for built-in effects |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char buf[CLEVO_KEYBOARD_REPORT_SIZE];
|
||||
|
||||
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
buf[0] = 0x14;
|
||||
buf[1] = 0x00;
|
||||
buf[2] = color_idx;
|
||||
buf[3] = red;
|
||||
buf[4] = green;
|
||||
buf[5] = blue;
|
||||
|
||||
WriteControl(buf);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SendColors(unsigned char* color_data, unsigned char brightness)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Per-key RGB mode (mode 0x33) |
|
||||
| 1. Set params with mode 0x33 and brightness |
|
||||
| 2. For each row 0-5: |
|
||||
| - Announce row: 16 00 [row] 00 00 00 00 00 |
|
||||
| - Send 65 bytes row data via output report |
|
||||
| |
|
||||
| Row data format (65 bytes): |
|
||||
| [0x00 padding][0x00 padding] |
|
||||
| [B0..B20][G0..G20][R0..R20] |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char ctrl_buf[CLEVO_KEYBOARD_REPORT_SIZE];
|
||||
unsigned char row_buf[CLEVO_KEYBOARD_ROW_DATA_SIZE];
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Clamp brightness |
|
||||
\*---------------------------------------------------------*/
|
||||
if(brightness > CLEVO_KEYBOARD_BRIGHTNESS_MAX)
|
||||
if(type == CLEVO_KB_ITE829X)
|
||||
{
|
||||
brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char buf[CLEVO_8291_REPORT_SIZE];
|
||||
memset(buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
buf[0] = CLEVO_8291_CMD_COLOR;
|
||||
buf[2] = color_idx;
|
||||
buf[3] = RGBGetRValue(color);
|
||||
buf[4] = RGBGetGValue(color);
|
||||
buf[5] = RGBGetBValue(color);
|
||||
WriteControl8291(buf);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SetBrightnessSpeed829x(unsigned char brightness, unsigned char speed)
|
||||
{
|
||||
if(brightness > CLEVO_829X_BRIGHTNESS_MAX)
|
||||
{
|
||||
brightness = CLEVO_829X_BRIGHTNESS_MAX;
|
||||
}
|
||||
|
||||
if(brightness != current_brightness_829x || speed != current_speed_829x)
|
||||
{
|
||||
current_brightness_829x = brightness;
|
||||
current_speed_829x = speed;
|
||||
SendCommand829x(CLEVO_829X_CMD_BRIGHTNESS, brightness, speed);
|
||||
}
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SendColorSlot829x(unsigned char cmd, unsigned char slot, RGBColor color)
|
||||
{
|
||||
SendCommand829x(cmd, slot, RGBGetRValue(color), RGBGetGValue(color), RGBGetBValue(color));
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x: Save/Clear BIOS keyboard state |
|
||||
\*---------------------------------------------------------*/
|
||||
void ClevoKeyboardController::SaveToBios829x()
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_SAVE_BIOS, 0x01);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::ClearBiosSave829x()
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_SAVE_BIOS, 0x00);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::StopAnimation829x()
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_ANIM, CLEVO_829X_CMD_STOP_ANIM);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SetEffect829x(unsigned char mode_value, const std::vector<RGBColor>& colors, unsigned int direction, unsigned int color_mode)
|
||||
{
|
||||
bool mode_changed = (mode_value != current_mode_829x);
|
||||
current_mode_829x = mode_value;
|
||||
bool use_custom_color = (color_mode != MODE_COLORS_RANDOM) && !colors.empty();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Animation modes: send [CC, 00, mode_id] on mode change |
|
||||
\*---------------------------------------------------------*/
|
||||
struct anim_entry { unsigned char mode; unsigned char anim_id; };
|
||||
static const anim_entry anim_modes[] =
|
||||
{
|
||||
{ CLEVO_829X_MODE_WAVE, 0x04 },
|
||||
{ CLEVO_829X_MODE_RANDOM, 0x09 },
|
||||
{ CLEVO_829X_MODE_SCAN, 0x0A },
|
||||
{ CLEVO_829X_MODE_SNAKE, 0x0B },
|
||||
{ CLEVO_829X_MODE_RAINBOW_CYCLE, 0x02 },
|
||||
{ CLEVO_829X_MODE_RAINBOW_GRAD, 0x04 },
|
||||
};
|
||||
|
||||
const anim_entry* anim_it = std::find_if(std::begin(anim_modes), std::end(anim_modes),
|
||||
[mode_value](const anim_entry& e) { return e.mode == mode_value; });
|
||||
|
||||
if(anim_it != std::end(anim_modes) && mode_changed)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_ANIM, anim_it->anim_id);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set params for per-key mode |
|
||||
| Direction-based effects (Wave/Snake) |
|
||||
| Slot = base + direction_index |
|
||||
| Custom color: base = 0xA1, Preset: base = 0x71 |
|
||||
\*---------------------------------------------------------*/
|
||||
memset(ctrl_buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
ctrl_buf[0] = 0x08;
|
||||
ctrl_buf[1] = 0x02; // Power on
|
||||
ctrl_buf[2] = CLEVO_KEYBOARD_MODE_DIRECT; // Per-key mode
|
||||
ctrl_buf[3] = 0x00; // Speed (unused)
|
||||
ctrl_buf[4] = brightness;
|
||||
ctrl_buf[5] = 0x00;
|
||||
ctrl_buf[6] = 0x00;
|
||||
/*---------------------------------------------------------*\
|
||||
| Map OpenRGB direction enum to firmware slot index |
|
||||
\*---------------------------------------------------------*/
|
||||
static const unsigned char dir_to_wave_idx[] =
|
||||
{
|
||||
6, /* MODE_DIRECTION_LEFT */
|
||||
7, /* MODE_DIRECTION_RIGHT */
|
||||
4, /* MODE_DIRECTION_UP */
|
||||
5, /* MODE_DIRECTION_DOWN */
|
||||
6, /* MODE_DIRECTION_HORIZONTAL */
|
||||
4, /* MODE_DIRECTION_VERTICAL */
|
||||
0, /* MODE_DIRECTION_UP_LEFT */
|
||||
1, /* MODE_DIRECTION_UP_RIGHT */
|
||||
2, /* MODE_DIRECTION_DOWN_LEFT */
|
||||
3, /* MODE_DIRECTION_DOWN_RIGHT */
|
||||
};
|
||||
|
||||
WriteControl(ctrl_buf);
|
||||
static const unsigned char dir_to_snake_idx[] =
|
||||
{
|
||||
0, /* MODE_DIRECTION_LEFT */
|
||||
0, /* MODE_DIRECTION_RIGHT */
|
||||
0, /* MODE_DIRECTION_UP */
|
||||
0, /* MODE_DIRECTION_DOWN */
|
||||
0, /* MODE_DIRECTION_HORIZONTAL */
|
||||
0, /* MODE_DIRECTION_VERTICAL */
|
||||
0, /* MODE_DIRECTION_UP_LEFT */
|
||||
1, /* MODE_DIRECTION_UP_RIGHT */
|
||||
2, /* MODE_DIRECTION_DOWN_LEFT */
|
||||
3, /* MODE_DIRECTION_DOWN_RIGHT */
|
||||
};
|
||||
|
||||
if((mode_value == CLEVO_829X_MODE_WAVE || mode_value == CLEVO_829X_MODE_RAINBOW_GRAD) && direction < sizeof(dir_to_wave_idx))
|
||||
{
|
||||
unsigned char base = use_custom_color ? CLEVO_829X_COLOR_SLOT_BASE : CLEVO_829X_PRESET_SLOT_BASE;
|
||||
unsigned char idx = dir_to_wave_idx[direction];
|
||||
unsigned char slot = base + idx;
|
||||
|
||||
if(use_custom_color)
|
||||
{
|
||||
SendColorSlot829x(CLEVO_829X_CMD_WAVE_COLOR, slot, colors[0]);
|
||||
}
|
||||
|
||||
if(!use_custom_color)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_WAVE_COLOR, slot);
|
||||
}
|
||||
}
|
||||
|
||||
if(mode_value == CLEVO_829X_MODE_SNAKE && direction < sizeof(dir_to_snake_idx))
|
||||
{
|
||||
unsigned char base = use_custom_color ? CLEVO_829X_COLOR_SLOT_BASE : CLEVO_829X_PRESET_SLOT_BASE;
|
||||
unsigned char idx = dir_to_snake_idx[direction];
|
||||
unsigned char slot = base + idx;
|
||||
|
||||
if(use_custom_color)
|
||||
{
|
||||
SendColorSlot829x(CLEVO_829X_CMD_SNAKE_COLOR, slot, colors[0]);
|
||||
}
|
||||
|
||||
if(!use_custom_color)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_SNAKE_COLOR, slot);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Send each row |
|
||||
| Breathing/Flashing: random or custom color |
|
||||
\*---------------------------------------------------------*/
|
||||
for(int row = 0; row < CLEVO_KEYBOARD_NUM_ROWS; row++)
|
||||
if(mode_value == CLEVO_829X_MODE_BREATH && use_custom_color)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Announce row data |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(ctrl_buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
ctrl_buf[0] = 0x16;
|
||||
ctrl_buf[1] = 0x00;
|
||||
ctrl_buf[2] = row;
|
||||
SendColorSlot829x(0x0A, CLEVO_829X_COLOR_CUSTOM, colors[0]);
|
||||
}
|
||||
|
||||
WriteControl(ctrl_buf);
|
||||
if(mode_value == CLEVO_829X_MODE_BREATH && !use_custom_color)
|
||||
{
|
||||
SendCommand829x(0x0A);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Build row data buffer |
|
||||
| Format: [pad][pad][B0..B20][G0..G20][R0..R20] |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(row_buf, 0x00, CLEVO_KEYBOARD_ROW_DATA_SIZE);
|
||||
if(mode_value == CLEVO_829X_MODE_BLINK && use_custom_color)
|
||||
{
|
||||
SendColorSlot829x(0x0B, CLEVO_829X_COLOR_CUSTOM, colors[0]);
|
||||
}
|
||||
|
||||
for(int col = 0; col < CLEVO_KEYBOARD_NUM_COLS; col++)
|
||||
if(mode_value == CLEVO_829X_MODE_BLINK && !use_custom_color)
|
||||
{
|
||||
SendCommand829x(0x0B);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Random: custom color only (multicolor is the default) |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == CLEVO_829X_MODE_RANDOM && use_custom_color)
|
||||
{
|
||||
SendColorSlot829x(CLEVO_829X_CMD_RANDOM_COLOR, CLEVO_829X_COLOR_SLOT_BASE, colors[0]);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Scan: 2 custom color bands |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == CLEVO_829X_MODE_SCAN)
|
||||
{
|
||||
for(size_t i = 0; i < colors.size() && i < 2; i++)
|
||||
{
|
||||
int led_idx = (row * CLEVO_KEYBOARD_NUM_COLS) + col;
|
||||
int color_offset = led_idx * 3;
|
||||
SendColorSlot829x(CLEVO_829X_CMD_SCAN_COLOR, CLEVO_829X_COLOR_SLOT_BASE + i, colors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char red = color_data[color_offset + 0];
|
||||
unsigned char green = color_data[color_offset + 1];
|
||||
unsigned char blue = color_data[color_offset + 2];
|
||||
/*---------------------------------------------------------*\
|
||||
| Fn Highlight: per-key color on function keys |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == CLEVO_829X_MODE_FN_COLOR && !colors.empty())
|
||||
{
|
||||
static const unsigned char fn_keys[] =
|
||||
{
|
||||
0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x09,
|
||||
0x0A, 0x0B, 0x0C, 0x21, 0x23, 0x31, 0x32, 0x33,
|
||||
0x53, 0x73, 0xA2
|
||||
};
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Row data layout (after 2-byte padding): |
|
||||
| Bytes 2-22: Blue values for columns 0-20 |
|
||||
| Bytes 23-43: Green values for columns 0-20 |
|
||||
| Bytes 44-64: Red values for columns 0-20 |
|
||||
\*-------------------------------------------------*/
|
||||
row_buf[2 + col] = blue;
|
||||
row_buf[2 + CLEVO_KEYBOARD_NUM_COLS + col] = green;
|
||||
row_buf[2 + CLEVO_KEYBOARD_NUM_COLS*2 + col] = red;
|
||||
SendCommand829x(CLEVO_829X_CMD_ANIM, CLEVO_829X_CMD_CLEAR);
|
||||
|
||||
for(unsigned char key : fn_keys)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_SET_LED, key,
|
||||
RGBGetRValue(colors[0]),
|
||||
RGBGetGValue(colors[0]),
|
||||
RGBGetBValue(colors[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SendColors(const unsigned char* color_data, unsigned char brightness, unsigned char speed)
|
||||
{
|
||||
int num_rows = GetNumRows();
|
||||
int num_cols = GetNumCols();
|
||||
|
||||
if(type == CLEVO_KB_ITE829X)
|
||||
{
|
||||
if(brightness > CLEVO_829X_BRIGHTNESS_MAX)
|
||||
{
|
||||
brightness = CLEVO_829X_BRIGHTNESS_MAX;
|
||||
}
|
||||
|
||||
SendCommand829x(CLEVO_829X_CMD_BRIGHTNESS, brightness, speed);
|
||||
|
||||
for(int row = 0; row < num_rows; row++)
|
||||
{
|
||||
for(int col = 0; col < num_cols; col++)
|
||||
{
|
||||
int idx = (row * num_cols + col) * 3;
|
||||
|
||||
SendCommand829x(CLEVO_829X_CMD_SET_LED,
|
||||
CLEVO_829X_LED_ID(row, col),
|
||||
color_data[idx + 0],
|
||||
color_data[idx + 1],
|
||||
color_data[idx + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291: row-based color transfer |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char ctrl_buf[CLEVO_8291_REPORT_SIZE];
|
||||
unsigned char row_buf[CLEVO_8291_ROW_DATA_SIZE];
|
||||
|
||||
if(brightness > CLEVO_8291_BRIGHTNESS_MAX)
|
||||
{
|
||||
brightness = CLEVO_8291_BRIGHTNESS_MAX;
|
||||
}
|
||||
|
||||
memset(ctrl_buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
ctrl_buf[0] = CLEVO_8291_CMD_MODE;
|
||||
ctrl_buf[1] = CLEVO_8291_POWER_ON;
|
||||
ctrl_buf[2] = CLEVO_KEYBOARD_MODE_DIRECT;
|
||||
ctrl_buf[4] = brightness;
|
||||
WriteControl8291(ctrl_buf);
|
||||
|
||||
for(int row = 0; row < num_rows; row++)
|
||||
{
|
||||
memset(ctrl_buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
ctrl_buf[0] = CLEVO_8291_CMD_ROW;
|
||||
ctrl_buf[2] = row;
|
||||
WriteControl8291(ctrl_buf);
|
||||
|
||||
memset(row_buf, 0x00, CLEVO_8291_ROW_DATA_SIZE);
|
||||
|
||||
for(int col = 0; col < num_cols; col++)
|
||||
{
|
||||
int idx = (row * num_cols + col) * 3;
|
||||
|
||||
row_buf[2 + col] = color_data[idx + 2];
|
||||
row_buf[2 + num_cols + col] = color_data[idx + 1];
|
||||
row_buf[2 + num_cols * 2 + col] = color_data[idx + 0];
|
||||
}
|
||||
|
||||
WriteRowData(row_buf);
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardController.h |
|
||||
| |
|
||||
| Driver for Clevo laptop per-key RGB keyboard (ITE 8291) |
|
||||
| Driver for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| |
|
||||
| Kyle Cascade ([email protected]) 16 Jan 2026 |
|
||||
| Valentin Lobstein ([email protected]) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -12,27 +14,75 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| ITE 8291 keyboard defines |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CLEVO_KEYBOARD_REPORT_SIZE 8
|
||||
#define CLEVO_KEYBOARD_ROW_DATA_SIZE 65
|
||||
/*---------------------------------------------------------*\
|
||||
| Device type enumeration |
|
||||
\*---------------------------------------------------------*/
|
||||
enum clevo_keyboard_type
|
||||
{
|
||||
CLEVO_KB_ITE8291,
|
||||
CLEVO_KB_ITE829X,
|
||||
};
|
||||
|
||||
#define CLEVO_KEYBOARD_NUM_ROWS 6
|
||||
#define CLEVO_KEYBOARD_NUM_COLS 21
|
||||
#define CLEVO_KEYBOARD_NUM_LEDS (CLEVO_KEYBOARD_NUM_ROWS * CLEVO_KEYBOARD_NUM_COLS)
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291 keyboard defines (PID 0x600B) |
|
||||
| 8 bytes, no report ID, row-based color data |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CLEVO_8291_REPORT_SIZE 8
|
||||
#define CLEVO_8291_ROW_DATA_SIZE 65
|
||||
#define CLEVO_8291_NUM_ROWS 6
|
||||
#define CLEVO_8291_NUM_COLS 21
|
||||
#define CLEVO_8291_NUM_LEDS (CLEVO_8291_NUM_ROWS * CLEVO_8291_NUM_COLS)
|
||||
#define CLEVO_8291_BRIGHTNESS_MAX 0x32
|
||||
#define CLEVO_8291_CMD_MODE 0x08
|
||||
#define CLEVO_8291_CMD_COLOR 0x14
|
||||
#define CLEVO_8291_CMD_ROW 0x16
|
||||
#define CLEVO_8291_POWER_OFF 0x01
|
||||
#define CLEVO_8291_POWER_ON 0x02
|
||||
#define CLEVO_8291_MODE_FLAG 0x08
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x keyboard defines (PID 0x8910) |
|
||||
| 6 bytes with report ID 0xCC, per-key color commands |
|
||||
| Protocol: [0xCC, cmd, d0, d1, d2, d3] |
|
||||
| LED ID: ((row & 0x07) << 5) | (col & 0x1F) |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CLEVO_829X_REPORT_ID 0xCC
|
||||
#define CLEVO_829X_REPORT_SIZE 6
|
||||
#define CLEVO_829X_NUM_ROWS 6
|
||||
#define CLEVO_829X_NUM_COLS 20
|
||||
#define CLEVO_829X_NUM_LEDS (CLEVO_829X_NUM_ROWS * CLEVO_829X_NUM_COLS)
|
||||
#define CLEVO_829X_BRIGHTNESS_MAX 0x0A
|
||||
#define CLEVO_829X_LED_ID(row, col) (unsigned char)((((row) & 0x07) << 5) | ((col) & 0x1F))
|
||||
|
||||
#define CLEVO_829X_CMD_SET_LED 0x01
|
||||
#define CLEVO_829X_CMD_BRIGHTNESS 0x09
|
||||
#define CLEVO_829X_CMD_ANIM 0x00
|
||||
#define CLEVO_829X_CMD_CLEAR 0x0C
|
||||
#define CLEVO_829X_CMD_WAVE_COLOR 0x15
|
||||
#define CLEVO_829X_CMD_SNAKE_COLOR 0x16
|
||||
#define CLEVO_829X_CMD_SCAN_COLOR 0x17
|
||||
#define CLEVO_829X_CMD_RANDOM_COLOR 0x18
|
||||
#define CLEVO_829X_COLOR_CUSTOM 0xAA
|
||||
#define CLEVO_829X_COLOR_SLOT_BASE 0xA1
|
||||
#define CLEVO_829X_PRESET_SLOT_BASE 0x71
|
||||
#define CLEVO_829X_CMD_SAVE_BIOS 0x20
|
||||
#define CLEVO_829X_CMD_STOP_ANIM 0x03
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Shared defines |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CLEVO_KEYBOARD_BRIGHTNESS_MIN 0x00
|
||||
#define CLEVO_KEYBOARD_BRIGHTNESS_MAX 0x32
|
||||
|
||||
#define CLEVO_KEYBOARD_SPEED_MIN 0x01
|
||||
#define CLEVO_KEYBOARD_SPEED_MIN 0x00
|
||||
#define CLEVO_KEYBOARD_SPEED_MAX 0x0A
|
||||
#define CLEVO_KEYBOARD_SPEED_DEFAULT 0x00
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| ITE 8291 modes |
|
||||
\*-----------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291 modes |
|
||||
\*---------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CLEVO_KEYBOARD_MODE_DIRECT = 0x33,
|
||||
@@ -47,9 +97,36 @@ enum
|
||||
CLEVO_KEYBOARD_MODE_SPARK = 0x11,
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Wave/reactive behaviour |
|
||||
\*-----------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x firmware modes |
|
||||
| Two command styles: |
|
||||
| cmd=0x00, d0=mode_id (animation select) |
|
||||
| cmd=mode_id, d0=0x00 (standalone effects) |
|
||||
\*---------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CLEVO_829X_MODE_DIRECT = 0xFD,
|
||||
CLEVO_829X_MODE_WAVE = 0xA0,
|
||||
CLEVO_829X_MODE_WAVE_COLOR = 0xB0,
|
||||
CLEVO_829X_MODE_BREATH = 0xA1,
|
||||
CLEVO_829X_MODE_BREATH_COLOR = 0xB1,
|
||||
CLEVO_829X_MODE_BLINK = 0xA2,
|
||||
CLEVO_829X_MODE_BLINK_COLOR = 0xB2,
|
||||
CLEVO_829X_MODE_RANDOM = 0xA3,
|
||||
CLEVO_829X_MODE_RANDOM_COLOR = 0xA9,
|
||||
CLEVO_829X_MODE_SCAN = 0xA4,
|
||||
/* Ripple (0x07) requires Insyde BIOS EC config, not supported */
|
||||
CLEVO_829X_MODE_SNAKE = 0xA6,
|
||||
CLEVO_829X_MODE_SNAKE_COLOR = 0xB6,
|
||||
CLEVO_829X_MODE_RAINBOW_CYCLE = 0xA7,
|
||||
CLEVO_829X_MODE_RAINBOW_GRAD = 0xA8,
|
||||
CLEVO_829X_MODE_FN_COLOR = 0xAF,
|
||||
CLEVO_829X_MODE_OFF = 0xFF,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Wave/reactive behaviour |
|
||||
\*---------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CLEVO_KEYBOARD_DIRECTION_LEFT = 0x01,
|
||||
@@ -67,23 +144,40 @@ enum
|
||||
class ClevoKeyboardController
|
||||
{
|
||||
public:
|
||||
ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info);
|
||||
ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info, clevo_keyboard_type kb_type);
|
||||
~ClevoKeyboardController();
|
||||
|
||||
clevo_keyboard_type GetType();
|
||||
int GetNumRows();
|
||||
int GetNumCols();
|
||||
int GetNumLEDs();
|
||||
unsigned char GetBrightnessMax();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetSerialString();
|
||||
std::string GetFirmwareVersion();
|
||||
|
||||
void TurnOff();
|
||||
void SetMode(unsigned char mode, unsigned char brightness, unsigned char speed, unsigned char behaviour);
|
||||
void SetModeColor(unsigned char color_idx, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SendColors(unsigned char* color_data, unsigned char brightness);
|
||||
void SetModeColor(unsigned char color_idx, RGBColor color);
|
||||
void SendColors(const unsigned char* color_data, unsigned char brightness, unsigned char speed);
|
||||
void SetEffect829x(unsigned char mode_value, const std::vector<RGBColor>& colors, unsigned int direction = 0, unsigned int color_mode = 0);
|
||||
void SetBrightnessSpeed829x(unsigned char brightness, unsigned char speed);
|
||||
void SaveToBios829x();
|
||||
void ClearBiosSave829x();
|
||||
void StopAnimation829x();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
unsigned short version;
|
||||
hid_device* dev;
|
||||
clevo_keyboard_type type;
|
||||
std::string location;
|
||||
unsigned short version;
|
||||
unsigned char current_mode_829x = 0xFF;
|
||||
unsigned char current_brightness_829x = 0xFF;
|
||||
unsigned char current_speed_829x = 0xFF;
|
||||
|
||||
void WriteControl(unsigned char* data);
|
||||
void WriteControl8291(unsigned char* data);
|
||||
void WriteRowData(unsigned char* data);
|
||||
void SendCommand829x(unsigned char cmd, unsigned char d0 = 0, unsigned char d1 = 0, unsigned char d2 = 0, unsigned char d3 = 0);
|
||||
void SendColorSlot829x(unsigned char cmd, unsigned char slot, RGBColor color);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Clevo per-key RGB keyboard (ITE 8291) |
|
||||
| Detector for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| |
|
||||
| Kyle Cascade ([email protected]) 16 Jan 2026 |
|
||||
| Valentin Lobstein ([email protected]) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -22,11 +24,12 @@
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Clevo Keyboard product IDs |
|
||||
| These are ITE 8291 per-key RGB keyboard controllers |
|
||||
| ITE 8291 and ITE 829x per-key RGB keyboard controllers |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CLEVO_KEYBOARD_PID_600B 0x600B
|
||||
#define CLEVO_KEYBOARD_PID_8291 0x600B
|
||||
#define CLEVO_KEYBOARD_PID_829X 0x8910
|
||||
|
||||
DetectedControllers DetectClevoKeyboardControllers(hid_device_info* info, const std::string& /*name*/)
|
||||
static DetectedControllers DetectClevoKeyboard(hid_device_info* info, clevo_keyboard_type kb_type)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
@@ -35,7 +38,7 @@ DetectedControllers DetectClevoKeyboardControllers(hid_device_info* info, const
|
||||
|
||||
if(dev)
|
||||
{
|
||||
ClevoKeyboardController* controller = new ClevoKeyboardController(dev, *info);
|
||||
ClevoKeyboardController* controller = new ClevoKeyboardController(dev, *info, kb_type);
|
||||
RGBController_ClevoKeyboard* rgb_controller = new RGBController_ClevoKeyboard(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
@@ -44,4 +47,15 @@ DetectedControllers DetectClevoKeyboardControllers(hid_device_info* info, const
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_PU("CLEVO Keyboard", DetectClevoKeyboardControllers, 0x048D, 0x600B, 0xFF03, 0x01);
|
||||
DetectedControllers DetectClevoKeyboard8291(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
return(DetectClevoKeyboard(info, CLEVO_KB_ITE8291));
|
||||
}
|
||||
|
||||
DetectedControllers DetectClevoKeyboard829x(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
return(DetectClevoKeyboard(info, CLEVO_KB_ITE829X));
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_PU("Clevo Keyboard (ITE 8291)", DetectClevoKeyboard8291, ITE_VID, CLEVO_KEYBOARD_PID_8291, 0xFF03, 0x01);
|
||||
REGISTER_HID_DETECTOR_PU("Clevo Keyboard (ITE 829x)", DetectClevoKeyboard829x, ITE_VID, CLEVO_KEYBOARD_PID_829X, 0xFF89, 0xCC);
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardDevices.cpp |
|
||||
| |
|
||||
| Device list for Clevo per-key RGB keyboards (ITE 8291) |
|
||||
| Device list for Clevo per-key RGB keyboards |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| |
|
||||
| Kyle Cascade ([email protected]) 21 Jan 2026 |
|
||||
| Valentin Lobstein ([email protected]) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -112,6 +114,48 @@ static const std::vector<unsigned int> clevo_tkl_values =
|
||||
15, // Right
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x LED value mapping |
|
||||
| LED ID = ((row & 7) << 5) | col |
|
||||
| Row 5 (F-keys) = 0xA0+, Row 4 (numbers) = 0x80+ |
|
||||
| Row 3 (QWERTY) = 0x60+, Row 2 (home) = 0x40+ |
|
||||
| Row 1 (Z row) = 0x20+, Row 0 (mods) = 0x00+ |
|
||||
\*---------------------------------------------------------*/
|
||||
static const std::vector<unsigned int> clevo_829x_full_values =
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Values in FULL layout visual order (same as CM keyboard) |
|
||||
| LED ID = ((row & 7) << 5) | col |
|
||||
| Row counts: 16, 21, 21, 17, 18, 13 |
|
||||
\*---------------------------------------------------------*/
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0, 0,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BSPC INS HOME PGUP NMLK NMDV NMTM NMMI */
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2D, 0x2E, 0x0E, 0x10, 0x12, 0x30, 0x31, 0x32, 0x33,
|
||||
/* TAB Q W E R T Y U I O P [ ] ANSI\ DEL END PGDN NM7 NM8 NM9 NMPL */
|
||||
0x40, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x0F, 0x11, 0x13, 0x50, 0x51, 0x52, 0x53,
|
||||
/* CPLK A S D F G H J K L ; ' # ENTR NM4 NM5 NM6 */
|
||||
0x60, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0, 0x6E, 0x70, 0x71, 0x72,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER */
|
||||
0x80, 0, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8F, 0x90, 0x91, 0x92, 0x93,
|
||||
/* LCTL LFNC LWIN LALT SPACE RALT RMNU RCTL ARWL ARDN ARWR NM0 NMPD */
|
||||
0xA0, 0xA2, 0xA3, 0xA4, 0xA5, 0xAA, 0xAB, 0xAC, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2,
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values clevo_829x_keyboard_layout
|
||||
{
|
||||
KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
clevo_829x_full_values,
|
||||
{
|
||||
/* No regional overlays needed */
|
||||
}
|
||||
},
|
||||
{
|
||||
/* No edit keys needed - all keys defined in full layout */
|
||||
}
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values clevo_keyboard_layout
|
||||
{
|
||||
KEYBOARD_SIZE_TKL,
|
||||
@@ -122,10 +166,9 @@ keyboard_keymap_overlay_values clevo_keyboard_layout
|
||||
}
|
||||
},
|
||||
{
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, Alternate Name, OpCode, |
|
||||
\*-------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Remove keys not present on Clevo keyboard |
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardDevices.h |
|
||||
| |
|
||||
| Device list for Clevo per-key RGB keyboards (ITE 8291) |
|
||||
| Device list for Clevo per-key RGB keyboards |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| |
|
||||
| Kyle Cascade ([email protected]) 21 Jan 2026 |
|
||||
| Valentin Lobstein ([email protected]) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -14,7 +16,8 @@
|
||||
#include <string>
|
||||
#include "KeyboardLayoutManager.h"
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Clevo keyboard layout definitions |
|
||||
\*-----------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| Clevo keyboard layout definitions |
|
||||
\*---------------------------------------------------------*/
|
||||
extern keyboard_keymap_overlay_values clevo_keyboard_layout;
|
||||
extern keyboard_keymap_overlay_values clevo_829x_keyboard_layout;
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_ClevoKeyboard.cpp |
|
||||
| |
|
||||
| RGBController for Clevo per-key RGB keyboard (ITE 8291) |
|
||||
| RGBController for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| |
|
||||
| Kyle Cascade ([email protected]) 16 Jan 2026 |
|
||||
| Valentin Lobstein ([email protected]) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <vector>
|
||||
#include "RGBController_ClevoKeyboard.h"
|
||||
#include "KeyboardLayoutManager.h"
|
||||
|
||||
@@ -40,152 +43,306 @@ RGBController_ClevoKeyboard::RGBController_ClevoKeyboard(ClevoKeyboardController
|
||||
Direct.value = CLEVO_KEYBOARD_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Direct.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Direct.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Direct.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Direct.brightness_max = controller->GetBrightnessMax();
|
||||
Direct.brightness = controller->GetBrightnessMax();
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = CLEVO_KEYBOARD_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Rainbow.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Rainbow.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Rainbow.speed = 0x05;
|
||||
Rainbow.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Rainbow.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Rainbow.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Rainbow);
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291 built-in effects (not available on ITE 829x) |
|
||||
\*---------------------------------------------------------*/
|
||||
if(controller->GetType() == CLEVO_KB_ITE8291)
|
||||
{
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = CLEVO_KEYBOARD_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Rainbow.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Rainbow.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Rainbow.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Rainbow.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Rainbow.brightness_max = controller->GetBrightnessMax();
|
||||
Rainbow.brightness = controller->GetBrightnessMax();
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = CLEVO_KEYBOARD_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Wave.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Wave.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Wave.speed = 0x05;
|
||||
Wave.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Wave.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Wave.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Wave.direction = MODE_DIRECTION_LEFT;
|
||||
Wave.colors_min = 1;
|
||||
Wave.colors_max = 1;
|
||||
Wave.colors.resize(1);
|
||||
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Wave);
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = CLEVO_KEYBOARD_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Wave.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Wave.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Wave.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Wave.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Wave.brightness_max = controller->GetBrightnessMax();
|
||||
Wave.brightness = controller->GetBrightnessMax();
|
||||
Wave.direction = MODE_DIRECTION_LEFT;
|
||||
Wave.colors_min = 1;
|
||||
Wave.colors_max = 1;
|
||||
Wave.colors.resize(1);
|
||||
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Wave);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CLEVO_KEYBOARD_MODE_BREATH;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Breathing.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Breathing.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Breathing.speed = 0x05;
|
||||
Breathing.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Breathing.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Breathing);
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CLEVO_KEYBOARD_MODE_BREATH;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Breathing.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Breathing.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Breathing.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Breathing.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = controller->GetBrightnessMax();
|
||||
Breathing.brightness = controller->GetBrightnessMax();
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Reactive;
|
||||
Reactive.name = "Reactive";
|
||||
Reactive.value = CLEVO_KEYBOARD_MODE_REACTIVE;
|
||||
Reactive.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Reactive.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Reactive.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Reactive.speed = 0x05;
|
||||
Reactive.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Reactive.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Reactive.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Reactive.colors_min = 1;
|
||||
Reactive.colors_max = 1;
|
||||
Reactive.colors.resize(1);
|
||||
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Reactive);
|
||||
mode Reactive;
|
||||
Reactive.name = "Reactive";
|
||||
Reactive.value = CLEVO_KEYBOARD_MODE_REACTIVE;
|
||||
Reactive.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Reactive.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Reactive.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Reactive.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Reactive.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Reactive.brightness_max = controller->GetBrightnessMax();
|
||||
Reactive.brightness = controller->GetBrightnessMax();
|
||||
Reactive.colors_min = 1;
|
||||
Reactive.colors_max = 1;
|
||||
Reactive.colors.resize(1);
|
||||
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Reactive);
|
||||
|
||||
mode Ripple;
|
||||
Ripple.name = "Ripple";
|
||||
Ripple.value = CLEVO_KEYBOARD_MODE_RIPPLE;
|
||||
Ripple.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Ripple.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Ripple.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Ripple.speed = 0x05;
|
||||
Ripple.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Ripple.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Ripple.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Ripple.colors_min = 1;
|
||||
Ripple.colors_max = 1;
|
||||
Ripple.colors.resize(1);
|
||||
Ripple.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Ripple);
|
||||
mode Ripple;
|
||||
Ripple.name = "Ripple";
|
||||
Ripple.value = CLEVO_KEYBOARD_MODE_RIPPLE;
|
||||
Ripple.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Ripple.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Ripple.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Ripple.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Ripple.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Ripple.brightness_max = controller->GetBrightnessMax();
|
||||
Ripple.brightness = controller->GetBrightnessMax();
|
||||
Ripple.colors_min = 1;
|
||||
Ripple.colors_max = 1;
|
||||
Ripple.colors.resize(1);
|
||||
Ripple.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Ripple);
|
||||
|
||||
mode Marquee;
|
||||
Marquee.name = "Marquee";
|
||||
Marquee.value = CLEVO_KEYBOARD_MODE_MARQUEE;
|
||||
Marquee.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Marquee.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Marquee.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Marquee.speed = 0x05;
|
||||
Marquee.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Marquee.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Marquee.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Marquee.colors_min = 1;
|
||||
Marquee.colors_max = 1;
|
||||
Marquee.colors.resize(1);
|
||||
Marquee.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Marquee);
|
||||
mode Marquee;
|
||||
Marquee.name = "Marquee";
|
||||
Marquee.value = CLEVO_KEYBOARD_MODE_MARQUEE;
|
||||
Marquee.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Marquee.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Marquee.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Marquee.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Marquee.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Marquee.brightness_max = controller->GetBrightnessMax();
|
||||
Marquee.brightness = controller->GetBrightnessMax();
|
||||
Marquee.colors_min = 1;
|
||||
Marquee.colors_max = 1;
|
||||
Marquee.colors.resize(1);
|
||||
Marquee.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Marquee);
|
||||
|
||||
mode Raindrop;
|
||||
Raindrop.name = "Raindrop";
|
||||
Raindrop.value = CLEVO_KEYBOARD_MODE_RAINDROP;
|
||||
Raindrop.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Raindrop.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Raindrop.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Raindrop.speed = 0x05;
|
||||
Raindrop.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Raindrop.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Raindrop.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Raindrop.colors_min = 1;
|
||||
Raindrop.colors_max = 1;
|
||||
Raindrop.colors.resize(1);
|
||||
Raindrop.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Raindrop);
|
||||
mode Raindrop;
|
||||
Raindrop.name = "Raindrop";
|
||||
Raindrop.value = CLEVO_KEYBOARD_MODE_RAINDROP;
|
||||
Raindrop.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Raindrop.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Raindrop.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Raindrop.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Raindrop.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Raindrop.brightness_max = controller->GetBrightnessMax();
|
||||
Raindrop.brightness = controller->GetBrightnessMax();
|
||||
Raindrop.colors_min = 1;
|
||||
Raindrop.colors_max = 1;
|
||||
Raindrop.colors.resize(1);
|
||||
Raindrop.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Raindrop);
|
||||
|
||||
mode Aurora;
|
||||
Aurora.name = "Aurora";
|
||||
Aurora.value = CLEVO_KEYBOARD_MODE_AURORA;
|
||||
Aurora.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Aurora.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Aurora.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Aurora.speed = 0x05;
|
||||
Aurora.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Aurora.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Aurora.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Aurora.colors_min = 1;
|
||||
Aurora.colors_max = 1;
|
||||
Aurora.colors.resize(1);
|
||||
Aurora.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Aurora);
|
||||
mode Aurora;
|
||||
Aurora.name = "Aurora";
|
||||
Aurora.value = CLEVO_KEYBOARD_MODE_AURORA;
|
||||
Aurora.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Aurora.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Aurora.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Aurora.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Aurora.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Aurora.brightness_max = controller->GetBrightnessMax();
|
||||
Aurora.brightness = controller->GetBrightnessMax();
|
||||
Aurora.colors_min = 1;
|
||||
Aurora.colors_max = 1;
|
||||
Aurora.colors.resize(1);
|
||||
Aurora.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Aurora);
|
||||
|
||||
mode Spark;
|
||||
Spark.name = "Spark";
|
||||
Spark.value = CLEVO_KEYBOARD_MODE_SPARK;
|
||||
Spark.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Spark.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Spark.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Spark.speed = 0x05;
|
||||
Spark.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Spark.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Spark.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Spark.colors_min = 1;
|
||||
Spark.colors_max = 1;
|
||||
Spark.colors.resize(1);
|
||||
Spark.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Spark);
|
||||
mode Spark;
|
||||
Spark.name = "Spark";
|
||||
Spark.value = CLEVO_KEYBOARD_MODE_SPARK;
|
||||
Spark.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Spark.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Spark.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Spark.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Spark.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Spark.brightness_max = controller->GetBrightnessMax();
|
||||
Spark.brightness = controller->GetBrightnessMax();
|
||||
Spark.colors_min = 1;
|
||||
Spark.colors_max = 1;
|
||||
Spark.colors.resize(1);
|
||||
Spark.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Spark);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x firmware effects |
|
||||
\*---------------------------------------------------------*/
|
||||
if(controller->GetType() == CLEVO_KB_ITE829X)
|
||||
{
|
||||
unsigned char bmax = controller->GetBrightnessMax();
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = CLEVO_829X_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_DIRECTION_DIAG;
|
||||
Wave.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Wave.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Wave.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Wave.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Wave.brightness_max = bmax;
|
||||
Wave.brightness = bmax;
|
||||
Wave.direction = MODE_DIRECTION_LEFT;
|
||||
Wave.colors_min = 1;
|
||||
Wave.colors_max = 1;
|
||||
Wave.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Wave);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CLEVO_829X_MODE_BREATH;
|
||||
Breathing.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Breathing.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Breathing.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Breathing.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Breathing.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = bmax;
|
||||
Breathing.brightness = bmax;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Flashing;
|
||||
Flashing.name = "Flashing";
|
||||
Flashing.value = CLEVO_829X_MODE_BLINK;
|
||||
Flashing.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Flashing.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Flashing.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Flashing.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Flashing.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Flashing.brightness_max = bmax;
|
||||
Flashing.brightness = bmax;
|
||||
Flashing.colors_min = 1;
|
||||
Flashing.colors_max = 1;
|
||||
Flashing.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Flashing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Flashing);
|
||||
|
||||
mode Random;
|
||||
Random.name = "Random";
|
||||
Random.value = CLEVO_829X_MODE_RANDOM;
|
||||
Random.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Random.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Random.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Random.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Random.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Random.brightness_max = bmax;
|
||||
Random.brightness = bmax;
|
||||
Random.colors_min = 1;
|
||||
Random.colors_max = 1;
|
||||
Random.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Random.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Random);
|
||||
|
||||
mode Scan;
|
||||
Scan.name = "Scan";
|
||||
Scan.value = CLEVO_829X_MODE_SCAN;
|
||||
Scan.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Scan.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Scan.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Scan.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Scan.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Scan.brightness_max = bmax;
|
||||
Scan.brightness = bmax;
|
||||
Scan.colors_min = 2;
|
||||
Scan.colors_max = 2;
|
||||
Scan.colors.resize(2);
|
||||
Scan.colors[0] = ToRGBColor(255, 0, 0);
|
||||
Scan.colors[1] = ToRGBColor(0, 0, 255);
|
||||
Scan.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Scan);
|
||||
|
||||
mode Snake;
|
||||
Snake.name = "Snake";
|
||||
Snake.value = CLEVO_829X_MODE_SNAKE;
|
||||
Snake.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_DIRECTION_DIAG;
|
||||
Snake.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Snake.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Snake.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Snake.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Snake.brightness_max = bmax;
|
||||
Snake.brightness = bmax;
|
||||
Snake.direction = MODE_DIRECTION_UP_LEFT;
|
||||
Snake.colors_min = 1;
|
||||
Snake.colors_max = 1;
|
||||
Snake.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Snake.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Snake);
|
||||
|
||||
mode RainbowCycle;
|
||||
RainbowCycle.name = "Spectrum Cycle";
|
||||
RainbowCycle.value = CLEVO_829X_MODE_RAINBOW_CYCLE;
|
||||
RainbowCycle.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
RainbowCycle.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
RainbowCycle.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
RainbowCycle.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
RainbowCycle.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
RainbowCycle.brightness_max = bmax;
|
||||
RainbowCycle.brightness = bmax;
|
||||
RainbowCycle.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(RainbowCycle);
|
||||
|
||||
mode RainbowGrad;
|
||||
RainbowGrad.name = "Rainbow Wave";
|
||||
RainbowGrad.value = CLEVO_829X_MODE_RAINBOW_GRAD;
|
||||
RainbowGrad.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_DIRECTION_DIAG;
|
||||
RainbowGrad.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
RainbowGrad.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
RainbowGrad.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
RainbowGrad.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
RainbowGrad.brightness_max = bmax;
|
||||
RainbowGrad.brightness = bmax;
|
||||
RainbowGrad.direction = MODE_DIRECTION_LEFT;
|
||||
RainbowGrad.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(RainbowGrad);
|
||||
|
||||
mode FnColor;
|
||||
FnColor.name = "Fn Highlight";
|
||||
FnColor.value = CLEVO_829X_MODE_FN_COLOR;
|
||||
FnColor.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
FnColor.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
FnColor.brightness_max = bmax;
|
||||
FnColor.brightness = bmax;
|
||||
FnColor.colors_min = 1;
|
||||
FnColor.colors_max = 1;
|
||||
FnColor.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
FnColor.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(FnColor);
|
||||
}
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
@@ -207,16 +364,22 @@ RGBController_ClevoKeyboard::~RGBController_ClevoKeyboard()
|
||||
void RGBController_ClevoKeyboard::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Create keyboard layout using KeyboardLayoutManager |
|
||||
| Select layout based on device type |
|
||||
\*---------------------------------------------------------*/
|
||||
KeyboardLayoutManager new_kb(KEYBOARD_LAYOUT_ISO_QWERTY,
|
||||
clevo_keyboard_layout.base_size,
|
||||
clevo_keyboard_layout.key_values);
|
||||
bool is_829x = (controller->GetType() == CLEVO_KB_ITE829X);
|
||||
|
||||
new_kb.ChangeKeys(clevo_keyboard_layout);
|
||||
keyboard_keymap_overlay_values& layout = is_829x
|
||||
? clevo_829x_keyboard_layout
|
||||
: clevo_keyboard_layout;
|
||||
|
||||
KeyboardLayoutManager new_kb(KEYBOARD_LAYOUT_ISO_QWERTY,
|
||||
layout.base_size,
|
||||
layout.key_values);
|
||||
|
||||
new_kb.ChangeKeys(layout);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create a matrix zone for the keyboard |
|
||||
| Create keyboard zone from KLM |
|
||||
\*---------------------------------------------------------*/
|
||||
zone keyboard_zone;
|
||||
|
||||
@@ -233,9 +396,6 @@ void RGBController_ClevoKeyboard::SetupZones()
|
||||
|
||||
zones.push_back(keyboard_zone);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create LEDs from the KeyboardLayoutManager data |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int led_idx = 0; led_idx < keyboard_zone.leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
@@ -249,36 +409,48 @@ void RGBController_ClevoKeyboard::SetupZones()
|
||||
SetupColors();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create buffer map to translate OpenRGB LED order to |
|
||||
| hardware LED order. The hardware expects 126 color values |
|
||||
| indexed by LED position (0-125). |
|
||||
| Build buffer map from LED values to color pointers |
|
||||
| 829x LED IDs have gaps (stride 32), need larger map |
|
||||
\*---------------------------------------------------------*/
|
||||
null_color = 0x00000000;
|
||||
buffer_map.resize(CLEVO_KEYBOARD_NUM_LEDS, &null_color);
|
||||
|
||||
size_t map_size = is_829x
|
||||
? CLEVO_829X_LED_ID(CLEVO_829X_NUM_ROWS - 1, CLEVO_829X_NUM_COLS - 1) + 1
|
||||
: (size_t)controller->GetNumLEDs();
|
||||
|
||||
buffer_map.resize(map_size, &null_color);
|
||||
|
||||
for(size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
buffer_map[leds[led_idx].value] = &colors[led_idx];
|
||||
if(leds[led_idx].value < buffer_map.size())
|
||||
{
|
||||
buffer_map[leds[led_idx].value] = &colors[led_idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_ClevoKeyboard::DeviceUpdateLEDs()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Build color data array using buffer map and send to device|
|
||||
| The buffer_map translates from hardware LED index to the |
|
||||
| corresponding color pointer for that LED. |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char color_data[CLEVO_KEYBOARD_NUM_LEDS * 3];
|
||||
int num_rows = controller->GetNumRows();
|
||||
int num_cols = controller->GetNumCols();
|
||||
bool is_829x = (controller->GetType() == CLEVO_KB_ITE829X);
|
||||
|
||||
for(int i = 0; i < CLEVO_KEYBOARD_NUM_LEDS; i++)
|
||||
std::vector<unsigned char> color_data(num_rows * num_cols * 3);
|
||||
|
||||
for(int row = 0; row < num_rows; row++)
|
||||
{
|
||||
color_data[i * 3 + 0] = RGBGetRValue(*buffer_map[i]);
|
||||
color_data[i * 3 + 1] = RGBGetGValue(*buffer_map[i]);
|
||||
color_data[i * 3 + 2] = RGBGetBValue(*buffer_map[i]);
|
||||
for(int col = 0; col < num_cols; col++)
|
||||
{
|
||||
int seq = row * num_cols + col;
|
||||
int led_id = is_829x ? CLEVO_829X_LED_ID(row, col) : seq;
|
||||
|
||||
color_data[seq * 3 + 0] = RGBGetRValue(*buffer_map[led_id]);
|
||||
color_data[seq * 3 + 1] = RGBGetGValue(*buffer_map[led_id]);
|
||||
color_data[seq * 3 + 2] = RGBGetBValue(*buffer_map[led_id]);
|
||||
}
|
||||
}
|
||||
|
||||
controller->SendColors(color_data, modes[active_mode].brightness);
|
||||
controller->SendColors(color_data.data(), modes[active_mode].brightness, modes[active_mode].speed);
|
||||
}
|
||||
|
||||
void RGBController_ClevoKeyboard::DeviceUpdateZoneLEDs(int /*zone*/)
|
||||
@@ -304,6 +476,16 @@ void RGBController_ClevoKeyboard::DeviceUpdateMode()
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Handle ITE 829x firmware effects |
|
||||
\*---------------------------------------------------------*/
|
||||
if(controller->GetType() == CLEVO_KB_ITE829X && mode_value != CLEVO_KEYBOARD_MODE_DIRECT)
|
||||
{
|
||||
controller->SetEffect829x(mode_value, modes[active_mode].colors, modes[active_mode].direction, modes[active_mode].color_mode);
|
||||
controller->SetBrightnessSpeed829x(modes[active_mode].brightness, modes[active_mode].speed);
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Handle Direct (per-key) mode |
|
||||
\*---------------------------------------------------------*/
|
||||
@@ -318,41 +500,26 @@ void RGBController_ClevoKeyboard::DeviceUpdateMode()
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char brightness = modes[active_mode].brightness;
|
||||
unsigned char speed = modes[active_mode].speed;
|
||||
unsigned char behaviour = 0x00;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set direction for wave mode |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == CLEVO_KEYBOARD_MODE_WAVE)
|
||||
{
|
||||
switch(modes[active_mode].direction)
|
||||
{
|
||||
case MODE_DIRECTION_LEFT:
|
||||
behaviour = CLEVO_KEYBOARD_DIRECTION_LEFT;
|
||||
break;
|
||||
case MODE_DIRECTION_RIGHT:
|
||||
behaviour = CLEVO_KEYBOARD_DIRECTION_RIGHT;
|
||||
break;
|
||||
case MODE_DIRECTION_UP:
|
||||
behaviour = CLEVO_KEYBOARD_DIRECTION_UP;
|
||||
break;
|
||||
case MODE_DIRECTION_DOWN:
|
||||
behaviour = CLEVO_KEYBOARD_DIRECTION_DOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
unsigned char behaviour = (mode_value == CLEVO_KEYBOARD_MODE_WAVE)
|
||||
? modes[active_mode].direction + 1
|
||||
: 0x00;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set mode color if applicable |
|
||||
\*---------------------------------------------------------*/
|
||||
if(modes[active_mode].colors.size() > 0)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
unsigned char green = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
unsigned char blue = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
|
||||
controller->SetModeColor(1, red, green, blue);
|
||||
controller->SetModeColor(1, modes[active_mode].colors[0]);
|
||||
}
|
||||
|
||||
controller->SetMode(mode_value, brightness, speed, behaviour);
|
||||
}
|
||||
|
||||
void RGBController_ClevoKeyboard::DeviceSaveMode()
|
||||
{
|
||||
if(controller->GetType() == CLEVO_KB_ITE829X)
|
||||
{
|
||||
DeviceUpdateMode();
|
||||
controller->SaveToBios829x();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_ClevoKeyboard.h |
|
||||
| |
|
||||
| RGBController for Clevo per-key RGB keyboard (ITE 8291) |
|
||||
| RGBController for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| |
|
||||
| Kyle Cascade ([email protected]) 16 Jan 2026 |
|
||||
| Valentin Lobstein ([email protected]) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -18,7 +20,7 @@
|
||||
class RGBController_ClevoKeyboard : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_ClevoKeyboard(ClevoKeyboardController* controller_ptr);
|
||||
explicit RGBController_ClevoKeyboard(ClevoKeyboardController* controller_ptr);
|
||||
~RGBController_ClevoKeyboard();
|
||||
|
||||
void SetupZones();
|
||||
@@ -28,6 +30,7 @@ public:
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
ClevoKeyboardController* controller;
|
||||
|
||||
@@ -45,7 +45,8 @@ void ColorfulGPUController::SetDirect(RGBColor color)
|
||||
uint8_t g = RGBGetGValue(color);
|
||||
uint8_t b = RGBGetBValue(color);
|
||||
|
||||
if(this->bus->info.pci_subsystem_device == COLORFUL_IGAME_RTX_4070_VULCAN_OCV)
|
||||
if(this->bus->info.pci_subsystem_device == COLORFUL_IGAME_RTX_4070_VULCAN_OCV
|
||||
|| this->bus->info.pci_subsystem_device == COLORFUL_IGAME_RTX_4090_NEPTUNE_OCV)
|
||||
{
|
||||
uint8_t data_pkt[COLORFUL_PACKET_LENGTH_V2] = { 0xAA, 0xEF, 0x01, 0x04, 0x88, 0x26 };
|
||||
for(int i=6; i < COLORFUL_PACKET_LENGTH_V2 -2; i = i + 3)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*---------------------------------------------------------*\
|
||||
/*---------------------------------------------------------*\
|
||||
| ColorfulGPUControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Colorful GPU |
|
||||
@@ -71,9 +71,11 @@ REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 Ti SUPER Advanced OC-V", Detec
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 Ti SUPER Ultra W", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TIS_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070TI_SUPER_ULTRA_W, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 SUPER Ultra W OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070_SUPER_ULTRA_W_OC, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 Vulcan OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070_VULCAN_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070_ULTRAW_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 SUPER Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070S_ULTRAW_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4080 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4080_ULTRAW_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4080 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4080_ULTRAW_OCV2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4090 Neptune OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4090_NEPTUNE_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4090 Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4090_ADVANCED_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4090 Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4090_ADVANCED_OCV2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5060 Ultra W OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5060_ULTRAW_OC, 0x61);
|
||||
@@ -81,4 +83,5 @@ REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5060 Ultra W OC", Detec
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5060 Ti Ultra W DUO OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060TI_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5060TI_ULTRAW_DUO_OC, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5060 Ti Ultra W DUO OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060TI_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5060TI_ULTRAW_DUO_OC_2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5070 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5070_ULTRAW_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5070 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5070_ULTRAW_OCV2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5070 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5070_ULTRAW_OCV2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5070 Ti Ultra W OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5070TI_ULTRAW_OC, 0x61);
|
||||
@@ -526,27 +526,26 @@ void CorsairPeripheralController::ReadFirmwareInfo()
|
||||
char offset = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
| Some Corsair keyboards (e.g. K70 RGB MK.2) do not |
|
||||
| answer the firmware-info query on the control |
|
||||
| interface until several seconds after the host first |
|
||||
| talks to them following a cold boot. A single read |
|
||||
| attempt returns all zeros, the device type comes back |
|
||||
| as 0x00, and the device is discarded as UNKNOWN. |
|
||||
| Retry the query until a valid device type byte is |
|
||||
| returned or the attempt cap is reached. Each failed |
|
||||
| attempt is paced by the 1s hid_read_timeout below, so |
|
||||
| the cap also bounds the detection stall for a device |
|
||||
| that opens but never answers. Observed need |
|
||||
| on a K70 RGB MK.2 cold boot is 2 attempts; the cap |
|
||||
| leaves generous headroom. |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
int attempt = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Read Firmware Info packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_READ;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet and try reading it using an HID read |
|
||||
| If that fails, repeat the send and read the reply as |
|
||||
| a feature report. |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
actual = hid_read_timeout(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH, 1000);
|
||||
|
||||
if(actual == 0)
|
||||
do
|
||||
{
|
||||
offset = 0;
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-------------------------------------------------*/
|
||||
@@ -559,10 +558,48 @@ void CorsairPeripheralController::ReadFirmwareInfo()
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_READ;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
|
||||
|
||||
hid_send_feature_report(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
actual = hid_get_feature_report(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
offset = 1;
|
||||
}
|
||||
/*-------------------------------------------------*\
|
||||
| Send packet and try reading it using an HID read |
|
||||
| If that fails, repeat the send and read the reply |
|
||||
| as a feature report. |
|
||||
\*-------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
actual = hid_read_timeout(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH, 1000);
|
||||
|
||||
if(actual == 0)
|
||||
{
|
||||
/*---------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*---------------------------------------------*/
|
||||
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Set up Read Firmware Info packet |
|
||||
\*---------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_READ;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
|
||||
|
||||
hid_send_feature_report(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
actual = hid_get_feature_report(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
attempt++;
|
||||
|
||||
LOG_DEBUG("[%s] Firmware info attempt %d/%d: device type %02X", CORSAIR_PERIPHERAL_CONTROLLER_NAME, attempt, CORSAIR_FW_INFO_MAX_ATTEMPTS, usb_buf[0x14 + offset]);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Stop as soon as a valid device type is returned |
|
||||
| 0xC0 keyboard / 0xC1 mouse / 0xC2 pad or stand |
|
||||
\*-------------------------------------------------*/
|
||||
if(usb_buf[0x14 + offset] == 0xC0
|
||||
|| usb_buf[0x14 + offset] == 0xC1
|
||||
|| usb_buf[0x14 + offset] == 0xC2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while(attempt < CORSAIR_FW_INFO_MAX_ATTEMPTS);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get device type |
|
||||
@@ -570,7 +607,7 @@ void CorsairPeripheralController::ReadFirmwareInfo()
|
||||
| 0xC1 Device is a mouse |
|
||||
| 0xC2 Device is a mousepad or headset stand |
|
||||
\*-----------------------------------------------------*/
|
||||
LOG_DEBUG("[%s] Device type %02X", CORSAIR_PERIPHERAL_CONTROLLER_NAME, usb_buf[0x14 + offset]);
|
||||
LOG_DEBUG("[%s] Device type %02X after %d attempt(s)", CORSAIR_PERIPHERAL_CONTROLLER_NAME, usb_buf[0x14 + offset], attempt);
|
||||
|
||||
switch(usb_buf[0x14 + offset])
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "RGBController.h"
|
||||
|
||||
#define CORSAIR_PERIPHERAL_PACKET_LENGTH 65
|
||||
#define CORSAIR_FW_INFO_MAX_ATTEMPTS 10
|
||||
|
||||
enum
|
||||
{
|
||||
|
||||
@@ -411,6 +411,7 @@ REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming White OC",
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_O24G_GAMING_WHITE_2, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG MATRIX PLATINUM GeForce RTX 4090", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_MATRIX_PLATINUM_RTX_4090_24G, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5060 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5060_O8G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5060 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5060TI_O16G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070_O12G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070TI_O16G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Ti Gaming BTF White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070TI_O16G_GAMING_BTF_WHITE, 0x67);
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EVGAKeyboardControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for EVGA keyboard devices |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_EVGAKeyboard.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| EVGA USB vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define EVGA_USB_VID 0x3842
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define Z15_ISO_PID 0x260E
|
||||
#define Z15_ANSI_PID 0x2608
|
||||
#define Z20_ANSI_PID 0x260A
|
||||
#define Z20_UK_PID 0x2610
|
||||
|
||||
DetectedControllers DetectEVGAKeyboardControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EVGAKeyboardController* controller = new EVGAKeyboardController(dev, info->path, info->product_id, name);
|
||||
RGBController_EVGAKeyboard* rgb_controller = new RGBController_EVGAKeyboard(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA Z15 Keyboard", DetectEVGAKeyboardControllers, EVGA_USB_VID, Z15_ISO_PID, 1, 0x08, 0x4B);
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA Z15 Keyboard", DetectEVGAKeyboardControllers, EVGA_USB_VID, Z15_ANSI_PID, 1, 0x08, 0x4B);
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA Z20 Keyboard", DetectEVGAKeyboardControllers, EVGA_USB_VID, Z20_ANSI_PID, 1, 0x08, 0x4B);
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA Z20 Keyboard", DetectEVGAKeyboardControllers, EVGA_USB_VID, Z20_UK_PID, 1, 0x08, 0x4B);
|
||||
|
||||
+5
-37
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EVGAUSBControllerDetect.cpp |
|
||||
| EVGAMouseControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for EVGA USB devices |
|
||||
| Detector for EVGA mouse devices |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -9,45 +9,18 @@
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_EVGAKeyboard.h"
|
||||
#include "RGBController_EVGAMouse.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| EVGA USB vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define EVGA_USB_VID 0x3842
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define Z15_ISO_PID 0x260E
|
||||
#define Z15_ANSI_PID 0x2608
|
||||
#define Z20_ANSI_PID 0x260A
|
||||
#define Z20_UK_PID 0x2610
|
||||
#define EVGA_USB_VID 0x3842
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Mouse product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define X20_WIRED_PID 0x2420
|
||||
#define X20_WIRELESS_ADAPTER_PID 0x2402
|
||||
|
||||
DetectedControllers DetectEVGAKeyboardControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EVGAKeyboardController* controller = new EVGAKeyboardController(dev, info->path, info->product_id, name);
|
||||
RGBController_EVGAKeyboard* rgb_controller = new RGBController_EVGAKeyboard(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
#define X20_WIRED_PID 0x2420
|
||||
#define X20_WIRELESS_ADAPTER_PID 0x2402
|
||||
|
||||
DetectedControllers DetectEVGAMouse(hid_device_info* info, const std::string &name, int connection_type)
|
||||
{
|
||||
@@ -77,10 +50,5 @@ DetectedControllers DetectWirelessEVGAMouse(hid_device_info* info, const std::st
|
||||
return(DetectEVGAMouse(info, name, EVGA_PERIPHERAL_CONNECTION_TYPE_WIRELESS));
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA Z15 Keyboard", DetectEVGAKeyboardControllers, EVGA_USB_VID, Z15_ISO_PID, 1, 0x08, 0x4B);
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA Z15 Keyboard", DetectEVGAKeyboardControllers, EVGA_USB_VID, Z15_ANSI_PID, 1, 0x08, 0x4B);
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA Z20 Keyboard", DetectEVGAKeyboardControllers, EVGA_USB_VID, Z20_ANSI_PID, 1, 0x08, 0x4B);
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA Z20 Keyboard", DetectEVGAKeyboardControllers, EVGA_USB_VID, Z20_UK_PID, 1, 0x08, 0x4B);
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA X20 Gaming Mouse", DetectWiredEVGAMouse, EVGA_USB_VID, X20_WIRED_PID, 2, 0xFFFF, 0);
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA X20 USB Receiver", DetectWirelessEVGAMouse, EVGA_USB_VID, X20_WIRELESS_ADAPTER_PID, 2, 0xFFFF, 0);
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EVisionKeyboardControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for EVision/Huafenda keyboards |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "EVisionKeyboardController.h"
|
||||
#include "RGBController_EVisionKeyboard.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "SettingsManager.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| EVision vendor ID |
|
||||
| NOTE: EVision (and Huafenda) use rebranded Sonix MCUs |
|
||||
| Some EVision/Huafenda keyboards use the Sonix VID while |
|
||||
| others use EVision's VID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define SONIX_VID 0x0C45
|
||||
#define EVISION_VID 0x320F
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| EVision Usage Page |
|
||||
\*---------------------------------------------------------*/
|
||||
#define EVISION_KEYBOARD_USAGE_PAGE 0xFF1C
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define EVISION_SONIX_5004_PID 0x5004
|
||||
#define EVISION_SONIX_5104_PID 0x5104
|
||||
#define EVISION_SONIX_5204_PID 0x5204
|
||||
#define EVISION_SONIX_652F_PID 0x652F
|
||||
#define EVISION_SONIX_7672_PID 0x7672
|
||||
#define EVISION_SONIX_7698_PID 0x7698
|
||||
#define EVISION_SONIX_8520_PID 0x8520
|
||||
#define EVISION_5000_PID 0x5000
|
||||
#define EVISION_502A_PID 0x502A
|
||||
#define EVISION_505B_PID 0x505B
|
||||
#define EVISION_5064_PID 0x5064
|
||||
#define EVISION_5078_PID 0x5078
|
||||
#define EVISION_5084_PID 0x5084
|
||||
|
||||
DetectedControllers DetectEVisionKeyboards(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EVisionKeyboardController* controller = new EVisionKeyboardController(dev, info->path, name);
|
||||
RGBController_EVisionKeyboard* rgb_controller = new RGBController_EVisionKeyboard(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*---------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:5004", DetectEVisionKeyboards, SONIX_VID, EVISION_SONIX_5004_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:5104", DetectEVisionKeyboards, SONIX_VID, EVISION_SONIX_5104_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:5204", DetectEVisionKeyboards, SONIX_VID, EVISION_SONIX_5204_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:652F", DetectEVisionKeyboards, SONIX_VID, EVISION_SONIX_652F_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:7672", DetectEVisionKeyboards, SONIX_VID, EVISION_SONIX_7672_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:7698", DetectEVisionKeyboards, SONIX_VID, EVISION_SONIX_7698_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:8520", DetectEVisionKeyboards, SONIX_VID, EVISION_SONIX_8520_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:5000", DetectEVisionKeyboards, EVISION_VID, EVISION_5000_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:502A", DetectEVisionKeyboards, EVISION_VID, EVISION_502A_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:505B", DetectEVisionKeyboards, EVISION_VID, EVISION_505B_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:5078", DetectEVisionKeyboards, EVISION_VID, EVISION_5078_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:5064", DetectEVisionKeyboards, EVISION_VID, EVISION_5064_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:5084", DetectEVisionKeyboards, EVISION_VID, EVISION_5084_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
@@ -1,129 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EVisionKeyboardControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for EVision keyboards |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "EVisionKeyboardController.h"
|
||||
#include "EVisionV2KeyboardController.h"
|
||||
#include "RGBController_EVisionKeyboard.h"
|
||||
#include "RGBController_EVisionV2Keyboard.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "SettingsManager.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define EVISION_KEYBOARD_VID 0x0C45
|
||||
#define EVISION_KEYBOARD2_VID 0x320F
|
||||
#define EVISION_KEYBOARD3_VID 0x3299
|
||||
#define EVISION_KEYBOARD_USAGE_PAGE 0xFF1C
|
||||
#define ENDORFY_OMNIS_PID 0x0012
|
||||
#define DEXP_BLAZE_PID 0x5084
|
||||
#define GLORIOUS_GMMK_TKL_PID 0x5064
|
||||
#define REDRAGON_K550_PID 0x5204
|
||||
#define MARS_GAMING_MKMINI_PID 0x5078
|
||||
#define SKILLKORP_K5_PID 0x505B
|
||||
#define REDRAGON_K552_PID 0x5104
|
||||
#define REDRAGON_K552_V2_PID 0x5000
|
||||
#define REDRAGON_K556_PID 0x5004
|
||||
#define TECWARE_PHANTOM_ELITE_PID 0x652F
|
||||
#define WARRIOR_KANE_TC235 0x8520
|
||||
#define WOMIER_K87_PID 0x502A
|
||||
#define WOMIER_K66_PID 0x7698
|
||||
#define BYGG_CSB_ICL01_PID 0x5041
|
||||
#define GAMEPOWER_OGRE_RGB_PID 0x7672
|
||||
|
||||
DetectedControllers DetectEVisionKeyboards(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EVisionKeyboardController* controller = new EVisionKeyboardController(dev, info->path, name);
|
||||
RGBController_EVisionKeyboard* rgb_controller = new RGBController_EVisionKeyboard(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectEVisionV2Keyboards(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
json settings = ResourceManager::get()->GetSettingsManager()->GetSettings("EVision2Settings");
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EVisionV2KeyboardController* controller = new EVisionV2KeyboardController(dev, info->path, EVISION_V2_KEYBOARD_LAYOUT, name);
|
||||
RGBController_EVisionV2Keyboard* rgb_controller = new RGBController_EVisionV2Keyboard(controller, EVISION_V2_KEYBOARD_PART_KEYBOARD);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
|
||||
if(!settings.contains("AdditionalZones") || settings["AdditionalZones"] == true)
|
||||
{
|
||||
rgb_controller = new RGBController_EVisionV2Keyboard(controller, EVISION_V2_KEYBOARD_PART_LOGO);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
|
||||
rgb_controller = new RGBController_EVisionV2Keyboard(controller, EVISION_V2_KEYBOARD_PART_EDGE);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectEndorfyKeyboards(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
json settings = ResourceManager::get()->GetSettingsManager()->GetSettings("EndorfySettings");
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EVisionV2KeyboardController* controller = new EVisionV2KeyboardController(dev, info->path, ENDORFY_KEYBOARD_LAYOUT, name);
|
||||
RGBController_EVisionV2Keyboard* rgb_controller = new RGBController_EVisionV2Keyboard(controller, EVISION_V2_KEYBOARD_PART_KEYBOARD);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
|
||||
if(!settings.contains("AdditionalZones") || settings["AdditionalZones"] == true)
|
||||
{
|
||||
rgb_controller = new RGBController_EVisionV2Keyboard(controller, ENDORFY_KEYBOARD_PART_EDGE);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*---------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:5078", DetectEVisionKeyboards, EVISION_KEYBOARD2_VID, MARS_GAMING_MKMINI_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:5204", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, REDRAGON_K550_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:5104", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, REDRAGON_K552_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:5000", DetectEVisionKeyboards, EVISION_KEYBOARD2_VID, REDRAGON_K552_V2_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:5004", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, REDRAGON_K556_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:652F", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, TECWARE_PHANTOM_ELITE_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:8520", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, WARRIOR_KANE_TC235, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:502A", DetectEVisionKeyboards, EVISION_KEYBOARD2_VID, WOMIER_K87_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:7698", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, WOMIER_K66_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:5064", DetectEVisionKeyboards, EVISION_KEYBOARD2_VID, GLORIOUS_GMMK_TKL_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:5084", DetectEVisionKeyboards, EVISION_KEYBOARD2_VID, DEXP_BLAZE_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:505B", DetectEVisionKeyboards, EVISION_KEYBOARD2_VID, SKILLKORP_K5_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("Endorfy Omnis", DetectEndorfyKeyboards, EVISION_KEYBOARD3_VID, ENDORFY_OMNIS_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("CSB/ICL01 Keyboard", DetectEVisionV2Keyboards, EVISION_KEYBOARD2_VID, BYGG_CSB_ICL01_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("Gamepower Ogre RGB 0C45:7672", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, GAMEPOWER_OGRE_RGB_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EVisionKeyboardV2ControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for EVision V2 keyboards |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "EVisionV2KeyboardController.h"
|
||||
#include "RGBController_EVisionV2Keyboard.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "SettingsManager.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| EVision vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define EVISION_VID 0x320F
|
||||
#define SPCGEAR_VID 0x3299
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| EVision Usage Page |
|
||||
\*---------------------------------------------------------*/
|
||||
#define EVISION_KEYBOARD_USAGE_PAGE 0xFF1C
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ENDORFY_OMNIS_PID 0x0012
|
||||
#define BYGG_CSB_ICL01_PID 0x5041
|
||||
|
||||
DetectedControllers DetectEVisionV2Keyboards(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
json settings = ResourceManager::get()->GetSettingsManager()->GetSettings("EVision2Settings");
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EVisionV2KeyboardController* controller = new EVisionV2KeyboardController(dev, info->path, EVISION_V2_KEYBOARD_LAYOUT, name);
|
||||
RGBController_EVisionV2Keyboard* rgb_controller = new RGBController_EVisionV2Keyboard(controller, EVISION_V2_KEYBOARD_PART_KEYBOARD);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
|
||||
if(!settings.contains("AdditionalZones") || settings["AdditionalZones"] == true)
|
||||
{
|
||||
rgb_controller = new RGBController_EVisionV2Keyboard(controller, EVISION_V2_KEYBOARD_PART_LOGO);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
|
||||
rgb_controller = new RGBController_EVisionV2Keyboard(controller, EVISION_V2_KEYBOARD_PART_EDGE);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectEndorfyKeyboards(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
json settings = ResourceManager::get()->GetSettingsManager()->GetSettings("EndorfySettings");
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EVisionV2KeyboardController* controller = new EVisionV2KeyboardController(dev, info->path, ENDORFY_KEYBOARD_LAYOUT, name);
|
||||
RGBController_EVisionV2Keyboard* rgb_controller = new RGBController_EVisionV2Keyboard(controller, EVISION_V2_KEYBOARD_PART_KEYBOARD);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
|
||||
if(!settings.contains("AdditionalZones") || settings["AdditionalZones"] == true)
|
||||
{
|
||||
rgb_controller = new RGBController_EVisionV2Keyboard(controller, ENDORFY_KEYBOARD_PART_EDGE);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*---------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:5041", DetectEVisionV2Keyboards, EVISION_VID, BYGG_CSB_ICL01_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
REGISTER_HID_DETECTOR_IP("Endorfy Omnis", DetectEndorfyKeyboards, SPCGEAR_VID, ENDORFY_OMNIS_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
|
||||
@@ -0,0 +1,205 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EdifierHaloController.cpp |
|
||||
| |
|
||||
| Driver for Edifier Halo series USB/HID devices |
|
||||
| |
|
||||
| Bartholomew Ho <[email protected]> 20 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogManager.h"
|
||||
#include "EdifierHaloController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
EdifierHaloController::EdifierHaloController(hid_device* dev_handle, const char* path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
|
||||
wchar_t name_string[256];
|
||||
int result;
|
||||
|
||||
result = hid_get_manufacturer_string(dev, name_string, 256);
|
||||
if(result == 0)
|
||||
{
|
||||
device_name = StringUtils::wstring_to_string(name_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
device_name = "Edifier";
|
||||
LOG_WARNING("[EdifierHaloController] Failed to read manufacturer string for %s", path);
|
||||
}
|
||||
|
||||
result = hid_get_product_string(dev, name_string, 256);
|
||||
if(result == 0)
|
||||
{
|
||||
device_name.append(" ").append(StringUtils::wstring_to_string(name_string));
|
||||
}
|
||||
else
|
||||
{
|
||||
device_name.append(" Halo PixelBar");
|
||||
LOG_WARNING("[EdifierHaloController] Failed to read product string for %s", path);
|
||||
}
|
||||
|
||||
wchar_t serial_string[128];
|
||||
result = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
if(result == 0)
|
||||
{
|
||||
serial = StringUtils::wstring_to_string(serial_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
serial = "";
|
||||
LOG_DEBUG("[EdifierHaloController] No serial number available for %s", path);
|
||||
}
|
||||
}
|
||||
|
||||
EdifierHaloController::~EdifierHaloController()
|
||||
{
|
||||
if(dev)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
}
|
||||
|
||||
std::string EdifierHaloController::GetDeviceName() const
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string EdifierHaloController::GetSerial() const
|
||||
{
|
||||
return(serial);
|
||||
}
|
||||
|
||||
std::string EdifierHaloController::GetLocation() const
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
void EdifierHaloController::SetAmbientLightPower(bool enabled)
|
||||
{
|
||||
unsigned char mode = enabled ? 0x01 : 0x00;
|
||||
unsigned char payload[] =
|
||||
{
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
mode,
|
||||
0xFF,
|
||||
0xFF
|
||||
};
|
||||
SendEdifierPacket(0x6b, payload, sizeof(payload));
|
||||
}
|
||||
|
||||
void EdifierHaloController::SetAmbientLight(unsigned char effect, unsigned char r, unsigned char g, unsigned char b, unsigned char brightness, unsigned char speed)
|
||||
{
|
||||
unsigned char raw_brightness = 0x3c;
|
||||
if (brightness == 1) raw_brightness = 0x14;
|
||||
else if (brightness == 2) raw_brightness = 0x28;
|
||||
else if (brightness == 3) raw_brightness = 0x3c;
|
||||
|
||||
if (speed < 1) speed = 1;
|
||||
if (speed > 10) speed = 10;
|
||||
|
||||
unsigned char payload[] =
|
||||
{
|
||||
0x13,
|
||||
effect,
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
raw_brightness,
|
||||
speed
|
||||
};
|
||||
SendEdifierPacket(0x6b, payload, sizeof(payload));
|
||||
}
|
||||
|
||||
void EdifierHaloController::SetPixelScreenColor(unsigned char r, unsigned char g, unsigned char b)
|
||||
{
|
||||
unsigned char payload[] =
|
||||
{
|
||||
0x03,
|
||||
r,
|
||||
g,
|
||||
b
|
||||
};
|
||||
SendEdifierPacket(0xef, payload, sizeof(payload));
|
||||
}
|
||||
|
||||
void EdifierHaloController::SetScreenUIModel(unsigned char model_id, unsigned char r, unsigned char g, unsigned char b)
|
||||
{
|
||||
unsigned char payload[] =
|
||||
{
|
||||
0x02,
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
0x00,
|
||||
0x01,
|
||||
model_id,
|
||||
0xff,
|
||||
0xff
|
||||
};
|
||||
SendEdifierPacket(0xef, payload, sizeof(payload));
|
||||
}
|
||||
|
||||
void EdifierHaloController::SetScreenScene(unsigned char category, unsigned char index, unsigned char r, unsigned char g, unsigned char b)
|
||||
{
|
||||
unsigned char payload[] =
|
||||
{
|
||||
0x01, // group
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
0x00,
|
||||
0x01,
|
||||
category,
|
||||
index,
|
||||
0xff // option
|
||||
};
|
||||
SendEdifierPacket(0xef, payload, sizeof(payload));
|
||||
}
|
||||
|
||||
void EdifierHaloController::SendEdifierPacket(unsigned char commandIndex, const unsigned char* payload, unsigned int payload_size)
|
||||
{
|
||||
if(!dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char packet[64];
|
||||
memset(packet, 0x00, sizeof(packet));
|
||||
|
||||
packet[0] = 0x2e;
|
||||
packet[1] = 0xaa;
|
||||
packet[2] = 0xec;
|
||||
packet[3] = commandIndex;
|
||||
packet[4] = (unsigned char)((payload_size >> 8) & 0xff);
|
||||
packet[5] = (unsigned char)(payload_size & 0xff);
|
||||
|
||||
if(payload_size > 0 && payload != nullptr)
|
||||
{
|
||||
memcpy(&packet[6], payload, payload_size);
|
||||
}
|
||||
|
||||
// Calculate checksum
|
||||
unsigned int sum = 0;
|
||||
for(unsigned int i = 1; i < 6 + payload_size; i++)
|
||||
{
|
||||
sum += packet[i];
|
||||
}
|
||||
packet[6 + payload_size] = (unsigned char)(sum & 0xff);
|
||||
|
||||
std::lock_guard<std::mutex> guard(device_mutex);
|
||||
int bytes_written = hid_write(dev, packet, sizeof(packet));
|
||||
if(bytes_written != sizeof(packet))
|
||||
{
|
||||
LOG_ERROR("[EdifierHaloController] Failed to write HID packet (%d/%d bytes): %ls",
|
||||
bytes_written, (int)sizeof(packet), hid_error(dev));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EdifierHaloController.h |
|
||||
| |
|
||||
| Driver for Edifier Halo series USB/HID devices |
|
||||
| |
|
||||
| Bartholomew Ho <[email protected]> 20 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
|
||||
enum
|
||||
{
|
||||
EDIFIER_HALO_AMBIENT_MODE_BREATHING = 1, // Breathing
|
||||
EDIFIER_HALO_AMBIENT_MODE_TIDE = 2, // Rainbow
|
||||
EDIFIER_HALO_AMBIENT_MODE_STATIC = 3, // Static
|
||||
EDIFIER_HALO_AMBIENT_MODE_RIPPLE = 4, // Glittering and colorful
|
||||
EDIFIER_HALO_AMBIENT_MODE_FLOW = 5, // Light-flow
|
||||
EDIFIER_HALO_AMBIENT_MODE_DYNAMIC = 6 // Dynamic Shadows
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EDIFIER_HALO_AMBIENT_SPEED_SLOWEST = 1,
|
||||
EDIFIER_HALO_AMBIENT_SPEED_FASTEST = 10
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EDIFIER_HALO_AMBIENT_BRIGHTNESS_LOWEST = 1,
|
||||
EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST = 3
|
||||
};
|
||||
|
||||
class EdifierHaloController
|
||||
{
|
||||
public:
|
||||
EdifierHaloController(hid_device* dev_handle, const char* path);
|
||||
~EdifierHaloController();
|
||||
|
||||
std::string GetDeviceName() const;
|
||||
std::string GetSerial() const;
|
||||
std::string GetLocation() const;
|
||||
|
||||
void SetAmbientLight(unsigned char effect, unsigned char r, unsigned char g, unsigned char b, unsigned char brightness, unsigned char speed);
|
||||
void SetAmbientLightPower(bool enabled);
|
||||
void SetPixelScreenColor(unsigned char r, unsigned char g, unsigned char b);
|
||||
void SetScreenUIModel(unsigned char model_id, unsigned char r, unsigned char g, unsigned char b);
|
||||
void SetScreenScene(unsigned char category, unsigned char index, unsigned char r, unsigned char g, unsigned char b);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string device_name;
|
||||
std::string serial;
|
||||
std::string location;
|
||||
std::mutex device_mutex;
|
||||
|
||||
void SendEdifierPacket(unsigned char commandIndex, const unsigned char* payload, unsigned int payload_size);
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EdifierHaloControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Edifier Halo PixelBar USB/HID devices |
|
||||
| |
|
||||
| Bartholomew Ho <[email protected]> 20 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include <memory>
|
||||
#include "DetectionManager.h"
|
||||
#include "LogManager.h"
|
||||
#include "RGBController_EdifierHaloPixelbarAmbient.h"
|
||||
#include "RGBController_EdifierHaloPixelbarScreen.h"
|
||||
#include "EdifierHaloController.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Edifier HID vendor and product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define EDIFIER_VID 0x2D99
|
||||
#define EDIFIER_PIXELBAR_PID 0xA106
|
||||
#define EDIFIER_PIXELBAR_INTERFACE 4
|
||||
#define EDIFIER_PIXELBAR_USAGE_PAGE 0xFF14
|
||||
#define EDIFIER_PIXELBAR_USAGE 0x01
|
||||
|
||||
DetectedControllers DetectEdifierHaloControllers(hid_device_info* info, const std::string&)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EdifierHaloController* controller = new EdifierHaloController(dev, info->path);
|
||||
|
||||
RGBController_EdifierHaloPixelbarAmbient* ambient_controller = new RGBController_EdifierHaloPixelbarAmbient(controller);
|
||||
RGBController_EdifierHaloPixelbarScreen* screen_controller = new RGBController_EdifierHaloPixelbarScreen(controller);
|
||||
|
||||
detected_controllers.push_back(ambient_controller);
|
||||
detected_controllers.push_back(screen_controller);
|
||||
|
||||
LOG_INFO("[EdifierHaloPixelbarDetect] Detected Edifier Halo PixelBar at %s (Instantiated Ambient & Screen controllers)", info->path);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING("[EdifierHaloPixelbarDetect] Failed to open Edifier Halo PixelBar at %s", info->path);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Edifier Halo Pixelbar", DetectEdifierHaloControllers, EDIFIER_VID, EDIFIER_PIXELBAR_PID, EDIFIER_PIXELBAR_INTERFACE, EDIFIER_PIXELBAR_USAGE_PAGE, EDIFIER_PIXELBAR_USAGE);
|
||||
@@ -0,0 +1,182 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_EdifierHaloPixelbarAmbient.cpp |
|
||||
| |
|
||||
| RGBController for Edifier Halo PixelBar Ambient Light |
|
||||
| |
|
||||
| Bartholomew Ho <[email protected]> 20 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_EdifierHaloPixelbarAmbient.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Edifier Halo Pixelbar
|
||||
@category Speaker
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :x:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectEdifierHaloControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_EdifierHaloPixelbarAmbient::RGBController_EdifierHaloPixelbarAmbient(EdifierHaloController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
first_leds_update_ignored = false;
|
||||
first_mode_update_ignored = false;
|
||||
|
||||
name = "Edifier Halo Pixelbar - Light Effects";
|
||||
vendor = "Edifier";
|
||||
type = DEVICE_TYPE_SPEAKER;
|
||||
description = "Edifier Halo PixelBar Light Effects";
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
// Setup modes
|
||||
mode breathing_mode;
|
||||
breathing_mode.name = "Breathing";
|
||||
breathing_mode.value = EDIFIER_HALO_AMBIENT_MODE_BREATHING;
|
||||
breathing_mode.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
breathing_mode.color_mode = MODE_COLORS_PER_LED;
|
||||
breathing_mode.speed_min = EDIFIER_HALO_AMBIENT_SPEED_SLOWEST;
|
||||
breathing_mode.speed_max = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
breathing_mode.speed = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
breathing_mode.brightness_min = EDIFIER_HALO_AMBIENT_BRIGHTNESS_LOWEST;
|
||||
breathing_mode.brightness_max = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
breathing_mode.brightness = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
modes.push_back(breathing_mode);
|
||||
|
||||
mode tide_mode;
|
||||
tide_mode.name = "Rainbow";
|
||||
tide_mode.value = EDIFIER_HALO_AMBIENT_MODE_TIDE;
|
||||
tide_mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
tide_mode.color_mode = MODE_COLORS_NONE;
|
||||
tide_mode.speed_min = EDIFIER_HALO_AMBIENT_SPEED_SLOWEST;
|
||||
tide_mode.speed_max = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
tide_mode.speed = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
tide_mode.brightness_min = EDIFIER_HALO_AMBIENT_BRIGHTNESS_LOWEST;
|
||||
tide_mode.brightness_max = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
tide_mode.brightness = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
modes.push_back(tide_mode);
|
||||
|
||||
mode static_mode;
|
||||
static_mode.name = "Static";
|
||||
static_mode.value = EDIFIER_HALO_AMBIENT_MODE_STATIC;
|
||||
static_mode.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
static_mode.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
static_mode.brightness_min = EDIFIER_HALO_AMBIENT_BRIGHTNESS_LOWEST;
|
||||
static_mode.brightness_max = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
static_mode.brightness = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
modes.push_back(static_mode);
|
||||
|
||||
mode ripple_mode;
|
||||
ripple_mode.name = "Glittering and colorful";
|
||||
ripple_mode.value = EDIFIER_HALO_AMBIENT_MODE_RIPPLE;
|
||||
ripple_mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
ripple_mode.color_mode = MODE_COLORS_NONE;
|
||||
ripple_mode.speed_min = EDIFIER_HALO_AMBIENT_SPEED_SLOWEST;
|
||||
ripple_mode.speed_max = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
ripple_mode.speed = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
ripple_mode.brightness_min = EDIFIER_HALO_AMBIENT_BRIGHTNESS_LOWEST;
|
||||
ripple_mode.brightness_max = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
ripple_mode.brightness = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
modes.push_back(ripple_mode);
|
||||
|
||||
mode flow_mode;
|
||||
flow_mode.name = "Light-flow";
|
||||
flow_mode.value = EDIFIER_HALO_AMBIENT_MODE_FLOW;
|
||||
flow_mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
flow_mode.color_mode = MODE_COLORS_NONE;
|
||||
flow_mode.speed_min = EDIFIER_HALO_AMBIENT_SPEED_SLOWEST;
|
||||
flow_mode.speed_max = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
flow_mode.speed = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
flow_mode.brightness_min = EDIFIER_HALO_AMBIENT_BRIGHTNESS_LOWEST;
|
||||
flow_mode.brightness_max = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
flow_mode.brightness = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
modes.push_back(flow_mode);
|
||||
|
||||
mode dynamic_mode;
|
||||
dynamic_mode.name = "Dynamic Shadows";
|
||||
dynamic_mode.value = EDIFIER_HALO_AMBIENT_MODE_DYNAMIC;
|
||||
dynamic_mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
dynamic_mode.color_mode = MODE_COLORS_NONE;
|
||||
dynamic_mode.speed_min = EDIFIER_HALO_AMBIENT_SPEED_SLOWEST;
|
||||
dynamic_mode.speed_max = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
dynamic_mode.speed = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
dynamic_mode.brightness_min = EDIFIER_HALO_AMBIENT_BRIGHTNESS_LOWEST;
|
||||
dynamic_mode.brightness_max = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
dynamic_mode.brightness = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
modes.push_back(dynamic_mode);
|
||||
|
||||
// Default to Static mode
|
||||
active_mode = 2;
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_EdifierHaloPixelbarAmbient::~RGBController_EdifierHaloPixelbarAmbient()
|
||||
{
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarAmbient::SetupZones()
|
||||
{
|
||||
zone ambient_zone;
|
||||
ambient_zone.name = "Light Effects";
|
||||
ambient_zone.type = ZONE_TYPE_SINGLE;
|
||||
ambient_zone.leds_min = 1;
|
||||
ambient_zone.leds_max = 1;
|
||||
ambient_zone.leds_count = 1;
|
||||
zones.push_back(ambient_zone);
|
||||
|
||||
led ambient_led;
|
||||
ambient_led.name = "Light Effects";
|
||||
leds.push_back(ambient_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarAmbient::DeviceUpdateLEDs()
|
||||
{
|
||||
if(!first_leds_update_ignored)
|
||||
{
|
||||
first_leds_update_ignored = true;
|
||||
return;
|
||||
}
|
||||
|
||||
int active_idx = GetActiveMode();
|
||||
RGBColor color = colors[0];
|
||||
unsigned char r = RGBGetRValue(color);
|
||||
unsigned char g = RGBGetGValue(color);
|
||||
unsigned char b = RGBGetBValue(color);
|
||||
|
||||
unsigned char effect = modes[active_idx].value;
|
||||
unsigned char brightness = modes[active_idx].brightness;
|
||||
unsigned char speed = modes[active_idx].speed;
|
||||
|
||||
controller->SetAmbientLightPower(true);
|
||||
controller->SetAmbientLight(effect, r, g, b, brightness, speed);
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarAmbient::DeviceUpdateZoneLEDs(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarAmbient::DeviceUpdateSingleLED(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarAmbient::DeviceUpdateMode()
|
||||
{
|
||||
if(!first_mode_update_ignored)
|
||||
{
|
||||
first_mode_update_ignored = true;
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_EdifierHaloPixelbarAmbient.h |
|
||||
| |
|
||||
| RGBController for Edifier Halo PixelBar Ambient Light |
|
||||
| |
|
||||
| Bartholomew Ho <[email protected]> 20 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "RGBController.h"
|
||||
#include "EdifierHaloController.h"
|
||||
|
||||
class RGBController_EdifierHaloPixelbarAmbient : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_EdifierHaloPixelbarAmbient(EdifierHaloController* controller_ptr);
|
||||
~RGBController_EdifierHaloPixelbarAmbient();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
EdifierHaloController* controller;
|
||||
bool first_leds_update_ignored;
|
||||
bool first_mode_update_ignored;
|
||||
};
|
||||
@@ -0,0 +1,173 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_EdifierHaloPixelbarScreen.cpp |
|
||||
| |
|
||||
| RGBController for Edifier Halo PixelBar Screen Color |
|
||||
| |
|
||||
| Bartholomew Ho <[email protected]> 20 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_EdifierHaloPixelbarScreen.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Edifier Halo Pixelbar - Screen
|
||||
@category Speaker
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :x:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectEdifierHaloControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
struct CategoryDefinition
|
||||
{
|
||||
std::string name;
|
||||
unsigned char category_id;
|
||||
};
|
||||
|
||||
RGBController_EdifierHaloPixelbarScreen::RGBController_EdifierHaloPixelbarScreen(EdifierHaloController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
first_leds_update_ignored = false;
|
||||
first_mode_update_ignored = false;
|
||||
|
||||
name = "Edifier Halo Pixelbar - Pixel Display";
|
||||
vendor = "Edifier";
|
||||
type = DEVICE_TYPE_SPEAKER;
|
||||
description = "Edifier Halo PixelBar Pixel Display Color";
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
// Clock 1 to Clock 11 (11 built-in clock styles)
|
||||
for(unsigned char i = 0; i < 11; ++i)
|
||||
{
|
||||
mode m;
|
||||
m.name = "Clock " + std::to_string(i + 1);
|
||||
m.value = (0 << 8) | i;
|
||||
m.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
m.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(m);
|
||||
}
|
||||
|
||||
// Default built-in layouts for other categories
|
||||
std::vector<CategoryDefinition> categories =
|
||||
{
|
||||
{ "Gaming", 1 },
|
||||
{ "Work", 2 },
|
||||
{ "Study", 3 },
|
||||
{ "Cats", 4 },
|
||||
{ "Dogs", 5 },
|
||||
{ "Buzzwords", 6 },
|
||||
{ "Cyberpunk", 7 },
|
||||
{ "Spectrum", 8 }
|
||||
};
|
||||
|
||||
for(const CategoryDefinition& cat : categories)
|
||||
{
|
||||
mode m;
|
||||
m.name = cat.name;
|
||||
m.value = (cat.category_id << 8) | 0;
|
||||
m.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
m.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(m);
|
||||
}
|
||||
|
||||
// Default to Clock 1 mode
|
||||
active_mode = 0;
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_EdifierHaloPixelbarScreen::~RGBController_EdifierHaloPixelbarScreen()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarScreen::SetupZones()
|
||||
{
|
||||
zone screen_zone;
|
||||
screen_zone.name = "Screen Color";
|
||||
screen_zone.type = ZONE_TYPE_SINGLE;
|
||||
screen_zone.leds_min = 1;
|
||||
screen_zone.leds_max = 1;
|
||||
screen_zone.leds_count = 1;
|
||||
zones.push_back(screen_zone);
|
||||
|
||||
led screen_led;
|
||||
screen_led.name = "Screen Text";
|
||||
leds.push_back(screen_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarScreen::DeviceUpdateLEDs()
|
||||
{
|
||||
if(!first_leds_update_ignored)
|
||||
{
|
||||
first_leds_update_ignored = true;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char r = 255;
|
||||
unsigned char g = 255;
|
||||
unsigned char b = 255;
|
||||
|
||||
if(!colors.empty())
|
||||
{
|
||||
RGBColor color = colors[0];
|
||||
r = RGBGetRValue(color);
|
||||
g = RGBGetGValue(color);
|
||||
b = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
// For all other modes, color updates are sent using SetPixelScreenColor
|
||||
controller->SetPixelScreenColor(r, g, b);
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarScreen::DeviceUpdateZoneLEDs(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarScreen::DeviceUpdateSingleLED(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarScreen::DeviceUpdateMode()
|
||||
{
|
||||
if(!first_mode_update_ignored)
|
||||
{
|
||||
first_mode_update_ignored = true;
|
||||
return;
|
||||
}
|
||||
|
||||
int active_idx = GetActiveMode();
|
||||
unsigned char r = 255;
|
||||
unsigned char g = 255;
|
||||
unsigned char b = 255;
|
||||
|
||||
if(!colors.empty())
|
||||
{
|
||||
RGBColor color = colors[0];
|
||||
r = RGBGetRValue(color);
|
||||
g = RGBGetGValue(color);
|
||||
b = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
unsigned int mode_val = modes[active_idx].value;
|
||||
unsigned char category = (mode_val >> 8) & 0xFF;
|
||||
unsigned char index = mode_val & 0xFF;
|
||||
|
||||
if(category == 0) // Clock category (11 built-in styles)
|
||||
{
|
||||
controller->SetScreenScene(0, index, r, g, b);
|
||||
}
|
||||
else // Other categories (Gaming, Working, etc.) use the default built-in layouts
|
||||
{
|
||||
controller->SetScreenUIModel(category, r, g, b);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_EdifierHaloPixelbarScreen.h |
|
||||
| |
|
||||
| RGBController for Edifier Halo PixelBar Screen Color |
|
||||
| |
|
||||
| Bartholomew Ho <[email protected]> 20 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "RGBController.h"
|
||||
#include "EdifierHaloController.h"
|
||||
|
||||
class RGBController_EdifierHaloPixelbarScreen : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_EdifierHaloPixelbarScreen(EdifierHaloController* controller_ptr);
|
||||
~RGBController_EdifierHaloPixelbarScreen();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
EdifierHaloController* controller;
|
||||
bool first_leds_update_ignored;
|
||||
bool first_mode_update_ignored;
|
||||
};
|
||||
@@ -1,133 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EpomakerController.cpp |
|
||||
| |
|
||||
| Driver for Epomaker keyboard |
|
||||
| |
|
||||
| Alvaro Munoz (alvaromunoz) 05 Jun 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <math.h>
|
||||
#include "EpomakerController.h"
|
||||
#include "LogManager.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
EpomakerController::EpomakerController(hid_device* dev_handle, char *_path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = _path;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get device name from HID manufacturer and product strings |
|
||||
\*---------------------------------------------------------*/
|
||||
wchar_t name_string[HID_MAX_STR];
|
||||
|
||||
hid_get_manufacturer_string(dev, name_string, HID_MAX_STR);
|
||||
device_name = StringUtils::wstring_to_string(name_string);
|
||||
|
||||
hid_get_product_string(dev, name_string, HID_MAX_STR);
|
||||
device_name.append(" ").append(StringUtils::wstring_to_string(name_string));
|
||||
|
||||
current_mode = EPOMAKER_MODE_ALWAYS_ON;
|
||||
current_speed = EPOMAKER_SPEED_DEFAULT;
|
||||
current_brightness = EPOMAKER_BRIGHTNESS_DEFAULT;
|
||||
current_dazzle = EPOMAKER_OPTION_DAZZLE_OFF;
|
||||
current_option = EPOMAKER_OPTION_DEFAULT;
|
||||
}
|
||||
|
||||
EpomakerController::~EpomakerController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string EpomakerController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string EpomakerController::GetSerial()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string EpomakerController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
void EpomakerController::SetMode(unsigned char mode, unsigned char speed, unsigned char brightness)
|
||||
{
|
||||
current_mode = mode;
|
||||
current_speed = speed;
|
||||
current_brightness = brightness;
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void EpomakerController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
current_red = red;
|
||||
current_green = green;
|
||||
current_blue = blue;
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void EpomakerController::SetDazzle(bool is_dazzle)
|
||||
{
|
||||
if(is_dazzle)
|
||||
{
|
||||
current_dazzle = EPOMAKER_OPTION_DAZZLE_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_dazzle = EPOMAKER_OPTION_DAZZLE_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
void EpomakerController::SetOption(unsigned char option)
|
||||
{
|
||||
current_option = option;
|
||||
}
|
||||
|
||||
void EpomakerController::SendUpdate()
|
||||
{
|
||||
unsigned char buffer[EPOMAKER_PACKET_LENGTH + 1] = { 0x00 };
|
||||
|
||||
buffer[EPOMAKER_BYTE_COMMAND] = EPOMAKER_COMMAND_RGB;
|
||||
buffer[EPOMAKER_BYTE_MODE] = current_mode;
|
||||
buffer[EPOMAKER_BYTE_SPEED] = current_speed;
|
||||
buffer[EPOMAKER_BYTE_BRIGHTNESS] = current_brightness;
|
||||
buffer[EPOMAKER_BYTE_FLAGS] = current_option | current_dazzle;
|
||||
buffer[EPOMAKER_BYTE_RED] = current_red;
|
||||
buffer[EPOMAKER_BYTE_GREEN] = current_green;
|
||||
buffer[EPOMAKER_BYTE_BLUE] = current_blue;
|
||||
|
||||
int sum_bits = 0;
|
||||
for(int i = EPOMAKER_BYTE_COMMAND; i <= EPOMAKER_BYTE_BLUE; i++)
|
||||
{
|
||||
sum_bits += buffer[i];
|
||||
}
|
||||
|
||||
int next_pow2 = (int)(pow(2, ceil(log2((double)(sum_bits)))));
|
||||
int filler = next_pow2 - sum_bits - 1;
|
||||
|
||||
buffer[EPOMAKER_BYTE_FILLER] = filler;
|
||||
|
||||
int send_buffer_result = hid_send_feature_report(dev, buffer, (sizeof(buffer) / sizeof(buffer[0])));
|
||||
if(send_buffer_result<0)
|
||||
{
|
||||
LOG_ERROR("[EPOMAKER]: Send Buffer Error. HIDAPI Error: %ls", hid_error(dev));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EpomakerControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Epomaker keyboard |
|
||||
| |
|
||||
| Alvaro Munoz (alvaromunoz) 05 Jun 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "EpomakerController.h"
|
||||
#include "RGBController_EpomakerController.h"
|
||||
|
||||
#define EPOMAKER_VID 0x3151
|
||||
#define EPOMAKER_TH80_Pro_USB_PID 0x4010
|
||||
#define ATTACKSHARK_K86_USB_PID 0x4015
|
||||
#define EPOMAKER_TH80_Pro_Dongle_PID 0x4011 /* Attack shark's Dongle is the same. */
|
||||
#define EPOMAKER_TH80_Pro_BT_PID 0x4013
|
||||
#define ATTACKSHARK_K86_BT_PID 0x401
|
||||
|
||||
DetectedControllers DetectEpomakerControllers(hid_device_info* info, const std::string&)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EpomakerController* controller = new EpomakerController(dev, info->path);
|
||||
RGBController_EpomakerController* rgb_controller = new RGBController_EpomakerController(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_I("Epomaker TH80 Pro (USB Cable)", DetectEpomakerControllers, EPOMAKER_VID, EPOMAKER_TH80_Pro_USB_PID, 2);
|
||||
REGISTER_HID_DETECTOR_I("Epomaker TH80 Pro (USB Dongle)", DetectEpomakerControllers, EPOMAKER_VID, EPOMAKER_TH80_Pro_Dongle_PID, 2);
|
||||
REGISTER_HID_DETECTOR_I("Attack Shark K86 (USB Cable)", DetectEpomakerControllers, EPOMAKER_VID, ATTACKSHARK_K86_USB_PID, 2);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Bluetooth Not implemented |
|
||||
\*---------------------------------------------------------*/
|
||||
//REGISTER_HID_DETECTOR("Epomaker TH80 Pro (Bluetooth)", DetectEpomakerControllers, EPOMAKER_VID, EPOMAKER_TH80_Pro_BT_PID);
|
||||
//REGISTER_HID_DETECTOR("Attack Shark K86 (Bluetooth)", DetectEpomakerControllers, EPOMAKER_VID, ATTACKSHARK_K86_BT_PID);
|
||||
@@ -99,3 +99,4 @@ REGISTER_I2C_PCI_DETECTOR("Gainward GeForce RTX 3080 Phoenix", DetectGa
|
||||
REGISTER_I2C_PCI_DETECTOR("Gainward GeForce RTX 3080 Ti Phoenix", DetectGainwardGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, GAINWARD_SUB_VEN, NVIDIA_RTX3080TI_DEV, 0x49);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gainward GeForce RTX 3090 Phoenix", DetectGainwardGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090_DEV, GAINWARD_SUB_VEN, NVIDIA_RTX3090_DEV, 0x49);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gainward GeForce RTX 3090 Ti Phantom", DetectGainwardGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090TI_DEV, GAINWARD_SUB_VEN, GAINWARD_RTX_3090TI_PHANTOM, 0x49);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gainward GeForce RTX 4080 Phantom GS", DetectGainwardGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, GAINWARD_SUB_VEN, GAINWARD_RTX_4080_PHANTOM_GS_SUB_DEV, 0x49);
|
||||
|
||||
+3
-2
@@ -44,8 +44,9 @@ bool TestForGigabyteRGBFusion2BlackwellGPUController(i2c_smbus_interface* bus, u
|
||||
//GeForce RTX 5070 Ti Gaming OC 16G 0x01 0x01 0x01 0x00
|
||||
//GeForce RTX 5070 Gaming OC 12G 0x01 0x01 0x01 0x00
|
||||
//GeForce RTX 5080 AORUS MASTER 16G 0x01 0x01 0x01 0x10
|
||||
//Radeon RX 9070 XT GAMING OC 16G 0x01 0x02 0x01 0x00
|
||||
|
||||
if(res < 0 || data_readpkt[0] != 0x01 || data_readpkt[1] != 0x01 || data_readpkt[2] != 0x01)
|
||||
if(res < 0 || data_readpkt[0] != 0x01 || (data_readpkt[1] != 0x01 && data_readpkt[1] != 0x02) || data_readpkt[2] != 0x01)
|
||||
{
|
||||
// Assemble C-string with respons for debugging
|
||||
std::string text = "";
|
||||
@@ -57,7 +58,7 @@ bool TestForGigabyteRGBFusion2BlackwellGPUController(i2c_smbus_interface* bus, u
|
||||
text.append(str);
|
||||
}
|
||||
|
||||
LOG_DEBUG("[%s] at address 0x%02X invalid. Expected 0x01 0x01 0x01 [0x*] but received:%s", GIGABYTEGPU_CONTROLLER_NAME3, address, text.c_str());
|
||||
LOG_DEBUG("[%s] at address 0x%02X invalid. Expected 0x01 0x01/0x02 0x01 [0x*] but received:%s", GIGABYTEGPU_CONTROLLER_NAME3, address, text.c_str());
|
||||
pass = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -170,6 +170,7 @@ REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 5090 MASTER ICE",
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 7600 GAMING OC 8G", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI33_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX7600_GAMING_OC_8G_SUB_DEV, 0x55);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 7600 GAMING OC 8G", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI33_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX7600_GAMING_OC_8G_SUB_DEV2, 0x55);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 7600 XT GAMING OC 16G", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI33_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX7600XT_GAMING_OC_16G_SUB_DEV, 0x55);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 6700 XT EAGLE 12G", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI22_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX6700XT_EAGLE_12G_SUB_DEV, 0x63);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 6700 XT GAMING OC 12G", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI22_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX6700XT_GAMING_OC_12G_SUB_DEV, 0x62);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 6800 XT GAMING OC", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV1, GIGABYTE_SUB_VEN, GIGABYTE_RX6800XT_GAMING_OC_SUB_DEV, 0x62);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 6900 XT GAMING OC", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV1, GIGABYTE_SUB_VEN, GIGABYTE_RX6900XT_GAMING_OC_SUB_DEV, 0x62);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -64,7 +64,7 @@ RGBFusion2USBController::RGBFusion2USBController(hid_device* handle, const char*
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(report.support_cmd_flag >= 0x02)
|
||||
if(report.support_cmd_flag & 0x02)
|
||||
{
|
||||
EnableLampArray(false);
|
||||
}
|
||||
@@ -365,7 +365,18 @@ bool RGBFusion2USBController::SetStripBuiltinEffectState(int hdr, bool enable)
|
||||
|
||||
if(hdr == -1)
|
||||
{
|
||||
bitmask = 0x01 | 0x02 | 0x08 | 0x10;
|
||||
switch(product_id)
|
||||
{
|
||||
case 0xa100:
|
||||
bitmask = 0x01;
|
||||
break;
|
||||
case 0x5711:
|
||||
bitmask = 0x01 | 0x02 | 0x08 | 0x10;
|
||||
break;
|
||||
default:
|
||||
bitmask = 0x01 | 0x02;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -394,8 +405,6 @@ bool RGBFusion2USBController::SetStripBuiltinEffectState(int hdr, bool enable)
|
||||
int new_effect_disabled = enable
|
||||
? (base_mask & ~bitmask)
|
||||
: (base_mask | bitmask);
|
||||
|
||||
// Skip redundant writes only after we have synchronized at least once
|
||||
if(effect_disabled >= 0 && new_effect_disabled == effect_disabled)
|
||||
{
|
||||
return true;
|
||||
@@ -440,7 +449,11 @@ bool RGBFusion2USBController::EnableLampArray(bool enable)
|
||||
|
||||
std::string RGBFusion2USBController::GetDeviceName()
|
||||
{
|
||||
return(name);
|
||||
if(product_id == 0xa100)
|
||||
{
|
||||
return ("GC-USB");
|
||||
}
|
||||
return (name);
|
||||
}
|
||||
|
||||
std::string RGBFusion2USBController::GetDeviceDescription()
|
||||
@@ -736,31 +749,39 @@ std::vector<Gen2StripInfo> RGBFusion2USBController::ExportGen2Strips() const
|
||||
/*---------------------------------------------------------*\
|
||||
| Scan Headers for Gen2 Devices |
|
||||
\*---------------------------------------------------------*/
|
||||
bool RGBFusion2USBController::ScanGen2Strips()
|
||||
bool RGBFusion2USBController::ScanGen2Strips(uint8_t enabled_headers)
|
||||
{
|
||||
for(unsigned i = 0; i < 4; ++i)
|
||||
for(unsigned int i = 0; i < 4; ++i)
|
||||
{
|
||||
if(g2_strip_info[i].LedsOfStrip.capacity() < 15)
|
||||
{
|
||||
g2_strip_info[i].LedsOfStrip.reserve(15);
|
||||
}
|
||||
g2_strip_info[i].numStrip = 0;
|
||||
g2_strip_info[i].totalLeds = 0;
|
||||
g2_strip_info[i].LedsOfStrip.resize(0);
|
||||
|
||||
g2_strip_info[i].numStrip = 0;
|
||||
g2_strip_info[i].totalLeds = 0;
|
||||
g2_strip_info[i].LedsOfStrip.clear();
|
||||
}
|
||||
|
||||
const unsigned int hdr_lim = (product_id == 0x5711) ? 4u : 2u;
|
||||
|
||||
for(unsigned int slot = 0; slot < hdr_lim; ++slot)
|
||||
{
|
||||
if(!(enabled_headers & (1U << slot)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
static constexpr uint8_t delta[4] = {4, 5, 0, 1};
|
||||
uint8_t scan_cmd = static_cast<uint8_t>(GEN2_LED_BASE_SCAN + delta[slot]);
|
||||
uint8_t info_cmd = static_cast<uint8_t>(scan_cmd + 2);
|
||||
|
||||
uint8_t scan_cmd = GEN2_LED_BASE_SCAN + delta[slot];
|
||||
uint8_t info_cmd = scan_cmd + 2;
|
||||
|
||||
if(!SendCCReport(scan_cmd, 0x00, 0x00))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(700));
|
||||
|
||||
if(!SendCCReport(info_cmd, 0x00, 0x00))
|
||||
@@ -768,48 +789,60 @@ bool RGBFusion2USBController::ScanGen2Strips()
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char feature_buf[64] = {0};
|
||||
feature_buf[0] = report_id;
|
||||
int recv_len = hid_get_feature_report(dev, feature_buf, sizeof(feature_buf));
|
||||
unsigned char feat_buf[64] = {0};
|
||||
feat_buf[0] = report_id;
|
||||
|
||||
int recv_len = hid_get_feature_report
|
||||
(
|
||||
dev,
|
||||
feat_buf,
|
||||
sizeof(feat_buf)
|
||||
);
|
||||
|
||||
if(recv_len < 64)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int seg_count = static_cast<int>(feature_buf[1]);
|
||||
if(seg_count < 0)
|
||||
{
|
||||
seg_count = 0;
|
||||
}
|
||||
int seg_count = feat_buf[1];
|
||||
|
||||
if(seg_count > 15)
|
||||
{
|
||||
seg_count = 15;
|
||||
seg_count = 15;
|
||||
}
|
||||
Gen2StripInfo& dst = g2_strip_info[slot];
|
||||
dst.numStrip = static_cast<uint8_t>(seg_count);
|
||||
dst.LedsOfStrip.resize(static_cast<size_t>(seg_count));
|
||||
|
||||
uint32_t total_leds = 0;
|
||||
const int counts_base = 2;
|
||||
Gen2StripInfo& dst = g2_strip_info[slot];
|
||||
dst.numStrip = seg_count;
|
||||
dst.LedsOfStrip.resize(seg_count);
|
||||
uint32_t total_leds = 0;
|
||||
const int counts_base = 2;
|
||||
|
||||
for(int k = 0; k < seg_count; ++k)
|
||||
{
|
||||
const int off = counts_base + (k * 2);
|
||||
uint16_t lo = static_cast<uint16_t>(feature_buf[off + 0]);
|
||||
uint16_t hi = static_cast<uint16_t>(feature_buf[off + 1]);
|
||||
uint16_t cnt = static_cast<uint16_t>(lo | (hi << 8));
|
||||
|
||||
dst.LedsOfStrip[static_cast<size_t>(k)] = cnt;
|
||||
total_leds += cnt;
|
||||
const int off = counts_base + (k * 2);
|
||||
uint16_t lo = feat_buf[off];
|
||||
uint16_t hi = feat_buf[off + 1];
|
||||
uint16_t cnt = lo | (hi << 8);
|
||||
dst.LedsOfStrip[k] = cnt;
|
||||
total_leds += cnt;
|
||||
}
|
||||
|
||||
dst.totalLeds = total_leds;
|
||||
dst.totalLeds = total_leds;
|
||||
|
||||
SetLedCount(0, 0, 0, 0);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
|
||||
SaveLEDState(false);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Check controller for persistent state support |
|
||||
\*---------------------------------------------------------*/
|
||||
bool RGBFusion2USBController::SupportsSaveLEDState() const
|
||||
{
|
||||
return(report_loaded && (report.support_cmd_flag & 0x01));
|
||||
}
|
||||
|
||||
@@ -234,6 +234,10 @@ union PktEffect
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
e.report_id = report_id;
|
||||
if(pid ==0xA100)
|
||||
{
|
||||
led = -1;
|
||||
}
|
||||
if(led == -1)
|
||||
{
|
||||
e.zone0 = (pid == 0x5711) ? 0x07FF : 0xFF;
|
||||
@@ -337,7 +341,9 @@ public:
|
||||
bool SetStripBuiltinEffectState(int hdr, bool enable);
|
||||
void SetStripColors(unsigned int hdr, RGBColor * colors, unsigned int num_colors, int single_led = -1);
|
||||
bool SupportsGen2() const;
|
||||
bool ScanGen2Strips();
|
||||
bool ScanGen2Strips(uint8_t hdr_mask);
|
||||
bool SaveLEDState(bool enable);
|
||||
bool SupportsSaveLEDState() const;
|
||||
|
||||
EncodedCalibration GetCalibration(bool refresh_from_hw = false);
|
||||
std::string GetDeviceName();
|
||||
@@ -357,7 +363,6 @@ private:
|
||||
uint32_t EncodeCalibrationBuffer(const std::string& rgb_order);
|
||||
bool RefreshHardwareInfo();
|
||||
void ResetController();
|
||||
bool SaveLEDState(bool enable);
|
||||
bool SaveCalState();
|
||||
bool SendCCReport(uint8_t a, uint8_t b, uint8_t c = 0);
|
||||
bool SendReport(uint8_t id, uint8_t a, uint8_t b, uint8_t c = 0);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#define DETECTOR_NAME "Gigabyte RGB Fusion 2 USB"
|
||||
|
||||
#define GC_USB_VID 0x0414
|
||||
#define IT8297_VID 0x048D
|
||||
#define IT8297_IFC 0
|
||||
#define IT8297_U 0xCC
|
||||
@@ -47,3 +48,4 @@ REGISTER_HID_DETECTOR_PU(DETECTOR_NAME, DetectGigabyteRGBFusion2USBControllers,
|
||||
REGISTER_HID_DETECTOR_PU(DETECTOR_NAME, DetectGigabyteRGBFusion2USBControllers, IT8297_VID, 0x8950, IT8297_UPG, IT8297_U);
|
||||
REGISTER_HID_DETECTOR_PU(DETECTOR_NAME, DetectGigabyteRGBFusion2USBControllers, IT8297_VID, 0x5702, IT8297_UPG, IT8297_U);
|
||||
REGISTER_HID_DETECTOR_PU(DETECTOR_NAME, DetectGigabyteRGBFusion2USBControllers, IT8297_VID, 0x5711, IT8297_UPG, IT8297_U);
|
||||
REGISTER_HID_DETECTOR_PU(DETECTOR_NAME, DetectGigabyteRGBFusion2USBControllers, GC_USB_VID, 0xa100, IT8297_UPG, IT8297_U);
|
||||
|
||||
+488
-105
@@ -46,7 +46,8 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFFFF;
|
||||
Direct.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.flags = MODE_FLAG_HAS_BRIGHTNESS
|
||||
| MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.brightness_min = RGBFUSION2_BRIGHTNESS_MIN;
|
||||
Direct.brightness_max = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
Direct.brightness = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
@@ -56,7 +57,9 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = EFFECT_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Static.flags = MODE_FLAG_HAS_BRIGHTNESS
|
||||
| MODE_FLAG_HAS_MODE_SPECIFIC_COLOR
|
||||
| MODE_FLAG_MANUAL_SAVE;
|
||||
Static.brightness_min = RGBFUSION2_BRIGHTNESS_MIN;
|
||||
Static.brightness_max = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
Static.brightness = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
@@ -69,7 +72,11 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = EFFECT_PULSE;
|
||||
Breathing.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Breathing.flags = MODE_FLAG_HAS_BRIGHTNESS
|
||||
| MODE_FLAG_HAS_SPEED
|
||||
| MODE_FLAG_HAS_MODE_SPECIFIC_COLOR
|
||||
| MODE_FLAG_HAS_RANDOM_COLOR
|
||||
| MODE_FLAG_MANUAL_SAVE;
|
||||
Breathing.brightness_min = RGBFUSION2_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = 100; // Set 100 max due to controller quirks
|
||||
Breathing.brightness = Breathing.brightness_max;
|
||||
@@ -85,7 +92,11 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
mode Blinking;
|
||||
Blinking.name = "Flashing";
|
||||
Blinking.value = EFFECT_BLINKING;
|
||||
Blinking.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Blinking.flags = MODE_FLAG_HAS_BRIGHTNESS
|
||||
| MODE_FLAG_HAS_SPEED
|
||||
| MODE_FLAG_HAS_MODE_SPECIFIC_COLOR
|
||||
| MODE_FLAG_HAS_RANDOM_COLOR
|
||||
| MODE_FLAG_MANUAL_SAVE;
|
||||
Blinking.brightness_min = RGBFUSION2_BRIGHTNESS_MIN;
|
||||
Blinking.brightness_max = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
Blinking.brightness = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
@@ -101,7 +112,9 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
mode ColorCycle;
|
||||
ColorCycle.name = "Color Cycle";
|
||||
ColorCycle.value = EFFECT_COLORCYCLE;
|
||||
ColorCycle.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
ColorCycle.flags = MODE_FLAG_HAS_BRIGHTNESS
|
||||
| MODE_FLAG_HAS_SPEED
|
||||
| MODE_FLAG_MANUAL_SAVE;
|
||||
ColorCycle.brightness_min = RGBFUSION2_BRIGHTNESS_MIN;
|
||||
ColorCycle.brightness_max = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
ColorCycle.brightness = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
@@ -114,7 +127,11 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
mode Flashing;
|
||||
Flashing.name = "Double Flash";
|
||||
Flashing.value = EFFECT_DFLASH;
|
||||
Flashing.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Flashing.flags = MODE_FLAG_HAS_BRIGHTNESS
|
||||
| MODE_FLAG_HAS_SPEED
|
||||
| MODE_FLAG_HAS_MODE_SPECIFIC_COLOR
|
||||
| MODE_FLAG_HAS_RANDOM_COLOR
|
||||
| MODE_FLAG_MANUAL_SAVE;
|
||||
Flashing.brightness_min = RGBFUSION2_BRIGHTNESS_MIN;
|
||||
Flashing.brightness_max = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
Flashing.brightness = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
@@ -130,7 +147,10 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = EFFECT_WAVE;
|
||||
Wave.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Wave.flags = MODE_FLAG_HAS_BRIGHTNESS
|
||||
| MODE_FLAG_HAS_SPEED
|
||||
| MODE_FLAG_REQUIRES_ENTIRE_DEVICE
|
||||
| MODE_FLAG_MANUAL_SAVE;
|
||||
Wave.brightness_min = RGBFUSION2_BRIGHTNESS_MIN;
|
||||
Wave.brightness_max = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
Wave.brightness = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
@@ -145,7 +165,8 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
mode Random;
|
||||
Random.name = "Random";
|
||||
Random.value = EFFECT_RANDOM;
|
||||
Random.flags = MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Random.flags = MODE_FLAG_HAS_BRIGHTNESS
|
||||
| MODE_FLAG_MANUAL_SAVE;
|
||||
Random.brightness_min = RGBFUSION2_BRIGHTNESS_MIN;
|
||||
Random.brightness_max = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
Random.brightness = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
@@ -157,7 +178,9 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
mode Wave1;
|
||||
Wave1.name = "Wave 1";
|
||||
Wave1.value = EFFECT_WAVE1;
|
||||
Wave1.flags = MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Wave1.flags = MODE_FLAG_HAS_BRIGHTNESS
|
||||
| MODE_FLAG_REQUIRES_ENTIRE_DEVICE
|
||||
| MODE_FLAG_MANUAL_SAVE;
|
||||
Wave1.brightness_min = RGBFUSION2_BRIGHTNESS_MIN;
|
||||
Wave1.brightness_max = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
Wave1.brightness = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
@@ -169,7 +192,9 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
mode Wave2;
|
||||
Wave2.name = "Wave 2";
|
||||
Wave2.value = EFFECT_WAVE2;
|
||||
Wave2.flags = MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Wave2.flags = MODE_FLAG_HAS_BRIGHTNESS
|
||||
| MODE_FLAG_REQUIRES_ENTIRE_DEVICE
|
||||
| MODE_FLAG_MANUAL_SAVE;
|
||||
Wave2.brightness_min = RGBFUSION2_BRIGHTNESS_MIN;
|
||||
Wave2.brightness_max = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
Wave2.brightness = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
@@ -181,7 +206,9 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
mode Wave3;
|
||||
Wave3.name = "Wave 3";
|
||||
Wave3.value = EFFECT_WAVE3;
|
||||
Wave3.flags = MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Wave3.flags = MODE_FLAG_HAS_BRIGHTNESS
|
||||
| MODE_FLAG_REQUIRES_ENTIRE_DEVICE
|
||||
| MODE_FLAG_MANUAL_SAVE;
|
||||
Wave3.brightness_min = RGBFUSION2_BRIGHTNESS_MIN;
|
||||
Wave3.brightness_max = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
Wave3.brightness = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
@@ -193,7 +220,9 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
mode Wave4;
|
||||
Wave4.name = "Wave 4";
|
||||
Wave4.value = EFFECT_WAVE4;
|
||||
Wave4.flags = MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Wave4.flags = MODE_FLAG_HAS_BRIGHTNESS
|
||||
| MODE_FLAG_REQUIRES_ENTIRE_DEVICE
|
||||
| MODE_FLAG_MANUAL_SAVE;
|
||||
Wave4.brightness_min = RGBFUSION2_BRIGHTNESS_MIN;
|
||||
Wave4.brightness_max = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
Wave4.brightness = RGBFUSION2_BRIGHTNESS_MAX;
|
||||
@@ -202,6 +231,14 @@ RGBController_RGBFusion2USB::RGBController_RGBFusion2USB(RGBFusion2USBController
|
||||
Wave4.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Wave4);
|
||||
|
||||
if(!controller->SupportsSaveLEDState())
|
||||
{
|
||||
for(unsigned int mode_idx = 0; mode_idx < modes.size(); mode_idx++)
|
||||
{
|
||||
modes[mode_idx].flags &= ~MODE_FLAG_MANUAL_SAVE;
|
||||
}
|
||||
}
|
||||
|
||||
Init_Controller();
|
||||
SetupZones();
|
||||
}
|
||||
@@ -225,7 +262,7 @@ RGBController_RGBFusion2USB::~RGBController_RGBFusion2USB()
|
||||
\*---------------------------------------------------------*/
|
||||
void RGBController_RGBFusion2USB::Init_Controller()
|
||||
{
|
||||
|
||||
bool settings_changed = false;
|
||||
const gb_fusion2_device* src_layout = gb_fusion2_device_list[device_index];
|
||||
const std::string SectionGen2 = "Gigabyte-Gen2-ARGB";
|
||||
const std::string SectionCustomBase = "CustomLayout";
|
||||
@@ -240,37 +277,101 @@ void RGBController_RGBFusion2USB::Init_Controller()
|
||||
\*---------------------------------------------------------*/
|
||||
if(controller->SupportsGen2())
|
||||
{
|
||||
if(!device_settings.contains(SectionGen2))
|
||||
static const char* gen2_header_keys[4] =
|
||||
{
|
||||
device_settings[SectionGen2]["Enabled"] = false;
|
||||
settings_manager->SetSettings(detector_name, device_settings);
|
||||
settings_manager->SaveSettings();
|
||||
"D_LED1",
|
||||
"D_LED2",
|
||||
"D_LED3",
|
||||
"D_LED4"
|
||||
};
|
||||
|
||||
const unsigned int header_count = controller->ExportGen2Strips().size();
|
||||
|
||||
bool default_enabled = false;
|
||||
uint8_t enabled_headers = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Preserve the old global setting when migrating |
|
||||
\*-----------------------------------------------------*/
|
||||
if(device_settings[SectionGen2].contains("Enabled"))
|
||||
{
|
||||
default_enabled = device_settings[SectionGen2]["Enabled"];
|
||||
|
||||
device_settings[SectionGen2].erase("Enabled");
|
||||
settings_changed = true;
|
||||
}
|
||||
|
||||
supports_gen2 = device_settings[SectionGen2]["Enabled"];
|
||||
/*-----------------------------------------------------*\
|
||||
| Create and read the per-header settings |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int header = 0; header < header_count; ++header)
|
||||
{
|
||||
if(!device_settings[SectionGen2].contains(gen2_header_keys[header]))
|
||||
{
|
||||
device_settings[SectionGen2][gen2_header_keys[header]] = default_enabled;
|
||||
settings_changed = true;
|
||||
}
|
||||
|
||||
if(device_settings[SectionGen2][gen2_header_keys[header]])
|
||||
{
|
||||
enabled_headers |= 1U << header;
|
||||
}
|
||||
}
|
||||
|
||||
supports_gen2 = enabled_headers != 0;
|
||||
|
||||
if(supports_gen2)
|
||||
{
|
||||
controller->ScanGen2Strips();
|
||||
controller->ScanGen2Strips(enabled_headers);
|
||||
}
|
||||
}
|
||||
else if(device_settings.contains(SectionGen2))
|
||||
{
|
||||
device_settings.erase(SectionGen2);
|
||||
settings_changed = true;
|
||||
}
|
||||
|
||||
if(settings_changed)
|
||||
{
|
||||
settings_manager->SetSettings(detector_name, device_settings);
|
||||
settings_manager->SaveSettings();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create the custom layout from the generic layout |
|
||||
\*---------------------------------------------------------*/
|
||||
switch(product_id)
|
||||
if(device_num == 1)
|
||||
{
|
||||
case 0x8950:
|
||||
src_layout = gb_fusion2_device_list[device_index + 1];
|
||||
break;
|
||||
case 0x5711:
|
||||
src_layout = gb_fusion2_device_list[device_index + 2];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch(product_id)
|
||||
{
|
||||
break;
|
||||
case 0x5711:
|
||||
src_layout = gb_fusion2_device_list[device_index + 4];
|
||||
break;
|
||||
default:
|
||||
src_layout = gb_fusion2_device_list[device_index + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(product_id)
|
||||
{
|
||||
case 0x8950:
|
||||
src_layout = gb_fusion2_device_list[device_index + 2];
|
||||
break;
|
||||
case 0x5711:
|
||||
src_layout = gb_fusion2_device_list[device_index + 3];
|
||||
break;
|
||||
case 0xa100:
|
||||
src_layout = gb_fusion2_device_list[device_index + 5];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!device_settings.contains(SectionCustom))
|
||||
if(!device_settings.contains(SectionCustom) && (product_id != 0xA100))
|
||||
{
|
||||
device_settings[SectionCustom]["Enabled"] = false;
|
||||
device_settings[SectionCustom]["Data"] = BuildCustomLayoutJson(src_layout, ReverseLedLookup);
|
||||
@@ -282,7 +383,7 @@ void RGBController_RGBFusion2USB::Init_Controller()
|
||||
|
||||
EncodedCalibration hw_cal = controller->GetCalibration(false);
|
||||
|
||||
if(device_num == 0)
|
||||
if(device_num == 0 || product_id != 0xa100)
|
||||
{
|
||||
if(!device_settings.contains(SectionCalibration))
|
||||
{
|
||||
@@ -382,7 +483,7 @@ void RGBController_RGBFusion2USB::Init_Controller()
|
||||
(*instance_layout.zones)[zi] = (*src_layout->zones)[zi];
|
||||
}
|
||||
|
||||
if(custom_layout)
|
||||
if(custom_layout && (product_id != 0xA100))
|
||||
{
|
||||
LoadCustomLayoutFromJson(device_settings[SectionCustom]["Data"], LedLookup, &instance_layout);
|
||||
}
|
||||
@@ -428,6 +529,7 @@ void RGBController_RGBFusion2USB::SetupZones()
|
||||
first_run = true;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Clear any existing color/LED configuration |
|
||||
\*-----------------------------------------------------*/
|
||||
@@ -441,7 +543,7 @@ void RGBController_RGBFusion2USB::SetupZones()
|
||||
|
||||
for(num_zones = 0; num_zones < GB_FUSION2_ZONES_MAX; num_zones++)
|
||||
{
|
||||
if(!gb_fusion2_device_list[device_index]->zones[0][num_zones])
|
||||
if(!(*instance_layout.zones)[num_zones])
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -452,13 +554,20 @@ void RGBController_RGBFusion2USB::SetupZones()
|
||||
unsigned int d1 = 0, d2 = 0, d3 = 0, d4 = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up zones (Fixed so as to not spam the controller) |
|
||||
| Retrieve the latest Gen2 scan results |
|
||||
\*-----------------------------------------------------*/
|
||||
std::vector<Gen2StripInfo> strips;
|
||||
|
||||
if(supports_gen2)
|
||||
{
|
||||
strips = controller->ExportGen2Strips();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*-----------------------------------------------------*/
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Get zone configuration from device data |
|
||||
\*-------------------------------------------------*/
|
||||
const gb_fusion2_zone* zone_at_idx = (*instance_layout.zones)[zone_idx];
|
||||
|
||||
if(!zone_at_idx)
|
||||
@@ -466,36 +575,241 @@ void RGBController_RGBFusion2USB::SetupZones()
|
||||
continue;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Check if this is a fixed-size zone |
|
||||
\*-------------------------------------------------*/
|
||||
bool fixed_zone = (zone_at_idx->leds_min == zone_at_idx->leds_max);
|
||||
bool fixed_zone = (zone_at_idx->leds_min == 1 && zone_at_idx->leds_max == 1);
|
||||
|
||||
const Gen2StripInfo* gen2_info = nullptr;
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| (Re-)initialize the zone |
|
||||
| Locate the Gen2 result corresponding to this zone |
|
||||
\*-------------------------------------------------*/
|
||||
if(fixed_zone)
|
||||
if(supports_gen2 && !fixed_zone)
|
||||
{
|
||||
unsigned int slot = 0;
|
||||
|
||||
switch(zone_at_idx->idx)
|
||||
{
|
||||
case LED4:
|
||||
case HDR_D_LED2:
|
||||
slot = 1;
|
||||
break;
|
||||
case HDR_D_LED3:
|
||||
slot = 2;
|
||||
break;
|
||||
case HDR_D_LED4:
|
||||
slot = 3;
|
||||
break;
|
||||
default:
|
||||
slot = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if(slot < strips.size())
|
||||
{
|
||||
if(strips[slot].totalLeds > 0)
|
||||
{
|
||||
gen2_info = &strips[slot];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Automatically detected Gen2 ARGB zone |
|
||||
\*-------------------------------------------------*/
|
||||
if(gen2_info != nullptr)
|
||||
{
|
||||
bool preserve_segments = false;
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| A saved segment configuration may only rename |
|
||||
| or subdivide each detected physical strip. |
|
||||
\*---------------------------------------------*/
|
||||
if(zones[zone_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_SEGMENTS)
|
||||
{
|
||||
bool valid_segments = true;
|
||||
std::size_t segment_idx = 0;
|
||||
|
||||
for(std::size_t strip_idx = 0; strip_idx < gen2_info->LedsOfStrip.size(); strip_idx++)
|
||||
{
|
||||
unsigned int strip_leds = gen2_info->LedsOfStrip[strip_idx];
|
||||
|
||||
/*-------------------------------------*\
|
||||
| Require one group for this strip |
|
||||
\*-------------------------------------*/
|
||||
if(segment_idx >= zones[zone_idx].segments.size())
|
||||
{
|
||||
valid_segments = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!(zones[zone_idx].segments[segment_idx].flags & SEGMENT_FLAG_GROUP_START))
|
||||
{
|
||||
valid_segments = false;
|
||||
break;
|
||||
}
|
||||
|
||||
segment_idx++;
|
||||
|
||||
/*-------------------------------------*\
|
||||
| Validate subdivisions of this strip |
|
||||
\*-------------------------------------*/
|
||||
unsigned int member_leds = 0;
|
||||
bool found_member = false;
|
||||
|
||||
while(segment_idx < zones[zone_idx].segments.size())
|
||||
{
|
||||
const segment& member = zones[zone_idx].segments[segment_idx];
|
||||
|
||||
if(member.flags & SEGMENT_FLAG_GROUP_START)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(!(member.flags & SEGMENT_FLAG_GROUP_MEMBER)
|
||||
|| member.type != ZONE_TYPE_LINEAR
|
||||
|| member.leds_count == 0)
|
||||
{
|
||||
valid_segments = false;
|
||||
break;
|
||||
}
|
||||
|
||||
member_leds += member.leds_count;
|
||||
|
||||
if(member_leds > strip_leds)
|
||||
{
|
||||
valid_segments = false;
|
||||
break;
|
||||
}
|
||||
|
||||
found_member = true;
|
||||
segment_idx++;
|
||||
}
|
||||
|
||||
if(!valid_segments)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(!found_member || member_leds != strip_leds)
|
||||
{
|
||||
valid_segments = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(segment_idx != zones[zone_idx].segments.size())
|
||||
{
|
||||
valid_segments = false;
|
||||
}
|
||||
|
||||
preserve_segments = valid_segments;
|
||||
}
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Gen2 scan controls all zone-level geometry |
|
||||
\*---------------------------------------------*/
|
||||
zones[zone_idx].name = zone_at_idx->name;
|
||||
zones[zone_idx].type = ZONE_TYPE_SEGMENTED;
|
||||
zones[zone_idx].leds_count = gen2_info->totalLeds;
|
||||
zones[zone_idx].leds_min = zones[zone_idx].leds_count;
|
||||
zones[zone_idx].leds_max = zones[zone_idx].leds_count;
|
||||
zones[zone_idx].matrix_map.width = 0;
|
||||
zones[zone_idx].matrix_map.height = 0;
|
||||
zones[zone_idx].matrix_map.map.clear();
|
||||
zones[zone_idx].flags = ZONE_FLAG_MANUALLY_CONFIGURABLE_SEGMENTS;
|
||||
|
||||
if(preserve_segments)
|
||||
{
|
||||
zones[zone_idx].flags |= ZONE_FLAG_MANUALLY_CONFIGURED_SEGMENTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
zones[zone_idx].segments.clear();
|
||||
zones[zone_idx].segments.reserve(gen2_info->LedsOfStrip.size() * 2);
|
||||
|
||||
unsigned int start_idx = 0;
|
||||
|
||||
for(std::size_t strip_idx = 0; strip_idx < gen2_info->LedsOfStrip.size(); strip_idx++)
|
||||
{
|
||||
unsigned int strip_leds = gen2_info->LedsOfStrip[strip_idx];
|
||||
|
||||
/*-------------------------------------*\
|
||||
| Empty marker for a physical strip |
|
||||
\*-------------------------------------*/
|
||||
segment group;
|
||||
|
||||
group.name = "Strip " + std::to_string(strip_idx + 1);
|
||||
group.type = ZONE_TYPE_LINEAR;
|
||||
group.start_idx = 0;
|
||||
group.leds_count = 0;
|
||||
group.flags = SEGMENT_FLAG_GROUP_START;
|
||||
group.matrix_map.width = 0;
|
||||
group.matrix_map.height = 0;
|
||||
group.matrix_map.map.clear();
|
||||
|
||||
zones[zone_idx].segments.push_back(group);
|
||||
|
||||
/*-------------------------------------*\
|
||||
| Initial member covers the whole strip |
|
||||
\*-------------------------------------*/
|
||||
segment member;
|
||||
|
||||
member.name = "Strip " + std::to_string(strip_idx + 1);
|
||||
member.type = ZONE_TYPE_LINEAR;
|
||||
member.start_idx = start_idx;
|
||||
member.leds_count = strip_leds;
|
||||
member.flags = SEGMENT_FLAG_GROUP_MEMBER;
|
||||
member.matrix_map.width = 0;
|
||||
member.matrix_map.height = 0;
|
||||
member.matrix_map.map.clear();
|
||||
zones[zone_idx].segments.push_back(member);
|
||||
start_idx += strip_leds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Fixed motherboard zone |
|
||||
\*-------------------------------------------------*/
|
||||
else if(fixed_zone)
|
||||
{
|
||||
zones[zone_idx].name = zone_at_idx->name;
|
||||
zones[zone_idx].type = ZONE_TYPE_SINGLE;
|
||||
zones[zone_idx].leds_min = zone_at_idx->leds_min;
|
||||
zones[zone_idx].leds_max = zone_at_idx->leds_max;
|
||||
zones[zone_idx].leds_count = zones[zone_idx].leds_min;
|
||||
zones[zone_idx].leds_count = zone_at_idx->leds_min;
|
||||
zones[zone_idx].flags = 0;
|
||||
zones[zone_idx].matrix_map.width = 0;
|
||||
zones[zone_idx].matrix_map.height = 0;
|
||||
zones[zone_idx].matrix_map.map.clear();
|
||||
zones[zone_idx].segments.clear();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Manually configurable ARGB zone |
|
||||
\*-------------------------------------------------*/
|
||||
else
|
||||
{
|
||||
zones[zone_idx].leds_min = zone_at_idx->leds_min;
|
||||
zones[zone_idx].leds_max = zone_at_idx->leds_max;
|
||||
bool reset_manual_zone = first_run || !(zones[zone_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURABLE_SIZE);
|
||||
|
||||
if(first_run)
|
||||
if(reset_manual_zone)
|
||||
{
|
||||
zones[zone_idx].flags = ZONE_FLAG_MANUALLY_CONFIGURABLE_SIZE
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_NAME
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_TYPE
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_MATRIX_MAP
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_SEGMENTS;
|
||||
zones[zone_idx].name = zone_at_idx->name;
|
||||
zones[zone_idx].type = ZONE_TYPE_LINEAR;
|
||||
zones[zone_idx].leds_count = zone_at_idx->leds_min;
|
||||
zones[zone_idx].matrix_map.width = 0;
|
||||
zones[zone_idx].matrix_map.height = 0;
|
||||
zones[zone_idx].matrix_map.map.clear();
|
||||
zones[zone_idx].segments.clear();
|
||||
}
|
||||
|
||||
zones[zone_idx].leds_min = zone_at_idx->leds_min;
|
||||
zones[zone_idx].leds_max = zone_at_idx->leds_max;
|
||||
|
||||
if(!(zones[zone_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_NAME))
|
||||
{
|
||||
zones[zone_idx].name = zone_at_idx->name;
|
||||
@@ -515,8 +829,29 @@ void RGBController_RGBFusion2USB::SetupZones()
|
||||
{
|
||||
zones[zone_idx].matrix_map.width = 0;
|
||||
zones[zone_idx].matrix_map.height = 0;
|
||||
zones[zone_idx].matrix_map.map.resize(0);
|
||||
zones[zone_idx].matrix_map.map.clear();
|
||||
}
|
||||
|
||||
if(!(zones[zone_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_SEGMENTS))
|
||||
{
|
||||
zones[zone_idx].segments.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Initialize per-zone modes |
|
||||
\*-------------------------------------------------*/
|
||||
if(zones[zone_idx].modes.empty())
|
||||
{
|
||||
for(std::size_t mode_idx = 0; mode_idx < modes.size(); mode_idx++)
|
||||
{
|
||||
if(!(modes[mode_idx].flags & MODE_FLAG_REQUIRES_ENTIRE_DEVICE))
|
||||
{
|
||||
zones[zone_idx].modes.push_back(modes[mode_idx]);
|
||||
}
|
||||
}
|
||||
|
||||
zones[zone_idx].active_mode = -1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
@@ -525,8 +860,7 @@ void RGBController_RGBFusion2USB::SetupZones()
|
||||
for(unsigned int led_idx = 0; led_idx < zones[zone_idx].leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
|
||||
new_led.name = zone_at_idx->name;
|
||||
new_led.name = zones[zone_idx].name;
|
||||
new_led.value = zone_at_idx->idx;
|
||||
|
||||
if(!fixed_zone)
|
||||
@@ -538,7 +872,7 @@ void RGBController_RGBFusion2USB::SetupZones()
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| If not a fixed-size zone, set up LED sizes |
|
||||
| Restore the ARGB header LED counts |
|
||||
\*-------------------------------------------------*/
|
||||
if(!fixed_zone)
|
||||
{
|
||||
@@ -576,50 +910,67 @@ void RGBController_RGBFusion2USB::DeviceConfigureZone(int zone_idx)
|
||||
|
||||
void RGBController_RGBFusion2USB::DeviceUpdateLEDs()
|
||||
{
|
||||
int mode_value = (modes[active_mode].value);
|
||||
bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
|
||||
int mode_value = modes[active_mode].value;
|
||||
bool random = modes[active_mode].color_mode == MODE_COLORS_RANDOM;
|
||||
uint32_t* color = &null_color;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| If Wave 1-4 then use special sequence. |
|
||||
| Entire-device modes use the special wave sequence |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == 6 || (mode_value >= 9 && mode_value <= 12))
|
||||
if(modes[active_mode].flags & MODE_FLAG_REQUIRES_ENTIRE_DEVICE)
|
||||
{
|
||||
controller->SetStripBuiltinEffectState(-1, true);
|
||||
controller->SetLEDEffect(-1, 1, 0, 0xFF, 0, color);
|
||||
controller->SetLEDEffect(-1, EFFECT_STATIC, 0, 0xFF, false, color);
|
||||
controller->ApplyEffect();
|
||||
controller->SetLEDEffect( 2, mode_value, modes[active_mode].speed, modes[active_mode].brightness, random, color);
|
||||
controller->SetLEDEffect(2, mode_value, modes[active_mode].speed, modes[active_mode].brightness, random, color);
|
||||
controller->ApplyEffect();
|
||||
return;
|
||||
}
|
||||
|
||||
for(int zone_idx = 0; zone_idx < (int)zones.size(); zone_idx++)
|
||||
{
|
||||
mode* selected_mode = &modes[active_mode];
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Use the zone-specific mode when one is selected |
|
||||
\*---------------------------------------------------------*/
|
||||
if(zones[zone_idx].active_mode >= 0)
|
||||
{
|
||||
selected_mode = &zones[zone_idx].modes[zones[zone_idx].active_mode];
|
||||
}
|
||||
|
||||
mode_value = selected_mode->value;
|
||||
random = selected_mode->color_mode == MODE_COLORS_RANDOM;
|
||||
color = &null_color;
|
||||
|
||||
if(zones[zone_idx].type == ZONE_TYPE_SINGLE)
|
||||
{
|
||||
for(std::size_t led_idx = 0; led_idx < zones[zone_idx].leds_count; led_idx++)
|
||||
{
|
||||
int led_mode_value = mode_value;
|
||||
uint32_t* led_color = color;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Motherboard LEDs always use effect mode, so use static for|
|
||||
| direct mode but get colors from zone |
|
||||
\*---------------------------------------------------------*/
|
||||
if(modes[active_mode].value == 0xFFFF)
|
||||
if(selected_mode->value == 0xFFFF)
|
||||
{
|
||||
color = &zones[zone_idx].colors[led_idx];
|
||||
mode_value = EFFECT_STATIC;
|
||||
led_color = &zones[zone_idx].colors[led_idx];
|
||||
led_mode_value = EFFECT_STATIC;
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| If the mode uses mode-specific color, get color from mode |
|
||||
\*---------------------------------------------------------*/
|
||||
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
else if(selected_mode->color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
color = &modes[active_mode].colors[0];
|
||||
led_color = &selected_mode->colors[0];
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Apply the mode and color to the zone |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetLEDEffect(zones[zone_idx].leds[led_idx].value, mode_value, modes[active_mode].speed, modes[active_mode].brightness, random, color);
|
||||
controller->SetLEDEffect(zones[zone_idx].leds[led_idx].value, led_mode_value, selected_mode->speed, selected_mode->brightness, random, led_color);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
@@ -634,7 +985,7 @@ void RGBController_RGBFusion2USB::DeviceUpdateLEDs()
|
||||
/*---------------------------------------------------------*\
|
||||
| Direct mode addresses a different register |
|
||||
\*---------------------------------------------------------*/
|
||||
if(modes[active_mode].value == 0xFFFF)
|
||||
if(selected_mode->value == 0xFFFF)
|
||||
{
|
||||
controller->SetStripBuiltinEffectState(hdr, false);
|
||||
controller->SetStripColors(hdr, zones[zone_idx].colors, zones[zone_idx].leds_count);
|
||||
@@ -648,45 +999,52 @@ void RGBController_RGBFusion2USB::DeviceUpdateLEDs()
|
||||
/*---------------------------------------------------------*\
|
||||
| If mode has mode specific color, load color from mode |
|
||||
\*---------------------------------------------------------*/
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
if(selected_mode->color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
color = &modes[active_mode].colors[0];
|
||||
color = &selected_mode->colors[0];
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Apply hardware effects to LED strips |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetStripBuiltinEffectState(hdr, true);
|
||||
controller->SetLEDEffect(hdr, mode_value, modes[active_mode].speed, modes[active_mode].brightness, random, color);
|
||||
controller->SetLEDEffect(hdr, mode_value, selected_mode->speed, selected_mode->brightness, random, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
controller->ApplyEffect();
|
||||
}
|
||||
|
||||
void RGBController_RGBFusion2USB::DeviceUpdateZoneLEDs(int zone)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Get mode parameters |
|
||||
\*---------------------------------------------------------*/
|
||||
int mode_value = (modes[active_mode].value);
|
||||
bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
|
||||
int mode_value = modes[active_mode].value;
|
||||
bool random = modes[active_mode].color_mode == MODE_COLORS_RANDOM;
|
||||
uint32_t* color = &null_color;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| If Wave 1-4 then use special sequence. |
|
||||
| Entire-device modes cannot be updated one zone at a time |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == 6 || (mode_value >= 9 && mode_value <= 12))
|
||||
if(modes[active_mode].flags & MODE_FLAG_REQUIRES_ENTIRE_DEVICE)
|
||||
{
|
||||
controller->SetStripBuiltinEffectState(-1, true);
|
||||
controller->SetLEDEffect(-1, 1, 0, 0xFF, 0, color);
|
||||
controller->ApplyEffect();
|
||||
controller->SetLEDEffect( 2, mode_value, modes[active_mode].speed, modes[active_mode].brightness, random, color);
|
||||
controller->ApplyEffect();
|
||||
DeviceUpdateLEDs();
|
||||
return;
|
||||
}
|
||||
|
||||
mode* selected_mode = &modes[active_mode];
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Use the zone-specific mode when one is selected |
|
||||
\*---------------------------------------------------------*/
|
||||
if(zones[zone].active_mode >= 0)
|
||||
{
|
||||
selected_mode = &zones[zone].modes[zones[zone].active_mode];
|
||||
}
|
||||
|
||||
mode_value = selected_mode->value;
|
||||
random = selected_mode->color_mode == MODE_COLORS_RANDOM;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set motherboard LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
@@ -694,28 +1052,31 @@ void RGBController_RGBFusion2USB::DeviceUpdateZoneLEDs(int zone)
|
||||
{
|
||||
for(std::size_t led_idx = 0; led_idx < zones[zone].leds_count; led_idx++)
|
||||
{
|
||||
int led_mode_value = mode_value;
|
||||
uint32_t* led_color = color;
|
||||
|
||||
/*------------------------------------------------------------*\
|
||||
| Motherboard LEDs always use effect mode, so use static for |
|
||||
| direct mode but get colors from zone |
|
||||
\*------------------------------------------------------------*/
|
||||
if(mode_value == 0xFFFF)
|
||||
if(selected_mode->value == 0xFFFF)
|
||||
{
|
||||
color = &zones[zone].colors[led_idx];
|
||||
mode_value = EFFECT_STATIC;
|
||||
led_color = &zones[zone].colors[led_idx];
|
||||
led_mode_value = EFFECT_STATIC;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| If the mode uses mode-specific color, get color from mode |
|
||||
\*---------------------------------------------------------*/
|
||||
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
else if(selected_mode->color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
color = &modes[active_mode].colors[0];
|
||||
led_color = &selected_mode->colors[0];
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Apply the mode and color to the zone |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetLEDEffect(zones[zone].leds[led_idx].value, mode_value, modes[active_mode].speed, modes[active_mode].brightness, random, color);
|
||||
controller->SetLEDEffect(zones[zone].leds[led_idx].value, led_mode_value, selected_mode->speed, selected_mode->brightness, random, led_color);
|
||||
controller->ApplyEffect();
|
||||
}
|
||||
}
|
||||
@@ -732,7 +1093,7 @@ void RGBController_RGBFusion2USB::DeviceUpdateZoneLEDs(int zone)
|
||||
/*---------------------------------------------------------*\
|
||||
| Direct mode addresses a different register |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == 0xFFFF)
|
||||
if(selected_mode->value == 0xFFFF)
|
||||
{
|
||||
controller->SetStripBuiltinEffectState(hdr, false);
|
||||
controller->SetStripColors(hdr, zones[zone].colors, zones[zone].leds_count);
|
||||
@@ -746,16 +1107,16 @@ void RGBController_RGBFusion2USB::DeviceUpdateZoneLEDs(int zone)
|
||||
/*---------------------------------------------------------*\
|
||||
| If mode has mode specific color, load color from mode |
|
||||
\*---------------------------------------------------------*/
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
if(selected_mode->color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
color = &modes[active_mode].colors[0];
|
||||
color = &selected_mode->colors[0];
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Apply built-in effects to LED strips |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetStripBuiltinEffectState(hdr, true);
|
||||
controller->SetLEDEffect(hdr, mode_value, modes[active_mode].speed, modes[active_mode].brightness, random, color);
|
||||
controller->SetLEDEffect(hdr, mode_value, selected_mode->speed, selected_mode->brightness, random, color);
|
||||
controller->ApplyEffect();
|
||||
}
|
||||
}
|
||||
@@ -764,26 +1125,38 @@ void RGBController_RGBFusion2USB::DeviceUpdateZoneLEDs(int zone)
|
||||
|
||||
void RGBController_RGBFusion2USB::DeviceUpdateSingleLED(int led)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Get mode parameters |
|
||||
\*---------------------------------------------------------*/
|
||||
int mode_value = (modes[active_mode].value);
|
||||
bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
|
||||
int mode_value = modes[active_mode].value;
|
||||
bool random = modes[active_mode].color_mode == MODE_COLORS_RANDOM;
|
||||
uint32_t* color = &null_color;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| If Wave 1-4 then use special sequence. |
|
||||
| Entire-device modes cannot update an individual LED |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == 6 || (mode_value >= 9 && mode_value <= 12))
|
||||
if(modes[active_mode].flags & MODE_FLAG_REQUIRES_ENTIRE_DEVICE)
|
||||
{
|
||||
controller->SetStripBuiltinEffectState(-1, true);
|
||||
controller->SetLEDEffect(-1, 1, 0, 0xFF, 0, color);
|
||||
controller->ApplyEffect();
|
||||
controller->SetLEDEffect( 2, mode_value, modes[active_mode].speed, modes[active_mode].brightness, random, color);
|
||||
controller->ApplyEffect();
|
||||
DeviceUpdateLEDs();
|
||||
return;
|
||||
}
|
||||
unsigned int zone_idx = GetLED_Zone(led);
|
||||
|
||||
int zone_idx = GetLED_Zone(led);
|
||||
|
||||
if(zone_idx < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mode* selected_mode = &modes[active_mode];
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Use the zone-specific mode when one is selected |
|
||||
\*---------------------------------------------------------*/
|
||||
if(zones[zone_idx].active_mode >= 0)
|
||||
{
|
||||
selected_mode = &zones[zone_idx].modes[zones[zone_idx].active_mode];
|
||||
}
|
||||
|
||||
mode_value = selected_mode->value;
|
||||
random = selected_mode->color_mode == MODE_COLORS_RANDOM;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set motherboard LEDs |
|
||||
@@ -794,7 +1167,7 @@ void RGBController_RGBFusion2USB::DeviceUpdateSingleLED(int led)
|
||||
| Motherboard LEDs always use effect mode, so use static for|
|
||||
| direct mode but get colors from zone |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == 0xFFFF)
|
||||
if(selected_mode->value == 0xFFFF)
|
||||
{
|
||||
color = &colors[led];
|
||||
mode_value = EFFECT_STATIC;
|
||||
@@ -803,12 +1176,12 @@ void RGBController_RGBFusion2USB::DeviceUpdateSingleLED(int led)
|
||||
/*---------------------------------------------------------*\
|
||||
| If the mode uses mode-specific color, get color from mode |
|
||||
\*---------------------------------------------------------*/
|
||||
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
else if(selected_mode->color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
color = &modes[active_mode].colors[0];
|
||||
color = &selected_mode->colors[0];
|
||||
}
|
||||
|
||||
controller->SetLEDEffect(leds[led].value, mode_value, modes[active_mode].speed, modes[active_mode].brightness, random, color);
|
||||
controller->SetLEDEffect(leds[led].value, mode_value, selected_mode->speed, selected_mode->brightness, random, color);
|
||||
controller->ApplyEffect();
|
||||
}
|
||||
|
||||
@@ -826,6 +1199,11 @@ void RGBController_RGBFusion2USB::DeviceUpdateMode()
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_RGBFusion2USB::DeviceUpdateZoneMode(int zone)
|
||||
{
|
||||
DeviceUpdateZoneLEDs(zone);
|
||||
}
|
||||
|
||||
int RGBController_RGBFusion2USB::GetLED_Zone(int led_idx)
|
||||
{
|
||||
for(int zone_idx = 0; zone_idx < (int)zones.size(); zone_idx++)
|
||||
@@ -845,6 +1223,11 @@ int RGBController_RGBFusion2USB::GetLED_Zone(int led_idx)
|
||||
return(-1);
|
||||
}
|
||||
|
||||
void RGBController_RGBFusion2USB::DeviceSaveMode()
|
||||
{
|
||||
controller->SaveLEDState(true);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Convert calibration data to JSON |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
@@ -57,6 +57,8 @@ public:
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceUpdateZoneMode(int zone);
|
||||
void DeviceSaveMode() override;
|
||||
|
||||
private:
|
||||
std::string detector_name;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HoltekA070ControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Holtek A070 Mouse |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "HoltekA070Controller.h"
|
||||
#include "RGBController_HoltekA070.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Holtek Semiconductor Inc. vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HOLTEK_VID 0x04D9
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Mouse product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HOLTEK_A070_PID 0xA070
|
||||
|
||||
DetectedControllers DetectHoltekA070Controllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HoltekA070Controller* controller = new HoltekA070Controller(dev, info->path, name);
|
||||
RGBController_HoltekA070* rgb_controller = new RGBController_HoltekA070(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Holtek USB Gaming Mouse", DetectHoltekA070Controllers, HOLTEK_VID, HOLTEK_A070_PID, 1, 0xFF00, 2);
|
||||
@@ -0,0 +1,43 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HoltekA1FAControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Holtek A1FA Mousemat |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "HoltekA1FAController.h"
|
||||
#include "RGBController_HoltekA1FA.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Holtek Semiconductor Inc. vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HOLTEK_VID 0x04D9
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Mousemats product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HOLTEK_A1FA_PID 0xA1FA
|
||||
|
||||
DetectedControllers DetectHoltekA1FAControllers(hid_device_info *info, const std::string &name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HoltekA1FAController* controller = new HoltekA1FAController(dev, info->path, name);
|
||||
RGBController_HoltekA1FA* rgb_controller = new RGBController_HoltekA1FA(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Holtek Mousemat", DetectHoltekA1FAControllers, HOLTEK_VID, HOLTEK_A1FA_PID, 2, 0xFF00, 0xFF00);
|
||||
@@ -1,67 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HoltekControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Holtek devices |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "HoltekA070Controller.h"
|
||||
#include "RGBController_HoltekA070.h"
|
||||
#include "HoltekA1FAController.h"
|
||||
#include "RGBController_HoltekA1FA.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Holtek Semiconductor Inc. vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HOLTEK_VID 0x04D9
|
||||
/*---------------------------------------------------------*\
|
||||
| Mouse product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HOLTEK_A070_PID 0xA070
|
||||
/*---------------------------------------------------------*\
|
||||
| Mousemats product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HOLTEK_A1FA_PID 0xA1FA
|
||||
|
||||
DetectedControllers DetectHoltekControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HoltekA070Controller* controller = new HoltekA070Controller(dev, info->path, name);
|
||||
RGBController_HoltekA070* rgb_controller = new RGBController_HoltekA070(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectHoltekMousemats(hid_device_info *info, const std::string &name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HoltekA1FAController* controller = new HoltekA1FAController(dev, info->path, name);
|
||||
RGBController_HoltekA1FA* rgb_controller = new RGBController_HoltekA1FA(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Holtek USB Gaming Mouse", DetectHoltekControllers, HOLTEK_VID, HOLTEK_A070_PID, 1, 0xFF00, 2);
|
||||
REGISTER_HID_DETECTOR_IPU("Holtek Mousemat", DetectHoltekMousemats, HOLTEK_VID, HOLTEK_A1FA_PID, 2, 0xFF00, 0xFF00);
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperXAlloyElite2ControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for HyperX Alloy Elite 2 keyboards |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "HyperXAlloyElite2Controller.h"
|
||||
#include "RGBController_HyperXAlloyElite2.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HYPERX_KEYBOARD_VID 0x0951
|
||||
#define HYPERX_ALLOY_ELITE_2_PID 0x1711
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs (HP) |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HP_KEYBOARD_VID 0x03F0
|
||||
#define HYPERX_ALLOY_ELITE_2_HP_PID 0x058F
|
||||
|
||||
DetectedControllers DetectHyperXAlloyElite2(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXAlloyElite2Controller* controller = new HyperXAlloyElite2Controller(dev, info->path, name);
|
||||
RGBController_HyperXAlloyElite2* rgb_controller = new RGBController_HyperXAlloyElite2(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
REGISTER_HID_DETECTOR_IP("HyperX Alloy Elite 2", DetectHyperXAlloyElite2, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_2_PID, 3, 0xFF90);
|
||||
REGISTER_HID_DETECTOR_IP("HyperX Alloy Elite 2 (HP)", DetectHyperXAlloyElite2, HP_KEYBOARD_VID, HYPERX_ALLOY_ELITE_2_HP_PID, 3, 0xFF90);
|
||||
#else
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Elite 2", DetectHyperXAlloyElite2, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_2_PID, 0);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Elite 2 (HP)", DetectHyperXAlloyElite2, HP_KEYBOARD_VID, HYPERX_ALLOY_ELITE_2_HP_PID, 0);
|
||||
#endif
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperXAlloyEliteControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for HyperX Alloy Elite keyboards |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "HyperXAlloyEliteController.h"
|
||||
#include "RGBController_HyperXAlloyElite.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HYPERX_KEYBOARD_VID 0x0951
|
||||
#define HYPERX_ALLOY_ELITE_PID 0x16BE
|
||||
|
||||
DetectedControllers DetectHyperXAlloyElite(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXAlloyEliteController* controller = new HyperXAlloyEliteController(dev, info->path, name);
|
||||
RGBController_HyperXAlloyElite* rgb_controller = new RGBController_HyperXAlloyElite(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IP("HyperX Alloy Elite RGB", DetectHyperXAlloyElite, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_PID, 2, 0xFF01);
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperXAlloyFPSControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for HyperX Alloy FPS keyboards |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "HyperXAlloyFPSController.h"
|
||||
#include "RGBController_HyperXAlloyFPS.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HYPERX_KEYBOARD_VID 0x0951
|
||||
#define HYPERX_ALLOY_FPS_RGB_PID 0x16DC
|
||||
|
||||
DetectedControllers DetectHyperXAlloyFPS(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXAlloyFPSController* controller = new HyperXAlloyFPSController(dev, info->path, name);
|
||||
RGBController_HyperXAlloyFPS* rgb_controller = new RGBController_HyperXAlloyFPS(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IP("HyperX Alloy FPS RGB", DetectHyperXAlloyFPS, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_FPS_RGB_PID, 2, 0xFF01);
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperXAlloyOrigins60and65ControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for HyperX Alloy Origins 60 and 65 keyboards |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "HyperXAlloyOrigins60and65Controller.h"
|
||||
#include "RGBController_HyperXAlloyOrigins60and65.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HYPERX_KEYBOARD_VID 0x0951
|
||||
#define HYPERX_ALLOY_ORIGINS_60_PID 0x1734
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs (HP) |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HP_KEYBOARD_VID 0x03F0
|
||||
#define HYPERX_ALLOY_ORIGINS_60_HP_PID 0x0C8E
|
||||
#define HYPERX_ALLOY_ORIGINS_65_HP_PID 0x038F
|
||||
|
||||
AlloyOrigins60and65MappingLayoutType GetAlloyOrigins60and65MappingLayoutType(int pid)
|
||||
{
|
||||
switch(pid)
|
||||
{
|
||||
case HYPERX_ALLOY_ORIGINS_60_PID:
|
||||
case HYPERX_ALLOY_ORIGINS_60_HP_PID:
|
||||
return ALLOY_ORIGINS_60_LAYOUT;
|
||||
|
||||
case HYPERX_ALLOY_ORIGINS_65_HP_PID:
|
||||
return ALLOY_ORIGINS_65_LAYOUT;
|
||||
|
||||
default:
|
||||
return ALLOY_ORIGINS_60_LAYOUT;
|
||||
}
|
||||
}
|
||||
|
||||
DetectedControllers DetectHyperXAlloyOrigins60and65(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXAlloyOrigins60and65Controller* controller = new HyperXAlloyOrigins60and65Controller(dev, info->path, name);
|
||||
AlloyOrigins60and65MappingLayoutType layout = GetAlloyOrigins60and65MappingLayoutType(info->product_id);
|
||||
RGBController_HyperXAlloyOrigins60and65* rgb_controller = new RGBController_HyperXAlloyOrigins60and65(controller, layout);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins 60", DetectHyperXAlloyOrigins60and65, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_60_PID, 3);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins 60 (HP)", DetectHyperXAlloyOrigins60and65, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_60_HP_PID, 3);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins 65 (HP)", DetectHyperXAlloyOrigins60and65, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_65_HP_PID, 3);
|
||||
#else
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins 60", DetectHyperXAlloyOrigins60and65, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_60_PID, 0);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins 60 (HP)", DetectHyperXAlloyOrigins60and65, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_60_HP_PID, 0);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins 65 (HP)", DetectHyperXAlloyOrigins60and65, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_65_HP_PID, 0);
|
||||
#endif
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperXAlloyOriginsControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for HyperX Alloy Origins keyboards |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "HyperXAlloyOriginsController.h"
|
||||
#include "RGBController_HyperXAlloyOrigins.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HYPERX_KEYBOARD_VID 0x0951
|
||||
#define HYPERX_ALLOY_ORIGINS_PID 0x16E5
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs (HP) |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HP_KEYBOARD_VID 0x03F0
|
||||
#define HYPERX_ALLOY_ORIGINS_HP_PID 0x0591
|
||||
|
||||
DetectedControllers DetectHyperXAlloyOrigins(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXAlloyOriginsController* controller = new HyperXAlloyOriginsController(dev, info->path, name);
|
||||
RGBController_HyperXAlloyOrigins* rgb_controller = new RGBController_HyperXAlloyOrigins(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins", DetectHyperXAlloyOrigins, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_PID, 3);
|
||||
REGISTER_HID_DETECTOR_IP("HyperX Alloy Origins (HP)", DetectHyperXAlloyOrigins, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_HP_PID, 3, 0xFF90);
|
||||
#else
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins", DetectHyperXAlloyOrigins, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_PID, 0);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins (HP)", DetectHyperXAlloyOrigins, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_HP_PID, 0);
|
||||
#endif
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperXAlloyOriginsCoreControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for HyperX Alloy Origins Core keyboards |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "HyperXAlloyOriginsCoreController.h"
|
||||
#include "RGBController_HyperXAlloyOriginsCore.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HYPERX_KEYBOARD_VID 0x0951
|
||||
#define HYPERX_ALLOY_ORIGINS_CORE_PID 0x16E6
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs (HP) |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HP_KEYBOARD_VID 0x03F0
|
||||
#define HYPERX_ALLOY_ORIGINS_CORE_HP_PID 0x098F
|
||||
|
||||
DetectedControllers DetectHyperXAlloyOriginsCore(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXAlloyOriginsCoreController* controller = new HyperXAlloyOriginsCoreController(dev, info, name);
|
||||
RGBController_HyperXAlloyOriginsCore* rgb_controller = new RGBController_HyperXAlloyOriginsCore(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins Core", DetectHyperXAlloyOriginsCore, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_CORE_PID, 2);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins Core (HP)", DetectHyperXAlloyOriginsCore, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_CORE_HP_PID, 2);
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperXEve1800ControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for HyperX Eve 1800 keyboards |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "HyperXEve1800Controller.h"
|
||||
#include "RGBController_HyperXEve1800.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs (HP) |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HP_KEYBOARD_VID 0x03F0
|
||||
#define HYPERX_EVE_1800_HP_PID 0x08C2
|
||||
|
||||
DetectedControllers DetectHyperXEve1800(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXEve1800Controller* controller = new HyperXEve1800Controller(dev, info->path, name);
|
||||
RGBController_HyperXEve1800* rgb_controller = new RGBController_HyperXEve1800(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return detected_controllers;
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_I("HyperX Eve 1800 (HP)", DetectHyperXEve1800, HP_KEYBOARD_VID, HYPERX_EVE_1800_HP_PID, 2);
|
||||
@@ -1,242 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperXKeyboardControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for HyperX keyboards |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "HyperXAlloyEliteController.h"
|
||||
#include "HyperXAlloyElite2Controller.h"
|
||||
#include "HyperXAlloyFPSController.h"
|
||||
#include "HyperXAlloyOriginsController.h"
|
||||
#include "HyperXAlloyOriginsCoreController.h"
|
||||
#include "HyperXAlloyOrigins60and65Controller.h"
|
||||
#include "HyperXEve1800Controller.h"
|
||||
#include "HyperXOrigins2_65Controller.h"
|
||||
#include "RGBController_HyperXAlloyElite.h"
|
||||
#include "RGBController_HyperXAlloyElite2.h"
|
||||
#include "RGBController_HyperXAlloyFPS.h"
|
||||
#include "RGBController_HyperXAlloyOrigins.h"
|
||||
#include "RGBController_HyperXAlloyOriginsCore.h"
|
||||
#include "RGBController_HyperXAlloyOrigins60and65.h"
|
||||
#include "RGBController_HyperXEve1800.h"
|
||||
#include "RGBController_HyperXOrigins2_65.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HYPERX_KEYBOARD_VID 0x0951
|
||||
|
||||
#define HYPERX_ALLOY_ELITE_PID 0x16BE
|
||||
#define HYPERX_ALLOY_ELITE_2_PID 0x1711
|
||||
#define HYPERX_ALLOY_FPS_RGB_PID 0x16DC
|
||||
#define HYPERX_ALLOY_ORIGINS_PID 0x16E5
|
||||
#define HYPERX_ALLOY_ORIGINS_CORE_PID 0x16E6
|
||||
#define HYPERX_ALLOY_ORIGINS_60_PID 0x1734
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs (HP) |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HP_KEYBOARD_VID 0x03F0
|
||||
|
||||
#define HYPERX_ALLOY_ELITE_2_HP_PID 0x058F
|
||||
#define HYPERX_ALLOY_ORIGINS_60_HP_PID 0x0C8E
|
||||
#define HYPERX_ALLOY_ORIGINS_65_HP_PID 0x038F
|
||||
#define HYPERX_ALLOY_ORIGINS_CORE_HP_PID 0x098F
|
||||
#define HYPERX_ALLOY_ORIGINS_HP_PID 0x0591
|
||||
#define HYPERX_EVE_1800_HP_PID 0x08C2
|
||||
#define HYPERX_ORIGINS_2_65_HP_PID 0x0CC2
|
||||
|
||||
AlloyOrigins60and65MappingLayoutType GetAlloyOrigins60and65MappingLayoutType(int pid)
|
||||
{
|
||||
switch(pid)
|
||||
{
|
||||
case HYPERX_ALLOY_ORIGINS_60_PID:
|
||||
case HYPERX_ALLOY_ORIGINS_60_HP_PID:
|
||||
return ALLOY_ORIGINS_60_LAYOUT;
|
||||
|
||||
case HYPERX_ALLOY_ORIGINS_65_HP_PID:
|
||||
return ALLOY_ORIGINS_65_LAYOUT;
|
||||
|
||||
default:
|
||||
return ALLOY_ORIGINS_60_LAYOUT;
|
||||
}
|
||||
}
|
||||
|
||||
DetectedControllers DetectHyperXAlloyElite(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXAlloyEliteController* controller = new HyperXAlloyEliteController(dev, info->path, name);
|
||||
RGBController_HyperXAlloyElite* rgb_controller = new RGBController_HyperXAlloyElite(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectHyperXAlloyElite2(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXAlloyElite2Controller* controller = new HyperXAlloyElite2Controller(dev, info->path, name);
|
||||
RGBController_HyperXAlloyElite2* rgb_controller = new RGBController_HyperXAlloyElite2(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectHyperXAlloyFPS(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXAlloyFPSController* controller = new HyperXAlloyFPSController(dev, info->path, name);
|
||||
RGBController_HyperXAlloyFPS* rgb_controller = new RGBController_HyperXAlloyFPS(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectHyperXAlloyOrigins(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXAlloyOriginsController* controller = new HyperXAlloyOriginsController(dev, info->path, name);
|
||||
RGBController_HyperXAlloyOrigins* rgb_controller = new RGBController_HyperXAlloyOrigins(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectHyperXAlloyOriginsCore(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXAlloyOriginsCoreController* controller = new HyperXAlloyOriginsCoreController(dev, info, name);
|
||||
RGBController_HyperXAlloyOriginsCore* rgb_controller = new RGBController_HyperXAlloyOriginsCore(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectHyperXAlloyOrigins60and65(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXAlloyOrigins60and65Controller* controller = new HyperXAlloyOrigins60and65Controller(dev, info->path, name);
|
||||
AlloyOrigins60and65MappingLayoutType layout = GetAlloyOrigins60and65MappingLayoutType(info->product_id);
|
||||
RGBController_HyperXAlloyOrigins60and65* rgb_controller = new RGBController_HyperXAlloyOrigins60and65(controller, layout);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectHyperXOrigins2_65(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXOrigins2_65Controller* controller = new HyperXOrigins2_65Controller(dev, info->path, name);
|
||||
RGBController_HyperXOrigins2_65* rgb_controller = new RGBController_HyperXOrigins2_65(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectHyperXEve1800(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXEve1800Controller* controller = new HyperXEve1800Controller(dev, info->path, name);
|
||||
RGBController_HyperXEve1800* rgb_controller = new RGBController_HyperXEve1800(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return detected_controllers;
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IP("HyperX Alloy Elite RGB", DetectHyperXAlloyElite, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_PID, 2, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_IP("HyperX Alloy FPS RGB", DetectHyperXAlloyFPS, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_FPS_RGB_PID, 2, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins Core", DetectHyperXAlloyOriginsCore, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_CORE_PID, 2);
|
||||
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins Core (HP)", DetectHyperXAlloyOriginsCore, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_CORE_HP_PID, 2);
|
||||
|
||||
REGISTER_HID_DETECTOR_I("HyperX Origins 2 65 (HP)", DetectHyperXOrigins2_65, HP_KEYBOARD_VID, HYPERX_ORIGINS_2_65_HP_PID, 3);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Eve 1800 (HP)", DetectHyperXEve1800, HP_KEYBOARD_VID, HYPERX_EVE_1800_HP_PID, 2);
|
||||
|
||||
#ifdef _WIN32
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins", DetectHyperXAlloyOrigins, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_PID, 3);
|
||||
REGISTER_HID_DETECTOR_IP("HyperX Alloy Elite 2", DetectHyperXAlloyElite2, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_2_PID, 3, 0xFF90);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins 60", DetectHyperXAlloyOrigins60and65, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_60_PID, 3);
|
||||
|
||||
REGISTER_HID_DETECTOR_IP("HyperX Alloy Elite 2 (HP)", DetectHyperXAlloyElite2, HP_KEYBOARD_VID, HYPERX_ALLOY_ELITE_2_HP_PID, 3, 0xFF90);
|
||||
REGISTER_HID_DETECTOR_IP("HyperX Alloy Origins (HP)", DetectHyperXAlloyOrigins, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_HP_PID, 3, 0xFF90);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins 60 (HP)", DetectHyperXAlloyOrigins60and65, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_60_HP_PID, 3);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins 65 (HP)", DetectHyperXAlloyOrigins60and65, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_65_HP_PID, 3);
|
||||
#else
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins", DetectHyperXAlloyOrigins, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_PID, 0);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Elite 2", DetectHyperXAlloyElite2, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_2_PID, 0);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins 60", DetectHyperXAlloyOrigins60and65, HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_60_PID, 0);
|
||||
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Elite 2 (HP)", DetectHyperXAlloyElite2, HP_KEYBOARD_VID, HYPERX_ALLOY_ELITE_2_HP_PID, 0);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins (HP)", DetectHyperXAlloyOrigins, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_HP_PID, 0);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins 60 (HP)", DetectHyperXAlloyOrigins60and65, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_60_HP_PID, 0);
|
||||
REGISTER_HID_DETECTOR_I("HyperX Alloy Origins 65 (HP)", DetectHyperXAlloyOrigins60and65, HP_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_65_HP_PID, 0);
|
||||
#endif
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperXOrigins2_65ControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for HyperX Origins 2 65 keyboards |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "HyperXOrigins2_65Controller.h"
|
||||
#include "RGBController_HyperXOrigins2_65.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HyperX keyboard vendor and product IDs (HP) |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HP_KEYBOARD_VID 0x03F0
|
||||
#define HYPERX_ORIGINS_2_65_HP_PID 0x0CC2
|
||||
|
||||
DetectedControllers DetectHyperXOrigins2_65(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HyperXOrigins2_65Controller* controller = new HyperXOrigins2_65Controller(dev, info->path, name);
|
||||
RGBController_HyperXOrigins2_65* rgb_controller = new RGBController_HyperXOrigins2_65(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_I("HyperX Origins 2 65 (HP)", DetectHyperXOrigins2_65, HP_KEYBOARD_VID, HYPERX_ORIGINS_2_65_HP_PID, 3);
|
||||
+1
-1
@@ -768,7 +768,7 @@ void RGBController_LogitechHIDPP20::SetupZones()
|
||||
perkey_zone.leds_min = klm.GetKeyCount();
|
||||
perkey_zone.leds_max = klm.GetKeyCount();
|
||||
perkey_zone.leds_count = klm.GetKeyCount();
|
||||
perkey_zone.matrix_map = klm.GetKeyMap();
|
||||
perkey_zone.matrix_map = klm.GetKeyMap(KEYBOARD_MAP_FILL_TYPE_COUNT);
|
||||
zones.push_back(perkey_zone);
|
||||
|
||||
for(unsigned int i = 0; i < klm.GetKeyCount(); i++)
|
||||
|
||||
@@ -41,7 +41,7 @@ REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4070 Gaming X Slim",
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4070 Gaming X Slim White", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, MSI_SUB_VEN, MSI_RTX4070S_GAMING_X_SLIM_WHITE_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4070 SUPER Gaming X Slim", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, MSI_SUB_VEN, MSI_RTX4070S_GAMING_X_SLIM_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4070 SUPER Gaming X Slim White", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, MSI_SUB_VEN, MSI_RTX4070S_GAMING_X_SLIM_WHITE_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4070 SUPER Gaming X Slim MLG", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, MSI_SUB_VEN, MSI_RTX4070S_GAMING_X_SLIM_MLG_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4070 SUPER Gaming X Slim MLG", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, MSI_SUB_VEN, MSI_RTX4070S_GAMING_X_SLIM_MLG_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4070 Ti Gaming X Trio", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, MSI_SUB_VEN, MSI_RTX4070TI_GAMING_X_TRIO_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4070 Ti Gaming X Trio White", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, MSI_SUB_VEN, MSI_RTX4070TI_GAMING_X_TRIO_WHITE_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4070 Ti Gaming X Slim White", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, MSI_SUB_VEN, MSI_RTX4070TI_GAMING_X_SLIM_WHITE_SUB_DEV, 0x68);
|
||||
@@ -50,6 +50,7 @@ REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4070 Ti SUPER Gaming X Trio White",
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4070 Ti SUPER Gaming Slim", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4070TIS_DEV, MSI_SUB_VEN, MSI_RTX4070TIS_GAMING_SLIM_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4070 Ti SUPER Gaming X Slim", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4070TIS_DEV, MSI_SUB_VEN, MSI_RTX4070TIS_GAMING_X_SLIM_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4070 Ti SUPER Gaming White X Slim", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4070TIS_DEV, MSI_SUB_VEN, MSI_RTX4070TIS_GAMING_X_SLIM_WHITE_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4070 Ti SUPER Gaming White X Slim", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4070TIS_DEV, MSI_SUB_VEN, MSI_RTX4070TIS_GAMING_X_SLIM_WHITE_SUB_DEV_2, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4080 Gaming X Slim White", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, MSI_SUB_VEN, MSI_RTX4080S_GAMING_X_SLIM_WHITE_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4080 Gaming X Trio", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, MSI_SUB_VEN, MSI_RTX4080_GAMING_X_TRIO_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 4080 Gaming X Trio White", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, MSI_SUB_VEN, MSI_RTX4080_GAMING_X_TRIO_WHITE_SUB_DEV, 0x68);
|
||||
@@ -68,7 +69,7 @@ REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 5070 Ti VANGUARD SOC",
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 5080 Gaming Trio OC", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, MSI_SUB_VEN, MSI_RTX5080_GAMING_TRIO_OC_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 5080 VANGUARD OC SOC", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, MSI_SUB_VEN, MSI_RTX5080_VANGUARD_SOC_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 5080 SUPRIM SOC", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, MSI_SUB_VEN, MSI_RTX5080_SUPRIM_SOC_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 5080 SUPRIM LIQUID SOC", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, MSI_SUB_VEN, MSI_RTX5080_SUPRIM_LIQUID_SOC_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 5080 SUPRIM LIQUID SOC", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, MSI_SUB_VEN, MSI_RTX5080_SUPRIM_LIQUID_SOC_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 5090 Gaming Trio OC", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, MSI_SUB_VEN, MSI_RTX5090_GAMING_TRIO_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 5090 VANGUARD SOC", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, MSI_SUB_VEN, MSI_RTX5090_VANGUARD_SOC_SUB_DEV, 0x68);
|
||||
REGISTER_I2C_PCI_DETECTOR("MSI GeForce RTX 5090 SUPRIM SOC", DetectMSIGPUv2Controllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, MSI_SUB_VEN, MSI_RTX5090_SUPRIM_SOC_SUB_DEV, 0x68);
|
||||
|
||||
@@ -1,18 +1,40 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_MSIMonitor.cpp |
|
||||
| MSIMonitorController.cpp |
|
||||
| |
|
||||
| RGBController for MSI monitor (gaming controller) |
|
||||
| Driver for MSI monitor (gaming controller) |
|
||||
| |
|
||||
| Andy Herbert 2026 June 4 |
|
||||
| Ken Sanislo 2026 July 20 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <chrono>
|
||||
#include <string.h>
|
||||
#include <thread>
|
||||
#include "MSIMonitorController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Feature reports are control transfers and this panel |
|
||||
| holds one outstanding for tens of milliseconds. Back |
|
||||
| to back writes pin the shared control pipe at full |
|
||||
| duty and starve other non periodic traffic: a device |
|
||||
| with no interrupt OUT endpoint writes by SET_REPORT |
|
||||
| and stops answering, while its isochronous endpoints |
|
||||
| keep running. |
|
||||
| |
|
||||
| Idle a fixed interval after each write to leave the |
|
||||
| control pipe free. |
|
||||
\*---------------------------------------------------------*/
|
||||
void MSIMonitorController::SendFeatureReport(uint8_t *data, size_t length)
|
||||
{
|
||||
hid_send_feature_report(dev, data, length);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(MSI_MONITOR_PIPE_IDLE_MS));
|
||||
}
|
||||
|
||||
MSIMonitorController::MSIMonitorController(hid_device* dev_handle, const hid_device_info& info, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
@@ -117,5 +139,125 @@ void MSIMonitorController::Set(uint8_t mode_value, const std::vector<RGBColor> c
|
||||
| Send the data (1 packet) |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
hid_send_feature_report(dev, data, MSI_MONITOR_PACKET_SIZE);
|
||||
SendFeatureReport(data, MSI_MONITOR_PACKET_SIZE);
|
||||
}
|
||||
|
||||
uint8_t MSIMonitorController::GetLayoutVersion()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Ask the MCU which buffer layout it speaks. Request |
|
||||
| is [0x01][opcode] zero padded, reply is [0x01][0x5A] |
|
||||
| then data with the version at byte 3. |
|
||||
\*-----------------------------------------------------*/
|
||||
uint8_t request[MSI_MONITOR_QUERY_PACKET_SIZE];
|
||||
uint8_t reply[MSI_MONITOR_QUERY_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Unimplemented opcodes never answer, so a reply left |
|
||||
| queued by an earlier exchange would be read here and |
|
||||
| parsed as this query's answer. Drain first. |
|
||||
\*-----------------------------------------------------*/
|
||||
while(hid_read_timeout(dev, reply, MSI_MONITOR_QUERY_PACKET_SIZE, 0) > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(request, 0x00, MSI_MONITOR_QUERY_PACKET_SIZE);
|
||||
|
||||
request[0] = MSI_MONITOR_QUERY_REPORT_ID;
|
||||
request[1] = MSI_MONITOR_OPCODE_GET_VERSION;
|
||||
|
||||
if(hid_write(dev, request, MSI_MONITOR_QUERY_PACKET_SIZE) < 0)
|
||||
{
|
||||
return(MSI_MONITOR_VERSION_UNKNOWN);
|
||||
}
|
||||
|
||||
memset(reply, 0x00, MSI_MONITOR_QUERY_PACKET_SIZE);
|
||||
|
||||
if(hid_read_timeout(dev, reply, MSI_MONITOR_QUERY_PACKET_SIZE, 500) <= 0)
|
||||
{
|
||||
return(MSI_MONITOR_VERSION_UNKNOWN);
|
||||
}
|
||||
|
||||
if(reply[1] != MSI_MONITOR_QUERY_ACK)
|
||||
{
|
||||
return(MSI_MONITOR_VERSION_UNKNOWN);
|
||||
}
|
||||
|
||||
return(reply[3]);
|
||||
}
|
||||
|
||||
void MSIMonitorController::SetMode72(uint8_t mode_value, uint8_t speed, uint8_t brightness, RGBColor color1, RGBColor color2, bool user_palette, bool save, const std::vector<RGBColor>& led_colors, bool fill_both_arrays)
|
||||
{
|
||||
uint8_t data[MSI_MONITOR_72_PACKET_SIZE];
|
||||
memset(data, 0x00, MSI_MONITOR_72_PACKET_SIZE);
|
||||
|
||||
data[0] = 0x72;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Identical 11 byte control blocks at index 1 and 12 |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int base = 1; base <= 12; base += 11)
|
||||
{
|
||||
data[base + 0] = mode_value;
|
||||
data[base + 1] = RGBGetRValue(color1);
|
||||
data[base + 2] = RGBGetGValue(color1);
|
||||
data[base + 3] = RGBGetBValue(color1);
|
||||
data[base + 4] = speed;
|
||||
data[base + 5] = brightness;
|
||||
data[base + 6] = RGBGetRValue(color2);
|
||||
data[base + 7] = RGBGetGValue(color2);
|
||||
data[base + 8] = RGBGetBValue(color2);
|
||||
data[base + 9] = user_palette ? 0x80 : 0x00;
|
||||
data[base + 10] = 0x00;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The engine paints from the second inline colour array |
|
||||
| at index 95, not from Colour1 and not from the first |
|
||||
| array at index 23: on a 322URX a buffer carrying only |
|
||||
| Colour1 renders black, and walking one lit slot |
|
||||
| through the buffer only lights LEDs for the second |
|
||||
| array. That pairs with the control block at index 12 |
|
||||
| being the operative one. Built in palette modes |
|
||||
| leave the array clear so the firmware effect is not |
|
||||
| painted over. |
|
||||
| |
|
||||
| fill_both_arrays also writes the first array at index |
|
||||
| 23, for the dual block versions (11/13/15) whose two |
|
||||
| control blocks each drive their own run. On a single |
|
||||
| block layout the first array is inert, so filling it |
|
||||
| is harmless. Those versions also route colour index |
|
||||
| above 15 to a separate DragonShield emblem region not |
|
||||
| handled here - one reason they stay disabled. |
|
||||
\*-----------------------------------------------------*/
|
||||
if(user_palette)
|
||||
{
|
||||
for(unsigned int slot = 0; slot < MSI_MONITOR_72_ARRAY_SLOTS && slot < led_colors.size(); slot++)
|
||||
{
|
||||
unsigned int offset_b = MSI_MONITOR_72_ARRAY_B_INDEX + (slot * 3);
|
||||
|
||||
data[offset_b + 0] = RGBGetRValue(led_colors[slot]);
|
||||
data[offset_b + 1] = RGBGetGValue(led_colors[slot]);
|
||||
data[offset_b + 2] = RGBGetBValue(led_colors[slot]);
|
||||
|
||||
if(fill_both_arrays)
|
||||
{
|
||||
unsigned int offset_a = MSI_MONITOR_72_ARRAY_A_INDEX + (slot * 3);
|
||||
|
||||
data[offset_a + 0] = RGBGetRValue(led_colors[slot]);
|
||||
data[offset_a + 1] = RGBGetGValue(led_colors[slot]);
|
||||
data[offset_a + 2] = RGBGetBValue(led_colors[slot]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Final byte is store to flash: 0x01 persists across |
|
||||
| power cycles, 0x00 applies without a flash write. |
|
||||
| Keep 0x00 for streaming to avoid flicker and wear. |
|
||||
\*-----------------------------------------------------*/
|
||||
data[MSI_MONITOR_72_STORE_INDEX] = save ? 0x01 : 0x00;
|
||||
|
||||
SendFeatureReport(data, MSI_MONITOR_72_PACKET_SIZE);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_MSIMonitor.cpp |
|
||||
| MSIMonitorController.h |
|
||||
| |
|
||||
| RGBController for MSI monitor (gaming controller) |
|
||||
| Driver for MSI monitor (gaming controller) |
|
||||
| |
|
||||
| Andy Herbert 2026 June 1 |
|
||||
| Ken Sanislo 2026 July 20 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -18,6 +19,51 @@
|
||||
#define MSI_MONITOR_LEDS 9
|
||||
#define MSI_MONITOR_PACKET_SIZE 78
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| This panel holds each feature report outstanding for |
|
||||
| tens of ms while its MCU applies the frame, pinning the |
|
||||
| shared control pipe. Idle briefly after each write so |
|
||||
| other non periodic traffic on the bus is not starved. |
|
||||
| See SendFeatureReport. |
|
||||
\*---------------------------------------------------------*/
|
||||
#define MSI_MONITOR_PIPE_IDLE_MS 5
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| 0x72 layout (dual control block, e.g. MPG 322URX QD-OLED) |
|
||||
\*---------------------------------------------------------*/
|
||||
#define MSI_MONITOR_72_PACKET_SIZE 168
|
||||
#define MSI_MONITOR_72_STORE_INDEX 167
|
||||
#define MSI_MONITOR_72_ARRAY_A_INDEX 23
|
||||
#define MSI_MONITOR_72_ARRAY_B_INDEX 95
|
||||
#define MSI_MONITOR_72_ARRAY_SLOTS 24
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Fill order the firmware expects (vendor Direction enum). |
|
||||
| Only the physical origin differs; index 0 is that end. |
|
||||
| The controller mirrors RightToLeft into left origin so |
|
||||
| OpenRGB LED 0 is always the left/start. Circle and Ctype |
|
||||
| are non linear shapes: driven as a plain line for now, |
|
||||
| they want a custom layout once someone maps the shape. |
|
||||
\*---------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
MSI_MONITOR_72_DIR_RIGHT_TO_LEFT = 0,
|
||||
MSI_MONITOR_72_DIR_LEFT_TO_RIGHT = 1,
|
||||
MSI_MONITOR_72_DIR_UP_TO_DOWN = 2,
|
||||
MSI_MONITOR_72_DIR_CIRCLE = 3,
|
||||
MSI_MONITOR_72_DIR_CTYPE = 4,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Layout version query rides the short report channel: |
|
||||
| write [0x01][opcode], read [0x01][0x5A][data] |
|
||||
\*---------------------------------------------------------*/
|
||||
#define MSI_MONITOR_QUERY_PACKET_SIZE 64
|
||||
#define MSI_MONITOR_QUERY_REPORT_ID 0x01
|
||||
#define MSI_MONITOR_QUERY_ACK 0x5A
|
||||
#define MSI_MONITOR_OPCODE_GET_VERSION 0xB0
|
||||
#define MSI_MONITOR_VERSION_UNKNOWN 0
|
||||
|
||||
enum
|
||||
{
|
||||
MSI_MONITOR_OFF_MODE_VALUE = 0x00,
|
||||
@@ -31,6 +77,53 @@ enum
|
||||
MSI_MONITOR_RANDOM_MODE_VALUE = 0x1F
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| 0x72 layout mode values. These match the MSI Mystic |
|
||||
| Light motherboard mode enum value for value (see |
|
||||
| MSIMysticLightController/MSIMysticLightCommon.h): the |
|
||||
| monitor runs the same Nuvoton Mystic Light engine, so the |
|
||||
| effect numbering is shared with its motherboard sibling. |
|
||||
| Values 10-14 and 32 are the audio modes, not exposed |
|
||||
| here (they need the music level feed). |
|
||||
\*---------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
MSI_MONITOR_72_MODE_OFF = 0,
|
||||
MSI_MONITOR_72_MODE_STATIC = 1,
|
||||
MSI_MONITOR_72_MODE_BREATHING = 2,
|
||||
MSI_MONITOR_72_MODE_FLASHING = 3,
|
||||
MSI_MONITOR_72_MODE_DOUBLE_FLASHING = 4,
|
||||
MSI_MONITOR_72_MODE_LIGHTNING = 5,
|
||||
MSI_MONITOR_72_MODE_SCANNER = 6,
|
||||
MSI_MONITOR_72_MODE_METEOR = 7,
|
||||
MSI_MONITOR_72_MODE_WATER_DROP = 8,
|
||||
MSI_MONITOR_72_MODE_RAINBOW_MSI = 9,
|
||||
MSI_MONITOR_72_MODE_COLOR_RING = 15,
|
||||
MSI_MONITOR_72_MODE_PLANETARY = 16,
|
||||
MSI_MONITOR_72_MODE_DOUBLE_METEOR = 17,
|
||||
MSI_MONITOR_72_MODE_ENERGY = 18,
|
||||
MSI_MONITOR_72_MODE_BLINK = 19,
|
||||
MSI_MONITOR_72_MODE_CLOCK = 20,
|
||||
MSI_MONITOR_72_MODE_COLOR_PULSE = 21,
|
||||
MSI_MONITOR_72_MODE_COLOR_SHIFT = 22,
|
||||
MSI_MONITOR_72_MODE_COLOR_WAVE = 23,
|
||||
MSI_MONITOR_72_MODE_MARQUEE = 24,
|
||||
MSI_MONITOR_72_MODE_RAINBOW = 25,
|
||||
MSI_MONITOR_72_MODE_RAINBOW_WAVE = 26,
|
||||
MSI_MONITOR_72_MODE_VISOR = 27,
|
||||
MSI_MONITOR_72_MODE_JRAINBOW = 28,
|
||||
MSI_MONITOR_72_MODE_RAINBOW_FLASH = 29,
|
||||
MSI_MONITOR_72_MODE_RAINBOW_DBLFLASH = 30,
|
||||
MSI_MONITOR_72_MODE_RAINBOW_LINE = 33,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MSI_MONITOR_72_SPEED_LOW = 0,
|
||||
MSI_MONITOR_72_SPEED_MEDIUM = 1,
|
||||
MSI_MONITOR_72_SPEED_HIGH = 2,
|
||||
};
|
||||
|
||||
class MSIMonitorController
|
||||
{
|
||||
public:
|
||||
@@ -44,7 +137,12 @@ public:
|
||||
|
||||
void Set(uint8_t mode_value, const std::vector<RGBColor> colors, uint8_t last_bit);
|
||||
|
||||
uint8_t GetLayoutVersion();
|
||||
void SetMode72(uint8_t mode_value, uint8_t speed, uint8_t brightness, RGBColor color1, RGBColor color2, bool user_palette, bool save, const std::vector<RGBColor>& led_colors, bool fill_both_arrays);
|
||||
|
||||
private:
|
||||
void SendFeatureReport(uint8_t *data, size_t length);
|
||||
|
||||
hid_device *dev;
|
||||
std::string description;
|
||||
std::string location;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| MSIKeyboardControllerDetect.cpp |
|
||||
| MSIMonitorControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for MSI monitor (MSI Gaming Controller) |
|
||||
| |
|
||||
@@ -10,10 +10,107 @@
|
||||
#include "DetectionManager.h"
|
||||
#include "MSIMonitorController.h"
|
||||
#include "RGBController_MSIMonitor.h"
|
||||
#include "RGBController_MSIMonitor72.h"
|
||||
|
||||
#define MSI_USB_VID 0x1462
|
||||
#define MSI_USB_PID 0x3FA4
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Vendor layout table (from the version -> layout map). |
|
||||
| The firmware reports its version to the 0xB0 query but |
|
||||
| not a LED count, so count/direction/block-count come |
|
||||
| from here. Fields: version, LED count, fill direction |
|
||||
| (MSI_MONITOR_72_DIR_*), dual_block. |
|
||||
| |
|
||||
| Every entry here is a single linear run driven through |
|
||||
| the 168 byte 0x72 buffer. Direction mirrors the fill so |
|
||||
| OpenRGB LED 0 is the left/start on every model. Circle |
|
||||
| and Ctype have no simple line mapping - they are driven |
|
||||
| as a plain line here and should get a custom per model |
|
||||
| layout once an owner maps the physical shape. |
|
||||
| |
|
||||
| Only version 34 is hardware verified (MPG 322URX). The |
|
||||
| rest are derived from the vendor table: same buffer, LED |
|
||||
| count and direction are the only differences, so effect |
|
||||
| and single colour modes are correct by construction. |
|
||||
| |
|
||||
| Left out on purpose: |
|
||||
| - dual_block versions 11/13/15 are stubbed but disabled |
|
||||
| (see the commented block); their two control blocks |
|
||||
| drive two runs and the per LED split is unconfirmed. |
|
||||
| - Advanced/0x82 versions 31/47 need the 0x30 bulk report |
|
||||
| this controller does not implement. |
|
||||
| A version not matched here falls through to the legacy |
|
||||
| 0x71 controller, home of the MAG272 class. |
|
||||
\*---------------------------------------------------------*/
|
||||
struct MSIMonitor72Layout
|
||||
{
|
||||
uint8_t version;
|
||||
unsigned int leds;
|
||||
unsigned int direction;
|
||||
bool dual_block;
|
||||
};
|
||||
|
||||
static const MSIMonitor72Layout msi_monitor_72_layouts[] =
|
||||
{
|
||||
{ 34, 9, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MPG271QRXQD_OLED (MPG 322URX reports this) - verified */
|
||||
{ 5, 12, MSI_MONITOR_72_DIR_RIGHT_TO_LEFT, false }, /* MAG272R */
|
||||
{ 8, 24, MSI_MONITOR_72_DIR_CIRCLE, false }, /* MAG301CR - Circle, wants custom layout */
|
||||
{ 10, 9, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MAG273R */
|
||||
{ 12, 9, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MAG271VCR */
|
||||
{ 14, 14, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* NXG253R */
|
||||
{ 17, 8, MSI_MONITOR_72_DIR_RIGHT_TO_LEFT, false }, /* MAG2x5R */
|
||||
{ 20, 12, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MAG301RF */
|
||||
{ 21, 18, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MPG341QR */
|
||||
{ 22, 24, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MPG321QRF */
|
||||
{ 24, 12, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MAG321QR */
|
||||
{ 25, 24, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MPG321UR */
|
||||
{ 28, 9, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MAG273CQR */
|
||||
{ 29, 24, MSI_MONITOR_72_DIR_RIGHT_TO_LEFT, false }, /* MAG401QR */
|
||||
{ 30, 21, MSI_MONITOR_72_DIR_RIGHT_TO_LEFT, false }, /* MAG325CQRF */
|
||||
{ 32, 7, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MAG274QRF */
|
||||
{ 33, 7, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MPG274URFQD */
|
||||
{ 36, 9, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MPG275CQRXF */
|
||||
{ 37, 22, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MPG345CQRD */
|
||||
{ 38, 20, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MAG325CQRFQDE2 */
|
||||
{ 39, 8, MSI_MONITOR_72_DIR_RIGHT_TO_LEFT, false }, /* MPG321CURX_QD_OLED */
|
||||
{ 40, 12, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MAG322URDFE16 */
|
||||
{ 41, 14, MSI_MONITOR_72_DIR_RIGHT_TO_LEFT, false }, /* MPG242RX60N */
|
||||
{ 42, 22, MSI_MONITOR_72_DIR_CTYPE, false }, /* MPG274URDFWE16 - Ctype, wants custom layout */
|
||||
{ 43, 21, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MPG346CQRFX24 */
|
||||
{ 44, 9, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MPG271QRQD_OLEDX50 */
|
||||
{ 46, 9, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, false }, /* MPG341CQRQD_OLEDX36 */
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Dual block - stubbed but DISABLED. The dual_block path fills |
|
||||
| both colour arrays so uniform colour modes are correct, but each |
|
||||
| block drives its own run and the per LED split is unconfirmed, so |
|
||||
| Direct is a guess. These versions also map colour index above 15 |
|
||||
| to a separate DragonShield emblem region (unhandled). An owner |
|
||||
| should enable, test, and ideally give it a custom layout: |
|
||||
| { 11, 16, MSI_MONITOR_72_DIR_RIGHT_TO_LEFT, true }, MPG273CQR |
|
||||
| { 13, 21, MSI_MONITOR_72_DIR_LEFT_TO_RIGHT, true }, MPG343CQR |
|
||||
| { 15, 18, MSI_MONITOR_72_DIR_RIGHT_TO_LEFT, true }, MPG323CQR |
|
||||
| |
|
||||
| Advanced/0x82 - not addable here, need the 0x30 bulk report: |
|
||||
| version 31, 40 LEDs, MEG342CQD_OLED |
|
||||
| version 47, 83 LEDs, 4 areas, MEG_X |
|
||||
\*-----------------------------------------------------------------*/
|
||||
};
|
||||
|
||||
static const MSIMonitor72Layout* MSIMonitorLayout(uint8_t version)
|
||||
{
|
||||
for(unsigned int i = 0; i < (sizeof(msi_monitor_72_layouts) / sizeof(msi_monitor_72_layouts[0])); i++)
|
||||
{
|
||||
if(msi_monitor_72_layouts[i].version == version)
|
||||
{
|
||||
return(&msi_monitor_72_layouts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return(nullptr);
|
||||
}
|
||||
|
||||
DetectedControllers DetectMSIMonitorController(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
@@ -23,10 +120,41 @@ DetectedControllers DetectMSIMonitorController(hid_device_info* info, const std:
|
||||
|
||||
if(dev)
|
||||
{
|
||||
MSIMonitorController* controller = new MSIMonitorController(dev, *info, name);
|
||||
RGBController_MSIMonitor* rgb_controller = new RGBController_MSIMonitor(controller);
|
||||
/*-------------------------------------------------*\
|
||||
| One VID/PID covers several buffer layouts, so ask |
|
||||
| the MCU which one it speaks. A version in the |
|
||||
| 0x72 table selects the 168 byte layout and its |
|
||||
| LED count; anything else keeps the legacy 0x71 |
|
||||
| path, which is what the older monitors answer to. |
|
||||
\*-------------------------------------------------*/
|
||||
MSIMonitorController* controller = new MSIMonitorController(dev, *info, name);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
uint8_t version = controller->GetLayoutVersion();
|
||||
const MSIMonitor72Layout* layout = MSIMonitorLayout(version);
|
||||
|
||||
if(layout != nullptr)
|
||||
{
|
||||
detected_controllers.push_back(new RGBController_MSIMonitor72(controller, layout->leds, layout->direction, layout->dual_block));
|
||||
}
|
||||
else
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| 0x71 family (78 byte buffer), handled by the |
|
||||
| legacy controller as a plain line. For an owner |
|
||||
| who wants to bring one onto this controller: same |
|
||||
| operative block 12, but the second colour array |
|
||||
| is at index 50 (not 95) and store-flash at 77. |
|
||||
| RightToLeft mirroring applies. version, LEDs, |
|
||||
| direction: |
|
||||
| 1, 9, RightToLeft (early/generic) |
|
||||
| 2, 7, LeftToRight (malformed stub, skip) |
|
||||
| 3, 9, RightToLeft (early/generic) |
|
||||
| 4, 9, LeftToRight (early/generic) |
|
||||
| 6, 9, UpToDown MAG270CR |
|
||||
| 7, 7, LeftToRight MAG251RX |
|
||||
\*-------------------------------------------------*/
|
||||
detected_controllers.push_back(new RGBController_MSIMonitor(controller));
|
||||
}
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
|
||||
@@ -9,12 +9,8 @@
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include "RGBController_MSIMonitor.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name MSIMonitor
|
||||
@category Accessory
|
||||
@@ -112,10 +108,6 @@ RGBController_MSIMonitor::RGBController_MSIMonitor(MSIMonitorController* control
|
||||
|
||||
RGBController_MSIMonitor::~RGBController_MSIMonitor()
|
||||
{
|
||||
keepalive_thread_run = 0;
|
||||
keepalive_thread->join();
|
||||
delete keepalive_thread;
|
||||
|
||||
Shutdown();
|
||||
|
||||
delete controller;
|
||||
@@ -145,7 +137,6 @@ void RGBController_MSIMonitor::SetupZones()
|
||||
|
||||
void RGBController_MSIMonitor::DeviceUpdateLEDs()
|
||||
{
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
controller->Set(modes[active_mode].value, colors, active_mode == 0 ? 0x00 : 0x01);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_MSIMonitor.cpp |
|
||||
| RGBController_MSIMonitor.h |
|
||||
| |
|
||||
| RGBController for MSI monitor (gaming controller) |
|
||||
| |
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include "RGBController.h"
|
||||
#include "MSIMonitorController.h"
|
||||
|
||||
@@ -31,9 +30,4 @@ public:
|
||||
|
||||
private:
|
||||
MSIMonitorController* controller;
|
||||
std::thread* keepalive_thread;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
|
||||
|
||||
void KeepaliveThread();
|
||||
};
|
||||
|
||||
@@ -0,0 +1,570 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_MSIMonitor72.cpp |
|
||||
| |
|
||||
| RGBController for MSI monitors using the 0x72 dual |
|
||||
| control block layout (MPG 322URX QD-OLED) |
|
||||
| |
|
||||
| Ken Sanislo 19 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <algorithm>
|
||||
#include "RGBController_MSIMonitor72.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name MSIMonitor72
|
||||
@category Accessory
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectMSIMonitorController
|
||||
@comment Developed with MSI MPG 322URX QD-OLED
|
||||
\*-------------------------------------------------------------------*/
|
||||
RGBController_MSIMonitor72::RGBController_MSIMonitor72(MSIMonitorController* controller_ptr, unsigned int count, unsigned int direction, bool dual)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
led_count = count;
|
||||
reverse_order = (direction == MSI_MONITOR_72_DIR_RIGHT_TO_LEFT);
|
||||
dual_block = dual;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "MSI";
|
||||
type = DEVICE_TYPE_MONITOR;
|
||||
description = "MSI Monitor (Gaming Controller)";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| This layout has no Advanced mode, so Direct is Static |
|
||||
| driven from the inline per LED colour arrays. |
|
||||
\*-----------------------------------------------------*/
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = MSI_MONITOR_72_MODE_STATIC;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Direct.brightness_min = 0;
|
||||
Direct.brightness_max = 100;
|
||||
Direct.brightness = 100;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = MSI_MONITOR_72_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(1);
|
||||
Static.brightness_min = 0;
|
||||
Static.brightness_max = 100;
|
||||
Static.brightness = 100;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = MSI_MONITOR_72_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
Breathing.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
Breathing.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = 100;
|
||||
Breathing.brightness = 100;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Flashing;
|
||||
Flashing.name = "Flashing";
|
||||
Flashing.value = MSI_MONITOR_72_MODE_FLASHING;
|
||||
Flashing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Flashing.colors_min = 2;
|
||||
Flashing.colors_max = 2;
|
||||
Flashing.colors.resize(2);
|
||||
Flashing.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
Flashing.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
Flashing.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
Flashing.brightness_min = 0;
|
||||
Flashing.brightness_max = 100;
|
||||
Flashing.brightness = 100;
|
||||
Flashing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Flashing);
|
||||
|
||||
mode DoubleFlashing;
|
||||
DoubleFlashing.name = "Double Flashing";
|
||||
DoubleFlashing.value = MSI_MONITOR_72_MODE_DOUBLE_FLASHING;
|
||||
DoubleFlashing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
DoubleFlashing.colors_min = 2;
|
||||
DoubleFlashing.colors_max = 2;
|
||||
DoubleFlashing.colors.resize(2);
|
||||
DoubleFlashing.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
DoubleFlashing.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
DoubleFlashing.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
DoubleFlashing.brightness_min = 0;
|
||||
DoubleFlashing.brightness_max = 100;
|
||||
DoubleFlashing.brightness = 100;
|
||||
DoubleFlashing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(DoubleFlashing);
|
||||
|
||||
mode Lightning;
|
||||
Lightning.name = "Lightning";
|
||||
Lightning.value = MSI_MONITOR_72_MODE_LIGHTNING;
|
||||
Lightning.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Lightning.colors_min = 1;
|
||||
Lightning.colors_max = 1;
|
||||
Lightning.colors.resize(1);
|
||||
Lightning.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
Lightning.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
Lightning.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
Lightning.brightness_min = 0;
|
||||
Lightning.brightness_max = 100;
|
||||
Lightning.brightness = 100;
|
||||
Lightning.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Lightning);
|
||||
|
||||
mode Scanner;
|
||||
Scanner.name = "Scanner";
|
||||
Scanner.value = MSI_MONITOR_72_MODE_SCANNER;
|
||||
Scanner.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Scanner.colors_min = 1;
|
||||
Scanner.colors_max = 1;
|
||||
Scanner.colors.resize(1);
|
||||
Scanner.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
Scanner.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
Scanner.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
Scanner.brightness_min = 0;
|
||||
Scanner.brightness_max = 100;
|
||||
Scanner.brightness = 100;
|
||||
Scanner.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Scanner);
|
||||
|
||||
mode Meteor;
|
||||
Meteor.name = "Meteor";
|
||||
Meteor.value = MSI_MONITOR_72_MODE_METEOR;
|
||||
Meteor.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Meteor.colors_min = 1;
|
||||
Meteor.colors_max = 1;
|
||||
Meteor.colors.resize(1);
|
||||
Meteor.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
Meteor.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
Meteor.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
Meteor.brightness_min = 0;
|
||||
Meteor.brightness_max = 100;
|
||||
Meteor.brightness = 100;
|
||||
Meteor.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Meteor);
|
||||
|
||||
mode WaterDrop;
|
||||
WaterDrop.name = "Water Drop";
|
||||
WaterDrop.value = MSI_MONITOR_72_MODE_WATER_DROP;
|
||||
WaterDrop.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
WaterDrop.colors_min = 1;
|
||||
WaterDrop.colors_max = 1;
|
||||
WaterDrop.colors.resize(1);
|
||||
WaterDrop.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
WaterDrop.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
WaterDrop.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
WaterDrop.brightness_min = 0;
|
||||
WaterDrop.brightness_max = 100;
|
||||
WaterDrop.brightness = 100;
|
||||
WaterDrop.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(WaterDrop);
|
||||
|
||||
mode RainbowMSI;
|
||||
RainbowMSI.name = "Rainbow";
|
||||
RainbowMSI.value = MSI_MONITOR_72_MODE_RAINBOW_MSI;
|
||||
RainbowMSI.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
RainbowMSI.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
RainbowMSI.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
RainbowMSI.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
RainbowMSI.brightness_min = 0;
|
||||
RainbowMSI.brightness_max = 100;
|
||||
RainbowMSI.brightness = 100;
|
||||
RainbowMSI.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(RainbowMSI);
|
||||
|
||||
mode ColorRing;
|
||||
ColorRing.name = "Color Ring";
|
||||
ColorRing.value = MSI_MONITOR_72_MODE_COLOR_RING;
|
||||
ColorRing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
ColorRing.colors_min = 1;
|
||||
ColorRing.colors_max = 1;
|
||||
ColorRing.colors.resize(1);
|
||||
ColorRing.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
ColorRing.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
ColorRing.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
ColorRing.brightness_min = 0;
|
||||
ColorRing.brightness_max = 100;
|
||||
ColorRing.brightness = 100;
|
||||
ColorRing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(ColorRing);
|
||||
|
||||
mode Planetary;
|
||||
Planetary.name = "Planetary";
|
||||
Planetary.value = MSI_MONITOR_72_MODE_PLANETARY;
|
||||
Planetary.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Planetary.colors_min = 1;
|
||||
Planetary.colors_max = 1;
|
||||
Planetary.colors.resize(1);
|
||||
Planetary.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
Planetary.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
Planetary.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
Planetary.brightness_min = 0;
|
||||
Planetary.brightness_max = 100;
|
||||
Planetary.brightness = 100;
|
||||
Planetary.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Planetary);
|
||||
|
||||
mode DoubleMeteor;
|
||||
DoubleMeteor.name = "Double Meteor";
|
||||
DoubleMeteor.value = MSI_MONITOR_72_MODE_DOUBLE_METEOR;
|
||||
DoubleMeteor.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
DoubleMeteor.colors_min = 1;
|
||||
DoubleMeteor.colors_max = 1;
|
||||
DoubleMeteor.colors.resize(1);
|
||||
DoubleMeteor.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
DoubleMeteor.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
DoubleMeteor.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
DoubleMeteor.brightness_min = 0;
|
||||
DoubleMeteor.brightness_max = 100;
|
||||
DoubleMeteor.brightness = 100;
|
||||
DoubleMeteor.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(DoubleMeteor);
|
||||
|
||||
mode Energy;
|
||||
Energy.name = "Energy";
|
||||
Energy.value = MSI_MONITOR_72_MODE_ENERGY;
|
||||
Energy.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Energy.colors_min = 1;
|
||||
Energy.colors_max = 1;
|
||||
Energy.colors.resize(1);
|
||||
Energy.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
Energy.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
Energy.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
Energy.brightness_min = 0;
|
||||
Energy.brightness_max = 100;
|
||||
Energy.brightness = 100;
|
||||
Energy.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Energy);
|
||||
|
||||
mode Blink;
|
||||
Blink.name = "Blink";
|
||||
Blink.value = MSI_MONITOR_72_MODE_BLINK;
|
||||
Blink.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Blink.colors_min = 1;
|
||||
Blink.colors_max = 1;
|
||||
Blink.colors.resize(1);
|
||||
Blink.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
Blink.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
Blink.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
Blink.brightness_min = 0;
|
||||
Blink.brightness_max = 100;
|
||||
Blink.brightness = 100;
|
||||
Blink.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Blink);
|
||||
|
||||
mode Clock;
|
||||
Clock.name = "Clock";
|
||||
Clock.value = MSI_MONITOR_72_MODE_CLOCK;
|
||||
Clock.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Clock.colors_min = 1;
|
||||
Clock.colors_max = 1;
|
||||
Clock.colors.resize(1);
|
||||
Clock.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
Clock.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
Clock.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
Clock.brightness_min = 0;
|
||||
Clock.brightness_max = 100;
|
||||
Clock.brightness = 100;
|
||||
Clock.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Clock);
|
||||
|
||||
mode ColorPulse;
|
||||
ColorPulse.name = "Color Pulse";
|
||||
ColorPulse.value = MSI_MONITOR_72_MODE_COLOR_PULSE;
|
||||
ColorPulse.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
ColorPulse.colors_min = 1;
|
||||
ColorPulse.colors_max = 1;
|
||||
ColorPulse.colors.resize(1);
|
||||
ColorPulse.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
ColorPulse.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
ColorPulse.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
ColorPulse.brightness_min = 0;
|
||||
ColorPulse.brightness_max = 100;
|
||||
ColorPulse.brightness = 100;
|
||||
ColorPulse.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(ColorPulse);
|
||||
|
||||
mode ColorShift;
|
||||
ColorShift.name = "Color Shift";
|
||||
ColorShift.value = MSI_MONITOR_72_MODE_COLOR_SHIFT;
|
||||
ColorShift.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
ColorShift.colors_min = 2;
|
||||
ColorShift.colors_max = 2;
|
||||
ColorShift.colors.resize(2);
|
||||
ColorShift.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
ColorShift.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
ColorShift.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
ColorShift.brightness_min = 0;
|
||||
ColorShift.brightness_max = 100;
|
||||
ColorShift.brightness = 100;
|
||||
ColorShift.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(ColorShift);
|
||||
|
||||
mode ColorWave;
|
||||
ColorWave.name = "Color Wave";
|
||||
ColorWave.value = MSI_MONITOR_72_MODE_COLOR_WAVE;
|
||||
ColorWave.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
ColorWave.colors_min = 2;
|
||||
ColorWave.colors_max = 2;
|
||||
ColorWave.colors.resize(2);
|
||||
ColorWave.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
ColorWave.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
ColorWave.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
ColorWave.brightness_min = 0;
|
||||
ColorWave.brightness_max = 100;
|
||||
ColorWave.brightness = 100;
|
||||
ColorWave.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(ColorWave);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Mode 24 marquee behaviour is model dependent. On the |
|
||||
| dual block / richer boards it wants the marker bytes |
|
||||
| plus a per LED array of separate colours (a user |
|
||||
| defined marquee). The vendor app does not even offer |
|
||||
| it for version 34, but the firmware still runs it as |
|
||||
| a one colour rolling band, so we expose that. |
|
||||
\*-----------------------------------------------------*/
|
||||
mode Marquee;
|
||||
Marquee.name = "Marquee";
|
||||
Marquee.value = MSI_MONITOR_72_MODE_MARQUEE;
|
||||
Marquee.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Marquee.colors_min = 1;
|
||||
Marquee.colors_max = 1;
|
||||
Marquee.colors.resize(1);
|
||||
Marquee.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
Marquee.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
Marquee.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
Marquee.brightness_min = 0;
|
||||
Marquee.brightness_max = 100;
|
||||
Marquee.brightness = 100;
|
||||
Marquee.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Marquee);
|
||||
|
||||
mode SpectrumCycle;
|
||||
SpectrumCycle.name = "Spectrum Cycle";
|
||||
SpectrumCycle.value = MSI_MONITOR_72_MODE_RAINBOW;
|
||||
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
SpectrumCycle.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
SpectrumCycle.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
SpectrumCycle.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
SpectrumCycle.brightness_min = 0;
|
||||
SpectrumCycle.brightness_max = 100;
|
||||
SpectrumCycle.brightness = 100;
|
||||
SpectrumCycle.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(SpectrumCycle);
|
||||
|
||||
mode RainbowWave;
|
||||
RainbowWave.name = "Rainbow Wave";
|
||||
RainbowWave.value = MSI_MONITOR_72_MODE_RAINBOW_WAVE;
|
||||
RainbowWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
RainbowWave.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
RainbowWave.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
RainbowWave.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
RainbowWave.brightness_min = 0;
|
||||
RainbowWave.brightness_max = 100;
|
||||
RainbowWave.brightness = 100;
|
||||
RainbowWave.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(RainbowWave);
|
||||
|
||||
mode Visor;
|
||||
Visor.name = "Visor";
|
||||
Visor.value = MSI_MONITOR_72_MODE_VISOR;
|
||||
Visor.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Visor.colors_min = 1;
|
||||
Visor.colors_max = 1;
|
||||
Visor.colors.resize(1);
|
||||
Visor.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
Visor.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
Visor.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
Visor.brightness_min = 0;
|
||||
Visor.brightness_max = 100;
|
||||
Visor.brightness = 100;
|
||||
Visor.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Visor);
|
||||
|
||||
mode JRainbow;
|
||||
JRainbow.name = "JRainbow";
|
||||
JRainbow.value = MSI_MONITOR_72_MODE_JRAINBOW;
|
||||
JRainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
JRainbow.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
JRainbow.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
JRainbow.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
JRainbow.brightness_min = 0;
|
||||
JRainbow.brightness_max = 100;
|
||||
JRainbow.brightness = 100;
|
||||
JRainbow.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(JRainbow);
|
||||
|
||||
mode RainbowFlash;
|
||||
RainbowFlash.name = "Rainbow Flashing";
|
||||
RainbowFlash.value = MSI_MONITOR_72_MODE_RAINBOW_FLASH;
|
||||
RainbowFlash.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
RainbowFlash.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
RainbowFlash.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
RainbowFlash.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
RainbowFlash.brightness_min = 0;
|
||||
RainbowFlash.brightness_max = 100;
|
||||
RainbowFlash.brightness = 100;
|
||||
RainbowFlash.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(RainbowFlash);
|
||||
|
||||
mode RainbowDblFlash;
|
||||
RainbowDblFlash.name = "Rainbow Double Flashing";
|
||||
RainbowDblFlash.value = MSI_MONITOR_72_MODE_RAINBOW_DBLFLASH;
|
||||
RainbowDblFlash.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
RainbowDblFlash.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
RainbowDblFlash.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
RainbowDblFlash.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
RainbowDblFlash.brightness_min = 0;
|
||||
RainbowDblFlash.brightness_max = 100;
|
||||
RainbowDblFlash.brightness = 100;
|
||||
RainbowDblFlash.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(RainbowDblFlash);
|
||||
|
||||
mode RainbowLine;
|
||||
RainbowLine.name = "Rainbow Line";
|
||||
RainbowLine.value = MSI_MONITOR_72_MODE_RAINBOW_LINE;
|
||||
RainbowLine.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
RainbowLine.speed_min = MSI_MONITOR_72_SPEED_LOW;
|
||||
RainbowLine.speed_max = MSI_MONITOR_72_SPEED_HIGH;
|
||||
RainbowLine.speed = MSI_MONITOR_72_SPEED_MEDIUM;
|
||||
RainbowLine.brightness_min = 0;
|
||||
RainbowLine.brightness_max = 100;
|
||||
RainbowLine.brightness = 100;
|
||||
RainbowLine.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(RainbowLine);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = MSI_MONITOR_72_MODE_OFF;
|
||||
Off.flags = MODE_FLAG_MANUAL_SAVE;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_MSIMonitor72::~RGBController_MSIMonitor72()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_MSIMonitor72::SetupZones()
|
||||
{
|
||||
zone new_zone;
|
||||
|
||||
new_zone.name = "Rear";
|
||||
new_zone.type = ZONE_TYPE_LINEAR;
|
||||
new_zone.leds_min = led_count;
|
||||
new_zone.leds_max = led_count;
|
||||
new_zone.leds_count = led_count;
|
||||
|
||||
zones.emplace_back(new_zone);
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < led_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = "LED " + std::to_string(led_idx + 1);
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_MSIMonitor72::DeviceUpdateLEDs()
|
||||
{
|
||||
DeviceUpdateMode();
|
||||
}
|
||||
|
||||
void RGBController_MSIMonitor72::DeviceUpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_MSIMonitor72::DeviceUpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_MSIMonitor72::ApplyMode(bool save)
|
||||
{
|
||||
const mode& active = modes[active_mode];
|
||||
|
||||
RGBColor color1 = 0;
|
||||
RGBColor color2 = 0;
|
||||
bool user_palette = false;
|
||||
std::vector<RGBColor> led_colors;
|
||||
|
||||
if(active.color_mode == MODE_COLORS_PER_LED)
|
||||
{
|
||||
user_palette = true;
|
||||
led_colors = colors;
|
||||
|
||||
if(led_colors.size() > 0)
|
||||
{
|
||||
color1 = led_colors[0];
|
||||
}
|
||||
}
|
||||
else if(active.color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
user_palette = true;
|
||||
|
||||
if(active.colors.size() > 0)
|
||||
{
|
||||
color1 = active.colors[0];
|
||||
|
||||
if(active.colors.size() > 1)
|
||||
{
|
||||
color2 = active.colors[1];
|
||||
}
|
||||
}
|
||||
|
||||
led_colors.assign(led_count, color1);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| RightToLeft layouts start at the right end, so mirror |
|
||||
| the per LED order to keep OpenRGB LED 0 on the left. |
|
||||
| Uniform colour modes are unaffected by the order. |
|
||||
\*-----------------------------------------------------*/
|
||||
if(reverse_order)
|
||||
{
|
||||
std::reverse(led_colors.begin(), led_colors.end());
|
||||
}
|
||||
|
||||
controller->SetMode72((uint8_t)active.value, (uint8_t)active.speed, (uint8_t)active.brightness, color1, color2, user_palette, save, led_colors, dual_block);
|
||||
}
|
||||
|
||||
void RGBController_MSIMonitor72::DeviceUpdateMode()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Updates are volatile. Persisting to flash is the |
|
||||
| Save To Device button (DeviceSaveMode), so live edits |
|
||||
| do not burn flash write cycles. |
|
||||
\*-----------------------------------------------------*/
|
||||
ApplyMode(false);
|
||||
}
|
||||
|
||||
void RGBController_MSIMonitor72::DeviceSaveMode()
|
||||
{
|
||||
ApplyMode(true);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_MSIMonitor72.h |
|
||||
| |
|
||||
| RGBController for MSI monitors using the 0x72 dual |
|
||||
| control block layout (MPG 322URX QD-OLED) |
|
||||
| |
|
||||
| Ken Sanislo 19 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "MSIMonitorController.h"
|
||||
|
||||
class RGBController_MSIMonitor72 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_MSIMonitor72(MSIMonitorController* controller_ptr, unsigned int count, unsigned int direction, bool dual);
|
||||
~RGBController_MSIMonitor72();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
void ApplyMode(bool save);
|
||||
|
||||
MSIMonitorController* controller;
|
||||
unsigned int led_count;
|
||||
bool reverse_order;
|
||||
bool dual_block;
|
||||
};
|
||||
+4
@@ -73,6 +73,8 @@ static const std::string board_names[] =
|
||||
"MSI MEG Z890 UNIFY-X (MS-7E20)",
|
||||
"MSI PRO X870E-S EVO WIFI (MS-7E86)",
|
||||
"MSI PRO Z890-P WIFI (MS-7E34)",
|
||||
"MSI B850 GAMING PLUS WIFI PZ (MS-7E75)",
|
||||
"MSI MAG X870E TOMAHAWK MAX WIFI PZ (MS-7E84)",
|
||||
};
|
||||
|
||||
static const mystic_light_761_config board_configs[] =
|
||||
@@ -103,6 +105,8 @@ static const mystic_light_761_config board_configs[] =
|
||||
{ &(board_names[23]), 0, 0, 0, 1, &zone_set1, MSIMysticLight761Controller::DIRECT_MODE_ZONE_BASED }, // MSI MEG Z890 UNIFY-X (MS-7E20)
|
||||
{ &(board_names[24]), 0, 0, 0, 1, &zone_set1, MSIMysticLight761Controller::DIRECT_MODE_ZONE_BASED }, // MSI PRO X870E-S EVO WIFI (MS-7E86)
|
||||
{ &(board_names[25]), 0, 0, 0, 1, &zone_set1, MSIMysticLight761Controller::DIRECT_MODE_ZONE_BASED }, // MSI PRO Z890-P WIFI (MS-7E34)
|
||||
{ &(board_names[26]), 0, 0, 0, 1, &zone_set1, MSIMysticLight761Controller::DIRECT_MODE_ZONE_BASED }, // MSI B850 GAMING PLUS WIFI PZ (MS-7E75)
|
||||
{ &(board_names[27]), 0, 0, 0, 1, &zone_set1, MSIMysticLight761Controller::DIRECT_MODE_ZONE_BASED }, // MSI MAG X870E TOMAHAWK MAX WIFI PZ (MS-7E84)
|
||||
};
|
||||
|
||||
enum MSI_ZONE setup_map [] =
|
||||
|
||||
+4
-4
@@ -132,10 +132,10 @@ void RGBController_MSIMysticLight761::SetupZones()
|
||||
/*-------------------------------------------------*\
|
||||
| This is a fixed size zone |
|
||||
\*-------------------------------------------------*/
|
||||
if(((zd->zone_type != MSI_ZONE_J_RAINBOW_1)
|
||||
&& (zd->zone_type != MSI_ZONE_J_RAINBOW_2)
|
||||
&& (zd->zone_type != MSI_ZONE_J_RAINBOW_3)
|
||||
&& (zd->zone_type != MSI_ZONE_J_CORSAIR)))
|
||||
if(((zd->zone_type != MSI_ZONE_JAF)
|
||||
&& (zd->zone_type != MSI_ZONE_JARGB_1)
|
||||
&& (zd->zone_type != MSI_ZONE_JARGB_2)
|
||||
&& (zd->zone_type != MSI_ZONE_JARGB_3)))
|
||||
{
|
||||
zones[zone_idx].name = zd->name;
|
||||
zones[zone_idx].type = ZONE_TYPE_SINGLE;
|
||||
|
||||
+3
-2
@@ -50,6 +50,7 @@ static const nv_gpu_pci_device device_list[] =
|
||||
{NVIDIA_VEN, NVIDIA_RTX2080_A_DEV, NVIDIA_SUB_VEN, NVIDIA_RTX2080_FE_SUB_DEV, NVIDIA_ILLUMINATION_V1, TREATS_RGBW_AS_RGBW, "NVIDIA GeForce RTX 2080 FE" },
|
||||
{NVIDIA_VEN, NVIDIA_RTX2080S_DEV, NVIDIA_SUB_VEN, NVIDIA_RTX2080S_FE_SUB_DEV, NVIDIA_ILLUMINATION_V1, TREATS_RGBW_AS_RGBW, "NVIDIA GeForce RTX 2080 SUPER FE" },
|
||||
{NVIDIA_VEN, NVIDIA_RTX2080TI_A_DEV, NVIDIA_SUB_VEN, NVIDIA_RTX2080TI_FE_SUB_DEV, NVIDIA_ILLUMINATION_V1, TREATS_RGBW_AS_RGBW, "NVIDIA GeForce RTX 2080 Ti FE" },
|
||||
{NVIDIA_VEN, NVIDIA_RTX2080TI_A_DEV, NVIDIA_SUB_VEN, NVIDIA_RTX2080TI_FE_CP2077_SUB_DEV, NVIDIA_ILLUMINATION_V1, TREATS_RGBW_AS_RGBW, "NVIDIA GeForce RTX 2080 Ti Cyberpunk 2077" },
|
||||
{NVIDIA_VEN, NVIDIA_TITANRTX_DEV, NVIDIA_SUB_VEN, NVIDIA_TITANRTX_FE_SUB_DEV, NVIDIA_ILLUMINATION_V1, TREATS_RGBW_AS_RGBW, "NVIDIA TITAN RTX" },
|
||||
{NVIDIA_VEN, NVIDIA_RTX3050_DEV, NVIDIA_SUB_VEN, GAINWARD_RTX3050_SUB_DEV, NVIDIA_ILLUMINATION_V1, TREATS_RGBW_AS_RGB, "Gainward GeForce RTX 3050 LHR" },
|
||||
{NVIDIA_VEN, NVIDIA_RTX3060_8G_DEV, NVIDIA_SUB_VEN, NVIDIA_RTX3060_8G_DEV, NVIDIA_ILLUMINATION_V1, TREATS_RGBW_AS_RGB, "Gainward GeForce RTX 3060 Pegasus" },
|
||||
@@ -76,8 +77,8 @@ static const nv_gpu_pci_device device_list[] =
|
||||
{NVIDIA_VEN, NVIDIA_RTX4080S_DEV, NVIDIA_SUB_VEN, NVIDIA_RTX4080S_FE_SUB_DEV, NVIDIA_ILLUMINATION_V1, TREATS_RGBW_AS_RGBW, "NVIDIA GeForce RTX 4080 SUPER FE" },
|
||||
{NVIDIA_VEN, NVIDIA_RTX4090_DEV, NVIDIA_SUB_VEN, NVIDIA_RTX4090_FE_SUB_DEV, NVIDIA_ILLUMINATION_V1, TREATS_RGBW_AS_RGBW, "NVIDIA GeForce RTX 4090 FE" },
|
||||
{NVIDIA_VEN, NVIDIA_RTX4090_DEV, NVIDIA_SUB_VEN, NVIDIA_RTX4090_FE_SUB_DEV2, NVIDIA_ILLUMINATION_V1, TREATS_RGBW_AS_RGBW, "NVIDIA GeForce RTX 4090 FE" },
|
||||
{NVIDIA_VEN, NVIDIA_RTX5080_DEV, NVIDIA_SUB_VEN, NVIDIA_RTX5080_FE_SUB_DEV, NVIDIA_ILLUMINATION_V1, TREATS_RGBW_AS_RGBW, "NVIDIA GeForce RTX 5080 FE" },
|
||||
{NVIDIA_VEN, NVIDIA_RTX5090_DEV, NVIDIA_SUB_VEN, NVIDIA_RTX5090_FE_SUB_DEV, NVIDIA_ILLUMINATION_V1, TREATS_RGBW_AS_RGBW, "NVIDIA GeForce RTX 5090 FE" },
|
||||
{NVIDIA_VEN, NVIDIA_RTX5080_DEV, NVIDIA_SUB_VEN, NVIDIA_RTX5080_FE_SUB_DEV, NVIDIA_ILLUMINATION_V1, TREATS_RGBW_AS_RGBW, "NVIDIA GeForce RTX 5080 FE" },
|
||||
{NVIDIA_VEN, NVIDIA_RTX5090_DEV, NVIDIA_SUB_VEN, NVIDIA_RTX5090_FE_SUB_DEV, NVIDIA_ILLUMINATION_V1, TREATS_RGBW_AS_RGBW, "NVIDIA GeForce RTX 5090 FE" },
|
||||
};
|
||||
|
||||
DetectedControllers DetectNVIDIAIllumGPUs()
|
||||
|
||||
@@ -208,7 +208,8 @@ void NanoleafController::UpdateLEDs(std::vector<RGBColor>& colors)
|
||||
free(message);
|
||||
}
|
||||
else if((model == NANOLEAF_CANVAS_MODEL)
|
||||
|| (model == NANOLEAF_SHAPES_MODEL))
|
||||
|| (model == NANOLEAF_SHAPES_MODEL)
|
||||
|| (model == NANOLEAF_LINES_MODEL))
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Protocol V2 - https://forum.nanoleaf.me/docs |
|
||||
@@ -275,7 +276,8 @@ void NanoleafController::StartExternalControl()
|
||||
}
|
||||
}
|
||||
else if((model == NANOLEAF_CANVAS_MODEL)
|
||||
|| (model == NANOLEAF_SHAPES_MODEL))
|
||||
|| (model == NANOLEAF_SHAPES_MODEL)
|
||||
|| (model == NANOLEAF_LINES_MODEL))
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Protocol v2 does not return anything, use device IP and |
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define NANOLEAF_LIGHT_PANELS_MODEL "NL22"
|
||||
#define NANOLEAF_CANVAS_MODEL "NL29"
|
||||
#define NANOLEAF_SHAPES_MODEL "NL42"
|
||||
#define NANOLEAF_LINES_MODEL "NL59"
|
||||
|
||||
class NanoleafController
|
||||
{
|
||||
|
||||
@@ -77,3 +77,4 @@ REGISTER_I2C_PCI_DETECTOR("PowerColor Red Devil RX6900XT", DetectPowerC
|
||||
REGISTER_I2C_PCI_DETECTOR("PowerColor Red Devil RX6900XT Ultimate", DetectPowerColorRedDevilGPUControllersV1, AMD_GPU_VEN, AMD_NAVI21_DEV2, POWERCOLOR_SUB_VEN, POWERCOLOR_RED_DEVIL_RX6900XT_ULTIMATE_SUB_DEV, 0x22);
|
||||
|
||||
REGISTER_I2C_PCI_DETECTOR("PowerColor Red Devil RX9070XT", DetectPowerColorRedDevilGPUControllersV2, AMD_GPU_VEN, AMD_NAVI48_DEV, POWERCOLOR_SUB_VEN, POWERCOLOR_RED_DEVIL_RX9070XT_SUB_DEV, 0x22);
|
||||
REGISTER_I2C_PCI_DETECTOR("PowerColor Red Devil RX9070", DetectPowerColorRedDevilGPUControllersV2, AMD_GPU_VEN, AMD_NAVI48_DEV, POWERCOLOR_SUB_VEN, POWERCOLOR_RED_DEVIL_RX9070_SUB_DEV, 0x22);
|
||||
|
||||
@@ -19,7 +19,115 @@
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
QMKKeychronController::QMKKeychronController(hid_device* dev_handle, const char *path)
|
||||
/*---------------------------------------------------------*\
|
||||
| Keychron Patch Types |
|
||||
| The Keychron protocol does not provide RGB matrix X/Y |
|
||||
| coordinates, only the position in the wiring matrix. |
|
||||
| For most Keychron keyboards, the wiring matrix mostly |
|
||||
| matches the physical position, but there are often a |
|
||||
| few misplaced LEDs. Implement a matrix patching system |
|
||||
| to apply keyboard-specific patches for these misplaced |
|
||||
| LEDs. |
|
||||
\*---------------------------------------------------------*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned int led_idx;
|
||||
unsigned int row;
|
||||
unsigned int col;
|
||||
} keychron_patch_entry;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short pid;
|
||||
unsigned int num_entries;
|
||||
const keychron_patch_entry* patch;
|
||||
} keychron_patch;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keychron K5 V2 ANSI Encoder |
|
||||
\*---------------------------------------------------------*/
|
||||
#define KEYCHRON_K5_V2_ANSI_RGB_PATCH_ENTRIES_COUNT \
|
||||
(sizeof(keychron_k5_v2_ansi_rgb_patch_entries) / sizeof(keychron_patch_entry))
|
||||
|
||||
static const keychron_patch_entry keychron_k5_v2_ansi_rgb_patch_entries[] =
|
||||
{
|
||||
{ 18, 0, 19 },
|
||||
{ 19, 0, 20 },
|
||||
{ 39, 1, 19 },
|
||||
{ 40, 1, 20 },
|
||||
{ 60, 2, 19 },
|
||||
{ 61, 2, 20 },
|
||||
{ 74, 3, 12 },
|
||||
{ 77, 3, 19 },
|
||||
{ 89, 4, 12 },
|
||||
{ 93, 4, 19 },
|
||||
{ 107, 5, 19 },
|
||||
{ 94, 5, 20 },
|
||||
};
|
||||
|
||||
static const keychron_patch keychron_k5_v2_ansi_rgb_patch =
|
||||
{
|
||||
KEYCHRON_K5_V2_ANSI_RGB_PID,
|
||||
KEYCHRON_K5_V2_ANSI_RGB_PATCH_ENTRIES_COUNT,
|
||||
keychron_k5_v2_ansi_rgb_patch_entries
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keychron Q2 ANSI Encoder |
|
||||
\*---------------------------------------------------------*/
|
||||
#define KEYCHRON_Q2_ANSI_ENCODER_PATCH_ENTRIES_COUNT (sizeof(keychron_q2_ansi_encoder_patch_entries) / sizeof(keychron_patch_entry))
|
||||
|
||||
static const keychron_patch_entry keychron_q2_ansi_encoder_patch_entries[] =
|
||||
{
|
||||
{ 60, 4, 9 },
|
||||
{ 61, 4, 10 },
|
||||
{ 62, 4, 11 },
|
||||
{ 63, 4, 12 },
|
||||
{ 54, 3, 12 },
|
||||
{ 55, 3, 13 },
|
||||
{ 64, 4, 13 },
|
||||
};
|
||||
|
||||
static const keychron_patch keychron_q2_ansi_encoder_patch =
|
||||
{
|
||||
KEYCHRON_Q2_ANSI_ENCODER_PID,
|
||||
KEYCHRON_Q2_ANSI_ENCODER_PATCH_ENTRIES_COUNT,
|
||||
keychron_q2_ansi_encoder_patch_entries
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keychron Q6 ANSI Encoder |
|
||||
\*---------------------------------------------------------*/
|
||||
#define KEYCHRON_Q6_ULTRA_8K_ANSI_PATCH_ENTRIES_COUNT (sizeof(keychron_q6_ultra_8k_ansi_patch_entries) / sizeof(keychron_patch_entry))
|
||||
|
||||
static const keychron_patch_entry keychron_q6_ultra_8k_ansi_patch_entries[] =
|
||||
{
|
||||
{ 19, 0, 20 },
|
||||
{ 40, 1, 20 },
|
||||
{ 77, 3, 20 },
|
||||
{ 107, 5, 20 },
|
||||
};
|
||||
|
||||
static const keychron_patch keychron_q6_ultra_8k_ansi_patch =
|
||||
{
|
||||
KEYCHRON_Q6_ULTRA_8K_ANSI_PID,
|
||||
KEYCHRON_Q6_ULTRA_8K_ANSI_PATCH_ENTRIES_COUNT,
|
||||
keychron_q6_ultra_8k_ansi_patch_entries
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| List of all Keychron patches |
|
||||
\*---------------------------------------------------------*/
|
||||
#define KEYCHRON_PATCH_COUNT (sizeof(keychron_patches) / sizeof(keychron_patch*))
|
||||
|
||||
static const keychron_patch* keychron_patches[] =
|
||||
{
|
||||
&keychron_q2_ansi_encoder_patch,
|
||||
&keychron_q6_ultra_8k_ansi_patch,
|
||||
&keychron_k5_v2_ansi_rgb_patch,
|
||||
};
|
||||
|
||||
QMKKeychronController::QMKKeychronController(hid_device* dev_handle, const char *path, unsigned short dev_pid)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Initialize controller fields |
|
||||
@@ -27,6 +135,7 @@ QMKKeychronController::QMKKeychronController(hid_device* dev_handle, const char
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
kc_protocol_version = 0;
|
||||
pid = dev_pid;
|
||||
supported_features = 0;
|
||||
via_protocol_version = 0;
|
||||
|
||||
@@ -143,6 +252,21 @@ QMKKeychronController::QMKKeychronController(hid_device* dev_handle, const char
|
||||
{
|
||||
keycodes[led_index] = CmdGetKeycode(0, led_info[led_index].row, led_info[led_index].col);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Apply matrix corrections |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int patch_idx = 0; patch_idx < KEYCHRON_PATCH_COUNT; patch_idx++)
|
||||
{
|
||||
if(pid == keychron_patches[patch_idx]->pid)
|
||||
{
|
||||
for(unsigned int patch_entry_idx = 0; patch_entry_idx < keychron_patches[patch_idx]->num_entries; patch_entry_idx++)
|
||||
{
|
||||
led_info[keychron_patches[patch_idx]->patch[patch_entry_idx].led_idx].row = keychron_patches[patch_idx]->patch[patch_entry_idx].row;
|
||||
led_info[keychron_patches[patch_idx]->patch[patch_entry_idx].led_idx].col = keychron_patches[patch_idx]->patch[patch_entry_idx].col;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QMKKeychronController::~QMKKeychronController()
|
||||
|
||||
@@ -114,6 +114,7 @@
|
||||
#define KEYCHRON_K17_MAX_ISO_ENCODER_RGB_PID 0x0A01
|
||||
#define KEYCHRON_K17_MAX_JIS_ENCODER_RGB_PID 0x0A02
|
||||
#define KEYCHRON_Q0_BASE_PID 0x0130
|
||||
#define KEYCHRON_Q0_HE_PID 0x0B00
|
||||
#define KEYCHRON_Q0_PLUS_PID 0x0131
|
||||
#define KEYCHRON_Q0_MAX_ENCODER_PID 0x0800
|
||||
#define KEYCHRON_Q1_HE_ANSI_ENCODER_PID 0x0B10
|
||||
@@ -389,7 +390,7 @@ enum KeychronVIABacklightValueID
|
||||
class QMKKeychronController
|
||||
{
|
||||
public:
|
||||
QMKKeychronController(hid_device* dev_handle, const char *path);
|
||||
QMKKeychronController(hid_device* dev_handle, const char *path, unsigned short dev_pid);
|
||||
~QMKKeychronController();
|
||||
|
||||
std::string GetLocation();
|
||||
@@ -419,6 +420,7 @@ private:
|
||||
std::string location;
|
||||
std::string name;
|
||||
unsigned short number_leds;
|
||||
unsigned short pid;
|
||||
std::string serial;
|
||||
unsigned short supported_features;
|
||||
std::string vendor;
|
||||
|
||||
@@ -23,7 +23,7 @@ DetectedControllers DetectQMKKeychronControllers(hid_device_info* info, const st
|
||||
|
||||
if(dev)
|
||||
{
|
||||
QMKKeychronController* controller = new QMKKeychronController(dev, info->path);
|
||||
QMKKeychronController* controller = new QMKKeychronController(dev, info->path, info->product_id);
|
||||
|
||||
if(controller->GetSupported())
|
||||
{
|
||||
@@ -129,6 +129,7 @@ REGISTER_HID_DETECTOR_IPU("Keychron K17 Max", DetectQMKKeychronControllers
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K17 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K17_MAX_ISO_ENCODER_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K17 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K17_MAX_JIS_ENCODER_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q0", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q0_BASE_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q0 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q0_HE_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q0 Plus", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q0_PLUS_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q0 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q0_MAX_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_HE_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
|
||||
@@ -12,22 +12,18 @@
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "RedSquareKeyroxController.h"
|
||||
#include "RedSquareKeyroxTKLClassicController.h"
|
||||
#include "RGBController_RedSquareKeyrox.h"
|
||||
#include "RGBController_RedSquareKeyroxTKLClassic.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Red Square vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define RED_SQUARE_VID 0x1A2C
|
||||
#define RED_SQUARE_KEYROX_TKL_CLASSIC_VID 0x0416
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Red Square product ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define RED_SQUARE_KEYROX_TKL_PID 0x1511
|
||||
#define RED_SQUARE_KEYROX_TKL_V2_PID 0x2511
|
||||
#define RED_SQUARE_KEYROX_TKL_CLASSIC_PID 0xC345
|
||||
|
||||
DetectedControllers DetectRedSquareKeyroxTKL(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
@@ -47,24 +43,5 @@ DetectedControllers DetectRedSquareKeyroxTKL(hid_device_info* info, const std::s
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectRedSquareKeyroxTKLClassic(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
RedSquareKeyroxTKLClassicController* controller = new RedSquareKeyroxTKLClassicController(dev, *info, name);
|
||||
RGBController_RedSquareKeyroxTKLClassic* rgb_controller = new RGBController_RedSquareKeyroxTKLClassic(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Red Square Keyrox TKL", DetectRedSquareKeyroxTKL, RED_SQUARE_VID, RED_SQUARE_KEYROX_TKL_PID, 3, 0xFF00, 2);
|
||||
REGISTER_HID_DETECTOR_IPU("Red Square Keyrox TKL V2", DetectRedSquareKeyroxTKL, RED_SQUARE_VID, RED_SQUARE_KEYROX_TKL_V2_PID, 3, 0xFF00, 2);
|
||||
REGISTER_HID_DETECTOR_I( "Red Square Keyrox TKL Classic", DetectRedSquareKeyroxTKLClassic, RED_SQUARE_KEYROX_TKL_CLASSIC_VID, RED_SQUARE_KEYROX_TKL_CLASSIC_PID, 2);
|
||||
|
||||
-169
@@ -1,169 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RedSquareKeyroxTKLClassicController.cpp |
|
||||
| |
|
||||
| Driver for Red Square Keyrox TKL Classic |
|
||||
| |
|
||||
| vlack 03 May 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "LogManager.h"
|
||||
#include "RedSquareKeyroxTKLClassicController.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
RedSquareKeyroxTKLClassicController::RedSquareKeyroxTKLClassicController(hid_device *dev_handle, const hid_device_info &info, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = info.path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
RedSquareKeyroxTKLClassicController::~RedSquareKeyroxTKLClassicController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string RedSquareKeyroxTKLClassicController::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string RedSquareKeyroxTKLClassicController::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string RedSquareKeyroxTKLClassicController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_wchar[128];
|
||||
hid_get_serial_number_string(dev, serial_wchar, 128);
|
||||
std::wstring serial_wstring(serial_wchar);
|
||||
|
||||
std::string serial_string;
|
||||
std::transform(serial_wstring.begin(), serial_wstring.end(), std::back_inserter(serial_string), [] (wchar_t i)
|
||||
{
|
||||
return (char)i;
|
||||
});
|
||||
|
||||
return serial_string;
|
||||
}
|
||||
|
||||
int RedSquareKeyroxTKLClassicController::GetDirection(int direction)
|
||||
{
|
||||
switch(direction)
|
||||
{
|
||||
case MODE_DIRECTION_LEFT:
|
||||
return 0x00;
|
||||
case MODE_DIRECTION_RIGHT:
|
||||
return 0x01;
|
||||
case MODE_DIRECTION_UP:
|
||||
return 0x02;
|
||||
case MODE_DIRECTION_DOWN:
|
||||
return 0x03;
|
||||
case MODE_DIRECTION_HORIZONTAL: // actually direction out
|
||||
return 0x04;
|
||||
case MODE_DIRECTION_VERTICAL: // actually direction in
|
||||
return 0x05;
|
||||
default:
|
||||
return 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
int RedSquareKeyroxTKLClassicController::GetDirectionRound(int direction)
|
||||
{
|
||||
switch(direction)
|
||||
{
|
||||
case MODE_DIRECTION_LEFT: // actually anticlockwise
|
||||
return 0x07;
|
||||
case MODE_DIRECTION_RIGHT: // actually clockwise
|
||||
return 0x06;
|
||||
default:
|
||||
return 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
void RedSquareKeyroxTKLClassicController::SetMode(mode m)
|
||||
{
|
||||
/*---------------------------------------------*\
|
||||
| Mode set command |
|
||||
\*---------------------------------------------*/
|
||||
|
||||
unsigned char usb_buf[CLASSIC_PACKET_DATA_LENGTH];
|
||||
memset(usb_buf, 0x00, CLASSIC_PACKET_DATA_LENGTH);
|
||||
|
||||
usb_buf[0] = 0x01;
|
||||
usb_buf[1] = 0x07;
|
||||
usb_buf[6] = m.value;
|
||||
usb_buf[7] = m.brightness; // brightness
|
||||
usb_buf[8] = m.speed; // speed
|
||||
|
||||
if(m.colors_max == 1 || m.colors_max == 2)
|
||||
{
|
||||
usb_buf[9] = RGBGetRValue(m.colors[0]); // front R
|
||||
usb_buf[10] = RGBGetGValue(m.colors[0]); // front G
|
||||
usb_buf[11] = RGBGetBValue(m.colors[0]); // front B
|
||||
}
|
||||
|
||||
if(m.colors_max == 2 && m.color_mode != MODE_COLORS_RANDOM)
|
||||
{
|
||||
usb_buf[12] = RGBGetRValue(m.colors[1]); // back R
|
||||
usb_buf[13] = RGBGetGValue(m.colors[1]); // back G
|
||||
usb_buf[14] = RGBGetBValue(m.colors[1]); // back B
|
||||
}
|
||||
|
||||
if(m.value == CLASSIC_RADAR_MODE_VALUE || m.value == CLASSIC_RUNNING_LINE_MODE_VALUE)
|
||||
{
|
||||
usb_buf[15] = GetDirectionRound(m.direction);
|
||||
}
|
||||
else
|
||||
{
|
||||
usb_buf[15] = GetDirection(m.direction);
|
||||
}
|
||||
|
||||
usb_buf[16] = m.color_mode == MODE_COLORS_RANDOM;
|
||||
|
||||
hid_write(dev, usb_buf, CLASSIC_PACKET_DATA_LENGTH);
|
||||
// sleep is necessary
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
|
||||
void RedSquareKeyroxTKLClassicController::SetLEDsData(std::vector<RGBColor> colors, std::vector<led> leds)
|
||||
{
|
||||
/*---------------------------------------------*\
|
||||
| LEDs data set command |
|
||||
\*---------------------------------------------*/
|
||||
|
||||
unsigned char usb_buf[CLASSIC_PACKET_DATA_LENGTH * 8];
|
||||
memset(usb_buf, 0x00, CLASSIC_PACKET_DATA_LENGTH * 8);
|
||||
|
||||
for(unsigned int i = 0; i < colors.size(); i++)
|
||||
{
|
||||
int offset = leds[i].value;
|
||||
usb_buf[offset - 1] = RGBGetRValue(colors[i]);
|
||||
usb_buf[offset] = RGBGetGValue(colors[i]);
|
||||
usb_buf[offset + 1] = RGBGetBValue(colors[i]);
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < 8; i++)
|
||||
{
|
||||
unsigned char packet[CLASSIC_PACKET_DATA_LENGTH];
|
||||
memset(packet, 0x00, CLASSIC_PACKET_DATA_LENGTH);
|
||||
|
||||
packet[0] = 0x01;
|
||||
packet[1] = 0x0F;
|
||||
packet[4] = i; // package number
|
||||
packet[5] = i == 7 ? 0x12 : 0x36; // package size
|
||||
|
||||
for (int x = 6; x < CLASSIC_PACKET_DATA_LENGTH; x++)
|
||||
{
|
||||
packet[x] = usb_buf[CLASSIC_PACKET_DATA_LENGTH * i + x];
|
||||
}
|
||||
hid_write(dev, packet, CLASSIC_PACKET_DATA_LENGTH);
|
||||
}
|
||||
|
||||
// sleep is necessary
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
-78
@@ -1,78 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RedSquareKeyroxTKLClassicController.h |
|
||||
| |
|
||||
| Driver for Red Square Keyrox TKL Classic |
|
||||
| |
|
||||
| vlack 03 May 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define CLASSIC_PACKET_DATA_LENGTH 64
|
||||
|
||||
/*---------------------------------------*\
|
||||
| Modes |
|
||||
\*---------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CLASSIC_CONST_MODE_VALUE = 0x00, // static
|
||||
CLASSIC_BREATHE_MODE_VALUE = 0x01, // breath
|
||||
CLASSIC_WAVE_MODE_VALUE = 0x02, // wave
|
||||
CLASSIC_FADE_MODE_VALUE = 0x03, // neon
|
||||
CLASSIC_RADAR_MODE_VALUE = 0x04, // radar
|
||||
CLASSIC_STAR_MODE_VALUE = 0x06, // интерактив
|
||||
CLASSIC_LINE_MODE_VALUE = 0x07, // сияние
|
||||
CLASSIC_RIPPLE_MODE_VALUE = 0x08, // рябь интерактив
|
||||
CLASSIC_STARS_MODE_VALUE = 0x09, // мерцание
|
||||
CLASSIC_CUSTOM_MODE_VALUE = 0x0A,
|
||||
CLASSIC_CROSS_MODE_VALUE = 0x0B, // скрещивание
|
||||
CLASSIC_WTF_MODE_VALUE = 0x0C, // быстрый отклик
|
||||
CLASSIC_RIPPLE_RANDOM_MODE_VALUE = 0x0E, // рябь
|
||||
CLASSIC_RUNNING_LINE_MODE_VALUE = 0x0F, // бегущая строка
|
||||
CLASSIC_FIREWORK_MODE_VALUE = 0x10, // firework
|
||||
};
|
||||
|
||||
/*-----------------------------*\
|
||||
| Other settings |
|
||||
\*-----------------------------*/
|
||||
enum
|
||||
{
|
||||
CLASSIC_KEYROX_BRIGHTNESS_MIN = 0x00,
|
||||
CLASSIC_KEYROX_BRIGHTNESS_MAX = 0x04,
|
||||
CLASSIC_KEYROX_SPEED_MIN = 0x00,
|
||||
CLASSIC_KEYROX_SPEED_MAX = 0x04,
|
||||
};
|
||||
|
||||
|
||||
class RedSquareKeyroxTKLClassicController
|
||||
{
|
||||
public:
|
||||
RedSquareKeyroxTKLClassicController(hid_device *dev_handle, const hid_device_info &info, std::string dev_name);
|
||||
~RedSquareKeyroxTKLClassicController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
int GetDirection(int direction);
|
||||
int GetDirectionRound(int direction);
|
||||
|
||||
void SetMode(mode m);
|
||||
void SetLEDsData(std::vector<RGBColor> colors, std::vector<led> leds);
|
||||
|
||||
protected:
|
||||
hid_device* dev;
|
||||
|
||||
private:
|
||||
std::string location;
|
||||
std::string name;
|
||||
std::string serial_number;
|
||||
std::vector<unsigned int> led_sequence_positions;
|
||||
};
|
||||
+10
-1
@@ -151,6 +151,9 @@ void RGBController_RoccatVulcanKeyboard::SetupZones()
|
||||
case ROCCAT_VULCAN_LAYOUT_FR:
|
||||
layout = ROCCAT_VULCAN_LAYOUT_UK;
|
||||
break;
|
||||
case ROCCAT_VULCAN_LAYOUT_JP:
|
||||
layout = ROCCAT_VULCAN_LAYOUT_JP;
|
||||
break;
|
||||
case ROCCAT_VULCAN_LAYOUT_US:
|
||||
default:
|
||||
layout = ROCCAT_VULCAN_LAYOUT_US;
|
||||
@@ -167,7 +170,13 @@ void RGBController_RoccatVulcanKeyboard::SetupZones()
|
||||
|
||||
if(pid == ROCCAT_VULCAN_II_MAX_PID)
|
||||
{
|
||||
keyboard_size = 108;
|
||||
/*---------------------------------------------------------*\
|
||||
| Dynamically calculate the main keyboard zone size by |
|
||||
| subtracting the 40 secondary/palm rest LEDs from the |
|
||||
| total layout size. This prevents JIS keys from overflow. |
|
||||
\*---------------------------------------------------------*/
|
||||
keyboard_size = keyboard[layout].size - 40;
|
||||
|
||||
}
|
||||
|
||||
zone keyboard_zone;
|
||||
|
||||
+19
-4
@@ -84,6 +84,10 @@ device_info RoccatVulcanKeyboardController::InitDeviceInfo()
|
||||
memset(buf, 0x00, packet_length);
|
||||
|
||||
buf[0] = report_id;
|
||||
/*-------------------------------------------------------------*\
|
||||
| Store the actual read bytes to verify data availability |
|
||||
\*-------------------------------------------------------------*/
|
||||
int res = hid_get_feature_report(dev_ctrl, buf, packet_length);
|
||||
hid_get_feature_report(dev_ctrl, buf, packet_length);
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
@@ -107,11 +111,22 @@ device_info RoccatVulcanKeyboardController::InitDeviceInfo()
|
||||
}
|
||||
else
|
||||
{
|
||||
dev_info.layout_type = buf[6];
|
||||
/*---------------------------------------------------------*\
|
||||
| Safe check for reported buffer length before accessing |
|
||||
| buf[6] to prevent out-of-bounds array access. |
|
||||
| Vulcan II Max (JP) returns 0x06 at buf[6] for JIS layout. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(res >= 7)
|
||||
{
|
||||
dev_info.layout_type = buf[6];
|
||||
LOG_DEBUG("[Roccat Vulcan Keyboard]: Detected layout '0x%02X'", buf[6]);
|
||||
}
|
||||
else
|
||||
{
|
||||
dev_info.layout_type = ROCCAT_VULCAN_LAYOUT_US;
|
||||
LOG_DEBUG("[Roccat Vulcan Keyboard]: Failed to detect layout, falling back to US");
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("[Roccat Vulcan Keyboard]: Detected layout '0x%02X'", buf[6]);
|
||||
|
||||
delete[] buf;
|
||||
return dev_info;
|
||||
}
|
||||
|
||||
+224
-1
@@ -22,6 +22,7 @@ enum
|
||||
ROCCAT_VULCAN_LAYOUT_DE = 1,
|
||||
ROCCAT_VULCAN_LAYOUT_UK = 2,
|
||||
ROCCAT_VULCAN_LAYOUT_FR = 3,
|
||||
ROCCAT_VULCAN_LAYOUT_JP = 6, /* Updated based on Vulcan II Max JIS firmware report value */
|
||||
};
|
||||
|
||||
#define NA 0xFFFFFFFF
|
||||
@@ -815,6 +816,16 @@ static unsigned int ROCCAT_VULCAN_II_MAX_LAYOUT_KEYS_ANSI[6][24] =
|
||||
{ 5, 8, 14, NA, NA, NA, 34, NA, NA, NA, 55, 61, 66, 74, NA, NA, 78, 83, 87, NA, 92, NA, 101, NA }
|
||||
};
|
||||
|
||||
static unsigned int ROCCAT_VULCAN_II_MAX_LAYOUT_KEYS_JIS[6][24] =
|
||||
{
|
||||
{ 0, NA, 7, 13, 19, 25, NA, 35, 40, 45, 51, 57, 63, 69, 73, NA, 78, 82, 87, NA, 108, 109, 110, NA },
|
||||
{ 1, 6, 8, 14, 20, 26, 30, 36, 41, 46, 52, 58, 64, 70, 74, NA, 79, 83, 88, NA, 91, 96, 100, 105 },
|
||||
{ 2, NA, 9, 15, 21, 27, 31, 37, 42, 47, 53, 59, 65, 71, 75, NA, 80, 84, 89, NA, 92, 97, 101, 106 },
|
||||
{ 3, NA, 10, 16, 22, 28, 32, 38, 43, 48, 54, 60, 66, 72, NA, NA, NA, NA, NA, NA, 93, 98, 102, NA },
|
||||
{ 4, NA, 11, 17, 23, 29, 33, 39, 44, 49, 55, 61, 67, NA, 76, NA, NA, 85, NA, NA, 94, 99, 103, 107 },
|
||||
{ 5, NA, 12, 18, 24, NA, 34, NA, NA, 50, 56, 62, 68, NA, 77, NA, 81, 86, 90, NA, 95, NA, 104, NA }
|
||||
};
|
||||
|
||||
static std::map<int, layout_info> RoccatVulcanIIMaxLayouts =
|
||||
{
|
||||
{
|
||||
@@ -1005,7 +1016,219 @@ static std::map<int, layout_info> RoccatVulcanIIMaxLayouts =
|
||||
{ "Key: Left Windows LED 2", 0x83 },
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Palm Rest LEDs (order approximate - needs verification) |
|
||||
| Palm Rest LEDs (order approximate - needs verification) |
|
||||
\*-------------------------------------------------------------*/
|
||||
{ "Palm Rest LED 1", 0x96 },
|
||||
{ "Palm Rest LED 2", 0xAD },
|
||||
{ "Palm Rest LED 3", 0xA7 },
|
||||
{ "Palm Rest LED 4", 0xA1 },
|
||||
{ "Palm Rest LED 5", 0x9B },
|
||||
{ "Palm Rest LED 6", 0x95 },
|
||||
{ "Palm Rest LED 7", 0xAC },
|
||||
{ "Palm Rest LED 8", 0xA6 },
|
||||
{ "Palm Rest LED 9", 0xA0 },
|
||||
{ "Palm Rest LED 10", 0x9A },
|
||||
{ "Palm Rest LED 11", 0x94 },
|
||||
{ "Palm Rest LED 12", 0xAB },
|
||||
{ "Palm Rest LED 13", 0xA5 },
|
||||
{ "Palm Rest LED 14", 0x9F },
|
||||
{ "Palm Rest LED 15", 0x99 },
|
||||
{ "Palm Rest LED 16", 0x93 }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
ROCCAT_VULCAN_LAYOUT_JP,
|
||||
{
|
||||
*ROCCAT_VULCAN_II_MAX_LAYOUT_KEYS_JIS,
|
||||
151,
|
||||
6,
|
||||
24,
|
||||
{
|
||||
{ KEY_EN_ESCAPE, 0x02 },
|
||||
{ KEY_JP_EJ, 0x03 },
|
||||
{ KEY_EN_TAB, 0x04 },
|
||||
{ KEY_EN_CAPS_LOCK, 0x05 },
|
||||
{ KEY_EN_LEFT_SHIFT, 0x00 },
|
||||
{ KEY_EN_LEFT_CONTROL, 0x01 },
|
||||
|
||||
{ KEY_EN_1, 0x08 },
|
||||
|
||||
{ KEY_EN_F1, 0x0D },
|
||||
{ KEY_EN_2, 0x0E },
|
||||
{ KEY_EN_Q, 0x09 },
|
||||
{ KEY_EN_A, 0x0A },
|
||||
{ KEY_EN_Z, 0x0B },
|
||||
{ KEY_EN_LEFT_WINDOWS, 0x07 },
|
||||
|
||||
{ KEY_EN_F2, 0x14 },
|
||||
{ KEY_EN_3, 0x15 },
|
||||
{ KEY_EN_W, 0x0F },
|
||||
{ KEY_EN_S, 0x10 },
|
||||
{ KEY_EN_X, 0x11 },
|
||||
{ KEY_EN_LEFT_ALT, 0x0C },
|
||||
|
||||
{ KEY_EN_F3, 0x19 },
|
||||
{ KEY_EN_4, 0x1A },
|
||||
{ KEY_EN_E, 0x16 },
|
||||
{ KEY_EN_D, 0x17 },
|
||||
{ KEY_EN_C, 0x18 },
|
||||
{ KEY_JP_MUHENKAN, 0x12 },
|
||||
|
||||
{ KEY_EN_F4, 0x1F },
|
||||
{ KEY_EN_5, 0x1E },
|
||||
{ KEY_EN_R, 0x1B },
|
||||
{ KEY_EN_F, 0x1C },
|
||||
{ KEY_EN_V, 0x21 },
|
||||
|
||||
{ KEY_EN_6, 0x24 },
|
||||
{ KEY_EN_T, 0x20 },
|
||||
{ KEY_EN_G, 0x1D },
|
||||
{ KEY_EN_B, 0x22 },
|
||||
{ KEY_EN_SPACE, 0x28 },
|
||||
|
||||
{ KEY_EN_F5, 0x23 },
|
||||
{ KEY_EN_7, 0x29 },
|
||||
{ KEY_EN_Y, 0x25 },
|
||||
{ KEY_EN_H, 0x26 },
|
||||
{ KEY_EN_N, 0x27 },
|
||||
|
||||
{ KEY_EN_F6, 0x2F },
|
||||
{ KEY_EN_8, 0x30 },
|
||||
{ KEY_EN_U, 0x3D },
|
||||
{ KEY_EN_J, 0x2B },
|
||||
{ KEY_EN_M, 0x2C },
|
||||
|
||||
{ KEY_EN_F7, 0x35 },
|
||||
{ KEY_EN_9, 0x36 },
|
||||
{ KEY_EN_I, 0x31 },
|
||||
{ KEY_EN_K, 0x32 },
|
||||
{ KEY_EN_COMMA, 0x33 },
|
||||
{ KEY_JP_HENKAN, 0x2D },
|
||||
|
||||
{ KEY_EN_F8, 0x3B },
|
||||
{ KEY_EN_0, 0x3C },
|
||||
{ KEY_EN_O, 0x37 },
|
||||
{ KEY_EN_L, 0x38 },
|
||||
{ KEY_EN_PERIOD, 0x39 },
|
||||
{ KEY_JP_KANA, 0x34 },
|
||||
|
||||
{ KEY_EN_F9, 0x41 },
|
||||
{ KEY_EN_MINUS, 0x42 },
|
||||
{ KEY_EN_P, 0x2A },
|
||||
{ KEY_EN_SEMICOLON, 0x3E },
|
||||
{ KEY_EN_FORWARD_SLASH, 0x3F },
|
||||
{ KEY_EN_RIGHT_FUNCTION, 0x40 },
|
||||
|
||||
{ KEY_EN_F10, 0x47 },
|
||||
{ KEY_JP_CHEVRON, 0x48 },
|
||||
{ KEY_JP_AT, 0x43 },
|
||||
{ KEY_JP_COLON, 0x44 },
|
||||
{ KEY_EN_BACK_SLASH, 0x45 },
|
||||
{ KEY_EN_MENU, 0x46 },
|
||||
|
||||
{ KEY_EN_F11, 0x4D },
|
||||
{ KEY_JP_YEN, 0x4E },
|
||||
{ KEY_EN_LEFT_BRACKET, 0x49 },
|
||||
{ KEY_EN_RIGHT_BRACKET, 0x4A },
|
||||
|
||||
{ KEY_EN_F12, 0x4F },
|
||||
{ KEY_EN_BACKSPACE, 0x50 },
|
||||
{ KEY_EN_ISO_ENTER, 0x52 },
|
||||
{ KEY_EN_RIGHT_SHIFT, 0x4B },
|
||||
{ KEY_EN_RIGHT_CONTROL, 0x4C },
|
||||
|
||||
{ KEY_EN_PRINT_SCREEN, 0x53 },
|
||||
{ KEY_EN_INSERT, 0x54 },
|
||||
{ KEY_EN_DELETE, 0x55 },
|
||||
{ KEY_EN_LEFT_ARROW, 0x56 },
|
||||
|
||||
{ KEY_EN_SCROLL_LOCK, 0x57 },
|
||||
{ KEY_EN_HOME, 0x58 },
|
||||
{ KEY_EN_END, 0x59 },
|
||||
{ KEY_EN_UP_ARROW, 0x5A },
|
||||
{ KEY_EN_DOWN_ARROW, 0x5B },
|
||||
|
||||
{ KEY_EN_PAUSE_BREAK, 0x5C },
|
||||
{ KEY_EN_PAGE_UP, 0x5D },
|
||||
{ KEY_EN_PAGE_DOWN, 0x5E },
|
||||
{ KEY_EN_RIGHT_ARROW, 0x5F },
|
||||
|
||||
{ KEY_EN_NUMPAD_LOCK, 0x60 },
|
||||
{ KEY_EN_NUMPAD_7, 0x61 },
|
||||
{ KEY_EN_NUMPAD_4, 0x62 },
|
||||
{ KEY_EN_NUMPAD_1, 0x6C },
|
||||
{ KEY_EN_NUMPAD_0, 0x64 },
|
||||
|
||||
{ KEY_EN_NUMPAD_DIVIDE, 0x65 },
|
||||
{ KEY_EN_NUMPAD_8, 0x66 },
|
||||
{ KEY_EN_NUMPAD_5, 0x67 },
|
||||
{ KEY_EN_NUMPAD_2, 0x68 },
|
||||
|
||||
{ KEY_EN_NUMPAD_TIMES, 0x69 },
|
||||
{ KEY_EN_NUMPAD_9, 0x6A },
|
||||
{ KEY_EN_NUMPAD_6, 0x6B },
|
||||
{ KEY_EN_NUMPAD_3, 0x63 },
|
||||
{ KEY_EN_NUMPAD_PERIOD, 0x6D },
|
||||
|
||||
{ KEY_EN_NUMPAD_MINUS, 0x6E },
|
||||
{ KEY_EN_NUMPAD_PLUS, 0x6F },
|
||||
{ KEY_EN_NUMPAD_ENTER, 0x71 },
|
||||
|
||||
{ KEY_EN_MEDIA_PREVIOUS, 0x72 },
|
||||
{ KEY_EN_MEDIA_PLAY_PAUSE, 0x73 },
|
||||
{ KEY_EN_MEDIA_NEXT, 0x74 },
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| F-Key Indicators (secondary LEDs) |
|
||||
\*-------------------------------------------------------------*/
|
||||
{ "Key: F1 LED 2", 0x89 },
|
||||
{ "Key: F2 LED 2", 0x7B },
|
||||
{ "Key: F3 LED 2", 0x81 },
|
||||
{ "Key: F4 LED 2", 0x87 },
|
||||
{ "Key: F5 LED 2", 0x8D },
|
||||
{ "Key: F6 LED 2", 0x76 },
|
||||
{ "Key: F7 LED 2", 0x7C },
|
||||
{ "Key: F8 LED 2", 0x82 },
|
||||
{ "Key: F9 LED 2", 0x88 },
|
||||
{ "Key: F10 LED 2", 0x8E },
|
||||
{ "Key: F11 LED 2", 0x7A },
|
||||
{ "Key: F12 LED 2", 0x80 },
|
||||
{ "Key: Print Screen LED 2", 0x86 },
|
||||
{ "Key: Scroll Lock LED 2", 0x8C },
|
||||
{ "Key: Pause/Break LED 2", 0x92 },
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Nav Cluster Indicators (secondary LEDs) |
|
||||
\*-------------------------------------------------------------*/
|
||||
{ "Key: Insert LED 2", 0x75 },
|
||||
{ "Key: Home LED 2", 0x7E },
|
||||
{ "Key: Page Up LED 2", 0x84 },
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Num Lock Indicator (secondary LED) |
|
||||
\*-------------------------------------------------------------*/
|
||||
{ "Key: Num Lock LED 2", 0x8B },
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Nav Cluster Indicators 2 (secondary LEDs) |
|
||||
\*-------------------------------------------------------------*/
|
||||
{ "Key: Delete LED 2", 0x78 },
|
||||
{ "Key: End LED 2", 0x90 },
|
||||
{ "Key: Page Down LED 2", 0x8A },
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Caps Lock Indicator (secondary LED) |
|
||||
\*-------------------------------------------------------------*/
|
||||
{ "Key: Caps Lock LED 2", 0x7D },
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Win Key Indicator (secondary LED) |
|
||||
\*-------------------------------------------------------------*/
|
||||
{ "Key: Left Windows LED 2", 0x83 },
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Palm Rest LEDs (order approximate - needs verification) |
|
||||
\*-------------------------------------------------------------*/
|
||||
{ "Palm Rest LED 1", 0x96 },
|
||||
{ "Palm Rest LED 2", 0xAD },
|
||||
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AkkoKeyboard.cpp |
|
||||
| |
|
||||
| RGBController for Akko Multi-modes keyboards |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_AkkoKeyboard.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Akko 3068B Plus
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :white_check_mark:
|
||||
@direct :x:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectRoyuanAkkoKeyboardControllers
|
||||
@comment
|
||||
Global-color hardware lighting support for Akko/RongYuan keyboards
|
||||
using USB ID 3151:4003 in wired mode.
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_AkkoKeyboard::RGBController_AkkoKeyboard(RoyuanKeyboardController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = "Akko 3068B Plus";
|
||||
vendor = "Akko";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "Akko 3068B Plus lighting controller";
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode off;
|
||||
off.name = "Off";
|
||||
off.value = ROYUAN_AKKO_EFFECT_OFF;
|
||||
off.flags = MODE_FLAG_AUTOMATIC_SAVE;
|
||||
off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(off);
|
||||
|
||||
mode static_mode;
|
||||
static_mode.name = "Static";
|
||||
static_mode.value = ROYUAN_AKKO_EFFECT_STATIC;
|
||||
static_mode.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
static_mode.color_mode = MODE_COLORS_PER_LED;
|
||||
static_mode.brightness_min = ROYUAN_AKKO_BRIGHTNESS_MIN;
|
||||
static_mode.brightness_max = ROYUAN_AKKO_BRIGHTNESS_MAX;
|
||||
static_mode.brightness = ROYUAN_AKKO_BRIGHTNESS_DEFAULT;
|
||||
modes.push_back(static_mode);
|
||||
|
||||
mode breathing;
|
||||
breathing.name = "Breathing";
|
||||
breathing.value = ROYUAN_AKKO_EFFECT_BREATHING;
|
||||
breathing.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
breathing.color_mode = MODE_COLORS_PER_LED;
|
||||
breathing.brightness_min = ROYUAN_AKKO_BRIGHTNESS_MIN;
|
||||
breathing.brightness_max = ROYUAN_AKKO_BRIGHTNESS_MAX;
|
||||
breathing.brightness = ROYUAN_AKKO_BRIGHTNESS_DEFAULT;
|
||||
breathing.speed_min = ROYUAN_AKKO_SPEED_MIN;
|
||||
breathing.speed_max = ROYUAN_AKKO_SPEED_MAX;
|
||||
breathing.speed = ROYUAN_AKKO_SPEED_DEFAULT;
|
||||
modes.push_back(breathing);
|
||||
|
||||
mode wave;
|
||||
wave.name = "Wave";
|
||||
wave.value = ROYUAN_AKKO_EFFECT_WAVE;
|
||||
wave.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
wave.color_mode = MODE_COLORS_PER_LED;
|
||||
wave.brightness_min = ROYUAN_AKKO_BRIGHTNESS_MIN;
|
||||
wave.brightness_max = ROYUAN_AKKO_BRIGHTNESS_MAX;
|
||||
wave.brightness = ROYUAN_AKKO_BRIGHTNESS_DEFAULT;
|
||||
wave.speed_min = ROYUAN_AKKO_SPEED_MIN;
|
||||
wave.speed_max = ROYUAN_AKKO_SPEED_MAX;
|
||||
wave.speed = ROYUAN_AKKO_SPEED_DEFAULT;
|
||||
modes.push_back(wave);
|
||||
|
||||
mode ripple;
|
||||
ripple.name = "Ripple";
|
||||
ripple.value = ROYUAN_AKKO_EFFECT_RIPPLE;
|
||||
ripple.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
ripple.color_mode = MODE_COLORS_PER_LED;
|
||||
ripple.brightness_min = ROYUAN_AKKO_BRIGHTNESS_MIN;
|
||||
ripple.brightness_max = ROYUAN_AKKO_BRIGHTNESS_MAX;
|
||||
ripple.brightness = ROYUAN_AKKO_BRIGHTNESS_DEFAULT;
|
||||
ripple.speed_min = ROYUAN_AKKO_SPEED_MIN;
|
||||
ripple.speed_max = ROYUAN_AKKO_SPEED_MAX;
|
||||
ripple.speed = ROYUAN_AKKO_SPEED_DEFAULT;
|
||||
modes.push_back(ripple);
|
||||
|
||||
mode reactive;
|
||||
reactive.name = "Reactive";
|
||||
reactive.value = ROYUAN_AKKO_EFFECT_REACTIVE;
|
||||
reactive.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
reactive.color_mode = MODE_COLORS_PER_LED;
|
||||
reactive.brightness_min = ROYUAN_AKKO_BRIGHTNESS_MIN;
|
||||
reactive.brightness_max = ROYUAN_AKKO_BRIGHTNESS_MAX;
|
||||
reactive.brightness = ROYUAN_AKKO_BRIGHTNESS_DEFAULT;
|
||||
reactive.speed_min = ROYUAN_AKKO_SPEED_MIN;
|
||||
reactive.speed_max = ROYUAN_AKKO_SPEED_MAX;
|
||||
reactive.speed = ROYUAN_AKKO_SPEED_DEFAULT;
|
||||
modes.push_back(reactive);
|
||||
|
||||
for(unsigned int mode_index = 0; mode_index < modes.size(); mode_index++)
|
||||
{
|
||||
if(modes[mode_index].value == controller->GetMode())
|
||||
{
|
||||
active_mode = mode_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_BRIGHTNESS)
|
||||
{
|
||||
modes[active_mode].brightness = controller->GetBrightness();
|
||||
}
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
modes[active_mode].speed = controller->GetSpeed();
|
||||
}
|
||||
|
||||
SetupZones();
|
||||
colors[0] = ToRGBColor(controller->GetRed(), controller->GetGreen(), controller->GetBlue());
|
||||
}
|
||||
|
||||
RGBController_AkkoKeyboard::~RGBController_AkkoKeyboard()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_AkkoKeyboard::SetupZones()
|
||||
{
|
||||
zone keyboard_zone;
|
||||
keyboard_zone.name = "Keyboard";
|
||||
keyboard_zone.type = ZONE_TYPE_SINGLE;
|
||||
keyboard_zone.leds_min = 1;
|
||||
keyboard_zone.leds_max = 1;
|
||||
keyboard_zone.leds_count = 1;
|
||||
keyboard_zone.matrix_map.Reset();
|
||||
zones.push_back(keyboard_zone);
|
||||
|
||||
led keyboard_led;
|
||||
keyboard_led.name = "Keyboard LEDs";
|
||||
keyboard_led.value = 0x00;
|
||||
leds.push_back(keyboard_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_AkkoKeyboard::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
}
|
||||
|
||||
void RGBController_AkkoKeyboard::DeviceUpdateLEDs()
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[0]);
|
||||
unsigned char grn = RGBGetGValue(colors[0]);
|
||||
unsigned char blu = RGBGetBValue(colors[0]);
|
||||
|
||||
controller->SetColor(red, grn, blu);
|
||||
}
|
||||
|
||||
void RGBController_AkkoKeyboard::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AkkoKeyboard::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AkkoKeyboard::DeviceUpdateMode()
|
||||
{
|
||||
controller->SetMode(
|
||||
modes[active_mode].value,
|
||||
modes[active_mode].speed,
|
||||
modes[active_mode].brightness
|
||||
);
|
||||
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AkkoKeyboard.h |
|
||||
| |
|
||||
| RGBController for Akko Multi-modes keyboards |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "RoyuanKeyboardController.h"
|
||||
|
||||
class RGBController_AkkoKeyboard : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_AkkoKeyboard(RoyuanKeyboardController* controller_ptr);
|
||||
~RGBController_AkkoKeyboard();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
RoyuanKeyboardController* controller;
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user