OpenRGB/Controllers/EVGAUSBController/EVGAMouseController/EVGAMouseController.h

206 lines
9.9 KiB
C++

/*---------------------------------------------------------*\
| 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-only |
\*---------------------------------------------------------*/
#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);
};