Publish LumaOps source
This commit is contained in:
@@ -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;
|
||||
};
|
||||
Reference in New Issue
Block a user