diff --git a/Controllers/CherryKeyboardController/CherryKeyboardController.cpp b/Controllers/CherryKeyboardController/CherryKeyboardController.cpp new file mode 100644 index 00000000..d9f36b74 --- /dev/null +++ b/Controllers/CherryKeyboardController/CherryKeyboardController.cpp @@ -0,0 +1,262 @@ +/*-----------------------------------------*\ +| CherryKeyboardController.cpp | +| | +| Driver for Cherry RGB keyboard lighting | +| controller | +| | +| Sebastian Kraus 12/25/2021 | +\*-----------------------------------------*/ + +#include "CherryKeyboardController.h" + +#include + +CherryKeyboardController::CherryKeyboardController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; +} + +CherryKeyboardController::~CherryKeyboardController() +{ + hid_close(dev); +} + +std::string CherryKeyboardController::GetDeviceLocation() +{ + return("HID: " + location); +} + +std::string CherryKeyboardController::GetSerialString() +{ + wchar_t serial_string[128]; + int ret = hid_get_serial_number_string(dev, serial_string, 128); + + if(ret != 0) + { + return(""); + } + + std::wstring return_wstring = serial_string; + std::string return_string(return_wstring.begin(), return_wstring.end()); + + return(return_string); +} + +void CherryKeyboardController::SetKeyboardColors + ( + unsigned char * color_data, + unsigned int size + ) +{ + unsigned int packet_size = 0; + unsigned int packet_offset = 0; + + while(size > 0) + { + if(size >= CHERRY_KB_MAX_PACKET_SIZE) + { + packet_size = CHERRY_KB_MAX_PACKET_SIZE; + } + else + { + packet_size = size; + } + + SendKeyboardData + ( + &color_data[packet_offset], + packet_size, + packet_offset + ); + + size -= packet_size; + packet_offset += packet_size; + } +} + +void CherryKeyboardController::SendKeyboardMode + ( + unsigned char mode + ) +{ + SendKeyboardParameter(CHERRY_KB_PARAMETER_MODE, 1, &mode); +} + +void CherryKeyboardController::SendKeyboardModeEx + ( + unsigned char mode, + unsigned char brightness, + unsigned char speed, + unsigned char direction, + unsigned char random_flag, + unsigned char red, + unsigned char green, + unsigned char blue + ) +{ + unsigned char parameter_data[8]; + + parameter_data[0] = mode; + parameter_data[1] = brightness; + parameter_data[2] = speed; + parameter_data[3] = direction; + parameter_data[4] = random_flag; + parameter_data[5] = red; + parameter_data[6] = green; + parameter_data[7] = blue; + + SendKeyboardParameter(0, 8, parameter_data); +} + +/*-------------------------------------------------------------------------------------------------*\ +| Private packet sending functions. | +\*-------------------------------------------------------------------------------------------------*/ + +void CherryKeyboardController::ComputeChecksum + ( + char usb_buf[CHERRY_KB_PACKET_SIZE] + ) +{ + unsigned short checksum = 0; + + for(unsigned int byte_idx = 0x03; byte_idx < CHERRY_KB_PACKET_SIZE; byte_idx++) + { + checksum += usb_buf[byte_idx]; + } + + usb_buf[0x01] = checksum & 0xFF; + usb_buf[0x02] = checksum >> 8; +} + +void CherryKeyboardController::SendKeyboardBegin() +{ + unsigned char usb_buf[CHERRY_KB_PACKET_SIZE]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up Keyboard Begin (0x01) packet | + | Note: Not computing checksum as packet contents are | + | fixed | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x04; + usb_buf[0x01] = CHERRY_KB_COMMAND_BEGIN; + usb_buf[0x02] = 0x00; + usb_buf[0x03] = CHERRY_KB_COMMAND_BEGIN; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_write(dev, usb_buf, CHERRY_KB_PACKET_SIZE); + hid_read(dev, usb_buf, CHERRY_KB_PACKET_SIZE); +} + +void CherryKeyboardController::SendKeyboardEnd() +{ + char usb_buf[CHERRY_KB_PACKET_SIZE]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up Keyboard End (0x02) packet | + | Note: Not computing checksum as packet contents are | + | fixed | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x04; + usb_buf[0x01] = CHERRY_KB_COMMAND_END; + usb_buf[0x02] = 0x00; + usb_buf[0x03] = CHERRY_KB_COMMAND_END; + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_write(dev, (unsigned char *)usb_buf, CHERRY_KB_PACKET_SIZE); + hid_read(dev, (unsigned char *)usb_buf, CHERRY_KB_PACKET_SIZE); +} + +void CherryKeyboardController::SendKeyboardData + ( + unsigned char * data, + unsigned char data_size, + unsigned short data_offset + ) +{ + char usb_buf[CHERRY_KB_PACKET_SIZE]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up Keyboard Color Data (0x0B) packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x04; + usb_buf[0x03] = CHERRY_KB_COMMAND_WRITE_CUSTOM_COLOR_DATA; + + usb_buf[0x04] = data_size; + usb_buf[0x05] = data_offset & 0x00FF; + usb_buf[0x06] = data_offset >> 8; + + /*-----------------------------------------------------*\ + | Copy in data bytes | + \*-----------------------------------------------------*/ + memcpy(&usb_buf[0x08], data, data_size); + + /*-----------------------------------------------------*\ + | Compute Checksum | + \*-----------------------------------------------------*/ + ComputeChecksum(usb_buf); + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_write(dev, (unsigned char *)usb_buf, CHERRY_KB_PACKET_SIZE); + hid_read(dev, (unsigned char *)usb_buf, CHERRY_KB_PACKET_SIZE); +} + +void CherryKeyboardController::SendKeyboardParameter + ( + unsigned char parameter, + unsigned char parameter_size, + unsigned char* parameter_data + ) +{ + char usb_buf[CHERRY_KB_PACKET_SIZE]; + + /*-----------------------------------------------------*\ + | Zero out buffer | + \*-----------------------------------------------------*/ + memset(usb_buf, 0x00, sizeof(usb_buf)); + + /*-----------------------------------------------------*\ + | Set up Keyboard Parameter (0x06) packet | + \*-----------------------------------------------------*/ + usb_buf[0x00] = 0x04; + usb_buf[0x03] = CHERRY_KB_COMMAND_SET_PARAMETER; + usb_buf[0x04] = parameter_size; + usb_buf[0x05] = parameter; + + /*-----------------------------------------------------*\ + | Copy in data bytes | + \*-----------------------------------------------------*/ + memcpy(&usb_buf[0x09], parameter_data, parameter_size); + + /*-----------------------------------------------------*\ + | Compute Checksum | + \*-----------------------------------------------------*/ + ComputeChecksum(usb_buf); + + /*-----------------------------------------------------*\ + | Send packet | + \*-----------------------------------------------------*/ + hid_write(dev, (unsigned char *)usb_buf, CHERRY_KB_PACKET_SIZE); + hid_read(dev, (unsigned char *)usb_buf, CHERRY_KB_PACKET_SIZE); +} diff --git a/Controllers/CherryKeyboardController/CherryKeyboardController.h b/Controllers/CherryKeyboardController/CherryKeyboardController.h new file mode 100644 index 00000000..b1212abb --- /dev/null +++ b/Controllers/CherryKeyboardController/CherryKeyboardController.h @@ -0,0 +1,150 @@ +/*-----------------------------------------*\ +| CherryKeyboardController.h | +| | +| Definitions and types for Cherry RGB | +| keyboard lighting controller | +| | +| Sebastian Kraus 12/25/2021 | +\*-----------------------------------------*/ + +#include "RGBController.h" + +#include +#include + +#pragma once + +#define CHERRY_KB_PACKET_SIZE 64 +#define CHERRY_KB_MAX_PACKET_SIZE ( 0x36 )/* max packet size for color*/ + /* update packets */ +enum +{ + CHERRY_KB_COMMAND_BEGIN = 0x01, /* Begin packet command */ + CHERRY_KB_COMMAND_END = 0x02, /* End packet command */ + CHERRY_KB_COMMAND_SET_PARAMETER = 0x06, /* Set parameter command */ + CHERRY_KB_COMMAND_READ_CUSTOM_COLOR_DATA = 0x1B, /* Read custom color data */ + CHERRY_KB_COMMAND_WRITE_CUSTOM_COLOR_DATA = 0x0B, /* Write custom color data */ +}; + +enum +{ + CHERRY_KB_PARAMETER_MODE = 0x00, /* Mode parameter */ + CHERRY_KB_PARAMETER_BRIGHTNESS = 0x01, /* Brightness parameter */ + CHERRY_KB_PARAMETER_SPEED = 0x02, /* Speed parameter */ + CHERRY_KB_PARAMETER_DIRECTION = 0x03, /* Direction parameter */ + CHERRY_KB_PARAMETER_RANDOM_COLOR_FLAG = 0x04, /* Random color parameter */ + CHERRY_KB_PARAMETER_MODE_COLOR = 0x05, /* Mode color (RGB) */ + CHERRY_KB_PARAMETER_POLLING_RATE = 0x0F, /* Polling rate */ + CHERRY_KB_PARAMETER_SURMOUNT_MODE_COLOR = 0x11, /* Surmount mode color */ +}; + +enum +{ + CHERRY_KB_MODE_WAVE = 0x00, + CHERRY_KB_MODE_SPECTRUM = 0x01, + CHERRY_KB_MODE_BREATHING = 0x02, + CHERRY_KB_MODE_STATIC = 0x03, + CHERRY_KB_MODE_RADAR = 0x04, + CHERRY_KB_MODE_VORTEX = 0x05, + CHERRY_KB_MODE_FIRE = 0x06, + CHERRY_KB_MODE_STARS = 0x07, + CHERRY_KB_MODE_CUSTOM = 0x08, + CHERRY_KB_MODE_ROLLING = 0x0A, + CHERRY_KB_MODE_RAIN = 0x0B, + CHERRY_KB_MODE_CURVE = 0x0C, + CHERRY_KB_MODE_WAVE_MID = 0x0E, + CHERRY_KB_MODE_SCAN = 0x0F, + CHERRY_KB_MODE_RADIATION = 0x12, + CHERRY_KB_MODE_RIPPLES = 0x13, + CHERRY_KB_MODE_SINGLE_KEY = 0x15, + +}; + +enum +{ + CHERRY_KB_BRIGHTNESS_LOWEST = 0x00, /* Lowest brightness (off) */ + CHERRY_KB_BRIGHTNESS_HIGHEST = 0x04, /* Highest brightness */ +}; + +enum +{ + CHERRY_KB_SPEED_SLOWEST = 0x04, /* Slowest speed setting */ + CHERRY_KB_SPEED_NORMAL = 0x02, /* Normal speed setting */ + CHERRY_KB_SPEED_FASTEST = 0x00, /* Fastest speed setting */ +}; + +enum +{ + CHERRY_KB_SURMOUNT_MODE_COLOR_RED = 0x01, /* Red surmount color */ + CHERRY_KB_SURMOUNT_MODE_COLOR_YELLOW = 0x02, /* Yellow surmount color */ + CHERRY_KB_SURMOUNT_MODE_COLOR_GREEN = 0x03, /* Green surmount color */ + CHERRY_KB_SURMOUNT_MODE_COLOR_BLUE = 0x04, /* Blue surmount color */ +}; + +enum +{ + CHERRY_KB_POLLING_RATE_125HZ = 0x00, /* 125Hz polling rate */ + CHERRY_KB_POLLING_RATE_250HZ = 0x01, /* 250Hz polling rate */ + CHERRY_KB_POLLING_RATE_500HZ = 0x02, /* 500Hz polling rate */ + CHERRY_KB_POLLING_RATE_1000HZ = 0x03, /* 1000Hz polling rate */ +}; + +class CherryKeyboardController +{ +public: + CherryKeyboardController(hid_device* dev_handle, const char* path); + ~CherryKeyboardController(); + + std::string GetDeviceLocation(); + std::string GetSerialString(); + + void SetKeyboardColors + ( + unsigned char * color_data, + unsigned int size + ); + + void SendKeyboardBegin(); + + void SendKeyboardMode + ( + unsigned char mode + ); + + void SendKeyboardModeEx + ( + unsigned char mode, + unsigned char brightness, + unsigned char speed, + unsigned char direction, + unsigned char random_flag, + unsigned char red, + unsigned char green, + unsigned char blue + ); + + void SendKeyboardData + ( + unsigned char * data, + unsigned char data_size, + unsigned short data_offset + ); + + void SendKeyboardEnd(); + +private: + hid_device* dev; + std::string location; + + void ComputeChecksum + ( + char usb_buf[CHERRY_KB_PACKET_SIZE] + ); + + void SendKeyboardParameter + ( + unsigned char parameter, + unsigned char parameter_size, + unsigned char* parameter_data + ); +}; diff --git a/Controllers/CherryKeyboardController/CherryKeyboardControllerDetect.cpp b/Controllers/CherryKeyboardController/CherryKeyboardControllerDetect.cpp new file mode 100644 index 00000000..bf38fcf8 --- /dev/null +++ b/Controllers/CherryKeyboardController/CherryKeyboardControllerDetect.cpp @@ -0,0 +1,43 @@ +#include "Detector.h" +#include "CherryKeyboardController.h" +#include "RGBController.h" +#include "RGBController_CherryKeyboard.h" +#include +#include + +/*-----------------------------------------------------*\ +| Keyboard product IDs | +\*-----------------------------------------------------*/ +#define CHERRY_KEYBOARD_VID 0x046A +#define CHERRY_KEYBOARD_USAGE_PAGE 0xFF1C +#define G30_8000N_PID 0x00DD + +/******************************************************************************************\ +* * +* DetectCherryKeyboards * +* * +* Tests the USB address to see if an Cherry RGB Keyboard controller exists there. * +* * +\******************************************************************************************/ + +void DetectCherryKeyboards(hid_device_info* info, const std::string& name) +{ + hid_device* dev = hid_open_path(info->path); + if( dev ) + { + CherryKeyboardController* controller = new CherryKeyboardController(dev, info->path); + RGBController_CherryKeyboard* rgb_controller = new RGBController_CherryKeyboard(controller); + rgb_controller->name = name; + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + +/*---------------------------------------------------------------------------------------------------------------------------------------------*\ +| Keyboards | +\*---------------------------------------------------------------------------------------------------------------------------------------------*/ +REGISTER_HID_DETECTOR_IP("Cherry Keyboard G80-3000N RGB TKL", DetectCherryKeyboards, CHERRY_KEYBOARD_VID, G30_8000N_PID, 1, CHERRY_KEYBOARD_USAGE_PAGE); +/*---------------------------------------------------------------------------------------------------------*\ +| Entries for dynamic UDEV rules | +| | +| DUMMY_DEVICE_DETECTOR("Cherry Keyboard G80-3000N RGB TKL", DetectCherryKeyboards, 0x046a, 0x00dd ) | +\*---------------------------------------------------------------------------------------------------------*/ \ No newline at end of file diff --git a/Controllers/CherryKeyboardController/RGBController_CherryKeyboard.cpp b/Controllers/CherryKeyboardController/RGBController_CherryKeyboard.cpp new file mode 100644 index 00000000..b594e1ed --- /dev/null +++ b/Controllers/CherryKeyboardController/RGBController_CherryKeyboard.cpp @@ -0,0 +1,347 @@ +/*-----------------------------------------*\ +| RGBController_CherryKeyboard.cpp | +| | +| Generic RGB Interface for Cherry RGB | +| Keyboard | +| | +| Sebastian Kraus 12/25/2021 | +\*-----------------------------------------*/ + +#include "RGBController_CherryKeyboard.h" + +//0xFFFFFFFF indicates an unused entry in matrix +#define NA 0xFFFFFFFF + +static unsigned int matrix_map[6][23] = + { { 0, NA, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, NA, NA, NA, NA, NA, NA }, + { 1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 85, 91, 97, NA, NA, NA, NA, NA, NA }, + { 2, 8, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, NA, 86, 92, 98, NA, NA, NA, NA, NA, NA }, + { 3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, NA, NA, NA, NA, NA, NA, NA, NA, NA }, + { 4, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70, NA, 82, NA, 94, NA, NA, NA, NA, NA, NA, NA }, + { 5, 11, 17, NA, NA, NA, 41, NA, NA, NA, 65, 71, 77, 83, 89, 95, 101, NA, NA, NA, NA, NA, NA } }; + +RGBController_CherryKeyboard::RGBController_CherryKeyboard(CherryKeyboardController* controller_ptr) +{ + controller = controller_ptr; + + name = "Cherry Keyboard Device"; + vendor = "Cherry"; + type = DEVICE_TYPE_KEYBOARD; + description = "Cherry Keyboard Device"; + location = controller->GetDeviceLocation(); + serial = controller->GetSerialString(); + + mode Custom; + Custom.name = "Custom"; + Custom.value = CHERRY_KB_MODE_CUSTOM; + Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + Custom.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Custom); + + mode Wave; + Wave.name = "Wave"; + Wave.value = CHERRY_KB_MODE_WAVE; + Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + Wave.speed_min = CHERRY_KB_SPEED_SLOWEST; + Wave.speed_max = CHERRY_KB_SPEED_FASTEST; + Wave.speed = CHERRY_KB_SPEED_NORMAL; + Wave.colors_min = 1; + Wave.colors_max = 1; + Wave.color_mode = MODE_COLORS_MODE_SPECIFIC; + Wave.colors.resize(1); + modes.push_back(Wave); + + mode Spectrum; + Spectrum.name = "Spectrum"; + Spectrum.value = CHERRY_KB_MODE_SPECTRUM; + Spectrum.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE; + Spectrum.speed_min = CHERRY_KB_SPEED_SLOWEST; + Spectrum.speed_max = CHERRY_KB_SPEED_FASTEST; + Spectrum.speed = CHERRY_KB_SPEED_NORMAL; + Spectrum.color_mode = MODE_COLORS_NONE; + Spectrum.colors.resize(1); + modes.push_back(Spectrum); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = CHERRY_KB_MODE_BREATHING; + Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + Breathing.speed_min = CHERRY_KB_SPEED_SLOWEST; + Breathing.speed_max = CHERRY_KB_SPEED_FASTEST; + Breathing.speed = CHERRY_KB_SPEED_NORMAL; + Breathing.colors_min = 1; + Breathing.colors_max = 1; + Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC; + Breathing.colors.resize(1); + modes.push_back(Breathing); + + mode Static; + Static.name = "Static"; + Static.value = CHERRY_KB_MODE_STATIC; + Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + Static.colors_min = 1; + Static.colors_max = 1; + Static.color_mode = MODE_COLORS_MODE_SPECIFIC; + Static.colors.resize(1); + modes.push_back(Static); + + mode Radar; + Radar.name = "Radar"; + Radar.value = CHERRY_KB_MODE_RADAR; + Radar.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + Radar.speed_min = CHERRY_KB_SPEED_SLOWEST; + Radar.speed_max = CHERRY_KB_SPEED_FASTEST; + Radar.speed = CHERRY_KB_SPEED_NORMAL; + Radar.colors_min = 1; + Radar.colors_max = 1; + Radar.color_mode = MODE_COLORS_MODE_SPECIFIC; + Radar.colors.resize(1); + modes.push_back(Radar); + + mode Vortex; + Vortex.name = "Vortex"; + Vortex.value = CHERRY_KB_MODE_VORTEX; + Vortex.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + Vortex.speed_min = CHERRY_KB_SPEED_SLOWEST; + Vortex.speed_max = CHERRY_KB_SPEED_FASTEST; + Vortex.speed = CHERRY_KB_SPEED_NORMAL; + Vortex.colors_min = 1; + Vortex.colors_max = 1; + Vortex.color_mode = MODE_COLORS_MODE_SPECIFIC; + Vortex.colors.resize(1); + modes.push_back(Vortex); + + mode Fire; + Fire.name = "Fire"; + Fire.value = CHERRY_KB_MODE_FIRE; + Fire.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + Fire.speed_min = CHERRY_KB_SPEED_SLOWEST; + Fire.speed_max = CHERRY_KB_SPEED_FASTEST; + Fire.speed = CHERRY_KB_SPEED_NORMAL; + Fire.colors_min = 1; + Fire.colors_max = 1; + Fire.color_mode = MODE_COLORS_MODE_SPECIFIC; + Fire.colors.resize(1); + modes.push_back(Fire); + + mode Stars; + Stars.name = "Stars"; + Stars.value = CHERRY_KB_MODE_STARS; + Stars.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + Stars.speed_min = CHERRY_KB_SPEED_SLOWEST; + Stars.speed_max = CHERRY_KB_SPEED_FASTEST; + Stars.speed = CHERRY_KB_SPEED_NORMAL; + Stars.color_mode = MODE_COLORS_MODE_SPECIFIC; + Stars.colors.resize(1); + modes.push_back(Stars); + + mode Rain; + Rain.name = "Rain"; + Rain.value = CHERRY_KB_MODE_RAIN; + Rain.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + Rain.speed_min = CHERRY_KB_SPEED_SLOWEST; + Rain.speed_max = CHERRY_KB_SPEED_FASTEST; + Rain.speed = CHERRY_KB_SPEED_NORMAL; + Rain.colors_min = 1; + Rain.colors_max = 1; + Rain.color_mode = MODE_COLORS_MODE_SPECIFIC; + Rain.colors.resize(1); + modes.push_back(Rain); + + mode Rolling; + Rolling.name = "Rolling"; + Rolling.value = CHERRY_KB_MODE_ROLLING; + Rolling.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE; + Rolling.speed_min = CHERRY_KB_SPEED_SLOWEST; + Rolling.speed_max = CHERRY_KB_SPEED_FASTEST; + Rolling.speed = CHERRY_KB_SPEED_NORMAL; + Rolling.color_mode = MODE_COLORS_NONE; + modes.push_back(Rolling); + + mode Curve; + Curve.name = "Curve"; + Curve.value = CHERRY_KB_MODE_CURVE; + Curve.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + Curve.speed_min = CHERRY_KB_SPEED_SLOWEST; + Curve.speed_max = CHERRY_KB_SPEED_FASTEST; + Curve.speed = CHERRY_KB_SPEED_NORMAL; + Curve.colors_min = 1; + Curve.colors_max = 1; + Curve.color_mode = MODE_COLORS_MODE_SPECIFIC; + Curve.colors.resize(1); + modes.push_back(Curve); + + mode WaveMid; + WaveMid.name = "Wave Mid"; + WaveMid.value = CHERRY_KB_MODE_WAVE_MID; + WaveMid.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + WaveMid.speed_min = CHERRY_KB_SPEED_SLOWEST; + WaveMid.speed_max = CHERRY_KB_SPEED_FASTEST; + WaveMid.speed = CHERRY_KB_SPEED_NORMAL; + WaveMid.color_mode = MODE_COLORS_NONE; + WaveMid.colors.resize(1); + modes.push_back(WaveMid); + + mode Scan; + Scan.name = "Scan"; + Scan.value = CHERRY_KB_MODE_SCAN; + Scan.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + Scan.colors_min = 1; + Scan.colors_max = 1; + Scan.color_mode = MODE_COLORS_MODE_SPECIFIC; + Scan.colors.resize(1); + modes.push_back(Scan); + + mode Radiation; + Radiation.name = "Radiation"; + Radiation.value = CHERRY_KB_MODE_RADIATION; + Radiation.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + Radiation.speed_min = CHERRY_KB_SPEED_SLOWEST; + Radiation.speed_max = CHERRY_KB_SPEED_FASTEST; + Radiation.speed = CHERRY_KB_SPEED_NORMAL; + Radiation.colors_min = 1; + Radiation.colors_max = 1; + Radiation.color_mode = MODE_COLORS_MODE_SPECIFIC; + Radiation.colors.resize(1); + modes.push_back(Radiation); + + mode Ripples; + Ripples.name = "Ripples"; + Ripples.value = CHERRY_KB_MODE_RIPPLES; + Ripples.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + Ripples.speed_min = CHERRY_KB_SPEED_SLOWEST; + Ripples.speed_max = CHERRY_KB_SPEED_FASTEST; + Ripples.speed = CHERRY_KB_SPEED_NORMAL; + Ripples.colors_min = 1; + Ripples.colors_max = 1; + Ripples.color_mode = MODE_COLORS_MODE_SPECIFIC; + Ripples.colors.resize(1); + modes.push_back(Ripples); + + mode SingleKey; + SingleKey.name = "Single Key"; + SingleKey.value = CHERRY_KB_MODE_SINGLE_KEY; + SingleKey.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_AUTOMATIC_SAVE; + SingleKey.speed_min = CHERRY_KB_SPEED_SLOWEST; + SingleKey.speed_max = CHERRY_KB_SPEED_FASTEST; + SingleKey.speed = CHERRY_KB_SPEED_NORMAL; + SingleKey.colors_min = 1; + SingleKey.colors_max = 1; + SingleKey.color_mode = MODE_COLORS_MODE_SPECIFIC; + SingleKey.colors.resize(1); + modes.push_back(SingleKey); + + SetupZones(); +} + +RGBController_CherryKeyboard::~RGBController_CherryKeyboard() +{ + /*---------------------------------------------------------*\ + | Delete the matrix map | + \*---------------------------------------------------------*/ + for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++) + { + if(zones[zone_index].matrix_map != NULL) + { + delete zones[zone_index].matrix_map; + } + } + + delete controller; +} + +void RGBController_CherryKeyboard::SetupZones() +{ + zone new_zone; + + new_zone.name = "Keyboard"; + new_zone.type = ZONE_TYPE_MATRIX; + new_zone.leds_min = 126; + new_zone.leds_max = 126; + new_zone.leds_count = 126; + new_zone.matrix_map = new matrix_map_type; + new_zone.matrix_map->height = 6; + new_zone.matrix_map->width = 23; + new_zone.matrix_map->map = (unsigned int *)&matrix_map; + + zones.push_back(new_zone); + + for(int led_idx = 0; led_idx < 126; led_idx++) + { + led new_led; + + new_led.name = "Keyboard LED "; + new_led.name.append(std::to_string(led_idx)); + + leds.push_back(new_led); + } + + SetupColors(); +} + +void RGBController_CherryKeyboard::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_CherryKeyboard::DeviceUpdateLEDs() +{ + unsigned char color_data[7*CHERRY_KB_MAX_PACKET_SIZE]; + + for(int led_idx = 0; led_idx < 126; led_idx++) + { + color_data[(3 * led_idx) + 0] = RGBGetRValue(colors[led_idx]); + color_data[(3 * led_idx) + 1] = RGBGetGValue(colors[led_idx]); + color_data[(3 * led_idx) + 2] = RGBGetBValue(colors[led_idx]); + } + + controller->SetKeyboardColors + ( + color_data, + CHERRY_KB_MAX_PACKET_SIZE * 7 + ); +} + +void RGBController_CherryKeyboard::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_CherryKeyboard::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_CherryKeyboard::SetCustomMode() +{ + +} + +void RGBController_CherryKeyboard::DeviceUpdateMode() +{ + unsigned char red = 0x00; + unsigned char grn = 0x00; + unsigned char blu = 0x00; + unsigned char random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM); + + if(modes[active_mode].colors.size() > 0) + { + red = RGBGetRValue(modes[active_mode].colors[0]); + grn = RGBGetGValue(modes[active_mode].colors[0]); + blu = RGBGetBValue(modes[active_mode].colors[0]); + } + + controller->SendKeyboardModeEx + ( + modes[active_mode].value, + CHERRY_KB_BRIGHTNESS_HIGHEST, + modes[active_mode].speed, + 0, + random, + red, + grn, + blu + ); +} diff --git a/Controllers/CherryKeyboardController/RGBController_CherryKeyboard.h b/Controllers/CherryKeyboardController/RGBController_CherryKeyboard.h new file mode 100644 index 00000000..79f1b4f8 --- /dev/null +++ b/Controllers/CherryKeyboardController/RGBController_CherryKeyboard.h @@ -0,0 +1,33 @@ +/*-----------------------------------------*\ +| RGBController_CherryKeyboard.h | +| | +| Generic RGB Interface for Cherry RGB | +| Keyboard | +| | +| Sebastian Kraus 12/25/2021 | +\*-----------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "CherryKeyboardController.h" + +class RGBController_CherryKeyboard : public RGBController +{ +public: + RGBController_CherryKeyboard(CherryKeyboardController* controller_ptr); + ~RGBController_CherryKeyboard(); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void DeviceUpdateMode(); + +private: + CherryKeyboardController* controller; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 32976a2d..0adad333 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -89,6 +89,7 @@ INCLUDEPATH += Controllers/AsusAuraCoreController/ \ Controllers/AsusAuraGPUController/ \ Controllers/AsusAuraUSBController/ \ + Controllers/CherryKeyboardController/ \ Controllers/CoolerMasterController/ \ Controllers/CorsairCommanderCoreController/ \ Controllers/CorsairDominatorPlatinumController/ \ @@ -319,6 +320,8 @@ HEADERS += Controllers/AsusLegacyUSBController/RGBController_AsusStrixClaw.h \ Controllers/BlinkyTapeController/BlinkyTapeController.h \ Controllers/BlinkyTapeController/RGBController_BlinkyTape.h \ + Controllers/CherryKeyboardController/CherryKeyboardController.h \ + Controllers/CherryKeyboardController/RGBController_CherryKeyboard.h \ Controllers/ColorfulGPUController/ColorfulGPUController.h \ Controllers/ColorfulGPUController/RGBController_ColorfulGPU.h \ Controllers/CoolerMasterController/CMARGBcontroller.h \ @@ -879,6 +882,9 @@ SOURCES += Controllers/BlinkyTapeController/BlinkyTapeController.cpp \ Controllers/BlinkyTapeController/BlinkyTapeControllerDetect.cpp \ Controllers/BlinkyTapeController/RGBController_BlinkyTape.cpp \ + Controllers/CherryKeyboardController/CherryKeyboardController.cpp \ + Controllers/CherryKeyboardController/CherryKeyboardControllerDetect.cpp \ + Controllers/CherryKeyboardController/RGBController_CherryKeyboard.cpp \ Controllers/ColorfulGPUController/ColorfulGPUController.cpp \ Controllers/ColorfulGPUController/ColorfulGPUControllerDetect.cpp \ Controllers/ColorfulGPUController/RGBController_ColorfulGPU.cpp \