Publish curated LumaOps source from c85ee9ef8f1454f5c305398902afbb9e6738de40
Managed validation / full (push) Failing after 8s
Managed validation / full (push) Failing after 8s
This commit is contained in:
1 parent
91f8b3e3c1
commit
def7920856
2271 files changed
+501225
-501178
No files matched your search
File diff suppressed because it is too large.
Load diff
+224
-224
@@ -1,224 +1,224 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG203LController.cpp |
|
||||
| |
|
||||
| Driver for Logitech G203L |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechG203LController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
#define PACKET_SIZE 20
|
||||
|
||||
LogitechG203LController::LogitechG203LController(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
|
||||
// enable software control
|
||||
unsigned char usb_buf[PACKET_SIZE];
|
||||
|
||||
memset(usb_buf, 0x00, PACKET_SIZE);
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0E;
|
||||
usb_buf[0x03] = 0x50;
|
||||
usb_buf[0x04] = 0x01;
|
||||
usb_buf[0x05] = 0x03;
|
||||
usb_buf[0x06] = 0x07;
|
||||
|
||||
SendPacket(usb_buf);
|
||||
}
|
||||
|
||||
LogitechG203LController::~LogitechG203LController()
|
||||
{
|
||||
if(dev != nullptr)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
}
|
||||
|
||||
std::string LogitechG203LController::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string LogitechG203LController::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechG203LController::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 LogitechG203LController::SendApply()
|
||||
{
|
||||
unsigned char usb_buf[PACKET_SIZE];
|
||||
|
||||
memset(usb_buf, 0x00, PACKET_SIZE);
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x12;
|
||||
usb_buf[0x03] = 0x70;
|
||||
|
||||
SendPacket(usb_buf);
|
||||
}
|
||||
|
||||
void LogitechG203LController::SetSingleLED(int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
unsigned char usb_buf[PACKET_SIZE];
|
||||
|
||||
memset(usb_buf, 0x00, PACKET_SIZE);
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x12;
|
||||
usb_buf[0x03] = 0x10;
|
||||
|
||||
usb_buf[0x04] = (unsigned char)led;
|
||||
usb_buf[0x05] = red;
|
||||
usb_buf[0x06] = green;
|
||||
usb_buf[0x07] = blue;
|
||||
|
||||
usb_buf[0x08] = 0xFF;
|
||||
|
||||
SendPacket(usb_buf);
|
||||
|
||||
SendApply();
|
||||
}
|
||||
|
||||
void LogitechG203LController::SetMode(
|
||||
int mode,
|
||||
int speed,
|
||||
unsigned char bright,
|
||||
unsigned char dir,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue)
|
||||
{
|
||||
unsigned char usb_buf[PACKET_SIZE];
|
||||
unsigned char brightness = bright * 5;
|
||||
|
||||
if(brightness == 0)
|
||||
{
|
||||
brightness = 1;
|
||||
}
|
||||
|
||||
memset(usb_buf, 0x00, PACKET_SIZE);
|
||||
|
||||
//Header
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0E;
|
||||
usb_buf[0x03] = 0x10;
|
||||
//Common Data
|
||||
usb_buf[0x04] = 0x00;
|
||||
usb_buf[0x05] = (unsigned char)mode;
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
//mode specific Data and position
|
||||
if(mode == LOGITECH_G203L_MODE_STATIC) usb_buf[0x09] = 0x02;
|
||||
if(mode == LOGITECH_G203L_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = (unsigned char)((speed>>8) & 0x000000FF);
|
||||
usb_buf[0x0C] = (unsigned char)(speed & 0x000000FF);
|
||||
usb_buf[0x0D] = brightness;
|
||||
}
|
||||
if(mode == LOGITECH_G203L_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = (unsigned char)((speed>>8) & 0x000000FF);
|
||||
usb_buf[0x0A] = (unsigned char)(speed & 0x000000FF);
|
||||
usb_buf[0x0C] = brightness;
|
||||
}
|
||||
if(mode == LOGITECH_G203L_MODE_WAVE)
|
||||
{
|
||||
usb_buf[0x0C] = (unsigned char)(speed & 0x000000FF);
|
||||
usb_buf[0x0D] = dir ? 0x01 : 0x06; //0x01: Left->Right 0x06: Right->Left
|
||||
usb_buf[0x0E] = brightness;
|
||||
usb_buf[0x0F] = (unsigned char)((speed>>8) & 0x000000FF);
|
||||
}
|
||||
if(mode == LOGITECH_G203L_MODE_COLORMIXING)
|
||||
{
|
||||
usb_buf[0x0C] = (unsigned char)(speed & 0x000000FF);
|
||||
usb_buf[0x0D] = (unsigned char)((speed>>8) & 0x000000FF);
|
||||
usb_buf[0x0E] = brightness;
|
||||
}
|
||||
|
||||
//END BYTE
|
||||
usb_buf[0x10] = 0x01;
|
||||
|
||||
SendPacket(usb_buf);
|
||||
}
|
||||
|
||||
void LogitechG203LController::SetDevice(std::vector<RGBColor> colors)
|
||||
{
|
||||
unsigned char usb_buf[PACKET_SIZE];
|
||||
|
||||
memset(usb_buf, 0x00, PACKET_SIZE);
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x12;
|
||||
usb_buf[0x03] = 0x10;
|
||||
|
||||
usb_buf[0x04] = 0x01;
|
||||
usb_buf[0x05] = RGBGetRValue(colors[0]);
|
||||
usb_buf[0x06] = RGBGetGValue(colors[0]);
|
||||
usb_buf[0x07] = RGBGetBValue(colors[0]);
|
||||
|
||||
usb_buf[0x08] = 0x02;
|
||||
usb_buf[0x09] = RGBGetRValue(colors[1]);
|
||||
usb_buf[0x0A] = RGBGetGValue(colors[1]);
|
||||
usb_buf[0x0B] = RGBGetBValue(colors[1]);
|
||||
|
||||
usb_buf[0x0C] = 0x03;
|
||||
usb_buf[0x0D] = RGBGetRValue(colors[2]);
|
||||
usb_buf[0x0E] = RGBGetGValue(colors[2]);
|
||||
usb_buf[0x0F] = RGBGetBValue(colors[2]);
|
||||
|
||||
usb_buf[0x10] = 0xFF;
|
||||
|
||||
SendPacket(usb_buf);
|
||||
|
||||
SendApply();
|
||||
}
|
||||
|
||||
void LogitechG203LController::SendPacket(unsigned char* buffer)
|
||||
{
|
||||
if(dev != nullptr)
|
||||
{
|
||||
if(hid_write(dev, buffer, PACKET_SIZE) == -1)
|
||||
{
|
||||
hid_close(dev);
|
||||
dev = hid_open_path(location.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(dev != nullptr)
|
||||
{
|
||||
if(hid_read_timeout(dev, buffer, PACKET_SIZE, 10) <= 0)
|
||||
{
|
||||
hid_close(dev);
|
||||
dev = hid_open_path(location.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG203LController.cpp |
|
||||
| |
|
||||
| Driver for Logitech G203L |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechG203LController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
#define PACKET_SIZE 20
|
||||
|
||||
LogitechG203LController::LogitechG203LController(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
|
||||
// enable software control
|
||||
unsigned char usb_buf[PACKET_SIZE];
|
||||
|
||||
memset(usb_buf, 0x00, PACKET_SIZE);
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0E;
|
||||
usb_buf[0x03] = 0x50;
|
||||
usb_buf[0x04] = 0x01;
|
||||
usb_buf[0x05] = 0x03;
|
||||
usb_buf[0x06] = 0x07;
|
||||
|
||||
SendPacket(usb_buf);
|
||||
}
|
||||
|
||||
LogitechG203LController::~LogitechG203LController()
|
||||
{
|
||||
if(dev != nullptr)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
}
|
||||
|
||||
std::string LogitechG203LController::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string LogitechG203LController::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechG203LController::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 LogitechG203LController::SendApply()
|
||||
{
|
||||
unsigned char usb_buf[PACKET_SIZE];
|
||||
|
||||
memset(usb_buf, 0x00, PACKET_SIZE);
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x12;
|
||||
usb_buf[0x03] = 0x70;
|
||||
|
||||
SendPacket(usb_buf);
|
||||
}
|
||||
|
||||
void LogitechG203LController::SetSingleLED(int led, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
unsigned char usb_buf[PACKET_SIZE];
|
||||
|
||||
memset(usb_buf, 0x00, PACKET_SIZE);
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x12;
|
||||
usb_buf[0x03] = 0x10;
|
||||
|
||||
usb_buf[0x04] = (unsigned char)led;
|
||||
usb_buf[0x05] = red;
|
||||
usb_buf[0x06] = green;
|
||||
usb_buf[0x07] = blue;
|
||||
|
||||
usb_buf[0x08] = 0xFF;
|
||||
|
||||
SendPacket(usb_buf);
|
||||
|
||||
SendApply();
|
||||
}
|
||||
|
||||
void LogitechG203LController::SetMode(
|
||||
int mode,
|
||||
int speed,
|
||||
unsigned char bright,
|
||||
unsigned char dir,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue)
|
||||
{
|
||||
unsigned char usb_buf[PACKET_SIZE];
|
||||
unsigned char brightness = bright * 5;
|
||||
|
||||
if(brightness == 0)
|
||||
{
|
||||
brightness = 1;
|
||||
}
|
||||
|
||||
memset(usb_buf, 0x00, PACKET_SIZE);
|
||||
|
||||
//Header
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0E;
|
||||
usb_buf[0x03] = 0x10;
|
||||
//Common Data
|
||||
usb_buf[0x04] = 0x00;
|
||||
usb_buf[0x05] = (unsigned char)mode;
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
//mode specific Data and position
|
||||
if(mode == LOGITECH_G203L_MODE_STATIC) usb_buf[0x09] = 0x02;
|
||||
if(mode == LOGITECH_G203L_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = (unsigned char)((speed>>8) & 0x000000FF);
|
||||
usb_buf[0x0C] = (unsigned char)(speed & 0x000000FF);
|
||||
usb_buf[0x0D] = brightness;
|
||||
}
|
||||
if(mode == LOGITECH_G203L_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = (unsigned char)((speed>>8) & 0x000000FF);
|
||||
usb_buf[0x0A] = (unsigned char)(speed & 0x000000FF);
|
||||
usb_buf[0x0C] = brightness;
|
||||
}
|
||||
if(mode == LOGITECH_G203L_MODE_WAVE)
|
||||
{
|
||||
usb_buf[0x0C] = (unsigned char)(speed & 0x000000FF);
|
||||
usb_buf[0x0D] = dir ? 0x01 : 0x06; //0x01: Left->Right 0x06: Right->Left
|
||||
usb_buf[0x0E] = brightness;
|
||||
usb_buf[0x0F] = (unsigned char)((speed>>8) & 0x000000FF);
|
||||
}
|
||||
if(mode == LOGITECH_G203L_MODE_COLORMIXING)
|
||||
{
|
||||
usb_buf[0x0C] = (unsigned char)(speed & 0x000000FF);
|
||||
usb_buf[0x0D] = (unsigned char)((speed>>8) & 0x000000FF);
|
||||
usb_buf[0x0E] = brightness;
|
||||
}
|
||||
|
||||
//END BYTE
|
||||
usb_buf[0x10] = 0x01;
|
||||
|
||||
SendPacket(usb_buf);
|
||||
}
|
||||
|
||||
void LogitechG203LController::SetDevice(std::vector<RGBColor> colors)
|
||||
{
|
||||
unsigned char usb_buf[PACKET_SIZE];
|
||||
|
||||
memset(usb_buf, 0x00, PACKET_SIZE);
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x12;
|
||||
usb_buf[0x03] = 0x10;
|
||||
|
||||
usb_buf[0x04] = 0x01;
|
||||
usb_buf[0x05] = RGBGetRValue(colors[0]);
|
||||
usb_buf[0x06] = RGBGetGValue(colors[0]);
|
||||
usb_buf[0x07] = RGBGetBValue(colors[0]);
|
||||
|
||||
usb_buf[0x08] = 0x02;
|
||||
usb_buf[0x09] = RGBGetRValue(colors[1]);
|
||||
usb_buf[0x0A] = RGBGetGValue(colors[1]);
|
||||
usb_buf[0x0B] = RGBGetBValue(colors[1]);
|
||||
|
||||
usb_buf[0x0C] = 0x03;
|
||||
usb_buf[0x0D] = RGBGetRValue(colors[2]);
|
||||
usb_buf[0x0E] = RGBGetGValue(colors[2]);
|
||||
usb_buf[0x0F] = RGBGetBValue(colors[2]);
|
||||
|
||||
usb_buf[0x10] = 0xFF;
|
||||
|
||||
SendPacket(usb_buf);
|
||||
|
||||
SendApply();
|
||||
}
|
||||
|
||||
void LogitechG203LController::SendPacket(unsigned char* buffer)
|
||||
{
|
||||
if(dev != nullptr)
|
||||
{
|
||||
if(hid_write(dev, buffer, PACKET_SIZE) == -1)
|
||||
{
|
||||
hid_close(dev);
|
||||
dev = hid_open_path(location.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(dev != nullptr)
|
||||
{
|
||||
if(hid_read_timeout(dev, buffer, PACKET_SIZE, 10) <= 0)
|
||||
{
|
||||
hid_close(dev);
|
||||
dev = hid_open_path(location.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +1,48 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG203LController.h |
|
||||
| |
|
||||
| Driver for Logitech G203L |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G203L_MODE_DIRECT = 0x07,
|
||||
LOGITECH_G203L_MODE_OFF = 0x00,
|
||||
LOGITECH_G203L_MODE_STATIC = 0x01,
|
||||
LOGITECH_G203L_MODE_CYCLE = 0x02,
|
||||
LOGITECH_G203L_MODE_WAVE = 0x03,
|
||||
LOGITECH_G203L_MODE_BREATHING = 0x04,
|
||||
LOGITECH_G203L_MODE_COLORMIXING = 0x06,
|
||||
};
|
||||
|
||||
class LogitechG203LController
|
||||
{
|
||||
public:
|
||||
LogitechG203LController(hid_device* dev_handle, const char* path, std::string dev_name);
|
||||
~LogitechG203LController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetSingleLED(int led, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetMode(int mode, int speed, unsigned char brightness, unsigned char dir, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetDevice(std::vector<RGBColor> colors);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
|
||||
void SendApply();
|
||||
void SendPacket(unsigned char* buffer);
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG203LController.h |
|
||||
| |
|
||||
| Driver for Logitech G203L |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G203L_MODE_DIRECT = 0x07,
|
||||
LOGITECH_G203L_MODE_OFF = 0x00,
|
||||
LOGITECH_G203L_MODE_STATIC = 0x01,
|
||||
LOGITECH_G203L_MODE_CYCLE = 0x02,
|
||||
LOGITECH_G203L_MODE_WAVE = 0x03,
|
||||
LOGITECH_G203L_MODE_BREATHING = 0x04,
|
||||
LOGITECH_G203L_MODE_COLORMIXING = 0x06,
|
||||
};
|
||||
|
||||
class LogitechG203LController
|
||||
{
|
||||
public:
|
||||
LogitechG203LController(hid_device* dev_handle, const char* path, std::string dev_name);
|
||||
~LogitechG203LController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetSingleLED(int led, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetMode(int mode, int speed, unsigned char brightness, unsigned char dir, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetDevice(std::vector<RGBColor> colors);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
|
||||
void SendApply();
|
||||
void SendPacket(unsigned char* buffer);
|
||||
};
|
||||
+202
-202
@@ -1,202 +1,202 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG203L.cpp |
|
||||
| |
|
||||
| Driver for Logitech G203L |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechG203L.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G203L
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechMouseG203L
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechG203L::RGBController_LogitechG203L(LogitechG203LController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = "Logitech Mouse Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = LOGITECH_G203L_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G203L_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = LOGITECH_G203L_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Cycle";
|
||||
Cycle.value = LOGITECH_G203L_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = 0x4E20;
|
||||
Cycle.speed_max = 0x03E8;
|
||||
Cycle.brightness = 20;
|
||||
Cycle.brightness_min = 0;
|
||||
Cycle.brightness_max = 20;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G203L_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.speed_min = 0x4E20;
|
||||
Breathing.speed_max = 0x03E8;
|
||||
Breathing.brightness = 20;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = 20;
|
||||
Breathing.colors.resize(1);
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = LOGITECH_G203L_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR;
|
||||
Wave.color_mode = MODE_COLORS_NONE;
|
||||
Wave.speed_min = 0x4E20;
|
||||
Wave.speed_max = 0x03E8;
|
||||
Wave.brightness = 20;
|
||||
Wave.brightness_min = 0;
|
||||
Wave.brightness_max = 20;
|
||||
modes.push_back(Wave);
|
||||
|
||||
mode Colormixing;
|
||||
Colormixing.name = "Colormixing";
|
||||
Colormixing.value = LOGITECH_G203L_MODE_COLORMIXING;
|
||||
Colormixing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Colormixing.color_mode = MODE_COLORS_NONE;
|
||||
Colormixing.speed_min = 0x4E20;
|
||||
Colormixing.speed_max = 0x03E8;
|
||||
Colormixing.brightness = 20;
|
||||
Colormixing.brightness_min = 0;
|
||||
Colormixing.brightness_max = 20;
|
||||
modes.push_back(Colormixing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechG203L::~RGBController_LogitechG203L()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechG203L::SetupZones()
|
||||
{
|
||||
zone g203L_zone;
|
||||
g203L_zone.name = "Mouse Zone";
|
||||
g203L_zone.type = ZONE_TYPE_LINEAR;
|
||||
g203L_zone.leds_min = 3;
|
||||
g203L_zone.leds_max = 3;
|
||||
g203L_zone.leds_count = 3;
|
||||
g203L_zone.matrix_map = NULL;
|
||||
zones.push_back(g203L_zone);
|
||||
|
||||
led g203L_led_l;
|
||||
g203L_led_l.name = "Mouse Left";
|
||||
g203L_led_l.value = 1;
|
||||
leds.push_back(g203L_led_l);
|
||||
|
||||
led g203L_led_c;
|
||||
g203L_led_c.name = "Mouse Center";
|
||||
g203L_led_c.value = 2;
|
||||
leds.push_back(g203L_led_c);
|
||||
|
||||
led g203L_led_r;
|
||||
g203L_led_r.name = "Mouse Right";
|
||||
g203L_led_r.value = 3;
|
||||
leds.push_back(g203L_led_r);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG203L::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechG203L::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetDevice(colors);
|
||||
controller->SetDevice(colors); //dirty workaround for color lag
|
||||
}
|
||||
|
||||
void RGBController_LogitechG203L::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG203L::UpdateSingleLED(int led)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[led]);
|
||||
unsigned char grn = RGBGetGValue(colors[led]);
|
||||
unsigned char blu = RGBGetBValue(colors[led]);
|
||||
|
||||
controller->SetSingleLED(leds[led].value, red, grn, blu);
|
||||
controller->SetSingleLED(leds[led].value, red, grn, blu); //dirty workaround for color lag
|
||||
}
|
||||
|
||||
void RGBController_LogitechG203L::DeviceUpdateMode()
|
||||
{
|
||||
unsigned char red = 0;
|
||||
unsigned char grn = 0;
|
||||
unsigned char blu = 0;
|
||||
unsigned char dir = 0;
|
||||
|
||||
if(modes[active_mode].color_mode & MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
red = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
grn = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
blu = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
}
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR)
|
||||
{
|
||||
dir = (unsigned char)modes[active_mode].direction;
|
||||
}
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_BRIGHTNESS)
|
||||
{
|
||||
//dunno where brightness is
|
||||
}
|
||||
|
||||
if(modes[active_mode].value == LOGITECH_G203L_MODE_DIRECT)
|
||||
{
|
||||
controller->SetDevice(colors);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, dir, red, grn, blu);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG203L.cpp |
|
||||
| |
|
||||
| Driver for Logitech G203L |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechG203L.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G203L
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechMouseG203L
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechG203L::RGBController_LogitechG203L(LogitechG203LController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = "Logitech Mouse Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = LOGITECH_G203L_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G203L_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = LOGITECH_G203L_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Cycle";
|
||||
Cycle.value = LOGITECH_G203L_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = 0x4E20;
|
||||
Cycle.speed_max = 0x03E8;
|
||||
Cycle.brightness = 20;
|
||||
Cycle.brightness_min = 0;
|
||||
Cycle.brightness_max = 20;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G203L_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.speed_min = 0x4E20;
|
||||
Breathing.speed_max = 0x03E8;
|
||||
Breathing.brightness = 20;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = 20;
|
||||
Breathing.colors.resize(1);
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = LOGITECH_G203L_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR;
|
||||
Wave.color_mode = MODE_COLORS_NONE;
|
||||
Wave.speed_min = 0x4E20;
|
||||
Wave.speed_max = 0x03E8;
|
||||
Wave.brightness = 20;
|
||||
Wave.brightness_min = 0;
|
||||
Wave.brightness_max = 20;
|
||||
modes.push_back(Wave);
|
||||
|
||||
mode Colormixing;
|
||||
Colormixing.name = "Colormixing";
|
||||
Colormixing.value = LOGITECH_G203L_MODE_COLORMIXING;
|
||||
Colormixing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Colormixing.color_mode = MODE_COLORS_NONE;
|
||||
Colormixing.speed_min = 0x4E20;
|
||||
Colormixing.speed_max = 0x03E8;
|
||||
Colormixing.brightness = 20;
|
||||
Colormixing.brightness_min = 0;
|
||||
Colormixing.brightness_max = 20;
|
||||
modes.push_back(Colormixing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechG203L::~RGBController_LogitechG203L()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechG203L::SetupZones()
|
||||
{
|
||||
zone g203L_zone;
|
||||
g203L_zone.name = "Mouse Zone";
|
||||
g203L_zone.type = ZONE_TYPE_LINEAR;
|
||||
g203L_zone.leds_min = 3;
|
||||
g203L_zone.leds_max = 3;
|
||||
g203L_zone.leds_count = 3;
|
||||
g203L_zone.matrix_map = NULL;
|
||||
zones.push_back(g203L_zone);
|
||||
|
||||
led g203L_led_l;
|
||||
g203L_led_l.name = "Mouse Left";
|
||||
g203L_led_l.value = 1;
|
||||
leds.push_back(g203L_led_l);
|
||||
|
||||
led g203L_led_c;
|
||||
g203L_led_c.name = "Mouse Center";
|
||||
g203L_led_c.value = 2;
|
||||
leds.push_back(g203L_led_c);
|
||||
|
||||
led g203L_led_r;
|
||||
g203L_led_r.name = "Mouse Right";
|
||||
g203L_led_r.value = 3;
|
||||
leds.push_back(g203L_led_r);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG203L::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechG203L::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetDevice(colors);
|
||||
controller->SetDevice(colors); //dirty workaround for color lag
|
||||
}
|
||||
|
||||
void RGBController_LogitechG203L::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG203L::UpdateSingleLED(int led)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[led]);
|
||||
unsigned char grn = RGBGetGValue(colors[led]);
|
||||
unsigned char blu = RGBGetBValue(colors[led]);
|
||||
|
||||
controller->SetSingleLED(leds[led].value, red, grn, blu);
|
||||
controller->SetSingleLED(leds[led].value, red, grn, blu); //dirty workaround for color lag
|
||||
}
|
||||
|
||||
void RGBController_LogitechG203L::DeviceUpdateMode()
|
||||
{
|
||||
unsigned char red = 0;
|
||||
unsigned char grn = 0;
|
||||
unsigned char blu = 0;
|
||||
unsigned char dir = 0;
|
||||
|
||||
if(modes[active_mode].color_mode & MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
red = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
grn = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
blu = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
}
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR)
|
||||
{
|
||||
dir = (unsigned char)modes[active_mode].direction;
|
||||
}
|
||||
|
||||
if(modes[active_mode].flags & MODE_FLAG_HAS_BRIGHTNESS)
|
||||
{
|
||||
//dunno where brightness is
|
||||
}
|
||||
|
||||
if(modes[active_mode].value == LOGITECH_G203L_MODE_DIRECT)
|
||||
{
|
||||
controller->SetDevice(colors);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, dir, red, grn, blu);
|
||||
}
|
||||
}
|
||||
+33
-33
@@ -1,33 +1,33 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG203L.h |
|
||||
| |
|
||||
| Driver for Logitech G203L |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG203LController.h"
|
||||
|
||||
class RGBController_LogitechG203L : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG203L(LogitechG203LController* controller_ptr);
|
||||
~RGBController_LogitechG203L();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG203LController* controller;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG203L.h |
|
||||
| |
|
||||
| Driver for Logitech G203L |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG203LController.h"
|
||||
|
||||
class RGBController_LogitechG203L : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG203L(LogitechG203LController* controller_ptr);
|
||||
~RGBController_LogitechG203L();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG203LController* controller;
|
||||
};
|
||||
+160
-160
@@ -1,160 +1,160 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG203LController.cpp |
|
||||
| |
|
||||
| Driver for Logitech G203L |
|
||||
| |
|
||||
| Eric Samuelson (edbgon) 06 Oct 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechG213Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechG213Controller::LogitechG213Controller(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG213Controller::~LogitechG213Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string LogitechG213Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string LogitechG213Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechG213Controller::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 LogitechG213Controller::SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0C;
|
||||
usb_buf[0x03] = 0x3A;
|
||||
usb_buf[0x04] = zone;
|
||||
usb_buf[0x05] = 0x01;
|
||||
usb_buf[0x06] = r;
|
||||
usb_buf[0x07] = g;
|
||||
usb_buf[0x08] = b;
|
||||
usb_buf[0x09] = 0x02;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 20);
|
||||
hid_read(dev, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG213Controller::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char direction,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
SendMode(LOGITECH_G213_ZONE_MODE_KEYBOARD, mode, speed, direction, red, green, blue);
|
||||
}
|
||||
|
||||
void LogitechG213Controller::SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char direction,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0C;
|
||||
usb_buf[0x03] = 0x3C;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 100 * speed;
|
||||
|
||||
if(mode == LOGITECH_G213_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_G213_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_G213_MODE_WAVE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = direction & 0xFF;
|
||||
usb_buf[0x0F] = speed >> 8;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 20);
|
||||
hid_read(dev, usb_buf, 20);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG203LController.cpp |
|
||||
| |
|
||||
| Driver for Logitech G203L |
|
||||
| |
|
||||
| Eric Samuelson (edbgon) 06 Oct 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechG213Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechG213Controller::LogitechG213Controller(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG213Controller::~LogitechG213Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string LogitechG213Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string LogitechG213Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechG213Controller::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 LogitechG213Controller::SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0C;
|
||||
usb_buf[0x03] = 0x3A;
|
||||
usb_buf[0x04] = zone;
|
||||
usb_buf[0x05] = 0x01;
|
||||
usb_buf[0x06] = r;
|
||||
usb_buf[0x07] = g;
|
||||
usb_buf[0x08] = b;
|
||||
usb_buf[0x09] = 0x02;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 20);
|
||||
hid_read(dev, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG213Controller::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char direction,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
SendMode(LOGITECH_G213_ZONE_MODE_KEYBOARD, mode, speed, direction, red, green, blue);
|
||||
}
|
||||
|
||||
void LogitechG213Controller::SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char direction,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0C;
|
||||
usb_buf[0x03] = 0x3C;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 100 * speed;
|
||||
|
||||
if(mode == LOGITECH_G213_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_G213_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_G213_MODE_WAVE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = direction & 0xFF;
|
||||
usb_buf[0x0F] = speed >> 8;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 20);
|
||||
hid_read(dev, usb_buf, 20);
|
||||
}
|
||||
@@ -1,95 +1,95 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG203LController.h |
|
||||
| |
|
||||
| Driver for Logitech G203L |
|
||||
| |
|
||||
| Eric Samuelson (edbgon) 06 Oct 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G213_ZONE_MODE_KEYBOARD = 0x00
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G213_MODE_OFF = 0x00,
|
||||
LOGITECH_G213_MODE_STATIC = 0x01,
|
||||
LOGITECH_G213_MODE_BREATHING = 0x02,
|
||||
LOGITECH_G213_MODE_CYCLE = 0x03,
|
||||
LOGITECH_G213_MODE_WAVE = 0x04,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G213_WAVE_MODE_LEFT = 0x06,
|
||||
LOGITECH_G213_WAVE_MODE_RIGHT = 0x01,
|
||||
LOGITECH_G213_WAVE_MODE_CENTER_EDGE = 0x03,
|
||||
LOGITECH_G213_WAVE_MODE_EDGE_CENTER = 0x08,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G213_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_G213_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_G213_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG213Controller
|
||||
{
|
||||
public:
|
||||
LogitechG213Controller(hid_device* dev_handle, const char* path, std::string dev_name);
|
||||
~LogitechG213Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b
|
||||
);
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char direction,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
|
||||
void SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char direction,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG203LController.h |
|
||||
| |
|
||||
| Driver for Logitech G203L |
|
||||
| |
|
||||
| Eric Samuelson (edbgon) 06 Oct 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G213_ZONE_MODE_KEYBOARD = 0x00
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G213_MODE_OFF = 0x00,
|
||||
LOGITECH_G213_MODE_STATIC = 0x01,
|
||||
LOGITECH_G213_MODE_BREATHING = 0x02,
|
||||
LOGITECH_G213_MODE_CYCLE = 0x03,
|
||||
LOGITECH_G213_MODE_WAVE = 0x04,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G213_WAVE_MODE_LEFT = 0x06,
|
||||
LOGITECH_G213_WAVE_MODE_RIGHT = 0x01,
|
||||
LOGITECH_G213_WAVE_MODE_CENTER_EDGE = 0x03,
|
||||
LOGITECH_G213_WAVE_MODE_EDGE_CENTER = 0x08,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G213_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_G213_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_G213_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG213Controller
|
||||
{
|
||||
public:
|
||||
LogitechG213Controller(hid_device* dev_handle, const char* path, std::string dev_name);
|
||||
~LogitechG213Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b
|
||||
);
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char direction,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
|
||||
void SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char direction,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
};
|
||||
+209
-209
@@ -1,209 +1,209 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG213.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G203L |
|
||||
| |
|
||||
| Eric Samuelson (edbgon) 06 Oct 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechG213.h"
|
||||
|
||||
static const char* led_names[] =
|
||||
{
|
||||
"Left Area",
|
||||
"Middle Area",
|
||||
"Right Area",
|
||||
"Arrow and Homekeys",
|
||||
"Numpad",
|
||||
};
|
||||
|
||||
static const unsigned char led_values[] =
|
||||
{
|
||||
0x01,
|
||||
0x02,
|
||||
0x03,
|
||||
0x04,
|
||||
0x05,
|
||||
};
|
||||
|
||||
#define LOGITECH_G213_ZONES (sizeof(led_values) / sizeof(led_values[ 0 ]))
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G213
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechKeyboardG213
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechG213::RGBController_LogitechG213(LogitechG213Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "Logitech G213 Keyboard Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFFFF;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G213_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Cycle";
|
||||
Cycle.value = LOGITECH_G213_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_G213_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G213_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G213_SPEED_NORMAL;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = LOGITECH_G213_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD;
|
||||
Wave.color_mode = MODE_COLORS_NONE;
|
||||
Wave.speed_min = LOGITECH_G213_SPEED_SLOWEST;
|
||||
Wave.speed_max = LOGITECH_G213_SPEED_FASTEST;
|
||||
Wave.speed = LOGITECH_G213_SPEED_NORMAL;
|
||||
Wave.direction = MODE_DIRECTION_LEFT;
|
||||
modes.push_back(Wave);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G213_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.speed_min = LOGITECH_G213_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G213_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G213_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechG213::~RGBController_LogitechG213()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechG213::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
zone new_zone;
|
||||
new_zone.name = "Keyboard";
|
||||
new_zone.type = ZONE_TYPE_LINEAR;
|
||||
new_zone.leds_min = 5;
|
||||
new_zone.leds_max = 5;
|
||||
new_zone.leds_count = 5;
|
||||
|
||||
new_zone.matrix_map = NULL;
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < LOGITECH_G213_ZONES; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = led_names[led_idx];
|
||||
new_led.value = led_values[led_idx];
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG213::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechG213::DeviceUpdateLEDs()
|
||||
{
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
controller->SetDirect((unsigned char)leds[led_idx].value, RGBGetRValue(colors[led_idx]), RGBGetGValue(colors[led_idx]), RGBGetBValue(colors[led_idx]));
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_LogitechG213::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
controller->SetDirect((unsigned char) zone, RGBGetRValue(zones[zone].colors[0]), RGBGetGValue(zones[zone].colors[0]), RGBGetBValue(zones[zone].colors[0]));
|
||||
}
|
||||
|
||||
void RGBController_LogitechG213::UpdateSingleLED(int led)
|
||||
{
|
||||
controller->SetDirect(leds[led].value, RGBGetRValue(colors[led]), RGBGetGValue(colors[led]), RGBGetBValue(colors[led]));
|
||||
}
|
||||
|
||||
void RGBController_LogitechG213::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Direct mode does not send a mode packet |
|
||||
| Call UpdateLEDs to send direct packet |
|
||||
\*---------------------------------------------------------*/
|
||||
if(active_mode == 0xFFFF)
|
||||
{
|
||||
UpdateLEDs();
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char red = 0;
|
||||
unsigned char grn = 0;
|
||||
unsigned char blu = 0;
|
||||
unsigned char direction = 0;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
red = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
grn = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
blu = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
}
|
||||
|
||||
switch (modes[active_mode].direction)
|
||||
{
|
||||
case MODE_DIRECTION_LEFT:
|
||||
// Right to left
|
||||
direction = LOGITECH_G213_WAVE_MODE_LEFT;
|
||||
break;
|
||||
case MODE_DIRECTION_RIGHT:
|
||||
// Left to right
|
||||
direction = LOGITECH_G213_WAVE_MODE_RIGHT;
|
||||
break;
|
||||
case MODE_DIRECTION_UP:
|
||||
// Edge to center
|
||||
direction = LOGITECH_G213_WAVE_MODE_EDGE_CENTER;
|
||||
break;
|
||||
case MODE_DIRECTION_DOWN:
|
||||
// Center to edge
|
||||
direction = LOGITECH_G213_WAVE_MODE_CENTER_EDGE;
|
||||
break;
|
||||
}
|
||||
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, direction, red, grn, blu);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG213.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G203L |
|
||||
| |
|
||||
| Eric Samuelson (edbgon) 06 Oct 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechG213.h"
|
||||
|
||||
static const char* led_names[] =
|
||||
{
|
||||
"Left Area",
|
||||
"Middle Area",
|
||||
"Right Area",
|
||||
"Arrow and Homekeys",
|
||||
"Numpad",
|
||||
};
|
||||
|
||||
static const unsigned char led_values[] =
|
||||
{
|
||||
0x01,
|
||||
0x02,
|
||||
0x03,
|
||||
0x04,
|
||||
0x05,
|
||||
};
|
||||
|
||||
#define LOGITECH_G213_ZONES (sizeof(led_values) / sizeof(led_values[ 0 ]))
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G213
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechKeyboardG213
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechG213::RGBController_LogitechG213(LogitechG213Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "Logitech G213 Keyboard Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFFFF;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G213_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Cycle";
|
||||
Cycle.value = LOGITECH_G213_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_G213_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G213_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G213_SPEED_NORMAL;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = LOGITECH_G213_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD;
|
||||
Wave.color_mode = MODE_COLORS_NONE;
|
||||
Wave.speed_min = LOGITECH_G213_SPEED_SLOWEST;
|
||||
Wave.speed_max = LOGITECH_G213_SPEED_FASTEST;
|
||||
Wave.speed = LOGITECH_G213_SPEED_NORMAL;
|
||||
Wave.direction = MODE_DIRECTION_LEFT;
|
||||
modes.push_back(Wave);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G213_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.speed_min = LOGITECH_G213_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G213_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G213_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechG213::~RGBController_LogitechG213()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechG213::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
zone new_zone;
|
||||
new_zone.name = "Keyboard";
|
||||
new_zone.type = ZONE_TYPE_LINEAR;
|
||||
new_zone.leds_min = 5;
|
||||
new_zone.leds_max = 5;
|
||||
new_zone.leds_count = 5;
|
||||
|
||||
new_zone.matrix_map = NULL;
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < LOGITECH_G213_ZONES; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = led_names[led_idx];
|
||||
new_led.value = led_values[led_idx];
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG213::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechG213::DeviceUpdateLEDs()
|
||||
{
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
controller->SetDirect((unsigned char)leds[led_idx].value, RGBGetRValue(colors[led_idx]), RGBGetGValue(colors[led_idx]), RGBGetBValue(colors[led_idx]));
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_LogitechG213::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
controller->SetDirect((unsigned char) zone, RGBGetRValue(zones[zone].colors[0]), RGBGetGValue(zones[zone].colors[0]), RGBGetBValue(zones[zone].colors[0]));
|
||||
}
|
||||
|
||||
void RGBController_LogitechG213::UpdateSingleLED(int led)
|
||||
{
|
||||
controller->SetDirect(leds[led].value, RGBGetRValue(colors[led]), RGBGetGValue(colors[led]), RGBGetBValue(colors[led]));
|
||||
}
|
||||
|
||||
void RGBController_LogitechG213::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Direct mode does not send a mode packet |
|
||||
| Call UpdateLEDs to send direct packet |
|
||||
\*---------------------------------------------------------*/
|
||||
if(active_mode == 0xFFFF)
|
||||
{
|
||||
UpdateLEDs();
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char red = 0;
|
||||
unsigned char grn = 0;
|
||||
unsigned char blu = 0;
|
||||
unsigned char direction = 0;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
red = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
grn = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
blu = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
}
|
||||
|
||||
switch (modes[active_mode].direction)
|
||||
{
|
||||
case MODE_DIRECTION_LEFT:
|
||||
// Right to left
|
||||
direction = LOGITECH_G213_WAVE_MODE_LEFT;
|
||||
break;
|
||||
case MODE_DIRECTION_RIGHT:
|
||||
// Left to right
|
||||
direction = LOGITECH_G213_WAVE_MODE_RIGHT;
|
||||
break;
|
||||
case MODE_DIRECTION_UP:
|
||||
// Edge to center
|
||||
direction = LOGITECH_G213_WAVE_MODE_EDGE_CENTER;
|
||||
break;
|
||||
case MODE_DIRECTION_DOWN:
|
||||
// Center to edge
|
||||
direction = LOGITECH_G213_WAVE_MODE_CENTER_EDGE;
|
||||
break;
|
||||
}
|
||||
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, direction, red, grn, blu);
|
||||
}
|
||||
+35
-35
@@ -1,35 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG213.h |
|
||||
| |
|
||||
| RGBController for Logitech G203L |
|
||||
| |
|
||||
| Eric Samuelson (edbgon) 06 Oct 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG213Controller.h"
|
||||
|
||||
class RGBController_LogitechG213 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG213(LogitechG213Controller* controller_ptr);
|
||||
~RGBController_LogitechG213();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG213Controller* controller;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG213.h |
|
||||
| |
|
||||
| RGBController for Logitech G203L |
|
||||
| |
|
||||
| Eric Samuelson (edbgon) 06 Oct 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG213Controller.h"
|
||||
|
||||
class RGBController_LogitechG213 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG213(LogitechG213Controller* controller_ptr);
|
||||
~RGBController_LogitechG213();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG213Controller* controller;
|
||||
};
|
||||
+154
-154
@@ -1,154 +1,154 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG560Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G560 |
|
||||
| |
|
||||
| Cheerpipe 28 Oct 2020 |
|
||||
| based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "LogitechG560Controller.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
LogitechG560Controller::LogitechG560Controller(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG560Controller::~LogitechG560Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string LogitechG560Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string LogitechG560Controller::GetDeviceName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
void LogitechG560Controller::SetDirectMode(uint8_t zone)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G560_LED_PACKET_SIZE];
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
usb_buf[0x03] = 0xCA;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G560_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG560Controller::SetOffMode(uint8_t zone)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G560_LED_PACKET_SIZE];
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
usb_buf[0x03] = 0x3F;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G560_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG560Controller::SendSpeakerMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G560_LED_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| This packet sets speaker into direct mode. This mode |
|
||||
| is used by Lightsync Ambilight and Music Visualizer |
|
||||
| realtime effect. |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x03] = 0x3A;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up mode and speed |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x04] = zone;
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| And set up the colors |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
if(mode == LOGITECH_G560_MODE_DIRECT) //G560 only has Direct Mode.
|
||||
{
|
||||
usb_buf[0x09] = 0x02;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G560_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG560Controller::fail_retry_write(hid_device *device, const unsigned char *data, size_t length)
|
||||
{
|
||||
unsigned char usb_buf_out[LOGI_G560_LED_PACKET_SIZE];
|
||||
unsigned int write_max_retry = LOGI_G560_LED_COMMAND_SEND_RETRIES;
|
||||
do
|
||||
{
|
||||
std::this_thread::sleep_for(1ms);
|
||||
int ret = hid_write(device, data, length);
|
||||
|
||||
/*-------------------------------------------------------------------------------------*\
|
||||
| HID write fails if a change led color and set volume command are sent at |
|
||||
| the same time because RGB controller and volume control shares the same interface. |
|
||||
\*-------------------------------------------------------------------------------------*/
|
||||
if(ret == 20)
|
||||
{
|
||||
std::this_thread::sleep_for(1ms);
|
||||
hid_read_timeout(dev, usb_buf_out, LOGI_G560_LED_PACKET_SIZE, 20);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_max_retry--;
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
|
||||
}while (write_max_retry > 0);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG560Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G560 |
|
||||
| |
|
||||
| Cheerpipe 28 Oct 2020 |
|
||||
| based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "LogitechG560Controller.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
LogitechG560Controller::LogitechG560Controller(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG560Controller::~LogitechG560Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string LogitechG560Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string LogitechG560Controller::GetDeviceName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
void LogitechG560Controller::SetDirectMode(uint8_t zone)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G560_LED_PACKET_SIZE];
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
usb_buf[0x03] = 0xCA;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G560_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG560Controller::SetOffMode(uint8_t zone)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G560_LED_PACKET_SIZE];
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
usb_buf[0x03] = 0x3F;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G560_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG560Controller::SendSpeakerMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G560_LED_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| This packet sets speaker into direct mode. This mode |
|
||||
| is used by Lightsync Ambilight and Music Visualizer |
|
||||
| realtime effect. |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x03] = 0x3A;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up mode and speed |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x04] = zone;
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| And set up the colors |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
if(mode == LOGITECH_G560_MODE_DIRECT) //G560 only has Direct Mode.
|
||||
{
|
||||
usb_buf[0x09] = 0x02;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G560_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG560Controller::fail_retry_write(hid_device *device, const unsigned char *data, size_t length)
|
||||
{
|
||||
unsigned char usb_buf_out[LOGI_G560_LED_PACKET_SIZE];
|
||||
unsigned int write_max_retry = LOGI_G560_LED_COMMAND_SEND_RETRIES;
|
||||
do
|
||||
{
|
||||
std::this_thread::sleep_for(1ms);
|
||||
int ret = hid_write(device, data, length);
|
||||
|
||||
/*-------------------------------------------------------------------------------------*\
|
||||
| HID write fails if a change led color and set volume command are sent at |
|
||||
| the same time because RGB controller and volume control shares the same interface. |
|
||||
\*-------------------------------------------------------------------------------------*/
|
||||
if(ret == 20)
|
||||
{
|
||||
std::this_thread::sleep_for(1ms);
|
||||
hid_read_timeout(dev, usb_buf_out, LOGI_G560_LED_PACKET_SIZE, 20);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_max_retry--;
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
|
||||
}while (write_max_retry > 0);
|
||||
}
|
||||
@@ -1,59 +1,59 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG560Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G560 |
|
||||
| |
|
||||
| Cheerpipe 28 Oct 2020 |
|
||||
| based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define LOGI_G560_LED_PACKET_SIZE 20
|
||||
#define LOGI_G560_LED_COMMAND_SEND_RETRIES 3
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G560_MODE_OFF = 0x00,
|
||||
LOGITECH_G560_MODE_DIRECT = 0x01,
|
||||
LOGITECH_G560_MODE_CYCLE = 0x02,
|
||||
LOGITECH_G560_MODE_BREATHING = 0x03,
|
||||
};
|
||||
|
||||
class LogitechG560Controller
|
||||
{
|
||||
public:
|
||||
LogitechG560Controller(hid_device* dev_handle, const char* path, std::string dev_name);
|
||||
~LogitechG560Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
|
||||
void SetDirectMode(uint8_t zone);
|
||||
void SetOffMode(uint8_t zone);
|
||||
|
||||
void SendSpeakerMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
|
||||
void fail_retry_write(hid_device *device, const unsigned char *data, size_t length);
|
||||
};
|
||||
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG560Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G560 |
|
||||
| |
|
||||
| Cheerpipe 28 Oct 2020 |
|
||||
| based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define LOGI_G560_LED_PACKET_SIZE 20
|
||||
#define LOGI_G560_LED_COMMAND_SEND_RETRIES 3
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G560_MODE_OFF = 0x00,
|
||||
LOGITECH_G560_MODE_DIRECT = 0x01,
|
||||
LOGITECH_G560_MODE_CYCLE = 0x02,
|
||||
LOGITECH_G560_MODE_BREATHING = 0x03,
|
||||
};
|
||||
|
||||
class LogitechG560Controller
|
||||
{
|
||||
public:
|
||||
LogitechG560Controller(hid_device* dev_handle, const char* path, std::string dev_name);
|
||||
~LogitechG560Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
|
||||
void SetDirectMode(uint8_t zone);
|
||||
void SetOffMode(uint8_t zone);
|
||||
|
||||
void SendSpeakerMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
|
||||
void fail_retry_write(hid_device *device, const unsigned char *data, size_t length);
|
||||
};
|
||||
|
||||
|
||||
+164
-164
@@ -1,164 +1,164 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG560.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G560 |
|
||||
| |
|
||||
| Cheerpipe 28 Oct 2020 |
|
||||
| based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechG560.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G560
|
||||
@category Speaker
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectLogitechG560
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechG560::RGBController_LogitechG560(LogitechG560Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_SPEAKER;
|
||||
description = "Logitech G560 Lightsync Speaker";
|
||||
location = controller->GetDeviceLocation();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G560_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = LOGITECH_G560_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG560::SetupZones()
|
||||
{
|
||||
zone G560_left_front;
|
||||
G560_left_front.name = "Left Front";
|
||||
G560_left_front.type = ZONE_TYPE_SINGLE;
|
||||
G560_left_front.leds_min = 1;
|
||||
G560_left_front.leds_max = 1;
|
||||
G560_left_front.leds_count = 1;
|
||||
G560_left_front.matrix_map = NULL;
|
||||
zones.push_back(G560_left_front);
|
||||
|
||||
led G560_left_front_led;
|
||||
G560_left_front_led.name = "Left Front";
|
||||
G560_left_front_led.value = 0x00;
|
||||
leds.push_back(G560_left_front_led);
|
||||
|
||||
|
||||
zone G560_right_front;
|
||||
G560_right_front.name = "Right Front";
|
||||
G560_right_front.type = ZONE_TYPE_SINGLE;
|
||||
G560_right_front.leds_min = 1;
|
||||
G560_right_front.leds_max = 1;
|
||||
G560_right_front.leds_count = 1;
|
||||
G560_right_front.matrix_map = NULL;
|
||||
zones.push_back(G560_right_front);
|
||||
|
||||
led G560_right_front_led;
|
||||
G560_right_front_led.name = "Right Front";
|
||||
G560_right_front_led.value = 0x01;
|
||||
leds.push_back(G560_right_front_led);
|
||||
|
||||
|
||||
zone G560_left_rear;
|
||||
G560_left_rear.name = "Left Rear";
|
||||
G560_left_rear.type = ZONE_TYPE_SINGLE;
|
||||
G560_left_rear.leds_min = 1;
|
||||
G560_left_rear.leds_max = 1;
|
||||
G560_left_rear.leds_count = 1;
|
||||
G560_left_rear.matrix_map = NULL;
|
||||
zones.push_back(G560_left_rear);
|
||||
|
||||
led G560_left_read_led;
|
||||
G560_left_read_led.name = "Left Rear";
|
||||
G560_left_read_led.value = 0x02;
|
||||
leds.push_back(G560_left_read_led);
|
||||
|
||||
|
||||
zone G560_right_rear;
|
||||
G560_right_rear.name = "Right Rear";
|
||||
G560_right_rear.type = ZONE_TYPE_SINGLE;
|
||||
G560_right_rear.leds_min = 1;
|
||||
G560_right_rear.leds_max = 1;
|
||||
G560_right_rear.leds_count = 1;
|
||||
G560_right_rear.matrix_map = NULL;
|
||||
zones.push_back(G560_right_rear);
|
||||
|
||||
led G560_right_rear_led;
|
||||
G560_right_rear_led.name = "Right Rear";
|
||||
G560_right_rear_led.value = 0x03;
|
||||
leds.push_back(G560_right_rear_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG560::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechG560::DeviceUpdateLEDs()
|
||||
{
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[led_idx]);
|
||||
unsigned char grn = RGBGetGValue(colors[led_idx]);
|
||||
unsigned char blu = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
controller->SendSpeakerMode((unsigned char)leds[led_idx].value, modes[active_mode].value, red, grn, blu);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_LogitechG560::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG560::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG560::DeviceUpdateMode()
|
||||
{
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
if(modes[active_mode].value == LOGITECH_G560_MODE_OFF)
|
||||
{
|
||||
controller->SetOffMode(leds[led_idx].value);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Required to "reset" RGB controller and start receiving |
|
||||
| color in direct mode |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetDirectMode(leds[led_idx].value);
|
||||
}
|
||||
|
||||
}
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG560.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G560 |
|
||||
| |
|
||||
| Cheerpipe 28 Oct 2020 |
|
||||
| based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechG560.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G560
|
||||
@category Speaker
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectLogitechG560
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechG560::RGBController_LogitechG560(LogitechG560Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_SPEAKER;
|
||||
description = "Logitech G560 Lightsync Speaker";
|
||||
location = controller->GetDeviceLocation();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G560_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = LOGITECH_G560_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG560::SetupZones()
|
||||
{
|
||||
zone G560_left_front;
|
||||
G560_left_front.name = "Left Front";
|
||||
G560_left_front.type = ZONE_TYPE_SINGLE;
|
||||
G560_left_front.leds_min = 1;
|
||||
G560_left_front.leds_max = 1;
|
||||
G560_left_front.leds_count = 1;
|
||||
G560_left_front.matrix_map = NULL;
|
||||
zones.push_back(G560_left_front);
|
||||
|
||||
led G560_left_front_led;
|
||||
G560_left_front_led.name = "Left Front";
|
||||
G560_left_front_led.value = 0x00;
|
||||
leds.push_back(G560_left_front_led);
|
||||
|
||||
|
||||
zone G560_right_front;
|
||||
G560_right_front.name = "Right Front";
|
||||
G560_right_front.type = ZONE_TYPE_SINGLE;
|
||||
G560_right_front.leds_min = 1;
|
||||
G560_right_front.leds_max = 1;
|
||||
G560_right_front.leds_count = 1;
|
||||
G560_right_front.matrix_map = NULL;
|
||||
zones.push_back(G560_right_front);
|
||||
|
||||
led G560_right_front_led;
|
||||
G560_right_front_led.name = "Right Front";
|
||||
G560_right_front_led.value = 0x01;
|
||||
leds.push_back(G560_right_front_led);
|
||||
|
||||
|
||||
zone G560_left_rear;
|
||||
G560_left_rear.name = "Left Rear";
|
||||
G560_left_rear.type = ZONE_TYPE_SINGLE;
|
||||
G560_left_rear.leds_min = 1;
|
||||
G560_left_rear.leds_max = 1;
|
||||
G560_left_rear.leds_count = 1;
|
||||
G560_left_rear.matrix_map = NULL;
|
||||
zones.push_back(G560_left_rear);
|
||||
|
||||
led G560_left_read_led;
|
||||
G560_left_read_led.name = "Left Rear";
|
||||
G560_left_read_led.value = 0x02;
|
||||
leds.push_back(G560_left_read_led);
|
||||
|
||||
|
||||
zone G560_right_rear;
|
||||
G560_right_rear.name = "Right Rear";
|
||||
G560_right_rear.type = ZONE_TYPE_SINGLE;
|
||||
G560_right_rear.leds_min = 1;
|
||||
G560_right_rear.leds_max = 1;
|
||||
G560_right_rear.leds_count = 1;
|
||||
G560_right_rear.matrix_map = NULL;
|
||||
zones.push_back(G560_right_rear);
|
||||
|
||||
led G560_right_rear_led;
|
||||
G560_right_rear_led.name = "Right Rear";
|
||||
G560_right_rear_led.value = 0x03;
|
||||
leds.push_back(G560_right_rear_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG560::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechG560::DeviceUpdateLEDs()
|
||||
{
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[led_idx]);
|
||||
unsigned char grn = RGBGetGValue(colors[led_idx]);
|
||||
unsigned char blu = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
controller->SendSpeakerMode((unsigned char)leds[led_idx].value, modes[active_mode].value, red, grn, blu);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_LogitechG560::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG560::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG560::DeviceUpdateMode()
|
||||
{
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
if(modes[active_mode].value == LOGITECH_G560_MODE_OFF)
|
||||
{
|
||||
controller->SetOffMode(leds[led_idx].value);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Required to "reset" RGB controller and start receiving |
|
||||
| color in direct mode |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetDirectMode(leds[led_idx].value);
|
||||
}
|
||||
|
||||
}
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
+35
-35
@@ -1,35 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG560.h |
|
||||
| |
|
||||
| RGBController for Logitech G560 |
|
||||
| |
|
||||
| Cheerpipe 28 Oct 2020 |
|
||||
| based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG560Controller.h"
|
||||
|
||||
class RGBController_LogitechG560 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG560(LogitechG560Controller* controller_ptr);
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG560Controller* controller;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG560.h |
|
||||
| |
|
||||
| RGBController for Logitech G560 |
|
||||
| |
|
||||
| Cheerpipe 28 Oct 2020 |
|
||||
| based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG560Controller.h"
|
||||
|
||||
class RGBController_LogitechG560 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG560(LogitechG560Controller* controller_ptr);
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG560Controller* controller;
|
||||
};
|
||||
@@ -1,68 +1,68 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG600Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G600 Gaming Mouse |
|
||||
| |
|
||||
| Austin B (austinleroy) 11 Sep 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechG600Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechG600Controller::LogitechG600Controller(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG600Controller::~LogitechG600Controller()
|
||||
{
|
||||
if(dev != nullptr)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
}
|
||||
|
||||
std::string LogitechG600Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechG600Controller::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 LogitechG600Controller::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
RGBColor color
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[8];
|
||||
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
usb_buf[0x00] = 0xF1;
|
||||
usb_buf[0x01] = RGBGetRValue(color);
|
||||
usb_buf[0x02] = RGBGetGValue(color);
|
||||
usb_buf[0x03] = RGBGetBValue(color);
|
||||
usb_buf[0x04] = mode;
|
||||
usb_buf[0x05] = speed & 0xFF;
|
||||
|
||||
hid_send_feature_report(dev, usb_buf, sizeof(usb_buf));
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG600Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G600 Gaming Mouse |
|
||||
| |
|
||||
| Austin B (austinleroy) 11 Sep 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechG600Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechG600Controller::LogitechG600Controller(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG600Controller::~LogitechG600Controller()
|
||||
{
|
||||
if(dev != nullptr)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
}
|
||||
|
||||
std::string LogitechG600Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechG600Controller::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 LogitechG600Controller::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
RGBColor color
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[8];
|
||||
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
usb_buf[0x00] = 0xF1;
|
||||
usb_buf[0x01] = RGBGetRValue(color);
|
||||
usb_buf[0x02] = RGBGetGValue(color);
|
||||
usb_buf[0x03] = RGBGetBValue(color);
|
||||
usb_buf[0x04] = mode;
|
||||
usb_buf[0x05] = speed & 0xFF;
|
||||
|
||||
hid_send_feature_report(dev, usb_buf, sizeof(usb_buf));
|
||||
}
|
||||
@@ -1,56 +1,56 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG600Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G600 Gaming Mouse |
|
||||
| |
|
||||
| Austin B (austinleroy) 11 Sep 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G600_MODE_DIRECT = 0x00,
|
||||
LOGITECH_G600_MODE_BREATHING = 0x01,
|
||||
LOGITECH_G600_MODE_CYCLE = 0x02
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is number of seconds for cycle to complete. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G600_SPEED_SLOWEST = 0x0F, /* Slowest speed */
|
||||
LOGITECH_G600_SPEED_NORMAL = 0x03, /* Normal speed */
|
||||
LOGITECH_G600_SPEED_FASTEST = 0x01, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG600Controller
|
||||
{
|
||||
public:
|
||||
LogitechG600Controller(hid_device* dev, const char* path, std::string dev_name);
|
||||
~LogitechG600Controller();
|
||||
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
RGBColor color
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG600Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G600 Gaming Mouse |
|
||||
| |
|
||||
| Austin B (austinleroy) 11 Sep 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G600_MODE_DIRECT = 0x00,
|
||||
LOGITECH_G600_MODE_BREATHING = 0x01,
|
||||
LOGITECH_G600_MODE_CYCLE = 0x02
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is number of seconds for cycle to complete. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G600_SPEED_SLOWEST = 0x0F, /* Slowest speed */
|
||||
LOGITECH_G600_SPEED_NORMAL = 0x03, /* Normal speed */
|
||||
LOGITECH_G600_SPEED_FASTEST = 0x01, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG600Controller
|
||||
{
|
||||
public:
|
||||
LogitechG600Controller(hid_device* dev, const char* path, std::string dev_name);
|
||||
~LogitechG600Controller();
|
||||
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
RGBColor color
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
};
|
||||
+114
-114
@@ -1,114 +1,114 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG600.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G600 Gaming Mouse |
|
||||
| |
|
||||
| Austin B (austinleroy) 11 Sep 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechG600.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G600
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :o:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechMouseG600
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechG600::RGBController_LogitechG600(LogitechG600Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = "Logitech Mouse Device";
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = LOGITECH_G600_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G600_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.color_mode = MODE_COLORS_PER_LED;
|
||||
Breathing.speed_min = LOGITECH_G600_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G600_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G600_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Spectrum Cycle";
|
||||
Cycle.value = LOGITECH_G600_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_G600_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G600_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G600_SPEED_NORMAL;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechG600::~RGBController_LogitechG600()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechG600::SetupZones()
|
||||
{
|
||||
zone side_lights_zone;
|
||||
side_lights_zone.name = "Side Lights";
|
||||
side_lights_zone.type = ZONE_TYPE_SINGLE;
|
||||
side_lights_zone.leds_min = 1;
|
||||
side_lights_zone.leds_max = 1;
|
||||
side_lights_zone.leds_count = 1;
|
||||
side_lights_zone.matrix_map = NULL;
|
||||
zones.push_back(side_lights_zone);
|
||||
|
||||
// Set up LED
|
||||
led g600_led;
|
||||
g600_led.name = "All";
|
||||
leds.push_back(g600_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG600::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Currently does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechG600::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, GetLED(0));
|
||||
}
|
||||
|
||||
void RGBController_LogitechG600::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG600::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG600::DeviceUpdateMode()
|
||||
{
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, GetLED(0));
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG600.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G600 Gaming Mouse |
|
||||
| |
|
||||
| Austin B (austinleroy) 11 Sep 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechG600.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G600
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :o:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechMouseG600
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechG600::RGBController_LogitechG600(LogitechG600Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = "Logitech Mouse Device";
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = LOGITECH_G600_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G600_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.color_mode = MODE_COLORS_PER_LED;
|
||||
Breathing.speed_min = LOGITECH_G600_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G600_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G600_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Spectrum Cycle";
|
||||
Cycle.value = LOGITECH_G600_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_G600_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G600_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G600_SPEED_NORMAL;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechG600::~RGBController_LogitechG600()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechG600::SetupZones()
|
||||
{
|
||||
zone side_lights_zone;
|
||||
side_lights_zone.name = "Side Lights";
|
||||
side_lights_zone.type = ZONE_TYPE_SINGLE;
|
||||
side_lights_zone.leds_min = 1;
|
||||
side_lights_zone.leds_max = 1;
|
||||
side_lights_zone.leds_count = 1;
|
||||
side_lights_zone.matrix_map = NULL;
|
||||
zones.push_back(side_lights_zone);
|
||||
|
||||
// Set up LED
|
||||
led g600_led;
|
||||
g600_led.name = "All";
|
||||
leds.push_back(g600_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG600::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Currently does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechG600::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, GetLED(0));
|
||||
}
|
||||
|
||||
void RGBController_LogitechG600::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG600::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG600::DeviceUpdateMode()
|
||||
{
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, GetLED(0));
|
||||
}
|
||||
+35
-35
@@ -1,35 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG600.h |
|
||||
| |
|
||||
| RGBController for Logitech G600 Gaming Mouse |
|
||||
| |
|
||||
| Austin B (austinleroy) 11 Sep 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG600Controller.h"
|
||||
|
||||
class RGBController_LogitechG600 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG600(LogitechG600Controller* controller_ptr);
|
||||
~RGBController_LogitechG600();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG600Controller* controller;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG600.h |
|
||||
| |
|
||||
| RGBController for Logitech G600 Gaming Mouse |
|
||||
| |
|
||||
| Austin B (austinleroy) 11 Sep 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG600Controller.h"
|
||||
|
||||
class RGBController_LogitechG600 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG600(LogitechG600Controller* controller_ptr);
|
||||
~RGBController_LogitechG600();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG600Controller* controller;
|
||||
};
|
||||
+192
-192
@@ -1,192 +1,192 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG810Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G810 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 11 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechG810Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechG810Controller::LogitechG810Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name)
|
||||
{
|
||||
dev_pkt_0x11 = dev_handle_0x11;
|
||||
dev_pkt_0x12 = dev_handle_0x12;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG810Controller::~LogitechG810Controller()
|
||||
{
|
||||
hid_close(dev_pkt_0x11);
|
||||
hid_close(dev_pkt_0x12);
|
||||
}
|
||||
|
||||
std::string LogitechG810Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechG810Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void LogitechG810Controller::Commit()
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void LogitechG810Controller::SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
SendDirectFrame(zone, frame_count, frame_data);
|
||||
}
|
||||
|
||||
void LogitechG810Controller::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
SendMode(LOGITECH_G810_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
|
||||
SendMode(LOGITECH_G810_ZONE_MODE_LOGO, mode, speed, red, green, blue);
|
||||
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void LogitechG810Controller::SendCommit()
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0C;
|
||||
usb_buf[0x03] = 0x5D;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG810Controller::SendDirectFrame
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x12;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0C;
|
||||
usb_buf[0x03] = 0x3D;
|
||||
usb_buf[0x05] = zone;
|
||||
usb_buf[0x07] = frame_count;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in frame data |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x08], frame_data, frame_count * 4);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x12, usb_buf, 64);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG810Controller::SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0D;
|
||||
usb_buf[0x03] = 0x3D;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 100 * speed;
|
||||
if(mode == LOGITECH_G810_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_G810_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = 0x64;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG810Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G810 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 11 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechG810Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechG810Controller::LogitechG810Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name)
|
||||
{
|
||||
dev_pkt_0x11 = dev_handle_0x11;
|
||||
dev_pkt_0x12 = dev_handle_0x12;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG810Controller::~LogitechG810Controller()
|
||||
{
|
||||
hid_close(dev_pkt_0x11);
|
||||
hid_close(dev_pkt_0x12);
|
||||
}
|
||||
|
||||
std::string LogitechG810Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechG810Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void LogitechG810Controller::Commit()
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void LogitechG810Controller::SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
SendDirectFrame(zone, frame_count, frame_data);
|
||||
}
|
||||
|
||||
void LogitechG810Controller::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
SendMode(LOGITECH_G810_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
|
||||
SendMode(LOGITECH_G810_ZONE_MODE_LOGO, mode, speed, red, green, blue);
|
||||
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void LogitechG810Controller::SendCommit()
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0C;
|
||||
usb_buf[0x03] = 0x5D;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG810Controller::SendDirectFrame
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x12;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0C;
|
||||
usb_buf[0x03] = 0x3D;
|
||||
usb_buf[0x05] = zone;
|
||||
usb_buf[0x07] = frame_count;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in frame data |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x08], frame_data, frame_count * 4);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x12, usb_buf, 64);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG810Controller::SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0D;
|
||||
usb_buf[0x03] = 0x3D;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 100 * speed;
|
||||
if(mode == LOGITECH_G810_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_G810_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = 0x64;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
@@ -1,102 +1,102 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG810Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G810 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 11 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_ZONE_MODE_KEYBOARD = 0x00,
|
||||
LOGITECH_G810_ZONE_MODE_LOGO = 0x01,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_ZONE_DIRECT_KEYBOARD = 0x01,
|
||||
LOGITECH_G810_ZONE_DIRECT_MEDIA = 0x02,
|
||||
LOGITECH_G810_ZONE_DIRECT_LOGO = 0x10,
|
||||
LOGITECH_G810_ZONE_DIRECT_INDICATORS = 0x40,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_MODE_OFF = 0x00,
|
||||
LOGITECH_G810_MODE_STATIC = 0x01,
|
||||
LOGITECH_G810_MODE_BREATHING = 0x02,
|
||||
LOGITECH_G810_MODE_CYCLE = 0x03,
|
||||
LOGITECH_G810_MODE_WAVE = 0x04,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_G810_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_G810_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG810Controller
|
||||
{
|
||||
public:
|
||||
LogitechG810Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name);
|
||||
~LogitechG810Controller();
|
||||
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void Commit();
|
||||
|
||||
void SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev_pkt_0x11;
|
||||
hid_device* dev_pkt_0x12;
|
||||
std::string name;
|
||||
|
||||
void SendDirectFrame
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
void SendCommit();
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG810Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G810 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 11 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_ZONE_MODE_KEYBOARD = 0x00,
|
||||
LOGITECH_G810_ZONE_MODE_LOGO = 0x01,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_ZONE_DIRECT_KEYBOARD = 0x01,
|
||||
LOGITECH_G810_ZONE_DIRECT_MEDIA = 0x02,
|
||||
LOGITECH_G810_ZONE_DIRECT_LOGO = 0x10,
|
||||
LOGITECH_G810_ZONE_DIRECT_INDICATORS = 0x40,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_MODE_OFF = 0x00,
|
||||
LOGITECH_G810_MODE_STATIC = 0x01,
|
||||
LOGITECH_G810_MODE_BREATHING = 0x02,
|
||||
LOGITECH_G810_MODE_CYCLE = 0x03,
|
||||
LOGITECH_G810_MODE_WAVE = 0x04,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_G810_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_G810_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG810Controller
|
||||
{
|
||||
public:
|
||||
LogitechG810Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name);
|
||||
~LogitechG810Controller();
|
||||
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void Commit();
|
||||
|
||||
void SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev_pkt_0x11;
|
||||
hid_device* dev_pkt_0x12;
|
||||
std::string name;
|
||||
|
||||
void SendDirectFrame
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
void SendCommit();
|
||||
};
|
||||
+402
-402
@@ -1,402 +1,402 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG810.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G810 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 12 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "RGBController_LogitechG810.h"
|
||||
|
||||
//0xFFFFFFFF indicates an unused entry in matrix
|
||||
#define NA 0xFFFFFFFF
|
||||
|
||||
static unsigned int matrix_map[7][23] =
|
||||
{ { 111, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 116, 114, 115, NA, 113, NA, 112, 110, NA, NA, NA },
|
||||
{ 37, NA, 54, 55, 56, 57, NA, 58, 59, 60, 61, NA, 62, 63, 64, 65, 66, 67, 68, 109, 108, 107, 106 },
|
||||
{ 49, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, NA, 41, 42, 38, NA, 69, 70, 71, 79, 80, 81, 82 },
|
||||
{ 39, NA, 16, 22, 4, 17, NA, 19, 24, 20, 8, 14, 15, 43, 44, 45, 72, 73, 74, 91, 92, 93, 83 },
|
||||
{ 53, NA, 0, 18, 3, 5, NA, 6, 7, 9, 10, 11, 47, 48, 46, 36, NA, NA, NA, 88, 89, 90, NA },
|
||||
{ 99, 96, 25, 23, 2, 21, NA, 1, NA, 13, 12, 50, 51, 52, 103, NA, NA, 78, NA, 85, 86, 87, 84 },
|
||||
{ 98, 101, 100, NA, NA, NA, NA, 40, NA, NA, NA, NA, 104, 105, 97, 102, 76, 77, 75, 94, NA, 95, NA } };
|
||||
|
||||
static const char* zone_names[] =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
};
|
||||
|
||||
static zone_type zone_types[] =
|
||||
{
|
||||
ZONE_TYPE_MATRIX,
|
||||
};
|
||||
|
||||
static const unsigned int zone_sizes[] =
|
||||
{
|
||||
117,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char * name;
|
||||
const unsigned char zone;
|
||||
const unsigned char idx;
|
||||
} led_type;
|
||||
|
||||
static const led_type led_names[] =
|
||||
{
|
||||
/* Key Label Zone, Index */
|
||||
{ KEY_EN_A, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x04 },
|
||||
{ KEY_EN_B, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x05 },
|
||||
{ KEY_EN_C, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x06 },
|
||||
{ KEY_EN_D, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x07 },
|
||||
{ KEY_EN_E, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x08 },
|
||||
{ KEY_EN_F, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x09 },
|
||||
{ KEY_EN_G, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x0A },
|
||||
{ KEY_EN_H, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x0B },
|
||||
{ KEY_EN_I, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x0C },
|
||||
{ KEY_EN_J, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x0D },
|
||||
{ KEY_EN_K, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x0E },
|
||||
{ KEY_EN_L, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x0F },
|
||||
{ KEY_EN_M, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x10 },
|
||||
{ KEY_EN_N, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x11 },
|
||||
{ KEY_EN_O, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x12 },
|
||||
{ KEY_EN_P, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x13 },
|
||||
{ KEY_EN_Q, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x14 },
|
||||
{ KEY_EN_R, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x15 },
|
||||
{ KEY_EN_S, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x16 },
|
||||
{ KEY_EN_T, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x17 },
|
||||
{ KEY_EN_U, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x18 },
|
||||
{ KEY_EN_V, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x19 },
|
||||
{ KEY_EN_W, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x1A },
|
||||
{ KEY_EN_X, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x1B },
|
||||
{ KEY_EN_Y, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x1C },
|
||||
{ KEY_EN_Z, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x1D },
|
||||
{ KEY_EN_1, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x1E },
|
||||
{ KEY_EN_2, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x1F },
|
||||
{ KEY_EN_3, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x20 },
|
||||
{ KEY_EN_4, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x21 },
|
||||
{ KEY_EN_5, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x22 },
|
||||
{ KEY_EN_6, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x23 },
|
||||
{ KEY_EN_7, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x24 },
|
||||
{ KEY_EN_8, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x25 },
|
||||
{ KEY_EN_9, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x26 },
|
||||
{ KEY_EN_0, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x27 },
|
||||
{ KEY_EN_ANSI_ENTER, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x28 },
|
||||
{ KEY_EN_ESCAPE, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x29 },
|
||||
{ KEY_EN_BACKSPACE, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x2A },
|
||||
{ KEY_EN_TAB, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x2B },
|
||||
{ KEY_EN_SPACE, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x2C },
|
||||
{ KEY_EN_MINUS, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x2D },
|
||||
{ KEY_EN_EQUALS, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x2E },
|
||||
{ KEY_EN_LEFT_BRACKET, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x2F },
|
||||
{ KEY_EN_RIGHT_BRACKET, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x30 },
|
||||
{ KEY_EN_ANSI_BACK_SLASH, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x31 },//ANSI only
|
||||
{ KEY_EN_POUND, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x32 },//ISO only
|
||||
{ KEY_EN_SEMICOLON, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x33 },
|
||||
{ KEY_EN_QUOTE, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x34 },
|
||||
{ KEY_EN_BACK_TICK, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x35 },
|
||||
{ KEY_EN_COMMA, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x36 },
|
||||
{ KEY_EN_PERIOD, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x37 },
|
||||
{ KEY_EN_FORWARD_SLASH, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x38 },
|
||||
{ KEY_EN_CAPS_LOCK, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x39 },
|
||||
{ KEY_EN_F1, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x3A },
|
||||
{ KEY_EN_F2, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x3B },
|
||||
{ KEY_EN_F3, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x3C },
|
||||
{ KEY_EN_F4, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x3D },
|
||||
{ KEY_EN_F5, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x3E },
|
||||
{ KEY_EN_F6, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x3F },
|
||||
{ KEY_EN_F7, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x40 },
|
||||
{ KEY_EN_F8, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x41 },
|
||||
{ KEY_EN_F9, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x42 },
|
||||
{ KEY_EN_F10, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x43 },
|
||||
{ KEY_EN_F11, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x44 },
|
||||
{ KEY_EN_F12, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x45 },
|
||||
{ KEY_EN_PRINT_SCREEN, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x46 },
|
||||
{ KEY_EN_SCROLL_LOCK, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x47 },
|
||||
{ KEY_EN_PAUSE_BREAK, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x48 },
|
||||
{ KEY_EN_INSERT, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x49 },
|
||||
{ KEY_EN_HOME, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x4A },
|
||||
{ KEY_EN_PAGE_UP, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x4B },
|
||||
{ KEY_EN_DELETE, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x4C },
|
||||
{ KEY_EN_END, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x4D },
|
||||
{ KEY_EN_PAGE_DOWN, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x4E },
|
||||
{ KEY_EN_RIGHT_ARROW, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x4F },
|
||||
{ KEY_EN_LEFT_ARROW, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x50 },
|
||||
{ KEY_EN_DOWN_ARROW, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x51 },
|
||||
{ KEY_EN_UP_ARROW, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x52 },
|
||||
{ KEY_EN_NUMPAD_LOCK, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x53 },
|
||||
{ KEY_EN_NUMPAD_DIVIDE, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x54 },
|
||||
{ KEY_EN_NUMPAD_TIMES, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x55 },
|
||||
{ KEY_EN_NUMPAD_MINUS, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x56 },
|
||||
{ KEY_EN_NUMPAD_PLUS, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x57 },
|
||||
{ KEY_EN_NUMPAD_ENTER, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x58 },
|
||||
{ KEY_EN_NUMPAD_1, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x59 },
|
||||
{ KEY_EN_NUMPAD_2, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x5A },
|
||||
{ KEY_EN_NUMPAD_3, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x5B },
|
||||
{ KEY_EN_NUMPAD_4, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x5C },
|
||||
{ KEY_EN_NUMPAD_5, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x5D },
|
||||
{ KEY_EN_NUMPAD_6, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x5E },
|
||||
{ KEY_EN_NUMPAD_7, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x5F },
|
||||
{ KEY_EN_NUMPAD_8, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x60 },
|
||||
{ KEY_EN_NUMPAD_9, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x61 },
|
||||
{ KEY_EN_NUMPAD_0, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x62 },
|
||||
{ KEY_EN_NUMPAD_PERIOD, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x63 },
|
||||
{ KEY_EN_ISO_BACK_SLASH, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x64 },//ISO only
|
||||
{ KEY_EN_MENU, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x65 },
|
||||
{ KEY_EN_LEFT_CONTROL, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE0 },
|
||||
{ KEY_EN_LEFT_SHIFT, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE1 },
|
||||
{ KEY_EN_LEFT_ALT, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE2 },
|
||||
{ KEY_EN_LEFT_WINDOWS, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE3 },
|
||||
{ KEY_EN_RIGHT_CONTROL, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE4 },
|
||||
{ KEY_EN_RIGHT_SHIFT, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE5 },
|
||||
{ KEY_EN_RIGHT_ALT, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE6 },
|
||||
{ KEY_EN_RIGHT_WINDOWS, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE7 },
|
||||
{ KEY_EN_MEDIA_NEXT, LOGITECH_G810_ZONE_DIRECT_MEDIA, 0xB5 },
|
||||
{ KEY_EN_MEDIA_PREVIOUS, LOGITECH_G810_ZONE_DIRECT_MEDIA, 0xB6 },
|
||||
{ KEY_EN_MEDIA_STOP, LOGITECH_G810_ZONE_DIRECT_MEDIA, 0xB7 },
|
||||
{ KEY_EN_MEDIA_PLAY_PAUSE, LOGITECH_G810_ZONE_DIRECT_MEDIA, 0xCD },
|
||||
{ KEY_EN_MEDIA_MUTE, LOGITECH_G810_ZONE_DIRECT_MEDIA, 0xE2 },
|
||||
{ "Logo", LOGITECH_G810_ZONE_DIRECT_LOGO, 0x01 },
|
||||
{ "Lighting", LOGITECH_G810_ZONE_DIRECT_INDICATORS, 0x01 },
|
||||
{ "Game Mode", LOGITECH_G810_ZONE_DIRECT_INDICATORS, 0x02 },
|
||||
{ "Caps Lock Indicator", LOGITECH_G810_ZONE_DIRECT_INDICATORS, 0x03 },
|
||||
{ "Scroll Lock Indicator", LOGITECH_G810_ZONE_DIRECT_INDICATORS, 0x04 },
|
||||
{ "Num Lock Indicator", LOGITECH_G810_ZONE_DIRECT_INDICATORS, 0x05 },
|
||||
};
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G810
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechKeyboardG810
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechG810::RGBController_LogitechG810(LogitechG810Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "Logitech Keyboard Device";
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFFFF;
|
||||
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 = LOGITECH_G810_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G810_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Cycle";
|
||||
Cycle.value = LOGITECH_G810_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_G810_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G810_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G810_SPEED_NORMAL;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G810_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.speed_min = LOGITECH_G810_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G810_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G810_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechG810::~RGBController_LogitechG810()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Delete the matrix map |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
|
||||
{
|
||||
if(zones[zone_index].matrix_map != NULL)
|
||||
{
|
||||
delete zones[zone_index].matrix_map;
|
||||
}
|
||||
}
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechG810::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int total_led_count = 0;
|
||||
for(unsigned int zone_idx = 0; zone_idx < 1; zone_idx++)
|
||||
{
|
||||
zone new_zone;
|
||||
new_zone.name = zone_names[zone_idx];
|
||||
new_zone.type = zone_types[zone_idx];
|
||||
new_zone.leds_min = zone_sizes[zone_idx];
|
||||
new_zone.leds_max = zone_sizes[zone_idx];
|
||||
new_zone.leds_count = zone_sizes[zone_idx];
|
||||
|
||||
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
|
||||
{
|
||||
new_zone.matrix_map = new matrix_map_type;
|
||||
new_zone.matrix_map->height = 7;
|
||||
new_zone.matrix_map->width = 23;
|
||||
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_zone.matrix_map = NULL;
|
||||
}
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
total_led_count += zone_sizes[zone_idx];
|
||||
}
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = led_names[led_idx].name;
|
||||
new_led.value = ( led_names[led_idx].zone << 8 ) + led_names[led_idx].idx;
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG810::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechG810::DeviceUpdateLEDs()
|
||||
{
|
||||
#define MAX_FRAMES_PER_PACKET 0x0E
|
||||
|
||||
unsigned char frame_buf[MAX_FRAMES_PER_PACKET * 4];
|
||||
unsigned char frame_cnt = 0;
|
||||
unsigned char prev_zone = 0;
|
||||
unsigned char zone = 0;
|
||||
unsigned char idx = 0;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| TODO: Send packets with multiple LED frames |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
zone = ( leds[led_idx].value >> 8 );
|
||||
idx = ( leds[led_idx].value & 0xFF );
|
||||
|
||||
if((zone != prev_zone) && (frame_cnt != 0))
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
frame_cnt = 0;
|
||||
}
|
||||
|
||||
frame_buf[(frame_cnt * 4) + 0] = idx;
|
||||
frame_buf[(frame_cnt * 4) + 1] = RGBGetRValue(colors[led_idx]);
|
||||
frame_buf[(frame_cnt * 4) + 2] = RGBGetGValue(colors[led_idx]);
|
||||
frame_buf[(frame_cnt * 4) + 3] = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
frame_cnt++;
|
||||
prev_zone = zone;
|
||||
|
||||
if(frame_cnt == MAX_FRAMES_PER_PACKET)
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
frame_cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(frame_cnt != 0)
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
}
|
||||
|
||||
controller->Commit();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG810::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG810::UpdateSingleLED(int led)
|
||||
{
|
||||
unsigned char frame[4];
|
||||
unsigned char zone;
|
||||
unsigned char idx;
|
||||
|
||||
zone = ( leds[led].value >> 8 );
|
||||
idx = ( leds[led].value & 0xFF );
|
||||
|
||||
frame[0] = idx;
|
||||
frame[1] = RGBGetRValue(colors[led]);
|
||||
frame[2] = RGBGetGValue(colors[led]);
|
||||
frame[3] = RGBGetBValue(colors[led]);
|
||||
|
||||
controller->SetDirect(zone, 1, frame);
|
||||
controller->Commit();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG810::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Direct mode does not send a mode packet |
|
||||
| Call UpdateLEDs to send direct packet |
|
||||
\*---------------------------------------------------------*/
|
||||
if(active_mode == 0xFFFF)
|
||||
{
|
||||
UpdateLEDs();
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char red = 0;
|
||||
unsigned char grn = 0;
|
||||
unsigned char blu = 0;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
red = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
grn = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
blu = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
}
|
||||
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, red, grn, blu);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG810.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G810 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 12 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "RGBController_LogitechG810.h"
|
||||
|
||||
//0xFFFFFFFF indicates an unused entry in matrix
|
||||
#define NA 0xFFFFFFFF
|
||||
|
||||
static unsigned int matrix_map[7][23] =
|
||||
{ { 111, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 116, 114, 115, NA, 113, NA, 112, 110, NA, NA, NA },
|
||||
{ 37, NA, 54, 55, 56, 57, NA, 58, 59, 60, 61, NA, 62, 63, 64, 65, 66, 67, 68, 109, 108, 107, 106 },
|
||||
{ 49, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, NA, 41, 42, 38, NA, 69, 70, 71, 79, 80, 81, 82 },
|
||||
{ 39, NA, 16, 22, 4, 17, NA, 19, 24, 20, 8, 14, 15, 43, 44, 45, 72, 73, 74, 91, 92, 93, 83 },
|
||||
{ 53, NA, 0, 18, 3, 5, NA, 6, 7, 9, 10, 11, 47, 48, 46, 36, NA, NA, NA, 88, 89, 90, NA },
|
||||
{ 99, 96, 25, 23, 2, 21, NA, 1, NA, 13, 12, 50, 51, 52, 103, NA, NA, 78, NA, 85, 86, 87, 84 },
|
||||
{ 98, 101, 100, NA, NA, NA, NA, 40, NA, NA, NA, NA, 104, 105, 97, 102, 76, 77, 75, 94, NA, 95, NA } };
|
||||
|
||||
static const char* zone_names[] =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
};
|
||||
|
||||
static zone_type zone_types[] =
|
||||
{
|
||||
ZONE_TYPE_MATRIX,
|
||||
};
|
||||
|
||||
static const unsigned int zone_sizes[] =
|
||||
{
|
||||
117,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char * name;
|
||||
const unsigned char zone;
|
||||
const unsigned char idx;
|
||||
} led_type;
|
||||
|
||||
static const led_type led_names[] =
|
||||
{
|
||||
/* Key Label Zone, Index */
|
||||
{ KEY_EN_A, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x04 },
|
||||
{ KEY_EN_B, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x05 },
|
||||
{ KEY_EN_C, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x06 },
|
||||
{ KEY_EN_D, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x07 },
|
||||
{ KEY_EN_E, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x08 },
|
||||
{ KEY_EN_F, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x09 },
|
||||
{ KEY_EN_G, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x0A },
|
||||
{ KEY_EN_H, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x0B },
|
||||
{ KEY_EN_I, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x0C },
|
||||
{ KEY_EN_J, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x0D },
|
||||
{ KEY_EN_K, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x0E },
|
||||
{ KEY_EN_L, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x0F },
|
||||
{ KEY_EN_M, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x10 },
|
||||
{ KEY_EN_N, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x11 },
|
||||
{ KEY_EN_O, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x12 },
|
||||
{ KEY_EN_P, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x13 },
|
||||
{ KEY_EN_Q, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x14 },
|
||||
{ KEY_EN_R, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x15 },
|
||||
{ KEY_EN_S, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x16 },
|
||||
{ KEY_EN_T, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x17 },
|
||||
{ KEY_EN_U, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x18 },
|
||||
{ KEY_EN_V, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x19 },
|
||||
{ KEY_EN_W, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x1A },
|
||||
{ KEY_EN_X, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x1B },
|
||||
{ KEY_EN_Y, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x1C },
|
||||
{ KEY_EN_Z, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x1D },
|
||||
{ KEY_EN_1, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x1E },
|
||||
{ KEY_EN_2, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x1F },
|
||||
{ KEY_EN_3, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x20 },
|
||||
{ KEY_EN_4, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x21 },
|
||||
{ KEY_EN_5, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x22 },
|
||||
{ KEY_EN_6, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x23 },
|
||||
{ KEY_EN_7, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x24 },
|
||||
{ KEY_EN_8, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x25 },
|
||||
{ KEY_EN_9, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x26 },
|
||||
{ KEY_EN_0, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x27 },
|
||||
{ KEY_EN_ANSI_ENTER, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x28 },
|
||||
{ KEY_EN_ESCAPE, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x29 },
|
||||
{ KEY_EN_BACKSPACE, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x2A },
|
||||
{ KEY_EN_TAB, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x2B },
|
||||
{ KEY_EN_SPACE, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x2C },
|
||||
{ KEY_EN_MINUS, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x2D },
|
||||
{ KEY_EN_EQUALS, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x2E },
|
||||
{ KEY_EN_LEFT_BRACKET, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x2F },
|
||||
{ KEY_EN_RIGHT_BRACKET, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x30 },
|
||||
{ KEY_EN_ANSI_BACK_SLASH, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x31 },//ANSI only
|
||||
{ KEY_EN_POUND, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x32 },//ISO only
|
||||
{ KEY_EN_SEMICOLON, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x33 },
|
||||
{ KEY_EN_QUOTE, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x34 },
|
||||
{ KEY_EN_BACK_TICK, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x35 },
|
||||
{ KEY_EN_COMMA, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x36 },
|
||||
{ KEY_EN_PERIOD, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x37 },
|
||||
{ KEY_EN_FORWARD_SLASH, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x38 },
|
||||
{ KEY_EN_CAPS_LOCK, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x39 },
|
||||
{ KEY_EN_F1, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x3A },
|
||||
{ KEY_EN_F2, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x3B },
|
||||
{ KEY_EN_F3, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x3C },
|
||||
{ KEY_EN_F4, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x3D },
|
||||
{ KEY_EN_F5, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x3E },
|
||||
{ KEY_EN_F6, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x3F },
|
||||
{ KEY_EN_F7, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x40 },
|
||||
{ KEY_EN_F8, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x41 },
|
||||
{ KEY_EN_F9, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x42 },
|
||||
{ KEY_EN_F10, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x43 },
|
||||
{ KEY_EN_F11, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x44 },
|
||||
{ KEY_EN_F12, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x45 },
|
||||
{ KEY_EN_PRINT_SCREEN, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x46 },
|
||||
{ KEY_EN_SCROLL_LOCK, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x47 },
|
||||
{ KEY_EN_PAUSE_BREAK, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x48 },
|
||||
{ KEY_EN_INSERT, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x49 },
|
||||
{ KEY_EN_HOME, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x4A },
|
||||
{ KEY_EN_PAGE_UP, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x4B },
|
||||
{ KEY_EN_DELETE, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x4C },
|
||||
{ KEY_EN_END, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x4D },
|
||||
{ KEY_EN_PAGE_DOWN, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x4E },
|
||||
{ KEY_EN_RIGHT_ARROW, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x4F },
|
||||
{ KEY_EN_LEFT_ARROW, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x50 },
|
||||
{ KEY_EN_DOWN_ARROW, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x51 },
|
||||
{ KEY_EN_UP_ARROW, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x52 },
|
||||
{ KEY_EN_NUMPAD_LOCK, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x53 },
|
||||
{ KEY_EN_NUMPAD_DIVIDE, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x54 },
|
||||
{ KEY_EN_NUMPAD_TIMES, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x55 },
|
||||
{ KEY_EN_NUMPAD_MINUS, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x56 },
|
||||
{ KEY_EN_NUMPAD_PLUS, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x57 },
|
||||
{ KEY_EN_NUMPAD_ENTER, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x58 },
|
||||
{ KEY_EN_NUMPAD_1, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x59 },
|
||||
{ KEY_EN_NUMPAD_2, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x5A },
|
||||
{ KEY_EN_NUMPAD_3, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x5B },
|
||||
{ KEY_EN_NUMPAD_4, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x5C },
|
||||
{ KEY_EN_NUMPAD_5, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x5D },
|
||||
{ KEY_EN_NUMPAD_6, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x5E },
|
||||
{ KEY_EN_NUMPAD_7, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x5F },
|
||||
{ KEY_EN_NUMPAD_8, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x60 },
|
||||
{ KEY_EN_NUMPAD_9, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x61 },
|
||||
{ KEY_EN_NUMPAD_0, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x62 },
|
||||
{ KEY_EN_NUMPAD_PERIOD, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x63 },
|
||||
{ KEY_EN_ISO_BACK_SLASH, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x64 },//ISO only
|
||||
{ KEY_EN_MENU, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0x65 },
|
||||
{ KEY_EN_LEFT_CONTROL, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE0 },
|
||||
{ KEY_EN_LEFT_SHIFT, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE1 },
|
||||
{ KEY_EN_LEFT_ALT, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE2 },
|
||||
{ KEY_EN_LEFT_WINDOWS, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE3 },
|
||||
{ KEY_EN_RIGHT_CONTROL, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE4 },
|
||||
{ KEY_EN_RIGHT_SHIFT, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE5 },
|
||||
{ KEY_EN_RIGHT_ALT, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE6 },
|
||||
{ KEY_EN_RIGHT_WINDOWS, LOGITECH_G810_ZONE_DIRECT_KEYBOARD, 0xE7 },
|
||||
{ KEY_EN_MEDIA_NEXT, LOGITECH_G810_ZONE_DIRECT_MEDIA, 0xB5 },
|
||||
{ KEY_EN_MEDIA_PREVIOUS, LOGITECH_G810_ZONE_DIRECT_MEDIA, 0xB6 },
|
||||
{ KEY_EN_MEDIA_STOP, LOGITECH_G810_ZONE_DIRECT_MEDIA, 0xB7 },
|
||||
{ KEY_EN_MEDIA_PLAY_PAUSE, LOGITECH_G810_ZONE_DIRECT_MEDIA, 0xCD },
|
||||
{ KEY_EN_MEDIA_MUTE, LOGITECH_G810_ZONE_DIRECT_MEDIA, 0xE2 },
|
||||
{ "Logo", LOGITECH_G810_ZONE_DIRECT_LOGO, 0x01 },
|
||||
{ "Lighting", LOGITECH_G810_ZONE_DIRECT_INDICATORS, 0x01 },
|
||||
{ "Game Mode", LOGITECH_G810_ZONE_DIRECT_INDICATORS, 0x02 },
|
||||
{ "Caps Lock Indicator", LOGITECH_G810_ZONE_DIRECT_INDICATORS, 0x03 },
|
||||
{ "Scroll Lock Indicator", LOGITECH_G810_ZONE_DIRECT_INDICATORS, 0x04 },
|
||||
{ "Num Lock Indicator", LOGITECH_G810_ZONE_DIRECT_INDICATORS, 0x05 },
|
||||
};
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G810
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechKeyboardG810
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechG810::RGBController_LogitechG810(LogitechG810Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "Logitech Keyboard Device";
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFFFF;
|
||||
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 = LOGITECH_G810_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G810_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Cycle";
|
||||
Cycle.value = LOGITECH_G810_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_G810_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G810_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G810_SPEED_NORMAL;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G810_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.speed_min = LOGITECH_G810_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G810_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G810_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechG810::~RGBController_LogitechG810()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Delete the matrix map |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
|
||||
{
|
||||
if(zones[zone_index].matrix_map != NULL)
|
||||
{
|
||||
delete zones[zone_index].matrix_map;
|
||||
}
|
||||
}
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechG810::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int total_led_count = 0;
|
||||
for(unsigned int zone_idx = 0; zone_idx < 1; zone_idx++)
|
||||
{
|
||||
zone new_zone;
|
||||
new_zone.name = zone_names[zone_idx];
|
||||
new_zone.type = zone_types[zone_idx];
|
||||
new_zone.leds_min = zone_sizes[zone_idx];
|
||||
new_zone.leds_max = zone_sizes[zone_idx];
|
||||
new_zone.leds_count = zone_sizes[zone_idx];
|
||||
|
||||
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
|
||||
{
|
||||
new_zone.matrix_map = new matrix_map_type;
|
||||
new_zone.matrix_map->height = 7;
|
||||
new_zone.matrix_map->width = 23;
|
||||
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_zone.matrix_map = NULL;
|
||||
}
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
total_led_count += zone_sizes[zone_idx];
|
||||
}
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = led_names[led_idx].name;
|
||||
new_led.value = ( led_names[led_idx].zone << 8 ) + led_names[led_idx].idx;
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG810::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechG810::DeviceUpdateLEDs()
|
||||
{
|
||||
#define MAX_FRAMES_PER_PACKET 0x0E
|
||||
|
||||
unsigned char frame_buf[MAX_FRAMES_PER_PACKET * 4];
|
||||
unsigned char frame_cnt = 0;
|
||||
unsigned char prev_zone = 0;
|
||||
unsigned char zone = 0;
|
||||
unsigned char idx = 0;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| TODO: Send packets with multiple LED frames |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
zone = ( leds[led_idx].value >> 8 );
|
||||
idx = ( leds[led_idx].value & 0xFF );
|
||||
|
||||
if((zone != prev_zone) && (frame_cnt != 0))
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
frame_cnt = 0;
|
||||
}
|
||||
|
||||
frame_buf[(frame_cnt * 4) + 0] = idx;
|
||||
frame_buf[(frame_cnt * 4) + 1] = RGBGetRValue(colors[led_idx]);
|
||||
frame_buf[(frame_cnt * 4) + 2] = RGBGetGValue(colors[led_idx]);
|
||||
frame_buf[(frame_cnt * 4) + 3] = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
frame_cnt++;
|
||||
prev_zone = zone;
|
||||
|
||||
if(frame_cnt == MAX_FRAMES_PER_PACKET)
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
frame_cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(frame_cnt != 0)
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
}
|
||||
|
||||
controller->Commit();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG810::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG810::UpdateSingleLED(int led)
|
||||
{
|
||||
unsigned char frame[4];
|
||||
unsigned char zone;
|
||||
unsigned char idx;
|
||||
|
||||
zone = ( leds[led].value >> 8 );
|
||||
idx = ( leds[led].value & 0xFF );
|
||||
|
||||
frame[0] = idx;
|
||||
frame[1] = RGBGetRValue(colors[led]);
|
||||
frame[2] = RGBGetGValue(colors[led]);
|
||||
frame[3] = RGBGetBValue(colors[led]);
|
||||
|
||||
controller->SetDirect(zone, 1, frame);
|
||||
controller->Commit();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG810::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Direct mode does not send a mode packet |
|
||||
| Call UpdateLEDs to send direct packet |
|
||||
\*---------------------------------------------------------*/
|
||||
if(active_mode == 0xFFFF)
|
||||
{
|
||||
UpdateLEDs();
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char red = 0;
|
||||
unsigned char grn = 0;
|
||||
unsigned char blu = 0;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
red = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
grn = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
blu = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
}
|
||||
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, red, grn, blu);
|
||||
}
|
||||
+35
-35
@@ -1,35 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG810.h |
|
||||
| |
|
||||
| RGBController for Logitech G810 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 12 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG810Controller.h"
|
||||
|
||||
class RGBController_LogitechG810 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG810(LogitechG810Controller* controller_ptr);
|
||||
~RGBController_LogitechG810();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG810Controller* controller;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG810.h |
|
||||
| |
|
||||
| RGBController for Logitech G810 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 12 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG810Controller.h"
|
||||
|
||||
class RGBController_LogitechG810 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG810(LogitechG810Controller* controller_ptr);
|
||||
~RGBController_LogitechG810();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG810Controller* controller;
|
||||
};
|
||||
+311
-311
@@ -1,311 +1,311 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG815Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G815 |
|
||||
| |
|
||||
| Cheerpipe 20 Mar 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechG815Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechG815Controller::LogitechG815Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name)
|
||||
{
|
||||
dev_pkt_0x11 = dev_handle_0x11;
|
||||
dev_pkt_0x12 = dev_handle_0x12;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG815Controller::~LogitechG815Controller()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string LogitechG815Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechG815Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void LogitechG815Controller::Commit()
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void LogitechG815Controller::SetDirect
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
SendDirectFrame(frame_type, frame_data);
|
||||
}
|
||||
|
||||
void LogitechG815Controller::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
SendMode(LOGITECH_G815_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
|
||||
SendMode(LOGITECH_G815_ZONE_MODE_LOGO, mode, speed, red, green, blue);
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void LogitechG815Controller::SendCommit()
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x10;
|
||||
usb_buf[0x03] = LOGITECH_G815_COMMIT_BYTE;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read_timeout(dev_pkt_0x11, usb_buf, 20, LOGITECH_READ_TIMEOUT);
|
||||
}
|
||||
|
||||
void LogitechG815Controller::InitializeDirect()
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x08;
|
||||
usb_buf[0x03] = 0x3E;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x08;
|
||||
usb_buf[0x03] = 0x1E;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0F;
|
||||
usb_buf[0x03] = 0x1E;
|
||||
usb_buf[0x10] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0F;
|
||||
usb_buf[0x03] = 0x1E;
|
||||
usb_buf[0x04] = 0x01;
|
||||
usb_buf[0x10] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG815Controller::SendSingleLed
|
||||
(
|
||||
unsigned char keyCode,
|
||||
unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up a 6F packet with a single color |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x10;
|
||||
usb_buf[0x03] = LOGITECH_G815_ZONE_FRAME_TYPE_LITTLE;
|
||||
|
||||
usb_buf[0x04] = keyCode;
|
||||
|
||||
usb_buf[0x05] = r;
|
||||
usb_buf[0x06] = g;
|
||||
usb_buf[0x07] = b;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG815Controller::SendDirectFrame
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x10;
|
||||
usb_buf[0x03] = frame_type;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in frame data |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x04], frame_data, 16);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read_timeout(dev_pkt_0x11, usb_buf, 20, LOGITECH_READ_TIMEOUT);
|
||||
}
|
||||
|
||||
void LogitechG815Controller::SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0D;
|
||||
usb_buf[0x03] = 0x3D; //TODO: Check if it is the correct value for G815
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 100 * speed;
|
||||
|
||||
if(mode == LOGITECH_G815_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_G815_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = 0x64;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG815Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G815 |
|
||||
| |
|
||||
| Cheerpipe 20 Mar 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechG815Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechG815Controller::LogitechG815Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name)
|
||||
{
|
||||
dev_pkt_0x11 = dev_handle_0x11;
|
||||
dev_pkt_0x12 = dev_handle_0x12;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG815Controller::~LogitechG815Controller()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string LogitechG815Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechG815Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void LogitechG815Controller::Commit()
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void LogitechG815Controller::SetDirect
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
SendDirectFrame(frame_type, frame_data);
|
||||
}
|
||||
|
||||
void LogitechG815Controller::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
SendMode(LOGITECH_G815_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
|
||||
SendMode(LOGITECH_G815_ZONE_MODE_LOGO, mode, speed, red, green, blue);
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void LogitechG815Controller::SendCommit()
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x10;
|
||||
usb_buf[0x03] = LOGITECH_G815_COMMIT_BYTE;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read_timeout(dev_pkt_0x11, usb_buf, 20, LOGITECH_READ_TIMEOUT);
|
||||
}
|
||||
|
||||
void LogitechG815Controller::InitializeDirect()
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x08;
|
||||
usb_buf[0x03] = 0x3E;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x08;
|
||||
usb_buf[0x03] = 0x1E;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0F;
|
||||
usb_buf[0x03] = 0x1E;
|
||||
usb_buf[0x10] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0F;
|
||||
usb_buf[0x03] = 0x1E;
|
||||
usb_buf[0x04] = 0x01;
|
||||
usb_buf[0x10] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG815Controller::SendSingleLed
|
||||
(
|
||||
unsigned char keyCode,
|
||||
unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up a 6F packet with a single color |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x10;
|
||||
usb_buf[0x03] = LOGITECH_G815_ZONE_FRAME_TYPE_LITTLE;
|
||||
|
||||
usb_buf[0x04] = keyCode;
|
||||
|
||||
usb_buf[0x05] = r;
|
||||
usb_buf[0x06] = g;
|
||||
usb_buf[0x07] = b;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG815Controller::SendDirectFrame
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x10;
|
||||
usb_buf[0x03] = frame_type;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in frame data |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x04], frame_data, 16);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read_timeout(dev_pkt_0x11, usb_buf, 20, LOGITECH_READ_TIMEOUT);
|
||||
}
|
||||
|
||||
void LogitechG815Controller::SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0D;
|
||||
usb_buf[0x03] = 0x3D; //TODO: Check if it is the correct value for G815
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 100 * speed;
|
||||
|
||||
if(mode == LOGITECH_G815_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_G815_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = 0x64;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
@@ -1,118 +1,118 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG815Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G815 |
|
||||
| |
|
||||
| Cheerpipe 20 Mar 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 "RGBController.h"
|
||||
|
||||
#define LOGITECH_G815_COMMIT_BYTE 0x7F
|
||||
#define LOGITECH_READ_TIMEOUT 300 //Timeout in ms
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G815_ZONE_MODE_KEYBOARD = 0x00,
|
||||
LOGITECH_G815_ZONE_MODE_LOGO = 0x01,
|
||||
LOGITECH_G815_ZONE_MODE_MULTIMEDIA = 0X02,
|
||||
LOGITECH_G815_ZONE_MODE_GKEYS = 0x03,
|
||||
LOGITECH_G815_ZONE_MODE_MODIFIERS = 0x04
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G815_ZONE_FRAME_TYPE_LITTLE = 0x1F,
|
||||
LOGITECH_G815_ZONE_FRAME_TYPE_BIG = 0x6F
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G815_ZONE_DIRECT_KEYBOARD = 0x01,
|
||||
LOGITECH_G815_ZONE_DIRECT_MEDIA = 0x02,
|
||||
LOGITECH_G815_ZONE_DIRECT_LOGO = 0x10,
|
||||
LOGITECH_G815_ZONE_DIRECT_INDICATORS = 0x40,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G815_MODE_OFF = 0x00,
|
||||
LOGITECH_G815_MODE_STATIC = 0x01,
|
||||
LOGITECH_G815_MODE_BREATHING = 0x02,
|
||||
LOGITECH_G815_MODE_CYCLE = 0x03,
|
||||
LOGITECH_G815_MODE_WAVE = 0x04,
|
||||
LOGITECH_G815_MODE_DIRECT = 0x05,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G815_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_G815_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_G815_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG815Controller
|
||||
{
|
||||
public:
|
||||
LogitechG815Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name);
|
||||
~LogitechG815Controller();
|
||||
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void Commit();
|
||||
void InitializeDirect();
|
||||
void SetDirect
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
void SendSingleLed
|
||||
(
|
||||
unsigned char keyCode,
|
||||
unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b
|
||||
);
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev_pkt_0x11;
|
||||
hid_device* dev_pkt_0x12;
|
||||
std::string name;
|
||||
|
||||
void SendDirectFrame
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
void SendCommit();
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG815Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G815 |
|
||||
| |
|
||||
| Cheerpipe 20 Mar 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 "RGBController.h"
|
||||
|
||||
#define LOGITECH_G815_COMMIT_BYTE 0x7F
|
||||
#define LOGITECH_READ_TIMEOUT 300 //Timeout in ms
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G815_ZONE_MODE_KEYBOARD = 0x00,
|
||||
LOGITECH_G815_ZONE_MODE_LOGO = 0x01,
|
||||
LOGITECH_G815_ZONE_MODE_MULTIMEDIA = 0X02,
|
||||
LOGITECH_G815_ZONE_MODE_GKEYS = 0x03,
|
||||
LOGITECH_G815_ZONE_MODE_MODIFIERS = 0x04
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G815_ZONE_FRAME_TYPE_LITTLE = 0x1F,
|
||||
LOGITECH_G815_ZONE_FRAME_TYPE_BIG = 0x6F
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G815_ZONE_DIRECT_KEYBOARD = 0x01,
|
||||
LOGITECH_G815_ZONE_DIRECT_MEDIA = 0x02,
|
||||
LOGITECH_G815_ZONE_DIRECT_LOGO = 0x10,
|
||||
LOGITECH_G815_ZONE_DIRECT_INDICATORS = 0x40,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G815_MODE_OFF = 0x00,
|
||||
LOGITECH_G815_MODE_STATIC = 0x01,
|
||||
LOGITECH_G815_MODE_BREATHING = 0x02,
|
||||
LOGITECH_G815_MODE_CYCLE = 0x03,
|
||||
LOGITECH_G815_MODE_WAVE = 0x04,
|
||||
LOGITECH_G815_MODE_DIRECT = 0x05,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G815_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_G815_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_G815_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG815Controller
|
||||
{
|
||||
public:
|
||||
LogitechG815Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name);
|
||||
~LogitechG815Controller();
|
||||
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void Commit();
|
||||
void InitializeDirect();
|
||||
void SetDirect
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
void SendSingleLed
|
||||
(
|
||||
unsigned char keyCode,
|
||||
unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b
|
||||
);
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev_pkt_0x11;
|
||||
hid_device* dev_pkt_0x12;
|
||||
std::string name;
|
||||
|
||||
void SendDirectFrame
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
void SendCommit();
|
||||
};
|
||||
+537
-537
File diff suppressed because it is too large.
Load diff
+36
-36
@@ -1,36 +1,36 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG815.h |
|
||||
| |
|
||||
| RGBController for Logitech G815 |
|
||||
| |
|
||||
| Cheerpipe 20 Mar 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG815Controller.h"
|
||||
|
||||
class RGBController_LogitechG815 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG815(LogitechG815Controller* controller_ptr);
|
||||
~RGBController_LogitechG815();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG815Controller* controller;
|
||||
std::vector<RGBColor> current_colors;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG815.h |
|
||||
| |
|
||||
| RGBController for Logitech G815 |
|
||||
| |
|
||||
| Cheerpipe 20 Mar 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG815Controller.h"
|
||||
|
||||
class RGBController_LogitechG815 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG815(LogitechG815Controller* controller_ptr);
|
||||
~RGBController_LogitechG815();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG815Controller* controller;
|
||||
std::vector<RGBColor> current_colors;
|
||||
};
|
||||
+192
-192
@@ -1,192 +1,192 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG910Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G910 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 11 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechG910Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechG910Controller::LogitechG910Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name)
|
||||
{
|
||||
dev_pkt_0x11 = dev_handle_0x11;
|
||||
dev_pkt_0x12 = dev_handle_0x12;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG910Controller::~LogitechG910Controller()
|
||||
{
|
||||
hid_close(dev_pkt_0x11);
|
||||
hid_close(dev_pkt_0x12);
|
||||
}
|
||||
|
||||
std::string LogitechG910Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechG910Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void LogitechG910Controller::Commit()
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void LogitechG910Controller::SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
SendDirectFrame(zone, frame_count, frame_data);
|
||||
}
|
||||
|
||||
void LogitechG910Controller::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
SendMode(LOGITECH_G910_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
|
||||
SendMode(LOGITECH_G910_ZONE_MODE_LOGO, mode, speed, red, green, blue);
|
||||
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void LogitechG910Controller::SendCommit()
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0F;
|
||||
usb_buf[0x03] = 0x5F;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG910Controller::SendDirectFrame
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x12;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0F;
|
||||
usb_buf[0x03] = 0x3F;
|
||||
usb_buf[0x05] = zone;
|
||||
usb_buf[0x07] = frame_count;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in frame data |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x08], frame_data, frame_count * 4);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x12, usb_buf, 64);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG910Controller::SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x10;
|
||||
usb_buf[0x03] = 0x3B;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 100 * speed;
|
||||
if(mode == LOGITECH_G910_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_G910_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = 0x64;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG910Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G910 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 11 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechG910Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechG910Controller::LogitechG910Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name)
|
||||
{
|
||||
dev_pkt_0x11 = dev_handle_0x11;
|
||||
dev_pkt_0x12 = dev_handle_0x12;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG910Controller::~LogitechG910Controller()
|
||||
{
|
||||
hid_close(dev_pkt_0x11);
|
||||
hid_close(dev_pkt_0x12);
|
||||
}
|
||||
|
||||
std::string LogitechG910Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechG910Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void LogitechG910Controller::Commit()
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void LogitechG910Controller::SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
SendDirectFrame(zone, frame_count, frame_data);
|
||||
}
|
||||
|
||||
void LogitechG910Controller::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
SendMode(LOGITECH_G910_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
|
||||
SendMode(LOGITECH_G910_ZONE_MODE_LOGO, mode, speed, red, green, blue);
|
||||
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void LogitechG910Controller::SendCommit()
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0F;
|
||||
usb_buf[0x03] = 0x5F;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG910Controller::SendDirectFrame
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x12;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0F;
|
||||
usb_buf[0x03] = 0x3F;
|
||||
usb_buf[0x05] = zone;
|
||||
usb_buf[0x07] = frame_count;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in frame data |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x08], frame_data, frame_count * 4);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x12, usb_buf, 64);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG910Controller::SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x10;
|
||||
usb_buf[0x03] = 0x3B;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 100 * speed;
|
||||
if(mode == LOGITECH_G910_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_G910_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = 0x64;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
@@ -1,102 +1,102 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG910Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G910 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 11 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G910_ZONE_MODE_KEYBOARD = 0x00,
|
||||
LOGITECH_G910_ZONE_MODE_LOGO = 0x01,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G910_ZONE_DIRECT_KEYBOARD = 0x01,
|
||||
LOGITECH_G910_ZONE_DIRECT_GKEYS = 0x04,
|
||||
LOGITECH_G910_ZONE_DIRECT_LOGO = 0x10,
|
||||
LOGITECH_G910_ZONE_DIRECT_INDICATORS = 0x40,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G910_MODE_OFF = 0x00,
|
||||
LOGITECH_G910_MODE_STATIC = 0x01,
|
||||
LOGITECH_G910_MODE_BREATHING = 0x02,
|
||||
LOGITECH_G910_MODE_CYCLE = 0x03,
|
||||
LOGITECH_G910_MODE_WAVE = 0x04,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G910_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_G910_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_G910_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG910Controller
|
||||
{
|
||||
public:
|
||||
LogitechG910Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name);
|
||||
~LogitechG910Controller();
|
||||
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void Commit();
|
||||
|
||||
void SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev_pkt_0x11;
|
||||
hid_device* dev_pkt_0x12;
|
||||
std::string name;
|
||||
|
||||
void SendDirectFrame
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
void SendCommit();
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG910Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G910 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 11 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G910_ZONE_MODE_KEYBOARD = 0x00,
|
||||
LOGITECH_G910_ZONE_MODE_LOGO = 0x01,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G910_ZONE_DIRECT_KEYBOARD = 0x01,
|
||||
LOGITECH_G910_ZONE_DIRECT_GKEYS = 0x04,
|
||||
LOGITECH_G910_ZONE_DIRECT_LOGO = 0x10,
|
||||
LOGITECH_G910_ZONE_DIRECT_INDICATORS = 0x40,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G910_MODE_OFF = 0x00,
|
||||
LOGITECH_G910_MODE_STATIC = 0x01,
|
||||
LOGITECH_G910_MODE_BREATHING = 0x02,
|
||||
LOGITECH_G910_MODE_CYCLE = 0x03,
|
||||
LOGITECH_G910_MODE_WAVE = 0x04,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G910_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_G910_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_G910_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG910Controller
|
||||
{
|
||||
public:
|
||||
LogitechG910Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name);
|
||||
~LogitechG910Controller();
|
||||
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void Commit();
|
||||
|
||||
void SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev_pkt_0x11;
|
||||
hid_device* dev_pkt_0x12;
|
||||
std::string name;
|
||||
|
||||
void SendDirectFrame
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
void SendCommit();
|
||||
};
|
||||
+403
-403
@@ -1,403 +1,403 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG910.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G910 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 12 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "RGBController_LogitechG910.h"
|
||||
|
||||
//0xFFFFFFFF indicates an unused entry in matrix
|
||||
#define NA 0xFFFFFFFF
|
||||
|
||||
static unsigned int matrix_map[8][24] =
|
||||
{ { NA, 111, 112, 113, 114, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA },
|
||||
{ 115, 37, NA, 54, 55, 56, 57, NA, 58, 59, 60, 61, NA, 62, 63, 64, 65, 66, 67, 68, NA, NA, NA, NA },
|
||||
{ 106, 49, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, NA, 41, 42, 38, NA, 69, 70, 71, 79, 80, 81, 82 },
|
||||
{ 107, 39, NA, 16, 22, 4, 17, NA, 19, 24, 20, 8, 14, 15, 43, 44, 45, 72, 73, 74, 91, 92, 93, 83 },
|
||||
{ 108, 53, NA, 0, 18, 3, 5, NA, 6, 7, 9, 10, 11, 47, 48, 46, 36, NA, NA, NA, 88, 89, 90, NA },
|
||||
{ 109, 99, 96, 25, 23, 2, 21, NA, 1, NA, 13, 12, 50, 51, 52, 103, NA, NA, 78, NA, 85, 86, 87, 84 },
|
||||
{ 110, 98, 101, 100, NA, NA, NA, NA, 40, NA, NA, NA, NA, 104, 105, 97, 102, 76, 77, 75, 94, NA, 95, NA },
|
||||
{ NA, NA, NA, 116, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA } };
|
||||
|
||||
static const char* zone_names[] =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
};
|
||||
|
||||
static zone_type zone_types[] =
|
||||
{
|
||||
ZONE_TYPE_MATRIX,
|
||||
};
|
||||
|
||||
static const unsigned int zone_sizes[] =
|
||||
{
|
||||
117,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char * name;
|
||||
const unsigned char zone;
|
||||
const unsigned char idx;
|
||||
} led_type;
|
||||
|
||||
static const led_type led_names[] =
|
||||
{
|
||||
/* Key Label Zone, Index */
|
||||
{ KEY_EN_A, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x04 },
|
||||
{ KEY_EN_B, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x05 },
|
||||
{ KEY_EN_C, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x06 },
|
||||
{ KEY_EN_D, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x07 },
|
||||
{ KEY_EN_E, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x08 },
|
||||
{ KEY_EN_F, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x09 },
|
||||
{ KEY_EN_G, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0A },
|
||||
{ KEY_EN_H, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0B },
|
||||
{ KEY_EN_I, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0C },
|
||||
{ KEY_EN_J, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0D },
|
||||
{ KEY_EN_K, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0E },
|
||||
{ KEY_EN_L, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0F },
|
||||
{ KEY_EN_M, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x10 },
|
||||
{ KEY_EN_N, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x11 },
|
||||
{ KEY_EN_O, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x12 },
|
||||
{ KEY_EN_P, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x13 },
|
||||
{ KEY_EN_Q, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x14 },
|
||||
{ KEY_EN_R, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x15 },
|
||||
{ KEY_EN_S, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x16 },
|
||||
{ KEY_EN_T, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x17 },
|
||||
{ KEY_EN_U, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x18 },
|
||||
{ KEY_EN_V, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x19 },
|
||||
{ KEY_EN_W, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1A },
|
||||
{ KEY_EN_X, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1B },
|
||||
{ KEY_EN_Y, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1C },
|
||||
{ KEY_EN_Z, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1D },
|
||||
{ KEY_EN_1, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1E },
|
||||
{ KEY_EN_2, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1F },
|
||||
{ KEY_EN_3, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x20 },
|
||||
{ KEY_EN_4, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x21 },
|
||||
{ KEY_EN_5, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x22 },
|
||||
{ KEY_EN_6, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x23 },
|
||||
{ KEY_EN_7, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x24 },
|
||||
{ KEY_EN_8, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x25 },
|
||||
{ KEY_EN_9, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x26 },
|
||||
{ KEY_EN_0, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x27 },
|
||||
{ KEY_EN_ANSI_ENTER, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x28 },
|
||||
{ KEY_EN_ESCAPE, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x29 },
|
||||
{ KEY_EN_BACKSPACE, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2A },
|
||||
{ KEY_EN_TAB, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2B },
|
||||
{ KEY_EN_SPACE, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2C },
|
||||
{ KEY_EN_MINUS, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2D },
|
||||
{ KEY_EN_EQUALS, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2E },
|
||||
{ KEY_EN_LEFT_BRACKET, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2F },
|
||||
{ KEY_EN_RIGHT_BRACKET, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x30 },
|
||||
{ KEY_EN_ANSI_BACK_SLASH, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x31 },//ANSI only
|
||||
{ KEY_EN_POUND, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x32 },//ISO only
|
||||
{ KEY_EN_SEMICOLON, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x33 },
|
||||
{ KEY_EN_QUOTE, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x34 },
|
||||
{ KEY_EN_BACK_TICK, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x35 },
|
||||
{ KEY_EN_COMMA, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x36 },
|
||||
{ KEY_EN_PERIOD, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x37 },
|
||||
{ KEY_EN_FORWARD_SLASH, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x38 },
|
||||
{ KEY_EN_CAPS_LOCK, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x39 },
|
||||
{ KEY_EN_F1, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3A },
|
||||
{ KEY_EN_F2, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3B },
|
||||
{ KEY_EN_F3, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3C },
|
||||
{ KEY_EN_F4, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3D },
|
||||
{ KEY_EN_F5, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3E },
|
||||
{ KEY_EN_F6, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3F },
|
||||
{ KEY_EN_F7, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x40 },
|
||||
{ KEY_EN_F8, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x41 },
|
||||
{ KEY_EN_F9, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x42 },
|
||||
{ KEY_EN_F10, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x43 },
|
||||
{ KEY_EN_F11, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x44 },
|
||||
{ KEY_EN_F12, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x45 },
|
||||
{ KEY_EN_PRINT_SCREEN, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x46 },
|
||||
{ KEY_EN_SCROLL_LOCK, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x47 },
|
||||
{ KEY_EN_PAUSE_BREAK, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x48 },
|
||||
{ KEY_EN_INSERT, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x49 },
|
||||
{ KEY_EN_HOME, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4A },
|
||||
{ KEY_EN_PAGE_UP, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4B },
|
||||
{ KEY_EN_DELETE, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4C },
|
||||
{ KEY_EN_END, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4D },
|
||||
{ KEY_EN_PAGE_DOWN, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4E },
|
||||
{ KEY_EN_RIGHT_ARROW, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4F },
|
||||
{ KEY_EN_LEFT_ARROW, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x50 },
|
||||
{ KEY_EN_DOWN_ARROW, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x51 },
|
||||
{ KEY_EN_UP_ARROW, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x52 },
|
||||
{ KEY_EN_NUMPAD_LOCK, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x53 },
|
||||
{ KEY_EN_NUMPAD_DIVIDE, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x54 },
|
||||
{ KEY_EN_NUMPAD_TIMES, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x55 },
|
||||
{ KEY_EN_NUMPAD_MINUS, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x56 },
|
||||
{ KEY_EN_NUMPAD_PLUS, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x57 },
|
||||
{ KEY_EN_NUMPAD_ENTER, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x58 },
|
||||
{ KEY_EN_NUMPAD_1, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x59 },
|
||||
{ KEY_EN_NUMPAD_2, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5A },
|
||||
{ KEY_EN_NUMPAD_3, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5B },
|
||||
{ KEY_EN_NUMPAD_4, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5C },
|
||||
{ KEY_EN_NUMPAD_5, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5D },
|
||||
{ KEY_EN_NUMPAD_6, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5E },
|
||||
{ KEY_EN_NUMPAD_7, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5F },
|
||||
{ KEY_EN_NUMPAD_8, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x60 },
|
||||
{ KEY_EN_NUMPAD_9, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x61 },
|
||||
{ KEY_EN_NUMPAD_0, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x62 },
|
||||
{ KEY_EN_NUMPAD_PERIOD, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x63 },
|
||||
{ KEY_EN_ISO_BACK_SLASH, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x64 },//ISO only
|
||||
{ KEY_EN_MENU, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x65 },
|
||||
{ KEY_EN_LEFT_CONTROL, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE0 },
|
||||
{ KEY_EN_LEFT_SHIFT, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE1 },
|
||||
{ KEY_EN_LEFT_ALT, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE2 },
|
||||
{ KEY_EN_LEFT_WINDOWS, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE3 },
|
||||
{ KEY_EN_RIGHT_CONTROL, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE4 },
|
||||
{ KEY_EN_RIGHT_SHIFT, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE5 },
|
||||
{ KEY_EN_RIGHT_ALT, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE6 },
|
||||
{ KEY_EN_RIGHT_WINDOWS, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE7 },
|
||||
{ "Key: G1", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x01 },
|
||||
{ "Key: G2", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x02 },
|
||||
{ "Key: G3", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x03 },
|
||||
{ "Key: G4", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x04 },
|
||||
{ "Key: G5", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x05 },
|
||||
{ "Key: G6", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x06 },
|
||||
{ "Key: G7", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x07 },
|
||||
{ "Key: G8", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x08 },
|
||||
{ "Key: G9", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x09 },
|
||||
{ "Logo", LOGITECH_G910_ZONE_DIRECT_LOGO, 0x01 },
|
||||
{ "Nameplate", LOGITECH_G910_ZONE_DIRECT_LOGO, 0x02 },
|
||||
};
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G910
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechKeyboardG910
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechG910::RGBController_LogitechG910(LogitechG910Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "Logitech Keyboard Device";
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFFFF;
|
||||
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 = LOGITECH_G910_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G910_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Cycle";
|
||||
Cycle.value = LOGITECH_G910_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_G910_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G910_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G910_SPEED_NORMAL;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G910_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.speed_min = LOGITECH_G910_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G910_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G910_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechG910::~RGBController_LogitechG910()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Delete the matrix map |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
|
||||
{
|
||||
if(zones[zone_index].matrix_map != NULL)
|
||||
{
|
||||
delete zones[zone_index].matrix_map;
|
||||
}
|
||||
}
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechG910::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int total_led_count = 0;
|
||||
for(unsigned int zone_idx = 0; zone_idx < 1; zone_idx++)
|
||||
{
|
||||
zone new_zone;
|
||||
new_zone.name = zone_names[zone_idx];
|
||||
new_zone.type = zone_types[zone_idx];
|
||||
new_zone.leds_min = zone_sizes[zone_idx];
|
||||
new_zone.leds_max = zone_sizes[zone_idx];
|
||||
new_zone.leds_count = zone_sizes[zone_idx];
|
||||
|
||||
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
|
||||
{
|
||||
new_zone.matrix_map = new matrix_map_type;
|
||||
new_zone.matrix_map->height = 8;
|
||||
new_zone.matrix_map->width = 24;
|
||||
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_zone.matrix_map = NULL;
|
||||
}
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
total_led_count += zone_sizes[zone_idx];
|
||||
}
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = led_names[led_idx].name;
|
||||
new_led.value = ( led_names[led_idx].zone << 8 ) + led_names[led_idx].idx;
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG910::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechG910::DeviceUpdateLEDs()
|
||||
{
|
||||
#define MAX_FRAMES_PER_PACKET 0x0E
|
||||
|
||||
unsigned char frame_buf[MAX_FRAMES_PER_PACKET * 4];
|
||||
unsigned char frame_cnt = 0;
|
||||
unsigned char prev_zone = 0;
|
||||
unsigned char zone = 0;
|
||||
unsigned char idx = 0;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| TODO: Send packets with multiple LED frames |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
zone = ( leds[led_idx].value >> 8 );
|
||||
idx = ( leds[led_idx].value & 0xFF );
|
||||
|
||||
if((zone != prev_zone) && (frame_cnt != 0))
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
frame_cnt = 0;
|
||||
}
|
||||
|
||||
frame_buf[(frame_cnt * 4) + 0] = idx;
|
||||
frame_buf[(frame_cnt * 4) + 1] = RGBGetRValue(colors[led_idx]);
|
||||
frame_buf[(frame_cnt * 4) + 2] = RGBGetGValue(colors[led_idx]);
|
||||
frame_buf[(frame_cnt * 4) + 3] = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
frame_cnt++;
|
||||
prev_zone = zone;
|
||||
|
||||
if(frame_cnt == MAX_FRAMES_PER_PACKET)
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
frame_cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(frame_cnt != 0)
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
}
|
||||
|
||||
controller->Commit();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG910::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG910::UpdateSingleLED(int led)
|
||||
{
|
||||
unsigned char frame[4];
|
||||
unsigned char zone;
|
||||
unsigned char idx;
|
||||
|
||||
zone = ( leds[led].value >> 8 );
|
||||
idx = ( leds[led].value & 0xFF );
|
||||
|
||||
frame[0] = idx;
|
||||
frame[1] = RGBGetRValue(colors[led]);
|
||||
frame[2] = RGBGetGValue(colors[led]);
|
||||
frame[3] = RGBGetBValue(colors[led]);
|
||||
|
||||
controller->SetDirect(zone, 1, frame);
|
||||
controller->Commit();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG910::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Direct mode does not send a mode packet |
|
||||
| Call UpdateLEDs to send direct packet |
|
||||
\*---------------------------------------------------------*/
|
||||
if(active_mode == 0xFFFF)
|
||||
{
|
||||
UpdateLEDs();
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char red = 0;
|
||||
unsigned char grn = 0;
|
||||
unsigned char blu = 0;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
red = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
grn = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
blu = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
}
|
||||
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, red, grn, blu);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG910.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G910 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 12 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "RGBController_LogitechG910.h"
|
||||
|
||||
//0xFFFFFFFF indicates an unused entry in matrix
|
||||
#define NA 0xFFFFFFFF
|
||||
|
||||
static unsigned int matrix_map[8][24] =
|
||||
{ { NA, 111, 112, 113, 114, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA },
|
||||
{ 115, 37, NA, 54, 55, 56, 57, NA, 58, 59, 60, 61, NA, 62, 63, 64, 65, 66, 67, 68, NA, NA, NA, NA },
|
||||
{ 106, 49, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, NA, 41, 42, 38, NA, 69, 70, 71, 79, 80, 81, 82 },
|
||||
{ 107, 39, NA, 16, 22, 4, 17, NA, 19, 24, 20, 8, 14, 15, 43, 44, 45, 72, 73, 74, 91, 92, 93, 83 },
|
||||
{ 108, 53, NA, 0, 18, 3, 5, NA, 6, 7, 9, 10, 11, 47, 48, 46, 36, NA, NA, NA, 88, 89, 90, NA },
|
||||
{ 109, 99, 96, 25, 23, 2, 21, NA, 1, NA, 13, 12, 50, 51, 52, 103, NA, NA, 78, NA, 85, 86, 87, 84 },
|
||||
{ 110, 98, 101, 100, NA, NA, NA, NA, 40, NA, NA, NA, NA, 104, 105, 97, 102, 76, 77, 75, 94, NA, 95, NA },
|
||||
{ NA, NA, NA, 116, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA } };
|
||||
|
||||
static const char* zone_names[] =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
};
|
||||
|
||||
static zone_type zone_types[] =
|
||||
{
|
||||
ZONE_TYPE_MATRIX,
|
||||
};
|
||||
|
||||
static const unsigned int zone_sizes[] =
|
||||
{
|
||||
117,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char * name;
|
||||
const unsigned char zone;
|
||||
const unsigned char idx;
|
||||
} led_type;
|
||||
|
||||
static const led_type led_names[] =
|
||||
{
|
||||
/* Key Label Zone, Index */
|
||||
{ KEY_EN_A, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x04 },
|
||||
{ KEY_EN_B, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x05 },
|
||||
{ KEY_EN_C, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x06 },
|
||||
{ KEY_EN_D, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x07 },
|
||||
{ KEY_EN_E, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x08 },
|
||||
{ KEY_EN_F, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x09 },
|
||||
{ KEY_EN_G, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0A },
|
||||
{ KEY_EN_H, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0B },
|
||||
{ KEY_EN_I, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0C },
|
||||
{ KEY_EN_J, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0D },
|
||||
{ KEY_EN_K, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0E },
|
||||
{ KEY_EN_L, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0F },
|
||||
{ KEY_EN_M, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x10 },
|
||||
{ KEY_EN_N, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x11 },
|
||||
{ KEY_EN_O, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x12 },
|
||||
{ KEY_EN_P, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x13 },
|
||||
{ KEY_EN_Q, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x14 },
|
||||
{ KEY_EN_R, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x15 },
|
||||
{ KEY_EN_S, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x16 },
|
||||
{ KEY_EN_T, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x17 },
|
||||
{ KEY_EN_U, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x18 },
|
||||
{ KEY_EN_V, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x19 },
|
||||
{ KEY_EN_W, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1A },
|
||||
{ KEY_EN_X, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1B },
|
||||
{ KEY_EN_Y, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1C },
|
||||
{ KEY_EN_Z, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1D },
|
||||
{ KEY_EN_1, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1E },
|
||||
{ KEY_EN_2, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1F },
|
||||
{ KEY_EN_3, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x20 },
|
||||
{ KEY_EN_4, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x21 },
|
||||
{ KEY_EN_5, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x22 },
|
||||
{ KEY_EN_6, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x23 },
|
||||
{ KEY_EN_7, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x24 },
|
||||
{ KEY_EN_8, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x25 },
|
||||
{ KEY_EN_9, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x26 },
|
||||
{ KEY_EN_0, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x27 },
|
||||
{ KEY_EN_ANSI_ENTER, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x28 },
|
||||
{ KEY_EN_ESCAPE, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x29 },
|
||||
{ KEY_EN_BACKSPACE, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2A },
|
||||
{ KEY_EN_TAB, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2B },
|
||||
{ KEY_EN_SPACE, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2C },
|
||||
{ KEY_EN_MINUS, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2D },
|
||||
{ KEY_EN_EQUALS, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2E },
|
||||
{ KEY_EN_LEFT_BRACKET, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2F },
|
||||
{ KEY_EN_RIGHT_BRACKET, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x30 },
|
||||
{ KEY_EN_ANSI_BACK_SLASH, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x31 },//ANSI only
|
||||
{ KEY_EN_POUND, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x32 },//ISO only
|
||||
{ KEY_EN_SEMICOLON, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x33 },
|
||||
{ KEY_EN_QUOTE, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x34 },
|
||||
{ KEY_EN_BACK_TICK, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x35 },
|
||||
{ KEY_EN_COMMA, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x36 },
|
||||
{ KEY_EN_PERIOD, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x37 },
|
||||
{ KEY_EN_FORWARD_SLASH, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x38 },
|
||||
{ KEY_EN_CAPS_LOCK, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x39 },
|
||||
{ KEY_EN_F1, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3A },
|
||||
{ KEY_EN_F2, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3B },
|
||||
{ KEY_EN_F3, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3C },
|
||||
{ KEY_EN_F4, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3D },
|
||||
{ KEY_EN_F5, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3E },
|
||||
{ KEY_EN_F6, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3F },
|
||||
{ KEY_EN_F7, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x40 },
|
||||
{ KEY_EN_F8, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x41 },
|
||||
{ KEY_EN_F9, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x42 },
|
||||
{ KEY_EN_F10, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x43 },
|
||||
{ KEY_EN_F11, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x44 },
|
||||
{ KEY_EN_F12, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x45 },
|
||||
{ KEY_EN_PRINT_SCREEN, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x46 },
|
||||
{ KEY_EN_SCROLL_LOCK, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x47 },
|
||||
{ KEY_EN_PAUSE_BREAK, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x48 },
|
||||
{ KEY_EN_INSERT, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x49 },
|
||||
{ KEY_EN_HOME, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4A },
|
||||
{ KEY_EN_PAGE_UP, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4B },
|
||||
{ KEY_EN_DELETE, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4C },
|
||||
{ KEY_EN_END, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4D },
|
||||
{ KEY_EN_PAGE_DOWN, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4E },
|
||||
{ KEY_EN_RIGHT_ARROW, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4F },
|
||||
{ KEY_EN_LEFT_ARROW, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x50 },
|
||||
{ KEY_EN_DOWN_ARROW, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x51 },
|
||||
{ KEY_EN_UP_ARROW, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x52 },
|
||||
{ KEY_EN_NUMPAD_LOCK, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x53 },
|
||||
{ KEY_EN_NUMPAD_DIVIDE, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x54 },
|
||||
{ KEY_EN_NUMPAD_TIMES, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x55 },
|
||||
{ KEY_EN_NUMPAD_MINUS, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x56 },
|
||||
{ KEY_EN_NUMPAD_PLUS, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x57 },
|
||||
{ KEY_EN_NUMPAD_ENTER, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x58 },
|
||||
{ KEY_EN_NUMPAD_1, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x59 },
|
||||
{ KEY_EN_NUMPAD_2, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5A },
|
||||
{ KEY_EN_NUMPAD_3, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5B },
|
||||
{ KEY_EN_NUMPAD_4, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5C },
|
||||
{ KEY_EN_NUMPAD_5, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5D },
|
||||
{ KEY_EN_NUMPAD_6, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5E },
|
||||
{ KEY_EN_NUMPAD_7, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5F },
|
||||
{ KEY_EN_NUMPAD_8, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x60 },
|
||||
{ KEY_EN_NUMPAD_9, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x61 },
|
||||
{ KEY_EN_NUMPAD_0, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x62 },
|
||||
{ KEY_EN_NUMPAD_PERIOD, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x63 },
|
||||
{ KEY_EN_ISO_BACK_SLASH, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x64 },//ISO only
|
||||
{ KEY_EN_MENU, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x65 },
|
||||
{ KEY_EN_LEFT_CONTROL, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE0 },
|
||||
{ KEY_EN_LEFT_SHIFT, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE1 },
|
||||
{ KEY_EN_LEFT_ALT, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE2 },
|
||||
{ KEY_EN_LEFT_WINDOWS, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE3 },
|
||||
{ KEY_EN_RIGHT_CONTROL, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE4 },
|
||||
{ KEY_EN_RIGHT_SHIFT, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE5 },
|
||||
{ KEY_EN_RIGHT_ALT, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE6 },
|
||||
{ KEY_EN_RIGHT_WINDOWS, LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE7 },
|
||||
{ "Key: G1", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x01 },
|
||||
{ "Key: G2", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x02 },
|
||||
{ "Key: G3", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x03 },
|
||||
{ "Key: G4", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x04 },
|
||||
{ "Key: G5", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x05 },
|
||||
{ "Key: G6", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x06 },
|
||||
{ "Key: G7", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x07 },
|
||||
{ "Key: G8", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x08 },
|
||||
{ "Key: G9", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x09 },
|
||||
{ "Logo", LOGITECH_G910_ZONE_DIRECT_LOGO, 0x01 },
|
||||
{ "Nameplate", LOGITECH_G910_ZONE_DIRECT_LOGO, 0x02 },
|
||||
};
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G910
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechKeyboardG910
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechG910::RGBController_LogitechG910(LogitechG910Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "Logitech Keyboard Device";
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFFFF;
|
||||
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 = LOGITECH_G910_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G910_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Cycle";
|
||||
Cycle.value = LOGITECH_G910_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_G910_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G910_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G910_SPEED_NORMAL;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G910_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.speed_min = LOGITECH_G910_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G910_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G910_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechG910::~RGBController_LogitechG910()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Delete the matrix map |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
|
||||
{
|
||||
if(zones[zone_index].matrix_map != NULL)
|
||||
{
|
||||
delete zones[zone_index].matrix_map;
|
||||
}
|
||||
}
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechG910::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int total_led_count = 0;
|
||||
for(unsigned int zone_idx = 0; zone_idx < 1; zone_idx++)
|
||||
{
|
||||
zone new_zone;
|
||||
new_zone.name = zone_names[zone_idx];
|
||||
new_zone.type = zone_types[zone_idx];
|
||||
new_zone.leds_min = zone_sizes[zone_idx];
|
||||
new_zone.leds_max = zone_sizes[zone_idx];
|
||||
new_zone.leds_count = zone_sizes[zone_idx];
|
||||
|
||||
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
|
||||
{
|
||||
new_zone.matrix_map = new matrix_map_type;
|
||||
new_zone.matrix_map->height = 8;
|
||||
new_zone.matrix_map->width = 24;
|
||||
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_zone.matrix_map = NULL;
|
||||
}
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
total_led_count += zone_sizes[zone_idx];
|
||||
}
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = led_names[led_idx].name;
|
||||
new_led.value = ( led_names[led_idx].zone << 8 ) + led_names[led_idx].idx;
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG910::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechG910::DeviceUpdateLEDs()
|
||||
{
|
||||
#define MAX_FRAMES_PER_PACKET 0x0E
|
||||
|
||||
unsigned char frame_buf[MAX_FRAMES_PER_PACKET * 4];
|
||||
unsigned char frame_cnt = 0;
|
||||
unsigned char prev_zone = 0;
|
||||
unsigned char zone = 0;
|
||||
unsigned char idx = 0;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| TODO: Send packets with multiple LED frames |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
zone = ( leds[led_idx].value >> 8 );
|
||||
idx = ( leds[led_idx].value & 0xFF );
|
||||
|
||||
if((zone != prev_zone) && (frame_cnt != 0))
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
frame_cnt = 0;
|
||||
}
|
||||
|
||||
frame_buf[(frame_cnt * 4) + 0] = idx;
|
||||
frame_buf[(frame_cnt * 4) + 1] = RGBGetRValue(colors[led_idx]);
|
||||
frame_buf[(frame_cnt * 4) + 2] = RGBGetGValue(colors[led_idx]);
|
||||
frame_buf[(frame_cnt * 4) + 3] = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
frame_cnt++;
|
||||
prev_zone = zone;
|
||||
|
||||
if(frame_cnt == MAX_FRAMES_PER_PACKET)
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
frame_cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(frame_cnt != 0)
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
}
|
||||
|
||||
controller->Commit();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG910::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG910::UpdateSingleLED(int led)
|
||||
{
|
||||
unsigned char frame[4];
|
||||
unsigned char zone;
|
||||
unsigned char idx;
|
||||
|
||||
zone = ( leds[led].value >> 8 );
|
||||
idx = ( leds[led].value & 0xFF );
|
||||
|
||||
frame[0] = idx;
|
||||
frame[1] = RGBGetRValue(colors[led]);
|
||||
frame[2] = RGBGetGValue(colors[led]);
|
||||
frame[3] = RGBGetBValue(colors[led]);
|
||||
|
||||
controller->SetDirect(zone, 1, frame);
|
||||
controller->Commit();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG910::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Direct mode does not send a mode packet |
|
||||
| Call UpdateLEDs to send direct packet |
|
||||
\*---------------------------------------------------------*/
|
||||
if(active_mode == 0xFFFF)
|
||||
{
|
||||
UpdateLEDs();
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char red = 0;
|
||||
unsigned char grn = 0;
|
||||
unsigned char blu = 0;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
red = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
grn = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
blu = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
}
|
||||
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, red, grn, blu);
|
||||
}
|
||||
+35
-35
@@ -1,35 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG910.h |
|
||||
| |
|
||||
| RGBController for Logitech G910 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 12 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG910Controller.h"
|
||||
|
||||
class RGBController_LogitechG910 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG910(LogitechG910Controller* controller_ptr);
|
||||
~RGBController_LogitechG910();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG910Controller* controller;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG910.h |
|
||||
| |
|
||||
| RGBController for Logitech G910 Orion Spectrum |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 12 Jun 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG910Controller.h"
|
||||
|
||||
class RGBController_LogitechG910 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG910(LogitechG910Controller* controller_ptr);
|
||||
~RGBController_LogitechG910();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG910Controller* controller;
|
||||
};
|
||||
+438
-438
@@ -1,438 +1,438 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG915Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G915 |
|
||||
| |
|
||||
| Cheerpipe 20 Mar 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechG915Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
const size_t MIN_DATA_FRAME_SIZE = 4;
|
||||
const size_t MAX_DATA_FRAME_SIZE = 16;
|
||||
const size_t HEADER_SIZE = 4;
|
||||
const size_t MESSAGE_LEN = 20;
|
||||
const size_t RESPONSE_LEN = 20;
|
||||
|
||||
LogitechG915Controller::LogitechG915Controller(hid_device* dev_handle, bool wired, std::string dev_name)
|
||||
{
|
||||
this->dev_handle = dev_handle;
|
||||
this->name = dev_name;
|
||||
|
||||
if(wired)
|
||||
{
|
||||
device_index = 0xFF;
|
||||
feature_4522_idx = 0x0E;
|
||||
feature_8040_idx = 0x13;
|
||||
feature_8071_idx = 0x09;
|
||||
feature_8081_idx = 0x0A;
|
||||
}
|
||||
else
|
||||
{
|
||||
device_index = 0x01;
|
||||
feature_4522_idx = 0x0F;
|
||||
feature_8040_idx = 0x14;
|
||||
feature_8071_idx = 0x0A;
|
||||
feature_8081_idx = 0x0B;
|
||||
}
|
||||
}
|
||||
|
||||
LogitechG915Controller::~LogitechG915Controller()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string LogitechG915Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechG915Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev_handle, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void LogitechG915Controller::Commit()
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void LogitechG915Controller::SetDirect
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data,
|
||||
size_t length
|
||||
)
|
||||
{
|
||||
SendDirectFrame(frame_type, frame_data, length);
|
||||
}
|
||||
|
||||
void LogitechG915Controller::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned short brightness,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
BeginModeSet();
|
||||
uint8_t logo_mode = mode;
|
||||
switch(mode)
|
||||
{
|
||||
case LOGITECH_G915_MODE_OFF:
|
||||
case LOGITECH_G915_MODE_STATIC:
|
||||
{
|
||||
logo_mode = mode; // static and off match
|
||||
break;
|
||||
}
|
||||
case LOGITECH_G915_MODE_BREATHING:
|
||||
{
|
||||
logo_mode = LOGITECH_G915_LOGO_MODE_BREATHING; //0x03
|
||||
break;
|
||||
}
|
||||
case LOGITECH_G915_MODE_CYCLE:
|
||||
case LOGITECH_G915_MODE_WAVE:
|
||||
{
|
||||
logo_mode = LOGITECH_G915_LOGO_MODE_CYCLE; //0x02
|
||||
break;
|
||||
}
|
||||
case LOGITECH_G915_MODE_RIPPLE:
|
||||
{
|
||||
logo_mode = LOGITECH_G915_LOGO_MODE_STATIC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SendMode(LOGITECH_G915_ZONE_MODE_KEYBOARD, mode, speed, brightness, red, green, blue);
|
||||
SendMode(LOGITECH_G915_ZONE_MODE_LOGO, logo_mode, speed, brightness, red, green, blue);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void LogitechG915Controller::SendCommit()
|
||||
{
|
||||
unsigned char usb_buf[MESSAGE_LEN];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_8081_idx;
|
||||
usb_buf[0x03] = LOGITECH_G915_COMMIT_BYTE;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read_timeout(dev_handle, usb_buf, RESPONSE_LEN, LOGITECH_READ_TIMEOUT);
|
||||
}
|
||||
|
||||
void LogitechG915Controller::BeginModeSet()
|
||||
{
|
||||
unsigned char usb_buf[MESSAGE_LEN];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_4522_idx;
|
||||
usb_buf[0x03] = 0x3E;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, RESPONSE_LEN);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_4522_idx;
|
||||
usb_buf[0x03] = 0x1E;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, RESPONSE_LEN);
|
||||
}
|
||||
|
||||
void LogitechG915Controller::InitializeModeSet()
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_8071_idx;
|
||||
usb_buf[0x03] = 0x5E;
|
||||
usb_buf[0x04] = 0x01;
|
||||
usb_buf[0x05] = 0x03;
|
||||
usb_buf[0x06] = 0x07;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, RESPONSE_LEN);
|
||||
}
|
||||
|
||||
void LogitechG915Controller::InitializeDirect()
|
||||
{
|
||||
unsigned char usb_buf[MESSAGE_LEN];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_4522_idx;
|
||||
usb_buf[0x03] = 0x3E;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, RESPONSE_LEN);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_4522_idx;
|
||||
usb_buf[0x03] = 0x1E;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, RESPONSE_LEN);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_8071_idx;
|
||||
usb_buf[0x03] = 0x1E;
|
||||
usb_buf[0x10] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_8071_idx;
|
||||
usb_buf[0x03] = 0x1E;
|
||||
usb_buf[0x04] = 0x01;
|
||||
usb_buf[0x10] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, RESPONSE_LEN);
|
||||
}
|
||||
|
||||
void LogitechG915Controller::SendSingleLed
|
||||
(
|
||||
unsigned char keyCode,
|
||||
unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b
|
||||
)
|
||||
{
|
||||
unsigned char little_frame[4] = { keyCode, r, g, b };
|
||||
SendDirectFrame(LOGITECH_G915_ZONE_FRAME_TYPE_LITTLE, little_frame, 4);
|
||||
}
|
||||
|
||||
void LogitechG915Controller::SendDirectFrame
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data,
|
||||
size_t length
|
||||
)
|
||||
{
|
||||
if(length < MIN_DATA_FRAME_SIZE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if(length > MAX_DATA_FRAME_SIZE)
|
||||
{
|
||||
length = MAX_DATA_FRAME_SIZE;
|
||||
}
|
||||
|
||||
unsigned char usb_buf[MESSAGE_LEN];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_8081_idx;
|
||||
usb_buf[0x03] = frame_type;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in frame data |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x04], frame_data, length);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read_timeout(dev_handle, usb_buf, RESPONSE_LEN, LOGITECH_READ_TIMEOUT);
|
||||
}
|
||||
|
||||
void LogitechG915Controller::SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned short brightness,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[MESSAGE_LEN];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_8071_idx;
|
||||
usb_buf[0x03] = LOGITECH_G915_ZONE_FRAME_TYPE_MODE;
|
||||
|
||||
usb_buf[0x04] = zone;
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
if(mode != LOGITECH_G915_MODE_RIPPLE)
|
||||
{
|
||||
speed = 100 * speed;
|
||||
}
|
||||
|
||||
// mode == LOGITECH_G915_MODE_OFF; No data to set
|
||||
if(mode == LOGITECH_G915_MODE_STATIC)
|
||||
{
|
||||
usb_buf[0x09] = 0x02;
|
||||
}
|
||||
else if((mode == LOGITECH_G915_MODE_BREATHING && zone == LOGITECH_G915_ZONE_MODE_KEYBOARD) \
|
||||
|| (mode == LOGITECH_G915_LOGO_MODE_BREATHING && zone == LOGITECH_G915_ZONE_MODE_LOGO))
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = brightness & 0xFF;
|
||||
}
|
||||
else if((mode == LOGITECH_G915_MODE_CYCLE && zone == LOGITECH_G915_ZONE_MODE_KEYBOARD) \
|
||||
|| (mode == LOGITECH_G915_LOGO_MODE_CYCLE && zone == LOGITECH_G915_ZONE_MODE_LOGO))
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = brightness & 0xFF;
|
||||
}
|
||||
else if(mode == LOGITECH_G915_MODE_WAVE)
|
||||
{
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x01; // Direction control 0x01 is horizontal
|
||||
usb_buf[0x0E] = brightness & 0xFF;
|
||||
usb_buf[0x0F] = speed >> 8;
|
||||
}
|
||||
else if(mode == LOGITECH_G915_MODE_RIPPLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed & 0xFF;
|
||||
}
|
||||
usb_buf[0x10] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, RESPONSE_LEN);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG915Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G915 |
|
||||
| |
|
||||
| Cheerpipe 20 Mar 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechG915Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
const size_t MIN_DATA_FRAME_SIZE = 4;
|
||||
const size_t MAX_DATA_FRAME_SIZE = 16;
|
||||
const size_t HEADER_SIZE = 4;
|
||||
const size_t MESSAGE_LEN = 20;
|
||||
const size_t RESPONSE_LEN = 20;
|
||||
|
||||
LogitechG915Controller::LogitechG915Controller(hid_device* dev_handle, bool wired, std::string dev_name)
|
||||
{
|
||||
this->dev_handle = dev_handle;
|
||||
this->name = dev_name;
|
||||
|
||||
if(wired)
|
||||
{
|
||||
device_index = 0xFF;
|
||||
feature_4522_idx = 0x0E;
|
||||
feature_8040_idx = 0x13;
|
||||
feature_8071_idx = 0x09;
|
||||
feature_8081_idx = 0x0A;
|
||||
}
|
||||
else
|
||||
{
|
||||
device_index = 0x01;
|
||||
feature_4522_idx = 0x0F;
|
||||
feature_8040_idx = 0x14;
|
||||
feature_8071_idx = 0x0A;
|
||||
feature_8081_idx = 0x0B;
|
||||
}
|
||||
}
|
||||
|
||||
LogitechG915Controller::~LogitechG915Controller()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string LogitechG915Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechG915Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev_handle, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void LogitechG915Controller::Commit()
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void LogitechG915Controller::SetDirect
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data,
|
||||
size_t length
|
||||
)
|
||||
{
|
||||
SendDirectFrame(frame_type, frame_data, length);
|
||||
}
|
||||
|
||||
void LogitechG915Controller::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned short brightness,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
BeginModeSet();
|
||||
uint8_t logo_mode = mode;
|
||||
switch(mode)
|
||||
{
|
||||
case LOGITECH_G915_MODE_OFF:
|
||||
case LOGITECH_G915_MODE_STATIC:
|
||||
{
|
||||
logo_mode = mode; // static and off match
|
||||
break;
|
||||
}
|
||||
case LOGITECH_G915_MODE_BREATHING:
|
||||
{
|
||||
logo_mode = LOGITECH_G915_LOGO_MODE_BREATHING; //0x03
|
||||
break;
|
||||
}
|
||||
case LOGITECH_G915_MODE_CYCLE:
|
||||
case LOGITECH_G915_MODE_WAVE:
|
||||
{
|
||||
logo_mode = LOGITECH_G915_LOGO_MODE_CYCLE; //0x02
|
||||
break;
|
||||
}
|
||||
case LOGITECH_G915_MODE_RIPPLE:
|
||||
{
|
||||
logo_mode = LOGITECH_G915_LOGO_MODE_STATIC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SendMode(LOGITECH_G915_ZONE_MODE_KEYBOARD, mode, speed, brightness, red, green, blue);
|
||||
SendMode(LOGITECH_G915_ZONE_MODE_LOGO, logo_mode, speed, brightness, red, green, blue);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void LogitechG915Controller::SendCommit()
|
||||
{
|
||||
unsigned char usb_buf[MESSAGE_LEN];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_8081_idx;
|
||||
usb_buf[0x03] = LOGITECH_G915_COMMIT_BYTE;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read_timeout(dev_handle, usb_buf, RESPONSE_LEN, LOGITECH_READ_TIMEOUT);
|
||||
}
|
||||
|
||||
void LogitechG915Controller::BeginModeSet()
|
||||
{
|
||||
unsigned char usb_buf[MESSAGE_LEN];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_4522_idx;
|
||||
usb_buf[0x03] = 0x3E;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, RESPONSE_LEN);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_4522_idx;
|
||||
usb_buf[0x03] = 0x1E;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, RESPONSE_LEN);
|
||||
}
|
||||
|
||||
void LogitechG915Controller::InitializeModeSet()
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_8071_idx;
|
||||
usb_buf[0x03] = 0x5E;
|
||||
usb_buf[0x04] = 0x01;
|
||||
usb_buf[0x05] = 0x03;
|
||||
usb_buf[0x06] = 0x07;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, RESPONSE_LEN);
|
||||
}
|
||||
|
||||
void LogitechG915Controller::InitializeDirect()
|
||||
{
|
||||
unsigned char usb_buf[MESSAGE_LEN];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_4522_idx;
|
||||
usb_buf[0x03] = 0x3E;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, RESPONSE_LEN);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_4522_idx;
|
||||
usb_buf[0x03] = 0x1E;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, RESPONSE_LEN);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_8071_idx;
|
||||
usb_buf[0x03] = 0x1E;
|
||||
usb_buf[0x10] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_8071_idx;
|
||||
usb_buf[0x03] = 0x1E;
|
||||
usb_buf[0x04] = 0x01;
|
||||
usb_buf[0x10] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, RESPONSE_LEN);
|
||||
}
|
||||
|
||||
void LogitechG915Controller::SendSingleLed
|
||||
(
|
||||
unsigned char keyCode,
|
||||
unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b
|
||||
)
|
||||
{
|
||||
unsigned char little_frame[4] = { keyCode, r, g, b };
|
||||
SendDirectFrame(LOGITECH_G915_ZONE_FRAME_TYPE_LITTLE, little_frame, 4);
|
||||
}
|
||||
|
||||
void LogitechG915Controller::SendDirectFrame
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data,
|
||||
size_t length
|
||||
)
|
||||
{
|
||||
if(length < MIN_DATA_FRAME_SIZE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if(length > MAX_DATA_FRAME_SIZE)
|
||||
{
|
||||
length = MAX_DATA_FRAME_SIZE;
|
||||
}
|
||||
|
||||
unsigned char usb_buf[MESSAGE_LEN];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_8081_idx;
|
||||
usb_buf[0x03] = frame_type;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in frame data |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x04], frame_data, length);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read_timeout(dev_handle, usb_buf, RESPONSE_LEN, LOGITECH_READ_TIMEOUT);
|
||||
}
|
||||
|
||||
void LogitechG915Controller::SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned short brightness,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[MESSAGE_LEN];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = device_index;
|
||||
usb_buf[0x02] = feature_8071_idx;
|
||||
usb_buf[0x03] = LOGITECH_G915_ZONE_FRAME_TYPE_MODE;
|
||||
|
||||
usb_buf[0x04] = zone;
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
if(mode != LOGITECH_G915_MODE_RIPPLE)
|
||||
{
|
||||
speed = 100 * speed;
|
||||
}
|
||||
|
||||
// mode == LOGITECH_G915_MODE_OFF; No data to set
|
||||
if(mode == LOGITECH_G915_MODE_STATIC)
|
||||
{
|
||||
usb_buf[0x09] = 0x02;
|
||||
}
|
||||
else if((mode == LOGITECH_G915_MODE_BREATHING && zone == LOGITECH_G915_ZONE_MODE_KEYBOARD) \
|
||||
|| (mode == LOGITECH_G915_LOGO_MODE_BREATHING && zone == LOGITECH_G915_ZONE_MODE_LOGO))
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = brightness & 0xFF;
|
||||
}
|
||||
else if((mode == LOGITECH_G915_MODE_CYCLE && zone == LOGITECH_G915_ZONE_MODE_KEYBOARD) \
|
||||
|| (mode == LOGITECH_G915_LOGO_MODE_CYCLE && zone == LOGITECH_G915_ZONE_MODE_LOGO))
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = brightness & 0xFF;
|
||||
}
|
||||
else if(mode == LOGITECH_G915_MODE_WAVE)
|
||||
{
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x01; // Direction control 0x01 is horizontal
|
||||
usb_buf[0x0E] = brightness & 0xFF;
|
||||
usb_buf[0x0F] = speed >> 8;
|
||||
}
|
||||
else if(mode == LOGITECH_G915_MODE_RIPPLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed & 0xFF;
|
||||
}
|
||||
usb_buf[0x10] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_handle, usb_buf, MESSAGE_LEN);
|
||||
hid_read(dev_handle, usb_buf, RESPONSE_LEN);
|
||||
}
|
||||
@@ -1,146 +1,146 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG915Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G915 |
|
||||
| |
|
||||
| Cheerpipe 20 Mar 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 "RGBController.h"
|
||||
|
||||
#define LOGITECH_G915_COMMIT_BYTE 0x7F
|
||||
#define LOGITECH_READ_TIMEOUT 300 //Timeout in ms
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G915_ZONE_MODE_KEYBOARD = 0x01,
|
||||
LOGITECH_G915_ZONE_MODE_LOGO = 0x00,
|
||||
LOGITECH_G915_ZONE_MODE_MULTIMEDIA = 0x02,
|
||||
LOGITECH_G915_ZONE_MODE_GKEYS = 0x03,
|
||||
LOGITECH_G915_ZONE_MODE_MODIFIERS = 0x04
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G915_ZONE_FRAME_TYPE_LITTLE = 0x1F,
|
||||
LOGITECH_G915_ZONE_FRAME_TYPE_BIG = 0x6F,
|
||||
LOGITECH_G915_ZONE_FRAME_TYPE_MODE = 0x1E
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G915_ZONE_DIRECT_KEYBOARD = 0x01,
|
||||
LOGITECH_G915_ZONE_DIRECT_MEDIA = 0x02,
|
||||
LOGITECH_G915_ZONE_DIRECT_LOGO = 0x10,
|
||||
LOGITECH_G915_ZONE_DIRECT_INDICATORS = 0x40,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G915_MODE_OFF = 0x00,
|
||||
LOGITECH_G915_MODE_STATIC = 0x01,
|
||||
LOGITECH_G915_MODE_BREATHING = 0x02,
|
||||
LOGITECH_G915_MODE_CYCLE = 0x03,
|
||||
LOGITECH_G915_MODE_WAVE = 0x04,
|
||||
LOGITECH_G915_MODE_RIPPLE = 0x05,
|
||||
LOGITECH_G915_MODE_DIRECT = 0xFF,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G915_LOGO_MODE_OFF = 0x00,
|
||||
LOGITECH_G915_LOGO_MODE_STATIC = 0x01,
|
||||
LOGITECH_G915_LOGO_MODE_CYCLE = 0x02,
|
||||
LOGITECH_G915_LOGO_MODE_BREATHING = 0x03,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G915_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_G915_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_G915_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
/* Ripple speeds are in ms directly. */
|
||||
enum
|
||||
{
|
||||
LOGITECH_G915_SPEED_RIPPLE_SLOW = 200,
|
||||
LOGITECH_G915_SPEED_RIPPLE_NORMAL = 20,
|
||||
LOGITECH_G915_SPEED_RIPPLE_FAST = 2,
|
||||
};
|
||||
|
||||
class LogitechG915Controller
|
||||
{
|
||||
public:
|
||||
LogitechG915Controller(hid_device* dev_handle, bool wired, std::string dev_name);
|
||||
~LogitechG915Controller();
|
||||
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void Commit();
|
||||
void InitializeDirect();
|
||||
void InitializeModeSet();
|
||||
void BeginModeSet();
|
||||
void SetDirect
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data,
|
||||
size_t length
|
||||
);
|
||||
void SendSingleLed
|
||||
(
|
||||
unsigned char keyCode,
|
||||
unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b
|
||||
);
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned short brightness,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev_handle;
|
||||
unsigned char feature_4522_idx;
|
||||
unsigned char device_index;
|
||||
unsigned char feature_8040_idx;
|
||||
unsigned char feature_8071_idx;
|
||||
unsigned char feature_8081_idx;
|
||||
std::string name;
|
||||
|
||||
void SendDirectFrame
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data,
|
||||
size_t length
|
||||
);
|
||||
|
||||
void SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned short brightness,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
void SendCommit();
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG915Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G915 |
|
||||
| |
|
||||
| Cheerpipe 20 Mar 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 "RGBController.h"
|
||||
|
||||
#define LOGITECH_G915_COMMIT_BYTE 0x7F
|
||||
#define LOGITECH_READ_TIMEOUT 300 //Timeout in ms
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G915_ZONE_MODE_KEYBOARD = 0x01,
|
||||
LOGITECH_G915_ZONE_MODE_LOGO = 0x00,
|
||||
LOGITECH_G915_ZONE_MODE_MULTIMEDIA = 0x02,
|
||||
LOGITECH_G915_ZONE_MODE_GKEYS = 0x03,
|
||||
LOGITECH_G915_ZONE_MODE_MODIFIERS = 0x04
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G915_ZONE_FRAME_TYPE_LITTLE = 0x1F,
|
||||
LOGITECH_G915_ZONE_FRAME_TYPE_BIG = 0x6F,
|
||||
LOGITECH_G915_ZONE_FRAME_TYPE_MODE = 0x1E
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G915_ZONE_DIRECT_KEYBOARD = 0x01,
|
||||
LOGITECH_G915_ZONE_DIRECT_MEDIA = 0x02,
|
||||
LOGITECH_G915_ZONE_DIRECT_LOGO = 0x10,
|
||||
LOGITECH_G915_ZONE_DIRECT_INDICATORS = 0x40,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G915_MODE_OFF = 0x00,
|
||||
LOGITECH_G915_MODE_STATIC = 0x01,
|
||||
LOGITECH_G915_MODE_BREATHING = 0x02,
|
||||
LOGITECH_G915_MODE_CYCLE = 0x03,
|
||||
LOGITECH_G915_MODE_WAVE = 0x04,
|
||||
LOGITECH_G915_MODE_RIPPLE = 0x05,
|
||||
LOGITECH_G915_MODE_DIRECT = 0xFF,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G915_LOGO_MODE_OFF = 0x00,
|
||||
LOGITECH_G915_LOGO_MODE_STATIC = 0x01,
|
||||
LOGITECH_G915_LOGO_MODE_CYCLE = 0x02,
|
||||
LOGITECH_G915_LOGO_MODE_BREATHING = 0x03,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G915_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_G915_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_G915_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
/* Ripple speeds are in ms directly. */
|
||||
enum
|
||||
{
|
||||
LOGITECH_G915_SPEED_RIPPLE_SLOW = 200,
|
||||
LOGITECH_G915_SPEED_RIPPLE_NORMAL = 20,
|
||||
LOGITECH_G915_SPEED_RIPPLE_FAST = 2,
|
||||
};
|
||||
|
||||
class LogitechG915Controller
|
||||
{
|
||||
public:
|
||||
LogitechG915Controller(hid_device* dev_handle, bool wired, std::string dev_name);
|
||||
~LogitechG915Controller();
|
||||
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void Commit();
|
||||
void InitializeDirect();
|
||||
void InitializeModeSet();
|
||||
void BeginModeSet();
|
||||
void SetDirect
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data,
|
||||
size_t length
|
||||
);
|
||||
void SendSingleLed
|
||||
(
|
||||
unsigned char keyCode,
|
||||
unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b
|
||||
);
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned short brightness,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev_handle;
|
||||
unsigned char feature_4522_idx;
|
||||
unsigned char device_index;
|
||||
unsigned char feature_8040_idx;
|
||||
unsigned char feature_8071_idx;
|
||||
unsigned char feature_8081_idx;
|
||||
std::string name;
|
||||
|
||||
void SendDirectFrame
|
||||
(
|
||||
unsigned char frame_type,
|
||||
unsigned char * frame_data,
|
||||
size_t length
|
||||
);
|
||||
|
||||
void SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned short brightness,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
void SendCommit();
|
||||
};
|
||||
+655
-655
File diff suppressed because it is too large.
Load diff
+38
-38
@@ -1,38 +1,38 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG915.h |
|
||||
| |
|
||||
| RGBController for Logitech G915 |
|
||||
| |
|
||||
| Cheerpipe 20 Mar 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG915Controller.h"
|
||||
|
||||
class RGBController_LogitechG915 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG915(LogitechG915Controller* controller_ptr, bool tkl);
|
||||
~RGBController_LogitechG915();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
bool is_tkl;
|
||||
|
||||
LogitechG915Controller* controller;
|
||||
std::vector<RGBColor> current_colors;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG915.h |
|
||||
| |
|
||||
| RGBController for Logitech G915 |
|
||||
| |
|
||||
| Cheerpipe 20 Mar 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG915Controller.h"
|
||||
|
||||
class RGBController_LogitechG915 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG915(LogitechG915Controller* controller_ptr, bool tkl);
|
||||
~RGBController_LogitechG915();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
bool is_tkl;
|
||||
|
||||
LogitechG915Controller* controller;
|
||||
std::vector<RGBColor> current_colors;
|
||||
};
|
||||
+154
-154
@@ -1,154 +1,154 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG933Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G933 |
|
||||
| |
|
||||
| Edbgon 21 Jun 2021 |
|
||||
| Based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "LogitechG933Controller.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
LogitechG933Controller::LogitechG933Controller(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG933Controller::~LogitechG933Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string LogitechG933Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string LogitechG933Controller::GetDeviceName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
void LogitechG933Controller::SetDirectMode(uint8_t zone)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G933_LED_PACKET_SIZE];
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
usb_buf[0x03] = 0xCA;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G933_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG933Controller::SetOffMode(uint8_t zone)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G933_LED_PACKET_SIZE];
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
usb_buf[0x03] = 0x3F;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G933_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG933Controller::SendHeadsetMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G933_LED_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| This packet sets speaker into direct mode. This mode |
|
||||
| is used by Lightsync Ambilight and Music Visualizer |
|
||||
| realtime effect. |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x03] = 0x3A;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up mode and speed |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x04] = zone;
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| And set up the colors |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
if(mode == LOGITECH_G933_MODE_DIRECT) //G933 only has Direct Mode.
|
||||
{
|
||||
usb_buf[0x09] = 0x02;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G933_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG933Controller::fail_retry_write(hid_device *device, const unsigned char *data, size_t length)
|
||||
{
|
||||
unsigned char usb_buf_out[LOGI_G933_LED_PACKET_SIZE];
|
||||
unsigned int write_max_retry = LOGI_G933_LED_COMMAND_SEND_RETRIES;
|
||||
do
|
||||
{
|
||||
std::this_thread::sleep_for(1ms);
|
||||
int ret = hid_write(device, data, length);
|
||||
|
||||
/*-------------------------------------------------------------------------------------*\
|
||||
| HID write fails if a change led color and set volume command are sent at |
|
||||
| the same time because RGB controller and volume control shares the same interface. |
|
||||
\*-------------------------------------------------------------------------------------*/
|
||||
if(ret == 20)
|
||||
{
|
||||
std::this_thread::sleep_for(1ms);
|
||||
hid_read_timeout(dev, usb_buf_out, LOGI_G933_LED_PACKET_SIZE, 20);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_max_retry--;
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
|
||||
}while (write_max_retry > 0);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG933Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G933 |
|
||||
| |
|
||||
| Edbgon 21 Jun 2021 |
|
||||
| Based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "LogitechG933Controller.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
LogitechG933Controller::LogitechG933Controller(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG933Controller::~LogitechG933Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string LogitechG933Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string LogitechG933Controller::GetDeviceName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
void LogitechG933Controller::SetDirectMode(uint8_t zone)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G933_LED_PACKET_SIZE];
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
usb_buf[0x03] = 0xCA;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G933_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG933Controller::SetOffMode(uint8_t zone)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G933_LED_PACKET_SIZE];
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
usb_buf[0x03] = 0x3F;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G933_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG933Controller::SendHeadsetMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G933_LED_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| This packet sets speaker into direct mode. This mode |
|
||||
| is used by Lightsync Ambilight and Music Visualizer |
|
||||
| realtime effect. |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x03] = 0x3A;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up mode and speed |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x04] = zone;
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| And set up the colors |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
if(mode == LOGITECH_G933_MODE_DIRECT) //G933 only has Direct Mode.
|
||||
{
|
||||
usb_buf[0x09] = 0x02;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G933_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG933Controller::fail_retry_write(hid_device *device, const unsigned char *data, size_t length)
|
||||
{
|
||||
unsigned char usb_buf_out[LOGI_G933_LED_PACKET_SIZE];
|
||||
unsigned int write_max_retry = LOGI_G933_LED_COMMAND_SEND_RETRIES;
|
||||
do
|
||||
{
|
||||
std::this_thread::sleep_for(1ms);
|
||||
int ret = hid_write(device, data, length);
|
||||
|
||||
/*-------------------------------------------------------------------------------------*\
|
||||
| HID write fails if a change led color and set volume command are sent at |
|
||||
| the same time because RGB controller and volume control shares the same interface. |
|
||||
\*-------------------------------------------------------------------------------------*/
|
||||
if(ret == 20)
|
||||
{
|
||||
std::this_thread::sleep_for(1ms);
|
||||
hid_read_timeout(dev, usb_buf_out, LOGI_G933_LED_PACKET_SIZE, 20);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_max_retry--;
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
|
||||
}while (write_max_retry > 0);
|
||||
}
|
||||
@@ -1,59 +1,59 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG933Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G933 |
|
||||
| |
|
||||
| Edbgon 21 Jun 2021 |
|
||||
| Based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define LOGI_G933_LED_PACKET_SIZE 20
|
||||
#define LOGI_G933_LED_COMMAND_SEND_RETRIES 3
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G933_MODE_OFF = 0x00,
|
||||
LOGITECH_G933_MODE_DIRECT = 0x01,
|
||||
LOGITECH_G933_MODE_CYCLE = 0x02,
|
||||
LOGITECH_G933_MODE_BREATHING = 0x03,
|
||||
};
|
||||
|
||||
class LogitechG933Controller
|
||||
{
|
||||
public:
|
||||
LogitechG933Controller(hid_device* dev_handle, const char* path, std::string dev_name);
|
||||
~LogitechG933Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
|
||||
void SetDirectMode(uint8_t zone);
|
||||
void SetOffMode(uint8_t zone);
|
||||
|
||||
void SendHeadsetMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
|
||||
void fail_retry_write(hid_device *device, const unsigned char *data, size_t length);
|
||||
};
|
||||
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG933Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G933 |
|
||||
| |
|
||||
| Edbgon 21 Jun 2021 |
|
||||
| Based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define LOGI_G933_LED_PACKET_SIZE 20
|
||||
#define LOGI_G933_LED_COMMAND_SEND_RETRIES 3
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G933_MODE_OFF = 0x00,
|
||||
LOGITECH_G933_MODE_DIRECT = 0x01,
|
||||
LOGITECH_G933_MODE_CYCLE = 0x02,
|
||||
LOGITECH_G933_MODE_BREATHING = 0x03,
|
||||
};
|
||||
|
||||
class LogitechG933Controller
|
||||
{
|
||||
public:
|
||||
LogitechG933Controller(hid_device* dev_handle, const char* path, std::string dev_name);
|
||||
~LogitechG933Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
|
||||
void SetDirectMode(uint8_t zone);
|
||||
void SetOffMode(uint8_t zone);
|
||||
|
||||
void SendHeadsetMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
|
||||
void fail_retry_write(hid_device *device, const unsigned char *data, size_t length);
|
||||
};
|
||||
|
||||
|
||||
+134
-134
@@ -1,134 +1,134 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG933.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G933 |
|
||||
| |
|
||||
| Edbgon 21 Jun 2021 |
|
||||
| Based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechG933.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G933
|
||||
@category Headset
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectLogitechG933
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechG933::RGBController_LogitechG933(LogitechG933Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_HEADSET;
|
||||
description = "Logitech G933 Lightsync Headset";
|
||||
location = controller->GetDeviceLocation();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G933_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = LOGITECH_G933_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG933::SetupZones()
|
||||
{
|
||||
zone G933_logo;
|
||||
G933_logo.name = "Logo";
|
||||
G933_logo.type = ZONE_TYPE_SINGLE;
|
||||
G933_logo.leds_min = 1;
|
||||
G933_logo.leds_max = 1;
|
||||
G933_logo.leds_count = 1;
|
||||
G933_logo.matrix_map = NULL;
|
||||
zones.push_back(G933_logo);
|
||||
|
||||
led G933_logo_led;
|
||||
G933_logo_led.name = "Logo";
|
||||
G933_logo_led.value = 0x00;
|
||||
leds.push_back(G933_logo_led);
|
||||
|
||||
zone G933_strip;
|
||||
G933_strip.name = "LED Strip";
|
||||
G933_strip.type = ZONE_TYPE_SINGLE;
|
||||
G933_strip.leds_min = 1;
|
||||
G933_strip.leds_max = 1;
|
||||
G933_strip.leds_count = 1;
|
||||
G933_strip.matrix_map = NULL;
|
||||
zones.push_back(G933_strip);
|
||||
|
||||
led G933_strip_led;
|
||||
G933_strip_led.name = "Led Strip";
|
||||
G933_strip_led.value = 0x01;
|
||||
leds.push_back(G933_strip_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG933::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechG933::DeviceUpdateLEDs()
|
||||
{
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[led_idx]);
|
||||
unsigned char grn = RGBGetGValue(colors[led_idx]);
|
||||
unsigned char blu = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
controller->SendHeadsetMode((unsigned char)leds[led_idx].value, modes[active_mode].value, red, grn, blu);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_LogitechG933::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG933::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG933::DeviceUpdateMode()
|
||||
{
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
if(modes[active_mode].value == LOGITECH_G933_MODE_OFF)
|
||||
{
|
||||
controller->SetOffMode(leds[led_idx].value);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Required to "reset" RGB controller and start receiving |
|
||||
| color in direct mode |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetDirectMode(leds[led_idx].value);
|
||||
}
|
||||
|
||||
}
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG933.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G933 |
|
||||
| |
|
||||
| Edbgon 21 Jun 2021 |
|
||||
| Based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechG933.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G933
|
||||
@category Headset
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectLogitechG933
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechG933::RGBController_LogitechG933(LogitechG933Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_HEADSET;
|
||||
description = "Logitech G933 Lightsync Headset";
|
||||
location = controller->GetDeviceLocation();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G933_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = LOGITECH_G933_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG933::SetupZones()
|
||||
{
|
||||
zone G933_logo;
|
||||
G933_logo.name = "Logo";
|
||||
G933_logo.type = ZONE_TYPE_SINGLE;
|
||||
G933_logo.leds_min = 1;
|
||||
G933_logo.leds_max = 1;
|
||||
G933_logo.leds_count = 1;
|
||||
G933_logo.matrix_map = NULL;
|
||||
zones.push_back(G933_logo);
|
||||
|
||||
led G933_logo_led;
|
||||
G933_logo_led.name = "Logo";
|
||||
G933_logo_led.value = 0x00;
|
||||
leds.push_back(G933_logo_led);
|
||||
|
||||
zone G933_strip;
|
||||
G933_strip.name = "LED Strip";
|
||||
G933_strip.type = ZONE_TYPE_SINGLE;
|
||||
G933_strip.leds_min = 1;
|
||||
G933_strip.leds_max = 1;
|
||||
G933_strip.leds_count = 1;
|
||||
G933_strip.matrix_map = NULL;
|
||||
zones.push_back(G933_strip);
|
||||
|
||||
led G933_strip_led;
|
||||
G933_strip_led.name = "Led Strip";
|
||||
G933_strip_led.value = 0x01;
|
||||
leds.push_back(G933_strip_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG933::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechG933::DeviceUpdateLEDs()
|
||||
{
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[led_idx]);
|
||||
unsigned char grn = RGBGetGValue(colors[led_idx]);
|
||||
unsigned char blu = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
controller->SendHeadsetMode((unsigned char)leds[led_idx].value, modes[active_mode].value, red, grn, blu);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_LogitechG933::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG933::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechG933::DeviceUpdateMode()
|
||||
{
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
if(modes[active_mode].value == LOGITECH_G933_MODE_OFF)
|
||||
{
|
||||
controller->SetOffMode(leds[led_idx].value);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Required to "reset" RGB controller and start receiving |
|
||||
| color in direct mode |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetDirectMode(leds[led_idx].value);
|
||||
}
|
||||
|
||||
}
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
+35
-35
@@ -1,35 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG933.h |
|
||||
| |
|
||||
| RGBController for Logitech G933 |
|
||||
| |
|
||||
| Edbgon 21 Jun 2021 |
|
||||
| Based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG933Controller.h"
|
||||
|
||||
class RGBController_LogitechG933 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG933(LogitechG933Controller* controller_ptr);
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG933Controller* controller;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechG933.h |
|
||||
| |
|
||||
| RGBController for Logitech G933 |
|
||||
| |
|
||||
| Edbgon 21 Jun 2021 |
|
||||
| Based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechG933Controller.h"
|
||||
|
||||
class RGBController_LogitechG933 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechG933(LogitechG933Controller* controller_ptr);
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechG933Controller* controller;
|
||||
};
|
||||
+187
-187
@@ -1,187 +1,187 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechGLightsyncController.cpp |
|
||||
| |
|
||||
| Driver for Logitech Lightsync |
|
||||
| |
|
||||
| TheRogueZeta 21 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechGLightsyncController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechGLightsyncController::LogitechGLightsyncController(hid_device* dev_cmd_handle, hid_device *dev_handle, const char *path, unsigned char hid_dev_index, unsigned char hid_feature_index, unsigned char hid_fctn_ase_id, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
cmd_dev = dev_cmd_handle;
|
||||
location = path;
|
||||
dev_index = hid_dev_index;
|
||||
feature_index = hid_feature_index;
|
||||
fctn_ase_id = hid_fctn_ase_id;
|
||||
mutex = nullptr;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechGLightsyncController::LogitechGLightsyncController(hid_device* dev_cmd_handle, hid_device *dev_handle, const char *path, unsigned char hid_dev_index, unsigned char hid_feature_index, unsigned char hid_fctn_ase_id, std::shared_ptr<std::mutex> mutex_ptr, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
cmd_dev = dev_cmd_handle;
|
||||
location = path;
|
||||
dev_index = hid_dev_index;
|
||||
feature_index = hid_feature_index;
|
||||
fctn_ase_id = hid_fctn_ase_id;
|
||||
mutex = mutex_ptr;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechGLightsyncController::~LogitechGLightsyncController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string LogitechGLightsyncController::GetDeviceLocation()
|
||||
{
|
||||
return ("HID: " + location);
|
||||
}
|
||||
|
||||
std::string LogitechGLightsyncController::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechGLightsyncController::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 LogitechGLightsyncController::UpdateMouseLED(
|
||||
unsigned char mode,
|
||||
std::uint16_t speed,
|
||||
unsigned char zone,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue,
|
||||
unsigned char brightness
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = dev_index;
|
||||
usb_buf[0x02] = feature_index;
|
||||
usb_buf[0x03] = fctn_ase_id;
|
||||
|
||||
usb_buf[0x04] = zone;
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 100 * speed;
|
||||
if (mode == LOGITECH_G_LIGHTSYNC_MODE_STATIC)
|
||||
{
|
||||
usb_buf[0x09] = 0x02;
|
||||
}
|
||||
if (mode == LOGITECH_G_LIGHTSYNC_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = brightness;
|
||||
}
|
||||
else if (mode == LOGITECH_G_LIGHTSYNC_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = brightness;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
| This code has to be protected to avoid crashes when |
|
||||
| this is called at the same time to change a powerplay |
|
||||
| mat and its paired wireless mouse leds. It will |
|
||||
| happen when using effects engines with high framerate |
|
||||
\*-----------------------------------------------------*/
|
||||
if(mutex)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(*mutex);
|
||||
|
||||
hid_write(dev, usb_buf, 20);
|
||||
hid_read(dev, usb_buf, 20);
|
||||
}
|
||||
else
|
||||
{
|
||||
hid_write(dev, usb_buf, 20);
|
||||
hid_read(dev, usb_buf, 20);
|
||||
}
|
||||
}
|
||||
|
||||
void LogitechGLightsyncController::SetDirectMode(bool direct)
|
||||
{
|
||||
unsigned char cmd_buf[7];
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(cmd_buf, 0x00, sizeof(cmd_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Command Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
cmd_buf[0x00] = 0x10;
|
||||
cmd_buf[0x01] = dev_index;
|
||||
cmd_buf[0x02] = feature_index;
|
||||
cmd_buf[0x03] = 0x8A;
|
||||
cmd_buf[0x04] = 0x00;
|
||||
cmd_buf[0x05] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| If direct, disable save to flash |
|
||||
\*-----------------------------------------------------*/
|
||||
if(direct)
|
||||
{
|
||||
cmd_buf[0x04] = 0x01;
|
||||
cmd_buf[0x05] = 0x01;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
| This code has to be protected to avoid crashes when |
|
||||
| this is called at the same time to change a powerplay |
|
||||
| mat and its paired wireless mouse leds. It will |
|
||||
| happen when using effects engines with high framerate |
|
||||
\*-----------------------------------------------------*/
|
||||
if(mutex)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(*mutex);
|
||||
|
||||
hid_write(cmd_dev, cmd_buf, 7);
|
||||
hid_read(dev, usb_buf, 20);
|
||||
}
|
||||
else
|
||||
{
|
||||
hid_write(cmd_dev, cmd_buf, 7);
|
||||
hid_read(dev, usb_buf, 20);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechGLightsyncController.cpp |
|
||||
| |
|
||||
| Driver for Logitech Lightsync |
|
||||
| |
|
||||
| TheRogueZeta 21 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechGLightsyncController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechGLightsyncController::LogitechGLightsyncController(hid_device* dev_cmd_handle, hid_device *dev_handle, const char *path, unsigned char hid_dev_index, unsigned char hid_feature_index, unsigned char hid_fctn_ase_id, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
cmd_dev = dev_cmd_handle;
|
||||
location = path;
|
||||
dev_index = hid_dev_index;
|
||||
feature_index = hid_feature_index;
|
||||
fctn_ase_id = hid_fctn_ase_id;
|
||||
mutex = nullptr;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechGLightsyncController::LogitechGLightsyncController(hid_device* dev_cmd_handle, hid_device *dev_handle, const char *path, unsigned char hid_dev_index, unsigned char hid_feature_index, unsigned char hid_fctn_ase_id, std::shared_ptr<std::mutex> mutex_ptr, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
cmd_dev = dev_cmd_handle;
|
||||
location = path;
|
||||
dev_index = hid_dev_index;
|
||||
feature_index = hid_feature_index;
|
||||
fctn_ase_id = hid_fctn_ase_id;
|
||||
mutex = mutex_ptr;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechGLightsyncController::~LogitechGLightsyncController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string LogitechGLightsyncController::GetDeviceLocation()
|
||||
{
|
||||
return ("HID: " + location);
|
||||
}
|
||||
|
||||
std::string LogitechGLightsyncController::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechGLightsyncController::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 LogitechGLightsyncController::UpdateMouseLED(
|
||||
unsigned char mode,
|
||||
std::uint16_t speed,
|
||||
unsigned char zone,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue,
|
||||
unsigned char brightness
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = dev_index;
|
||||
usb_buf[0x02] = feature_index;
|
||||
usb_buf[0x03] = fctn_ase_id;
|
||||
|
||||
usb_buf[0x04] = zone;
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 100 * speed;
|
||||
if (mode == LOGITECH_G_LIGHTSYNC_MODE_STATIC)
|
||||
{
|
||||
usb_buf[0x09] = 0x02;
|
||||
}
|
||||
if (mode == LOGITECH_G_LIGHTSYNC_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = brightness;
|
||||
}
|
||||
else if (mode == LOGITECH_G_LIGHTSYNC_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = brightness;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
| This code has to be protected to avoid crashes when |
|
||||
| this is called at the same time to change a powerplay |
|
||||
| mat and its paired wireless mouse leds. It will |
|
||||
| happen when using effects engines with high framerate |
|
||||
\*-----------------------------------------------------*/
|
||||
if(mutex)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(*mutex);
|
||||
|
||||
hid_write(dev, usb_buf, 20);
|
||||
hid_read(dev, usb_buf, 20);
|
||||
}
|
||||
else
|
||||
{
|
||||
hid_write(dev, usb_buf, 20);
|
||||
hid_read(dev, usb_buf, 20);
|
||||
}
|
||||
}
|
||||
|
||||
void LogitechGLightsyncController::SetDirectMode(bool direct)
|
||||
{
|
||||
unsigned char cmd_buf[7];
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(cmd_buf, 0x00, sizeof(cmd_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Command Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
cmd_buf[0x00] = 0x10;
|
||||
cmd_buf[0x01] = dev_index;
|
||||
cmd_buf[0x02] = feature_index;
|
||||
cmd_buf[0x03] = 0x8A;
|
||||
cmd_buf[0x04] = 0x00;
|
||||
cmd_buf[0x05] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| If direct, disable save to flash |
|
||||
\*-----------------------------------------------------*/
|
||||
if(direct)
|
||||
{
|
||||
cmd_buf[0x04] = 0x01;
|
||||
cmd_buf[0x05] = 0x01;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
| This code has to be protected to avoid crashes when |
|
||||
| this is called at the same time to change a powerplay |
|
||||
| mat and its paired wireless mouse leds. It will |
|
||||
| happen when using effects engines with high framerate |
|
||||
\*-----------------------------------------------------*/
|
||||
if(mutex)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(*mutex);
|
||||
|
||||
hid_write(cmd_dev, cmd_buf, 7);
|
||||
hid_read(dev, usb_buf, 20);
|
||||
}
|
||||
else
|
||||
{
|
||||
hid_write(cmd_dev, cmd_buf, 7);
|
||||
hid_read(dev, usb_buf, 20);
|
||||
}
|
||||
}
|
||||
+91
-91
@@ -1,91 +1,91 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechGLightsyncController.h |
|
||||
| |
|
||||
| Driver for Logitech Lightsync |
|
||||
| |
|
||||
| TheRogueZeta 21 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G_LIGHTSYNC_MODE_OFF = 0x00,
|
||||
LOGITECH_G_LIGHTSYNC_MODE_STATIC = 0x01,
|
||||
LOGITECH_G_LIGHTSYNC_MODE_CYCLE = 0x02,
|
||||
LOGITECH_G_LIGHTSYNC_MODE_BREATHING = 0x03,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_G_LIGHTSYNC_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_G_LIGHTSYNC_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechGLightsyncController
|
||||
{
|
||||
public:
|
||||
LogitechGLightsyncController
|
||||
(
|
||||
hid_device* ev_cmd_handle,
|
||||
hid_device* ev_handle,
|
||||
const char* ath,
|
||||
unsigned char id_dev_index,
|
||||
unsigned char id_feature_index,
|
||||
unsigned char id_fctn_ase_id,
|
||||
std::string ev_name
|
||||
);
|
||||
|
||||
LogitechGLightsyncController
|
||||
(
|
||||
hid_device* dev_cmd_handle,
|
||||
hid_device* dev_handle,
|
||||
const char* path,
|
||||
unsigned char hid_dev_index,
|
||||
unsigned char hid_feature_index,
|
||||
unsigned char hid_fctn_ase_id,
|
||||
std::shared_ptr<std::mutex> mutex_ptr,
|
||||
std::string dev_name
|
||||
);
|
||||
|
||||
~LogitechGLightsyncController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void UpdateMouseLED
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char zone,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue,
|
||||
unsigned char brightness
|
||||
);
|
||||
void SetDirectMode(bool direct);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
hid_device* cmd_dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
unsigned char dev_index;
|
||||
unsigned char feature_index;
|
||||
unsigned char fctn_ase_id;
|
||||
std::shared_ptr<std::mutex> mutex;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechGLightsyncController.h |
|
||||
| |
|
||||
| Driver for Logitech Lightsync |
|
||||
| |
|
||||
| TheRogueZeta 21 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G_LIGHTSYNC_MODE_OFF = 0x00,
|
||||
LOGITECH_G_LIGHTSYNC_MODE_STATIC = 0x01,
|
||||
LOGITECH_G_LIGHTSYNC_MODE_CYCLE = 0x02,
|
||||
LOGITECH_G_LIGHTSYNC_MODE_BREATHING = 0x03,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_G_LIGHTSYNC_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_G_LIGHTSYNC_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechGLightsyncController
|
||||
{
|
||||
public:
|
||||
LogitechGLightsyncController
|
||||
(
|
||||
hid_device* ev_cmd_handle,
|
||||
hid_device* ev_handle,
|
||||
const char* ath,
|
||||
unsigned char id_dev_index,
|
||||
unsigned char id_feature_index,
|
||||
unsigned char id_fctn_ase_id,
|
||||
std::string ev_name
|
||||
);
|
||||
|
||||
LogitechGLightsyncController
|
||||
(
|
||||
hid_device* dev_cmd_handle,
|
||||
hid_device* dev_handle,
|
||||
const char* path,
|
||||
unsigned char hid_dev_index,
|
||||
unsigned char hid_feature_index,
|
||||
unsigned char hid_fctn_ase_id,
|
||||
std::shared_ptr<std::mutex> mutex_ptr,
|
||||
std::string dev_name
|
||||
);
|
||||
|
||||
~LogitechGLightsyncController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void UpdateMouseLED
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char zone,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue,
|
||||
unsigned char brightness
|
||||
);
|
||||
void SetDirectMode(bool direct);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
hid_device* cmd_dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
unsigned char dev_index;
|
||||
unsigned char feature_index;
|
||||
unsigned char fctn_ase_id;
|
||||
std::shared_ptr<std::mutex> mutex;
|
||||
};
|
||||
+163
-163
@@ -1,163 +1,163 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGLightsync.cpp |
|
||||
| |
|
||||
| RGBController for Logitech Lightsync |
|
||||
| |
|
||||
| TheRogueZeta 21 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechGLightsync.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech Lightsync Mouse
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechMouseG303, DetectLogitechMouseG403
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechGLightsync::RGBController_LogitechGLightsync(LogitechGLightsyncController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = "Logitech G Lightsync Mouse";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G_LIGHTSYNC_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFF;
|
||||
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 = LOGITECH_G_LIGHTSYNC_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Static.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Spectrum Cycle";
|
||||
Cycle.value = LOGITECH_G_LIGHTSYNC_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
|
||||
Cycle.brightness_min = 0;
|
||||
Cycle.brightness_max = 100;
|
||||
Cycle.brightness = 100;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G_LIGHTSYNC_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Breathing.color_mode = MODE_COLORS_PER_LED;
|
||||
Breathing.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = 100;
|
||||
Breathing.brightness = 100;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechGLightsync::~RGBController_LogitechGLightsync()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync::SetupZones()
|
||||
{
|
||||
zone GLightsync_primary_zone;
|
||||
GLightsync_primary_zone.name = "DPI";
|
||||
GLightsync_primary_zone.type = ZONE_TYPE_SINGLE;
|
||||
GLightsync_primary_zone.leds_min = 1;
|
||||
GLightsync_primary_zone.leds_max = 1;
|
||||
GLightsync_primary_zone.leds_count = 1;
|
||||
GLightsync_primary_zone.matrix_map = NULL;
|
||||
zones.push_back(GLightsync_primary_zone);
|
||||
|
||||
led GLightsync_primary_led;
|
||||
GLightsync_primary_led.name = "DPI";
|
||||
leds.push_back(GLightsync_primary_led);
|
||||
|
||||
zone GLightsync_logo_zone;
|
||||
GLightsync_logo_zone.name = "Logo";
|
||||
GLightsync_logo_zone.type = ZONE_TYPE_SINGLE;
|
||||
GLightsync_logo_zone.leds_min = 1;
|
||||
GLightsync_logo_zone.leds_max = 1;
|
||||
GLightsync_logo_zone.leds_count = 1;
|
||||
GLightsync_logo_zone.matrix_map = NULL;
|
||||
zones.push_back(GLightsync_logo_zone);
|
||||
|
||||
led GLightsync_logo_led;
|
||||
GLightsync_logo_led.name = "Logo";
|
||||
leds.push_back(GLightsync_logo_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync::DeviceUpdateLEDs()
|
||||
{
|
||||
UpdateZoneLEDs(0);
|
||||
UpdateZoneLEDs(1);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[zone]);
|
||||
unsigned char grn = RGBGetGValue(colors[zone]);
|
||||
unsigned char blu = RGBGetBValue(colors[zone]);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Replace direct mode with static when sending to controller|
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char temp_mode = (modes[active_mode].value != 0xFF) ? modes[active_mode].value : LOGITECH_G_LIGHTSYNC_MODE_STATIC;
|
||||
|
||||
controller->UpdateMouseLED(temp_mode, modes[active_mode].speed, zone, red, grn, blu, modes[active_mode].brightness);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync::UpdateSingleLED(int led)
|
||||
{
|
||||
UpdateZoneLEDs(led);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| If direct mode is true, then sent the packet to put the |
|
||||
| mouse in direct mode. This code will only be called when |
|
||||
| we change modes as to not spam the device. |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetDirectMode(modes[active_mode].value == 0xFF);
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGLightsync.cpp |
|
||||
| |
|
||||
| RGBController for Logitech Lightsync |
|
||||
| |
|
||||
| TheRogueZeta 21 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechGLightsync.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech Lightsync Mouse
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechMouseG303, DetectLogitechMouseG403
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechGLightsync::RGBController_LogitechGLightsync(LogitechGLightsyncController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = "Logitech G Lightsync Mouse";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G_LIGHTSYNC_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFF;
|
||||
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 = LOGITECH_G_LIGHTSYNC_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Static.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Spectrum Cycle";
|
||||
Cycle.value = LOGITECH_G_LIGHTSYNC_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
|
||||
Cycle.brightness_min = 0;
|
||||
Cycle.brightness_max = 100;
|
||||
Cycle.brightness = 100;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G_LIGHTSYNC_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Breathing.color_mode = MODE_COLORS_PER_LED;
|
||||
Breathing.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = 100;
|
||||
Breathing.brightness = 100;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechGLightsync::~RGBController_LogitechGLightsync()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync::SetupZones()
|
||||
{
|
||||
zone GLightsync_primary_zone;
|
||||
GLightsync_primary_zone.name = "DPI";
|
||||
GLightsync_primary_zone.type = ZONE_TYPE_SINGLE;
|
||||
GLightsync_primary_zone.leds_min = 1;
|
||||
GLightsync_primary_zone.leds_max = 1;
|
||||
GLightsync_primary_zone.leds_count = 1;
|
||||
GLightsync_primary_zone.matrix_map = NULL;
|
||||
zones.push_back(GLightsync_primary_zone);
|
||||
|
||||
led GLightsync_primary_led;
|
||||
GLightsync_primary_led.name = "DPI";
|
||||
leds.push_back(GLightsync_primary_led);
|
||||
|
||||
zone GLightsync_logo_zone;
|
||||
GLightsync_logo_zone.name = "Logo";
|
||||
GLightsync_logo_zone.type = ZONE_TYPE_SINGLE;
|
||||
GLightsync_logo_zone.leds_min = 1;
|
||||
GLightsync_logo_zone.leds_max = 1;
|
||||
GLightsync_logo_zone.leds_count = 1;
|
||||
GLightsync_logo_zone.matrix_map = NULL;
|
||||
zones.push_back(GLightsync_logo_zone);
|
||||
|
||||
led GLightsync_logo_led;
|
||||
GLightsync_logo_led.name = "Logo";
|
||||
leds.push_back(GLightsync_logo_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync::DeviceUpdateLEDs()
|
||||
{
|
||||
UpdateZoneLEDs(0);
|
||||
UpdateZoneLEDs(1);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[zone]);
|
||||
unsigned char grn = RGBGetGValue(colors[zone]);
|
||||
unsigned char blu = RGBGetBValue(colors[zone]);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Replace direct mode with static when sending to controller|
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char temp_mode = (modes[active_mode].value != 0xFF) ? modes[active_mode].value : LOGITECH_G_LIGHTSYNC_MODE_STATIC;
|
||||
|
||||
controller->UpdateMouseLED(temp_mode, modes[active_mode].speed, zone, red, grn, blu, modes[active_mode].brightness);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync::UpdateSingleLED(int led)
|
||||
{
|
||||
UpdateZoneLEDs(led);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| If direct mode is true, then sent the packet to put the |
|
||||
| mouse in direct mode. This code will only be called when |
|
||||
| we change modes as to not spam the device. |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetDirectMode(modes[active_mode].value == 0xFF);
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
+35
-35
@@ -1,35 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGLightsync.h |
|
||||
| |
|
||||
| RGBController for Logitech Lightsync |
|
||||
| |
|
||||
| TheRogueZeta 21 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechGLightsyncController.h"
|
||||
|
||||
class RGBController_LogitechGLightsync : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechGLightsync(LogitechGLightsyncController* controller_ptr);
|
||||
~RGBController_LogitechGLightsync();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechGLightsyncController* controller;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGLightsync.h |
|
||||
| |
|
||||
| RGBController for Logitech Lightsync |
|
||||
| |
|
||||
| TheRogueZeta 21 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechGLightsyncController.h"
|
||||
|
||||
class RGBController_LogitechGLightsync : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechGLightsync(LogitechGLightsyncController* controller_ptr);
|
||||
~RGBController_LogitechGLightsync();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechGLightsyncController* controller;
|
||||
};
|
||||
+149
-149
@@ -1,149 +1,149 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGLightsync1zone.cpp |
|
||||
| |
|
||||
| RGBController for single zone Logitech Lightsync |
|
||||
| |
|
||||
| TheRogueZeta 21 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechGLightsync1zone.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech Lightsync Mouse (1 Zone)
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechMouseG203, DetectLogitechMouseGPRO
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechGLightsync1zone::RGBController_LogitechGLightsync1zone(LogitechGLightsyncController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = "Logitech G Lightsync Mouse Single Zone";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G_LIGHTSYNC_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFF;
|
||||
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 = LOGITECH_G_LIGHTSYNC_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Static.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Spectrum Cycle";
|
||||
Cycle.value = LOGITECH_G_LIGHTSYNC_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
|
||||
Cycle.brightness_min = 0;
|
||||
Cycle.brightness_max = 100;
|
||||
Cycle.brightness = 100;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G_LIGHTSYNC_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Breathing.color_mode = MODE_COLORS_PER_LED;
|
||||
Breathing.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = 100;
|
||||
Breathing.brightness = 100;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechGLightsync1zone::~RGBController_LogitechGLightsync1zone()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync1zone::SetupZones()
|
||||
{
|
||||
zone GLightsync_logo_zone;
|
||||
GLightsync_logo_zone.name = "Logo";
|
||||
GLightsync_logo_zone.type = ZONE_TYPE_SINGLE;
|
||||
GLightsync_logo_zone.leds_min = 1;
|
||||
GLightsync_logo_zone.leds_max = 1;
|
||||
GLightsync_logo_zone.leds_count = 1;
|
||||
GLightsync_logo_zone.matrix_map = NULL;
|
||||
zones.push_back(GLightsync_logo_zone);
|
||||
|
||||
led GLightsync_logo_led;
|
||||
GLightsync_logo_led.name = "Logo";
|
||||
leds.push_back(GLightsync_logo_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync1zone::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync1zone::DeviceUpdateLEDs()
|
||||
{
|
||||
UpdateZoneLEDs(0);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync1zone::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[zone]);
|
||||
unsigned char grn = RGBGetGValue(colors[zone]);
|
||||
unsigned char blu = RGBGetBValue(colors[zone]);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Replace direct mode with static when sending to controller|
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char temp_mode = (modes[active_mode].value != 0xFF) ? modes[active_mode].value : LOGITECH_G_LIGHTSYNC_MODE_STATIC;
|
||||
|
||||
controller->UpdateMouseLED(temp_mode, modes[active_mode].speed, zone, red, grn, blu, modes[active_mode].brightness);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync1zone::UpdateSingleLED(int led)
|
||||
{
|
||||
UpdateZoneLEDs(led);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync1zone::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| If direct mode is true, then sent the packet to put the |
|
||||
| mouse in direct mode. This code will only be called when |
|
||||
| we change modes as to not spam the device. |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetDirectMode(modes[active_mode].value == 0xFF);
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGLightsync1zone.cpp |
|
||||
| |
|
||||
| RGBController for single zone Logitech Lightsync |
|
||||
| |
|
||||
| TheRogueZeta 21 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechGLightsync1zone.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech Lightsync Mouse (1 Zone)
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechMouseG203, DetectLogitechMouseGPRO
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechGLightsync1zone::RGBController_LogitechGLightsync1zone(LogitechGLightsyncController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = "Logitech G Lightsync Mouse Single Zone";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G_LIGHTSYNC_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFF;
|
||||
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 = LOGITECH_G_LIGHTSYNC_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Static.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Spectrum Cycle";
|
||||
Cycle.value = LOGITECH_G_LIGHTSYNC_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
|
||||
Cycle.brightness_min = 0;
|
||||
Cycle.brightness_max = 100;
|
||||
Cycle.brightness = 100;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G_LIGHTSYNC_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Breathing.color_mode = MODE_COLORS_PER_LED;
|
||||
Breathing.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = 100;
|
||||
Breathing.brightness = 100;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechGLightsync1zone::~RGBController_LogitechGLightsync1zone()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync1zone::SetupZones()
|
||||
{
|
||||
zone GLightsync_logo_zone;
|
||||
GLightsync_logo_zone.name = "Logo";
|
||||
GLightsync_logo_zone.type = ZONE_TYPE_SINGLE;
|
||||
GLightsync_logo_zone.leds_min = 1;
|
||||
GLightsync_logo_zone.leds_max = 1;
|
||||
GLightsync_logo_zone.leds_count = 1;
|
||||
GLightsync_logo_zone.matrix_map = NULL;
|
||||
zones.push_back(GLightsync_logo_zone);
|
||||
|
||||
led GLightsync_logo_led;
|
||||
GLightsync_logo_led.name = "Logo";
|
||||
leds.push_back(GLightsync_logo_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync1zone::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync1zone::DeviceUpdateLEDs()
|
||||
{
|
||||
UpdateZoneLEDs(0);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync1zone::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[zone]);
|
||||
unsigned char grn = RGBGetGValue(colors[zone]);
|
||||
unsigned char blu = RGBGetBValue(colors[zone]);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Replace direct mode with static when sending to controller|
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char temp_mode = (modes[active_mode].value != 0xFF) ? modes[active_mode].value : LOGITECH_G_LIGHTSYNC_MODE_STATIC;
|
||||
|
||||
controller->UpdateMouseLED(temp_mode, modes[active_mode].speed, zone, red, grn, blu, modes[active_mode].brightness);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync1zone::UpdateSingleLED(int led)
|
||||
{
|
||||
UpdateZoneLEDs(led);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGLightsync1zone::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| If direct mode is true, then sent the packet to put the |
|
||||
| mouse in direct mode. This code will only be called when |
|
||||
| we change modes as to not spam the device. |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetDirectMode(modes[active_mode].value == 0xFF);
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
+35
-35
@@ -1,35 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGLightsync1zone.h |
|
||||
| |
|
||||
| RGBController for single zone Logitech Lightsync |
|
||||
| |
|
||||
| TheRogueZeta 21 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechGLightsyncController.h"
|
||||
|
||||
class RGBController_LogitechGLightsync1zone : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechGLightsync1zone(LogitechGLightsyncController* controller_ptr);
|
||||
~RGBController_LogitechGLightsync1zone();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechGLightsyncController* controller;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGLightsync1zone.h |
|
||||
| |
|
||||
| RGBController for single zone Logitech Lightsync |
|
||||
| |
|
||||
| TheRogueZeta 21 Apr 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechGLightsyncController.h"
|
||||
|
||||
class RGBController_LogitechGLightsync1zone : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechGLightsync1zone(LogitechGLightsyncController* controller_ptr);
|
||||
~RGBController_LogitechGLightsync1zone();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechGLightsyncController* controller;
|
||||
};
|
||||
+143
-143
@@ -1,143 +1,143 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGPowerPlay.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G PowerPlay |
|
||||
| |
|
||||
| TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechGPowerPlay.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech Powerplay Mat
|
||||
@category Mousemat
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechGPowerPlay::RGBController_LogitechGPowerPlay(LogitechGLightsyncController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_MOUSEMAT;
|
||||
description = "Logitech G PowerPlay Wireless Charging System";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G_LIGHTSYNC_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFF;
|
||||
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 = LOGITECH_G_LIGHTSYNC_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Static.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Spectrum Cycle";
|
||||
Cycle.value = LOGITECH_G_LIGHTSYNC_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G_LIGHTSYNC_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Breathing.color_mode = MODE_COLORS_PER_LED;
|
||||
Breathing.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechGPowerPlay::~RGBController_LogitechGPowerPlay()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechGPowerPlay::SetupZones()
|
||||
{
|
||||
zone GPowerPlay_logo_zone;
|
||||
GPowerPlay_logo_zone.name = "Logo";
|
||||
GPowerPlay_logo_zone.type = ZONE_TYPE_SINGLE;
|
||||
GPowerPlay_logo_zone.leds_min = 1;
|
||||
GPowerPlay_logo_zone.leds_max = 1;
|
||||
GPowerPlay_logo_zone.leds_count = 1;
|
||||
GPowerPlay_logo_zone.matrix_map = NULL;
|
||||
zones.push_back(GPowerPlay_logo_zone);
|
||||
|
||||
led GPowerPlay_logo_led;
|
||||
GPowerPlay_logo_led.name = "Logo";
|
||||
leds.push_back(GPowerPlay_logo_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechGPowerPlay::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechGPowerPlay::DeviceUpdateLEDs()
|
||||
{
|
||||
UpdateZoneLEDs(0);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGPowerPlay::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[zone]);
|
||||
unsigned char grn = RGBGetGValue(colors[zone]);
|
||||
unsigned char blu = RGBGetBValue(colors[zone]);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Replace direct mode with static when sending to controller|
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char temp_mode = (modes[active_mode].value != 0xFF) ? modes[active_mode].value : LOGITECH_G_LIGHTSYNC_MODE_STATIC;
|
||||
|
||||
controller->UpdateMouseLED(temp_mode, modes[active_mode].speed, zone, red, grn, blu, /* Brightness */ 0x64);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGPowerPlay::UpdateSingleLED(int led)
|
||||
{
|
||||
UpdateZoneLEDs(led);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGPowerPlay::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| If direct mode is true, then sent the packet to put the |
|
||||
| mouse in direct mode. This code will only be called when |
|
||||
| we change modes as to not spam the device. |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetDirectMode(modes[active_mode].value == 0xFF);
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGPowerPlay.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G PowerPlay |
|
||||
| |
|
||||
| TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechGPowerPlay.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech Powerplay Mat
|
||||
@category Mousemat
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechGPowerPlay::RGBController_LogitechGPowerPlay(LogitechGLightsyncController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_MOUSEMAT;
|
||||
description = "Logitech G PowerPlay Wireless Charging System";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_G_LIGHTSYNC_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFF;
|
||||
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 = LOGITECH_G_LIGHTSYNC_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Static.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Spectrum Cycle";
|
||||
Cycle.value = LOGITECH_G_LIGHTSYNC_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_G_LIGHTSYNC_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Breathing.color_mode = MODE_COLORS_PER_LED;
|
||||
Breathing.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechGPowerPlay::~RGBController_LogitechGPowerPlay()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechGPowerPlay::SetupZones()
|
||||
{
|
||||
zone GPowerPlay_logo_zone;
|
||||
GPowerPlay_logo_zone.name = "Logo";
|
||||
GPowerPlay_logo_zone.type = ZONE_TYPE_SINGLE;
|
||||
GPowerPlay_logo_zone.leds_min = 1;
|
||||
GPowerPlay_logo_zone.leds_max = 1;
|
||||
GPowerPlay_logo_zone.leds_count = 1;
|
||||
GPowerPlay_logo_zone.matrix_map = NULL;
|
||||
zones.push_back(GPowerPlay_logo_zone);
|
||||
|
||||
led GPowerPlay_logo_led;
|
||||
GPowerPlay_logo_led.name = "Logo";
|
||||
leds.push_back(GPowerPlay_logo_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechGPowerPlay::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechGPowerPlay::DeviceUpdateLEDs()
|
||||
{
|
||||
UpdateZoneLEDs(0);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGPowerPlay::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[zone]);
|
||||
unsigned char grn = RGBGetGValue(colors[zone]);
|
||||
unsigned char blu = RGBGetBValue(colors[zone]);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Replace direct mode with static when sending to controller|
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char temp_mode = (modes[active_mode].value != 0xFF) ? modes[active_mode].value : LOGITECH_G_LIGHTSYNC_MODE_STATIC;
|
||||
|
||||
controller->UpdateMouseLED(temp_mode, modes[active_mode].speed, zone, red, grn, blu, /* Brightness */ 0x64);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGPowerPlay::UpdateSingleLED(int led)
|
||||
{
|
||||
UpdateZoneLEDs(led);
|
||||
}
|
||||
|
||||
void RGBController_LogitechGPowerPlay::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| If direct mode is true, then sent the packet to put the |
|
||||
| mouse in direct mode. This code will only be called when |
|
||||
| we change modes as to not spam the device. |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->SetDirectMode(modes[active_mode].value == 0xFF);
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
+35
-35
@@ -1,35 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGPowerPlay.h |
|
||||
| |
|
||||
| RGBController for Logitech G PowerPlay |
|
||||
| |
|
||||
| TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechGLightsyncController.h"
|
||||
|
||||
class RGBController_LogitechGPowerPlay : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechGPowerPlay(LogitechGLightsyncController* controller_ptr);
|
||||
~RGBController_LogitechGPowerPlay();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechGLightsyncController* controller;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGPowerPlay.h |
|
||||
| |
|
||||
| RGBController for Logitech G PowerPlay |
|
||||
| |
|
||||
| TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechGLightsyncController.h"
|
||||
|
||||
class RGBController_LogitechGPowerPlay : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechGPowerPlay(LogitechGLightsyncController* controller_ptr);
|
||||
~RGBController_LogitechGPowerPlay();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechGLightsyncController* controller;
|
||||
};
|
||||
+192
-192
@@ -1,192 +1,192 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechGProController.cpp |
|
||||
| |
|
||||
| Driver for Logitech G Pro keyboard |
|
||||
| |
|
||||
| sanchezzzs 20 Oct 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechGProKeyboardController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechGProKeyboardController::LogitechGProKeyboardController(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name)
|
||||
{
|
||||
dev_pkt_0x11 = dev_handle_0x11;
|
||||
dev_pkt_0x12 = dev_handle_0x12;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechGProKeyboardController::~LogitechGProKeyboardController()
|
||||
{
|
||||
hid_close(dev_pkt_0x11);
|
||||
hid_close(dev_pkt_0x12);
|
||||
}
|
||||
|
||||
std::string LogitechGProKeyboardController::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechGProKeyboardController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void LogitechGProKeyboardController::Commit()
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void LogitechGProKeyboardController::SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
SendDirectFrame(zone, frame_count, frame_data);
|
||||
}
|
||||
|
||||
void LogitechGProKeyboardController::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
SendMode(LOGITECH_GPRO_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
|
||||
SendMode(LOGITECH_GPRO_ZONE_MODE_LOGO, mode, speed, red, green, blue);
|
||||
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void LogitechGProKeyboardController::SendCommit()
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0C;
|
||||
usb_buf[0x03] = 0x5D;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechGProKeyboardController::SendDirectFrame
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x12;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0C;
|
||||
usb_buf[0x03] = 0x3D;
|
||||
usb_buf[0x05] = zone;
|
||||
usb_buf[0x07] = frame_count;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in frame data |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x08], frame_data, frame_count * 4);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x12, usb_buf, 64);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechGProKeyboardController::SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0D;
|
||||
usb_buf[0x03] = 0x3D;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 100 * speed;
|
||||
if(mode == LOGITECH_GPRO_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_GPRO_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = 0x64;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechGProController.cpp |
|
||||
| |
|
||||
| Driver for Logitech G Pro keyboard |
|
||||
| |
|
||||
| sanchezzzs 20 Oct 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechGProKeyboardController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechGProKeyboardController::LogitechGProKeyboardController(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name)
|
||||
{
|
||||
dev_pkt_0x11 = dev_handle_0x11;
|
||||
dev_pkt_0x12 = dev_handle_0x12;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechGProKeyboardController::~LogitechGProKeyboardController()
|
||||
{
|
||||
hid_close(dev_pkt_0x11);
|
||||
hid_close(dev_pkt_0x12);
|
||||
}
|
||||
|
||||
std::string LogitechGProKeyboardController::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechGProKeyboardController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void LogitechGProKeyboardController::Commit()
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void LogitechGProKeyboardController::SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
SendDirectFrame(zone, frame_count, frame_data);
|
||||
}
|
||||
|
||||
void LogitechGProKeyboardController::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
SendMode(LOGITECH_GPRO_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
|
||||
SendMode(LOGITECH_GPRO_ZONE_MODE_LOGO, mode, speed, red, green, blue);
|
||||
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void LogitechGProKeyboardController::SendCommit()
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0C;
|
||||
usb_buf[0x03] = 0x5D;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechGProKeyboardController::SendDirectFrame
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x12;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0C;
|
||||
usb_buf[0x03] = 0x3D;
|
||||
usb_buf[0x05] = zone;
|
||||
usb_buf[0x07] = frame_count;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in frame data |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x08], frame_data, frame_count * 4);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x12, usb_buf, 64);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechGProKeyboardController::SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[20];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x0D;
|
||||
usb_buf[0x03] = 0x3D;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 100 * speed;
|
||||
if(mode == LOGITECH_GPRO_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_GPRO_MODE_BREATHING)
|
||||
{
|
||||
usb_buf[0x09] = speed >> 8;
|
||||
usb_buf[0x0A] = speed & 0xFF;
|
||||
usb_buf[0x0C] = 0x64;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, usb_buf, 20);
|
||||
}
|
||||
+102
-102
@@ -1,102 +1,102 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechGProController.h |
|
||||
| |
|
||||
| Driver for Logitech G Pro keyboard |
|
||||
| |
|
||||
| sanchezzzs 20 Oct 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 "RGBController.h"
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_GPRO_ZONE_MODE_KEYBOARD = 0x00,
|
||||
LOGITECH_GPRO_ZONE_MODE_LOGO = 0x01,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD = 0x01,
|
||||
LOGITECH_GPRO_ZONE_DIRECT_MEDIA = 0x02,
|
||||
LOGITECH_GPRO_ZONE_DIRECT_LOGO = 0x10,
|
||||
LOGITECH_GPRO_ZONE_DIRECT_INDICATORS = 0x40,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_GPRO_MODE_OFF = 0x00,
|
||||
LOGITECH_GPRO_MODE_STATIC = 0x01,
|
||||
LOGITECH_GPRO_MODE_BREATHING = 0x02,
|
||||
LOGITECH_GPRO_MODE_CYCLE = 0x03,
|
||||
LOGITECH_GPRO_MODE_WAVE = 0x04,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_GPRO_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_GPRO_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_GPRO_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechGProKeyboardController
|
||||
{
|
||||
public:
|
||||
LogitechGProKeyboardController(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name);
|
||||
~LogitechGProKeyboardController();
|
||||
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void Commit();
|
||||
|
||||
void SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev_pkt_0x11;
|
||||
hid_device* dev_pkt_0x12;
|
||||
std::string name;
|
||||
|
||||
void SendDirectFrame
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
void SendCommit();
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechGProController.h |
|
||||
| |
|
||||
| Driver for Logitech G Pro keyboard |
|
||||
| |
|
||||
| sanchezzzs 20 Oct 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 "RGBController.h"
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_GPRO_ZONE_MODE_KEYBOARD = 0x00,
|
||||
LOGITECH_GPRO_ZONE_MODE_LOGO = 0x01,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD = 0x01,
|
||||
LOGITECH_GPRO_ZONE_DIRECT_MEDIA = 0x02,
|
||||
LOGITECH_GPRO_ZONE_DIRECT_LOGO = 0x10,
|
||||
LOGITECH_GPRO_ZONE_DIRECT_INDICATORS = 0x40,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_GPRO_MODE_OFF = 0x00,
|
||||
LOGITECH_GPRO_MODE_STATIC = 0x01,
|
||||
LOGITECH_GPRO_MODE_BREATHING = 0x02,
|
||||
LOGITECH_GPRO_MODE_CYCLE = 0x03,
|
||||
LOGITECH_GPRO_MODE_WAVE = 0x04,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_GPRO_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_GPRO_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_GPRO_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechGProKeyboardController
|
||||
{
|
||||
public:
|
||||
LogitechGProKeyboardController(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12, std::string dev_name);
|
||||
~LogitechGProKeyboardController();
|
||||
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
void Commit();
|
||||
|
||||
void SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev_pkt_0x11;
|
||||
hid_device* dev_pkt_0x12;
|
||||
std::string name;
|
||||
|
||||
void SendDirectFrame
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
);
|
||||
|
||||
void SendMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
void SendCommit();
|
||||
};
|
||||
+379
-379
@@ -1,379 +1,379 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGPro.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G Pro keyboard |
|
||||
| |
|
||||
| sanchezzzs 20 Oct 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "RGBController_LogitechGProKeyboard.h"
|
||||
|
||||
//0xFFFFFFFF indicates an unused entry in matrix
|
||||
#define NA 0xFFFFFFFF
|
||||
|
||||
static unsigned int matrix_map[7][19] =
|
||||
{ { 89, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 93, 92, NA, NA, 91, NA, 90 },
|
||||
{ 37, NA, 54, 55, 56, 57, NA, 58, 59, 60, 61, NA, 62, 63, 64, 65, 66, 67, 68 },
|
||||
{ 49, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, NA, 41, 42, 38, NA, 69, 70, 71 },
|
||||
{ 39, NA, 16, 22, 4, 17, NA, 19, 24, 20, 8, 14, 15, 43, 44, 45, 72, 73, 74 },
|
||||
{ 53, NA, 0, 18, 3, 5, NA, 6, 7, 9, 10, 11, 47, 48, 46, 36, NA, NA, NA },
|
||||
{ 82, 79, 25, 23, 2, 21, NA, 1, NA, 13, 12, 50, 51, 52, 86, NA, NA, 78, NA },
|
||||
{ 81, 84, 83, NA, NA, NA, NA, 40, NA, NA, NA, NA, 87, 88, 80, 85, 76, 77, 75 } };
|
||||
|
||||
static const char* zone_names[] =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
};
|
||||
|
||||
static zone_type zone_types[] =
|
||||
{
|
||||
ZONE_TYPE_MATRIX,
|
||||
};
|
||||
|
||||
static const unsigned int zone_sizes[] =
|
||||
{
|
||||
94,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char * name;
|
||||
const unsigned char zone;
|
||||
const unsigned char idx;
|
||||
} led_type;
|
||||
|
||||
static const led_type led_names[] =
|
||||
{
|
||||
/* Key Label Zone, Index */
|
||||
{ KEY_EN_A, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x04 },//00
|
||||
{ KEY_EN_B, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x05 },
|
||||
{ KEY_EN_C, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x06 },
|
||||
{ KEY_EN_D, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x07 },
|
||||
{ KEY_EN_E, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x08 },
|
||||
{ KEY_EN_F, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x09 },
|
||||
{ KEY_EN_G, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x0A },
|
||||
{ KEY_EN_H, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x0B },
|
||||
{ KEY_EN_I, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x0C },
|
||||
{ KEY_EN_J, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x0D },
|
||||
{ KEY_EN_K, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x0E },//10
|
||||
{ KEY_EN_L, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x0F },
|
||||
{ KEY_EN_M, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x10 },
|
||||
{ KEY_EN_N, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x11 },
|
||||
{ KEY_EN_O, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x12 },
|
||||
{ KEY_EN_P, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x13 },
|
||||
{ KEY_EN_Q, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x14 },
|
||||
{ KEY_EN_R, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x15 },
|
||||
{ KEY_EN_S, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x16 },
|
||||
{ KEY_EN_T, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x17 },
|
||||
{ KEY_EN_U, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x18 },//20
|
||||
{ KEY_EN_V, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x19 },
|
||||
{ KEY_EN_W, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x1A },
|
||||
{ KEY_EN_X, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x1B },
|
||||
{ KEY_EN_Y, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x1C },
|
||||
{ KEY_EN_Z, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x1D },
|
||||
{ KEY_EN_1, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x1E },
|
||||
{ KEY_EN_2, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x1F },
|
||||
{ KEY_EN_3, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x20 },
|
||||
{ KEY_EN_4, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x21 },
|
||||
{ KEY_EN_5, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x22 },//30
|
||||
{ KEY_EN_6, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x23 },
|
||||
{ KEY_EN_7, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x24 },
|
||||
{ KEY_EN_8, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x25 },
|
||||
{ KEY_EN_9, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x26 },
|
||||
{ KEY_EN_0, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x27 },
|
||||
{ KEY_EN_ANSI_ENTER, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x28 },
|
||||
{ KEY_EN_ESCAPE, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x29 },
|
||||
{ KEY_EN_BACKSPACE, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x2A },
|
||||
{ KEY_EN_TAB, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x2B },
|
||||
{ KEY_EN_SPACE, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x2C },//40
|
||||
{ KEY_EN_MINUS, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x2D },
|
||||
{ KEY_EN_EQUALS, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x2E },
|
||||
{ KEY_EN_LEFT_BRACKET, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x2F },
|
||||
{ KEY_EN_RIGHT_BRACKET, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x30 },
|
||||
{ KEY_EN_ANSI_BACK_SLASH, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x31 },//ANSI only
|
||||
{ KEY_EN_POUND, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x32 },//ISO only
|
||||
{ KEY_EN_SEMICOLON, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x33 },
|
||||
{ KEY_EN_QUOTE, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x34 },
|
||||
{ KEY_EN_BACK_TICK, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x35 },
|
||||
{ KEY_EN_COMMA, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x36 },//50
|
||||
{ KEY_EN_PERIOD, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x37 },
|
||||
{ KEY_EN_FORWARD_SLASH, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x38 },
|
||||
{ KEY_EN_CAPS_LOCK, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x39 },
|
||||
{ KEY_EN_F1, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x3A },
|
||||
{ KEY_EN_F2, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x3B },
|
||||
{ KEY_EN_F3, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x3C },
|
||||
{ KEY_EN_F4, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x3D },
|
||||
{ KEY_EN_F5, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x3E },
|
||||
{ KEY_EN_F6, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x3F },
|
||||
{ KEY_EN_F7, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x40 },//60
|
||||
{ KEY_EN_F8, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x41 },
|
||||
{ KEY_EN_F9, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x42 },
|
||||
{ KEY_EN_F10, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x43 },
|
||||
{ KEY_EN_F11, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x44 },
|
||||
{ KEY_EN_F12, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x45 },
|
||||
{ KEY_EN_PRINT_SCREEN, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x46 },
|
||||
{ KEY_EN_SCROLL_LOCK, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x47 },
|
||||
{ KEY_EN_PAUSE_BREAK, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x48 },
|
||||
{ KEY_EN_INSERT, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x49 },
|
||||
{ KEY_EN_HOME, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x4A },//70
|
||||
{ KEY_EN_PAGE_UP, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x4B },
|
||||
{ KEY_EN_DELETE, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x4C },
|
||||
{ KEY_EN_END, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x4D },
|
||||
{ KEY_EN_PAGE_DOWN, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x4E },
|
||||
{ KEY_EN_RIGHT_ARROW, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x4F },
|
||||
{ KEY_EN_LEFT_ARROW, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x50 },
|
||||
{ KEY_EN_DOWN_ARROW, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x51 },
|
||||
{ KEY_EN_UP_ARROW, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x52 },
|
||||
{ KEY_EN_ISO_BACK_SLASH, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x64 },//ISO only
|
||||
{ KEY_EN_MENU, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x65 },//80
|
||||
{ KEY_EN_LEFT_CONTROL, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE0 },
|
||||
{ KEY_EN_LEFT_SHIFT, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE1 },
|
||||
{ KEY_EN_LEFT_ALT, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE2 },
|
||||
{ KEY_EN_LEFT_WINDOWS, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE3 },
|
||||
{ KEY_EN_RIGHT_CONTROL, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE4 },
|
||||
{ KEY_EN_RIGHT_SHIFT, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE5 },
|
||||
{ KEY_EN_RIGHT_ALT, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE6 },
|
||||
{ KEY_EN_RIGHT_FUNCTION, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE7 },
|
||||
{ "Logo", LOGITECH_GPRO_ZONE_DIRECT_LOGO, 0x01 },
|
||||
{ "Lighting", LOGITECH_GPRO_ZONE_DIRECT_INDICATORS, 0x01 },//90
|
||||
{ "Game Mode", LOGITECH_GPRO_ZONE_DIRECT_INDICATORS, 0x02 },
|
||||
{ "Caps Lock Indicator", LOGITECH_GPRO_ZONE_DIRECT_INDICATORS, 0x03 },
|
||||
{ "Scroll Lock Indicator", LOGITECH_GPRO_ZONE_DIRECT_INDICATORS, 0x04 },//93
|
||||
};
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G Pro
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechKeyboardGPro
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechGProKeyboard::RGBController_LogitechGProKeyboard(LogitechGProKeyboardController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "Logitech Keyboard Device";
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFFFF;
|
||||
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 = LOGITECH_GPRO_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_GPRO_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Cycle";
|
||||
Cycle.value = LOGITECH_GPRO_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_GPRO_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_GPRO_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_GPRO_SPEED_NORMAL;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_GPRO_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.speed_min = LOGITECH_GPRO_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_GPRO_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_GPRO_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechGProKeyboard::~RGBController_LogitechGProKeyboard()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Delete the matrix map |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
|
||||
{
|
||||
if(zones[zone_index].matrix_map != NULL)
|
||||
{
|
||||
delete zones[zone_index].matrix_map;
|
||||
}
|
||||
}
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechGProKeyboard::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int total_led_count = 0;
|
||||
for(unsigned int zone_idx = 0; zone_idx < 1; zone_idx++)
|
||||
{
|
||||
zone new_zone;
|
||||
new_zone.name = zone_names[zone_idx];
|
||||
new_zone.type = zone_types[zone_idx];
|
||||
new_zone.leds_min = zone_sizes[zone_idx];
|
||||
new_zone.leds_max = zone_sizes[zone_idx];
|
||||
new_zone.leds_count = zone_sizes[zone_idx];
|
||||
|
||||
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
|
||||
{
|
||||
new_zone.matrix_map = new matrix_map_type;
|
||||
new_zone.matrix_map->height = 7;
|
||||
new_zone.matrix_map->width = 19;
|
||||
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_zone.matrix_map = NULL;
|
||||
}
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
total_led_count += zone_sizes[zone_idx];
|
||||
}
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = led_names[led_idx].name;
|
||||
new_led.value = ( led_names[led_idx].zone << 8 ) + led_names[led_idx].idx;
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechGProKeyboard::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechGProKeyboard::DeviceUpdateLEDs()
|
||||
{
|
||||
#define MAX_FRAMES_PER_PACKET 0x0E
|
||||
|
||||
unsigned char frame_buf[MAX_FRAMES_PER_PACKET * 4];
|
||||
unsigned char frame_cnt = 0;
|
||||
unsigned char prev_zone = 0;
|
||||
unsigned char zone = 0;
|
||||
unsigned char idx = 0;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| TODO: Send packets with multiple LED frames |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
zone = ( leds[led_idx].value >> 8 );
|
||||
idx = ( leds[led_idx].value & 0xFF );
|
||||
|
||||
if((zone != prev_zone) && (frame_cnt != 0))
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
frame_cnt = 0;
|
||||
}
|
||||
|
||||
frame_buf[(frame_cnt * 4) + 0] = idx;
|
||||
frame_buf[(frame_cnt * 4) + 1] = RGBGetRValue(colors[led_idx]);
|
||||
frame_buf[(frame_cnt * 4) + 2] = RGBGetGValue(colors[led_idx]);
|
||||
frame_buf[(frame_cnt * 4) + 3] = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
frame_cnt++;
|
||||
prev_zone = zone;
|
||||
|
||||
if(frame_cnt == MAX_FRAMES_PER_PACKET)
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
frame_cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(frame_cnt != 0)
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
}
|
||||
|
||||
controller->Commit();
|
||||
}
|
||||
|
||||
void RGBController_LogitechGProKeyboard::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechGProKeyboard::UpdateSingleLED(int led)
|
||||
{
|
||||
unsigned char frame[4];
|
||||
unsigned char zone;
|
||||
unsigned char idx;
|
||||
|
||||
zone = ( leds[led].value >> 8 );
|
||||
idx = ( leds[led].value & 0xFF );
|
||||
|
||||
frame[0] = idx;
|
||||
frame[1] = RGBGetRValue(colors[led]);
|
||||
frame[2] = RGBGetGValue(colors[led]);
|
||||
frame[3] = RGBGetBValue(colors[led]);
|
||||
|
||||
controller->SetDirect(zone, 1, frame);
|
||||
controller->Commit();
|
||||
}
|
||||
|
||||
void RGBController_LogitechGProKeyboard::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Direct mode does not send a mode packet |
|
||||
| Call UpdateLEDs to send direct packet |
|
||||
\*---------------------------------------------------------*/
|
||||
if(active_mode == 0xFFFF)
|
||||
{
|
||||
UpdateLEDs();
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char red = 0;
|
||||
unsigned char grn = 0;
|
||||
unsigned char blu = 0;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
red = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
grn = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
blu = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
}
|
||||
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, red, grn, blu);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGPro.cpp |
|
||||
| |
|
||||
| RGBController for Logitech G Pro keyboard |
|
||||
| |
|
||||
| sanchezzzs 20 Oct 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "RGBController_LogitechGProKeyboard.h"
|
||||
|
||||
//0xFFFFFFFF indicates an unused entry in matrix
|
||||
#define NA 0xFFFFFFFF
|
||||
|
||||
static unsigned int matrix_map[7][19] =
|
||||
{ { 89, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 93, 92, NA, NA, 91, NA, 90 },
|
||||
{ 37, NA, 54, 55, 56, 57, NA, 58, 59, 60, 61, NA, 62, 63, 64, 65, 66, 67, 68 },
|
||||
{ 49, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, NA, 41, 42, 38, NA, 69, 70, 71 },
|
||||
{ 39, NA, 16, 22, 4, 17, NA, 19, 24, 20, 8, 14, 15, 43, 44, 45, 72, 73, 74 },
|
||||
{ 53, NA, 0, 18, 3, 5, NA, 6, 7, 9, 10, 11, 47, 48, 46, 36, NA, NA, NA },
|
||||
{ 82, 79, 25, 23, 2, 21, NA, 1, NA, 13, 12, 50, 51, 52, 86, NA, NA, 78, NA },
|
||||
{ 81, 84, 83, NA, NA, NA, NA, 40, NA, NA, NA, NA, 87, 88, 80, 85, 76, 77, 75 } };
|
||||
|
||||
static const char* zone_names[] =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
};
|
||||
|
||||
static zone_type zone_types[] =
|
||||
{
|
||||
ZONE_TYPE_MATRIX,
|
||||
};
|
||||
|
||||
static const unsigned int zone_sizes[] =
|
||||
{
|
||||
94,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char * name;
|
||||
const unsigned char zone;
|
||||
const unsigned char idx;
|
||||
} led_type;
|
||||
|
||||
static const led_type led_names[] =
|
||||
{
|
||||
/* Key Label Zone, Index */
|
||||
{ KEY_EN_A, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x04 },//00
|
||||
{ KEY_EN_B, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x05 },
|
||||
{ KEY_EN_C, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x06 },
|
||||
{ KEY_EN_D, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x07 },
|
||||
{ KEY_EN_E, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x08 },
|
||||
{ KEY_EN_F, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x09 },
|
||||
{ KEY_EN_G, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x0A },
|
||||
{ KEY_EN_H, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x0B },
|
||||
{ KEY_EN_I, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x0C },
|
||||
{ KEY_EN_J, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x0D },
|
||||
{ KEY_EN_K, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x0E },//10
|
||||
{ KEY_EN_L, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x0F },
|
||||
{ KEY_EN_M, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x10 },
|
||||
{ KEY_EN_N, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x11 },
|
||||
{ KEY_EN_O, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x12 },
|
||||
{ KEY_EN_P, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x13 },
|
||||
{ KEY_EN_Q, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x14 },
|
||||
{ KEY_EN_R, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x15 },
|
||||
{ KEY_EN_S, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x16 },
|
||||
{ KEY_EN_T, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x17 },
|
||||
{ KEY_EN_U, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x18 },//20
|
||||
{ KEY_EN_V, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x19 },
|
||||
{ KEY_EN_W, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x1A },
|
||||
{ KEY_EN_X, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x1B },
|
||||
{ KEY_EN_Y, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x1C },
|
||||
{ KEY_EN_Z, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x1D },
|
||||
{ KEY_EN_1, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x1E },
|
||||
{ KEY_EN_2, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x1F },
|
||||
{ KEY_EN_3, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x20 },
|
||||
{ KEY_EN_4, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x21 },
|
||||
{ KEY_EN_5, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x22 },//30
|
||||
{ KEY_EN_6, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x23 },
|
||||
{ KEY_EN_7, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x24 },
|
||||
{ KEY_EN_8, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x25 },
|
||||
{ KEY_EN_9, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x26 },
|
||||
{ KEY_EN_0, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x27 },
|
||||
{ KEY_EN_ANSI_ENTER, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x28 },
|
||||
{ KEY_EN_ESCAPE, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x29 },
|
||||
{ KEY_EN_BACKSPACE, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x2A },
|
||||
{ KEY_EN_TAB, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x2B },
|
||||
{ KEY_EN_SPACE, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x2C },//40
|
||||
{ KEY_EN_MINUS, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x2D },
|
||||
{ KEY_EN_EQUALS, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x2E },
|
||||
{ KEY_EN_LEFT_BRACKET, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x2F },
|
||||
{ KEY_EN_RIGHT_BRACKET, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x30 },
|
||||
{ KEY_EN_ANSI_BACK_SLASH, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x31 },//ANSI only
|
||||
{ KEY_EN_POUND, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x32 },//ISO only
|
||||
{ KEY_EN_SEMICOLON, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x33 },
|
||||
{ KEY_EN_QUOTE, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x34 },
|
||||
{ KEY_EN_BACK_TICK, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x35 },
|
||||
{ KEY_EN_COMMA, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x36 },//50
|
||||
{ KEY_EN_PERIOD, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x37 },
|
||||
{ KEY_EN_FORWARD_SLASH, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x38 },
|
||||
{ KEY_EN_CAPS_LOCK, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x39 },
|
||||
{ KEY_EN_F1, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x3A },
|
||||
{ KEY_EN_F2, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x3B },
|
||||
{ KEY_EN_F3, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x3C },
|
||||
{ KEY_EN_F4, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x3D },
|
||||
{ KEY_EN_F5, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x3E },
|
||||
{ KEY_EN_F6, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x3F },
|
||||
{ KEY_EN_F7, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x40 },//60
|
||||
{ KEY_EN_F8, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x41 },
|
||||
{ KEY_EN_F9, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x42 },
|
||||
{ KEY_EN_F10, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x43 },
|
||||
{ KEY_EN_F11, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x44 },
|
||||
{ KEY_EN_F12, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x45 },
|
||||
{ KEY_EN_PRINT_SCREEN, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x46 },
|
||||
{ KEY_EN_SCROLL_LOCK, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x47 },
|
||||
{ KEY_EN_PAUSE_BREAK, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x48 },
|
||||
{ KEY_EN_INSERT, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x49 },
|
||||
{ KEY_EN_HOME, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x4A },//70
|
||||
{ KEY_EN_PAGE_UP, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x4B },
|
||||
{ KEY_EN_DELETE, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x4C },
|
||||
{ KEY_EN_END, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x4D },
|
||||
{ KEY_EN_PAGE_DOWN, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x4E },
|
||||
{ KEY_EN_RIGHT_ARROW, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x4F },
|
||||
{ KEY_EN_LEFT_ARROW, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x50 },
|
||||
{ KEY_EN_DOWN_ARROW, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x51 },
|
||||
{ KEY_EN_UP_ARROW, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x52 },
|
||||
{ KEY_EN_ISO_BACK_SLASH, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x64 },//ISO only
|
||||
{ KEY_EN_MENU, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0x65 },//80
|
||||
{ KEY_EN_LEFT_CONTROL, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE0 },
|
||||
{ KEY_EN_LEFT_SHIFT, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE1 },
|
||||
{ KEY_EN_LEFT_ALT, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE2 },
|
||||
{ KEY_EN_LEFT_WINDOWS, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE3 },
|
||||
{ KEY_EN_RIGHT_CONTROL, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE4 },
|
||||
{ KEY_EN_RIGHT_SHIFT, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE5 },
|
||||
{ KEY_EN_RIGHT_ALT, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE6 },
|
||||
{ KEY_EN_RIGHT_FUNCTION, LOGITECH_GPRO_ZONE_DIRECT_KEYBOARD, 0xE7 },
|
||||
{ "Logo", LOGITECH_GPRO_ZONE_DIRECT_LOGO, 0x01 },
|
||||
{ "Lighting", LOGITECH_GPRO_ZONE_DIRECT_INDICATORS, 0x01 },//90
|
||||
{ "Game Mode", LOGITECH_GPRO_ZONE_DIRECT_INDICATORS, 0x02 },
|
||||
{ "Caps Lock Indicator", LOGITECH_GPRO_ZONE_DIRECT_INDICATORS, 0x03 },
|
||||
{ "Scroll Lock Indicator", LOGITECH_GPRO_ZONE_DIRECT_INDICATORS, 0x04 },//93
|
||||
};
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech G Pro
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechKeyboardGPro
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechGProKeyboard::RGBController_LogitechGProKeyboard(LogitechGProKeyboardController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "Logitech Keyboard Device";
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0xFFFF;
|
||||
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 = LOGITECH_GPRO_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_GPRO_MODE_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Cycle;
|
||||
Cycle.name = "Cycle";
|
||||
Cycle.value = LOGITECH_GPRO_MODE_CYCLE;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.speed_min = LOGITECH_GPRO_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_GPRO_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_GPRO_SPEED_NORMAL;
|
||||
modes.push_back(Cycle);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = LOGITECH_GPRO_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.speed_min = LOGITECH_GPRO_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_GPRO_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_GPRO_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechGProKeyboard::~RGBController_LogitechGProKeyboard()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Delete the matrix map |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
|
||||
{
|
||||
if(zones[zone_index].matrix_map != NULL)
|
||||
{
|
||||
delete zones[zone_index].matrix_map;
|
||||
}
|
||||
}
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechGProKeyboard::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int total_led_count = 0;
|
||||
for(unsigned int zone_idx = 0; zone_idx < 1; zone_idx++)
|
||||
{
|
||||
zone new_zone;
|
||||
new_zone.name = zone_names[zone_idx];
|
||||
new_zone.type = zone_types[zone_idx];
|
||||
new_zone.leds_min = zone_sizes[zone_idx];
|
||||
new_zone.leds_max = zone_sizes[zone_idx];
|
||||
new_zone.leds_count = zone_sizes[zone_idx];
|
||||
|
||||
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
|
||||
{
|
||||
new_zone.matrix_map = new matrix_map_type;
|
||||
new_zone.matrix_map->height = 7;
|
||||
new_zone.matrix_map->width = 19;
|
||||
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_zone.matrix_map = NULL;
|
||||
}
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
total_led_count += zone_sizes[zone_idx];
|
||||
}
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = led_names[led_idx].name;
|
||||
new_led.value = ( led_names[led_idx].zone << 8 ) + led_names[led_idx].idx;
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechGProKeyboard::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechGProKeyboard::DeviceUpdateLEDs()
|
||||
{
|
||||
#define MAX_FRAMES_PER_PACKET 0x0E
|
||||
|
||||
unsigned char frame_buf[MAX_FRAMES_PER_PACKET * 4];
|
||||
unsigned char frame_cnt = 0;
|
||||
unsigned char prev_zone = 0;
|
||||
unsigned char zone = 0;
|
||||
unsigned char idx = 0;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| TODO: Send packets with multiple LED frames |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
zone = ( leds[led_idx].value >> 8 );
|
||||
idx = ( leds[led_idx].value & 0xFF );
|
||||
|
||||
if((zone != prev_zone) && (frame_cnt != 0))
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
frame_cnt = 0;
|
||||
}
|
||||
|
||||
frame_buf[(frame_cnt * 4) + 0] = idx;
|
||||
frame_buf[(frame_cnt * 4) + 1] = RGBGetRValue(colors[led_idx]);
|
||||
frame_buf[(frame_cnt * 4) + 2] = RGBGetGValue(colors[led_idx]);
|
||||
frame_buf[(frame_cnt * 4) + 3] = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
frame_cnt++;
|
||||
prev_zone = zone;
|
||||
|
||||
if(frame_cnt == MAX_FRAMES_PER_PACKET)
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
frame_cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(frame_cnt != 0)
|
||||
{
|
||||
controller->SetDirect(prev_zone, frame_cnt, frame_buf);
|
||||
}
|
||||
|
||||
controller->Commit();
|
||||
}
|
||||
|
||||
void RGBController_LogitechGProKeyboard::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechGProKeyboard::UpdateSingleLED(int led)
|
||||
{
|
||||
unsigned char frame[4];
|
||||
unsigned char zone;
|
||||
unsigned char idx;
|
||||
|
||||
zone = ( leds[led].value >> 8 );
|
||||
idx = ( leds[led].value & 0xFF );
|
||||
|
||||
frame[0] = idx;
|
||||
frame[1] = RGBGetRValue(colors[led]);
|
||||
frame[2] = RGBGetGValue(colors[led]);
|
||||
frame[3] = RGBGetBValue(colors[led]);
|
||||
|
||||
controller->SetDirect(zone, 1, frame);
|
||||
controller->Commit();
|
||||
}
|
||||
|
||||
void RGBController_LogitechGProKeyboard::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Direct mode does not send a mode packet |
|
||||
| Call UpdateLEDs to send direct packet |
|
||||
\*---------------------------------------------------------*/
|
||||
if(active_mode == 0xFFFF)
|
||||
{
|
||||
UpdateLEDs();
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char red = 0;
|
||||
unsigned char grn = 0;
|
||||
unsigned char blu = 0;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
red = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
grn = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
blu = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
}
|
||||
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].speed, red, grn, blu);
|
||||
}
|
||||
+35
-35
@@ -1,35 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGPro.h |
|
||||
| |
|
||||
| RGBController for Logitech G Pro keyboard |
|
||||
| |
|
||||
| sanchezzzs 20 Oct 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechGProKeyboardController.h"
|
||||
|
||||
class RGBController_LogitechGProKeyboard : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechGProKeyboard(LogitechGProKeyboardController* controller_ptr);
|
||||
~RGBController_LogitechGProKeyboard();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechGProKeyboardController* controller;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechGPro.h |
|
||||
| |
|
||||
| RGBController for Logitech G Pro keyboard |
|
||||
| |
|
||||
| sanchezzzs 20 Oct 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechGProKeyboardController.h"
|
||||
|
||||
class RGBController_LogitechGProKeyboard : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechGProKeyboard(LogitechGProKeyboardController* controller_ptr);
|
||||
~RGBController_LogitechGProKeyboard();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LogitechGProKeyboardController* controller;
|
||||
};
|
||||
+5709
-5709
File diff suppressed because it is too large.
Load diff
+874
-874
File diff suppressed because it is too large.
Load diff
+433
-433
@@ -1,433 +1,433 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechHIDPP20Controller_Linux.cpp |
|
||||
| |
|
||||
| Linux-specific path-migration and device-name lookup |
|
||||
| for the unified Logitech HID++ 2.0 controller. |
|
||||
| |
|
||||
| Uses sysfs (/sys/class/hidraw) to find the same |
|
||||
| physical device on a new hidraw path after a USB <-> |
|
||||
| wireless transition, and to read Centurion sub-device |
|
||||
| friendly names from HID_NAME uevent fields. |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <dirent.h>
|
||||
#include "LogitechHIDPP20Controller.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
#define LOG_TAG log_tag.c_str()
|
||||
|
||||
std::string LogitechHIDPP20Controller::GetCenturionSubDeviceName(const std::string& path)
|
||||
{
|
||||
/*--------------------------------------------------------*\
|
||||
| Centurion sub-device friendly name comes from sysfs |
|
||||
| HID_NAME=, same field Solaar reads. The `path` arg is a |
|
||||
| hidraw dev path like /dev/hidraw5; extract the hidrawN |
|
||||
| basename and read /sys/class/hidraw/<basename>/device/ |
|
||||
| uevent. |
|
||||
\*--------------------------------------------------------*/
|
||||
std::string sysfs_name;
|
||||
size_t pos = path.rfind("hidraw");
|
||||
|
||||
if(pos == std::string::npos)
|
||||
{
|
||||
return sysfs_name;
|
||||
}
|
||||
|
||||
std::string uevent_path = "/sys/class/hidraw/" + path.substr(pos) + "/device/uevent";
|
||||
FILE* f = fopen(uevent_path.c_str(), "r");
|
||||
|
||||
if(!f)
|
||||
{
|
||||
return sysfs_name;
|
||||
}
|
||||
|
||||
char line[256];
|
||||
|
||||
while(fgets(line, sizeof(line), f))
|
||||
{
|
||||
if(strncmp(line, "HID_NAME=", 9) == 0)
|
||||
{
|
||||
sysfs_name = line + 9;
|
||||
|
||||
while(!sysfs_name.empty() && (sysfs_name.back() == '\n' || sysfs_name.back() == '\r'))
|
||||
{
|
||||
sysfs_name.pop_back();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return sysfs_name;
|
||||
}
|
||||
|
||||
bool LogitechHIDPP20Controller::ScanForDevice(bool force)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Scan sysfs for a hidraw with matching unitId. Called by |
|
||||
| the power thread either periodically (normal reactive |
|
||||
| mode — only when device_online==false, USB/wireless |
|
||||
| transition or physical unplug) or on demand from the |
|
||||
| reader thread after a HID++1.0 Device Connection |
|
||||
| notification arrives (force=true, bypasses the online |
|
||||
| gate). Finds the device on its new connection path. |
|
||||
| |
|
||||
| Reactive-only: we never migrate while the current path |
|
||||
| still works. On devices like the G502 X PLUS that expose |
|
||||
| both a USB-direct hidraw AND a wireless-via-dongle hidraw |
|
||||
| simultaneously (when paired to the receiver and plugged |
|
||||
| in at the same time), eager migration would bounce us off |
|
||||
| a working path onto one the firmware has actively muted, |
|
||||
| breaking control. The device signals which path is |
|
||||
| active by returning errors/going silent on the inactive |
|
||||
| path — our reader thread picks that up as a hid_read |
|
||||
| failure and flips device_online=false, at which point the |
|
||||
| power thread calls this function to pick the new path. |
|
||||
| |
|
||||
| Linux implementation: walks /sys/class/hidraw and matches |
|
||||
| on HID_UNIQ. The Windows counterpart (same class method, |
|
||||
| different .cpp file) uses hid_enumerate + serial_number. |
|
||||
| |
|
||||
| Match criteria: |
|
||||
| - device_online == false (caller should already ensure) |
|
||||
| - HID_UNIQ matches our unitId |
|
||||
| - Logitech VID (046D) |
|
||||
| - HID++ interface (usage_page 0xFF00, usage 2) |
|
||||
| - Different from our current path (device moved) |
|
||||
\*---------------------------------------------------------*/
|
||||
if(caps.unit_id.empty() || caps.unit_id == "00000000")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Online guard: never migrate off a working path unless |
|
||||
| the caller explicitly forces a re-check. The normal |
|
||||
| periodic scan path stays gated on device_online==false |
|
||||
| so it's a no-op when everything is healthy. |
|
||||
| |
|
||||
| The reader thread bypasses this guard (force=true) after |
|
||||
| seeing a HID++1.0 Device Connection Status notification |
|
||||
| from the Lightspeed receiver, which fires BEFORE the |
|
||||
| firmware fully switches its data flow from wireless to |
|
||||
| USB. At that moment device_online is still true (the |
|
||||
| current path hasn't failed yet), but we want the scan to |
|
||||
| run so we can migrate to the new path proactively. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(!force && device_online.load())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Normalize our unitId to lowercase hex without dashes for |
|
||||
| comparison. Sysfs HID_UNIQ varies between drivers: |
|
||||
| - Lightspeed virtual: "0d-12-5d-47" (dashes) |
|
||||
| - USB direct: "0D125D47" (no dashes) |
|
||||
| We strip dashes and lowercase both sides for matching. |
|
||||
\*---------------------------------------------------------*/
|
||||
std::string target_norm;
|
||||
|
||||
for(char c : caps.unit_id)
|
||||
{
|
||||
if(c != '-')
|
||||
{
|
||||
target_norm += (char)tolower(c);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Read our current PID from sysfs. Only migrate to paths |
|
||||
| with a DIFFERENT PID — same PID means same receiver, |
|
||||
| just a different pairing slot (e.g., stale pairing). |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int current_pid = 0;
|
||||
{
|
||||
std::string cur_hidraw = location.substr(location.rfind('/') + 1);
|
||||
std::string cur_uevent = "/sys/class/hidraw/" + cur_hidraw + "/device/uevent";
|
||||
std::ifstream cur_file(cur_uevent);
|
||||
std::string line;
|
||||
|
||||
while(std::getline(cur_file, line))
|
||||
{
|
||||
if(line.compare(0, 7, "HID_ID=") == 0)
|
||||
{
|
||||
size_t lc = line.rfind(':');
|
||||
|
||||
if(lc != std::string::npos)
|
||||
{
|
||||
sscanf(line.c_str() + lc + 1, "%x", ¤t_pid);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------*\
|
||||
| Collect ALL sysfs hidraws with matching unit_id + Logitech |
|
||||
| VID + different PID. With multiple Lightspeed dongles in |
|
||||
| the system, several hidraws can share the same HID_UNIQ: |
|
||||
| one is the live virt-slot on the connected dongle, others |
|
||||
| are stale virt-slots on dongles where our device is not |
|
||||
| actually present. We have to probe each one to find out |
|
||||
| which slot is real — sysfs alone can't tell them apart. |
|
||||
\*----------------------------------------------------------*/
|
||||
struct Candidate
|
||||
{
|
||||
std::string dev_path;
|
||||
unsigned int pid;
|
||||
};
|
||||
|
||||
std::vector<Candidate> candidates;
|
||||
|
||||
DIR* dir = opendir("/sys/class/hidraw");
|
||||
|
||||
if(!dir)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
struct dirent* entry;
|
||||
|
||||
while((entry = readdir(dir)) != nullptr)
|
||||
{
|
||||
if(strncmp(entry->d_name, "hidraw", 6) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string uevent_path = "/sys/class/hidraw/" +
|
||||
std::string(entry->d_name) + "/device/uevent";
|
||||
std::ifstream uevent(uevent_path);
|
||||
|
||||
if(!uevent.is_open())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
std::string hid_uniq;
|
||||
std::string hid_id;
|
||||
|
||||
while(std::getline(uevent, line))
|
||||
{
|
||||
if(line.compare(0, 9, "HID_UNIQ=") == 0)
|
||||
{
|
||||
hid_uniq = line.substr(9);
|
||||
}
|
||||
else if(line.compare(0, 7, "HID_ID=") == 0)
|
||||
{
|
||||
hid_id = line.substr(7);
|
||||
}
|
||||
}
|
||||
|
||||
std::string uniq_norm;
|
||||
|
||||
for(char c : hid_uniq)
|
||||
{
|
||||
if(c != '-')
|
||||
{
|
||||
uniq_norm += (char)tolower(c);
|
||||
}
|
||||
}
|
||||
|
||||
if(uniq_norm != target_norm)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(hid_id.find("0000046D") == std::string::npos &&
|
||||
hid_id.find("0000046d") == std::string::npos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string dev_path = "/dev/" + std::string(entry->d_name);
|
||||
|
||||
if(dev_path == location)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t last_colon = hid_id.rfind(':');
|
||||
|
||||
if(last_colon == std::string::npos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned int pid = 0;
|
||||
sscanf(hid_id.c_str() + last_colon + 1, "%x", &pid);
|
||||
|
||||
if(pid == current_pid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
candidates.push_back({dev_path, pid});
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
if(candidates.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------*\
|
||||
| Probe each candidate before committing. Two-dongle systems |
|
||||
| can expose multiple sysfs hidraws with the same HID_UNIQ: |
|
||||
| one is the live slot, others are stale pairings that |
|
||||
| respond with short-format UNKNOWN_DEVICE errors. Issue a |
|
||||
| cheap IRoot GetFeature (feat 0x0001) to distinguish them. |
|
||||
| A live slot returns a long-form response with feat_idx=0 |
|
||||
| and feat_byte matching the sub-index we asked for. A stale |
|
||||
| slot returns r[10 xx 8F 00 00 08 ...] (short error, code |
|
||||
| 0x08 UNKNOWN_DEVICE). We accept the first candidate that |
|
||||
| passes; the overall pending_path_check retry loop will |
|
||||
| naturally re-probe all candidates on subsequent scans if |
|
||||
| none pass on the current pass (e.g., mid-transition). |
|
||||
\*----------------------------------------------------------*/
|
||||
std::string found_path;
|
||||
hid_device* found_dev = nullptr;
|
||||
|
||||
for(size_t c = 0; c < candidates.size(); c++)
|
||||
{
|
||||
const Candidate& cand = candidates[c];
|
||||
|
||||
LOG_DEBUG("%s Scan: migration candidate at %s (pid=0x%04X, current=%s pid=0x%04X)",
|
||||
LOG_TAG, cand.dev_path.c_str(), cand.pid,
|
||||
location.c_str(), current_pid);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Multi-dongle caveat: hid_enumerate returns entries |
|
||||
| for ALL dongles with this PID (046D:4099 Lightspeed |
|
||||
| can appear several times in a single machine). Match |
|
||||
| strictly on the sysfs candidate's dev_path so each |
|
||||
| candidate resolves to its OWN dongle's HID++ |
|
||||
| interface — not the first match we stumble across. |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_device_info* devs = hid_enumerate(0x046D, (uint16_t)cand.pid);
|
||||
std::string hidpp20_path;
|
||||
|
||||
for(hid_device_info* d = devs; d != nullptr; d = d->next)
|
||||
{
|
||||
LOG_TRACE("%s Scan: enumerate PID=0x%04X path=%s page=0x%04X usage=%d",
|
||||
LOG_TAG, cand.pid, d->path, d->usage_page, d->usage);
|
||||
|
||||
if(std::string(d->path) == cand.dev_path &&
|
||||
d->usage_page == 0xFF00 && d->usage == 2 &&
|
||||
std::string(d->path) != location)
|
||||
{
|
||||
hidpp20_path = d->path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hid_free_enumeration(devs);
|
||||
|
||||
if(hidpp20_path.empty())
|
||||
{
|
||||
LOG_DEBUG("%s Scan: %s no matching LogitechHID++ interface in enum",
|
||||
LOG_TAG, cand.dev_path.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
hid_device* test_dev = hid_open_path(hidpp20_path.c_str());
|
||||
|
||||
if(!test_dev)
|
||||
{
|
||||
LOG_DEBUG("%s Scan: %s failed to open", LOG_TAG, hidpp20_path.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*\
|
||||
| Probe: HID++2.0 IRoot GetFeature for feat 0x0001 |
|
||||
| (IFeatureSet). Wire: w[10 FF 0000 000100] |
|
||||
| - report_id 0x10 (short) |
|
||||
| - device_index 0xFF |
|
||||
| - feat_idx 0x00 (IRoot) |
|
||||
| - address 0x00 (func 0 GetFeature, sw_id 0) |
|
||||
| - payload 00 01 00 (feat_id 0x0001) |
|
||||
| |
|
||||
| A live device returns r[11 xx 00 0X ...] — long form, |
|
||||
| feat_idx 0x00, the address byte we sent back, and the |
|
||||
| feature index in the payload. |
|
||||
| A stale slot returns r[10 xx 8F 00 00 08 ...] — short |
|
||||
| error form. Reject anything that starts with 0x10. |
|
||||
\*------------------------------------------------------*/
|
||||
uint8_t probe[7] = {0x10, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00};
|
||||
uint8_t reply[20] = {};
|
||||
int write_rc = hid_write(test_dev, probe, sizeof(probe));
|
||||
bool probe_ok = false;
|
||||
|
||||
if(write_rc >= 0)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Drain up to ~100ms, looking for a long-form response |
|
||||
| matching our probe. Skip stray reports from unrelated |
|
||||
| firmware events that might be queued on the hidraw. |
|
||||
\*-----------------------------------------------------*/
|
||||
std::chrono::steady_clock::time_point deadline = std::chrono::steady_clock::now() +
|
||||
std::chrono::milliseconds(100);
|
||||
|
||||
while(std::chrono::steady_clock::now() < deadline)
|
||||
{
|
||||
int read_rc = hid_read_timeout(test_dev, reply, sizeof(reply), 50);
|
||||
|
||||
if(read_rc <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(reply[0] == 0x11 && reply[2] == 0x00 && reply[3] == 0x00)
|
||||
{
|
||||
probe_ok = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(reply[0] == 0x10 && reply[2] == 0x8F)
|
||||
{
|
||||
LOG_DEBUG("%s Scan: %s probe rejected — err=0x%02X (stale slot)",
|
||||
LOG_TAG, hidpp20_path.c_str(), reply[5]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!probe_ok)
|
||||
{
|
||||
hid_close(test_dev);
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG_DEBUG("%s Scan: %s probe accepted (feat_idx=0x%02X)",
|
||||
LOG_TAG, hidpp20_path.c_str(), reply[4]);
|
||||
|
||||
found_path = hidpp20_path;
|
||||
found_dev = test_dev;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!found_dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO("%s Device migrated: %s -> %s", LOG_TAG, location.c_str(), found_path.c_str());
|
||||
|
||||
SwapHIDHandle(found_dev, found_path);
|
||||
return true;
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechHIDPP20Controller_Linux.cpp |
|
||||
| |
|
||||
| Linux-specific path-migration and device-name lookup |
|
||||
| for the unified Logitech HID++ 2.0 controller. |
|
||||
| |
|
||||
| Uses sysfs (/sys/class/hidraw) to find the same |
|
||||
| physical device on a new hidraw path after a USB <-> |
|
||||
| wireless transition, and to read Centurion sub-device |
|
||||
| friendly names from HID_NAME uevent fields. |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <dirent.h>
|
||||
#include "LogitechHIDPP20Controller.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
#define LOG_TAG log_tag.c_str()
|
||||
|
||||
std::string LogitechHIDPP20Controller::GetCenturionSubDeviceName(const std::string& path)
|
||||
{
|
||||
/*--------------------------------------------------------*\
|
||||
| Centurion sub-device friendly name comes from sysfs |
|
||||
| HID_NAME=, same field Solaar reads. The `path` arg is a |
|
||||
| hidraw dev path like /dev/hidraw5; extract the hidrawN |
|
||||
| basename and read /sys/class/hidraw/<basename>/device/ |
|
||||
| uevent. |
|
||||
\*--------------------------------------------------------*/
|
||||
std::string sysfs_name;
|
||||
size_t pos = path.rfind("hidraw");
|
||||
|
||||
if(pos == std::string::npos)
|
||||
{
|
||||
return sysfs_name;
|
||||
}
|
||||
|
||||
std::string uevent_path = "/sys/class/hidraw/" + path.substr(pos) + "/device/uevent";
|
||||
FILE* f = fopen(uevent_path.c_str(), "r");
|
||||
|
||||
if(!f)
|
||||
{
|
||||
return sysfs_name;
|
||||
}
|
||||
|
||||
char line[256];
|
||||
|
||||
while(fgets(line, sizeof(line), f))
|
||||
{
|
||||
if(strncmp(line, "HID_NAME=", 9) == 0)
|
||||
{
|
||||
sysfs_name = line + 9;
|
||||
|
||||
while(!sysfs_name.empty() && (sysfs_name.back() == '\n' || sysfs_name.back() == '\r'))
|
||||
{
|
||||
sysfs_name.pop_back();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return sysfs_name;
|
||||
}
|
||||
|
||||
bool LogitechHIDPP20Controller::ScanForDevice(bool force)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Scan sysfs for a hidraw with matching unitId. Called by |
|
||||
| the power thread either periodically (normal reactive |
|
||||
| mode — only when device_online==false, USB/wireless |
|
||||
| transition or physical unplug) or on demand from the |
|
||||
| reader thread after a HID++1.0 Device Connection |
|
||||
| notification arrives (force=true, bypasses the online |
|
||||
| gate). Finds the device on its new connection path. |
|
||||
| |
|
||||
| Reactive-only: we never migrate while the current path |
|
||||
| still works. On devices like the G502 X PLUS that expose |
|
||||
| both a USB-direct hidraw AND a wireless-via-dongle hidraw |
|
||||
| simultaneously (when paired to the receiver and plugged |
|
||||
| in at the same time), eager migration would bounce us off |
|
||||
| a working path onto one the firmware has actively muted, |
|
||||
| breaking control. The device signals which path is |
|
||||
| active by returning errors/going silent on the inactive |
|
||||
| path — our reader thread picks that up as a hid_read |
|
||||
| failure and flips device_online=false, at which point the |
|
||||
| power thread calls this function to pick the new path. |
|
||||
| |
|
||||
| Linux implementation: walks /sys/class/hidraw and matches |
|
||||
| on HID_UNIQ. The Windows counterpart (same class method, |
|
||||
| different .cpp file) uses hid_enumerate + serial_number. |
|
||||
| |
|
||||
| Match criteria: |
|
||||
| - device_online == false (caller should already ensure) |
|
||||
| - HID_UNIQ matches our unitId |
|
||||
| - Logitech VID (046D) |
|
||||
| - HID++ interface (usage_page 0xFF00, usage 2) |
|
||||
| - Different from our current path (device moved) |
|
||||
\*---------------------------------------------------------*/
|
||||
if(caps.unit_id.empty() || caps.unit_id == "00000000")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Online guard: never migrate off a working path unless |
|
||||
| the caller explicitly forces a re-check. The normal |
|
||||
| periodic scan path stays gated on device_online==false |
|
||||
| so it's a no-op when everything is healthy. |
|
||||
| |
|
||||
| The reader thread bypasses this guard (force=true) after |
|
||||
| seeing a HID++1.0 Device Connection Status notification |
|
||||
| from the Lightspeed receiver, which fires BEFORE the |
|
||||
| firmware fully switches its data flow from wireless to |
|
||||
| USB. At that moment device_online is still true (the |
|
||||
| current path hasn't failed yet), but we want the scan to |
|
||||
| run so we can migrate to the new path proactively. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(!force && device_online.load())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Normalize our unitId to lowercase hex without dashes for |
|
||||
| comparison. Sysfs HID_UNIQ varies between drivers: |
|
||||
| - Lightspeed virtual: "0d-12-5d-47" (dashes) |
|
||||
| - USB direct: "0D125D47" (no dashes) |
|
||||
| We strip dashes and lowercase both sides for matching. |
|
||||
\*---------------------------------------------------------*/
|
||||
std::string target_norm;
|
||||
|
||||
for(char c : caps.unit_id)
|
||||
{
|
||||
if(c != '-')
|
||||
{
|
||||
target_norm += (char)tolower(c);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Read our current PID from sysfs. Only migrate to paths |
|
||||
| with a DIFFERENT PID — same PID means same receiver, |
|
||||
| just a different pairing slot (e.g., stale pairing). |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int current_pid = 0;
|
||||
{
|
||||
std::string cur_hidraw = location.substr(location.rfind('/') + 1);
|
||||
std::string cur_uevent = "/sys/class/hidraw/" + cur_hidraw + "/device/uevent";
|
||||
std::ifstream cur_file(cur_uevent);
|
||||
std::string line;
|
||||
|
||||
while(std::getline(cur_file, line))
|
||||
{
|
||||
if(line.compare(0, 7, "HID_ID=") == 0)
|
||||
{
|
||||
size_t lc = line.rfind(':');
|
||||
|
||||
if(lc != std::string::npos)
|
||||
{
|
||||
sscanf(line.c_str() + lc + 1, "%x", ¤t_pid);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------*\
|
||||
| Collect ALL sysfs hidraws with matching unit_id + Logitech |
|
||||
| VID + different PID. With multiple Lightspeed dongles in |
|
||||
| the system, several hidraws can share the same HID_UNIQ: |
|
||||
| one is the live virt-slot on the connected dongle, others |
|
||||
| are stale virt-slots on dongles where our device is not |
|
||||
| actually present. We have to probe each one to find out |
|
||||
| which slot is real — sysfs alone can't tell them apart. |
|
||||
\*----------------------------------------------------------*/
|
||||
struct Candidate
|
||||
{
|
||||
std::string dev_path;
|
||||
unsigned int pid;
|
||||
};
|
||||
|
||||
std::vector<Candidate> candidates;
|
||||
|
||||
DIR* dir = opendir("/sys/class/hidraw");
|
||||
|
||||
if(!dir)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
struct dirent* entry;
|
||||
|
||||
while((entry = readdir(dir)) != nullptr)
|
||||
{
|
||||
if(strncmp(entry->d_name, "hidraw", 6) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string uevent_path = "/sys/class/hidraw/" +
|
||||
std::string(entry->d_name) + "/device/uevent";
|
||||
std::ifstream uevent(uevent_path);
|
||||
|
||||
if(!uevent.is_open())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
std::string hid_uniq;
|
||||
std::string hid_id;
|
||||
|
||||
while(std::getline(uevent, line))
|
||||
{
|
||||
if(line.compare(0, 9, "HID_UNIQ=") == 0)
|
||||
{
|
||||
hid_uniq = line.substr(9);
|
||||
}
|
||||
else if(line.compare(0, 7, "HID_ID=") == 0)
|
||||
{
|
||||
hid_id = line.substr(7);
|
||||
}
|
||||
}
|
||||
|
||||
std::string uniq_norm;
|
||||
|
||||
for(char c : hid_uniq)
|
||||
{
|
||||
if(c != '-')
|
||||
{
|
||||
uniq_norm += (char)tolower(c);
|
||||
}
|
||||
}
|
||||
|
||||
if(uniq_norm != target_norm)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(hid_id.find("0000046D") == std::string::npos &&
|
||||
hid_id.find("0000046d") == std::string::npos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string dev_path = "/dev/" + std::string(entry->d_name);
|
||||
|
||||
if(dev_path == location)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t last_colon = hid_id.rfind(':');
|
||||
|
||||
if(last_colon == std::string::npos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned int pid = 0;
|
||||
sscanf(hid_id.c_str() + last_colon + 1, "%x", &pid);
|
||||
|
||||
if(pid == current_pid)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
candidates.push_back({dev_path, pid});
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
if(candidates.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------*\
|
||||
| Probe each candidate before committing. Two-dongle systems |
|
||||
| can expose multiple sysfs hidraws with the same HID_UNIQ: |
|
||||
| one is the live slot, others are stale pairings that |
|
||||
| respond with short-format UNKNOWN_DEVICE errors. Issue a |
|
||||
| cheap IRoot GetFeature (feat 0x0001) to distinguish them. |
|
||||
| A live slot returns a long-form response with feat_idx=0 |
|
||||
| and feat_byte matching the sub-index we asked for. A stale |
|
||||
| slot returns r[10 xx 8F 00 00 08 ...] (short error, code |
|
||||
| 0x08 UNKNOWN_DEVICE). We accept the first candidate that |
|
||||
| passes; the overall pending_path_check retry loop will |
|
||||
| naturally re-probe all candidates on subsequent scans if |
|
||||
| none pass on the current pass (e.g., mid-transition). |
|
||||
\*----------------------------------------------------------*/
|
||||
std::string found_path;
|
||||
hid_device* found_dev = nullptr;
|
||||
|
||||
for(size_t c = 0; c < candidates.size(); c++)
|
||||
{
|
||||
const Candidate& cand = candidates[c];
|
||||
|
||||
LOG_DEBUG("%s Scan: migration candidate at %s (pid=0x%04X, current=%s pid=0x%04X)",
|
||||
LOG_TAG, cand.dev_path.c_str(), cand.pid,
|
||||
location.c_str(), current_pid);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Multi-dongle caveat: hid_enumerate returns entries |
|
||||
| for ALL dongles with this PID (046D:4099 Lightspeed |
|
||||
| can appear several times in a single machine). Match |
|
||||
| strictly on the sysfs candidate's dev_path so each |
|
||||
| candidate resolves to its OWN dongle's HID++ |
|
||||
| interface — not the first match we stumble across. |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_device_info* devs = hid_enumerate(0x046D, (uint16_t)cand.pid);
|
||||
std::string hidpp20_path;
|
||||
|
||||
for(hid_device_info* d = devs; d != nullptr; d = d->next)
|
||||
{
|
||||
LOG_TRACE("%s Scan: enumerate PID=0x%04X path=%s page=0x%04X usage=%d",
|
||||
LOG_TAG, cand.pid, d->path, d->usage_page, d->usage);
|
||||
|
||||
if(std::string(d->path) == cand.dev_path &&
|
||||
d->usage_page == 0xFF00 && d->usage == 2 &&
|
||||
std::string(d->path) != location)
|
||||
{
|
||||
hidpp20_path = d->path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hid_free_enumeration(devs);
|
||||
|
||||
if(hidpp20_path.empty())
|
||||
{
|
||||
LOG_DEBUG("%s Scan: %s no matching LogitechHID++ interface in enum",
|
||||
LOG_TAG, cand.dev_path.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
hid_device* test_dev = hid_open_path(hidpp20_path.c_str());
|
||||
|
||||
if(!test_dev)
|
||||
{
|
||||
LOG_DEBUG("%s Scan: %s failed to open", LOG_TAG, hidpp20_path.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*\
|
||||
| Probe: HID++2.0 IRoot GetFeature for feat 0x0001 |
|
||||
| (IFeatureSet). Wire: w[10 FF 0000 000100] |
|
||||
| - report_id 0x10 (short) |
|
||||
| - device_index 0xFF |
|
||||
| - feat_idx 0x00 (IRoot) |
|
||||
| - address 0x00 (func 0 GetFeature, sw_id 0) |
|
||||
| - payload 00 01 00 (feat_id 0x0001) |
|
||||
| |
|
||||
| A live device returns r[11 xx 00 0X ...] — long form, |
|
||||
| feat_idx 0x00, the address byte we sent back, and the |
|
||||
| feature index in the payload. |
|
||||
| A stale slot returns r[10 xx 8F 00 00 08 ...] — short |
|
||||
| error form. Reject anything that starts with 0x10. |
|
||||
\*------------------------------------------------------*/
|
||||
uint8_t probe[7] = {0x10, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00};
|
||||
uint8_t reply[20] = {};
|
||||
int write_rc = hid_write(test_dev, probe, sizeof(probe));
|
||||
bool probe_ok = false;
|
||||
|
||||
if(write_rc >= 0)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Drain up to ~100ms, looking for a long-form response |
|
||||
| matching our probe. Skip stray reports from unrelated |
|
||||
| firmware events that might be queued on the hidraw. |
|
||||
\*-----------------------------------------------------*/
|
||||
std::chrono::steady_clock::time_point deadline = std::chrono::steady_clock::now() +
|
||||
std::chrono::milliseconds(100);
|
||||
|
||||
while(std::chrono::steady_clock::now() < deadline)
|
||||
{
|
||||
int read_rc = hid_read_timeout(test_dev, reply, sizeof(reply), 50);
|
||||
|
||||
if(read_rc <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(reply[0] == 0x11 && reply[2] == 0x00 && reply[3] == 0x00)
|
||||
{
|
||||
probe_ok = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(reply[0] == 0x10 && reply[2] == 0x8F)
|
||||
{
|
||||
LOG_DEBUG("%s Scan: %s probe rejected — err=0x%02X (stale slot)",
|
||||
LOG_TAG, hidpp20_path.c_str(), reply[5]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!probe_ok)
|
||||
{
|
||||
hid_close(test_dev);
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG_DEBUG("%s Scan: %s probe accepted (feat_idx=0x%02X)",
|
||||
LOG_TAG, hidpp20_path.c_str(), reply[4]);
|
||||
|
||||
found_path = hidpp20_path;
|
||||
found_dev = test_dev;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!found_dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO("%s Device migrated: %s -> %s", LOG_TAG, location.c_str(), found_path.c_str());
|
||||
|
||||
SwapHIDHandle(found_dev, found_path);
|
||||
return true;
|
||||
}
|
||||
+302
-302
@@ -1,302 +1,302 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechHIDPP20Controller_Windows_MacOS.cpp |
|
||||
| |
|
||||
| Path-migration and device-name lookup for the unified |
|
||||
| Logitech HID++ 2.0 controller on Windows and macOS. |
|
||||
| |
|
||||
| Uses hidapi's hid_enumerate + hid_device_info fields |
|
||||
| (serial_number, product_string, product_id, usage_page) |
|
||||
| on platforms with no /sys/class/hidraw equivalent. |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "LogitechHIDPP20Controller.h"
|
||||
#include "LogManager.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
#define LOG_TAG log_tag.c_str()
|
||||
|
||||
std::string LogitechHIDPP20Controller::GetCenturionSubDeviceName(const std::string& path)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| On Windows, hidapi's hid_device_info carries a |
|
||||
| product_string field (wchar_t*). Enumerate all Logitech |
|
||||
| devices and find the one whose path matches `path`. |
|
||||
| |
|
||||
| Caveat: Windows hidapi typically returns the parent |
|
||||
| product string on every (interface, usage_page, usage) |
|
||||
| entry that maps to the same USB device, so Centurion |
|
||||
| sub-devices may share a name with the parent dongle. |
|
||||
| That's a less specific name than Linux's HID_NAME, but |
|
||||
| still better than "Logitech Centurion Device". |
|
||||
\*---------------------------------------------------------*/
|
||||
std::string friendly;
|
||||
|
||||
hid_device_info* devs = hid_enumerate(0x046D, 0x0000);
|
||||
|
||||
for(hid_device_info* d = devs; d != nullptr; d = d->next)
|
||||
{
|
||||
if(d->path == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(std::string(d->path) != path)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
friendly = StringUtils::wchar_to_string(d->product_string);
|
||||
break;
|
||||
}
|
||||
|
||||
hid_free_enumeration(devs);
|
||||
return friendly;
|
||||
}
|
||||
|
||||
bool LogitechHIDPP20Controller::ScanForDevice(bool force)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Scan hidapi for a Logitech device with matching unitId. |
|
||||
| Called by the power thread either periodically (normal |
|
||||
| reactive mode — only when device_online==false, USB/ |
|
||||
| wireless transition or physical unplug) or on demand |
|
||||
| from the reader thread after a HID++1.0 Device |
|
||||
| Connection notification arrives (force=true, bypasses |
|
||||
| the online gate). Finds the device on its new |
|
||||
| connection path. |
|
||||
| |
|
||||
| Reactive-only: we never migrate while the current path |
|
||||
| still works (same rationale as Linux — see the Linux |
|
||||
| companion file for the full explanation). |
|
||||
| |
|
||||
| Windows implementation: walks hid_enumerate(046D, *) and |
|
||||
| matches on hid_device_info::serial_number, which for |
|
||||
| Logitech devices generally corresponds to the same |
|
||||
| stable identity as the HID++-reported unit_id. If |
|
||||
| serial_number matching yields nothing (hidapi may not |
|
||||
| populate it for some Logitech devices on Windows), we |
|
||||
| fall through to IRoot probing every candidate on the |
|
||||
| matching usage_page/usage so we can still find the |
|
||||
| device albeit more slowly. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(caps.unit_id.empty() || caps.unit_id == "00000000")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!force && device_online.load())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string target_norm = StringUtils::normalize_hex_id(caps.unit_id);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Candidate = {path, pid, has_serial_match}. Serial matches |
|
||||
| sort first so we try the cheapest/most-likely candidate. |
|
||||
\*---------------------------------------------------------*/
|
||||
struct Candidate
|
||||
{
|
||||
std::string dev_path;
|
||||
unsigned int pid;
|
||||
bool serial_match;
|
||||
};
|
||||
|
||||
std::vector<Candidate> candidates;
|
||||
unsigned int current_pid = 0;
|
||||
|
||||
hid_device_info* devs = hid_enumerate(0x046D, 0x0000);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| First pass: find the entry matching our current path and |
|
||||
| record its product_id so we can skip same-PID candidates. |
|
||||
\*---------------------------------------------------------*/
|
||||
for(hid_device_info* d = devs; d != nullptr; d = d->next)
|
||||
{
|
||||
if(d->path != nullptr && std::string(d->path) == location)
|
||||
{
|
||||
current_pid = d->product_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Second pass: collect candidates that (a) aren't our |
|
||||
| current path, (b) speak the HID++ interface, and (c) have |
|
||||
| a plausible identity match — either the serial_number |
|
||||
| matches our unit_id, or at minimum their PID differs from |
|
||||
| ours so they can't be another slot on the same dongle. |
|
||||
\*---------------------------------------------------------*/
|
||||
for(hid_device_info* d = devs; d != nullptr; d = d->next)
|
||||
{
|
||||
if(d->path == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(std::string(d->path) == location)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Only HID++ interface (usage_page 0xFF00, usage 2). |
|
||||
| Note: on Windows hidapi may or may not populate |
|
||||
| usage / usage_page consistently. If either is zero, |
|
||||
| fall through — we'll probe unconditionally in that |
|
||||
| case rather than dropping a potential candidate. |
|
||||
\*-----------------------------------------------------*/
|
||||
bool usage_known = (d->usage_page != 0 || d->usage != 0);
|
||||
|
||||
if(usage_known && (d->usage_page != 0xFF00 || d->usage != 2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Compare serial_number (wchar_t*) against our unit_id. |
|
||||
| Normalize both and do an exact-match comparison. |
|
||||
| Empty/missing serial is allowed — falls through as a |
|
||||
| serial_match=false candidate so the probe path can |
|
||||
| still find it via a different-PID filter. |
|
||||
\*-----------------------------------------------------*/
|
||||
bool serial_match = false;
|
||||
|
||||
if(d->serial_number != nullptr && d->serial_number[0] != L'\0')
|
||||
{
|
||||
std::string sn = StringUtils::wchar_to_string(d->serial_number);
|
||||
std::string sn_norm = StringUtils::normalize_hex_id(sn);
|
||||
|
||||
if(!sn_norm.empty() && sn_norm == target_norm)
|
||||
{
|
||||
serial_match = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| If we have no serial match AND this path shares the |
|
||||
| current PID, skip. Same PID with no identity evidence |
|
||||
| is probably a sibling slot on the same dongle, not a |
|
||||
| valid migration target. |
|
||||
\*-----------------------------------------------------*/
|
||||
if(!serial_match && d->product_id == current_pid && current_pid != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Candidate c;
|
||||
c.dev_path = d->path;
|
||||
c.pid = d->product_id;
|
||||
c.serial_match = serial_match;
|
||||
candidates.push_back(c);
|
||||
}
|
||||
|
||||
hid_free_enumeration(devs);
|
||||
|
||||
if(candidates.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Sort so serial-matched candidates get probed first. |
|
||||
\*---------------------------------------------------------*/
|
||||
std::stable_sort(candidates.begin(), candidates.end(),
|
||||
[](const Candidate& a, const Candidate& b)
|
||||
{
|
||||
return a.serial_match && !b.serial_match;
|
||||
});
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Probe each candidate with IRoot GetFeature feat 0x0001. |
|
||||
| A live slot returns a long-form (0x11) response; a stale |
|
||||
| slot returns a short-form (0x10) error. See the Linux |
|
||||
| companion file for the wire-level explanation. |
|
||||
\*---------------------------------------------------------*/
|
||||
std::string found_path;
|
||||
hid_device* found_dev = nullptr;
|
||||
|
||||
for(size_t c = 0; c < candidates.size(); c++)
|
||||
{
|
||||
const Candidate& cand = candidates[c];
|
||||
|
||||
LOG_DEBUG("%s Scan: migration candidate at %s (pid=0x%04X, serial_match=%d)",
|
||||
LOG_TAG, cand.dev_path.c_str(), cand.pid,
|
||||
cand.serial_match ? 1 : 0);
|
||||
|
||||
hid_device* test_dev = hid_open_path(cand.dev_path.c_str());
|
||||
|
||||
if(!test_dev)
|
||||
{
|
||||
LOG_DEBUG("%s Scan: %s failed to open",
|
||||
LOG_TAG, cand.dev_path.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
uint8_t probe[7] = {0x10, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00};
|
||||
uint8_t reply[20] = {};
|
||||
int write_rc = hid_write(test_dev, probe, sizeof(probe));
|
||||
bool probe_ok = false;
|
||||
|
||||
if(write_rc >= 0)
|
||||
{
|
||||
std::chrono::steady_clock::time_point deadline = std::chrono::steady_clock::now() +
|
||||
std::chrono::milliseconds(100);
|
||||
|
||||
while(std::chrono::steady_clock::now() < deadline)
|
||||
{
|
||||
int read_rc = hid_read_timeout(test_dev, reply, sizeof(reply), 50);
|
||||
|
||||
if(read_rc <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(reply[0] == 0x11 && reply[2] == 0x00 && reply[3] == 0x00)
|
||||
{
|
||||
probe_ok = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(reply[0] == 0x10 && reply[2] == 0x8F)
|
||||
{
|
||||
LOG_DEBUG("%s Scan: %s probe rejected — err=0x%02X (stale slot)",
|
||||
LOG_TAG, cand.dev_path.c_str(), reply[5]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!probe_ok)
|
||||
{
|
||||
hid_close(test_dev);
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG_DEBUG("%s Scan: %s probe accepted (feat_idx=0x%02X)",
|
||||
LOG_TAG, cand.dev_path.c_str(), reply[4]);
|
||||
|
||||
found_path = cand.dev_path;
|
||||
found_dev = test_dev;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!found_dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO("%s Device migrated: %s -> %s",
|
||||
LOG_TAG, location.c_str(), found_path.c_str());
|
||||
|
||||
SwapHIDHandle(found_dev, found_path);
|
||||
return true;
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechHIDPP20Controller_Windows_MacOS.cpp |
|
||||
| |
|
||||
| Path-migration and device-name lookup for the unified |
|
||||
| Logitech HID++ 2.0 controller on Windows and macOS. |
|
||||
| |
|
||||
| Uses hidapi's hid_enumerate + hid_device_info fields |
|
||||
| (serial_number, product_string, product_id, usage_page) |
|
||||
| on platforms with no /sys/class/hidraw equivalent. |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "LogitechHIDPP20Controller.h"
|
||||
#include "LogManager.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
#define LOG_TAG log_tag.c_str()
|
||||
|
||||
std::string LogitechHIDPP20Controller::GetCenturionSubDeviceName(const std::string& path)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| On Windows, hidapi's hid_device_info carries a |
|
||||
| product_string field (wchar_t*). Enumerate all Logitech |
|
||||
| devices and find the one whose path matches `path`. |
|
||||
| |
|
||||
| Caveat: Windows hidapi typically returns the parent |
|
||||
| product string on every (interface, usage_page, usage) |
|
||||
| entry that maps to the same USB device, so Centurion |
|
||||
| sub-devices may share a name with the parent dongle. |
|
||||
| That's a less specific name than Linux's HID_NAME, but |
|
||||
| still better than "Logitech Centurion Device". |
|
||||
\*---------------------------------------------------------*/
|
||||
std::string friendly;
|
||||
|
||||
hid_device_info* devs = hid_enumerate(0x046D, 0x0000);
|
||||
|
||||
for(hid_device_info* d = devs; d != nullptr; d = d->next)
|
||||
{
|
||||
if(d->path == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(std::string(d->path) != path)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
friendly = StringUtils::wchar_to_string(d->product_string);
|
||||
break;
|
||||
}
|
||||
|
||||
hid_free_enumeration(devs);
|
||||
return friendly;
|
||||
}
|
||||
|
||||
bool LogitechHIDPP20Controller::ScanForDevice(bool force)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Scan hidapi for a Logitech device with matching unitId. |
|
||||
| Called by the power thread either periodically (normal |
|
||||
| reactive mode — only when device_online==false, USB/ |
|
||||
| wireless transition or physical unplug) or on demand |
|
||||
| from the reader thread after a HID++1.0 Device |
|
||||
| Connection notification arrives (force=true, bypasses |
|
||||
| the online gate). Finds the device on its new |
|
||||
| connection path. |
|
||||
| |
|
||||
| Reactive-only: we never migrate while the current path |
|
||||
| still works (same rationale as Linux — see the Linux |
|
||||
| companion file for the full explanation). |
|
||||
| |
|
||||
| Windows implementation: walks hid_enumerate(046D, *) and |
|
||||
| matches on hid_device_info::serial_number, which for |
|
||||
| Logitech devices generally corresponds to the same |
|
||||
| stable identity as the HID++-reported unit_id. If |
|
||||
| serial_number matching yields nothing (hidapi may not |
|
||||
| populate it for some Logitech devices on Windows), we |
|
||||
| fall through to IRoot probing every candidate on the |
|
||||
| matching usage_page/usage so we can still find the |
|
||||
| device albeit more slowly. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(caps.unit_id.empty() || caps.unit_id == "00000000")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!force && device_online.load())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string target_norm = StringUtils::normalize_hex_id(caps.unit_id);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Candidate = {path, pid, has_serial_match}. Serial matches |
|
||||
| sort first so we try the cheapest/most-likely candidate. |
|
||||
\*---------------------------------------------------------*/
|
||||
struct Candidate
|
||||
{
|
||||
std::string dev_path;
|
||||
unsigned int pid;
|
||||
bool serial_match;
|
||||
};
|
||||
|
||||
std::vector<Candidate> candidates;
|
||||
unsigned int current_pid = 0;
|
||||
|
||||
hid_device_info* devs = hid_enumerate(0x046D, 0x0000);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| First pass: find the entry matching our current path and |
|
||||
| record its product_id so we can skip same-PID candidates. |
|
||||
\*---------------------------------------------------------*/
|
||||
for(hid_device_info* d = devs; d != nullptr; d = d->next)
|
||||
{
|
||||
if(d->path != nullptr && std::string(d->path) == location)
|
||||
{
|
||||
current_pid = d->product_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Second pass: collect candidates that (a) aren't our |
|
||||
| current path, (b) speak the HID++ interface, and (c) have |
|
||||
| a plausible identity match — either the serial_number |
|
||||
| matches our unit_id, or at minimum their PID differs from |
|
||||
| ours so they can't be another slot on the same dongle. |
|
||||
\*---------------------------------------------------------*/
|
||||
for(hid_device_info* d = devs; d != nullptr; d = d->next)
|
||||
{
|
||||
if(d->path == nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(std::string(d->path) == location)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Only HID++ interface (usage_page 0xFF00, usage 2). |
|
||||
| Note: on Windows hidapi may or may not populate |
|
||||
| usage / usage_page consistently. If either is zero, |
|
||||
| fall through — we'll probe unconditionally in that |
|
||||
| case rather than dropping a potential candidate. |
|
||||
\*-----------------------------------------------------*/
|
||||
bool usage_known = (d->usage_page != 0 || d->usage != 0);
|
||||
|
||||
if(usage_known && (d->usage_page != 0xFF00 || d->usage != 2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Compare serial_number (wchar_t*) against our unit_id. |
|
||||
| Normalize both and do an exact-match comparison. |
|
||||
| Empty/missing serial is allowed — falls through as a |
|
||||
| serial_match=false candidate so the probe path can |
|
||||
| still find it via a different-PID filter. |
|
||||
\*-----------------------------------------------------*/
|
||||
bool serial_match = false;
|
||||
|
||||
if(d->serial_number != nullptr && d->serial_number[0] != L'\0')
|
||||
{
|
||||
std::string sn = StringUtils::wchar_to_string(d->serial_number);
|
||||
std::string sn_norm = StringUtils::normalize_hex_id(sn);
|
||||
|
||||
if(!sn_norm.empty() && sn_norm == target_norm)
|
||||
{
|
||||
serial_match = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| If we have no serial match AND this path shares the |
|
||||
| current PID, skip. Same PID with no identity evidence |
|
||||
| is probably a sibling slot on the same dongle, not a |
|
||||
| valid migration target. |
|
||||
\*-----------------------------------------------------*/
|
||||
if(!serial_match && d->product_id == current_pid && current_pid != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Candidate c;
|
||||
c.dev_path = d->path;
|
||||
c.pid = d->product_id;
|
||||
c.serial_match = serial_match;
|
||||
candidates.push_back(c);
|
||||
}
|
||||
|
||||
hid_free_enumeration(devs);
|
||||
|
||||
if(candidates.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Sort so serial-matched candidates get probed first. |
|
||||
\*---------------------------------------------------------*/
|
||||
std::stable_sort(candidates.begin(), candidates.end(),
|
||||
[](const Candidate& a, const Candidate& b)
|
||||
{
|
||||
return a.serial_match && !b.serial_match;
|
||||
});
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Probe each candidate with IRoot GetFeature feat 0x0001. |
|
||||
| A live slot returns a long-form (0x11) response; a stale |
|
||||
| slot returns a short-form (0x10) error. See the Linux |
|
||||
| companion file for the wire-level explanation. |
|
||||
\*---------------------------------------------------------*/
|
||||
std::string found_path;
|
||||
hid_device* found_dev = nullptr;
|
||||
|
||||
for(size_t c = 0; c < candidates.size(); c++)
|
||||
{
|
||||
const Candidate& cand = candidates[c];
|
||||
|
||||
LOG_DEBUG("%s Scan: migration candidate at %s (pid=0x%04X, serial_match=%d)",
|
||||
LOG_TAG, cand.dev_path.c_str(), cand.pid,
|
||||
cand.serial_match ? 1 : 0);
|
||||
|
||||
hid_device* test_dev = hid_open_path(cand.dev_path.c_str());
|
||||
|
||||
if(!test_dev)
|
||||
{
|
||||
LOG_DEBUG("%s Scan: %s failed to open",
|
||||
LOG_TAG, cand.dev_path.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
uint8_t probe[7] = {0x10, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00};
|
||||
uint8_t reply[20] = {};
|
||||
int write_rc = hid_write(test_dev, probe, sizeof(probe));
|
||||
bool probe_ok = false;
|
||||
|
||||
if(write_rc >= 0)
|
||||
{
|
||||
std::chrono::steady_clock::time_point deadline = std::chrono::steady_clock::now() +
|
||||
std::chrono::milliseconds(100);
|
||||
|
||||
while(std::chrono::steady_clock::now() < deadline)
|
||||
{
|
||||
int read_rc = hid_read_timeout(test_dev, reply, sizeof(reply), 50);
|
||||
|
||||
if(read_rc <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(reply[0] == 0x11 && reply[2] == 0x00 && reply[3] == 0x00)
|
||||
{
|
||||
probe_ok = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(reply[0] == 0x10 && reply[2] == 0x8F)
|
||||
{
|
||||
LOG_DEBUG("%s Scan: %s probe rejected — err=0x%02X (stale slot)",
|
||||
LOG_TAG, cand.dev_path.c_str(), reply[5]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!probe_ok)
|
||||
{
|
||||
hid_close(test_dev);
|
||||
continue;
|
||||
}
|
||||
|
||||
LOG_DEBUG("%s Scan: %s probe accepted (feat_idx=0x%02X)",
|
||||
LOG_TAG, cand.dev_path.c_str(), reply[4]);
|
||||
|
||||
found_path = cand.dev_path;
|
||||
found_dev = test_dev;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!found_dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO("%s Device migrated: %s -> %s",
|
||||
LOG_TAG, location.c_str(), found_path.c_str());
|
||||
|
||||
SwapHIDHandle(found_dev, found_path);
|
||||
return true;
|
||||
}
|
||||
+146
-146
@@ -1,146 +1,146 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechHIDPP20IdleSettings.cpp |
|
||||
| |
|
||||
| Host-side idle/dim/sleep settings storage helper for |
|
||||
| Logitech HID++ 2.0 devices. Loads the configuration |
|
||||
| block from SettingsManager JSON, caches it, and writes |
|
||||
| changes back through SettingsManager::SetSettings(). |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "LogitechHIDPP20IdleSettings.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "SettingsManager.h"
|
||||
|
||||
static const char* SETTINGS_KEY = "LogitechHIDPP20IdleSettings";
|
||||
|
||||
LogitechHIDPP20IdleSettings* LogitechHIDPP20IdleSettings::instance()
|
||||
{
|
||||
static LogitechHIDPP20IdleSettings inst;
|
||||
return &inst;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Minimum idle / sleep values the controller will honor. |
|
||||
| Matches what Logitech firmware typically clamps to on |
|
||||
| HID++ 2.0 devices, and guarantees the skip-dim path's |
|
||||
| sleep_delay math always produces a positive window. |
|
||||
\*---------------------------------------------------------*/
|
||||
static const int MIN_IDLE_S = 15;
|
||||
static const int MIN_SLEEP_S = 45;
|
||||
static const int MIN_DIM_WINDOW = 30; // sleep must exceed idle by at least this
|
||||
|
||||
static void ClampProfile(LogitechHIDPP20IdleProfile& p)
|
||||
{
|
||||
if(p.dim_brightness < 0) p.dim_brightness = 0;
|
||||
if(p.dim_brightness > 100) p.dim_brightness = 100;
|
||||
|
||||
if(p.idle_timeout_s < MIN_IDLE_S)
|
||||
{
|
||||
p.idle_timeout_s = MIN_IDLE_S;
|
||||
}
|
||||
|
||||
if(p.sleep_timeout_s < MIN_SLEEP_S)
|
||||
{
|
||||
p.sleep_timeout_s = MIN_SLEEP_S;
|
||||
}
|
||||
|
||||
if(p.sleep_timeout_s < p.idle_timeout_s + MIN_DIM_WINDOW)
|
||||
{
|
||||
p.sleep_timeout_s = p.idle_timeout_s + MIN_DIM_WINDOW;
|
||||
}
|
||||
}
|
||||
|
||||
static LogitechHIDPP20IdleProfile ProfileFromJson(const json& j)
|
||||
{
|
||||
LogitechHIDPP20IdleProfile p;
|
||||
|
||||
if(j.contains("dim_when_idle")) p.dim_when_idle = j["dim_when_idle"];
|
||||
if(j.contains("dim_brightness")) p.dim_brightness = j["dim_brightness"];
|
||||
if(j.contains("idle_timeout_s")) p.idle_timeout_s = j["idle_timeout_s"];
|
||||
if(j.contains("allow_sleep")) p.allow_sleep = j["allow_sleep"];
|
||||
if(j.contains("sleep_timeout_s")) p.sleep_timeout_s = j["sleep_timeout_s"];
|
||||
|
||||
ClampProfile(p);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static json ProfileToJson(const LogitechHIDPP20IdleProfile& p)
|
||||
{
|
||||
json j;
|
||||
|
||||
j["dim_when_idle"] = p.dim_when_idle;
|
||||
j["dim_brightness"] = p.dim_brightness;
|
||||
j["idle_timeout_s"] = p.idle_timeout_s;
|
||||
j["allow_sleep"] = p.allow_sleep;
|
||||
j["sleep_timeout_s"] = p.sleep_timeout_s;
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
void LogitechHIDPP20IdleSettings::load()
|
||||
{
|
||||
json settings = ResourceManager::get()->GetSettingsManager()->GetSettings(SETTINGS_KEY);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Empty / missing key means the plugin is not in use. |
|
||||
| Reset both profiles to defaults with configured=false so |
|
||||
| the controller defers to firmware. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(!settings.is_object() || settings.empty())
|
||||
{
|
||||
configured = false;
|
||||
on_battery = LogitechHIDPP20IdleProfile{};
|
||||
plugged_in = LogitechHIDPP20IdleProfile{};
|
||||
return;
|
||||
}
|
||||
|
||||
configured = true;
|
||||
|
||||
if(settings.contains("on_battery"))
|
||||
{
|
||||
on_battery = ProfileFromJson(settings["on_battery"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
on_battery = LogitechHIDPP20IdleProfile{};
|
||||
}
|
||||
|
||||
if(settings.contains("plugged_in"))
|
||||
{
|
||||
plugged_in = ProfileFromJson(settings["plugged_in"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
plugged_in = LogitechHIDPP20IdleProfile{};
|
||||
}
|
||||
}
|
||||
|
||||
void LogitechHIDPP20IdleSettings::save()
|
||||
{
|
||||
json settings;
|
||||
|
||||
settings["on_battery"] = ProfileToJson(on_battery);
|
||||
settings["plugged_in"] = ProfileToJson(plugged_in);
|
||||
|
||||
SettingsManager* mgr = ResourceManager::get()->GetSettingsManager();
|
||||
mgr->SetSettings(SETTINGS_KEY, settings);
|
||||
mgr->SaveSettings();
|
||||
|
||||
configured = true;
|
||||
}
|
||||
|
||||
void LogitechHIDPP20IdleSettings::setOnBattery(const LogitechHIDPP20IdleProfile& p)
|
||||
{
|
||||
on_battery = p;
|
||||
configured = true;
|
||||
}
|
||||
|
||||
void LogitechHIDPP20IdleSettings::setPluggedIn(const LogitechHIDPP20IdleProfile& p)
|
||||
{
|
||||
plugged_in = p;
|
||||
configured = true;
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechHIDPP20IdleSettings.cpp |
|
||||
| |
|
||||
| Host-side idle/dim/sleep settings storage helper for |
|
||||
| Logitech HID++ 2.0 devices. Loads the configuration |
|
||||
| block from SettingsManager JSON, caches it, and writes |
|
||||
| changes back through SettingsManager::SetSettings(). |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "LogitechHIDPP20IdleSettings.h"
|
||||
#include "ResourceManager.h"
|
||||
#include "SettingsManager.h"
|
||||
|
||||
static const char* SETTINGS_KEY = "LogitechHIDPP20IdleSettings";
|
||||
|
||||
LogitechHIDPP20IdleSettings* LogitechHIDPP20IdleSettings::instance()
|
||||
{
|
||||
static LogitechHIDPP20IdleSettings inst;
|
||||
return &inst;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Minimum idle / sleep values the controller will honor. |
|
||||
| Matches what Logitech firmware typically clamps to on |
|
||||
| HID++ 2.0 devices, and guarantees the skip-dim path's |
|
||||
| sleep_delay math always produces a positive window. |
|
||||
\*---------------------------------------------------------*/
|
||||
static const int MIN_IDLE_S = 15;
|
||||
static const int MIN_SLEEP_S = 45;
|
||||
static const int MIN_DIM_WINDOW = 30; // sleep must exceed idle by at least this
|
||||
|
||||
static void ClampProfile(LogitechHIDPP20IdleProfile& p)
|
||||
{
|
||||
if(p.dim_brightness < 0) p.dim_brightness = 0;
|
||||
if(p.dim_brightness > 100) p.dim_brightness = 100;
|
||||
|
||||
if(p.idle_timeout_s < MIN_IDLE_S)
|
||||
{
|
||||
p.idle_timeout_s = MIN_IDLE_S;
|
||||
}
|
||||
|
||||
if(p.sleep_timeout_s < MIN_SLEEP_S)
|
||||
{
|
||||
p.sleep_timeout_s = MIN_SLEEP_S;
|
||||
}
|
||||
|
||||
if(p.sleep_timeout_s < p.idle_timeout_s + MIN_DIM_WINDOW)
|
||||
{
|
||||
p.sleep_timeout_s = p.idle_timeout_s + MIN_DIM_WINDOW;
|
||||
}
|
||||
}
|
||||
|
||||
static LogitechHIDPP20IdleProfile ProfileFromJson(const json& j)
|
||||
{
|
||||
LogitechHIDPP20IdleProfile p;
|
||||
|
||||
if(j.contains("dim_when_idle")) p.dim_when_idle = j["dim_when_idle"];
|
||||
if(j.contains("dim_brightness")) p.dim_brightness = j["dim_brightness"];
|
||||
if(j.contains("idle_timeout_s")) p.idle_timeout_s = j["idle_timeout_s"];
|
||||
if(j.contains("allow_sleep")) p.allow_sleep = j["allow_sleep"];
|
||||
if(j.contains("sleep_timeout_s")) p.sleep_timeout_s = j["sleep_timeout_s"];
|
||||
|
||||
ClampProfile(p);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static json ProfileToJson(const LogitechHIDPP20IdleProfile& p)
|
||||
{
|
||||
json j;
|
||||
|
||||
j["dim_when_idle"] = p.dim_when_idle;
|
||||
j["dim_brightness"] = p.dim_brightness;
|
||||
j["idle_timeout_s"] = p.idle_timeout_s;
|
||||
j["allow_sleep"] = p.allow_sleep;
|
||||
j["sleep_timeout_s"] = p.sleep_timeout_s;
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
void LogitechHIDPP20IdleSettings::load()
|
||||
{
|
||||
json settings = ResourceManager::get()->GetSettingsManager()->GetSettings(SETTINGS_KEY);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Empty / missing key means the plugin is not in use. |
|
||||
| Reset both profiles to defaults with configured=false so |
|
||||
| the controller defers to firmware. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(!settings.is_object() || settings.empty())
|
||||
{
|
||||
configured = false;
|
||||
on_battery = LogitechHIDPP20IdleProfile{};
|
||||
plugged_in = LogitechHIDPP20IdleProfile{};
|
||||
return;
|
||||
}
|
||||
|
||||
configured = true;
|
||||
|
||||
if(settings.contains("on_battery"))
|
||||
{
|
||||
on_battery = ProfileFromJson(settings["on_battery"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
on_battery = LogitechHIDPP20IdleProfile{};
|
||||
}
|
||||
|
||||
if(settings.contains("plugged_in"))
|
||||
{
|
||||
plugged_in = ProfileFromJson(settings["plugged_in"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
plugged_in = LogitechHIDPP20IdleProfile{};
|
||||
}
|
||||
}
|
||||
|
||||
void LogitechHIDPP20IdleSettings::save()
|
||||
{
|
||||
json settings;
|
||||
|
||||
settings["on_battery"] = ProfileToJson(on_battery);
|
||||
settings["plugged_in"] = ProfileToJson(plugged_in);
|
||||
|
||||
SettingsManager* mgr = ResourceManager::get()->GetSettingsManager();
|
||||
mgr->SetSettings(SETTINGS_KEY, settings);
|
||||
mgr->SaveSettings();
|
||||
|
||||
configured = true;
|
||||
}
|
||||
|
||||
void LogitechHIDPP20IdleSettings::setOnBattery(const LogitechHIDPP20IdleProfile& p)
|
||||
{
|
||||
on_battery = p;
|
||||
configured = true;
|
||||
}
|
||||
|
||||
void LogitechHIDPP20IdleSettings::setPluggedIn(const LogitechHIDPP20IdleProfile& p)
|
||||
{
|
||||
plugged_in = p;
|
||||
configured = true;
|
||||
}
|
||||
+47
-47
@@ -1,47 +1,47 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechHIDPP20IdleSettings.h |
|
||||
| |
|
||||
| Host-side idle/dim/sleep configuration for Logitech |
|
||||
| HID++ 2.0 devices. Two profiles (on_battery, plugged_in)|
|
||||
| selected at runtime based on the device's external- |
|
||||
| power flag. `configured == false` means the JSON key |
|
||||
| is absent entirely — the controller defers to firmware. |
|
||||
| Qt-free so the controller can consume it directly. |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct LogitechHIDPP20IdleProfile
|
||||
{
|
||||
bool dim_when_idle = false;
|
||||
int dim_brightness = 50;
|
||||
int idle_timeout_s = 60;
|
||||
bool allow_sleep = false;
|
||||
int sleep_timeout_s = 300;
|
||||
};
|
||||
|
||||
class LogitechHIDPP20IdleSettings
|
||||
{
|
||||
public:
|
||||
static LogitechHIDPP20IdleSettings* instance();
|
||||
|
||||
void load();
|
||||
void save();
|
||||
|
||||
bool isConfigured() const { return configured; }
|
||||
const LogitechHIDPP20IdleProfile& onBattery() const { return on_battery; }
|
||||
const LogitechHIDPP20IdleProfile& pluggedIn() const { return plugged_in; }
|
||||
|
||||
void setOnBattery(const LogitechHIDPP20IdleProfile& p);
|
||||
void setPluggedIn(const LogitechHIDPP20IdleProfile& p);
|
||||
|
||||
private:
|
||||
LogitechHIDPP20IdleSettings() = default;
|
||||
|
||||
bool configured = false;
|
||||
LogitechHIDPP20IdleProfile on_battery;
|
||||
LogitechHIDPP20IdleProfile plugged_in;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechHIDPP20IdleSettings.h |
|
||||
| |
|
||||
| Host-side idle/dim/sleep configuration for Logitech |
|
||||
| HID++ 2.0 devices. Two profiles (on_battery, plugged_in)|
|
||||
| selected at runtime based on the device's external- |
|
||||
| power flag. `configured == false` means the JSON key |
|
||||
| is absent entirely — the controller defers to firmware. |
|
||||
| Qt-free so the controller can consume it directly. |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct LogitechHIDPP20IdleProfile
|
||||
{
|
||||
bool dim_when_idle = false;
|
||||
int dim_brightness = 50;
|
||||
int idle_timeout_s = 60;
|
||||
bool allow_sleep = false;
|
||||
int sleep_timeout_s = 300;
|
||||
};
|
||||
|
||||
class LogitechHIDPP20IdleSettings
|
||||
{
|
||||
public:
|
||||
static LogitechHIDPP20IdleSettings* instance();
|
||||
|
||||
void load();
|
||||
void save();
|
||||
|
||||
bool isConfigured() const { return configured; }
|
||||
const LogitechHIDPP20IdleProfile& onBattery() const { return on_battery; }
|
||||
const LogitechHIDPP20IdleProfile& pluggedIn() const { return plugged_in; }
|
||||
|
||||
void setOnBattery(const LogitechHIDPP20IdleProfile& p);
|
||||
void setPluggedIn(const LogitechHIDPP20IdleProfile& p);
|
||||
|
||||
private:
|
||||
LogitechHIDPP20IdleSettings() = default;
|
||||
|
||||
bool configured = false;
|
||||
LogitechHIDPP20IdleProfile on_battery;
|
||||
LogitechHIDPP20IdleProfile plugged_in;
|
||||
};
|
||||
+1796
-1796
File diff suppressed because it is too large.
Load diff
+72
-72
@@ -1,72 +1,72 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechHIDPP20.h |
|
||||
| |
|
||||
| RGBController for unified Logitech HID++ 2.0 devices |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechHIDPP20Controller.h"
|
||||
|
||||
class RGBController_LogitechHIDPP20 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechHIDPP20(LogitechHIDPP20Controller* controller_ptr);
|
||||
~RGBController_LogitechHIDPP20();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
bool ReapplyActiveMode();
|
||||
|
||||
private:
|
||||
LogitechHIDPP20Controller* controller;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Repaint callback handler. Registered with the controller |
|
||||
| as request_repaint_fn and invoked from the power thread |
|
||||
| for dim/wake when no animation is driving updates. |
|
||||
\*---------------------------------------------------------*/
|
||||
void OnRepaintRequest();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| When true, the next DeviceUpdateMode cycle sends its |
|
||||
| SetZoneEffect calls with persist=true instead of the |
|
||||
| default ephemeral write. Used by DeviceSaveMode to replay |
|
||||
| the active mode as a NVM-committed effect on 0x8070 |
|
||||
| devices, which default to non-persistent live writes. |
|
||||
\*---------------------------------------------------------*/
|
||||
bool save_pending = false;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Maps OpenRGB LED index -> HID++ per-key zone ID |
|
||||
\*---------------------------------------------------------*/
|
||||
std::vector<uint16_t> led_to_zone_id;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Reverse map: zone_id -> LED index (-1 if no LED). |
|
||||
| Indexed 0..255 (zone IDs are bytes). Built once in |
|
||||
| SetupZones to avoid scanning led_to_zone_id at commit |
|
||||
| time, which would be O(N) per acked zone. |
|
||||
\*---------------------------------------------------------*/
|
||||
std::vector<int> zone_id_to_led_idx;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Last successfully committed colors for delta updates. |
|
||||
| An entry of HIDPP20_UNCOMMITTED (0xFF000000) marks an LED |
|
||||
| whose last write didn't ACK and which therefore needs to |
|
||||
| be re-pushed in the next frame regardless of color delta. |
|
||||
| The high byte (0xFF) is impossible for any value produced |
|
||||
| by ToRGBColor() so it never collides with a real color. |
|
||||
\*---------------------------------------------------------*/
|
||||
std::vector<RGBColor> sent_colors;
|
||||
uint32_t last_init_gen = 0;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechHIDPP20.h |
|
||||
| |
|
||||
| RGBController for unified Logitech HID++ 2.0 devices |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechHIDPP20Controller.h"
|
||||
|
||||
class RGBController_LogitechHIDPP20 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechHIDPP20(LogitechHIDPP20Controller* controller_ptr);
|
||||
~RGBController_LogitechHIDPP20();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
bool ReapplyActiveMode();
|
||||
|
||||
private:
|
||||
LogitechHIDPP20Controller* controller;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Repaint callback handler. Registered with the controller |
|
||||
| as request_repaint_fn and invoked from the power thread |
|
||||
| for dim/wake when no animation is driving updates. |
|
||||
\*---------------------------------------------------------*/
|
||||
void OnRepaintRequest();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| When true, the next DeviceUpdateMode cycle sends its |
|
||||
| SetZoneEffect calls with persist=true instead of the |
|
||||
| default ephemeral write. Used by DeviceSaveMode to replay |
|
||||
| the active mode as a NVM-committed effect on 0x8070 |
|
||||
| devices, which default to non-persistent live writes. |
|
||||
\*---------------------------------------------------------*/
|
||||
bool save_pending = false;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Maps OpenRGB LED index -> HID++ per-key zone ID |
|
||||
\*---------------------------------------------------------*/
|
||||
std::vector<uint16_t> led_to_zone_id;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Reverse map: zone_id -> LED index (-1 if no LED). |
|
||||
| Indexed 0..255 (zone IDs are bytes). Built once in |
|
||||
| SetupZones to avoid scanning led_to_zone_id at commit |
|
||||
| time, which would be O(N) per acked zone. |
|
||||
\*---------------------------------------------------------*/
|
||||
std::vector<int> zone_id_to_led_idx;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Last successfully committed colors for delta updates. |
|
||||
| An entry of HIDPP20_UNCOMMITTED (0xFF000000) marks an LED |
|
||||
| whose last write didn't ACK and which therefore needs to |
|
||||
| be re-pushed in the next frame regardless of color delta. |
|
||||
| The high byte (0xFF) is impossible for any value produced |
|
||||
| by ToRGBColor() so it never collides with a real color. |
|
||||
\*---------------------------------------------------------*/
|
||||
std::vector<RGBColor> sent_colors;
|
||||
uint32_t last_init_gen = 0;
|
||||
};
|
||||
+68
-68
@@ -1,68 +1,68 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechLightspeedController.cpp |
|
||||
| |
|
||||
| Driver for Logitech Lightspeed |
|
||||
| |
|
||||
| TheRogueZeta 05 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechLightspeedController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechLightspeedController::LogitechLightspeedController(hid_device* dev_handle, const char* path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
}
|
||||
|
||||
LogitechLightspeedController::~LogitechLightspeedController()
|
||||
{
|
||||
delete lightspeed;
|
||||
}
|
||||
|
||||
std::string LogitechLightspeedController::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location + " (Receiver) \r\nWireless Index: " + std::to_string(lightspeed->device_index));
|
||||
}
|
||||
|
||||
std::string LogitechLightspeedController::GetSerialString()
|
||||
{
|
||||
if (lightspeed->device_index == 255 && lightspeed->wireless)
|
||||
{
|
||||
LOG_DEBUG("[%s] Skipped get serial number as this is the reciever", lightspeed->device_name.c_str());
|
||||
return("");
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
//int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
//LOG_DEBUG("[%s] hid_get_serial_number_string Returned status - %i : %s", lightspeed->device_name.c_str(), ret, ((ret == 0) ? "SUCCESS" : "FAILED"));
|
||||
|
||||
//if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::string return_string(StringUtils::wstring_to_string(serial_string));
|
||||
|
||||
return(return_string);
|
||||
}
|
||||
}
|
||||
|
||||
void LogitechLightspeedController::SendMouseMode
|
||||
(
|
||||
uint8_t mode,
|
||||
uint16_t speed,
|
||||
uint8_t zone,
|
||||
uint8_t red,
|
||||
uint8_t green,
|
||||
uint8_t blue,
|
||||
uint8_t brightness
|
||||
)
|
||||
{
|
||||
lightspeed->setMode(mode, speed, zone, red, green, blue, brightness);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechLightspeedController.cpp |
|
||||
| |
|
||||
| Driver for Logitech Lightspeed |
|
||||
| |
|
||||
| TheRogueZeta 05 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechLightspeedController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechLightspeedController::LogitechLightspeedController(hid_device* dev_handle, const char* path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
}
|
||||
|
||||
LogitechLightspeedController::~LogitechLightspeedController()
|
||||
{
|
||||
delete lightspeed;
|
||||
}
|
||||
|
||||
std::string LogitechLightspeedController::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location + " (Receiver) \r\nWireless Index: " + std::to_string(lightspeed->device_index));
|
||||
}
|
||||
|
||||
std::string LogitechLightspeedController::GetSerialString()
|
||||
{
|
||||
if (lightspeed->device_index == 255 && lightspeed->wireless)
|
||||
{
|
||||
LOG_DEBUG("[%s] Skipped get serial number as this is the reciever", lightspeed->device_name.c_str());
|
||||
return("");
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
//int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
//LOG_DEBUG("[%s] hid_get_serial_number_string Returned status - %i : %s", lightspeed->device_name.c_str(), ret, ((ret == 0) ? "SUCCESS" : "FAILED"));
|
||||
|
||||
//if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
std::string return_string(StringUtils::wstring_to_string(serial_string));
|
||||
|
||||
return(return_string);
|
||||
}
|
||||
}
|
||||
|
||||
void LogitechLightspeedController::SendMouseMode
|
||||
(
|
||||
uint8_t mode,
|
||||
uint16_t speed,
|
||||
uint8_t zone,
|
||||
uint8_t red,
|
||||
uint8_t green,
|
||||
uint8_t blue,
|
||||
uint8_t brightness
|
||||
)
|
||||
{
|
||||
lightspeed->setMode(mode, speed, zone, red, green, blue, brightness);
|
||||
}
|
||||
+59
-59
@@ -1,59 +1,59 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechLightspeedController.h |
|
||||
| |
|
||||
| Driver for Logitech Lightspeed |
|
||||
| |
|
||||
| TheRogueZeta 05 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
#include "LogManager.h"
|
||||
#include "LogitechProtocolCommon.h"
|
||||
|
||||
#define LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN 0x01
|
||||
#define LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX 0x64
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechLightspeedController
|
||||
{
|
||||
public:
|
||||
LogitechLightspeedController(hid_device* dev_handle, const char* path);
|
||||
~LogitechLightspeedController();
|
||||
|
||||
logitech_device* lightspeed;
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SendMouseMode
|
||||
(
|
||||
uint8_t mode,
|
||||
uint16_t speed,
|
||||
uint8_t zone,
|
||||
uint8_t red,
|
||||
uint8_t green,
|
||||
uint8_t blue,
|
||||
uint8_t brightness
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechLightspeedController.h |
|
||||
| |
|
||||
| Driver for Logitech Lightspeed |
|
||||
| |
|
||||
| TheRogueZeta 05 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
#include "LogManager.h"
|
||||
#include "LogitechProtocolCommon.h"
|
||||
|
||||
#define LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN 0x01
|
||||
#define LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX 0x64
|
||||
|
||||
/*---------------------------------------------------------------------------------------------*\
|
||||
| Speed is 1000 for fast and 20000 for slow. |
|
||||
| Values are multiplied by 100 later to give lots of GUI steps. |
|
||||
\*---------------------------------------------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST = 0xC8, /* Slowest speed */
|
||||
LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL = 0x32, /* Normal speed */
|
||||
LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST = 0x0A, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechLightspeedController
|
||||
{
|
||||
public:
|
||||
LogitechLightspeedController(hid_device* dev_handle, const char* path);
|
||||
~LogitechLightspeedController();
|
||||
|
||||
logitech_device* lightspeed;
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SendMouseMode
|
||||
(
|
||||
uint8_t mode,
|
||||
uint16_t speed,
|
||||
uint8_t zone,
|
||||
uint8_t red,
|
||||
uint8_t green,
|
||||
uint8_t blue,
|
||||
uint8_t brightness
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
};
|
||||
+248
-248
@@ -1,248 +1,248 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechLightspeed.cpp |
|
||||
| |
|
||||
| RGBController for Logitech Lightspeed |
|
||||
| |
|
||||
| TheRogueZeta 05 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechLightspeed.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech Lightspeed
|
||||
@category Keyboard,Mouse,Mousemat,Headset
|
||||
@type USB
|
||||
@save :white_check_mark:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechWireless,DetectLogitechWired
|
||||
@comment The Lightspeed controller is the generic RGB Controller
|
||||
for all Logitech HID++ devices that support feature page 8070.
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechLightspeed::RGBController_LogitechLightspeed(LogitechLightspeedController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
bool connected = controller->lightspeed->connected();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_DEVICE_LED_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
if(connected)
|
||||
{
|
||||
name = controller->lightspeed->device_name;
|
||||
vendor = "Logitech";
|
||||
description = "Logitech Wireless Lightspeed Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
switch(controller->lightspeed->logitech_device_type)
|
||||
{
|
||||
case LOGITECH_DEVICE_TYPE_KEYBOARD:
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
break;
|
||||
|
||||
case LOGITECH_DEVICE_TYPE_MOUSE:
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
break;
|
||||
|
||||
case LOGITECH_DEVICE_TYPE_MOUSEPAD:
|
||||
type = DEVICE_TYPE_MOUSEMAT;
|
||||
break;
|
||||
|
||||
case LOGITECH_DEVICE_TYPE_HEADSET:
|
||||
type = DEVICE_TYPE_HEADSET;
|
||||
break;
|
||||
|
||||
default:
|
||||
type = DEVICE_TYPE_UNKNOWN;
|
||||
LOG_INFO("Logitech device type not known: %i", controller->lightspeed->logitech_device_type);
|
||||
}
|
||||
|
||||
logitech_led fx = controller->lightspeed->getLED_info(0);
|
||||
|
||||
for(uint8_t i = 0; i < fx.fx.size(); i++)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Logitech devices don't have a set order for effects and |
|
||||
| each device needs to have the effect index mapped |
|
||||
\*---------------------------------------------------------*/
|
||||
switch(fx.fx[i].mode)
|
||||
{
|
||||
case LOGITECH_DEVICE_LED_OFF:
|
||||
/* Do nothing as it's already added */
|
||||
break;
|
||||
|
||||
case LOGITECH_DEVICE_LED_ON:
|
||||
{
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = i;
|
||||
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 = i;
|
||||
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.color_mode = MODE_COLORS_PER_LED;
|
||||
Static.brightness_min = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN;
|
||||
Static.brightness_max = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX;
|
||||
Static.brightness = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX;
|
||||
modes.push_back(Static);
|
||||
LOG_DEBUG("[%s] Adding %s & %s modes at index - %02i", name.c_str(), Direct.name.c_str(), Static.name.c_str(), i);
|
||||
break;
|
||||
}
|
||||
|
||||
case LOGITECH_DEVICE_LED_SPECTRUM:
|
||||
{
|
||||
mode Cycle;
|
||||
Cycle.name = "Spectrum Cycle";
|
||||
Cycle.value = i;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.brightness_min = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN;
|
||||
Cycle.brightness_max = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX;
|
||||
Cycle.brightness = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX;
|
||||
Cycle.speed_min = LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL;
|
||||
modes.push_back(Cycle);
|
||||
LOG_DEBUG("[%s] Adding %s mode at index - %02i", name.c_str(), Cycle.name.c_str(), i);
|
||||
break;
|
||||
}
|
||||
|
||||
case LOGITECH_DEVICE_LED_BREATHING:
|
||||
{
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = i;
|
||||
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Breathing.color_mode = MODE_COLORS_PER_LED;
|
||||
Breathing.brightness_min = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX;
|
||||
Breathing.brightness = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX;
|
||||
Breathing.speed_min = LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
LOG_DEBUG("[%s] Adding %s mode at index - %02i", name.c_str(), Breathing.name.c_str(), i);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG_WARNING("[%s] Effect at index - %02i not added: Value %04X unrecognised", name.c_str(), i, fx.fx[i].mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
else
|
||||
{
|
||||
name = "Idle Lightspeed Device";
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_UNKNOWN;
|
||||
description = "Idle Logitech Wireless Lightspeed Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
}
|
||||
}
|
||||
|
||||
RGBController_LogitechLightspeed::~RGBController_LogitechLightspeed()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechLightspeed::SetupZones()
|
||||
{
|
||||
const std::string zone_string = "Zone";
|
||||
const std::string led_string = "LED";
|
||||
uint8_t led_count = controller->lightspeed->getLED_count();
|
||||
|
||||
LOG_DEBUG("[%s] Setting up %d LEDs", name.c_str(), led_count);
|
||||
if(led_count > 0)
|
||||
{
|
||||
for(size_t i = 0; i < led_count; i++)
|
||||
{
|
||||
zone Lightspeed_logo_zone;
|
||||
led Lightspeed_logo_led;
|
||||
logitech_led new_led = controller->lightspeed->getLED_info((uint8_t)i);
|
||||
|
||||
if(new_led.location < NUM_LOGITECH_LED_LOCATIONS )
|
||||
{
|
||||
Lightspeed_logo_zone.name = logitech_led_locations[new_led.location];
|
||||
Lightspeed_logo_zone.name.append(" ");
|
||||
Lightspeed_logo_led.name = Lightspeed_logo_zone.name;
|
||||
Lightspeed_logo_led.name.append(led_string);
|
||||
Lightspeed_logo_zone.name.append(zone_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string name = " " + std::to_string(i);
|
||||
Lightspeed_logo_zone.name = zone_string + name;
|
||||
Lightspeed_logo_led.name = led_string + name;
|
||||
}
|
||||
|
||||
Lightspeed_logo_zone.type = ZONE_TYPE_SINGLE;
|
||||
Lightspeed_logo_zone.leds_min = 1;
|
||||
Lightspeed_logo_zone.leds_max = 1;
|
||||
Lightspeed_logo_zone.leds_count = 1;
|
||||
Lightspeed_logo_zone.matrix_map = NULL;
|
||||
zones.push_back(Lightspeed_logo_zone);
|
||||
|
||||
Lightspeed_logo_led.value = (unsigned int)i;
|
||||
leds.push_back(Lightspeed_logo_led);
|
||||
}
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechLightspeed::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechLightspeed::DeviceUpdateLEDs()
|
||||
{
|
||||
for(std::vector<led>::iterator led_index = leds.begin(); led_index != leds.end(); led_index++)
|
||||
{
|
||||
UpdateZoneLEDs(led_index->value);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_LogitechLightspeed::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[zone]);
|
||||
unsigned char grn = RGBGetGValue(colors[zone]);
|
||||
unsigned char blu = RGBGetBValue(colors[zone]);
|
||||
|
||||
controller->SendMouseMode(modes[active_mode].value, modes[active_mode].speed, zone, red, grn, blu, modes[active_mode].brightness);
|
||||
}
|
||||
|
||||
void RGBController_LogitechLightspeed::UpdateSingleLED(int led)
|
||||
{
|
||||
UpdateZoneLEDs(led);
|
||||
}
|
||||
|
||||
void RGBController_LogitechLightspeed::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| If direct mode is true, then sent the packet to put the |
|
||||
| mouse in direct mode. This code will only be called when |
|
||||
| we change modes as to not spam the device. |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->lightspeed->setDirectMode(modes[active_mode].name == "Direct");
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechLightspeed.cpp |
|
||||
| |
|
||||
| RGBController for Logitech Lightspeed |
|
||||
| |
|
||||
| TheRogueZeta 05 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechLightspeed.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech Lightspeed
|
||||
@category Keyboard,Mouse,Mousemat,Headset
|
||||
@type USB
|
||||
@save :white_check_mark:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLogitechWireless,DetectLogitechWired
|
||||
@comment The Lightspeed controller is the generic RGB Controller
|
||||
for all Logitech HID++ devices that support feature page 8070.
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechLightspeed::RGBController_LogitechLightspeed(LogitechLightspeedController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
bool connected = controller->lightspeed->connected();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = LOGITECH_DEVICE_LED_OFF;
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
if(connected)
|
||||
{
|
||||
name = controller->lightspeed->device_name;
|
||||
vendor = "Logitech";
|
||||
description = "Logitech Wireless Lightspeed Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
switch(controller->lightspeed->logitech_device_type)
|
||||
{
|
||||
case LOGITECH_DEVICE_TYPE_KEYBOARD:
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
break;
|
||||
|
||||
case LOGITECH_DEVICE_TYPE_MOUSE:
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
break;
|
||||
|
||||
case LOGITECH_DEVICE_TYPE_MOUSEPAD:
|
||||
type = DEVICE_TYPE_MOUSEMAT;
|
||||
break;
|
||||
|
||||
case LOGITECH_DEVICE_TYPE_HEADSET:
|
||||
type = DEVICE_TYPE_HEADSET;
|
||||
break;
|
||||
|
||||
default:
|
||||
type = DEVICE_TYPE_UNKNOWN;
|
||||
LOG_INFO("Logitech device type not known: %i", controller->lightspeed->logitech_device_type);
|
||||
}
|
||||
|
||||
logitech_led fx = controller->lightspeed->getLED_info(0);
|
||||
|
||||
for(uint8_t i = 0; i < fx.fx.size(); i++)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Logitech devices don't have a set order for effects and |
|
||||
| each device needs to have the effect index mapped |
|
||||
\*---------------------------------------------------------*/
|
||||
switch(fx.fx[i].mode)
|
||||
{
|
||||
case LOGITECH_DEVICE_LED_OFF:
|
||||
/* Do nothing as it's already added */
|
||||
break;
|
||||
|
||||
case LOGITECH_DEVICE_LED_ON:
|
||||
{
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = i;
|
||||
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 = i;
|
||||
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.color_mode = MODE_COLORS_PER_LED;
|
||||
Static.brightness_min = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN;
|
||||
Static.brightness_max = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX;
|
||||
Static.brightness = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX;
|
||||
modes.push_back(Static);
|
||||
LOG_DEBUG("[%s] Adding %s & %s modes at index - %02i", name.c_str(), Direct.name.c_str(), Static.name.c_str(), i);
|
||||
break;
|
||||
}
|
||||
|
||||
case LOGITECH_DEVICE_LED_SPECTRUM:
|
||||
{
|
||||
mode Cycle;
|
||||
Cycle.name = "Spectrum Cycle";
|
||||
Cycle.value = i;
|
||||
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Cycle.color_mode = MODE_COLORS_NONE;
|
||||
Cycle.brightness_min = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN;
|
||||
Cycle.brightness_max = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX;
|
||||
Cycle.brightness = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX;
|
||||
Cycle.speed_min = LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST;
|
||||
Cycle.speed_max = LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST;
|
||||
Cycle.speed = LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL;
|
||||
modes.push_back(Cycle);
|
||||
LOG_DEBUG("[%s] Adding %s mode at index - %02i", name.c_str(), Cycle.name.c_str(), i);
|
||||
break;
|
||||
}
|
||||
|
||||
case LOGITECH_DEVICE_LED_BREATHING:
|
||||
{
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = i;
|
||||
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Breathing.color_mode = MODE_COLORS_PER_LED;
|
||||
Breathing.brightness_min = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX;
|
||||
Breathing.brightness = LOGITECH_G_PRO_WIRELESS_BRIGHTNESS_MAX;
|
||||
Breathing.speed_min = LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST;
|
||||
Breathing.speed_max = LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST;
|
||||
Breathing.speed = LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL;
|
||||
modes.push_back(Breathing);
|
||||
LOG_DEBUG("[%s] Adding %s mode at index - %02i", name.c_str(), Breathing.name.c_str(), i);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG_WARNING("[%s] Effect at index - %02i not added: Value %04X unrecognised", name.c_str(), i, fx.fx[i].mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
else
|
||||
{
|
||||
name = "Idle Lightspeed Device";
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_UNKNOWN;
|
||||
description = "Idle Logitech Wireless Lightspeed Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
}
|
||||
}
|
||||
|
||||
RGBController_LogitechLightspeed::~RGBController_LogitechLightspeed()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechLightspeed::SetupZones()
|
||||
{
|
||||
const std::string zone_string = "Zone";
|
||||
const std::string led_string = "LED";
|
||||
uint8_t led_count = controller->lightspeed->getLED_count();
|
||||
|
||||
LOG_DEBUG("[%s] Setting up %d LEDs", name.c_str(), led_count);
|
||||
if(led_count > 0)
|
||||
{
|
||||
for(size_t i = 0; i < led_count; i++)
|
||||
{
|
||||
zone Lightspeed_logo_zone;
|
||||
led Lightspeed_logo_led;
|
||||
logitech_led new_led = controller->lightspeed->getLED_info((uint8_t)i);
|
||||
|
||||
if(new_led.location < NUM_LOGITECH_LED_LOCATIONS )
|
||||
{
|
||||
Lightspeed_logo_zone.name = logitech_led_locations[new_led.location];
|
||||
Lightspeed_logo_zone.name.append(" ");
|
||||
Lightspeed_logo_led.name = Lightspeed_logo_zone.name;
|
||||
Lightspeed_logo_led.name.append(led_string);
|
||||
Lightspeed_logo_zone.name.append(zone_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string name = " " + std::to_string(i);
|
||||
Lightspeed_logo_zone.name = zone_string + name;
|
||||
Lightspeed_logo_led.name = led_string + name;
|
||||
}
|
||||
|
||||
Lightspeed_logo_zone.type = ZONE_TYPE_SINGLE;
|
||||
Lightspeed_logo_zone.leds_min = 1;
|
||||
Lightspeed_logo_zone.leds_max = 1;
|
||||
Lightspeed_logo_zone.leds_count = 1;
|
||||
Lightspeed_logo_zone.matrix_map = NULL;
|
||||
zones.push_back(Lightspeed_logo_zone);
|
||||
|
||||
Lightspeed_logo_led.value = (unsigned int)i;
|
||||
leds.push_back(Lightspeed_logo_led);
|
||||
}
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechLightspeed::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechLightspeed::DeviceUpdateLEDs()
|
||||
{
|
||||
for(std::vector<led>::iterator led_index = leds.begin(); led_index != leds.end(); led_index++)
|
||||
{
|
||||
UpdateZoneLEDs(led_index->value);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_LogitechLightspeed::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(colors[zone]);
|
||||
unsigned char grn = RGBGetGValue(colors[zone]);
|
||||
unsigned char blu = RGBGetBValue(colors[zone]);
|
||||
|
||||
controller->SendMouseMode(modes[active_mode].value, modes[active_mode].speed, zone, red, grn, blu, modes[active_mode].brightness);
|
||||
}
|
||||
|
||||
void RGBController_LogitechLightspeed::UpdateSingleLED(int led)
|
||||
{
|
||||
UpdateZoneLEDs(led);
|
||||
}
|
||||
|
||||
void RGBController_LogitechLightspeed::DeviceUpdateMode()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| If direct mode is true, then sent the packet to put the |
|
||||
| mouse in direct mode. This code will only be called when |
|
||||
| we change modes as to not spam the device. |
|
||||
\*---------------------------------------------------------*/
|
||||
controller->lightspeed->setDirectMode(modes[active_mode].name == "Direct");
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
+36
-36
@@ -1,36 +1,36 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechLightspeed.h |
|
||||
| |
|
||||
| RGBController for Logitech Lightspeed |
|
||||
| |
|
||||
| TheRogueZeta 05 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechLightspeedController.h"
|
||||
|
||||
class RGBController_LogitechLightspeed : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechLightspeed(LogitechLightspeedController* controller_ptr);
|
||||
~RGBController_LogitechLightspeed();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
uint16_t pid; //This is a workaround fix for G502 mode breathing / spectrum cycle swap
|
||||
private:
|
||||
LogitechLightspeedController* controller;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechLightspeed.h |
|
||||
| |
|
||||
| RGBController for Logitech Lightspeed |
|
||||
| |
|
||||
| TheRogueZeta 05 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechLightspeedController.h"
|
||||
|
||||
class RGBController_LogitechLightspeed : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechLightspeed(LogitechLightspeedController* controller_ptr);
|
||||
~RGBController_LogitechLightspeed();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
uint16_t pid; //This is a workaround fix for G502 mode breathing / spectrum cycle swap
|
||||
private:
|
||||
LogitechLightspeedController* controller;
|
||||
};
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,317 +1,317 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechProtocolCommon.h |
|
||||
| |
|
||||
| Common functionality for Logitech RAP and FAP protocols |
|
||||
| |
|
||||
| Chris M (Dr_No) 04 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "LogManager.h"
|
||||
|
||||
#define LOGITECH_PROTOCOL_TIMEOUT 300 //Timeout in ms
|
||||
#define LOGITECH_HEADER_SIZE 3
|
||||
#define LOGITECH_SHORT_MESSAGE 0x10
|
||||
#define LOGITECH_SHORT_MESSAGE_LEN 7
|
||||
#define LOGITECH_LONG_MESSAGE 0x11
|
||||
#define LOGITECH_LONG_MESSAGE_LEN 20
|
||||
#define LOGITECH_FAP_RESPONSE_LEN 64 //Define a universal response buffer and allow the hidapi to determine the size
|
||||
|
||||
#define LOGITECH_DEFAULT_DEVICE_INDEX 0xFF
|
||||
#define LOGITECH_RECEIVER_DEVICE_INDEX 0xFF //The Unifying receiver uses RAP or register access protocol
|
||||
#define LOGITECH_SET_REGISTER_REQUEST 0x80
|
||||
#define LOGITECH_GET_REGISTER_REQUEST 0x81
|
||||
|
||||
#define LOGITECH_HIDPP_PAGE_ROOT_IDX 0x00 //Used for querying the feature index
|
||||
#define LOGITECH_CMD_ROOT_GET_FEATURE 0x01
|
||||
#define LOGITECH_CMD_ROOT_GET_PROTOCOL 0x11
|
||||
|
||||
#define LOGITECH_HIDPP_PAGE_FEATURE_SET 0x0001
|
||||
#define LOGITECH_CMD_FEATURE_SET_GET_COUNT 0x01
|
||||
#define LOGITECH_CMD_FEATURE_SET_GET_ID 0x11
|
||||
|
||||
#define LOGITECH_HIDPP_PAGE_DEVICE_NAME_TYPE 0x0005
|
||||
#define LOTITECH_CMD_DEVICE_NAME_TYPE_GET_COUNT 0x01
|
||||
#define LOGITECH_CMD_DEVICE_NAME_TYPE_GET_DEVICE_NAME 0x11
|
||||
#define LOGITECH_CMD_DEVICE_NAME_TYPE_GET_TYPE 0x21
|
||||
|
||||
#define LOGITECH_HIDPP_PAGE_RGB_EFFECTS1 0x8070
|
||||
#define LOGITECH_HIDPP_PAGE_RGB_EFFECTS2 0x8071
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_GET_COUNT 0x00
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_GET_INFO 0x10
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_GET_CONTROL 0x20
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_SET_CONTROL 0x30
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_GET_STATE 0x40
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_SET_STATE 0x50
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_GET_CONFIG 0x60
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_SET_CONFIG 0x70
|
||||
|
||||
enum LOGITECH_DEVICE_TYPE
|
||||
{
|
||||
LOGITECH_DEVICE_TYPE_KEYBOARD = 0,
|
||||
LOGITECH_DEVICE_TYPE_REMOTECONTROL = 1,
|
||||
LOGITECH_DEVICE_TYPE_NUMPAD = 2,
|
||||
LOGITECH_DEVICE_TYPE_MOUSE = 3,
|
||||
LOGITECH_DEVICE_TYPE_MOUSEPAD = 4,
|
||||
LOGITECH_DEVICE_TYPE_TRACKBALL = 5,
|
||||
LOGITECH_DEVICE_TYPE_PRESENTER = 6,
|
||||
LOGITECH_DEVICE_TYPE_RECEIVER = 7,
|
||||
LOGITECH_DEVICE_TYPE_HEADSET = 8
|
||||
};
|
||||
|
||||
enum LOGITECH_DEVICE_MODE
|
||||
{
|
||||
LOGITECH_DEVICE_LED_OFF = 0x0000,
|
||||
LOGITECH_DEVICE_LED_ON = 0x0001,
|
||||
LOGITECH_DEVICE_LED_SPECTRUM = 0x0003,
|
||||
LOGITECH_DEVICE_LED_WAVE = 0x0004,
|
||||
LOGITECH_DEVICE_LED_STAR = 0x0005,
|
||||
LOGITECH_DEVICE_LED_BREATHING = 0x000A,
|
||||
LOGITECH_DEVICE_LED_RIPPLE = 0x000B,
|
||||
LOGITECH_DEVICE_LED_CUSTOM = 0x000C
|
||||
};
|
||||
|
||||
enum LOGITECH_FP8070
|
||||
{
|
||||
LOGITECH_FP8070_INFO = 0x00,
|
||||
LOGITECH_FP8070_ZONE_INFO = 0x10,
|
||||
LOGITECH_FP8070_EFFECT_INFO = 0x20,
|
||||
LOGITECH_FP8070_SET_EFFECT = 0x30,
|
||||
LOGITECH_FP8070_SET_CFG = 0x40,
|
||||
LOGITECH_FP8070_GET_CFG = 0x50,
|
||||
LOGITECH_FP8070_GET_BIN_INFO = 0x60,
|
||||
LOGITECH_FP8070_GET_SW_CTL = 0x70,
|
||||
LOGITECH_FP8070_SET_SW_CTL = 0x80,
|
||||
LOGITECH_FP8070_GET_STATUS = 0x90,
|
||||
LOGITECH_FP8070_CLEAR_EFFECT = 0xA0,
|
||||
LOGITECH_FP8070_SET_DIR = 0xB0,
|
||||
LOGITECH_FP8070_GET_COLOUR = 0xC0,
|
||||
LOGITECH_FP8070_SYNC_CFG = 0xD0,
|
||||
LOGITECH_FP8070_GET_EFFECT = 0xE0,
|
||||
LOGITECH_FP8070_SET_BIN_INFO = 0xF0,
|
||||
};
|
||||
|
||||
enum LOGITECH_FP8071
|
||||
{
|
||||
LOGITECH_FP8071_INFO = 0x00,
|
||||
LOGITECH_FP8071_SET_LED_EFFECT = 0x10,
|
||||
LOGITECH_FP8071_ZONE_PATTERN = 0x20,
|
||||
LOGITECH_FP8071_CONFIG = 0x30,
|
||||
LOGITECH_FP8070_BIN_INFO = 0x40,
|
||||
LOGITECH_FP8071_CONTROL = 0x50,
|
||||
LOGITECH_FP8071_SYNC_CFG = 0x60,
|
||||
LOGITECH_FP8071_PWR_CFG = 0x70,
|
||||
LOGITECH_FP8071_PWR_MODE = 0x80,
|
||||
LOGITECH_FP8071_SHUTDOWN = 0x90
|
||||
};
|
||||
|
||||
enum LOGITECH_FP8071_FLAGS
|
||||
{
|
||||
FP8071_SUPPORTS_GET_STATUS = 0x01,
|
||||
FP8071_RESERVED = 0x02,
|
||||
FP8071_SUPPORTS_SET_BIN_INFO = 0x04,
|
||||
FP8071_MONOCHROME_ONLY = 0x08,
|
||||
FP8071_NO_SYNC_SUPPORT = 0x10,
|
||||
FP8071_SUPPORTS_SHUTDOWN = 0x20,
|
||||
FP8071_SUPPORTS_CLUSTER_CHANGED = 0x40,
|
||||
};
|
||||
|
||||
extern const char* logitech_led_locations[];
|
||||
extern const int NUM_LOGITECH_LED_LOCATIONS;
|
||||
|
||||
// Used for: {GET,SET}_REGISTER_{REQ,RSP}, SET_LONG_REGISTER_RSP, GET_LONG_REGISTER_REQ
|
||||
struct message_short
|
||||
{
|
||||
unsigned char address;
|
||||
unsigned char data[3];
|
||||
};
|
||||
|
||||
// Used for: SET_LONG_REGISTER_REQ, GET_LONG_REGISTER_RSP
|
||||
struct message_long
|
||||
{
|
||||
unsigned char address;
|
||||
unsigned char data[16];
|
||||
};
|
||||
|
||||
// Used for: ERROR_MSG
|
||||
struct message_error
|
||||
{
|
||||
unsigned char sub_id;
|
||||
unsigned char address;
|
||||
unsigned char error_code;
|
||||
unsigned char padding; /* set to 0 */
|
||||
};
|
||||
|
||||
union shortFAPrequest
|
||||
{
|
||||
uint8_t buffer[LOGITECH_SHORT_MESSAGE_LEN];
|
||||
struct
|
||||
{
|
||||
uint8_t report_id;
|
||||
uint8_t device_index;
|
||||
uint8_t feature_index;
|
||||
uint8_t feature_command;
|
||||
uint8_t data[LOGITECH_SHORT_MESSAGE_LEN - 4];
|
||||
};
|
||||
|
||||
void init(uint8_t device_index, uint8_t feature_index)
|
||||
{
|
||||
this->report_id = LOGITECH_SHORT_MESSAGE;
|
||||
this->device_index = device_index;
|
||||
this->feature_index = feature_index;
|
||||
this->feature_command = feature_command;
|
||||
for(size_t i = 0; i < sizeof(data); i++)
|
||||
{
|
||||
this->data[i] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
int size()
|
||||
{
|
||||
return LOGITECH_SHORT_MESSAGE_LEN;
|
||||
};
|
||||
};
|
||||
|
||||
union longFAPrequest
|
||||
{
|
||||
uint8_t buffer[LOGITECH_LONG_MESSAGE_LEN];
|
||||
struct
|
||||
{
|
||||
uint8_t report_id;
|
||||
uint8_t device_index;
|
||||
uint8_t feature_index;
|
||||
uint8_t feature_command;
|
||||
uint8_t data[LOGITECH_LONG_MESSAGE_LEN - 4];
|
||||
};
|
||||
|
||||
void init(uint8_t device_index, uint8_t feature_index, uint8_t feature_command)
|
||||
{
|
||||
this->report_id = LOGITECH_LONG_MESSAGE;
|
||||
this->device_index = device_index;
|
||||
this->feature_index = feature_index;
|
||||
this->feature_command = feature_command;
|
||||
for(size_t i = 0; i < sizeof(data); i++)
|
||||
{
|
||||
this->data[i] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
int size()
|
||||
{
|
||||
return LOGITECH_LONG_MESSAGE_LEN;
|
||||
};
|
||||
};
|
||||
|
||||
union blankFAPmessage
|
||||
{
|
||||
uint8_t buffer[LOGITECH_FAP_RESPONSE_LEN];
|
||||
struct
|
||||
{
|
||||
uint8_t report_id;
|
||||
uint8_t device_index;
|
||||
uint8_t feature_index;
|
||||
uint8_t feature_command;
|
||||
uint8_t data[LOGITECH_FAP_RESPONSE_LEN - 4];
|
||||
};
|
||||
|
||||
//blank this buffer entirely
|
||||
void init()
|
||||
{
|
||||
for(size_t i = 0; i < sizeof(buffer); i++)
|
||||
{
|
||||
this->buffer[i] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
int size()
|
||||
{
|
||||
return LOGITECH_FAP_RESPONSE_LEN;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename K, typename V>
|
||||
static std::map<V, K> reverse_map(const std::map<K, V>& map)
|
||||
{
|
||||
std::map<V, K> reversed_map;
|
||||
|
||||
for(const std::pair<const K, V>& entry : map)
|
||||
{
|
||||
reversed_map[entry.second] = entry.first;
|
||||
}
|
||||
|
||||
return reversed_map;
|
||||
}
|
||||
|
||||
struct logitech_fx
|
||||
{
|
||||
uint8_t index;
|
||||
uint16_t speed; //period
|
||||
LOGITECH_DEVICE_MODE mode;
|
||||
};
|
||||
|
||||
typedef std::map<uint8_t, hid_device*> usages;
|
||||
typedef std::map<uint16_t, uint8_t> features;
|
||||
typedef std::map<uint8_t, uint16_t> rvrse_features;
|
||||
typedef std::map<uint16_t, uint8_t> wireless_map;
|
||||
|
||||
typedef std::vector<logitech_fx> leds_fx;
|
||||
|
||||
struct logitech_led
|
||||
{
|
||||
uint16_t location;
|
||||
uint8_t fx_count;
|
||||
leds_fx fx;
|
||||
};
|
||||
|
||||
int getWirelessDevice(usages _usages, uint16_t pid, wireless_map *wireless_devices); //Helper function needed outside of class
|
||||
|
||||
class logitech_device
|
||||
{
|
||||
public:
|
||||
logitech_device(char *path, usages _usages, uint8_t _device_index, bool _wireless);
|
||||
logitech_device(char *path, usages _usages, uint8_t _device_index, bool _wireless, std::shared_ptr<std::mutex> mutex_ptr);
|
||||
|
||||
~logitech_device();
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| usages is a std::map that stores all the devices HID usages |
|
||||
| This is to ensure that we can communicate to all windows usages |
|
||||
\*-----------------------------------------------------------------*/
|
||||
usages device_usages;
|
||||
features feature_list;
|
||||
uint8_t device_index;
|
||||
uint8_t RGB_feature_index; //Stored for quick use
|
||||
uint8_t logitech_device_type;
|
||||
bool wireless;
|
||||
std::string device_name;
|
||||
std::string location;
|
||||
std::string protocol_version;
|
||||
|
||||
bool connected();
|
||||
bool is_valid();
|
||||
void flushReadQueue();
|
||||
uint8_t getFeatureIndex(uint16_t feature_page);
|
||||
uint8_t getLED_count();
|
||||
logitech_led getLED_info(uint8_t LED_num);
|
||||
uint8_t setDirectMode(bool direct);
|
||||
uint8_t setMode(uint8_t mode, uint16_t speed, uint8_t zone, uint8_t red, uint8_t green, uint8_t blue, uint8_t brightness);
|
||||
uint8_t set8071Effects(uint8_t control);
|
||||
uint8_t set8071TimeoutControl(uint8_t control);
|
||||
int getDeviceName();
|
||||
private:
|
||||
std::map<uint8_t, logitech_led> leds;
|
||||
std::shared_ptr<std::mutex> mutex;
|
||||
|
||||
hid_device* getDevice(uint8_t usage_index);
|
||||
uint16_t getFeaturePage(uint8_t feature_index);
|
||||
int getDeviceFeatureList();
|
||||
void getRGBconfig();
|
||||
void initialiseDevice();
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechProtocolCommon.h |
|
||||
| |
|
||||
| Common functionality for Logitech RAP and FAP protocols |
|
||||
| |
|
||||
| Chris M (Dr_No) 04 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "LogManager.h"
|
||||
|
||||
#define LOGITECH_PROTOCOL_TIMEOUT 300 //Timeout in ms
|
||||
#define LOGITECH_HEADER_SIZE 3
|
||||
#define LOGITECH_SHORT_MESSAGE 0x10
|
||||
#define LOGITECH_SHORT_MESSAGE_LEN 7
|
||||
#define LOGITECH_LONG_MESSAGE 0x11
|
||||
#define LOGITECH_LONG_MESSAGE_LEN 20
|
||||
#define LOGITECH_FAP_RESPONSE_LEN 64 //Define a universal response buffer and allow the hidapi to determine the size
|
||||
|
||||
#define LOGITECH_DEFAULT_DEVICE_INDEX 0xFF
|
||||
#define LOGITECH_RECEIVER_DEVICE_INDEX 0xFF //The Unifying receiver uses RAP or register access protocol
|
||||
#define LOGITECH_SET_REGISTER_REQUEST 0x80
|
||||
#define LOGITECH_GET_REGISTER_REQUEST 0x81
|
||||
|
||||
#define LOGITECH_HIDPP_PAGE_ROOT_IDX 0x00 //Used for querying the feature index
|
||||
#define LOGITECH_CMD_ROOT_GET_FEATURE 0x01
|
||||
#define LOGITECH_CMD_ROOT_GET_PROTOCOL 0x11
|
||||
|
||||
#define LOGITECH_HIDPP_PAGE_FEATURE_SET 0x0001
|
||||
#define LOGITECH_CMD_FEATURE_SET_GET_COUNT 0x01
|
||||
#define LOGITECH_CMD_FEATURE_SET_GET_ID 0x11
|
||||
|
||||
#define LOGITECH_HIDPP_PAGE_DEVICE_NAME_TYPE 0x0005
|
||||
#define LOTITECH_CMD_DEVICE_NAME_TYPE_GET_COUNT 0x01
|
||||
#define LOGITECH_CMD_DEVICE_NAME_TYPE_GET_DEVICE_NAME 0x11
|
||||
#define LOGITECH_CMD_DEVICE_NAME_TYPE_GET_TYPE 0x21
|
||||
|
||||
#define LOGITECH_HIDPP_PAGE_RGB_EFFECTS1 0x8070
|
||||
#define LOGITECH_HIDPP_PAGE_RGB_EFFECTS2 0x8071
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_GET_COUNT 0x00
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_GET_INFO 0x10
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_GET_CONTROL 0x20
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_SET_CONTROL 0x30
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_GET_STATE 0x40
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_SET_STATE 0x50
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_GET_CONFIG 0x60
|
||||
#define LOGITECH_CMD_RGB_EFFECTS_SET_CONFIG 0x70
|
||||
|
||||
enum LOGITECH_DEVICE_TYPE
|
||||
{
|
||||
LOGITECH_DEVICE_TYPE_KEYBOARD = 0,
|
||||
LOGITECH_DEVICE_TYPE_REMOTECONTROL = 1,
|
||||
LOGITECH_DEVICE_TYPE_NUMPAD = 2,
|
||||
LOGITECH_DEVICE_TYPE_MOUSE = 3,
|
||||
LOGITECH_DEVICE_TYPE_MOUSEPAD = 4,
|
||||
LOGITECH_DEVICE_TYPE_TRACKBALL = 5,
|
||||
LOGITECH_DEVICE_TYPE_PRESENTER = 6,
|
||||
LOGITECH_DEVICE_TYPE_RECEIVER = 7,
|
||||
LOGITECH_DEVICE_TYPE_HEADSET = 8
|
||||
};
|
||||
|
||||
enum LOGITECH_DEVICE_MODE
|
||||
{
|
||||
LOGITECH_DEVICE_LED_OFF = 0x0000,
|
||||
LOGITECH_DEVICE_LED_ON = 0x0001,
|
||||
LOGITECH_DEVICE_LED_SPECTRUM = 0x0003,
|
||||
LOGITECH_DEVICE_LED_WAVE = 0x0004,
|
||||
LOGITECH_DEVICE_LED_STAR = 0x0005,
|
||||
LOGITECH_DEVICE_LED_BREATHING = 0x000A,
|
||||
LOGITECH_DEVICE_LED_RIPPLE = 0x000B,
|
||||
LOGITECH_DEVICE_LED_CUSTOM = 0x000C
|
||||
};
|
||||
|
||||
enum LOGITECH_FP8070
|
||||
{
|
||||
LOGITECH_FP8070_INFO = 0x00,
|
||||
LOGITECH_FP8070_ZONE_INFO = 0x10,
|
||||
LOGITECH_FP8070_EFFECT_INFO = 0x20,
|
||||
LOGITECH_FP8070_SET_EFFECT = 0x30,
|
||||
LOGITECH_FP8070_SET_CFG = 0x40,
|
||||
LOGITECH_FP8070_GET_CFG = 0x50,
|
||||
LOGITECH_FP8070_GET_BIN_INFO = 0x60,
|
||||
LOGITECH_FP8070_GET_SW_CTL = 0x70,
|
||||
LOGITECH_FP8070_SET_SW_CTL = 0x80,
|
||||
LOGITECH_FP8070_GET_STATUS = 0x90,
|
||||
LOGITECH_FP8070_CLEAR_EFFECT = 0xA0,
|
||||
LOGITECH_FP8070_SET_DIR = 0xB0,
|
||||
LOGITECH_FP8070_GET_COLOUR = 0xC0,
|
||||
LOGITECH_FP8070_SYNC_CFG = 0xD0,
|
||||
LOGITECH_FP8070_GET_EFFECT = 0xE0,
|
||||
LOGITECH_FP8070_SET_BIN_INFO = 0xF0,
|
||||
};
|
||||
|
||||
enum LOGITECH_FP8071
|
||||
{
|
||||
LOGITECH_FP8071_INFO = 0x00,
|
||||
LOGITECH_FP8071_SET_LED_EFFECT = 0x10,
|
||||
LOGITECH_FP8071_ZONE_PATTERN = 0x20,
|
||||
LOGITECH_FP8071_CONFIG = 0x30,
|
||||
LOGITECH_FP8070_BIN_INFO = 0x40,
|
||||
LOGITECH_FP8071_CONTROL = 0x50,
|
||||
LOGITECH_FP8071_SYNC_CFG = 0x60,
|
||||
LOGITECH_FP8071_PWR_CFG = 0x70,
|
||||
LOGITECH_FP8071_PWR_MODE = 0x80,
|
||||
LOGITECH_FP8071_SHUTDOWN = 0x90
|
||||
};
|
||||
|
||||
enum LOGITECH_FP8071_FLAGS
|
||||
{
|
||||
FP8071_SUPPORTS_GET_STATUS = 0x01,
|
||||
FP8071_RESERVED = 0x02,
|
||||
FP8071_SUPPORTS_SET_BIN_INFO = 0x04,
|
||||
FP8071_MONOCHROME_ONLY = 0x08,
|
||||
FP8071_NO_SYNC_SUPPORT = 0x10,
|
||||
FP8071_SUPPORTS_SHUTDOWN = 0x20,
|
||||
FP8071_SUPPORTS_CLUSTER_CHANGED = 0x40,
|
||||
};
|
||||
|
||||
extern const char* logitech_led_locations[];
|
||||
extern const int NUM_LOGITECH_LED_LOCATIONS;
|
||||
|
||||
// Used for: {GET,SET}_REGISTER_{REQ,RSP}, SET_LONG_REGISTER_RSP, GET_LONG_REGISTER_REQ
|
||||
struct message_short
|
||||
{
|
||||
unsigned char address;
|
||||
unsigned char data[3];
|
||||
};
|
||||
|
||||
// Used for: SET_LONG_REGISTER_REQ, GET_LONG_REGISTER_RSP
|
||||
struct message_long
|
||||
{
|
||||
unsigned char address;
|
||||
unsigned char data[16];
|
||||
};
|
||||
|
||||
// Used for: ERROR_MSG
|
||||
struct message_error
|
||||
{
|
||||
unsigned char sub_id;
|
||||
unsigned char address;
|
||||
unsigned char error_code;
|
||||
unsigned char padding; /* set to 0 */
|
||||
};
|
||||
|
||||
union shortFAPrequest
|
||||
{
|
||||
uint8_t buffer[LOGITECH_SHORT_MESSAGE_LEN];
|
||||
struct
|
||||
{
|
||||
uint8_t report_id;
|
||||
uint8_t device_index;
|
||||
uint8_t feature_index;
|
||||
uint8_t feature_command;
|
||||
uint8_t data[LOGITECH_SHORT_MESSAGE_LEN - 4];
|
||||
};
|
||||
|
||||
void init(uint8_t device_index, uint8_t feature_index)
|
||||
{
|
||||
this->report_id = LOGITECH_SHORT_MESSAGE;
|
||||
this->device_index = device_index;
|
||||
this->feature_index = feature_index;
|
||||
this->feature_command = feature_command;
|
||||
for(size_t i = 0; i < sizeof(data); i++)
|
||||
{
|
||||
this->data[i] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
int size()
|
||||
{
|
||||
return LOGITECH_SHORT_MESSAGE_LEN;
|
||||
};
|
||||
};
|
||||
|
||||
union longFAPrequest
|
||||
{
|
||||
uint8_t buffer[LOGITECH_LONG_MESSAGE_LEN];
|
||||
struct
|
||||
{
|
||||
uint8_t report_id;
|
||||
uint8_t device_index;
|
||||
uint8_t feature_index;
|
||||
uint8_t feature_command;
|
||||
uint8_t data[LOGITECH_LONG_MESSAGE_LEN - 4];
|
||||
};
|
||||
|
||||
void init(uint8_t device_index, uint8_t feature_index, uint8_t feature_command)
|
||||
{
|
||||
this->report_id = LOGITECH_LONG_MESSAGE;
|
||||
this->device_index = device_index;
|
||||
this->feature_index = feature_index;
|
||||
this->feature_command = feature_command;
|
||||
for(size_t i = 0; i < sizeof(data); i++)
|
||||
{
|
||||
this->data[i] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
int size()
|
||||
{
|
||||
return LOGITECH_LONG_MESSAGE_LEN;
|
||||
};
|
||||
};
|
||||
|
||||
union blankFAPmessage
|
||||
{
|
||||
uint8_t buffer[LOGITECH_FAP_RESPONSE_LEN];
|
||||
struct
|
||||
{
|
||||
uint8_t report_id;
|
||||
uint8_t device_index;
|
||||
uint8_t feature_index;
|
||||
uint8_t feature_command;
|
||||
uint8_t data[LOGITECH_FAP_RESPONSE_LEN - 4];
|
||||
};
|
||||
|
||||
//blank this buffer entirely
|
||||
void init()
|
||||
{
|
||||
for(size_t i = 0; i < sizeof(buffer); i++)
|
||||
{
|
||||
this->buffer[i] = 0;
|
||||
}
|
||||
};
|
||||
|
||||
int size()
|
||||
{
|
||||
return LOGITECH_FAP_RESPONSE_LEN;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename K, typename V>
|
||||
static std::map<V, K> reverse_map(const std::map<K, V>& map)
|
||||
{
|
||||
std::map<V, K> reversed_map;
|
||||
|
||||
for(const std::pair<const K, V>& entry : map)
|
||||
{
|
||||
reversed_map[entry.second] = entry.first;
|
||||
}
|
||||
|
||||
return reversed_map;
|
||||
}
|
||||
|
||||
struct logitech_fx
|
||||
{
|
||||
uint8_t index;
|
||||
uint16_t speed; //period
|
||||
LOGITECH_DEVICE_MODE mode;
|
||||
};
|
||||
|
||||
typedef std::map<uint8_t, hid_device*> usages;
|
||||
typedef std::map<uint16_t, uint8_t> features;
|
||||
typedef std::map<uint8_t, uint16_t> rvrse_features;
|
||||
typedef std::map<uint16_t, uint8_t> wireless_map;
|
||||
|
||||
typedef std::vector<logitech_fx> leds_fx;
|
||||
|
||||
struct logitech_led
|
||||
{
|
||||
uint16_t location;
|
||||
uint8_t fx_count;
|
||||
leds_fx fx;
|
||||
};
|
||||
|
||||
int getWirelessDevice(usages _usages, uint16_t pid, wireless_map *wireless_devices); //Helper function needed outside of class
|
||||
|
||||
class logitech_device
|
||||
{
|
||||
public:
|
||||
logitech_device(char *path, usages _usages, uint8_t _device_index, bool _wireless);
|
||||
logitech_device(char *path, usages _usages, uint8_t _device_index, bool _wireless, std::shared_ptr<std::mutex> mutex_ptr);
|
||||
|
||||
~logitech_device();
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| usages is a std::map that stores all the devices HID usages |
|
||||
| This is to ensure that we can communicate to all windows usages |
|
||||
\*-----------------------------------------------------------------*/
|
||||
usages device_usages;
|
||||
features feature_list;
|
||||
uint8_t device_index;
|
||||
uint8_t RGB_feature_index; //Stored for quick use
|
||||
uint8_t logitech_device_type;
|
||||
bool wireless;
|
||||
std::string device_name;
|
||||
std::string location;
|
||||
std::string protocol_version;
|
||||
|
||||
bool connected();
|
||||
bool is_valid();
|
||||
void flushReadQueue();
|
||||
uint8_t getFeatureIndex(uint16_t feature_page);
|
||||
uint8_t getLED_count();
|
||||
logitech_led getLED_info(uint8_t LED_num);
|
||||
uint8_t setDirectMode(bool direct);
|
||||
uint8_t setMode(uint8_t mode, uint16_t speed, uint8_t zone, uint8_t red, uint8_t green, uint8_t blue, uint8_t brightness);
|
||||
uint8_t set8071Effects(uint8_t control);
|
||||
uint8_t set8071TimeoutControl(uint8_t control);
|
||||
int getDeviceName();
|
||||
private:
|
||||
std::map<uint8_t, logitech_led> leds;
|
||||
std::shared_ptr<std::mutex> mutex;
|
||||
|
||||
hid_device* getDevice(uint8_t usage_index);
|
||||
uint16_t getFeaturePage(uint8_t feature_index);
|
||||
int getDeviceFeatureList();
|
||||
void getRGBconfig();
|
||||
void initialiseDevice();
|
||||
};
|
||||
@@ -1,102 +1,102 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechX56Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech X56 |
|
||||
| |
|
||||
| Edbgon 11 Jun 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechX56Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechX56Controller::LogitechX56Controller(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechX56Controller::~LogitechX56Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string LogitechX56Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string LogitechX56Controller::GetDeviceName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechX56Controller::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 LogitechX56Controller::SetColor(RGBColor color, uint8_t brightness)
|
||||
{
|
||||
unsigned char buf[X56_CONTROLLER_PACKET_SIZE];
|
||||
unsigned char cbuf[X56_CONTROLLER_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, X56_CONTROLLER_PACKET_SIZE);
|
||||
memset(cbuf, 0x00, X56_CONTROLLER_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up init packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x09;
|
||||
buf[0x02] = 0x02;
|
||||
buf[0x03] = brightness;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up color packet |
|
||||
\*-----------------------------------------------------*/
|
||||
cbuf[0x00] = 0x09;
|
||||
cbuf[0x02] = 0x03;
|
||||
cbuf[0x03] = RGBGetRValue(color);
|
||||
cbuf[0x04] = RGBGetGValue(color);
|
||||
cbuf[0x05] = RGBGetBValue(color);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packets |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, buf, X56_CONTROLLER_PACKET_SIZE);
|
||||
hid_send_feature_report(dev, cbuf, X56_CONTROLLER_PACKET_SIZE);
|
||||
|
||||
}
|
||||
|
||||
void LogitechX56Controller::Save()
|
||||
{
|
||||
uint8_t buffer[X56_CONTROLLER_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buffer, 0x00, X56_CONTROLLER_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up init packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buffer[0x00] = 0x01;
|
||||
buffer[0x01] = 0x01;
|
||||
|
||||
hid_send_feature_report(dev, buffer, X56_CONTROLLER_PACKET_SIZE);
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechX56Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech X56 |
|
||||
| |
|
||||
| Edbgon 11 Jun 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogitechX56Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
LogitechX56Controller::LogitechX56Controller(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechX56Controller::~LogitechX56Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string LogitechX56Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string LogitechX56Controller::GetDeviceName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string LogitechX56Controller::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 LogitechX56Controller::SetColor(RGBColor color, uint8_t brightness)
|
||||
{
|
||||
unsigned char buf[X56_CONTROLLER_PACKET_SIZE];
|
||||
unsigned char cbuf[X56_CONTROLLER_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, X56_CONTROLLER_PACKET_SIZE);
|
||||
memset(cbuf, 0x00, X56_CONTROLLER_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up init packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x09;
|
||||
buf[0x02] = 0x02;
|
||||
buf[0x03] = brightness;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up color packet |
|
||||
\*-----------------------------------------------------*/
|
||||
cbuf[0x00] = 0x09;
|
||||
cbuf[0x02] = 0x03;
|
||||
cbuf[0x03] = RGBGetRValue(color);
|
||||
cbuf[0x04] = RGBGetGValue(color);
|
||||
cbuf[0x05] = RGBGetBValue(color);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packets |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, buf, X56_CONTROLLER_PACKET_SIZE);
|
||||
hid_send_feature_report(dev, cbuf, X56_CONTROLLER_PACKET_SIZE);
|
||||
|
||||
}
|
||||
|
||||
void LogitechX56Controller::Save()
|
||||
{
|
||||
uint8_t buffer[X56_CONTROLLER_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buffer, 0x00, X56_CONTROLLER_PACKET_SIZE);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up init packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buffer[0x00] = 0x01;
|
||||
buffer[0x01] = 0x01;
|
||||
|
||||
hid_send_feature_report(dev, buffer, X56_CONTROLLER_PACKET_SIZE);
|
||||
}
|
||||
@@ -1,38 +1,38 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechX56Controller.h |
|
||||
| |
|
||||
| Driver for Logitech X56 |
|
||||
| |
|
||||
| Edbgon 11 Jun 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 "RGBController.h"
|
||||
|
||||
#define X56_CONTROLLER_PACKET_SIZE 64
|
||||
|
||||
class LogitechX56Controller
|
||||
{
|
||||
public:
|
||||
LogitechX56Controller(hid_device* dev_handle, const char* path, std::string dev_name);
|
||||
|
||||
~LogitechX56Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetColor(RGBColor colors, uint8_t brightness);
|
||||
void Save();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechX56Controller.h |
|
||||
| |
|
||||
| Driver for Logitech X56 |
|
||||
| |
|
||||
| Edbgon 11 Jun 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 "RGBController.h"
|
||||
|
||||
#define X56_CONTROLLER_PACKET_SIZE 64
|
||||
|
||||
class LogitechX56Controller
|
||||
{
|
||||
public:
|
||||
LogitechX56Controller(hid_device* dev_handle, const char* path, std::string dev_name);
|
||||
|
||||
~LogitechX56Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetColor(RGBColor colors, uint8_t brightness);
|
||||
void Save();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
};
|
||||
+110
-110
@@ -1,110 +1,110 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechX56.cpp |
|
||||
| |
|
||||
| RGBController for Logitech X56 |
|
||||
| |
|
||||
| Edbgon 11 Jun 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechX56.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech X56
|
||||
@category Gamepad
|
||||
@type USB
|
||||
@save :white_check_mark:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectLogitechX56
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechX56::RGBController_LogitechX56(LogitechX56Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_GAMEPAD;
|
||||
description = "Logitech X56 Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
Direct.brightness_min = 0x00;
|
||||
Direct.brightness_max = 0x64;
|
||||
Direct.brightness = 0x64;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechX56::~RGBController_LogitechX56()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechX56::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Each device has only one zone and LED |
|
||||
\*---------------------------------------------------------*/
|
||||
zone x56_zone;
|
||||
x56_zone.name = "X56";
|
||||
x56_zone.type = ZONE_TYPE_SINGLE;
|
||||
x56_zone.leds_min = 1;
|
||||
x56_zone.leds_max = 1;
|
||||
x56_zone.leds_count = 1;
|
||||
x56_zone.matrix_map = NULL;
|
||||
zones.push_back(x56_zone);
|
||||
|
||||
led x56_led;
|
||||
x56_led.name = "X56";
|
||||
leds.push_back(x56_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechX56::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechX56::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetColor(colors[0], modes[active_mode].brightness);
|
||||
}
|
||||
|
||||
void RGBController_LogitechX56::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Packet expects both LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechX56::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Packet expects both LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechX56::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechX56::DeviceSaveMode()
|
||||
{
|
||||
controller->Save();
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechX56.cpp |
|
||||
| |
|
||||
| RGBController for Logitech X56 |
|
||||
| |
|
||||
| Edbgon 11 Jun 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LogitechX56.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Logitech X56
|
||||
@category Gamepad
|
||||
@type USB
|
||||
@save :white_check_mark:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectLogitechX56
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_LogitechX56::RGBController_LogitechX56(LogitechX56Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "Logitech";
|
||||
type = DEVICE_TYPE_GAMEPAD;
|
||||
description = "Logitech X56 Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
Direct.brightness_min = 0x00;
|
||||
Direct.brightness_max = 0x64;
|
||||
Direct.brightness = 0x64;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LogitechX56::~RGBController_LogitechX56()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LogitechX56::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Each device has only one zone and LED |
|
||||
\*---------------------------------------------------------*/
|
||||
zone x56_zone;
|
||||
x56_zone.name = "X56";
|
||||
x56_zone.type = ZONE_TYPE_SINGLE;
|
||||
x56_zone.leds_min = 1;
|
||||
x56_zone.leds_max = 1;
|
||||
x56_zone.leds_count = 1;
|
||||
x56_zone.matrix_map = NULL;
|
||||
zones.push_back(x56_zone);
|
||||
|
||||
led x56_led;
|
||||
x56_led.name = "X56";
|
||||
leds.push_back(x56_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LogitechX56::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_LogitechX56::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetColor(colors[0], modes[active_mode].brightness);
|
||||
}
|
||||
|
||||
void RGBController_LogitechX56::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Packet expects both LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechX56::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Packet expects both LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechX56::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LogitechX56::DeviceSaveMode()
|
||||
{
|
||||
controller->Save();
|
||||
}
|
||||
@@ -1,36 +1,36 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechX56.h |
|
||||
| |
|
||||
| RGBController for Logitech X56 |
|
||||
| |
|
||||
| Edbgon 11 Jun 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechX56Controller.h"
|
||||
|
||||
class RGBController_LogitechX56 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechX56(LogitechX56Controller* controller_ptr);
|
||||
~RGBController_LogitechX56();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
LogitechX56Controller* controller;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LogitechX56.h |
|
||||
| |
|
||||
| RGBController for Logitech X56 |
|
||||
| |
|
||||
| Edbgon 11 Jun 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "LogitechX56Controller.h"
|
||||
|
||||
class RGBController_LogitechX56 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LogitechX56(LogitechX56Controller* controller_ptr);
|
||||
~RGBController_LogitechX56();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
LogitechX56Controller* controller;
|
||||
};
|
||||
Reference in new issue
Block a user