From d3e7dba2b7dc6f1224886561c42facb2ef6a0276 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Tue, 23 Jun 2026 19:22:06 -0500 Subject: [PATCH] Add supported feature check in QMKKeychronController --- .../QMKKeychronController.cpp | 50 ++++++++++++++++--- .../QMKKeychronController.h | 19 ++++++- .../QMKKeychronControllerDetect.cpp | 17 +++++-- 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/Controllers/QMKController/QMKKeychronController/QMKKeychronController.cpp b/Controllers/QMKController/QMKKeychronController/QMKKeychronController.cpp index 4795bd5a7..931372869 100644 --- a/Controllers/QMKController/QMKKeychronController/QMKKeychronController.cpp +++ b/Controllers/QMKController/QMKKeychronController/QMKKeychronController.cpp @@ -24,9 +24,11 @@ QMKKeychronController::QMKKeychronController(hid_device* dev_handle, const char /*-----------------------------------------------------*\ | Initialize controller fields | \*-----------------------------------------------------*/ - dev = dev_handle; - location = path; - supported = false; + dev = dev_handle; + location = path; + kc_protocol_version = 0; + supported_features = 0; + via_protocol_version = 0; /*-----------------------------------------------------*\ | Read product string | @@ -86,6 +88,21 @@ QMKKeychronController::QMKKeychronController(hid_device* dev_handle, const char \*-----------------------------------------------------*/ CmdGetKeychronProtocolVersion(&kc_protocol_version); + /*-----------------------------------------------------*\ + | Get supported Keychron features | + \*-----------------------------------------------------*/ + CmdGetSupportFeature(&supported_features); + + if(!GetSupported()) + { + return; + } + + /*-----------------------------------------------------*\ + | Get Keychron RGB protocol version | + \*-----------------------------------------------------*/ + CmdGetKeychronRGBProtocolVersion(&kc_rgb_protocol_version); + /*-----------------------------------------------------*\ | Get count of LEDs | \*-----------------------------------------------------*/ @@ -153,13 +170,14 @@ 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)); + 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)); } bool QMKKeychronController::GetSupported() { - return(supported); + return(supported_features & KC_FEATURE_KEYCHRON_RGB); } unsigned short QMKKeychronController::GetKeycode(unsigned short led_index) @@ -246,6 +264,16 @@ void QMKKeychronController::CmdGetKeychronProtocolVersion 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 QMKKeychronController::CmdGetLEDIndexByRow(unsigned char row) { unsigned char args[4]; @@ -284,6 +312,16 @@ void QMKKeychronController::CmdGetNumberLEDs *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 diff --git a/Controllers/QMKController/QMKKeychronController/QMKKeychronController.h b/Controllers/QMKController/QMKKeychronController/QMKKeychronController.h index 1b5d62173..254b04166 100644 --- a/Controllers/QMKController/QMKKeychronController/QMKKeychronController.h +++ b/Controllers/QMKController/QMKKeychronController/QMKKeychronController.h @@ -74,6 +74,20 @@ enum KeychronKCRGBCommand 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) | \*---------------------------------------------------------*/ @@ -150,20 +164,23 @@ public: private: hid_device* dev; unsigned char kc_protocol_version; + unsigned short kc_rgb_protocol_version; std::vector keycodes; std::vector led_info; std::string location; std::string name; unsigned short number_leds; std::string serial; - bool supported; + unsigned short supported_features; std::string vendor; unsigned short via_protocol_version; unsigned short CmdGetKeycode(unsigned char layer, unsigned char row, unsigned char col); void CmdGetKeychronProtocolVersion(unsigned char* kc_protocol_version); + void CmdGetKeychronRGBProtocolVersion(unsigned short* kc_rgb_protocol_version); std::vector 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); diff --git a/Controllers/QMKController/QMKKeychronController/QMKKeychronControllerDetect.cpp b/Controllers/QMKController/QMKKeychronController/QMKKeychronControllerDetect.cpp index b451a9209..2f3733ea3 100644 --- a/Controllers/QMKController/QMKKeychronController/QMKKeychronControllerDetect.cpp +++ b/Controllers/QMKController/QMKKeychronController/QMKKeychronControllerDetect.cpp @@ -14,16 +14,23 @@ #include "QMKKeychronController.h" #include "RGBController_QMKKeychron.h" -void DetectQMKKeychronController(hid_device_info* info, const std::string& name) +void DetectQMKKeychronController(hid_device_info *info, const std::string&) { - hid_device* dev = hid_open_path(info->path); + hid_device *dev = hid_open_path(info->path); if(dev) { - QMKKeychronController* controller = new QMKKeychronController(dev, info->path); - RGBController_QMKKeychron* rgb_controller = new RGBController_QMKKeychron(controller); + QMKKeychronController* controller = new QMKKeychronController(dev, info->path); - ResourceManager::get()->RegisterRGBController(rgb_controller); + if(controller->GetSupported()) + { + RGBController_QMKKeychron* rgb_controller = new RGBController_QMKKeychron(controller); + ResourceManager::get()->RegisterRGBController(rgb_controller); + } + else + { + delete controller; + } } }