Add support for Wooting devices with firmware v2.12 and above

This commit is contained in:
Diogo Trindade
2025-12-26 05:59:54 +00:00
committed by Adam Honse
parent b6ad5e9223
commit 298d80e056
11 changed files with 960 additions and 487 deletions

View File

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
| |
| RGBController for Wooting keyboard |
| |
| Diogo Trindade (diogotr7) 04 Mar 2021 |
| Diogo Trindade (diogotr7) 25 Dec 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |

View File

@@ -56,28 +56,20 @@ std::string WootingKeyboardController::GetSerial()
return(StringUtils::wstring_to_string(serial_string));
}
uint8_t WootingKeyboardController::GetWootingType()
WOOTING_DEVICE_TYPE WootingKeyboardController::GetWootingType()
{
return wooting_type;
}
void WootingKeyboardController::SendInitialize()
{
wooting_usb_send_feature(WOOTING_COLOR_INIT_COMMAND, 0,0,0,0);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
bool WootingKeyboardController::wooting_usb_send_feature(uint8_t commandId, uint8_t parameter0, uint8_t parameter1, uint8_t parameter2, uint8_t parameter3)
{
/*---------------------------------------------------------*\
| Prevent sending unnecessary data to the Wootings if the |
| index exceedes it's capabilities |
\*---------------------------------------------------------*/
if ((commandId == WOOTING_SINGLE_COLOR_COMMAND && parameter0 > key_code_limit)
|| (commandId == WOOTING_SINGLE_RESET_COMMAND && parameter3 > key_code_limit))
{
/*-----------------------------------------------------*\
| This is not a USB error so let's return true. |
| wooting_rgb_direct_set_key would also behave |
| differently otherwise. |
\*-----------------------------------------------------*/
return true;
}
uint8_t feature_buffer[WOOTING_COMMAND_SIZE] = { 0, 0xD0, 0xDA };
/*---------------------------------------------------------*\

View File

@@ -4,6 +4,7 @@
| Driver for Wooting keyboard |
| |
| Chris M (Dr_No) 09 Jul 2021 |
| Diogo Trindade (diogotr7) 25 Dec 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -17,20 +18,20 @@
#include "LogManager.h"
#define WOOTING_COMMAND_SIZE 8
#define WOOTING_REPORT_SIZE 129
#define WOOTING_RAW_COLORS_REPORT 11
#define WOOTING_SINGLE_COLOR_COMMAND 30
#define WOOTING_SINGLE_RESET_COMMAND 31
#define WOOTING_RESET_ALL_COMMAND 32
#define WOOTING_COLOR_INIT_COMMAND 33
#define WOOTING_ONE_KEY_CODE_LIMIT 95
#define WOOTING_TWO_KEY_CODE_LIMIT 116
#define RGB_RAW_BUFFER_SIZE 96
#define WOOTING_RGB_ROWS 6
#define WOOTING_RGB_COLUMNS 21
#define WOOTING_ONE_RGB_COLUMNS 17
#define WOOTING_TWO_RGB_COLUMNS 21
#define WOOTING_60_RGB_COLUMNS 14
#define WOOTING_3PAD_RGB_COLUMNS 7
/*---------------------------------------------------------*\
| Placeholder for compilation. Redefined by each subclass |
@@ -41,7 +42,9 @@ enum WOOTING_DEVICE_TYPE
{
WOOTING_KB_TKL = 0,
WOOTING_KB_FULL = 1,
WOOTING_80HE = 2
WOOTING_KB_60PER = 2,
WOOTING_KB_3PAD = 3,
WOOTING_KB_80PER = 4,
};
enum RGB_PARTS
@@ -64,21 +67,17 @@ public:
std::string vendor;
std::string description;
std::string location;
uint8_t wooting_type;
uint8_t key_code_limit;
WOOTING_DEVICE_TYPE wooting_type;
std::string GetName();
std::string GetVendor();
std::string GetDescription();
std::string GetLocation();
std::string GetSerial();
uint8_t GetWootingType();
WOOTING_DEVICE_TYPE GetWootingType();
bool wooting_usb_send_feature(uint8_t command, uint8_t param0,
uint8_t param1, uint8_t param2, uint8_t param3);
virtual void SendDirect(RGBColor* colors, uint8_t color_count) = 0;
private:
virtual void SendInitialize() = 0;
virtual bool wooting_usb_send_buffer(RGB_PARTS part_number, uint8_t* rgb_buffer) = 0;
virtual void SendInitialize();
};

View File

@@ -3,7 +3,7 @@
| |
| Detector for Wooting keyboard |
| |
| Diogo Trindade (diogotr7) 04 Mar 2021 |
| Diogo Trindade (diogotr7) 25 Dec 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -11,11 +11,15 @@
#include <hidapi.h>
#include "Detector.h"
#include "WootingOneKeyboardController.h"
#include "WootingTwoKeyboardController.h"
#include "WootingV1KeyboardController.h"
#include "WootingV2KeyboardController.h"
#include "WootingV3KeyboardController.h"
#include "RGBController_WootingKeyboard.h"
#include "LogManager.h"
#define WOOTING_CONFIG_USAGE_PAGE_V2 0x1337
#define WOOTING_CONFIG_USAGE_PAGE_V3 0xFF55
/*-----------------------------------------------------*\
| Wooting vendor ID |
\*-----------------------------------------------------*/
@@ -24,110 +28,159 @@
/*-----------------------------------------------------*\
| Keyboard product IDs |
| Gamepad Mode: X = Xbox | C = Classic | N = None |
\*-----------------------------------------------------*/
#define WOOTING_ONE_OLD_PID 0xFF01
#define WOOTING_TWO_OLD_PID 0xFF02
#define WOOTING_ONE_X_PID 0x1100
#define WOOTING_ONE_C_PID 0x1101
#define WOOTING_ONE_N_PID 0x1102
#define WOOTING_TWO_X_PID 0x1200
#define WOOTING_TWO_C_PID 0x1201
#define WOOTING_TWO_N_PID 0x1202
#define WOOTING_TWO_LE_X_PID 0x1210
#define WOOTING_TWO_LE_C_PID 0x1211
#define WOOTING_TWO_LE_N_PID 0x1212
#define WOOTING_TWO_HE_X_PID 0x1220
#define WOOTING_TWO_HE_C_PID 0x1221
#define WOOTING_TWO_HE_N_PID 0x1222
#define WOOTING_TWO_HE_ARM_X_PID 0x1230
#define WOOTING_TWO_HE_ARM_C_PID 0x1231
#define WOOTING_TWO_HE_ARM_N_PID 0x1232
#define WOOTING_TWO_60_X_PID 0x1300
#define WOOTING_TWO_60_C_PID 0x1301
#define WOOTING_TWO_60_N_PID 0x1302
#define WOOTING_TWO_60_HE_ARM_X_PID 0x1310
#define WOOTING_TWO_60_HE_ARM_C_PID 0x1311
#define WOOTING_TWO_60_HE_ARM_N_PID 0x1312
#define WOOTING_TWO_UWU_RGB_X_PID 0x1510
#define WOOTING_TWO_UWU_RGB_C_PID 0x1511
#define WOOTING_TWO_UWU_RGB_N_PID 0x1512
#define WOOTING_TWO_80HE_PID 0x1400
#define WOOTING_ONE_LEGACY_PID 0xFF01
#define WOOTING_TWO_LEGACY_PID 0xFF02
#define WOOTING_ONE_PID 0x1100
#define WOOTING_TWO_PID 0x1200
#define WOOTING_TWO_LE_PID 0x1210
#define WOOTING_TWO_HE_PID 0x1220
#define WOOTING_TWO_HE_ARM_PID 0x1230
#define WOOTING_60HE_PID 0x1300
#define WOOTING_60HE_ARM_PID 0x1310
#define WOOTING_60HE_PLUS_PID 0x1320
#define WOOTING_60HE_V2_PID 0x1340
#define WOOTING_80HE_PID 0x1400
#define WOOTING_UWU_RGB_PID 0x1510
void DetectWootingOneKeyboardControllers(hid_device_info* info, const std::string& name)
/*-----------------------------------------------------*\
| Product ID helpers |
| XINP: Xbox input emulation enabled |
| DINP: Classic DirectInput emulation enabled |
| NONE: Controller emulation disabled |
\*-----------------------------------------------------*/
#define XINP_PID(pid) (pid | 0x0000)
#define DINP_PID(pid) (pid | 0x0001)
#define NONE_PID(pid) (pid | 0x0002)
void DetectWootingControllers(hid_device_info *info, const std::string &name)
{
static const char* controller_name = "WootingONE";
static const char *controller_name = "Wooting";
LOG_DEBUG("[%s] Interface %i\tPage %04X\tUsage %i\tPath %s", controller_name, info->interface_number, info->usage_page, info->usage, info->path);
hid_device* dev = hid_open_path(info->path);
hid_device *dev = hid_open_path(info->path);
if(dev)
if(!dev)
return;
WOOTING_DEVICE_TYPE wooting_type;
uint16_t pid = info->product_id;
if(pid == WOOTING_ONE_LEGACY_PID)
{
// TODO: 60% Keymap for Wooting Two 60HE
uint8_t wooting_type = (info->product_id == WOOTING_ONE_OLD_PID) ? WOOTING_KB_TKL : WOOTING_KB_FULL;
wooting_type = WOOTING_KB_TKL;
}
else if(pid == WOOTING_TWO_LEGACY_PID)
{
wooting_type = WOOTING_KB_FULL;
}
else
{
//on modern devices, mask out the last nibble to get base PID
switch(pid & 0xFFF0)
{
case WOOTING_ONE_LEGACY_PID:
case WOOTING_ONE_PID:
wooting_type = WOOTING_KB_TKL;
break;
case WOOTING_TWO_LEGACY_PID:
case WOOTING_TWO_PID:
case WOOTING_TWO_LE_PID:
case WOOTING_TWO_HE_PID:
case WOOTING_TWO_HE_ARM_PID:
wooting_type = WOOTING_KB_FULL;
break;
case WOOTING_60HE_PID:
case WOOTING_60HE_ARM_PID:
case WOOTING_60HE_PLUS_PID:
case WOOTING_60HE_V2_PID:
wooting_type = WOOTING_KB_60PER;
break;
case WOOTING_80HE_PID:
wooting_type = WOOTING_KB_80PER;
break;
case WOOTING_UWU_RGB_PID:
wooting_type = WOOTING_KB_3PAD;
break;
default:
//default to largest keyboard if unknown
wooting_type = WOOTING_KB_FULL;
break;
}
}
LOG_DEBUG("[%s] Device type %i opened - creating Controller", controller_name, wooting_type);
WootingOneKeyboardController* controller = new WootingOneKeyboardController(dev, info->path, wooting_type, name);
LOG_INFO("[%s] Detected Wooting device type %i for device at path %s", controller_name, wooting_type, info->path);
//V1 firmware used the ATMEL VID, and uses the V1 controller
if(info->vendor_id == WOOTING_OLD_VID && info->usage_page == WOOTING_CONFIG_USAGE_PAGE_V2)
{
LOG_DEBUG("[%s] Old VID detected - creating V1 Controller", controller_name);
WootingV1KeyboardController *controller = new WootingV1KeyboardController(dev, info->path, wooting_type, name);
LOG_DEBUG("[%s] Controller created - creating RGBController", controller_name);
RGBController_WootingKeyboard* rgb_controller = new RGBController_WootingKeyboard(controller);
RGBController_WootingKeyboard *rgb_controller = new RGBController_WootingKeyboard(controller);
LOG_DEBUG("[%s] Initialization complete - Registering controller\t%s", controller_name, name.c_str());
ResourceManager::get()->RegisterRGBController(rgb_controller);
return;
}
}
void DetectWootingTwoKeyboardControllers(hid_device_info* info, const std::string& name)
{
static const char* controller_name = "WootingTWO";
LOG_DEBUG("[%s] Interface %i\tPage %04X\tUsage %i\tPath %s", controller_name, info->interface_number, info->usage_page, info->usage, info->path);
hid_device* dev = hid_open_path(info->path);
if(dev)
//V2-V2.11 firmware uses the V2 protocol indicated by the V2 usage page
if(info->usage_page == WOOTING_CONFIG_USAGE_PAGE_V2)
{
uint8_t wooting_type;
switch(info->product_id)
{
case WOOTING_TWO_80HE_PID : wooting_type = WOOTING_80HE; break;
default : wooting_type = WOOTING_KB_FULL; break;
}
LOG_DEBUG("[%s] V2 usage page detected - creating V2 Controller", controller_name);
WootingV2KeyboardController *controller = new WootingV2KeyboardController(dev, info->path, wooting_type, name);
LOG_DEBUG("[%s] Device type %i opened - creating Controller", controller_name, wooting_type);
WootingTwoKeyboardController* controller = new WootingTwoKeyboardController(dev, info->path, wooting_type, name);
LOG_DEBUG("[%s] Controller created - creating RGBController", controller_name);
RGBController_WootingKeyboard* rgb_controller = new RGBController_WootingKeyboard(controller);
LOG_DEBUG("[%s] Controller created - creating RGBController", controller_name);
RGBController_WootingKeyboard *rgb_controller = new RGBController_WootingKeyboard(controller);
LOG_DEBUG("[%s] Initialization complete - Registering controller\t%s", controller_name, name.c_str());
ResourceManager::get()->RegisterRGBController(rgb_controller);
return;
}
}
REGISTER_HID_DETECTOR_PU("Wooting One (Legacy)", DetectWootingOneKeyboardControllers, WOOTING_OLD_VID, WOOTING_ONE_OLD_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two (Legacy)", DetectWootingOneKeyboardControllers, WOOTING_OLD_VID, WOOTING_TWO_OLD_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting One (Xbox)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_ONE_X_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting One (Classic)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_ONE_C_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting One (None)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_ONE_N_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two (Xbox)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_X_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two (Classic)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_C_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two (None)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_N_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two LE (Xbox)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_LE_X_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two LE (Classic)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_LE_C_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two LE (None)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_LE_N_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two HE (Xbox)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_HE_X_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two HE (Classic)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_HE_C_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two HE (None)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_HE_N_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two HE (ARM) (Xbox)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_HE_ARM_X_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two HE (ARM) (Classic)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_HE_ARM_C_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two HE (ARM) (None)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_HE_ARM_N_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two 60HE (Xbox)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_60_X_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two 60HE (Classic)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_60_C_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two 60HE (None)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_60_N_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two 60HE (ARM) (Xbox)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_60_HE_ARM_X_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two 60HE (ARM) (Classic)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_60_HE_ARM_C_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two 60HE (ARM) (None)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_60_HE_ARM_N_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two UwU RGB (Xbox)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_UWU_RGB_X_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two UwU RGB (Classic)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_UWU_RGB_C_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two UwU RGB (None)", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_UWU_RGB_N_PID, 0x1337, 1);
REGISTER_HID_DETECTOR_PU("Wooting Two 80HE", DetectWootingTwoKeyboardControllers, WOOTING_NEW_VID, WOOTING_TWO_80HE_PID, 0x1337, 1);
//V2.12+ firmware uses the new report structure indicated by the V3 usage page
if(info->usage_page == WOOTING_CONFIG_USAGE_PAGE_V3)
{
LOG_DEBUG("[%s] V3 usage page detected - creating V3 Controller", controller_name);
WootingV3KeyboardController *controller = new WootingV3KeyboardController(dev, info->path, wooting_type, name);
LOG_DEBUG("[%s] Controller created - creating RGBController", controller_name);
RGBController_WootingKeyboard *rgb_controller = new RGBController_WootingKeyboard(controller);
LOG_DEBUG("[%s] Initialization complete - Registering controller\t%s", controller_name, name.c_str());
ResourceManager::get()->RegisterRGBController(rgb_controller);
return;
}
hid_close(dev);
LOG_TRACE("[%s] No compatible Wooting controller found for device at path %s", controller_name, info->path);
}
/*-----------------------------------------------------*\
| Wooting keyboards use different PIDs based on which |
| gamepad emulation mode is selected. We can use their |
| base PID, and set the last nibble to get the modes. |
\*-----------------------------------------------------*/
#define REGISTER_WOOTING_DETECTOR(name, vid, pid) \
static HIDDeviceDetector detector_wooting_##vid##_##pid##_base(name, DetectWootingControllers, vid, NONE_PID(pid), HID_INTERFACE_ANY, HID_USAGE_PAGE_ANY, HID_USAGE_ANY); \
static HIDDeviceDetector detector_wooting_##vid##_##pid##_xinp(name, DetectWootingControllers, vid, XINP_PID(pid), HID_INTERFACE_ANY, HID_USAGE_PAGE_ANY, HID_USAGE_ANY); \
static HIDDeviceDetector detector_wooting_##vid##_##pid##_dinp(name, DetectWootingControllers, vid, DINP_PID(pid), HID_INTERFACE_ANY, HID_USAGE_PAGE_ANY, HID_USAGE_ANY)
// Legacy devices with V1 firmware
REGISTER_HID_DETECTOR_P("Wooting One (Legacy)", DetectWootingControllers, WOOTING_OLD_VID, WOOTING_ONE_LEGACY_PID, WOOTING_CONFIG_USAGE_PAGE_V2);
REGISTER_HID_DETECTOR_P("Wooting Two (Legacy)", DetectWootingControllers, WOOTING_OLD_VID, WOOTING_TWO_LEGACY_PID, WOOTING_CONFIG_USAGE_PAGE_V2);
// All other devices
REGISTER_WOOTING_DETECTOR("Wooting One", WOOTING_NEW_VID, WOOTING_ONE_PID );
REGISTER_WOOTING_DETECTOR("Wooting Two", WOOTING_NEW_VID, WOOTING_TWO_PID );
REGISTER_WOOTING_DETECTOR("Wooting Two Lekker Edition", WOOTING_NEW_VID, WOOTING_TWO_LE_PID );
REGISTER_WOOTING_DETECTOR("Wooting Two HE", WOOTING_NEW_VID, WOOTING_TWO_HE_PID );
REGISTER_WOOTING_DETECTOR("Wooting Two HE (ARM)", WOOTING_NEW_VID, WOOTING_TWO_HE_ARM_PID);
REGISTER_WOOTING_DETECTOR("Wooting 60HE", WOOTING_NEW_VID, WOOTING_60HE_PID );
REGISTER_WOOTING_DETECTOR("Wooting 60HE (ARM)", WOOTING_NEW_VID, WOOTING_60HE_ARM_PID );
REGISTER_WOOTING_DETECTOR("Wooting 60HE+", WOOTING_NEW_VID, WOOTING_60HE_PLUS_PID );
REGISTER_WOOTING_DETECTOR("Wooting 60HEv2", WOOTING_NEW_VID, WOOTING_60HE_V2_PID );
REGISTER_WOOTING_DETECTOR("Wooting 80HE", WOOTING_NEW_VID, WOOTING_80HE_PID );
REGISTER_WOOTING_DETECTOR("Wooting UwU RGB", WOOTING_NEW_VID, WOOTING_UWU_RGB_PID );

View File

@@ -1,9 +1,9 @@
/*---------------------------------------------------------*\
| WootingOneKeyboardController.cpp |
| WootingV1KeyboardController.cpp |
| |
| Driver for Wooting One keyboard |
| Driver for Wooting keyboards with v1 firmware |
| |
| Diogo Trindade (diogotr7) 04 Mar 2021 |
| Diogo Trindade (diogotr7) 25 Dec 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -11,13 +11,14 @@
#include <cstring>
#include "StringUtils.h"
#include "WootingOneKeyboardController.h"
#include "WootingV1KeyboardController.h"
#undef WOOTING_CONTROLLER_NAME
#define WOOTING_CONTROLLER_NAME "[WootingONE] "
//0xFFFFFFFF indicates an unused entry in matrix
#define NA 0xFFFFFFFF
#define RGB_RAW_BUFFER_SIZE 96
static const unsigned int rgb_led_index[WOOTING_RGB_ROWS][WOOTING_RGB_COLUMNS] =
{
@@ -53,13 +54,13 @@ static uint16_t getCrc16ccitt(const uint8_t* buffer, uint16_t size)
return crc;
}
WootingOneKeyboardController::WootingOneKeyboardController(hid_device* dev_handle, const char *path, uint8_t wooting_type, std::string dev_name)
WootingV1KeyboardController::WootingV1KeyboardController(hid_device* dev_handle, const char *path, WOOTING_DEVICE_TYPE wooting_type, std::string dev_name)
{
dev = dev_handle;
location = path;
name = dev_name;
this->wooting_type = wooting_type;
key_code_limit = (wooting_type == WOOTING_KB_TKL) ? WOOTING_ONE_KEY_CODE_LIMIT : WOOTING_TWO_KEY_CODE_LIMIT;
key_code_limit = WOOTING_TWO_KEY_CODE_LIMIT;
/*---------------------------------------------------------*\
| Get device HID manufacturer and product strings |
@@ -76,12 +77,12 @@ WootingOneKeyboardController::WootingOneKeyboardController(hid_device* dev_handl
SendInitialize();
}
WootingOneKeyboardController::~WootingOneKeyboardController()
WootingV1KeyboardController::~WootingV1KeyboardController()
{
}
void WootingOneKeyboardController::SendDirect(RGBColor* colors, uint8_t colour_count)
void WootingV1KeyboardController::SendDirect(RGBColor* colors, uint8_t colour_count)
{
const uint8_t pwm_mem_map[48] =
{
@@ -97,9 +98,11 @@ void WootingOneKeyboardController::SendDirect(RGBColor* colors, uint8_t colour_c
unsigned char buffer3[RGB_RAW_BUFFER_SIZE] = {0};
unsigned char buffer4[RGB_RAW_BUFFER_SIZE] = {0};
for(std::size_t color_idx = 0; color_idx < colour_count; color_idx++)
for(std::size_t index = 0; index < colour_count; index++)
{
unsigned char led_index = rgb_led_index[color_idx % 6][color_idx / 6];
unsigned char row = index / WOOTING_RGB_COLUMNS;
unsigned char col = index % WOOTING_RGB_COLUMNS;
unsigned char led_index = rgb_led_index[row][col];
if(led_index > key_code_limit)
{
@@ -130,9 +133,9 @@ void WootingOneKeyboardController::SendDirect(RGBColor* colors, uint8_t colour_c
}
unsigned char buffer_index = pwm_mem_map[led_index % 24];
buffer_pointer[buffer_index + 0x00] = RGBGetRValue(colors[color_idx]);
buffer_pointer[buffer_index + 0x10] = RGBGetGValue(colors[color_idx]);
buffer_pointer[buffer_index + 0x20] = RGBGetBValue(colors[color_idx]);
buffer_pointer[buffer_index + 0x00] = RGBGetRValue(colors[index]);
buffer_pointer[buffer_index + 0x10] = RGBGetGValue(colors[index]);
buffer_pointer[buffer_index + 0x20] = RGBGetBValue(colors[index]);
}
wooting_usb_send_buffer(RGB_PARTS::PART0, buffer0);
@@ -145,14 +148,7 @@ void WootingOneKeyboardController::SendDirect(RGBColor* colors, uint8_t colour_c
}
}
void WootingOneKeyboardController::SendInitialize()
{
wooting_usb_send_feature(WOOTING_COLOR_INIT_COMMAND, 0,0,0,0);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
bool WootingOneKeyboardController::wooting_usb_send_buffer(RGB_PARTS part_number, uint8_t* rgb_buffer)
bool WootingV1KeyboardController::wooting_usb_send_buffer(RGB_PARTS part_number, uint8_t* rgb_buffer)
{
unsigned char report_buffer[WOOTING_REPORT_SIZE] = {0};

View File

@@ -1,9 +1,9 @@
/*---------------------------------------------------------*\
| WootingOneKeyboardController.h |
| WootingV1KeyboardController.h |
| |
| Driver for Wooting One keyboard |
| Driver for Wooting keyboards with v1 firmware |
| |
| Diogo Trindade (diogotr7) 04 Mar 2021 |
| Diogo Trindade (diogotr7) 25 Dec 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -13,15 +13,20 @@
#include "WootingKeyboardController.h"
class WootingOneKeyboardController : public WootingKeyboardController
#define WOOTING_REPORT_SIZE 129
#define WOOTING_ONE_KEY_CODE_LIMIT 95
#define WOOTING_TWO_KEY_CODE_LIMIT 116
class WootingV1KeyboardController : public WootingKeyboardController
{
public:
WootingOneKeyboardController(hid_device* dev_handle, const char *path, uint8_t wooting_type, std::string dev_name);
~WootingOneKeyboardController();
WootingV1KeyboardController(hid_device* dev_handle, const char *path, WOOTING_DEVICE_TYPE wooting_type, std::string dev_name);
~WootingV1KeyboardController();
uint8_t key_code_limit;
void SendDirect(RGBColor* colors, uint8_t colour_count);
private:
void SendInitialize();
bool wooting_usb_send_buffer(RGB_PARTS part_number, uint8_t* report_buffer);
};

View File

@@ -1,9 +1,10 @@
/*---------------------------------------------------------*\
| WootingTwoKeyboardController.cpp |
| WootingV2KeyboardController.cpp |
| |
| Driver for Wooting Two keyboard |
| Driver for Wooting keyboards with v2 firmware |
| |
| Chris M (Dr_No) 09 Jul 2021 |
| Diogo Trindade (diogotr7) 25 Dec 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -11,7 +12,7 @@
#include <cstring>
#include "StringUtils.h"
#include "WootingTwoKeyboardController.h"
#include "WootingV2KeyboardController.h"
#define WOOTING_TWO_REPORT_SIZE 257
@@ -26,23 +27,12 @@ typedef uint16_t R5G6B5_color;
#define RGB888ToRGBcolor16(r, g, b) ((R5G6B5_color)((red & 0xF8) << 8 | (green & 0xFC) << 3 | (b & 0xF8) >> 3))
#define RGB32ToRGBcolor16(color32) ((R5G6B5_color)((color32 & 0xF8) << 8 | (color32 & 0xFC00) >> 5 | (color32 & 0xF80000) >> 19))
static unsigned int matrix_to_led_index_map_full[WOOTING_RGB_ROWS * WOOTING_TWO_RGB_COLUMNS] =
{
0, 21, 42, 63, 84, 105, 1, 22, 43, 64, 85, 106, 2, 23, 44, 65, 86, 107, 3, 24, 45,
66, 87, NA, 4, 25, 46, 67, 88, NA, 5, 26, 47, 68, 89, NA, 6, 27, 48, 69, 90, 111,
7, 28, 49, 70, 91, NA, 8, 29, 50, 71, 92, NA, 9, 30, 51, 72, 93, NA, 10, 31, 52,
73, 94, 115, 11, 32, 53, 74, 95, 116, 12, 33, 54, 75, NA, 117, 13, 34, 55, 76, 97, 118,
14, 35, 56, 77, 98, 119, 15, 36, 57, NA, 99, 120, 16, 37, 58, NA, 16, 121, 17, 38, 59,
80, 101, NA, 18, 39, 60, 81, 102, 123, 19, 40, 61, 82, 103, 124, 20, 41, 62, NA, 104, NA
};
WootingTwoKeyboardController::WootingTwoKeyboardController(hid_device* dev_handle, const char *path, uint8_t wooting_type, std::string dev_name)
WootingV2KeyboardController::WootingV2KeyboardController(hid_device* dev_handle, const char *path, WOOTING_DEVICE_TYPE wooting_type, std::string dev_name)
{
dev = dev_handle;
location = path;
name = dev_name;
this->wooting_type = wooting_type;
key_code_limit = (wooting_type == WOOTING_KB_TKL) ? WOOTING_ONE_KEY_CODE_LIMIT : WOOTING_TWO_KEY_CODE_LIMIT;
/*---------------------------------------------------------*\
| Get device HID manufacturer and product strings |
@@ -59,38 +49,24 @@ WootingTwoKeyboardController::WootingTwoKeyboardController(hid_device* dev_handl
SendInitialize();
}
WootingTwoKeyboardController::~WootingTwoKeyboardController()
WootingV2KeyboardController::~WootingV2KeyboardController()
{
}
void WootingTwoKeyboardController::SendDirect(RGBColor* colors, uint8_t color_count)
void WootingV2KeyboardController::SendDirect(RGBColor* colors, uint8_t color_count)
{
uint8_t rgb_buffer[WOOTING_TWO_REPORT_SIZE] = { 0, 0xD0, 0xDA, WOOTING_RAW_COLORS_REPORT};
for(std::size_t index = 0; index < color_count; index++)
{
uint8_t buffer_index = 4 + (matrix_to_led_index_map_full[index] * 2);
size_t buffer_index = 4 + (index * 2);
R5G6B5_color color16 = RGB32ToRGBcolor16(colors[index]);
LOG_TRACE("%sSetting LED %03i @ buffer %03i - RGB32 %08X RGB16 %04X", WOOTING_CONTROLLER_NAME, index, buffer_index, colors[index], color16);
rgb_buffer[buffer_index] = color16 & 0xFF;
rgb_buffer[buffer_index+1] = color16 >> 8;
}
wooting_usb_send_buffer(RGB_PARTS::PART0, rgb_buffer);
}
void WootingTwoKeyboardController::SendInitialize()
{
wooting_usb_send_feature(WOOTING_COLOR_INIT_COMMAND, 0,0,0,0);
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
bool WootingTwoKeyboardController::wooting_usb_send_buffer(RGB_PARTS /*part_number*/, uint8_t* report_buffer)
{
uint16_t report_size = hid_write(dev, report_buffer, WOOTING_TWO_REPORT_SIZE);
uint16_t report_size = hid_write(dev, rgb_buffer, WOOTING_TWO_REPORT_SIZE);
LOG_DEBUG("%sSend buffer returned - %04i expected %04i", WOOTING_CONTROLLER_NAME, report_size, WOOTING_TWO_REPORT_SIZE);
return (report_size == WOOTING_TWO_REPORT_SIZE);
}

View File

@@ -1,9 +1,10 @@
/*---------------------------------------------------------*\
| WootingTwoKeyboardController.h |
| WootingV2KeyboardController.h |
| |
| Driver for Wooting Two keyboard |
| Driver for Wooting keyboards with v2 firmware |
| |
| Chris M (Dr_No) 09 Jul 2021 |
| Diogo Trindade (diogotr7) 25 Dec 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
@@ -13,15 +14,11 @@
#include "WootingKeyboardController.h"
class WootingTwoKeyboardController : public WootingKeyboardController
class WootingV2KeyboardController : public WootingKeyboardController
{
public:
WootingTwoKeyboardController(hid_device* dev_handle, const char *path, uint8_t wooting_type, std::string dev_name);
~WootingTwoKeyboardController();
WootingV2KeyboardController(hid_device* dev_handle, const char *path, WOOTING_DEVICE_TYPE wooting_type, std::string dev_name);
~WootingV2KeyboardController();
void SendDirect(RGBColor* colors, uint8_t colour_count);
private:
void SendInitialize();
bool wooting_usb_send_buffer(RGB_PARTS part_number, uint8_t* report_buffer);
};

View File

@@ -0,0 +1,76 @@
/*---------------------------------------------------------*\
| WootingV3KeyboardController.cpp |
| |
| Driver for Wooting keyboards with v3 firmware |
| |
| Diogo Trindade (diogotr7) 25 Dec 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <cstring>
#include "StringUtils.h"
#include "WootingV3KeyboardController.h"
#define WOOTING_V3_REPORT_SIZE 2046
#undef WOOTING_CONTROLLER_NAME
#define WOOTING_CONTROLLER_NAME "[WootingTWO] "
//Indicates an unused entry in matrix
#define NA 0x7D
//WootingTwo uses a 16bit color space
typedef uint16_t R5G6B5_color;
#define RGB888ToRGBcolor16(r, g, b) ((R5G6B5_color)((red & 0xF8) << 8 | (green & 0xFC) << 3 | (b & 0xF8) >> 3))
#define RGB32ToRGBcolor16(color32) ((R5G6B5_color)((color32 & 0xF8) << 8 | (color32 & 0xFC00) >> 5 | (color32 & 0xF80000) >> 19))
WootingV3KeyboardController::WootingV3KeyboardController(hid_device* dev_handle, const char *path, WOOTING_DEVICE_TYPE wooting_type, std::string dev_name)
{
dev = dev_handle;
location = path;
name = dev_name;
this->wooting_type = wooting_type;
/*---------------------------------------------------------*\
| Get device HID manufacturer and product strings |
\*---------------------------------------------------------*/
const int szTemp = 256;
wchar_t tmpName[szTemp];
hid_get_manufacturer_string(dev, tmpName, szTemp);
vendor = std::string(StringUtils::wstring_to_string(tmpName));
hid_get_product_string(dev, tmpName, szTemp);
description = std::string(StringUtils::wstring_to_string(tmpName));
SendInitialize();
}
WootingV3KeyboardController::~WootingV3KeyboardController()
{
}
void WootingV3KeyboardController::SendDirect(RGBColor* colors, uint8_t color_count)
{
uint8_t rgb_buffer[WOOTING_V3_REPORT_SIZE] = {0};
rgb_buffer[0] = 4;
rgb_buffer[1] = 0xD1;
rgb_buffer[2] = 0xDA;
rgb_buffer[3] = WOOTING_RAW_COLORS_REPORT;
for(std::size_t index = 0; index < color_count; index++)
{
size_t buffer_index = 4 + (index * 2);
R5G6B5_color color16 = RGB32ToRGBcolor16(colors[index]);
rgb_buffer[buffer_index] = color16 & 0xFF;
rgb_buffer[buffer_index+1] = color16 >> 8;
}
uint16_t report_size = hid_write(dev, rgb_buffer, WOOTING_V3_REPORT_SIZE);
LOG_DEBUG("%sSend buffer returned - %04i expected %04i", WOOTING_CONTROLLER_NAME, report_size, WOOTING_V3_REPORT_SIZE);
}

View File

@@ -0,0 +1,23 @@
/*---------------------------------------------------------*\
| WootingV3KeyboardController.h |
| |
| Driver for Wooting keyboards with v3 firmware |
| |
| Diogo Trindade (diogotr7) 25 Dec 2025 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "WootingKeyboardController.h"
class WootingV3KeyboardController : public WootingKeyboardController
{
public:
WootingV3KeyboardController(hid_device* dev_handle, const char *path, WOOTING_DEVICE_TYPE wooting_type, std::string dev_name);
~WootingV3KeyboardController();
void SendDirect(RGBColor* colors, uint8_t colour_count);
};