Publish LumaOps source
This commit is contained in:
@@ -0,0 +1,423 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairPeripheralV2Controller.cpp |
|
||||
| |
|
||||
| Driver for Corsair V2 peripherals |
|
||||
| |
|
||||
| Chris M (Dr_No) 07 Aug 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "CorsairPeripheralV2Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_handle, const char* path, std::string name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
device_name = name;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get PID |
|
||||
| If the PID is in the know wireless receivers list |
|
||||
| switch the write_cmd to talk to the device and retry |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int pid = GetAddress(0x12);
|
||||
|
||||
switch(pid)
|
||||
{
|
||||
case CORSAIR_SLIPSTREAM_WIRELESS_PID1:
|
||||
case CORSAIR_SLIPSTREAM_WIRELESS_V2_PID1:
|
||||
case CORSAIR_SLIPSTREAM_WIRELESS_PID2:
|
||||
write_cmd = CORSAIR_V2_WRITE_WIRELESS_ID;
|
||||
pid = GetAddress(0x12);
|
||||
break;
|
||||
|
||||
case CORSAIR_K57_RGB_WIRED_PID:
|
||||
write_cmd = 0x80;
|
||||
light_ctrl = CORSAIR_V2_LIGHT_CTRL1;
|
||||
skip_reads = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| If the hid_pid passed in from the detector does not match |
|
||||
| the pid reported by the device then it is likey |
|
||||
| behind a wireless receiver. |
|
||||
\*---------------------------------------------------------*/
|
||||
LOG_DEBUG("[%s] Setting write CMD to %02X for %s mode for PID %04X", device_name.c_str(),
|
||||
write_cmd, (write_cmd == CORSAIR_V2_WRITE_WIRELESS_ID) ? "wireless" : "wired", pid);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get VID |
|
||||
| NB: this can be achieved with GetAddress(0x11) but we |
|
||||
| also need to set the packet length capabilities for |
|
||||
| the device being set up. |
|
||||
\*---------------------------------------------------------*/
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_GET;
|
||||
buffer[3] = 0x11;
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
uint16_t result = hid_read_timeout(dev, buffer, CORSAIR_V2_PACKET_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
result++;
|
||||
pkt_sze = std::max(result, (uint16_t)CORSAIR_V2_WRITE_SIZE);
|
||||
LOG_DEBUG("[%s] Packet length set to %d", device_name.c_str(), pkt_sze);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| NB: If the device is not found in the device list |
|
||||
| then wireless mode may not work reliably |
|
||||
\*---------------------------------------------------------*/
|
||||
bool not_found = true;
|
||||
|
||||
for(uint16_t i = 0; i < CORSAIR_V2_DEVICE_COUNT; i++)
|
||||
{
|
||||
LOG_DEBUG("[%s] Checking PID %04X against index %d with %04X - %smatch", device_name.c_str(),
|
||||
pid, i, corsair_v2_device_list[i]->pid, corsair_v2_device_list[i]->pid == pid ? "" : "no ");
|
||||
if(corsair_v2_device_list[i]->pid == pid)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set device ID |
|
||||
\*---------------------------------------------------------*/
|
||||
not_found = false;
|
||||
device_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(not_found)
|
||||
{
|
||||
LOG_ERROR("[%s] device capabilities not found. Please creata a new device request.",
|
||||
device_name.c_str());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Check lighting control endpoints |
|
||||
| If lighting control endpoint 2 is unavailable |
|
||||
| then use endpoint 1. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(light_ctrl == CORSAIR_V2_LIGHT_CTRL2)
|
||||
{
|
||||
result = StartTransaction(0);
|
||||
if(result > 0)
|
||||
{
|
||||
light_ctrl = CORSAIR_V2_LIGHT_CTRL1;
|
||||
StartTransaction(0);
|
||||
}
|
||||
StopTransaction(0);
|
||||
LOG_DEBUG("[%s] Lighting Endpoint set to %02X", device_name.c_str(), light_ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
CorsairPeripheralV2Controller::~CorsairPeripheralV2Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
const corsair_v2_device* CorsairPeripheralV2Controller::GetDeviceData()
|
||||
{
|
||||
return corsair_v2_device_list[device_index];
|
||||
}
|
||||
|
||||
std::string CorsairPeripheralV2Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string CorsairPeripheralV2Controller::GetErrorString(uint8_t err)
|
||||
{
|
||||
switch(err)
|
||||
{
|
||||
case 1:
|
||||
return "Invalid Value";
|
||||
case 3:
|
||||
return "Failed";
|
||||
case 5:
|
||||
return "Unsupported";
|
||||
default:
|
||||
return "Protocol Error (Unknown)";
|
||||
}
|
||||
}
|
||||
|
||||
std::string CorsairPeripheralV2Controller::GetFirmwareString()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string CorsairPeripheralV2Controller::GetName()
|
||||
{
|
||||
return device_name;
|
||||
}
|
||||
|
||||
std::string CorsairPeripheralV2Controller::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 CorsairPeripheralV2Controller::SetRenderMode(corsair_v2_device_mode mode)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set Mode |
|
||||
\*---------------------------------------------------------*/
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_SET;
|
||||
buffer[3] = CORSAIR_V2_VALUE_MODE;
|
||||
buffer[5] = mode;
|
||||
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2Controller::LightingControl(uint8_t opt1)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| The Corsair command is the same for each initialisation |
|
||||
| packet and the registers and options differ for |
|
||||
| each peripheral supported by the protocol |
|
||||
\*---------------------------------------------------------*/
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_GET;
|
||||
buffer[3] = opt1;
|
||||
buffer[5] = 0x00;
|
||||
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CorsairPeripheralV2Controller::GetKeyboardLayout()
|
||||
{
|
||||
return GetAddress(0x41);
|
||||
}
|
||||
|
||||
unsigned int CorsairPeripheralV2Controller::GetAddress(uint8_t address)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
uint8_t read[CORSAIR_V2_WRITE_SIZE];
|
||||
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
memset(read, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_GET;
|
||||
buffer[3] = address;
|
||||
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_read_timeout(dev, read, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
|
||||
unsigned int temp = (unsigned int)(read[6] << 24 | read[5] << 16 | read[4] << 8 | read[3]);
|
||||
LOG_DEBUG("[%s] GetAddress %02X - %02X %02X - %02X %02X %02X %02X %02X %02X %02X %02X", device_name.c_str(),
|
||||
address, read[0], read[1], read[2], read[3], read[4], read[5], read[6], read[7], read[8], read[9]);
|
||||
|
||||
uint8_t result = read[2];
|
||||
if(result > 0)
|
||||
{
|
||||
LOG_DEBUG("[%s] An error occurred! Get Address %02X failed - %d %s", device_name.c_str(),
|
||||
address, result, GetErrorString(result).c_str());
|
||||
return -1;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
unsigned char CorsairPeripheralV2Controller::StartTransaction(uint8_t opt1)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_START_TX;
|
||||
buffer[3] = opt1;
|
||||
buffer[4] = light_ctrl;
|
||||
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
|
||||
return buffer[2];
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2Controller::StopTransaction(uint8_t opt1)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_STOP_TX;
|
||||
buffer[3] = 0x01;
|
||||
buffer[4] = opt1;
|
||||
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2Controller::ClearPacketBuffer()
|
||||
{
|
||||
if(skip_reads)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t result = 0;
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
|
||||
do
|
||||
{
|
||||
result = hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
|
||||
}
|
||||
while(result > 0);
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
|
||||
{
|
||||
const uint8_t offset1 = 8;
|
||||
const uint8_t offset2 = 4;
|
||||
uint16_t remaining = data_size;
|
||||
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
memset(buffer, 0, CORSAIR_V2_PACKET_SIZE);
|
||||
|
||||
ClearPacketBuffer();
|
||||
StartTransaction(0);
|
||||
/*---------------------------------------------------------*\
|
||||
| Set the data header in packet 1 with the data length |
|
||||
| signaling how many packets to expect to the device |
|
||||
\*---------------------------------------------------------*/
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_BLK_W1;
|
||||
buffer[4] = data_size & 0xFF;
|
||||
buffer[5] = data_size >> 8;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Check if the data needs more than 1 packet |
|
||||
\*---------------------------------------------------------*/
|
||||
uint16_t copy_bytes = pkt_sze - offset1;
|
||||
if(remaining < copy_bytes)
|
||||
{
|
||||
copy_bytes = remaining;
|
||||
}
|
||||
|
||||
memcpy(&buffer[offset1], &data[0], copy_bytes);
|
||||
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
|
||||
}
|
||||
|
||||
remaining -= copy_bytes;
|
||||
buffer[2] = CORSAIR_V2_CMD_BLK_WN;
|
||||
copy_bytes = pkt_sze - offset2;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Send the remaining packets |
|
||||
\*---------------------------------------------------------*/
|
||||
while(remaining)
|
||||
{
|
||||
uint16_t index = data_size - remaining;
|
||||
if(remaining < copy_bytes)
|
||||
{
|
||||
memset(&buffer[offset2], 0, copy_bytes);
|
||||
copy_bytes = remaining;
|
||||
}
|
||||
|
||||
memcpy(&buffer[offset2], &data[index], copy_bytes);
|
||||
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
|
||||
}
|
||||
|
||||
remaining -= copy_bytes;
|
||||
}
|
||||
|
||||
StopTransaction(0);
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2Controller::UpdateHWMode(uint16_t mode, corsair_v2_color /*color_mode*/, uint8_t /*speed*/,
|
||||
uint8_t /*direction*/, uint8_t /*brightness*/, std::vector<RGBColor> /*colors*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| If we are switching to `Direct` mode |
|
||||
| set device in software mode |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode == CORSAIR_V2_MODE_DIRECT)
|
||||
{
|
||||
SetRenderMode(CORSAIR_V2_MODE_SW);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
SetRenderMode(CORSAIR_V2_MODE_HW);
|
||||
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
*/
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set the data header in packet 1 with the data length |
|
||||
| signaling how many packets to expect to the device |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_BLK_W1;
|
||||
buffer[3] = CORSAIR_V2_MODE_HW;
|
||||
buffer[4] = 0x30;
|
||||
buffer[8] = mode & 0xFF;
|
||||
buffer[9] = mode >> 8;
|
||||
|
||||
buffer[10] = CORSAIR_V2_COLOR_SPECIFIC;
|
||||
buffer[11] = speed;
|
||||
|
||||
buffer[14] = colors.size();
|
||||
|
||||
for(size_t i = 0; i < colors.size(); ++i)
|
||||
{
|
||||
uint8_t offset = 15 + (i * 4);
|
||||
|
||||
buffer[offset] = brightness;
|
||||
buffer[offset + 1] = RGBGetBValue(colors[i]);
|
||||
buffer[offset + 2] = RGBGetGValue(colors[i]);
|
||||
buffer[offset + 3] = RGBGetRValue(colors[i]);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairPeripheralV2Controller.h |
|
||||
| |
|
||||
| Driver for Corsair V2 peripherals |
|
||||
| |
|
||||
| Chris M (Dr_No) 07 Aug 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "LogManager.h"
|
||||
#include "RGBController.h"
|
||||
#include "CorsairPeripheralV2Devices.h"
|
||||
|
||||
#define NA 0xFFFFFFFF
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
#define CORSAIR_V2_TIMEOUT 50
|
||||
#define CORSAIR_V2_TIMEOUT_SHORT 3
|
||||
#define CORSAIR_V2_VALUE_MODE 3
|
||||
#define CORSAIR_V2_WRITE_WIRED_ID 8
|
||||
#define CORSAIR_V2_WRITE_WIRELESS_ID 9
|
||||
#define CORSAIR_V2_WRITE_SIZE 65
|
||||
#define CORSAIR_V2_PACKET_SIZE 1024
|
||||
|
||||
#define CORSAIR_V2_LIGHT_CTRL1 1
|
||||
#define CORSAIR_V2_LIGHT_CTRL2 34 /* 0x22 */
|
||||
#define CORSAIR_V2_UPDATE_PERIOD 30000
|
||||
#define CORSAIR_V2_SLEEP_PERIOD 12500ms
|
||||
|
||||
#define CORSAIR_V2_BRIGHTNESS_MIN 0
|
||||
#define CORSAIR_V2_BRIGHTNESS_MAX 0xFF
|
||||
|
||||
enum corsair_v2_cmd
|
||||
{
|
||||
CORSAIR_V2_CMD_SET = 0x01, /* Command for setting values */
|
||||
CORSAIR_V2_CMD_GET = 0x02, /* Command for getting values */
|
||||
CORSAIR_V2_CMD_STOP_TX = 0x05, /* Finish Transaction */
|
||||
CORSAIR_V2_CMD_BLK_W1 = 0x06, /* Block write packet 1 */
|
||||
CORSAIR_V2_CMD_BLK_WN = 0x07, /* Block write remaining packets */
|
||||
CORSAIR_V2_CMD_START_TX = 0x0D, /* Start Transaction */
|
||||
};
|
||||
|
||||
enum corsair_v2_mode
|
||||
{
|
||||
CORSAIR_V2_MODE_DIRECT = 0x0012,
|
||||
CORSAIR_V2_MODE_STATIC = 0x207E,
|
||||
CORSAIR_V2_MODE_FLASHING = 0xAD4F,
|
||||
CORSAIR_V2_MODE_BREATHING = 0xA5FA,
|
||||
CORSAIR_V2_MODE_SPECTRUM = 0x7BFF,
|
||||
CORSAIR_V2_MODE_RAINBOW = 0xB94C,
|
||||
CORSAIR_V2_MODE_RAIN = 0xA07E,
|
||||
CORSAIR_V2_MODE_SPIRAL = 0xAB87,
|
||||
CORSAIR_V2_MODE_WATERCOLOR = 0x0022,
|
||||
CORSAIR_V2_MODE_REACTIVE = 0xB1F9,
|
||||
CORSAIR_V2_MODE_RIPPLE = 0x09A2,
|
||||
CORSAIR_V2_MODE_VISOR = 0x90C0
|
||||
};
|
||||
|
||||
enum corsair_v2_color
|
||||
{
|
||||
CORSAIR_V2_COLOR_NONE = 0x00,
|
||||
CORSAIR_V2_COLOR_SPECIFIC = 0x01,
|
||||
CORSAIR_V2_COLOR_RANDOM = 0x02,
|
||||
CORSAIR_V2_COLOR_UNKNOWN = 0x03
|
||||
};
|
||||
|
||||
|
||||
class CorsairPeripheralV2Controller
|
||||
{
|
||||
public:
|
||||
CorsairPeripheralV2Controller(hid_device* dev_handle, const char* path, std::string name);
|
||||
virtual ~CorsairPeripheralV2Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetErrorString(uint8_t err);
|
||||
std::string GetFirmwareString();
|
||||
std::string GetName();
|
||||
std::string GetSerialString();
|
||||
const corsair_v2_device* GetDeviceData();
|
||||
unsigned int GetKeyboardLayout();
|
||||
|
||||
void SetRenderMode(corsair_v2_device_mode mode);
|
||||
void LightingControl(uint8_t opt1);
|
||||
void SetLEDs(uint8_t *data, uint16_t data_size);
|
||||
void UpdateHWMode(uint16_t mode, corsair_v2_color color_mode, uint8_t speed,
|
||||
uint8_t direction, uint8_t brightness, std::vector<RGBColor> colors);
|
||||
|
||||
virtual void SetLedsDirect(std::vector<RGBColor *> colors) = 0;
|
||||
|
||||
protected:
|
||||
uint16_t device_index;
|
||||
std::string device_name;
|
||||
uint8_t light_ctrl = CORSAIR_V2_LIGHT_CTRL2;
|
||||
|
||||
private:
|
||||
void ClearPacketBuffer();
|
||||
unsigned int GetAddress(uint8_t address);
|
||||
unsigned char StartTransaction(uint8_t opt1);
|
||||
void StopTransaction(uint8_t opt1);
|
||||
|
||||
hid_device* dev;
|
||||
|
||||
uint8_t write_cmd = CORSAIR_V2_WRITE_WIRED_ID;
|
||||
uint16_t pkt_sze = CORSAIR_V2_WRITE_SIZE;
|
||||
bool skip_reads = false;
|
||||
std::string firmware_version;
|
||||
std::string location;
|
||||
};
|
||||
@@ -0,0 +1,100 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairPeripheralV2ControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Corsair V2 peripherals |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| OpenRGB includes |
|
||||
\*-----------------------------------------------------*/
|
||||
#include <hidapi.h>
|
||||
#include "Detector.h"
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Corsair Peripheral specific includes |
|
||||
\*-----------------------------------------------------*/
|
||||
#include "CorsairPeripheralV2Devices.h"
|
||||
#include "RGBController_CorsairV2Hardware.h"
|
||||
#include "RGBController_CorsairV2Software.h"
|
||||
|
||||
#define CORSAIR_PERIPHERAL_CONTROLLER_NAME "Corsair V2 Peripheral"
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Corsair vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_VID 0x1B1C
|
||||
|
||||
void DetectCorsairV2HardwareControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CorsairPeripheralV2HWController* controller = new CorsairPeripheralV2HWController(dev, info->path, name);
|
||||
RGBController_CorsairV2HW* rgb_controller = new RGBController_CorsairV2HW(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
} /* DetectCorsairV2HardwareControllers() */
|
||||
|
||||
void DetectCorsairV2SoftwareControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CorsairPeripheralV2SWController* controller = new CorsairPeripheralV2SWController(dev, info->path, name);
|
||||
RGBController_CorsairV2SW* rgb_controller = new RGBController_CorsairV2SW(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
} /* DetectCorsairV2SoftwareControllers() */
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K55 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K55_RGB_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K57 RGB (Wired)", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K57_RGB_WIRED_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO Low Profile", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_LP_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO TKL Black", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_TKL_B_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO TKL White", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_TKL_W_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 Core RGB", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K70_CORE_RGB_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 Core RGB TKL", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K70_CORE_RGB_TKL_PID, 1, 0xFF42);
|
||||
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB PRO", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K70_RGB_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB PRO V2", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K70_RGB_PRO_V2_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB TKL", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K70_RGB_TKL_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB TKL Champion Series", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K70_RGB_TKL_CS_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K95 RGB PLATINUM XT", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K95_PLATINUM_XT_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K100 RGB Optical", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K100_OPTICAL_V1_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K100 RGB Optical", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K100_OPTICAL_V2_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K100 MX Red", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K100_MXRED_PID, 1, 0xFF42);
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Mice |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Dark Core RGB SE (Wired)", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_DARK_CORE_RGB_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Dark Core RGB Pro SE (Wired)", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_DARK_CORE_RGB_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Harpoon Wireless (Wired)", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_HARPOON_WIRELESS_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Ironclaw Wireless (Wired)", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_IRONCLAW_WIRELESS_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Katar Pro", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_KATAR_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Katar Pro V2", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_KATAR_PRO_V2_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Katar Pro XT", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_KATAR_PRO_XT_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair M55 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_M55_RGB_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair M65 RGB Ultra Wired", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_M65_RGB_ULTRA_WIRED_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair M65 RGB Ultra Wireless (Wired)", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_M65_RGB_ULTRA_WIRELESS_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair M75 Gaming Mouse", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_M75_GAMING_MOUSE_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Slipstream Wireless Receiver HW", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_SLIPSTREAM_WIRELESS_PID1, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Slipstream Wireless Receiver SW", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_SLIPSTREAM_WIRELESS_PID2, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Slipstream Wireless Receiver HW", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_SLIPSTREAM_WIRELESS_V2_PID1, 1, 0xFF42);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Mousemat |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IP("Corsair MM700", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_MM700_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair MM700 3XL", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_MM700_3XL_PID, 1, 0xFF42);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,118 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairPeripheralV2Devices.h |
|
||||
| |
|
||||
| Device list for Corsair V2 peripherals |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "RGBController.h"
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "KeyboardLayoutManager.h"
|
||||
|
||||
#define CORSAIR_ZONES_MAX 6
|
||||
|
||||
enum corsair_v2_device_mode
|
||||
{
|
||||
CORSAIR_V2_MODE_HW = 0x01, /* Hardware RGB mode */
|
||||
CORSAIR_V2_MODE_SW = 0x02, /* Software RGB mode */
|
||||
};
|
||||
|
||||
enum corsair_v2_supports
|
||||
{
|
||||
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK = 1,
|
||||
CORSAIR_V2_TYPE_HW_COLOUR_BLOCK = 2,
|
||||
CORSAIR_V2_TYPE_SW_TRIPLETS = 3,
|
||||
CORSAIR_V2_TYPE_HW_TRIPLETS = 4,
|
||||
};
|
||||
|
||||
enum corsair_v2_kb_layout
|
||||
{
|
||||
CORSAIR_V2_KB_LAYOUT_ANSI = 0x01, /* US ANSI Layout */
|
||||
CORSAIR_V2_KB_LAYOUT_ISO = 0x02, /* EURO ISO Layout */
|
||||
CORSAIR_V2_KB_LAYOUT_ABNT = 0x03, /* Brazilian Layout */
|
||||
CORSAIR_V2_KB_LAYOUT_JIS = 0x04, /* Japanese Layout */
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
std::string name;
|
||||
zone_type type;
|
||||
uint8_t rows;
|
||||
uint8_t cols;
|
||||
} corsair_v2_zone;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t zone;
|
||||
uint8_t row;
|
||||
uint8_t col;
|
||||
uint8_t index;
|
||||
const char* name;
|
||||
} corsair_v2_led;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t pid;
|
||||
device_type type;
|
||||
uint8_t rows;
|
||||
uint8_t cols;
|
||||
const corsair_v2_zone* zones[CORSAIR_ZONES_MAX];
|
||||
keyboard_keymap_overlay_values* layout_new;
|
||||
} corsair_v2_device;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Corsair V2 Protocol Keyboards |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_K55_RGB_PRO_PID 0x1BA4
|
||||
#define CORSAIR_K57_RGB_WIRED_PID 0x1B6E
|
||||
#define CORSAIR_K57_RGB_WIRELESS_PID 0x1B62
|
||||
#define CORSAIR_K60_RGB_PRO_PID 0x1BA0
|
||||
#define CORSAIR_K60_RGB_PRO_LP_PID 0x1BAD
|
||||
#define CORSAIR_K60_RGB_PRO_TKL_B_PID 0x1BC7
|
||||
#define CORSAIR_K60_RGB_PRO_TKL_W_PID 0x1BED
|
||||
#define CORSAIR_K70_CORE_RGB_PID 0x1BFD
|
||||
#define CORSAIR_K70_CORE_RGB_TKL_PID 0x2B01
|
||||
#define CORSAIR_K70_RGB_PRO_PID 0x1BC4
|
||||
#define CORSAIR_K70_RGB_PRO_V2_PID 0x1BB3
|
||||
#define CORSAIR_K70_RGB_TKL_PID 0x1B73
|
||||
#define CORSAIR_K70_RGB_TKL_CS_PID 0x1BB9
|
||||
#define CORSAIR_K95_PLATINUM_XT_PID 0x1B89
|
||||
#define CORSAIR_K100_OPTICAL_V1_PID 0x1B7C
|
||||
#define CORSAIR_K100_OPTICAL_V2_PID 0x1BC5
|
||||
#define CORSAIR_K100_MXRED_PID 0x1B7D
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Corsair V2 Protocol Mice |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_DARK_CORE_RGB_PID 0x1B4B
|
||||
#define CORSAIR_DARK_CORE_RGB_PRO_PID 0x1B7E
|
||||
#define CORSAIR_HARPOON_WIRELESS_PID 0x1B5E
|
||||
#define CORSAIR_IRONCLAW_WIRELESS_PID 0x1B4C
|
||||
#define CORSAIR_KATAR_PRO_PID 0x1B93
|
||||
#define CORSAIR_KATAR_PRO_V2_PID 0x1BBA
|
||||
#define CORSAIR_KATAR_PRO_XT_PID 0x1BAC
|
||||
#define CORSAIR_M55_RGB_PRO_PID 0x1B70
|
||||
#define CORSAIR_M65_RGB_ULTRA_WIRED_PID 0x1B9E
|
||||
#define CORSAIR_M65_RGB_ULTRA_WIRELESS_PID 0x1BB5
|
||||
#define CORSAIR_M75_GAMING_MOUSE_PID 0x1BF0
|
||||
#define CORSAIR_SLIPSTREAM_WIRELESS_PID1 0x1BA6
|
||||
#define CORSAIR_SLIPSTREAM_WIRELESS_V2_PID1 0x1B66
|
||||
#define CORSAIR_SLIPSTREAM_WIRELESS_PID2 0x1B65
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Corsair V2 Protocol Mousemats |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_MM700_PID 0x1B9B
|
||||
#define CORSAIR_MM700_3XL_PID 0x1BC9
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| These constant values are defined in |
|
||||
| CorsairPeripheralV2Devices.cpp |
|
||||
\*-----------------------------------------------------*/
|
||||
extern const unsigned int CORSAIR_V2_DEVICE_COUNT;
|
||||
extern const corsair_v2_device** corsair_v2_device_list;
|
||||
@@ -0,0 +1,88 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairPeripheralV2HardwareController.cpp |
|
||||
| |
|
||||
| Driver for Corsair V2 peripherals - hardware modes |
|
||||
| |
|
||||
| Chris M (Dr_No) 07 Dec 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "LogManager.h"
|
||||
#include "CorsairPeripheralV2HardwareController.h"
|
||||
|
||||
CorsairPeripheralV2HWController::CorsairPeripheralV2HWController(hid_device* dev_handle, const char* path, std::string name) : CorsairPeripheralV2Controller(dev_handle, path, name)
|
||||
{
|
||||
SetRenderMode(CORSAIR_V2_MODE_SW);
|
||||
LightingControl(0x5F);
|
||||
}
|
||||
|
||||
CorsairPeripheralV2HWController::~CorsairPeripheralV2HWController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2HWController::SetLedsDirect(std::vector<RGBColor *>colors)
|
||||
{
|
||||
switch(light_ctrl)
|
||||
{
|
||||
case CORSAIR_V2_LIGHT_CTRL1:
|
||||
SetLedsDirectColourBlocks(colors);
|
||||
break;
|
||||
case CORSAIR_V2_LIGHT_CTRL2:
|
||||
SetLedsDirectTriplets(colors);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("[%s] Error setting Direct mode: Device supportes returned %i",
|
||||
device_name.c_str(), light_ctrl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2HWController::SetLedsDirectColourBlocks(std::vector<RGBColor *>colors)
|
||||
{
|
||||
uint16_t count = (uint16_t)colors.size();
|
||||
uint16_t green = count;
|
||||
uint16_t blue = (count * 2);
|
||||
uint16_t length = (count * 3);
|
||||
uint8_t* buffer = new uint8_t[length];
|
||||
|
||||
memset(buffer, 0, length);
|
||||
|
||||
for(std::size_t i = 0; i < count; i++)
|
||||
{
|
||||
RGBColor color = *colors[i];
|
||||
|
||||
buffer[i] = RGBGetRValue(color);
|
||||
buffer[i + green] = RGBGetGValue(color);
|
||||
buffer[i + blue] = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
SetLEDs(buffer, length);
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2HWController::SetLedsDirectTriplets(std::vector<RGBColor *>colors)
|
||||
{
|
||||
uint16_t count = (uint16_t)colors.size();
|
||||
uint16_t length = (count * 3) + CORSAIR_V2HW_DATA_OFFSET;
|
||||
uint8_t* buffer = new uint8_t[length];
|
||||
|
||||
memset(buffer, 0, length);
|
||||
|
||||
buffer[0] = CORSAIR_V2_MODE_DIRECT & 0xFF;
|
||||
buffer[1] = CORSAIR_V2_MODE_DIRECT >> 8;
|
||||
for(std::size_t i = 0; i < count; i++)
|
||||
{
|
||||
RGBColor color = *colors[i];
|
||||
std::size_t idx = (i * 3) + CORSAIR_V2HW_DATA_OFFSET;
|
||||
|
||||
buffer[idx] = RGBGetRValue(color);
|
||||
buffer[idx + 1] = RGBGetGValue(color);
|
||||
buffer[idx + 2] = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
SetLEDs(buffer, length);
|
||||
delete[] buffer;
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairPeripheralV2HardwareController.h |
|
||||
| |
|
||||
| Driver for Corsair V2 peripherals - hardware modes |
|
||||
| |
|
||||
| Chris M (Dr_No) 07 Dec 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "CorsairPeripheralV2Controller.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
|
||||
#undef CORSAIR_V2_WRITE_SIZE
|
||||
#define CORSAIR_V2_WRITE_SIZE 1025
|
||||
#define CORSAIR_V2HW_DATA_OFFSET 2
|
||||
|
||||
class CorsairPeripheralV2HWController : public CorsairPeripheralV2Controller
|
||||
{
|
||||
public:
|
||||
CorsairPeripheralV2HWController(hid_device* dev_handle, const char* path, std::string name);
|
||||
~CorsairPeripheralV2HWController();
|
||||
|
||||
void SetLedsDirect(std::vector<RGBColor *> colors);
|
||||
|
||||
private:
|
||||
void SetLedsDirectColourBlocks(std::vector<RGBColor *> colors);
|
||||
void SetLedsDirectTriplets(std::vector<RGBColor *> colors);
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairPeripheralV2SoftwareController.cpp |
|
||||
| |
|
||||
| Driver for Corsair V2 peripherals - software modes |
|
||||
| |
|
||||
| Chris M (Dr_No) 11 Aug 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "LogManager.h"
|
||||
#include "CorsairPeripheralV2SoftwareController.h"
|
||||
|
||||
CorsairPeripheralV2SWController::CorsairPeripheralV2SWController(hid_device* dev_handle, const char* path, std::string name) : CorsairPeripheralV2Controller(dev_handle, path, name)
|
||||
{
|
||||
SetRenderMode(CORSAIR_V2_MODE_SW);
|
||||
LightingControl(0x5F);
|
||||
}
|
||||
|
||||
CorsairPeripheralV2SWController::~CorsairPeripheralV2SWController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2SWController::SetLedsDirect(std::vector<RGBColor *>colors)
|
||||
{
|
||||
uint16_t count = (uint16_t)colors.size();
|
||||
uint16_t green = count;
|
||||
uint16_t blue = count * 2;
|
||||
uint16_t length = count * 3;
|
||||
uint8_t* buffer = new uint8_t[length];
|
||||
|
||||
memset(buffer, 0, length);
|
||||
|
||||
for(std::size_t i = 0; i < count; i++)
|
||||
{
|
||||
RGBColor color = *colors[i];
|
||||
|
||||
buffer[i] = RGBGetRValue(color);
|
||||
buffer[green + i] = RGBGetGValue(color);
|
||||
buffer[blue + i] = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
SetLEDs(buffer, length);
|
||||
delete[] buffer;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairPeripheralV2SoftwareController.h |
|
||||
| |
|
||||
| Driver for Corsair V2 peripherals - software modes |
|
||||
| |
|
||||
| Chris M (Dr_No) 11 Aug 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "CorsairPeripheralV2Controller.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
|
||||
class CorsairPeripheralV2SWController : public CorsairPeripheralV2Controller
|
||||
{
|
||||
public:
|
||||
CorsairPeripheralV2SWController(hid_device* dev_handle, const char* path, std::string name);
|
||||
~CorsairPeripheralV2SWController();
|
||||
|
||||
void SetLedsDirect(std::vector<RGBColor *> colors);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
@@ -0,0 +1,280 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CorsairV2HardwareController.cpp |
|
||||
| |
|
||||
| RGBController for Corsair V2 peripherals - hardware |
|
||||
| modes |
|
||||
| |
|
||||
| Chris M (Dr_No) 10 Dec 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "LogManager.h"
|
||||
#include "RGBController_CorsairV2Hardware.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Corsair Peripherals V2 Hardware
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectCorsairV2HardwareControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CorsairV2HW::RGBController_CorsairV2HW(CorsairPeripheralV2Controller *controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
const corsair_v2_device* corsair = controller->GetDeviceData();
|
||||
|
||||
name = controller->GetName();
|
||||
vendor = "Corsair";
|
||||
description = "Corsair Peripheral V2 HW Device";
|
||||
type = corsair->type;
|
||||
version = controller->GetFirmwareString();
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = CORSAIR_V2_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 = CORSAIR_V2_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(Static.colors_max);
|
||||
Static.brightness_min = CORSAIR_V2_BRIGHTNESS_MIN;
|
||||
Static.brightness_max = CORSAIR_V2_BRIGHTNESS_MAX;
|
||||
Static.brightness = CORSAIR_V2_BRIGHTNESS_MAX;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Static);
|
||||
|
||||
SetupZones();
|
||||
/*-----------------------------------------------------*\
|
||||
| The Corsair K55 RGB PRO requires a packet within |
|
||||
| 1 minutes of sending the lighting change in order |
|
||||
| to not revert back into rainbow mode. Start a thread |
|
||||
| to continuously send a keepalive packet every 50 sec |
|
||||
\*-----------------------------------------------------*/
|
||||
keepalive_thread_run = true;
|
||||
keepalive_thread = new std::thread(&RGBController_CorsairV2HW::KeepaliveThread, this);
|
||||
}
|
||||
|
||||
RGBController_CorsairV2HW::~RGBController_CorsairV2HW()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Close keepalive thread |
|
||||
\*-----------------------------------------------------*/
|
||||
keepalive_thread_run = false;
|
||||
keepalive_thread->join();
|
||||
delete keepalive_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_CorsairV2HW::SetupZones()
|
||||
{
|
||||
std::string physical_size;
|
||||
KEYBOARD_LAYOUT new_layout;
|
||||
unsigned int max_led_value = 0;
|
||||
const corsair_v2_device* corsair = controller->GetDeviceData();
|
||||
unsigned int layout = controller->GetKeyboardLayout();
|
||||
|
||||
switch(layout)
|
||||
{
|
||||
case CORSAIR_V2_KB_LAYOUT_ISO:
|
||||
new_layout = KEYBOARD_LAYOUT_ISO_QWERTY;
|
||||
break;
|
||||
|
||||
case CORSAIR_V2_KB_LAYOUT_JIS:
|
||||
new_layout = KEYBOARD_LAYOUT_JIS;
|
||||
break;
|
||||
|
||||
case CORSAIR_V2_KB_LAYOUT_ANSI:
|
||||
case CORSAIR_V2_KB_LAYOUT_ABNT:
|
||||
default:
|
||||
new_layout = KEYBOARD_LAYOUT_ANSI_QWERTY;
|
||||
break;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Fill in zones from the device data |
|
||||
\*---------------------------------------------------------*/
|
||||
for(size_t i = 0; i < CORSAIR_ZONES_MAX; i++)
|
||||
{
|
||||
if(corsair->zones[i] == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
zone new_zone;
|
||||
|
||||
new_zone.name = corsair->zones[i]->name;
|
||||
new_zone.type = corsair->zones[i]->type;
|
||||
|
||||
if(new_zone.type == ZONE_TYPE_MATRIX)
|
||||
{
|
||||
KeyboardLayoutManager new_kb(new_layout, corsair->layout_new->base_size, corsair->layout_new->key_values);
|
||||
|
||||
matrix_map_type * new_map = new matrix_map_type;
|
||||
new_zone.matrix_map = new_map;
|
||||
|
||||
new_map->height = corsair->zones[i]->rows;
|
||||
new_map->width = corsair->zones[i]->cols;
|
||||
new_map->map = new unsigned int[new_map->height * new_map->width];
|
||||
|
||||
if(corsair->layout_new->base_size != KEYBOARD_SIZE_EMPTY)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Minor adjustments to keyboard layout |
|
||||
\*---------------------------------------------------------*/
|
||||
keyboard_keymap_overlay_values* temp = corsair->layout_new;
|
||||
new_kb.ChangeKeys(*temp);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Matrix map still uses declared zone rows and columns |
|
||||
| as the packet structure depends on the matrix map |
|
||||
\*---------------------------------------------------------*/
|
||||
new_kb.GetKeyMap(new_map->map, KEYBOARD_MAP_FILL_TYPE_COUNT, new_map->height, new_map->width);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create LEDs for the Matrix zone |
|
||||
| Place keys in the layout to populate the matrix |
|
||||
\*---------------------------------------------------------*/
|
||||
new_zone.leds_count = new_kb.GetKeyCount();
|
||||
LOG_DEBUG("[%s] Created KB matrix with %d rows and %d columns containing %d keys",
|
||||
controller->GetName().c_str(), new_kb.GetRowCount(), new_kb.GetColumnCount(), new_zone.leds_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);
|
||||
max_led_value = std::max(max_led_value, new_led.value);
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Add 1 the max_led_value to account for the 0th index |
|
||||
\*---------------------------------------------------------*/
|
||||
max_led_value++;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_zone.leds_count = corsair->zones[i]->rows * corsair->zones[i]->cols;
|
||||
new_zone.matrix_map = NULL;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create LEDs for the Linear / Single zone |
|
||||
\*---------------------------------------------------------*/
|
||||
for(size_t led_idx = 0; led_idx < new_zone.leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
|
||||
new_led.name = new_zone.name + " ";
|
||||
new_led.name.append(std::to_string( led_idx ));
|
||||
new_led.value = (unsigned int)leds.size();
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
max_led_value = std::max(max_led_value, (unsigned int)leds.size());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| name is not set yet so description is used instead |
|
||||
\*---------------------------------------------------------*/
|
||||
LOG_DEBUG("[%s] Creating a %s zone: %s with %d LEDs", description.c_str(),
|
||||
((new_zone.type == ZONE_TYPE_MATRIX) ? "matrix": "linear"),
|
||||
new_zone.name.c_str(), new_zone.leds_count);
|
||||
new_zone.leds_min = new_zone.leds_count;
|
||||
new_zone.leds_max = new_zone.leds_count;
|
||||
zones.push_back(new_zone);
|
||||
}
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create a buffer map of pointers which contains the |
|
||||
| layout order of colors the device expects. |
|
||||
\*---------------------------------------------------------*/
|
||||
for(size_t led_idx = 0; led_idx < max_led_value; led_idx++)
|
||||
{
|
||||
buffer_map.push_back(&null_color);
|
||||
}
|
||||
|
||||
for(size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
buffer_map[leds[led_idx].value] = &colors[led_idx];
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CorsairV2HW::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_CorsairV2HW::DeviceUpdateLEDs()
|
||||
{
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
|
||||
controller->SetLedsDirect(buffer_map);
|
||||
}
|
||||
|
||||
void RGBController_CorsairV2HW::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
controller->SetLedsDirect(buffer_map);
|
||||
}
|
||||
|
||||
void RGBController_CorsairV2HW::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
controller->SetLedsDirect(buffer_map);
|
||||
}
|
||||
|
||||
void RGBController_CorsairV2HW::DeviceUpdateMode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_CorsairV2HW::KeepaliveThread()
|
||||
{
|
||||
while(keepalive_thread_run.load())
|
||||
{
|
||||
if(active_mode == 0)
|
||||
{
|
||||
if((std::chrono::steady_clock::now() - last_update_time) >
|
||||
std::chrono::milliseconds(CORSAIR_V2_UPDATE_PERIOD))
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(CORSAIR_V2_SLEEP_PERIOD);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CorsairV2HardwareController.h |
|
||||
| |
|
||||
| RGBController for Corsair V2 peripherals - hardware |
|
||||
| modes |
|
||||
| |
|
||||
| Chris M (Dr_No) 10 Dec 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "CorsairPeripheralV2Controller.h"
|
||||
#include "CorsairPeripheralV2HardwareController.h"
|
||||
|
||||
class RGBController_CorsairV2HW : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CorsairV2HW(CorsairPeripheralV2Controller* controller_ptr);
|
||||
~RGBController_CorsairV2HW();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void KeepaliveThread();
|
||||
|
||||
private:
|
||||
CorsairPeripheralV2Controller* controller;
|
||||
|
||||
RGBColor null_color = 0;
|
||||
std::vector<RGBColor *> buffer_map;
|
||||
|
||||
std::thread* keepalive_thread;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::chrono::time_point
|
||||
<std::chrono::steady_clock> last_update_time;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,267 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CorsairV2SoftwareController.cpp |
|
||||
| |
|
||||
| RGBController for Corsair V2 peripherals - software |
|
||||
| modes |
|
||||
| |
|
||||
| Chris M (Dr_No) 11 Aug 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "LogManager.h"
|
||||
#include "RGBController_CorsairV2Software.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Corsair Peripherals V2 Software
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectCorsairV2SoftwareControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CorsairV2SW::RGBController_CorsairV2SW(CorsairPeripheralV2Controller *controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
const corsair_v2_device* corsair = controller->GetDeviceData();
|
||||
|
||||
name = controller->GetName();
|
||||
vendor = "Corsair";
|
||||
description = "Corsair Peripheral V2 SW Device";
|
||||
type = corsair->type;
|
||||
version = controller->GetFirmwareString();
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = CORSAIR_V2_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
/*-----------------------------------------------------*\
|
||||
| The Corsair K55 RGB PRO requires a packet within |
|
||||
| 1 minutes of sending the lighting change in order |
|
||||
| to not revert back into rainbow mode. Start a thread |
|
||||
| to continuously send a keepalive packet every 50 sec |
|
||||
\*-----------------------------------------------------*/
|
||||
keepalive_thread_run = true;
|
||||
keepalive_thread = new std::thread(&RGBController_CorsairV2SW::KeepaliveThread, this);
|
||||
}
|
||||
|
||||
RGBController_CorsairV2SW::~RGBController_CorsairV2SW()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Close keepalive thread |
|
||||
\*-----------------------------------------------------*/
|
||||
keepalive_thread_run = false;
|
||||
keepalive_thread->join();
|
||||
delete keepalive_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_CorsairV2SW::SetupZones()
|
||||
{
|
||||
std::string physical_size;
|
||||
KEYBOARD_LAYOUT new_layout;
|
||||
unsigned int max_led_value = 0;
|
||||
const corsair_v2_device* corsair = controller->GetDeviceData();
|
||||
unsigned int layout = controller->GetKeyboardLayout();
|
||||
|
||||
switch(layout)
|
||||
{
|
||||
case CORSAIR_V2_KB_LAYOUT_ISO:
|
||||
new_layout = KEYBOARD_LAYOUT_ISO_QWERTY;
|
||||
break;
|
||||
|
||||
case CORSAIR_V2_KB_LAYOUT_JIS:
|
||||
new_layout = KEYBOARD_LAYOUT_JIS;
|
||||
break;
|
||||
|
||||
case CORSAIR_V2_KB_LAYOUT_ANSI:
|
||||
case CORSAIR_V2_KB_LAYOUT_ABNT:
|
||||
default:
|
||||
new_layout = KEYBOARD_LAYOUT_ANSI_QWERTY;
|
||||
break;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Fill in zones from the device data |
|
||||
\*---------------------------------------------------------*/
|
||||
for(size_t i = 0; i < CORSAIR_ZONES_MAX; i++)
|
||||
{
|
||||
if(corsair->zones[i] == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
zone new_zone;
|
||||
|
||||
new_zone.name = corsair->zones[i]->name;
|
||||
new_zone.type = corsair->zones[i]->type;
|
||||
|
||||
if(new_zone.type == ZONE_TYPE_MATRIX)
|
||||
{
|
||||
KeyboardLayoutManager new_kb(new_layout, corsair->layout_new->base_size, corsair->layout_new->key_values);
|
||||
|
||||
matrix_map_type * new_map = new matrix_map_type;
|
||||
new_zone.matrix_map = new_map;
|
||||
|
||||
new_map->height = corsair->zones[i]->rows;
|
||||
new_map->width = corsair->zones[i]->cols;
|
||||
new_map->map = new unsigned int[new_map->height * new_map->width];
|
||||
|
||||
if(corsair->layout_new->base_size != KEYBOARD_SIZE_EMPTY)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Minor adjustments to keyboard layout |
|
||||
\*---------------------------------------------------------*/
|
||||
keyboard_keymap_overlay_values* temp = corsair->layout_new;
|
||||
new_kb.ChangeKeys(*temp);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Matrix map still uses declared zone rows and columns |
|
||||
| as the packet structure depends on the matrix map |
|
||||
\*---------------------------------------------------------*/
|
||||
new_kb.GetKeyMap(new_map->map, KEYBOARD_MAP_FILL_TYPE_COUNT, new_map->height, new_map->width);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create LEDs for the Matrix zone |
|
||||
| Place keys in the layout to populate the matrix |
|
||||
\*---------------------------------------------------------*/
|
||||
new_zone.leds_count = new_kb.GetKeyCount();
|
||||
LOG_DEBUG("[%s] Created KB matrix with %d rows and %d columns containing %d keys",
|
||||
controller->GetName().c_str(), new_kb.GetRowCount(), new_kb.GetColumnCount(), new_zone.leds_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);
|
||||
max_led_value = std::max(max_led_value, new_led.value);
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Add 1 the max_led_value to account for the 0th index |
|
||||
\*---------------------------------------------------------*/
|
||||
max_led_value++;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_zone.leds_count = corsair->zones[i]->rows * corsair->zones[i]->cols;
|
||||
new_zone.matrix_map = NULL;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create LEDs for the Linear / Single zone |
|
||||
\*---------------------------------------------------------*/
|
||||
for(size_t led_idx = 0; led_idx < new_zone.leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
|
||||
new_led.name = new_zone.name + " ";
|
||||
new_led.name.append(std::to_string( led_idx ));
|
||||
new_led.value = (unsigned int)leds.size();
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
max_led_value = std::max(max_led_value, (unsigned int)leds.size());
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| name is not set yet so description is used instead |
|
||||
\*---------------------------------------------------------*/
|
||||
LOG_DEBUG("[%s] Creating a %s zone: %s with %d LEDs", description.c_str(),
|
||||
((new_zone.type == ZONE_TYPE_MATRIX) ? "matrix": "linear"),
|
||||
new_zone.name.c_str(), new_zone.leds_count);
|
||||
new_zone.leds_min = new_zone.leds_count;
|
||||
new_zone.leds_max = new_zone.leds_count;
|
||||
zones.push_back(new_zone);
|
||||
}
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create a buffer map of pointers which contains the |
|
||||
| layout order of colors the device expects. |
|
||||
\*---------------------------------------------------------*/
|
||||
for(size_t led_idx = 0; led_idx < max_led_value; led_idx++)
|
||||
{
|
||||
buffer_map.push_back(&null_color);
|
||||
}
|
||||
|
||||
for(size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
buffer_map[leds[led_idx].value] = &colors[led_idx];
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CorsairV2SW::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_CorsairV2SW::DeviceUpdateLEDs()
|
||||
{
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
|
||||
controller->SetLedsDirect(buffer_map);
|
||||
}
|
||||
|
||||
void RGBController_CorsairV2SW::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
controller->SetLedsDirect(buffer_map);
|
||||
}
|
||||
|
||||
void RGBController_CorsairV2SW::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
controller->SetLedsDirect(buffer_map);
|
||||
}
|
||||
|
||||
void RGBController_CorsairV2SW::DeviceUpdateMode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_CorsairV2SW::KeepaliveThread()
|
||||
{
|
||||
while(keepalive_thread_run.load())
|
||||
{
|
||||
if(active_mode == 0)
|
||||
{
|
||||
if((std::chrono::steady_clock::now() - last_update_time) >
|
||||
std::chrono::milliseconds(CORSAIR_V2_UPDATE_PERIOD))
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(CORSAIR_V2_SLEEP_PERIOD);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CorsairV2SoftwareController.h |
|
||||
| |
|
||||
| RGBController for Corsair V2 peripherals - software |
|
||||
| modes |
|
||||
| |
|
||||
| Chris M (Dr_No) 11 Aug 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "CorsairPeripheralV2Controller.h"
|
||||
#include "CorsairPeripheralV2HardwareController.h"
|
||||
#include "CorsairPeripheralV2SoftwareController.h"
|
||||
|
||||
class RGBController_CorsairV2SW : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CorsairV2SW(CorsairPeripheralV2Controller* controller_ptr);
|
||||
~RGBController_CorsairV2SW();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void KeepaliveThread();
|
||||
|
||||
private:
|
||||
CorsairPeripheralV2Controller* controller;
|
||||
|
||||
RGBColor null_color = 0;
|
||||
std::vector<RGBColor *> buffer_map;
|
||||
|
||||
std::thread* keepalive_thread;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::chrono::time_point
|
||||
<std::chrono::steady_clock> last_update_time;
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user