Publish LumaOps source
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKCommon.h |
|
||||
| |
|
||||
| Common QMK definitions |
|
||||
| |
|
||||
| Adam Honse <calcprogrammer1@gmail.com) 24 Jun 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char x; /* X position in RGB matrix (0-224) */
|
||||
unsigned char y; /* Y position in RGB matrix (0-64) */
|
||||
unsigned char flags; /* LED flags */
|
||||
unsigned char row; /* Row in key matrix */
|
||||
unsigned char col; /* Column in key matrix */
|
||||
bool valid; /* Is this LED valid? */
|
||||
} qmk_rgb_matrix_led_info;
|
||||
@@ -0,0 +1,533 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKKeychronController.cpp |
|
||||
| |
|
||||
| Driver for Keychron QMK-based keyboards |
|
||||
| |
|
||||
| Amadej Kastelic 21 Jun 2026 |
|
||||
| Adam Honse <calcprogrammer1@gmail.com> 22 Jun 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <string.h>
|
||||
#include "hsv.h"
|
||||
#include "QMKKeychronController.h"
|
||||
#include "QMKViaCommands.h"
|
||||
#include "StringUtils.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
QMKKeychronController::QMKKeychronController(hid_device* dev_handle, const char *path)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Initialize controller fields |
|
||||
\*-----------------------------------------------------*/
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
kc_protocol_version = 0;
|
||||
supported_features = 0;
|
||||
via_protocol_version = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read product string |
|
||||
\*-----------------------------------------------------*/
|
||||
wchar_t product_string[256];
|
||||
|
||||
int ret = hid_get_product_string(dev, product_string, 256);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
name = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
name = StringUtils::wstring_to_string(product_string);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read vendor string |
|
||||
\*-----------------------------------------------------*/
|
||||
wchar_t vendor_string[256];
|
||||
|
||||
ret = hid_get_manufacturer_string(dev, vendor_string, 256);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
vendor = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
vendor = StringUtils::wstring_to_string(vendor_string);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read serial string |
|
||||
\*-----------------------------------------------------*/
|
||||
wchar_t serial_string[256];
|
||||
|
||||
ret = hid_get_serial_number_string(dev, serial_string, 256);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
serial = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
serial = StringUtils::wstring_to_string(serial_string);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get VIA protocol version |
|
||||
\*-----------------------------------------------------*/
|
||||
CmdGetViaProtocolVersion(&via_protocol_version);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get Keychron protocol version |
|
||||
\*-----------------------------------------------------*/
|
||||
CmdGetKeychronProtocolVersion(&kc_protocol_version);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get Keychron firmware version |
|
||||
\*-----------------------------------------------------*/
|
||||
kc_firmware_version = CmdGetKeychronFirmwareVersion();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get supported Keychron features |
|
||||
\*-----------------------------------------------------*/
|
||||
CmdGetSupportFeature(&supported_features);
|
||||
|
||||
if(!GetSupported())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get Keychron RGB protocol version |
|
||||
\*-----------------------------------------------------*/
|
||||
CmdGetKeychronRGBProtocolVersion(&kc_rgb_protocol_version);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get count of LEDs |
|
||||
\*-----------------------------------------------------*/
|
||||
CmdGetNumberLEDs(&number_leds);
|
||||
|
||||
led_info.resize(number_leds);
|
||||
keycodes.resize(number_leds);
|
||||
|
||||
for(std::size_t led_idx = 0; led_idx < led_info.size(); led_idx++)
|
||||
{
|
||||
led_info[led_idx].valid = false;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get info and keycode for all LEDs |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned char row = 0; row < 32; row++)
|
||||
{
|
||||
std::vector<unsigned char> row_leds = CmdGetLEDIndexByRow(row);
|
||||
|
||||
for(unsigned char col = 0; col < row_leds.size(); col++)
|
||||
{
|
||||
if(row_leds[col] != 0xFF && row_leds[col] < led_info.size() && led_info[row_leds[col]].valid == false)
|
||||
{
|
||||
led_info[row_leds[col]].valid = true;
|
||||
led_info[row_leds[col]].col = col;
|
||||
led_info[row_leds[col]].row = row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned short led_index = 0; led_index < number_leds; led_index++)
|
||||
{
|
||||
keycodes[led_index] = CmdGetKeycode(0, led_info[led_index].row, led_info[led_index].col);
|
||||
}
|
||||
}
|
||||
|
||||
QMKKeychronController::~QMKKeychronController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string QMKKeychronController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string QMKKeychronController::GetName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string QMKKeychronController::GetSerial()
|
||||
{
|
||||
return(serial);
|
||||
}
|
||||
|
||||
std::string QMKKeychronController::GetVendor()
|
||||
{
|
||||
return(vendor);
|
||||
}
|
||||
|
||||
std::string QMKKeychronController::GetVersion()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Format multi-line version text |
|
||||
\*-----------------------------------------------------*/
|
||||
return("VIA: " + std::to_string(via_protocol_version) + "\r\n" +
|
||||
"Keychron: " + std::to_string(kc_protocol_version) + "\r\n" +
|
||||
"Keychron RGB: " + std::to_string(kc_rgb_protocol_version) + "\r\n" +
|
||||
"Keychron FW: " + kc_firmware_version);
|
||||
}
|
||||
|
||||
bool QMKKeychronController::GetSupported()
|
||||
{
|
||||
return(supported_features & KC_FEATURE_KEYCHRON_RGB);
|
||||
}
|
||||
|
||||
unsigned short QMKKeychronController::GetKeycode(unsigned short led_index)
|
||||
{
|
||||
return(keycodes[led_index]);
|
||||
}
|
||||
|
||||
unsigned short QMKKeychronController::GetLEDCount()
|
||||
{
|
||||
return(number_leds);
|
||||
}
|
||||
|
||||
qmk_rgb_matrix_led_info QMKKeychronController::GetLEDInfo(unsigned short led_index)
|
||||
{
|
||||
return(led_info[led_index]);
|
||||
}
|
||||
|
||||
void QMKKeychronController::SaveMode()
|
||||
{
|
||||
CmdSaveMode();
|
||||
}
|
||||
|
||||
void QMKKeychronController::SendLEDs(unsigned short number_leds, RGBColor* color_data)
|
||||
{
|
||||
unsigned short led_start_index = 0;
|
||||
unsigned char number_packet_leds = 9;
|
||||
|
||||
while(led_start_index < number_leds)
|
||||
{
|
||||
if((number_leds - led_start_index) < 9)
|
||||
{
|
||||
number_packet_leds = (number_leds - led_start_index);
|
||||
}
|
||||
|
||||
CmdSendLEDs(led_start_index, number_packet_leds, &color_data[led_start_index]);
|
||||
|
||||
led_start_index += number_packet_leds;
|
||||
}
|
||||
}
|
||||
|
||||
void QMKKeychronController::SetMode(unsigned short mode, unsigned char speed, unsigned char hue, unsigned char sat, unsigned char val)
|
||||
{
|
||||
if(mode == 0xFFFF)
|
||||
{
|
||||
CmdSetRGBMatrixMode(KEYCHRON_QHE_PER_KEY_RGB_EFFECT);
|
||||
CmdSetPerKeyRGBType(KEYCHRON_PER_KEY_RGB_SOLID);
|
||||
}
|
||||
else
|
||||
{
|
||||
CmdSetRGBMatrixMode((unsigned char)mode);
|
||||
CmdSetColorHS(hue, sat);
|
||||
CmdSetBrightness(val);
|
||||
CmdSetSpeed(speed);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned short QMKKeychronController::CmdGetKeycode
|
||||
(
|
||||
unsigned char layer,
|
||||
unsigned char row,
|
||||
unsigned char col
|
||||
)
|
||||
{
|
||||
unsigned char args[3];
|
||||
unsigned char response[5];
|
||||
unsigned short keycode;
|
||||
|
||||
args[0] = layer;
|
||||
args[1] = row;
|
||||
args[2] = col;
|
||||
|
||||
ViaSendCommand(QMK_VIA_CMD_VIA_DYNAMIC_KEYMAP_GET_KEYCODE, args, sizeof(args), response, sizeof(response));
|
||||
|
||||
keycode = ( response[3] << 8 )| response[4];
|
||||
|
||||
return(keycode);
|
||||
}
|
||||
|
||||
|
||||
std::string QMKKeychronController::CmdGetKeychronFirmwareVersion()
|
||||
{
|
||||
char response[30];
|
||||
|
||||
ViaSendCommand(KC_GET_FIRMWARE_VERSION, NULL, 0, (unsigned char*)response, sizeof(response));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Ensure response null termination |
|
||||
\*-----------------------------------------------------*/
|
||||
response[29] = 0;
|
||||
|
||||
return(std::string(response));
|
||||
}
|
||||
|
||||
void QMKKeychronController::CmdGetKeychronProtocolVersion
|
||||
(
|
||||
unsigned char* kc_protocol_version
|
||||
)
|
||||
{
|
||||
ViaSendCommand(KC_GET_PROTOCOL_VERSION, NULL, 0, (unsigned char*)kc_protocol_version, sizeof(unsigned char));
|
||||
}
|
||||
|
||||
void QMKKeychronController::CmdGetKeychronRGBProtocolVersion(unsigned short* kc_rgb_protocol_version)
|
||||
{
|
||||
ViaSendCommandSub(KC_KEYCHRON_RGB, KEYCHRON_RGB_PROTOCOL_VER, NULL, 0, (unsigned char*)kc_rgb_protocol_version, sizeof(unsigned short));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The RGB protocol version byte order is reversed |
|
||||
\*-----------------------------------------------------*/
|
||||
*kc_rgb_protocol_version = ((*kc_rgb_protocol_version & 0x00FF) << 8) | ((*kc_rgb_protocol_version & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
std::vector<unsigned char> QMKKeychronController::CmdGetLEDIndexByRow(unsigned char row)
|
||||
{
|
||||
unsigned char args[4];
|
||||
unsigned char response[KEYCHRON_QHE_PACKET_SIZE - 2];
|
||||
|
||||
args[0] = row;
|
||||
args[1] = 0xFF;
|
||||
args[2] = 0xFF;
|
||||
args[3] = 0xFF;
|
||||
|
||||
int bytes_read = ViaSendCommandSub(KC_KEYCHRON_RGB, KEYCHRON_RGB_LED_IDX, args, sizeof(args), response, sizeof(response));
|
||||
|
||||
std::vector<unsigned char> result;
|
||||
|
||||
if(bytes_read > 0)
|
||||
{
|
||||
for(int i = 1; i < bytes_read; i++)
|
||||
{
|
||||
result.push_back(response[i] == 0xFF ? -1 : response[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void QMKKeychronController::CmdGetNumberLEDs
|
||||
(
|
||||
unsigned short* number_leds
|
||||
)
|
||||
{
|
||||
ViaSendCommandSub(KC_KEYCHRON_RGB, KEYCHRON_RGB_LED_COUNT, NULL, 0, (unsigned char*)number_leds, sizeof(unsigned short));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The LED count byte order is reversed |
|
||||
\*-----------------------------------------------------*/
|
||||
*number_leds = ((*number_leds & 0x00FF) << 8) | ((*number_leds & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
void QMKKeychronController::CmdGetSupportFeature(unsigned short* supported_features)
|
||||
{
|
||||
ViaSendCommand(KC_GET_SUPPORT_FEATURE, NULL, 0, (unsigned char*)supported_features, sizeof(unsigned short));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The supported features byte order is reversed |
|
||||
\*-----------------------------------------------------*/
|
||||
*supported_features = ((*supported_features & 0x00FF) << 8) | ((*supported_features & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
void QMKKeychronController::CmdGetViaProtocolVersion
|
||||
(
|
||||
unsigned short* via_protocol_version
|
||||
)
|
||||
{
|
||||
ViaSendCommand(QMK_VIA_CMD_GET_PROTOCOL_VERSION, NULL, 0, (unsigned char*)via_protocol_version, sizeof(unsigned short));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The protocol version byte order is reversed |
|
||||
\*-----------------------------------------------------*/
|
||||
*via_protocol_version = ((*via_protocol_version & 0x00FF) << 8) | ((*via_protocol_version & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
void QMKKeychronController::CmdSaveMode()
|
||||
{
|
||||
ViaSendCommandSub(KC_KEYCHRON_RGB, KEYCHRON_RGB_SAVE, NULL, 0, NULL, 0);
|
||||
}
|
||||
|
||||
void QMKKeychronController::CmdSendLEDs(unsigned char start_index, unsigned char number_leds, RGBColor* color_data)
|
||||
{
|
||||
unsigned char args[KEYCHRON_QHE_PACKET_SIZE - 2];
|
||||
|
||||
args[0] = start_index;
|
||||
args[1] = number_leds;
|
||||
|
||||
if(number_leds > 9)
|
||||
{
|
||||
number_leds = 9;
|
||||
}
|
||||
|
||||
for(unsigned char led_index = 0; led_index < number_leds; led_index++)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| VialRGB sends direct packets in HSV for some |
|
||||
| inexplicable reason, so do the RGB to HSV |
|
||||
| conversion before sending |
|
||||
\*-------------------------------------------------*/
|
||||
hsv_t hsv_color;
|
||||
rgb2hsv(color_data[led_index], &hsv_color);
|
||||
|
||||
args[2 + (led_index * 3)] = (unsigned char)((float)hsv_color.hue * (256.0f / 360.0f));
|
||||
args[3 + (led_index * 3)] = hsv_color.saturation;
|
||||
args[4 + (led_index * 3)] = hsv_color.value;
|
||||
}
|
||||
|
||||
ViaSendCommandSub(KC_KEYCHRON_RGB, KEYCHRON_RGB_PER_KEY_SET_COLOR, args, sizeof(args), NULL, 0);
|
||||
}
|
||||
|
||||
void QMKKeychronController::CmdSetBrightness(unsigned char brightness)
|
||||
{
|
||||
unsigned char args[3];
|
||||
|
||||
args[0] = QMK_VIA_RGB_MATRIX_CHANNEL;
|
||||
args[1] = QMK_VIA_RGB_MATRIX_BRIGHTNESS;
|
||||
args[2] = brightness;
|
||||
|
||||
ViaSendCommand(QMK_VIA_CMD_CUSTOM_SET_VALUE, args, sizeof(args), NULL, 0);
|
||||
}
|
||||
|
||||
void QMKKeychronController::CmdSetColorHS(unsigned char h, unsigned char s)
|
||||
{
|
||||
unsigned char args[4];
|
||||
|
||||
args[0] = QMK_VIA_RGB_MATRIX_CHANNEL;
|
||||
args[1] = QMK_VIA_RGB_MATRIX_COLOR;
|
||||
args[2] = h;
|
||||
args[3] = s;
|
||||
|
||||
ViaSendCommand(QMK_VIA_CMD_CUSTOM_SET_VALUE, args, sizeof(args), NULL, 0);
|
||||
}
|
||||
|
||||
void QMKKeychronController::CmdSetPerKeyRGBType(unsigned char type)
|
||||
{
|
||||
unsigned char args[1];
|
||||
|
||||
args[0] = type;
|
||||
|
||||
ViaSendCommandSub(KC_KEYCHRON_RGB, KEYCHRON_RGB_PER_KEY_SET_TYPE, args, sizeof(args), NULL, 0);
|
||||
}
|
||||
|
||||
void QMKKeychronController::CmdSetRGBMatrixMode(unsigned char mode)
|
||||
{
|
||||
unsigned char args[3];
|
||||
|
||||
args[0] = QMK_VIA_RGB_MATRIX_CHANNEL;
|
||||
args[1] = QMK_VIA_RGB_MATRIX_EFFECT;
|
||||
args[2] = mode;
|
||||
|
||||
ViaSendCommand(QMK_VIA_CMD_CUSTOM_SET_VALUE, args, sizeof(args), NULL, 0);
|
||||
}
|
||||
|
||||
void QMKKeychronController::CmdSetSpeed(unsigned char speed)
|
||||
{
|
||||
unsigned char args[3];
|
||||
|
||||
args[0] = QMK_VIA_RGB_MATRIX_CHANNEL;
|
||||
args[1] = QMK_VIA_RGB_MATRIX_EFFECT_SPEED;
|
||||
args[2] = speed;
|
||||
|
||||
ViaSendCommand(QMK_VIA_CMD_CUSTOM_SET_VALUE, args, sizeof(args), NULL, 0);
|
||||
}
|
||||
|
||||
int QMKKeychronController::ViaSendCommand
|
||||
(
|
||||
unsigned char cmd,
|
||||
unsigned char* data_in,
|
||||
unsigned char data_in_size,
|
||||
unsigned char* data_out,
|
||||
unsigned char data_out_size
|
||||
)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Standard VIA command with no sub-command |
|
||||
| |
|
||||
| Byte 0: Command |
|
||||
| Byte 1+: Data |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char usb_buf[KEYCHRON_QHE_PACKET_SIZE + 1];
|
||||
|
||||
memset(usb_buf, 0, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Write command, offsetting by 1 for HID report ID |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[1] = cmd;
|
||||
memcpy(&usb_buf[2], data_in, data_in_size);
|
||||
|
||||
hid_write(dev, usb_buf, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read response |
|
||||
\*-----------------------------------------------------*/
|
||||
int bytes_received = hid_read_timeout(dev, usb_buf, sizeof(usb_buf) - 1, 1000);
|
||||
|
||||
if(usb_buf[0] != cmd)
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
|
||||
memcpy(data_out, &usb_buf[1], data_out_size);
|
||||
|
||||
return(bytes_received - 1);
|
||||
}
|
||||
|
||||
int QMKKeychronController::ViaSendCommandSub
|
||||
(
|
||||
unsigned char cmd,
|
||||
unsigned char subcmd,
|
||||
unsigned char* data_in,
|
||||
unsigned char data_in_size,
|
||||
unsigned char* data_out,
|
||||
unsigned char data_out_size
|
||||
)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Standard VIA command with sub-command |
|
||||
| |
|
||||
| Byte 0: Command |
|
||||
| Byte 1: Sub-Command |
|
||||
| Byte 2+: Data |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char usb_buf[KEYCHRON_QHE_PACKET_SIZE + 1];
|
||||
|
||||
memset(usb_buf, 0, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Write command, offsetting by 1 for HID report ID |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[1] = cmd;
|
||||
usb_buf[2] = subcmd;
|
||||
memcpy(&usb_buf[3], data_in, data_in_size);
|
||||
|
||||
hid_write(dev, usb_buf, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read response |
|
||||
\*-----------------------------------------------------*/
|
||||
int bytes_received = hid_read_timeout(dev, usb_buf, sizeof(usb_buf) - 1, 1000);
|
||||
|
||||
if(usb_buf[0] != cmd || usb_buf[1] != subcmd)
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
|
||||
memcpy(data_out, &usb_buf[2], data_out_size);
|
||||
|
||||
return(bytes_received - 2);
|
||||
}
|
||||
@@ -0,0 +1,448 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKKeychronController.h |
|
||||
| |
|
||||
| Driver for Keychron QMK-based keyboards |
|
||||
| |
|
||||
| Amadej Kastelic 21 Jun 2026 |
|
||||
| Adam Honse <calcprogrammer1@gmail.com> 22 Jun 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "QMKCommon.h"
|
||||
#include "RGBController.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keychron vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define KEYCHRON_VID 0x3434
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define KEYCHRON_C1_PRO_ANSI_RGB_PID 0x0510
|
||||
#define KEYCHRON_C1_PRO_8K_ANSI_PID 0x0521
|
||||
#define KEYCHRON_C1_PRO_8K_ISO_PID 0x051D
|
||||
#define KEYCHRON_C1_PRO_8K_JIS_PID 0x051E
|
||||
#define KEYCHRON_C1_PRO_V2_ANSI_RGB_PID 0x0516
|
||||
#define KEYCHRON_C2_PRO_ANSI_RGB_PID 0x0520
|
||||
#define KEYCHRON_C2_PRO_8K_ANSI_PID 0x0522
|
||||
#define KEYCHRON_C2_PRO_8K_ISO_PID 0x052D
|
||||
#define KEYCHRON_C2_PRO_V2_ANSI_RGB_PID 0x0526
|
||||
#define KEYCHRON_C3_PRO_ANSI_RGB_PID 0x0433
|
||||
#define KEYCHRON_C3_PRO_8K_ANSI_PID 0x0530
|
||||
#define KEYCHRON_C3_PRO_8K_ISO_PID 0x0531
|
||||
#define KEYCHRON_C3_PRO_8K_JIS_PID 0x0532
|
||||
#define KEYCHRON_K0_MAX_PID 0x0A06
|
||||
#define KEYCHRON_K1_MAX_ANSI_RGB_PID 0x0A10
|
||||
#define KEYCHRON_K1_MAX_ISO_RGB_PID 0x0A11
|
||||
#define KEYCHRON_K1_MAX_JIS_RGB_PID 0x0A12
|
||||
#define KEYCHRON_K1_V6_ANSI_RGB_PID 0x0D10
|
||||
#define KEYCHRON_K1_V6_ISO_RGB_PID 0x0D11
|
||||
#define KEYCHRON_K1_V6_JIS_RGB_PID 0x0D12
|
||||
#define KEYCHRON_K2_HE_ANSI_PID 0x0E20
|
||||
#define KEYCHRON_K2_HE_ISO_PID 0x0E21
|
||||
#define KEYCHRON_K2_HE_JIS_PID 0x0E22
|
||||
#define KEYCHRON_K2_MAX_ANSI_RGB_PID 0x0A20
|
||||
#define KEYCHRON_K2_MAX_ISO_RGB_PID 0x0A21
|
||||
#define KEYCHRON_K2_MAX_JIS_RGB_PID 0x0A22
|
||||
#define KEYCHRON_K2_V3_ANSI_RGB_PID 0x0D20
|
||||
#define KEYCHRON_K2_V3_ISO_RGB_PID 0x0D21
|
||||
#define KEYCHRON_K2_V3_JIS_RGB_PID 0x0D22
|
||||
#define KEYCHRON_K3_MAX_ANSI_RGB_PID 0x0A30
|
||||
#define KEYCHRON_K3_MAX_ISO_RGB_PID 0x0A31
|
||||
#define KEYCHRON_K3_MAX_JIS_RGB_PID 0x0A32
|
||||
#define KEYCHRON_K3_V3_ANSI_RGB_PID 0x0D30
|
||||
#define KEYCHRON_K3_V3_ISO_RGB_PID 0x0D31
|
||||
#define KEYCHRON_K3_V3_JIS_RGB_PID 0x0D32
|
||||
#define KEYCHRON_K4_HE_ANSI_PID 0x0E40
|
||||
#define KEYCHRON_K4_HE_ISO_PID 0x0E41
|
||||
#define KEYCHRON_K4_HE_JIS_PID 0x0E42
|
||||
#define KEYCHRON_K4_MAX_ANSI_RGB_PID 0x0A40
|
||||
#define KEYCHRON_K4_MAX_ISO_RGB_PID 0x0A41
|
||||
#define KEYCHRON_K4_MAX_JIS_RGB_PID 0x0A42
|
||||
#define KEYCHRON_K4_V3_ANSI_RGB_PID 0x0D40
|
||||
#define KEYCHRON_K4_V3_ISO_RGB_PID 0x0D41
|
||||
#define KEYCHRON_K4_V3_JIS_RGB_PID 0x0D42
|
||||
#define KEYCHRON_K5_MAX_ANSI_RGB_PID 0x0A50
|
||||
#define KEYCHRON_K5_MAX_ISO_RGB_PID 0x0A51
|
||||
#define KEYCHRON_K5_MAX_JIS_RGB_PID 0x0A52
|
||||
#define KEYCHRON_K5_MAX_JIS_V2_RGB_PID 0x0A58
|
||||
#define KEYCHRON_K5_V2_ANSI_RGB_PID 0x0D50
|
||||
#define KEYCHRON_K5_V2_ISO_RGB_PID 0x0D51
|
||||
#define KEYCHRON_K5_V2_JIS_RGB_PID 0x0D52
|
||||
#define KEYCHRON_K6_HE_ANSI_PID 0x0E60
|
||||
#define KEYCHRON_K7_MAX_ANSI_RGB_PID 0x0A70
|
||||
#define KEYCHRON_K7_MAX_ISO_RGB_PID 0x0A71
|
||||
#define KEYCHRON_K7_MAX_JIS_RGB_PID 0x0A72
|
||||
#define KEYCHRON_K7_MAX_JIS_V2_RGB_PID 0x0A76
|
||||
#define KEYCHRON_K8_HE_ANSI_PID 0x0E80
|
||||
#define KEYCHRON_K8_HE_ISO_PID 0x0E81
|
||||
#define KEYCHRON_K8_HE_JIS_PID 0x0E82
|
||||
#define KEYCHRON_K8_MAX_ANSI_RGB_PID 0x0A80
|
||||
#define KEYCHRON_K8_MAX_ISO_RGB_PID 0x0A81
|
||||
#define KEYCHRON_K8_MAX_JIS_RGB_PID 0x0A82
|
||||
#define KEYCHRON_K8_PRO_ANSI_RGB_PID 0x0280
|
||||
#define KEYCHRON_K8_PRO_ISO_RGB_PID 0x0281
|
||||
#define KEYCHRON_K8_PRO_JIS_RGB_PID 0x0282
|
||||
#define KEYCHRON_K8_V2_ANSI_RGB_PID 0x0D80
|
||||
#define KEYCHRON_K8_V2_ISO_RGB_PID 0x0D81
|
||||
#define KEYCHRON_K8_V2_JIS_RGB_PID 0x0D82
|
||||
#define KEYCHRON_K9_MAX_ANSI_RGB_PID 0x0A90
|
||||
#define KEYCHRON_K10_HE_ANSI_PID 0x0EA0
|
||||
#define KEYCHRON_K10_HE_ISO_PID 0x0EA1
|
||||
#define KEYCHRON_K10_MAX_ANSI_RGB_PID 0x0AA0
|
||||
#define KEYCHRON_K10_MAX_ISO_RGB_PID 0x0AA1
|
||||
#define KEYCHRON_K10_MAX_JIS_RGB_PID 0x0AA2
|
||||
#define KEYCHRON_K10_V2_ANSI_RGB_PID 0x0DA0
|
||||
#define KEYCHRON_K10_V2_ISO_RGB_PID 0x0DA1
|
||||
#define KEYCHRON_K10_V2_JIS_RGB_PID 0x0DA2
|
||||
#define KEYCHRON_K11_MAX_ANSI_ENCODER_RGB_PID 0x0AB3
|
||||
#define KEYCHRON_K11_MAX_ISO_ENCODER_RGB_PID 0x0AB4
|
||||
#define KEYCHRON_K11_MAX_JIS_ENCODER_RGB_PID 0x0AB5
|
||||
#define KEYCHRON_K13_MAX_ANSI_RGB_PID 0x0AD0
|
||||
#define KEYCHRON_K13_MAX_ISO_RGB_PID 0x0AD1
|
||||
#define KEYCHRON_K13_MAX_JIS_RGB_PID 0x0AD2
|
||||
#define KEYCHRON_K15_MAX_ANSI_ENCODER_RGB_PID 0x0AF0
|
||||
#define KEYCHRON_K15_MAX_ISO_ENCODER_RGB_PID 0x0AF1
|
||||
#define KEYCHRON_K17_MAX_ANSI_ENCODER_RGB_PID 0x0A00
|
||||
#define KEYCHRON_K17_MAX_ISO_ENCODER_RGB_PID 0x0A01
|
||||
#define KEYCHRON_K17_MAX_JIS_ENCODER_RGB_PID 0x0A02
|
||||
#define KEYCHRON_Q0_BASE_PID 0x0130
|
||||
#define KEYCHRON_Q0_PLUS_PID 0x0131
|
||||
#define KEYCHRON_Q0_MAX_ENCODER_PID 0x0800
|
||||
#define KEYCHRON_Q1_HE_ANSI_ENCODER_PID 0x0B10
|
||||
#define KEYCHRON_Q1_HE_ISO_ENCODER_PID 0x0B11
|
||||
#define KEYCHRON_Q1_HE_JIS_ENCODER_PID 0x0B12
|
||||
#define KEYCHRON_Q1_MAX_ANSI_ENCODER_PID 0x0810
|
||||
#define KEYCHRON_Q1_MAX_ISO_ENCODER_PID 0x0811
|
||||
#define KEYCHRON_Q1_MAX_JIS_ENCODER_PID 0x0812
|
||||
#define KEYCHRON_Q1_V1_ANSI_PID 0x0100
|
||||
#define KEYCHRON_Q1_V1_ANSI_ENCODER_PID 0x0101
|
||||
#define KEYCHRON_Q1_V1_ISO_PID 0x0102
|
||||
#define KEYCHRON_Q1_V1_ISO_ENCODER_PID 0x0103
|
||||
#define KEYCHRON_Q1_V2_ANSI_PID 0x0106
|
||||
#define KEYCHRON_Q1_V2_ANSI_ENCODER_PID 0x0107
|
||||
#define KEYCHRON_Q1_V2_ISO_PID 0x0108
|
||||
#define KEYCHRON_Q1_V2_ISO_ENCODER_PID 0x0109
|
||||
#define KEYCHRON_Q1_V2_JIS_PID 0x010A
|
||||
#define KEYCHRON_Q1_V2_JIS_ENCODER_PID 0x010B
|
||||
#define KEYCHRON_Q2_ANSI_PID 0x0110
|
||||
#define KEYCHRON_Q2_ANSI_ENCODER_PID 0x0111
|
||||
#define KEYCHRON_Q2_ISO_PID 0x0112
|
||||
#define KEYCHRON_Q2_ISO_ENCODER_PID 0x0113
|
||||
#define KEYCHRON_Q2_JIS_PID 0x0114
|
||||
#define KEYCHRON_Q2_JIS_ENCODER_PID 0x0115
|
||||
#define KEYCHRON_Q2_HE_ANSI_ENCODER_PID 0x0B20
|
||||
#define KEYCHRON_Q2_MAX_ANSI_ENCODER_PID 0x0820
|
||||
#define KEYCHRON_Q2_MAX_ISO_ENCODER_PID 0x0821
|
||||
#define KEYCHRON_Q3_ANSI_PID 0x0120
|
||||
#define KEYCHRON_Q3_ANSI_ENCODER_PID 0x0121
|
||||
#define KEYCHRON_Q3_ISO_PID 0x0122
|
||||
#define KEYCHRON_Q3_ISO_ENCODER_PID 0x0123
|
||||
#define KEYCHRON_Q3_JIS_PID 0x0124
|
||||
#define KEYCHRON_Q3_JIS_ENCODER_PID 0x0125
|
||||
#define KEYCHRON_Q3_HE_ANSI_ENCODER_PID 0x0B30
|
||||
#define KEYCHRON_Q3_HE_ISO_ENCODER_PID 0x0B31
|
||||
#define KEYCHRON_Q3_HE_JIS_ENCODER_PID 0x0B32
|
||||
#define KEYCHRON_Q3_MAX_ANSI_ENCODER_PID 0x0830
|
||||
#define KEYCHRON_Q3_MAX_ISO_ENCODER_PID 0x0831
|
||||
#define KEYCHRON_Q4_ANSI_PID 0x0140
|
||||
#define KEYCHRON_Q4_ISO_PID 0x0142
|
||||
#define KEYCHRON_Q4_HE_ANSI_PID 0x0B40
|
||||
#define KEYCHRON_Q5_ANSI_PID 0x0150
|
||||
#define KEYCHRON_Q5_ANSI_ENCODER_PID 0x0151
|
||||
#define KEYCHRON_Q5_ISO_PID 0x0152
|
||||
#define KEYCHRON_Q5_ISO_ENCODER_PID 0x0153
|
||||
#define KEYCHRON_Q5_HE_ANSI_ENCODER_PID 0x0B50
|
||||
#define KEYCHRON_Q5_HE_ISO_ENCODER_PID 0x0B51
|
||||
#define KEYCHRON_Q5_HE_JIS_ENCODER_PID 0x0B52
|
||||
#define KEYCHRON_Q5_MAX_ANSI_ENCODER_PID 0x0850
|
||||
#define KEYCHRON_Q5_MAX_ISO_ENCODER_PID 0x0851
|
||||
#define KEYCHRON_Q5_MAX_JIS_ENCODER_PID 0x0852
|
||||
#define KEYCHRON_Q6_ANSI_PID 0x0160
|
||||
#define KEYCHRON_Q6_ANSI_ENCODER_PID 0x0161
|
||||
#define KEYCHRON_Q6_ISO_PID 0x0162
|
||||
#define KEYCHRON_Q6_ISO_ENCODER_PID 0x0163
|
||||
#define KEYCHRON_Q6_HE_ANSI_ENCODER_PID 0x0B60
|
||||
#define KEYCHRON_Q6_HE_ISO_ENCODER_PID 0x0B61
|
||||
#define KEYCHRON_Q6_HE_JIS_ENCODER_PID 0x0B62
|
||||
#define KEYCHRON_Q6_MAX_ANSI_ENCODER_PID 0x0860
|
||||
#define KEYCHRON_Q6_MAX_ISO_ENCODER_PID 0x0861
|
||||
#define KEYCHRON_Q7_ANSI_PID 0x0170
|
||||
#define KEYCHRON_Q7_ISO_PID 0x0172
|
||||
#define KEYCHRON_Q8_ANSI_PID 0x0180
|
||||
#define KEYCHRON_Q8_ANSI_ENCODER_PID 0x0181
|
||||
#define KEYCHRON_Q8_ISO_PID 0x0182
|
||||
#define KEYCHRON_Q8_ISO_ENCODER_PID 0x0183
|
||||
#define KEYCHRON_Q8_MAX_ANSI_ENCODER_PID 0x0880
|
||||
#define KEYCHRON_Q9_ANSI_PID 0x0190
|
||||
#define KEYCHRON_Q9_ANSI_ENCODER_PID 0x0191
|
||||
#define KEYCHRON_Q9_ISO_PID 0x0192
|
||||
#define KEYCHRON_Q9_ISO_ENCODER_PID 0x0193
|
||||
#define KEYCHRON_Q9_PLUS_ANSI_ENCODER_PID 0x0194
|
||||
#define KEYCHRON_Q10_ANSI_ENCODER_PID 0x01A1
|
||||
#define KEYCHRON_Q10_ISO_ENCODER_PID 0x01A3
|
||||
#define KEYCHRON_Q10_MAX_ANSI_ENCODER_PID 0x08A0
|
||||
#define KEYCHRON_Q10_MAX_ISO_ENCODER_PID 0x08A1
|
||||
#define KEYCHRON_Q11_ANSI_ENCODER_PID 0x01E0
|
||||
#define KEYCHRON_Q11_ISO_ENCODER_PID 0x01E1
|
||||
#define KEYCHRON_Q12_ANSI_ENCODER_PID 0x01D1
|
||||
#define KEYCHRON_Q12_ISO_ENCODER_PID 0x01D3
|
||||
#define KEYCHRON_Q12_HE_ANSI_ENCODER_PID 0x0BC0
|
||||
#define KEYCHRON_Q12_HE_ISO_ENCODER_PID 0x0BC1
|
||||
#define KEYCHRON_Q12_MAX_ANSI_ENCODER_PID 0x08C3
|
||||
#define KEYCHRON_Q12_MAX_ISO_ENCODER_PID 0x08C4
|
||||
#define KEYCHRON_Q13_MAX_ANSI_ENCODER_PID 0x08D0
|
||||
#define KEYCHRON_Q13_MAX_JIS_ENCODER_PID 0x08D2
|
||||
#define KEYCHRON_Q14_MAX_ANSI_ENCODER_PID 0x08E0
|
||||
#define KEYCHRON_Q15_MAX_ANSI_ENCODER_PID 0x08F0
|
||||
#define KEYCHRON_Q60_MAX_ANSI_PID 0x08C0
|
||||
#define KEYCHRON_Q65_MAX_ANSI_ENCODER_PID 0x08B0
|
||||
#define KEYCHRON_S1_ANSI_RGB_PID 0x0410
|
||||
#define KEYCHRON_V1_ABNT2_ENCODER_PID 0x0317
|
||||
#define KEYCHRON_V1_ANSI_PID 0x0310
|
||||
#define KEYCHRON_V1_ANSI_ENCODER_PID 0x0311
|
||||
#define KEYCHRON_V1_ISO_PID 0x0312
|
||||
#define KEYCHRON_V1_ISO_ENCODER_PID 0x0313
|
||||
#define KEYCHRON_V1_JIS_PID 0x0314
|
||||
#define KEYCHRON_V1_JIS_ENCODER_PID 0x0315
|
||||
#define KEYCHRON_V1_8K_ANSI_ENCODER_PID 0x0F10
|
||||
#define KEYCHRON_V1_MAX_ANSI_ENCODER_PID 0x0913
|
||||
#define KEYCHRON_V1_MAX_ISO_ENCODER_PID 0x0914
|
||||
#define KEYCHRON_V1_MAX_JIS_ENCODER_PID 0x0915
|
||||
#define KEYCHRON_V2_ABNT2_ENCODER_PID 0x0327
|
||||
#define KEYCHRON_V2_ANSI_PID 0x0320
|
||||
#define KEYCHRON_V2_ANSI_ENCODER_PID 0x0321
|
||||
#define KEYCHRON_V2_ISO_PID 0x0322
|
||||
#define KEYCHRON_V2_ISO_ENCODER_PID 0x0323
|
||||
#define KEYCHRON_V2_JIS_PID 0x0324
|
||||
#define KEYCHRON_V2_JIS_ENCODER_PID 0x0325
|
||||
#define KEYCHRON_V2_MAX_ANSI_ENCODER_PID 0x0920
|
||||
#define KEYCHRON_V2_MAX_ISO_ENCODER_PID 0x0921
|
||||
#define KEYCHRON_V2_MAX_JIS_ENCODER_PID 0x0922
|
||||
#define KEYCHRON_V3_ABNT2_ENCODER_PID 0x0337
|
||||
#define KEYCHRON_V3_ANSI_PID 0x0330
|
||||
#define KEYCHRON_V3_ANSI_ENCODER_PID 0x0331
|
||||
#define KEYCHRON_V3_ISO_PID 0x0332
|
||||
#define KEYCHRON_V3_ISO_ENCODER_PID 0x0333
|
||||
#define KEYCHRON_V3_JIS_PID 0x0334
|
||||
#define KEYCHRON_V3_JIS_ENCODER_PID 0x0335
|
||||
#define KEYCHRON_V3_MAX_ANSI_ENCODER_PID 0x0933
|
||||
#define KEYCHRON_V3_MAX_ISO_ENCODER_PID 0x0934
|
||||
#define KEYCHRON_V3_MAX_JIS_ENCODER_PID 0x0935
|
||||
#define KEYCHRON_V4_ANSI_PID 0x0340
|
||||
#define KEYCHRON_V4_ISO_PID 0x0342
|
||||
#define KEYCHRON_V4_MAX_ANSI_PID 0x0940
|
||||
#define KEYCHRON_V4_MAX_ISO_PID 0x0941
|
||||
#define KEYCHRON_V5_ANSI_PID 0x0350
|
||||
#define KEYCHRON_V5_ANSI_ENCODER_PID 0x0351
|
||||
#define KEYCHRON_V5_ISO_PID 0x0352
|
||||
#define KEYCHRON_V5_ISO_ENCODER_PID 0x0353
|
||||
#define KEYCHRON_V5_MAX_ANSI_ENCODER_PID 0x0950
|
||||
#define KEYCHRON_V5_MAX_ISO_ENCODER_PID 0x0951
|
||||
#define KEYCHRON_V5_MAX_JIS_ENCODER_PID 0x0952
|
||||
#define KEYCHRON_V6_ABNT2_ENCODER_PID 0x0367
|
||||
#define KEYCHRON_V6_ANSI_PID 0x0360
|
||||
#define KEYCHRON_V6_ANSI_ENCODER_PID 0x0361
|
||||
#define KEYCHRON_V6_ISO_PID 0x0362
|
||||
#define KEYCHRON_V6_ISO_ENCODER_PID 0x0363
|
||||
#define KEYCHRON_V6_MAX_ANSI_ENCODER_PID 0x0960
|
||||
#define KEYCHRON_V6_MAX_ISO_ENCODER_PID 0x0961
|
||||
#define KEYCHRON_V6_MAX_JIS_ENCODER_PID 0x0962
|
||||
#define KEYCHRON_V6_V2_ISO_ENCODER_PID 0x0368
|
||||
#define KEYCHRON_V7_ANSI_PID 0x0370
|
||||
#define KEYCHRON_V7_ISO_PID 0x0372
|
||||
#define KEYCHRON_V8_ANSI_PID 0x0380
|
||||
#define KEYCHRON_V8_ANSI_ENCODER_PID 0x0381
|
||||
#define KEYCHRON_V8_ISO_PID 0x0382
|
||||
#define KEYCHRON_V8_ISO_ENCODER_PID 0x0383
|
||||
#define KEYCHRON_V8_MAX_ANSI_ENCODER_PID 0x0980
|
||||
#define KEYCHRON_V8_MAX_ISO_ENCODER_PID 0x0981
|
||||
#define KEYCHRON_V10_ANSI_ENCODER_PID 0x03A1
|
||||
#define KEYCHRON_V10_ISO_ENCODER_PID 0x03A3
|
||||
#define KEYCHRON_V10_MAX_ANSI_ENCODER_PID 0x09A0
|
||||
#define KEYCHRON_V10_MAX_ISO_ENCODER_PID 0x09A1
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| QMK raw HID usage page/usage |
|
||||
\*---------------------------------------------------------*/
|
||||
#define KEYCHRON_QMK_USAGE_PAGE 0xFF60
|
||||
#define KEYCHRON_QMK_USAGE 0x61
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HID packet constants |
|
||||
\*---------------------------------------------------------*/
|
||||
#define KEYCHRON_QHE_PACKET_SIZE 32
|
||||
#define KEYCHRON_QHE_HID_READ_TIMEOUT 1000
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keychron-specific VIA protocol extension |
|
||||
\*---------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
KC_GET_PROTOCOL_VERSION = 0xA0,
|
||||
KC_GET_FIRMWARE_VERSION = 0xA1,
|
||||
KC_GET_SUPPORT_FEATURE = 0xA2,
|
||||
KC_GET_DEFAULT_LAYER = 0xA3,
|
||||
KC_MISC_CMD_GROUP = 0xA7,
|
||||
KC_KEYCHRON_RGB = 0xA8,
|
||||
KC_ANALOG_MATRIX = 0xA9,
|
||||
KC_WIRELESS_DFU = 0xAA,
|
||||
KC_FACTORY_TEST = 0xAB
|
||||
};
|
||||
|
||||
enum KeychronKCRGBCommand
|
||||
{
|
||||
KEYCHRON_RGB_PROTOCOL_VER = 0x01,
|
||||
KEYCHRON_RGB_SAVE = 0x02,
|
||||
KEYCHRON_RGB_GET_INDICATORS = 0x03,
|
||||
KEYCHRON_RGB_SET_INDICATORS = 0x04,
|
||||
KEYCHRON_RGB_LED_COUNT = 0x05,
|
||||
KEYCHRON_RGB_LED_IDX = 0x06,
|
||||
KEYCHRON_RGB_PER_KEY_GET_TYPE = 0x07,
|
||||
KEYCHRON_RGB_PER_KEY_SET_TYPE = 0x08,
|
||||
KEYCHRON_RGB_PER_KEY_GET_COLOR = 0x09,
|
||||
KEYCHRON_RGB_PER_KEY_SET_COLOR = 0x0A,
|
||||
KEYCHRON_RGB_MIXED_GET_INFO = 0x0B,
|
||||
KEYCHRON_RGB_MIXED_GET_REGIONS = 0x0C,
|
||||
KEYCHRON_RGB_MIXED_SET_REGIONS = 0x0D,
|
||||
KEYCHRON_RGB_MIXED_GET_EFFECTS = 0x0E,
|
||||
KEYCHRON_RGB_MIXED_SET_EFFECTS = 0x0F,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
KC_FEATURE_DEFAULT_LAYER = ( 1 << 0 ),
|
||||
KC_FEATURE_BLUETOOTH = ( 1 << 1 ),
|
||||
KC_FEATURE_P24G = ( 1 << 2 ),
|
||||
KC_FEATURE_ANALOG_MATRIX = ( 1 << 3 ),
|
||||
KC_FEATURE_STATE_NOTIFY = ( 1 << 4 ),
|
||||
KC_FEATURE_DYNAMIC_DEBOUNCE = ( 1 << 5 ),
|
||||
KC_FEATURE_SNAP_CLICK = ( 1 << 6 ),
|
||||
KC_FEATURE_KEYCHRON_RGB = ( 1 << 7 ),
|
||||
KC_FEATURE_QUICK_START = ( 1 << 8 ),
|
||||
KC_FEATURE_NKRO = ( 1 << 9 ),
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Per-key RGB animation types (PER_KEY_RGB_SET_TYPE value) |
|
||||
\*---------------------------------------------------------*/
|
||||
enum KeychronPerKeyRgbType
|
||||
{
|
||||
KEYCHRON_PER_KEY_RGB_SOLID = 0,
|
||||
KEYCHRON_PER_KEY_RGB_BREATHING = 1,
|
||||
KEYCHRON_PER_KEY_RGB_REACTIVE_SIMPLE = 2,
|
||||
KEYCHRON_PER_KEY_RGB_REACTIVE_WIDE = 3,
|
||||
KEYCHRON_PER_KEY_RGB_REACTIVE_SPLASH = 4,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| VIA backlight value IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define KEYCHRON_VIA_BACKLIGHT_TYPE_RGB_MATRIX 0x03
|
||||
|
||||
enum KeychronVIABacklightValueID
|
||||
{
|
||||
KEYCHRON_VIA_BACKLIGHT_BRIGHTNESS = 0x01,
|
||||
KEYCHRON_VIA_BACKLIGHT_EFFECT = 0x02,
|
||||
KEYCHRON_VIA_BACKLIGHT_SPEED = 0x03,
|
||||
KEYCHRON_VIA_BACKLIGHT_COLOR = 0x04,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Q1 HE effect IDs |
|
||||
| |
|
||||
| Determined by the number of standard effects enabled |
|
||||
| in the Q1 HE firmware (info.json animations) + |
|
||||
| 2 custom effects (PER_KEY_RGB, MIXED_RGB). |
|
||||
| May need adjustment for other firmware versions. |
|
||||
\*---------------------------------------------------------*/
|
||||
#define KEYCHRON_QHE_PER_KEY_RGB_EFFECT 23
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Brightness and speed ranges |
|
||||
\*---------------------------------------------------------*/
|
||||
#define KEYCHRON_QHE_MIN_BRIGHTNESS 0x00
|
||||
#define KEYCHRON_QHE_MAX_BRIGHTNESS 0xFF
|
||||
#define KEYCHRON_QHE_MIN_SPEED 0x00
|
||||
#define KEYCHRON_QHE_MAX_SPEED 0xFF
|
||||
|
||||
class QMKKeychronController
|
||||
{
|
||||
public:
|
||||
QMKKeychronController(hid_device* dev_handle, const char *path);
|
||||
~QMKKeychronController();
|
||||
|
||||
std::string GetLocation();
|
||||
std::string GetName();
|
||||
std::string GetSerial();
|
||||
std::string GetVendor();
|
||||
std::string GetVersion();
|
||||
|
||||
bool GetSupported();
|
||||
|
||||
unsigned short GetKeycode(unsigned short led_index);
|
||||
unsigned short GetLEDCount();
|
||||
qmk_rgb_matrix_led_info GetLEDInfo(unsigned short led_index);
|
||||
|
||||
void SendLEDs(unsigned short number_leds, RGBColor* color_data);
|
||||
void SetMode(unsigned short mode, unsigned char speed, unsigned char hue, unsigned char sat, unsigned char val);
|
||||
|
||||
void SaveMode();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string kc_firmware_version;
|
||||
unsigned char kc_protocol_version;
|
||||
unsigned short kc_rgb_protocol_version;
|
||||
std::vector<unsigned short> keycodes;
|
||||
std::vector<qmk_rgb_matrix_led_info> led_info;
|
||||
std::string location;
|
||||
std::string name;
|
||||
unsigned short number_leds;
|
||||
std::string serial;
|
||||
unsigned short supported_features;
|
||||
std::string vendor;
|
||||
unsigned short via_protocol_version;
|
||||
|
||||
unsigned short CmdGetKeycode(unsigned char layer, unsigned char row, unsigned char col);
|
||||
std::string CmdGetKeychronFirmwareVersion();
|
||||
void CmdGetKeychronProtocolVersion(unsigned char* kc_protocol_version);
|
||||
void CmdGetKeychronRGBProtocolVersion(unsigned short* kc_rgb_protocol_version);
|
||||
std::vector<unsigned char> CmdGetLEDIndexByRow(unsigned char row);
|
||||
void CmdGetNumberLEDs(unsigned short* number_leds);
|
||||
void CmdGetSupportFeature(unsigned short* supported_features);
|
||||
void CmdGetViaProtocolVersion(unsigned short* via_protocol_version);
|
||||
void CmdSaveMode();
|
||||
void CmdSendLEDs(unsigned char start_index, unsigned char number_leds, RGBColor* color_data);
|
||||
void CmdSetBrightness(unsigned char brightness);
|
||||
void CmdSetColorHS(unsigned char h, unsigned char s);
|
||||
void CmdSetPerKeyRGBType(unsigned char type);
|
||||
void CmdSetRGBMatrixMode(unsigned char mode);
|
||||
void CmdSetSpeed(unsigned char speed);
|
||||
|
||||
int ViaSendCommand
|
||||
(
|
||||
unsigned char cmd,
|
||||
unsigned char* data_in,
|
||||
unsigned char data_in_size,
|
||||
unsigned char* data_out,
|
||||
unsigned char data_out_size
|
||||
);
|
||||
|
||||
int ViaSendCommandSub
|
||||
(
|
||||
unsigned char cmd,
|
||||
unsigned char subcmd,
|
||||
unsigned char* data_in,
|
||||
unsigned char data_in_size,
|
||||
unsigned char* data_out,
|
||||
unsigned char data_out_size
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,279 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKKeychronControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Keychron QMK-based keyboards |
|
||||
| |
|
||||
| Amadej Kastelic 21 Jun 2026 |
|
||||
| Adam Honse <calcprogrammer1@gmail.com> 22 Jun 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "Detector.h"
|
||||
#include "QMKKeychronController.h"
|
||||
#include "RGBController_QMKKeychron.h"
|
||||
|
||||
void DetectQMKKeychronControllers(hid_device_info *info, const std::string&)
|
||||
{
|
||||
hid_device *dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
QMKKeychronController* controller = new QMKKeychronController(dev, info->path);
|
||||
|
||||
if(controller->GetSupported())
|
||||
{
|
||||
RGBController_QMKKeychron* rgb_controller = new RGBController_QMKKeychron(controller);
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron C1 Pro", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_C1_PRO_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron C1 Pro 8K", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_C1_PRO_8K_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron C1 Pro 8K", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_C1_PRO_8K_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron C1 Pro 8K", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_C1_PRO_8K_JIS_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron C1 Pro V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_C1_PRO_V2_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron C2 Pro", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_C2_PRO_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron C2 Pro 8K", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_C2_PRO_8K_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron C2 Pro 8K", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_C2_PRO_8K_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron C2 Pro V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_C2_PRO_V2_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron C3 Pro", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_C3_PRO_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron C3 Pro 8K", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_C3_PRO_8K_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron C3 Pro 8K", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_C3_PRO_8K_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron C3 Pro 8K", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_C3_PRO_8K_JIS_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K0 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K0_MAX_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K1 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K1_MAX_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K1 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K1_MAX_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K1 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K1_MAX_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K1 V6", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K1_V6_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K1 V6", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K1_V6_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K1 V6", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K1_V6_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K2 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K2_HE_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K2 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K2_HE_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K2 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K2_HE_JIS_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K2 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K2_MAX_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K2 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K2_MAX_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K2 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K2_MAX_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K2 V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K2_V3_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K2 V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K2_V3_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K2 V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K2_V3_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K3 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K3_MAX_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K3 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K3_MAX_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K3 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K3_MAX_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K3 V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K3_V3_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K3 V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K3_V3_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K3 V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K3_V3_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K4 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K4_HE_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K4 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K4_HE_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K4 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K4_HE_JIS_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K4 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K4_MAX_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K4 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K4_MAX_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K4 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K4_MAX_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K4 V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K4_V3_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K4 V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K4_V3_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K4 V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K4_V3_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K5 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K5_MAX_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K5 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K5_MAX_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K5 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K5_MAX_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K5 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K5_MAX_JIS_V2_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K5 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K5_V2_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K5 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K5_V2_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K5 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K5_V2_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K6 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K6_HE_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K7 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K7_MAX_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K7 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K7_MAX_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K7 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K7_MAX_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K7 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K7_MAX_JIS_V2_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K8 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K8_HE_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K8 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K8_HE_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K8 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K8_HE_JIS_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K8 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K8_MAX_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K8 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K8_MAX_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K8 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K8_MAX_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K8 Pro", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K8_PRO_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K8 Pro", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K8_PRO_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K8 Pro", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K8_PRO_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K8 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K8_V2_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K8 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K8_V2_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K8 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K8_V2_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K9 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K9_MAX_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K10 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K10_HE_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K10 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K10_HE_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K10 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K10_MAX_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K10 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K10_MAX_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K10 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K10_MAX_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K10 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K10_V2_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K10 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K10_V2_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K10 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K10_V2_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K11 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K11_MAX_ANSI_ENCODER_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K11 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K11_MAX_ISO_ENCODER_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K11 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K11_MAX_JIS_ENCODER_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K13 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K13_MAX_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K13 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K13_MAX_ISO_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K13 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K13_MAX_JIS_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K15 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K15_MAX_ANSI_ENCODER_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K15 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K15_MAX_ISO_ENCODER_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K17 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K17_MAX_ANSI_ENCODER_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K17 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K17_MAX_ISO_ENCODER_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron K17 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_K17_MAX_JIS_ENCODER_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q0", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q0_BASE_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q0 Plus", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q0_PLUS_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q0 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q0_MAX_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_HE_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_HE_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_HE_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_MAX_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_MAX_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 V1", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_V1_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 V1", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_V1_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 V1", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_V1_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 V1", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_V1_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_V2_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_V2_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_V2_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_V2_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_V2_JIS_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q1 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q1_V2_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q2_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q2_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q2_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q2_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q2_JIS_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q2_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q2 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q2_HE_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q2 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q2_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q2 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q2_MAX_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q3_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q3_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q3_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q3_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q3_JIS_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q3_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q3 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q3_HE_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q3 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q3_HE_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q3 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q3_HE_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q3 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q3_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q3 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q3_MAX_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q4", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q4_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q4", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q4_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q4 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q4_HE_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q5", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q5_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q5", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q5_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q5", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q5_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q5", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q5_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q5 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q5_HE_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q5 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q5_HE_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q5 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q5_HE_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q5 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q5_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q5 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q5_MAX_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q5 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q5_MAX_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q6", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q6_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q6", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q6_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q6", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q6_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q6", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q6_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q6 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q6_HE_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q6 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q6_HE_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q6 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q6_HE_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q6 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q6_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q6 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q6_MAX_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q7", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q7_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q7", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q7_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q8", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q8_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q8", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q8_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q8", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q8_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q8", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q8_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q8 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q8_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q9", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q9_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q9", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q9_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q9", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q9_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q9", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q9_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q9 Plus", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q9_PLUS_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q10", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q10_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q10", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q10_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q10 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q10_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q10 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q10_MAX_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q11", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q11_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q11", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q11_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q12", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q12_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q12", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q12_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q12 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q12_HE_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q12 HE", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q12_HE_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q12 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q12_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q12 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q12_MAX_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q13 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q13_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q13 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q13_MAX_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q14 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q14_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q15 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q15_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q60 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q60_MAX_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron Q65 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_Q65_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron S1", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_S1_ANSI_RGB_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V1", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V1_ABNT2_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V1", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V1_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V1", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V1_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V1", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V1_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V1", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V1_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V1", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V1_JIS_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V1", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V1_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V1 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V1_8K_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V1 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V1_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V1 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V1_MAX_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V1 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V1_MAX_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V2_ABNT2_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V2_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V2_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V2_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V2_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V2_JIS_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V2_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V2 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V2_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V2 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V2_MAX_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V2 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V2_MAX_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V3_ABNT2_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V3_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V3_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V3_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V3_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V3_JIS_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V3", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V3_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V3 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V3_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V3 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V3_MAX_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V3 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V3_MAX_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V4", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V4_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V4", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V4_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V4 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V4_MAX_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V4 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V4_MAX_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V5", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V5_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V5", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V5_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V5", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V5_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V5", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V5_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V5 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V5_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V5 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V5_MAX_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V5 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V5_MAX_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V6", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V6_ABNT2_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V6", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V6_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V6", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V6_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V6", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V6_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V6", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V6_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V6 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V6_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V6 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V6_MAX_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V6 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V6_MAX_JIS_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V6 V2", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V6_V2_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V7", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V7_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V7", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V7_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V8", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V8_ANSI_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V8", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V8_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V8", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V8_ISO_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V8", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V8_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V8 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V8_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V8 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V8_MAX_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V10", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V10_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V10", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V10_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V10 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V10_MAX_ANSI_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
REGISTER_HID_DETECTOR_IPU("Keychron V10 Max", DetectQMKKeychronControllers, KEYCHRON_VID, KEYCHRON_V10_MAX_ISO_ENCODER_PID, 1, KEYCHRON_QMK_USAGE_PAGE, KEYCHRON_QMK_USAGE);
|
||||
@@ -0,0 +1,239 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_QMKKeychron.cpp |
|
||||
| |
|
||||
| RGBController for Keychron QMK-based keyboards |
|
||||
| |
|
||||
| Amadej Kastelic 21 Jun 2026 |
|
||||
| Adam Honse <calcprogrammer1@gmail.com> 22 Jun 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "hsv.h"
|
||||
#include "RGBController_QMKKeychron.h"
|
||||
#include "QMKKeycodes.h"
|
||||
#include "QMKKeychronController.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name QMK Keychron
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :white_check_mark:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectQMKKeychronController
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
std::string name;
|
||||
int value;
|
||||
int flags;
|
||||
} kc_effect;
|
||||
|
||||
static const kc_effect kc_effects[] =
|
||||
{
|
||||
{ "Direct", 0xFFFF, MODE_FLAG_HAS_PER_LED_COLOR },
|
||||
{ "Solid Color", 1, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Breathing", 2, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Band Spiral", 3, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Cycle All", 4, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Cycle Left Right", 5, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Cycle Up Down", 6, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Rainbow Moving Chevron", 7, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Cycle Out In", 8, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Cycle Out In Dual", 9, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Cycle Pinwheel", 10, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Cycle Spiral", 11, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Dual Beacon", 12, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Rainbow Beacon", 13, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Jellybean Raindrops", 14, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Pixel Rain", 15, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Typing Heatmap", 16, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Digital Rain", 17, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Solid Reactive Simple", 18, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Solid Reactive Multiwide", 19, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Solid Reactive Multinexus", 20, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Splash", 21, MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE },
|
||||
{ "Solid Splash", 22, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE },
|
||||
};
|
||||
|
||||
RGBController_QMKKeychron::RGBController_QMKKeychron(QMKKeychronController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetName();
|
||||
vendor = controller->GetVendor();
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "QMK Keychron Device";
|
||||
location = controller->GetLocation();
|
||||
serial = controller->GetSerial();
|
||||
version = controller->GetVersion();
|
||||
|
||||
for(const kc_effect& effect : kc_effects)
|
||||
{
|
||||
mode m;
|
||||
m.name = effect.name;
|
||||
m.value = effect.value;
|
||||
m.flags = effect.flags;
|
||||
|
||||
if(m.flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
|
||||
{
|
||||
m.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
m.colors_min = 1;
|
||||
m.colors_max = 1;
|
||||
m.colors.resize(1);
|
||||
}
|
||||
else if(m.flags & MODE_FLAG_HAS_PER_LED_COLOR)
|
||||
{
|
||||
m.color_mode = MODE_COLORS_PER_LED;
|
||||
m.colors_min = 0;
|
||||
m.colors_max = 0;
|
||||
m.colors.resize(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m.color_mode = MODE_COLORS_NONE;
|
||||
m.colors_min = 0;
|
||||
m.colors_max = 0;
|
||||
m.colors.resize(0);
|
||||
}
|
||||
|
||||
if(m.flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
m.speed_min = KEYCHRON_QHE_MIN_SPEED;
|
||||
m.speed_max = KEYCHRON_QHE_MAX_SPEED;
|
||||
m.speed = KEYCHRON_QHE_MAX_SPEED / 2;
|
||||
}
|
||||
|
||||
if(m.flags & MODE_FLAG_HAS_BRIGHTNESS)
|
||||
{
|
||||
m.brightness_min = KEYCHRON_QHE_MIN_BRIGHTNESS;
|
||||
m.brightness_max = KEYCHRON_QHE_MAX_BRIGHTNESS;
|
||||
m.brightness = KEYCHRON_QHE_MAX_BRIGHTNESS;
|
||||
}
|
||||
|
||||
modes.push_back(m);
|
||||
}
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_QMKKeychron::~RGBController_QMKKeychron()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_QMKKeychron::SetupZones()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Build matrix map |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char max_col = 0;
|
||||
unsigned char max_row = 0;
|
||||
|
||||
for(unsigned short led_index = 0; led_index < controller->GetLEDCount(); led_index++)
|
||||
{
|
||||
qmk_rgb_matrix_led_info info = controller->GetLEDInfo(led_index);
|
||||
|
||||
if(info.col > max_col)
|
||||
{
|
||||
max_col = info.col;
|
||||
}
|
||||
|
||||
if(info.row > max_row)
|
||||
{
|
||||
max_row = info.row;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char height = max_row + 1;
|
||||
unsigned char width = max_col + 1;
|
||||
|
||||
unsigned int* matrix_map = new unsigned int[width * height];
|
||||
|
||||
memset(matrix_map, 0xFF, (sizeof(unsigned int) * (width * height)));
|
||||
|
||||
for(unsigned short led_index = 0; led_index < controller->GetLEDCount(); led_index++)
|
||||
{
|
||||
qmk_rgb_matrix_led_info info = controller->GetLEDInfo(led_index);
|
||||
|
||||
matrix_map[(width * info.row) + info.col] = (unsigned int)led_index;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Create keyboard zone |
|
||||
\*-----------------------------------------------------*/
|
||||
zone keyboard;
|
||||
|
||||
keyboard.name = "Keyboard";
|
||||
keyboard.type = ZONE_TYPE_MATRIX;
|
||||
keyboard.leds_min = controller->GetLEDCount();
|
||||
keyboard.leds_max = controller->GetLEDCount();
|
||||
keyboard.leds_count = controller->GetLEDCount();
|
||||
keyboard.matrix_map = new matrix_map_type;
|
||||
keyboard.matrix_map->height = height;
|
||||
keyboard.matrix_map->width = width;
|
||||
keyboard.matrix_map->map = matrix_map;
|
||||
|
||||
zones.push_back(keyboard);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Create keyboard LEDs |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned short led_idx = 0; led_idx < controller->GetLEDCount(); led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = qmk_keynames[controller->GetKeycode(led_idx)];
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_QMKKeychron::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
}
|
||||
|
||||
void RGBController_QMKKeychron::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SendLEDs((unsigned short)colors.size(), colors.data());
|
||||
}
|
||||
|
||||
void RGBController_QMKKeychron::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_QMKKeychron::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_QMKKeychron::DeviceUpdateMode()
|
||||
{
|
||||
unsigned char hue = 0;
|
||||
unsigned char sat = 255;
|
||||
unsigned char val = modes[active_mode].brightness;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
hsv_t hsv_color;
|
||||
rgb2hsv(modes[active_mode].colors[0], &hsv_color);
|
||||
|
||||
hue = (unsigned char)((float)hsv_color.hue * (256.0f / 360.0f));
|
||||
sat = hsv_color.saturation;
|
||||
val = hsv_color.value;
|
||||
}
|
||||
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, hue, sat, val);
|
||||
}
|
||||
|
||||
void RGBController_QMKKeychron::DeviceSaveMode()
|
||||
{
|
||||
controller->SaveMode();
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_QMKKeychron.h |
|
||||
| |
|
||||
| RGBController for Keychron QMK-based keyboards |
|
||||
| |
|
||||
| Amadej Kastelic 21 Jun 2026 |
|
||||
| Adam Honse <calcprogrammer1@gmail.com> 22 Jun 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "QMKKeychronController.h"
|
||||
|
||||
class RGBController_QMKKeychron : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_QMKKeychron(QMKKeychronController* controller_ptr);
|
||||
~RGBController_QMKKeychron();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
QMKKeychronController* controller;
|
||||
};
|
||||
@@ -0,0 +1,153 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKKeycodes.cpp |
|
||||
| |
|
||||
| List of QMK keycode values |
|
||||
| |
|
||||
| Adam Honse <calcprogrammer1@gmail.com) 07 Oct 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "QMKKeycodes.h"
|
||||
#include "RGBControllerKeyNames.h"
|
||||
|
||||
std::map<qmk_keycode, std::string> qmk_keynames =
|
||||
{
|
||||
{ QMK_KC_NO, KEY_EN_UNUSED },
|
||||
{ QMK_KC_TRANSPARENT, KEY_EN_RIGHT_FUNCTION },
|
||||
{ QMK_KC_A, KEY_EN_A },
|
||||
{ QMK_KC_B, KEY_EN_B },
|
||||
{ QMK_KC_C, KEY_EN_C },
|
||||
{ QMK_KC_D, KEY_EN_D },
|
||||
{ QMK_KC_E, KEY_EN_E },
|
||||
{ QMK_KC_F, KEY_EN_F },
|
||||
{ QMK_KC_G, KEY_EN_G },
|
||||
{ QMK_KC_H, KEY_EN_H },
|
||||
{ QMK_KC_I, KEY_EN_I },
|
||||
{ QMK_KC_J, KEY_EN_J },
|
||||
{ QMK_KC_K, KEY_EN_K },
|
||||
{ QMK_KC_L, KEY_EN_L },
|
||||
{ QMK_KC_M, KEY_EN_M },
|
||||
{ QMK_KC_N, KEY_EN_N },
|
||||
{ QMK_KC_O, KEY_EN_O },
|
||||
{ QMK_KC_P, KEY_EN_P },
|
||||
{ QMK_KC_Q, KEY_EN_Q },
|
||||
{ QMK_KC_R, KEY_EN_R },
|
||||
{ QMK_KC_S, KEY_EN_S },
|
||||
{ QMK_KC_T, KEY_EN_T },
|
||||
{ QMK_KC_U, KEY_EN_U },
|
||||
{ QMK_KC_V, KEY_EN_V },
|
||||
{ QMK_KC_W, KEY_EN_W },
|
||||
{ QMK_KC_X, KEY_EN_X },
|
||||
{ QMK_KC_Y, KEY_EN_Y },
|
||||
{ QMK_KC_Z, KEY_EN_Z },
|
||||
{ QMK_KC_1, KEY_EN_1 },
|
||||
{ QMK_KC_2, KEY_EN_2 },
|
||||
{ QMK_KC_3, KEY_EN_3 },
|
||||
{ QMK_KC_4, KEY_EN_4 },
|
||||
{ QMK_KC_5, KEY_EN_5 },
|
||||
{ QMK_KC_6, KEY_EN_6 },
|
||||
{ QMK_KC_7, KEY_EN_7 },
|
||||
{ QMK_KC_8, KEY_EN_8 },
|
||||
{ QMK_KC_9, KEY_EN_9 },
|
||||
{ QMK_KC_0, KEY_EN_0 },
|
||||
{ QMK_KC_ENTER, KEY_EN_ANSI_ENTER },
|
||||
{ QMK_KC_ESCAPE, KEY_EN_ESCAPE },
|
||||
{ QMK_KC_BACKSPACE, KEY_EN_BACKSPACE },
|
||||
{ QMK_KC_TAB, KEY_EN_TAB },
|
||||
{ QMK_KC_SPACE, KEY_EN_SPACE },
|
||||
{ QMK_KC_MINUS, KEY_EN_MINUS },
|
||||
{ QMK_KC_EQUAL, KEY_EN_EQUALS },
|
||||
{ QMK_KC_LEFT_BRACKET, KEY_EN_LEFT_BRACKET },
|
||||
{ QMK_KC_RIGHT_BRACKET, KEY_EN_RIGHT_BRACKET },
|
||||
{ QMK_KC_BACKSLASH, KEY_EN_ANSI_BACK_SLASH },
|
||||
{ QMK_KC_NONUS_HASH, KEY_EN_POUND },
|
||||
{ QMK_KC_SEMICOLON, KEY_EN_SEMICOLON },
|
||||
{ QMK_KC_QUOTE, KEY_EN_QUOTE },
|
||||
{ QMK_KC_GRAVE, KEY_EN_BACK_TICK },
|
||||
{ QMK_KC_COMMA, KEY_EN_COMMA },
|
||||
{ QMK_KC_DOT, KEY_EN_PERIOD },
|
||||
{ QMK_KC_SLASH, KEY_EN_FORWARD_SLASH },
|
||||
{ QMK_KC_CAPS_LOCK, KEY_EN_CAPS_LOCK },
|
||||
{ QMK_KC_F1, KEY_EN_F1 },
|
||||
{ QMK_KC_F2, KEY_EN_F2 },
|
||||
{ QMK_KC_F3, KEY_EN_F3 },
|
||||
{ QMK_KC_F4, KEY_EN_F4 },
|
||||
{ QMK_KC_F5, KEY_EN_F5 },
|
||||
{ QMK_KC_F6, KEY_EN_F6 },
|
||||
{ QMK_KC_F7, KEY_EN_F7 },
|
||||
{ QMK_KC_F8, KEY_EN_F8 },
|
||||
{ QMK_KC_F9, KEY_EN_F9 },
|
||||
{ QMK_KC_F10, KEY_EN_F10 },
|
||||
{ QMK_KC_F11, KEY_EN_F11 },
|
||||
{ QMK_KC_F12, KEY_EN_F12 },
|
||||
{ QMK_KC_PRINT_SCREEN, KEY_EN_PRINT_SCREEN },
|
||||
{ QMK_KC_SCROLL_LOCK, KEY_EN_SCROLL_LOCK },
|
||||
{ QMK_KC_PAUSE, KEY_EN_PAUSE_BREAK },
|
||||
{ QMK_KC_INSERT, KEY_EN_INSERT },
|
||||
{ QMK_KC_HOME, KEY_EN_HOME },
|
||||
{ QMK_KC_PAGE_UP, KEY_EN_PAGE_UP },
|
||||
{ QMK_KC_DELETE, KEY_EN_DELETE },
|
||||
{ QMK_KC_END, KEY_EN_END },
|
||||
{ QMK_KC_PAGE_DOWN, KEY_EN_PAGE_DOWN },
|
||||
{ QMK_KC_RIGHT, KEY_EN_RIGHT_ARROW },
|
||||
{ QMK_KC_LEFT, KEY_EN_LEFT_ARROW },
|
||||
{ QMK_KC_DOWN, KEY_EN_DOWN_ARROW },
|
||||
{ QMK_KC_UP, KEY_EN_UP_ARROW },
|
||||
{ QMK_KC_NUM_LOCK, KEY_EN_NUMPAD_LOCK },
|
||||
{ QMK_KC_KP_SLASH, KEY_EN_NUMPAD_DIVIDE },
|
||||
{ QMK_KC_KP_ASTERISK, KEY_EN_NUMPAD_TIMES },
|
||||
{ QMK_KC_KP_MINUS, KEY_EN_NUMPAD_MINUS },
|
||||
{ QMK_KC_KP_PLUS, KEY_EN_NUMPAD_PLUS },
|
||||
{ QMK_KC_KP_ENTER, KEY_EN_NUMPAD_ENTER },
|
||||
{ QMK_KC_KP_1, KEY_EN_NUMPAD_1 },
|
||||
{ QMK_KC_KP_2, KEY_EN_NUMPAD_2 },
|
||||
{ QMK_KC_KP_3, KEY_EN_NUMPAD_3 },
|
||||
{ QMK_KC_KP_4, KEY_EN_NUMPAD_4 },
|
||||
{ QMK_KC_KP_5, KEY_EN_NUMPAD_5 },
|
||||
{ QMK_KC_KP_6, KEY_EN_NUMPAD_6 },
|
||||
{ QMK_KC_KP_7, KEY_EN_NUMPAD_7 },
|
||||
{ QMK_KC_KP_8, KEY_EN_NUMPAD_8 },
|
||||
{ QMK_KC_KP_9, KEY_EN_NUMPAD_9 },
|
||||
{ QMK_KC_KP_0, KEY_EN_NUMPAD_0 },
|
||||
{ QMK_KC_KP_DOT, KEY_EN_NUMPAD_PERIOD },
|
||||
{ QMK_KC_NONUS_BACKSLASH, KEY_EN_ISO_BACK_SLASH },
|
||||
{ QMK_KC_APPLICATION, KEY_EN_MENU },
|
||||
{ QMK_KC_F13, "Key: F13" },
|
||||
{ QMK_KC_F14, "Key: F14" },
|
||||
{ QMK_KC_F15, "Key: F15" },
|
||||
{ QMK_KC_F16, "Key: F16" },
|
||||
{ QMK_KC_F17, "Key: F17" },
|
||||
{ QMK_KC_F18, "Key: F18" },
|
||||
{ QMK_KC_F19, "Key: F19" },
|
||||
{ QMK_KC_F20, "Key: F20" },
|
||||
{ QMK_KC_F21, "Key: F21" },
|
||||
{ QMK_KC_F22, "Key: F22" },
|
||||
{ QMK_KC_F23, "Key: F23" },
|
||||
{ QMK_KC_F24, "Key: F24" },
|
||||
{ QMK_KC_AUDIO_MUTE, KEY_EN_MEDIA_MUTE },
|
||||
{ QMK_KC_AUDIO_VOL_UP, KEY_EN_MEDIA_VOLUME_UP },
|
||||
{ QMK_KC_AUDIO_VOL_DOWN, KEY_EN_MEDIA_VOLUME_DOWN },
|
||||
{ QMK_KC_MEDIA_NEXT_TRACK, KEY_EN_MEDIA_NEXT },
|
||||
{ QMK_KC_MEDIA_PREV_TRACK, KEY_EN_MEDIA_PREVIOUS },
|
||||
{ QMK_KC_MEDIA_STOP, KEY_EN_MEDIA_STOP },
|
||||
{ QMK_KC_MEDIA_PLAY_PAUSE, KEY_EN_MEDIA_PLAY_PAUSE },
|
||||
{ QMK_KC_MEDIA_SELECT, "Key: Media Select" },
|
||||
{ QMK_KC_MEDIA_EJECT, "Key: Media Eject" },
|
||||
{ QMK_KC_BRIGHTNESS_UP, "Key: Brightness Up" },
|
||||
{ QMK_KC_BRIGHTNESS_DOWN, "Key: Brightness Down" },
|
||||
{ 196, "Key: Task Manager" }, /* From OpenRGB QMK */
|
||||
{ 202, "Key: RGB Brightness Up" }, /* From OpenRGB QMK */
|
||||
{ 203, "Key: RGB Brightness Down" }, /* From OpenRGB QMK */
|
||||
{ 216, KEY_EN_LEFT_SHIFT }, /* Space Cadet Left Shift */
|
||||
{ 217, KEY_EN_RIGHT_SHIFT }, /* Space Cadet Right Shift */
|
||||
{ QMK_KC_LEFT_CTRL, KEY_EN_LEFT_CONTROL },
|
||||
{ QMK_KC_LEFT_SHIFT, KEY_EN_LEFT_SHIFT },
|
||||
{ QMK_KC_LEFT_ALT, KEY_EN_LEFT_ALT },
|
||||
{ QMK_KC_LEFT_GUI, KEY_EN_LEFT_WINDOWS },
|
||||
{ QMK_KC_RIGHT_CTRL, KEY_EN_RIGHT_CONTROL },
|
||||
{ QMK_KC_RIGHT_SHIFT, KEY_EN_RIGHT_SHIFT },
|
||||
{ QMK_KC_RIGHT_ALT, KEY_EN_RIGHT_ALT },
|
||||
{ QMK_KC_RIGHT_GUI, KEY_EN_RIGHT_WINDOWS },
|
||||
};
|
||||
@@ -0,0 +1,754 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKKeycodes.h |
|
||||
| |
|
||||
| List of QMK keycode values |
|
||||
| |
|
||||
| Adam Honse <calcprogrammer1@gmail.com) 06 Oct 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
typedef unsigned short qmk_keycode;
|
||||
enum
|
||||
{
|
||||
QMK_KC_NO = 0x0000,
|
||||
QMK_KC_TRANSPARENT = 0x0001,
|
||||
QMK_KC_A = 0x0004,
|
||||
QMK_KC_B = 0x0005,
|
||||
QMK_KC_C = 0x0006,
|
||||
QMK_KC_D = 0x0007,
|
||||
QMK_KC_E = 0x0008,
|
||||
QMK_KC_F = 0x0009,
|
||||
QMK_KC_G = 0x000A,
|
||||
QMK_KC_H = 0x000B,
|
||||
QMK_KC_I = 0x000C,
|
||||
QMK_KC_J = 0x000D,
|
||||
QMK_KC_K = 0x000E,
|
||||
QMK_KC_L = 0x000F,
|
||||
QMK_KC_M = 0x0010,
|
||||
QMK_KC_N = 0x0011,
|
||||
QMK_KC_O = 0x0012,
|
||||
QMK_KC_P = 0x0013,
|
||||
QMK_KC_Q = 0x0014,
|
||||
QMK_KC_R = 0x0015,
|
||||
QMK_KC_S = 0x0016,
|
||||
QMK_KC_T = 0x0017,
|
||||
QMK_KC_U = 0x0018,
|
||||
QMK_KC_V = 0x0019,
|
||||
QMK_KC_W = 0x001A,
|
||||
QMK_KC_X = 0x001B,
|
||||
QMK_KC_Y = 0x001C,
|
||||
QMK_KC_Z = 0x001D,
|
||||
QMK_KC_1 = 0x001E,
|
||||
QMK_KC_2 = 0x001F,
|
||||
QMK_KC_3 = 0x0020,
|
||||
QMK_KC_4 = 0x0021,
|
||||
QMK_KC_5 = 0x0022,
|
||||
QMK_KC_6 = 0x0023,
|
||||
QMK_KC_7 = 0x0024,
|
||||
QMK_KC_8 = 0x0025,
|
||||
QMK_KC_9 = 0x0026,
|
||||
QMK_KC_0 = 0x0027,
|
||||
QMK_KC_ENTER = 0x0028,
|
||||
QMK_KC_ESCAPE = 0x0029,
|
||||
QMK_KC_BACKSPACE = 0x002A,
|
||||
QMK_KC_TAB = 0x002B,
|
||||
QMK_KC_SPACE = 0x002C,
|
||||
QMK_KC_MINUS = 0x002D,
|
||||
QMK_KC_EQUAL = 0x002E,
|
||||
QMK_KC_LEFT_BRACKET = 0x002F,
|
||||
QMK_KC_RIGHT_BRACKET = 0x0030,
|
||||
QMK_KC_BACKSLASH = 0x0031,
|
||||
QMK_KC_NONUS_HASH = 0x0032,
|
||||
QMK_KC_SEMICOLON = 0x0033,
|
||||
QMK_KC_QUOTE = 0x0034,
|
||||
QMK_KC_GRAVE = 0x0035,
|
||||
QMK_KC_COMMA = 0x0036,
|
||||
QMK_KC_DOT = 0x0037,
|
||||
QMK_KC_SLASH = 0x0038,
|
||||
QMK_KC_CAPS_LOCK = 0x0039,
|
||||
QMK_KC_F1 = 0x003A,
|
||||
QMK_KC_F2 = 0x003B,
|
||||
QMK_KC_F3 = 0x003C,
|
||||
QMK_KC_F4 = 0x003D,
|
||||
QMK_KC_F5 = 0x003E,
|
||||
QMK_KC_F6 = 0x003F,
|
||||
QMK_KC_F7 = 0x0040,
|
||||
QMK_KC_F8 = 0x0041,
|
||||
QMK_KC_F9 = 0x0042,
|
||||
QMK_KC_F10 = 0x0043,
|
||||
QMK_KC_F11 = 0x0044,
|
||||
QMK_KC_F12 = 0x0045,
|
||||
QMK_KC_PRINT_SCREEN = 0x0046,
|
||||
QMK_KC_SCROLL_LOCK = 0x0047,
|
||||
QMK_KC_PAUSE = 0x0048,
|
||||
QMK_KC_INSERT = 0x0049,
|
||||
QMK_KC_HOME = 0x004A,
|
||||
QMK_KC_PAGE_UP = 0x004B,
|
||||
QMK_KC_DELETE = 0x004C,
|
||||
QMK_KC_END = 0x004D,
|
||||
QMK_KC_PAGE_DOWN = 0x004E,
|
||||
QMK_KC_RIGHT = 0x004F,
|
||||
QMK_KC_LEFT = 0x0050,
|
||||
QMK_KC_DOWN = 0x0051,
|
||||
QMK_KC_UP = 0x0052,
|
||||
QMK_KC_NUM_LOCK = 0x0053,
|
||||
QMK_KC_KP_SLASH = 0x0054,
|
||||
QMK_KC_KP_ASTERISK = 0x0055,
|
||||
QMK_KC_KP_MINUS = 0x0056,
|
||||
QMK_KC_KP_PLUS = 0x0057,
|
||||
QMK_KC_KP_ENTER = 0x0058,
|
||||
QMK_KC_KP_1 = 0x0059,
|
||||
QMK_KC_KP_2 = 0x005A,
|
||||
QMK_KC_KP_3 = 0x005B,
|
||||
QMK_KC_KP_4 = 0x005C,
|
||||
QMK_KC_KP_5 = 0x005D,
|
||||
QMK_KC_KP_6 = 0x005E,
|
||||
QMK_KC_KP_7 = 0x005F,
|
||||
QMK_KC_KP_8 = 0x0060,
|
||||
QMK_KC_KP_9 = 0x0061,
|
||||
QMK_KC_KP_0 = 0x0062,
|
||||
QMK_KC_KP_DOT = 0x0063,
|
||||
QMK_KC_NONUS_BACKSLASH = 0x0064,
|
||||
QMK_KC_APPLICATION = 0x0065,
|
||||
QMK_KC_KB_POWER = 0x0066,
|
||||
QMK_KC_KP_EQUAL = 0x0067,
|
||||
QMK_KC_F13 = 0x0068,
|
||||
QMK_KC_F14 = 0x0069,
|
||||
QMK_KC_F15 = 0x006A,
|
||||
QMK_KC_F16 = 0x006B,
|
||||
QMK_KC_F17 = 0x006C,
|
||||
QMK_KC_F18 = 0x006D,
|
||||
QMK_KC_F19 = 0x006E,
|
||||
QMK_KC_F20 = 0x006F,
|
||||
QMK_KC_F21 = 0x0070,
|
||||
QMK_KC_F22 = 0x0071,
|
||||
QMK_KC_F23 = 0x0072,
|
||||
QMK_KC_F24 = 0x0073,
|
||||
QMK_KC_EXECUTE = 0x0074,
|
||||
QMK_KC_HELP = 0x0075,
|
||||
QMK_KC_MENU = 0x0076,
|
||||
QMK_KC_SELECT = 0x0077,
|
||||
QMK_KC_STOP = 0x0078,
|
||||
QMK_KC_AGAIN = 0x0079,
|
||||
QMK_KC_UNDO = 0x007A,
|
||||
QMK_KC_CUT = 0x007B,
|
||||
QMK_KC_COPY = 0x007C,
|
||||
QMK_KC_PASTE = 0x007D,
|
||||
QMK_KC_FIND = 0x007E,
|
||||
QMK_KC_KB_MUTE = 0x007F,
|
||||
QMK_KC_KB_VOLUME_UP = 0x0080,
|
||||
QMK_KC_KB_VOLUME_DOWN = 0x0081,
|
||||
QMK_KC_LOCKING_CAPS_LOCK = 0x0082,
|
||||
QMK_KC_LOCKING_NUM_LOCK = 0x0083,
|
||||
QMK_KC_LOCKING_SCROLL_LOCK = 0x0084,
|
||||
QMK_KC_KP_COMMA = 0x0085,
|
||||
QMK_KC_KP_EQUAL_AS400 = 0x0086,
|
||||
QMK_KC_INTERNATIONAL_1 = 0x0087,
|
||||
QMK_KC_INTERNATIONAL_2 = 0x0088,
|
||||
QMK_KC_INTERNATIONAL_3 = 0x0089,
|
||||
QMK_KC_INTERNATIONAL_4 = 0x008A,
|
||||
QMK_KC_INTERNATIONAL_5 = 0x008B,
|
||||
QMK_KC_INTERNATIONAL_6 = 0x008C,
|
||||
QMK_KC_INTERNATIONAL_7 = 0x008D,
|
||||
QMK_KC_INTERNATIONAL_8 = 0x008E,
|
||||
QMK_KC_INTERNATIONAL_9 = 0x008F,
|
||||
QMK_KC_LANGUAGE_1 = 0x0090,
|
||||
QMK_KC_LANGUAGE_2 = 0x0091,
|
||||
QMK_KC_LANGUAGE_3 = 0x0092,
|
||||
QMK_KC_LANGUAGE_4 = 0x0093,
|
||||
QMK_KC_LANGUAGE_5 = 0x0094,
|
||||
QMK_KC_LANGUAGE_6 = 0x0095,
|
||||
QMK_KC_LANGUAGE_7 = 0x0096,
|
||||
QMK_KC_LANGUAGE_8 = 0x0097,
|
||||
QMK_KC_LANGUAGE_9 = 0x0098,
|
||||
QMK_KC_ALTERNATE_ERASE = 0x0099,
|
||||
QMK_KC_SYSTEM_REQUEST = 0x009A,
|
||||
QMK_KC_CANCEL = 0x009B,
|
||||
QMK_KC_CLEAR = 0x009C,
|
||||
QMK_KC_PRIOR = 0x009D,
|
||||
QMK_KC_RETURN = 0x009E,
|
||||
QMK_KC_SEPARATOR = 0x009F,
|
||||
QMK_KC_OUT = 0x00A0,
|
||||
QMK_KC_OPER = 0x00A1,
|
||||
QMK_KC_CLEAR_AGAIN = 0x00A2,
|
||||
QMK_KC_CRSEL = 0x00A3,
|
||||
QMK_KC_EXSEL = 0x00A4,
|
||||
QMK_KC_SYSTEM_POWER = 0x00A5,
|
||||
QMK_KC_SYSTEM_SLEEP = 0x00A6,
|
||||
QMK_KC_SYSTEM_WAKE = 0x00A7,
|
||||
QMK_KC_AUDIO_MUTE = 0x00A8,
|
||||
QMK_KC_AUDIO_VOL_UP = 0x00A9,
|
||||
QMK_KC_AUDIO_VOL_DOWN = 0x00AA,
|
||||
QMK_KC_MEDIA_NEXT_TRACK = 0x00AB,
|
||||
QMK_KC_MEDIA_PREV_TRACK = 0x00AC,
|
||||
QMK_KC_MEDIA_STOP = 0x00AD,
|
||||
QMK_KC_MEDIA_PLAY_PAUSE = 0x00AE,
|
||||
QMK_KC_MEDIA_SELECT = 0x00AF,
|
||||
QMK_KC_MEDIA_EJECT = 0x00B0,
|
||||
QMK_KC_MAIL = 0x00B1,
|
||||
QMK_KC_CALCULATOR = 0x00B2,
|
||||
QMK_KC_MY_COMPUTER = 0x00B3,
|
||||
QMK_KC_WWW_SEARCH = 0x00B4,
|
||||
QMK_KC_WWW_HOME = 0x00B5,
|
||||
QMK_KC_WWW_BACK = 0x00B6,
|
||||
QMK_KC_WWW_FORWARD = 0x00B7,
|
||||
QMK_KC_WWW_STOP = 0x00B8,
|
||||
QMK_KC_WWW_REFRESH = 0x00B9,
|
||||
QMK_KC_WWW_FAVORITES = 0x00BA,
|
||||
QMK_KC_MEDIA_FAST_FORWARD = 0x00BB,
|
||||
QMK_KC_MEDIA_REWIND = 0x00BC,
|
||||
QMK_KC_BRIGHTNESS_UP = 0x00BD,
|
||||
QMK_KC_BRIGHTNESS_DOWN = 0x00BE,
|
||||
QMK_KC_CONTROL_PANEL = 0x00BF,
|
||||
QMK_KC_ASSISTANT = 0x00C0,
|
||||
QMK_KC_MISSION_CONTROL = 0x00C1,
|
||||
QMK_KC_LAUNCHPAD = 0x00C2,
|
||||
QMK_QK_MOUSE_CURSOR_UP = 0x00CD,
|
||||
QMK_QK_MOUSE_CURSOR_DOWN = 0x00CE,
|
||||
QMK_QK_MOUSE_CURSOR_LEFT = 0x00CF,
|
||||
QMK_QK_MOUSE_CURSOR_RIGHT = 0x00D0,
|
||||
QMK_QK_MOUSE_BUTTON_1 = 0x00D1,
|
||||
QMK_QK_MOUSE_BUTTON_2 = 0x00D2,
|
||||
QMK_QK_MOUSE_BUTTON_3 = 0x00D3,
|
||||
QMK_QK_MOUSE_BUTTON_4 = 0x00D4,
|
||||
QMK_QK_MOUSE_BUTTON_5 = 0x00D5,
|
||||
QMK_QK_MOUSE_BUTTON_6 = 0x00D6,
|
||||
QMK_QK_MOUSE_BUTTON_7 = 0x00D7,
|
||||
QMK_QK_MOUSE_BUTTON_8 = 0x00D8,
|
||||
QMK_QK_MOUSE_WHEEL_UP = 0x00D9,
|
||||
QMK_QK_MOUSE_WHEEL_DOWN = 0x00DA,
|
||||
QMK_QK_MOUSE_WHEEL_LEFT = 0x00DB,
|
||||
QMK_QK_MOUSE_WHEEL_RIGHT = 0x00DC,
|
||||
QMK_QK_MOUSE_ACCELERATION_0 = 0x00DD,
|
||||
QMK_QK_MOUSE_ACCELERATION_1 = 0x00DE,
|
||||
QMK_QK_MOUSE_ACCELERATION_2 = 0x00DF,
|
||||
QMK_KC_LEFT_CTRL = 0x00E0,
|
||||
QMK_KC_LEFT_SHIFT = 0x00E1,
|
||||
QMK_KC_LEFT_ALT = 0x00E2,
|
||||
QMK_KC_LEFT_GUI = 0x00E3,
|
||||
QMK_KC_RIGHT_CTRL = 0x00E4,
|
||||
QMK_KC_RIGHT_SHIFT = 0x00E5,
|
||||
QMK_KC_RIGHT_ALT = 0x00E6,
|
||||
QMK_KC_RIGHT_GUI = 0x00E7,
|
||||
QMK_QK_SWAP_HANDS_TOGGLE = 0x56F0,
|
||||
QMK_QK_SWAP_HANDS_TAP_TOGGLE = 0x56F1,
|
||||
QMK_QK_SWAP_HANDS_MOMENTARY_ON = 0x56F2,
|
||||
QMK_QK_SWAP_HANDS_MOMENTARY_OFF = 0x56F3,
|
||||
QMK_QK_SWAP_HANDS_OFF = 0x56F4,
|
||||
QMK_QK_SWAP_HANDS_ON = 0x56F5,
|
||||
QMK_QK_SWAP_HANDS_ONE_SHOT = 0x56F6,
|
||||
QMK_QK_MAGIC_SWAP_CONTROL_CAPS_LOCK = 0x7000,
|
||||
QMK_QK_MAGIC_UNSWAP_CONTROL_CAPS_LOCK = 0x7001,
|
||||
QMK_QK_MAGIC_TOGGLE_CONTROL_CAPS_LOCK = 0x7002,
|
||||
QMK_QK_MAGIC_CAPS_LOCK_AS_CONTROL_OFF = 0x7003,
|
||||
QMK_QK_MAGIC_CAPS_LOCK_AS_CONTROL_ON = 0x7004,
|
||||
QMK_QK_MAGIC_SWAP_LALT_LGUI = 0x7005,
|
||||
QMK_QK_MAGIC_UNSWAP_LALT_LGUI = 0x7006,
|
||||
QMK_QK_MAGIC_SWAP_RALT_RGUI = 0x7007,
|
||||
QMK_QK_MAGIC_UNSWAP_RALT_RGUI = 0x7008,
|
||||
QMK_QK_MAGIC_GUI_ON = 0x7009,
|
||||
QMK_QK_MAGIC_GUI_OFF = 0x700A,
|
||||
QMK_QK_MAGIC_TOGGLE_GUI = 0x700B,
|
||||
QMK_QK_MAGIC_SWAP_GRAVE_ESC = 0x700C,
|
||||
QMK_QK_MAGIC_UNSWAP_GRAVE_ESC = 0x700D,
|
||||
QMK_QK_MAGIC_SWAP_BACKSLASH_BACKSPACE = 0x700E,
|
||||
QMK_QK_MAGIC_UNSWAP_BACKSLASH_BACKSPACE = 0x700F,
|
||||
QMK_QK_MAGIC_TOGGLE_BACKSLASH_BACKSPACE = 0x7010,
|
||||
QMK_QK_MAGIC_NKRO_ON = 0x7011,
|
||||
QMK_QK_MAGIC_NKRO_OFF = 0x7012,
|
||||
QMK_QK_MAGIC_TOGGLE_NKRO = 0x7013,
|
||||
QMK_QK_MAGIC_SWAP_ALT_GUI = 0x7014,
|
||||
QMK_QK_MAGIC_UNSWAP_ALT_GUI = 0x7015,
|
||||
QMK_QK_MAGIC_TOGGLE_ALT_GUI = 0x7016,
|
||||
QMK_QK_MAGIC_SWAP_LCTL_LGUI = 0x7017,
|
||||
QMK_QK_MAGIC_UNSWAP_LCTL_LGUI = 0x7018,
|
||||
QMK_QK_MAGIC_SWAP_RCTL_RGUI = 0x7019,
|
||||
QMK_QK_MAGIC_UNSWAP_RCTL_RGUI = 0x701A,
|
||||
QMK_QK_MAGIC_SWAP_CTL_GUI = 0x701B,
|
||||
QMK_QK_MAGIC_UNSWAP_CTL_GUI = 0x701C,
|
||||
QMK_QK_MAGIC_TOGGLE_CTL_GUI = 0x701D,
|
||||
QMK_QK_MAGIC_EE_HANDS_LEFT = 0x701E,
|
||||
QMK_QK_MAGIC_EE_HANDS_RIGHT = 0x701F,
|
||||
QMK_QK_MAGIC_SWAP_ESCAPE_CAPS_LOCK = 0x7020,
|
||||
QMK_QK_MAGIC_UNSWAP_ESCAPE_CAPS_LOCK = 0x7021,
|
||||
QMK_QK_MAGIC_TOGGLE_ESCAPE_CAPS_LOCK = 0x7022,
|
||||
QMK_QK_MIDI_ON = 0x7100,
|
||||
QMK_QK_MIDI_OFF = 0x7101,
|
||||
QMK_QK_MIDI_TOGGLE = 0x7102,
|
||||
QMK_QK_MIDI_NOTE_C_0 = 0x7103,
|
||||
QMK_QK_MIDI_NOTE_C_SHARP_0 = 0x7104,
|
||||
QMK_QK_MIDI_NOTE_D_0 = 0x7105,
|
||||
QMK_QK_MIDI_NOTE_D_SHARP_0 = 0x7106,
|
||||
QMK_QK_MIDI_NOTE_E_0 = 0x7107,
|
||||
QMK_QK_MIDI_NOTE_F_0 = 0x7108,
|
||||
QMK_QK_MIDI_NOTE_F_SHARP_0 = 0x7109,
|
||||
QMK_QK_MIDI_NOTE_G_0 = 0x710A,
|
||||
QMK_QK_MIDI_NOTE_G_SHARP_0 = 0x710B,
|
||||
QMK_QK_MIDI_NOTE_A_0 = 0x710C,
|
||||
QMK_QK_MIDI_NOTE_A_SHARP_0 = 0x710D,
|
||||
QMK_QK_MIDI_NOTE_B_0 = 0x710E,
|
||||
QMK_QK_MIDI_NOTE_C_1 = 0x710F,
|
||||
QMK_QK_MIDI_NOTE_C_SHARP_1 = 0x7110,
|
||||
QMK_QK_MIDI_NOTE_D_1 = 0x7111,
|
||||
QMK_QK_MIDI_NOTE_D_SHARP_1 = 0x7112,
|
||||
QMK_QK_MIDI_NOTE_E_1 = 0x7113,
|
||||
QMK_QK_MIDI_NOTE_F_1 = 0x7114,
|
||||
QMK_QK_MIDI_NOTE_F_SHARP_1 = 0x7115,
|
||||
QMK_QK_MIDI_NOTE_G_1 = 0x7116,
|
||||
QMK_QK_MIDI_NOTE_G_SHARP_1 = 0x7117,
|
||||
QMK_QK_MIDI_NOTE_A_1 = 0x7118,
|
||||
QMK_QK_MIDI_NOTE_A_SHARP_1 = 0x7119,
|
||||
QMK_QK_MIDI_NOTE_B_1 = 0x711A,
|
||||
QMK_QK_MIDI_NOTE_C_2 = 0x711B,
|
||||
QMK_QK_MIDI_NOTE_C_SHARP_2 = 0x711C,
|
||||
QMK_QK_MIDI_NOTE_D_2 = 0x711D,
|
||||
QMK_QK_MIDI_NOTE_D_SHARP_2 = 0x711E,
|
||||
QMK_QK_MIDI_NOTE_E_2 = 0x711F,
|
||||
QMK_QK_MIDI_NOTE_F_2 = 0x7120,
|
||||
QMK_QK_MIDI_NOTE_F_SHARP_2 = 0x7121,
|
||||
QMK_QK_MIDI_NOTE_G_2 = 0x7122,
|
||||
QMK_QK_MIDI_NOTE_G_SHARP_2 = 0x7123,
|
||||
QMK_QK_MIDI_NOTE_A_2 = 0x7124,
|
||||
QMK_QK_MIDI_NOTE_A_SHARP_2 = 0x7125,
|
||||
QMK_QK_MIDI_NOTE_B_2 = 0x7126,
|
||||
QMK_QK_MIDI_NOTE_C_3 = 0x7127,
|
||||
QMK_QK_MIDI_NOTE_C_SHARP_3 = 0x7128,
|
||||
QMK_QK_MIDI_NOTE_D_3 = 0x7129,
|
||||
QMK_QK_MIDI_NOTE_D_SHARP_3 = 0x712A,
|
||||
QMK_QK_MIDI_NOTE_E_3 = 0x712B,
|
||||
QMK_QK_MIDI_NOTE_F_3 = 0x712C,
|
||||
QMK_QK_MIDI_NOTE_F_SHARP_3 = 0x712D,
|
||||
QMK_QK_MIDI_NOTE_G_3 = 0x712E,
|
||||
QMK_QK_MIDI_NOTE_G_SHARP_3 = 0x712F,
|
||||
QMK_QK_MIDI_NOTE_A_3 = 0x7130,
|
||||
QMK_QK_MIDI_NOTE_A_SHARP_3 = 0x7131,
|
||||
QMK_QK_MIDI_NOTE_B_3 = 0x7132,
|
||||
QMK_QK_MIDI_NOTE_C_4 = 0x7133,
|
||||
QMK_QK_MIDI_NOTE_C_SHARP_4 = 0x7134,
|
||||
QMK_QK_MIDI_NOTE_D_4 = 0x7135,
|
||||
QMK_QK_MIDI_NOTE_D_SHARP_4 = 0x7136,
|
||||
QMK_QK_MIDI_NOTE_E_4 = 0x7137,
|
||||
QMK_QK_MIDI_NOTE_F_4 = 0x7138,
|
||||
QMK_QK_MIDI_NOTE_F_SHARP_4 = 0x7139,
|
||||
QMK_QK_MIDI_NOTE_G_4 = 0x713A,
|
||||
QMK_QK_MIDI_NOTE_G_SHARP_4 = 0x713B,
|
||||
QMK_QK_MIDI_NOTE_A_4 = 0x713C,
|
||||
QMK_QK_MIDI_NOTE_A_SHARP_4 = 0x713D,
|
||||
QMK_QK_MIDI_NOTE_B_4 = 0x713E,
|
||||
QMK_QK_MIDI_NOTE_C_5 = 0x713F,
|
||||
QMK_QK_MIDI_NOTE_C_SHARP_5 = 0x7140,
|
||||
QMK_QK_MIDI_NOTE_D_5 = 0x7141,
|
||||
QMK_QK_MIDI_NOTE_D_SHARP_5 = 0x7142,
|
||||
QMK_QK_MIDI_NOTE_E_5 = 0x7143,
|
||||
QMK_QK_MIDI_NOTE_F_5 = 0x7144,
|
||||
QMK_QK_MIDI_NOTE_F_SHARP_5 = 0x7145,
|
||||
QMK_QK_MIDI_NOTE_G_5 = 0x7146,
|
||||
QMK_QK_MIDI_NOTE_G_SHARP_5 = 0x7147,
|
||||
QMK_QK_MIDI_NOTE_A_5 = 0x7148,
|
||||
QMK_QK_MIDI_NOTE_A_SHARP_5 = 0x7149,
|
||||
QMK_QK_MIDI_NOTE_B_5 = 0x714A,
|
||||
QMK_QK_MIDI_OCTAVE_N2 = 0x714B,
|
||||
QMK_QK_MIDI_OCTAVE_N1 = 0x714C,
|
||||
QMK_QK_MIDI_OCTAVE_0 = 0x714D,
|
||||
QMK_QK_MIDI_OCTAVE_1 = 0x714E,
|
||||
QMK_QK_MIDI_OCTAVE_2 = 0x714F,
|
||||
QMK_QK_MIDI_OCTAVE_3 = 0x7150,
|
||||
QMK_QK_MIDI_OCTAVE_4 = 0x7151,
|
||||
QMK_QK_MIDI_OCTAVE_5 = 0x7152,
|
||||
QMK_QK_MIDI_OCTAVE_6 = 0x7153,
|
||||
QMK_QK_MIDI_OCTAVE_7 = 0x7154,
|
||||
QMK_QK_MIDI_OCTAVE_DOWN = 0x7155,
|
||||
QMK_QK_MIDI_OCTAVE_UP = 0x7156,
|
||||
QMK_QK_MIDI_TRANSPOSE_N6 = 0x7157,
|
||||
QMK_QK_MIDI_TRANSPOSE_N5 = 0x7158,
|
||||
QMK_QK_MIDI_TRANSPOSE_N4 = 0x7159,
|
||||
QMK_QK_MIDI_TRANSPOSE_N3 = 0x715A,
|
||||
QMK_QK_MIDI_TRANSPOSE_N2 = 0x715B,
|
||||
QMK_QK_MIDI_TRANSPOSE_N1 = 0x715C,
|
||||
QMK_QK_MIDI_TRANSPOSE_0 = 0x715D,
|
||||
QMK_QK_MIDI_TRANSPOSE_1 = 0x715E,
|
||||
QMK_QK_MIDI_TRANSPOSE_2 = 0x715F,
|
||||
QMK_QK_MIDI_TRANSPOSE_3 = 0x7160,
|
||||
QMK_QK_MIDI_TRANSPOSE_4 = 0x7161,
|
||||
QMK_QK_MIDI_TRANSPOSE_5 = 0x7162,
|
||||
QMK_QK_MIDI_TRANSPOSE_6 = 0x7163,
|
||||
QMK_QK_MIDI_TRANSPOSE_DOWN = 0x7164,
|
||||
QMK_QK_MIDI_TRANSPOSE_UP = 0x7165,
|
||||
QMK_QK_MIDI_VELOCITY_0 = 0x7166,
|
||||
QMK_QK_MIDI_VELOCITY_1 = 0x7167,
|
||||
QMK_QK_MIDI_VELOCITY_2 = 0x7168,
|
||||
QMK_QK_MIDI_VELOCITY_3 = 0x7169,
|
||||
QMK_QK_MIDI_VELOCITY_4 = 0x716A,
|
||||
QMK_QK_MIDI_VELOCITY_5 = 0x716B,
|
||||
QMK_QK_MIDI_VELOCITY_6 = 0x716C,
|
||||
QMK_QK_MIDI_VELOCITY_7 = 0x716D,
|
||||
QMK_QK_MIDI_VELOCITY_8 = 0x716E,
|
||||
QMK_QK_MIDI_VELOCITY_9 = 0x716F,
|
||||
QMK_QK_MIDI_VELOCITY_10 = 0x7170,
|
||||
QMK_QK_MIDI_VELOCITY_DOWN = 0x7171,
|
||||
QMK_QK_MIDI_VELOCITY_UP = 0x7172,
|
||||
QMK_QK_MIDI_CHANNEL_1 = 0x7173,
|
||||
QMK_QK_MIDI_CHANNEL_2 = 0x7174,
|
||||
QMK_QK_MIDI_CHANNEL_3 = 0x7175,
|
||||
QMK_QK_MIDI_CHANNEL_4 = 0x7176,
|
||||
QMK_QK_MIDI_CHANNEL_5 = 0x7177,
|
||||
QMK_QK_MIDI_CHANNEL_6 = 0x7178,
|
||||
QMK_QK_MIDI_CHANNEL_7 = 0x7179,
|
||||
QMK_QK_MIDI_CHANNEL_8 = 0x717A,
|
||||
QMK_QK_MIDI_CHANNEL_9 = 0x717B,
|
||||
QMK_QK_MIDI_CHANNEL_10 = 0x717C,
|
||||
QMK_QK_MIDI_CHANNEL_11 = 0x717D,
|
||||
QMK_QK_MIDI_CHANNEL_12 = 0x717E,
|
||||
QMK_QK_MIDI_CHANNEL_13 = 0x717F,
|
||||
QMK_QK_MIDI_CHANNEL_14 = 0x7180,
|
||||
QMK_QK_MIDI_CHANNEL_15 = 0x7181,
|
||||
QMK_QK_MIDI_CHANNEL_16 = 0x7182,
|
||||
QMK_QK_MIDI_CHANNEL_DOWN = 0x7183,
|
||||
QMK_QK_MIDI_CHANNEL_UP = 0x7184,
|
||||
QMK_QK_MIDI_ALL_NOTES_OFF = 0x7185,
|
||||
QMK_QK_MIDI_SUSTAIN = 0x7186,
|
||||
QMK_QK_MIDI_PORTAMENTO = 0x7187,
|
||||
QMK_QK_MIDI_SOSTENUTO = 0x7188,
|
||||
QMK_QK_MIDI_SOFT = 0x7189,
|
||||
QMK_QK_MIDI_LEGATO = 0x718A,
|
||||
QMK_QK_MIDI_MODULATION = 0x718B,
|
||||
QMK_QK_MIDI_MODULATION_SPEED_DOWN = 0x718C,
|
||||
QMK_QK_MIDI_MODULATION_SPEED_UP = 0x718D,
|
||||
QMK_QK_MIDI_PITCH_BEND_DOWN = 0x718E,
|
||||
QMK_QK_MIDI_PITCH_BEND_UP = 0x718F,
|
||||
QMK_QK_SEQUENCER_ON = 0x7200,
|
||||
QMK_QK_SEQUENCER_OFF = 0x7201,
|
||||
QMK_QK_SEQUENCER_TOGGLE = 0x7202,
|
||||
QMK_QK_SEQUENCER_TEMPO_DOWN = 0x7203,
|
||||
QMK_QK_SEQUENCER_TEMPO_UP = 0x7204,
|
||||
QMK_QK_SEQUENCER_RESOLUTION_DOWN = 0x7205,
|
||||
QMK_QK_SEQUENCER_RESOLUTION_UP = 0x7206,
|
||||
QMK_QK_SEQUENCER_STEPS_ALL = 0x7207,
|
||||
QMK_QK_SEQUENCER_STEPS_CLEAR = 0x7208,
|
||||
QMK_QK_JOYSTICK_BUTTON_0 = 0x7400,
|
||||
QMK_QK_JOYSTICK_BUTTON_1 = 0x7401,
|
||||
QMK_QK_JOYSTICK_BUTTON_2 = 0x7402,
|
||||
QMK_QK_JOYSTICK_BUTTON_3 = 0x7403,
|
||||
QMK_QK_JOYSTICK_BUTTON_4 = 0x7404,
|
||||
QMK_QK_JOYSTICK_BUTTON_5 = 0x7405,
|
||||
QMK_QK_JOYSTICK_BUTTON_6 = 0x7406,
|
||||
QMK_QK_JOYSTICK_BUTTON_7 = 0x7407,
|
||||
QMK_QK_JOYSTICK_BUTTON_8 = 0x7408,
|
||||
QMK_QK_JOYSTICK_BUTTON_9 = 0x7409,
|
||||
QMK_QK_JOYSTICK_BUTTON_10 = 0x740A,
|
||||
QMK_QK_JOYSTICK_BUTTON_11 = 0x740B,
|
||||
QMK_QK_JOYSTICK_BUTTON_12 = 0x740C,
|
||||
QMK_QK_JOYSTICK_BUTTON_13 = 0x740D,
|
||||
QMK_QK_JOYSTICK_BUTTON_14 = 0x740E,
|
||||
QMK_QK_JOYSTICK_BUTTON_15 = 0x740F,
|
||||
QMK_QK_JOYSTICK_BUTTON_16 = 0x7410,
|
||||
QMK_QK_JOYSTICK_BUTTON_17 = 0x7411,
|
||||
QMK_QK_JOYSTICK_BUTTON_18 = 0x7412,
|
||||
QMK_QK_JOYSTICK_BUTTON_19 = 0x7413,
|
||||
QMK_QK_JOYSTICK_BUTTON_20 = 0x7414,
|
||||
QMK_QK_JOYSTICK_BUTTON_21 = 0x7415,
|
||||
QMK_QK_JOYSTICK_BUTTON_22 = 0x7416,
|
||||
QMK_QK_JOYSTICK_BUTTON_23 = 0x7417,
|
||||
QMK_QK_JOYSTICK_BUTTON_24 = 0x7418,
|
||||
QMK_QK_JOYSTICK_BUTTON_25 = 0x7419,
|
||||
QMK_QK_JOYSTICK_BUTTON_26 = 0x741A,
|
||||
QMK_QK_JOYSTICK_BUTTON_27 = 0x741B,
|
||||
QMK_QK_JOYSTICK_BUTTON_28 = 0x741C,
|
||||
QMK_QK_JOYSTICK_BUTTON_29 = 0x741D,
|
||||
QMK_QK_JOYSTICK_BUTTON_30 = 0x741E,
|
||||
QMK_QK_JOYSTICK_BUTTON_31 = 0x741F,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_1 = 0x7440,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_2 = 0x7441,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_3 = 0x7442,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_4 = 0x7443,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_5 = 0x7444,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_6 = 0x7445,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_7 = 0x7446,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_8 = 0x7447,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_9 = 0x7448,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_10 = 0x7449,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_11 = 0x744A,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_12 = 0x744B,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_13 = 0x744C,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_14 = 0x744D,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_15 = 0x744E,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_16 = 0x744F,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_17 = 0x7450,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_18 = 0x7451,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_19 = 0x7452,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_20 = 0x7453,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_21 = 0x7454,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_22 = 0x7455,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_23 = 0x7456,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_24 = 0x7457,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_25 = 0x7458,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_26 = 0x7459,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_27 = 0x745A,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_28 = 0x745B,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_29 = 0x745C,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_30 = 0x745D,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_31 = 0x745E,
|
||||
QMK_QK_PROGRAMMABLE_BUTTON_32 = 0x745F,
|
||||
QMK_QK_AUDIO_ON = 0x7480,
|
||||
QMK_QK_AUDIO_OFF = 0x7481,
|
||||
QMK_QK_AUDIO_TOGGLE = 0x7482,
|
||||
QMK_QK_AUDIO_CLICKY_TOGGLE = 0x748A,
|
||||
QMK_QK_AUDIO_CLICKY_ON = 0x748B,
|
||||
QMK_QK_AUDIO_CLICKY_OFF = 0x748C,
|
||||
QMK_QK_AUDIO_CLICKY_UP = 0x748D,
|
||||
QMK_QK_AUDIO_CLICKY_DOWN = 0x748E,
|
||||
QMK_QK_AUDIO_CLICKY_RESET = 0x748F,
|
||||
QMK_QK_MUSIC_ON = 0x7490,
|
||||
QMK_QK_MUSIC_OFF = 0x7491,
|
||||
QMK_QK_MUSIC_TOGGLE = 0x7492,
|
||||
QMK_QK_MUSIC_MODE_NEXT = 0x7493,
|
||||
QMK_QK_AUDIO_VOICE_NEXT = 0x7494,
|
||||
QMK_QK_AUDIO_VOICE_PREVIOUS = 0x7495,
|
||||
QMK_QK_STENO_BOLT = 0x74F0,
|
||||
QMK_QK_STENO_GEMINI = 0x74F1,
|
||||
QMK_QK_STENO_COMB = 0x74F2,
|
||||
QMK_QK_STENO_COMB_MAX = 0x74FC,
|
||||
QMK_QK_MACRO_0 = 0x7700,
|
||||
QMK_QK_MACRO_1 = 0x7701,
|
||||
QMK_QK_MACRO_2 = 0x7702,
|
||||
QMK_QK_MACRO_3 = 0x7703,
|
||||
QMK_QK_MACRO_4 = 0x7704,
|
||||
QMK_QK_MACRO_5 = 0x7705,
|
||||
QMK_QK_MACRO_6 = 0x7706,
|
||||
QMK_QK_MACRO_7 = 0x7707,
|
||||
QMK_QK_MACRO_8 = 0x7708,
|
||||
QMK_QK_MACRO_9 = 0x7709,
|
||||
QMK_QK_MACRO_10 = 0x770A,
|
||||
QMK_QK_MACRO_11 = 0x770B,
|
||||
QMK_QK_MACRO_12 = 0x770C,
|
||||
QMK_QK_MACRO_13 = 0x770D,
|
||||
QMK_QK_MACRO_14 = 0x770E,
|
||||
QMK_QK_MACRO_15 = 0x770F,
|
||||
QMK_QK_MACRO_16 = 0x7710,
|
||||
QMK_QK_MACRO_17 = 0x7711,
|
||||
QMK_QK_MACRO_18 = 0x7712,
|
||||
QMK_QK_MACRO_19 = 0x7713,
|
||||
QMK_QK_MACRO_20 = 0x7714,
|
||||
QMK_QK_MACRO_21 = 0x7715,
|
||||
QMK_QK_MACRO_22 = 0x7716,
|
||||
QMK_QK_MACRO_23 = 0x7717,
|
||||
QMK_QK_MACRO_24 = 0x7718,
|
||||
QMK_QK_MACRO_25 = 0x7719,
|
||||
QMK_QK_MACRO_26 = 0x771A,
|
||||
QMK_QK_MACRO_27 = 0x771B,
|
||||
QMK_QK_MACRO_28 = 0x771C,
|
||||
QMK_QK_MACRO_29 = 0x771D,
|
||||
QMK_QK_MACRO_30 = 0x771E,
|
||||
QMK_QK_MACRO_31 = 0x771F,
|
||||
QMK_QK_OUTPUT_AUTO = 0x7780,
|
||||
QMK_QK_OUTPUT_NEXT = 0x7781,
|
||||
QMK_QK_OUTPUT_PREV = 0x7782,
|
||||
QMK_QK_OUTPUT_NONE = 0x7783,
|
||||
QMK_QK_OUTPUT_USB = 0x7784,
|
||||
QMK_QK_OUTPUT_2P4GHZ = 0x7785,
|
||||
QMK_QK_OUTPUT_BLUETOOTH = 0x7786,
|
||||
QMK_QK_BLUETOOTH_PROFILE_NEXT = 0x7790,
|
||||
QMK_QK_BLUETOOTH_PROFILE_PREV = 0x7791,
|
||||
QMK_QK_BLUETOOTH_UNPAIR = 0x7792,
|
||||
QMK_QK_BLUETOOTH_PROFILE1 = 0x7793,
|
||||
QMK_QK_BLUETOOTH_PROFILE2 = 0x7794,
|
||||
QMK_QK_BLUETOOTH_PROFILE3 = 0x7795,
|
||||
QMK_QK_BLUETOOTH_PROFILE4 = 0x7796,
|
||||
QMK_QK_BLUETOOTH_PROFILE5 = 0x7797,
|
||||
QMK_QK_BACKLIGHT_ON = 0x7800,
|
||||
QMK_QK_BACKLIGHT_OFF = 0x7801,
|
||||
QMK_QK_BACKLIGHT_TOGGLE = 0x7802,
|
||||
QMK_QK_BACKLIGHT_DOWN = 0x7803,
|
||||
QMK_QK_BACKLIGHT_UP = 0x7804,
|
||||
QMK_QK_BACKLIGHT_STEP = 0x7805,
|
||||
QMK_QK_BACKLIGHT_TOGGLE_BREATHING = 0x7806,
|
||||
QMK_QK_LED_MATRIX_ON = 0x7810,
|
||||
QMK_QK_LED_MATRIX_OFF = 0x7811,
|
||||
QMK_QK_LED_MATRIX_TOGGLE = 0x7812,
|
||||
QMK_QK_LED_MATRIX_MODE_NEXT = 0x7813,
|
||||
QMK_QK_LED_MATRIX_MODE_PREVIOUS = 0x7814,
|
||||
QMK_QK_LED_MATRIX_BRIGHTNESS_UP = 0x7815,
|
||||
QMK_QK_LED_MATRIX_BRIGHTNESS_DOWN = 0x7816,
|
||||
QMK_QK_LED_MATRIX_SPEED_UP = 0x7817,
|
||||
QMK_QK_LED_MATRIX_SPEED_DOWN = 0x7818,
|
||||
QMK_QK_UNDERGLOW_TOGGLE = 0x7820,
|
||||
QMK_QK_UNDERGLOW_MODE_NEXT = 0x7821,
|
||||
QMK_QK_UNDERGLOW_MODE_PREVIOUS = 0x7822,
|
||||
QMK_QK_UNDERGLOW_HUE_UP = 0x7823,
|
||||
QMK_QK_UNDERGLOW_HUE_DOWN = 0x7824,
|
||||
QMK_QK_UNDERGLOW_SATURATION_UP = 0x7825,
|
||||
QMK_QK_UNDERGLOW_SATURATION_DOWN = 0x7826,
|
||||
QMK_QK_UNDERGLOW_VALUE_UP = 0x7827,
|
||||
QMK_QK_UNDERGLOW_VALUE_DOWN = 0x7828,
|
||||
QMK_QK_UNDERGLOW_SPEED_UP = 0x7829,
|
||||
QMK_QK_UNDERGLOW_SPEED_DOWN = 0x782A,
|
||||
QMK_RGB_MODE_PLAIN = 0x782B,
|
||||
QMK_RGB_MODE_BREATHE = 0x782C,
|
||||
QMK_RGB_MODE_RAINBOW = 0x782D,
|
||||
QMK_RGB_MODE_SWIRL = 0x782E,
|
||||
QMK_RGB_MODE_SNAKE = 0x782F,
|
||||
QMK_RGB_MODE_KNIGHT = 0x7830,
|
||||
QMK_RGB_MODE_XMAS = 0x7831,
|
||||
QMK_RGB_MODE_GRADIENT = 0x7832,
|
||||
QMK_RGB_MODE_RGBTEST = 0x7833,
|
||||
QMK_RGB_MODE_TWINKLE = 0x7834,
|
||||
QMK_QK_RGB_MATRIX_ON = 0x7840,
|
||||
QMK_QK_RGB_MATRIX_OFF = 0x7841,
|
||||
QMK_QK_RGB_MATRIX_TOGGLE = 0x7842,
|
||||
QMK_QK_RGB_MATRIX_MODE_NEXT = 0x7843,
|
||||
QMK_QK_RGB_MATRIX_MODE_PREVIOUS = 0x7844,
|
||||
QMK_QK_RGB_MATRIX_HUE_UP = 0x7845,
|
||||
QMK_QK_RGB_MATRIX_HUE_DOWN = 0x7846,
|
||||
QMK_QK_RGB_MATRIX_SATURATION_UP = 0x7847,
|
||||
QMK_QK_RGB_MATRIX_SATURATION_DOWN = 0x7848,
|
||||
QMK_QK_RGB_MATRIX_VALUE_UP = 0x7849,
|
||||
QMK_QK_RGB_MATRIX_VALUE_DOWN = 0x784A,
|
||||
QMK_QK_RGB_MATRIX_SPEED_UP = 0x784B,
|
||||
QMK_QK_RGB_MATRIX_SPEED_DOWN = 0x784C,
|
||||
QMK_QK_BOOTLOADER = 0x7C00,
|
||||
QMK_QK_REBOOT = 0x7C01,
|
||||
QMK_QK_DEBUG_TOGGLE = 0x7C02,
|
||||
QMK_QK_CLEAR_EEPROM = 0x7C03,
|
||||
QMK_QK_MAKE = 0x7C04,
|
||||
QMK_QK_AUTO_SHIFT_DOWN = 0x7C10,
|
||||
QMK_QK_AUTO_SHIFT_UP = 0x7C11,
|
||||
QMK_QK_AUTO_SHIFT_REPORT = 0x7C12,
|
||||
QMK_QK_AUTO_SHIFT_ON = 0x7C13,
|
||||
QMK_QK_AUTO_SHIFT_OFF = 0x7C14,
|
||||
QMK_QK_AUTO_SHIFT_TOGGLE = 0x7C15,
|
||||
QMK_QK_GRAVE_ESCAPE = 0x7C16,
|
||||
QMK_QK_VELOCIKEY_TOGGLE = 0x7C17,
|
||||
QMK_QK_SPACE_CADET_LEFT_CTRL_PARENTHESIS_OPEN = 0x7C18,
|
||||
QMK_QK_SPACE_CADET_RIGHT_CTRL_PARENTHESIS_CLOSE = 0x7C19,
|
||||
QMK_QK_SPACE_CADET_LEFT_SHIFT_PARENTHESIS_OPEN = 0x7C1A,
|
||||
QMK_QK_SPACE_CADET_RIGHT_SHIFT_PARENTHESIS_CLOSE = 0x7C1B,
|
||||
QMK_QK_SPACE_CADET_LEFT_ALT_PARENTHESIS_OPEN = 0x7C1C,
|
||||
QMK_QK_SPACE_CADET_RIGHT_ALT_PARENTHESIS_CLOSE = 0x7C1D,
|
||||
QMK_QK_SPACE_CADET_RIGHT_SHIFT_ENTER = 0x7C1E,
|
||||
QMK_QK_UNICODE_MODE_NEXT = 0x7C30,
|
||||
QMK_QK_UNICODE_MODE_PREVIOUS = 0x7C31,
|
||||
QMK_QK_UNICODE_MODE_MACOS = 0x7C32,
|
||||
QMK_QK_UNICODE_MODE_LINUX = 0x7C33,
|
||||
QMK_QK_UNICODE_MODE_WINDOWS = 0x7C34,
|
||||
QMK_QK_UNICODE_MODE_BSD = 0x7C35,
|
||||
QMK_QK_UNICODE_MODE_WINCOMPOSE = 0x7C36,
|
||||
QMK_QK_UNICODE_MODE_EMACS = 0x7C37,
|
||||
QMK_QK_HAPTIC_ON = 0x7C40,
|
||||
QMK_QK_HAPTIC_OFF = 0x7C41,
|
||||
QMK_QK_HAPTIC_TOGGLE = 0x7C42,
|
||||
QMK_QK_HAPTIC_RESET = 0x7C43,
|
||||
QMK_QK_HAPTIC_FEEDBACK_TOGGLE = 0x7C44,
|
||||
QMK_QK_HAPTIC_BUZZ_TOGGLE = 0x7C45,
|
||||
QMK_QK_HAPTIC_MODE_NEXT = 0x7C46,
|
||||
QMK_QK_HAPTIC_MODE_PREVIOUS = 0x7C47,
|
||||
QMK_QK_HAPTIC_CONTINUOUS_TOGGLE = 0x7C48,
|
||||
QMK_QK_HAPTIC_CONTINUOUS_UP = 0x7C49,
|
||||
QMK_QK_HAPTIC_CONTINUOUS_DOWN = 0x7C4A,
|
||||
QMK_QK_HAPTIC_DWELL_UP = 0x7C4B,
|
||||
QMK_QK_HAPTIC_DWELL_DOWN = 0x7C4C,
|
||||
QMK_QK_COMBO_ON = 0x7C50,
|
||||
QMK_QK_COMBO_OFF = 0x7C51,
|
||||
QMK_QK_COMBO_TOGGLE = 0x7C52,
|
||||
QMK_QK_DYNAMIC_MACRO_RECORD_START_1 = 0x7C53,
|
||||
QMK_QK_DYNAMIC_MACRO_RECORD_START_2 = 0x7C54,
|
||||
QMK_QK_DYNAMIC_MACRO_RECORD_STOP = 0x7C55,
|
||||
QMK_QK_DYNAMIC_MACRO_PLAY_1 = 0x7C56,
|
||||
QMK_QK_DYNAMIC_MACRO_PLAY_2 = 0x7C57,
|
||||
QMK_QK_LEADER = 0x7C58,
|
||||
QMK_QK_LOCK = 0x7C59,
|
||||
QMK_QK_ONE_SHOT_ON = 0x7C5A,
|
||||
QMK_QK_ONE_SHOT_OFF = 0x7C5B,
|
||||
QMK_QK_ONE_SHOT_TOGGLE = 0x7C5C,
|
||||
QMK_QK_KEY_OVERRIDE_TOGGLE = 0x7C5D,
|
||||
QMK_QK_KEY_OVERRIDE_ON = 0x7C5E,
|
||||
QMK_QK_KEY_OVERRIDE_OFF = 0x7C5F,
|
||||
QMK_QK_SECURE_LOCK = 0x7C60,
|
||||
QMK_QK_SECURE_UNLOCK = 0x7C61,
|
||||
QMK_QK_SECURE_TOGGLE = 0x7C62,
|
||||
QMK_QK_SECURE_REQUEST = 0x7C63,
|
||||
QMK_QK_DYNAMIC_TAPPING_TERM_PRINT = 0x7C70,
|
||||
QMK_QK_DYNAMIC_TAPPING_TERM_UP = 0x7C71,
|
||||
QMK_QK_DYNAMIC_TAPPING_TERM_DOWN = 0x7C72,
|
||||
QMK_QK_CAPS_WORD_TOGGLE = 0x7C73,
|
||||
QMK_QK_AUTOCORRECT_ON = 0x7C74,
|
||||
QMK_QK_AUTOCORRECT_OFF = 0x7C75,
|
||||
QMK_QK_AUTOCORRECT_TOGGLE = 0x7C76,
|
||||
QMK_QK_TRI_LAYER_LOWER = 0x7C77,
|
||||
QMK_QK_TRI_LAYER_UPPER = 0x7C78,
|
||||
QMK_QK_REPEAT_KEY = 0x7C79,
|
||||
QMK_QK_ALT_REPEAT_KEY = 0x7C7A,
|
||||
QMK_QK_LAYER_LOCK = 0x7C7B,
|
||||
QMK_QK_KB_0 = 0x7E00,
|
||||
QMK_QK_KB_1 = 0x7E01,
|
||||
QMK_QK_KB_2 = 0x7E02,
|
||||
QMK_QK_KB_3 = 0x7E03,
|
||||
QMK_QK_KB_4 = 0x7E04,
|
||||
QMK_QK_KB_5 = 0x7E05,
|
||||
QMK_QK_KB_6 = 0x7E06,
|
||||
QMK_QK_KB_7 = 0x7E07,
|
||||
QMK_QK_KB_8 = 0x7E08,
|
||||
QMK_QK_KB_9 = 0x7E09,
|
||||
QMK_QK_KB_10 = 0x7E0A,
|
||||
QMK_QK_KB_11 = 0x7E0B,
|
||||
QMK_QK_KB_12 = 0x7E0C,
|
||||
QMK_QK_KB_13 = 0x7E0D,
|
||||
QMK_QK_KB_14 = 0x7E0E,
|
||||
QMK_QK_KB_15 = 0x7E0F,
|
||||
QMK_QK_KB_16 = 0x7E10,
|
||||
QMK_QK_KB_17 = 0x7E11,
|
||||
QMK_QK_KB_18 = 0x7E12,
|
||||
QMK_QK_KB_19 = 0x7E13,
|
||||
QMK_QK_KB_20 = 0x7E14,
|
||||
QMK_QK_KB_21 = 0x7E15,
|
||||
QMK_QK_KB_22 = 0x7E16,
|
||||
QMK_QK_KB_23 = 0x7E17,
|
||||
QMK_QK_KB_24 = 0x7E18,
|
||||
QMK_QK_KB_25 = 0x7E19,
|
||||
QMK_QK_KB_26 = 0x7E1A,
|
||||
QMK_QK_KB_27 = 0x7E1B,
|
||||
QMK_QK_KB_28 = 0x7E1C,
|
||||
QMK_QK_KB_29 = 0x7E1D,
|
||||
QMK_QK_KB_30 = 0x7E1E,
|
||||
QMK_QK_KB_31 = 0x7E1F,
|
||||
QMK_QK_USER_0 = 0x7E40,
|
||||
QMK_QK_USER_1 = 0x7E41,
|
||||
QMK_QK_USER_2 = 0x7E42,
|
||||
QMK_QK_USER_3 = 0x7E43,
|
||||
QMK_QK_USER_4 = 0x7E44,
|
||||
QMK_QK_USER_5 = 0x7E45,
|
||||
QMK_QK_USER_6 = 0x7E46,
|
||||
QMK_QK_USER_7 = 0x7E47,
|
||||
QMK_QK_USER_8 = 0x7E48,
|
||||
QMK_QK_USER_9 = 0x7E49,
|
||||
QMK_QK_USER_10 = 0x7E4A,
|
||||
QMK_QK_USER_11 = 0x7E4B,
|
||||
QMK_QK_USER_12 = 0x7E4C,
|
||||
QMK_QK_USER_13 = 0x7E4D,
|
||||
QMK_QK_USER_14 = 0x7E4E,
|
||||
QMK_QK_USER_15 = 0x7E4F,
|
||||
QMK_QK_USER_16 = 0x7E50,
|
||||
QMK_QK_USER_17 = 0x7E51,
|
||||
QMK_QK_USER_18 = 0x7E52,
|
||||
QMK_QK_USER_19 = 0x7E53,
|
||||
QMK_QK_USER_20 = 0x7E54,
|
||||
QMK_QK_USER_21 = 0x7E55,
|
||||
QMK_QK_USER_22 = 0x7E56,
|
||||
QMK_QK_USER_23 = 0x7E57,
|
||||
QMK_QK_USER_24 = 0x7E58,
|
||||
QMK_QK_USER_25 = 0x7E59,
|
||||
QMK_QK_USER_26 = 0x7E5A,
|
||||
QMK_QK_USER_27 = 0x7E5B,
|
||||
QMK_QK_USER_28 = 0x7E5C,
|
||||
QMK_QK_USER_29 = 0x7E5D,
|
||||
QMK_QK_USER_30 = 0x7E5E,
|
||||
QMK_QK_USER_31 = 0x7E5F,
|
||||
};
|
||||
|
||||
extern std::map<qmk_keycode, std::string> qmk_keynames;
|
||||
@@ -0,0 +1,292 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKOpenRGBBaseController.cpp |
|
||||
| |
|
||||
| Common Driver for OpenRGB QMK Keyboard Protocol |
|
||||
| |
|
||||
| ChrisM 20 Dec 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "LogManager.h"
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "SettingsManager.h"
|
||||
#include "QMKOpenRGBBaseController.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
QMKOpenRGBBaseController::QMKOpenRGBBaseController(hid_device *dev_handle, const char *path, unsigned char max_led_count)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Get QMKOpenRGB settings |
|
||||
\*-------------------------------------------------*/
|
||||
json qmk_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("QMKOpenRGBDevices");
|
||||
if(qmk_settings.contains("leds_per_update"))
|
||||
{
|
||||
if(qmk_settings["leds_per_update"] > max_led_count)
|
||||
{
|
||||
qmk_settings["leds_per_update"] = max_led_count;
|
||||
}
|
||||
else if(qmk_settings["leds_per_update"] < 1)
|
||||
{
|
||||
qmk_settings["leds_per_update"] = 1;
|
||||
}
|
||||
SettingsManager* settings_manager = ResourceManager::get()->GetSettingsManager();
|
||||
settings_manager->SetSettings("QMKOpenRGBDevices", qmk_settings);
|
||||
settings_manager->SaveSettings();
|
||||
leds_per_update = qmk_settings["leds_per_update"];
|
||||
}
|
||||
else
|
||||
{
|
||||
leds_per_update = max_led_count;
|
||||
}
|
||||
|
||||
if(qmk_settings.contains("delay"))
|
||||
{
|
||||
delay = (unsigned int)qmk_settings["delay"] * 1ms;
|
||||
}
|
||||
else
|
||||
{
|
||||
delay = 0ms;
|
||||
}
|
||||
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
|
||||
GetDeviceInfo();
|
||||
GetModeInfo();
|
||||
}
|
||||
|
||||
QMKOpenRGBBaseController::~QMKOpenRGBBaseController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string QMKOpenRGBBaseController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string QMKOpenRGBBaseController::GetDeviceName()
|
||||
{
|
||||
return device_name;
|
||||
}
|
||||
|
||||
std::string QMKOpenRGBBaseController::GetDeviceVendor()
|
||||
{
|
||||
return device_vendor;
|
||||
}
|
||||
|
||||
unsigned int QMKOpenRGBBaseController::GetTotalNumberOfLEDs()
|
||||
{
|
||||
return total_number_of_leds;
|
||||
}
|
||||
|
||||
unsigned int QMKOpenRGBBaseController::GetTotalNumberOfLEDsWithEmptySpace()
|
||||
{
|
||||
return total_number_of_leds_with_empty_space;
|
||||
}
|
||||
|
||||
unsigned int QMKOpenRGBBaseController::GetMode()
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
|
||||
unsigned int QMKOpenRGBBaseController::GetModeSpeed()
|
||||
{
|
||||
return mode_speed;
|
||||
}
|
||||
|
||||
unsigned int QMKOpenRGBBaseController::GetModeColor()
|
||||
{
|
||||
return mode_color;
|
||||
}
|
||||
|
||||
std::vector<point_t> QMKOpenRGBBaseController::GetLEDPoints()
|
||||
{
|
||||
return led_points;
|
||||
}
|
||||
|
||||
std::vector<unsigned int> QMKOpenRGBBaseController::GetLEDFlags()
|
||||
{
|
||||
return led_flags;
|
||||
}
|
||||
|
||||
std::vector<std::string> QMKOpenRGBBaseController::GetLEDNames()
|
||||
{
|
||||
return led_names;
|
||||
}
|
||||
|
||||
std::vector<RGBColor> QMKOpenRGBBaseController::GetLEDColors()
|
||||
{
|
||||
return led_colors;
|
||||
}
|
||||
|
||||
unsigned int QMKOpenRGBBaseController::GetProtocolVersion()
|
||||
{
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_GET_PROTOCOL_VERSION;
|
||||
|
||||
int bytes_read = 0;
|
||||
do
|
||||
{
|
||||
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
|
||||
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_OPENRGB_HID_READ_TIMEOUT);
|
||||
} while(bytes_read <= 0);
|
||||
|
||||
return usb_buf[1];
|
||||
}
|
||||
|
||||
std::string QMKOpenRGBBaseController::GetQMKVersion()
|
||||
{
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_GET_QMK_VERSION;
|
||||
|
||||
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
|
||||
hid_read(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
std::string qmk_version;
|
||||
int i = 1;
|
||||
while (usb_buf[i] != 0)
|
||||
{
|
||||
qmk_version.push_back(usb_buf[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
return qmk_version;
|
||||
}
|
||||
|
||||
void QMKOpenRGBBaseController::GetDeviceInfo()
|
||||
{
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_GET_DEVICE_INFO;
|
||||
|
||||
int bytes_read = 0;
|
||||
do
|
||||
{
|
||||
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
|
||||
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_OPENRGB_HID_READ_TIMEOUT);
|
||||
} while(bytes_read <= 0);
|
||||
|
||||
total_number_of_leds = usb_buf[QMK_OPENRGB_TOTAL_NUMBER_OF_LEDS_BYTE];
|
||||
total_number_of_leds_with_empty_space = usb_buf[QMK_OPENRGB_TOTAL_NUMBER_OF_LEDS_WITH_EMPTY_SPACE_BYTE];
|
||||
|
||||
int i = QMK_OPENRGB_TOTAL_NUMBER_OF_LEDS_WITH_EMPTY_SPACE_BYTE + 1;
|
||||
while (usb_buf[i] != 0)
|
||||
{
|
||||
device_name.push_back(usb_buf[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
i++;
|
||||
while (usb_buf[i] != 0)
|
||||
{
|
||||
device_vendor.push_back(usb_buf[i]);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void QMKOpenRGBBaseController::GetModeInfo()
|
||||
{
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_GET_MODE_INFO;
|
||||
|
||||
int bytes_read = 0;
|
||||
do
|
||||
{
|
||||
hid_write(dev, usb_buf, 65);
|
||||
bytes_read = hid_read_timeout(dev, usb_buf, 65, QMK_OPENRGB_HID_READ_TIMEOUT);
|
||||
} while(bytes_read <= 0);
|
||||
|
||||
mode = usb_buf[QMK_OPENRGB_MODE_BYTE];
|
||||
mode_speed = usb_buf[QMK_OPENRGB_SPEED_BYTE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| QMK hue range is between 0-255 so hue needs to be |
|
||||
| converted |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned int oldRange = 255;
|
||||
unsigned int newRange = 359;
|
||||
unsigned int convertedHue = (usb_buf[QMK_OPENRGB_HUE_BYTE] * newRange / oldRange);
|
||||
|
||||
hsv_t hsv;
|
||||
hsv.hue = convertedHue;
|
||||
hsv.saturation = usb_buf[QMK_OPENRGB_SATURATION_BYTE];
|
||||
hsv.value = usb_buf[QMK_OPENRGB_VALUE_BYTE];
|
||||
|
||||
mode_color = hsv2rgb(&hsv);
|
||||
}
|
||||
|
||||
void QMKOpenRGBBaseController::SetMode(hsv_t hsv_color, unsigned char mode, unsigned char speed)
|
||||
{
|
||||
SetMode(hsv_color, mode, speed, false);
|
||||
}
|
||||
|
||||
void QMKOpenRGBBaseController::SetMode(hsv_t hsv_color, unsigned char mode, unsigned char speed, bool save)
|
||||
{
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_SET_MODE;
|
||||
usb_buf[0x02] = hsv_color.hue * 255 / 359;
|
||||
usb_buf[0x03] = hsv_color.saturation;
|
||||
usb_buf[0x04] = hsv_color.value;
|
||||
usb_buf[0x05] = mode;
|
||||
usb_buf[0x06] = speed;
|
||||
usb_buf[0x07] = save;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read_timeout(dev, usb_buf, 65, QMK_OPENRGB_HID_READ_TIMEOUT);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKOpenRGBBaseController.h |
|
||||
| |
|
||||
| Common Driver for OpenRGB QMK Keyboard Protocol |
|
||||
| |
|
||||
| ChrisM 20 Dec 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LogManager.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "SettingsManager.h"
|
||||
#include "QMKOpenRGBController.h"
|
||||
|
||||
class QMKOpenRGBBaseController
|
||||
{
|
||||
public:
|
||||
QMKOpenRGBBaseController(hid_device *dev_handle, const char *path, unsigned char max_led_count);
|
||||
virtual ~QMKOpenRGBBaseController();
|
||||
|
||||
std::string GetLocation();
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceVendor();
|
||||
|
||||
unsigned int GetTotalNumberOfLEDs();
|
||||
unsigned int GetTotalNumberOfLEDsWithEmptySpace();
|
||||
unsigned int GetMode();
|
||||
unsigned int GetModeSpeed();
|
||||
unsigned int GetModeColor();
|
||||
|
||||
std::vector<point_t> GetLEDPoints();
|
||||
std::vector<unsigned int> GetLEDFlags();
|
||||
std::vector<std::string> GetLEDNames();
|
||||
std::vector<RGBColor> GetLEDColors();
|
||||
|
||||
unsigned int GetProtocolVersion();
|
||||
std::string GetQMKVersion();
|
||||
void GetDeviceInfo();
|
||||
void GetModeInfo();
|
||||
|
||||
void SetMode(hsv_t hsv_color, unsigned char mode, unsigned char speed);
|
||||
void SetMode(hsv_t hsv_color, unsigned char mode, unsigned char speed, bool save);
|
||||
|
||||
virtual void GetLEDInfo(unsigned int leds_count) = 0;
|
||||
virtual void DirectModeSetSingleLED(unsigned int led, unsigned char red, unsigned char green, unsigned char blue) = 0;
|
||||
virtual void DirectModeSetLEDs(std::vector<RGBColor> colors, unsigned int leds_count) = 0;
|
||||
|
||||
protected:
|
||||
hid_device *dev;
|
||||
|
||||
unsigned int leds_per_update;
|
||||
|
||||
std::string location;
|
||||
|
||||
std::string device_name;
|
||||
std::string device_vendor;
|
||||
|
||||
std::chrono::milliseconds delay;
|
||||
|
||||
unsigned int total_number_of_leds;
|
||||
unsigned int total_number_of_leds_with_empty_space;
|
||||
unsigned int mode;
|
||||
unsigned int mode_speed;
|
||||
|
||||
RGBColor mode_color;
|
||||
|
||||
std::vector<point_t> led_points;
|
||||
std::vector<unsigned int> led_flags;
|
||||
std::vector<std::string> led_names;
|
||||
std::vector<RGBColor> led_colors;
|
||||
|
||||
private:
|
||||
};
|
||||
@@ -0,0 +1,133 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKOpenRGBController.h |
|
||||
| |
|
||||
| Driver for OpenRGB QMK Keyboard Protocol |
|
||||
| |
|
||||
| Kasper 10 Oct 2020 |
|
||||
| Jath03 28 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <hidapi.h>
|
||||
#include "ResourceManager.h"
|
||||
#include "RGBController.h"
|
||||
#include "hsv.h"
|
||||
|
||||
#define QMK_OPENRGB_PACKET_SIZE 65
|
||||
#define QMK_OPENRGB_HID_READ_TIMEOUT 50
|
||||
|
||||
enum CommandsId
|
||||
{
|
||||
QMK_OPENRGB_GET_PROTOCOL_VERSION = 1,
|
||||
QMK_OPENRGB_GET_QMK_VERSION,
|
||||
QMK_OPENRGB_GET_DEVICE_INFO,
|
||||
QMK_OPENRGB_GET_MODE_INFO,
|
||||
QMK_OPENRGB_GET_LED_INFO,
|
||||
QMK_OPENRGB_GET_IS_MODE_ENABLED,
|
||||
QMK_OPENRGB_GET_ENABLED_MODES = QMK_OPENRGB_GET_IS_MODE_ENABLED,
|
||||
|
||||
QMK_OPENRGB_SET_MODE,
|
||||
QMK_OPENRGB_DIRECT_MODE_SET_SINGLE_LED,
|
||||
QMK_OPENRGB_DIRECT_MODE_SET_LEDS,
|
||||
};
|
||||
|
||||
enum Modes
|
||||
{
|
||||
QMK_OPENRGB_MODE_OPENRGB_DIRECT = 1,
|
||||
QMK_OPENRGB_MODE_SOLID_COLOR,
|
||||
QMK_OPENRGB_MODE_ALPHA_MOD,
|
||||
QMK_OPENRGB_MODE_GRADIENT_UP_DOWN,
|
||||
QMK_OPENRGB_MODE_GRADIENT_LEFT_RIGHT,
|
||||
QMK_OPENRGB_MODE_BREATHING,
|
||||
QMK_OPENRGB_MODE_BAND_SAT,
|
||||
QMK_OPENRGB_MODE_BAND_VAL,
|
||||
QMK_OPENRGB_MODE_BAND_PINWHEEL_SAT,
|
||||
QMK_OPENRGB_MODE_BAND_PINWHEEL_VAL,
|
||||
QMK_OPENRGB_MODE_BAND_SPIRAL_SAT,
|
||||
QMK_OPENRGB_MODE_BAND_SPIRAL_VAL,
|
||||
QMK_OPENRGB_MODE_CYCLE_ALL,
|
||||
QMK_OPENRGB_MODE_CYCLE_LEFT_RIGHT,
|
||||
QMK_OPENRGB_MODE_CYCLE_UP_DOWN,
|
||||
QMK_OPENRGB_MODE_CYCLE_OUT_IN,
|
||||
QMK_OPENRGB_MODE_CYCLE_OUT_IN_DUAL,
|
||||
QMK_OPENRGB_MODE_RAINBOW_MOVING_CHEVRON,
|
||||
QMK_OPENRGB_MODE_CYCLE_PINWHEEL,
|
||||
QMK_OPENRGB_MODE_CYCLE_SPIRAL,
|
||||
QMK_OPENRGB_MODE_DUAL_BEACON,
|
||||
QMK_OPENRGB_MODE_RAINBOW_BEACON,
|
||||
QMK_OPENRGB_MODE_RAINBOW_PINWHEELS,
|
||||
QMK_OPENRGB_MODE_RAINDROPS,
|
||||
QMK_OPENRGB_MODE_JELLYBEAN_RAINDROPS,
|
||||
QMK_OPENRGB_MODE_HUE_BREATHING,
|
||||
QMK_OPENRGB_MODE_HUE_PENDULUM,
|
||||
QMK_OPENRGB_MODE_HUE_WAVE,
|
||||
QMK_OPENRGB_MODE_TYPING_HEATMAP,
|
||||
QMK_OPENRGB_MODE_DIGITAL_RAIN,
|
||||
QMK_OPENRGB_MODE_SOLID_REACTIVE_SIMPLE,
|
||||
QMK_OPENRGB_MODE_SOLID_REACTIVE,
|
||||
QMK_OPENRGB_MODE_SOLID_REACTIVE_WIDE,
|
||||
QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTIWIDE,
|
||||
QMK_OPENRGB_MODE_SOLID_REACTIVE_CROSS,
|
||||
QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTICROSS,
|
||||
QMK_OPENRGB_MODE_SOLID_REACTIVE_NEXUS,
|
||||
QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTINEXUS,
|
||||
QMK_OPENRGB_MODE_SPLASH,
|
||||
QMK_OPENRGB_MODE_MULTISPLASH,
|
||||
QMK_OPENRGB_MODE_SOLID_SPLASH,
|
||||
QMK_OPENRGB_MODE_SOLID_MULTISPLASH,
|
||||
QMK_OPENRGB_MODE_PIXEL_RAIN,
|
||||
QMK_OPENRGB_MODE_PIXEL_FLOW,
|
||||
QMK_OPENRGB_MODE_PIXEL_FRACTAL,
|
||||
};
|
||||
|
||||
enum SpeedCommands
|
||||
{
|
||||
QMK_OPENRGB_SPEED_SLOWEST = 0x00, /* Slowest speed */
|
||||
QMK_OPENRGB_SPEED_NORMAL = 0x7F, /* Normal speed */
|
||||
QMK_OPENRGB_SPEED_FASTEST = 0xFF, /* Fastest speed */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
QMK_OPENRGB_FAILURE = 25, /* Failure status code */
|
||||
QMK_OPENRGB_SUCCESS = 50, /* Success status code */
|
||||
QMK_OPENRGB_END_OF_MESSAGE = 100, /* End of Message status code */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
QMK_OPENRGB_TOTAL_NUMBER_OF_LEDS_BYTE = 1,
|
||||
QMK_OPENRGB_TOTAL_NUMBER_OF_LEDS_WITH_EMPTY_SPACE_BYTE = 2
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
QMK_OPENRGB_MODE_BYTE = 1,
|
||||
QMK_OPENRGB_SPEED_BYTE = 2,
|
||||
QMK_OPENRGB_HUE_BYTE = 3,
|
||||
QMK_OPENRGB_SATURATION_BYTE = 4,
|
||||
QMK_OPENRGB_VALUE_BYTE = 5,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
QMK_OPENRGB_POINT_X_BYTE = 1,
|
||||
QMK_OPENRGB_POINT_Y_BYTE = 2,
|
||||
QMK_OPENRGB_FLAG_BYTE = 3,
|
||||
QMK_OPENRGB_R_COLOR_BYTE = 4,
|
||||
QMK_OPENRGB_G_COLOR_BYTE = 5,
|
||||
QMK_OPENRGB_B_COLOR_BYTE = 6,
|
||||
QMK_OPENRGB_KEYCODE_BYTE = 7
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
} point_t;
|
||||
@@ -0,0 +1,167 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKOpenRGBControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for OpenRGB QMK Keyboard Protocol |
|
||||
| |
|
||||
| Kasper 10 Oct 2020 |
|
||||
| Jath03 28 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "Detector.h"
|
||||
#include "QMKOpenRGBRev9Controller.h"
|
||||
#include "QMKOpenRGBRevBController.h"
|
||||
#include "QMKOpenRGBRevDController.h"
|
||||
#include "RGBController_QMKOpenRGBRev9.h"
|
||||
#include "RGBController_QMKOpenRGBRevB.h"
|
||||
#include "RGBController_QMKOpenRGBRevD.h"
|
||||
#include "RGBController_QMKOpenRGBRevE.h"
|
||||
#include "LogManager.h"
|
||||
#include "SettingsManager.h"
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Protocol version |
|
||||
\*-----------------------------------------------------*/
|
||||
#define QMK_OPENRGB_PROTOCOL_VERSION_9 0x09
|
||||
#define QMK_OPENRGB_PROTOCOL_VERSION_B 0x0B
|
||||
#define QMK_OPENRGB_PROTOCOL_VERSION_C 0x0C
|
||||
#define QMK_OPENRGB_PROTOCOL_VERSION_D 0x0D
|
||||
#define QMK_OPENRGB_PROTOCOL_VERSION_E 0x0E
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Usage and Usage Page |
|
||||
\*-----------------------------------------------------*/
|
||||
#define QMK_USAGE_PAGE 0xFF60
|
||||
#define QMK_USAGE 0x61
|
||||
|
||||
unsigned int GetProtocolVersion(hid_device *dev)
|
||||
{
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_GET_PROTOCOL_VERSION;
|
||||
|
||||
int bytes_read = 0;
|
||||
do
|
||||
{
|
||||
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
|
||||
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_OPENRGB_HID_READ_TIMEOUT);
|
||||
} while(bytes_read <= 0);
|
||||
|
||||
return usb_buf[1];
|
||||
}
|
||||
|
||||
void DetectQMKOpenRGBControllers(hid_device_info *info, const std::string&)
|
||||
{
|
||||
hid_device *dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Use Rev9 controller for getting protocol version. |
|
||||
| Protocol version request may not change across |
|
||||
| protocol versions |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned int version = GetProtocolVersion(dev);
|
||||
|
||||
switch(version)
|
||||
{
|
||||
case QMK_OPENRGB_PROTOCOL_VERSION_9:
|
||||
{
|
||||
QMKOpenRGBRev9Controller* controller = new QMKOpenRGBRev9Controller(dev, info->path);
|
||||
RGBController_QMKOpenRGBRev9* rgb_controller = new RGBController_QMKOpenRGBRev9(controller);
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
break;
|
||||
case QMK_OPENRGB_PROTOCOL_VERSION_B:
|
||||
{
|
||||
QMKOpenRGBRevBController* controller = new QMKOpenRGBRevBController(dev, info->path);
|
||||
RGBController_QMKOpenRGBRevB* rgb_controller = new RGBController_QMKOpenRGBRevB(controller, false);
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
break;
|
||||
case QMK_OPENRGB_PROTOCOL_VERSION_C:
|
||||
{
|
||||
QMKOpenRGBRevBController* controller = new QMKOpenRGBRevBController(dev, info->path);
|
||||
RGBController_QMKOpenRGBRevB* rgb_controller = new RGBController_QMKOpenRGBRevB(controller, true);
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
break;
|
||||
case QMK_OPENRGB_PROTOCOL_VERSION_D:
|
||||
{
|
||||
QMKOpenRGBRevDController* controller = new QMKOpenRGBRevDController(dev, info->path);
|
||||
RGBController_QMKOpenRGBRevD* rgb_controller = new RGBController_QMKOpenRGBRevD(controller, true);
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
break;
|
||||
case QMK_OPENRGB_PROTOCOL_VERSION_E:
|
||||
{
|
||||
QMKOpenRGBRevDController* controller = new QMKOpenRGBRevDController(dev, info->path);
|
||||
RGBController_QMKOpenRGBRevE* rgb_controller = new RGBController_QMKOpenRGBRevE(controller, true);
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (version == 0)
|
||||
{
|
||||
LOG_WARNING("[QMK OpenRGB] Detection failed - the detected keyboard does not have the OpenRGB protocol feature enabled! \n"
|
||||
"Please make sure your keyboard supports RGB Matrix, add OPENRGB_ENABLE = yes to the rules.mk inside your keymap folder, compile and flash again!");
|
||||
}
|
||||
else if (version < QMK_OPENRGB_PROTOCOL_VERSION_9)
|
||||
{
|
||||
LOG_WARNING("[QMK OpenRGB] Detection failed - the detected keyboard is using an outdated protocol version %i. Please update to to the update to the latest version of QMK-OpenRGB! \n"
|
||||
"For officaly supported QMK boards grab <a href=\"https://github.com/Kasper24/QMK-OpenRGB\">url</a> \n"
|
||||
"For Sonix boards grab <a href=\"https://github.com/SonixQMK/qmk_firmware/tree/sn32_openrgb\">url</a>", version);
|
||||
}
|
||||
else if (version > QMK_OPENRGB_PROTOCOL_VERSION_E)
|
||||
{
|
||||
LOG_WARNING("[QMK OpenRGB] Detection failed - the detected keyboard is using version protocol %i which is not supported by this OpenRGB build. Please update OpenRGB!", version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterQMKDetectors()
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Get QMKOpenRGB settings |
|
||||
\*-------------------------------------------------*/
|
||||
json qmk_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("QMKOpenRGBDevices");
|
||||
|
||||
if(qmk_settings.contains("devices"))
|
||||
{
|
||||
for(unsigned int device_idx = 0; device_idx < qmk_settings["devices"].size(); device_idx++)
|
||||
{
|
||||
if( qmk_settings["devices"][device_idx].contains("usb_pid")
|
||||
&& qmk_settings["devices"][device_idx].contains("usb_vid")
|
||||
&& qmk_settings["devices"][device_idx].contains("name"))
|
||||
{
|
||||
std::string usb_pid_str = qmk_settings["devices"][device_idx]["usb_pid"];
|
||||
std::string usb_vid_str = qmk_settings["devices"][device_idx]["usb_vid"];
|
||||
std::string name = qmk_settings["devices"][device_idx]["name"];
|
||||
|
||||
/*-------------------------------------*\
|
||||
| Parse hex string to integer |
|
||||
\*-------------------------------------*/
|
||||
unsigned short usb_pid = std::stoi(usb_pid_str, 0, 16);
|
||||
unsigned short usb_vid = std::stoi(usb_vid_str, 0, 16);
|
||||
|
||||
REGISTER_DYNAMIC_HID_DETECTOR_IPU(name, DetectQMKOpenRGBControllers, usb_vid, usb_pid, 1, QMK_USAGE_PAGE, QMK_USAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_DYNAMIC_DETECTOR("QMK OpenRGB Devices", RegisterQMKDetectors);
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKOpenRGBRev9Controller.cpp |
|
||||
| |
|
||||
| Driver for OpenRGB QMK Keyboard Protocol Revision 9 |
|
||||
| Revision 9 was initially supported by OpenRGB 0.6 |
|
||||
| |
|
||||
| Kasper 10 Oct 2020 |
|
||||
| Jath03 28 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "QMKKeycodes.h"
|
||||
#include "QMKOpenRGBRev9Controller.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
QMKOpenRGBRev9Controller::QMKOpenRGBRev9Controller(hid_device *dev_handle, const char *path) :
|
||||
QMKOpenRGBBaseController(dev_handle, path, 20)
|
||||
{
|
||||
}
|
||||
|
||||
QMKOpenRGBRev9Controller::~QMKOpenRGBRev9Controller()
|
||||
{
|
||||
}
|
||||
|
||||
void QMKOpenRGBRev9Controller::GetLEDInfo(unsigned int led)
|
||||
{
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_GET_LED_INFO;
|
||||
usb_buf[0x02] = led;
|
||||
|
||||
int bytes_read = 0;
|
||||
do
|
||||
{
|
||||
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
|
||||
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_OPENRGB_HID_READ_TIMEOUT);
|
||||
} while(bytes_read <= 0);
|
||||
|
||||
if(usb_buf[62] != QMK_OPENRGB_FAILURE)
|
||||
{
|
||||
led_points.push_back(point_t{usb_buf[QMK_OPENRGB_POINT_X_BYTE], usb_buf[QMK_OPENRGB_POINT_Y_BYTE]});
|
||||
led_flags.push_back(usb_buf[QMK_OPENRGB_FLAG_BYTE]);
|
||||
led_colors.push_back(ToRGBColor(usb_buf[QMK_OPENRGB_R_COLOR_BYTE], usb_buf[QMK_OPENRGB_G_COLOR_BYTE], usb_buf[QMK_OPENRGB_B_COLOR_BYTE]));
|
||||
}
|
||||
|
||||
if(usb_buf[QMK_OPENRGB_KEYCODE_BYTE] != 0)
|
||||
{
|
||||
if(qmk_keynames.count(usb_buf[QMK_OPENRGB_KEYCODE_BYTE]) > 0)
|
||||
{
|
||||
led_names.push_back(qmk_keynames[usb_buf[QMK_OPENRGB_KEYCODE_BYTE]]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("[%s] Key code: %d (%02X) @ offset %d was not found in the QMK keyname map",
|
||||
device_name.c_str(), usb_buf[QMK_OPENRGB_KEYCODE_BYTE],
|
||||
usb_buf[QMK_OPENRGB_KEYCODE_BYTE], led);
|
||||
led_names.push_back(KEY_EN_UNUSED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool QMKOpenRGBRev9Controller::GetIsModeEnabled(unsigned int mode)
|
||||
{
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_GET_IS_MODE_ENABLED;
|
||||
usb_buf[0x02] = mode;
|
||||
|
||||
int bytes_read = 0;
|
||||
do
|
||||
{
|
||||
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
|
||||
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_OPENRGB_HID_READ_TIMEOUT);
|
||||
} while(bytes_read <= 0);
|
||||
|
||||
return usb_buf[1] == QMK_OPENRGB_SUCCESS ? true : false;
|
||||
}
|
||||
|
||||
void QMKOpenRGBRev9Controller::DirectModeSetSingleLED(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_DIRECT_MODE_SET_SINGLE_LED;
|
||||
usb_buf[0x02] = led;
|
||||
usb_buf[0x03] = red;
|
||||
usb_buf[0x04] = green;
|
||||
usb_buf[0x05] = blue;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read_timeout(dev, usb_buf, 65, QMK_OPENRGB_HID_READ_TIMEOUT);
|
||||
}
|
||||
|
||||
void QMKOpenRGBRev9Controller::DirectModeSetLEDs(std::vector<RGBColor> colors, unsigned int leds_count)
|
||||
{
|
||||
unsigned int leds_sent = 0;
|
||||
unsigned int tmp_leds_per_update = leds_per_update;
|
||||
|
||||
while (leds_sent < leds_count)
|
||||
{
|
||||
if ((leds_count - leds_sent) < tmp_leds_per_update)
|
||||
{
|
||||
tmp_leds_per_update = leds_count - leds_sent;
|
||||
}
|
||||
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_DIRECT_MODE_SET_LEDS;
|
||||
usb_buf[0x02] = leds_sent;
|
||||
usb_buf[0x03] = tmp_leds_per_update;
|
||||
|
||||
for (unsigned int led_idx = 0; led_idx < tmp_leds_per_update; led_idx++)
|
||||
{
|
||||
usb_buf[(led_idx * 3) + 4] = RGBGetRValue(colors[led_idx + leds_sent]);
|
||||
usb_buf[(led_idx * 3) + 5] = RGBGetGValue(colors[led_idx + leds_sent]);
|
||||
usb_buf[(led_idx * 3) + 6] = RGBGetBValue(colors[led_idx + leds_sent]);
|
||||
}
|
||||
|
||||
hid_write(dev, usb_buf, 65);
|
||||
|
||||
if(delay > 0ms)
|
||||
{
|
||||
std::this_thread::sleep_for(delay);
|
||||
}
|
||||
|
||||
leds_sent += tmp_leds_per_update;
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKOpenRGBRev9Controller.h |
|
||||
| |
|
||||
| Driver for OpenRGB QMK Keyboard Protocol Revision 9 |
|
||||
| Revision 9 was initially supported by OpenRGB 0.6 |
|
||||
| |
|
||||
| Kasper 10 Oct 2020 |
|
||||
| Jath03 28 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "QMKOpenRGBBaseController.h"
|
||||
|
||||
class QMKOpenRGBRev9Controller : public QMKOpenRGBBaseController
|
||||
{
|
||||
public:
|
||||
QMKOpenRGBRev9Controller(hid_device *dev_handle, const char *path);
|
||||
~QMKOpenRGBRev9Controller();
|
||||
|
||||
//Virtual function implementations
|
||||
void GetLEDInfo(unsigned int led);
|
||||
void DirectModeSetSingleLED(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void DirectModeSetLEDs(std::vector<RGBColor> colors, unsigned int num_colors);
|
||||
|
||||
//Protocol Specific functions
|
||||
bool GetIsModeEnabled(unsigned int mode);
|
||||
|
||||
private:
|
||||
};
|
||||
+762
@@ -0,0 +1,762 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_QMKOpenRGBRev9.cpp |
|
||||
| |
|
||||
| RGBController for OpenRGB QMK Keyboard Protocol |
|
||||
| Revision 9 |
|
||||
| |
|
||||
| Kasper 10 Oct 2020 |
|
||||
| Jath03 28 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "hsv.h"
|
||||
#include "LogManager.h"
|
||||
#include "RGBController_QMKOpenRGBRev9.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Quantum Mechanical Keyboard (QMK)
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors
|
||||
@comment Please see [the github page](https://github.com/qmk/qmk_firmware#supported-keyboards) for the up to date list of
|
||||
keyboards supported by the QMK controller.
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_QMKOpenRGBRev9::RGBController_QMKOpenRGBRev9(QMKOpenRGBRev9Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = controller->GetDeviceVendor();
|
||||
description = "QMK OpenRGB Device (Protocol Version " + std::to_string(controller->GetProtocolVersion()) + ")";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
location = controller->GetLocation();
|
||||
version = controller->GetQMKVersion();
|
||||
|
||||
unsigned int current_mode = 1;
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_OPENRGB_DIRECT))
|
||||
{
|
||||
InitializeMode("Direct", current_mode, MODE_FLAG_HAS_PER_LED_COLOR, MODE_COLORS_PER_LED);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_SOLID_COLOR))
|
||||
{
|
||||
InitializeMode("Static", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_ALPHA_MOD))
|
||||
{
|
||||
InitializeMode("Alpha Mod", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_GRADIENT_UP_DOWN))
|
||||
{
|
||||
InitializeMode("Gradient Up Down", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_GRADIENT_LEFT_RIGHT))
|
||||
{
|
||||
InitializeMode("Gradient Left Right", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_BREATHING))
|
||||
{
|
||||
InitializeMode("Breathing", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_BAND_SAT))
|
||||
{
|
||||
InitializeMode("Band Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_BAND_VAL))
|
||||
{
|
||||
InitializeMode("Band Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_BAND_PINWHEEL_SAT))
|
||||
{
|
||||
InitializeMode("Band Pinwheel Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_BAND_PINWHEEL_VAL))
|
||||
{
|
||||
InitializeMode("Band Pinwheel Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_BAND_SPIRAL_SAT))
|
||||
{
|
||||
InitializeMode("Band Spiral Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_BAND_SPIRAL_VAL))
|
||||
{
|
||||
InitializeMode("Band Spiral Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_CYCLE_ALL))
|
||||
{
|
||||
InitializeMode("Cycle All", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_CYCLE_LEFT_RIGHT))
|
||||
{
|
||||
InitializeMode("Cycle Left Right", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_CYCLE_UP_DOWN))
|
||||
{
|
||||
InitializeMode("Cycle Up Down", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_CYCLE_OUT_IN))
|
||||
{
|
||||
InitializeMode("Cycle Out In", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_CYCLE_OUT_IN_DUAL))
|
||||
{
|
||||
InitializeMode("Cycle Out In Dual", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_RAINBOW_MOVING_CHEVRON))
|
||||
{
|
||||
InitializeMode("Rainbow Moving Chevron", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_CYCLE_PINWHEEL))
|
||||
{
|
||||
InitializeMode("Cycle Pinwheel", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_CYCLE_SPIRAL))
|
||||
{
|
||||
InitializeMode("Cycle Spiral", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_DUAL_BEACON))
|
||||
{
|
||||
InitializeMode("Dual Beacon", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_RAINBOW_BEACON))
|
||||
{
|
||||
InitializeMode("Rainbow Beacon", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_RAINBOW_PINWHEELS))
|
||||
{
|
||||
InitializeMode("Rainbow Pinwheels", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_RAINDROPS))
|
||||
{
|
||||
InitializeMode("Raindrops", current_mode, 0, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_JELLYBEAN_RAINDROPS))
|
||||
{
|
||||
InitializeMode("Jellybean Raindrops", current_mode, 0, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_HUE_BREATHING))
|
||||
{
|
||||
InitializeMode("Hue Breathing", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_HUE_PENDULUM))
|
||||
{
|
||||
InitializeMode("Hue Pendulum", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_HUE_WAVE))
|
||||
{
|
||||
InitializeMode("Hue Wave", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_TYPING_HEATMAP))
|
||||
{
|
||||
InitializeMode("Typing Heatmap", current_mode, 0, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_DIGITAL_RAIN))
|
||||
{
|
||||
InitializeMode("Digital Rain", current_mode, 0, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_SOLID_REACTIVE_SIMPLE))
|
||||
{
|
||||
InitializeMode("Solid Reactive Simple", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_SOLID_REACTIVE))
|
||||
{
|
||||
InitializeMode("Solid Reactive", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_SOLID_REACTIVE_WIDE))
|
||||
{
|
||||
InitializeMode("Solid Reactive Wide", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTIWIDE))
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Wide", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_SOLID_REACTIVE_CROSS))
|
||||
{
|
||||
InitializeMode("Solid Reactive Cross", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTICROSS))
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Cross", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_SOLID_REACTIVE_NEXUS))
|
||||
{
|
||||
InitializeMode("Solid Reactive Nexus", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTINEXUS))
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Nexus", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_SPLASH))
|
||||
{
|
||||
InitializeMode("Rainbow Reactive Splash", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_MULTISPLASH))
|
||||
{
|
||||
InitializeMode("Rainbow Reactive Multi Splash", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_SOLID_SPLASH))
|
||||
{
|
||||
InitializeMode("Solid Reactive Splash", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
if(controller->GetIsModeEnabled(QMK_OPENRGB_MODE_SOLID_MULTISPLASH))
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Splash", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
|
||||
}
|
||||
|
||||
active_mode = controller->GetMode() - 1;
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_QMKOpenRGBRev9::~RGBController_QMKOpenRGBRev9()
|
||||
{
|
||||
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
|
||||
{
|
||||
if(zones[zone_index].matrix_map != NULL)
|
||||
{
|
||||
delete zones[zone_index].matrix_map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRev9::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Get the number of LEDs from the device |
|
||||
\*---------------------------------------------------------*/
|
||||
const unsigned int total_number_of_leds = controller->GetTotalNumberOfLEDs();
|
||||
const unsigned int total_number_of_leds_with_empty_space = controller->GetTotalNumberOfLEDsWithEmptySpace();
|
||||
|
||||
LOG_INFO("[%s] Keyboard has %u LEDs total", name.c_str(), total_number_of_leds);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get information for each LED |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < std::max(total_number_of_leds, total_number_of_leds_with_empty_space); i++)
|
||||
{
|
||||
controller->GetLEDInfo(i);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get LED vectors from controller |
|
||||
\*---------------------------------------------------------*/
|
||||
std::vector<point_t> led_points = controller->GetLEDPoints();
|
||||
std::vector<unsigned int> led_flags = controller->GetLEDFlags();
|
||||
std::vector<std::string> led_names = controller->GetLEDNames();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Count key LEDs and underglow LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int number_of_key_leds;
|
||||
unsigned int number_of_underglow_leds;
|
||||
|
||||
CountKeyTypes(led_flags, total_number_of_leds, number_of_key_leds, number_of_underglow_leds);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Add LED names for underglow zone |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int number_of_leds = number_of_key_leds + number_of_underglow_leds;
|
||||
bool has_underglow = number_of_underglow_leds > 0;
|
||||
LOG_INFO("[%s] Keyboard has %u underglow LEDs", name.c_str(), number_of_underglow_leds);
|
||||
|
||||
for(unsigned int i = 0; i < number_of_underglow_leds; i++)
|
||||
{
|
||||
led_names.push_back("Underglow: " + std::to_string(number_of_key_leds + i));
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create sets for row and column position values |
|
||||
\*---------------------------------------------------------*/
|
||||
std::set<int> rows, columns;
|
||||
for (unsigned int i = 0; i < number_of_leds; i++)
|
||||
{
|
||||
rows.insert(led_points[i].y);
|
||||
columns.insert(led_points[i].x);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Calculate matrix map from QMK positions |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int divisor = CalculateDivisor(led_points, rows, columns);
|
||||
LOG_DEBUG("[%s] Distance between standard keys calculated to be %u", name.c_str(), divisor);
|
||||
|
||||
VectorMatrix matrix_map;
|
||||
VectorMatrix underglow_map;
|
||||
|
||||
PlaceLEDsInMaps(rows, columns, divisor, led_points, led_flags, matrix_map, underglow_map);
|
||||
CleanMatrixMaps(matrix_map, underglow_map, (unsigned int)rows.size(), has_underglow);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| These vectors are class members because if they go out of |
|
||||
| scope, the underlying array (used by each zones' |
|
||||
| matrix_map) is unallocated. |
|
||||
\*---------------------------------------------------------*/
|
||||
flat_matrix_map = FlattenMatrixMap(matrix_map);
|
||||
flat_underglow_map = FlattenMatrixMap(underglow_map);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create Keyboard zone |
|
||||
\*---------------------------------------------------------*/
|
||||
zone keys_zone;
|
||||
keys_zone.name = "Keyboard";
|
||||
keys_zone.type = ZONE_TYPE_MATRIX;
|
||||
keys_zone.leds_min = number_of_key_leds;
|
||||
keys_zone.leds_max = keys_zone.leds_min;
|
||||
keys_zone.leds_count = keys_zone.leds_min;
|
||||
keys_zone.matrix_map = new matrix_map_type;
|
||||
keys_zone.matrix_map->width = (unsigned int)matrix_map[0].size();
|
||||
keys_zone.matrix_map->height = (unsigned int)matrix_map.size();
|
||||
keys_zone.matrix_map->map = flat_matrix_map.data();
|
||||
zones.push_back(keys_zone);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create Underglow zone if it exists |
|
||||
\*---------------------------------------------------------*/
|
||||
if(has_underglow)
|
||||
{
|
||||
zone underglow_zone;
|
||||
underglow_zone.name = "Underglow";
|
||||
underglow_zone.type = ZONE_TYPE_MATRIX;
|
||||
underglow_zone.leds_min = number_of_underglow_leds;
|
||||
underglow_zone.leds_max = underglow_zone.leds_min;
|
||||
underglow_zone.leds_count = underglow_zone.leds_min;
|
||||
underglow_zone.matrix_map = new matrix_map_type;
|
||||
underglow_zone.matrix_map->width = (unsigned int)underglow_map[0].size();
|
||||
underglow_zone.matrix_map->height = (unsigned int)underglow_map.size();
|
||||
underglow_zone.matrix_map->map = flat_underglow_map.data();
|
||||
zones.push_back(underglow_zone);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int led_idx = 0; led_idx < number_of_leds; led_idx++)
|
||||
{
|
||||
led keyboard_led;
|
||||
|
||||
if(led_idx < led_names.size())
|
||||
{
|
||||
keyboard_led.name = led_names[led_idx];
|
||||
}
|
||||
keyboard_led.value = led_idx;
|
||||
|
||||
leds.push_back(keyboard_led);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Setup Colors |
|
||||
\*---------------------------------------------------------*/
|
||||
SetupColors();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Initialize colors from device values |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < leds.size(); i++)
|
||||
{
|
||||
colors[i] = controller->GetLEDColors()[i];
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRev9::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRev9::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->DirectModeSetLEDs(colors, controller->GetTotalNumberOfLEDs());
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRev9::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRev9::UpdateSingleLED(int led)
|
||||
{
|
||||
RGBColor color = colors[led];
|
||||
unsigned char red = RGBGetRValue(color);
|
||||
unsigned char grn = RGBGetGValue(color);
|
||||
unsigned char blu = RGBGetBValue(color);
|
||||
|
||||
controller->DirectModeSetSingleLED(led, red, grn, blu);
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRev9::DeviceUpdateMode()
|
||||
{
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_PER_LED)
|
||||
{
|
||||
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, 127);
|
||||
}
|
||||
else if(modes[active_mode].color_mode == MODE_COLORS_NONE)
|
||||
{
|
||||
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, modes[active_mode].speed);
|
||||
}
|
||||
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
RGBColor rgb_color = modes[active_mode].colors[0];
|
||||
hsv_t hsv_color;
|
||||
rgb2hsv(rgb_color, &hsv_color);
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
controller->SetMode(hsv_color, modes[active_mode].value, modes[active_mode].speed);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetMode(hsv_color, modes[active_mode].value, 127);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRev9::InitializeMode
|
||||
(
|
||||
std::string name,
|
||||
unsigned int ¤t_mode,
|
||||
unsigned int flags,
|
||||
unsigned int color_mode
|
||||
)
|
||||
{
|
||||
mode qmk_mode;
|
||||
qmk_mode.name = name;
|
||||
qmk_mode.value = current_mode++;
|
||||
qmk_mode.flags = flags;
|
||||
qmk_mode.color_mode = color_mode;
|
||||
|
||||
if(flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
qmk_mode.speed_min = QMK_OPENRGB_SPEED_SLOWEST;
|
||||
qmk_mode.speed_max = QMK_OPENRGB_SPEED_FASTEST;
|
||||
qmk_mode.speed = QMK_OPENRGB_SPEED_NORMAL;
|
||||
}
|
||||
if(flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
|
||||
{
|
||||
qmk_mode.colors_min = 1;
|
||||
qmk_mode.colors_max = 1;
|
||||
qmk_mode.colors.resize(1);
|
||||
qmk_mode.colors[0] = controller->GetModeColor();
|
||||
}
|
||||
|
||||
modes.push_back(qmk_mode);
|
||||
}
|
||||
|
||||
unsigned int RGBController_QMKOpenRGBRev9::CalculateDivisor
|
||||
(
|
||||
std::vector<point_t> led_points,
|
||||
std::set<int> rows,
|
||||
std::set<int> /*columns*/
|
||||
)
|
||||
{
|
||||
std::vector< std::vector<point_t> > row_points(rows.size());
|
||||
for(const point_t &pt : led_points)
|
||||
{
|
||||
for(const int &i : rows)
|
||||
{
|
||||
if(pt.y == i)
|
||||
{
|
||||
row_points[std::distance(rows.begin(), rows.find(i))].push_back(pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int last_pos;
|
||||
std::vector<int> distances;
|
||||
for(const std::vector<point_t> &row : row_points)
|
||||
{
|
||||
last_pos = 0;
|
||||
std::for_each(row.begin(), row.end(), [&distances, &last_pos](const point_t &pt)
|
||||
{
|
||||
distances.push_back(std::abs(pt.x - last_pos));
|
||||
last_pos = pt.x;
|
||||
});
|
||||
}
|
||||
std::map<int, int> counts;
|
||||
for(const int &i : distances)
|
||||
{
|
||||
counts[i]++;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Guard against empty distances (malformed LED data) |
|
||||
\*---------------------------------------------------------*/
|
||||
if(distances.empty())
|
||||
{
|
||||
LOG_WARNING("[%s] No valid LED distances found, using default divisor of 1", name.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int divisor = distances[0];
|
||||
for(const std::pair<const int, int> &i : counts)
|
||||
{
|
||||
if(counts[divisor] < i.second)
|
||||
{
|
||||
divisor = i.first;
|
||||
}
|
||||
}
|
||||
|
||||
if(divisor == 0)
|
||||
{
|
||||
LOG_WARNING("[%s] Calculated divisor is 0, using default of 1. This may indicate malformed LED position data.", name.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return divisor;
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRev9::CountKeyTypes
|
||||
(
|
||||
std::vector<unsigned int> led_flags,
|
||||
unsigned int total_led_count,
|
||||
unsigned int& key_leds,
|
||||
unsigned int& underglow_leds
|
||||
)
|
||||
{
|
||||
underglow_leds = 0;
|
||||
key_leds = 0;
|
||||
|
||||
for(unsigned int i = 0; i < total_led_count; i++)
|
||||
{
|
||||
if(led_flags[i] & 2)
|
||||
{
|
||||
underglow_leds++;
|
||||
}
|
||||
else if(led_flags[i] != 0)
|
||||
{
|
||||
key_leds++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRev9::PlaceLEDsInMaps
|
||||
(
|
||||
std::set<int> unique_rows,
|
||||
std::set<int> /*unique_cols*/,
|
||||
unsigned int divisor,
|
||||
std::vector<point_t> led_points,
|
||||
std::vector<unsigned int> led_flags,
|
||||
VectorMatrix& matrix_map_xl,
|
||||
VectorMatrix& underglow_map_xl
|
||||
)
|
||||
{
|
||||
matrix_map_xl = MakeEmptyMatrixMap(unique_rows.size(), (std::size_t)(std::round(255 / divisor) + 10));
|
||||
underglow_map_xl = MakeEmptyMatrixMap(unique_rows.size(), (std::size_t)(std::round(255 / divisor) + 10));
|
||||
|
||||
unsigned int x = 0;
|
||||
unsigned int y = 0;
|
||||
unsigned int underglow_counter = 0;
|
||||
|
||||
for(unsigned int i = 0; i < controller->GetTotalNumberOfLEDs(); i++)
|
||||
{
|
||||
if(led_points[i].x != 255 && led_points[i].y != 255)
|
||||
{
|
||||
bool underglow = led_flags[i] & 2;
|
||||
|
||||
x = (unsigned int)(std::round(led_points[i].x / divisor));
|
||||
y = (unsigned int)(std::distance(unique_rows.begin(), unique_rows.find(led_points[i].y)));
|
||||
|
||||
if(!underglow)
|
||||
{
|
||||
while(matrix_map_xl[y][x] != NO_LED)
|
||||
{
|
||||
x++;
|
||||
}
|
||||
matrix_map_xl[y][x] = i;
|
||||
LOG_DEBUG("[%s] Key Matrix LED %u, (%u, %u) being placed into (%u, %u)", name.c_str(), i, led_points[i].x, led_points[i].y, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
while(underglow_map_xl[y][x] != NO_LED)
|
||||
{
|
||||
x++;
|
||||
}
|
||||
underglow_map_xl[y][x] = underglow_counter;
|
||||
underglow_counter++;
|
||||
LOG_DEBUG("[%s] Underglow LED %u, (%u, %u) being placed into (%u, %u)", name.c_str(), i, led_points[i].x, led_points[i].y, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VectorMatrix RGBController_QMKOpenRGBRev9::MakeEmptyMatrixMap
|
||||
(
|
||||
std::size_t height,
|
||||
std::size_t width
|
||||
)
|
||||
{
|
||||
std::vector<std::vector<unsigned int> > matrix_map(height);
|
||||
for(std::size_t i = 0; i < height; i++)
|
||||
{
|
||||
for(std::size_t j = 0; j < width; j++)
|
||||
{
|
||||
matrix_map[i].push_back(NO_LED);
|
||||
}
|
||||
}
|
||||
return matrix_map;
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRev9::CleanMatrixMaps
|
||||
(
|
||||
VectorMatrix& matrix_map,
|
||||
VectorMatrix& underglow_map,
|
||||
unsigned int height,
|
||||
bool has_underglow
|
||||
)
|
||||
{
|
||||
bool empty_col = true;
|
||||
bool empty_col_udg = true;
|
||||
bool empty_row = true;
|
||||
int width = 0;
|
||||
int width_udg = 0;
|
||||
|
||||
std::vector<int> empty_rows;
|
||||
|
||||
bool can_break;
|
||||
bool can_break_udg;
|
||||
|
||||
for(unsigned int i = 0; i < height; i++)
|
||||
{
|
||||
empty_row = true;
|
||||
can_break = false;
|
||||
can_break_udg = false;
|
||||
|
||||
for(int j = (int)matrix_map[i].size() - 1; j --> 0; )
|
||||
{
|
||||
if(matrix_map[i][j] != NO_LED && width < (j + 1) && !can_break)
|
||||
{
|
||||
width = (j + 1);
|
||||
can_break = true;
|
||||
empty_row = false;
|
||||
}
|
||||
else if(matrix_map[i][j] != NO_LED)
|
||||
{
|
||||
empty_row = false;
|
||||
}
|
||||
if(underglow_map[i][j] != NO_LED && width_udg < (j + 1) && !can_break_udg)
|
||||
{
|
||||
width_udg = (j + 1);
|
||||
can_break_udg = true;
|
||||
}
|
||||
if (can_break && can_break_udg) break;
|
||||
}
|
||||
|
||||
if(matrix_map[i][0] != NO_LED)
|
||||
{
|
||||
empty_col = false;
|
||||
}
|
||||
|
||||
if(underglow_map[i][0] != NO_LED)
|
||||
{
|
||||
empty_col_udg = false;
|
||||
}
|
||||
|
||||
if(empty_row)
|
||||
{
|
||||
empty_rows.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int new_height = height - (unsigned int)empty_rows.size();
|
||||
width = empty_col ? width - 1 : width;
|
||||
width_udg = empty_col_udg && empty_col ? width_udg - 1 : width_udg;
|
||||
LOG_DEBUG("[%s] Key LED Matrix: %ux%u", name.c_str(), width, new_height);
|
||||
LOG_DEBUG("[%s] Underglow LED Matrix: %ux%u", name.c_str(), width_udg, new_height);
|
||||
|
||||
for(unsigned int i = (unsigned int)empty_rows.size(); i --> 0; )
|
||||
{
|
||||
matrix_map.erase(matrix_map.begin() + empty_rows[i]);
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < new_height; i++)
|
||||
{
|
||||
if(empty_col)
|
||||
{
|
||||
matrix_map[i].erase(matrix_map[i].begin(), matrix_map[i].begin() + 1);
|
||||
}
|
||||
|
||||
if(empty_col_udg && empty_col)
|
||||
{
|
||||
underglow_map[i].erase(underglow_map[i].begin(), underglow_map[i].begin() + 1);
|
||||
}
|
||||
|
||||
matrix_map[i].erase(matrix_map[i].begin()+width, matrix_map[i].end());
|
||||
|
||||
if(has_underglow)
|
||||
{
|
||||
underglow_map[i].erase(underglow_map[i].begin()+width_udg, underglow_map[i].end());
|
||||
}
|
||||
}
|
||||
|
||||
if(has_underglow)
|
||||
{
|
||||
for(unsigned int i = new_height; i < height; i++)
|
||||
{
|
||||
underglow_map[i].erase(underglow_map[i].begin()+width_udg, underglow_map[i].end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<unsigned int> RGBController_QMKOpenRGBRev9::FlattenMatrixMap
|
||||
(
|
||||
VectorMatrix matrix_map
|
||||
)
|
||||
{
|
||||
std::vector<unsigned int> flat_map;
|
||||
|
||||
for(const std::vector<unsigned int> &row : matrix_map)
|
||||
{
|
||||
for(const unsigned int &item : row)
|
||||
{
|
||||
flat_map.push_back(item);
|
||||
}
|
||||
}
|
||||
return flat_map;
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_QMKOpenRGBRev9.h |
|
||||
| |
|
||||
| RGBController for OpenRGB QMK Keyboard Protocol |
|
||||
| Revision 9 |
|
||||
| |
|
||||
| Kasper 10 Oct 2020 |
|
||||
| Jath03 28 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "RGBController.h"
|
||||
#include "QMKOpenRGBRev9Controller.h"
|
||||
|
||||
#define NO_LED 0xFFFFFFFF
|
||||
|
||||
typedef std::vector<std::vector<unsigned int>> VectorMatrix;
|
||||
|
||||
class RGBController_QMKOpenRGBRev9 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_QMKOpenRGBRev9(QMKOpenRGBRev9Controller* controller_ptr);
|
||||
~RGBController_QMKOpenRGBRev9();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
QMKOpenRGBRev9Controller* controller;
|
||||
std::vector<unsigned int> flat_matrix_map;
|
||||
std::vector<unsigned int> flat_underglow_map;
|
||||
|
||||
void InitializeMode
|
||||
(
|
||||
std::string name,
|
||||
unsigned int ¤t_mode,
|
||||
unsigned int flags,
|
||||
unsigned int color_mode
|
||||
);
|
||||
|
||||
unsigned int CalculateDivisor
|
||||
(
|
||||
std::vector<point_t> led_points,
|
||||
std::set<int> rows,
|
||||
std::set<int> columns
|
||||
);
|
||||
|
||||
void CountKeyTypes
|
||||
(
|
||||
std::vector<unsigned int> led_flags,
|
||||
unsigned int total_led_count,
|
||||
unsigned int& key_leds,
|
||||
unsigned int& underglow_leds
|
||||
);
|
||||
|
||||
void PlaceLEDsInMaps
|
||||
(
|
||||
std::set<int> unique_rows,
|
||||
std::set<int> unique_cols,
|
||||
unsigned int divisor,
|
||||
std::vector<point_t> led_points,
|
||||
std::vector<unsigned int> led_flags,
|
||||
VectorMatrix& matrix_map_xl,
|
||||
VectorMatrix& underglow_map_xl
|
||||
);
|
||||
|
||||
VectorMatrix MakeEmptyMatrixMap
|
||||
(
|
||||
std::size_t height,
|
||||
std::size_t width
|
||||
);
|
||||
|
||||
void CleanMatrixMaps
|
||||
(
|
||||
VectorMatrix& matrix_map,
|
||||
VectorMatrix& underglow_map,
|
||||
unsigned int height,
|
||||
bool has_underglow
|
||||
);
|
||||
|
||||
std::vector<unsigned int> FlattenMatrixMap
|
||||
(
|
||||
VectorMatrix matrix_map
|
||||
);
|
||||
};
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKOpenRGBRevBController.cpp |
|
||||
| |
|
||||
| Driver for OpenRGB QMK Keyboard Protocol Revision B |
|
||||
| |
|
||||
| Kasper 28 Jun 2021 |
|
||||
| Jath03 28 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "QMKKeycodes.h"
|
||||
#include "QMKOpenRGBRevBController.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
QMKOpenRGBRevBController::QMKOpenRGBRevBController(hid_device *dev_handle, const char *path) :
|
||||
QMKOpenRGBBaseController(dev_handle, path, 20)
|
||||
{
|
||||
}
|
||||
|
||||
QMKOpenRGBRevBController::~QMKOpenRGBRevBController()
|
||||
{
|
||||
}
|
||||
|
||||
void QMKOpenRGBRevBController::GetLEDInfo(unsigned int leds_count)
|
||||
{
|
||||
unsigned int leds_sent = 0;
|
||||
unsigned int leds_per_update_info = 8;
|
||||
|
||||
while (leds_sent < leds_count)
|
||||
{
|
||||
if ((leds_count - leds_sent) < leds_per_update_info)
|
||||
{
|
||||
leds_per_update_info = leds_count - leds_sent;
|
||||
}
|
||||
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_GET_LED_INFO;
|
||||
usb_buf[0x02] = leds_sent;
|
||||
usb_buf[0x03] = leds_per_update_info;
|
||||
|
||||
int bytes_read = 0;
|
||||
do
|
||||
{
|
||||
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
|
||||
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_OPENRGB_HID_READ_TIMEOUT);
|
||||
} while(bytes_read <= 0);
|
||||
|
||||
for (unsigned int led_idx = 0; led_idx < leds_per_update_info; led_idx++)
|
||||
{
|
||||
unsigned int offset = led_idx * 7;
|
||||
|
||||
if(usb_buf[(offset) + QMK_OPENRGB_FLAG_BYTE] != QMK_OPENRGB_FAILURE)
|
||||
{
|
||||
led_points.push_back(point_t{usb_buf[(offset) + QMK_OPENRGB_POINT_X_BYTE], usb_buf[(offset) + QMK_OPENRGB_POINT_Y_BYTE]});
|
||||
led_flags.push_back(usb_buf[(offset) + QMK_OPENRGB_FLAG_BYTE]);
|
||||
led_colors.push_back(ToRGBColor(usb_buf[(offset) + QMK_OPENRGB_R_COLOR_BYTE], usb_buf[(offset) + QMK_OPENRGB_G_COLOR_BYTE], usb_buf[(offset) + QMK_OPENRGB_B_COLOR_BYTE]));
|
||||
}
|
||||
|
||||
if(usb_buf[(offset) + QMK_OPENRGB_KEYCODE_BYTE] != 0)
|
||||
{
|
||||
if(qmk_keynames.count(usb_buf[(offset) + QMK_OPENRGB_KEYCODE_BYTE]) > 0)
|
||||
{
|
||||
led_names.push_back(qmk_keynames[usb_buf[(offset) + QMK_OPENRGB_KEYCODE_BYTE]]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("[%s] Key code: %d (%02X) @ offset %d was not found in the QMK keyname map",
|
||||
device_name.c_str(), usb_buf[offset + QMK_OPENRGB_KEYCODE_BYTE],
|
||||
usb_buf[offset + QMK_OPENRGB_KEYCODE_BYTE], leds_sent + led_idx);
|
||||
led_names.push_back(KEY_EN_UNUSED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leds_sent += leds_per_update_info;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<unsigned int> QMKOpenRGBRevBController::GetEnabledModes()
|
||||
{
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_GET_ENABLED_MODES;
|
||||
|
||||
int bytes_read = 0;
|
||||
do
|
||||
{
|
||||
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
|
||||
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_OPENRGB_HID_READ_TIMEOUT);
|
||||
} while(bytes_read <= 0);
|
||||
|
||||
std::vector<unsigned int> enabled_modes;
|
||||
int i = 1;
|
||||
while (usb_buf[i] != 0)
|
||||
{
|
||||
enabled_modes.push_back(usb_buf[i]);
|
||||
i++;
|
||||
}
|
||||
return enabled_modes;
|
||||
}
|
||||
|
||||
void QMKOpenRGBRevBController::DirectModeSetSingleLED(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_DIRECT_MODE_SET_SINGLE_LED;
|
||||
usb_buf[0x02] = led;
|
||||
usb_buf[0x03] = red;
|
||||
usb_buf[0x04] = green;
|
||||
usb_buf[0x05] = blue;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read_timeout(dev, usb_buf, 65, QMK_OPENRGB_HID_READ_TIMEOUT);
|
||||
}
|
||||
|
||||
void QMKOpenRGBRevBController::DirectModeSetLEDs(std::vector<RGBColor> colors, unsigned int leds_count)
|
||||
{
|
||||
unsigned int leds_sent = 0;
|
||||
unsigned int tmp_leds_per_update = leds_per_update;
|
||||
|
||||
while (leds_sent < leds_count)
|
||||
{
|
||||
if ((leds_count - leds_sent) < tmp_leds_per_update)
|
||||
{
|
||||
tmp_leds_per_update = leds_count - leds_sent;
|
||||
}
|
||||
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_DIRECT_MODE_SET_LEDS;
|
||||
usb_buf[0x02] = leds_sent;
|
||||
usb_buf[0x03] = tmp_leds_per_update;
|
||||
|
||||
for (unsigned int led_idx = 0; led_idx < tmp_leds_per_update; led_idx++)
|
||||
{
|
||||
usb_buf[(led_idx * 3) + 4] = RGBGetRValue(colors[led_idx + leds_sent]);
|
||||
usb_buf[(led_idx * 3) + 5] = RGBGetGValue(colors[led_idx + leds_sent]);
|
||||
usb_buf[(led_idx * 3) + 6] = RGBGetBValue(colors[led_idx + leds_sent]);
|
||||
}
|
||||
|
||||
hid_write(dev, usb_buf, 65);
|
||||
|
||||
if(delay > 0ms)
|
||||
{
|
||||
std::this_thread::sleep_for(delay);
|
||||
}
|
||||
|
||||
leds_sent += tmp_leds_per_update;
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKOpenRGBRevBController.h |
|
||||
| |
|
||||
| Driver for OpenRGB QMK Keyboard Protocol Revision B |
|
||||
| |
|
||||
| Kasper 28 Jun 2021 |
|
||||
| Jath03 28 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "QMKOpenRGBBaseController.h"
|
||||
|
||||
class QMKOpenRGBRevBController : public QMKOpenRGBBaseController
|
||||
{
|
||||
public:
|
||||
QMKOpenRGBRevBController(hid_device *dev_handle, const char *path);
|
||||
~QMKOpenRGBRevBController();
|
||||
|
||||
//Virtual function implementations
|
||||
void GetLEDInfo(unsigned int leds_count);
|
||||
void DirectModeSetSingleLED(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void DirectModeSetLEDs(std::vector<RGBColor> colors, unsigned int num_colors);
|
||||
|
||||
//Protocol Specific functions
|
||||
std::vector<unsigned int> GetEnabledModes();
|
||||
|
||||
private:
|
||||
};
|
||||
+807
@@ -0,0 +1,807 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_QMKOpenRGBRevB.cpp |
|
||||
| |
|
||||
| RGBController for OpenRGB QMK Keyboard Protocol |
|
||||
| Revision B |
|
||||
| |
|
||||
| Kasper 28 Jun 2021 |
|
||||
| Jath03 28 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "hsv.h"
|
||||
#include "LogManager.h"
|
||||
#include "RGBController_QMKOpenRGBRevB.h"
|
||||
|
||||
RGBController_QMKOpenRGBRevB::RGBController_QMKOpenRGBRevB(QMKOpenRGBRevBController* controller_ptr, bool save)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = controller->GetDeviceVendor();
|
||||
description = "QMK OpenRGB Device (Protocol Version " + std::to_string(controller->GetProtocolVersion()) + ")";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
location = controller->GetLocation();
|
||||
version = controller->GetQMKVersion();
|
||||
|
||||
unsigned int current_mode = 1;
|
||||
std::vector<unsigned int> enabled_modes = controller->GetEnabledModes();
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_COLOR) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Static", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_ALPHA_MOD) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Alpha Mod", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_GRADIENT_UP_DOWN) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Gradient Up Down", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_GRADIENT_LEFT_RIGHT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Gradient Left Right", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BREATHING) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Breathing", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_SAT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_VAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_PINWHEEL_SAT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Pinwheel Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_PINWHEEL_VAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Pinwheel Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_SPIRAL_SAT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Spiral Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_SPIRAL_VAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Spiral Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_ALL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle All", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_LEFT_RIGHT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Left Right", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_UP_DOWN) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Up Down", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_OUT_IN) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Out In", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_OUT_IN_DUAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Out In Dual", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINBOW_MOVING_CHEVRON) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Moving Chevron", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_PINWHEEL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Pinwheel", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_SPIRAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Spiral", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_DUAL_BEACON) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Dual Beacon", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINBOW_BEACON) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Beacon", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINBOW_PINWHEELS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Pinwheels", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINDROPS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Raindrops", current_mode, 0, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_JELLYBEAN_RAINDROPS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Jellybean Raindrops", current_mode, 0, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_HUE_BREATHING) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Hue Breathing", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_HUE_PENDULUM) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Hue Pendulum", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_HUE_WAVE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Hue Wave", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_TYPING_HEATMAP) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Typing Heatmap", current_mode, 0, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_DIGITAL_RAIN) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Digital Rain", current_mode, 0, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_SIMPLE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Simple", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_WIDE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Wide", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTIWIDE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Wide", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_CROSS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Cross", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTICROSS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Cross", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_NEXUS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Nexus", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTINEXUS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Nexus", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SPLASH) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Reactive Splash", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_MULTISPLASH) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Reactive Multi Splash", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_SPLASH) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Splash", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_MULTISPLASH) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Splash", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_OPENRGB_DIRECT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Direct", current_mode, MODE_FLAG_HAS_PER_LED_COLOR, MODE_COLORS_PER_LED, save);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| As we are insertting direct mode at index 0 |
|
||||
| for it to be the first mode in the UI there will |
|
||||
| be a mismatch between the values. QMK has direct |
|
||||
| mode last in order, while in OpenRGB it's first. |
|
||||
\*-----------------------------------------------------*/
|
||||
if(controller->GetMode() == (current_mode - 1))
|
||||
{
|
||||
active_mode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
active_mode = controller->GetMode();
|
||||
}
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_QMKOpenRGBRevB::~RGBController_QMKOpenRGBRevB()
|
||||
{
|
||||
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
|
||||
{
|
||||
if(zones[zone_index].matrix_map != NULL)
|
||||
{
|
||||
delete zones[zone_index].matrix_map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevB::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Get the number of LEDs from the device |
|
||||
\*---------------------------------------------------------*/
|
||||
const unsigned int total_number_of_leds = controller->GetTotalNumberOfLEDs();
|
||||
const unsigned int total_number_of_leds_with_empty_space = controller->GetTotalNumberOfLEDsWithEmptySpace();
|
||||
|
||||
LOG_INFO("[%s] Keyboard has %u LEDs total", name.c_str(), total_number_of_leds);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get information for each LED |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->GetLEDInfo(std::max(total_number_of_leds, total_number_of_leds_with_empty_space));
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get LED vectors from controller |
|
||||
\*---------------------------------------------------------*/
|
||||
std::vector<point_t> led_points = controller->GetLEDPoints();
|
||||
std::vector<unsigned int> led_flags = controller->GetLEDFlags();
|
||||
std::vector<std::string> led_names = controller->GetLEDNames();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Count key LEDs and underglow LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int number_of_key_leds;
|
||||
unsigned int number_of_underglow_leds;
|
||||
|
||||
CountKeyTypes(led_flags, total_number_of_leds, number_of_key_leds, number_of_underglow_leds);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Add LED names for underglow zone |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int number_of_leds = number_of_key_leds + number_of_underglow_leds;
|
||||
bool has_underglow = number_of_underglow_leds > 0;
|
||||
LOG_INFO("[%s] Keyboard has %u underglow LEDs", name.c_str(), number_of_underglow_leds);
|
||||
|
||||
for(unsigned int i = 0; i < number_of_underglow_leds; i++)
|
||||
{
|
||||
led_names.push_back("Underglow: " + std::to_string(number_of_key_leds + i));
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create sets for row and column position values |
|
||||
\*---------------------------------------------------------*/
|
||||
std::set<int> rows, columns;
|
||||
for (unsigned int i = 0; i < number_of_leds; i++)
|
||||
{
|
||||
rows.insert(led_points[i].y);
|
||||
columns.insert(led_points[i].x);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Calculate matrix map from QMK positions |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int divisor = CalculateDivisor(led_points, rows, columns);
|
||||
LOG_DEBUG("[%s] Distance between standard keys calculated to be %u", name.c_str(), divisor);
|
||||
|
||||
VectorMatrix matrix_map;
|
||||
VectorMatrix underglow_map;
|
||||
|
||||
PlaceLEDsInMaps(rows, columns, divisor, led_points, led_flags, matrix_map, underglow_map);
|
||||
CleanMatrixMaps(matrix_map, underglow_map, (unsigned int)rows.size(), has_underglow);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| These vectors are class members because if they go out of |
|
||||
| scope, the underlying array (used by each zones' |
|
||||
| matrix_map) is unallocated. |
|
||||
\*---------------------------------------------------------*/
|
||||
flat_matrix_map = FlattenMatrixMap(matrix_map);
|
||||
flat_underglow_map = FlattenMatrixMap(underglow_map);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create Keyboard zone |
|
||||
\*---------------------------------------------------------*/
|
||||
zone keys_zone;
|
||||
keys_zone.name = "Keyboard";
|
||||
keys_zone.type = ZONE_TYPE_MATRIX;
|
||||
keys_zone.leds_min = number_of_key_leds;
|
||||
keys_zone.leds_max = keys_zone.leds_min;
|
||||
keys_zone.leds_count = keys_zone.leds_min;
|
||||
keys_zone.matrix_map = new matrix_map_type;
|
||||
keys_zone.matrix_map->width = (unsigned int)matrix_map[0].size();
|
||||
keys_zone.matrix_map->height = (unsigned int)matrix_map.size();
|
||||
keys_zone.matrix_map->map = flat_matrix_map.data();
|
||||
zones.push_back(keys_zone);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create Underglow zone if it exists |
|
||||
\*---------------------------------------------------------*/
|
||||
if(has_underglow)
|
||||
{
|
||||
zone underglow_zone;
|
||||
underglow_zone.name = "Underglow";
|
||||
underglow_zone.type = ZONE_TYPE_MATRIX;
|
||||
underglow_zone.leds_min = number_of_underglow_leds;
|
||||
underglow_zone.leds_max = underglow_zone.leds_min;
|
||||
underglow_zone.leds_count = underglow_zone.leds_min;
|
||||
underglow_zone.matrix_map = new matrix_map_type;
|
||||
underglow_zone.matrix_map->width = (unsigned int)underglow_map[0].size();
|
||||
underglow_zone.matrix_map->height = (unsigned int)underglow_map.size();
|
||||
underglow_zone.matrix_map->map = flat_underglow_map.data();
|
||||
zones.push_back(underglow_zone);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int led_idx = 0; led_idx < number_of_leds; led_idx++)
|
||||
{
|
||||
led keyboard_led;
|
||||
|
||||
if(led_idx < led_names.size())
|
||||
{
|
||||
keyboard_led.name = led_names[led_idx];
|
||||
}
|
||||
keyboard_led.value = led_idx;
|
||||
|
||||
leds.push_back(keyboard_led);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Setup Colors |
|
||||
\*---------------------------------------------------------*/
|
||||
SetupColors();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Initialize colors from device values |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < leds.size(); i++)
|
||||
{
|
||||
colors[i] = controller->GetLEDColors()[i];
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevB::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevB::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->DirectModeSetLEDs(colors, controller->GetTotalNumberOfLEDs());
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevB::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevB::UpdateSingleLED(int led)
|
||||
{
|
||||
RGBColor color = colors[led];
|
||||
unsigned char red = RGBGetRValue(color);
|
||||
unsigned char grn = RGBGetGValue(color);
|
||||
unsigned char blu = RGBGetBValue(color);
|
||||
|
||||
controller->DirectModeSetSingleLED(led, red, grn, blu);
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevB::DeviceUpdateMode()
|
||||
{
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_PER_LED)
|
||||
{
|
||||
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, 127, false);
|
||||
}
|
||||
else if(modes[active_mode].color_mode == MODE_COLORS_NONE)
|
||||
{
|
||||
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, modes[active_mode].speed, false);
|
||||
}
|
||||
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
RGBColor rgb_color = modes[active_mode].colors[0];
|
||||
hsv_t hsv_color;
|
||||
rgb2hsv(rgb_color, &hsv_color);
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
controller->SetMode(hsv_color, modes[active_mode].value, modes[active_mode].speed, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetMode(hsv_color, modes[active_mode].value, 127, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevB::DeviceSaveMode()
|
||||
{
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_NONE)
|
||||
{
|
||||
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, modes[active_mode].speed, true);
|
||||
}
|
||||
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
RGBColor rgb_color = modes[active_mode].colors[0];
|
||||
hsv_t hsv_color;
|
||||
rgb2hsv(rgb_color, &hsv_color);
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
controller->SetMode(hsv_color, modes[active_mode].value, modes[active_mode].speed, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetMode(hsv_color, modes[active_mode].value, 127, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevB::InitializeMode
|
||||
(
|
||||
std::string name,
|
||||
unsigned int ¤t_mode,
|
||||
unsigned int flags,
|
||||
unsigned int color_mode,
|
||||
bool save
|
||||
)
|
||||
{
|
||||
mode qmk_mode;
|
||||
qmk_mode.name = name;
|
||||
qmk_mode.value = current_mode++;
|
||||
qmk_mode.flags = flags;
|
||||
qmk_mode.color_mode = color_mode;
|
||||
|
||||
if(flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
qmk_mode.speed_min = QMK_OPENRGB_SPEED_SLOWEST;
|
||||
qmk_mode.speed_max = QMK_OPENRGB_SPEED_FASTEST;
|
||||
qmk_mode.speed = QMK_OPENRGB_SPEED_NORMAL;
|
||||
}
|
||||
if(flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
|
||||
{
|
||||
qmk_mode.colors_min = 1;
|
||||
qmk_mode.colors_max = 1;
|
||||
qmk_mode.colors.resize(1);
|
||||
qmk_mode.colors[0] = controller->GetModeColor();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Direct mode it the last mode on the QMK firmware |
|
||||
| but we still want it to appear first on the UI |
|
||||
\*-----------------------------------------------------*/
|
||||
if(flags & MODE_FLAG_HAS_PER_LED_COLOR)
|
||||
{
|
||||
modes.insert(modes.begin(), qmk_mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Every mode apart from direct is save-able |
|
||||
\*-----------------------------------------------------*/
|
||||
if(save == true)
|
||||
{
|
||||
qmk_mode.flags = flags | MODE_FLAG_MANUAL_SAVE;
|
||||
}
|
||||
modes.push_back(qmk_mode);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int RGBController_QMKOpenRGBRevB::CalculateDivisor
|
||||
(
|
||||
std::vector<point_t> led_points,
|
||||
std::set<int> rows,
|
||||
std::set<int> /*columns*/
|
||||
)
|
||||
{
|
||||
std::vector< std::vector<point_t> > row_points(rows.size());
|
||||
for(const point_t &pt : led_points)
|
||||
{
|
||||
for(const int &i : rows)
|
||||
{
|
||||
if(pt.y == i)
|
||||
{
|
||||
row_points[std::distance(rows.begin(), rows.find(i))].push_back(pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int last_pos;
|
||||
std::vector<int> distances;
|
||||
for(const std::vector<point_t> &row : row_points)
|
||||
{
|
||||
last_pos = 0;
|
||||
std::for_each(row.begin(), row.end(), [&distances, &last_pos](const point_t &pt)
|
||||
{
|
||||
distances.push_back(std::abs(pt.x - last_pos));
|
||||
last_pos = pt.x;
|
||||
});
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Guard against empty distances (malformed LED data) |
|
||||
\*---------------------------------------------------------*/
|
||||
if(distances.empty())
|
||||
{
|
||||
LOG_WARNING("[%s] No valid LED distances found, using default divisor of 1", name.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::map<int, int> counts;
|
||||
for(const int &i : distances)
|
||||
{
|
||||
counts[i]++;
|
||||
}
|
||||
|
||||
unsigned int divisor = distances[0];
|
||||
for(const std::pair<const int, int> &i : counts)
|
||||
{
|
||||
if(counts[divisor] < i.second)
|
||||
{
|
||||
divisor = i.first;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Guard against zero divisor (prevents division by zero) |
|
||||
\*---------------------------------------------------------*/
|
||||
if(divisor == 0)
|
||||
{
|
||||
LOG_WARNING("[%s] Calculated divisor is 0, using default of 1. This may indicate malformed LED position data.", name.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return divisor;
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevB::CountKeyTypes
|
||||
(
|
||||
std::vector<unsigned int> led_flags,
|
||||
unsigned int total_led_count,
|
||||
unsigned int& key_leds,
|
||||
unsigned int& underglow_leds
|
||||
)
|
||||
{
|
||||
underglow_leds = 0;
|
||||
key_leds = 0;
|
||||
|
||||
for(unsigned int i = 0; i < total_led_count; i++)
|
||||
{
|
||||
if(led_flags[i] & 2)
|
||||
{
|
||||
underglow_leds++;
|
||||
}
|
||||
else if(led_flags[i] != 0)
|
||||
{
|
||||
key_leds++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevB::PlaceLEDsInMaps
|
||||
(
|
||||
std::set<int> unique_rows,
|
||||
std::set<int> /*unique_cols*/,
|
||||
unsigned int divisor,
|
||||
std::vector<point_t> led_points,
|
||||
std::vector<unsigned int> led_flags,
|
||||
VectorMatrix& matrix_map_xl,
|
||||
VectorMatrix& underglow_map_xl
|
||||
)
|
||||
{
|
||||
matrix_map_xl = MakeEmptyMatrixMap(unique_rows.size(), (std::size_t)(std::round(255 / divisor) + 10));
|
||||
underglow_map_xl = MakeEmptyMatrixMap(unique_rows.size(), (std::size_t)(std::round(255 / divisor) + 10));
|
||||
|
||||
unsigned int x = 0;
|
||||
unsigned int y = 0;
|
||||
unsigned int underglow_counter = 0;
|
||||
|
||||
for(unsigned int i = 0; i < controller->GetTotalNumberOfLEDs(); i++)
|
||||
{
|
||||
if(led_points[i].x != 255 && led_points[i].y != 255)
|
||||
{
|
||||
bool underglow = led_flags[i] & 2;
|
||||
|
||||
x = (unsigned int)(std::round(led_points[i].x / divisor));
|
||||
y = (unsigned int)(std::distance(unique_rows.begin(), unique_rows.find(led_points[i].y)));
|
||||
|
||||
if(!underglow)
|
||||
{
|
||||
while(matrix_map_xl[y][x] != NO_LED)
|
||||
{
|
||||
x++;
|
||||
}
|
||||
matrix_map_xl[y][x] = i;
|
||||
LOG_DEBUG("[%s] Key Matrix LED %u, (%u, %u) being placed into (%u, %u)", name.c_str(), i, led_points[i].x, led_points[i].y, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
while(underglow_map_xl[y][x] != NO_LED)
|
||||
{
|
||||
x++;
|
||||
}
|
||||
underglow_map_xl[y][x] = underglow_counter;
|
||||
underglow_counter++;
|
||||
LOG_DEBUG("[%s] Underglow LED %u, (%u, %u) being placed into (%u, %u)", name.c_str(), i, led_points[i].x, led_points[i].y, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VectorMatrix RGBController_QMKOpenRGBRevB::MakeEmptyMatrixMap
|
||||
(
|
||||
std::size_t height,
|
||||
std::size_t width
|
||||
)
|
||||
{
|
||||
std::vector<std::vector<unsigned int> > matrix_map(height);
|
||||
for(std::size_t i = 0; i < height; i++)
|
||||
{
|
||||
for(std::size_t j = 0; j < width; j++)
|
||||
{
|
||||
matrix_map[i].push_back(NO_LED);
|
||||
}
|
||||
}
|
||||
return matrix_map;
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevB::CleanMatrixMaps
|
||||
(
|
||||
VectorMatrix& matrix_map,
|
||||
VectorMatrix& underglow_map,
|
||||
unsigned int height,
|
||||
bool has_underglow
|
||||
)
|
||||
{
|
||||
bool empty_col = true;
|
||||
bool empty_col_udg = true;
|
||||
bool empty_row = true;
|
||||
int width = 0;
|
||||
int width_udg = 0;
|
||||
|
||||
std::vector<int> empty_rows;
|
||||
|
||||
bool can_break;
|
||||
bool can_break_udg;
|
||||
|
||||
for(unsigned int i = 0; i < height; i++)
|
||||
{
|
||||
empty_row = true;
|
||||
can_break = false;
|
||||
can_break_udg = false;
|
||||
|
||||
for(int j = (int)matrix_map[i].size() - 1; j --> 0; )
|
||||
{
|
||||
if(matrix_map[i][j] != NO_LED && width < (j + 1) && !can_break)
|
||||
{
|
||||
width = (j + 1);
|
||||
can_break = true;
|
||||
empty_row = false;
|
||||
}
|
||||
else if(matrix_map[i][j] != NO_LED)
|
||||
{
|
||||
empty_row = false;
|
||||
}
|
||||
if(underglow_map[i][j] != NO_LED && width_udg < (j + 1) && !can_break_udg)
|
||||
{
|
||||
width_udg = (j + 1);
|
||||
can_break_udg = true;
|
||||
}
|
||||
if (can_break && can_break_udg) break;
|
||||
}
|
||||
|
||||
if(matrix_map[i][0] != NO_LED)
|
||||
{
|
||||
empty_col = false;
|
||||
}
|
||||
|
||||
if(underglow_map[i][0] != NO_LED)
|
||||
{
|
||||
empty_col_udg = false;
|
||||
}
|
||||
|
||||
if(empty_row)
|
||||
{
|
||||
empty_rows.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int new_height = height - (unsigned int)empty_rows.size();
|
||||
width = empty_col ? width - 1 : width;
|
||||
width_udg = empty_col_udg && empty_col ? width_udg - 1 : width_udg;
|
||||
LOG_DEBUG("[%s] Key LED Matrix: %ux%u", name.c_str(), width, new_height);
|
||||
LOG_DEBUG("[%s] Underglow LED Matrix: %ux%u", name.c_str(), width_udg, new_height);
|
||||
|
||||
for(unsigned int i = (unsigned int)empty_rows.size(); i --> 0; )
|
||||
{
|
||||
matrix_map.erase(matrix_map.begin()+empty_rows[i]);
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < new_height; i++)
|
||||
{
|
||||
if(empty_col)
|
||||
{
|
||||
matrix_map[i].erase(matrix_map[i].begin(), matrix_map[i].begin() + 1);
|
||||
}
|
||||
|
||||
if(empty_col_udg && empty_col)
|
||||
{
|
||||
underglow_map[i].erase(underglow_map[i].begin(), underglow_map[i].begin() + 1);
|
||||
}
|
||||
|
||||
matrix_map[i].erase(matrix_map[i].begin()+width, matrix_map[i].end());
|
||||
|
||||
if(has_underglow)
|
||||
{
|
||||
underglow_map[i].erase(underglow_map[i].begin()+width_udg, underglow_map[i].end());
|
||||
}
|
||||
}
|
||||
|
||||
if(has_underglow)
|
||||
{
|
||||
for(unsigned int i = new_height; i < height; i++)
|
||||
{
|
||||
underglow_map[i].erase(underglow_map[i].begin()+width_udg, underglow_map[i].end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<unsigned int> RGBController_QMKOpenRGBRevB::FlattenMatrixMap
|
||||
(
|
||||
VectorMatrix matrix_map
|
||||
)
|
||||
{
|
||||
std::vector<unsigned int> flat_map;
|
||||
|
||||
for(const std::vector<unsigned int> &row : matrix_map)
|
||||
{
|
||||
for(const unsigned int &item : row)
|
||||
{
|
||||
flat_map.push_back(item);
|
||||
}
|
||||
}
|
||||
return flat_map;
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_QMKOpenRGBRevB.h |
|
||||
| |
|
||||
| RGBController for OpenRGB QMK Keyboard Protocol |
|
||||
| Revision B |
|
||||
| |
|
||||
| Kasper 28 Jun 2021 |
|
||||
| Jath03 28 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "RGBController.h"
|
||||
#include "QMKOpenRGBRevBController.h"
|
||||
|
||||
#define NO_LED 0xFFFFFFFF
|
||||
|
||||
typedef std::vector<std::vector<unsigned int>> VectorMatrix;
|
||||
|
||||
class RGBController_QMKOpenRGBRevB : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_QMKOpenRGBRevB(QMKOpenRGBRevBController* controller_ptr, bool save);
|
||||
~RGBController_QMKOpenRGBRevB();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
QMKOpenRGBRevBController* controller;
|
||||
std::vector<unsigned int> flat_matrix_map;
|
||||
std::vector<unsigned int> flat_underglow_map;
|
||||
|
||||
void InitializeMode
|
||||
(
|
||||
std::string name,
|
||||
unsigned int ¤t_mode,
|
||||
unsigned int flags,
|
||||
unsigned int color_mode,
|
||||
bool save
|
||||
);
|
||||
|
||||
unsigned int CalculateDivisor
|
||||
(
|
||||
std::vector<point_t> led_points,
|
||||
std::set<int> rows,
|
||||
std::set<int> columns
|
||||
);
|
||||
|
||||
void CountKeyTypes
|
||||
(
|
||||
std::vector<unsigned int> led_flags,
|
||||
unsigned int total_led_count,
|
||||
unsigned int& key_leds,
|
||||
unsigned int& underglow_leds
|
||||
);
|
||||
|
||||
void PlaceLEDsInMaps
|
||||
(
|
||||
std::set<int> unique_rows,
|
||||
std::set<int> unique_cols,
|
||||
unsigned int divisor,
|
||||
std::vector<point_t> led_points,
|
||||
std::vector<unsigned int> led_flags,
|
||||
VectorMatrix& matrix_map_xl,
|
||||
VectorMatrix& underglow_map_xl
|
||||
);
|
||||
|
||||
VectorMatrix MakeEmptyMatrixMap
|
||||
(
|
||||
std::size_t height,
|
||||
std::size_t width
|
||||
);
|
||||
|
||||
void CleanMatrixMaps
|
||||
(
|
||||
VectorMatrix& matrix_map,
|
||||
VectorMatrix& underglow_map,
|
||||
unsigned int height,
|
||||
bool has_underglow
|
||||
);
|
||||
|
||||
std::vector<unsigned int> FlattenMatrixMap
|
||||
(
|
||||
VectorMatrix matrix_map
|
||||
);
|
||||
};
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKOpenRGBRevDController.cpp |
|
||||
| |
|
||||
| Driver for OpenRGB QMK Keyboard Protocol Revision D |
|
||||
| |
|
||||
| Neneya 26 Dec 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "QMKKeycodes.h"
|
||||
#include "QMKOpenRGBRevDController.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
QMKOpenRGBRevDController::QMKOpenRGBRevDController(hid_device *dev_handle, const char *path) :
|
||||
QMKOpenRGBBaseController(dev_handle, path, 15)
|
||||
{
|
||||
}
|
||||
|
||||
QMKOpenRGBRevDController::~QMKOpenRGBRevDController()
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<unsigned int> QMKOpenRGBRevDController::GetLEDValues()
|
||||
{
|
||||
return led_values;
|
||||
}
|
||||
|
||||
void QMKOpenRGBRevDController::GetLEDInfo(unsigned int leds_count)
|
||||
{
|
||||
unsigned int leds_sent = 0;
|
||||
unsigned int leds_per_update_info = 8;
|
||||
|
||||
std::vector<point_t> underglow_points;
|
||||
std::vector<unsigned int> underglow_flags;
|
||||
std::vector<std::string> underglow_names;
|
||||
std::vector<RGBColor> underglow_colors;
|
||||
std::vector<unsigned int> underglow_values;
|
||||
|
||||
while (leds_sent < leds_count)
|
||||
{
|
||||
if ((leds_count - leds_sent) < leds_per_update_info)
|
||||
{
|
||||
leds_per_update_info = leds_count - leds_sent;
|
||||
}
|
||||
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_GET_LED_INFO;
|
||||
usb_buf[0x02] = leds_sent;
|
||||
usb_buf[0x03] = leds_per_update_info;
|
||||
|
||||
int bytes_read = 0;
|
||||
do
|
||||
{
|
||||
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
|
||||
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_OPENRGB_HID_READ_TIMEOUT);
|
||||
} while(bytes_read <= 0);
|
||||
|
||||
for (unsigned int led_idx = 0; led_idx < leds_per_update_info; led_idx++)
|
||||
{
|
||||
unsigned int offset = led_idx * 7;
|
||||
|
||||
if(usb_buf[offset + QMK_OPENRGB_FLAG_BYTE] != QMK_OPENRGB_FAILURE)
|
||||
{
|
||||
if(usb_buf[offset + QMK_OPENRGB_FLAG_BYTE] & 2)
|
||||
{
|
||||
underglow_points.push_back(point_t{usb_buf[offset + QMK_OPENRGB_POINT_X_BYTE], usb_buf[offset + QMK_OPENRGB_POINT_Y_BYTE]});
|
||||
underglow_flags.push_back(usb_buf[offset + QMK_OPENRGB_FLAG_BYTE]);
|
||||
underglow_colors.push_back(ToRGBColor(usb_buf[offset + QMK_OPENRGB_R_COLOR_BYTE], usb_buf[offset + QMK_OPENRGB_G_COLOR_BYTE], usb_buf[offset + QMK_OPENRGB_B_COLOR_BYTE]));
|
||||
underglow_values.push_back((unsigned int)(underglow_values.size() + led_values.size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
led_points.push_back(point_t{usb_buf[offset + QMK_OPENRGB_POINT_X_BYTE], usb_buf[offset + QMK_OPENRGB_POINT_Y_BYTE]});
|
||||
led_flags.push_back(usb_buf[offset + QMK_OPENRGB_FLAG_BYTE]);
|
||||
led_colors.push_back(ToRGBColor(usb_buf[offset + QMK_OPENRGB_R_COLOR_BYTE], usb_buf[offset + QMK_OPENRGB_G_COLOR_BYTE], usb_buf[offset + QMK_OPENRGB_B_COLOR_BYTE]));
|
||||
led_values.push_back((unsigned int)(underglow_values.size() + led_values.size()));
|
||||
}
|
||||
}
|
||||
|
||||
if(usb_buf[offset + QMK_OPENRGB_KEYCODE_BYTE] != 0)
|
||||
{
|
||||
if(qmk_keynames.count(usb_buf[offset + QMK_OPENRGB_KEYCODE_BYTE]) > 0)
|
||||
{
|
||||
led_names.push_back(qmk_keynames[usb_buf[offset + QMK_OPENRGB_KEYCODE_BYTE]]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_DEBUG("[%s] Key code: %d (%02X) @ offset %d was not found in the QMK keyname map",
|
||||
device_name.c_str(), usb_buf[offset + QMK_OPENRGB_KEYCODE_BYTE],
|
||||
usb_buf[offset + QMK_OPENRGB_KEYCODE_BYTE], leds_sent + led_idx);
|
||||
led_names.push_back(KEY_EN_UNUSED);
|
||||
}
|
||||
}
|
||||
else if(usb_buf[offset + QMK_OPENRGB_FLAG_BYTE] & 2)
|
||||
{
|
||||
underglow_names.push_back("Underglow: " + std::to_string(underglow_names.size() + led_names.size()));
|
||||
}
|
||||
}
|
||||
|
||||
leds_sent += leds_per_update_info;
|
||||
}
|
||||
|
||||
led_points.insert(led_points.end(), underglow_points.begin(), underglow_points.end());
|
||||
led_flags.insert(led_flags.end(), underglow_flags.begin(), underglow_flags.end());
|
||||
led_colors.insert(led_colors.end(), underglow_colors.begin(), underglow_colors.end());
|
||||
led_names.insert(led_names.end(), underglow_names.begin(), underglow_names.end());
|
||||
led_values.insert(led_values.end(), underglow_values.begin(), underglow_values.end());
|
||||
}
|
||||
|
||||
std::vector<unsigned int> QMKOpenRGBRevDController::GetEnabledModes()
|
||||
{
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_GET_ENABLED_MODES;
|
||||
|
||||
int bytes_read = 0;
|
||||
do
|
||||
{
|
||||
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
|
||||
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_OPENRGB_HID_READ_TIMEOUT);
|
||||
} while(bytes_read <= 0);
|
||||
|
||||
std::vector<unsigned int> enabled_modes;
|
||||
int i = 1;
|
||||
while (usb_buf[i] != 0)
|
||||
{
|
||||
enabled_modes.push_back(usb_buf[i]);
|
||||
i++;
|
||||
}
|
||||
return enabled_modes;
|
||||
}
|
||||
|
||||
void QMKOpenRGBRevDController::DirectModeSetSingleLED(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_DIRECT_MODE_SET_SINGLE_LED;
|
||||
usb_buf[0x02] = led_values[led];
|
||||
usb_buf[0x03] = red;
|
||||
usb_buf[0x04] = green;
|
||||
usb_buf[0x05] = blue;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read_timeout(dev, usb_buf, 65, QMK_OPENRGB_HID_READ_TIMEOUT);
|
||||
}
|
||||
|
||||
void QMKOpenRGBRevDController::DirectModeSetLEDs(std::vector<RGBColor> colors, unsigned int leds_count)
|
||||
{
|
||||
unsigned int leds_sent = 0;
|
||||
unsigned int tmp_leds_per_update = leds_per_update;
|
||||
|
||||
while (leds_sent < leds_count)
|
||||
{
|
||||
if ((leds_count - leds_sent) < tmp_leds_per_update)
|
||||
{
|
||||
tmp_leds_per_update = leds_count - leds_sent;
|
||||
}
|
||||
|
||||
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up config table request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = QMK_OPENRGB_DIRECT_MODE_SET_LEDS;
|
||||
usb_buf[0x02] = tmp_leds_per_update;
|
||||
|
||||
for (unsigned int led_idx = 0; led_idx < tmp_leds_per_update; led_idx++)
|
||||
{
|
||||
usb_buf[(led_idx * 4) + 3] = led_values[led_idx + leds_sent];
|
||||
usb_buf[(led_idx * 4) + 4] = RGBGetRValue(colors[led_idx + leds_sent]);
|
||||
usb_buf[(led_idx * 4) + 5] = RGBGetGValue(colors[led_idx + leds_sent]);
|
||||
usb_buf[(led_idx * 4) + 6] = RGBGetBValue(colors[led_idx + leds_sent]);
|
||||
}
|
||||
|
||||
hid_write(dev, usb_buf, 65);
|
||||
|
||||
if(delay > 0ms)
|
||||
{
|
||||
std::this_thread::sleep_for(delay);
|
||||
}
|
||||
|
||||
leds_sent += tmp_leds_per_update;
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKOpenRGBRevDController.h |
|
||||
| |
|
||||
| Driver for OpenRGB QMK Keyboard Protocol Revision D |
|
||||
| |
|
||||
| Neneya 26 Dec 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "QMKOpenRGBBaseController.h"
|
||||
|
||||
class QMKOpenRGBRevDController : public QMKOpenRGBBaseController
|
||||
{
|
||||
public:
|
||||
QMKOpenRGBRevDController(hid_device *dev_handle, const char *path);
|
||||
~QMKOpenRGBRevDController();
|
||||
|
||||
//Virtual function implementations
|
||||
void GetLEDInfo(unsigned int leds_count);
|
||||
void DirectModeSetSingleLED(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void DirectModeSetLEDs(std::vector<RGBColor> colors, unsigned int num_colors);
|
||||
|
||||
//Protocol Specific functions
|
||||
std::vector<unsigned int> GetLEDValues();
|
||||
std::vector<unsigned int> GetEnabledModes();
|
||||
|
||||
private:
|
||||
std::vector<unsigned int> led_values;
|
||||
};
|
||||
+804
@@ -0,0 +1,804 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_QMKOpenRGBRevD.cpp |
|
||||
| |
|
||||
| RGBController for OpenRGB QMK Keyboard Protocol |
|
||||
| Revision D |
|
||||
| |
|
||||
| Neneya 26 Dec 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "hsv.h"
|
||||
#include "LogManager.h"
|
||||
#include "RGBController_QMKOpenRGBRevD.h"
|
||||
|
||||
RGBController_QMKOpenRGBRevD::RGBController_QMKOpenRGBRevD(QMKOpenRGBRevDController* controller_ptr, bool save)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = controller->GetDeviceVendor();
|
||||
description = "QMK OpenRGB Device (Protocol Version " + std::to_string(controller->GetProtocolVersion()) + ")";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
location = controller->GetLocation();
|
||||
version = controller->GetQMKVersion();
|
||||
|
||||
unsigned int current_mode = 1;
|
||||
std::vector<unsigned int> enabled_modes = controller->GetEnabledModes();
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_COLOR) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Static", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_ALPHA_MOD) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Alpha Mod", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_GRADIENT_UP_DOWN) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Gradient Up Down", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_GRADIENT_LEFT_RIGHT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Gradient Left Right", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BREATHING) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Breathing", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_SAT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_VAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_PINWHEEL_SAT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Pinwheel Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_PINWHEEL_VAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Pinwheel Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_SPIRAL_SAT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Spiral Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_SPIRAL_VAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Spiral Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_ALL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle All", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_LEFT_RIGHT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Left Right", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_UP_DOWN) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Up Down", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_OUT_IN) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Out In", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_OUT_IN_DUAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Out In Dual", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINBOW_MOVING_CHEVRON) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Moving Chevron", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_PINWHEEL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Pinwheel", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_SPIRAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Spiral", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_DUAL_BEACON) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Dual Beacon", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINBOW_BEACON) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Beacon", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINBOW_PINWHEELS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Pinwheels", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINDROPS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Raindrops", current_mode, 0, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_JELLYBEAN_RAINDROPS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Jellybean Raindrops", current_mode, 0, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_HUE_BREATHING) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Hue Breathing", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_HUE_PENDULUM) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Hue Pendulum", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_HUE_WAVE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Hue Wave", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_TYPING_HEATMAP) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Typing Heatmap", current_mode, 0, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_DIGITAL_RAIN) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Digital Rain", current_mode, 0, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_SIMPLE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Simple", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_WIDE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Wide", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTIWIDE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Wide", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_CROSS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Cross", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTICROSS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Cross", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_NEXUS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Nexus", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTINEXUS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Nexus", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SPLASH) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Reactive Splash", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_MULTISPLASH) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Reactive Multi Splash", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_SPLASH) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Splash", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_MULTISPLASH) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Splash", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_OPENRGB_DIRECT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Direct", current_mode, MODE_FLAG_HAS_PER_LED_COLOR, MODE_COLORS_PER_LED, save);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| As we are insertting direct mode at index 0 |
|
||||
| for it to be the first mode in the UI there will |
|
||||
| be a mismatch between the values. QMK has direct |
|
||||
| mode last in order, while in OpenRGB it's first. |
|
||||
\*-----------------------------------------------------*/
|
||||
if(controller->GetMode() == (current_mode - 1))
|
||||
{
|
||||
active_mode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
active_mode = controller->GetMode();
|
||||
}
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_QMKOpenRGBRevD::~RGBController_QMKOpenRGBRevD()
|
||||
{
|
||||
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
|
||||
{
|
||||
if(zones[zone_index].matrix_map != NULL)
|
||||
{
|
||||
delete zones[zone_index].matrix_map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevD::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Get the number of LEDs from the device |
|
||||
\*---------------------------------------------------------*/
|
||||
const unsigned int total_number_of_leds = controller->GetTotalNumberOfLEDs();
|
||||
const unsigned int total_number_of_leds_with_empty_space = controller->GetTotalNumberOfLEDsWithEmptySpace();
|
||||
|
||||
LOG_INFO("[%s] Keyboard has %u LEDs total", name.c_str(), total_number_of_leds);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get information for each LED |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->GetLEDInfo(std::max(total_number_of_leds, total_number_of_leds_with_empty_space));
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get LED vectors from controller |
|
||||
\*---------------------------------------------------------*/
|
||||
std::vector<point_t> led_points = controller->GetLEDPoints();
|
||||
std::vector<unsigned int> led_flags = controller->GetLEDFlags();
|
||||
std::vector<std::string> led_names = controller->GetLEDNames();
|
||||
std::vector<unsigned int> led_values = controller->GetLEDValues();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Count key LEDs and underglow LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int number_of_key_leds;
|
||||
unsigned int number_of_underglow_leds;
|
||||
|
||||
CountKeyTypes(led_flags, total_number_of_leds, number_of_key_leds, number_of_underglow_leds);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Count total LEDs and check if underglow exists |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int number_of_leds = number_of_key_leds + number_of_underglow_leds;
|
||||
bool has_underglow = number_of_underglow_leds > 0;
|
||||
LOG_INFO("[%s] Keyboard has %u underglow LEDs", name.c_str(), number_of_underglow_leds);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create sets for row and column position values |
|
||||
\*---------------------------------------------------------*/
|
||||
std::set<int> rows, columns;
|
||||
for (unsigned int i = 0; i < number_of_leds; i++)
|
||||
{
|
||||
rows.insert(led_points[i].y);
|
||||
columns.insert(led_points[i].x);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Calculate matrix map from QMK positions |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int divisor = CalculateDivisor(led_points, rows, columns);
|
||||
LOG_DEBUG("[%s] Distance between standard keys calculated to be %u", name.c_str(), divisor);
|
||||
|
||||
VectorMatrix matrix_map;
|
||||
VectorMatrix underglow_map;
|
||||
|
||||
PlaceLEDsInMaps(rows, columns, divisor, led_points, led_flags, matrix_map, underglow_map);
|
||||
CleanMatrixMaps(matrix_map, underglow_map, (unsigned int)rows.size(), has_underglow);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| These vectors are class members because if they go out of |
|
||||
| scope, the underlying array (used by each zones' |
|
||||
| matrix_map) is unallocated. |
|
||||
\*---------------------------------------------------------*/
|
||||
flat_matrix_map = FlattenMatrixMap(matrix_map);
|
||||
flat_underglow_map = FlattenMatrixMap(underglow_map);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create Keyboard zone |
|
||||
\*---------------------------------------------------------*/
|
||||
zone keys_zone;
|
||||
keys_zone.name = "Keyboard";
|
||||
keys_zone.type = ZONE_TYPE_MATRIX;
|
||||
keys_zone.leds_min = number_of_key_leds;
|
||||
keys_zone.leds_max = keys_zone.leds_min;
|
||||
keys_zone.leds_count = keys_zone.leds_min;
|
||||
keys_zone.matrix_map = new matrix_map_type;
|
||||
keys_zone.matrix_map->width = (unsigned int)matrix_map[0].size();
|
||||
keys_zone.matrix_map->height = (unsigned int)matrix_map.size();
|
||||
keys_zone.matrix_map->map = flat_matrix_map.data();
|
||||
zones.push_back(keys_zone);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create Underglow zone if it exists |
|
||||
\*---------------------------------------------------------*/
|
||||
if(has_underglow)
|
||||
{
|
||||
zone underglow_zone;
|
||||
underglow_zone.name = "Underglow";
|
||||
underglow_zone.type = ZONE_TYPE_MATRIX;
|
||||
underglow_zone.leds_min = number_of_underglow_leds;
|
||||
underglow_zone.leds_max = underglow_zone.leds_min;
|
||||
underglow_zone.leds_count = underglow_zone.leds_min;
|
||||
underglow_zone.matrix_map = new matrix_map_type;
|
||||
underglow_zone.matrix_map->width = (unsigned int)underglow_map[0].size();
|
||||
underglow_zone.matrix_map->height = (unsigned int)underglow_map.size();
|
||||
underglow_zone.matrix_map->map = flat_underglow_map.data();
|
||||
zones.push_back(underglow_zone);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int led_idx = 0; led_idx < number_of_leds; led_idx++)
|
||||
{
|
||||
led keyboard_led;
|
||||
|
||||
if(led_idx < led_names.size())
|
||||
{
|
||||
keyboard_led.name = led_names[led_idx];
|
||||
}
|
||||
if(led_idx < led_values.size()){
|
||||
keyboard_led.value = led_values[led_idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
keyboard_led.value = led_idx;
|
||||
}
|
||||
|
||||
leds.push_back(keyboard_led);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Setup Colors |
|
||||
\*---------------------------------------------------------*/
|
||||
SetupColors();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Initialize colors from device values |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < leds.size(); i++)
|
||||
{
|
||||
colors[i] = controller->GetLEDColors()[i];
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevD::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevD::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->DirectModeSetLEDs(colors, controller->GetTotalNumberOfLEDs());
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevD::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevD::UpdateSingleLED(int led)
|
||||
{
|
||||
RGBColor color = colors[led];
|
||||
unsigned char red = RGBGetRValue(color);
|
||||
unsigned char grn = RGBGetGValue(color);
|
||||
unsigned char blu = RGBGetBValue(color);
|
||||
|
||||
controller->DirectModeSetSingleLED(led, red, grn, blu);
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevD::DeviceUpdateMode()
|
||||
{
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_PER_LED)
|
||||
{
|
||||
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, 127, false);
|
||||
}
|
||||
else if(modes[active_mode].color_mode == MODE_COLORS_NONE)
|
||||
{
|
||||
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, modes[active_mode].speed, false);
|
||||
}
|
||||
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
RGBColor rgb_color = modes[active_mode].colors[0];
|
||||
hsv_t hsv_color;
|
||||
rgb2hsv(rgb_color, &hsv_color);
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
controller->SetMode(hsv_color, modes[active_mode].value, modes[active_mode].speed, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetMode(hsv_color, modes[active_mode].value, 127, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevD::DeviceSaveMode()
|
||||
{
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_NONE)
|
||||
{
|
||||
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, modes[active_mode].speed, true);
|
||||
}
|
||||
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
RGBColor rgb_color = modes[active_mode].colors[0];
|
||||
hsv_t hsv_color;
|
||||
rgb2hsv(rgb_color, &hsv_color);
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
controller->SetMode(hsv_color, modes[active_mode].value, modes[active_mode].speed, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetMode(hsv_color, modes[active_mode].value, 127, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevD::InitializeMode
|
||||
(
|
||||
std::string name,
|
||||
unsigned int ¤t_mode,
|
||||
unsigned int flags,
|
||||
unsigned int color_mode,
|
||||
bool save
|
||||
)
|
||||
{
|
||||
mode qmk_mode;
|
||||
qmk_mode.name = name;
|
||||
qmk_mode.value = current_mode++;
|
||||
qmk_mode.flags = flags;
|
||||
qmk_mode.color_mode = color_mode;
|
||||
|
||||
if(flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
qmk_mode.speed_min = QMK_OPENRGB_SPEED_SLOWEST;
|
||||
qmk_mode.speed_max = QMK_OPENRGB_SPEED_FASTEST;
|
||||
qmk_mode.speed = QMK_OPENRGB_SPEED_NORMAL;
|
||||
}
|
||||
if(flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
|
||||
{
|
||||
qmk_mode.colors_min = 1;
|
||||
qmk_mode.colors_max = 1;
|
||||
qmk_mode.colors.resize(1);
|
||||
qmk_mode.colors[0] = controller->GetModeColor();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Direct mode it the last mode on the QMK firmware |
|
||||
| but we still want it to appear first on the UI |
|
||||
\*-----------------------------------------------------*/
|
||||
if(flags & MODE_FLAG_HAS_PER_LED_COLOR)
|
||||
{
|
||||
modes.insert(modes.begin(), qmk_mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Every mode apart from direct is save-able |
|
||||
\*-----------------------------------------------------*/
|
||||
if(save == true)
|
||||
{
|
||||
qmk_mode.flags = flags | MODE_FLAG_MANUAL_SAVE;
|
||||
}
|
||||
modes.push_back(qmk_mode);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int RGBController_QMKOpenRGBRevD::CalculateDivisor
|
||||
(
|
||||
std::vector<point_t> led_points,
|
||||
std::set<int> rows,
|
||||
std::set<int> /*columns*/
|
||||
)
|
||||
{
|
||||
std::vector< std::vector<point_t> > row_points(rows.size());
|
||||
for(const point_t &pt : led_points)
|
||||
{
|
||||
for(const int &i : rows)
|
||||
{
|
||||
if(pt.y == i)
|
||||
{
|
||||
row_points[std::distance(rows.begin(), rows.find(i))].push_back(pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int last_pos;
|
||||
std::vector<int> distances;
|
||||
for(const std::vector<point_t> &row : row_points)
|
||||
{
|
||||
last_pos = 0;
|
||||
std::for_each(row.begin(), row.end(), [&distances, &last_pos](const point_t &pt)
|
||||
{
|
||||
distances.push_back(std::abs(pt.x - last_pos));
|
||||
last_pos = pt.x;
|
||||
});
|
||||
}
|
||||
std::map<int, int> counts;
|
||||
for(const int &i : distances)
|
||||
{
|
||||
counts[i]++;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Guard against empty distances (malformed LED data) |
|
||||
\*---------------------------------------------------------*/
|
||||
if(distances.empty())
|
||||
{
|
||||
LOG_WARNING("[%s] No valid LED distances found, using default divisor of 1", name.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int divisor = distances[0];
|
||||
for(const std::pair<const int, int> &i : counts)
|
||||
{
|
||||
if(counts[divisor] < i.second)
|
||||
{
|
||||
divisor = i.first;
|
||||
}
|
||||
}
|
||||
|
||||
if(divisor == 0)
|
||||
{
|
||||
LOG_WARNING("[%s] Calculated divisor is 0, using default of 1. This may indicate malformed LED position data.", name.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return divisor;
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevD::CountKeyTypes
|
||||
(
|
||||
std::vector<unsigned int> led_flags,
|
||||
unsigned int total_led_count,
|
||||
unsigned int& key_leds,
|
||||
unsigned int& underglow_leds
|
||||
)
|
||||
{
|
||||
underglow_leds = 0;
|
||||
key_leds = 0;
|
||||
|
||||
for(unsigned int i = 0; i < total_led_count; i++)
|
||||
{
|
||||
if(led_flags[i] & 2)
|
||||
{
|
||||
underglow_leds++;
|
||||
}
|
||||
else if(led_flags[i] != 0)
|
||||
{
|
||||
key_leds++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevD::PlaceLEDsInMaps
|
||||
(
|
||||
std::set<int> unique_rows,
|
||||
std::set<int> /*unique_cols*/,
|
||||
unsigned int divisor,
|
||||
std::vector<point_t> led_points,
|
||||
std::vector<unsigned int> led_flags,
|
||||
VectorMatrix& matrix_map_xl,
|
||||
VectorMatrix& underglow_map_xl
|
||||
)
|
||||
{
|
||||
matrix_map_xl = MakeEmptyMatrixMap(unique_rows.size(), (std::size_t)(std::round(255 / divisor) + 10));
|
||||
underglow_map_xl = MakeEmptyMatrixMap(unique_rows.size(), (std::size_t)(std::round(255 / divisor) + 10));
|
||||
|
||||
unsigned int x = 0;
|
||||
unsigned int y = 0;
|
||||
unsigned int underglow_counter = 0;
|
||||
|
||||
for(unsigned int i = 0; i < controller->GetTotalNumberOfLEDs(); i++)
|
||||
{
|
||||
if(led_points[i].x != 255 && led_points[i].y != 255)
|
||||
{
|
||||
bool underglow = led_flags[i] & 2;
|
||||
|
||||
x = (unsigned int)(std::round(led_points[i].x / divisor));
|
||||
y = (unsigned int)(std::distance(unique_rows.begin(), unique_rows.find(led_points[i].y)));
|
||||
|
||||
if(!underglow)
|
||||
{
|
||||
while(matrix_map_xl[y][x] != NO_LED)
|
||||
{
|
||||
x++;
|
||||
}
|
||||
matrix_map_xl[y][x] = i;
|
||||
LOG_DEBUG("[%s] Key Matrix LED %u, (%u, %u) being placed into (%u, %u)", name.c_str(), i, led_points[i].x, led_points[i].y, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
while(underglow_map_xl[y][x] != NO_LED)
|
||||
{
|
||||
x++;
|
||||
}
|
||||
underglow_map_xl[y][x] = underglow_counter;
|
||||
underglow_counter++;
|
||||
LOG_DEBUG("[%s] Underglow LED %u, (%u, %u) being placed into (%u, %u)", name.c_str(), i, led_points[i].x, led_points[i].y, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VectorMatrix RGBController_QMKOpenRGBRevD::MakeEmptyMatrixMap
|
||||
(
|
||||
std::size_t height,
|
||||
std::size_t width
|
||||
)
|
||||
{
|
||||
std::vector<std::vector<unsigned int> > matrix_map(height);
|
||||
for(std::size_t i = 0; i < height; i++)
|
||||
{
|
||||
for(std::size_t j = 0; j < width; j++)
|
||||
{
|
||||
matrix_map[i].push_back(NO_LED);
|
||||
}
|
||||
}
|
||||
return matrix_map;
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevD::CleanMatrixMaps
|
||||
(
|
||||
VectorMatrix& matrix_map,
|
||||
VectorMatrix& underglow_map,
|
||||
unsigned int height,
|
||||
bool has_underglow
|
||||
)
|
||||
{
|
||||
bool empty_col = true;
|
||||
bool empty_col_udg = true;
|
||||
bool empty_row = true;
|
||||
int width = 0;
|
||||
int width_udg = 0;
|
||||
|
||||
std::vector<int> empty_rows;
|
||||
|
||||
bool can_break;
|
||||
bool can_break_udg;
|
||||
|
||||
for(unsigned int i = 0; i < height; i++)
|
||||
{
|
||||
empty_row = true;
|
||||
can_break = false;
|
||||
can_break_udg = false;
|
||||
|
||||
for(int j = (int)matrix_map[i].size() - 1; j --> 0; )
|
||||
{
|
||||
if(matrix_map[i][j] != NO_LED && width < (j + 1) && !can_break)
|
||||
{
|
||||
width = (j + 1);
|
||||
can_break = true;
|
||||
empty_row = false;
|
||||
}
|
||||
else if(matrix_map[i][j] != NO_LED)
|
||||
{
|
||||
empty_row = false;
|
||||
}
|
||||
if(underglow_map[i][j] != NO_LED && width_udg < (j + 1) && !can_break_udg)
|
||||
{
|
||||
width_udg = (j + 1);
|
||||
can_break_udg = true;
|
||||
}
|
||||
if (can_break && can_break_udg) break;
|
||||
}
|
||||
|
||||
if(matrix_map[i][0] != NO_LED)
|
||||
{
|
||||
empty_col = false;
|
||||
}
|
||||
|
||||
if(underglow_map[i][0] != NO_LED)
|
||||
{
|
||||
empty_col_udg = false;
|
||||
}
|
||||
|
||||
if(empty_row)
|
||||
{
|
||||
empty_rows.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int new_height = height - (unsigned int)empty_rows.size();
|
||||
width = empty_col ? width - 1 : width;
|
||||
width_udg = empty_col_udg && empty_col ? width_udg - 1 : width_udg;
|
||||
LOG_DEBUG("[%s] Key LED Matrix: %ux%u", name.c_str(), width, new_height);
|
||||
LOG_DEBUG("[%s] Underglow LED Matrix: %ux%u", name.c_str(), width_udg, new_height);
|
||||
|
||||
for(unsigned int i = (unsigned int)empty_rows.size(); i --> 0; )
|
||||
{
|
||||
matrix_map.erase(matrix_map.begin()+empty_rows[i]);
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < new_height; i++)
|
||||
{
|
||||
if(empty_col)
|
||||
{
|
||||
matrix_map[i].erase(matrix_map[i].begin(), matrix_map[i].begin() + 1);
|
||||
}
|
||||
|
||||
if(empty_col_udg && empty_col)
|
||||
{
|
||||
underglow_map[i].erase(underglow_map[i].begin(), underglow_map[i].begin() + 1);
|
||||
}
|
||||
|
||||
matrix_map[i].erase(matrix_map[i].begin()+width, matrix_map[i].end());
|
||||
|
||||
if(has_underglow)
|
||||
{
|
||||
underglow_map[i].erase(underglow_map[i].begin()+width_udg, underglow_map[i].end());
|
||||
}
|
||||
}
|
||||
|
||||
if(has_underglow)
|
||||
{
|
||||
for(unsigned int i = new_height; i < height; i++)
|
||||
{
|
||||
underglow_map[i].erase(underglow_map[i].begin()+width_udg, underglow_map[i].end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<unsigned int> RGBController_QMKOpenRGBRevD::FlattenMatrixMap
|
||||
(
|
||||
VectorMatrix matrix_map
|
||||
)
|
||||
{
|
||||
std::vector<unsigned int> flat_map;
|
||||
|
||||
for(const std::vector<unsigned int> &row : matrix_map)
|
||||
{
|
||||
for(const unsigned int &item : row)
|
||||
{
|
||||
flat_map.push_back(item);
|
||||
}
|
||||
}
|
||||
return flat_map;
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_QMKOpenRGBRevD.h |
|
||||
| |
|
||||
| RGBController for OpenRGB QMK Keyboard Protocol |
|
||||
| Revision D |
|
||||
| |
|
||||
| Neneya 26 Dec 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "RGBController.h"
|
||||
#include "QMKOpenRGBRevDController.h"
|
||||
|
||||
#define NO_LED 0xFFFFFFFF
|
||||
|
||||
typedef std::vector<std::vector<unsigned int>> VectorMatrix;
|
||||
|
||||
class RGBController_QMKOpenRGBRevD : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_QMKOpenRGBRevD(QMKOpenRGBRevDController* controller_ptr, bool save);
|
||||
~RGBController_QMKOpenRGBRevD();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
QMKOpenRGBRevDController* controller;
|
||||
std::vector<unsigned int> flat_matrix_map;
|
||||
std::vector<unsigned int> flat_underglow_map;
|
||||
|
||||
void InitializeMode
|
||||
(
|
||||
std::string name,
|
||||
unsigned int ¤t_mode,
|
||||
unsigned int flags,
|
||||
unsigned int color_mode,
|
||||
bool save
|
||||
);
|
||||
|
||||
unsigned int CalculateDivisor
|
||||
(
|
||||
std::vector<point_t> led_points,
|
||||
std::set<int> rows,
|
||||
std::set<int> columns
|
||||
);
|
||||
|
||||
void CountKeyTypes
|
||||
(
|
||||
std::vector<unsigned int> led_flags,
|
||||
unsigned int total_led_count,
|
||||
unsigned int& key_leds,
|
||||
unsigned int& underglow_leds
|
||||
);
|
||||
|
||||
void PlaceLEDsInMaps
|
||||
(
|
||||
std::set<int> unique_rows,
|
||||
std::set<int> unique_cols,
|
||||
unsigned int divisor,
|
||||
std::vector<point_t> led_points,
|
||||
std::vector<unsigned int> led_flags,
|
||||
VectorMatrix& matrix_map_xl,
|
||||
VectorMatrix& underglow_map_xl
|
||||
);
|
||||
|
||||
VectorMatrix MakeEmptyMatrixMap
|
||||
(
|
||||
std::size_t height,
|
||||
std::size_t width
|
||||
);
|
||||
|
||||
void CleanMatrixMaps
|
||||
(
|
||||
VectorMatrix& matrix_map,
|
||||
VectorMatrix& underglow_map,
|
||||
unsigned int height,
|
||||
bool has_underglow
|
||||
);
|
||||
|
||||
std::vector<unsigned int> FlattenMatrixMap
|
||||
(
|
||||
VectorMatrix matrix_map
|
||||
);
|
||||
};
|
||||
+820
@@ -0,0 +1,820 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_QMKOpenRGBRevE.cpp |
|
||||
| |
|
||||
| RGBController for OpenRGB QMK Keyboard Protocol |
|
||||
| Revision E |
|
||||
| |
|
||||
| Neneya 26 Dec 2021 |
|
||||
| HorrorTroll 11 Jul 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "hsv.h"
|
||||
#include "LogManager.h"
|
||||
#include "RGBController_QMKOpenRGBRevE.h"
|
||||
|
||||
RGBController_QMKOpenRGBRevE::RGBController_QMKOpenRGBRevE(QMKOpenRGBRevDController* controller_ptr, bool save)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = controller->GetDeviceVendor();
|
||||
description = "QMK OpenRGB Device (Protocol Version " + std::to_string(controller->GetProtocolVersion()) + ")";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
location = controller->GetLocation();
|
||||
version = controller->GetQMKVersion();
|
||||
|
||||
unsigned int current_mode = 1;
|
||||
std::vector<unsigned int> enabled_modes = controller->GetEnabledModes();
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_COLOR) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Static", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_ALPHA_MOD) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Alpha Mod", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_GRADIENT_UP_DOWN) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Gradient Up Down", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_GRADIENT_LEFT_RIGHT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Gradient Left Right", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BREATHING) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Breathing", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_SAT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_VAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_PINWHEEL_SAT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Pinwheel Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_PINWHEEL_VAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Pinwheel Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_SPIRAL_SAT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Spiral Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_SPIRAL_VAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Band Spiral Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_ALL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle All", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_LEFT_RIGHT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Left Right", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_UP_DOWN) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Up Down", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINBOW_MOVING_CHEVRON) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Moving Chevron", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_OUT_IN) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Out In", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_OUT_IN_DUAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Out In Dual", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_PINWHEEL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Pinwheel", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_SPIRAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Cycle Spiral", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_DUAL_BEACON) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Dual Beacon", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINBOW_BEACON) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Beacon", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINBOW_PINWHEELS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Pinwheels", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINDROPS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Raindrops", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_JELLYBEAN_RAINDROPS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Jellybean Raindrops", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_HUE_BREATHING) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Hue Breathing", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_HUE_PENDULUM) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Hue Pendulum", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_HUE_WAVE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Hue Wave", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_TYPING_HEATMAP) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Typing Heatmap", current_mode, 0, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_DIGITAL_RAIN) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Digital Rain", current_mode, 0, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_SIMPLE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Simple", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_WIDE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Wide", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTIWIDE) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Wide", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_CROSS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Cross", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTICROSS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Cross", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_NEXUS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Nexus", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTINEXUS) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Nexus", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SPLASH) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Reactive Splash", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_MULTISPLASH) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Rainbow Reactive Multi Splash", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_SPLASH) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Splash", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_MULTISPLASH) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Solid Reactive Multi Splash", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_PIXEL_RAIN) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Pixel Rain", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_PIXEL_FLOW) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Pixel Flow", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_PIXEL_FRACTAL) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Pixel Fractal", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
|
||||
}
|
||||
|
||||
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_OPENRGB_DIRECT) != enabled_modes.end())
|
||||
{
|
||||
InitializeMode("Direct", current_mode, MODE_FLAG_HAS_PER_LED_COLOR, MODE_COLORS_PER_LED, save);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| As we are insertting direct mode at index 0 |
|
||||
| for it to be the first mode in the UI there will |
|
||||
| be a mismatch between the values. QMK has direct |
|
||||
| mode last in order, while in OpenRGB it's first. |
|
||||
\*-----------------------------------------------------*/
|
||||
if(controller->GetMode() == (current_mode - 1))
|
||||
{
|
||||
active_mode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
active_mode = controller->GetMode();
|
||||
}
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_QMKOpenRGBRevE::~RGBController_QMKOpenRGBRevE()
|
||||
{
|
||||
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
|
||||
{
|
||||
if(zones[zone_index].matrix_map != NULL)
|
||||
{
|
||||
delete zones[zone_index].matrix_map;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevE::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Get the number of LEDs from the device |
|
||||
\*---------------------------------------------------------*/
|
||||
const unsigned int total_number_of_leds = controller->GetTotalNumberOfLEDs();
|
||||
const unsigned int total_number_of_leds_with_empty_space = controller->GetTotalNumberOfLEDsWithEmptySpace();
|
||||
|
||||
LOG_INFO("[%s] Keyboard has %u LEDs total", name.c_str(), total_number_of_leds);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get information for each LED |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->GetLEDInfo(std::max(total_number_of_leds, total_number_of_leds_with_empty_space));
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get LED vectors from controller |
|
||||
\*---------------------------------------------------------*/
|
||||
std::vector<point_t> led_points = controller->GetLEDPoints();
|
||||
std::vector<unsigned int> led_flags = controller->GetLEDFlags();
|
||||
std::vector<std::string> led_names = controller->GetLEDNames();
|
||||
std::vector<unsigned int> led_values = controller->GetLEDValues();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Count key LEDs and underglow LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int number_of_key_leds;
|
||||
unsigned int number_of_underglow_leds;
|
||||
|
||||
CountKeyTypes(led_flags, total_number_of_leds, number_of_key_leds, number_of_underglow_leds);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Count total LEDs and check if underglow exists |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int number_of_leds = number_of_key_leds + number_of_underglow_leds;
|
||||
bool has_underglow = number_of_underglow_leds > 0;
|
||||
LOG_INFO("[%s] Keyboard has %u underglow LEDs", name.c_str(), number_of_underglow_leds);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create sets for row and column position values |
|
||||
\*---------------------------------------------------------*/
|
||||
std::set<int> rows, columns;
|
||||
for (unsigned int i = 0; i < number_of_leds; i++)
|
||||
{
|
||||
rows.insert(led_points[i].y);
|
||||
columns.insert(led_points[i].x);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Calculate matrix map from QMK positions |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int divisor = CalculateDivisor(led_points, rows, columns);
|
||||
LOG_DEBUG("[%s] Distance between standard keys calculated to be %u", name.c_str(), divisor);
|
||||
|
||||
VectorMatrix matrix_map;
|
||||
VectorMatrix underglow_map;
|
||||
|
||||
PlaceLEDsInMaps(rows, columns, divisor, led_points, led_flags, matrix_map, underglow_map);
|
||||
CleanMatrixMaps(matrix_map, underglow_map, (unsigned int)rows.size(), has_underglow);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| These vectors are class members because if they go out of |
|
||||
| scope, the underlying array (used by each zones' |
|
||||
| matrix_map) is unallocated. |
|
||||
\*---------------------------------------------------------*/
|
||||
flat_matrix_map = FlattenMatrixMap(matrix_map);
|
||||
flat_underglow_map = FlattenMatrixMap(underglow_map);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create Keyboard zone |
|
||||
\*---------------------------------------------------------*/
|
||||
zone keys_zone;
|
||||
keys_zone.name = "Keyboard";
|
||||
keys_zone.type = ZONE_TYPE_MATRIX;
|
||||
keys_zone.leds_min = number_of_key_leds;
|
||||
keys_zone.leds_max = keys_zone.leds_min;
|
||||
keys_zone.leds_count = keys_zone.leds_min;
|
||||
keys_zone.matrix_map = new matrix_map_type;
|
||||
keys_zone.matrix_map->width = (unsigned int)matrix_map[0].size();
|
||||
keys_zone.matrix_map->height = (unsigned int)matrix_map.size();
|
||||
keys_zone.matrix_map->map = flat_matrix_map.data();
|
||||
zones.push_back(keys_zone);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create Underglow zone if it exists |
|
||||
\*---------------------------------------------------------*/
|
||||
if(has_underglow)
|
||||
{
|
||||
zone underglow_zone;
|
||||
underglow_zone.name = "Underglow";
|
||||
underglow_zone.type = ZONE_TYPE_MATRIX;
|
||||
underglow_zone.leds_min = number_of_underglow_leds;
|
||||
underglow_zone.leds_max = underglow_zone.leds_min;
|
||||
underglow_zone.leds_count = underglow_zone.leds_min;
|
||||
underglow_zone.matrix_map = new matrix_map_type;
|
||||
underglow_zone.matrix_map->width = (unsigned int)underglow_map[0].size();
|
||||
underglow_zone.matrix_map->height = (unsigned int)underglow_map.size();
|
||||
underglow_zone.matrix_map->map = flat_underglow_map.data();
|
||||
zones.push_back(underglow_zone);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int led_idx = 0; led_idx < number_of_leds; led_idx++)
|
||||
{
|
||||
led keyboard_led;
|
||||
|
||||
if(led_idx < led_names.size())
|
||||
{
|
||||
keyboard_led.name = led_names[led_idx];
|
||||
}
|
||||
if(led_idx < led_values.size()){
|
||||
keyboard_led.value = led_values[led_idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
keyboard_led.value = led_idx;
|
||||
}
|
||||
|
||||
leds.push_back(keyboard_led);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Setup Colors |
|
||||
\*---------------------------------------------------------*/
|
||||
SetupColors();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Initialize colors from device values |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < leds.size(); i++)
|
||||
{
|
||||
colors[i] = controller->GetLEDColors()[i];
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevE::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevE::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->DirectModeSetLEDs(colors, controller->GetTotalNumberOfLEDs());
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevE::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevE::UpdateSingleLED(int led)
|
||||
{
|
||||
RGBColor color = colors[led];
|
||||
unsigned char red = RGBGetRValue(color);
|
||||
unsigned char grn = RGBGetGValue(color);
|
||||
unsigned char blu = RGBGetBValue(color);
|
||||
|
||||
controller->DirectModeSetSingleLED(led, red, grn, blu);
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevE::DeviceUpdateMode()
|
||||
{
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_PER_LED)
|
||||
{
|
||||
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, 127, false);
|
||||
}
|
||||
else if(modes[active_mode].color_mode == MODE_COLORS_NONE)
|
||||
{
|
||||
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, modes[active_mode].speed, false);
|
||||
}
|
||||
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
RGBColor rgb_color = modes[active_mode].colors[0];
|
||||
hsv_t hsv_color;
|
||||
rgb2hsv(rgb_color, &hsv_color);
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
controller->SetMode(hsv_color, modes[active_mode].value, modes[active_mode].speed, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetMode(hsv_color, modes[active_mode].value, 127, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevE::DeviceSaveMode()
|
||||
{
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_NONE)
|
||||
{
|
||||
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, modes[active_mode].speed, true);
|
||||
}
|
||||
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
RGBColor rgb_color = modes[active_mode].colors[0];
|
||||
hsv_t hsv_color;
|
||||
rgb2hsv(rgb_color, &hsv_color);
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
controller->SetMode(hsv_color, modes[active_mode].value, modes[active_mode].speed, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetMode(hsv_color, modes[active_mode].value, 127, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevE::InitializeMode
|
||||
(
|
||||
std::string name,
|
||||
unsigned int ¤t_mode,
|
||||
unsigned int flags,
|
||||
unsigned int color_mode,
|
||||
bool save
|
||||
)
|
||||
{
|
||||
mode qmk_mode;
|
||||
qmk_mode.name = name;
|
||||
qmk_mode.value = current_mode++;
|
||||
qmk_mode.flags = flags;
|
||||
qmk_mode.color_mode = color_mode;
|
||||
|
||||
if(flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
qmk_mode.speed_min = QMK_OPENRGB_SPEED_SLOWEST;
|
||||
qmk_mode.speed_max = QMK_OPENRGB_SPEED_FASTEST;
|
||||
qmk_mode.speed = QMK_OPENRGB_SPEED_NORMAL;
|
||||
}
|
||||
if(flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
|
||||
{
|
||||
qmk_mode.colors_min = 1;
|
||||
qmk_mode.colors_max = 1;
|
||||
qmk_mode.colors.resize(1);
|
||||
qmk_mode.colors[0] = controller->GetModeColor();
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Direct mode it the last mode on the QMK firmware |
|
||||
| but we still want it to appear first on the UI |
|
||||
\*-----------------------------------------------------*/
|
||||
if(flags & MODE_FLAG_HAS_PER_LED_COLOR)
|
||||
{
|
||||
modes.insert(modes.begin(), qmk_mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Every mode apart from direct is save-able |
|
||||
\*-----------------------------------------------------*/
|
||||
if(save == true)
|
||||
{
|
||||
qmk_mode.flags = flags | MODE_FLAG_MANUAL_SAVE;
|
||||
}
|
||||
modes.push_back(qmk_mode);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int RGBController_QMKOpenRGBRevE::CalculateDivisor
|
||||
(
|
||||
std::vector<point_t> led_points,
|
||||
std::set<int> rows,
|
||||
std::set<int> /*columns*/
|
||||
)
|
||||
{
|
||||
std::vector< std::vector<point_t> > row_points(rows.size());
|
||||
for(const point_t &pt : led_points)
|
||||
{
|
||||
for(const int &i : rows)
|
||||
{
|
||||
if(pt.y == i)
|
||||
{
|
||||
row_points[std::distance(rows.begin(), rows.find(i))].push_back(pt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int last_pos;
|
||||
std::vector<int> distances;
|
||||
for(const std::vector<point_t> &row : row_points)
|
||||
{
|
||||
last_pos = 0;
|
||||
std::for_each(row.begin(), row.end(), [&distances, &last_pos](const point_t &pt)
|
||||
{
|
||||
distances.push_back(std::abs(pt.x - last_pos));
|
||||
last_pos = pt.x;
|
||||
});
|
||||
}
|
||||
std::map<int, int> counts;
|
||||
for(const int &i : distances)
|
||||
{
|
||||
counts[i]++;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Guard against empty distances (malformed LED data) |
|
||||
\*---------------------------------------------------------*/
|
||||
if(distances.empty())
|
||||
{
|
||||
LOG_WARNING("[%s] No valid LED distances found, using default divisor of 1", name.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int divisor = distances[0];
|
||||
for(const std::pair<const int, int> &i : counts)
|
||||
{
|
||||
if(counts[divisor] < i.second)
|
||||
{
|
||||
divisor = i.first;
|
||||
}
|
||||
}
|
||||
|
||||
if(divisor == 0)
|
||||
{
|
||||
LOG_WARNING("[%s] Calculated divisor is 0, using default of 1. This may indicate malformed LED position data.", name.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return divisor;
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevE::CountKeyTypes
|
||||
(
|
||||
std::vector<unsigned int> led_flags,
|
||||
unsigned int total_led_count,
|
||||
unsigned int& key_leds,
|
||||
unsigned int& underglow_leds
|
||||
)
|
||||
{
|
||||
underglow_leds = 0;
|
||||
key_leds = 0;
|
||||
|
||||
for(unsigned int i = 0; i < total_led_count; i++)
|
||||
{
|
||||
if(led_flags[i] & 2)
|
||||
{
|
||||
underglow_leds++;
|
||||
}
|
||||
else if(led_flags[i] != 0)
|
||||
{
|
||||
key_leds++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevE::PlaceLEDsInMaps
|
||||
(
|
||||
std::set<int> unique_rows,
|
||||
std::set<int> /*unique_cols*/,
|
||||
unsigned int divisor,
|
||||
std::vector<point_t> led_points,
|
||||
std::vector<unsigned int> led_flags,
|
||||
VectorMatrix& matrix_map_xl,
|
||||
VectorMatrix& underglow_map_xl
|
||||
)
|
||||
{
|
||||
matrix_map_xl = MakeEmptyMatrixMap(unique_rows.size(), (std::size_t)(std::round(255 / divisor) + 10));
|
||||
underglow_map_xl = MakeEmptyMatrixMap(unique_rows.size(), (std::size_t)(std::round(255 / divisor) + 10));
|
||||
|
||||
unsigned int x = 0;
|
||||
unsigned int y = 0;
|
||||
unsigned int underglow_counter = 0;
|
||||
|
||||
for(unsigned int i = 0; i < controller->GetTotalNumberOfLEDs(); i++)
|
||||
{
|
||||
if(led_points[i].x != 255 && led_points[i].y != 255)
|
||||
{
|
||||
bool underglow = led_flags[i] & 2;
|
||||
|
||||
x = (unsigned int)(std::round(led_points[i].x / divisor));
|
||||
y = (unsigned int)(std::distance(unique_rows.begin(), unique_rows.find(led_points[i].y)));
|
||||
|
||||
if(!underglow)
|
||||
{
|
||||
while(matrix_map_xl[y][x] != NO_LED)
|
||||
{
|
||||
x++;
|
||||
}
|
||||
matrix_map_xl[y][x] = i;
|
||||
LOG_DEBUG("[%s] Key Matrix LED %u, (%u, %u) being placed into (%u, %u)", name.c_str(), i, led_points[i].x, led_points[i].y, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
while(underglow_map_xl[y][x] != NO_LED)
|
||||
{
|
||||
x++;
|
||||
}
|
||||
underglow_map_xl[y][x] = underglow_counter;
|
||||
underglow_counter++;
|
||||
LOG_DEBUG("[%s] Underglow LED %u, (%u, %u) being placed into (%u, %u)", name.c_str(), i, led_points[i].x, led_points[i].y, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VectorMatrix RGBController_QMKOpenRGBRevE::MakeEmptyMatrixMap
|
||||
(
|
||||
std::size_t height,
|
||||
std::size_t width
|
||||
)
|
||||
{
|
||||
std::vector<std::vector<unsigned int> > matrix_map(height);
|
||||
for(std::size_t i = 0; i < height; i++)
|
||||
{
|
||||
for(std::size_t j = 0; j < width; j++)
|
||||
{
|
||||
matrix_map[i].push_back(NO_LED);
|
||||
}
|
||||
}
|
||||
return matrix_map;
|
||||
}
|
||||
|
||||
void RGBController_QMKOpenRGBRevE::CleanMatrixMaps
|
||||
(
|
||||
VectorMatrix& matrix_map,
|
||||
VectorMatrix& underglow_map,
|
||||
unsigned int height,
|
||||
bool has_underglow
|
||||
)
|
||||
{
|
||||
bool empty_col = true;
|
||||
bool empty_col_udg = true;
|
||||
bool empty_row = true;
|
||||
int width = 0;
|
||||
int width_udg = 0;
|
||||
|
||||
std::vector<int> empty_rows;
|
||||
|
||||
bool can_break;
|
||||
bool can_break_udg;
|
||||
|
||||
for(unsigned int i = 0; i < height; i++)
|
||||
{
|
||||
empty_row = true;
|
||||
can_break = false;
|
||||
can_break_udg = false;
|
||||
|
||||
for(int j = (int)matrix_map[i].size() - 1; j --> 0; )
|
||||
{
|
||||
if(matrix_map[i][j] != NO_LED && width < (j + 1) && !can_break)
|
||||
{
|
||||
width = (j + 1);
|
||||
can_break = true;
|
||||
empty_row = false;
|
||||
}
|
||||
else if(matrix_map[i][j] != NO_LED)
|
||||
{
|
||||
empty_row = false;
|
||||
}
|
||||
if(underglow_map[i][j] != NO_LED && width_udg < (j + 1) && !can_break_udg)
|
||||
{
|
||||
width_udg = (j + 1);
|
||||
can_break_udg = true;
|
||||
}
|
||||
if (can_break && can_break_udg) break;
|
||||
}
|
||||
|
||||
if(matrix_map[i][0] != NO_LED)
|
||||
{
|
||||
empty_col = false;
|
||||
}
|
||||
|
||||
if(underglow_map[i][0] != NO_LED)
|
||||
{
|
||||
empty_col_udg = false;
|
||||
}
|
||||
|
||||
if(empty_row)
|
||||
{
|
||||
empty_rows.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int new_height = height - (unsigned int)empty_rows.size();
|
||||
width = empty_col ? width - 1 : width;
|
||||
width_udg = empty_col_udg && empty_col ? width_udg - 1 : width_udg;
|
||||
LOG_DEBUG("[%s] Key LED Matrix: %ux%u", name.c_str(), width, new_height);
|
||||
LOG_DEBUG("[%s] Underglow LED Matrix: %ux%u", name.c_str(), width_udg, new_height);
|
||||
|
||||
for(unsigned int i = (unsigned int)empty_rows.size(); i --> 0; )
|
||||
{
|
||||
matrix_map.erase(matrix_map.begin()+empty_rows[i]);
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < new_height; i++)
|
||||
{
|
||||
if(empty_col)
|
||||
{
|
||||
matrix_map[i].erase(matrix_map[i].begin(), matrix_map[i].begin() + 1);
|
||||
}
|
||||
|
||||
if(empty_col_udg && empty_col)
|
||||
{
|
||||
underglow_map[i].erase(underglow_map[i].begin(), underglow_map[i].begin() + 1);
|
||||
}
|
||||
|
||||
matrix_map[i].erase(matrix_map[i].begin()+width, matrix_map[i].end());
|
||||
|
||||
if(has_underglow)
|
||||
{
|
||||
underglow_map[i].erase(underglow_map[i].begin()+width_udg, underglow_map[i].end());
|
||||
}
|
||||
}
|
||||
|
||||
if(has_underglow)
|
||||
{
|
||||
for(unsigned int i = new_height; i < height; i++)
|
||||
{
|
||||
underglow_map[i].erase(underglow_map[i].begin()+width_udg, underglow_map[i].end());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<unsigned int> RGBController_QMKOpenRGBRevE::FlattenMatrixMap
|
||||
(
|
||||
VectorMatrix matrix_map
|
||||
)
|
||||
{
|
||||
std::vector<unsigned int> flat_map;
|
||||
|
||||
for(const std::vector<unsigned int> &row : matrix_map)
|
||||
{
|
||||
for(const unsigned int &item : row)
|
||||
{
|
||||
flat_map.push_back(item);
|
||||
}
|
||||
}
|
||||
return flat_map;
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_QMKOpenRGBRevE.h |
|
||||
| |
|
||||
| RGBController for OpenRGB QMK Keyboard Protocol |
|
||||
| Revision E |
|
||||
| |
|
||||
| Neneya 26 Dec 2021 |
|
||||
| HorrorTroll 11 Jul 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "RGBController.h"
|
||||
#include "QMKOpenRGBRevDController.h"
|
||||
|
||||
#define NO_LED 0xFFFFFFFF
|
||||
|
||||
typedef std::vector<std::vector<unsigned int>> VectorMatrix;
|
||||
|
||||
class RGBController_QMKOpenRGBRevE : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_QMKOpenRGBRevE(QMKOpenRGBRevDController* controller_ptr, bool save);
|
||||
~RGBController_QMKOpenRGBRevE();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
QMKOpenRGBRevDController* controller;
|
||||
std::vector<unsigned int> flat_matrix_map;
|
||||
std::vector<unsigned int> flat_underglow_map;
|
||||
|
||||
void InitializeMode
|
||||
(
|
||||
std::string name,
|
||||
unsigned int ¤t_mode,
|
||||
unsigned int flags,
|
||||
unsigned int color_mode,
|
||||
bool save
|
||||
);
|
||||
|
||||
unsigned int CalculateDivisor
|
||||
(
|
||||
std::vector<point_t> led_points,
|
||||
std::set<int> rows,
|
||||
std::set<int> columns
|
||||
);
|
||||
|
||||
void CountKeyTypes
|
||||
(
|
||||
std::vector<unsigned int> led_flags,
|
||||
unsigned int total_led_count,
|
||||
unsigned int& key_leds,
|
||||
unsigned int& underglow_leds
|
||||
);
|
||||
|
||||
void PlaceLEDsInMaps
|
||||
(
|
||||
std::set<int> unique_rows,
|
||||
std::set<int> unique_cols,
|
||||
unsigned int divisor,
|
||||
std::vector<point_t> led_points,
|
||||
std::vector<unsigned int> led_flags,
|
||||
VectorMatrix& matrix_map_xl,
|
||||
VectorMatrix& underglow_map_xl
|
||||
);
|
||||
|
||||
VectorMatrix MakeEmptyMatrixMap
|
||||
(
|
||||
std::size_t height,
|
||||
std::size_t width
|
||||
);
|
||||
|
||||
void CleanMatrixMaps
|
||||
(
|
||||
VectorMatrix& matrix_map,
|
||||
VectorMatrix& underglow_map,
|
||||
unsigned int height,
|
||||
bool has_underglow
|
||||
);
|
||||
|
||||
std::vector<unsigned int> FlattenMatrixMap
|
||||
(
|
||||
VectorMatrix matrix_map
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,71 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKViaCommands.h |
|
||||
| |
|
||||
| List of QMK VIA command values |
|
||||
| |
|
||||
| Adam Honse <calcprogrammer1@gmail.com) 21 Jun 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
QMK_VIA_CMD_GET_PROTOCOL_VERSION = 0x01,
|
||||
QMK_VIA_CMD_GET_KEYBOARD_VALUE = 0x02,
|
||||
QMK_VIA_CMD_SET_KEYBOARD_VALUE = 0x03,
|
||||
QMK_VIA_CMD_VIA_DYNAMIC_KEYMAP_GET_KEYCODE = 0x04,
|
||||
QMK_VIA_CMD_VIA_DYNAMIC_KEYMAP_SET_KEYCODE = 0x05,
|
||||
QMK_VIA_CMD_VIA_DYNAMIC_KEYMAP_RESET = 0x06,
|
||||
QMK_VIA_CMD_CUSTOM_SET_VALUE = 0x07,
|
||||
QMK_VIA_CMD_CUSTOM_GET_VALUE = 0x08,
|
||||
QMK_VIA_CMD_CUSTOM_SAVE = 0x09,
|
||||
QMK_VIA_CMD_EEPROM_RESET = 0x0A,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
QMK_VIA_CUSTOM_CHANNEL = 0,
|
||||
QMK_VIA_BACKLIGHT_CHANNEL = 1,
|
||||
QMK_VIA_RGBLIGHT_CHANNEL = 2,
|
||||
QMK_VIA_RGB_MATRIX_CHANNEL = 3,
|
||||
QMK_VIA_AUDIO_CHANNEL = 4,
|
||||
QMK_VIA_LED_MATRIX_CHANNEL = 5,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
QMK_VIA_BACKLIGHT_BRIGHTNESS = 1,
|
||||
QMK_VIA_BACKLIGHT_EFFECT = 2,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
QMK_VIA_RGBLIGHT_BRIGHTNESS = 1,
|
||||
QMK_VIA_RGBLIGHT_EFFECT = 2,
|
||||
QMK_VIA_RGBLIGHT_EFFECT_SPEED = 3,
|
||||
QMK_VIA_RGBLIGHT_COLOR = 4,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
QMK_VIA_RGB_MATRIX_BRIGHTNESS = 1,
|
||||
QMK_VIA_RGB_MATRIX_EFFECT = 2,
|
||||
QMK_VIA_RGB_MATRIX_EFFECT_SPEED = 3,
|
||||
QMK_VIA_RGB_MATRIX_COLOR = 4,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
QMK_VIA_LED_MATRIX_BRIGHTNESS = 1,
|
||||
QMK_VIA_LED_MATRIX_EFFECT = 2,
|
||||
QMK_VIA_LED_MATRIX_EFFECT_SPEED = 3,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
QMK_VIA_AUDIO_ENABLE = 1,
|
||||
QMK_VIA_AUDIO_CLICKY_ENABLE = 2,
|
||||
};
|
||||
@@ -0,0 +1,473 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKVialRGBController.cpp |
|
||||
| |
|
||||
| Driver for VialRGB QMK Keyboard Protocol |
|
||||
| |
|
||||
| Adam Honse <calcprogrammer1@gmail.com) 29 Sep 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "hsv.h"
|
||||
#include "QMKVialRGBController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Portions of this controller adapted from Raspberry Pi |
|
||||
| RPiKeyboardConfig utility: |
|
||||
| https://github.com/raspberrypi/rpi-keyboard-config |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
QMKVialRGBController::QMKVialRGBController(hid_device *dev_handle, const char *path)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Initialize controller fields |
|
||||
\*-----------------------------------------------------*/
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
supported = false;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read product string |
|
||||
\*-----------------------------------------------------*/
|
||||
wchar_t product_string[256];
|
||||
|
||||
int ret = hid_get_product_string(dev, product_string, 256);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
name = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
name = StringUtils::wstring_to_string(product_string);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read vendor string |
|
||||
\*-----------------------------------------------------*/
|
||||
wchar_t vendor_string[256];
|
||||
|
||||
ret = hid_get_manufacturer_string(dev, vendor_string, 256);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
vendor = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
vendor = StringUtils::wstring_to_string(vendor_string);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read serial string |
|
||||
\*-----------------------------------------------------*/
|
||||
wchar_t serial_string[256];
|
||||
|
||||
ret = hid_get_serial_number_string(dev, serial_string, 256);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
serial = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
serial = StringUtils::wstring_to_string(serial_string);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get VIA, Vial, and VialRGB information |
|
||||
\*-----------------------------------------------------*/
|
||||
CmdGetViaProtocolVersion(&via_protocol_version);
|
||||
|
||||
if(via_protocol_version < 9)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CmdGetVialInfo(&vial_protocol_version, &keyboard_uid, &vialrgb_flag);
|
||||
|
||||
if((vial_protocol_version < 4) || ((vialrgb_flag & 1) == 0))
|
||||
{
|
||||
supported = false;
|
||||
return;
|
||||
}
|
||||
|
||||
CmdGetVialRGBInfo(&vialrgb_protocol_version, &maximum_brightness);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get list of supported effects |
|
||||
\*-----------------------------------------------------*/
|
||||
CmdGetSupportedEffects();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get count of LEDs |
|
||||
\*-----------------------------------------------------*/
|
||||
CmdGetNumberLEDs(&number_leds);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get info and keycode for all LEDs |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned short led_index = 0; led_index < number_leds; led_index++)
|
||||
{
|
||||
led_info.push_back(CmdGetLEDInfo(led_index));
|
||||
keycodes.push_back(CmdGetKeycode(0, led_info[led_index].row, led_info[led_index].col));
|
||||
}
|
||||
|
||||
supported = true;
|
||||
}
|
||||
|
||||
QMKVialRGBController::~QMKVialRGBController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string QMKVialRGBController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string QMKVialRGBController::GetName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string QMKVialRGBController::GetSerial()
|
||||
{
|
||||
return(serial);
|
||||
}
|
||||
|
||||
std::string QMKVialRGBController::GetVendor()
|
||||
{
|
||||
return(vendor);
|
||||
}
|
||||
|
||||
std::string QMKVialRGBController::GetVersion()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Format UID string |
|
||||
\*-----------------------------------------------------*/
|
||||
char uid_buf[17];
|
||||
snprintf(uid_buf, sizeof(uid_buf), "%016llX", keyboard_uid);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Format multi-line version text |
|
||||
\*-----------------------------------------------------*/
|
||||
return("VIA: " + std::to_string(via_protocol_version) + "\r\n"
|
||||
+ "Vial: " + std::to_string(vial_protocol_version) + "\r\n"
|
||||
+ "VialRGB: " + std::to_string(vialrgb_protocol_version) + "\r\n"
|
||||
+ "UID: " + uid_buf);
|
||||
}
|
||||
|
||||
bool QMKVialRGBController::GetSupported()
|
||||
{
|
||||
return(supported);
|
||||
}
|
||||
|
||||
unsigned short QMKVialRGBController::GetEffect(std::size_t effect_idx)
|
||||
{
|
||||
return(supported_effects[effect_idx]);
|
||||
}
|
||||
|
||||
std::size_t QMKVialRGBController::GetEffectCount()
|
||||
{
|
||||
return(supported_effects.size());
|
||||
}
|
||||
|
||||
unsigned short QMKVialRGBController::GetKeycode(unsigned short led_index)
|
||||
{
|
||||
return(keycodes[led_index]);
|
||||
}
|
||||
|
||||
unsigned short QMKVialRGBController::GetLEDCount()
|
||||
{
|
||||
return(number_leds);
|
||||
}
|
||||
|
||||
qmk_rgb_matrix_led_info QMKVialRGBController::GetLEDInfo(unsigned short led_index)
|
||||
{
|
||||
return(led_info[led_index]);
|
||||
}
|
||||
|
||||
void QMKVialRGBController::GetMode
|
||||
(
|
||||
unsigned short* mode,
|
||||
unsigned char* speed,
|
||||
unsigned char* hue,
|
||||
unsigned char* sat,
|
||||
unsigned char* val
|
||||
)
|
||||
{
|
||||
CmdGetMode(mode, speed, hue, sat, val);
|
||||
}
|
||||
|
||||
void QMKVialRGBController::SendLEDs
|
||||
(
|
||||
unsigned short number_leds,
|
||||
RGBColor* color_data
|
||||
)
|
||||
{
|
||||
unsigned short led_start_index = 0;
|
||||
unsigned char number_packet_leds = 9;
|
||||
|
||||
while(led_start_index < number_leds)
|
||||
{
|
||||
if((number_leds - led_start_index) < 9)
|
||||
{
|
||||
number_packet_leds = (number_leds - led_start_index);
|
||||
}
|
||||
|
||||
CmdSendLEDs(led_start_index, number_packet_leds, &color_data[led_start_index]);
|
||||
|
||||
led_start_index += number_packet_leds;
|
||||
}
|
||||
}
|
||||
|
||||
void QMKVialRGBController::SetMode
|
||||
(
|
||||
unsigned short mode,
|
||||
unsigned char speed,
|
||||
unsigned char hue,
|
||||
unsigned char sat,
|
||||
unsigned char val
|
||||
)
|
||||
{
|
||||
CmdSetMode(mode, speed, hue, sat, val);
|
||||
}
|
||||
|
||||
unsigned short QMKVialRGBController::CmdGetKeycode
|
||||
(
|
||||
unsigned char layer,
|
||||
unsigned char row,
|
||||
unsigned char col
|
||||
)
|
||||
{
|
||||
unsigned char data[5];
|
||||
unsigned short keycode;
|
||||
|
||||
data[0] = row;
|
||||
data[1] = col;
|
||||
|
||||
SendCheckCommand(CMD_VIA_DYNAMIC_KEYMAP_GET_KEYCODE, layer, data, 2, data, 5);
|
||||
|
||||
memcpy(&keycode, &data[3], sizeof(unsigned short));
|
||||
|
||||
return(keycode);
|
||||
}
|
||||
|
||||
qmk_rgb_matrix_led_info QMKVialRGBController::CmdGetLEDInfo
|
||||
(
|
||||
unsigned short led_index
|
||||
)
|
||||
{
|
||||
qmk_rgb_matrix_led_info data;
|
||||
|
||||
SendCheckCommand(CMD_LIGHTING_GET_VALUE, VIALRGB_GET_LED_INFO, (unsigned char*)&led_index, sizeof(led_index), (unsigned char*)&data, sizeof(data));
|
||||
|
||||
return(data);
|
||||
}
|
||||
|
||||
void QMKVialRGBController::CmdGetMode
|
||||
(
|
||||
unsigned short* mode,
|
||||
unsigned char* speed,
|
||||
unsigned char* hue,
|
||||
unsigned char* sat,
|
||||
unsigned char* val
|
||||
)
|
||||
{
|
||||
unsigned char data[6];
|
||||
|
||||
SendCheckCommand(CMD_LIGHTING_GET_VALUE, VIALRGB_GET_MODE, NULL, 0, data, 6);
|
||||
|
||||
memcpy(mode, &data[0], sizeof(unsigned short));
|
||||
*speed = data[2];
|
||||
*hue = data[3];
|
||||
*sat = data[4];
|
||||
*val = data[5];
|
||||
}
|
||||
|
||||
void QMKVialRGBController::CmdGetNumberLEDs
|
||||
(
|
||||
unsigned short* number_leds
|
||||
)
|
||||
{
|
||||
SendCheckCommand(CMD_LIGHTING_GET_VALUE, VIALRGB_GET_NUMBER_LEDS, NULL, 0, (unsigned char*)number_leds, sizeof(unsigned short));
|
||||
}
|
||||
|
||||
void QMKVialRGBController::CmdGetSupportedEffects()
|
||||
{
|
||||
unsigned short packet_effects[15];
|
||||
unsigned short max_effect = 0;
|
||||
|
||||
supported_effects.clear();
|
||||
|
||||
supported_effects.push_back(0);
|
||||
|
||||
while(max_effect < VIALRGB_EFFECT_SKIP)
|
||||
{
|
||||
SendCheckCommand(CMD_LIGHTING_GET_VALUE, VIALRGB_GET_SUPPORTED, (unsigned char*)&max_effect, sizeof(max_effect), (unsigned char*)packet_effects, sizeof(packet_effects));
|
||||
|
||||
for(unsigned int effect_idx = 0; effect_idx < 15; effect_idx++)
|
||||
{
|
||||
if(packet_effects[effect_idx] == VIALRGB_EFFECT_SKIP)
|
||||
{
|
||||
return;
|
||||
}
|
||||
supported_effects.push_back(packet_effects[effect_idx]);
|
||||
max_effect = packet_effects[effect_idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QMKVialRGBController::CmdGetVialInfo
|
||||
(
|
||||
unsigned int* vial_protocol,
|
||||
unsigned long long* keyboard_uid,
|
||||
unsigned char* vialrgb_flag
|
||||
)
|
||||
{
|
||||
unsigned char data[sizeof(int) + sizeof(unsigned long long) + sizeof(unsigned char)];
|
||||
|
||||
SendCommand(CMD_VIAL_COMMAND, VIAL_GET_KEYBOARD_ID, NULL, 0, data, sizeof(data));
|
||||
|
||||
memcpy(vial_protocol, &data[0], sizeof(int));
|
||||
memcpy(keyboard_uid, &data[sizeof(int)], sizeof(unsigned long long));
|
||||
memcpy(vialrgb_flag, &data[sizeof(int) + sizeof(unsigned long long)], sizeof(unsigned char));
|
||||
}
|
||||
|
||||
void QMKVialRGBController::CmdGetVialRGBInfo
|
||||
(
|
||||
unsigned short* vialrgb_protocol_version,
|
||||
unsigned char* maximum_brightness
|
||||
)
|
||||
{
|
||||
unsigned char data[sizeof(unsigned short) + sizeof(unsigned char)];
|
||||
|
||||
SendCommand(CMD_VIAL_COMMAND, VIAL_GET_KEYBOARD_ID, NULL, 0, data, sizeof(data));
|
||||
|
||||
memcpy(vialrgb_protocol_version, &data[0], sizeof(unsigned short));
|
||||
memcpy(maximum_brightness, &data[sizeof(unsigned char)], sizeof(unsigned short));
|
||||
}
|
||||
|
||||
void QMKVialRGBController::CmdGetViaProtocolVersion
|
||||
(
|
||||
unsigned short* via_protocol_version
|
||||
)
|
||||
{
|
||||
SendCheckCommand(CMD_GET_PROTOCOL_VERSION, 0, NULL, 0, (unsigned char*)via_protocol_version, sizeof(unsigned int));
|
||||
}
|
||||
|
||||
void QMKVialRGBController::CmdSendLEDs
|
||||
(
|
||||
unsigned short start_index,
|
||||
unsigned char number_leds,
|
||||
RGBColor* color_data
|
||||
)
|
||||
{
|
||||
unsigned char data[30];
|
||||
|
||||
memcpy(&data[0], &start_index, sizeof(start_index));
|
||||
memcpy(&data[2], &number_leds, sizeof(number_leds));
|
||||
|
||||
if(number_leds > 9)
|
||||
{
|
||||
number_leds = 9;
|
||||
}
|
||||
|
||||
for(unsigned char led_index = 0; led_index < number_leds; led_index++)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| VialRGB sends direct packets in HSV for some |
|
||||
| inexplicable reason, so do the RGB to HSV |
|
||||
| conversion before sending |
|
||||
\*-------------------------------------------------*/
|
||||
hsv_t hsv_color;
|
||||
rgb2hsv(color_data[led_index], &hsv_color);
|
||||
|
||||
data[3 + (led_index * 3)] = (unsigned char)((float)hsv_color.hue * (256.0f / 360.0f));
|
||||
data[4 + (led_index * 3)] = hsv_color.saturation;
|
||||
data[5 + (led_index * 3)] = hsv_color.value;
|
||||
}
|
||||
|
||||
SendCheckCommand(CMD_LIGHTING_SET_VALUE, VIALRGB_DIRECT_FASTSET, data, sizeof(data), NULL, 0);
|
||||
}
|
||||
|
||||
void QMKVialRGBController::CmdSetMode
|
||||
(
|
||||
unsigned short mode,
|
||||
unsigned char speed,
|
||||
unsigned char hue,
|
||||
unsigned char sat,
|
||||
unsigned char val
|
||||
)
|
||||
{
|
||||
unsigned char data[6];
|
||||
|
||||
memcpy(&data[0], &mode, sizeof(unsigned short));
|
||||
|
||||
data[2] = speed;
|
||||
data[3] = hue;
|
||||
data[4] = sat;
|
||||
data[5] = val;
|
||||
|
||||
SendCommand(CMD_LIGHTING_SET_VALUE, VIALRGB_SET_MODE, data, sizeof(data), NULL, 0);
|
||||
}
|
||||
|
||||
int QMKVialRGBController::SendCommand
|
||||
(
|
||||
unsigned char cmd,
|
||||
unsigned char subcmd,
|
||||
unsigned char* data_in,
|
||||
unsigned char data_in_size,
|
||||
unsigned char* data_out,
|
||||
unsigned char data_out_size
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[MSG_LEN + 1];
|
||||
|
||||
memset(usb_buf, 0, sizeof(usb_buf));
|
||||
|
||||
usb_buf[0] = 0x00;
|
||||
usb_buf[1] = cmd;
|
||||
usb_buf[2] = subcmd;
|
||||
|
||||
memcpy(&usb_buf[3], data_in, data_in_size);
|
||||
|
||||
hid_write(dev, usb_buf, sizeof(usb_buf));
|
||||
int bytes_received = hid_read_timeout(dev, usb_buf, sizeof(usb_buf)-1, 1000);
|
||||
|
||||
memcpy(data_out, &usb_buf[0], data_out_size);
|
||||
|
||||
return(bytes_received);
|
||||
}
|
||||
|
||||
int QMKVialRGBController::SendCheckCommand
|
||||
(
|
||||
unsigned char cmd,
|
||||
unsigned char subcmd,
|
||||
unsigned char* data_in,
|
||||
unsigned char data_in_size,
|
||||
unsigned char* data_out,
|
||||
unsigned char data_out_size
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[MSG_LEN + 1];
|
||||
|
||||
memset(usb_buf, 0, sizeof(usb_buf));
|
||||
|
||||
usb_buf[0] = 0x00;
|
||||
usb_buf[1] = cmd;
|
||||
usb_buf[2] = subcmd;
|
||||
|
||||
memcpy(&usb_buf[3], data_in, data_in_size);
|
||||
|
||||
hid_write(dev, usb_buf, sizeof(usb_buf));
|
||||
int bytes_received = hid_read_timeout(dev, usb_buf, sizeof(usb_buf)-1, 1000);
|
||||
|
||||
memcpy(data_out, &usb_buf[2], data_out_size);
|
||||
|
||||
return(bytes_received);
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKVialRGBController.h |
|
||||
| |
|
||||
| Driver for VialRGB QMK Keyboard Protocol |
|
||||
| |
|
||||
| Adam Honse <calcprogrammer1@gmail.com) 29 Sep 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "ResourceManager.h"
|
||||
#include "QMKCommon.h"
|
||||
#include "RGBController.h"
|
||||
|
||||
#define MSG_LEN 32
|
||||
|
||||
enum
|
||||
{
|
||||
CMD_GET_PROTOCOL_VERSION = 0x01,
|
||||
CMD_GET_KEYBOARD_VALUE = 0x02,
|
||||
CMD_SET_KEYBOARD_VALUE = 0x03,
|
||||
CMD_VIA_DYNAMIC_KEYMAP_GET_KEYCODE = 0x04,
|
||||
CMD_VIA_DYNAMIC_KEYMAP_SET_KEYCODE = 0x05,
|
||||
CMD_VIA_DYNAMIC_KEYMAP_RESET = 0x06,
|
||||
CMD_LIGHTING_SET_VALUE = 0x07,
|
||||
CMD_LIGHTING_GET_VALUE = 0x08,
|
||||
CMD_VIAL_COMMAND = 0xFE,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
VIAL_GET_KEYBOARD_ID = 0x00,
|
||||
VIAL_GET_SIZE = 0x01,
|
||||
VIAL_GET_DEFINITION = 0x02,
|
||||
VIAL_GET_UNLOCK_STATUS = 0x05,
|
||||
VIAL_UNLOCK_START = 0x06,
|
||||
VIAL_UNLOCK_POLL = 0x07,
|
||||
VIAL_LOCK = 0x08,
|
||||
VIALRGB_GET_INFO = 0x40,
|
||||
VIALRGB_GET_MODE = 0x41,
|
||||
VIALRGB_GET_SUPPORTED = 0x42,
|
||||
VIALRGB_GET_NUMBER_LEDS = 0x43,
|
||||
VIALRGB_GET_LED_INFO = 0x44,
|
||||
VIALRGB_SET_MODE = 0x41,
|
||||
VIALRGB_DIRECT_FASTSET = 0x42,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
VIALRGB_EFFECT_OFF,
|
||||
VIALRGB_EFFECT_DIRECT,
|
||||
VIALRGB_EFFECT_SOLID_COLOR,
|
||||
VIALRGB_EFFECT_ALPHAS_MODS,
|
||||
VIALRGB_EFFECT_GRADIENT_UP_DOWN,
|
||||
VIALRGB_EFFECT_GRADIENT_LEFT_RIGHT,
|
||||
VIALRGB_EFFECT_BREATHING,
|
||||
VIALRGB_EFFECT_BAND_SAT,
|
||||
VIALRGB_EFFECT_BAND_VAL,
|
||||
VIALRGB_EFFECT_BAND_PINWHEEL_SAT,
|
||||
VIALRGB_EFFECT_BAND_PINWHEEL_VAL,
|
||||
VIALRGB_EFFECT_BAND_SPIRAL_SAT,
|
||||
VIALRGB_EFFECT_BAND_SPIRAL_VAL,
|
||||
VIALRGB_EFFECT_CYCLE_ALL,
|
||||
VIALRGB_EFFECT_CYCLE_LEFT_RIGHT,
|
||||
VIALRGB_EFFECT_CYCLE_UP_DOWN,
|
||||
VIALRGB_EFFECT_RAINBOW_MOVING_CHEVRON,
|
||||
VIALRGB_EFFECT_CYCLE_OUT_IN,
|
||||
VIALRGB_EFFECT_CYCLE_OUT_IN_DUAL,
|
||||
VIALRGB_EFFECT_CYCLE_PINWHEEL,
|
||||
VIALRGB_EFFECT_CYCLE_SPIRAL,
|
||||
VIALRGB_EFFECT_DUAL_BEACON,
|
||||
VIALRGB_EFFECT_RAINBOW_BEACON,
|
||||
VIALRGB_EFFECT_RAINBOW_PINWHEELS,
|
||||
VIALRGB_EFFECT_RAINDROPS,
|
||||
VIALRGB_EFFECT_JELLYBEAN_RAINDROPS,
|
||||
VIALRGB_EFFECT_HUE_BREATHING,
|
||||
VIALRGB_EFFECT_HUE_PENDULUM,
|
||||
VIALRGB_EFFECT_HUE_WAVE,
|
||||
VIALRGB_EFFECT_TYPING_HEATMAP,
|
||||
VIALRGB_EFFECT_DIGITAL_RAIN,
|
||||
VIALRGB_EFFECT_SOLID_REACTIVE_SIMPLE,
|
||||
VIALRGB_EFFECT_SOLID_REACTIVE,
|
||||
VIALRGB_EFFECT_SOLID_REACTIVE_WIDE,
|
||||
VIALRGB_EFFECT_SOLID_REACTIVE_MULTIWIDE,
|
||||
VIALRGB_EFFECT_SOLID_REACTIVE_CROSS,
|
||||
VIALRGB_EFFECT_SOLID_REACTIVE_MULTICROSS,
|
||||
VIALRGB_EFFECT_SOLID_REACTIVE_NEXUS,
|
||||
VIALRGB_EFFECT_SOLID_REACTIVE_MULTINEXUS,
|
||||
VIALRGB_EFFECT_SPLASH,
|
||||
VIALRGB_EFFECT_MULTISPLASH,
|
||||
VIALRGB_EFFECT_SOLID_SPLASH,
|
||||
VIALRGB_EFFECT_SOLID_MULTISPLASH,
|
||||
VIALRGB_EFFECT_PIXEL_RAIN,
|
||||
VIALRGB_EFFECT_PIXEL_FRACTAL,
|
||||
VIALRGB_EFFECT_SKIP = 0xFFFF
|
||||
};
|
||||
|
||||
class QMKVialRGBController
|
||||
{
|
||||
public:
|
||||
QMKVialRGBController(hid_device *dev_handle, const char *path);
|
||||
~QMKVialRGBController();
|
||||
|
||||
std::string GetLocation();
|
||||
std::string GetName();
|
||||
std::string GetSerial();
|
||||
std::string GetVendor();
|
||||
std::string GetVersion();
|
||||
|
||||
bool GetSupported();
|
||||
|
||||
unsigned short GetEffect(std::size_t effect_idx);
|
||||
std::size_t GetEffectCount();
|
||||
unsigned short GetKeycode(unsigned short led_index);
|
||||
unsigned short GetLEDCount();
|
||||
qmk_rgb_matrix_led_info GetLEDInfo(unsigned short led_index);
|
||||
|
||||
void GetMode
|
||||
(
|
||||
unsigned short* mode,
|
||||
unsigned char* speed,
|
||||
unsigned char* hue,
|
||||
unsigned char* sat,
|
||||
unsigned char* val
|
||||
);
|
||||
|
||||
void SendLEDs
|
||||
(
|
||||
unsigned short number_leds,
|
||||
RGBColor* color_data
|
||||
);
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned short mode,
|
||||
unsigned char speed,
|
||||
unsigned char hue,
|
||||
unsigned char sat,
|
||||
unsigned char val
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
unsigned long long keyboard_uid;
|
||||
std::vector<unsigned short> keycodes;
|
||||
std::vector<qmk_rgb_matrix_led_info> led_info;
|
||||
std::string location;
|
||||
unsigned char maximum_brightness;
|
||||
std::string name;
|
||||
unsigned short number_leds;
|
||||
std::string serial;
|
||||
bool supported;
|
||||
std::vector<unsigned short> supported_effects;
|
||||
std::string vendor;
|
||||
unsigned short via_protocol_version;
|
||||
unsigned int vial_protocol_version;
|
||||
unsigned short vialrgb_protocol_version;
|
||||
unsigned char vialrgb_flag;
|
||||
|
||||
unsigned short CmdGetKeycode
|
||||
(
|
||||
unsigned char layer,
|
||||
unsigned char row,
|
||||
unsigned char col
|
||||
);
|
||||
|
||||
qmk_rgb_matrix_led_info CmdGetLEDInfo
|
||||
(
|
||||
unsigned short led_index
|
||||
);
|
||||
|
||||
void CmdGetMode
|
||||
(
|
||||
unsigned short* mode,
|
||||
unsigned char* speed,
|
||||
unsigned char* hue,
|
||||
unsigned char* sat,
|
||||
unsigned char* val
|
||||
);
|
||||
|
||||
void CmdGetNumberLEDs
|
||||
(
|
||||
unsigned short* number_leds
|
||||
);
|
||||
|
||||
void CmdGetSupportedEffects();
|
||||
|
||||
void CmdGetVialInfo
|
||||
(
|
||||
unsigned int* vial_protocol_version,
|
||||
unsigned long long* keyboard_uid,
|
||||
unsigned char* vialrgb_flag
|
||||
);
|
||||
|
||||
void CmdGetVialRGBInfo
|
||||
(
|
||||
unsigned short* vialrgb_protocol_version,
|
||||
unsigned char* maximum_brightness
|
||||
);
|
||||
|
||||
void CmdGetViaProtocolVersion
|
||||
(
|
||||
unsigned short* via_protocol_version
|
||||
);
|
||||
|
||||
void CmdSendLEDs
|
||||
(
|
||||
unsigned short start_index,
|
||||
unsigned char number_leds,
|
||||
RGBColor* color_data
|
||||
);
|
||||
|
||||
void CmdSetMode
|
||||
(
|
||||
unsigned short mode,
|
||||
unsigned char speed,
|
||||
unsigned char hue,
|
||||
unsigned char sat,
|
||||
unsigned char val
|
||||
);
|
||||
|
||||
int SendCommand
|
||||
(
|
||||
unsigned char cmd,
|
||||
unsigned char subcmd,
|
||||
unsigned char* data_in,
|
||||
unsigned char data_in_size,
|
||||
unsigned char* data_out,
|
||||
unsigned char data_out_size
|
||||
);
|
||||
|
||||
int SendCheckCommand
|
||||
(
|
||||
unsigned char cmd,
|
||||
unsigned char subcmd,
|
||||
unsigned char* data_in,
|
||||
unsigned char data_in_size,
|
||||
unsigned char* data_out,
|
||||
unsigned char data_out_size
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,84 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| QMKVialRGBControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for VialRGB QMK Keyboard Protocol |
|
||||
| |
|
||||
| Adam Honse <calcprogrammer1@gmail.com> 29 Sep 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "Detector.h"
|
||||
#include "QMKVialRGBController.h"
|
||||
#include "RGBController_QMKVialRGB.h"
|
||||
#include "SettingsManager.h"
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| USB IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define RASPBERRY_PI_VID 0x2E8A
|
||||
#define RASPBERRY_PI_500_PLUS_PID 0x0011
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Usage and Usage Page |
|
||||
\*-----------------------------------------------------*/
|
||||
#define QMK_USAGE_PAGE 0xFF60
|
||||
#define QMK_USAGE 0x61
|
||||
|
||||
void DetectQMKVialRGBControllers(hid_device_info *info, const std::string&)
|
||||
{
|
||||
hid_device *dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
QMKVialRGBController* controller = new QMKVialRGBController(dev, info->path);
|
||||
|
||||
if(controller->GetSupported())
|
||||
{
|
||||
RGBController_QMKVialRGB* rgb_controller = new RGBController_QMKVialRGB(controller);
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterQMKVialRGBDetectors()
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Get QMKVialRGB settings |
|
||||
\*-------------------------------------------------*/
|
||||
json vial_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("QMKVialRGBDevices");
|
||||
|
||||
if(vial_settings.contains("devices"))
|
||||
{
|
||||
for(unsigned int device_idx = 0; device_idx < vial_settings["devices"].size(); device_idx++)
|
||||
{
|
||||
if( vial_settings["devices"][device_idx].contains("usb_pid")
|
||||
&& vial_settings["devices"][device_idx].contains("usb_vid")
|
||||
&& vial_settings["devices"][device_idx].contains("name"))
|
||||
{
|
||||
std::string usb_pid_str = vial_settings["devices"][device_idx]["usb_pid"];
|
||||
std::string usb_vid_str = vial_settings["devices"][device_idx]["usb_vid"];
|
||||
std::string name = vial_settings["devices"][device_idx]["name"];
|
||||
|
||||
/*-------------------------------------*\
|
||||
| Parse hex string to integer |
|
||||
\*-------------------------------------*/
|
||||
unsigned short usb_pid = std::stoi(usb_pid_str, 0, 16);
|
||||
unsigned short usb_vid = std::stoi(usb_vid_str, 0, 16);
|
||||
|
||||
REGISTER_DYNAMIC_HID_DETECTOR_PU(name, DetectQMKVialRGBControllers, usb_vid, usb_pid, QMK_USAGE_PAGE, QMK_USAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_DYNAMIC_DETECTOR("QMK VialRGB Devices", RegisterQMKVialRGBDetectors);
|
||||
|
||||
REGISTER_HID_DETECTOR_PU( "Raspberry Pi 500+", DetectQMKVialRGBControllers, RASPBERRY_PI_VID, RASPBERRY_PI_500_PLUS_PID, QMK_USAGE_PAGE, QMK_USAGE );
|
||||
@@ -0,0 +1,268 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_QMKVialRGB.cpp |
|
||||
| |
|
||||
| RGBController for VialRGB QMK Keyboard Protocol |
|
||||
| |
|
||||
| Adam Honse <calcprogrammer1@gmail.com) 29 Sep 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "hsv.h"
|
||||
#include "QMKKeycodes.h"
|
||||
#include "RGBController_QMKVialRGB.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short value;
|
||||
std::string name;
|
||||
bool has_speed;
|
||||
} vialrgb_mode;
|
||||
|
||||
#define VIALRGB_NUM_MODES (sizeof(vialrgb_modes) / sizeof(vialrgb_mode))
|
||||
|
||||
static const vialrgb_mode vialrgb_modes[] =
|
||||
{
|
||||
{ VIALRGB_EFFECT_OFF, "Off", false },
|
||||
{ VIALRGB_EFFECT_DIRECT, "Direct", false },
|
||||
{ VIALRGB_EFFECT_SOLID_COLOR, "Static", false },
|
||||
{ VIALRGB_EFFECT_ALPHAS_MODS, "Alphas Mods", true },
|
||||
{ VIALRGB_EFFECT_GRADIENT_UP_DOWN, "Gradient Up Down", true },
|
||||
{ VIALRGB_EFFECT_GRADIENT_LEFT_RIGHT, "Gradient Left Right", true },
|
||||
{ VIALRGB_EFFECT_BREATHING, "Breathing", true },
|
||||
{ VIALRGB_EFFECT_BAND_SAT, "Band Sat", true },
|
||||
{ VIALRGB_EFFECT_BAND_VAL, "Band Val", true },
|
||||
{ VIALRGB_EFFECT_BAND_PINWHEEL_SAT, "Band Pinwheel Sat", true },
|
||||
{ VIALRGB_EFFECT_BAND_PINWHEEL_VAL, "Band Pinwheel Val", true },
|
||||
{ VIALRGB_EFFECT_BAND_SPIRAL_SAT, "Band Spiral Sat", true },
|
||||
{ VIALRGB_EFFECT_BAND_SPIRAL_VAL, "Band Spiral Val", true },
|
||||
{ VIALRGB_EFFECT_CYCLE_ALL, "Cycle All", true },
|
||||
{ VIALRGB_EFFECT_CYCLE_LEFT_RIGHT, "Cycle Left Right", true },
|
||||
{ VIALRGB_EFFECT_CYCLE_UP_DOWN, "Cycle Up Down", true },
|
||||
{ VIALRGB_EFFECT_RAINBOW_MOVING_CHEVRON, "Rainbow Moving Chevron", true },
|
||||
{ VIALRGB_EFFECT_CYCLE_OUT_IN, "Cycle Out In", true },
|
||||
{ VIALRGB_EFFECT_CYCLE_OUT_IN_DUAL, "Cycle Out In Dual", true },
|
||||
{ VIALRGB_EFFECT_CYCLE_PINWHEEL, "Cycle Pinwheel", true },
|
||||
{ VIALRGB_EFFECT_CYCLE_SPIRAL, "Cycle Spiral", true },
|
||||
{ VIALRGB_EFFECT_DUAL_BEACON, "Dual Beacon", true },
|
||||
{ VIALRGB_EFFECT_RAINBOW_BEACON, "Rainbow Beacon", true },
|
||||
{ VIALRGB_EFFECT_RAINBOW_PINWHEELS, "Rainbow Pinwheels", true },
|
||||
{ VIALRGB_EFFECT_RAINDROPS, "Raindrops", true },
|
||||
{ VIALRGB_EFFECT_JELLYBEAN_RAINDROPS, "Jellybean Raindrops", true },
|
||||
{ VIALRGB_EFFECT_HUE_BREATHING, "Hue Breathing", true },
|
||||
{ VIALRGB_EFFECT_HUE_PENDULUM, "Hue Pendulum", true },
|
||||
{ VIALRGB_EFFECT_HUE_WAVE, "Hue Wave", true },
|
||||
{ VIALRGB_EFFECT_TYPING_HEATMAP, "Typing Heatmap", true },
|
||||
{ VIALRGB_EFFECT_DIGITAL_RAIN, "Digital Rain", true },
|
||||
{ VIALRGB_EFFECT_SOLID_REACTIVE_SIMPLE, "Solid Reactive Simple", true },
|
||||
{ VIALRGB_EFFECT_SOLID_REACTIVE, "Solid Reactive", true },
|
||||
{ VIALRGB_EFFECT_SOLID_REACTIVE_WIDE, "Solid Reactive Wide", true },
|
||||
{ VIALRGB_EFFECT_SOLID_REACTIVE_MULTIWIDE, "Solid Reactive Multiwide", true },
|
||||
{ VIALRGB_EFFECT_SOLID_REACTIVE_CROSS, "Solid Reactive Cross", true },
|
||||
{ VIALRGB_EFFECT_SOLID_REACTIVE_MULTICROSS, "Solid Reactive Multicross", true },
|
||||
{ VIALRGB_EFFECT_SOLID_REACTIVE_NEXUS, "Solid Reactive Nexus", true },
|
||||
{ VIALRGB_EFFECT_SOLID_REACTIVE_MULTINEXUS, "Solid Reactive Multinexus", true },
|
||||
{ VIALRGB_EFFECT_SPLASH, "Splash", true },
|
||||
{ VIALRGB_EFFECT_MULTISPLASH, "Multisplash", true },
|
||||
{ VIALRGB_EFFECT_SOLID_SPLASH, "Solid Splash", true },
|
||||
{ VIALRGB_EFFECT_SOLID_MULTISPLASH, "Solid Multisplash", true },
|
||||
{ VIALRGB_EFFECT_PIXEL_RAIN, "Pixel Rain", true },
|
||||
{ VIALRGB_EFFECT_PIXEL_FRACTAL, "Pixel Fractal", true },
|
||||
};
|
||||
|
||||
RGBController_QMKVialRGB::RGBController_QMKVialRGB(QMKVialRGBController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
name = controller->GetName();
|
||||
description = "QMK VialRGB Device";
|
||||
vendor = controller->GetVendor();
|
||||
location = controller->GetLocation();
|
||||
serial = controller->GetSerial();
|
||||
version = controller->GetVersion();
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read mode list |
|
||||
\*-----------------------------------------------------*/
|
||||
for(std::size_t effect_idx = 0; effect_idx < controller->GetEffectCount(); effect_idx++)
|
||||
{
|
||||
unsigned short mode_index = controller->GetEffect(effect_idx);
|
||||
mode new_mode;
|
||||
|
||||
if(mode_index > VIALRGB_NUM_MODES)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
new_mode.name = vialrgb_modes[mode_index].name;
|
||||
new_mode.value = vialrgb_modes[mode_index].value;
|
||||
|
||||
if(new_mode.value == VIALRGB_EFFECT_DIRECT)
|
||||
{
|
||||
new_mode.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
new_mode.color_mode = MODE_COLORS_PER_LED;
|
||||
}
|
||||
|
||||
if(new_mode.value >= VIALRGB_EFFECT_SOLID_COLOR)
|
||||
{
|
||||
new_mode.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
new_mode.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
new_mode.colors_min = 1;
|
||||
new_mode.colors_max = 1;
|
||||
new_mode.colors.resize(1);
|
||||
}
|
||||
|
||||
if(vialrgb_modes[mode_index].has_speed)
|
||||
{
|
||||
new_mode.flags |= MODE_FLAG_HAS_SPEED;
|
||||
new_mode.speed_min = 0;
|
||||
new_mode.speed_max = 255;
|
||||
new_mode.speed = 128;
|
||||
}
|
||||
|
||||
modes.push_back(new_mode);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read current mode |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned short cur_mode;
|
||||
unsigned char cur_speed;
|
||||
unsigned char cur_hue;
|
||||
unsigned char cur_sat;
|
||||
unsigned char cur_val;
|
||||
|
||||
controller->GetMode(&cur_mode, &cur_speed, &cur_hue, &cur_sat, &cur_val);
|
||||
|
||||
active_mode = cur_mode;
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
modes[active_mode].speed = cur_speed;
|
||||
}
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
hsv_t hsv_color;
|
||||
hsv_color.hue = (unsigned int)((float)cur_hue * (360.0f / 256.0f));
|
||||
hsv_color.saturation = cur_sat;
|
||||
hsv_color.value = cur_val;
|
||||
|
||||
RGBColor rgb_color = hsv2rgb(&hsv_color);
|
||||
modes[active_mode].colors[0] = rgb_color;
|
||||
}
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_QMKVialRGB::~RGBController_QMKVialRGB()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_QMKVialRGB::SetupZones()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Build matrix map |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char max_col = 0;
|
||||
unsigned char max_row = 0;
|
||||
|
||||
for(unsigned short led_index = 0; led_index < controller->GetLEDCount(); led_index++)
|
||||
{
|
||||
qmk_rgb_matrix_led_info info = controller->GetLEDInfo(led_index);
|
||||
|
||||
if(info.col > max_col)
|
||||
{
|
||||
max_col = info.col;
|
||||
}
|
||||
|
||||
if(info.row > max_row)
|
||||
{
|
||||
max_row = info.row;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char height = max_row + 1;
|
||||
unsigned char width = max_col + 1;
|
||||
|
||||
unsigned int* matrix_map = new unsigned int[width * height];
|
||||
|
||||
memset(matrix_map, 0xFF, (sizeof(unsigned int) * (width * height)));
|
||||
|
||||
for(unsigned short led_index = 0; led_index < controller->GetLEDCount(); led_index++)
|
||||
{
|
||||
qmk_rgb_matrix_led_info info = controller->GetLEDInfo(led_index);
|
||||
|
||||
matrix_map[(width * info.row) + info.col] = (unsigned int)led_index;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Create keyboard zone |
|
||||
\*-----------------------------------------------------*/
|
||||
zone keyboard;
|
||||
|
||||
keyboard.name = "Keyboard";
|
||||
keyboard.type = ZONE_TYPE_MATRIX;
|
||||
keyboard.leds_min = controller->GetLEDCount();
|
||||
keyboard.leds_max = controller->GetLEDCount();
|
||||
keyboard.leds_count = controller->GetLEDCount();
|
||||
keyboard.matrix_map = new matrix_map_type;
|
||||
keyboard.matrix_map->height = height;
|
||||
keyboard.matrix_map->width = width;
|
||||
keyboard.matrix_map->map = matrix_map;
|
||||
|
||||
zones.push_back(keyboard);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Create keyboard LEDs |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned short led_idx = 0; led_idx < controller->GetLEDCount(); led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = qmk_keynames[controller->GetKeycode(led_idx)];
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_QMKVialRGB::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_QMKVialRGB::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SendLEDs((unsigned short)colors.size(), colors.data());
|
||||
}
|
||||
|
||||
void RGBController_QMKVialRGB::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_QMKVialRGB::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_QMKVialRGB::DeviceUpdateMode()
|
||||
{
|
||||
unsigned char hue = 0;
|
||||
unsigned char sat = 0;
|
||||
unsigned char val = 0;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
hsv_t hsv_color;
|
||||
rgb2hsv(modes[active_mode].colors[0], &hsv_color);
|
||||
|
||||
hue = (unsigned char)((float)hsv_color.hue * (256.0f / 360.0f));
|
||||
sat = hsv_color.saturation;
|
||||
val = hsv_color.value;
|
||||
}
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, hue, sat, val);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_QMKVialRGB.h |
|
||||
| |
|
||||
| RGBController for VialRGB QMK Keyboard Protocol |
|
||||
| |
|
||||
| Adam Honse <calcprogrammer1@gmail.com) 29 Sep 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "QMKVialRGBController.h"
|
||||
#include "RGBController.h"
|
||||
|
||||
class RGBController_QMKVialRGB : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_QMKVialRGB(QMKVialRGBController* controller_ptr);
|
||||
~RGBController_QMKVialRGB();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
QMKVialRGBController* controller;
|
||||
};
|
||||
Reference in New Issue
Block a user