Publish LumaOps source
This commit is contained in:
+56
@@ -0,0 +1,56 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| GenesisXenon200Controller.cpp |
|
||||
| |
|
||||
| Driver for Genesis Xenon 200 mouse |
|
||||
| |
|
||||
| chrabonszcz Jul 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "GenesisXenon200Controller.h"
|
||||
|
||||
GenesisXenon200Controller::GenesisXenon200Controller(hid_device* dev_handle, hid_device* cmd_dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
cmd_dev = cmd_dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
GenesisXenon200Controller::~GenesisXenon200Controller()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string GenesisXenon200Controller::GetLocationString()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string GenesisXenon200Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
void GenesisXenon200Controller::SaveMode(unsigned char mode, unsigned char value, RGBColor color)
|
||||
{
|
||||
unsigned char usb_buf[154];
|
||||
|
||||
usb_buf[0] = 0x04;
|
||||
|
||||
hid_get_feature_report(dev, usb_buf, 154);
|
||||
|
||||
usb_buf[0x5D] = mode;
|
||||
usb_buf[0x60] = value;
|
||||
usb_buf[0x61] = RGBGetRValue(color);
|
||||
usb_buf[0x62] = RGBGetGValue(color);
|
||||
usb_buf[0x63] = RGBGetBValue(color);
|
||||
|
||||
hid_send_feature_report(dev, usb_buf, 154);
|
||||
|
||||
usb_buf[0] = 0x08;
|
||||
hid_get_feature_report(cmd_dev, usb_buf, 9);
|
||||
hid_send_feature_report(cmd_dev, usb_buf, 9);
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| GenesisXenon200Controller.h |
|
||||
| |
|
||||
| Driver for Genesis Xenon 200 mouse |
|
||||
| |
|
||||
| chrabonszcz Jul 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
class GenesisXenon200Controller
|
||||
{
|
||||
public:
|
||||
GenesisXenon200Controller(hid_device* dev_handle, hid_device* cmd_dev_handle, const char* path, std::string dev_name);
|
||||
~GenesisXenon200Controller();
|
||||
|
||||
std::string GetLocationString();
|
||||
std::string GetNameString();
|
||||
|
||||
void SaveMode(unsigned char mode, unsigned char value, RGBColor color);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
hid_device* cmd_dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
};
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_GenesisXenon200.cpp |
|
||||
| |
|
||||
| RGBController for Genesis Xenon 200 mouse |
|
||||
| |
|
||||
| chrabonszcz Jul 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Genesis Xenon 200
|
||||
@type USB
|
||||
@save :white_check_mark:
|
||||
@direct :x:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectSinowealthMouse
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_GenesisXenon200.h"
|
||||
|
||||
RGBController_GenesisXenon200::RGBController_GenesisXenon200(GenesisXenon200Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Genesis";
|
||||
description = "Genesis Xenon 200 Mouse Device";
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
location = controller->GetLocationString();
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = GENESIS_XENON_200_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.brightness = 1;
|
||||
Static.brightness_min = 0;
|
||||
Static.brightness_max = 2;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = GENESIS_XENON_200_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.speed = 1;
|
||||
Breathing.speed_min = 0;
|
||||
Breathing.speed_max = 2;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1);
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode SpectrumCycle;
|
||||
SpectrumCycle.name = "Spectrum Cycle";
|
||||
SpectrumCycle.value = GENESIS_XENON_200_MODE_SPECTRUM_CYCLE;
|
||||
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
SpectrumCycle.color_mode = MODE_COLORS_NONE;
|
||||
SpectrumCycle.speed = 1;
|
||||
SpectrumCycle.speed_min = 0;
|
||||
SpectrumCycle.speed_max = 2;
|
||||
modes.push_back(SpectrumCycle);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = GENESIS_XENON_200_MODE_OFF;
|
||||
Off.flags = MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
RGBController_GenesisXenon200::~RGBController_GenesisXenon200()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_GenesisXenon200::DeviceUpdateMode()
|
||||
{
|
||||
RGBColor color = 0;
|
||||
unsigned char value = 0;
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
color = modes[active_mode].colors[0];
|
||||
}
|
||||
|
||||
switch(modes[active_mode].value)
|
||||
{
|
||||
case GENESIS_XENON_200_MODE_STATIC:
|
||||
|
||||
value = GENESIS_XENON_200_STATIC_BRIGHTESS_VALUES[modes[active_mode].brightness];
|
||||
break;
|
||||
|
||||
case GENESIS_XENON_200_MODE_BREATHING:
|
||||
|
||||
value = GENESIS_XENON_200_BREATHING_SPEED_VALUES[modes[active_mode].speed];
|
||||
break;
|
||||
|
||||
case GENESIS_XENON_200_MODE_SPECTRUM_CYCLE:
|
||||
|
||||
value = GENESIS_XENON_200_SPECTRUM_CYCLE_SPEED_VALUES[modes[active_mode].speed];
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
controller->SaveMode(modes[active_mode].value, value, color);
|
||||
}
|
||||
|
||||
void RGBController_GenesisXenon200::DeviceUpdateLEDs()
|
||||
{
|
||||
DeviceUpdateMode();
|
||||
}
|
||||
|
||||
void RGBController_GenesisXenon200::DeviceSaveMode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_GenesisXenon200::SetupZones()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_GenesisXenon200::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_GenesisXenon200::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_GenesisXenon200::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_GenesisXenon200.h |
|
||||
| |
|
||||
| RGBController for Genesis Xenon 200 mouse |
|
||||
| |
|
||||
| chrabonszcz Jul 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GenesisXenon200Controller.h"
|
||||
#include "RGBController.h"
|
||||
|
||||
#define GENESIS_XENON_200_MODE_STATIC 0x18
|
||||
#define GENESIS_XENON_200_MODE_BREATHING 0x12
|
||||
#define GENESIS_XENON_200_MODE_SPECTRUM_CYCLE 0x14
|
||||
#define GENESIS_XENON_200_MODE_OFF 0x11
|
||||
|
||||
const unsigned char GENESIS_XENON_200_STATIC_BRIGHTESS_VALUES[] {0x11, 0x51, 0xA1};
|
||||
const unsigned char GENESIS_XENON_200_BREATHING_SPEED_VALUES[] {0x51, 0x31, 0x11};
|
||||
const unsigned char GENESIS_XENON_200_SPECTRUM_CYCLE_SPEED_VALUES[] {0xC1, 0x81, 0x41};
|
||||
|
||||
class RGBController_GenesisXenon200 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_GenesisXenon200(GenesisXenon200Controller* controller_ptr);
|
||||
~RGBController_GenesisXenon200();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
GenesisXenon200Controller* controller;
|
||||
};
|
||||
+253
@@ -0,0 +1,253 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_Sinowealth1007.cpp |
|
||||
| |
|
||||
| RGBController for Sinowealth mice with PID 1007 |
|
||||
| |
|
||||
| Moon_darker (Vaker) 02 Feb 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_Sinowealth1007.h"
|
||||
|
||||
static const char *led_names[] =
|
||||
{
|
||||
"Top Left",
|
||||
"Middle Left",
|
||||
"Bottom Left",
|
||||
"Bottom Middle",
|
||||
"Bottom Right",
|
||||
"Middle Right",
|
||||
"Top Right"
|
||||
};
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Sinowealth 1007 Mouse
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :x:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectSinowealthMouse
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_Sinowealth1007::RGBController_Sinowealth1007(SinowealthController1007* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetName();
|
||||
vendor = "ZET";
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = "ZET Fury Pro Mouse Device";
|
||||
location = controller->GetLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Custom;
|
||||
Custom.name = "Custom";
|
||||
Custom.value = ZET_FURY_PRO_MODE_CUSTOM;
|
||||
Custom.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Custom.color_mode = MODE_COLORS_PER_LED;
|
||||
Custom.speed = ZET_FURY_PRO_SPEED_DEF;
|
||||
modes.push_back(Custom);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = ZET_FURY_PRO_MODE_OFF;
|
||||
Off.flags = MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
Off.speed = ZET_FURY_PRO_SPEED_DEF;
|
||||
Off.brightness = ZET_FURY_PRO_BRIGHTNESS_DEF;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow Wave";
|
||||
Rainbow.value = ZET_FURY_PRO_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
Rainbow.speed_min = ZET_FURY_PRO_SPEED_MIN;
|
||||
Rainbow.speed_max = ZET_FURY_PRO_SPEED_MAX;
|
||||
Rainbow.speed = ZET_FURY_PRO_SPEED_DEF;
|
||||
Rainbow.direction = MODE_DIRECTION_RIGHT;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = ZET_FURY_PRO_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.brightness_min = ZET_FURY_PRO_BRIGHTNESS_MIN;
|
||||
Static.brightness_max = ZET_FURY_PRO_BRIGHTNESS_MAX;
|
||||
Static.brightness = ZET_FURY_PRO_BRIGHTNESS_DEF;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(Static.colors_max);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = ZET_FURY_PRO_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.speed_min = ZET_FURY_PRO_SPEED_MIN;
|
||||
Breathing.speed_max = ZET_FURY_PRO_SPEED_MAX;
|
||||
Breathing.speed = ZET_FURY_PRO_SPEED_DEF;
|
||||
Breathing.colors_min = 7;
|
||||
Breathing.colors_max = 7;
|
||||
Breathing.colors.resize(Breathing.colors_max);
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Pendulum;
|
||||
Pendulum.name = "Pendulum";
|
||||
Pendulum.value = ZET_FURY_PRO_MODE_PENDULUM;
|
||||
Pendulum.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED;
|
||||
Pendulum.color_mode = MODE_COLORS_NONE;
|
||||
Pendulum.speed_min = ZET_FURY_PRO_SPEED_MIN;
|
||||
Pendulum.speed_max = ZET_FURY_PRO_SPEED_MAX;
|
||||
Pendulum.speed = ZET_FURY_PRO_SPEED_DEF;
|
||||
modes.push_back(Pendulum);
|
||||
|
||||
mode Spectrum;
|
||||
Spectrum.name = "Spectrum Cycle";
|
||||
Spectrum.value = ZET_FURY_PRO_MODE_SPECTRUM;
|
||||
Spectrum.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED;
|
||||
Spectrum.color_mode = MODE_COLORS_NONE;
|
||||
Spectrum.speed_min = ZET_FURY_PRO_SPEED_MIN;
|
||||
Spectrum.speed_max = ZET_FURY_PRO_SPEED_MAX;
|
||||
Spectrum.speed = ZET_FURY_PRO_SPEED_DEF;
|
||||
modes.push_back(Spectrum);
|
||||
|
||||
mode TwoColors;
|
||||
TwoColors.name = "Two Colors"; // Should this be called "Flashing Two Colors" or smth like that maybe? Rapidly changes between 2 colors
|
||||
TwoColors.value = ZET_FURY_PRO_MODE_TWO_COLORS;
|
||||
TwoColors.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
TwoColors.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
TwoColors.colors_min = 2;
|
||||
TwoColors.colors_max = 2;
|
||||
TwoColors.colors.resize(TwoColors.colors_max);
|
||||
modes.push_back(TwoColors);
|
||||
|
||||
mode Reactive;
|
||||
Reactive.name = "Reactive";
|
||||
Reactive.value = ZET_FURY_PRO_MODE_REACTIVE;
|
||||
Reactive.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED;
|
||||
Reactive.color_mode = MODE_COLORS_RANDOM;
|
||||
Reactive.speed_min = ZET_FURY_PRO_SPEED_MIN;
|
||||
Reactive.speed_max = ZET_FURY_PRO_SPEED_MAX;
|
||||
Reactive.speed = ZET_FURY_PRO_SPEED_DEF;
|
||||
Reactive.colors_min = 7;
|
||||
Reactive.colors_max = 7;
|
||||
Reactive.colors.resize(Reactive.colors_max);
|
||||
modes.push_back(Reactive);
|
||||
|
||||
mode Flicker;
|
||||
Flicker.name = "Flicker"; // One color fluctuates around max brightness for some time, then changes to another
|
||||
Flicker.value = ZET_FURY_PRO_MODE_FLICKER;
|
||||
Flicker.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR;
|
||||
Flicker.color_mode = MODE_COLORS_NONE;
|
||||
Flicker.speed_min = ZET_FURY_PRO_SPEED_MIN;
|
||||
Flicker.speed_max = ZET_FURY_PRO_SPEED_MAX;
|
||||
Flicker.speed = ZET_FURY_PRO_SPEED_DEF;
|
||||
Flicker.direction = MODE_DIRECTION_RIGHT;
|
||||
modes.push_back(Flicker);
|
||||
|
||||
mode Rain;
|
||||
Rain.name = "Rain"; // More like bad LSD trip
|
||||
Rain.value = ZET_FURY_PRO_MODE_RAIN;
|
||||
Rain.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED;
|
||||
Rain.color_mode = MODE_COLORS_NONE;
|
||||
Rain.speed_min = ZET_FURY_PRO_SPEED_MIN;
|
||||
Rain.speed_max = ZET_FURY_PRO_SPEED_MAX;
|
||||
Rain.speed = ZET_FURY_PRO_SPEED_DEF;
|
||||
modes.push_back(Rain);
|
||||
|
||||
mode Snake;
|
||||
Snake.name = "Snake";
|
||||
Snake.value = ZET_FURY_PRO_MODE_SNAKE;
|
||||
Snake.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED;
|
||||
Snake.color_mode = MODE_COLORS_NONE;
|
||||
Snake.speed_min = ZET_FURY_PRO_SPEED_MIN;
|
||||
Snake.speed_max = ZET_FURY_PRO_SPEED_MAX;
|
||||
Snake.speed = ZET_FURY_PRO_SPEED_DEF;
|
||||
modes.push_back(Snake);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_Sinowealth1007::~RGBController_Sinowealth1007()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_Sinowealth1007::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Create a single zone |
|
||||
\*---------------------------------------------------------*/
|
||||
zone new_zone;
|
||||
new_zone.name = "Mouse";
|
||||
new_zone.type = ZONE_TYPE_LINEAR;
|
||||
new_zone.leds_min = controller->GetLEDCount();
|
||||
new_zone.leds_max = controller->GetLEDCount();
|
||||
new_zone.leds_count = controller->GetLEDCount();
|
||||
new_zone.matrix_map = NULL;
|
||||
zones.push_back(new_zone);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
for (unsigned int led_idx = 0; led_idx < new_zone.leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = led_names[led_idx];
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_Sinowealth1007::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_Sinowealth1007::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetLEDColors(colors);
|
||||
}
|
||||
|
||||
void RGBController_Sinowealth1007::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_Sinowealth1007::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_Sinowealth1007::DeviceUpdateMode()
|
||||
{
|
||||
unsigned char random = (modes[active_mode].flags & MODE_FLAG_HAS_RANDOM_COLOR) ? (unsigned char)ZET_FURY_PRO_SUBMODE_SET_COLOR : 0x00;
|
||||
random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM) ? (unsigned char)ZET_FURY_PRO_SUBMODE_RANDOM : random;
|
||||
|
||||
if (modes[active_mode].value == ZET_FURY_PRO_MODE_BREATHING)
|
||||
{
|
||||
random = ZET_FURY_PRO_SUBMODE_SET_COLOR; // An unfortunate exception that has no random option but requires this
|
||||
}
|
||||
|
||||
if (!(modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR))
|
||||
{
|
||||
modes[active_mode].direction = MODE_DIRECTION_RIGHT; // Left and right are backwards, and we don't want to always append 0x80
|
||||
}
|
||||
|
||||
controller->SetMode(modes[active_mode].value,
|
||||
(modes[active_mode].speed ? modes[active_mode].speed : modes[active_mode].brightness),
|
||||
modes[active_mode].direction ? ZET_FURY_PRO_DIR_RIGHT : ZET_FURY_PRO_DIR_LEFT,
|
||||
modes[active_mode].colors,
|
||||
random,
|
||||
(modes[active_mode].color_mode == MODE_COLORS_PER_LED));
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_Sinowealth1007.h |
|
||||
| |
|
||||
| RGBController for Sinowealth mice with PID 1007 |
|
||||
| |
|
||||
| Moon_darker (Vaker) 25 Jan 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "SinowealthController1007.h"
|
||||
|
||||
class RGBController_Sinowealth1007 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_Sinowealth1007(SinowealthController1007* controller_ptr);
|
||||
~RGBController_Sinowealth1007();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
SinowealthController1007* controller;
|
||||
};
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| SinowealthController1007.cpp |
|
||||
| |
|
||||
| Driver for Sinowealth mice with PID 1007 |
|
||||
| |
|
||||
| Moon_darker (Vaker) 02 Feb 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogManager.h"
|
||||
#include "SinowealthController1007.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
SinowealthController1007::SinowealthController1007(hid_device* dev, char *_path, std::string dev_name)
|
||||
{
|
||||
this->dev = dev;
|
||||
this->location = _path;
|
||||
this->name = dev_name;
|
||||
|
||||
this->led_count = 7;
|
||||
this->current_mode = ZET_FURY_PRO_MODE_CUSTOM + ZET_FURY_PRO_SPEED_DEF;
|
||||
this->current_direction = ZET_FURY_PRO_DIR_RIGHT;
|
||||
|
||||
memset(device_colors, 0x00, sizeof(device_colors));
|
||||
}
|
||||
|
||||
SinowealthController1007::~SinowealthController1007()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string SinowealthController1007::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string SinowealthController1007::GetName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
unsigned int SinowealthController1007::GetLEDCount()
|
||||
{
|
||||
return(led_count);
|
||||
}
|
||||
|
||||
std::string SinowealthController1007::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 SinowealthController1007::SetLEDColors(const std::vector<RGBColor>& colors)
|
||||
{
|
||||
memset(device_colors, 0x00, sizeof(device_colors));
|
||||
|
||||
unsigned int color_counter = 0;
|
||||
for (RGBColor color: colors)
|
||||
{
|
||||
unsigned int pkt_pointer = (color_counter * 3); // 3 bytes per color
|
||||
|
||||
device_colors[pkt_pointer] = RGBGetRValue(color);
|
||||
device_colors[pkt_pointer + 1] = RGBGetGValue(color);
|
||||
device_colors[pkt_pointer + 2] = RGBGetBValue(color);
|
||||
|
||||
if (++color_counter == 7) break;
|
||||
}
|
||||
|
||||
SendPacket();
|
||||
}
|
||||
|
||||
void SinowealthController1007::SetMode(
|
||||
unsigned char mode,
|
||||
unsigned char spd_or_lum,
|
||||
unsigned char direction,
|
||||
const std::vector<RGBColor>& colors,
|
||||
unsigned char random,
|
||||
bool has_per_led_colors)
|
||||
{
|
||||
current_mode = mode + (spd_or_lum ? spd_or_lum : ZET_FURY_PRO_SPEED_DEF);
|
||||
current_direction = random ? random : direction;
|
||||
|
||||
if (!has_per_led_colors)
|
||||
{
|
||||
memset(device_colors, 0x00, sizeof(device_colors));
|
||||
SetLEDColors(colors);
|
||||
}
|
||||
}
|
||||
|
||||
void SinowealthController1007::SendPacket()
|
||||
{
|
||||
if (GetProfile() < 0) return;
|
||||
|
||||
unsigned char usb_buf[ZET_FURY_PRO_STATE_BUFFER_LENGTH];
|
||||
memcpy(usb_buf, device_configuration, sizeof(usb_buf));
|
||||
memcpy(usb_buf + 23, device_colors, sizeof(device_colors)); // colors are bytes 23-43 in RGB format counting from 0
|
||||
|
||||
usb_buf[21] = current_mode;
|
||||
usb_buf[22] = current_direction;
|
||||
|
||||
hid_send_feature_report(dev, usb_buf, sizeof(usb_buf));
|
||||
}
|
||||
|
||||
int SinowealthController1007::GetProfile()
|
||||
{
|
||||
int bytesReceived;
|
||||
|
||||
memset(device_configuration, 0x00, ZET_FURY_PRO_STATE_BUFFER_LENGTH);
|
||||
device_configuration[0] = 0x04;
|
||||
|
||||
bytesReceived = hid_get_feature_report(dev, device_configuration, ZET_FURY_PRO_STATE_BUFFER_LENGTH);
|
||||
if (bytesReceived < 0)
|
||||
{
|
||||
LOG_ERROR("[ZET Fury Pro] Error reading device configuration!");
|
||||
}
|
||||
|
||||
return bytesReceived;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| SinowealthController1007.h |
|
||||
| |
|
||||
| Driver for Sinowealth mice with PID 1007 |
|
||||
| |
|
||||
| Moon_darker (Vaker) 25 Jan 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define ZET_FURY_PRO_STATE_BUFFER_LENGTH 59
|
||||
#define ZET_FURY_PRO_COLOR_BUFFER_LENGTH 21
|
||||
|
||||
#define ZET_FURY_PRO_BRIGHTNESS_MIN 1
|
||||
#define ZET_FURY_PRO_BRIGHTNESS_MAX 9
|
||||
#define ZET_FURY_PRO_BRIGHTNESS_DEF 9
|
||||
|
||||
#define ZET_FURY_PRO_SPEED_MIN 1
|
||||
#define ZET_FURY_PRO_SPEED_MAX 3
|
||||
#define ZET_FURY_PRO_SPEED_DEF 2
|
||||
|
||||
enum
|
||||
{
|
||||
ZET_FURY_PRO_MODE_OFF = 0x00,
|
||||
ZET_FURY_PRO_MODE_RAINBOW = 0x10,
|
||||
ZET_FURY_PRO_MODE_STATIC = 0x20,
|
||||
ZET_FURY_PRO_MODE_BREATHING = 0x30,
|
||||
ZET_FURY_PRO_MODE_PENDULUM = 0x40,
|
||||
ZET_FURY_PRO_MODE_SPECTRUM = 0x50,
|
||||
ZET_FURY_PRO_MODE_CUSTOM = 0x60,
|
||||
ZET_FURY_PRO_MODE_TWO_COLORS = 0x70,
|
||||
ZET_FURY_PRO_MODE_REACTIVE = 0x80,
|
||||
ZET_FURY_PRO_MODE_FLICKER = 0x90,
|
||||
ZET_FURY_PRO_MODE_RAIN = 0xA0,
|
||||
ZET_FURY_PRO_MODE_SNAKE = 0xB0,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ZET_FURY_PRO_SUBMODE_SET_COLOR = 0x07,
|
||||
ZET_FURY_PRO_SUBMODE_RANDOM = 0x80,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ZET_FURY_PRO_DIR_LEFT = 0x80,
|
||||
ZET_FURY_PRO_DIR_RIGHT = 0x00,
|
||||
};
|
||||
|
||||
class SinowealthController1007
|
||||
{
|
||||
public:
|
||||
SinowealthController1007(hid_device* dev, char *_path, std::string dev_name);
|
||||
~SinowealthController1007();
|
||||
|
||||
unsigned int GetLEDCount();
|
||||
std::string GetLocation();
|
||||
std::string GetName();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetLEDColors(const std::vector<RGBColor>& colors);
|
||||
void SetMode(unsigned char mode, unsigned char spd_or_lum, unsigned char direction, const std::vector<RGBColor>& colors, unsigned char random, bool has_per_led_colors);
|
||||
int GetProfile();
|
||||
void SendPacket();
|
||||
private:
|
||||
hid_device* dev;
|
||||
|
||||
unsigned int led_count;
|
||||
|
||||
unsigned char current_mode;
|
||||
unsigned char current_direction;
|
||||
unsigned char device_configuration[ZET_FURY_PRO_STATE_BUFFER_LENGTH];
|
||||
unsigned char device_colors[ZET_FURY_PRO_COLOR_BUFFER_LENGTH];
|
||||
|
||||
std::string location;
|
||||
std::string name;
|
||||
};
|
||||
@@ -0,0 +1,249 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_Sinowealth.cpp |
|
||||
| |
|
||||
| RGBController for Sinowealth mice, including Glorious |
|
||||
| |
|
||||
| Niels Westphal (crashniels) 20 May 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_Sinowealth.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Sinowealth Mice
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :x:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectSinowealthMouse
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_Sinowealth::RGBController_Sinowealth(SinowealthController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetName();
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = "Sinowealth Device";
|
||||
location = controller->GetLocation();
|
||||
serial = controller->GetSerialString();
|
||||
version = controller->GetFirmwareVersion();
|
||||
|
||||
mode Static;
|
||||
Static.name = "Custom";
|
||||
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Static.brightness_min = GLORIOUS_BRIGHTNESS_LOW;
|
||||
Static.brightness = GLORIOUS_BRIGHTNESS_NORMAL;
|
||||
Static.brightness_max = GLORIOUS_BRIGHTNESS_HIGH;
|
||||
Static.color_mode = MODE_COLORS_PER_LED;
|
||||
Static.value = GLORIOUS_MODE_STATIC;
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.flags = MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
Off.value = GLORIOUS_MODE_OFF;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Rainbow.speed_min = GLORIOUS_SPEED_SLOW;
|
||||
Rainbow.speed = GLORIOUS_SPEED_NORMAL;
|
||||
Rainbow.speed_max = GLORIOUS_SPEED_FAST;
|
||||
Rainbow.direction = MODE_DIRECTION_UP;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
Rainbow.value = GLORIOUS_MODE_RAINBOW;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode SpectrumBreathing;
|
||||
SpectrumBreathing.name = "Seemless Breathing";
|
||||
SpectrumBreathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
SpectrumBreathing.speed_min = GLORIOUS_SPEED_SLOW;
|
||||
SpectrumBreathing.speed = GLORIOUS_SPEED_NORMAL;
|
||||
SpectrumBreathing.speed_max = GLORIOUS_SPEED_FAST;
|
||||
SpectrumBreathing.colors_min = 7;
|
||||
SpectrumBreathing.colors_max = 7;
|
||||
SpectrumBreathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
SpectrumBreathing.value = GLORIOUS_MODE_SPECTRUM_BREATING;
|
||||
SpectrumBreathing.colors.resize(7);
|
||||
modes.push_back(SpectrumBreathing);
|
||||
|
||||
mode Chase;
|
||||
Chase.name = "Tail";
|
||||
Chase.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Chase.speed_min = GLORIOUS_SPEED_SLOW;
|
||||
Chase.speed = GLORIOUS_SPEED_NORMAL;
|
||||
Chase.speed_max = GLORIOUS_SPEED_FAST;
|
||||
Chase.brightness_min = GLORIOUS_BRIGHTNESS_LOW;
|
||||
Chase.brightness = GLORIOUS_BRIGHTNESS_NORMAL;
|
||||
Chase.brightness_max = GLORIOUS_BRIGHTNESS_HIGH;
|
||||
Chase.color_mode = MODE_COLORS_NONE;
|
||||
Chase.value = GLORIOUS_MODE_TAIL;
|
||||
modes.push_back(Chase);
|
||||
|
||||
mode SpectrumCycle;
|
||||
SpectrumCycle.name = "Spectrum Cycle";
|
||||
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
SpectrumCycle.speed_min = GLORIOUS_SPEED_SLOW;
|
||||
SpectrumCycle.speed = GLORIOUS_SPEED_NORMAL;
|
||||
SpectrumCycle.speed_max = GLORIOUS_SPEED_FAST;
|
||||
SpectrumCycle.color_mode = MODE_COLORS_NONE;
|
||||
SpectrumCycle.value = GLORIOUS_MODE_SPECTRUM_CYCLE;
|
||||
modes.push_back(SpectrumCycle);
|
||||
|
||||
mode Flashing;
|
||||
Flashing.name = "Rave";
|
||||
Flashing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Flashing.speed_min = GLORIOUS_SPEED_SLOW;
|
||||
Flashing.speed = GLORIOUS_SPEED_NORMAL;
|
||||
Flashing.speed_max = GLORIOUS_SPEED_FAST;
|
||||
Flashing.brightness_min = GLORIOUS_BRIGHTNESS_LOW;
|
||||
Flashing.brightness = GLORIOUS_BRIGHTNESS_NORMAL;
|
||||
Flashing.brightness_max = GLORIOUS_BRIGHTNESS_HIGH;
|
||||
Flashing.colors_min = 2;
|
||||
Flashing.colors_max = 2;
|
||||
Flashing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Flashing.value = GLORIOUS_MODE_RAVE;
|
||||
Flashing.colors.resize(2);
|
||||
modes.push_back(Flashing);
|
||||
|
||||
mode Epilepsy;
|
||||
Epilepsy.name = "Epilepsy";
|
||||
Epilepsy.flags = MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Epilepsy.color_mode = MODE_COLORS_NONE;
|
||||
Epilepsy.value = GLORIOUS_MODE_EPILEPSY;
|
||||
modes.push_back(Epilepsy);
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Wave.speed_min = GLORIOUS_SPEED_SLOW;
|
||||
Wave.speed = GLORIOUS_SPEED_NORMAL;
|
||||
Wave.speed_max = GLORIOUS_SPEED_FAST;
|
||||
Wave.brightness_min = GLORIOUS_BRIGHTNESS_LOW;
|
||||
Wave.brightness = GLORIOUS_BRIGHTNESS_NORMAL;
|
||||
Wave.brightness_max = GLORIOUS_BRIGHTNESS_HIGH;
|
||||
Wave.color_mode = MODE_COLORS_NONE;
|
||||
Wave.value = GLORIOUS_MODE_WAVE;
|
||||
modes.push_back(Wave);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Breathing.speed_min = GLORIOUS_SPEED_SLOW;
|
||||
Breathing.speed = GLORIOUS_SPEED_NORMAL;
|
||||
Breathing.speed_max = GLORIOUS_SPEED_FAST;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.value = GLORIOUS_MODE_BREATHING;
|
||||
Breathing.colors.resize(1);
|
||||
modes.push_back(Breathing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_Sinowealth::~RGBController_Sinowealth()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_Sinowealth::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Create a single zone |
|
||||
\*---------------------------------------------------------*/
|
||||
zone new_zone;
|
||||
new_zone.name = "Mouse";
|
||||
new_zone.type = ZONE_TYPE_SINGLE;
|
||||
new_zone.leds_min = controller->GetLEDCount();
|
||||
new_zone.leds_max = controller->GetLEDCount();
|
||||
new_zone.leds_count = controller->GetLEDCount();
|
||||
new_zone.matrix_map = NULL;
|
||||
zones.push_back(new_zone);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
for(std::size_t led_idx = 0; led_idx < zones[0].leds_count; led_idx++)
|
||||
{
|
||||
led* new_led = new led();
|
||||
new_led->name = "Mouse LED";
|
||||
leds.push_back(*new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_Sinowealth::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_Sinowealth::DeviceUpdateLEDs()
|
||||
{
|
||||
DeviceUpdateMode();
|
||||
}
|
||||
|
||||
void RGBController_Sinowealth::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_Sinowealth::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_Sinowealth::DeviceUpdateMode()
|
||||
{
|
||||
unsigned int direction = 0;
|
||||
unsigned int speed = GLORIOUS_SPEED_FAST;
|
||||
unsigned int brightness = GLORIOUS_BRIGHTNESS_HIGH;
|
||||
|
||||
if (modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
speed = modes[active_mode].speed;
|
||||
}
|
||||
|
||||
if (modes[active_mode].flags & MODE_FLAG_HAS_BRIGHTNESS)
|
||||
{
|
||||
brightness = modes[active_mode].brightness;
|
||||
}
|
||||
|
||||
if ((modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR) ||
|
||||
(modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_UD) ||
|
||||
(modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_HV))
|
||||
{
|
||||
if (modes[active_mode].direction == MODE_DIRECTION_UP)
|
||||
{
|
||||
direction = GLORIOUS_DIRECTION_UP;
|
||||
}
|
||||
else
|
||||
{
|
||||
direction = GLORIOUS_DIRECTION_DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
if (modes[active_mode].color_mode == MODE_COLORS_NONE)
|
||||
{
|
||||
controller->SetMode(modes[active_mode].value, speed, brightness, direction, 0);
|
||||
}
|
||||
else if (modes[active_mode].color_mode == MODE_COLORS_PER_LED)
|
||||
{
|
||||
controller->SetMode(modes[active_mode].value, speed, brightness, direction, &colors[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetMode(modes[active_mode].value, speed, brightness, direction, &modes[active_mode].colors[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_Sinowealth.h |
|
||||
| |
|
||||
| RGBController for Sinowealth mice, including Glorious |
|
||||
| |
|
||||
| Niels Westphal (crashniels) 20 May 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "SinowealthController.h"
|
||||
|
||||
class RGBController_Sinowealth : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_Sinowealth(SinowealthController* controller_ptr);
|
||||
~RGBController_Sinowealth();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
SinowealthController* controller;
|
||||
};
|
||||
@@ -0,0 +1,208 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| SinowealthController.cpp |
|
||||
| |
|
||||
| Driver for Sinowealth mice, including Glorious |
|
||||
| |
|
||||
| Niels Westphal (crashniels) 20 May 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogManager.h"
|
||||
#include "SinowealthController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
SinowealthController::SinowealthController(hid_device* dev_data_handle, hid_device* dev_cmd_handle, char *_path, std::string dev_name)
|
||||
{
|
||||
dev_data = dev_data_handle;
|
||||
dev_cmd = dev_cmd_handle;
|
||||
location = _path;
|
||||
name = dev_name;
|
||||
|
||||
led_count = 1;
|
||||
}
|
||||
|
||||
SinowealthController::~SinowealthController()
|
||||
{
|
||||
hid_close(dev_data);
|
||||
|
||||
/*---------------------------------------------------------------------*\
|
||||
| If the dev_cmd handle was passed in as the same device as dev_data |
|
||||
| then attempting to close it a second time will segfault |
|
||||
\*---------------------------------------------------------------------*/
|
||||
if(dev_cmd)
|
||||
{
|
||||
hid_close(dev_cmd);
|
||||
}
|
||||
}
|
||||
|
||||
std::string SinowealthController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string SinowealthController::GetName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
unsigned int SinowealthController::GetLEDCount()
|
||||
{
|
||||
return(led_count);
|
||||
}
|
||||
|
||||
std::string SinowealthController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev_cmd, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string SinowealthController::GetFirmwareVersion()
|
||||
{
|
||||
unsigned char usb_buf[SINOWEALTH_COMMAND_REPORT_SIZE + 1]; // Additional byte for null-terminator
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
usb_buf[0] = 5;
|
||||
usb_buf[1] = 1;
|
||||
|
||||
int ret = hid_send_feature_report(dev_cmd, usb_buf, SINOWEALTH_COMMAND_REPORT_SIZE);
|
||||
if(ret < 0) return("");
|
||||
|
||||
usb_buf[1] = 0;
|
||||
ret = hid_get_feature_report(dev_cmd, usb_buf, SINOWEALTH_COMMAND_REPORT_SIZE);
|
||||
if(ret < 0) return("");
|
||||
|
||||
return std::string(reinterpret_cast<char*>(usb_buf) + 2); // Skip report and command byte
|
||||
}
|
||||
|
||||
void SinowealthController::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char brightness,
|
||||
unsigned char direction,
|
||||
RGBColor* color_buf
|
||||
)
|
||||
{
|
||||
if (GetProfile() < SINOWEALTH_CONFIG_SIZE_MIN) return;
|
||||
|
||||
unsigned char usb_buf[SINOWEALTH_CONFIG_REPORT_SIZE];
|
||||
memcpy(usb_buf, device_configuration, SINOWEALTH_CONFIG_SIZE); // Yes, we only copy 167 bytes back, for now - if anything weird starts happening use SINOWEALTH_CONFIG_REPORT_SIZE
|
||||
|
||||
usb_buf[0x03] = 0x7B; //write to device
|
||||
usb_buf[0x06] = 0x00;
|
||||
|
||||
usb_buf[0x35] = mode;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case GLORIOUS_MODE_RAINBOW:
|
||||
usb_buf[0x36] = ((brightness & 0xF) << 4) | (speed & 0xF);
|
||||
usb_buf[0x37] = direction;
|
||||
break;
|
||||
case GLORIOUS_MODE_STATIC:
|
||||
usb_buf[0x38] = ((brightness & 0xF) << 4);
|
||||
usb_buf[0x39] = RGBGetRValue(color_buf[0]);
|
||||
usb_buf[0x3A] = RGBGetBValue(color_buf[0]);
|
||||
usb_buf[0x3B] = RGBGetGValue(color_buf[0]);
|
||||
break;
|
||||
case GLORIOUS_MODE_SPECTRUM_BREATING:
|
||||
//colours not yet researched
|
||||
usb_buf[0x3C] = ((brightness & 0xF) << 4) | (speed & 0xF);
|
||||
usb_buf[0x3D] = 0x07; //maybe some kind of bank change?+
|
||||
//usb_buf[0x3D] = 0x06;
|
||||
usb_buf[0x3E] = RGBGetRValue(color_buf[0]); //mode 3 red 1
|
||||
usb_buf[0x3F] = RGBGetBValue(color_buf[0]); //mode 3 blue 1
|
||||
usb_buf[0x40] = RGBGetGValue(color_buf[0]); //mode 3 green 1
|
||||
usb_buf[0x41] = RGBGetRValue(color_buf[1]); //mode 3 red 2
|
||||
usb_buf[0x42] = RGBGetBValue(color_buf[1]); //mode 3 blue 2
|
||||
usb_buf[0x43] = RGBGetGValue(color_buf[1]); //mode 3 green 2
|
||||
usb_buf[0x44] = RGBGetRValue(color_buf[2]); //mode 3 red 3
|
||||
usb_buf[0x45] = RGBGetBValue(color_buf[2]); //mode 3 blue 3
|
||||
usb_buf[0x46] = RGBGetGValue(color_buf[2]); //mode 3 green 3
|
||||
usb_buf[0x47] = RGBGetRValue(color_buf[3]); //mode 3 red 4
|
||||
usb_buf[0x48] = RGBGetBValue(color_buf[3]); //mode 3 blue 4
|
||||
usb_buf[0x49] = RGBGetGValue(color_buf[3]); //mode 3 green 4
|
||||
usb_buf[0x4A] = RGBGetRValue(color_buf[4]); //mode 3 red 5
|
||||
usb_buf[0x4B] = RGBGetBValue(color_buf[4]); //mode 3 blue 5
|
||||
usb_buf[0x4C] = RGBGetGValue(color_buf[4]); //mode 3 green 5
|
||||
usb_buf[0x4D] = RGBGetRValue(color_buf[5]); //mode 3 red 6
|
||||
usb_buf[0x4E] = RGBGetBValue(color_buf[5]); //mode 3 blue 6
|
||||
usb_buf[0x4F] = RGBGetGValue(color_buf[5]); //mode 3 green 6
|
||||
usb_buf[0x50] = RGBGetRValue(color_buf[6]); //mode 3 red 7
|
||||
usb_buf[0x51] = RGBGetBValue(color_buf[6]); //mode 3 blue 7
|
||||
usb_buf[0x52] = RGBGetGValue(color_buf[6]); //mode 3 green 7
|
||||
break;
|
||||
case GLORIOUS_MODE_TAIL:
|
||||
usb_buf[0x53] = ((brightness & 0xF) << 4) | (speed & 0xF);
|
||||
break;
|
||||
case GLORIOUS_MODE_SPECTRUM_CYCLE:
|
||||
usb_buf[0x54] = ((brightness & 0xF) << 4) | (speed & 0xF);
|
||||
break;
|
||||
case GLORIOUS_MODE_RAVE:
|
||||
usb_buf[0x74] = ((brightness & 0xF) << 4) | (speed & 0xF);
|
||||
usb_buf[0x75] = RGBGetRValue(color_buf[0]); //mode 7 red 1
|
||||
usb_buf[0x76] = RGBGetBValue(color_buf[0]); //mode 7 blue 1
|
||||
usb_buf[0x77] = RGBGetGValue(color_buf[0]); //mode 7 green 1
|
||||
usb_buf[0x78] = RGBGetRValue(color_buf[1]); //mode 7 red 2
|
||||
usb_buf[0x79] = RGBGetBValue(color_buf[1]); //mode 7 blue 2
|
||||
usb_buf[0x7A] = RGBGetGValue(color_buf[1]); //mode 7 green 2
|
||||
break;
|
||||
case GLORIOUS_MODE_WAVE:
|
||||
usb_buf[0x7C] = ((brightness & 0xF) << 4) | (speed & 0xF);
|
||||
break;
|
||||
case GLORIOUS_MODE_BREATHING:
|
||||
usb_buf[0x7D] = ((brightness & 0xF) << 4) | (speed & 0xF);
|
||||
usb_buf[0x7E] = RGBGetRValue(color_buf[0]); //mode 0a red
|
||||
usb_buf[0x7F] = RGBGetBValue(color_buf[0]); //mode 0a blue
|
||||
usb_buf[0x80] = RGBGetGValue(color_buf[0]); //mode 0a green
|
||||
case GLORIOUS_MODE_OFF:
|
||||
usb_buf[0x81] = 0x00; //mode 0 either 0x00 or 0x03
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
hid_send_feature_report(dev_data, usb_buf, SINOWEALTH_CONFIG_REPORT_SIZE);
|
||||
}
|
||||
|
||||
int SinowealthController::GetProfile()
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[SINOWEALTH_COMMAND_REPORT_SIZE];
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
usb_buf[0] = 0x05;
|
||||
usb_buf[1] = 0x11;
|
||||
|
||||
actual = hid_send_feature_report(dev_cmd, usb_buf, sizeof(usb_buf));
|
||||
|
||||
if (actual != SINOWEALTH_COMMAND_REPORT_SIZE)
|
||||
{
|
||||
LOG_ERROR("[Sinowealth Mouse] Error sending read request!");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(device_configuration, 0x00, SINOWEALTH_CONFIG_REPORT_SIZE);
|
||||
device_configuration[0] = 0x04;
|
||||
|
||||
actual = hid_get_feature_report(dev_data, device_configuration, SINOWEALTH_CONFIG_REPORT_SIZE);
|
||||
|
||||
if (actual < 0)
|
||||
{
|
||||
LOG_ERROR("[Sinowealth Mouse] Error reading device configuration!");
|
||||
}
|
||||
}
|
||||
|
||||
return actual;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| SinowealthController.h |
|
||||
| |
|
||||
| Driver for Sinowealth mice, including Glorious |
|
||||
| |
|
||||
| Niels Westphal (crashniels) 20 May 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define SINOWEALTH_CONFIG_SIZE 167
|
||||
#define SINOWEALTH_CONFIG_SIZE_MIN 131
|
||||
#define SINOWEALTH_CONFIG_REPORT_SIZE 520
|
||||
#define SINOWEALTH_COMMAND_REPORT_SIZE 6
|
||||
|
||||
enum
|
||||
{
|
||||
GLORIOUS_MODE_OFF = 0x00, //does nothing
|
||||
GLORIOUS_MODE_RAINBOW = 0x01,
|
||||
GLORIOUS_MODE_STATIC = 0x02,
|
||||
GLORIOUS_MODE_SPECTRUM_BREATING = 0x03,
|
||||
GLORIOUS_MODE_TAIL = 0x04,
|
||||
GLORIOUS_MODE_SPECTRUM_CYCLE = 0x05,
|
||||
GLORIOUS_MODE_RAVE = 0x07,
|
||||
GLORIOUS_MODE_EPILEPSY = 0x08, //not in the official software
|
||||
GLORIOUS_MODE_WAVE = 0x09,
|
||||
GLORIOUS_MODE_BREATHING = 0x0A,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GLORIOUS_SPEED_SLOW = 0x01,
|
||||
GLORIOUS_SPEED_NORMAL = 0x02,
|
||||
GLORIOUS_SPEED_FAST = 0x03,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GLORIOUS_BRIGHTNESS_LOW = 0x01,
|
||||
GLORIOUS_BRIGHTNESS_NORMAL = 0x02,
|
||||
GLORIOUS_BRIGHTNESS_HIGH = 0x04,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GLORIOUS_DIRECTION_DOWN = 0x00,
|
||||
GLORIOUS_DIRECTION_UP = 0x01,
|
||||
};
|
||||
|
||||
class SinowealthController
|
||||
{
|
||||
public:
|
||||
SinowealthController(hid_device* dev_data_handle, hid_device* dev_cmd_handle, char *_path, std::string dev_name); //RGB, Command, path
|
||||
~SinowealthController();
|
||||
|
||||
unsigned int GetLEDCount();
|
||||
std::string GetLocation();
|
||||
std::string GetName();
|
||||
std::string GetSerialString();
|
||||
std::string GetFirmwareVersion();
|
||||
|
||||
void SetMode(unsigned char mode, unsigned char speed, unsigned char brightness, unsigned char direction, RGBColor* color_buf);
|
||||
int GetProfile();
|
||||
|
||||
private:
|
||||
hid_device* dev_cmd;
|
||||
hid_device* dev_data;
|
||||
unsigned int led_count;
|
||||
unsigned char device_configuration[SINOWEALTH_CONFIG_REPORT_SIZE];
|
||||
std::string location;
|
||||
std::string name;
|
||||
};
|
||||
@@ -0,0 +1,485 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| SinowealthControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Sinowealth, Genesis and Everest brand Mice |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "Detector.h"
|
||||
#include "RGBController_SinowealthKeyboard10c.h"
|
||||
#include "SinowealthController.h"
|
||||
#include "SinowealthController1007.h"
|
||||
#include "SinowealthKeyboard10cController.h"
|
||||
#include "SinowealthKeyboard10cDevices.h"
|
||||
#include "SinowealthKeyboardController.h" // Disabled
|
||||
#include "SinowealthKeyboard16Controller.h" // Disabled
|
||||
#include "SinowealthKeyboard90Controller.h"
|
||||
#include "SinowealthGMOWController.h"
|
||||
#include "GenesisXenon200Controller.cpp"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_Sinowealth.h"
|
||||
#include "RGBController_Sinowealth1007.h"
|
||||
#include "RGBController_SinowealthKeyboard.h" // Disabled
|
||||
#include "RGBController_SinowealthKeyboard16.h" // Disabled
|
||||
#include "RGBController_SinowealthKeyboard90.h"
|
||||
#include "RGBController_SinowealthGMOW.h"
|
||||
#include "RGBController_GenesisXenon200.h"
|
||||
#include <hidapi.h>
|
||||
#include "LogManager.h"
|
||||
|
||||
#define SINOWEALTH_VID 0x258A
|
||||
|
||||
#define Glorious_Model_O_PID 0x0036
|
||||
#define Glorious_Model_OW_PID1 0x2022 // wireless
|
||||
#define Glorious_Model_OW_PID2 0x2011 // when connected via cable
|
||||
#define Glorious_Model_D_PID 0x0033
|
||||
#define Glorious_Model_DW_PID1 0x2023 // Wireless
|
||||
#define Glorious_Model_DW_PID2 0x2012 // When connected via cable
|
||||
#define Everest_GT100_PID 0x0029
|
||||
#define ZET_FURY_PRO_PID 0x1007
|
||||
#define Fl_Esports_F11_PID 0x0049
|
||||
#define RGB_KEYBOARD_0016PID 0x0016
|
||||
#define GENESIS_THOR_300_PID 0x0090
|
||||
#define GENESIS_XENON_200_PID 0x1007
|
||||
#define RGB_KEYBOARD_010CPID 0x010C
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectSinowealthControllers *
|
||||
* *
|
||||
* Tests the USB address to see if a Sinowealth controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
#define MAX_EXPECTED_REPORT_SIZE 2048
|
||||
|
||||
struct expected_report
|
||||
{
|
||||
unsigned int id;
|
||||
unsigned int size; // Up to MAX_EXPECTED_REPORT_SIZE!
|
||||
unsigned char* cmd_buf = nullptr;
|
||||
unsigned int cmd_size;
|
||||
hid_device* cmd_device = nullptr;
|
||||
hid_device* device = nullptr;
|
||||
unsigned char* response = nullptr;
|
||||
|
||||
expected_report(unsigned int id, unsigned size) : id(id), size(size) {}
|
||||
expected_report(unsigned int id, unsigned size, unsigned char* cmd_buf, unsigned int cmd_size) : id(id), size(size), cmd_buf(cmd_buf), cmd_size(cmd_size) {}
|
||||
};
|
||||
|
||||
typedef std::vector<expected_report> expected_reports;
|
||||
|
||||
static int GetDeviceCount(hid_device_info* info, unsigned int &device_count_total, unsigned int device_count_expected)
|
||||
{
|
||||
hid_device_info* info_temp = info;
|
||||
|
||||
while(info_temp)
|
||||
{
|
||||
if(info_temp->vendor_id == info->vendor_id // constant SINOWEALTH_VID
|
||||
&& info_temp->product_id == info->product_id // NON-constant
|
||||
&& info_temp->usage_page == info->usage_page) // constant 0xFF00
|
||||
{
|
||||
device_count_total++;
|
||||
}
|
||||
info_temp = info_temp->next;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*\
|
||||
| If we have an expected number and what's left is a multiple of it |
|
||||
\*----------------------------------------------------------------------*/
|
||||
if(device_count_expected == 0 || device_count_total % device_count_expected == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool DetectUsages(hid_device_info* info, std::string name, unsigned int device_count_expected, expected_reports& reports)
|
||||
{
|
||||
hid_device_info* info_temp = info;
|
||||
hid_device* device = nullptr;
|
||||
|
||||
bool restart_flag = false;
|
||||
unsigned int device_count = 0;
|
||||
unsigned int device_count_total = 0;
|
||||
unsigned char tmp_buf[MAX_EXPECTED_REPORT_SIZE];
|
||||
|
||||
/*-----------------------------------------------------------------------------------------------*\
|
||||
| Yeah, it might seem suboptimal to go over this list twice, but read this first: |
|
||||
| Sinowealth controllers report many collections on the same interface, usage page and usage id |
|
||||
| We can't know if detector was called for the 1st time (first collection), or 2nd, 3rd, etc... |
|
||||
| Relying on pure luck in this question is... not the best approach IMO, so here's how it works: |
|
||||
| 1. Count remaining devices with our expected VID + PID + Usage Page |
|
||||
| 2. We know in advance how many collections currently expected device reports, so we compare |
|
||||
| remaining amount with expected amount |
|
||||
| 3. If remaining amount is a multiple of expected amount - we're on the first collection of one |
|
||||
| of connected devices, and proceed with finding expected reports |
|
||||
\*-----------------------------------------------------------------------------------------------*/
|
||||
if(!GetDeviceCount(info, device_count_total, device_count_expected))
|
||||
{
|
||||
LOG_DEBUG("[%s] Detection stage skipped - devices left %d (expected %d) ", name.c_str(), device_count_total, device_count_expected);
|
||||
reports.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------*\
|
||||
| Check all devices provided in hid_device_info |
|
||||
\*---------------------------------------------------------------*/
|
||||
while(info_temp)
|
||||
{
|
||||
/*----------------------------------------------------------------*\
|
||||
| If it's still our device |
|
||||
\*----------------------------------------------------------------*/
|
||||
if(info_temp->vendor_id == info->vendor_id // constant SINOWEALTH_VID
|
||||
&& info_temp->product_id == info->product_id // NON-constant
|
||||
&& info_temp->usage_page == info->usage_page) // constant 0xFF00
|
||||
{
|
||||
/*----------------------------------------------------------*\
|
||||
| Open current device to check if it has expected report IDs |
|
||||
\*----------------------------------------------------------*/
|
||||
bool report_found = false;
|
||||
device = hid_open_path(info_temp->path);
|
||||
|
||||
if(!device)
|
||||
{
|
||||
LOG_ERROR("[%s] Couldn't open path \"HID: %s\", do we have enough permissions?", name.c_str(), info_temp->path);
|
||||
reports.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
for(expected_report& report: reports)
|
||||
{
|
||||
/*-----------------------------------------------------------*\
|
||||
| We shouldn't do any checks if device is already found |
|
||||
\*-----------------------------------------------------------*/
|
||||
if(report.device != nullptr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(tmp_buf, 0x00, sizeof(tmp_buf));
|
||||
tmp_buf[0] = report.id;
|
||||
|
||||
/*--------------------------------------------------------------------------------------*\
|
||||
| If we need to send a command before requesting data, send it and flag the report |
|
||||
| (DON'T TRY TO CREATE MORE THAN 1 EXPECTED REPORT SENDING COMMANDS) |
|
||||
\*--------------------------------------------------------------------------------------*/
|
||||
if(report.cmd_buf != nullptr && report.cmd_device == nullptr)
|
||||
{
|
||||
if(hid_send_feature_report(device, report.cmd_buf, report.cmd_size) > -1)
|
||||
{
|
||||
restart_flag = true; // Because Windows
|
||||
report.cmd_device = device;
|
||||
LOG_TRACE("[%s] Successfully sent command for ReportId 0x%02X to device at location \"HID: %s\", handle: %08X", name.c_str(), report.id, info_temp->path, device);
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------*\
|
||||
| Now we try to request data for expected feature report |
|
||||
\*------------------------------------------------------*/
|
||||
if(report.cmd_buf == nullptr || report.cmd_device != nullptr)
|
||||
{
|
||||
/*---------------------------------------------------------------------------*\
|
||||
| If device actually responds to expected report ID, set a flag |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
if(hid_get_feature_report(device, tmp_buf, report.size) > -1)
|
||||
{
|
||||
device_count++;
|
||||
report_found = true;
|
||||
report.device = device;
|
||||
|
||||
report.response = new unsigned char[report.size];
|
||||
std::memcpy(report.response, tmp_buf, report.size);
|
||||
|
||||
LOG_TRACE("[%s] Successfully requested feature ReportId 0x%02X from device at location \"HID: %s\", handle: %08X", name.c_str(), report.id, info_temp->path, device);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*\
|
||||
| If it doesn't - make sure to close it! |
|
||||
| Don't close if restart flag is set because we found cmd_dev |
|
||||
\*-----------------------------------------------------------*/
|
||||
if(!report_found && !restart_flag) hid_close(device);
|
||||
}
|
||||
|
||||
info_temp = restart_flag ? info : info_temp->next;
|
||||
restart_flag = false;
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| If we found everything we expected, stop going through devices list |
|
||||
| We don't want to go too far in case there are multiple Sinowealth devices |
|
||||
| with the same VID & PID |
|
||||
| (I don't care how unlikely it is, we must be prepared for everything) |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
if(device_count == reports.size()) info_temp = nullptr;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*\
|
||||
| If we found less devices than expected - sad, lets clean up |
|
||||
\*-----------------------------------------------------------*/
|
||||
if(device_count < reports.size())
|
||||
{
|
||||
for(expected_report& report: reports)
|
||||
{
|
||||
if(report.response != nullptr)
|
||||
{
|
||||
delete[] report.response;
|
||||
report.response = nullptr;
|
||||
}
|
||||
if(report.device != nullptr)
|
||||
{
|
||||
hid_close(report.device);
|
||||
}
|
||||
}
|
||||
|
||||
reports.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void DetectGenesisXenon200(hid_device_info* info, const std::string name)
|
||||
{
|
||||
expected_reports reports{expected_report(0x04, 154), expected_report(0x08, 9)};
|
||||
if(!DetectUsages(info, name, 5, reports))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hid_device* dev = reports.at(0).device;
|
||||
hid_device* cmd_dev = reports.at(1).device;
|
||||
|
||||
GenesisXenon200Controller* controller = new GenesisXenon200Controller(dev, cmd_dev, info->path, name);
|
||||
RGBController* rgb_controller = new RGBController_GenesisXenon200(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
|
||||
}
|
||||
|
||||
static void DetectZetFuryPro(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
#ifdef USE_HID_USAGE
|
||||
expected_reports reports{expected_report(0x04, 59)};
|
||||
if(!DetectUsages(info, name, 5, reports))
|
||||
{
|
||||
return;
|
||||
}
|
||||
hid_device* dev = reports.at(0).device;
|
||||
#else
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
#endif
|
||||
|
||||
if(dev)
|
||||
{
|
||||
SinowealthController1007* controller = new SinowealthController1007(dev, info->path, name);
|
||||
RGBController_Sinowealth1007* rgb_controller = new RGBController_Sinowealth1007(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
static void DetectSinowealthMouse(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
#ifdef USE_HID_USAGE
|
||||
unsigned char command[6] = {0x05, 0x11, 0x00, 0x00, 0x00, 0x00};
|
||||
expected_reports reports{expected_report(0x04, 520, command, sizeof(command))};
|
||||
|
||||
if(!DetectUsages(info, name, 3, reports))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hid_device *dev = reports.at(0).device;
|
||||
hid_device *dev_cmd = reports.at(0).cmd_device;
|
||||
#else
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
hid_device* dev_cmd = dev;
|
||||
#endif
|
||||
|
||||
if(dev && dev_cmd)
|
||||
{
|
||||
SinowealthController* controller = new SinowealthController(dev, dev_cmd, info->path, name);
|
||||
RGBController_Sinowealth* rgb_controller = new RGBController_Sinowealth(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
static void DetectGMOW_Cable(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
LOG_DEBUG("[%s] Detected connection via USB cable", name.c_str());
|
||||
hid_device *dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
SinowealthGMOWController* controller = new SinowealthGMOWController(dev, info->path, GMOW_CABLE_CONNECTED, name);
|
||||
RGBController_GMOW* rgb_controller = new RGBController_GMOW(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
static void DetectGMOW_Dongle(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| When the GMOW is connected only via the wireless dongle, only one |
|
||||
| device shows up (PID=2022), and RGB packets go to that device. |
|
||||
| Same for when it is only plugged in via a cable but not a dongle (except |
|
||||
| the device is PID=2011). However, when both are plugged in, packets |
|
||||
| should only go to the cable connected device |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
LOG_DEBUG("[%s] Detected connection via wireless dongle", name.c_str());
|
||||
hid_device_info* start = hid_enumerate(SINOWEALTH_VID,0);
|
||||
hid_device_info* curr = start;
|
||||
|
||||
while(curr)
|
||||
{
|
||||
if(curr->product_id == Glorious_Model_OW_PID2 || curr->product_id == Glorious_Model_DW_PID2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
curr = curr->next;
|
||||
}
|
||||
hid_free_enumeration(start);
|
||||
|
||||
hid_device *dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
SinowealthGMOWController* controller = new SinowealthGMOWController(dev, info->path, GMOW_DONGLE_CONNECTED, name);
|
||||
RGBController_GMOW* rgb_controller = new RGBController_GMOW(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
// static void DetectSinowealthKeyboard16(hid_device_info* info, const std::string& name)
|
||||
// {
|
||||
// #ifdef USE_HID_USAGE
|
||||
// unsigned char command[6] = {0x05, 0x83, 0x00, 0x00, 0x00, 0x00};
|
||||
// expected_reports reports{expected_report(0x06, 1032, command, sizeof(command))};
|
||||
// if(!DetectUsages(info, name, 3, reports))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// hid_device *dev = reports.at(0).device;
|
||||
// hid_device *dev_cmd = reports.at(0).cmd_device;
|
||||
// #else
|
||||
// hid_device* dev = hid_open_path(info->path);
|
||||
// hid_device* dev_cmd = dev;
|
||||
// #endif
|
||||
// if(dev && dev_cmd)
|
||||
// {
|
||||
// SinowealthKeyboard16Controller* controller = new SinowealthKeyboard16Controller(dev_cmd, dev, info->path, name);
|
||||
// RGBController_SinowealthKeyboard16* rgb_controller = new RGBController_SinowealthKeyboard16(controller);
|
||||
//
|
||||
// ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
// }
|
||||
// }
|
||||
|
||||
// static void DetectSinowealthKeyboard(hid_device_info* info, const std::string& name)
|
||||
// {
|
||||
// #ifdef USE_HID_USAGE
|
||||
// unsigned char command[6] = {0x05, 0x83, 0xB6, 0x00, 0x00, 0x00};
|
||||
// expected_reports reports{expected_report(0x06, 1032, command, sizeof(command))};
|
||||
// if(!DetectUsages(info, name, 3, reports))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// hid_device *dev = reports.at(0).device;
|
||||
// hid_device *dev_cmd = reports.at(0).cmd_device;
|
||||
//
|
||||
// if(dev && dev_cmd)
|
||||
// {
|
||||
// SinowealthKeyboardController* controller = new SinowealthKeyboardController(dev_cmd, dev, info->path, name);
|
||||
// RGBController_SinowealthKeyboard* rgb_controller = new RGBController_SinowealthKeyboard(controller);
|
||||
//
|
||||
// ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
// }
|
||||
// #else
|
||||
// // It is unknown why this code used the MOUSE controller here; could it be the reason why it was disabled?
|
||||
// hid_device* dev = hid_open_path(info->path);
|
||||
//
|
||||
// if(dev)
|
||||
// {
|
||||
// SinowealthController* controller = new SinowealthController(dev, dev, info->path, name);
|
||||
// RGBController_Sinowealth* rgb_controller = new RGBController_Sinowealth(controller);
|
||||
//
|
||||
// ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
// }
|
||||
// #endif
|
||||
// }
|
||||
|
||||
static void DetectSinowealthGenesisKeyboard(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
unsigned int pid = info->product_id;
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
SinowealthKeyboard90Controller* controller = new SinowealthKeyboard90Controller(dev, info->path, pid, name);
|
||||
RGBController_SinowealthKeyboard90* rgb_controller = new RGBController_SinowealthKeyboard90(controller);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
static void DetectSinowealthKeyboard10c(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
unsigned char command[7] = {0x06, 0x82, 0x01, 0x00, 0x01, 0x00, 0x06};
|
||||
expected_reports reports{expected_report(0x06, 520, command, 520)};
|
||||
|
||||
if(!DetectUsages(info, name, 3, reports))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
hid_device *dev = reports.at(0).device;
|
||||
unsigned char model_id = reports.at(0).response[13];
|
||||
|
||||
if(dev && sinowealth_10c_keyboards.find(model_id) != sinowealth_10c_keyboards.end())
|
||||
{
|
||||
SinowealthKeyboard10cController* controller = new SinowealthKeyboard10cController(dev, info->path, sinowealth_10c_keyboards.at(model_id).device_name);
|
||||
RGBController_SinowealthKeyboard10c* rgb_controller = new RGBController_SinowealthKeyboard10c(controller, model_id);
|
||||
|
||||
ResourceManager::get()->RegisterRGBController(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_HID_USAGE
|
||||
REGISTER_HID_DETECTOR_P("Glorious Model O / O-", DetectSinowealthMouse, SINOWEALTH_VID, Glorious_Model_O_PID, 0xFF00 );
|
||||
REGISTER_HID_DETECTOR_P("Glorious Model D / D-", DetectSinowealthMouse, SINOWEALTH_VID, Glorious_Model_D_PID, 0xFF00 );
|
||||
REGISTER_HID_DETECTOR_P("Everest GT-100 RGB", DetectSinowealthMouse, SINOWEALTH_VID, Everest_GT100_PID, 0xFF00 );
|
||||
REGISTER_HID_DETECTOR_IPU("ZET Fury Pro", DetectZetFuryPro, SINOWEALTH_VID, ZET_FURY_PRO_PID, 1, 0xFF00, 1 );
|
||||
REGISTER_HID_DETECTOR_PU("Glorious Model O / O- Wireless", DetectGMOW_Dongle, SINOWEALTH_VID, Glorious_Model_OW_PID1, 0xFFFF, 1 );
|
||||
REGISTER_HID_DETECTOR_PU("Glorious Model O / O- Wireless", DetectGMOW_Cable, SINOWEALTH_VID, Glorious_Model_OW_PID2, 0xFFFF, 0x0000 );
|
||||
REGISTER_HID_DETECTOR_PU("Glorious Model D / D- Wireless", DetectGMOW_Dongle, SINOWEALTH_VID, Glorious_Model_DW_PID1, 0xFFFF, 0x0000 );
|
||||
REGISTER_HID_DETECTOR_PU("Glorious Model D / D- Wireless", DetectGMOW_Cable, SINOWEALTH_VID, Glorious_Model_DW_PID2, 0xFFFF, 0x0000 );
|
||||
REGISTER_HID_DETECTOR_PU("Genesis Xenon 200", DetectGenesisXenon200, SINOWEALTH_VID, GENESIS_XENON_200_PID, 0xFF00, 1 );
|
||||
REGISTER_HID_DETECTOR_IPU("Genesis Thor 300", DetectSinowealthGenesisKeyboard, SINOWEALTH_VID, GENESIS_THOR_300_PID, 1, 0xFF00, 1 );
|
||||
REGISTER_HID_DETECTOR_IPU("Sinowealth Keyboard", DetectSinowealthKeyboard10c, SINOWEALTH_VID, RGB_KEYBOARD_010CPID, 1, 0xFF00, 1 );
|
||||
|
||||
// Sinowealth keyboards are disabled due to VID/PID pairs being reused from Redragon keyboards, which ended up in bricking the latter
|
||||
//REGISTER_HID_DETECTOR_P("FL ESPORTS F11", DetectSinowealthKeyboard, SINOWEALTH_VID, Fl_Esports_F11_PID, 0xFF00 );
|
||||
//REGISTER_HID_DETECTOR_P("Sinowealth Keyboard", DetectSinowealthKeyboard16, SINOWEALTH_VID, RGB_KEYBOARD_0016PID, 0xFF00 );
|
||||
#else
|
||||
REGISTER_HID_DETECTOR_I("Glorious Model O / O-", DetectSinowealthMouse, SINOWEALTH_VID, Glorious_Model_O_PID, 1);
|
||||
REGISTER_HID_DETECTOR_I("Glorious Model D / D-", DetectSinowealthMouse, SINOWEALTH_VID, Glorious_Model_D_PID, 1);
|
||||
REGISTER_HID_DETECTOR_I("Everest GT-100 RGB", DetectSinowealthMouse, SINOWEALTH_VID, Everest_GT100_PID, 1);
|
||||
REGISTER_HID_DETECTOR_I("ZET Fury Pro", DetectZetFuryPro, SINOWEALTH_VID, ZET_FURY_PRO_PID, 1);
|
||||
REGISTER_HID_DETECTOR_I("Glorious Model O / O- Wireless", DetectGMOW_Dongle, SINOWEALTH_VID, Glorious_Model_OW_PID1, 1);
|
||||
REGISTER_HID_DETECTOR_I("Glorious Model O / O- Wireless", DetectGMOW_Cable, SINOWEALTH_VID, Glorious_Model_OW_PID2, 2);
|
||||
REGISTER_HID_DETECTOR_I("Glorious Model D / D- Wireless", DetectGMOW_Dongle, SINOWEALTH_VID, Glorious_Model_DW_PID1, 2);
|
||||
REGISTER_HID_DETECTOR_I("Glorious Model D / D- Wireless", DetectGMOW_Cable, SINOWEALTH_VID, Glorious_Model_DW_PID2, 2);
|
||||
REGISTER_HID_DETECTOR_I("Genesis Xenon 200", DetectGenesisXenon200, SINOWEALTH_VID, GENESIS_XENON_200_PID, 1);
|
||||
REGISTER_HID_DETECTOR_I("Genesis Thor 300", DetectSinowealthGenesisKeyboard, SINOWEALTH_VID, GENESIS_THOR_300_PID, 1);
|
||||
|
||||
//REGISTER_HID_DETECTOR_I("FL ESPORTS F11", DetectSinowealthKeyboard, SINOWEALTH_VID, Fl_Esports_F11_PID, 1);
|
||||
//REGISTER_HID_DETECTOR_I("Sinowealth Keyboard", DetectSinowealthKeyboard16, SINOWEALTH_VID, RGB_KEYBOARD_0016PID, 1);
|
||||
#endif
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_SinowealthGMOW.cpp |
|
||||
| |
|
||||
| RGBController for Glorious Model O Wireless |
|
||||
| |
|
||||
| Matt Silva (thesilvanator) May 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Sinowealth Glorious Model O Wireless
|
||||
@type USB
|
||||
@save :white_check_mark:
|
||||
@direct :x:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectSinowealthMouse
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_SinowealthGMOW.h"
|
||||
|
||||
RGBController_GMOW::RGBController_GMOW(SinowealthGMOWController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetName();
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = "Sinowealth Device";
|
||||
location = controller->GetLocation();
|
||||
serial = controller->GetSerialString();
|
||||
version = controller->GetFirmwareVersion();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.flags = MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
Off.value = GMOW_MODE_OFF;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode RainbowWave;
|
||||
RainbowWave.name = "Rainbow Wave";
|
||||
RainbowWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
RainbowWave.speed_min = GMOW_SPEED1_MIN;
|
||||
RainbowWave.speed = GMOW_SPEED1_MID;
|
||||
RainbowWave.speed_max = GMOW_SPEED1_MAX;
|
||||
RainbowWave.direction = MODE_DIRECTION_UP;
|
||||
RainbowWave.color_mode = MODE_COLORS_NONE;
|
||||
RainbowWave.brightness_min = GMOW_BRIGHTNESS_MIN;
|
||||
RainbowWave.brightness = GMOW_BRIGHTNESS_MID;
|
||||
RainbowWave.brightness_max = GMOW_BRIGHTNESS_MAX;
|
||||
RainbowWave.value = GMOW_MODE_RAINBOW_WAVE;
|
||||
modes.push_back(RainbowWave);
|
||||
|
||||
mode SpectrumCycle;
|
||||
SpectrumCycle.name = "Spectrum Cycle";
|
||||
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
SpectrumCycle.speed_min = GMOW_SPEED1_MIN;
|
||||
SpectrumCycle.speed = GMOW_SPEED1_MID;
|
||||
SpectrumCycle.speed_max = GMOW_SPEED1_MAX;
|
||||
SpectrumCycle.color_mode = MODE_COLORS_NONE;
|
||||
SpectrumCycle.brightness_min = GMOW_BRIGHTNESS_MIN;
|
||||
SpectrumCycle.brightness = GMOW_BRIGHTNESS_MID;
|
||||
SpectrumCycle.brightness_max = GMOW_BRIGHTNESS_MAX;
|
||||
SpectrumCycle.value = GMOW_MODE_SPECTRUM_CYCLE;
|
||||
modes.push_back(SpectrumCycle);
|
||||
|
||||
mode CustomBreathing;
|
||||
CustomBreathing.name = "Custom Breathing";
|
||||
CustomBreathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
CustomBreathing.speed_min = GMOW_SPEED1_MIN;
|
||||
CustomBreathing.speed = GMOW_SPEED1_MID;
|
||||
CustomBreathing.speed_max = GMOW_SPEED1_MAX;
|
||||
CustomBreathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
CustomBreathing.colors_min = 2;
|
||||
CustomBreathing.colors_max = 7;
|
||||
CustomBreathing.brightness_min = GMOW_BRIGHTNESS_MIN;
|
||||
CustomBreathing.brightness = GMOW_BRIGHTNESS_MID;
|
||||
CustomBreathing.brightness_max = GMOW_BRIGHTNESS_MAX;
|
||||
CustomBreathing.value = GMOW_MODE_CUSTOM_BREATHING;
|
||||
CustomBreathing.colors.resize(7);
|
||||
modes.push_back(CustomBreathing);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.brightness_min = GMOW_BRIGHTNESS_MIN;
|
||||
Static.brightness = GMOW_BRIGHTNESS_MID;
|
||||
Static.brightness_max = GMOW_BRIGHTNESS_MAX;
|
||||
Static.value = GMOW_MODE_STATIC;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Breathing.speed_min = GMOW_SPEED1_MIN;
|
||||
Breathing.speed = GMOW_SPEED1_MID;
|
||||
Breathing.speed_max = GMOW_SPEED1_MAX;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.brightness_min = GMOW_BRIGHTNESS_MIN;
|
||||
Breathing.brightness = GMOW_BRIGHTNESS_MID;
|
||||
Breathing.brightness_max = GMOW_BRIGHTNESS_MAX;
|
||||
Breathing.value = GMOW_MODE_BREATHING;
|
||||
Breathing.colors.resize(1);
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Tail;
|
||||
Tail.name = "Tail";
|
||||
Tail.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Tail.speed_min = GMOW_SPEED1_MIN;
|
||||
Tail.speed = GMOW_SPEED1_MID;
|
||||
Tail.speed_max = GMOW_SPEED1_MAX;
|
||||
Tail.color_mode = MODE_COLORS_NONE;
|
||||
Tail.brightness_min = GMOW_BRIGHTNESS_MIN;
|
||||
Tail.brightness = GMOW_BRIGHTNESS_MID;
|
||||
Tail.brightness_max = GMOW_BRIGHTNESS_MAX;
|
||||
Tail.value = GMOW_MODE_TAIL;
|
||||
modes.push_back(Tail);
|
||||
|
||||
mode Rave;
|
||||
Rave.name = "Rave";
|
||||
Rave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Rave.speed_min = GMOW_SPEED2_MIN;
|
||||
Rave.speed = GMOW_SPEED2_MID;
|
||||
Rave.speed_max = GMOW_SPEED2_MAX;
|
||||
Rave.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Rave.colors_min = 1;
|
||||
Rave.colors_max = 2;
|
||||
Rave.brightness_min = GMOW_BRIGHTNESS_MIN;
|
||||
Rave.brightness = GMOW_BRIGHTNESS_MID;
|
||||
Rave.brightness_max = GMOW_BRIGHTNESS_MAX;
|
||||
Rave.value = GMOW_MODE_RAVE;
|
||||
Rave.colors.resize(2);
|
||||
modes.push_back(Rave);
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Wave.speed_min = GMOW_SPEED2_MIN;
|
||||
Wave.speed = GMOW_SPEED2_MID;
|
||||
Wave.speed_max = GMOW_SPEED2_MAX;
|
||||
Wave.color_mode = MODE_COLORS_NONE;
|
||||
Wave.brightness_min = GMOW_BRIGHTNESS_MIN;
|
||||
Wave.brightness = GMOW_BRIGHTNESS_MID;
|
||||
Wave.brightness_max = GMOW_BRIGHTNESS_MAX;
|
||||
Wave.value = GMOW_MODE_WAVE;
|
||||
modes.push_back(Wave);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_GMOW::~RGBController_GMOW()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_GMOW::SetupZones()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_GMOW::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_GMOW::DeviceUpdateLEDs()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_GMOW::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_GMOW::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_GMOW::DeviceUpdateMode()
|
||||
{
|
||||
mode curr = modes[active_mode];
|
||||
controller->SetMode(active_mode, curr.speed,curr.brightness, curr.brightness, curr.colors.data(), (unsigned char)curr.colors.size());
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_SinowealthGMOW.h |
|
||||
| |
|
||||
| RGBController for Glorious Model O Wireless |
|
||||
| |
|
||||
| Matt Silva (thesilvanator) May 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "SinowealthGMOWController.h"
|
||||
|
||||
class RGBController_GMOW : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_GMOW(SinowealthGMOWController* sinowealth_ptr);
|
||||
~RGBController_GMOW();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
SinowealthGMOWController* controller;
|
||||
};
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| SinowealthGMOWController.cpp |
|
||||
| |
|
||||
| Driver for Glorious Model O Wireless |
|
||||
| |
|
||||
| Matt Silva (thesilvanator) May 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include "LogManager.h"
|
||||
#include "SinowealthGMOWController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
SinowealthGMOWController::SinowealthGMOWController(hid_device* dev_handle, char *_path, int _type, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = _path;
|
||||
name = dev_name;
|
||||
type = _type;
|
||||
|
||||
memset(mode_packet,0x00, GMOW_PACKET_SIZE);
|
||||
mode_packet[0x03] = 0x02;
|
||||
mode_packet[0x05] = 0x02;
|
||||
mode_packet[0x07] = 0x01;
|
||||
mode_packet[0x08] = 0xFF;
|
||||
|
||||
memset(wired_packet,0x00, GMOW_PACKET_SIZE);
|
||||
wired_packet[0x03] = 0x02;
|
||||
wired_packet[0x04] = 0x02;
|
||||
wired_packet[0x05] = 0x02;
|
||||
wired_packet[0x06] = 0x02;
|
||||
wired_packet[0x07] = 0x01;
|
||||
|
||||
memcpy(less_packet, wired_packet, GMOW_PACKET_SIZE);
|
||||
less_packet[0x07] = 0x00;
|
||||
}
|
||||
|
||||
SinowealthGMOWController::~SinowealthGMOWController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string SinowealthGMOWController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string SinowealthGMOWController::GetName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string SinowealthGMOWController::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));
|
||||
}
|
||||
|
||||
std::string SinowealthGMOWController::GetFirmwareVersion()
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
unsigned char buf_send[GMOW_PACKET_SIZE] = {0};
|
||||
unsigned char buf_receive[GMOW_PACKET_SIZE] = {0};
|
||||
|
||||
if(type == GMOW_CABLE_CONNECTED)
|
||||
{
|
||||
buf_send[0x03] = 0x02;
|
||||
}
|
||||
|
||||
buf_send[0x04] = 0x03;
|
||||
buf_send[0x06] = 0x81;
|
||||
|
||||
hid_send_feature_report(dev,buf_send, GMOW_PACKET_SIZE);
|
||||
|
||||
std::this_thread::sleep_for(50ms);
|
||||
|
||||
hid_get_feature_report(dev,buf_receive,GMOW_PACKET_SIZE);
|
||||
|
||||
char str[128] = {0};
|
||||
snprintf(str,128,"%d.%d.%d.%d", buf_receive[7],
|
||||
buf_receive[8],
|
||||
buf_receive[9],
|
||||
buf_receive[10]);
|
||||
|
||||
return std::string(str);
|
||||
}
|
||||
|
||||
void SinowealthGMOWController::SetMode(unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char wired_brightness,
|
||||
unsigned char less_brightness,
|
||||
RGBColor* color_buf,
|
||||
unsigned char color_count)
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
unsigned char mode_buff[GMOW_PACKET_SIZE];
|
||||
memcpy(mode_buff, mode_packet, GMOW_PACKET_SIZE);
|
||||
mode_buff[0x09] = mode;
|
||||
|
||||
unsigned char wired_buff[GMOW_PACKET_SIZE];
|
||||
memcpy(wired_buff, wired_packet, GMOW_PACKET_SIZE);
|
||||
wired_buff[0x08] = wired_brightness;
|
||||
|
||||
unsigned char less_buff[GMOW_PACKET_SIZE];
|
||||
memcpy(less_buff, less_packet, GMOW_PACKET_SIZE);
|
||||
less_buff[0x08] = less_brightness;
|
||||
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case GMOW_MODE_RAINBOW_WAVE:
|
||||
mode_buff[0x04] = 0x05;
|
||||
mode_buff[0x0B] = speed;
|
||||
break;
|
||||
case GMOW_MODE_SPECTRUM_CYCLE:
|
||||
mode_buff[0x04] = 0x05;
|
||||
mode_buff[0x0B] = speed;
|
||||
mode_buff[0x0C] = 0xFF;
|
||||
break;
|
||||
case GMOW_MODE_CUSTOM_BREATHING:
|
||||
{
|
||||
mode_buff[0x04] = color_count * 3 + 5;
|
||||
mode_buff[0x0B] = speed;
|
||||
|
||||
for(unsigned int i = 0; i < color_count; i++)
|
||||
{
|
||||
unsigned char r = (char)RGBGetRValue(color_buf[i]);
|
||||
unsigned char g = (char)RGBGetGValue(color_buf[i]);
|
||||
unsigned char b = (char)RGBGetBValue(color_buf[i]);
|
||||
|
||||
if(r == 0x00 && g == 0x00 && b == 0x00)
|
||||
{
|
||||
r = 0x01;
|
||||
}
|
||||
|
||||
mode_buff[0x0C + 3*i + 0] = r;
|
||||
mode_buff[0x0C + 3*i + 1] = g;
|
||||
mode_buff[0x0C + 3*i + 2] = b;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
case GMOW_MODE_STATIC:
|
||||
{
|
||||
mode_buff[0x04] = 0x05;
|
||||
mode_buff[0x0B] = 0x09; // rate is replaced with 9
|
||||
|
||||
unsigned char r = (char)RGBGetRValue(color_buf[0]);
|
||||
unsigned char g = (char)RGBGetGValue(color_buf[0]);
|
||||
unsigned char b = (char)RGBGetBValue(color_buf[0]);
|
||||
|
||||
if(r == 0 && g == 0 && b == 0)
|
||||
{
|
||||
r = 1;
|
||||
}
|
||||
|
||||
mode_buff[0x0C] = r;
|
||||
mode_buff[0x0D] = g;
|
||||
mode_buff[0x0E] = b;
|
||||
}
|
||||
break;
|
||||
case GMOW_MODE_BREATHING:
|
||||
{
|
||||
mode_buff[0x04] = 0x08;
|
||||
mode_buff[0x0B] = speed;
|
||||
|
||||
unsigned char r = (char)RGBGetRValue(color_buf[0]);
|
||||
unsigned char g = (char)RGBGetGValue(color_buf[0]);
|
||||
unsigned char b = (char)RGBGetBValue(color_buf[0]);
|
||||
|
||||
if(r == 0 && g == 0 && b == 0)
|
||||
{
|
||||
r = 1;
|
||||
}
|
||||
|
||||
mode_buff[0x0C] = r;
|
||||
mode_buff[0x0D] = g;
|
||||
mode_buff[0x0E] = b;
|
||||
}
|
||||
break;
|
||||
case GMOW_MODE_TAIL:
|
||||
mode_buff[0x04] = 0x05;
|
||||
mode_buff[0x0B] = speed;
|
||||
break;
|
||||
case GMOW_MODE_RAVE:
|
||||
{
|
||||
mode_buff[0x04] = color_count * 3 + 5;
|
||||
mode_buff[0x0B] = speed;
|
||||
|
||||
for(unsigned int i = 0; i < color_count; i++) {
|
||||
unsigned char r = (char)RGBGetRValue(color_buf[i]);
|
||||
unsigned char g = (char)RGBGetGValue(color_buf[i]);
|
||||
unsigned char b = (char)RGBGetBValue(color_buf[i]);
|
||||
|
||||
if(r == 0 && g == 0 && b == 0)
|
||||
{
|
||||
r = 1;
|
||||
}
|
||||
|
||||
mode_buff[0x0C + 3*i + 0] = r;
|
||||
mode_buff[0x0C + 3*i + 1] = g;
|
||||
mode_buff[0x0C + 3*i + 2] = b;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GMOW_MODE_WAVE:
|
||||
mode_buff[0x04] = 0x05;
|
||||
mode_buff[0x0B] = speed;
|
||||
break;
|
||||
case GMOW_MODE_OFF:
|
||||
mode_buff[0x04] = 0x05;
|
||||
mode_buff[0x0B] = 0x09;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(50ms);
|
||||
hid_send_feature_report(dev, mode_buff, GMOW_PACKET_SIZE);
|
||||
|
||||
std::this_thread::sleep_for(50ms);
|
||||
hid_send_feature_report(dev, wired_buff, GMOW_PACKET_SIZE);
|
||||
|
||||
std::this_thread::sleep_for(50ms);
|
||||
hid_send_feature_report(dev, less_buff, GMOW_PACKET_SIZE);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| SinowealthGMOWController.h |
|
||||
| |
|
||||
| Driver for Glorious Model O Wireless |
|
||||
| |
|
||||
| Matt Silva (thesilvanator) May 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define GMOW_PACKET_SIZE 64 + 1
|
||||
|
||||
enum
|
||||
{
|
||||
GMOW_MODE_OFF = 0x00,
|
||||
GMOW_MODE_RAINBOW_WAVE = 0x01,
|
||||
GMOW_MODE_SPECTRUM_CYCLE = 0x02,
|
||||
GMOW_MODE_CUSTOM_BREATHING = 0x03,
|
||||
GMOW_MODE_STATIC = 0x04,
|
||||
GMOW_MODE_BREATHING = 0x05,
|
||||
GMOW_MODE_TAIL = 0x06,
|
||||
GMOW_MODE_RAVE = 0x07,
|
||||
GMOW_MODE_WAVE = 0x08,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GMOW_SPEED1_MIN = 0x14,
|
||||
GMOW_SPEED1_MID = 0x0B,
|
||||
GMOW_SPEED1_MAX = 0x01,
|
||||
|
||||
GMOW_SPEED2_MIN = 0xC8,
|
||||
GMOW_SPEED2_MID = 0x6E,
|
||||
GMOW_SPEED2_MAX = 0x0A,
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
GMOW_BRIGHTNESS_MIN = 0x00,
|
||||
GMOW_BRIGHTNESS_MID = 0x7F,
|
||||
GMOW_BRIGHTNESS_MAX = 0xFF,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GMOW_CABLE_CONNECTED,
|
||||
GMOW_DONGLE_CONNECTED
|
||||
};
|
||||
|
||||
|
||||
class SinowealthGMOWController
|
||||
{
|
||||
public:
|
||||
SinowealthGMOWController(hid_device* dev_handle, char *_path, int type, std::string dev_name);
|
||||
~SinowealthGMOWController();
|
||||
|
||||
std::string GetLocation();
|
||||
std::string GetName();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetMode(unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char wired_brightness,
|
||||
unsigned char less_brightness,
|
||||
RGBColor* color_buf,
|
||||
unsigned char color_count);
|
||||
|
||||
std::string GetFirmwareVersion();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
unsigned char mode_packet[GMOW_PACKET_SIZE];
|
||||
unsigned char wired_packet[GMOW_PACKET_SIZE];
|
||||
unsigned char less_packet[GMOW_PACKET_SIZE];
|
||||
|
||||
std::string location;
|
||||
std::string name;
|
||||
int type;
|
||||
};
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_SinowealthKeyboard10c.cpp |
|
||||
| |
|
||||
| RGBController for Sinowealth Keyboards with PID 010C |
|
||||
| |
|
||||
| Rodrigo Tavares 27 Nov 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "KeyboardLayoutManager.h"
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "SinowealthKeyboard10cController.h"
|
||||
#include "SinowealthKeyboard10cDevices.h"
|
||||
#include "RGBController_SinowealthKeyboard10c.h"
|
||||
|
||||
using namespace kbd10c;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Sinowealth Keyboard
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectSinowealthKeyboard10c
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_SinowealthKeyboard10c::RGBController_SinowealthKeyboard10c(
|
||||
SinowealthKeyboard10cController* controller_ptr, unsigned char model_id)
|
||||
: model_id(model_id)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetName();
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
vendor = "Sinowealth";
|
||||
description = "Sinowealth Keyboard Device";
|
||||
location = controller->GetLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
Off.value = MODE_OFF;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
Direct.value = MODE_DIRECT;
|
||||
modes.push_back(Direct);
|
||||
|
||||
active_mode = MODE_DIRECT;
|
||||
|
||||
SetupZones();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| The Sinowealth 010C Keyboard requires a steady stream |
|
||||
| of packets in order to not revert out of direct mode. |
|
||||
| Start a thread to continuously refresh the device |
|
||||
\*---------------------------------------------------------*/
|
||||
keepalive_thread_run = true;
|
||||
keepalive_thread = new std::thread(&RGBController_SinowealthKeyboard10c::KeepaliveThreadFunction, this);
|
||||
}
|
||||
|
||||
RGBController_SinowealthKeyboard10c::~RGBController_SinowealthKeyboard10c()
|
||||
{
|
||||
keepalive_thread_run = false;
|
||||
keepalive_thread->join();
|
||||
delete keepalive_thread;
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard10c::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Create the keyboard zone usiung Keyboard Layout Manager |
|
||||
\*---------------------------------------------------------*/
|
||||
zone new_zone;
|
||||
new_zone.name = ZONE_EN_KEYBOARD;
|
||||
new_zone.type = ZONE_TYPE_MATRIX;
|
||||
|
||||
sinowealth_device device = sinowealth_10c_keyboards.at(model_id);
|
||||
|
||||
KeyboardLayoutManager new_kb(KEYBOARD_LAYOUT_ANSI_QWERTY, device.keyboard_layout.base_size,
|
||||
device.keyboard_layout.key_values);
|
||||
new_kb.ChangeKeys(device.keyboard_layout.edit_keys);
|
||||
|
||||
matrix_map_type* new_map = new matrix_map_type;
|
||||
new_zone.matrix_map = new_map;
|
||||
new_zone.matrix_map->height = new_kb.GetRowCount();
|
||||
new_zone.matrix_map->width = new_kb.GetColumnCount();
|
||||
|
||||
new_zone.matrix_map->map = new unsigned int[new_map->height * new_map->width];
|
||||
new_zone.leds_count = new_kb.GetRowCount() * new_kb.GetColumnCount();
|
||||
new_zone.leds_min = new_zone.leds_count;
|
||||
new_zone.leds_max = new_zone.leds_count;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| These keyboards use sparse LED indexes — for example, a |
|
||||
| 99-key board might use LED indexes 0–112, leaving some |
|
||||
| numbers unused. Empty positions are marked 0xFFFFFFFF. |
|
||||
| |
|
||||
| We map each key to its actual LED index, filling the |
|
||||
| `leds` vector by those indexes and leaving gaps where no |
|
||||
| LED exists. |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
new_kb.GetKeyMap(new_map->map, KEYBOARD_MAP_FILL_TYPE_VALUE, new_map->height, new_map->width);
|
||||
|
||||
leds.resize(new_zone.leds_count);
|
||||
|
||||
for(unsigned int i = 0, j = 0; i < new_zone.leds_count; i++)
|
||||
{
|
||||
if(new_map->map[i] == 0xFFFFFFFF)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
led new_led;
|
||||
|
||||
new_led.name = new_kb.GetKeyNameAt(j);
|
||||
new_led.value = new_kb.GetKeyValueAt(j);
|
||||
|
||||
leds[new_map->map[i]] = new_led;
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard10c::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard10c::DeviceUpdateLEDs()
|
||||
{
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
controller->SetLEDsDirect(colors);
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard10c::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard10c::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard10c::DeviceUpdateMode()
|
||||
{
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard10c::KeepaliveThreadFunction()
|
||||
{
|
||||
while(keepalive_thread_run.load())
|
||||
{
|
||||
if(active_mode == MODE_DIRECT && (std::chrono::steady_clock::now() - last_update_time) > 1s)
|
||||
{
|
||||
UpdateLEDs();
|
||||
}
|
||||
std::this_thread::sleep_for(500ms);
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_SinowealthKeyboard10c.h |
|
||||
| |
|
||||
| RGBController for Sinowealth Keyboards with PID 010C |
|
||||
| |
|
||||
| Rodrigo Tavares 27 Nov 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "SinowealthKeyboard10cController.h"
|
||||
|
||||
class RGBController_SinowealthKeyboard10c : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_SinowealthKeyboard10c(SinowealthKeyboard10cController* controller_ptr, unsigned char model_id);
|
||||
~RGBController_SinowealthKeyboard10c();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
void KeepaliveThreadFunction();
|
||||
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
|
||||
unsigned char model_id;
|
||||
SinowealthKeyboard10cController* controller;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::thread* keepalive_thread;
|
||||
};
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| SinowealthKeyboard10cController.cpp |
|
||||
| |
|
||||
| Driver for Sinowealth Keyboards with PID 010C |
|
||||
| |
|
||||
| Rodrigo Tavares 27 Nov 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "SinowealthKeyboard10cController.h"
|
||||
#include "RGBController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
using namespace kbd10c;
|
||||
|
||||
SinowealthKeyboard10cController::SinowealthKeyboard10cController(hid_device* dev_handle, char* path,
|
||||
std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
name = dev_name;
|
||||
|
||||
current_mode = MODE_DIRECT;
|
||||
|
||||
location = path;
|
||||
}
|
||||
|
||||
SinowealthKeyboard10cController::~SinowealthKeyboard10cController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string SinowealthKeyboard10cController::GetLocation()
|
||||
{
|
||||
return ("HID: " + location);
|
||||
}
|
||||
|
||||
std::string SinowealthKeyboard10cController::GetName()
|
||||
{
|
||||
return (name);
|
||||
}
|
||||
|
||||
unsigned char SinowealthKeyboard10cController::GetCurrentMode()
|
||||
{
|
||||
return current_mode;
|
||||
}
|
||||
|
||||
std::string SinowealthKeyboard10cController::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 SinowealthKeyboard10cController::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
{
|
||||
const int buffer_size = 520;
|
||||
unsigned char buf[buffer_size];
|
||||
memset(buf, 0x00, buffer_size);
|
||||
|
||||
buf[0x00] = 0x06;
|
||||
buf[0x01] = 0x08;
|
||||
buf[0x04] = 0x01;
|
||||
buf[0x06] = 0x7A;
|
||||
buf[0x07] = 0x01;
|
||||
|
||||
for(size_t i = 0; i < colors.size(); ++i)
|
||||
{
|
||||
buf[0x08 + i * 3] = RGBGetRValue(colors[i]);
|
||||
buf[0x08 + i * 3 + 1] = RGBGetGValue(colors[i]);
|
||||
buf[0x08 + i * 3 + 2] = RGBGetBValue(colors[i]);
|
||||
}
|
||||
|
||||
hid_send_feature_report(dev, buf, buffer_size);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| SinowealthKeyboard10cController.h |
|
||||
| |
|
||||
| Driver for Sinowealth Keyboards with PID 010C |
|
||||
| |
|
||||
| Rodrigo Tavares 27 Nov 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace kbd10c
|
||||
{
|
||||
enum
|
||||
{
|
||||
MODE_OFF = 0x0,
|
||||
MODE_DIRECT = 0x1,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
class SinowealthKeyboard10cController
|
||||
{
|
||||
public:
|
||||
SinowealthKeyboard10cController(hid_device* dev_handle, char *_path, std::string dev_name);
|
||||
~SinowealthKeyboard10cController();
|
||||
|
||||
unsigned int GetLEDCount();
|
||||
std::string GetLocation();
|
||||
std::string GetName();
|
||||
std::string GetSerialString();
|
||||
unsigned char GetCurrentMode();
|
||||
void SetLEDsDirect(std::vector<RGBColor> colors);
|
||||
private:
|
||||
hid_device* dev;
|
||||
device_type type;
|
||||
unsigned char current_mode;
|
||||
std::string location;
|
||||
std::string name;
|
||||
};
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| SinowealthKeyboard10cDevices.cpp |
|
||||
| |
|
||||
| Device list for Sinowealth Keyboards with PID 010C |
|
||||
| |
|
||||
| Rodrigo Tavares 27 Nov 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "SinowealthKeyboard10cDevices.h"
|
||||
#include "KeyboardLayoutManager.h"
|
||||
#include "RGBControllerKeyNames.h"
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| KEYMAPS |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
const keyboard_keymap_overlay_values aula_f99_layout
|
||||
{
|
||||
KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 NULL NULL NULL DEL HOME END PGUP PGDN */
|
||||
0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 0, 0, 0,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BSPC NULL NULL NULL NMLK NMDV NMTM NMMI */
|
||||
1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 0, 0, 0, 91, 97, 103, 109,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ NULL NULL NULL NM7 NM8 NM9 NMPL */
|
||||
2, 8, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80, 0, 0, 0, 92, 98, 104, 110,
|
||||
/* CPLK A S D F G H J K L ; " # ENTR NM4 NM5 NM6 */
|
||||
3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 0, 81, 93, 99, 105,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER */
|
||||
4, 0, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 82, 88, 94, 100, 106, 112,
|
||||
/* LCTL LWIN LALT SPC RALT RFNC RMNU RCTL ARWL ARWD ARWR NM0 NMPD */
|
||||
5, 11, 17, 35, 53, 59, 0, 65, 83, 89, 95, 101, 107,
|
||||
},
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*--------------------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, Alternate Name, OpCode, |
|
||||
\*--------------------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 0, 14, 78, KEY_EN_DELETE, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Replace Print w/ Delete
|
||||
{ 0, 0, 15, 90, KEY_EN_HOME, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Replace ScrLk w/ Home
|
||||
{ 0, 0, 16, 96, KEY_EN_END, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Replace Pause w/ End
|
||||
{ 0, 0, 17, 102, KEY_EN_PAGE_UP, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert PgUp
|
||||
{ 0, 0, 18, 108, KEY_EN_PAGE_DOWN, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert PgDn
|
||||
|
||||
{ 0, 1, 14, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Remove Insert
|
||||
{ 0, 1, 15, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove Home
|
||||
{ 0, 1, 15, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove PgUp
|
||||
|
||||
{ 0, 2, 1, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Padding after Tab
|
||||
{ 0, 2, 15, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove Delete
|
||||
{ 0, 2, 15, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove End
|
||||
{ 0, 2, 15, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove PgDn
|
||||
|
||||
{ 0, 3, 1, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Padding after CapsLk
|
||||
{ 0, 3, 13, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove extra key
|
||||
{ 0, 3, 14, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove padding
|
||||
{ 0, 3, 14, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove padding
|
||||
{ 0, 4, 12, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove extra key
|
||||
{ 0, 4, 15, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove padding
|
||||
{ 0, 5, 12, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove Menu
|
||||
{ 0, 5, 16, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove padding
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const keyboard_keymap_overlay_values aula_f75_layout
|
||||
{
|
||||
KEYBOARD_SIZE_SEVENTY_FIVE,
|
||||
{
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 */
|
||||
0, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BSPC DEL */
|
||||
1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ PGUP */
|
||||
2, 8, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80,
|
||||
/* CPLK A S D F G H J K L ; " # ENTR PGDN */
|
||||
3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 0, 81,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU END */
|
||||
4, 0, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70,
|
||||
/* LCTL LWIN LALT SPC RALT RFNC RMNU RCTL ARWL ARWD ARWR */
|
||||
5, 11, 17, 35, 0, 53, 0, 59,
|
||||
},
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*--------------------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, Alternate Name, OpCode, |
|
||||
\*--------------------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 0, 0, 0, KEY_EN_ESCAPE, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Insert ESC
|
||||
{ 0, 1, 14, 85, KEY_EN_DELETE, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Delete
|
||||
{ 0, 2, 14, 86, KEY_EN_PAGE_UP, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert PgUp
|
||||
{ 0, 3, 14, 87, KEY_EN_PAGE_DOWN, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert PgDn
|
||||
|
||||
{ 0, 4, 12, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove RShift gap
|
||||
{ 0, 4, 13, 82, KEY_EN_UP_ARROW, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert UpArrow
|
||||
{ 0, 4, 14, 88, KEY_EN_END, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert End
|
||||
|
||||
{ 0, 5, 10, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove RAlt
|
||||
{ 0, 5, 11, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove RMenu
|
||||
|
||||
{ 0, 5, 12, 77, KEY_EN_LEFT_ARROW, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert LeftArrow
|
||||
{ 0, 5, 13, 83, KEY_EN_DOWN_ARROW, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert DownArrow
|
||||
{ 0, 5, 14, 89, KEY_EN_RIGHT_ARROW, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert RightArrow
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const keyboard_keymap_overlay_values aula_f87_layout
|
||||
{
|
||||
KEYBOARD_SIZE_TKL,
|
||||
{
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRNT SCRL PAUSE */
|
||||
0, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BSPC INSRT HOME PGUP */
|
||||
1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 85, 91, 97,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ DEL END PGDN */
|
||||
2, 8, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80, 86, 92, 98,
|
||||
/* CPLK A S D F G H J K L ; " # ENTR */
|
||||
3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 0, 81,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU */
|
||||
4, 0, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 82, 94,
|
||||
/* LCTL LWIN LALT SPC RALT RFNC RMNU RCTL ARWL ARWD ARWR */
|
||||
5, 11, 17, 35, 53, 59, 65, 83, 89, 95, 101
|
||||
},
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*--------------------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, Alternate Name, OpCode, |
|
||||
\*--------------------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 4, 12, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove RShift gap
|
||||
{ 0, 4, 14, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Add gap after RShift
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const keyboard_keymap_overlay_values leobog_hi75c_pro_layout
|
||||
{
|
||||
KEYBOARD_SIZE_SEVENTY_FIVE,
|
||||
{
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 */
|
||||
0, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BSPC DEL */
|
||||
1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ END */
|
||||
2, 8, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80,
|
||||
/* CPLK A S D F G H J K L ; " # ENTR PGUP */
|
||||
3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 0, 81,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU PGDN */
|
||||
4, 0, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70,
|
||||
/* LCTL LWIN LALT SPC RALT RFNC RMNU RCTL ARWL ARWD ARWR */
|
||||
5, 11, 17, 35, 53, 59, 0, 65,
|
||||
},
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*--------------------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, Alternate Name, OpCode, |
|
||||
\*--------------------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 0, 0, 0, KEY_EN_ESCAPE, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Insert ESC
|
||||
{ 0, 1, 14, 85, KEY_EN_DELETE, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Delete
|
||||
{ 0, 2, 14, 86, KEY_EN_END, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert End
|
||||
{ 0, 3, 14, 87, KEY_EN_PAGE_UP, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert PgUp
|
||||
{ 0, 4, 14, 88, KEY_EN_PAGE_DOWN, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert PgDn
|
||||
|
||||
{ 0, 4, 12, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove RShift gap
|
||||
{ 0, 4, 13, 82, KEY_EN_UP_ARROW, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert UpArrow
|
||||
|
||||
{ 0, 5, 12, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove RMenu
|
||||
{ 0, 5, 13, 77, KEY_EN_LEFT_ARROW, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert LeftArrow
|
||||
{ 0, 5, 14, 83, KEY_EN_DOWN_ARROW, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert DownArrow
|
||||
{ 0, 5, 15, 89, KEY_EN_RIGHT_ARROW, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert RightArrow
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const keyboard_keymap_overlay_values redragon_k686_eisa_pro
|
||||
{
|
||||
KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
{
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 NULL NULL NULL DEL HOME END PGUP PGDN */
|
||||
0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 0, 0, 0,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BSPC NULL NULL NULL NMLK NMDV NMTM NMMI */
|
||||
1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 0, 0, 0, 91, 97, 103, 109,
|
||||
/* TAB Q W E R T Y U I O P [ ] \ NULL NULL NULL NM7 NM8 NM9 NMPL */
|
||||
2, 8, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80, 0, 0, 0, 92, 98, 104, 110,
|
||||
/* CPLK A S D F G H J K L ; " # ENTR NM4 NM5 NM6 */
|
||||
3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 0, 81, 93, 99, 105,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER */
|
||||
4, 0, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 82, 88, 94, 100, 106, 112,
|
||||
/* LCTL LWIN LALT SPC RALT RFNC RMNU RCTL ARWL ARWD ARWR NM0 NMPD */
|
||||
5, 11, 17, 35, 53, 59, 0, 65, 83, 89, 95, 101, 107,
|
||||
},
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*--------------------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, Alternate Name, OpCode, |
|
||||
\*--------------------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 0, 14, 78, KEY_EN_DELETE, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Replace Print w/ Delete
|
||||
{ 0, 0, 15, 90, KEY_EN_INSERT, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Replace ScrLk w/ Insert
|
||||
{ 0, 0, 16, 96, KEY_EN_END, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Replace Pause w/ End
|
||||
{ 0, 0, 17, 102, KEY_EN_PAGE_UP, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert PgUp
|
||||
{ 0, 0, 18, 108, KEY_EN_PAGE_DOWN, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert PgDn
|
||||
{ 0, 2, 13, 75, KEY_EN_POUND, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Insert ] } Key
|
||||
{ 0, 4, 1, 76, KEY_EN_ISO_BACK_SLASH, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Insert \ | Key
|
||||
|
||||
{ 0, 1, 14, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Remove Insert
|
||||
{ 0, 1, 15, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove Home
|
||||
{ 0, 1, 15, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove PgUp
|
||||
|
||||
{ 0, 2, 1, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Padding after Tab
|
||||
{ 0, 2, 15, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove Delete
|
||||
{ 0, 2, 15, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove End
|
||||
{ 0, 2, 15, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove PgDn
|
||||
|
||||
{ 0, 3, 1, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Padding after CapsLk
|
||||
{ 0, 3, 13, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove extra key
|
||||
{ 0, 3, 14, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove padding
|
||||
{ 0, 3, 14, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove padding
|
||||
{ 0, 4, 12, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove extra key
|
||||
{ 0, 4, 15, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove padding
|
||||
{ 0, 5, 12, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove Menu
|
||||
{ 0, 5, 16, 0, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT, }, // Remove padding
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| DEVICE MODEL MAPPING |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
const sinowealth_device_map sinowealth_10c_keyboards{
|
||||
{
|
||||
0xCD, { "AULA F75", aula_f75_layout },
|
||||
},
|
||||
{
|
||||
0xA4, { "AULA F99", aula_f99_layout },
|
||||
},
|
||||
{
|
||||
0x0B, { "AULA F87 Pro", aula_f87_layout },
|
||||
},
|
||||
{
|
||||
0xA3, { "LEOBOG Hi75C Pro", leobog_hi75c_pro_layout },
|
||||
},
|
||||
{
|
||||
0x20, { "Redragon K686 Eisa Pro", redragon_k686_eisa_pro },
|
||||
},
|
||||
{
|
||||
0x05, { "Redragon K686 Eisa Pro", redragon_k686_eisa_pro },
|
||||
},
|
||||
};
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| SinowealthKeyboard10cDevices.cpp |
|
||||
| |
|
||||
| Device list for Sinowealth Keyboards with PID 010C |
|
||||
| |
|
||||
| Rodrigo Tavares 27 Nov 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "KeyboardLayoutManager.h"
|
||||
|
||||
typedef std::pair<const char*, unsigned char> led_pair;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
std::string device_name;
|
||||
keyboard_keymap_overlay_values keyboard_layout;
|
||||
} sinowealth_device;
|
||||
|
||||
typedef std::map<unsigned char, sinowealth_device> sinowealth_device_map;
|
||||
|
||||
extern const sinowealth_device_map sinowealth_10c_keyboards;
|
||||
+463
@@ -0,0 +1,463 @@
|
||||
/*------------------------------------------*\
|
||||
| RGBController_SinowealthKeyboard16.cpp |
|
||||
| |
|
||||
| Definitions and types for Sinowealth |
|
||||
| Keyboard with PID:0016, |
|
||||
| Hopefully generic for this PID, |
|
||||
| this was made spefically for ZUOYA X51 |
|
||||
| |
|
||||
| Zagorodnikov Aleksey (glooom) 26.07.2021 |
|
||||
| based on initial implementation from |
|
||||
| Dmitri Kalinichenko (Dima-Kal) 23/06/2021 |
|
||||
\*-----------------------------------------=*/
|
||||
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "RGBController_SinowealthKeyboard16.h"
|
||||
#include <algorithm>
|
||||
|
||||
#define NA 0xFFFFFFFF
|
||||
|
||||
using namespace kbd16;
|
||||
|
||||
static unsigned int matrix_map[6][22] =
|
||||
{ { 0, NA, 2, 3, 4, 5, NA, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, NA, NA, NA, NA },
|
||||
{ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, NA, 36, 37, 38, 39, 40, 41, 42, 43 },
|
||||
{ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, NA, 59, 60, 61, 62, 63, 64, 65 },
|
||||
{ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, NA, 79, NA, NA, NA, NA, 84, 85, 86, 87 },
|
||||
{ 88, NA, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, NA, NA, 102, NA, 104, NA, 106, 107, 108, 109 },
|
||||
{ 110, 111, 112, NA, NA, 115, NA, NA, 118, 119, 120, NA, 122, NA, NA, 125, 126, 127, 128, 129, 130, 131 }
|
||||
};
|
||||
|
||||
static const char *led_names_tkl[] =
|
||||
{
|
||||
KEY_EN_ESCAPE,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_F1,
|
||||
KEY_EN_F2,
|
||||
KEY_EN_F3,
|
||||
KEY_EN_F4,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_F5,
|
||||
KEY_EN_F6,
|
||||
KEY_EN_F7,
|
||||
KEY_EN_F8,
|
||||
KEY_EN_F9,
|
||||
KEY_EN_F10,
|
||||
KEY_EN_F11,
|
||||
KEY_EN_F12,
|
||||
KEY_EN_PRINT_SCREEN,
|
||||
KEY_EN_SCROLL_LOCK,
|
||||
KEY_EN_PAUSE_BREAK,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
|
||||
KEY_EN_BACK_TICK,
|
||||
KEY_EN_1,
|
||||
KEY_EN_2,
|
||||
KEY_EN_3,
|
||||
KEY_EN_4,
|
||||
KEY_EN_5,
|
||||
KEY_EN_6,
|
||||
KEY_EN_7,
|
||||
KEY_EN_8,
|
||||
KEY_EN_9,
|
||||
KEY_EN_0,
|
||||
KEY_EN_MINUS,
|
||||
KEY_EN_EQUALS,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_BACKSPACE,
|
||||
KEY_EN_INSERT,
|
||||
KEY_EN_HOME,
|
||||
KEY_EN_PAGE_UP,
|
||||
KEY_EN_NUMPAD_LOCK,
|
||||
KEY_EN_NUMPAD_DIVIDE,
|
||||
KEY_EN_NUMPAD_TIMES,
|
||||
KEY_EN_NUMPAD_MINUS,
|
||||
|
||||
KEY_EN_TAB,
|
||||
KEY_EN_Q,
|
||||
KEY_EN_W,
|
||||
KEY_EN_E,
|
||||
KEY_EN_R,
|
||||
KEY_EN_T,
|
||||
KEY_EN_Y,
|
||||
KEY_EN_U,
|
||||
KEY_EN_I,
|
||||
KEY_EN_O,
|
||||
KEY_EN_P,
|
||||
KEY_EN_LEFT_BRACKET,
|
||||
KEY_EN_RIGHT_BRACKET,
|
||||
KEY_EN_ANSI_BACK_SLASH,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_DELETE,
|
||||
KEY_EN_END,
|
||||
KEY_EN_PAGE_DOWN,
|
||||
KEY_EN_NUMPAD_7,
|
||||
KEY_EN_NUMPAD_8,
|
||||
KEY_EN_NUMPAD_9,
|
||||
KEY_EN_NUMPAD_PLUS,
|
||||
|
||||
KEY_EN_CAPS_LOCK,
|
||||
KEY_EN_A,
|
||||
KEY_EN_S,
|
||||
KEY_EN_D,
|
||||
KEY_EN_F,
|
||||
KEY_EN_G,
|
||||
KEY_EN_H,
|
||||
KEY_EN_J,
|
||||
KEY_EN_K,
|
||||
KEY_EN_L,
|
||||
KEY_EN_SEMICOLON,
|
||||
KEY_EN_QUOTE,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_ANSI_ENTER,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_NUMPAD_4,
|
||||
KEY_EN_NUMPAD_5,
|
||||
KEY_EN_NUMPAD_6,
|
||||
KEY_EN_NUMPAD_PLUS,
|
||||
|
||||
KEY_EN_LEFT_SHIFT,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_Z,
|
||||
KEY_EN_X,
|
||||
KEY_EN_C,
|
||||
KEY_EN_V,
|
||||
KEY_EN_B,
|
||||
KEY_EN_N,
|
||||
KEY_EN_M,
|
||||
KEY_EN_COMMA,
|
||||
KEY_EN_PERIOD,
|
||||
KEY_EN_FORWARD_SLASH,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_RIGHT_SHIFT,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UP_ARROW,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_NUMPAD_1,
|
||||
KEY_EN_NUMPAD_2,
|
||||
KEY_EN_NUMPAD_3,
|
||||
KEY_EN_NUMPAD_ENTER,
|
||||
|
||||
KEY_EN_LEFT_CONTROL,
|
||||
KEY_EN_LEFT_WINDOWS,
|
||||
KEY_EN_LEFT_ALT,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_SPACE,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_RIGHT_ALT,
|
||||
KEY_EN_RIGHT_FUNCTION,
|
||||
KEY_EN_RIGHT_WINDOWS,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_RIGHT_CONTROL,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_LEFT_ARROW,
|
||||
KEY_EN_DOWN_ARROW,
|
||||
KEY_EN_RIGHT_ARROW,
|
||||
KEY_EN_NUMPAD_0,
|
||||
KEY_EN_NUMPAD_0,
|
||||
KEY_EN_NUMPAD_PERIOD,
|
||||
KEY_EN_NUMPAD_ENTER
|
||||
};
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Sinowealth Keyboard 16
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :x:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectSinowealthKeyboard
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_SinowealthKeyboard16::RGBController_SinowealthKeyboard16(SinowealthKeyboard16Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetName();
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "Sinowealth Keyboard Device";
|
||||
location = controller->GetLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
std::vector<ModeCfg> modes_cfg = controller->GetDeviceModes();
|
||||
std::vector<ModeColorCfg> color_presets = controller->GetDeviceColors();
|
||||
|
||||
int mode_id = 0;
|
||||
|
||||
for(const ModeCfg &cfg : modes_cfg)
|
||||
{
|
||||
mode Mode = getModeItem(mode_id);
|
||||
|
||||
Mode.brightness = cfg.brightness;
|
||||
Mode.speed = cfg.speed;
|
||||
Mode.direction = cfg.direction_left;
|
||||
|
||||
if(cfg.color == COLOR_PRESET_RANDOM)
|
||||
{
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
Mode.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
}
|
||||
|
||||
ModeColorCfg mode_color = color_presets[mode_id];
|
||||
|
||||
for(unsigned int i = Mode.colors_min; i < Mode.colors_max; i++)
|
||||
{
|
||||
RGBColor color = (mode_color.preset[i].blue << 16) | (mode_color.preset[i].green << 8) | (mode_color.preset[i].red);
|
||||
Mode.colors.push_back(color);
|
||||
}
|
||||
|
||||
modes.push_back(Mode);
|
||||
mode_id++;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| This keyboard supports 5 configurable custom profiles. |
|
||||
| The first one is named "Custom" and the others are "Custom 2" to |
|
||||
| "Custom 5". Leaving the first one just "Custom" to adhere to |
|
||||
| common mode names scheme. |
|
||||
\*-----------------------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < 5; i++)
|
||||
{
|
||||
mode PerLed;
|
||||
|
||||
PerLed.name = "Custom";
|
||||
|
||||
if(i > 0)
|
||||
{
|
||||
PerLed.name += " " + std::to_string(i + 1);
|
||||
}
|
||||
|
||||
PerLed.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
PerLed.color_mode = MODE_COLORS_PER_LED;
|
||||
PerLed.value = MODE_PER_KEY1+i;
|
||||
|
||||
modes.push_back(PerLed);
|
||||
}
|
||||
|
||||
SetupZones();
|
||||
|
||||
int device_mode = controller->GetCurrentMode();
|
||||
|
||||
if(device_mode >= MODE_PER_KEY1)
|
||||
{
|
||||
device_mode = mode_id+(device_mode & 0x0F);
|
||||
colors = controller->GetPerLedColors();
|
||||
}
|
||||
|
||||
active_mode = device_mode;
|
||||
}
|
||||
|
||||
RGBController_SinowealthKeyboard16::~RGBController_SinowealthKeyboard16()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
mode RGBController_SinowealthKeyboard16::getModeItem(unsigned int mode_id)
|
||||
{
|
||||
mode Mode;
|
||||
|
||||
Mode.value = mode_id;
|
||||
Mode.brightness_min = BRIGHTNESS_OFF;
|
||||
Mode.brightness_max = BRIGHTNESS_FULL;
|
||||
Mode.speed_min = SPEED_SLOW;
|
||||
Mode.speed_max = SPEED_FASTEST;
|
||||
Mode.colors_min = 0;
|
||||
Mode.colors_max = COLOR_PRESETS_IN_MODE;
|
||||
|
||||
switch(mode_id)
|
||||
{
|
||||
case 0:
|
||||
Mode.name = "Off";
|
||||
Mode.flags = 0;
|
||||
Mode.color_mode = MODE_COLORS_NONE;
|
||||
break;
|
||||
case 1:
|
||||
Mode.name = "Spectrum Cycle";
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Mode.color_mode = MODE_COLORS_NONE;
|
||||
break;
|
||||
case 2:
|
||||
Mode.name = "Breathing";
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
break;
|
||||
case 3:
|
||||
Mode.name = "Static";
|
||||
Mode.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
break;
|
||||
case 4:
|
||||
Mode.name = "Ripples Shining";
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
break;
|
||||
case 5:
|
||||
Mode.name = "Reactive";
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
break;
|
||||
case 6:
|
||||
Mode.name = "Flash Away";
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
break;
|
||||
case 7:
|
||||
Mode.name = "Sine Wave";
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
break;
|
||||
case 8:
|
||||
Mode.name = "Raindrops";
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
break;
|
||||
case 9:
|
||||
Mode.name = "Rainbow Wave";
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
break;
|
||||
case 10:
|
||||
Mode.name = "Rainbow Wheel";
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
break;
|
||||
case 11:
|
||||
Mode.name = "Adorn";
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
break;
|
||||
case 12:
|
||||
Mode.name = "Stars Twinkle";
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
break;
|
||||
case 13:
|
||||
Mode.name = "Shadow Disappear";
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
break;
|
||||
case 14:
|
||||
Mode.name = "Retro Snake";
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
break;
|
||||
default:
|
||||
Mode.name = "Unknown Mode";
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
break;
|
||||
}
|
||||
|
||||
return Mode;
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard16::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
zone new_zone;
|
||||
|
||||
new_zone.name = ZONE_EN_KEYBOARD;
|
||||
new_zone.type = ZONE_TYPE_MATRIX;
|
||||
new_zone.leds_count = controller->GetLEDCount();
|
||||
new_zone.leds_min = new_zone.leds_count;
|
||||
new_zone.leds_max = new_zone.leds_count;
|
||||
new_zone.matrix_map = new matrix_map_type;
|
||||
new_zone.matrix_map->height = 6;
|
||||
new_zone.matrix_map->width = 22;
|
||||
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int led_idx = 0; led_idx < new_zone.leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = led_names_tkl[led_idx];
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard16::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard16::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetLEDsDirect(colors);
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard16::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard16::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard16::DeviceUpdateMode()
|
||||
{
|
||||
mode ActiveMode = modes[active_mode];
|
||||
|
||||
int color_mode;
|
||||
|
||||
if(ActiveMode.color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
color_mode = COLOR_PRESET_0;
|
||||
}
|
||||
else
|
||||
{
|
||||
color_mode = COLOR_PRESET_RANDOM;
|
||||
}
|
||||
|
||||
controller->ClearMode();
|
||||
|
||||
if(ActiveMode.colors.size())
|
||||
{
|
||||
controller->SetColorsForMode(ActiveMode.value, &ActiveMode.colors[0]);
|
||||
}
|
||||
|
||||
controller->SetMode(ActiveMode.value, ActiveMode.brightness, ActiveMode.speed, ActiveMode.direction, color_mode);
|
||||
|
||||
if(ActiveMode.value >= MODE_PER_KEY1)
|
||||
{
|
||||
colors = controller->GetPerLedColors();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(color_mode == COLOR_PRESET_RANDOM)
|
||||
{
|
||||
std::generate(colors.begin(), colors.end(), std::rand);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::fill(colors.begin(), colors.end(), ActiveMode.colors[0]);
|
||||
}
|
||||
}
|
||||
|
||||
SignalUpdate();
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*------------------------------------------*\
|
||||
| RGBController_SinowealthKeyboard16.h |
|
||||
| |
|
||||
| Definitions and types for Sinowealth |
|
||||
| Keyboard with PID:0016, |
|
||||
| Hopefully generic for this PID, |
|
||||
| this was made spefically for ZUOYA X51 |
|
||||
| |
|
||||
| Zagorodnikov Aleksey (glooom) 26.07.2021 |
|
||||
| based on initial implementation from |
|
||||
| Dmitri Kalinichenko (Dima-Kal) 23/06/2021 |
|
||||
\*-----------------------------------------=*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "SinowealthKeyboard16Controller.h"
|
||||
|
||||
class RGBController_SinowealthKeyboard16 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_SinowealthKeyboard16(SinowealthKeyboard16Controller* controller_ptr);
|
||||
~RGBController_SinowealthKeyboard16();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
SinowealthKeyboard16Controller* controller;
|
||||
|
||||
mode getModeItem(unsigned int mode_id);
|
||||
};
|
||||
+340
@@ -0,0 +1,340 @@
|
||||
/*------------------------------------------*\
|
||||
| SinowealthKeyboard16Controller.cpp |
|
||||
| |
|
||||
| Definitions and types for Sinowealth |
|
||||
| Keyboard with PID:0016, |
|
||||
| Hopefully generic for this PID, |
|
||||
| this was made spefically for ZUOYA X51 |
|
||||
| |
|
||||
| Zagorodnikov Aleksey (glooom) 26.07.2021 |
|
||||
| based on initial implementation from |
|
||||
| Dmitri Kalinichenko (Dima-Kal) 23/06/2021 |
|
||||
\*-----------------------------------------=*/
|
||||
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include "LogManager.h"
|
||||
#include "SinowealthKeyboard16Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
using namespace kbd16;
|
||||
|
||||
static unsigned char request_init[] = {0x05, 0x01, 0xAA, 0xBB, 0x2F, 0x3E};
|
||||
static unsigned char request_modes[] = {0x05, 0x83, 0x00, 0x00, 0x00, 0x00};
|
||||
static unsigned char request_colors[] = {0x05, 0x88, 0xA8, 0x00, 0x40, 0x00};
|
||||
static unsigned char request_per_led_cm12[] = {0x05, 0x89, 0xAC, 0x00, 0x40, 0x00};
|
||||
static unsigned char request_per_led_cm34[] = {0x05, 0x89, 0xB0, 0x00, 0x40, 0x00};
|
||||
static unsigned char request_per_led_cm5[] = {0x05, 0x89, 0xB4, 0x00, 0x40, 0x00};
|
||||
|
||||
|
||||
SinowealthKeyboard16Controller::SinowealthKeyboard16Controller(hid_device* cmd_handle, hid_device* data_handle, char* path, std::string dev_name)
|
||||
{
|
||||
dev_cmd = cmd_handle;
|
||||
dev_data = data_handle;
|
||||
name = dev_name;
|
||||
|
||||
led_count = 132;
|
||||
|
||||
current_mode = MODE_OFF;
|
||||
location = path;
|
||||
|
||||
memset(mode_config_buf, 0x00, sizeof(mode_config_buf));
|
||||
|
||||
initCommunication();
|
||||
UpdateConfigurationFromDevice();
|
||||
}
|
||||
|
||||
SinowealthKeyboard16Controller::~SinowealthKeyboard16Controller()
|
||||
{
|
||||
hid_close(dev_cmd);
|
||||
hid_close(dev_data);
|
||||
}
|
||||
|
||||
std::string SinowealthKeyboard16Controller::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string SinowealthKeyboard16Controller::GetName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
unsigned char SinowealthKeyboard16Controller::GetCurrentMode()
|
||||
{
|
||||
return current_mode;
|
||||
}
|
||||
|
||||
unsigned int SinowealthKeyboard16Controller::GetLEDCount()
|
||||
{
|
||||
return led_count;
|
||||
}
|
||||
|
||||
std::string SinowealthKeyboard16Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev_cmd, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void SinowealthKeyboard16Controller::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
{
|
||||
const int colors_offset = led_count;
|
||||
int i = colors_start_idx;
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| CM2 and CM4 presets are located in second half of corresponding arrays |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
if(current_custom_preset == 1 || current_custom_preset == 3)
|
||||
{
|
||||
i += (led_count * 3);
|
||||
}
|
||||
|
||||
for(const RGBColor &color : colors)
|
||||
{
|
||||
per_button_color_buf[i] = RGBGetBValue(color);
|
||||
per_button_color_buf[i + colors_offset] = RGBGetGValue(color);
|
||||
per_button_color_buf[i + colors_offset + colors_offset] = RGBGetRValue(color);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
sendConfig(per_button_color_buf);
|
||||
}
|
||||
|
||||
void SinowealthKeyboard16Controller::SetMode(unsigned char mode, unsigned char brightness, unsigned char speed, bool direction_left, unsigned char color_mode)
|
||||
{
|
||||
if(mode >= MODE_PER_KEY1)
|
||||
{
|
||||
current_custom_preset = (mode & 0x0F);
|
||||
mode_config_buf[current_mode_idx] = MODE_PER_KEY;
|
||||
mode_config_buf[per_key_mode_idx] = 1;
|
||||
mode_config_buf[current_mode_idx+1] = (0x20 | current_custom_preset);
|
||||
|
||||
GetButtonColorsConfig(per_button_color_buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
mode_config_buf[current_mode_idx] = mode;
|
||||
device_modes[mode].brightness = brightness;
|
||||
device_modes[mode].speed = speed;
|
||||
device_modes[mode].color = color_mode;
|
||||
device_modes[mode].direction_left = direction_left;
|
||||
mode_config_buf[per_key_mode_idx] = 0;
|
||||
}
|
||||
|
||||
if(sendConfig(mode_config_buf))
|
||||
{
|
||||
current_mode = mode;
|
||||
}
|
||||
}
|
||||
|
||||
void SinowealthKeyboard16Controller::SetColorsForMode(unsigned char mode, RGBColor *profiles)
|
||||
{
|
||||
if(mode >= MODE_PER_KEY1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < COLOR_PRESETS_IN_MODE; i++)
|
||||
{
|
||||
modes_colors[mode].preset[i].red = RGBGetRValue(profiles[i]);
|
||||
modes_colors[mode].preset[i].green = RGBGetGValue(profiles[i]);
|
||||
modes_colors[mode].preset[i].blue = RGBGetBValue(profiles[i]);
|
||||
}
|
||||
|
||||
sendConfig(colors_config_buf);
|
||||
}
|
||||
|
||||
void SinowealthKeyboard16Controller::ClearMode()
|
||||
{
|
||||
mode_config_buf[per_key_mode_idx] = 0;
|
||||
mode_config_buf[current_mode_idx] = 0;
|
||||
mode_config_buf[current_mode_idx+1] = 0;
|
||||
|
||||
sendConfig(mode_config_buf);
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Before apply new settings, keyboard needs turn off LEDs and wait |
|
||||
| ~200ms, otherwise sometime glitches happens. |
|
||||
\*-----------------------------------------------------------------*/
|
||||
std::this_thread::sleep_for(200ms);
|
||||
}
|
||||
|
||||
std::vector<ModeCfg> SinowealthKeyboard16Controller::GetDeviceModes()
|
||||
{
|
||||
std::vector<ModeCfg> modes;
|
||||
|
||||
for(int i = 0; i < profiles_count; i++)
|
||||
{
|
||||
modes.push_back(device_modes[i]);
|
||||
}
|
||||
|
||||
return modes;
|
||||
}
|
||||
|
||||
std::vector<ModeColorCfg> SinowealthKeyboard16Controller::GetDeviceColors()
|
||||
{
|
||||
std::vector<ModeColorCfg> presets;
|
||||
|
||||
for(int i = 0; i < profiles_count; i++)
|
||||
{
|
||||
presets.push_back(modes_colors[i]);
|
||||
}
|
||||
|
||||
return presets;
|
||||
}
|
||||
|
||||
std::vector<RGBColor> SinowealthKeyboard16Controller::GetPerLedColors()
|
||||
{
|
||||
const int colors_offset = led_count;
|
||||
int start_idx = colors_start_idx;
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| CM2 and CM4 presets are located in second half of corresponding arrays |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
if(current_custom_preset == 1 || current_custom_preset == 3)
|
||||
{
|
||||
start_idx += (led_count * 3);
|
||||
}
|
||||
|
||||
std::vector<RGBColor> res;
|
||||
res.resize(led_count);
|
||||
|
||||
for(unsigned int i = 0; i < led_count; i++)
|
||||
{
|
||||
RGBColor color = (per_button_color_buf[start_idx+i] << 16)
|
||||
| (per_button_color_buf[start_idx+i+colors_offset] << 8)
|
||||
| (per_button_color_buf[start_idx+i+colors_offset+colors_offset]);
|
||||
|
||||
res[i] = color;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void SinowealthKeyboard16Controller::UpdateConfigurationFromDevice()
|
||||
{
|
||||
GetModesConfig(mode_config_buf);
|
||||
GetColorsConfig(colors_config_buf);
|
||||
|
||||
current_mode = mode_config_buf[current_mode_idx];
|
||||
device_modes = (struct ModeCfg*) &mode_config_buf[profiles_start_idx];
|
||||
modes_colors = (struct ModeColorCfg*) &colors_config_buf[colors_start_idx];
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| When OEM software switch keyboard to custom mode it set 0x0F into 0x15 |
|
||||
| byte and 01 into 0x14 byte. However if user manually switch to this mode |
|
||||
| through Fn+1 the keyboard only sets 0x14 byte by itself, but not touched |
|
||||
| 0x15 byte. Not sure what part is more important, so managing both bytes. |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
if(current_mode == MODE_PER_KEY || mode_config_buf[per_key_mode_idx] == 1)
|
||||
{
|
||||
current_custom_preset = (mode_config_buf[current_mode_idx+1] & 0x0F);
|
||||
current_mode = ((MODE_PER_KEY&0xF) << 4) | current_custom_preset;
|
||||
|
||||
GetButtonColorsConfig(per_button_color_buf);
|
||||
}
|
||||
}
|
||||
|
||||
void SinowealthKeyboard16Controller::GetModesConfig(unsigned char *buf)
|
||||
{
|
||||
if(!getConfig(request_modes, buf))
|
||||
{
|
||||
LOG_ERROR("[%s] Could not read modes config table", name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void SinowealthKeyboard16Controller::GetColorsConfig(unsigned char *buf)
|
||||
{
|
||||
if(!getConfig(request_colors, buf))
|
||||
{
|
||||
LOG_ERROR("[%s] Could not read colors config table", name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void SinowealthKeyboard16Controller::GetButtonColorsConfig(unsigned char *buf)
|
||||
{
|
||||
unsigned char *req;
|
||||
|
||||
switch(current_custom_preset)
|
||||
{
|
||||
case 2: // CM3
|
||||
case 3: // CM4
|
||||
req = request_per_led_cm34;
|
||||
break;
|
||||
case 4: // CM5
|
||||
req = request_per_led_cm5;
|
||||
break;
|
||||
case 0: // CM1
|
||||
case 1: // CM2
|
||||
default:
|
||||
req = request_per_led_cm12;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!getConfig(req, buf))
|
||||
{
|
||||
LOG_ERROR("[%s] Could not read per LED config table", name.c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SinowealthKeyboard16Controller::initCommunication()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This needs to be sent first time after powerup keyboard. |
|
||||
\*---------------------------------------------------------*/
|
||||
hid_send_feature_report(dev_cmd, request_init, 6);
|
||||
}
|
||||
|
||||
bool SinowealthKeyboard16Controller::getConfig(unsigned char *request, unsigned char *buf)
|
||||
{
|
||||
hid_send_feature_report(dev_cmd, request, 6);
|
||||
|
||||
unsigned char response[PAYLOAD_LEN];
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*---------------------------------------------------------*/
|
||||
memset(response, 0x00, PAYLOAD_LEN);
|
||||
|
||||
response[0] = 0x06;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get the response and put it in the response buffer |
|
||||
\*---------------------------------------------------------*/
|
||||
if(hid_get_feature_report(dev_data, response, PAYLOAD_LEN) != -1)
|
||||
{
|
||||
response[1] &= ~0x80; // Clear response flag
|
||||
response[2] = request[2];
|
||||
response[3] = request[3];
|
||||
response[4] = request[4];
|
||||
response[5] = request[5];
|
||||
memcpy(buf,response,PAYLOAD_LEN);
|
||||
read_config_error = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
read_config_error = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SinowealthKeyboard16Controller::sendConfig(unsigned char *buf)
|
||||
{
|
||||
if(read_config_error)
|
||||
{
|
||||
LOG_ERROR("[%s] Can't send new config if reading old config fail", name.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
int result = hid_send_feature_report(dev_data, buf, PAYLOAD_LEN);
|
||||
return (result != -1);
|
||||
}
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
/*------------------------------------------*\
|
||||
| SinowealthKeyboard16Controller.h |
|
||||
| |
|
||||
| Definitions and types for Sinowealth |
|
||||
| Keyboard with PID:0016, |
|
||||
| Hopefully generic for this PID, |
|
||||
| this was made spefically for ZUOYA X51 |
|
||||
| |
|
||||
| Zagorodnikov Aleksey (glooom) 26.07.2021 |
|
||||
| based on initial implementation from |
|
||||
| Dmitri Kalinichenko (Dima-Kal) 23/06/2021 |
|
||||
\*-----------------------------------------=*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
#define PAYLOAD_LEN 1032
|
||||
#define COLOR_PRESETS_IN_MODE 7
|
||||
|
||||
namespace kbd16
|
||||
{
|
||||
enum
|
||||
{
|
||||
MODE_OFF = 0,
|
||||
/*
|
||||
MODE_COLOR_LOOP = 1,
|
||||
MODE_RESPIRE = 2,
|
||||
MODE_STATIC = 3,
|
||||
MODE_RIPPLES_SHINING = 4,
|
||||
MODE_REACTION = 5,
|
||||
MODE_FLASH_AWAY = 6,
|
||||
MODE_SINE_WAVE = 7,
|
||||
MODE_RAINDROPS = 8,
|
||||
MODE_NEON_STREAM = 9,
|
||||
MODE_RAINBOW_WHEEL = 10,
|
||||
MODE_ADORN = 11,
|
||||
MODE_STARS_TWINKLE = 12,
|
||||
MODE_SHADOW_DISAPPEAR = 13,
|
||||
MODE_RETRO_SNAKE = 14,
|
||||
*/
|
||||
MODE_PER_KEY = 0x0F, // General mode for custom presets
|
||||
MODE_PER_KEY1 = 0xF0,
|
||||
MODE_PER_KEY2 = 0xF1,
|
||||
MODE_PER_KEY3 = 0xF2,
|
||||
MODE_PER_KEY4 = 0xF3,
|
||||
MODE_PER_KEY5 = 0xF4,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SPEED_SLOW = 0x00,
|
||||
SPEED_NORMAL = 0x01,
|
||||
SPEED_FAST = 0x02,
|
||||
SPEED_FASTER = 0x03,
|
||||
SPEED_FASTEST = 0x04,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
BRIGHTNESS_OFF = 0x00,
|
||||
BRIGHTNESS_QUARTER = 0x01,
|
||||
BRIGHTNESS_HALF = 0x02,
|
||||
BRIGHTNESS_THREE_QUARTERS = 0x03,
|
||||
BRIGHTNESS_FULL = 0x04,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
COLOR_PRESET_0 = 0,
|
||||
COLOR_PRESET_1 = 1,
|
||||
COLOR_PRESET_2 = 2,
|
||||
COLOR_PRESET_3 = 3,
|
||||
COLOR_PRESET_4 = 4,
|
||||
COLOR_PRESET_5 = 5,
|
||||
COLOR_PRESET_6 = 6,
|
||||
COLOR_PRESET_RANDOM = 7,
|
||||
};
|
||||
}
|
||||
|
||||
struct ModeCfg
|
||||
{
|
||||
unsigned char color:3;
|
||||
unsigned char :4;
|
||||
unsigned char direction_left:1;
|
||||
unsigned char brightness:4;
|
||||
unsigned char speed:4;
|
||||
};
|
||||
|
||||
struct ColorCfg
|
||||
{
|
||||
unsigned char blue:8;
|
||||
unsigned char green:8;
|
||||
unsigned char red:8;
|
||||
};
|
||||
|
||||
struct ModeColorCfg
|
||||
{
|
||||
ColorCfg preset[COLOR_PRESETS_IN_MODE];
|
||||
};
|
||||
|
||||
class SinowealthKeyboard16Controller
|
||||
{
|
||||
public:
|
||||
SinowealthKeyboard16Controller(hid_device* cmd_handle, hid_device* data_handle, char *_path, std::string dev_name);
|
||||
~SinowealthKeyboard16Controller();
|
||||
|
||||
unsigned int GetLEDCount();
|
||||
std::string GetLocation();
|
||||
std::string GetName();
|
||||
std::string GetSerialString();
|
||||
unsigned char GetCurrentMode();
|
||||
std::vector<ModeCfg> GetDeviceModes();
|
||||
std::vector<ModeColorCfg> GetDeviceColors();
|
||||
std::vector<RGBColor> GetPerLedColors();
|
||||
|
||||
void SetLEDColor(RGBColor* color_buf);
|
||||
void SetMode(unsigned char mode, unsigned char brightness, unsigned char speed, RGBColor* color_buf);
|
||||
void ClearMode();
|
||||
void SetMode(unsigned char mode, unsigned char brightness, unsigned char speed, bool direction_left, unsigned char color_mode);
|
||||
void SetColorsForMode(unsigned char mode, RGBColor profiles[COLOR_PRESETS_IN_MODE]);
|
||||
void GetProfile();
|
||||
void ReadFirmwareInfo();
|
||||
void SetLEDsDirect(std::vector<RGBColor> colors);
|
||||
|
||||
const int per_key_mode_idx = 20;
|
||||
const int current_mode_idx = 21;
|
||||
const int profiles_start_idx = 32;
|
||||
const int profiles_count = 15;
|
||||
const int colors_start_idx = 8;
|
||||
|
||||
private:
|
||||
hid_device* dev_cmd;
|
||||
hid_device* dev_data;
|
||||
device_type type;
|
||||
std::string name;
|
||||
|
||||
unsigned int led_count;
|
||||
|
||||
unsigned char current_mode;
|
||||
struct ModeCfg* device_modes;
|
||||
struct ModeColorCfg* modes_colors;
|
||||
|
||||
std::string location;
|
||||
|
||||
unsigned char mode_config_buf[PAYLOAD_LEN];
|
||||
unsigned char colors_config_buf[PAYLOAD_LEN];
|
||||
unsigned char per_button_color_buf[PAYLOAD_LEN];
|
||||
bool read_config_error = false;
|
||||
unsigned char current_custom_preset = 0;
|
||||
|
||||
void GetModesConfig(unsigned char *buf);
|
||||
void GetColorsConfig(unsigned char *buf);
|
||||
void GetButtonColorsConfig(unsigned char *buf);
|
||||
|
||||
void initCommunication();
|
||||
bool getConfig(unsigned char reqest[], unsigned char *buf);
|
||||
bool sendConfig(unsigned char *buf);
|
||||
|
||||
void UpdateConfigurationFromDevice();
|
||||
};
|
||||
+249
@@ -0,0 +1,249 @@
|
||||
/*------------------------------------------*\
|
||||
| RGBController_SinowealthKeyboard90.cpp |
|
||||
| |
|
||||
| Definitions and types for Sinowealth |
|
||||
| Keyboard with PID:0090, |
|
||||
| made spefically for Genesis Thor 300 |
|
||||
| |
|
||||
| Jan Baier 30/06/2022 |
|
||||
\*-----------------------------------------=*/
|
||||
|
||||
#include "RGBController_SinowealthKeyboard90.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
using namespace thor300;
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Genesis Thor 300
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :rotating_light:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectSinowealthGenesisKeyboard
|
||||
@comment Direct mode is not supported by the keyboard
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_SinowealthKeyboard90::RGBController_SinowealthKeyboard90(SinowealthKeyboard90Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "Sinowealth";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "Generic Sinowealth Keyboard";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
AddMode("Breathing", MODE_BREATHING, true );
|
||||
AddMode("CCW Rotation", MODE_CCW_ROTATION, false );
|
||||
AddMode("CW Rotation", MODE_CW_ROTATION, false );
|
||||
AddMode("Flowers Blossom", MODE_FLOWERS_BLOSSOM, false );
|
||||
AddMode("Neon", MODE_NEON, true );
|
||||
AddMode("Prismo", MODE_PRISMO, false );
|
||||
AddMode("Rainbow Wave", MODE_RAINBOW, false );
|
||||
AddMode("Raindrops", MODE_RAINDROPS, true );
|
||||
AddMode("Reactive", MODE_RESPONSE, false );
|
||||
AddMode("Single Key Reactive", MODE_RESPONSE_SINGLE, true );
|
||||
AddMode("Snake", MODE_SNAKE, true );
|
||||
AddMode("Stars Twinkling", MODE_TWINKLING, true );
|
||||
AddMode("Static", MODE_STATIC, true );
|
||||
AddMode("Tornado", MODE_TORNADO, true );
|
||||
AddMode("Wave 1", MODE_WAVE_1, true );
|
||||
AddMode("Wave 2", MODE_WAVE_2, false );
|
||||
AddMode("Wave 3", MODE_WAVE_3, true );
|
||||
AddMode("Wave 4", MODE_WAVE_4, true );
|
||||
AddMode("Wave 5", MODE_WAVE_5, false );
|
||||
|
||||
mode Custom;
|
||||
Custom.name = "Custom";
|
||||
Custom.value = MODE_CUSTOM;
|
||||
Custom.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Custom.brightness_min = BRIGHTNESS_OFF;
|
||||
Custom.brightness_max = BRIGHTNESS_FULL;
|
||||
Custom.brightness = BRIGHTNESS_FULL;
|
||||
Custom.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Custom);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = MODE_STATIC;
|
||||
Off.flags = MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Off);
|
||||
|
||||
active_mode = (int)modes.size() - 1;
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_SinowealthKeyboard90::~RGBController_SinowealthKeyboard90()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| 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_SinowealthKeyboard90::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zone |
|
||||
\*---------------------------------------------------------*/
|
||||
zone new_zone;
|
||||
new_zone.name = "Keyboard";
|
||||
new_zone.type = ZONE_TYPE_MATRIX;
|
||||
new_zone.leds_count = 104;
|
||||
new_zone.leds_min = new_zone.leds_count;
|
||||
new_zone.leds_max = new_zone.leds_count;
|
||||
|
||||
new_zone.matrix_map = new matrix_map_type;
|
||||
new_zone.matrix_map->height = 6;
|
||||
new_zone.matrix_map->width = 23;
|
||||
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < new_zone.leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = led_names[led_idx].name;
|
||||
new_led.value = led_names[led_idx].idx;
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard90::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard90::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SendMode(modes[active_mode].value, modes[active_mode].brightness);
|
||||
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
unsigned char key = leds[led_idx].value;
|
||||
unsigned char red = RGBGetRValue(colors[led_idx]);
|
||||
unsigned char green = RGBGetGValue(colors[led_idx]);
|
||||
unsigned char blue = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
controller->SendSingleLED(key, red, green, blue);
|
||||
}
|
||||
|
||||
controller->SendCommit();
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard90::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard90::UpdateSingleLED(int /*key*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard90::DeviceUpdateMode()
|
||||
{
|
||||
if (modes[active_mode].value == MODE_CUSTOM)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char mode_color = COLOR_RAINBOW;
|
||||
if (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
{
|
||||
mode_color = MapRGBToColorEnum(modes[active_mode].colors.at(0));
|
||||
}
|
||||
controller->SendMode
|
||||
(
|
||||
modes[active_mode].value,
|
||||
modes[active_mode].brightness,
|
||||
modes[active_mode].speed,
|
||||
mode_color
|
||||
);
|
||||
}
|
||||
|
||||
unsigned char RGBController_SinowealthKeyboard90::MapRGBToColorEnum(RGBColor color)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(color);
|
||||
unsigned char green = RGBGetGValue(color);
|
||||
unsigned char blue = RGBGetBValue(color);
|
||||
|
||||
if (red & green & blue)
|
||||
{
|
||||
return COLOR_WHITE;
|
||||
}
|
||||
if (red & green)
|
||||
{
|
||||
return COLOR_YELLOW;
|
||||
}
|
||||
if (red & blue)
|
||||
{
|
||||
return COLOR_VIOLET;
|
||||
}
|
||||
if (green & blue)
|
||||
{
|
||||
return COLOR_CYAN;
|
||||
}
|
||||
if (red)
|
||||
{
|
||||
return COLOR_RED;
|
||||
}
|
||||
if (green)
|
||||
{
|
||||
return COLOR_GREEN;
|
||||
}
|
||||
if (blue)
|
||||
{
|
||||
return COLOR_BLUE;
|
||||
}
|
||||
return COLOR_RAINBOW;
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard90::AddMode
|
||||
(
|
||||
std::string name,
|
||||
unsigned char value,
|
||||
bool color_support
|
||||
)
|
||||
{
|
||||
mode Mode;
|
||||
Mode.name = name;
|
||||
Mode.value = value;
|
||||
if (color_support)
|
||||
{
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS |
|
||||
MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR |
|
||||
MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Mode.colors_min = 1;
|
||||
Mode.colors_max = 1;
|
||||
Mode.color_mode = MODE_COLORS_RANDOM;
|
||||
Mode.colors.resize(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Mode.color_mode = MODE_COLORS_NONE;
|
||||
}
|
||||
Mode.brightness_min = BRIGHTNESS_OFF;
|
||||
Mode.brightness_max = BRIGHTNESS_FULL;
|
||||
Mode.brightness = BRIGHTNESS_FULL;
|
||||
Mode.speed_min = SPEED_SLOWEST;
|
||||
Mode.speed_max = SPEED_FASTEST;
|
||||
Mode.speed = SPEED_NORMAL;
|
||||
modes.push_back(Mode);
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*------------------------------------------*\
|
||||
| RGBController_SinowealthKeyboard90.h |
|
||||
| |
|
||||
| Definitions and types for Sinowealth |
|
||||
| Keyboard with PID:0090, |
|
||||
| made spefically for Genesis Thor 300 |
|
||||
| |
|
||||
| Jan Baier 30/06/2022 |
|
||||
\*-----------------------------------------=*/
|
||||
|
||||
#pragma once
|
||||
#include "RGBController.h"
|
||||
#include "SinowealthKeyboard90Controller.h"
|
||||
|
||||
class RGBController_SinowealthKeyboard90 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_SinowealthKeyboard90(SinowealthKeyboard90Controller* controller_ptr);
|
||||
~RGBController_SinowealthKeyboard90();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
SinowealthKeyboard90Controller* controller;
|
||||
|
||||
void AddMode(std::string name, unsigned char value, bool color_support);
|
||||
unsigned char MapRGBToColorEnum(RGBColor color);
|
||||
};
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*------------------------------------------*\
|
||||
| SinowealthKeyboard90Controller.cpp |
|
||||
| |
|
||||
| Definitions and types for Sinowealth |
|
||||
| Keyboard with PID:0090, |
|
||||
| made spefically for Genesis Thor 300 |
|
||||
| |
|
||||
| Jan Baier 30/06/2022 |
|
||||
\*-----------------------------------------=*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogManager.h"
|
||||
#include "SinowealthKeyboard90Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
using namespace thor300;
|
||||
|
||||
SinowealthKeyboard90Controller::SinowealthKeyboard90Controller(hid_device* dev_handle, const char* path, const unsigned short pid, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
usb_pid = pid;
|
||||
}
|
||||
|
||||
SinowealthKeyboard90Controller::~SinowealthKeyboard90Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string SinowealthKeyboard90Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string SinowealthKeyboard90Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string SinowealthKeyboard90Controller::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));
|
||||
}
|
||||
|
||||
unsigned short SinowealthKeyboard90Controller::GetUSBPID()
|
||||
{
|
||||
return(usb_pid);
|
||||
}
|
||||
|
||||
void SinowealthKeyboard90Controller::SendFeatureReport
|
||||
(
|
||||
unsigned char cmd,
|
||||
unsigned char arg1,
|
||||
unsigned char arg2,
|
||||
unsigned char arg3,
|
||||
unsigned char arg4,
|
||||
unsigned char arg5
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[8];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x0A;
|
||||
usb_buf[0x01] = cmd;
|
||||
usb_buf[0x02] = arg1;
|
||||
usb_buf[0x03] = arg2;
|
||||
usb_buf[0x04] = arg3;
|
||||
usb_buf[0x05] = arg4;
|
||||
usb_buf[0x06] = arg5;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, (unsigned char *)usb_buf, sizeof(usb_buf));
|
||||
}
|
||||
|
||||
void SinowealthKeyboard90Controller::SendMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned char brightness,
|
||||
unsigned char speed,
|
||||
unsigned char color
|
||||
)
|
||||
{
|
||||
SendFeatureReport(0x03, 0x01);
|
||||
SendFeatureReport(0x0A, mode, brightness, speed, color);
|
||||
}
|
||||
|
||||
void SinowealthKeyboard90Controller::SendSingleLED
|
||||
(
|
||||
unsigned char key,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
SendFeatureReport(0x0C, 0x01, key, red, green, blue);
|
||||
}
|
||||
|
||||
void SinowealthKeyboard90Controller::SendCommit()
|
||||
{
|
||||
SendSingleLED(0x89);
|
||||
}
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
/*------------------------------------------*\
|
||||
| SinowealthKeyboard90Controller.h |
|
||||
| |
|
||||
| Definitions and types for Sinowealth |
|
||||
| Keyboard with PID:0090, |
|
||||
| made spefically for Genesis Thor 300 |
|
||||
| |
|
||||
| Jan Baier 30/06/2022 |
|
||||
\*-----------------------------------------=*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
#define NA 0xFFFFFF
|
||||
|
||||
namespace thor300
|
||||
{
|
||||
static const unsigned int matrix_map[6][23] =
|
||||
{ { 0, NA, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, NA, 13, 14, 15, NA, NA, NA, NA, NA },
|
||||
{ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, NA, 30, 31, 32, NA, 33, 34, 35, 36 },
|
||||
{ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, NA, NA, 50, 51, 52, NA, 53, 54, 55, NA },
|
||||
{ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, NA, NA, NA, NA, NA, 70, 71, 72, 73 },
|
||||
{ 74, NA, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, NA, 85, NA, NA, 86, NA, NA, 87, 88, 89, NA },
|
||||
{ 90, 91, 92, NA, NA, NA, 93, NA, NA, NA, 94, 95, 96, 97, NA, 98, 99, 100, NA, 101, NA, 102, 103 }
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const char * name;
|
||||
const unsigned char idx;
|
||||
} led_type;
|
||||
|
||||
static const led_type led_names[] =
|
||||
{
|
||||
/* Key Label Index */
|
||||
{ KEY_EN_ESCAPE, 0x01 },
|
||||
{ KEY_EN_F1, 0x03 },
|
||||
{ KEY_EN_F2, 0x04 },
|
||||
{ KEY_EN_F3, 0x05 },
|
||||
{ KEY_EN_F4, 0x06 },
|
||||
{ KEY_EN_F5, 0x07 },
|
||||
{ KEY_EN_F6, 0x08 },
|
||||
{ KEY_EN_F7, 0x09 },
|
||||
{ KEY_EN_F8, 0x0A },
|
||||
{ KEY_EN_F9, 0x0B },
|
||||
{ KEY_EN_F10, 0x0C },
|
||||
{ KEY_EN_F11, 0x0D },
|
||||
{ KEY_EN_F12, 0x0F },
|
||||
{ KEY_EN_PRINT_SCREEN, 0x10 },
|
||||
{ KEY_EN_SCROLL_LOCK, 0x11 },
|
||||
{ KEY_EN_PAUSE_BREAK, 0x12 },
|
||||
{ KEY_EN_BACK_TICK, 0x18 },
|
||||
{ KEY_EN_1, 0x19 },
|
||||
{ KEY_EN_2, 0x1A },
|
||||
{ KEY_EN_3, 0x1B },
|
||||
{ KEY_EN_4, 0x1C },
|
||||
{ KEY_EN_5, 0x1D },
|
||||
{ KEY_EN_6, 0x1E },
|
||||
{ KEY_EN_7, 0x1F },
|
||||
{ KEY_EN_8, 0x20 },
|
||||
{ KEY_EN_9, 0x21 },
|
||||
{ KEY_EN_0, 0x22 },
|
||||
{ KEY_EN_MINUS, 0x23 },
|
||||
{ KEY_EN_EQUALS, 0x24 },
|
||||
{ KEY_EN_BACKSPACE, 0x26 },
|
||||
{ KEY_EN_INSERT, 0x27 },
|
||||
{ KEY_EN_HOME, 0x28 },
|
||||
{ KEY_EN_PAGE_UP, 0x29 },
|
||||
{ KEY_EN_NUMPAD_LOCK, 0x2A },
|
||||
{ KEY_EN_NUMPAD_DIVIDE, 0x2B },
|
||||
{ KEY_EN_NUMPAD_TIMES, 0x2C },
|
||||
{ KEY_EN_NUMPAD_MINUS, 0x2D },
|
||||
{ KEY_EN_TAB, 0x2F },
|
||||
{ KEY_EN_Q, 0x30 },
|
||||
{ KEY_EN_W, 0x31 },
|
||||
{ KEY_EN_E, 0x32 },
|
||||
{ KEY_EN_R, 0x33 },
|
||||
{ KEY_EN_T, 0x34 },
|
||||
{ KEY_EN_Y, 0x35 },
|
||||
{ KEY_EN_U, 0x36 },
|
||||
{ KEY_EN_I, 0x37 },
|
||||
{ KEY_EN_O, 0x38 },
|
||||
{ KEY_EN_P, 0x39 },
|
||||
{ KEY_EN_LEFT_BRACKET, 0x3A },
|
||||
{ KEY_EN_RIGHT_BRACKET, 0x3B },
|
||||
{ KEY_EN_DELETE, 0x3E },
|
||||
{ KEY_EN_END, 0x3F },
|
||||
{ KEY_EN_PAGE_DOWN, 0x40 },
|
||||
{ KEY_EN_NUMPAD_7, 0x41 },
|
||||
{ KEY_EN_NUMPAD_8, 0x42 },
|
||||
{ KEY_EN_NUMPAD_9, 0x43 },
|
||||
{ KEY_EN_CAPS_LOCK, 0x46 },
|
||||
{ KEY_EN_A, 0x47 },
|
||||
{ KEY_EN_S, 0x48 },
|
||||
{ KEY_EN_D, 0x49 },
|
||||
{ KEY_EN_F, 0x4A },
|
||||
{ KEY_EN_G, 0x4B },
|
||||
{ KEY_EN_H, 0x4C },
|
||||
{ KEY_EN_J, 0x4D },
|
||||
{ KEY_EN_K, 0x4E },
|
||||
{ KEY_EN_L, 0x4F },
|
||||
{ KEY_EN_SEMICOLON, 0x50 },
|
||||
{ KEY_EN_QUOTE, 0x51 },
|
||||
{ KEY_EN_ANSI_BACK_SLASH, 0x52 },
|
||||
{ KEY_EN_ANSI_ENTER, 0x54 },
|
||||
{ KEY_EN_NUMPAD_4, 0x58 },
|
||||
{ KEY_EN_NUMPAD_5, 0x59 },
|
||||
{ KEY_EN_NUMPAD_6, 0x5A },
|
||||
{ KEY_EN_NUMPAD_PLUS, 0x44 },
|
||||
{ KEY_EN_LEFT_SHIFT, 0x5D },
|
||||
{ KEY_EN_Z, 0x5F },
|
||||
{ KEY_EN_X, 0x60 },
|
||||
{ KEY_EN_C, 0x61 },
|
||||
{ KEY_EN_V, 0x62 },
|
||||
{ KEY_EN_B, 0x63 },
|
||||
{ KEY_EN_N, 0x64 },
|
||||
{ KEY_EN_M, 0x65 },
|
||||
{ KEY_EN_COMMA, 0x66 },
|
||||
{ KEY_EN_PERIOD, 0x67 },
|
||||
{ KEY_EN_FORWARD_SLASH, 0x68 },
|
||||
{ KEY_EN_RIGHT_SHIFT, 0x6B },
|
||||
{ KEY_EN_UP_ARROW, 0x6D },
|
||||
{ KEY_EN_NUMPAD_1, 0x6F },
|
||||
{ KEY_EN_NUMPAD_2, 0x70 },
|
||||
{ KEY_EN_NUMPAD_3, 0x71 },
|
||||
{ KEY_EN_LEFT_CONTROL, 0x74 },
|
||||
{ KEY_EN_LEFT_WINDOWS, 0x75 },
|
||||
{ KEY_EN_LEFT_ALT, 0x76 },
|
||||
{ KEY_EN_SPACE, 0x79 },
|
||||
{ KEY_EN_RIGHT_ALT, 0x7C },
|
||||
{ KEY_EN_RIGHT_FUNCTION, 0x7D },
|
||||
{ KEY_EN_MENU, 0x7E },
|
||||
{ KEY_EN_RIGHT_CONTROL, 0x80 },
|
||||
{ KEY_EN_LEFT_ARROW, 0x83 },
|
||||
{ KEY_EN_DOWN_ARROW, 0x84 },
|
||||
{ KEY_EN_RIGHT_ARROW, 0x85 },
|
||||
{ KEY_EN_NUMPAD_0, 0x86 },
|
||||
{ KEY_EN_NUMPAD_PERIOD, 0x88 },
|
||||
{ KEY_EN_NUMPAD_ENTER, 0x72 }
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SPEED_SLOWEST = 0x00,
|
||||
SPEED_SLOW = 0x01,
|
||||
SPEED_NORMAL = 0x02,
|
||||
SPEED_FAST = 0x03,
|
||||
SPEED_FASTEST = 0x04,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
BRIGHTNESS_OFF = 0x00,
|
||||
BRIGHTNESS_QUARTER = 0x01,
|
||||
BRIGHTNESS_HALF = 0x02,
|
||||
BRIGHTNESS_THREE_QUARTERS = 0x03,
|
||||
BRIGHTNESS_FULL = 0x04,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
COLOR_RED = 0x00,
|
||||
COLOR_GREEN = 0x01,
|
||||
COLOR_BLUE = 0x02,
|
||||
COLOR_YELLOW = 0x03,
|
||||
COLOR_VIOLET = 0x04,
|
||||
COLOR_CYAN = 0x05,
|
||||
COLOR_WHITE = 0x06,
|
||||
COLOR_RAINBOW = 0x07,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MODE_PRISMO = 0x00,
|
||||
MODE_BREATHING = 0x01,
|
||||
MODE_WAVE_1 = 0x02,
|
||||
MODE_FLOWERS_BLOSSOM = 0x03,
|
||||
MODE_RAINBOW = 0x04,
|
||||
MODE_WAVE_2 = 0x05,
|
||||
MODE_CW_ROTATION = 0x06,
|
||||
MODE_WAVE_3 = 0x07,
|
||||
MODE_RESPONSE = 0x08,
|
||||
MODE_CCW_ROTATION = 0x09,
|
||||
MODE_SNAKE = 0x0A,
|
||||
MODE_WAVE_4 = 0x0B,
|
||||
MODE_TORNADO = 0x0C,
|
||||
MODE_NEON = 0x0D,
|
||||
MODE_TWINKLING = 0x0E,
|
||||
MODE_RESPONSE_SINGLE = 0x0F,
|
||||
MODE_STATIC = 0x10,
|
||||
MODE_RAINDROPS = 0x11,
|
||||
MODE_WAVE_5 = 0x12,
|
||||
MODE_CUSTOM = 0x13,
|
||||
};
|
||||
}
|
||||
|
||||
class SinowealthKeyboard90Controller
|
||||
{
|
||||
public:
|
||||
SinowealthKeyboard90Controller(hid_device* dev_handle, const char* path, const unsigned short pid, std::string dev_name);
|
||||
~SinowealthKeyboard90Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
unsigned short GetUSBPID();
|
||||
|
||||
void SendMode
|
||||
(
|
||||
unsigned char mode = thor300::MODE_CUSTOM,
|
||||
unsigned char brightness = thor300::BRIGHTNESS_HALF,
|
||||
unsigned char speed = thor300::SPEED_NORMAL,
|
||||
unsigned char color = thor300::COLOR_RAINBOW
|
||||
);
|
||||
|
||||
void SendSingleLED
|
||||
(
|
||||
unsigned char key,
|
||||
unsigned char red = 0x00,
|
||||
unsigned char green = 0x00,
|
||||
unsigned char blue = 0x00
|
||||
);
|
||||
|
||||
void SendCommit();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string name;
|
||||
std::string location;
|
||||
unsigned short usb_pid;
|
||||
|
||||
void SendFeatureReport
|
||||
(
|
||||
unsigned char cmd,
|
||||
unsigned char arg1 = 0x00,
|
||||
unsigned char arg2 = 0x00,
|
||||
unsigned char arg3 = 0x00,
|
||||
unsigned char arg4 = 0x00,
|
||||
unsigned char arg5 = 0x00
|
||||
);
|
||||
};
|
||||
+479
@@ -0,0 +1,479 @@
|
||||
/*------------------------------------------*\
|
||||
| RGBController_SinowealthKeyboard.cpp |
|
||||
| |
|
||||
| Definitions and types for Sinowealth |
|
||||
| Keyboard, Hopefully generic, this was |
|
||||
| made spefically for FL eSports F11 KB |
|
||||
| |
|
||||
| Dmitri Kalinichenko (Dima-Kal) 23/06/2021 |
|
||||
\*-----------------------------------------=*/
|
||||
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "RGBController_SinowealthKeyboard.h"
|
||||
|
||||
#define NA 0xFFFFFFFF
|
||||
|
||||
static unsigned int tkl_matrix_map[6][17] =
|
||||
{ { 8, NA, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24},
|
||||
{ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45},
|
||||
{ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66},
|
||||
{ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, NA, NA, NA, NA},
|
||||
{ 93, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 106, NA, NA, NA, 107, NA},
|
||||
{ 113, 114, 115, NA, NA, NA, 118, NA, NA, NA, NA, 121, 122, 123, 127, 128, 129}};
|
||||
|
||||
|
||||
static const char *led_names_tkl[] =
|
||||
{
|
||||
KEY_EN_ESCAPE,
|
||||
KEY_EN_F1,
|
||||
KEY_EN_F2,
|
||||
KEY_EN_F3,
|
||||
KEY_EN_F4,
|
||||
KEY_EN_F5,
|
||||
KEY_EN_F6,
|
||||
KEY_EN_F7,
|
||||
KEY_EN_F8,
|
||||
KEY_EN_F9,
|
||||
KEY_EN_F10,
|
||||
KEY_EN_F11,
|
||||
KEY_EN_F12,
|
||||
KEY_EN_PRINT_SCREEN,
|
||||
KEY_EN_SCROLL_LOCK,
|
||||
"Key: Pause",
|
||||
|
||||
KEY_EN_BACK_TICK,
|
||||
KEY_EN_1,
|
||||
KEY_EN_2,
|
||||
KEY_EN_3,
|
||||
KEY_EN_4,
|
||||
KEY_EN_5,
|
||||
KEY_EN_6,
|
||||
KEY_EN_7,
|
||||
KEY_EN_8,
|
||||
KEY_EN_9,
|
||||
KEY_EN_0,
|
||||
KEY_EN_MINUS,
|
||||
KEY_EN_EQUALS,
|
||||
KEY_EN_BACKSPACE,
|
||||
KEY_EN_INSERT,
|
||||
KEY_EN_HOME,
|
||||
KEY_EN_PAGE_UP,
|
||||
|
||||
KEY_EN_TAB,
|
||||
KEY_EN_Q,
|
||||
KEY_EN_W,
|
||||
KEY_EN_E,
|
||||
KEY_EN_R,
|
||||
KEY_EN_T,
|
||||
KEY_EN_Y,
|
||||
KEY_EN_U,
|
||||
KEY_EN_I,
|
||||
KEY_EN_O,
|
||||
KEY_EN_P,
|
||||
KEY_EN_LEFT_BRACKET,
|
||||
KEY_EN_RIGHT_BRACKET,
|
||||
KEY_EN_ANSI_BACK_SLASH,
|
||||
KEY_EN_DELETE,
|
||||
KEY_EN_END,
|
||||
KEY_EN_PAGE_DOWN,
|
||||
|
||||
KEY_EN_CAPS_LOCK,
|
||||
KEY_EN_A,
|
||||
KEY_EN_S,
|
||||
KEY_EN_D,
|
||||
KEY_EN_F,
|
||||
KEY_EN_G,
|
||||
KEY_EN_H,
|
||||
KEY_EN_J,
|
||||
KEY_EN_K,
|
||||
KEY_EN_L,
|
||||
KEY_EN_SEMICOLON,
|
||||
KEY_EN_QUOTE,
|
||||
KEY_EN_ANSI_ENTER,
|
||||
|
||||
KEY_EN_LEFT_SHIFT,
|
||||
KEY_EN_Z,
|
||||
KEY_EN_X,
|
||||
KEY_EN_C,
|
||||
KEY_EN_V,
|
||||
KEY_EN_B,
|
||||
KEY_EN_N,
|
||||
KEY_EN_M,
|
||||
KEY_EN_COMMA,
|
||||
KEY_EN_PERIOD,
|
||||
KEY_EN_FORWARD_SLASH,
|
||||
KEY_EN_RIGHT_SHIFT,
|
||||
KEY_EN_UP_ARROW,
|
||||
|
||||
KEY_EN_LEFT_CONTROL,
|
||||
KEY_EN_LEFT_WINDOWS,
|
||||
KEY_EN_LEFT_ALT,
|
||||
KEY_EN_SPACE,
|
||||
KEY_EN_RIGHT_CONTROL,
|
||||
KEY_EN_RIGHT_ALT,
|
||||
KEY_EN_RIGHT_WINDOWS,
|
||||
KEY_EN_RIGHT_FUNCTION,
|
||||
KEY_EN_LEFT_ARROW,
|
||||
KEY_EN_DOWN_ARROW,
|
||||
KEY_EN_RIGHT_ARROW,
|
||||
};
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Sinowealth Keyboard
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :x:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectSinowealthKeyboard
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_SinowealthKeyboard::RGBController_SinowealthKeyboard(SinowealthKeyboardController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetName();
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "Sinowealth Keyboard Device";
|
||||
location = controller->GetLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.value = MODE_STATIC;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Custom;
|
||||
Custom.name = "Custom";
|
||||
Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Custom.color_mode = MODE_COLORS_PER_LED;
|
||||
Custom.value = MODE_PER_KEY;
|
||||
modes.push_back(Custom);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.flags = 0;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
Off.value = MODE_OFF;
|
||||
modes.push_back(Off);
|
||||
|
||||
mode Respire;
|
||||
Respire.name = "Respire";
|
||||
Respire.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Respire.speed_min = SPEED_SLOW;
|
||||
Respire.speed = SPEED_NORMAL;
|
||||
Respire.speed_max = SPEED_FASTEST;
|
||||
Respire.color_mode = MODE_COLORS_RANDOM;
|
||||
Respire.value = MODE_RESPIRE;
|
||||
Respire.colors_min = 1;
|
||||
Respire.colors_max = 1;
|
||||
Respire.colors.resize(1);
|
||||
modes.push_back(Respire);
|
||||
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Rainbow.speed_min = SPEED_SLOW;
|
||||
Rainbow.speed = SPEED_NORMAL;
|
||||
Rainbow.speed_max = SPEED_FASTEST;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
Rainbow.value = MODE_RAINBOW;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode FlashAway;
|
||||
FlashAway.name = "Flash Away";
|
||||
FlashAway.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
FlashAway.speed_min = SPEED_SLOW;
|
||||
FlashAway.speed = SPEED_NORMAL;
|
||||
FlashAway.speed_max = SPEED_FASTEST;
|
||||
FlashAway.color_mode = MODE_COLORS_RANDOM;
|
||||
FlashAway.value = MODE_FLASH_AWAY;
|
||||
FlashAway.colors_min = 1;
|
||||
FlashAway.colors_max = 1;
|
||||
FlashAway.colors.resize(1);
|
||||
modes.push_back(FlashAway);
|
||||
|
||||
mode Raindrops;
|
||||
Raindrops.name = "Raindrops";
|
||||
Raindrops.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Raindrops.speed_min = SPEED_SLOW;
|
||||
Raindrops.speed = SPEED_NORMAL;
|
||||
Raindrops.speed_max = SPEED_FASTEST;
|
||||
Raindrops.color_mode = MODE_COLORS_RANDOM;
|
||||
Raindrops.value = MODE_RAINDROPS;
|
||||
Raindrops.colors_min = 1;
|
||||
Raindrops.colors_max = 1;
|
||||
Raindrops.colors.resize(1);
|
||||
modes.push_back(Raindrops);
|
||||
|
||||
mode RainbowWheel;
|
||||
RainbowWheel.name = "Rainbow Wheel";
|
||||
RainbowWheel.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
RainbowWheel.speed_min = SPEED_SLOW;
|
||||
RainbowWheel.speed = SPEED_NORMAL;
|
||||
RainbowWheel.speed_max = SPEED_FASTEST;
|
||||
RainbowWheel.color_mode = MODE_COLORS_RANDOM;
|
||||
RainbowWheel.value = MODE_RAINBOW_WHEEL;
|
||||
RainbowWheel.colors_min = 1;
|
||||
RainbowWheel.colors_max = 1;
|
||||
RainbowWheel.colors.resize(1);
|
||||
modes.push_back(RainbowWheel);
|
||||
|
||||
mode RipplesShining;
|
||||
RipplesShining.name = "Ripples Shining";
|
||||
RipplesShining.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
RipplesShining.speed_min = SPEED_SLOW;
|
||||
RipplesShining.speed = SPEED_NORMAL;
|
||||
RipplesShining.speed_max = SPEED_FASTEST;
|
||||
RipplesShining.color_mode = MODE_COLORS_RANDOM;
|
||||
RipplesShining.value = MODE_RIPPLES_SHINING;
|
||||
RipplesShining.colors_min = 1;
|
||||
RipplesShining.colors_max = 1;
|
||||
RipplesShining.colors.resize(1);
|
||||
modes.push_back(RipplesShining);
|
||||
|
||||
mode StarsTwinkle;
|
||||
StarsTwinkle.name = "Stars Twinkle";
|
||||
StarsTwinkle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
StarsTwinkle.speed_min = SPEED_SLOW;
|
||||
StarsTwinkle.speed = SPEED_NORMAL;
|
||||
StarsTwinkle.speed_max = SPEED_FASTEST;
|
||||
StarsTwinkle.color_mode = MODE_COLORS_RANDOM;
|
||||
StarsTwinkle.value = MODE_STARS_TWINKLE;
|
||||
StarsTwinkle.colors_min = 1;
|
||||
StarsTwinkle.colors_max = 1;
|
||||
StarsTwinkle.colors.resize(1);
|
||||
modes.push_back(StarsTwinkle);
|
||||
|
||||
mode ShadowDisappear;
|
||||
ShadowDisappear.name = "Shadow Disappear";
|
||||
ShadowDisappear.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
ShadowDisappear.speed_min = SPEED_SLOW;
|
||||
ShadowDisappear.speed = SPEED_NORMAL;
|
||||
ShadowDisappear.speed_max = SPEED_FASTEST;
|
||||
ShadowDisappear.color_mode = MODE_COLORS_RANDOM;
|
||||
ShadowDisappear.value = MODE_SHADOW_DISAPPEAR;
|
||||
ShadowDisappear.colors_min = 1;
|
||||
ShadowDisappear.colors_max = 1;
|
||||
ShadowDisappear.colors.resize(1);
|
||||
modes.push_back(ShadowDisappear);
|
||||
|
||||
mode RetroSnake;
|
||||
RetroSnake.name = "Retro Snake";
|
||||
RetroSnake.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
RetroSnake.speed_min = SPEED_SLOW;
|
||||
RetroSnake.speed = SPEED_NORMAL;
|
||||
RetroSnake.speed_max = SPEED_FASTEST;
|
||||
RetroSnake.color_mode = MODE_COLORS_RANDOM;
|
||||
RetroSnake.value = MODE_RETRO_SNAKE;
|
||||
RetroSnake.colors_min = 1;
|
||||
RetroSnake.colors_max = 1;
|
||||
RetroSnake.colors.resize(1);
|
||||
modes.push_back(RetroSnake);
|
||||
|
||||
mode NeonStream;
|
||||
NeonStream.name = "Neon Stream";
|
||||
NeonStream.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
NeonStream.speed_min = SPEED_SLOW;
|
||||
NeonStream.speed = SPEED_NORMAL;
|
||||
NeonStream.speed_max = SPEED_FASTEST;
|
||||
NeonStream.color_mode = MODE_COLORS_RANDOM;
|
||||
NeonStream.value = MODE_NEON_STREAM;
|
||||
NeonStream.colors_min = 1;
|
||||
NeonStream.colors_max = 1;
|
||||
NeonStream.colors.resize(1);
|
||||
modes.push_back(NeonStream);
|
||||
|
||||
mode Reaction;
|
||||
Reaction.name = "Reaction";
|
||||
Reaction.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Reaction.speed_min = SPEED_SLOW;
|
||||
Reaction.speed = SPEED_NORMAL;
|
||||
Reaction.speed_max = SPEED_FASTEST;
|
||||
Reaction.color_mode = MODE_COLORS_RANDOM;
|
||||
Reaction.value = MODE_REACTION;
|
||||
Reaction.colors_min = 1;
|
||||
Reaction.colors_max = 1;
|
||||
Reaction.colors.resize(1);
|
||||
modes.push_back(Reaction);
|
||||
|
||||
mode SineWave;
|
||||
SineWave.name = "Sine Wave";
|
||||
SineWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
SineWave.speed_min = SPEED_SLOW;
|
||||
SineWave.speed = SPEED_NORMAL;
|
||||
SineWave.speed_max = SPEED_FASTEST;
|
||||
SineWave.color_mode = MODE_COLORS_RANDOM;
|
||||
SineWave.value = MODE_SINE_WAVE;
|
||||
SineWave.colors_min = 1;
|
||||
SineWave.colors_max = 1;
|
||||
SineWave.colors.resize(1);
|
||||
modes.push_back(SineWave);
|
||||
|
||||
mode RetinueScanning;
|
||||
RetinueScanning.name = "Retinue Scanning";
|
||||
RetinueScanning.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
RetinueScanning.speed_min = SPEED_SLOW;
|
||||
RetinueScanning.speed = SPEED_NORMAL;
|
||||
RetinueScanning.speed_max = SPEED_FASTEST;
|
||||
RetinueScanning.color_mode = MODE_COLORS_RANDOM;
|
||||
RetinueScanning.value = MODE_RETINUE_SCANNING;
|
||||
RetinueScanning.colors_min = 1;
|
||||
RetinueScanning.colors_max = 1;
|
||||
RetinueScanning.colors.resize(1);
|
||||
modes.push_back(RetinueScanning);
|
||||
|
||||
mode RotatingWindmill;
|
||||
RotatingWindmill.name = "Rotating Windmill";
|
||||
RotatingWindmill.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
RotatingWindmill.speed_min = SPEED_SLOW;
|
||||
RotatingWindmill.speed = SPEED_NORMAL;
|
||||
RotatingWindmill.speed_max = SPEED_FASTEST;
|
||||
RotatingWindmill.color_mode = MODE_COLORS_RANDOM;
|
||||
RotatingWindmill.value = MODE_ROTATING_WINDMILL;
|
||||
RotatingWindmill.colors_min = 1;
|
||||
RotatingWindmill.colors_max = 1;
|
||||
RotatingWindmill.colors.resize(1);
|
||||
modes.push_back(RotatingWindmill);
|
||||
|
||||
mode ColorfulWaterfall;
|
||||
ColorfulWaterfall.name = "Colorful Waterfall";
|
||||
ColorfulWaterfall.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
ColorfulWaterfall.speed_min = SPEED_SLOW;
|
||||
ColorfulWaterfall.speed = SPEED_NORMAL;
|
||||
ColorfulWaterfall.speed_max = SPEED_FASTEST;
|
||||
ColorfulWaterfall.color_mode = MODE_COLORS_NONE;
|
||||
ColorfulWaterfall.value = MODE_COLORFUL_WATERFALL;
|
||||
modes.push_back(ColorfulWaterfall);
|
||||
|
||||
mode Blossoming;
|
||||
Blossoming.name = "Blossoming";
|
||||
Blossoming.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Blossoming.speed_min = SPEED_SLOW;
|
||||
Blossoming.speed = SPEED_NORMAL;
|
||||
Blossoming.speed_max = SPEED_FASTEST;
|
||||
Blossoming.color_mode = MODE_COLORS_NONE;
|
||||
Blossoming.value = MODE_BLOSSOMING;
|
||||
modes.push_back(Blossoming);
|
||||
|
||||
mode RotatingStorm;
|
||||
RotatingStorm.name = "Rotating Storm";
|
||||
RotatingStorm.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
RotatingStorm.speed_min = SPEED_SLOW;
|
||||
RotatingStorm.speed = SPEED_NORMAL;
|
||||
RotatingStorm.speed_max = SPEED_FASTEST;
|
||||
RotatingStorm.color_mode = MODE_COLORS_RANDOM;
|
||||
RotatingStorm.value = MODE_ROTATING_STORM;
|
||||
RotatingStorm.colors_min = 1;
|
||||
RotatingStorm.colors_max = 1;
|
||||
RotatingStorm.colors.resize(1);
|
||||
modes.push_back(RotatingStorm);
|
||||
|
||||
mode Collision;
|
||||
Collision.name = "Collision";
|
||||
Collision.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Collision.speed_min = SPEED_SLOW;
|
||||
Collision.speed = SPEED_NORMAL;
|
||||
Collision.speed_max = SPEED_FASTEST;
|
||||
Collision.color_mode = MODE_COLORS_RANDOM;
|
||||
Collision.value = MODE_COLLISION;
|
||||
Collision.colors_min = 1;
|
||||
Collision.colors_max = 1;
|
||||
Collision.colors.resize(1);
|
||||
modes.push_back(Collision);
|
||||
|
||||
mode Perfect;
|
||||
Perfect.name = "Perfect";
|
||||
Perfect.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Perfect.speed_min = SPEED_SLOW;
|
||||
Perfect.speed = SPEED_NORMAL;
|
||||
Perfect.speed_max = SPEED_FASTEST;
|
||||
Perfect.color_mode = MODE_COLORS_RANDOM;
|
||||
Perfect.value = MODE_PERFECT;
|
||||
Perfect.colors_min = 1;
|
||||
Perfect.colors_max = 1;
|
||||
Perfect.colors.resize(1);
|
||||
modes.push_back(Perfect);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_SinowealthKeyboard::~RGBController_SinowealthKeyboard()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
zone new_zone;
|
||||
|
||||
new_zone.name = ZONE_EN_KEYBOARD;
|
||||
new_zone.type = ZONE_TYPE_MATRIX;
|
||||
new_zone.leds_min = 86;
|
||||
new_zone.leds_max = 86;
|
||||
new_zone.leds_count = 86;
|
||||
new_zone.matrix_map = new matrix_map_type;
|
||||
new_zone.matrix_map->height = 6;
|
||||
new_zone.matrix_map->width = 17;
|
||||
new_zone.matrix_map->map = (unsigned int *)&tkl_matrix_map;
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int led_idx = 0; led_idx < 86; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = led_names_tkl[led_idx];
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*---------------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetLEDsDirect(colors);
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_SinowealthKeyboard::DeviceUpdateMode()
|
||||
{
|
||||
unsigned int brightness = BRIGHTNESS_FULL;
|
||||
RGBColor* selected_color = (modes[active_mode].color_mode == MODE_COLORS_NONE) ? 0 : &modes[active_mode].colors[0];
|
||||
|
||||
if(modes[active_mode].value == MODE_STATIC)
|
||||
{
|
||||
controller->SetStaticColor(selected_color);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetMode(modes[active_mode].value, brightness, modes[active_mode].speed, modes[active_mode].color_mode);
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*------------------------------------------*\
|
||||
| RGBController_SinowealthKeyboard.h |
|
||||
| |
|
||||
| Definitions and types for Sinowealth |
|
||||
| Keyboard, Hopefully generic, this was |
|
||||
| made spefically for FL eSports F11 KB |
|
||||
| |
|
||||
| Dmitri Kalinichenko (Dima-Kal) 23/06/2021 |
|
||||
\*-----------------------------------------=*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "SinowealthKeyboardController.h"
|
||||
|
||||
class RGBController_SinowealthKeyboard : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_SinowealthKeyboard(SinowealthKeyboardController* controller_ptr);
|
||||
~RGBController_SinowealthKeyboard();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
SinowealthKeyboardController* controller;
|
||||
};
|
||||
+283
@@ -0,0 +1,283 @@
|
||||
/*------------------------------------------*\
|
||||
| SinowealthKeyboardController.cpp |
|
||||
| |
|
||||
| Definitions and types for Sinowealth |
|
||||
| Keyboard, Hopefully generic, this was |
|
||||
| made spefically for FL eSports F11 KB |
|
||||
| |
|
||||
| Dmitri Kalinichenko (Dima-Kal) 23/06/2021 |
|
||||
\*-----------------------------------------=*/
|
||||
|
||||
#include <cstring>
|
||||
#include "SinowealthKeyboardController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
static unsigned char send_per_key_part_of_command_packet[] = { 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00,
|
||||
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
static unsigned char mode_brightness_speed_packet[] = { 0x06, 0x03, 0xB6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x5A, 0xA5, 0x03, 0x03, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x55, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x20, 0x00, 0x44, 0x07, 0x30,
|
||||
0x07, 0x23, 0x00, 0x23, 0x00, 0x23, 0x07, 0x33, 0x07, 0x23, 0x07, 0x23, 0x07, 0x23, 0x07, 0x23,
|
||||
0x07, 0x23, 0x07, 0x23, 0x07, 0x23, 0x07, 0x23, 0x07, 0x23, 0x07, 0x23, 0x07, 0x23, 0x07, 0x23,
|
||||
0x07, 0x23, 0x00, 0x10, 0x00, 0x10, 0x07, 0x44, 0x07, 0x44, 0x07, 0x44, 0x07, 0x44, 0x07, 0x44,
|
||||
0x07, 0x44, 0x07, 0x44, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xA5, 0x03, 0x03 };
|
||||
|
||||
static unsigned char tkl_keys_per_key_index[] = { 0x08, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x1d, 0x1E, 0x1F,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D,
|
||||
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
|
||||
0x40, 0x41, 0x42, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
|
||||
0x50, 0x51, 0x52, 0x54, 0x5D, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x6A, 0x6B,
|
||||
0x71, 0x72, 0x73, 0x76, 0x79, 0x7A, 0x7B, 0x7F, 0x80, 0x81 };
|
||||
|
||||
static unsigned int keys_tkl_keys_indices_static_command[] = { 0x0022, 0x0024, 0x0026, 0x0027, 0x0029, 0x002B, 0x002D, 0x002E, 0x002F,
|
||||
0x0030, 0x0031, 0x0032, 0x0037, 0x0039, 0x003B, 0x003C, 0x003E,
|
||||
0x0040, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x004C, 0x004E,
|
||||
0x0050, 0x0051, 0x0053, 0x0055, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C,
|
||||
0x0061, 0x0063, 0x0065, 0x0066, 0x0068, 0x006A, 0x006C, 0x006D, 0x006E, 0x006F,
|
||||
0x0070, 0x0071, 0x0076, 0x0078, 0x007A, 0x007B, 0x007D, 0x007F,
|
||||
0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x008B, 0x008D, 0x008F,
|
||||
0x0090, 0x0092, 0x0094, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B,
|
||||
0x00A0, 0x00A2, 0x00A4, 0x00A5, 0x00A7, 0x00A9, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
|
||||
0x00B0, 0x00B5, 0x00B7, 0x00B9, 0x00BA, 0x00BC, 0x00BE,
|
||||
0x00C0, 0x00E1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00CA, 0x00CC, 0x00CE, 0x00CF,
|
||||
0x00D1, 0x00D3, 0x00D5, 0x00D6, 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DF,
|
||||
0x00E1, 0x00E3, 0x00E4, 0x00E6, 0x00E8, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
||||
0x00F4, 0x00F6, 0x00F8, 0x00F9, 0x00FB, 0x00FD, 0x00FF,
|
||||
0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0109, 0x010B, 0x010D, 0x010E,
|
||||
0x0110, 0x0112, 0x0114, 0x0115, 0x0116, 0x0117, 0x0118, 0x0119, 0x011E,
|
||||
0x0120, 0x0122, 0x0123, 0x0125, 0x0127, 0x0129, 0x012A, 0x012B, 0x012C, 0x012D, 0x012E,
|
||||
0x0133, 0x0135, 0x0137, 0x0138, 0x013A, 0x013C, 0x013E, 0x013F,
|
||||
0x0140, 0x0141, 0x0142, 0x0143, 0x0148, 0x014A, 0x014C, 0x014D, 0x014F,
|
||||
0x0151, 0x0153, 0x0154, 0x0155, 0x0156, 0x0157, 0x0158, 0x015D, 0x015F,
|
||||
0x0161, 0x0162, 0x0164, 0x0166, 0x0168, 0x0169, 0x016A, 0x016B, 0x016C, 0x016D,
|
||||
0x0172, 0x0174, 0x0176, 0x0177, 0x0179, 0x017B, 0x017D, 0x017E, 0x017F,
|
||||
0x0180, 0x0181, 0x0182, 0x0187, 0x0189, 0x018B, 0x018C, 0x018E,
|
||||
0x0190, 0x0192, 0x0193, 0x0194, 0x0195, 0x0196, 0x0197, 0x019C, 0x019E,
|
||||
0x01A0, 0x01A1, 0x01A3, 0x01A5, 0x01A7, 0x01A8, 0x01A9, 0x01AA, 0x01AB, 0x01AC,
|
||||
0x01B1, 0x01B3, 0x01B5, 0x01B6, 0x01B8, 0x01BA, 0x01BC, 0x01BD, 0x01BE, 0x01BF,
|
||||
0x01C0, 0x01C1, 0x01C6, 0x01C8, 0x01CA, 0x01Cb, 0x01CD, 0x01CF,
|
||||
0x01D1, 0x01D2, 0x01D3, 0x01D4, 0x01D5, 0x01D6, 0x01DB, 0x01DD, 0x01DF,
|
||||
0x01E0, 0x01E2, 0x01E4, 0x01E6, 0x01E7, 0x01E8, 0x01E9, 0x01EA};
|
||||
|
||||
|
||||
SinowealthKeyboardController::SinowealthKeyboardController(hid_device* dev_cmd_handle, hid_device* dev_data_handle, char* path, std::string dev_name)
|
||||
{
|
||||
dev_cmd = dev_cmd_handle;
|
||||
dev_data = dev_data_handle;
|
||||
name = dev_name;
|
||||
|
||||
led_count = sizeof(tkl_keys_per_key_index) / sizeof(*tkl_keys_per_key_index);
|
||||
|
||||
current_mode = MODE_STATIC;
|
||||
current_speed = SPEED_NORMAL;
|
||||
|
||||
location = path;
|
||||
}
|
||||
|
||||
SinowealthKeyboardController::~SinowealthKeyboardController()
|
||||
{
|
||||
hid_close(dev_cmd);
|
||||
hid_close(dev_data);
|
||||
}
|
||||
|
||||
std::string SinowealthKeyboardController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string SinowealthKeyboardController::GetName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
unsigned char SinowealthKeyboardController::GetCurrentMode()
|
||||
{
|
||||
return current_mode;
|
||||
}
|
||||
|
||||
unsigned int SinowealthKeyboardController::GetLEDCount()
|
||||
{
|
||||
return(sizeof(tkl_keys_per_key_index) / sizeof(*tkl_keys_per_key_index));
|
||||
}
|
||||
|
||||
std::string SinowealthKeyboardController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev_cmd, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void SinowealthKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
{
|
||||
const int buffer_size = 1032;
|
||||
|
||||
unsigned char buf[buffer_size];
|
||||
unsigned int num_keys = sizeof(tkl_keys_per_key_index) / sizeof(*tkl_keys_per_key_index);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Direct packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x06;
|
||||
buf[0x01] = 0x09;
|
||||
buf[0x02] = 0xBC;
|
||||
buf[0x03] = 0x00;
|
||||
buf[0x04] = 0x40;
|
||||
|
||||
for(unsigned int i = 0 ; i < (sizeof(send_per_key_part_of_command_packet) / sizeof(char)); i++)
|
||||
{
|
||||
buf[0x027C + i] = send_per_key_part_of_command_packet[i];
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < num_keys; i++)
|
||||
{
|
||||
buf[tkl_keys_per_key_index[i]] = RGBGetBValue(colors[i]);
|
||||
buf[tkl_keys_per_key_index[i] + 0x7E] = RGBGetGValue(colors[i]);
|
||||
buf[tkl_keys_per_key_index[i] + 0x7E + 0x7E] = RGBGetRValue(colors[i]);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev_data, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
void SinowealthKeyboardController::SetStaticColor(RGBColor* color_buf)
|
||||
{
|
||||
const int buffer_size = 1032;
|
||||
|
||||
unsigned char usb_buf[buffer_size];
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
int offset = 0;
|
||||
|
||||
usb_buf[offset] = 0x06;
|
||||
offset += 1;
|
||||
|
||||
usb_buf[offset] = 0x08;
|
||||
offset += 1;
|
||||
|
||||
usb_buf[offset] = 0xB8;
|
||||
offset += 2;
|
||||
|
||||
usb_buf[offset] = 0x40;
|
||||
|
||||
usb_buf[0x1D] = RGBGetRValue(color_buf[0]);
|
||||
usb_buf[0x1E] = RGBGetGValue(color_buf[0]);
|
||||
usb_buf[0x1F] = RGBGetBValue(color_buf[0]);
|
||||
|
||||
unsigned int size_of_keys_array = sizeof (keys_tkl_keys_indices_static_command)/ sizeof(int);
|
||||
|
||||
for(unsigned int i = 0x00; i < size_of_keys_array; i++)
|
||||
{
|
||||
unsigned int key_code = keys_tkl_keys_indices_static_command[i];
|
||||
usb_buf[key_code] = 0xFF;
|
||||
}
|
||||
|
||||
hid_send_feature_report(dev_data, usb_buf, sizeof(usb_buf));
|
||||
}
|
||||
|
||||
void SinowealthKeyboardController::SetMode(unsigned char mode, unsigned char brightness, unsigned char speed, unsigned char color_mode)
|
||||
{
|
||||
const int buffer_size = 1032;
|
||||
|
||||
int mode_byte_index = 0x15;
|
||||
const int speed_and_brightness_byte_index_start = 0x29; // Speed + brightnes level value, Seriously?
|
||||
|
||||
unsigned int color_mode_value = color_mode == MODE_COLORS_RANDOM ? 0x07 : 0x00; // 0x07 - Value to set random color mode
|
||||
|
||||
unsigned char usb_buf[buffer_size];
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
unsigned int mode_brightness_speed_packet_length = sizeof(mode_brightness_speed_packet)/sizeof(char);
|
||||
|
||||
for(unsigned int i = 0x00; i < mode_brightness_speed_packet_length; i++)
|
||||
{
|
||||
usb_buf[i] = mode_brightness_speed_packet[i];
|
||||
}
|
||||
|
||||
usb_buf[mode_byte_index] = mode;
|
||||
|
||||
int speed_and_brightness_byte_index = speed_and_brightness_byte_index_start + ((mode - 2) * 2);
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case MODE_OFF:
|
||||
break;
|
||||
case MODE_RAINBOW:
|
||||
break;
|
||||
case MODE_FLASH_AWAY:
|
||||
break;
|
||||
case MODE_RAINDROPS:
|
||||
break;
|
||||
case MODE_RAINBOW_WHEEL:
|
||||
break;
|
||||
case MODE_RIPPLES_SHINING:
|
||||
break;
|
||||
case MODE_STARS_TWINKLE:
|
||||
break;
|
||||
case MODE_SHADOW_DISAPPEAR:
|
||||
break;
|
||||
case MODE_RETRO_SNAKE:
|
||||
break;
|
||||
case MODE_NEON_STREAM:
|
||||
break;
|
||||
case MODE_REACTION:
|
||||
break;
|
||||
case MODE_SINE_WAVE:
|
||||
break;
|
||||
case MODE_RETINUE_SCANNING:
|
||||
break;
|
||||
case MODE_ROTATING_WINDMILL:
|
||||
break;
|
||||
case MODE_COLORFUL_WATERFALL:
|
||||
break;
|
||||
case MODE_BLOSSOMING:
|
||||
break;
|
||||
case MODE_ROTATING_STORM:
|
||||
break;
|
||||
case MODE_COLLISION:
|
||||
break;
|
||||
case MODE_PERFECT:
|
||||
break;
|
||||
case MODE_PER_KEY:
|
||||
usb_buf[mode_byte_index - 1] = 0x01;
|
||||
usb_buf[0x27] = 0x24;
|
||||
break;
|
||||
}
|
||||
|
||||
int color_mode_byte_index = speed_and_brightness_byte_index - 1;
|
||||
|
||||
usb_buf[speed_and_brightness_byte_index] = speed + brightness;
|
||||
usb_buf[color_mode_byte_index] = color_mode_value;
|
||||
|
||||
int result = hid_send_feature_report(dev_data, usb_buf, sizeof(usb_buf));
|
||||
|
||||
if(result != -1)
|
||||
{
|
||||
current_mode = mode;
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*------------------------------------------*\
|
||||
| SinowealthKeyboardController.h |
|
||||
| |
|
||||
| Definitions and types for Sinowealth |
|
||||
| Keyboard, Hopefully generic, this was |
|
||||
| made spefically for FL eSports F11 KB |
|
||||
| |
|
||||
| Dmitri Kalinichenko (Dima-Kal) 23/06/2021 |
|
||||
\*-----------------------------------------=*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
MODE_OFF = 0x0,
|
||||
MODE_STATIC = 0x1,
|
||||
MODE_RESPIRE = 0x2,
|
||||
MODE_RAINBOW = 0x3,
|
||||
MODE_FLASH_AWAY = 0x4,
|
||||
MODE_RAINDROPS = 0x5,
|
||||
MODE_RAINBOW_WHEEL = 0x6,
|
||||
MODE_RIPPLES_SHINING = 0x7,
|
||||
MODE_STARS_TWINKLE = 0x8,
|
||||
MODE_SHADOW_DISAPPEAR = 0x9,
|
||||
MODE_RETRO_SNAKE = 0xA,
|
||||
MODE_NEON_STREAM = 0xB,
|
||||
MODE_REACTION = 0xC,
|
||||
MODE_SINE_WAVE = 0xD,
|
||||
MODE_RETINUE_SCANNING = 0xE,
|
||||
MODE_ROTATING_WINDMILL = 0xF,
|
||||
MODE_COLORFUL_WATERFALL = 0x10,
|
||||
MODE_BLOSSOMING = 0x11,
|
||||
MODE_ROTATING_STORM = 0x12,
|
||||
MODE_COLLISION = 0x13,
|
||||
MODE_PERFECT = 0x14,
|
||||
MODE_PER_KEY = 0x15
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SPEED_SLOW = 0x12,
|
||||
SPEED_NORMAL = 0x22,
|
||||
SPEED_FASTER = 0x32,
|
||||
SPEED_FASTEST = 0x42,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
BRIGHTNESS_OFF = 0x0,
|
||||
BRIGHTNESS_QUARTER = 0x1,
|
||||
BRIGHTNESS_HALF = 0x2,
|
||||
BRIGHTNESS_THREE_QUARTERS = 0x3,
|
||||
BRIGHTNESS_FULL = 0x4
|
||||
};
|
||||
|
||||
|
||||
class SinowealthKeyboardController
|
||||
{
|
||||
public:
|
||||
SinowealthKeyboardController(hid_device* dev_cmd_handle, hid_device* dev_data_handle, char *_path, std::string dev_name); //RGB, Command, path
|
||||
~SinowealthKeyboardController();
|
||||
|
||||
unsigned int GetLEDCount();
|
||||
std::string GetLocation();
|
||||
std::string GetName();
|
||||
std::string GetSerialString();
|
||||
unsigned char GetCurrentMode();
|
||||
|
||||
void SetLEDColor(RGBColor* color_buf);
|
||||
void SetStaticColor(RGBColor* color_buf);
|
||||
void SetMode(unsigned char mode, unsigned char brightness, unsigned char speed, unsigned char color_mode);
|
||||
void GetProfile();
|
||||
void ReadFirmwareInfo();
|
||||
void SetLEDsDirect(std::vector<RGBColor> colors);
|
||||
private:
|
||||
hid_device* dev_cmd;
|
||||
hid_device* dev_data;
|
||||
device_type type;
|
||||
unsigned int led_count;
|
||||
unsigned char current_mode;
|
||||
unsigned char current_speed;
|
||||
std::string location;
|
||||
std::string name;
|
||||
};
|
||||
Reference in New Issue
Block a user