Compare commits

..
Author SHA1 Message Date
Adam Honse 9e7ec5f429 SDK v6: Implement client and server flags to indicate capabilities and negotiate local client status 2026-01-28 11:27:51 -06:00
Adam Honse 0e3fca55f6 SDK documentation updates 2026-01-25 16:49:20 -06:00
Adam Honse 78130c9b1e Expose LogManager in ResourceManager so that plugins can use it 2026-01-24 22:33:40 -06:00
Adam Honse 5d3f2bdbfe Update NetworkClient to use log manager and use common name constant in server logs 2026-01-24 19:32:15 -06:00
Adam Honse 7adefe8cc6 Use std::string.assign when setting strings in the SDK protocol and description handlers so that string size limit is enforced, then strip out null terminators 2026-01-24 19:32:15 -06:00
Adam Honse 2bdb7b54c0 Add optional HID device hotplug support (requires https://gitlab.com/OpenRGBDevelopers/hidapi-hotplug) 2026-01-24 19:32:15 -06:00
Adam Honse cd7aefed66 SDK v6: Use unique IDs for identifying RGBControllers in SDK protocol 2026-01-24 19:32:15 -06:00
Adam Honse d0b7678dde Rework list handling in ResourceManager by having NetworkClient own its own list rather than sharing ResourceManager's list 2026-01-24 19:32:15 -06:00
Adam Honse 9bb2a4e693 Move HID detector calls to RunHIDDetector/RunHIDWrappedDetector functions and return controller list from detector functions 2026-01-24 19:32:15 -06:00
Adam Honse 1ccaadd5d0 Detection progress SDK integration, NetworkClient callback rework 2026-01-24 19:32:15 -06:00
Adam Honse 06d8ae3cf7 Split out detection system from ResourceManager into DetectionManager
* Split detection system out into its own class, DetectionManager
    * Clean up ResourceManger's many callbacks into just two, one for detection and one general purpose
2026-01-24 19:32:15 -06:00
Adam Honse c6b74e5926 SDK Version 6 Updates
* SDK Protocol
    * Server sends its name to client
    * ProfileManager
      * Rename existing profile commands
      * Add Upload Profile, Download Profile, and Get Active Profile commands
    * SettingsManager
      * Add Get, Set, and Save Settings commands
    * Add zone::active_mode, zone::mode fields for zone-specific modes
    * Add NET_PACKET_ID_RGBCONTROLLER_UPDATEZONEMODE packet for updating zone modes
    * Add segment::matrix_map to segment packet
    * Add NET_PACKET_ID_RGBCONTROLLER_SIGNALUPDATE packet for passing SignalUpdate signal from server to clients
  * NetworkServer
    * Formatting cleanup
    * Use per-controller threads for handling NetworkServer controller-specific packets to avoid delays from controller mutexes
  * NetworkClient
    * Formatting cleanup
  * RGBController
    * Clean up and modularize descriptor functions
2026-01-24 19:32:15 -06:00
Adam Honse 975fc8a031 Rework Profiles to use JSON format
* Update OpenRGB Plugin Interface to include functions for loading/saving profile JSON data into OpenRGB profiles
    * Update ProfileManager to handle auto-load profiles (Exit, Open, Resume, Suspend) and move their settings to ProfileManager section
    * Update ProfileManager to store profiles in "profiles" folder in .json format
    * Update ProfileManager to store size profile in sizes.json
    * Update ProfileManager to perform device UpdateMode/UpdateColors when loading profile
    * Code cleanup of ProfileManager and profile-related code
2026-01-24 19:32:15 -06:00
Adam Honse 5e1685976c RGBController API Overhaul
* Reorganize and clean up RGBController API functions
    * Add functions to get protected RGBController member values
    * Make NetworkClient, ProfileManager, and ResourceManager friend classes so they can access protected members
    * Protected previously-public RGBController members
        * Information strings (name, vendor, description, version, serial location)
        * Device type
        * Active mode
        * Flags
        * LEDs vector
        * LED alternate names vector
        * Modes vector
        * Colors vector
        * Zones vector
    * Add CONTROLLER_FLAG_HIDDEN to allow plugins to hide controllers from control GUI
    * Add update reason codes to RGBController update callback and signal updates on more RGBController events
    * Add loop zone types and segmented zone type
    * Add matrix map field to segments
    * Rework matrix_map_type from using pointers to vector to prevent memory leaks
    * Rework KeyboardLayoutManager to return new matrix_map_type
    * Add access mutex to RGBController API
    * Add per-zone modes ot RGBController API
    * Add JSON description functions to RGBController API
2026-01-24 19:32:13 -06:00
Adam Honse 7783d9fa34 Move plugin SDK integration from callback into plugin API and PluginManager 2026-01-24 19:30:45 -06:00
Adam Honse 15f7e3cb96 Update Plugin API to 5 and SDK Protocol to 6 2026-01-24 19:30:44 -06:00
Adam Honse 40862f052f Update default builds to Qt6
* Update Debian packages to use Qt6
  * Update Fedora packages to use Qt6
  * Update default AppImage builds to use Qt6
  * Update default Windows builds to use Qt6
  * Update default MacOS builds to use Qt6
2026-01-24 19:30:44 -06:00
948 changed files with 30003 additions and 104431 deletions
+16 -4
View File
@@ -536,7 +536,10 @@ before_script:
- macos
stage: build
script:
- ./scripts/build-macos.sh qt6 arm
- eval $(/opt/homebrew/bin/brew shellenv)
- qmake OpenRGB.pro
- make -j16
- macdeployqt OpenRGB.app -codesign=OpenRGB
artifacts:
name: "${CI_PROJECT_NAME}_MacOS_ARM64_${CI_COMMIT_SHORT_SHA}"
@@ -552,7 +555,10 @@ before_script:
- macos
stage: build
script:
- ./scripts/build-macos.sh qt5 arm
- eval $(/opt/homebrew/bin/brew shellenv)
- /opt/homebrew/opt/qt@5/bin/qmake OpenRGB.pro
- make -j16
- /opt/homebrew/opt/qt@5/bin/macdeployqt OpenRGB.app -codesign=OpenRGB
artifacts:
name: "${CI_PROJECT_NAME}_MacOS_Qt5_ARM64_${CI_COMMIT_SHORT_SHA}"
@@ -568,7 +574,10 @@ before_script:
- macos
stage: build
script:
- ./scripts/build-macos.sh qt6 intel
- eval $(/usr/local/bin/brew shellenv)
- arch -x86_64 /usr/local/bin/qmake OpenRGB.pro
- arch -x86_64 make -j16
- arch -x86_64 /usr/local/bin/macdeployqt OpenRGB.app -codesign=OpenRGB
artifacts:
name: "${CI_PROJECT_NAME}_MacOS_Intel_${CI_COMMIT_SHORT_SHA}"
@@ -584,7 +593,10 @@ before_script:
- macos
stage: build
script:
- ./scripts/build-macos.sh qt5 intel
- eval $(/usr/local/bin/brew shellenv)
- arch -x86_64 /usr/local/opt/qt@5/bin/qmake OpenRGB.pro
- arch -x86_64 make -j16
- arch -x86_64 /usr/local/opt/qt@5/bin/macdeployqt OpenRGB.app -codesign=OpenRGB
artifacts:
name: "${CI_PROJECT_NAME}_MacOS_Intel_Qt5_${CI_COMMIT_SHORT_SHA}"
+2 -1
View File
@@ -22,12 +22,13 @@ CODEOWNERS @Calcprogrammer1
/Controllers/BlinkyTapeController/
/Controllers/CoolerMasterController/ @Dr_No
/Controllers/CorsairCommanderCoreController/
/Controllers/CorsairDRAMController/
/Controllers/CorsairDominatorPlatinumController/
/Controllers/CorsairHydroController/
/Controllers/CorsairHydroPlatinumController/
/Controllers/CorsairLightingNodeController/
/Controllers/CorsairPeripheralController/
/Controllers/CorsairVengeanceController/
/Controllers/CorsairVengeanceProController/
/Controllers/CorsairWirelessController/
/Controllers/CreativeController/
/Controllers/CrucialController/
-15
View File
@@ -119,21 +119,6 @@ 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 |
\*-----------------------------------------------------*/
-4
View File
@@ -69,7 +69,3 @@ OpenRGB is written in C++, uses the Qt framework for UI, and uses the QMake buil
Translation files are located in [`OpenRGB/qt/i18n/`](https://gitlab.com/CalcProgrammer1/OpenRGB/-/tree/master/qt/i18n), where languages are formatted using ISO 639-1 format: `OpenRGB_xx_XX.ts` — `xx_XX` representing the language code.
In order to translate a file, you need to [fork](https://gitlab.com/CalcProgrammer1/OpenRGB/-/forks/new) the project, create a new file for your language with `lupdate` (or edit an exisiting one), edit the file with `qtlinguist`, commit, push, and create a merge request.
## AI Guidelines
OpenRGB is an open source project developed by humans for humans. As a general rule, AI generated submissions are not permitted. The licensing behind AI generated code is problematic. If you choose to use AI for assistance in your development process, we can't stop you, but do not credit the AI in commits (no AI authorship/co-authorship). Ultimately, you as a human developer are responsible for the code you submit and it is expected that any code you submit you fully understand and have manually vetted before submission. Merge requests that appear to be straight from an AI output, commits with AI tool authorship or co-authorship tags, or otherwise AI generated submissions are subject to closure.
@@ -0,0 +1,66 @@
/*---------------------------------------------------------*\
| 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);
@@ -1,40 +0,0 @@
/*---------------------------------------------------------*\
| 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);
@@ -173,8 +173,6 @@ RGBController_BloodyB820R::RGBController_BloodyB820R(BloodyB820RController *cont
RGBController_BloodyB820R::~RGBController_BloodyB820R()
{
Shutdown();
delete controller;
}
@@ -1,44 +0,0 @@
/*---------------------------------------------------------*\
| 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);
@@ -89,8 +89,6 @@ RGBController_BloodyMouse::RGBController_BloodyMouse(BloodyMouseController *cont
RGBController_BloodyMouse::~RGBController_BloodyMouse()
{
Shutdown();
delete controller;
}
@@ -44,8 +44,6 @@ RGBController_AMBX::RGBController_AMBX(AMBXController* controller_ptr)
RGBController_AMBX::~RGBController_AMBX()
{
Shutdown();
delete controller;
}
@@ -132,8 +132,6 @@ RGBController_AMDWraithPrism::RGBController_AMDWraithPrism(AMDWraithPrismControl
RGBController_AMDWraithPrism::~RGBController_AMDWraithPrism()
{
Shutdown();
delete controller;
}
@@ -31,7 +31,7 @@ AOCKeyboardController::~AOCKeyboardController()
std::string AOCKeyboardController::GetDeviceLocation()
{
return("HID: " + location);
return("HID " + location);
}
std::string AOCKeyboardController::GetDeviceName()
@@ -257,8 +257,6 @@ RGBController_AOCKeyboard::RGBController_AOCKeyboard(AOCKeyboardController* cont
RGBController_AOCKeyboard::~RGBController_AOCKeyboard()
{
Shutdown();
delete controller;
}
@@ -27,7 +27,7 @@ AOCMouseController::~AOCMouseController()
std::string AOCMouseController::GetDeviceLocation()
{
return("HID: " + location);
return("HID " + location);
}
std::string AOCMouseController::GetDeviceName()
@@ -123,8 +123,6 @@ RGBController_AOCMouse::RGBController_AOCMouse(AOCMouseController* controller_pt
RGBController_AOCMouse::~RGBController_AOCMouse()
{
Shutdown();
delete controller;
}
@@ -27,7 +27,7 @@ AOCMousematController::~AOCMousematController()
std::string AOCMousematController::GetDeviceLocation()
{
return("HID: " + location);
return("HID " + location);
}
std::string AOCMousematController::GetDeviceName()
@@ -113,8 +113,6 @@ RGBController_AOCMousemat::RGBController_AOCMousemat(AOCMousematController* cont
RGBController_AOCMousemat::~RGBController_AOCMousemat()
{
Shutdown();
delete controller;
}
@@ -191,7 +191,7 @@ void PolychromeUSBController::SetDeviceInfo()
WriteRGSwap(rgswap_final[0], rgswap_final[1], rgswap_final[2], rgswap_final[3], rgswap_final[4], rgswap_final[5], rgswap_final[6], rgswap_final[7]);
}
void PolychromeUSBController::SetZoneSize(int zone, int new_size)
void PolychromeUSBController::DeviceResizeZone(int zone, int new_size)
{
unsigned char zonecfg[POLYCHROME_USB_ZONE_MAX_NUM];
@@ -135,7 +135,7 @@ public:
unsigned int configsize
);
void SetZoneSize(int zone, int new_size);
void DeviceResizeZone(int zone, int new_size);
void SetRGSwap(bool reset);
protected:
@@ -185,25 +185,8 @@ RGBController_PolychromeUSB::RGBController_PolychromeUSB(PolychromeUSBController
SetupZones();
}
RGBController_PolychromeUSB::~RGBController_PolychromeUSB()
{
Shutdown();
delete controller;
}
void RGBController_PolychromeUSB::SetupZones()
{
/*-----------------------------------------------------*\
| Only set LED count on the first run |
\*-----------------------------------------------------*/
bool first_run = false;
if(zones.size() == 0)
{
first_run = true;
}
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
@@ -214,62 +197,35 @@ void RGBController_PolychromeUSB::SetupZones()
/*-------------------------------------------------*\
| Set zones and leds |
\*-------------------------------------------------*/
for(std::size_t channel_idx = 0; channel_idx < zones.size(); channel_idx++)
for(unsigned int channel_idx = 0; channel_idx < zones.size(); channel_idx++)
{
PolychromeDeviceInfo device_info = controller->GetPolychromeDevices()[channel_idx];
zones[channel_idx].type = ZONE_TYPE_LINEAR;
if(device_info.device_type== PolychromeDeviceType::ADDRESSABLE)
{
zones[channel_idx].leds_min = 0;
zones[channel_idx].leds_max = ASROCK_ADDRESSABLE_MAX_LEDS;
if(first_run)
{
zones[channel_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;
}
if(!(zones[channel_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_NAME))
{
zones[channel_idx].name = polychrome_USB_zone_names[device_info.zone_type];
}
if(!(zones[channel_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_SIZE))
{
zones[channel_idx].leds_count = device_info.num_leds;
}
if(!(zones[channel_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_TYPE))
{
zones[channel_idx].type = ZONE_TYPE_LINEAR;
}
if(!(zones[channel_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_MATRIX_MAP))
{
zones[channel_idx].matrix_map.width = 0;
zones[channel_idx].matrix_map.height = 0;
zones[channel_idx].matrix_map.map.resize(0);
}
zones[channel_idx].name = polychrome_USB_zone_names[device_info.zone_type];
zones[channel_idx].leds_min = 0;
zones[channel_idx].leds_max = ASROCK_ADDRESSABLE_MAX_LEDS;
zones[channel_idx].leds_count = device_info.num_leds;
}
else if(device_info.device_type==PolychromeDeviceType::FIXED)
{
zones[channel_idx].name = polychrome_USB_zone_names[device_info.zone_type];
zones[channel_idx].type = ZONE_TYPE_LINEAR;
zones[channel_idx].leds_min = device_info.num_leds;
zones[channel_idx].leds_max = device_info.num_leds;
zones[channel_idx].leds_count = device_info.num_leds;
zones[channel_idx].name = polychrome_USB_zone_names[device_info.zone_type];
zones[channel_idx].leds_min = device_info.num_leds;
zones[channel_idx].leds_max = device_info.num_leds;
zones[channel_idx].leds_count = device_info.num_leds;
}
for(unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
{
led new_led;
new_led.name = zones[channel_idx].name;
new_led.name.append(", LED ");
new_led.name.append(std::to_string(led_ch_idx + 1));
new_led.value = (unsigned int)channel_idx;
new_led.value = channel_idx;
leds.push_back(new_led);
}
@@ -315,14 +271,10 @@ void RGBController_PolychromeUSB::SetupZones()
}
}
void RGBController_PolychromeUSB::DeviceConfigureZone(int zone_idx)
void RGBController_PolychromeUSB::DeviceResizeZone(int zone, int new_size)
{
if((size_t)zone_idx < zones.size())
{
controller->SetZoneSize(zones_info[zone_idx].zone, zones[zone_idx].leds_count);
SetupZones();
}
zones[zone].leds_count = (unsigned char) new_size;
controller->DeviceResizeZone(zones_info[zone].zone, new_size);
}
void RGBController_PolychromeUSB::DeviceUpdateLEDs()
@@ -334,14 +286,9 @@ 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;
}
@@ -352,11 +299,6 @@ 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())
@@ -364,7 +306,7 @@ void RGBController_PolychromeUSB::DeviceUpdateZoneLEDs(int zone)
set_mode = active_mode;
}
controller->WriteZone((unsigned char)zone, set_mode, zones_info[zone].speed, zones[zone].colors[0], false);
controller->WriteZone(zone, set_mode, zones_info[zone].speed, zones[zone].colors[0], false);
}
void RGBController_PolychromeUSB::DeviceUpdateSingleLED(int led)
@@ -372,17 +314,12 @@ 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((unsigned char)channel, set_mode, zones_info[channel].speed, zones[channel].colors[0], false);
controller->WriteZone(channel, set_mode, zones_info[channel].speed, zones[channel].colors[0], false);
}
unsigned char RGBController_PolychromeUSB::GetDeviceMode(unsigned char zone)
@@ -19,11 +19,10 @@ class RGBController_PolychromeUSB : public RGBController
{
public:
RGBController_PolychromeUSB(PolychromeUSBController* controller_ptr);
~RGBController_PolychromeUSB();
void SetupZones();
void DeviceConfigureZone(int zone_idx);
void DeviceResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void DeviceUpdateZoneLEDs(int zone);
@@ -36,7 +36,7 @@ ASRockASRRGBSMBusController::~ASRockASRRGBSMBusController()
std::string ASRockASRRGBSMBusController::GetDeviceLocation()
{
std::string return_string(bus->info.device_name);
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
@@ -113,8 +113,6 @@ RGBController_ASRockASRRGBSMBus::RGBController_ASRockASRRGBSMBus(ASRockASRRGBSMB
RGBController_ASRockASRRGBSMBus::~RGBController_ASRockASRRGBSMBus()
{
Shutdown();
delete controller;
}
@@ -161,6 +159,13 @@ void RGBController_ASRockASRRGBSMBus::SetupZones()
SetupColors();
}
void RGBController_ASRockASRRGBSMBus::DeviceResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_ASRockASRRGBSMBus::DeviceUpdateLEDs()
{
for(unsigned int led = 0; led < colors.size(); led++)
@@ -22,6 +22,8 @@ public:
void SetupZones();
void DeviceResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void DeviceUpdateZoneLEDs(int zone);
void DeviceUpdateSingleLED(int led);
@@ -1,199 +0,0 @@
/*---------------------------------------------------------*\
| 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);
}
}
@@ -1,55 +0,0 @@
/*---------------------------------------------------------*\
| 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);
};
@@ -1,46 +0,0 @@
/*---------------------------------------------------------*\
| 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);
@@ -1,127 +0,0 @@
/*---------------------------------------------------------*\
| 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();
}
@@ -1,34 +0,0 @@
/*---------------------------------------------------------*\
| 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;
};
@@ -36,7 +36,7 @@ ASRockPolychromeV1SMBusController::~ASRockPolychromeV1SMBusController()
std::string ASRockPolychromeV1SMBusController::GetDeviceLocation()
{
std::string return_string(bus->info.device_name);
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
@@ -230,8 +230,6 @@ RGBController_ASRockPolychromeV1SMBus::RGBController_ASRockPolychromeV1SMBus(ASR
RGBController_ASRockPolychromeV1SMBus::~RGBController_ASRockPolychromeV1SMBus()
{
Shutdown();
delete controller;
}
@@ -298,9 +296,10 @@ void RGBController_ASRockPolychromeV1SMBus::SetupZones()
SetupColors();
}
void RGBController_ASRockPolychromeV1SMBus::DeviceConfigureZone(int zone_idx)
void RGBController_ASRockPolychromeV1SMBus::DeviceResizeZone(int zone, int new_size)
{
controller-> SetARGBSize(zones[zone_idx].leds_count & 0xFF);
LOG_TRACE("[%s] DeviceResizeZone(%02X, %02X)", name.c_str(), zone, new_size);
controller-> SetARGBSize(new_size & 0xFF);
zones[POLYCHROME_V1_ZONE_ADDRESSABLE].leds_count = 1;
}
@@ -23,7 +23,7 @@ public:
void SetupZones();
void DeviceConfigureZone(int zone_idx);
void DeviceResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void DeviceUpdateZoneLEDs(int zone);
@@ -37,7 +37,7 @@ ASRockPolychromeV2SMBusController::~ASRockPolychromeV2SMBusController()
std::string ASRockPolychromeV2SMBusController::GetDeviceLocation()
{
std::string return_string(bus->info.device_name);
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
@@ -185,8 +185,6 @@ RGBController_ASRockPolychromeV2SMBus::RGBController_ASRockPolychromeV2SMBus(ASR
RGBController_ASRockPolychromeV2SMBus::~RGBController_ASRockPolychromeV2SMBus()
{
Shutdown();
delete controller;
}
@@ -238,6 +236,7 @@ void RGBController_ASRockPolychromeV2SMBus::SetupZones()
}
}
unsigned int led_count = 0;
/*---------------------------------------------------------*\
| Set up LEDs |
\*---------------------------------------------------------*/
@@ -267,6 +266,8 @@ void RGBController_ASRockPolychromeV2SMBus::SetupZones()
\*---------------------------------------------------------*/
leds.push_back(*new_led);
led_count++;
if(zone_idx == POLYCHROME_V2_ZONE_ADDRESSABLE)
{
break;
@@ -278,7 +279,7 @@ void RGBController_ASRockPolychromeV2SMBus::SetupZones()
SetupColors();
}
void RGBController_ASRockPolychromeV2SMBus::DeviceConfigureZone(int /*zone_idx*/)
void RGBController_ASRockPolychromeV2SMBus::DeviceResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
@@ -23,7 +23,7 @@ public:
void SetupZones();
void DeviceConfigureZone(int zone_idx);
void DeviceResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void DeviceUpdateZoneLEDs(int zone);
@@ -85,31 +85,31 @@ uint16_t GetFirmwareVersion(i2c_smbus_interface* bus, uint8_t address)
}
}
DetectedControllers DetectASRockSMBusControllers(std::vector<i2c_smbus_interface*>& buses)
DetectedControllers DetectASRockSMBusControllers(std::vector<i2c_smbus_interface*>& busses)
{
DetectedControllers detected_controllers;
for(unsigned int bus = 0; bus < buses.size(); bus++)
for(unsigned int bus = 0; bus < busses.size(); bus++)
{
IF_MOBO_SMBUS(buses[bus]->info.pci_vendor, buses[bus]->info.pci_device)
IF_MOBO_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
{
if(buses[bus]->info.pci_subsystem_vendor == ASROCK_SUB_VEN)
if(busses[bus]->pci_subsystem_vendor == ASROCK_SUB_VEN)
{
LOG_DEBUG(SMBUS_CHECK_DEVICE_MESSAGE_EN, ASROCK_DETECTOR_NAME, bus, VENDOR_NAME, SMBUS_ADDRESS);
// Check for Polychrome controller at 0x6A
if(TestForPolychromeSMBusController(buses[bus], SMBUS_ADDRESS))
if(TestForPolychromeSMBusController(busses[bus], SMBUS_ADDRESS))
{
LOG_DEBUG("[%s] Detected a device at address 0x%02X, testing for a known controller", ASROCK_DETECTOR_NAME, SMBUS_ADDRESS);
u16_to_u8 version;
version.u16 = GetFirmwareVersion(buses[bus], SMBUS_ADDRESS);
version.u16 = GetFirmwareVersion(busses[bus], SMBUS_ADDRESS);
switch(version.msb)
{
case ASROCK_TYPE_ASRLED:
{
LOG_DEBUG("[%s] Found a ASR RGB LED Controller", ASROCK_DETECTOR_NAME);
ASRockASRRGBSMBusController* controller = new ASRockASRRGBSMBusController(buses[bus], SMBUS_ADDRESS);
ASRockASRRGBSMBusController* controller = new ASRockASRRGBSMBusController(busses[bus], SMBUS_ADDRESS);
controller-> fw_version = version.u16;
RGBController_ASRockASRRGBSMBus* rgb_controller = new RGBController_ASRockASRRGBSMBus(controller);
detected_controllers.push_back(rgb_controller);
@@ -119,7 +119,7 @@ DetectedControllers DetectASRockSMBusControllers(std::vector<i2c_smbus_interface
case ASROCK_TYPE_POLYCHROME_V1:
{
LOG_DEBUG("[%s] Found a Polychrome v1 Controller", ASROCK_DETECTOR_NAME);
ASRockPolychromeV1SMBusController* controller = new ASRockPolychromeV1SMBusController(buses[bus], SMBUS_ADDRESS);
ASRockPolychromeV1SMBusController* controller = new ASRockPolychromeV1SMBusController(busses[bus], SMBUS_ADDRESS);
controller-> fw_version = version.u16;
RGBController_ASRockPolychromeV1SMBus* rgb_controller = new RGBController_ASRockPolychromeV1SMBus(controller);
detected_controllers.push_back(rgb_controller);
@@ -129,7 +129,7 @@ DetectedControllers DetectASRockSMBusControllers(std::vector<i2c_smbus_interface
case ASROCK_TYPE_POLYCHROME_V2:
{
LOG_DEBUG("[%s] Found a Polychrome v2 Controller", ASROCK_DETECTOR_NAME);
ASRockPolychromeV2SMBusController* controller = new ASRockPolychromeV2SMBusController(buses[bus], SMBUS_ADDRESS);
ASRockPolychromeV2SMBusController* controller = new ASRockPolychromeV2SMBusController(busses[bus], SMBUS_ADDRESS);
controller-> fw_version = version.u16;
RGBController_ASRockPolychromeV2SMBus* rgb_controller = new RGBController_ASRockPolychromeV2SMBus(controller);
detected_controllers.push_back(rgb_controller);
@@ -1,50 +0,0 @@
/*---------------------------------------------------------*\
| 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);
@@ -1,80 +0,0 @@
/*---------------------------------------------------------*\
| 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);
}
@@ -1,56 +0,0 @@
/*---------------------------------------------------------*\
| 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;
};
@@ -1,231 +0,0 @@
/*---------------------------------------------------------*\
| 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();
}
@@ -1,33 +0,0 @@
/*---------------------------------------------------------*\
| 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;
};
@@ -1,152 +0,0 @@
/*---------------------------------------------------------*\
| 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();
}
@@ -1,35 +0,0 @@
/*---------------------------------------------------------*\
| 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;
};
@@ -125,13 +125,6 @@ RGBController_Alienware::RGBController_Alienware(AlienwareController* controller
controller->UpdateDim();
}
RGBController_Alienware::~RGBController_Alienware()
{
Shutdown();
delete controller;
}
void RGBController_Alienware::SetupZones()
{
/*-------------------------------------------------*\
@@ -19,7 +19,6 @@ class RGBController_Alienware : public RGBController
{
public:
RGBController_Alienware(AlienwareController* controller_ptr);
~RGBController_Alienware();
void SetupZones();
@@ -278,8 +278,6 @@ RGBController_AlienwareAW410K::RGBController_AlienwareAW410K(AlienwareAW410KCont
RGBController_AlienwareAW410K::~RGBController_AlienwareAW410K()
{
Shutdown();
delete controller;
}
@@ -1,43 +0,0 @@
/*---------------------------------------------------------*\
| 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);
@@ -277,8 +277,6 @@ RGBController_AlienwareAW510K::RGBController_AlienwareAW510K(AlienwareAW510KCont
RGBController_AlienwareAW510K::~RGBController_AlienwareAW510K()
{
Shutdown();
delete controller;
}
@@ -1,7 +1,7 @@
/*---------------------------------------------------------*\
| AlienwareAW410KControllerDetect.cpp |
| AlienwareKeyboardControllerDetect.cpp |
| |
| Detector for Alienware AW410K Keyboard |
| Detector for Alienware Keyboard |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -10,17 +10,38 @@
#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_AW410K_PID 0x1968
#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);
}
DetectedControllers DetectAlienwareAW410KControllers(hid_device_info* info, const std::string& name)
{
@@ -40,4 +61,5 @@ 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);
@@ -46,8 +46,6 @@ RGBController_AlienwareAW3423DWF::RGBController_AlienwareAW3423DWF(AlienwareAW34
RGBController_AlienwareAW3423DWF::~RGBController_AlienwareAW3423DWF()
{
Shutdown();
delete controller;
}
@@ -46,8 +46,6 @@ RGBController_AlienwareMonitor::RGBController_AlienwareMonitor(AlienwareMonitorC
RGBController_AlienwareMonitor::~RGBController_AlienwareMonitor()
{
Shutdown();
delete controller;
}
@@ -144,8 +144,6 @@ RGBController_AnnePro2::RGBController_AnnePro2(AnnePro2Controller* controller_pt
RGBController_AnnePro2::~RGBController_AnnePro2()
{
Shutdown();
delete controller;
}
@@ -21,13 +21,13 @@
DetectedControllers DetectArcticControllers()
{
DetectedControllers detected_controllers;
std::vector<std::string> ports;
std::vector<std::string *> ports;
ports = find_usb_serial_port(CH341_VID, CH341_PID);
for(unsigned int device = 0; device < ports.size(); device++)
{
ArcticController *controller = new ArcticController(ports[device]);
ArcticController *controller = new ArcticController(*ports[device]);
if(controller->IsPresent())
{
@@ -38,6 +38,8 @@ DetectedControllers DetectArcticControllers()
{
delete controller;
}
delete ports[device];
}
return(detected_controllers);
@@ -55,8 +55,6 @@ RGBController_Arctic::RGBController_Arctic(ArcticController* controller_ptr)
RGBController_Arctic::~RGBController_Arctic()
{
Shutdown();
keepalive_thread_run = false;
keepalive_thread.join();
delete controller;
@@ -125,8 +125,6 @@ RGBController_Areson::RGBController_Areson(AresonController* controller_ptr)
RGBController_Areson::~RGBController_Areson()
{
Shutdown();
delete controller;
}
@@ -45,13 +45,6 @@ RGBController_AuraCore::RGBController_AuraCore(AuraCoreController* controller_pt
SetupZones();
}
RGBController_AuraCore::~RGBController_AuraCore()
{
Shutdown();
delete controller;
}
void RGBController_AuraCore::SetupKeyboard()
{
name = "ASUS Aura Keyboard";
@@ -177,6 +170,11 @@ void RGBController_AuraCore::SetupGA15DH()
modes.push_back(Static);
}
RGBController_AuraCore::~RGBController_AuraCore()
{
delete controller;
}
void RGBController_AuraCore::SetupZones()
{
zone auraZone;
@@ -268,8 +268,6 @@ RGBController_AsusAuraCoreLaptop::RGBController_AsusAuraCoreLaptop(AsusAuraCoreL
RGBController_AsusAuraCoreLaptop::~RGBController_AsusAuraCoreLaptop()
{
Shutdown();
delete controller;
}
@@ -32,7 +32,7 @@ std::string AuraGPUController::GetDeviceName()
std::string AuraGPUController::GetDeviceLocation()
{
std::string return_string(bus->info.device_name);
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
@@ -79,7 +79,7 @@ void AuraGPUController::AuraGPURegisterWrite(unsigned char reg, unsigned char va
bool AuraGPUController::SaveOnlyApplies()
{
switch (bus->info.pci_subsystem_device)
switch (bus->pci_subsystem_device)
{
case ASUS_VEGA64_STRIX:
return false;
@@ -21,7 +21,7 @@
bool TestForAsusAuraGPUController(i2c_smbus_interface* bus, unsigned char address)
{
if(bus->info.pci_vendor == AMD_GPU_VEN && !is_amd_gpu_i2c_bus(bus))
if(bus->pci_vendor == AMD_GPU_VEN && !is_amd_gpu_i2c_bus(bus))
{
return false;
}
@@ -124,8 +124,6 @@ RGBController_AuraGPU::RGBController_AuraGPU(AuraGPUController * controller_ptr)
RGBController_AuraGPU::~RGBController_AuraGPU()
{
Shutdown();
delete controller;
}
@@ -112,8 +112,6 @@ RGBController_AuraHeadsetStand::RGBController_AuraHeadsetStand(AuraHeadsetStandC
RGBController_AuraHeadsetStand::~RGBController_AuraHeadsetStand()
{
Shutdown();
delete controller;
}
@@ -380,8 +380,6 @@ RGBController_AuraKeyboard::RGBController_AuraKeyboard(AuraKeyboardController* c
RGBController_AuraKeyboard::~RGBController_AuraKeyboard()
{
Shutdown();
delete controller;
}
@@ -45,8 +45,6 @@ RGBController_AuraMonitor::RGBController_AuraMonitor(AuraMonitorController* cont
RGBController_AuraMonitor::~RGBController_AuraMonitor()
{
Shutdown();
delete controller;
}
@@ -22,7 +22,6 @@
#define AURA_ROG_GLADIUS_II_WIRELESS_1_PID 0x189E
#define AURA_ROG_GLADIUS_II_WIRELESS_2_PID 0x18A0
#define AURA_ROG_GLADIUS_III_PID 0x197B
#define AURA_ROG_GLADIUS_III_CORE_PID 0x1C8D
#define AURA_ROG_GLADIUS_III_WIRELESS_USB_PID 0x197D
#define AURA_ROG_GLADIUS_III_WIRELESS_2_4_PID 0x197F
#define AURA_ROG_GLADIUS_III_WIRELESS_BT_PID 0x1981
@@ -218,20 +217,6 @@ static std::map<int,mouse_type> aura_mouse_devices =
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_WAVE, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_COMET, AURA_MOUSE_MODE_BATTERY }
}
},
{
AURA_ROG_GLADIUS_III_CORE_PID, // ROG Gladius III Core
{
0,
0,
0,
100,
false,
1,
false,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_NONE, AURA_MOUSE_MODE_REACTIVE }
}
},
{
AURA_ROG_GLADIUS_III_WIRELESS_USB_PID, // ROG Gladius III Wireless USB
{
@@ -185,8 +185,6 @@ RGBController_AuraMouse::RGBController_AuraMouse(AuraMouseController* controller
RGBController_AuraMouse::~RGBController_AuraMouse()
{
Shutdown();
delete controller;
}
@@ -116,8 +116,6 @@ RGBController_AsusROGSpatha::RGBController_AsusROGSpatha(AsusAuraMouseGen1Contro
RGBController_AsusROGSpatha::~RGBController_AsusROGSpatha()
{
Shutdown();
delete controller;
}
@@ -79,8 +79,6 @@ RGBController_AsusROGStrixEvolve::RGBController_AsusROGStrixEvolve(AsusAuraMouse
RGBController_AsusROGStrixEvolve::~RGBController_AsusROGStrixEvolve()
{
Shutdown();
delete controller;
}
@@ -182,8 +182,6 @@ RGBController_AuraMousemat::RGBController_AuraMousemat(AuraMousematController* c
RGBController_AuraMousemat::~RGBController_AuraMousemat()
{
Shutdown();
delete controller;
}
@@ -19,10 +19,7 @@ AsusAuraRyuoAIOController::AsusAuraRyuoAIOController(hid_device* dev_handle, con
| Manually adding device info for now |
| TODO: Implement config table accurately |
\*-----------------------------------------------------*/
uint8_t leds = (dev_name.find("Ryujin") != std::string::npos) ? 5 : 12;
device_info.push_back({0x00, 0x00, leds, 0, AuraDeviceType::FIXED});
device_info.push_back({0x00, 0x00, 12, 0, AuraDeviceType::FIXED});
}
AsusAuraRyuoAIOController::~AsusAuraRyuoAIOController()
@@ -128,8 +128,6 @@ RGBController_AsusAuraRyuoAIO::RGBController_AsusAuraRyuoAIO(AsusAuraRyuoAIOCont
RGBController_AsusAuraRyuoAIO::~RGBController_AsusAuraRyuoAIO()
{
Shutdown();
delete controller;
}
@@ -410,8 +410,6 @@ RGBController_AuraTUFKeyboard::RGBController_AuraTUFKeyboard(AuraTUFKeyboardCont
RGBController_AuraTUFKeyboard::~RGBController_AuraTUFKeyboard()
{
Shutdown();
delete controller;
}
@@ -119,8 +119,6 @@ RGBController_AuraUSB::RGBController_AuraUSB(AuraUSBController* controller_ptr)
RGBController_AuraUSB::~RGBController_AuraUSB()
{
Shutdown();
delete controller;
}
@@ -147,68 +145,41 @@ void RGBController_AuraUSB::SetupZones()
| Set zones and leds |
\*-------------------------------------------------*/
int addressableCounter = 1;
for(std::size_t channel_idx = 0; channel_idx < zones.size(); channel_idx++)
for (unsigned int channel_idx = 0; channel_idx < zones.size(); channel_idx++)
{
AuraDeviceInfo device_info = controller->GetAuraDevices()[channel_idx];
zones[channel_idx].type = ZONE_TYPE_LINEAR;
if(device_info.device_type == AuraDeviceType::FIXED)
{
zones[channel_idx].name = "Aura Mainboard";
zones[channel_idx].type = ZONE_TYPE_LINEAR;
zones[channel_idx].leds_min = device_info.num_leds;
zones[channel_idx].leds_max = device_info.num_leds;
zones[channel_idx].leds_count = device_info.num_leds;
zones[channel_idx].name = "Aura Mainboard";
zones[channel_idx].leds_min = device_info.num_leds;
zones[channel_idx].leds_max = device_info.num_leds;
zones[channel_idx].leds_count = device_info.num_leds;
}
else
{
zones[channel_idx].leds_min = 0;
zones[channel_idx].leds_max = AURA_ADDRESSABLE_MAX_LEDS;
zones[channel_idx].name = "Aura Addressable ";
zones[channel_idx].name.append(std::to_string(addressableCounter));
zones[channel_idx].leds_min = 0;
zones[channel_idx].leds_max = AURA_ADDRESSABLE_MAX_LEDS;
addressableCounter++;
if(first_run)
{
zones[channel_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[channel_idx].leds_count = 0;
}
if(!(zones[channel_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_NAME))
{
zones[channel_idx].name = "Addressable RGB Header ";
zones[channel_idx].name.append(std::to_string(addressableCounter));
}
if(!(zones[channel_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_SIZE))
{
zones[channel_idx].leds_count = 0;
}
if(!(zones[channel_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_TYPE))
{
zones[channel_idx].type = ZONE_TYPE_LINEAR;
}
if(!(zones[channel_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_MATRIX_MAP))
{
zones[channel_idx].matrix_map.width = 0;
zones[channel_idx].matrix_map.height = 0;
zones[channel_idx].matrix_map.map.resize(0);
}
addressableCounter++;
}
unsigned int num_mainboard_leds = device_info.num_leds - device_info.num_headers;
for(unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
for (unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
{
unsigned led_idx = led_ch_idx + 1;
led new_led;
new_led.name = zones[channel_idx].name;
if(device_info.device_type == AuraDeviceType::FIXED && led_ch_idx >= num_mainboard_leds)
{
new_led.name.append(", RGB Header ");
@@ -218,10 +189,9 @@ void RGBController_AuraUSB::SetupZones()
{
new_led.name.append(", LED ");
}
new_led.name.append(std::to_string(led_idx));
new_led.value = (unsigned int)channel_idx;
new_led.value = channel_idx;
leds.push_back(new_led);
}
@@ -230,10 +200,17 @@ void RGBController_AuraUSB::SetupZones()
SetupColors();
}
void RGBController_AuraUSB::DeviceConfigureZone(int zone_idx)
void RGBController_AuraUSB::DeviceResizeZone(int zone, int new_size)
{
if((size_t)zone_idx < zones.size())
if((size_t) zone >= zones.size())
{
return;
}
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
{
zones[zone].leds_count = new_size;
SetupZones();
}
}
@@ -24,7 +24,7 @@ public:
void SetupZones();
void DeviceConfigureZone(int zone_idx);
void DeviceResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void DeviceUpdateZoneLEDs(int zone);
@@ -120,7 +120,6 @@
#define AURA_TERMINAL_PID 0x1889
#define ROG_STRIX_LC120_PID 0x879E
#define AURA_RYUO_AIO_PID 0x1887
#define AURA_RYUJIN_AIO_PID 0x18AE
#define ASUS_ROG_ALLY_PID 0x1ABE
#define ASUS_ROG_ALLY_X_PID 0x1B4C
@@ -464,7 +463,6 @@ REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Origin COD",
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Wireless", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_WIRELESS_1_PID, 1, 0xFF13);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Wireless", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_WIRELESS_2_PID, 2, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III Core", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_CORE_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III Wireless USB", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_WIRELESS_USB_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III Wireless 2.4Ghz", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_WIRELESS_2_4_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III Wireless Bluetooth", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_WIRELESS_BT_PID, 0, 0xFF01);
@@ -525,7 +523,6 @@ REGISTER_HID_DETECTOR_PU("ASUS ROG PG32UQ", DetectAs
REGISTER_HID_DETECTOR ("ASUS ROG AURA Terminal", DetectAsusAuraUSBTerminal, AURA_USB_VID, AURA_TERMINAL_PID);
REGISTER_HID_DETECTOR_PU ("ASUS ROG Strix LC", DetectAsusAuraUSBROGStrixLC, AURA_USB_VID, ROG_STRIX_LC120_PID, 0x00FF, 1);
REGISTER_HID_DETECTOR_PU ("ASUS ROG Ryuo AIO", DetectAsusAuraUSBRyuoAIO, AURA_USB_VID, AURA_RYUO_AIO_PID, 0xFF72, 0x00A1);
REGISTER_HID_DETECTOR_PU ("ASUS ROG Ryujin AIO", DetectAsusAuraUSBRyuoAIO, AURA_USB_VID, AURA_RYUJIN_AIO_PID, 0xFF72, 0x00A1);
REGISTER_HID_DETECTOR_I ("ASUS ROG Throne", DetectAsusAuraUSBHeadsetStand, AURA_USB_VID, AURA_ROG_THRONE_PID, 0);
REGISTER_HID_DETECTOR_I ("ASUS ROG Throne QI", DetectAsusAuraUSBHeadsetStand, AURA_USB_VID, AURA_ROG_THRONE_QI_PID, 0);
REGISTER_HID_DETECTOR_I ("ASUS ROG Throne QI GUNDAM", DetectAsusAuraUSBHeadsetStand, AURA_USB_VID, AURA_ROG_THRONE_QI_GUNDAM_PID, 0);
@@ -117,8 +117,6 @@ RGBController_AsusROGAlly::RGBController_AsusROGAlly(ROGAllyController* controll
RGBController_AsusROGAlly::~RGBController_AsusROGAlly()
{
Shutdown();
delete controller;
}
@@ -129,8 +129,6 @@ RGBController_AsusROGStrixLC::RGBController_AsusROGStrixLC(AsusROGStrixLCControl
RGBController_AsusROGStrixLC::~RGBController_AsusROGStrixLC()
{
Shutdown();
delete controller;
}
@@ -283,8 +283,6 @@ RGBController_AsusCerberusKeyboard::RGBController_AsusCerberusKeyboard(AsusCerbe
RGBController_AsusCerberusKeyboard::~RGBController_AsusCerberusKeyboard()
{
Shutdown();
delete controller;
}
@@ -165,8 +165,6 @@ RGBController_AsusSagarisKeyboard::RGBController_AsusSagarisKeyboard(AsusSagaris
RGBController_AsusSagarisKeyboard::~RGBController_AsusSagarisKeyboard()
{
Shutdown();
delete controller;
}
@@ -89,7 +89,7 @@ void AsusMonitorController::SetDirect(std::vector<RGBColor> colors)
usb_buf[0x00] = 0xEC;
usb_buf[0x01] = 0x40;
usb_buf[0x02] = 0x84;
usb_buf[0x04] = (uint8_t)colors.size();
usb_buf[0x04] = colors.size();
for(size_t i = 0; i < colors.size(); i++)
{
@@ -46,8 +46,6 @@ RGBController_AsusMonitor::RGBController_AsusMonitor(AsusMonitorController* cont
RGBController_AsusMonitor::~RGBController_AsusMonitor()
{
Shutdown();
delete controller;
}
@@ -92,13 +92,6 @@ RGBController_AsusTUFLaptopLinux::RGBController_AsusTUFLaptopLinux(AsusTUFLaptop
SetupZones();
}
RGBController_AsusTUFLaptopLinux::~RGBController_AsusTUFLaptopLinux()
{
Shutdown();
delete controller;
}
void RGBController_AsusTUFLaptopLinux::SetupZones()
{
/*---------------------------------------------------------*\
@@ -16,7 +16,6 @@ class RGBController_AsusTUFLaptopLinux : public RGBController
{
public:
RGBController_AsusTUFLaptopLinux(AsusTUFLaptopLinuxController* controller_ptr);
~RGBController_AsusTUFLaptopLinux();
void SetupZones();
@@ -85,8 +85,6 @@ RGBController_AsusTUFLaptopWMI::RGBController_AsusTUFLaptopWMI(AsusTUFLaptopCont
RGBController_AsusTUFLaptopWMI::~RGBController_AsusTUFLaptopWMI()
{
Shutdown();
delete controller;
}
@@ -24,12 +24,12 @@
DetectedControllers DetectBlinkyTapeControllers()
{
DetectedControllers detected_controllers;
std::vector<std::string> device_locations = find_usb_serial_port(BLINKINLABS_VID, BLINKYTAPE_PID);
std::vector<std::string *> device_locations = find_usb_serial_port(BLINKINLABS_VID, BLINKYTAPE_PID);
for(unsigned int device_idx = 0; device_idx < device_locations.size(); device_idx++)
{
BlinkyTapeController* controller = new BlinkyTapeController();
controller->Initialize(device_locations[device_idx]);
controller->Initialize(*device_locations[device_idx]);
RGBController_BlinkyTape* rgb_controller = new RGBController_BlinkyTape(controller);
@@ -44,88 +44,84 @@ RGBController_BlinkyTape::RGBController_BlinkyTape(BlinkyTapeController* control
RGBController_BlinkyTape::~RGBController_BlinkyTape()
{
Shutdown();
delete controller;
}
void RGBController_BlinkyTape::SetupZones()
{
/*-------------------------------------------------*\
| Only set LED count on the first run |
\*-------------------------------------------------*/
bool first_run = false;
if(zones.size() == 0)
{
first_run = true;
}
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
zones.clear();
leds.clear();
colors.clear();
zones.resize(1);
/*-----------------------------------------------------*\
| Set up zones |
\*-----------------------------------------------------*/
zones[0].leds_min = 0;
zones[0].leds_max = 512;
zone led_zone;
led_zone.name = "LED Strip";
led_zone.type = ZONE_TYPE_LINEAR;
led_zone.leds_min = 0;
led_zone.leds_max = 512;
led_zone.leds_count = 0;
zones.push_back(led_zone);
if(first_run)
{
zones[0].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;
}
if(!(zones[0].flags & ZONE_FLAG_MANUALLY_CONFIGURED_NAME))
{
zones[0].name = "Addressable RGB Header";
}
if(!(zones[0].flags & ZONE_FLAG_MANUALLY_CONFIGURED_SIZE))
{
zones[0].leds_count = 0;
}
if(!(zones[0].flags & ZONE_FLAG_MANUALLY_CONFIGURED_TYPE))
{
zones[0].type = ZONE_TYPE_LINEAR;
}
if(!(zones[0].flags & ZONE_FLAG_MANUALLY_CONFIGURED_MATRIX_MAP))
{
zones[0].matrix_map.width = 0;
zones[0].matrix_map.height = 0;
zones[0].matrix_map.map.resize(0);
}
/*-----------------------------------------------------*\
| Set up LEDs |
\*-----------------------------------------------------*/
for(size_t led_idx = leds.size(); led_idx < zones[0].leds_count; led_idx++)
{
led new_led;
new_led.name = zones[0].name + ", LED ";
new_led.name.append(std::to_string(led_idx));
leds.push_back(new_led);
}
SetupColors();
DeviceResizeZone(0, led_zone.leds_count);
}
void RGBController_BlinkyTape::DeviceConfigureZone(int zone_idx)
void RGBController_BlinkyTape::DeviceResizeZone(int zone, int new_size)
{
if((size_t)zone_idx < zones.size())
/*-------------------------------------------------*\
| Explicitly cast these to avoid compiler warnings |
\*-------------------------------------------------*/
const unsigned int zone_u = static_cast<unsigned int>(zone);
const unsigned int new_size_u = static_cast<unsigned int>(new_size);
/*-------------------------------------------------*\
| Check that the zone is in bounds |
\*-------------------------------------------------*/
if((zone_u > zones.size()) || (zone < 0))
{
SetupZones();
return;
}
/*-------------------------------------------------*\
| And that the new size is in bounds |
\*-------------------------------------------------*/
if((new_size_u > zones.at(zone).leds_max) || (new_size_u < zones.at(zone).leds_min))
{
return;
}
/*-------------------------------------------------*\
| And that there's actually a change |
\*-------------------------------------------------*/
if(zones.at(zone).leds_count == new_size_u)
{
return;
}
/*-------------------------------------------------*\
| If the new size is less than the current size, |
| just chop off the end |
\*-------------------------------------------------*/
if(leds.size() > new_size_u)
{
leds.resize(new_size);
}
/*-------------------------------------------------*\
| Otherwise, add new LEDs to the end |
\*-------------------------------------------------*/
if(leds.size() < new_size_u)
{
for(size_t led_idx = leds.size(); led_idx < new_size_u; led_idx++)
{
led new_led;
new_led.name = "LED ";
new_led.name.append(std::to_string(led_idx));
leds.push_back(new_led);
}
}
zones.at(zone).leds_count = new_size;
SetupColors();
}
void RGBController_BlinkyTape::DeviceUpdateLEDs()
@@ -23,7 +23,7 @@ public:
void SetupZones();
void DeviceConfigureZone(int zone_idx);
void DeviceResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void DeviceUpdateZoneLEDs(int zone);
@@ -312,8 +312,6 @@ RGBController_CherryKeyboard::RGBController_CherryKeyboard(CherryKeyboardControl
RGBController_CherryKeyboard::~RGBController_CherryKeyboard()
{
Shutdown();
delete controller;
}
@@ -1,25 +1,21 @@
/*---------------------------------------------------------*\
| ClevoKeyboardController.cpp |
| |
| Driver for Clevo per-key RGB keyboard |
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
| Driver for Clevo laptop per-key RGB keyboard (ITE 8291) |
| Protocol based on tuxedo-drivers ite_8291 module |
| |
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
| Valentin Lobstein (balgogan@protonmail.com) 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"
#include <cstring>
ClevoKeyboardController::ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info, clevo_keyboard_type kb_type)
ClevoKeyboardController::ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info)
{
dev = dev_handle;
type = kb_type;
location = info.path;
version = info.release_number;
}
@@ -29,31 +25,6 @@ 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);
@@ -69,7 +40,10 @@ std::string ClevoKeyboardController::GetSerialString()
return("");
}
return(StringUtils::wstring_to_string(serial_string));
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
std::string ClevoKeyboardController::GetFirmwareVersion()
@@ -79,355 +53,147 @@ std::string ClevoKeyboardController::GetFirmwareVersion()
return(version_string);
}
/*---------------------------------------------------------*\
| ITE 8291: 8-byte feature report, no report ID |
\*---------------------------------------------------------*/
void ClevoKeyboardController::WriteControl8291(unsigned char* data)
void ClevoKeyboardController::WriteControl(unsigned char* data)
{
hid_send_feature_report(dev, data, CLEVO_8291_REPORT_SIZE);
hid_send_feature_report(dev, data, CLEVO_KEYBOARD_REPORT_SIZE);
}
void ClevoKeyboardController::WriteRowData(unsigned char* data)
{
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);
hid_write(dev, data, CLEVO_KEYBOARD_ROW_DATA_SIZE);
}
void ClevoKeyboardController::TurnOff()
{
if(type == CLEVO_KB_ITE829X)
{
SendCommand829x(CLEVO_829X_CMD_BRIGHTNESS);
return;
}
/*---------------------------------------------------------*\
| Turn off: 08 01 00 00 00 00 00 00 |
\*---------------------------------------------------------*/
unsigned char buf[CLEVO_KEYBOARD_REPORT_SIZE];
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);
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
buf[0] = 0x08;
buf[1] = 0x01;
WriteControl(buf);
}
void ClevoKeyboardController::SetMode(unsigned char mode, unsigned char brightness, unsigned char speed, unsigned char behaviour)
{
if(type == CLEVO_KB_ITE829X)
{
SendCommand829x(CLEVO_829X_CMD_BRIGHTNESS, brightness, speed);
return;
}
/*---------------------------------------------------------*\
| Set params: 08 [power] [mode] [speed] [brightness] 08 |
| [behaviour] 00 |
| power: 01=off, 02=on |
\*---------------------------------------------------------*/
unsigned char buf[CLEVO_KEYBOARD_REPORT_SIZE];
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;
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
buf[0] = 0x08;
buf[1] = 0x02; // Power on
buf[2] = mode;
buf[3] = speed;
buf[4] = brightness;
buf[5] = CLEVO_8291_MODE_FLAG;
buf[5] = 0x08;
buf[6] = behaviour;
WriteControl8291(buf);
WriteControl(buf);
}
void ClevoKeyboardController::SetModeColor(unsigned char color_idx, RGBColor color)
void ClevoKeyboardController::SetModeColor(unsigned char color_idx, unsigned char red, unsigned char green, unsigned char blue)
{
if(type == CLEVO_KB_ITE829X)
{
return;
}
/*---------------------------------------------------------*\
| 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];
unsigned char buf[CLEVO_8291_REPORT_SIZE];
memset(buf, 0x00, CLEVO_8291_REPORT_SIZE);
buf[0] = CLEVO_8291_CMD_COLOR;
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
buf[0] = 0x14;
buf[1] = 0x00;
buf[2] = color_idx;
buf[3] = RGBGetRValue(color);
buf[4] = RGBGetGValue(color);
buf[5] = RGBGetBValue(color);
WriteControl8291(buf);
buf[3] = red;
buf[4] = green;
buf[5] = blue;
WriteControl(buf);
}
void ClevoKeyboardController::SetBrightnessSpeed829x(unsigned char brightness, unsigned char speed)
void ClevoKeyboardController::SendColors(unsigned char* color_data, unsigned char brightness)
{
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();
/*---------------------------------------------------------*\
| 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];
/*---------------------------------------------------------*\
| Animation modes: send [CC, 00, mode_id] on mode change |
| Clamp brightness |
\*---------------------------------------------------------*/
struct anim_entry { unsigned char mode; unsigned char anim_id; };
static const anim_entry anim_modes[] =
if(brightness > CLEVO_KEYBOARD_BRIGHTNESS_MAX)
{
{ 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);
brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
}
/*---------------------------------------------------------*\
| Direction-based effects (Wave/Snake) |
| Slot = base + direction_index |
| Custom color: base = 0xA1, Preset: base = 0x71 |
| Set params for per-key mode |
\*---------------------------------------------------------*/
/*---------------------------------------------------------*\
| 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 */
};
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);
}
}
/*---------------------------------------------------------*\
| Breathing/Flashing: random or custom color |
\*---------------------------------------------------------*/
if(mode_value == CLEVO_829X_MODE_BREATH && use_custom_color)
{
SendColorSlot829x(0x0A, CLEVO_829X_COLOR_CUSTOM, colors[0]);
}
if(mode_value == CLEVO_829X_MODE_BREATH && !use_custom_color)
{
SendCommand829x(0x0A);
}
if(mode_value == CLEVO_829X_MODE_BLINK && use_custom_color)
{
SendColorSlot829x(0x0B, CLEVO_829X_COLOR_CUSTOM, colors[0]);
}
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++)
{
SendColorSlot829x(CLEVO_829X_CMD_SCAN_COLOR, CLEVO_829X_COLOR_SLOT_BASE + i, colors[i]);
}
}
/*---------------------------------------------------------*\
| 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
};
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;
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;
WriteControl8291(ctrl_buf);
ctrl_buf[5] = 0x00;
ctrl_buf[6] = 0x00;
for(int row = 0; row < num_rows; row++)
WriteControl(ctrl_buf);
/*---------------------------------------------------------*\
| Send each row |
\*---------------------------------------------------------*/
for(int row = 0; row < CLEVO_KEYBOARD_NUM_ROWS; row++)
{
memset(ctrl_buf, 0x00, CLEVO_8291_REPORT_SIZE);
ctrl_buf[0] = CLEVO_8291_CMD_ROW;
/*-----------------------------------------------------*\
| Announce row data |
\*-----------------------------------------------------*/
memset(ctrl_buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
ctrl_buf[0] = 0x16;
ctrl_buf[1] = 0x00;
ctrl_buf[2] = row;
WriteControl8291(ctrl_buf);
memset(row_buf, 0x00, CLEVO_8291_ROW_DATA_SIZE);
WriteControl(ctrl_buf);
for(int col = 0; col < num_cols; col++)
/*-----------------------------------------------------*\
| Build row data buffer |
| Format: [pad][pad][B0..B20][G0..G20][R0..R20] |
\*-----------------------------------------------------*/
memset(row_buf, 0x00, CLEVO_KEYBOARD_ROW_DATA_SIZE);
for(int col = 0; col < CLEVO_KEYBOARD_NUM_COLS; col++)
{
int idx = (row * num_cols + col) * 3;
int led_idx = (row * CLEVO_KEYBOARD_NUM_COLS) + col;
int color_offset = led_idx * 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];
unsigned char red = color_data[color_offset + 0];
unsigned char green = color_data[color_offset + 1];
unsigned char blue = color_data[color_offset + 2];
/*-------------------------------------------------*\
| 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;
}
WriteRowData(row_buf);
@@ -1,11 +1,9 @@
/*---------------------------------------------------------*\
| ClevoKeyboardController.h |
| |
| Driver for Clevo per-key RGB keyboard |
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
| Driver for Clevo laptop per-key RGB keyboard (ITE 8291) |
| |
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -14,75 +12,27 @@
#pragma once
#include <string>
#include <vector>
#include <hidapi.h>
#include "RGBController.h"
/*---------------------------------------------------------*\
| Device type enumeration |
\*---------------------------------------------------------*/
enum clevo_keyboard_type
{
CLEVO_KB_ITE8291,
CLEVO_KB_ITE829X,
};
/*-----------------------------------------------------*\
| ITE 8291 keyboard defines |
\*-----------------------------------------------------*/
#define CLEVO_KEYBOARD_REPORT_SIZE 8
#define CLEVO_KEYBOARD_ROW_DATA_SIZE 65
/*---------------------------------------------------------*\
| 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
#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 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_SPEED_MIN 0x00
#define CLEVO_KEYBOARD_SPEED_MAX 0x0A
#define CLEVO_KEYBOARD_SPEED_DEFAULT 0x00
#define CLEVO_KEYBOARD_BRIGHTNESS_MAX 0x32
/*---------------------------------------------------------*\
| ITE 8291 modes |
\*---------------------------------------------------------*/
#define CLEVO_KEYBOARD_SPEED_MIN 0x01
#define CLEVO_KEYBOARD_SPEED_MAX 0x0A
/*-----------------------------------------------------*\
| ITE 8291 modes |
\*-----------------------------------------------------*/
enum
{
CLEVO_KEYBOARD_MODE_DIRECT = 0x33,
@@ -97,36 +47,9 @@ enum
CLEVO_KEYBOARD_MODE_SPARK = 0x11,
};
/*---------------------------------------------------------*\
| 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 |
\*---------------------------------------------------------*/
/*-----------------------------------------------------*\
| Wave/reactive behaviour |
\*-----------------------------------------------------*/
enum
{
CLEVO_KEYBOARD_DIRECTION_LEFT = 0x01,
@@ -144,40 +67,23 @@ enum
class ClevoKeyboardController
{
public:
ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info, clevo_keyboard_type kb_type);
ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info);
~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, 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();
void SetModeColor(unsigned char color_idx, unsigned char red, unsigned char green, unsigned char blue);
void SendColors(unsigned char* color_data, unsigned char brightness);
private:
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;
hid_device* dev;
std::string location;
unsigned short version;
void WriteControl8291(unsigned char* data);
void WriteControl(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,18 +1,16 @@
/*---------------------------------------------------------*\
| ClevoKeyboardControllerDetect.cpp |
| |
| Detector for Clevo per-key RGB keyboard |
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
| Detector for Clevo per-key RGB keyboard (ITE 8291) |
| |
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "ClevoKeyboardController.h"
#include "DetectionManager.h"
#include "ClevoKeyboardController.h"
#include "RGBController_ClevoKeyboard.h"
#include "RGBController.h"
#include <hidapi.h>
@@ -24,12 +22,11 @@
/*---------------------------------------------------------*\
| Clevo Keyboard product IDs |
| ITE 8291 and ITE 829x per-key RGB keyboard controllers |
| These are ITE 8291 per-key RGB keyboard controllers |
\*---------------------------------------------------------*/
#define CLEVO_KEYBOARD_PID_8291 0x600B
#define CLEVO_KEYBOARD_PID_829X 0x8910
#define CLEVO_KEYBOARD_PID_600B 0x600B
static DetectedControllers DetectClevoKeyboard(hid_device_info* info, clevo_keyboard_type kb_type)
DetectedControllers DetectClevoKeyboardControllers(hid_device_info* info, const std::string& name)
{
DetectedControllers detected_controllers;
hid_device* dev;
@@ -38,7 +35,7 @@ static DetectedControllers DetectClevoKeyboard(hid_device_info* info, clevo_keyb
if(dev)
{
ClevoKeyboardController* controller = new ClevoKeyboardController(dev, *info, kb_type);
ClevoKeyboardController* controller = new ClevoKeyboardController(dev, *info);
RGBController_ClevoKeyboard* rgb_controller = new RGBController_ClevoKeyboard(controller);
detected_controllers.push_back(rgb_controller);
@@ -47,15 +44,4 @@ static DetectedControllers DetectClevoKeyboard(hid_device_info* info, clevo_keyb
return(detected_controllers);
}
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);
REGISTER_HID_DETECTOR_PU("CLEVO Keyboard", DetectClevoKeyboardControllers, 0x048D, 0x600B, 0xFF03, 0x01);
@@ -1,11 +1,9 @@
/*---------------------------------------------------------*\
| ClevoKeyboardDevices.cpp |
| |
| Device list for Clevo per-key RGB keyboards |
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
| Device list for Clevo per-key RGB keyboards (ITE 8291) |
| |
| Kyle Cascade (kyle@cascade.family) 21 Jan 2026 |
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -114,48 +112,6 @@ 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,
@@ -166,9 +122,10 @@ keyboard_keymap_overlay_values clevo_keyboard_layout
}
},
{
/*---------------------------------------------------------*\
| Edit Keys |
\*---------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------------------------------------------*\
| Edit Keys |
| Zone, Row, Column, Value, Key, Alternate Name, OpCode, |
\*-------------------------------------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------*\
| Remove keys not present on Clevo keyboard |
@@ -1,11 +1,9 @@
/*---------------------------------------------------------*\
| ClevoKeyboardDevices.h |
| |
| Device list for Clevo per-key RGB keyboards |
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
| Device list for Clevo per-key RGB keyboards (ITE 8291) |
| |
| Kyle Cascade (kyle@cascade.family) 21 Jan 2026 |
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -16,8 +14,7 @@
#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,17 +1,14 @@
/*---------------------------------------------------------*\
| RGBController_ClevoKeyboard.cpp |
| |
| RGBController for Clevo per-key RGB keyboard |
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
| RGBController for Clevo per-key RGB keyboard (ITE 8291) |
| |
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
| Valentin Lobstein (balgogan@protonmail.com) 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"
@@ -43,306 +40,152 @@ 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 = controller->GetBrightnessMax();
Direct.brightness = controller->GetBrightnessMax();
Direct.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
Direct.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
/*---------------------------------------------------------*\
| 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 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);
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 Off;
Off.name = "Off";
@@ -356,30 +199,22 @@ RGBController_ClevoKeyboard::RGBController_ClevoKeyboard(ClevoKeyboardController
RGBController_ClevoKeyboard::~RGBController_ClevoKeyboard()
{
Shutdown();
delete controller;
}
void RGBController_ClevoKeyboard::SetupZones()
{
/*---------------------------------------------------------*\
| Select layout based on device type |
| Create keyboard layout using KeyboardLayoutManager |
\*---------------------------------------------------------*/
bool is_829x = (controller->GetType() == CLEVO_KB_ITE829X);
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);
clevo_keyboard_layout.base_size,
clevo_keyboard_layout.key_values);
new_kb.ChangeKeys(layout);
new_kb.ChangeKeys(clevo_keyboard_layout);
/*---------------------------------------------------------*\
| Create keyboard zone from KLM |
| Create a matrix zone for the keyboard |
\*---------------------------------------------------------*/
zone keyboard_zone;
@@ -396,6 +231,9 @@ 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;
@@ -409,48 +247,36 @@ void RGBController_ClevoKeyboard::SetupZones()
SetupColors();
/*---------------------------------------------------------*\
| Build buffer map from LED values to color pointers |
| 829x LED IDs have gaps (stride 32), need larger map |
| Create buffer map to translate OpenRGB LED order to |
| hardware LED order. The hardware expects 126 color values |
| indexed by LED position (0-125). |
\*---------------------------------------------------------*/
null_color = 0x00000000;
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);
buffer_map.resize(CLEVO_KEYBOARD_NUM_LEDS, &null_color);
for(size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
if(leds[led_idx].value < buffer_map.size())
{
buffer_map[leds[led_idx].value] = &colors[led_idx];
}
buffer_map[leds[led_idx].value] = &colors[led_idx];
}
}
void RGBController_ClevoKeyboard::DeviceUpdateLEDs()
{
int num_rows = controller->GetNumRows();
int num_cols = controller->GetNumCols();
bool is_829x = (controller->GetType() == CLEVO_KB_ITE829X);
/*---------------------------------------------------------*\
| 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];
std::vector<unsigned char> color_data(num_rows * num_cols * 3);
for(int row = 0; row < num_rows; row++)
for(int i = 0; i < CLEVO_KEYBOARD_NUM_LEDS; 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]);
}
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]);
}
controller->SendColors(color_data.data(), modes[active_mode].brightness, modes[active_mode].speed);
controller->SendColors(color_data, modes[active_mode].brightness);
}
void RGBController_ClevoKeyboard::DeviceUpdateZoneLEDs(int /*zone*/)
@@ -476,16 +302,6 @@ 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 |
\*---------------------------------------------------------*/
@@ -500,26 +316,41 @@ void RGBController_ClevoKeyboard::DeviceUpdateMode()
\*---------------------------------------------------------*/
unsigned char brightness = modes[active_mode].brightness;
unsigned char speed = modes[active_mode].speed;
unsigned char behaviour = (mode_value == CLEVO_KEYBOARD_MODE_WAVE)
? modes[active_mode].direction + 1
: 0x00;
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;
}
}
/*---------------------------------------------------------*\
| Set mode color if applicable |
\*---------------------------------------------------------*/
if(modes[active_mode].colors.size() > 0)
{
controller->SetModeColor(1, modes[active_mode].colors[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->SetMode(mode_value, brightness, speed, behaviour);
}
void RGBController_ClevoKeyboard::DeviceSaveMode()
{
if(controller->GetType() == CLEVO_KB_ITE829X)
{
DeviceUpdateMode();
controller->SaveToBios829x();
}
}
@@ -1,11 +1,9 @@
/*---------------------------------------------------------*\
| RGBController_ClevoKeyboard.h |
| |
| RGBController for Clevo per-key RGB keyboard |
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
| RGBController for Clevo per-key RGB keyboard (ITE 8291) |
| |
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -20,7 +18,7 @@
class RGBController_ClevoKeyboard : public RGBController
{
public:
explicit RGBController_ClevoKeyboard(ClevoKeyboardController* controller_ptr);
RGBController_ClevoKeyboard(ClevoKeyboardController* controller_ptr);
~RGBController_ClevoKeyboard();
void SetupZones();
@@ -30,7 +28,6 @@ public:
void DeviceUpdateSingleLED(int led);
void DeviceUpdateMode();
void DeviceSaveMode();
private:
ClevoKeyboardController* controller;
@@ -10,9 +10,8 @@
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <cstring>
#include "ClevoLightbarController.h"
#include "StringUtils.h"
#include <cstring>
ClevoLightbarController::ClevoLightbarController(hid_device* dev_handle, const hid_device_info& info)
{
@@ -41,7 +40,10 @@ std::string ClevoLightbarController::GetSerialString()
return("");
}
return(StringUtils::wstring_to_string(serial_string));
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
std::string ClevoLightbarController::GetFirmwareVersion()
@@ -9,8 +9,8 @@
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "ClevoLightbarController.h"
#include "DetectionManager.h"
#include "ClevoLightbarController.h"
#include "RGBController_ClevoLightbar.h"
#include "RGBController.h"
#include <hidapi.h>
@@ -25,7 +25,7 @@
\*---------------------------------------------------------*/
#define CLEVO_LIGHTBAR_PID 0x7001
DetectedControllers DetectClevoLightbarControllers(hid_device_info* info, const std::string& /*name*/)
DetectedControllers DetectClevoLightbarControllers(hid_device_info* info, const std::string& name)
{
DetectedControllers detected_controllers;
hid_device* dev;
@@ -121,8 +121,6 @@ RGBController_ClevoLightbar::RGBController_ClevoLightbar(ClevoLightbarController
RGBController_ClevoLightbar::~RGBController_ClevoLightbar()
{
Shutdown();
delete controller;
}
@@ -26,7 +26,7 @@ ColorfulGPUController::~ColorfulGPUController()
std::string ColorfulGPUController::GetDeviceLocation()
{
std::string return_string(bus->info.device_name);
std::string return_string(bus->device_name);
char addr[5];
snprintf(addr, 5, "0x%02X", dev);
return_string.append(", address ");
@@ -45,8 +45,7 @@ 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
|| this->bus->info.pci_subsystem_device == COLORFUL_IGAME_RTX_4090_NEPTUNE_OCV)
if(this->bus->pci_subsystem_device == COLORFUL_IGAME_RTX_4070_VULCAN_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)
@@ -52,7 +52,7 @@ REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Advanced OC 12G L-V", Detec
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ultra W OC 12G L-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ultra W OC 12G L-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_GA106_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ultra W OC 12G L-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G_2, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Ultra W OC LHR-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Ultra W OC LHR-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Ultra W OC LHR-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G_2, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3070_ADVANCED_OCV, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060TI_ADVANCED_OC, 0x61);
@@ -71,17 +71,8 @@ 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);
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_2, 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, 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 Ti Ultra W OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5070TI_ULTRAW_OC, 0x61);
@@ -44,8 +44,6 @@ RGBController_ColorfulGPU::RGBController_ColorfulGPU(ColorfulGPUController * col
RGBController_ColorfulGPU::~RGBController_ColorfulGPU()
{
Shutdown();
delete controller;
}

Some files were not shown because too many files have changed in this diff Show More