Publish curated LumaOps source from c85ee9ef8f1454f5c305398902afbb9e6738de40
Managed validation / full (push) Failing after 8s

This commit is contained in:
Public Source Publisher committed 2026-09-30 00:26:45 +00:00
1 parent 91f8b3e3c1
commit def7920856
2271 files changed
+501225 -501178

No files matched your search

@@ -1,297 +1,297 @@
/*---------------------------------------------------------*\
| KeychronKeyboardController.cpp |
| |
| Driver for Keychron keyboard |
| |
| Morgan Guimard (morg) 20 Feb 2022 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <string.h>
#include "KeychronKeyboardController.h"
#include "StringUtils.h"
using namespace std::chrono_literals;
KeychronKeyboardController::KeychronKeyboardController(hid_device* dev_handle, const hid_device_info& info, std::string dev_name)
{
dev = dev_handle;
location = info.path;
name = dev_name;
}
KeychronKeyboardController::~KeychronKeyboardController()
{
hid_close(dev);
}
std::string KeychronKeyboardController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string KeychronKeyboardController::GetNameString()
{
return(name);
}
std::string KeychronKeyboardController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
return(StringUtils::wstring_to_string(serial_string));
}
void KeychronKeyboardController:: SetLedSequencePositions(std::vector<unsigned int> positions)
{
led_sequence_positions = positions;
}
void KeychronKeyboardController::SetMode(std::vector<mode> modes, int active_mode, std::vector<RGBColor> colors)
{
/*-----------------------------------------*\
| Turn customization on/off |
| Custom mode needs to turn it on |
\*-----------------------------------------*/
SetCustomization(modes[active_mode].value == CUSTOM_MODE_VALUE);
/*-----------------------------------------*\
| Tells the device we're about to send the |
| pages (18 pages) |
\*-----------------------------------------*/
StartEffectPage();
unsigned char usb_buf[PACKET_DATA_LENGTH];
/*-----------------------------------------*\
| Configure the modes |
| LED Effect Page structure: |
| |
| OK.. this was from the original PDF |
| which appears to not be exact/up to date |
|-------------------------------------------|
| [0] Specialeffects mode1-32 |
| [1] colorFull color: 0x00 Monochrome:0x01 |
| [2] R Color ratio 0x00-0xFF |
| [3] G Color Ratio0x00-0xFF |
| [4] B Colour ratio0x00-0xFF |
| full color is 0,invalid |
| [5] dynamicdirection |
| left to right: 0x00 |
| right to left: 0x01 |
| down to up: 0x02 |
| up to down: 0x03 |
| [6] brightnesscontrol 0x00-0x0F |
| 0x0F brightest |
| [7] Periodiccontrol0x00-0x0F |
| 0x0F longest cycle |
| [8:13] Reserved |
| [14] Checkcode_L0xAA |
| [15] Checkcode_H0x55 |
|-------------------------------------------|
| Fixes: |
| color mode is 8th byte |
| brightness is 9th byte |
| speed is 10th byte |
| direction is 11th byte |
\*-----------------------------------------*/
unsigned char selected_mode[EFFECT_PAGE_LENGTH];
for(unsigned int i = 0; i < 5; i++) // 5 packets
{
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
for(unsigned int j = 0; j < 4; j++) // of 4 effects
{
const mode& m = modes[1 + j + i * 4]; // skip 1 first mode (Custom)
int offset = j * EFFECT_PAGE_LENGTH;
usb_buf[offset + 0] = m.value; // mode value
if(m.flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
{
usb_buf[offset + 1] = RGBGetRValue(m.colors[0]);
usb_buf[offset + 2] = RGBGetGValue(m.colors[0]);
usb_buf[offset + 3] = RGBGetBValue(m.colors[0]);
}
usb_buf[offset + 8] = m.color_mode == MODE_COLORS_RANDOM; // random switch
usb_buf[offset + 9] = m.brightness;
usb_buf[offset + 10] = m.speed;
usb_buf[offset + 11] = m.direction;
usb_buf[offset + 14] = EFFECT_PAGE_CHECK_CODE_L;
usb_buf[offset + 15] = EFFECT_PAGE_CHECK_CODE_H;
/*-----------------------------------------*\
| Backup active mode values for later use |
| Custom and off share the same mode value |
\*-----------------------------------------*/
if(m.value == modes[active_mode].value || (m.value == LIGHTS_OFF_MODE_VALUE && modes[active_mode].value == CUSTOM_MODE_VALUE))
{
usb_buf[offset + 9] = modes[active_mode].brightness;
for(unsigned int x = 0; x < EFFECT_PAGE_LENGTH; x++)
{
selected_mode[x] = usb_buf[offset+x];
}
}
}
Send(usb_buf); // Sends the packet
}
// packets count sent: 5
/*-----------------------------------------*\
| 3 times an empty packet - guess why... |
\*-----------------------------------------*/
for(unsigned int i = 0; i < 3; i++)
{
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
Send(usb_buf);
}
// packets count sent: 8
/*-----------------------------------------*\
| Customization stuff |
| 9 times * 16 blocks 80 RR GG BB |
\*-----------------------------------------*/
unsigned char color_buf[COLOR_BUF_SIZE];
memset(color_buf, 0x00, COLOR_BUF_SIZE);
for(unsigned int i = 0; i < COLOR_BUF_SIZE; i += 4)
{
color_buf[i] = 0x80;
}
for(unsigned int c = 0; c < colors.size(); c++)
{
int offset = led_sequence_positions[c] * 4;
color_buf[offset + 1] = RGBGetRValue(colors[c]);
color_buf[offset + 2] = RGBGetGValue(colors[c]);
color_buf[offset + 3] = RGBGetBValue(colors[c]);
}
for(unsigned int p = 0; p < 9; p++)
{
memcpy(usb_buf, &color_buf[p * PACKET_DATA_LENGTH], PACKET_DATA_LENGTH);
Send(usb_buf);
}
// packets count sent: 17
/*-----------------------------------------*\
| Tells the device what the active mode is |
| This is the last packet |
\*-----------------------------------------*/
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
memcpy(usb_buf, &selected_mode[0], EFFECT_PAGE_LENGTH);
Send(usb_buf);
// packets count sent: 18 - let's hope the keyboard ACK in next frame
/*-----------------------------------------*\
| Tells the device that the pages are sent |
\*-----------------------------------------*/
EndCommunication();
/*-----------------------------------------*\
| Tells the device to apply what we've sent |
\*-----------------------------------------*/
StartEffectCommand();
}
void KeychronKeyboardController::StartEffectCommand()
{
unsigned char usb_buf[PACKET_DATA_LENGTH];
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
usb_buf[0x00] = PACKET_HEADER;
usb_buf[0x01] = LED_EFFECT_START_COMMAND;
Send(usb_buf);
}
void KeychronKeyboardController::StartEffectPage()
{
/*-----------------------------------------*\
| LED_SPECIAL_EFFECT_PACKETS: |
| Packet amount that will be sent in this |
| transaction |
\*-----------------------------------------*/
unsigned char usb_buf[PACKET_DATA_LENGTH];
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
usb_buf[0x00] = PACKET_HEADER;
usb_buf[0x01] = WRITE_LED_SPECIAL_EFFECT_AREA_COMMAND;
usb_buf[0x08] = LED_SPECIAL_EFFECT_PACKETS;
Send(usb_buf);
Read();
}
void KeychronKeyboardController::SetCustomization(bool state)
{
unsigned char usb_buf[PACKET_DATA_LENGTH];
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
usb_buf[0x00] = PACKET_HEADER;
usb_buf[0x01] = state ? TURN_ON_CUSTOMIZATION_COMMAND : TURN_OFF_CUSTOMIZATION_COMMAND;
Send(usb_buf);
Read();
}
void KeychronKeyboardController::EndCommunication()
{
unsigned char usb_buf[PACKET_DATA_LENGTH];
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
usb_buf[0x00] = PACKET_HEADER;
usb_buf[0x01] = COMMUNICATION_END_COMMAND;
Send(usb_buf);
Read();
}
void KeychronKeyboardController::Read()
{
unsigned char usb_buf[PACKET_DATA_LENGTH+1];
memset(usb_buf, 0x00, PACKET_DATA_LENGTH+1);
usb_buf[0x00] = REPORT_ID;
hid_get_feature_report(dev, usb_buf, PACKET_DATA_LENGTH+1);
std::this_thread::sleep_for(10ms);
}
void KeychronKeyboardController::Send(unsigned char data[PACKET_DATA_LENGTH])
{
unsigned char usb_buf[PACKET_DATA_LENGTH+1];
usb_buf[0] = REPORT_ID;
for(unsigned int x = 0; x < PACKET_DATA_LENGTH; x++)
{
usb_buf[x+1] = data[x];
}
hid_send_feature_report(dev, usb_buf, PACKET_DATA_LENGTH+1);
std::this_thread::sleep_for(10ms);
}
/*---------------------------------------------------------*\
| KeychronKeyboardController.cpp |
| |
| Driver for Keychron keyboard |
| |
| Morgan Guimard (morg) 20 Feb 2022 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include <string.h>
#include "KeychronKeyboardController.h"
#include "StringUtils.h"
using namespace std::chrono_literals;
KeychronKeyboardController::KeychronKeyboardController(hid_device* dev_handle, const hid_device_info& info, std::string dev_name)
{
dev = dev_handle;
location = info.path;
name = dev_name;
}
KeychronKeyboardController::~KeychronKeyboardController()
{
hid_close(dev);
}
std::string KeychronKeyboardController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string KeychronKeyboardController::GetNameString()
{
return(name);
}
std::string KeychronKeyboardController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
return(StringUtils::wstring_to_string(serial_string));
}
void KeychronKeyboardController:: SetLedSequencePositions(std::vector<unsigned int> positions)
{
led_sequence_positions = positions;
}
void KeychronKeyboardController::SetMode(std::vector<mode> modes, int active_mode, std::vector<RGBColor> colors)
{
/*-----------------------------------------*\
| Turn customization on/off |
| Custom mode needs to turn it on |
\*-----------------------------------------*/
SetCustomization(modes[active_mode].value == CUSTOM_MODE_VALUE);
/*-----------------------------------------*\
| Tells the device we're about to send the |
| pages (18 pages) |
\*-----------------------------------------*/
StartEffectPage();
unsigned char usb_buf[PACKET_DATA_LENGTH];
/*-----------------------------------------*\
| Configure the modes |
| LED Effect Page structure: |
| |
| OK.. this was from the original PDF |
| which appears to not be exact/up to date |
|-------------------------------------------|
| [0] Specialeffects mode1-32 |
| [1] colorFull color: 0x00 Monochrome:0x01 |
| [2] R Color ratio 0x00-0xFF |
| [3] G Color Ratio0x00-0xFF |
| [4] B Colour ratio0x00-0xFF |
| full color is 0,invalid |
| [5] dynamicdirection |
| left to right: 0x00 |
| right to left: 0x01 |
| down to up: 0x02 |
| up to down: 0x03 |
| [6] brightnesscontrol 0x00-0x0F |
| 0x0F brightest |
| [7] Periodiccontrol0x00-0x0F |
| 0x0F longest cycle |
| [8:13] Reserved |
| [14] Checkcode_L0xAA |
| [15] Checkcode_H0x55 |
|-------------------------------------------|
| Fixes: |
| color mode is 8th byte |
| brightness is 9th byte |
| speed is 10th byte |
| direction is 11th byte |
\*-----------------------------------------*/
unsigned char selected_mode[EFFECT_PAGE_LENGTH];
for(unsigned int i = 0; i < 5; i++) // 5 packets
{
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
for(unsigned int j = 0; j < 4; j++) // of 4 effects
{
const mode& m = modes[1 + j + i * 4]; // skip 1 first mode (Custom)
int offset = j * EFFECT_PAGE_LENGTH;
usb_buf[offset + 0] = m.value; // mode value
if(m.flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
{
usb_buf[offset + 1] = RGBGetRValue(m.colors[0]);
usb_buf[offset + 2] = RGBGetGValue(m.colors[0]);
usb_buf[offset + 3] = RGBGetBValue(m.colors[0]);
}
usb_buf[offset + 8] = m.color_mode == MODE_COLORS_RANDOM; // random switch
usb_buf[offset + 9] = m.brightness;
usb_buf[offset + 10] = m.speed;
usb_buf[offset + 11] = m.direction;
usb_buf[offset + 14] = EFFECT_PAGE_CHECK_CODE_L;
usb_buf[offset + 15] = EFFECT_PAGE_CHECK_CODE_H;
/*-----------------------------------------*\
| Backup active mode values for later use |
| Custom and off share the same mode value |
\*-----------------------------------------*/
if(m.value == modes[active_mode].value || (m.value == LIGHTS_OFF_MODE_VALUE && modes[active_mode].value == CUSTOM_MODE_VALUE))
{
usb_buf[offset + 9] = modes[active_mode].brightness;
for(unsigned int x = 0; x < EFFECT_PAGE_LENGTH; x++)
{
selected_mode[x] = usb_buf[offset+x];
}
}
}
Send(usb_buf); // Sends the packet
}
// packets count sent: 5
/*-----------------------------------------*\
| 3 times an empty packet - guess why... |
\*-----------------------------------------*/
for(unsigned int i = 0; i < 3; i++)
{
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
Send(usb_buf);
}
// packets count sent: 8
/*-----------------------------------------*\
| Customization stuff |
| 9 times * 16 blocks 80 RR GG BB |
\*-----------------------------------------*/
unsigned char color_buf[COLOR_BUF_SIZE];
memset(color_buf, 0x00, COLOR_BUF_SIZE);
for(unsigned int i = 0; i < COLOR_BUF_SIZE; i += 4)
{
color_buf[i] = 0x80;
}
for(unsigned int c = 0; c < colors.size(); c++)
{
int offset = led_sequence_positions[c] * 4;
color_buf[offset + 1] = RGBGetRValue(colors[c]);
color_buf[offset + 2] = RGBGetGValue(colors[c]);
color_buf[offset + 3] = RGBGetBValue(colors[c]);
}
for(unsigned int p = 0; p < 9; p++)
{
memcpy(usb_buf, &color_buf[p * PACKET_DATA_LENGTH], PACKET_DATA_LENGTH);
Send(usb_buf);
}
// packets count sent: 17
/*-----------------------------------------*\
| Tells the device what the active mode is |
| This is the last packet |
\*-----------------------------------------*/
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
memcpy(usb_buf, &selected_mode[0], EFFECT_PAGE_LENGTH);
Send(usb_buf);
// packets count sent: 18 - let's hope the keyboard ACK in next frame
/*-----------------------------------------*\
| Tells the device that the pages are sent |
\*-----------------------------------------*/
EndCommunication();
/*-----------------------------------------*\
| Tells the device to apply what we've sent |
\*-----------------------------------------*/
StartEffectCommand();
}
void KeychronKeyboardController::StartEffectCommand()
{
unsigned char usb_buf[PACKET_DATA_LENGTH];
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
usb_buf[0x00] = PACKET_HEADER;
usb_buf[0x01] = LED_EFFECT_START_COMMAND;
Send(usb_buf);
}
void KeychronKeyboardController::StartEffectPage()
{
/*-----------------------------------------*\
| LED_SPECIAL_EFFECT_PACKETS: |
| Packet amount that will be sent in this |
| transaction |
\*-----------------------------------------*/
unsigned char usb_buf[PACKET_DATA_LENGTH];
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
usb_buf[0x00] = PACKET_HEADER;
usb_buf[0x01] = WRITE_LED_SPECIAL_EFFECT_AREA_COMMAND;
usb_buf[0x08] = LED_SPECIAL_EFFECT_PACKETS;
Send(usb_buf);
Read();
}
void KeychronKeyboardController::SetCustomization(bool state)
{
unsigned char usb_buf[PACKET_DATA_LENGTH];
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
usb_buf[0x00] = PACKET_HEADER;
usb_buf[0x01] = state ? TURN_ON_CUSTOMIZATION_COMMAND : TURN_OFF_CUSTOMIZATION_COMMAND;
Send(usb_buf);
Read();
}
void KeychronKeyboardController::EndCommunication()
{
unsigned char usb_buf[PACKET_DATA_LENGTH];
memset(usb_buf, 0x00, PACKET_DATA_LENGTH);
usb_buf[0x00] = PACKET_HEADER;
usb_buf[0x01] = COMMUNICATION_END_COMMAND;
Send(usb_buf);
Read();
}
void KeychronKeyboardController::Read()
{
unsigned char usb_buf[PACKET_DATA_LENGTH+1];
memset(usb_buf, 0x00, PACKET_DATA_LENGTH+1);
usb_buf[0x00] = REPORT_ID;
hid_get_feature_report(dev, usb_buf, PACKET_DATA_LENGTH+1);
std::this_thread::sleep_for(10ms);
}
void KeychronKeyboardController::Send(unsigned char data[PACKET_DATA_LENGTH])
{
unsigned char usb_buf[PACKET_DATA_LENGTH+1];
usb_buf[0] = REPORT_ID;
for(unsigned int x = 0; x < PACKET_DATA_LENGTH; x++)
{
usb_buf[x+1] = data[x];
}
hid_send_feature_report(dev, usb_buf, PACKET_DATA_LENGTH+1);
std::this_thread::sleep_for(10ms);
}
@@ -1,120 +1,120 @@
/*---------------------------------------------------------*\
| KeychronKeyboardController.h |
| |
| Driver for Keychron keyboard |
| |
| Morgan Guimard (morg) 20 Feb 2022 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include <string>
#include <hidapi.h>
#define REPORT_ID 0x00
#define PACKET_DATA_LENGTH 64
#define COLOR_BUF_SIZE 576
#define EFFECT_PAGE_LENGTH 16
#define LED_SPECIAL_EFFECT_PACKETS 0x12
#define PACKET_HEADER 0x04
#define EFFECT_PAGE_CHECK_CODE_L 0xAA
#define EFFECT_PAGE_CHECK_CODE_H 0x55
/*-----------------------------------------*\
| Commands |
\*-----------------------------------------*/
enum
{
COMMUNICATION_END_COMMAND = 0x02,
GET_BASIC_INFO_COMMAND = 0x05,
READ_KEY_DEFINITION_AREA_COMMAND = 0x10,
WRITE_KEY_DEFINITION_AREA_COMMAND = 0x11,
READ_LED_EFFECT_DEFINITION_AREA_COMMAND = 0x12,
WRITE_LED_SPECIAL_EFFECT_AREA_COMMAND = 0x13,
READ_MACRO_DEFINITION_AREA_COMMAND = 0x14,
WRITE_MACRO_DEFINITION_AREA_COMMAND = 0x15,
READ_GAME_MODE_AREA_COMMAND = 0x16,
WRITE_GAME_MODE_AREA_COMMAND = 0x17,
TURN_ON_CUSTOMIZATION_COMMAND = 0x18,
TURN_OFF_CUSTOMIZATION_COMMAND = 0x19,
LED_EFFECT_START_COMMAND = 0xF0,
LED_SYNC_INITIAL_COMMAND = 0xF1,
LED_SYNC_START_COMMAND = 0xF2,
LED_SYNC_STOP_COMMAND = 0xF3,
RANDOM_PACKET_START_COMMAND = 0xAB,
};
/*-----------------------------------------*\
| Modes |
\*-----------------------------------------*/
enum
{
CUSTOM_MODE_VALUE = 0x00,
STATIC_MODE_VALUE = 0x01,
KEYSTROKE_LIGHT_UP_MODE_VALUE = 0x02,
KEYSTROKE_DIM_MODE_VALUE = 0x03,
SPARKLE_MODE_VALUE = 0x04,
RAIN_MODE_VALUE = 0x05,
RANDOM_COLORS_MODE_VALUE = 0x06,
BREATHING_MODE_VALUE = 0x07,
SPECTRUM_CYCLE_MODE_VALUE = 0x08,
RING_GRADIENT_MODE_VALUE = 0x09,
VERTICAL_GRADIENT_MODE_VALUE = 0x0A,
HORIZONTAL_GRADIENT_WAVE_MODE_VALUE = 0x0B,
AROUND_EDGES_MODE_VALUE = 0x0C,
KEYSTROKE_HORIZONTAL_LINES_VALUE = 0x0D,
KEYSTROKE_TITLED_LINES_MODE_VALUE = 0x0E,
KEYSTROKE_RIPPLES_MODE_VALUE = 0x0F,
SEQUENCE_MODE_VALUE = 0x10,
WAVE_LINE_MODE_VALUE = 0x11,
TILTED_LINES_MODE_VALUE = 0x12,
BACK_AND_FORTH_MODE_VALUE = 0x13,
LIGHTS_OFF_MODE_VALUE = 0x80,
};
/*-----------------------------------------*\
| Other settings |
\*-----------------------------------------*/
enum
{
KEYCHRON_MIN_SPEED = 0x00,
KEYCHRON_MAX_SPEED = 0x0F,
KEYCHRON_MIN_BRIGHTNESS = 0x00,
KEYCHRON_MAX_BRIGHTNESS = 0x0F,
};
class KeychronKeyboardController
{
public:
KeychronKeyboardController(hid_device* dev_handle, const hid_device_info& info, std::string dev_name);
~KeychronKeyboardController();
std::string GetDeviceLocation();
std::string GetNameString();
std::string GetSerialString();
void SetLedSequencePositions(std::vector<unsigned int> positions);
void SetMode(std::vector<mode> modes, int active_mode, std::vector<RGBColor> colors);
protected:
hid_device* dev;
private:
std::string location;
std::string name;
std::string version;
std::vector<unsigned int> led_sequence_positions;
void SetCustomization(bool state);
void StartEffectPage();
void StartEffectCommand();
void EndCommunication();
void Read();
void Send(unsigned char data[PACKET_DATA_LENGTH]);
};
/*---------------------------------------------------------*\
| KeychronKeyboardController.h |
| |
| Driver for Keychron keyboard |
| |
| Morgan Guimard (morg) 20 Feb 2022 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include <string>
#include <hidapi.h>
#define REPORT_ID 0x00
#define PACKET_DATA_LENGTH 64
#define COLOR_BUF_SIZE 576
#define EFFECT_PAGE_LENGTH 16
#define LED_SPECIAL_EFFECT_PACKETS 0x12
#define PACKET_HEADER 0x04
#define EFFECT_PAGE_CHECK_CODE_L 0xAA
#define EFFECT_PAGE_CHECK_CODE_H 0x55
/*-----------------------------------------*\
| Commands |
\*-----------------------------------------*/
enum
{
COMMUNICATION_END_COMMAND = 0x02,
GET_BASIC_INFO_COMMAND = 0x05,
READ_KEY_DEFINITION_AREA_COMMAND = 0x10,
WRITE_KEY_DEFINITION_AREA_COMMAND = 0x11,
READ_LED_EFFECT_DEFINITION_AREA_COMMAND = 0x12,
WRITE_LED_SPECIAL_EFFECT_AREA_COMMAND = 0x13,
READ_MACRO_DEFINITION_AREA_COMMAND = 0x14,
WRITE_MACRO_DEFINITION_AREA_COMMAND = 0x15,
READ_GAME_MODE_AREA_COMMAND = 0x16,
WRITE_GAME_MODE_AREA_COMMAND = 0x17,
TURN_ON_CUSTOMIZATION_COMMAND = 0x18,
TURN_OFF_CUSTOMIZATION_COMMAND = 0x19,
LED_EFFECT_START_COMMAND = 0xF0,
LED_SYNC_INITIAL_COMMAND = 0xF1,
LED_SYNC_START_COMMAND = 0xF2,
LED_SYNC_STOP_COMMAND = 0xF3,
RANDOM_PACKET_START_COMMAND = 0xAB,
};
/*-----------------------------------------*\
| Modes |
\*-----------------------------------------*/
enum
{
CUSTOM_MODE_VALUE = 0x00,
STATIC_MODE_VALUE = 0x01,
KEYSTROKE_LIGHT_UP_MODE_VALUE = 0x02,
KEYSTROKE_DIM_MODE_VALUE = 0x03,
SPARKLE_MODE_VALUE = 0x04,
RAIN_MODE_VALUE = 0x05,
RANDOM_COLORS_MODE_VALUE = 0x06,
BREATHING_MODE_VALUE = 0x07,
SPECTRUM_CYCLE_MODE_VALUE = 0x08,
RING_GRADIENT_MODE_VALUE = 0x09,
VERTICAL_GRADIENT_MODE_VALUE = 0x0A,
HORIZONTAL_GRADIENT_WAVE_MODE_VALUE = 0x0B,
AROUND_EDGES_MODE_VALUE = 0x0C,
KEYSTROKE_HORIZONTAL_LINES_VALUE = 0x0D,
KEYSTROKE_TITLED_LINES_MODE_VALUE = 0x0E,
KEYSTROKE_RIPPLES_MODE_VALUE = 0x0F,
SEQUENCE_MODE_VALUE = 0x10,
WAVE_LINE_MODE_VALUE = 0x11,
TILTED_LINES_MODE_VALUE = 0x12,
BACK_AND_FORTH_MODE_VALUE = 0x13,
LIGHTS_OFF_MODE_VALUE = 0x80,
};
/*-----------------------------------------*\
| Other settings |
\*-----------------------------------------*/
enum
{
KEYCHRON_MIN_SPEED = 0x00,
KEYCHRON_MAX_SPEED = 0x0F,
KEYCHRON_MIN_BRIGHTNESS = 0x00,
KEYCHRON_MAX_BRIGHTNESS = 0x0F,
};
class KeychronKeyboardController
{
public:
KeychronKeyboardController(hid_device* dev_handle, const hid_device_info& info, std::string dev_name);
~KeychronKeyboardController();
std::string GetDeviceLocation();
std::string GetNameString();
std::string GetSerialString();
void SetLedSequencePositions(std::vector<unsigned int> positions);
void SetMode(std::vector<mode> modes, int active_mode, std::vector<RGBColor> colors);
protected:
hid_device* dev;
private:
std::string location;
std::string name;
std::string version;
std::vector<unsigned int> led_sequence_positions;
void SetCustomization(bool state);
void StartEffectPage();
void StartEffectCommand();
void EndCommunication();
void Read();
void Send(unsigned char data[PACKET_DATA_LENGTH]);
};
@@ -1,39 +1,39 @@
/*---------------------------------------------------------*\
| KeychronKeyboardControllerDetect.cpp |
| |
| Detector for Keychron keyboard |
| |
| Morgan Guimard (morg) 20 Feb 2022 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "Detector.h"
#include "KeychronKeyboardController.h"
#include "RGBController_KeychronKeyboard.h"
/*---------------------------------------------------------*\
| KeychronKeyboard vendor ID |
\*---------------------------------------------------------*/
#define KEYCHRON_KEYBOARD_VID 0x05AC
/*---------------------------------------------------------*\
| Product ID |
\*---------------------------------------------------------*/
#define KEYCHRON_K3_V2_OPTICAL_RGB_PID 0x024F
void DetectKeychronKeyboardControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
KeychronKeyboardController* controller = new KeychronKeyboardController(dev, *info, name);
RGBController_KeychronKeyboard* rgb_controller = new RGBController_KeychronKeyboard(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR_IPU("Keychron Gaming Keyboard 1", DetectKeychronKeyboardControllers, KEYCHRON_KEYBOARD_VID, KEYCHRON_K3_V2_OPTICAL_RGB_PID, 0, 0x0001, 0x06);
/*---------------------------------------------------------*\
| KeychronKeyboardControllerDetect.cpp |
| |
| Detector for Keychron keyboard |
| |
| Morgan Guimard (morg) 20 Feb 2022 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#include "Detector.h"
#include "KeychronKeyboardController.h"
#include "RGBController_KeychronKeyboard.h"
/*---------------------------------------------------------*\
| KeychronKeyboard vendor ID |
\*---------------------------------------------------------*/
#define KEYCHRON_KEYBOARD_VID 0x05AC
/*---------------------------------------------------------*\
| Product ID |
\*---------------------------------------------------------*/
#define KEYCHRON_K3_V2_OPTICAL_RGB_PID 0x024F
void DetectKeychronKeyboardControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
KeychronKeyboardController* controller = new KeychronKeyboardController(dev, *info, name);
RGBController_KeychronKeyboard* rgb_controller = new RGBController_KeychronKeyboard(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR_IPU("Keychron Gaming Keyboard 1", DetectKeychronKeyboardControllers, KEYCHRON_KEYBOARD_VID, KEYCHRON_K3_V2_OPTICAL_RGB_PID, 0, 0x0001, 0x06);
File diff suppressed because it is too large. Load diff
@@ -1,34 +1,34 @@
/*---------------------------------------------------------*\
| RGBController_KeychronKeyboard.h |
| |
| RGBController for Keychron keyboard |
| |
| Morgan Guimard (morg) 20 Feb 2022 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "KeychronKeyboardController.h"
class RGBController_KeychronKeyboard : public RGBController
{
public:
RGBController_KeychronKeyboard(KeychronKeyboardController* controller_ptr);
~RGBController_KeychronKeyboard();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
private:
KeychronKeyboardController* controller;
};
/*---------------------------------------------------------*\
| RGBController_KeychronKeyboard.h |
| |
| RGBController for Keychron keyboard |
| |
| Morgan Guimard (morg) 20 Feb 2022 |
| |
| This file is part of the OpenRGB project |
| SPDX-License-Identifier: GPL-2.0-or-later |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "KeychronKeyboardController.h"
class RGBController_KeychronKeyboard : public RGBController
{
public:
RGBController_KeychronKeyboard(KeychronKeyboardController* controller_ptr);
~RGBController_KeychronKeyboard();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
private:
KeychronKeyboardController* controller;
};