Publish LumaOps source
This commit is contained in:
@@ -0,0 +1,426 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EVGAKeyboardController.cpp |
|
||||
| |
|
||||
| Driver for EVGA keyboard |
|
||||
| |
|
||||
| Chris M (Dr_No) 25 Nov 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "EVGAKeyboardController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
static uint8_t packet_map[EVGA_KEYBOARD_FULL_SIZE_KEYCOUNT + EVGA_KEYBOARD_Z20_EXTRA_KEYS] =
|
||||
{
|
||||
/*00 ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 */
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
||||
|
||||
/*10 F10 F11 F12 PRT SLK PBK ` 1 2 3 */
|
||||
11, 12, 13, 14, 15, 16, 22, 23, 24, 25,
|
||||
|
||||
/*20 4 5 6 7 8 9 0 - = BSP */
|
||||
26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
|
||||
|
||||
/*30 INS HME PUP TAB Q W E R T Y */
|
||||
36, 37, 38, 44, 45, 46, 47, 48, 49, 50,
|
||||
|
||||
/*40 U I O P [ ] \ DEL END PDN */
|
||||
51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
|
||||
|
||||
/*50 CAP A S D F G H J K L */
|
||||
66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
|
||||
|
||||
/*60 ; ' ENT LSH Z X C V B N */
|
||||
76, 77, 78, 83, 84, 85, 86, 87, 88, 89,
|
||||
|
||||
/*70 M , . / RSH UP LCTL LWIN LALT SPC */
|
||||
90, 91, 92, 93, 94, 96, 103, 104, 105, 106,
|
||||
|
||||
/*80 RALT RFNC MENU RCTL LFT DWN RGT NLK NM/ NM* */
|
||||
107, 108, 109, 110, 111, 112, 113, 39, 40, 41,
|
||||
|
||||
/*90 NM- NM+ NETR NM1 NM2 NM3 NM4 NM5 NM6 NM7 */
|
||||
42, 64, 101, 98, 99, 100, 79, 80, 81, 61,
|
||||
|
||||
/*100 NM8 NM9 NM0 NM. PRV PLY NXT MTE R1 R2 */
|
||||
62, 63, 114, 115, 18, 19, 20, 118, 176, 177,
|
||||
|
||||
/*110 R3 R4 R5 R6 R7 R8 R9 L1 L2 L3 */
|
||||
178, 179, 180, 181, 182, 183, 184, 160, 161, 162,
|
||||
|
||||
/*120 L4 L5 L6 L7 L8 L9 GM M1 M2 M3 */
|
||||
163, 164, 165, 166, 167, 168, 0, 21, 43, 65,
|
||||
|
||||
/*130 M4 M5 */
|
||||
82, 102
|
||||
};
|
||||
|
||||
EVGAKeyboardController::EVGAKeyboardController(hid_device* dev_handle, const char* path, uint16_t kb_pid, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
pid = kb_pid;
|
||||
|
||||
SetSleepTime();
|
||||
}
|
||||
|
||||
EVGAKeyboardController::~EVGAKeyboardController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string EVGAKeyboardController::GetName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string EVGAKeyboardController::GetSerial()
|
||||
{
|
||||
wchar_t serial_string[HID_MAX_STR];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, HID_MAX_STR);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string EVGAKeyboardController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
uint16_t EVGAKeyboardController::GetPid()
|
||||
{
|
||||
return(pid);
|
||||
}
|
||||
|
||||
void EVGAKeyboardController::SetLedsDirect(std::vector<RGBColor> colors)
|
||||
{
|
||||
uint8_t buffer[EVGA_KEYBOARD_CONTROLLER_ID_6_SIZE] = { 0x06, 0xEA, 0x02, 0x01 };
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Set up Direct packet |
|
||||
| packet_map is the index of the Key from full_matrix_map and |
|
||||
| the value is the position in the direct packet buffer |
|
||||
\*-----------------------------------------------------------------*/
|
||||
for(size_t i = 0; i < colors.size(); i++)
|
||||
{
|
||||
RGBColor key = colors[i];
|
||||
uint16_t offset = EVGA_KB_ZONE_BYTE + (packet_map[i] * 4);
|
||||
|
||||
buffer[offset + 0] = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
buffer[offset + 1] = RGBGetRValue(key);
|
||||
buffer[offset + 2] = RGBGetGValue(key);
|
||||
buffer[offset + 3] = RGBGetBValue(key);
|
||||
}
|
||||
|
||||
buffer[EVGA_KB_CRC_BYTE] = GetChecksum(&buffer[8], EVGA_KEYBOARD_CONTROLLER_ID_6_SIZE - EVGA_KB_ZONE_BYTE);
|
||||
hid_send_feature_report(dev, buffer, EVGA_KEYBOARD_CONTROLLER_ID_6_SIZE);
|
||||
}
|
||||
|
||||
void EVGAKeyboardController::SaveMode()
|
||||
{
|
||||
uint8_t buffer[EVGA_KEYBOARD_CONTROLLER_ID_4_SIZE] = { 0x04, 0xEA, 0x02, 0x12 };
|
||||
|
||||
hid_send_feature_report(dev, buffer, EVGA_KEYBOARD_CONTROLLER_ID_4_SIZE);
|
||||
}
|
||||
|
||||
void EVGAKeyboardController::SetMode(uint8_t mode, uint16_t speed, uint8_t brightness,
|
||||
uint8_t direction, std::vector<RGBColor> colors)
|
||||
{
|
||||
SetHWModes();
|
||||
SendMode(mode, direction);
|
||||
SendColour(mode, speed, brightness, direction, colors);
|
||||
}
|
||||
|
||||
void EVGAKeyboardController::GetStatus(mode *mode)
|
||||
{
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Gets the status of mode mode->value from the keyboard and then |
|
||||
| sets Colors, Brightness, Speed, Direction for the mode. |
|
||||
\*-----------------------------------------------------------------*/
|
||||
uint8_t buffer[EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE] = { 0x07, 0xEA, 0x02, 0x0C, 0x01 };
|
||||
buffer[EVGA_KB_MODE_BYTE] += mode->value;
|
||||
|
||||
hid_send_feature_report(dev, buffer, EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE);
|
||||
int result = hid_get_feature_report (dev, buffer, EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE);
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| If the read is successful fill in value from the packet |
|
||||
\*-----------------------------------------------------------------*/
|
||||
if(result > 0)
|
||||
{
|
||||
switch(mode->value)
|
||||
{
|
||||
case EVGA_KEYBOARD_CONTROLLER_MODE_STATIC:
|
||||
mode->brightness = FindColours(&buffer[EVGA_KB_SPEED_LSB], mode->colors_max, mode->colors);
|
||||
break;
|
||||
|
||||
case EVGA_KEYBOARD_CONTROLLER_MODE_BREATHING:
|
||||
mode->brightness = buffer[27];
|
||||
mode->speed = buffer[EVGA_KB_SPEED_LSB] << 8 | buffer[EVGA_KB_SPEED_MSB];
|
||||
mode->colors.push_back(ToRGBColor(buffer[28], buffer[29], buffer[30]));
|
||||
mode->colors.push_back(ToRGBColor(buffer[33], buffer[34], buffer[35]));
|
||||
break;
|
||||
|
||||
case EVGA_KEYBOARD_CONTROLLER_MODE_PULSE:
|
||||
mode->brightness = FindColours(&buffer[33], buffer[EVGA_KB_COLORS_SZ], mode->colors);
|
||||
mode->speed = buffer[EVGA_KB_SPEED_LSB] << 8 | buffer[EVGA_KB_SPEED_MSB];
|
||||
break;
|
||||
|
||||
case EVGA_KEYBOARD_CONTROLLER_MODE_SPIRAL:
|
||||
case EVGA_KEYBOARD_CONTROLLER_MODE_RAINBOW:
|
||||
case EVGA_KEYBOARD_CONTROLLER_MODE_TRIGGER:
|
||||
mode->direction = FindDirection(mode->value, buffer[11] + buffer[12]);
|
||||
mode->brightness = FindColours(&buffer[27], buffer[EVGA_KB_COLORS_SZ], mode->colors);
|
||||
mode->speed = buffer[EVGA_KB_SPEED_LSB] << 8 | buffer[EVGA_KB_SPEED_MSB];
|
||||
break;
|
||||
|
||||
case EVGA_KEYBOARD_CONTROLLER_MODE_STAR:
|
||||
mode->brightness = buffer[EVGA_KB_COLORS_SZ];
|
||||
mode->speed = buffer[EVGA_KB_SPEED_LSB];
|
||||
break;
|
||||
}
|
||||
LOG_DEBUG("[%s] Mode %d Setup with %d colours @ %04X speed and %02X brightness", name.c_str(), mode->value, mode->colors.size(), mode->speed, mode->brightness);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_INFO("[%s] An error occured reading data for mode %d", name.c_str(), mode->value);
|
||||
}
|
||||
}
|
||||
|
||||
void EVGAKeyboardController::SetHWModes()
|
||||
{
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Send Initialise Hardware Modes |
|
||||
\*-----------------------------------------------------------------*/
|
||||
uint8_t buffer[EVGA_KEYBOARD_CONTROLLER_ID_6_SIZE] = { 0x06, 0xEA, 0x02 };
|
||||
|
||||
hid_send_feature_report(dev, buffer, EVGA_KEYBOARD_CONTROLLER_ID_6_SIZE);
|
||||
}
|
||||
|
||||
void EVGAKeyboardController::SendMode(uint8_t mode, uint8_t direction)
|
||||
{
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Send Mode |
|
||||
\*-----------------------------------------------------------------*/
|
||||
uint8_t buffer[EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE] = { 0x07, 0xEA, 0x02, 0x0C };
|
||||
|
||||
buffer[EVGA_KB_ZONE_BYTE] = mode;
|
||||
buffer[EVGA_KB_DIR_BYTE] = direction;
|
||||
|
||||
buffer[EVGA_KB_CRC_BYTE] = GetChecksum(&buffer[8], EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE - EVGA_KB_ZONE_BYTE);
|
||||
hid_send_feature_report(dev, buffer, EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE);
|
||||
}
|
||||
|
||||
void EVGAKeyboardController::SendColour(uint8_t mode, uint16_t speed, uint8_t brightness, uint8_t direction, std::vector<RGBColor> colors)
|
||||
{
|
||||
uint8_t buffer[EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE] = { 0x07, 0xEA, 0x02, 0x0C };
|
||||
|
||||
speed *= (mode == EVGA_KEYBOARD_CONTROLLER_MODE_TRIGGER) ? 10 : 100;
|
||||
buffer[EVGA_KB_MODE_BYTE] += mode;
|
||||
buffer[EVGA_KB_ZONE_BYTE] = EVGA_KEYBOARD_CONTROLLER_ZONE_ALL_KEYS; //zone
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Static mode does not have speed but it will be overwritten |
|
||||
\*-----------------------------------------------------------------*/
|
||||
buffer[EVGA_KB_SPEED_LSB] = speed & 0xFF;
|
||||
buffer[EVGA_KB_SPEED_MSB] = speed >> 8;
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Static, Breathing and Star modes have fixed colour sizes |
|
||||
| buffer[26] will be overwritten for these modes |
|
||||
\*-----------------------------------------------------------------*/
|
||||
buffer[EVGA_KB_COLORS_SZ] = (uint8_t)colors.size();
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case EVGA_KEYBOARD_CONTROLLER_MODE_STATIC:
|
||||
FillColours(&buffer[24], brightness, colors);
|
||||
break;
|
||||
|
||||
case EVGA_KEYBOARD_CONTROLLER_MODE_BREATHING:
|
||||
for(size_t i = 0; i < colors.size(); i++)
|
||||
{
|
||||
uint8_t offset = (uint8_t)(26 + (i * 5));
|
||||
|
||||
buffer[offset + 0] = 0x0A;
|
||||
buffer[offset + 1] = brightness;
|
||||
buffer[offset + 2] = RGBGetRValue(colors[i]);
|
||||
buffer[offset + 3] = RGBGetGValue(colors[i]);
|
||||
buffer[offset + 4] = RGBGetBValue(colors[i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case EVGA_KEYBOARD_CONTROLLER_MODE_PULSE:
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Buffer 27 thru 32 could be defining a "Transition Color" |
|
||||
| 27 Identifier ?? |
|
||||
| 28 Time in ms ?? |
|
||||
| 29 - 32 Looks to be "Black" |
|
||||
\*-----------------------------------------------------------------*/
|
||||
buffer[27] = 0x0A;
|
||||
buffer[28] = 0x0A;
|
||||
buffer[29] = 0xFF;
|
||||
|
||||
FillColours(&buffer[33], brightness, colors);
|
||||
break;
|
||||
|
||||
case EVGA_KEYBOARD_CONTROLLER_MODE_SPIRAL:
|
||||
buffer[11] = direction;
|
||||
|
||||
FillColours(&buffer[27], brightness, colors);
|
||||
break;
|
||||
|
||||
case EVGA_KEYBOARD_CONTROLLER_MODE_RAINBOW:
|
||||
buffer[12] = direction;
|
||||
|
||||
FillColours(&buffer[27], brightness, colors);
|
||||
break;
|
||||
|
||||
case EVGA_KEYBOARD_CONTROLLER_MODE_TRIGGER:
|
||||
buffer[3]--; //Why EVGA??
|
||||
buffer[12] = direction;
|
||||
|
||||
FillColours(&buffer[27], brightness, colors);
|
||||
break;
|
||||
|
||||
case EVGA_KEYBOARD_CONTROLLER_MODE_STAR:
|
||||
buffer[3]++; //Why EVGA??
|
||||
buffer[26] = brightness;
|
||||
break;
|
||||
}
|
||||
|
||||
buffer[EVGA_KB_CRC_BYTE] = GetChecksum(&buffer[8], EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE - EVGA_KB_ZONE_BYTE);
|
||||
hid_send_feature_report(dev, buffer, EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE);
|
||||
}
|
||||
|
||||
void EVGAKeyboardController::FillColours(uint8_t * buffer, uint8_t brightness, std::vector<RGBColor> colors)
|
||||
{
|
||||
for(size_t i = 0; i < colors.size(); i++)
|
||||
{
|
||||
uint8_t offset = (uint8_t)(i * 4);
|
||||
|
||||
buffer[offset + 0] = brightness;
|
||||
buffer[offset + 1] = RGBGetRValue(colors[i]);
|
||||
buffer[offset + 2] = RGBGetGValue(colors[i]);
|
||||
buffer[offset + 3] = RGBGetBValue(colors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t EVGAKeyboardController::GetChecksum(uint8_t * data, size_t count)
|
||||
{
|
||||
uint8_t checksum = 0;
|
||||
|
||||
for(size_t i = 0; i < count; i++)
|
||||
{
|
||||
checksum -= data[i];
|
||||
}
|
||||
|
||||
return(checksum);
|
||||
}
|
||||
|
||||
uint8_t EVGAKeyboardController::FindDirection(uint8_t mode, uint8_t direction)
|
||||
{
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Converts EVGAs buffer direction value to OpenRGB's directions |
|
||||
\*-----------------------------------------------------------------*/
|
||||
uint8_t temp = 0;
|
||||
|
||||
for(size_t i = 0; i < sizeof(direction_map[mode]); i++)
|
||||
{
|
||||
if(direction_map[mode][i] == direction)
|
||||
{
|
||||
temp = direction_map[mode][i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(temp);
|
||||
}
|
||||
|
||||
uint8_t EVGAKeyboardController::FindColours(uint8_t * data, uint8_t count, std::vector<RGBColor> &colors)
|
||||
{
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Converts EVGAs buffer colours to OpenRGB's colours |
|
||||
\*-----------------------------------------------------------------*/
|
||||
colors.clear();
|
||||
|
||||
for(size_t i = 0; i < count; i++)
|
||||
{
|
||||
uint8_t offset = (uint8_t)(i * 4);
|
||||
|
||||
colors.push_back(ToRGBColor(data[offset + 1],data[offset + 2],data[offset + 3]));
|
||||
}
|
||||
|
||||
return(data[0]);
|
||||
}
|
||||
|
||||
uint8_t EVGAKeyboardController::GetMode()
|
||||
{
|
||||
static const uint16_t index = 1289;
|
||||
NFIPacket();
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Requests the current set mode from the keyboard |
|
||||
| |
|
||||
| Request: 04 ea 02 07 01 00 00 6c 00 00 00 00 00 00 00 00 00 |
|
||||
| Response: 04 ea 02 07 01 00 c0 6c 04 00 00 00 00 00 00 00 00 |
|
||||
| Key Count?? ⇗ |
|
||||
\*-----------------------------------------------------------------*/
|
||||
uint8_t buffer[EVGA_KEYBOARD_CONTROLLER_ID_3_SIZE] = { 0x08, 0xEA, 0x02, 0x01, 0xFE };
|
||||
|
||||
hid_send_feature_report(dev, buffer, EVGA_KEYBOARD_CONTROLLER_ID_3_SIZE);
|
||||
int result = hid_get_feature_report (dev, buffer, EVGA_KEYBOARD_CONTROLLER_ID_3_SIZE);
|
||||
|
||||
if(result > 0)
|
||||
{
|
||||
LOG_DEBUG("[%s] Returned mode %02X - %02X %02X %02X %02X %02X", name.c_str(), buffer[index], buffer[index-2], buffer[index-1], buffer[index], buffer[index+1], buffer[index+2]);
|
||||
return(buffer[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_INFO("[%s] An error occured reading current mode", name.c_str());
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
void EVGAKeyboardController::NFIPacket()
|
||||
{
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Not sure what this packet is doing but it appears to be |
|
||||
| required to retrieve the current mode from the (first) profile |
|
||||
\*-----------------------------------------------------------------*/
|
||||
uint8_t buffer1[EVGA_KEYBOARD_CONTROLLER_ID_4_SIZE] = { 0x04, 0xEA, 0x02, 0x33, 0x00, 0x00, 0x00, 0x01 };
|
||||
hid_send_feature_report(dev, buffer1, EVGA_KEYBOARD_CONTROLLER_ID_4_SIZE);
|
||||
|
||||
uint8_t buffer2[EVGA_KEYBOARD_CONTROLLER_ID_4_SIZE] = { 0x04, 0xEA, 0x02, 0x06, 0x01 };
|
||||
hid_send_feature_report(dev, buffer2, EVGA_KEYBOARD_CONTROLLER_ID_4_SIZE);
|
||||
}
|
||||
|
||||
void EVGAKeyboardController::SetSleepTime()
|
||||
{
|
||||
/*-----------------------------------------------------------------*\
|
||||
| After a set timer the LED lighting on this keyboard will "sleep" |
|
||||
\*-----------------------------------------------------------------*/
|
||||
const uint16_t minutes = 0; //Max value in Unleashed is 300min
|
||||
const uint8_t multiply = 0xEA;
|
||||
|
||||
uint8_t buffer1[EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE] = { 0x07, 0xEA, 0x02, 0x1B, 0x00, 0x00, 0x00, 0xFE, 0x02 };
|
||||
hid_send_feature_report(dev, buffer1, EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE);
|
||||
|
||||
uint8_t buffer2[EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE] = { 0x07, 0xEA, 0x02, 0x03 };
|
||||
|
||||
uint32_t sleep = minutes * multiply;
|
||||
buffer2[EVGA_KB_ZONE_BYTE] = (sleep == 0) ? 0 : EVGA_KEYBOARD_CONTROLLER_ZONE_ALL_KEYS; //zone
|
||||
buffer2[9] = sleep & 0xFF;
|
||||
buffer2[10] = (sleep >> 8) & 0xFF;
|
||||
buffer2[11] = (sleep >> 16) & 0xFF;
|
||||
|
||||
buffer2[EVGA_KB_CRC_BYTE] = GetChecksum(&buffer2[8], EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE - EVGA_KB_ZONE_BYTE);
|
||||
hid_send_feature_report(dev, buffer2, EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE);
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EVGAKeyboardController.h |
|
||||
| |
|
||||
| Driver for EVGA keyboard |
|
||||
| |
|
||||
| Chris M (Dr_No) 25 Nov 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "LogManager.h"
|
||||
#include "RGBController.h"
|
||||
|
||||
#define NA 0xFFFFFFFF
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
#define EVGA_KEYBOARD_CONTROLLER_ID_3_SIZE 1597
|
||||
#define EVGA_KEYBOARD_CONTROLLER_ID_4_SIZE 17
|
||||
#define EVGA_KEYBOARD_CONTROLLER_ID_6_SIZE 792
|
||||
#define EVGA_KEYBOARD_CONTROLLER_ID_7_SIZE 136
|
||||
#define EVGA_KEYBOARD_CONTROLLER_INTERRUPT_TIMEOUT 250
|
||||
|
||||
#define EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MIN 0
|
||||
#define EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX 255
|
||||
#define EVGA_KEYBOARD_FULL_SIZE_KEYCOUNT 108
|
||||
#define EVGA_KEYBOARD_Z20_EXTRA_KEYS 24
|
||||
#define EVGA_KEYBOARD_Z20_EXTRA_ZONES 3
|
||||
|
||||
static const uint8_t direction_map[8][4] =
|
||||
{
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 1, 0, 0, 0 }, //Spiral - Left = Anti Clockwise, Right = Clockwise
|
||||
{ 3, 2, 0, 1 }, //Rainbow
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 1, 2, 0 }, //Trigger - Right = Typing, Left = Single, Up = 3x3
|
||||
};
|
||||
|
||||
enum EVGA_Keyboard_Controller_Modes
|
||||
{
|
||||
EVGA_KEYBOARD_CONTROLLER_MODE_OFF = 0x00, //Turn off - All leds off
|
||||
EVGA_KEYBOARD_CONTROLLER_MODE_STATIC = 0x01, //Static Mode - Set entire zone to a single color.
|
||||
EVGA_KEYBOARD_CONTROLLER_MODE_BREATHING = 0x02, //Breathing Mode - Fades between fully off and fully on.
|
||||
EVGA_KEYBOARD_CONTROLLER_MODE_PULSE = 0x03, //Flashing Mode - Abruptly changing between fully off and fully on.
|
||||
EVGA_KEYBOARD_CONTROLLER_MODE_SPIRAL = 0x04, //Spiral Mode - All keys light in a colourful spiral
|
||||
EVGA_KEYBOARD_CONTROLLER_MODE_RAINBOW = 0x05, //Rainbow Wave Mode - Cycle thru the color spectrum as a wave across all LEDs
|
||||
EVGA_KEYBOARD_CONTROLLER_MODE_STAR = 0x06, //Starry Night effect
|
||||
EVGA_KEYBOARD_CONTROLLER_MODE_TRIGGER = 0x07, //Key reactive
|
||||
EVGA_KEYBOARD_CONTROLLER_MODE_DIRECT = 0xFF, //Direct Led Control - Independently set LEDs in zone
|
||||
};
|
||||
|
||||
enum EVGA_Keyboard_Controller_Zones
|
||||
{
|
||||
EVGA_KEYBOARD_CONTROLLER_ZONE_NUMPAD_KEYS = (1 << 0),
|
||||
EVGA_KEYBOARD_CONTROLLER_ZONE_FUNCTION_KEYS = (1 << 1),
|
||||
EVGA_KEYBOARD_CONTROLLER_ZONE_NUMBER_KEYS = (1 << 2),
|
||||
EVGA_KEYBOARD_CONTROLLER_ZONE_ARROW_KEYS = (1 << 3),
|
||||
EVGA_KEYBOARD_CONTROLLER_ZONE_WASD_KEYS = (1 << 4),
|
||||
EVGA_KEYBOARD_CONTROLLER_ZONE_ALL_KEYS = (1 << 7),
|
||||
};
|
||||
|
||||
enum EVGA_Keyboard_Controller_Byte_Map
|
||||
{
|
||||
EVGA_KB_REPORT_BYTE = 0,
|
||||
EVGA_KB_COMMAND_BYTE = 1,
|
||||
EVGA_KB_FUNCTION_BYTE = 2,
|
||||
EVGA_KB_MODE_BYTE = 3,
|
||||
EVGA_KB_CRC_BYTE = 7,
|
||||
EVGA_KB_ZONE_BYTE = 8,
|
||||
EVGA_KB_DIR_BYTE = 9,
|
||||
EVGA_KB_SPEED_LSB = 24,
|
||||
EVGA_KB_SPEED_MSB = 25,
|
||||
EVGA_KB_COLORS_SZ = 26,
|
||||
};
|
||||
|
||||
enum EVGA_Keyboard_Controller_Speed
|
||||
{
|
||||
EVGA_KEYBOARD_CONTROLLER_SPEED_SLOWEST = 0x64, // Slowest speed
|
||||
EVGA_KEYBOARD_CONTROLLER_SPEED_SLOWISH = 0x3E, // Slowish speed
|
||||
EVGA_KEYBOARD_CONTROLLER_SPEED_NORMAL = 0x32, // Normal speed
|
||||
EVGA_KEYBOARD_CONTROLLER_SPEED_FASTEST = 0x05, // Fastest speed
|
||||
};
|
||||
|
||||
class EVGAKeyboardController
|
||||
{
|
||||
public:
|
||||
EVGAKeyboardController(hid_device* dev_handle, const char* path, uint16_t kb_pid, std::string dev_name);
|
||||
~EVGAKeyboardController();
|
||||
|
||||
std::string GetName();
|
||||
std::string GetSerial();
|
||||
std::string GetLocation();
|
||||
|
||||
void SaveMode();
|
||||
void SetHWModes();
|
||||
void SetLedsDirect(std::vector<RGBColor> colors);
|
||||
void SetMode(uint8_t mode, uint16_t speed, uint8_t brightness,
|
||||
uint8_t direction, std::vector<RGBColor> colors);
|
||||
void SetSleepTime();
|
||||
void GetStatus(mode *mode);
|
||||
uint8_t GetMode();
|
||||
uint16_t GetPid();
|
||||
private:
|
||||
std::string name;
|
||||
std::string location;
|
||||
hid_device* dev;
|
||||
uint16_t pid;
|
||||
|
||||
void NFIPacket();
|
||||
void FillColours(uint8_t * buffer, uint8_t brightness, std::vector<RGBColor> colors);
|
||||
void SendMode(uint8_t mode, uint8_t direction);
|
||||
void SendColour(uint8_t mode, uint16_t speed, uint8_t brightness, uint8_t direction, std::vector<RGBColor> colors);
|
||||
uint8_t GetChecksum(uint8_t * data, size_t count);
|
||||
|
||||
uint8_t FindDirection(uint8_t mode, uint8_t direction);
|
||||
uint8_t FindColours(uint8_t * data, uint8_t count, std::vector<RGBColor> &colors);
|
||||
};
|
||||
@@ -0,0 +1,549 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_EVGAKeyboard.cpp |
|
||||
| |
|
||||
| RGBController for EVGA keyboard |
|
||||
| |
|
||||
| Chris M (Dr_No) 25 Nov 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <time.h>
|
||||
#include "Colors.h"
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "RGBController_EVGAKeyboard.h"
|
||||
|
||||
static unsigned int full_matrix_map[6][21] =
|
||||
{
|
||||
{ 0, NA, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 104, 105, 106, 107 },
|
||||
{ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 87, 88, 89, 90 },
|
||||
{ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 99, 100, 101, 91 },
|
||||
{ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, NA, NA, NA, NA, 96, 97, 98, NA },
|
||||
{ 63, NA, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, NA, NA, 75, NA, 93, 94, 95, 92 },
|
||||
{ 76, 77, 78, NA, NA, NA, 79, NA, NA, NA, 80, 81, 82, 83, 84, 85, 86, 102, NA, 103, NA }
|
||||
};
|
||||
|
||||
static unsigned int Z20_extra_zones[EVGA_KEYBOARD_Z20_EXTRA_ZONES][9] =
|
||||
{
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8 }, //Index 108
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8 }, //Index 117
|
||||
{ 0, 1, 2, 3, 4, 5, NA, NA, NA } //Index 126
|
||||
};
|
||||
|
||||
const char* Z20_zone_names[EVGA_KEYBOARD_Z20_EXTRA_ZONES] =
|
||||
{
|
||||
"Right Side LEDs",
|
||||
"Left Side LEDs",
|
||||
"Macro Keys"
|
||||
};
|
||||
|
||||
static const char *led_names[] =
|
||||
{
|
||||
KEY_EN_ESCAPE, // 00
|
||||
KEY_EN_F1,
|
||||
KEY_EN_F2,
|
||||
KEY_EN_F3,
|
||||
KEY_EN_F4,
|
||||
KEY_EN_F5,
|
||||
KEY_EN_F6,
|
||||
KEY_EN_F7,
|
||||
KEY_EN_F8,
|
||||
KEY_EN_F9,
|
||||
KEY_EN_F10, // 10
|
||||
KEY_EN_F11,
|
||||
KEY_EN_F12,
|
||||
KEY_EN_PRINT_SCREEN,
|
||||
KEY_EN_SCROLL_LOCK,
|
||||
KEY_EN_PAUSE_BREAK,
|
||||
|
||||
KEY_EN_BACK_TICK,
|
||||
KEY_EN_1,
|
||||
KEY_EN_2,
|
||||
KEY_EN_3,
|
||||
KEY_EN_4, // 20
|
||||
KEY_EN_5,
|
||||
KEY_EN_6,
|
||||
KEY_EN_7,
|
||||
KEY_EN_8,
|
||||
KEY_EN_9,
|
||||
KEY_EN_0,
|
||||
KEY_EN_MINUS,
|
||||
KEY_EN_EQUALS,
|
||||
KEY_EN_BACKSPACE,
|
||||
KEY_EN_INSERT, // 30
|
||||
KEY_EN_HOME,
|
||||
KEY_EN_PAGE_UP,
|
||||
|
||||
KEY_EN_TAB,
|
||||
KEY_EN_Q,
|
||||
KEY_EN_W,
|
||||
KEY_EN_E,
|
||||
KEY_EN_R,
|
||||
KEY_EN_T,
|
||||
KEY_EN_Y,
|
||||
KEY_EN_U, // 40
|
||||
KEY_EN_I,
|
||||
KEY_EN_O,
|
||||
KEY_EN_P,
|
||||
KEY_EN_LEFT_BRACKET,
|
||||
KEY_EN_RIGHT_BRACKET,
|
||||
KEY_EN_ANSI_BACK_SLASH,
|
||||
KEY_EN_DELETE,
|
||||
KEY_EN_END,
|
||||
KEY_EN_PAGE_DOWN,
|
||||
|
||||
KEY_EN_CAPS_LOCK, // 50
|
||||
KEY_EN_A,
|
||||
KEY_EN_S,
|
||||
KEY_EN_D,
|
||||
KEY_EN_F,
|
||||
KEY_EN_G,
|
||||
KEY_EN_H,
|
||||
KEY_EN_J,
|
||||
KEY_EN_K,
|
||||
KEY_EN_L,
|
||||
KEY_EN_SEMICOLON, // 60
|
||||
KEY_EN_QUOTE,
|
||||
KEY_EN_ANSI_ENTER,
|
||||
|
||||
KEY_EN_LEFT_SHIFT,
|
||||
KEY_EN_Z,
|
||||
KEY_EN_X,
|
||||
KEY_EN_C,
|
||||
KEY_EN_V,
|
||||
KEY_EN_B,
|
||||
KEY_EN_N,
|
||||
KEY_EN_M, // 70
|
||||
KEY_EN_COMMA,
|
||||
KEY_EN_PERIOD,
|
||||
KEY_EN_FORWARD_SLASH,
|
||||
KEY_EN_RIGHT_SHIFT,
|
||||
KEY_EN_UP_ARROW,
|
||||
|
||||
KEY_EN_LEFT_CONTROL,
|
||||
KEY_EN_LEFT_WINDOWS,
|
||||
KEY_EN_LEFT_ALT,
|
||||
KEY_EN_SPACE,
|
||||
KEY_EN_RIGHT_ALT, // 80
|
||||
KEY_EN_RIGHT_FUNCTION,
|
||||
KEY_EN_MENU,
|
||||
KEY_EN_RIGHT_CONTROL,
|
||||
KEY_EN_LEFT_ARROW,
|
||||
KEY_EN_DOWN_ARROW,
|
||||
KEY_EN_RIGHT_ARROW,
|
||||
|
||||
KEY_EN_NUMPAD_LOCK,
|
||||
KEY_EN_NUMPAD_DIVIDE,
|
||||
KEY_EN_NUMPAD_TIMES,
|
||||
KEY_EN_NUMPAD_MINUS, // 90
|
||||
KEY_EN_NUMPAD_PLUS,
|
||||
KEY_EN_NUMPAD_ENTER,
|
||||
KEY_EN_NUMPAD_1,
|
||||
KEY_EN_NUMPAD_2,
|
||||
KEY_EN_NUMPAD_3,
|
||||
KEY_EN_NUMPAD_4,
|
||||
KEY_EN_NUMPAD_5,
|
||||
KEY_EN_NUMPAD_6,
|
||||
KEY_EN_NUMPAD_7,
|
||||
KEY_EN_NUMPAD_8, // 100
|
||||
KEY_EN_NUMPAD_9,
|
||||
KEY_EN_NUMPAD_0,
|
||||
KEY_EN_NUMPAD_PERIOD,
|
||||
|
||||
KEY_EN_MEDIA_PREVIOUS,
|
||||
KEY_EN_MEDIA_PLAY_PAUSE,
|
||||
KEY_EN_MEDIA_NEXT,
|
||||
KEY_EN_MEDIA_MUTE,
|
||||
|
||||
"Key: Right LED 1",
|
||||
"Key: Right LED 2",
|
||||
"Key: Right LED 3", //110
|
||||
"Key: Right LED 4",
|
||||
"Key: Right LED 5",
|
||||
"Key: Right LED 6",
|
||||
"Key: Right LED 7",
|
||||
"Key: Right LED 8",
|
||||
"Key: Right LED 9",
|
||||
|
||||
"Key: Left LED 1",
|
||||
"Key: Left LED 2",
|
||||
"Key: Left LED 3",
|
||||
"Key: Left LED 4", //120
|
||||
"Key: Left LED 5",
|
||||
"Key: Left LED 6",
|
||||
"Key: Left LED 7",
|
||||
"Key: Left LED 8",
|
||||
"Key: Left LED 9",
|
||||
|
||||
"Key: Feature Button",
|
||||
"Key: Macro 1",
|
||||
"Key: Macro 2",
|
||||
"Key: Macro 3",
|
||||
"Key: Macro 4", //130
|
||||
"Key: Macro 5",
|
||||
};
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name EVGA USB Keyboard
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectEVGAKeyboardControllers
|
||||
@comment The EVGA USB keyboard controller currently supports
|
||||
the Z15 (both ISO & ANSI) as well as the Z20 ANSI keyboards
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_EVGAKeyboard::RGBController_EVGAKeyboard(EVGAKeyboardController* controller_ptr)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Initialise the random functions from the clock |
|
||||
\*-----------------------------------------------------*/
|
||||
std::srand((unsigned int)time(NULL));
|
||||
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetName();
|
||||
vendor = "EVGA";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "EVGA Keyboard Device";
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = EVGA_KEYBOARD_CONTROLLER_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = EVGA_KEYBOARD_CONTROLLER_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.brightness_min = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MIN;
|
||||
Static.brightness_max = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
|
||||
//controller->GetStatus(&Static);
|
||||
Static.colors.resize(Static.colors_max);
|
||||
Static.brightness = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = EVGA_KEYBOARD_CONTROLLER_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 2;
|
||||
Breathing.brightness_min = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Breathing.speed_min = EVGA_KEYBOARD_CONTROLLER_SPEED_SLOWEST;
|
||||
Breathing.speed_max = EVGA_KEYBOARD_CONTROLLER_SPEED_FASTEST;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
|
||||
//controller->GetStatus(&Breathing);
|
||||
Breathing.colors.resize(Breathing.colors_max);
|
||||
Breathing.brightness = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Breathing.speed = EVGA_KEYBOARD_CONTROLLER_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Pulse;
|
||||
Pulse.name = "Flashing";
|
||||
Pulse.value = EVGA_KEYBOARD_CONTROLLER_MODE_PULSE;
|
||||
Pulse.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Pulse.colors_min = 2;
|
||||
Pulse.colors_max = 7;
|
||||
Pulse.brightness_min = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MIN;
|
||||
Pulse.brightness_max = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Pulse.speed_min = EVGA_KEYBOARD_CONTROLLER_SPEED_SLOWEST;
|
||||
Pulse.speed_max = EVGA_KEYBOARD_CONTROLLER_SPEED_FASTEST;
|
||||
Pulse.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
|
||||
//controller->GetStatus(&Pulse);
|
||||
Pulse.colors.resize(Pulse.colors_max);
|
||||
Pulse.brightness = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Pulse.speed = EVGA_KEYBOARD_CONTROLLER_SPEED_NORMAL;
|
||||
modes.push_back(Pulse);
|
||||
|
||||
mode Spiral;
|
||||
Spiral.name = "Spiral";
|
||||
Spiral.value = EVGA_KEYBOARD_CONTROLLER_MODE_SPIRAL;
|
||||
Spiral.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Spiral.colors_min = 7;
|
||||
Spiral.colors_max = 7;
|
||||
Spiral.brightness_min = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MIN;
|
||||
Spiral.brightness_max = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Spiral.speed_min = EVGA_KEYBOARD_CONTROLLER_SPEED_SLOWEST;
|
||||
Spiral.speed_max = EVGA_KEYBOARD_CONTROLLER_SPEED_FASTEST;
|
||||
Spiral.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
|
||||
//controller->GetStatus(&Spiral);
|
||||
Spiral.colors.resize(Spiral.colors_max);
|
||||
Spiral.colors = { COLOR_RED, COLOR_DARKORANGE, COLOR_YELLOW, COLOR_LIME, COLOR_BLUE, COLOR_DARKVIOLET, COLOR_MAGENTA};
|
||||
Spiral.brightness = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Spiral.speed = EVGA_KEYBOARD_CONTROLLER_SPEED_NORMAL;
|
||||
modes.push_back(Spiral);
|
||||
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow Wave";
|
||||
Rainbow.value = EVGA_KEYBOARD_CONTROLLER_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Rainbow.colors_min = 3;
|
||||
Rainbow.colors_max = 7;
|
||||
Rainbow.brightness_min = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MIN;
|
||||
Rainbow.brightness_max = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Rainbow.speed_min = EVGA_KEYBOARD_CONTROLLER_SPEED_SLOWISH;
|
||||
Rainbow.speed_max = EVGA_KEYBOARD_CONTROLLER_SPEED_FASTEST;
|
||||
Rainbow.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
|
||||
//controller->GetStatus(&Rainbow);
|
||||
Rainbow.colors.resize(Rainbow.colors_max);
|
||||
Rainbow.colors = { COLOR_RED, COLOR_DARKORANGE, COLOR_YELLOW, COLOR_LIME, COLOR_BLUE, COLOR_DARKVIOLET, COLOR_MAGENTA};
|
||||
Rainbow.brightness = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Rainbow.speed = EVGA_KEYBOARD_CONTROLLER_SPEED_NORMAL;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode Star;
|
||||
Star.name = "Star Shining";
|
||||
Star.value = EVGA_KEYBOARD_CONTROLLER_MODE_STAR;
|
||||
Star.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Star.brightness_min = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MIN;
|
||||
Star.brightness_max = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Star.speed_min = EVGA_KEYBOARD_CONTROLLER_SPEED_SLOWEST;
|
||||
Star.speed_max = EVGA_KEYBOARD_CONTROLLER_SPEED_FASTEST;
|
||||
Star.color_mode = MODE_COLORS_NONE;
|
||||
|
||||
//controller->GetStatus(&Star);
|
||||
Star.brightness = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Star.speed = EVGA_KEYBOARD_CONTROLLER_SPEED_NORMAL;
|
||||
modes.push_back(Star);
|
||||
|
||||
mode Typing;
|
||||
Typing.name = "Typing Lighting";
|
||||
Typing.value = EVGA_KEYBOARD_CONTROLLER_MODE_TRIGGER;
|
||||
Typing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Typing.colors_min = 1;
|
||||
Typing.colors_max = 7;
|
||||
Typing.brightness_min = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MIN;
|
||||
Typing.brightness_max = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Typing.speed_min = EVGA_KEYBOARD_CONTROLLER_SPEED_SLOWEST;
|
||||
Typing.speed_max = EVGA_KEYBOARD_CONTROLLER_SPEED_FASTEST;
|
||||
Typing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
|
||||
//controller->GetStatus(&Typing);
|
||||
Typing.direction = 0;
|
||||
Typing.colors.resize(Typing.colors_max);
|
||||
Typing.colors = { COLOR_RED, COLOR_DARKORANGE, COLOR_YELLOW, COLOR_LIME, COLOR_BLUE, COLOR_DARKVIOLET, COLOR_MAGENTA};
|
||||
Typing.brightness = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Typing.speed = EVGA_KEYBOARD_CONTROLLER_SPEED_NORMAL;
|
||||
modes.push_back(Typing);
|
||||
|
||||
mode Single;
|
||||
Single.name = "Reactive (Single Key)";
|
||||
Single.value = EVGA_KEYBOARD_CONTROLLER_MODE_TRIGGER;
|
||||
Single.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Single.colors_min = 1;
|
||||
Single.colors_max = 7;
|
||||
Single.brightness_min = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MIN;
|
||||
Single.brightness_max = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Single.speed_min = EVGA_KEYBOARD_CONTROLLER_SPEED_SLOWEST;
|
||||
Single.speed_max = EVGA_KEYBOARD_CONTROLLER_SPEED_FASTEST;
|
||||
Single.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
|
||||
//controller->GetStatus(&Single);
|
||||
Single.direction = 1;
|
||||
Single.colors.resize(Single.colors_max);
|
||||
Single.colors = { COLOR_RED, COLOR_DARKORANGE, COLOR_YELLOW, COLOR_LIME, COLOR_BLUE, COLOR_DARKVIOLET, COLOR_MAGENTA};
|
||||
Single.brightness = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
Single.speed = EVGA_KEYBOARD_CONTROLLER_SPEED_NORMAL;
|
||||
modes.push_back(Single);
|
||||
|
||||
mode ThreeBy3;
|
||||
ThreeBy3.name = "Reactive (3x3 Key)";
|
||||
ThreeBy3.value = EVGA_KEYBOARD_CONTROLLER_MODE_TRIGGER;
|
||||
ThreeBy3.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
ThreeBy3.colors_min = 1;
|
||||
ThreeBy3.colors_max = 7;
|
||||
ThreeBy3.brightness_min = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MIN;
|
||||
ThreeBy3.brightness_max = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
ThreeBy3.speed_min = EVGA_KEYBOARD_CONTROLLER_SPEED_SLOWEST;
|
||||
ThreeBy3.speed_max = EVGA_KEYBOARD_CONTROLLER_SPEED_FASTEST;
|
||||
ThreeBy3.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
|
||||
//controller->GetStatus(&ThreeBy3);
|
||||
ThreeBy3.direction = 2;
|
||||
ThreeBy3.colors.resize(ThreeBy3.colors_max);
|
||||
ThreeBy3.colors = { COLOR_RED, COLOR_DARKORANGE, COLOR_YELLOW, COLOR_LIME, COLOR_BLUE, COLOR_DARKVIOLET, COLOR_MAGENTA};
|
||||
ThreeBy3.brightness = EVGA_KEYBOARD_CONTROLLER_BRIGHTNESS_MAX;
|
||||
ThreeBy3.speed = EVGA_KEYBOARD_CONTROLLER_SPEED_NORMAL;
|
||||
modes.push_back(ThreeBy3);
|
||||
|
||||
//uint8_t set_mode = controller->GetMode();
|
||||
//active_mode = set_mode;
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_EVGAKeyboard::~RGBController_EVGAKeyboard()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_EVGAKeyboard::SetupZones()
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Set up the base configuration common to |
|
||||
| Z15 and Z20 |
|
||||
\*-------------------------------------------------*/
|
||||
zone KB_zone;
|
||||
KB_zone.name = ZONE_EN_KEYBOARD;
|
||||
KB_zone.type = ZONE_TYPE_MATRIX;
|
||||
KB_zone.leds_min = EVGA_KEYBOARD_FULL_SIZE_KEYCOUNT;
|
||||
KB_zone.leds_max = EVGA_KEYBOARD_FULL_SIZE_KEYCOUNT;
|
||||
KB_zone.leds_count = EVGA_KEYBOARD_FULL_SIZE_KEYCOUNT;
|
||||
|
||||
KB_zone.matrix_map = new matrix_map_type;
|
||||
KB_zone.matrix_map->height = 6;
|
||||
KB_zone.matrix_map->width = 21;
|
||||
KB_zone.matrix_map->map = (unsigned int *)&full_matrix_map;
|
||||
zones.push_back(KB_zone);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Add configuration for the Z20 |
|
||||
\*-------------------------------------------------*/
|
||||
if(controller->GetPid() == 0x260A || controller->GetPid() == 0x2610)
|
||||
{
|
||||
|
||||
for(uint8_t i = 0; i < EVGA_KEYBOARD_Z20_EXTRA_ZONES; i++)
|
||||
{
|
||||
uint8_t zone_size = sizeof(Z20_extra_zones[i]) / sizeof(Z20_extra_zones[i][0]);
|
||||
|
||||
for(uint8_t count = 0; count < zone_size; count++)
|
||||
{
|
||||
if(Z20_extra_zones[i][count] == NA)
|
||||
{
|
||||
zone_size = count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
zone new_zone;
|
||||
new_zone.name = Z20_zone_names[i];
|
||||
new_zone.type = ZONE_TYPE_MATRIX;
|
||||
new_zone.leds_min = zone_size;
|
||||
new_zone.leds_max = zone_size;
|
||||
new_zone.leds_count = zone_size;
|
||||
|
||||
new_zone.matrix_map = new matrix_map_type;
|
||||
new_zone.matrix_map->height = 1;
|
||||
new_zone.matrix_map->width = zone_size;
|
||||
new_zone.matrix_map->map = (unsigned int *)&Z20_extra_zones[i];
|
||||
zones.push_back(new_zone);
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Clear any existing color/LED configuration |
|
||||
\*-------------------------------------------------*/
|
||||
leds.clear();
|
||||
colors.clear();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up leds |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t zone_index = 0; zone_index < zones.size(); zone_index++)
|
||||
{
|
||||
unsigned int zone_offset = (unsigned int)leds.size();
|
||||
|
||||
for(unsigned int led_index = 0; led_index < zones[zone_index].leds_count; led_index++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.value = led_index + zone_offset;
|
||||
new_led.name = led_names[new_led.value];
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_EVGAKeyboard::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_EVGAKeyboard::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetLedsDirect(colors);
|
||||
}
|
||||
|
||||
void RGBController_EVGAKeyboard::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
std::vector<RGBColor> colour;
|
||||
for(size_t i = 0; i < zones[zone].leds_count; i++)
|
||||
{
|
||||
colour.push_back(zones[zone].colors[i]);
|
||||
}
|
||||
|
||||
controller->SetLedsDirect(colour);
|
||||
}
|
||||
|
||||
void RGBController_EVGAKeyboard::UpdateSingleLED(int led)
|
||||
{
|
||||
std::vector<RGBColor> colour;
|
||||
colour.push_back(colors[led]);
|
||||
|
||||
controller->SetLedsDirect(colour);
|
||||
}
|
||||
|
||||
void RGBController_EVGAKeyboard::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| No mode set packets required for Direct mode but an |
|
||||
| extra packet is sent when switching back to HW modes |
|
||||
\*---------------------------------------------------------*/
|
||||
mode set_mode = modes[active_mode];
|
||||
|
||||
if(current_mode == EVGA_KEYBOARD_CONTROLLER_MODE_DIRECT)
|
||||
{
|
||||
controller->SetHWModes();
|
||||
}
|
||||
current_mode = set_mode.value;
|
||||
|
||||
if(set_mode.value == EVGA_KEYBOARD_CONTROLLER_MODE_DIRECT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Random colours are generated randoms from software |
|
||||
\*---------------------------------------------------------*/
|
||||
uint8_t direction = direction_map[set_mode.value][set_mode.direction];
|
||||
std::vector<RGBColor> colours = (set_mode.colors);
|
||||
|
||||
if(set_mode.color_mode == MODE_COLORS_RANDOM)
|
||||
{
|
||||
for(unsigned int i = 0; i < colours.size(); i++)
|
||||
{
|
||||
colours[i] = GetRandomColor();
|
||||
}
|
||||
}
|
||||
|
||||
controller->SetMode( set_mode.value, set_mode.speed, set_mode.brightness, direction, colours );
|
||||
}
|
||||
|
||||
void RGBController_EVGAKeyboard::DeviceSaveMode()
|
||||
{
|
||||
controller->SaveMode();
|
||||
}
|
||||
|
||||
RGBColor RGBController_EVGAKeyboard::GetRandomColor()
|
||||
{
|
||||
return (rand() % 16777215);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_EVGAKeyboard.h |
|
||||
| |
|
||||
| RGBController for EVGA keyboard |
|
||||
| |
|
||||
| Chris M (Dr_No) 25 Nov 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "EVGAKeyboardController.h"
|
||||
|
||||
class RGBController_EVGAKeyboard : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_EVGAKeyboard(EVGAKeyboardController* controller_ptr);
|
||||
~RGBController_EVGAKeyboard();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
uint8_t current_mode;
|
||||
|
||||
int GetDeviceMode();
|
||||
RGBColor GetRandomColor();
|
||||
|
||||
EVGAKeyboardController* controller;
|
||||
};
|
||||
@@ -0,0 +1,345 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EVGAMouseController.cpp |
|
||||
| |
|
||||
| Driver for EVGA mouse |
|
||||
| |
|
||||
| Cooper Knaak 23 Jan 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include "EVGAMouseController.h"
|
||||
#include "LogManager.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
#define HID_MAX_STR 255
|
||||
#define EVGA_PERIPHERAL_LED_SOURCE_OF_TRUTH EVGA_PERIPHERAL_LED_LOGO
|
||||
/*----------------------------------------------------------------*\
|
||||
| Maximum number of attempts to read from a device before failing. |
|
||||
\*----------------------------------------------------------------*/
|
||||
#define EVGA_PERIPHERAL_MAX_ATTEMPTS 100
|
||||
/*-----------------------------------------------------------------*\
|
||||
| The delay between sending packets to the device in wireless mode. |
|
||||
| In wireless mode, sending packets too close to each other causes |
|
||||
| them to have no effect, despite the device responding properly. |
|
||||
\*-----------------------------------------------------------------*/
|
||||
#define EVGA_PERIPHERAL_PACKET_DELAY std::chrono::milliseconds(10)
|
||||
|
||||
/*--------------------------------------------------------------------------------*\
|
||||
| Returns true if both buffers have equal bytes at each position, false otherwise. |
|
||||
| Each buffer must be an array of bytes at least size bytes long. |
|
||||
\*--------------------------------------------------------------------------------*/
|
||||
static bool BuffersAreEqual(unsigned char *buffer1, unsigned char *buffer2, int size)
|
||||
{
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
if(buffer1[i] != buffer2[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
EVGAMouseController::EVGAMouseController(hid_device* dev_handle, char * path, int connection_type, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
this->connection_type = connection_type;
|
||||
|
||||
led_states.resize(EVGA_PERIPHERAL_LED_COUNT);
|
||||
for(EVGAMouseControllerDeviceState &led_state : led_states)
|
||||
{
|
||||
led_state.mode = EVGA_PERIPHERAL_MODE_STATIC;
|
||||
led_state.brightness = 255;
|
||||
led_state.speed = 100;
|
||||
led_state.colors.resize(1);
|
||||
led_state.colors[0] = ToRGBColor(255, 255, 255);
|
||||
}
|
||||
}
|
||||
|
||||
EVGAMouseController::~EVGAMouseController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string EVGAMouseController::GetName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string EVGAMouseController::GetSerial()
|
||||
{
|
||||
wchar_t serial_string[HID_MAX_STR];
|
||||
int ret = hid_get_indexed_string(dev, 2, serial_string, HID_MAX_STR);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string EVGAMouseController::GetLocation()
|
||||
{
|
||||
return location;
|
||||
}
|
||||
|
||||
uint8_t EVGAMouseController::GetMode()
|
||||
{
|
||||
return GetState().mode;
|
||||
}
|
||||
|
||||
EVGAMouseControllerDeviceState EVGAMouseController::GetState()
|
||||
{
|
||||
RefreshDeviceState(EVGA_PERIPHERAL_LED_SOURCE_OF_TRUTH);
|
||||
return led_states[EVGA_PERIPHERAL_LED_SOURCE_OF_TRUTH];
|
||||
}
|
||||
|
||||
RGBColor EVGAMouseController::GetColorOfLed(int led)
|
||||
{
|
||||
RefreshDeviceState(led);
|
||||
return led_states[led].colors[0];
|
||||
}
|
||||
|
||||
void EVGAMouseController::SetMode(uint8_t mode, uint8_t index)
|
||||
{
|
||||
unsigned char buffer[EVGA_PERIPHERAL_PACKET_SIZE] =
|
||||
{
|
||||
0x00, /* report id - must be 0x00 according to hid_send_feature_report */
|
||||
0x00, 0x00, 0x00, 0x1D, /* header bits - always the same */
|
||||
0x02, 0x81, 0x01 /* 0x81 sets the mode, which is specified below. */
|
||||
};
|
||||
|
||||
buffer[EVGA_PERIPHERAL_LED_INDEX_BYTE] = index;
|
||||
buffer[EVGA_PERIPHERAL_MODE_BYTE] = mode;
|
||||
int err = hid_send_feature_report(dev, buffer, EVGA_PERIPHERAL_PACKET_SIZE);
|
||||
if(err == -1)
|
||||
{
|
||||
const wchar_t* err_str = hid_error(dev);
|
||||
LOG_DEBUG("[%s] Error writing buffer %s", name.c_str(), err_str);
|
||||
}
|
||||
led_states[index].mode = mode;
|
||||
err = hid_get_feature_report(dev, buffer, EVGA_PERIPHERAL_PACKET_SIZE);
|
||||
if(err == -1)
|
||||
{
|
||||
const wchar_t* err_str = hid_error(dev);
|
||||
LOG_DEBUG("[%s] Error reading buffer %s", name.c_str(), err_str);
|
||||
}
|
||||
}
|
||||
|
||||
void EVGAMouseController::SetLed(uint8_t index, uint8_t brightness, uint8_t speed, RGBColor color)
|
||||
{
|
||||
std::vector<RGBColor> colors;
|
||||
colors.push_back(color);
|
||||
|
||||
SetLed(index, brightness, speed, colors, false);
|
||||
}
|
||||
|
||||
void EVGAMouseController::SetLed(uint8_t index, uint8_t brightness, uint8_t speed, const std::vector<RGBColor>& colors)
|
||||
{
|
||||
SetLed(index, brightness, speed, colors, false);
|
||||
}
|
||||
|
||||
void EVGAMouseController::SetLedAndActivate(uint8_t index, uint8_t brightness, uint8_t speed, const std::vector<RGBColor>& colors)
|
||||
{
|
||||
/*------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Activating some modes requires two identical packets: one for setting the color, and one for setting the color AND activating. |
|
||||
\*------------------------------------------------------------------------------------------------------------------------------*/
|
||||
SetLed(index, brightness, speed, colors, false);
|
||||
SetLed(index, brightness, speed, colors, true);
|
||||
}
|
||||
|
||||
void EVGAMouseController::SetAllLeds(uint8_t brightness, uint8_t speed, const std::vector<RGBColor>& colors)
|
||||
{
|
||||
for(unsigned int i = 0; i < EVGA_PERIPHERAL_LED_COUNT; i++)
|
||||
{
|
||||
SetLed(i, brightness, speed, colors);
|
||||
}
|
||||
}
|
||||
|
||||
void EVGAMouseController::SetAllLedsAndActivate(uint8_t brightness, uint8_t speed, const std::vector<RGBColor>& colors)
|
||||
{
|
||||
for(unsigned int i = 0; i < EVGA_PERIPHERAL_LED_COUNT; i++)
|
||||
{
|
||||
SetLedAndActivate(i, brightness, speed, colors);
|
||||
}
|
||||
}
|
||||
|
||||
void EVGAMouseController::SetLed(uint8_t index, uint8_t brightness, uint8_t speed, const std::vector<RGBColor>& colors, bool activate)
|
||||
{
|
||||
unsigned char buffer[EVGA_PERIPHERAL_PACKET_SIZE] =
|
||||
{
|
||||
0x00, /* report id - must be 0x00 according to hid_send_feature_report */
|
||||
0x00, 0x00, static_cast<unsigned char>(connection_type), 0x1D,
|
||||
0x02, 0x00, 0x02 /* header bits - always the same */
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------------------*\
|
||||
| Setting the mode to breathing sends 3 packets: first to activate the mode, second to set the list of colors and |
|
||||
| third to send a packet identical to the second but with the first byte set ot 0xA1. This "activates" the mode. |
|
||||
\*---------------------------------------------------------------------------------------------------------------*/
|
||||
if(activate)
|
||||
{
|
||||
buffer[1] = 0xA1;
|
||||
}
|
||||
|
||||
buffer[EVGA_PERIPHERAL_LED_INDEX_BYTE] = index;
|
||||
/*-----------------------------------------------------------------------------------------*\
|
||||
| Unleash RGB supports individual modes on the LEDs, but OpenRGB does not. Use one specific |
|
||||
| LED's mode for any LED. |
|
||||
\*-----------------------------------------------------------------------------------------*/
|
||||
buffer[EVGA_PERIPHERAL_MODE_BYTE] = led_states[EVGA_PERIPHERAL_LED_SOURCE_OF_TRUTH].mode;
|
||||
buffer[EVGA_PERIPHERAL_BRIGHTNESS_BYTE] = brightness;
|
||||
buffer[EVGA_PERIPHERAL_SPEED_BYTE] = speed;
|
||||
|
||||
/*-----------------------------------------------------------------------*\
|
||||
| 7 is the maximum number of colors that can be set from the vendor's UI. |
|
||||
\*-----------------------------------------------------------------------*/
|
||||
unsigned char color_count = (unsigned char)std::min(colors.size(), static_cast<std::vector<RGBColor>::size_type>(7));
|
||||
buffer[EVGA_PERIPHERAL_COLOR_COUNT_BYTE] = color_count;
|
||||
for(unsigned char i = 0; i < color_count; i++)
|
||||
{
|
||||
buffer[15 + i * 3] = RGBGetRValue(colors[i]);
|
||||
buffer[16 + i * 3] = RGBGetGValue(colors[i]);
|
||||
buffer[17 + i * 3] = RGBGetBValue(colors[i]);
|
||||
}
|
||||
int err = hid_send_feature_report(dev, buffer, EVGA_PERIPHERAL_PACKET_SIZE);
|
||||
if(err == -1)
|
||||
{
|
||||
const wchar_t* err_str = hid_error(dev);
|
||||
LOG_DEBUG("[%s] Error writing buffer %s", name.c_str(), err_str);
|
||||
}
|
||||
led_states[index].brightness = brightness;
|
||||
led_states[index].speed = speed;
|
||||
led_states[index].colors = colors;
|
||||
/*------------------------------------------------------------------------------------*\
|
||||
| If the device returns a response not ready packet, future writes will silently fail. |
|
||||
| Wait until the device sends a valid packet to proceed. |
|
||||
\*------------------------------------------------------------------------------------*/
|
||||
ReadPacketOrLogErrors(buffer, EVGA_PERIPHERAL_MAX_ATTEMPTS);
|
||||
}
|
||||
|
||||
void EVGAMouseController::RefreshDeviceState()
|
||||
{
|
||||
RefreshDeviceState(EVGA_PERIPHERAL_LED_FRONT);
|
||||
RefreshDeviceState(EVGA_PERIPHERAL_LED_WHEEL);
|
||||
RefreshDeviceState(EVGA_PERIPHERAL_LED_LOGO);
|
||||
}
|
||||
|
||||
void EVGAMouseController::RefreshDeviceState(int led)
|
||||
{
|
||||
unsigned char buffer[EVGA_PERIPHERAL_PACKET_SIZE] =
|
||||
{
|
||||
0x00,
|
||||
0x00, 0x00, static_cast<unsigned char>(connection_type), 0x1D,
|
||||
0x02, 0x80, 0x02
|
||||
};
|
||||
buffer[EVGA_PERIPHERAL_LED_INDEX_BYTE] = static_cast<unsigned char>(led);
|
||||
int err = hid_send_feature_report(dev, buffer, EVGA_PERIPHERAL_PACKET_SIZE);
|
||||
if(err == -1)
|
||||
{
|
||||
const wchar_t* err_str = hid_error(dev);
|
||||
LOG_DEBUG("[%s] Error writing buffer %s", name.c_str(), err_str);
|
||||
}
|
||||
/*------------------------------------------------------------------------------*\
|
||||
| Wait in wireless mode or else packets might be sent too quickly to take effect |
|
||||
\*------------------------------------------------------------------------------*/
|
||||
Wait();
|
||||
if(ReadPacketOrLogErrors(buffer, EVGA_PERIPHERAL_MAX_ATTEMPTS))
|
||||
{
|
||||
int color_count = buffer[EVGA_PERIPHERAL_COLOR_COUNT_BYTE];
|
||||
if(color_count == 0)
|
||||
{
|
||||
LOG_VERBOSE("[%s] No colors read from response. The device is likely asleep.", name.c_str());
|
||||
return;
|
||||
}
|
||||
led_states[led].mode = buffer[EVGA_PERIPHERAL_MODE_BYTE];
|
||||
led_states[led].brightness = buffer[EVGA_PERIPHERAL_BRIGHTNESS_BYTE];
|
||||
led_states[led].speed = buffer[EVGA_PERIPHERAL_SPEED_BYTE];
|
||||
led_states[led].colors.resize(std::max(color_count, 1));
|
||||
for(int i = 0; i < color_count; i++)
|
||||
{
|
||||
uint8_t r = buffer[EVGA_PERIPHERAL_RED_BYTE + i * 3];
|
||||
uint8_t g = buffer[EVGA_PERIPHERAL_GREEN_BYTE + i * 3];
|
||||
uint8_t b = buffer[EVGA_PERIPHERAL_BLUE_BYTE + i * 3];
|
||||
led_states[led].colors[i] = ToRGBColor(r, g, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool EVGAMouseController::ReadPacketOrLogErrors(unsigned char *buffer, int max_attempts)
|
||||
{
|
||||
int bytes_read = ReadPacketOrWait(buffer, max_attempts);
|
||||
if(bytes_read == -1)
|
||||
{
|
||||
const wchar_t* err_str = hid_error(dev);
|
||||
LOG_DEBUG("[%s] Error reading buffer %s", name.c_str(), err_str);
|
||||
return false;
|
||||
}
|
||||
else if(IsResponseNotReadyPacket(buffer))
|
||||
{
|
||||
LOG_VERBOSE("[%s] Retries exhausted reading from device. Write may have failed.", name.c_str());
|
||||
return false;
|
||||
}
|
||||
else if(IsAsleepPacket(buffer))
|
||||
{
|
||||
LOG_VERBOSE("[%s] Device is asleep. Cannot send or receive packets until the device is awoken.", name.c_str());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int EVGAMouseController::ReadPacketOrWait(unsigned char *buffer, int max_attempts)
|
||||
{
|
||||
int attempts = 1;
|
||||
Wait();
|
||||
int bytes_read = hid_get_feature_report(dev, buffer, EVGA_PERIPHERAL_PACKET_SIZE);
|
||||
while(bytes_read == EVGA_PERIPHERAL_PACKET_SIZE && attempts < max_attempts && IsResponseNotReadyPacket(buffer))
|
||||
{
|
||||
Wait();
|
||||
bytes_read = hid_get_feature_report(dev, buffer, EVGA_PERIPHERAL_PACKET_SIZE);
|
||||
attempts++;
|
||||
}
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
void EVGAMouseController::Wait()
|
||||
{
|
||||
if(connection_type == EVGA_PERIPHERAL_CONNECTION_TYPE_WIRELESS)
|
||||
{
|
||||
std::this_thread::sleep_for(EVGA_PERIPHERAL_PACKET_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
bool EVGAMouseController::IsAsleepPacket(unsigned char *buffer)
|
||||
{
|
||||
const int expected_packet_size = 8;
|
||||
unsigned char expected_buffer[expected_packet_size] =
|
||||
{
|
||||
0x00,
|
||||
0xA4, 0x00, 0x02, 0x1D,
|
||||
0x02, 0x80, 0x02
|
||||
};
|
||||
return BuffersAreEqual(buffer, expected_buffer, expected_packet_size);
|
||||
}
|
||||
|
||||
bool EVGAMouseController::IsResponseNotReadyPacket(unsigned char *buffer)
|
||||
{
|
||||
const int expected_packet_size = 8;
|
||||
unsigned char expected_buffer[expected_packet_size] =
|
||||
{
|
||||
0x00,
|
||||
0xA0, 0x00, 0x02, 0x1D,
|
||||
0x02, 0x80, 0x02
|
||||
};
|
||||
return BuffersAreEqual(buffer, expected_buffer, expected_packet_size);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EVGAMouseController.h |
|
||||
| |
|
||||
| Driver for EVGA mouse |
|
||||
| |
|
||||
| Cooper Knaak 23 Jan 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define EVGA_PERIPHERAL_PACKET_SIZE 65
|
||||
#define EVGA_PERIPHERAL_LED_COUNT 3
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
enum
|
||||
{
|
||||
EVGA_PERIPHERAL_MODE_STATIC = 1,
|
||||
EVGA_PERIPHERAL_MODE_BREATHING = 2,
|
||||
EVGA_PERIPHERAL_MODE_RAINBOW = 3,
|
||||
EVGA_PERIPHERAL_MODE_PULSE = 4,
|
||||
EVGA_PERIPHERAL_MODE_TRIGGER = 6
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EVGA_PERIPHERAL_LED_FRONT = 0,
|
||||
EVGA_PERIPHERAL_LED_WHEEL = 1,
|
||||
EVGA_PERIPHERAL_LED_LOGO = 2
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------*\
|
||||
| All values in this enum account for the required 0x0 byte at index 0 |
|
||||
| when using hid* APIs. The byte controlling the red value of an LED is |
|
||||
| at index 15 in the buffer passed to hid* APIs because there is a 0x0 |
|
||||
| byte at the beginning of said buffer. It would only be index 14 in the |
|
||||
| raw packet received by the peripheral. |
|
||||
\*----------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
EVGA_PERIPHERAL_CONNECTION_TYPE_BYTE = 3,
|
||||
EVGA_PERIPHERAL_LED_INDEX_BYTE = 8,
|
||||
EVGA_PERIPHERAL_MODE_BYTE = 9,
|
||||
/*--------------*\
|
||||
| Range [0, 100] |
|
||||
\*--------------*/
|
||||
EVGA_PERIPHERAL_BRIGHTNESS_BYTE = 10,
|
||||
/*--------------*\
|
||||
| Range [0, 100] |
|
||||
\*--------------*/
|
||||
EVGA_PERIPHERAL_SPEED_BYTE = 11,
|
||||
/*-------------------------------------------------------*\
|
||||
| Determines when the lights initiate and terminate: |
|
||||
| immediately, on key press, or on key release. |
|
||||
| Currently unused because OpenRGB does not support this. |
|
||||
\*-------------------------------------------------------*/
|
||||
EVGA_PERIPHERAL_EFFECT_DURATION_BYTE = 13,
|
||||
/*---------------------------------------------------------------------------------*\
|
||||
| The byte at this index specifies how many colors are being passed in this packet. |
|
||||
| The colors are a sequence of 3 bytes per color: red, green, then blue. Thus, when |
|
||||
| passing 1 for this byte, the device will read the 3 next bytes as the color. When |
|
||||
| passing 7, the device will read the next 21 bytes in sets of 3. |
|
||||
\*---------------------------------------------------------------------------------*/
|
||||
EVGA_PERIPHERAL_COLOR_COUNT_BYTE = 14,
|
||||
EVGA_PERIPHERAL_RED_BYTE = 15,
|
||||
EVGA_PERIPHERAL_GREEN_BYTE = 16,
|
||||
EVGA_PERIPHERAL_BLUE_BYTE = 17,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EVGA_PERIPHERAL_CONNECTION_TYPE_WIRED = 0,
|
||||
EVGA_PERIPHERAL_CONNECTION_TYPE_WIRELESS = 2,
|
||||
};
|
||||
|
||||
struct EVGAMouseControllerDeviceState
|
||||
{
|
||||
uint8_t mode;
|
||||
uint8_t brightness;
|
||||
uint8_t speed;
|
||||
std::vector<RGBColor> colors;
|
||||
};
|
||||
|
||||
class EVGAMouseController
|
||||
{
|
||||
public:
|
||||
EVGAMouseController(hid_device* dev_handle, char * path, int connection_type, std::string dev_name);
|
||||
~EVGAMouseController();
|
||||
|
||||
std::string GetName();
|
||||
std::string GetSerial();
|
||||
std::string GetLocation();
|
||||
|
||||
/*---------------------------------------------------------------*\
|
||||
| Gets the mode, colors, or entire state currently on the device. |
|
||||
| OpenRGB does not support per-zone modes. All zones must be set |
|
||||
| to the same mode. It's possible to use the vendor's software |
|
||||
| to set each LED to separate states. These methods use the logo |
|
||||
| LED (#2) as the source of truth. |
|
||||
\*---------------------------------------------------------------*/
|
||||
uint8_t GetMode();
|
||||
EVGAMouseControllerDeviceState GetState();
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| Gets the color of the given LED from the device. If a device is in a mode |
|
||||
| with multiple colors, returns the first color in the list. |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
RGBColor GetColorOfLed(int led);
|
||||
|
||||
inline void SetMode(uint8_t mode)
|
||||
{
|
||||
SetMode(mode, 0);
|
||||
SetMode(mode, 1);
|
||||
SetMode(mode, 2);
|
||||
}
|
||||
void SetMode(uint8_t mode, uint8_t index);
|
||||
|
||||
/*-----------------------------------*\
|
||||
| Set a single LED to a single color. |
|
||||
\*-----------------------------------*/
|
||||
void SetLed(uint8_t index, uint8_t brightness, uint8_t speed, RGBColor color);
|
||||
/*---------------------------------------------------*\
|
||||
| Set the LED at the given index to a list of colors. |
|
||||
\*---------------------------------------------------*/
|
||||
void SetLed(uint8_t index, uint8_t brightness, uint8_t speed, const std::vector<RGBColor>& colors);
|
||||
/*---------------------------------------------------------------------------*\
|
||||
| Set the LED at the given index to a list of colors, then activate the mode. |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
void SetLedAndActivate(uint8_t index, uint8_t brightness, uint8_t speed, const std::vector<RGBColor>& colors);
|
||||
/*---------------------------------*\
|
||||
| Set all LEDs to a list of colors. |
|
||||
\*---------------------------------*/
|
||||
void SetAllLeds(uint8_t brightness, uint8_t speed, const std::vector<RGBColor>& colors);
|
||||
/*---------------------------------------------------------*\
|
||||
| Set all LEDs to a list of colors, then activate the mode. |
|
||||
\*---------------------------------------------------------*/
|
||||
void SetAllLedsAndActivate(uint8_t brightness, uint8_t speed, const std::vector<RGBColor>& colors);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
int connection_type;
|
||||
|
||||
std::vector<EVGAMouseControllerDeviceState> led_states;
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------------------*\
|
||||
| Sets the led to the given colors with the given brightness and speed. if activate is true, activates the current |
|
||||
| mode. If false, just sets the colors. |
|
||||
\*----------------------------------------------------------------------------------------------------------------*/
|
||||
void SetLed(uint8_t index, uint8_t brightness, uint8_t speed, const std::vector<RGBColor>& colors, bool activate);
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Requests and stores the current mode and colors for all leds from the device. |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
void RefreshDeviceState();
|
||||
|
||||
/*----------------------------------------------------------------------------------*\
|
||||
| Requests and stores the current mode and colors for the given led from the device. |
|
||||
\*----------------------------------------------------------------------------------*/
|
||||
void RefreshDeviceState(int led);
|
||||
|
||||
/*-----------------------------------------------------------------------------------*\
|
||||
| Repeatedly reads a packet from the device until a valid packet is received. If no |
|
||||
| such packet is received after max_attempts tries, returns false. Otherwise, returns |
|
||||
| true. buffer must be an array with size EVGA_PERIPHERAL_PACKET_SIZE. |
|
||||
\*-----------------------------------------------------------------------------------*/
|
||||
bool ReadPacketOrLogErrors(unsigned char *buffer, int max_attempts);
|
||||
|
||||
/*-----------------------------------------------------------------------------------*\
|
||||
| Repeatedly reads a packet from the device until a valid packet is received. If a |
|
||||
| "response not ready" packet is returned, try again, up to a maximum number of tries |
|
||||
| max_attempts. buffer must be an array with size EVGA_PERIPHERAL_PACKET_SIZE. |
|
||||
| Returns the number of bytes read or -1 on error. |
|
||||
\*-----------------------------------------------------------------------------------*/
|
||||
int ReadPacketOrWait(unsigned char *buffer, int max_attempts);
|
||||
|
||||
/*-----------------------------------------------------------------------------*\
|
||||
| Waits a predetermined amount of time to avoid sending packets to frequently. |
|
||||
| In wireless mode, packets sent too close together might overwrite each other, |
|
||||
| causing earlier ones to silently not propagate. Does not wait in connection |
|
||||
| types that do not have this problem. |
|
||||
\*-----------------------------------------------------------------------------*/
|
||||
void Wait();
|
||||
|
||||
/*------------------------------------------------------------------------------*\
|
||||
| Returns true if the packet received from the device signals that the device is |
|
||||
| asleep and will not send or receive other packets. |
|
||||
\*------------------------------------------------------------------------------*/
|
||||
bool IsAsleepPacket(unsigned char *buffer);
|
||||
|
||||
/*------------------------------------------------------------------------------*\
|
||||
| Returns true if the packet received from the device signals that the device is |
|
||||
| still processing a request device state packet. In this case, the request to |
|
||||
| read from the device should be retried at a later time. |
|
||||
\*------------------------------------------------------------------------------*/
|
||||
bool IsResponseNotReadyPacket(unsigned char *buffer);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_EVGAMouse.cpp |
|
||||
| |
|
||||
| RGBController for EVGA mouse |
|
||||
| |
|
||||
| Cooper Knaak 23 Jan 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_EVGAMouse.h"
|
||||
#include "Colors.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name EVGA USB X20 Mouse
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectWiredEVGAMouse,DetectWirelessEVGAMouse
|
||||
@comment The EVGA USB mouse currently supports the X20 (both wired
|
||||
and wireless, but not bluetooth).
|
||||
\*-------------------------------------------------------------------*/
|
||||
RGBController_EVGAMouse::RGBController_EVGAMouse(EVGAMouseController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetName();
|
||||
vendor = "EVGA";
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = "EVGA Mouse Device";
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = EVGA_PERIPHERAL_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Static.brightness_min = EVGA_PERIPHERAL_BRIGHTNESS_MIN;
|
||||
Static.brightness_max = EVGA_PERIPHERAL_BRIGHTNESS_MAX;
|
||||
Static.brightness = EVGA_PERIPHERAL_BRIGHTNESS_MAX;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(Static.colors_max);
|
||||
Static.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = EVGA_PERIPHERAL_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Breathing.brightness_min = EVGA_PERIPHERAL_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = EVGA_PERIPHERAL_BRIGHTNESS_MAX;
|
||||
Breathing.brightness = EVGA_PERIPHERAL_BRIGHTNESS_MAX;
|
||||
Breathing.colors_min = 2;
|
||||
Breathing.colors_max = 2;
|
||||
Breathing.colors = {COLOR_GREEN, COLOR_BLUE};
|
||||
Breathing.speed_min = EVGA_PERIPHERAL_SPEED_SLOWEST;
|
||||
Breathing.speed_max = EVGA_PERIPHERAL_SPEED_FASTEST;
|
||||
Breathing.speed = EVGA_PERIPHERAL_SPEED_FASTEST;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Spectrum Cycle";
|
||||
Rainbow.value = EVGA_PERIPHERAL_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Rainbow.brightness_min = EVGA_PERIPHERAL_BRIGHTNESS_MIN;
|
||||
Rainbow.brightness_max = EVGA_PERIPHERAL_BRIGHTNESS_MAX;
|
||||
Rainbow.brightness = EVGA_PERIPHERAL_BRIGHTNESS_MAX;
|
||||
Rainbow.speed_min = EVGA_PERIPHERAL_SPEED_SLOWEST;
|
||||
Rainbow.speed_max = EVGA_PERIPHERAL_SPEED_FASTEST;
|
||||
Rainbow.speed = EVGA_PERIPHERAL_SPEED_FASTEST;
|
||||
Rainbow.colors = {COLOR_RED, COLOR_YELLOW, COLOR_GREEN, COLOR_CYAN, COLOR_BLUE, COLOR_MAGENTA, COLOR_WHITE};
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode Pulse;
|
||||
Pulse.name = "Pulse";
|
||||
Pulse.value = EVGA_PERIPHERAL_MODE_PULSE;
|
||||
Pulse.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Pulse.brightness_min = EVGA_PERIPHERAL_BRIGHTNESS_MIN;
|
||||
Pulse.brightness_max = EVGA_PERIPHERAL_BRIGHTNESS_MAX;
|
||||
Pulse.brightness = EVGA_PERIPHERAL_BRIGHTNESS_MAX;
|
||||
Pulse.speed_min = EVGA_PERIPHERAL_SPEED_SLOWEST;
|
||||
Pulse.speed_max = EVGA_PERIPHERAL_SPEED_FASTEST;
|
||||
Pulse.speed = EVGA_PERIPHERAL_SPEED_FASTEST;
|
||||
Pulse.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Pulse.colors_min = 2;
|
||||
Pulse.colors_max = 7;
|
||||
Pulse.colors = {COLOR_RED, COLOR_YELLOW, COLOR_GREEN, COLOR_CYAN, COLOR_BLUE, COLOR_MAGENTA, COLOR_WHITE};
|
||||
modes.push_back(Pulse);
|
||||
|
||||
mode Trigger;
|
||||
Trigger.name = "Trigger";
|
||||
/*-----------------------------------*\
|
||||
| Pulse to Trigger skips from 4 to 6. |
|
||||
\*-----------------------------------*/
|
||||
Trigger.value = EVGA_PERIPHERAL_MODE_TRIGGER;
|
||||
Trigger.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Trigger.brightness_min = EVGA_PERIPHERAL_BRIGHTNESS_MIN;
|
||||
Trigger.brightness_max = EVGA_PERIPHERAL_BRIGHTNESS_MAX;
|
||||
Trigger.brightness = EVGA_PERIPHERAL_BRIGHTNESS_MAX;
|
||||
Trigger.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Trigger.colors_min = 7;
|
||||
Trigger.colors_max = 7;
|
||||
Trigger.colors = {COLOR_RED, COLOR_YELLOW, COLOR_GREEN, COLOR_CYAN, COLOR_BLUE, COLOR_MAGENTA, COLOR_WHITE};
|
||||
modes.push_back(Trigger);
|
||||
|
||||
active_mode = EVGA_PERIPHERAL_MODE_STATIC;
|
||||
|
||||
Init_Controller();
|
||||
SetupZones();
|
||||
|
||||
EVGAMouseControllerDeviceState current_state = controller->GetState();
|
||||
for(unsigned int i = 0; i < modes.size(); i++)
|
||||
{
|
||||
if(modes[i].value == current_state.mode)
|
||||
{
|
||||
active_mode = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
modes[active_mode].colors = current_state.colors;
|
||||
}
|
||||
modes[active_mode].brightness = current_state.brightness;
|
||||
modes[active_mode].speed = current_state.speed;
|
||||
colors.resize(EVGA_PERIPHERAL_LED_COUNT);
|
||||
for(unsigned int i = 0; i < colors.size(); i++)
|
||||
{
|
||||
colors[i] = controller->GetColorOfLed(i);
|
||||
}
|
||||
}
|
||||
|
||||
RGBController_EVGAMouse::~RGBController_EVGAMouse()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_EVGAMouse::Init_Controller()
|
||||
{
|
||||
/*------------------------------------------------------------------------------------------*\
|
||||
| Since each LED can have its own mode, each one needs to be its own zone with a single LED. |
|
||||
\*------------------------------------------------------------------------------------------*/
|
||||
zone front_zone;
|
||||
front_zone.name = "Front";
|
||||
front_zone.type = ZONE_TYPE_SINGLE;
|
||||
front_zone.leds_min = 1;
|
||||
front_zone.leds_max = 1;
|
||||
front_zone.leds_count = 1;
|
||||
front_zone.matrix_map = NULL;
|
||||
zones.push_back(front_zone);
|
||||
|
||||
zone wheel_zone;
|
||||
wheel_zone.name = "Scroll Wheel";
|
||||
wheel_zone.type = ZONE_TYPE_SINGLE;
|
||||
wheel_zone.leds_min = 1;
|
||||
wheel_zone.leds_max = 1;
|
||||
wheel_zone.leds_count = 1;
|
||||
wheel_zone.matrix_map = NULL;
|
||||
zones.push_back(wheel_zone);
|
||||
|
||||
zone logo_zone;
|
||||
logo_zone.name = "Logo";
|
||||
logo_zone.type = ZONE_TYPE_SINGLE;
|
||||
logo_zone.leds_min = 1;
|
||||
logo_zone.leds_max = 1;
|
||||
logo_zone.leds_count = 1;
|
||||
logo_zone.matrix_map = NULL;
|
||||
zones.push_back(logo_zone);
|
||||
|
||||
led front_led;
|
||||
front_led.name = "Front LED";
|
||||
front_led.value = 0;
|
||||
leds.push_back(front_led);
|
||||
|
||||
led wheel_led;
|
||||
wheel_led.name = "Scroll Wheel LED";
|
||||
wheel_led.value = 1;
|
||||
leds.push_back(wheel_led);
|
||||
|
||||
led back_led;
|
||||
back_led.name = "Back LED";
|
||||
back_led.value = 2;
|
||||
leds.push_back(back_led);
|
||||
}
|
||||
|
||||
void RGBController_EVGAMouse::SetupZones()
|
||||
{
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_EVGAMouse::ResizeZone(int /* zone */, int /* new_size */)
|
||||
{
|
||||
/*--------------------------------------*\
|
||||
| This device does not support resizing. |
|
||||
\*--------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_EVGAMouse::DeviceUpdateLEDs()
|
||||
{
|
||||
for(unsigned int i = 0; i < colors.size(); i++)
|
||||
{
|
||||
controller->SetLed(i, modes[active_mode].brightness, modes[active_mode].speed, colors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_EVGAMouse::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
controller->SetLed(zone, modes[active_mode].brightness, modes[active_mode].speed, colors[zone]);
|
||||
}
|
||||
|
||||
void RGBController_EVGAMouse::UpdateSingleLED(int led)
|
||||
{
|
||||
controller->SetLed(led, modes[active_mode].brightness, modes[active_mode].speed, colors[led]);
|
||||
}
|
||||
|
||||
void RGBController_EVGAMouse::DeviceUpdateMode()
|
||||
{
|
||||
controller->SetMode(modes[active_mode].value);
|
||||
/*--------------------------------------------------------------------*\
|
||||
| Modes with specific colors should use their mode's colors. All other |
|
||||
| modes should use the colors stored in this controller. |
|
||||
\*--------------------------------------------------------------------*/
|
||||
std::vector<RGBColor>* temp_colors = &colors;
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Rainbow does not have mode specific colors that can be controlled by OpenRGB, so it does not have |
|
||||
| the corresponding flag. However, to properly activate it, you still must pass the correct list of |
|
||||
| colors in the LED packet. Specifying the wrong number of colors causes the effect to restart the |
|
||||
| cycle earlier in the sequence than it is supposed to. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
if((modes[active_mode].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR) || modes[active_mode].value == EVGA_PERIPHERAL_MODE_RAINBOW)
|
||||
{
|
||||
temp_colors = &(modes[active_mode].colors);
|
||||
}
|
||||
if(modes[active_mode].value == EVGA_PERIPHERAL_MODE_BREATHING)
|
||||
{
|
||||
controller->SetAllLedsAndActivate(modes[active_mode].brightness, modes[active_mode].speed, *temp_colors);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetAllLeds(modes[active_mode].brightness, modes[active_mode].speed, *temp_colors);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_EVGAMouse::DeviceSaveMode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int RGBController_EVGAMouse::GetDeviceMode()
|
||||
{
|
||||
return controller->GetMode();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_EVGAMouse.h |
|
||||
| |
|
||||
| RGBController for EVGA mouse |
|
||||
| |
|
||||
| Cooper Knaak 23 Jan 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "RGBController.h"
|
||||
#include "EVGAMouseController.h"
|
||||
|
||||
#define EVGA_PERIPHERAL_BRIGHTNESS_MIN 0
|
||||
#define EVGA_PERIPHERAL_BRIGHTNESS_MAX 100
|
||||
#define EVGA_PERIPHERAL_SPEED_SLOWEST 0
|
||||
#define EVGA_PERIPHERAL_SPEED_FASTEST 100
|
||||
|
||||
class RGBController_EVGAMouse : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_EVGAMouse(EVGAMouseController* evga);
|
||||
~RGBController_EVGAMouse();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
void Init_Controller();
|
||||
int GetDeviceMode();
|
||||
|
||||
EVGAMouseController* controller;
|
||||
};
|
||||
@@ -0,0 +1,77 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EVGAUSBControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for EVGA USB devices |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "Detector.h"
|
||||
#include "RGBController_EVGAKeyboard.h"
|
||||
#include "RGBController_EVGAMouse.h"
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| EVGA USB vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define EVGA_USB_VID 0x3842
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define Z15_ISO_PID 0x260E
|
||||
#define Z15_ANSI_PID 0x2608
|
||||
#define Z20_ANSI_PID 0x260A
|
||||
#define Z20_UK_PID 0x2610
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Mouse product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define X20_WIRED_PID 0x2420
|
||||
#define X20_WIRELESS_ADAPTER_PID 0x2402
|
||||
|
||||
void DetectEVGAKeyboardControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EVGAKeyboardController* controller = new EVGAKeyboardController(dev, info->path, info->product_id, name);
|
||||
RGBController_EVGAKeyboard* rgb_controller = new RGBController_EVGAKeyboard(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectEVGAMouse(hid_device_info* info, const std::string &name, int connection_type)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EVGAMouseController* controller = new EVGAMouseController(dev, info->path, connection_type, name);
|
||||
RGBController_EVGAMouse* rgb_controller = new RGBController_EVGAMouse(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
void DetectWiredEVGAMouse(hid_device_info* info, const std::string &name)
|
||||
{
|
||||
DetectEVGAMouse(info, name, EVGA_PERIPHERAL_CONNECTION_TYPE_WIRED);
|
||||
}
|
||||
|
||||
void DetectWirelessEVGAMouse(hid_device_info* info, const std::string &name)
|
||||
{
|
||||
DetectEVGAMouse(info, name, EVGA_PERIPHERAL_CONNECTION_TYPE_WIRELESS);
|
||||
}
|
||||
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA Z15 Keyboard", DetectEVGAKeyboardControllers, EVGA_USB_VID, Z15_ISO_PID, 1, 0x08, 0x4B);
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA Z15 Keyboard", DetectEVGAKeyboardControllers, EVGA_USB_VID, Z15_ANSI_PID, 1, 0x08, 0x4B);
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA Z20 Keyboard", DetectEVGAKeyboardControllers, EVGA_USB_VID, Z20_ANSI_PID, 1, 0x08, 0x4B);
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA Z20 Keyboard", DetectEVGAKeyboardControllers, EVGA_USB_VID, Z20_UK_PID, 1, 0x08, 0x4B);
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA X20 Gaming Mouse", DetectWiredEVGAMouse, EVGA_USB_VID, X20_WIRED_PID, 2, 0xFFFF, 0);
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA X20 USB Receiver", DetectWirelessEVGAMouse, EVGA_USB_VID, X20_WIRELESS_ADAPTER_PID, 2, 0xFFFF, 0);
|
||||
Reference in New Issue
Block a user