From 0b45eac52c1d0a47c47f4a6f24016fd7a2595ec2 Mon Sep 17 00:00:00 2001 From: Soufian Batta Date: Sat, 10 Jan 2026 21:20:38 +0000 Subject: [PATCH] Add Support on Mountain Everest 60 Device /3 --- .../Mountain60KeyboardController.cpp | 275 ++++++++++ .../Mountain60KeyboardController.h | 95 ++++ .../MountainKeyboardControllerDetect.cpp | 37 +- .../RGBController_Mountain60Keyboard.cpp | 490 ++++++++++++++++++ .../RGBController_Mountain60Keyboard.h | 51 ++ 5 files changed, 946 insertions(+), 2 deletions(-) create mode 100644 Controllers/MountainKeyboardController/Mountain60KeyboardController.cpp create mode 100644 Controllers/MountainKeyboardController/Mountain60KeyboardController.h create mode 100644 Controllers/MountainKeyboardController/RGBController_Mountain60Keyboard.cpp create mode 100644 Controllers/MountainKeyboardController/RGBController_Mountain60Keyboard.h diff --git a/Controllers/MountainKeyboardController/Mountain60KeyboardController.cpp b/Controllers/MountainKeyboardController/Mountain60KeyboardController.cpp new file mode 100644 index 000000000..ebeab9288 --- /dev/null +++ b/Controllers/MountainKeyboardController/Mountain60KeyboardController.cpp @@ -0,0 +1,275 @@ +/*---------------------------------------------------------*\ +| Mountain60KeyboardController.cpp | +| | +| Driver for Mountain keyboard | +| | +| O'D.Sæzl Jan 2025 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include +#include +#include +#include "Mountain60KeyboardController.h" +#include "StringUtils.h" + +using namespace std::chrono_literals; + +Mountain60KeyboardController::Mountain60KeyboardController(hid_device* dev_handle, const char* path) +{ + dev = dev_handle; + location = path; +} + +Mountain60KeyboardController::~Mountain60KeyboardController() +{ + hid_close(dev); +} + +std::string Mountain60KeyboardController::GetDeviceLocation() +{ + return("HID: " + location); +} + +const char* Mountain60KeyboardController::GetPath() +{ + return location.c_str(); +} + +std::string Mountain60KeyboardController::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 Mountain60KeyboardController::SetDevice(hid_device* new_device) +{ + hid_close(dev); + dev = new_device; +} + +void Mountain60KeyboardController::UpdateData() +{ + unsigned char usb_buf[MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE]; + unsigned char read[MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE]; + memset(usb_buf, 0x00, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + + usb_buf[0x01] = MOUNTAIN60_KEYBOARD_CHECK_NUMPAD; + usb_buf[0x02] = 0x46; //constant data + usb_buf[0x03] = 0x23; //constant data + usb_buf[0x04] = 0xEA; //constant data + + hid_send_feature_report(dev, usb_buf, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + memset(read, 0x00, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + hid_get_feature_report(dev, read, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); +} + +void Mountain60KeyboardController::SendModeDetails(const mode* current_mode) +{ + unsigned char usb_buf[MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE]; + unsigned char color_mode [] = {MOUNTAIN60_KEYBOARD_COLOR_MODE_SINGLE,MOUNTAIN60_KEYBOARD_COLOR_MODE_DUAL}; + memset(usb_buf, 0x00, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + + usb_buf[0x01] = MOUNTAIN60_KEYBOARD_SEND_CMD; + usb_buf[0x02] = 0x46; //constant data + usb_buf[0x03] = 0x23; //constant data + usb_buf[0x04] = 0xEA; //constant data + + usb_buf[0x05] = current_mode->value; + usb_buf[0x07] = current_mode->value == MOUNTAIN60_KEYBOARD_MODE_STATIC ? 0x32 : current_mode->speed * 25; + usb_buf[0x08] = current_mode->brightness * 25; + usb_buf[0x09] = current_mode->color_mode == MODE_COLORS_RANDOM ? MOUNTAIN60_KEYBOARD_COLOR_MODE_RAINBOW : color_mode[current_mode->colors.size() - 1]; + usb_buf[0x0A] = ConvertDirection(current_mode->direction,current_mode->value == MOUNTAIN60_KEYBOARD_MODE_TORNADO); + + for (int idx = 0; idx < current_mode->colors.size(); ++idx) + { + unsigned int offset = 12 + (idx * 3); + usb_buf[offset] = RGBGetRValue(current_mode->colors[idx]); + usb_buf[offset+1] = RGBGetGValue(current_mode->colors[idx]); + usb_buf[offset+2] = RGBGetBValue(current_mode->colors[idx]); + } + + hid_send_feature_report(dev, usb_buf, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + std::this_thread::sleep_for(10ms); + SaveData(current_mode->value); +} + +void Mountain60KeyboardController::SelectMode(unsigned char mode_idx) +{ + unsigned char usb_buf[MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE]; + unsigned char read[MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE]; + memset(usb_buf, 0x00, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + + usb_buf[0x01] = MOUNTAIN60_KEYBOARD_SELECT_MODE_CMD; + usb_buf[0x02] = 0x46; //constant data + usb_buf[0x03] = 0x23; //constant data + usb_buf[0x04] = 0xEA; //constant data + usb_buf[0x05] = 0x01; //constant data + + usb_buf[0x09] = mode_idx; + + hid_send_feature_report(dev, usb_buf, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + memset(read, 0x00, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + hid_get_feature_report(dev, read, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); +} + +void Mountain60KeyboardController::SaveData(unsigned char mode_idx) +{ + unsigned char usb_buf[MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE]; + unsigned char read[MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE]; + memset(usb_buf, 0x00, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + + usb_buf[0x01] = MOUNTAIN60_KEYBOARD_SAVE_CMD; + usb_buf[0x02] = 0x46; //constant data + usb_buf[0x03] = 0x23; //constant data + usb_buf[0x04] = 0xEA; //constant data + + usb_buf[0x05] = mode_idx; + + hid_send_feature_report(dev, usb_buf, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + memset(read, 0x00, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + hid_get_feature_report(dev, read, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); +} + +void Mountain60KeyboardController::SendDirectStartPacketCmd(unsigned int brightness) +{ + unsigned char usb_buf[MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE]; + unsigned char read[MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE]; + memset(usb_buf, 0x00, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + + usb_buf[0x01] = MOUNTAIN60_KEYBOARD_START_DIRECT_CMD; + usb_buf[0x02] = 0x46; //constant data + usb_buf[0x03] = 0x23; //constant data + usb_buf[0x04] = 0xEA; //constant data + usb_buf[0x06] = 0xC0; //constant data + + usb_buf[0x05] = brightness * 25; + + hid_send_feature_report(dev, usb_buf, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + memset(read, 0x00, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + hid_get_feature_report(dev, read, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); +} + +void Mountain60KeyboardController::SendDirectPacketCmd(unsigned char stream_control, unsigned char *data, unsigned int data_size) +{ + unsigned char usb_buf[MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE]; + memset(usb_buf, 0x00, MOUNTAIN60_KEYBOARD_USB_BUFFER_HEADER_SIZE); + + usb_buf[0x01] = MOUNTAIN60_KEYBOARD_MAP_DIRECT_CMD; + usb_buf[0x02] = 0x46; //constant data + usb_buf[0x03] = 0x23; //constant data + usb_buf[0x04] = 0xEA; //constant data + + usb_buf[0x05] = stream_control; + + if(data_size <= MOUNTAIN60_KEYBOARD_USB_MAX_DIRECT_PAYLOAD_SIZE) + { + unsigned char read[MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE]; + memcpy(&usb_buf[MOUNTAIN60_KEYBOARD_USB_BUFFER_HEADER_SIZE],data,data_size); + + if(data_size < MOUNTAIN60_KEYBOARD_USB_MAX_DIRECT_PAYLOAD_SIZE) + { + memset(&usb_buf[MOUNTAIN60_KEYBOARD_USB_BUFFER_HEADER_SIZE + data_size],0xFF,MOUNTAIN60_KEYBOARD_USB_MAX_DIRECT_PAYLOAD_SIZE-data_size); + } + + hid_send_feature_report(dev, usb_buf, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + memset(read, 0x00, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + hid_get_feature_report(dev, read, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + } +} + +void Mountain60KeyboardController::SendDirectPacketFinishCmd() +{ + unsigned char usb_buf[MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE]; + unsigned char read[MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE]; + memset(usb_buf, 0x00, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + + usb_buf[0x01] = MOUNTAIN60_KEYBOARD_END_DIRECT_CMD; + usb_buf[0x02] = 0x46; //constant data + usb_buf[0x03] = 0x23; //constant data + usb_buf[0x04] = 0xEA; //constant data + + hid_send_feature_report(dev, usb_buf, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + memset(read, 0x00, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); + hid_get_feature_report(dev, read, MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE); +} + +void Mountain60KeyboardController::SendDirect(unsigned int brightness, unsigned char* color_data, unsigned int data_size) +{ + static unsigned char prv_buffer[MOUNTAIN60_KEYBOARD_TRANSFER_BUFFER_SIZE] = {0xFF}; + unsigned char *data_ptr = color_data; + unsigned char *prv_data_ptr = prv_buffer; + unsigned int data_len = data_size; + unsigned char stream_control_flag = 0x0E; + + SendDirectStartPacketCmd(brightness); + + while(data_len>0) + { + if(data_len >= MOUNTAIN60_KEYBOARD_USB_MAX_DIRECT_PAYLOAD_SIZE) + { + Mountain60KeyboardController::SendDirectPacketCmd(stream_control_flag,data_ptr,MOUNTAIN60_KEYBOARD_USB_MAX_DIRECT_PAYLOAD_SIZE); + memcpy(prv_data_ptr,data_ptr,MOUNTAIN60_KEYBOARD_USB_MAX_DIRECT_PAYLOAD_SIZE); + + data_ptr += MOUNTAIN60_KEYBOARD_USB_MAX_DIRECT_PAYLOAD_SIZE; + prv_data_ptr += MOUNTAIN60_KEYBOARD_USB_MAX_DIRECT_PAYLOAD_SIZE; + data_len -= MOUNTAIN60_KEYBOARD_USB_MAX_DIRECT_PAYLOAD_SIZE; + } + else + { + stream_control_flag = 0x0A; + Mountain60KeyboardController::SendDirectPacketCmd(stream_control_flag,data_ptr,data_len); + memcpy(prv_data_ptr,data_ptr,data_len); + data_len = 0; + } + } + + SendDirectPacketFinishCmd(); +} + +unsigned char Mountain60KeyboardController::ConvertDirection(unsigned int direction, bool rotation) +{ + unsigned char ret; + switch(direction) + { + case MODE_DIRECTION_LEFT: + { + ret = rotation?MOUNTAIN60_KEYBOARD_DIRECTION_ANTICLK:MOUNTAIN60_KEYBOARD_DIRECTION_LEFT; + } + break; + + case MODE_DIRECTION_RIGHT: + { + ret = rotation?MOUNTAIN60_KEYBOARD_DIRECTION_CLK:MOUNTAIN60_KEYBOARD_DIRECTION_RIGHT; + } + break; + + case MODE_DIRECTION_UP: + { + ret = MOUNTAIN60_KEYBOARD_DIRECTION_UP; + } + break; + + case MODE_DIRECTION_DOWN: + { + ret = MOUNTAIN60_KEYBOARD_DIRECTION_DOWN; + } + break; + + default: + { + ret = MOUNTAIN60_KEYBOARD_DIRECTION_LEFT; + } + break; + } + return ret; +} diff --git a/Controllers/MountainKeyboardController/Mountain60KeyboardController.h b/Controllers/MountainKeyboardController/Mountain60KeyboardController.h new file mode 100644 index 000000000..e50ace9d5 --- /dev/null +++ b/Controllers/MountainKeyboardController/Mountain60KeyboardController.h @@ -0,0 +1,95 @@ +/*---------------------------------------------------------*\ +| MountainKeyboardController.h | +| | +| Driver for Mountain keyboard | +| | +| O'D.Sæzl Jan 2023 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#pragma once + +#include +#include +#include "RGBController.h" + +#define MOUNTAIN60_KEYBOARD_MAX_TRANSFER_COLORS 191 +#define MOUNTAIN60_KEYBOARD_TRANSFER_BUFFER_SIZE (4*MOUNTAIN60_KEYBOARD_MAX_TRANSFER_COLORS) + +#define MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE 65 +#define MOUNTAIN60_KEYBOARD_USB_BUFFER_HEADER_SIZE 9 + +#define MOUNTAIN60_KEYBOARD_USB_MAX_DIRECT_PAYLOAD_SIZE \ +(MOUNTAIN60_KEYBOARD_USB_BUFFER_SIZE-MOUNTAIN60_KEYBOARD_USB_BUFFER_HEADER_SIZE) + + enum +{ + MOUNTAIN60_KEYBOARD_CHECK_NUMPAD = 0x08, + MOUNTAIN60_KEYBOARD_SELECT_MODE_CMD = 0x16, + MOUNTAIN60_KEYBOARD_SEND_CMD = 0x17, + MOUNTAIN60_KEYBOARD_START_DIRECT_CMD = 0x34, + MOUNTAIN60_KEYBOARD_MAP_DIRECT_CMD = 0x35, + MOUNTAIN60_KEYBOARD_END_DIRECT_CMD = 0x36, + MOUNTAIN60_KEYBOARD_SAVE_CMD = 0x1A, +}; + +enum +{ + MOUNTAIN60_KEYBOARD_MODE_STATIC = 0x01, + MOUNTAIN60_KEYBOARD_MODE_COLOR_WAVE = 0x02, + MOUNTAIN60_KEYBOARD_MODE_TORNADO = 0x03, + MOUNTAIN60_KEYBOARD_MODE_BREATHING = 0x04, + MOUNTAIN60_KEYBOARD_MODE_REACTIVE = 0x05, + MOUNTAIN60_KEYBOARD_MODE_MATRIX = 0x06, + MOUNTAIN60_KEYBOARD_MODE_CUSTOM = 0x07, + MOUNTAIN60_KEYBOARD_MODE_YETI = 0x08, + MOUNTAIN60_KEYBOARD_MODE_OFF = 0x09, + MOUNTAIN60_KEYBOARD_MODE_INVALID = 0xFF, +}; + +enum +{ + MOUNTAIN60_KEYBOARD_COLOR_MODE_RAINBOW = 0x02, + MOUNTAIN60_KEYBOARD_COLOR_MODE_SINGLE = 0x00, + MOUNTAIN60_KEYBOARD_COLOR_MODE_DUAL = 0x10 +}; + +enum +{ + MOUNTAIN60_KEYBOARD_DIRECTION_UP = 0x06, + MOUNTAIN60_KEYBOARD_DIRECTION_DOWN = 0x02, + MOUNTAIN60_KEYBOARD_DIRECTION_LEFT = 0x04, + MOUNTAIN60_KEYBOARD_DIRECTION_RIGHT = 0x00, + MOUNTAIN60_KEYBOARD_DIRECTION_ANTICLK = 0x0A, + MOUNTAIN60_KEYBOARD_DIRECTION_CLK = 0x09, +}; + +class Mountain60KeyboardController +{ +public: + Mountain60KeyboardController(hid_device* dev_handle, const char* path); + ~Mountain60KeyboardController(); + + const char* GetPath(); + std::string GetSerialString(); + std::string GetDeviceLocation(); + + void UpdateData(); + void SaveData(unsigned char mode_idx); + void SelectMode(unsigned char mode_idx); + void SetDevice(hid_device * new_device); + void SendModeDetails(const mode* current_mode); + void SendDirect(unsigned int brightness,unsigned char* color_data, unsigned int color_count); + +private: + unsigned char ConvertDirection(unsigned int direction, bool rotation); + + void SendDirectStartPacketCmd(unsigned int brightness); + void SendDirectPacketCmd(unsigned char stream_control, unsigned char *data, unsigned int data_size); + void SendDirectPacketFinishCmd(); + + hid_device* dev; + std::string location; +}; diff --git a/Controllers/MountainKeyboardController/MountainKeyboardControllerDetect.cpp b/Controllers/MountainKeyboardController/MountainKeyboardControllerDetect.cpp index 03e30403c..1a27e9068 100644 --- a/Controllers/MountainKeyboardController/MountainKeyboardControllerDetect.cpp +++ b/Controllers/MountainKeyboardController/MountainKeyboardControllerDetect.cpp @@ -3,7 +3,7 @@ | | | Detector for Mountain keyboard | | | -| Wojciech Lazarski Jan 2023 | +| Wojciech Lazarski / O'D.Sæzl Jan 2023 | | | | This file is part of the OpenRGB project | | SPDX-License-Identifier: GPL-2.0-or-later | @@ -11,9 +11,25 @@ #include #include "Detector.h" +#include "QMessageLogger" #include "MountainKeyboardController.h" #include "RGBController_MountainKeyboard.h" +#include "Mountain60KeyboardController.h" +#include "RGBController_Mountain60Keyboard.h" +/*---------------------------------------------------------------*\ +| Mountain vendor ID | +\*---------------------------------------------------------------*/ +#define MOUNTAIN_VID 0x3282 + +/*----------------------------------------------------------------*\ +| Everest 60 keyboard Connection IDs | +\*----------------------------------------------------------------*/ +#define MOUNTAIN60_EVEREST_60_PID_ANSII 0x0005 +#define MOUNTAIN60_EVEREST_60_PID_ISO 0x0006 +#define MOUNTAIN60_EVEREST_60_INTERFACE 2 +#define MOUNTAIN60_EVEREST_60_U 0x01 +#define MOUNTAIN60_EVEREST_60_UP 0xffff /*----------------------------------------------------------------------------------------*\ | | | DetectMountainKeyboardControllers | @@ -22,6 +38,21 @@ | | \*----------------------------------------------------------------------------------------*/ +void DetectMountain60KeyboardControllers(hid_device_info* info, const std::string& name) +{ + QMessageLogger* log = new QMessageLogger(); + + log->info("Hello World 2"); + hid_device* dev = hid_open_path(info->path); + if(dev) + { + Mountain60KeyboardController* controller = new Mountain60KeyboardController(dev, info->path); + RGBController_Mountain60Keyboard* rgb_controller = new RGBController_Mountain60Keyboard(controller); + rgb_controller->name = name; + ResourceManager::get()->RegisterRGBController(rgb_controller); + } +} + void DetectMountainKeyboardControllers(hid_device_info* info, const std::string& name) { hid_device* dev = hid_open_path(info->path); @@ -33,6 +64,8 @@ void DetectMountainKeyboardControllers(hid_device_info* info, const std::string& ResourceManager::get()->RegisterRGBController(rgb_controller); } -} /* DetectMountainKeyboardControllers() */ +} REGISTER_HID_DETECTOR_IPU("Mountain Everest", DetectMountainKeyboardControllers, MOUNTAIN_VID, MOUNTAIN_EVEREST_PID, 3, 0xFF00, 0x01); +REGISTER_HID_DETECTOR_IPU("Mountain Everest 60", DetectMountain60KeyboardControllers, MOUNTAIN_VID, MOUNTAIN60_EVEREST_60_PID_ANSII, MOUNTAIN60_EVEREST_60_INTERFACE, MOUNTAIN60_EVEREST_60_UP, MOUNTAIN60_EVEREST_60_U); +REGISTER_HID_DETECTOR_IPU("Mountain Everest 60", DetectMountain60KeyboardControllers, MOUNTAIN_VID, MOUNTAIN60_EVEREST_60_PID_ISO, MOUNTAIN60_EVEREST_60_INTERFACE, MOUNTAIN60_EVEREST_60_UP, MOUNTAIN60_EVEREST_60_U); diff --git a/Controllers/MountainKeyboardController/RGBController_Mountain60Keyboard.cpp b/Controllers/MountainKeyboardController/RGBController_Mountain60Keyboard.cpp new file mode 100644 index 000000000..a25d5475c --- /dev/null +++ b/Controllers/MountainKeyboardController/RGBController_Mountain60Keyboard.cpp @@ -0,0 +1,490 @@ +/*---------------------------------------------------------*\ +| RGBController_MountainKeyboard.cpp | +| | +| RGBController for Mountain keyboard | +| | +| O'D.Sæzl Jan 2023 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#include "RGBController_Mountain60Keyboard.h" +#include "RGBControllerKeyNames.h" +#include "KeyboardLayoutManager.h" + +using namespace std::chrono_literals; + +/*-------------------------------*\ +| TODO: Detect detached keypad | +\*-------------------------------*/ + +std::vector mountain60_keyboard_key_id_values = + { + /* ESC 1 2 3 4 5 6 7 8 9 0 - = BSPC */ + 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + /* TAB Q W E R T Y U I O P [ ] \ */ + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + /* CPLK A S D F G H J K L ; " ENTR */ + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, + /* LSFT Z X C V B N M , . / RSFT ARWU DEL */ + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 97, 94, 56, + /* LCTL LWIN LALT SPC RALT RFNC FNC ARWL ARWD ARWR */ + 105, 106, 107, 110, 113, 115, 119, 120, 121, +}; + +layout_values mountain60_layout = + { + mountain60_keyboard_key_id_values, + { + /*------------------------------------------*\ + | No regional layout fix for the moment | + \*------------------------------------------*/ + }, +}; + +keyboard_keymap_overlay_values mountain60_keyboard_overlay_no_numpad = + { + KEYBOARD_SIZE::KEYBOARD_SIZE_SIXTY, + mountain60_layout, + { + /*--------------------------------------------------------------------------------------------------------------------------------*\ + | Edit Keys | + | Zone, Row, Column, Value, Key, Alt name, OpCode, | + \*---------------------------------------------------------------------------------------------------------------------------------*/ + { 0, 4, 13, 120, KEY_EN_DOWN_ARROW, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 4, 12, 119, KEY_EN_LEFT_ARROW, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 4, 14, 121, KEY_EN_RIGHT_ARROW, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 4, 14, 121, KEY_EN_RIGHT_ARROW, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 3, 13, 99, KEY_EN_UP_ARROW, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 12, 97, KEY_EN_RIGHT_SHIFT, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 2, 85, KEY_EN_Z, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 3, 86, KEY_EN_X, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 4, 87, KEY_EN_C, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 5, 88, KEY_EN_B, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 6, 89, KEY_EN_V, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 7, 90, KEY_EN_N, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 8, 91, KEY_EN_M, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 9, 92, KEY_EN_COMMA, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 10, 93, KEY_EN_PERIOD, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 14, 56, KEY_EN_DELETE, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 2, 13, 76, KEY_EN_ANSI_ENTER, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 0, 84, KEY_EN_LEFT_SHIFT, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + //upper edge + { 0, 0, 0, 126, "Edge 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_ROW, }, + { 0, 0, 1, 127, "Edge 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 2, 128, "Edge 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 3, 129, "Edge 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 4, 130, "Edge 5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 5, 131, "Edge 6", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 6, 132, "Edge 7", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 7, 133, "Edge 8", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 8, 134, "Edge 9", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 9, 135, "Edge 10", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 10, 136, "Edge 11", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 11, 137, "Edge 12", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 12, 138, "Edge 13", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 13, 139, "Edge 14", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 14, 140, "Edge 15", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 15, 141, "Edge 16", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + //left edge + { 0, 0, 0, 169, "Edge 44", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 1, 0, 168, "Edge 43", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 2, 0, 167, "Edge 42", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 3, 0, 166, "Edge 41", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 4, 0, 165, "Edge 40", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 5, 0, 164, "Edge 39", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + //down edge + { 0, 6, 0, 1, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_ROW, }, + { 0, 6, 0, 163, "Edge 38", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 1, 162, "Edge 37", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 2, 161, "Edge 36", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 3, 160, "Edge 35", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 4, 159, "Edge 34", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 5, 158, "Edge 33", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 6, 157, "Edge 32", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 7, 156, "Edge 31", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 8, 155, "Edge 30", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 9, 154, "Edge 29", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 10, 153, "Edge 28", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 11, 152, "Edge 27", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 12, 151, "Edge 26", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 13, 150, "Edge 25", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 14, 149, "Edge 24", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 15, 148, "Edge 23", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + //right edge + { 0, 1, 16, 142, "Edge 17", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 2, 16, 143, "Edge 18", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 3, 16, 144, "Edge 19", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 4, 16, 145, "Edge 20", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 5, 16, 146, "Edge 21", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 16, 147, "Edge 22", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 16, 147, "Edge 22", KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + //numpad left edge + { 0, 0, 17, 191, "Numpad Edge 22", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 1, 17, 190, "Numpad Edge 21", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 2, 17, 189, "Numpad Edge 20", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 3, 17, 188, "Numpad Edge 19", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 4, 17, 187, "Numpad Edge 18", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 5, 17, 186, "Numpad Edge 17", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + //numpad upper edge + { 0, 0, 18, 170, "Numpad Edge 1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 19, 171, "Numpad Edge 2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 20, 172, "Numpad Edge 3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 21, 173, "Numpad Edge 4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 0, 22, 174, "Numpad Edge 5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + //numpad down edge + { 0, 6, 17, 185, "Numpad Edge 12", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT }, + { 0, 6, 18, 184, "Numpad Edge 13", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 19, 183, "Numpad Edge 14", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 20, 182, "Numpad Edge 15", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 21, 181, "Numpad Edge 16", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + //numpad right edge + { 0, 1, 22, 175, "Numpad Edge 6", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 2, 22, 176, "Numpad Edge 7", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 3, 22, 177, "Numpad Edge 8", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 4, 22, 178, "Numpad Edge 9", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 5, 22, 179, "Numpad Edge 10", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 22, 180, "Numpad Edge 11", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, + { 0, 6, 22, 180, "Numpad Edge 11", KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + //numpad keys + { 0, 1, 18, 38, KEY_EN_NUMPAD_LOCK, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 1, 19, 39, KEY_EN_NUMPAD_DIVIDE, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 1, 20, 40, KEY_EN_NUMPAD_TIMES, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 1, 21, 41, KEY_EN_NUMPAD_MINUS, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 2, 18, 59, KEY_EN_NUMPAD_7, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 2, 19, 60, KEY_EN_NUMPAD_8, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 2, 20, 61, KEY_EN_NUMPAD_9, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 2, 21, 62, KEY_EN_NUMPAD_PLUS, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 18, 80, KEY_EN_NUMPAD_4, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 19, 81, KEY_EN_NUMPAD_5, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 3, 20, 82, KEY_EN_NUMPAD_6, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 4, 18, 101, KEY_EN_NUMPAD_1, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 4, 19, 102, KEY_EN_NUMPAD_2, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 4, 20, 103, KEY_EN_NUMPAD_3, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 5, 18, 122, KEY_EN_NUMPAD_0, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 5, 20, 124, KEY_EN_NUMPAD_PERIOD, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + { 0, 5, 21, 125, KEY_EN_NUMPAD_ENTER, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, + } +}; + +/**------------------------------------------------------------------*\ + @name Mountain Keyboard + @category Keyboard + @type USB + @save :white_check_mark: + @direct :white_check_mark: + @effects :white_check_mark: + @detectors DetectMountainKeyboardControllers + @comment +\*-------------------------------------------------------------------*/ + +RGBController_Mountain60Keyboard::RGBController_Mountain60Keyboard(Mountain60KeyboardController* controller_ptr) +{ + controller = controller_ptr; + name = "Mountain Everest 60 Keyboard"; + vendor = "Mountain"; + type = DEVICE_TYPE_KEYBOARD; + description = "Mountain Everest Keyboard 60%"; + location = controller->GetDeviceLocation(); + serial = controller->GetSerialString(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = MOUNTAIN60_KEYBOARD_MODE_CUSTOM; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE; + Direct.brightness_min = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MIN; + Direct.brightness = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + Direct.brightness_max = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + mode Off; + Off.name = "Off"; + Off.value = MOUNTAIN60_KEYBOARD_MODE_OFF; + Off.flags = MODE_FLAG_MANUAL_SAVE; + Off.color_mode = MODE_COLORS_NONE; + modes.push_back(Off); + + mode Static; + Static.name = "Static"; + Static.value = MOUNTAIN60_KEYBOARD_MODE_STATIC; + Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE; + Static.brightness_min = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MIN; + Static.brightness = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + Static.brightness_max = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + Static.color_mode = MODE_COLORS_MODE_SPECIFIC; + Static.colors_min = 1; + Static.colors_max = 1; + Static.colors.resize(1); + modes.push_back(Static); + + mode ColorWaveRainbow; + ColorWaveRainbow.name = "Rainbow Wave"; + ColorWaveRainbow.value = MOUNTAIN60_KEYBOARD_MODE_COLOR_WAVE; + ColorWaveRainbow.flags = MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_MANUAL_SAVE; + ColorWaveRainbow.brightness_min = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MIN; + ColorWaveRainbow.brightness = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + ColorWaveRainbow.brightness_max = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + ColorWaveRainbow.speed_min = MOUNTAIN60_KEYBOARD_SPEED_MIN; + ColorWaveRainbow.speed = MOUNTAIN60_KEYBOARD_SPEED_DEFAULT; + ColorWaveRainbow.speed_max = MOUNTAIN60_KEYBOARD_SPEED_MAX; + ColorWaveRainbow.color_mode = MODE_COLORS_RANDOM; + + modes.push_back(ColorWaveRainbow); + + mode ColorWave; + ColorWave.name = "ColorWave"; + ColorWave.value = MOUNTAIN60_KEYBOARD_MODE_COLOR_WAVE; + ColorWave.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_MANUAL_SAVE; + ColorWave.brightness_min = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MIN; + ColorWave.brightness = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + ColorWave.brightness_max = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + ColorWave.speed_min = MOUNTAIN60_KEYBOARD_SPEED_MIN; + ColorWave.speed = MOUNTAIN60_KEYBOARD_SPEED_DEFAULT; + ColorWave.speed_max = MOUNTAIN60_KEYBOARD_SPEED_MAX; + ColorWave.colors_min = 1; + ColorWave.colors_max = 2; + ColorWave.colors.resize(2); + ColorWave.color_mode = MODE_COLORS_MODE_SPECIFIC; + modes.push_back(ColorWave); + + mode Tornado; + Tornado.name = "Tornado"; + Tornado.value = MOUNTAIN60_KEYBOARD_MODE_TORNADO; + Tornado.flags = MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_MANUAL_SAVE; + Tornado.brightness_min = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MIN; + Tornado.brightness = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + Tornado.brightness_max = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + Tornado.speed_min = MOUNTAIN60_KEYBOARD_SPEED_MIN; + Tornado.speed = MOUNTAIN60_KEYBOARD_SPEED_DEFAULT; + Tornado.speed_max = MOUNTAIN60_KEYBOARD_SPEED_MAX; + Tornado.colors_min = 1; + Tornado.colors_max = 1; + Tornado.colors.resize(1); + Tornado.color_mode = MODE_COLORS_MODE_SPECIFIC; + modes.push_back(Tornado); + + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = MOUNTAIN60_KEYBOARD_MODE_BREATHING; + Breathing.flags = MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE; + Breathing.brightness_min = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MIN; + Breathing.brightness = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + Breathing.brightness_max = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + Breathing.speed_min = MOUNTAIN60_KEYBOARD_SPEED_MIN; + Breathing.speed = MOUNTAIN60_KEYBOARD_SPEED_DEFAULT; + Breathing.speed_max = MOUNTAIN60_KEYBOARD_SPEED_MAX; + Breathing.colors_min = 1; + Breathing.colors_max = 2; + Breathing.colors.resize(2); + Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC; + modes.push_back(Breathing); + + mode Reactive; + Reactive.name = "Reactive"; + Reactive.value = MOUNTAIN60_KEYBOARD_MODE_REACTIVE; + Reactive.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE; + Reactive.brightness_min = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MIN; + Reactive.brightness = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + Reactive.brightness_max = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + Reactive.speed_min = MOUNTAIN60_KEYBOARD_SPEED_MIN; + Reactive.speed = MOUNTAIN60_KEYBOARD_SPEED_DEFAULT; + Reactive.speed_max = MOUNTAIN60_KEYBOARD_SPEED_MAX; + Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC; + Reactive.colors_min = 1; + Reactive.colors_max = 2; + Reactive.colors.resize(2); + modes.push_back(Reactive); + + mode Matrix; + Matrix.name = "Matrix"; + Matrix.value = MOUNTAIN60_KEYBOARD_MODE_MATRIX; + Matrix.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE; + Matrix.brightness_min = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MIN; + Matrix.brightness = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + Matrix.brightness_max = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + Matrix.speed_min = MOUNTAIN60_KEYBOARD_SPEED_MIN; + Matrix.speed = MOUNTAIN60_KEYBOARD_SPEED_DEFAULT; + Matrix.speed_max = MOUNTAIN60_KEYBOARD_SPEED_MAX; + Matrix.color_mode = MODE_COLORS_MODE_SPECIFIC; + Matrix.colors_min = 1; + Matrix.colors_max = 2; + Matrix.colors.resize(2); + modes.push_back(Matrix); + + mode Yeti; + Yeti.name = "Yeti"; + Yeti.value = MOUNTAIN60_KEYBOARD_MODE_YETI; + Yeti.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE; + Yeti.brightness_min = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MIN; + Yeti.brightness = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + Yeti.brightness_max = MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX; + Yeti.speed_min = MOUNTAIN60_KEYBOARD_SPEED_MIN; + Yeti.speed = MOUNTAIN60_KEYBOARD_SPEED_DEFAULT; + Yeti.speed_max = MOUNTAIN60_KEYBOARD_SPEED_MAX; + Yeti.color_mode = MODE_COLORS_MODE_SPECIFIC; + Yeti.colors_min = 1; + Yeti.colors_max = 2; + Yeti.colors.resize(2); + modes.push_back(Yeti); + + SetupZones(); + + /*-----------------------------------------------------*\ + | The Mountain Everest 60 keyboard need to send a | + | specific packet frequently so that leds get updated | + \*-----------------------------------------------------*/ + mountain_thread = new std::thread(&RGBController_Mountain60Keyboard::UpdateMountain, this); + mountaint_thread_running = true; + update_device = true; + found_device = true; +} + +RGBController_Mountain60Keyboard::~RGBController_Mountain60Keyboard() +{ + update_device = false; + mountaint_thread_running = false; + mountain_thread->join(); + delete mountain_thread; + + /*---------------------------------------------------------*\ + | Delete the matrix map | + \*---------------------------------------------------------*/ + for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++) + { + if(zones[zone_index].type == ZONE_TYPE_MATRIX) + { + delete zones[zone_index].matrix_map; + } + } + + delete controller; +} + +void RGBController_Mountain60Keyboard::SetupZones() +{ + KeyboardLayoutManager new_kb(KEYBOARD_LAYOUT_ANSI_QWERTY, KEYBOARD_SIZE_SIXTY, mountain60_layout); + new_kb.ChangeKeys(mountain60_keyboard_overlay_no_numpad); + + zone new_zone; + matrix_map_type * new_map = new matrix_map_type; + + new_zone.name = "Mountain Everest 60"; + new_zone.type = ZONE_TYPE_MATRIX; + new_zone.matrix_map = new_map; + new_zone.matrix_map->height = new_kb.GetRowCount(); + new_zone.matrix_map->width = new_kb.GetColumnCount(); + new_zone.matrix_map->map = new unsigned int[new_map->height * new_map->width]; + new_zone.leds_count = new_kb.GetKeyCount(); + new_zone.leds_min = new_zone.leds_count; + new_zone.leds_max = new_zone.leds_count; + + new_kb.GetKeyMap(new_map->map, KEYBOARD_MAP_FILL_TYPE_COUNT); + + for(unsigned int led_idx = 0; led_idx < new_zone.leds_count; led_idx++) + { + led new_led; + new_led.name = new_kb.GetKeyNameAt(led_idx); + new_led.value = new_kb.GetKeyValueAt(led_idx); + leds.push_back(new_led); + } + + zones.push_back(new_zone); + SetupColors(); + DeviceUpdateMode(); + update_device = true; +} + +void RGBController_Mountain60Keyboard::ResizeZone(int /*zone*/, int /*new_size*/) +{ + /*---------------------------------------------------------*\ + | This device does not support resizing zones | + \*---------------------------------------------------------*/ +} + +void RGBController_Mountain60Keyboard::DeviceUpdateLEDs() +{ + if (update_device.load()) + { + unsigned char* color_data = new unsigned char[(leds.size()*4)]; + + /*---------------------------------------------------------*\ + | Filling the color_data vector with progressive index | + | leaving space for RGB data | + \*---------------------------------------------------------*/ + for(unsigned int led_idx = 0; led_idx < leds.size(); led_idx++) + { + const unsigned int idx = led_idx * 4; + color_data[idx] = leds[led_idx].value; + color_data[idx + 1] = RGBGetRValue(colors[led_idx]); + color_data[idx + 2] = RGBGetGValue(colors[led_idx]); + color_data[idx + 3] = RGBGetBValue(colors[led_idx]); + } + + controller->SendDirect(modes[active_mode].brightness, color_data, (leds.size()*4)); + delete[] color_data; + } +} + +void RGBController_Mountain60Keyboard::UpdateZoneLEDs(int /*zone*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_Mountain60Keyboard::UpdateSingleLED(int /*led*/) +{ + DeviceUpdateLEDs(); +} + +void RGBController_Mountain60Keyboard::DeviceUpdateMode() +{ + static mode current_mode; + + if(modes[active_mode].value != current_mode.value && found_device.load()) + { + current_mode = modes[active_mode]; + controller->SelectMode(modes[active_mode].value); + } + + if(current_mode.color_mode != MODE_FLAG_HAS_PER_LED_COLOR && update_device.load()) + { + controller->SendModeDetails(&modes[active_mode]); + } +} + +void RGBController_Mountain60Keyboard::DeviceSaveMode() +{ + controller->SaveData(modes[active_mode].value); +} + +void RGBController_Mountain60Keyboard::UpdateMountain() +{ + while (mountaint_thread_running.load()) + { + std::this_thread::sleep_for(MOUNTAIN60_KEEP_LIVE_PERIOD); + + controller->UpdateData(); + + const char* Path = controller->GetPath(); + hid_device * rescan_device = hid_open_path(Path); + + if (rescan_device) + { + if (!found_device.load()) + { + controller->SetDevice(rescan_device); + found_device = true; + update_device = true; + } + } + else + { + if (found_device.load()) + { + update_device = false; + found_device = false; + } + } + } +} diff --git a/Controllers/MountainKeyboardController/RGBController_Mountain60Keyboard.h b/Controllers/MountainKeyboardController/RGBController_Mountain60Keyboard.h new file mode 100644 index 000000000..89a670836 --- /dev/null +++ b/Controllers/MountainKeyboardController/RGBController_Mountain60Keyboard.h @@ -0,0 +1,51 @@ +/*---------------------------------------------------------*\ +| RGBController_MountainKeyboard.h | +| | +| RGBController for Mountain keyboard | +| | +| O'D.Sæzl Jan 2023 | +| | +| This file is part of the OpenRGB project | +| SPDX-License-Identifier: GPL-2.0-only | +\*---------------------------------------------------------*/ + +#pragma once + +#include +#include "RGBController.h" +#include "Mountain60KeyboardController.h" + +#define MOUNTAIN60_KEYBOARD_BRIGHTNESS_MIN 0 +#define MOUNTAIN60_KEYBOARD_BRIGHTNESS_MAX 4 + +#define MOUNTAIN60_KEYBOARD_SPEED_MIN 0 +#define MOUNTAIN60_KEYBOARD_SPEED_MAX 4 +#define MOUNTAIN60_KEYBOARD_SPEED_DEFAULT 2 +#define MOUNTAIN60_KEEP_LIVE_PERIOD 500ms + + +class RGBController_Mountain60Keyboard : public RGBController +{ +public: + RGBController_Mountain60Keyboard(Mountain60KeyboardController* controller_ptr); + ~RGBController_Mountain60Keyboard(); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void DeviceUpdateMode(); + void DeviceSaveMode(); + void UpdateMountain(); + +private: + Mountain60KeyboardController* controller; + std::thread* mountain_thread; + std::atomic mountaint_thread_running; + std::atomic update_device; + std::atomic found_device; +};