Compare commits

...
Author SHA1 Message Date
Adam Honse d6e9ee3978 Add option for introducing a delay (in milliseconds) between direct mode LED packets for the QMK OpenRGB protocol 2021-09-11 20:10:37 -05:00
Thomas Dubosc e4692cb562 Adds ASUS ROG Strix GTX 1660S O6G Gaming GPU 2021-09-10 13:13:37 +00:00
morg 4f62d68f6d Add ability to drag and drop plugin files into the UI 2021-09-08 22:22:31 -05:00
morg 70a2fa81c8 Enable the remove plugin button only when a plugin is selected. 2021-09-09 03:03:44 +00:00
Ksaper 04c430e31b Add a logging message for when openrgb is not enabled in the firmware 2021-09-09 03:01:02 +00:00
Ksaper 56640b5922 Improve logging message 2021-09-09 03:01:02 +00:00
Ksaper 96427c4015 Add a logging message when procotol version is too old 2021-09-09 03:01:02 +00:00
Ksaper 5b02b3430e Add support for saving to eeprom 2021-09-09 03:01:02 +00:00
Adam Honse 4991e7744b Add Yeelight devices settings page 2021-09-06 17:30:55 -05:00
Adam Honse d0260a7eb0 Add Philips Wiz devices settings page 2021-09-06 16:46:39 -05:00
Marcin a6da9a25b7 Simplify Logitech G915 detection logic 2021-09-03 13:54:22 +02:00
Timo Gurr 00197be5fa Do not hardcode the pkgconf command 2021-09-03 04:23:09 +00:00
Adam Honse c0d5529083 Free temporary enumeration from Razer Chroma ARGB controller detection 2021-09-02 23:19:25 -05:00
Qwex 2e032314a4 Fix Razer Chroma ARGB controller detection if interface 1 is earlier in the hidapi enumeration list than interface 0 2021-09-03 04:10:16 +00:00
yawor 7036c05bc2 Add support for Logitech G915
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-09-02 22:46:53 -05:00
Alexey Zagorodnikov 1045af20b2 Add support for another Sinowealth keyboard with PID 0016
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-09-02 22:13:44 -05:00
morg 70024faabd Reviews log messages, fixed some typos and ensure consistency 2021-09-02 13:09:44 +02:00
morg 344e7c7551 Make sure the exit action is the last action in the tray menu 2021-09-02 04:18:10 +00:00
morg 3699889250 Prompt users to resize or setup zones. #1407 2021-09-02 03:30:40 +00:00
morg bdc1b6f3f4 Add Http Hook Plugin to the plugin list. 2021-08-31 23:08:13 +00:00
B Horn b4e76c8281 Fixing breathing + LED setting
Signed-off-by: B Horn <[email protected]>
2021-08-31 23:04:40 +00:00
Chris b72dbf4638 Updating UDEV rules 2021-08-31 23:04:40 +00:00
Chris 61e4c74d6a Code path streamlined and cleanup 2021-08-31 23:04:40 +00:00
B Horn 94ab89c95d Rival 3 support
Signed-off-by: B Horn <[email protected]>
2021-08-31 23:04:40 +00:00
Chris ea238cf6e6 Adding internal row and column count for Coolermaster keyboards
- Removes front light bar row from all but MK750
- Removes Numpad for TKL
+ Splitting out vendor name for clarity on information tab.
2021-08-31 23:03:41 +00:00
Adam Honse db77a76f45 Update AUMA0-E8K40101 Aura SMBus device to use V1 register layout 2021-08-31 13:52:33 -05:00
Adam Honse cbdebf7ec8 Scroll plugins list by pixel rather than by item 2021-08-29 23:09:28 -05:00
Adam Honse 2800e76e9d Add GetTrayMenu to plugin API to provide a dedicated interface for registering a tray menu for a plugin 2021-08-29 22:58:58 -05:00
Adam Honse 2f25c4af7f More plugin updates, enum for location 2021-08-30 02:56:57 +00:00
Adam Honse 702be2401b Add comment indicating location is mandatory, list possible locations, rename SettingsTabBar to SettingsTab for consistency 2021-08-30 02:56:57 +00:00
Adam Honse 524fd057fe Add tab icon fields (string and image) to the plugin information and add comments to make it easier for plugin developers to fill in information structure 2021-08-30 02:56:57 +00:00
Adam Honse 759aa341c2 Code cleanup, only allow one registered callback in PluginManager and PluginPage 2021-08-30 02:56:57 +00:00
Adam Honse 2643ed0d8f Unload old plugin and load new one when replacing an existing plugin during install 2021-08-30 02:56:57 +00:00
Adam Honse 208deaea12 Remove plugin from active plugins list when removing plugin from user interface 2021-08-30 02:56:57 +00:00
Adam Honse 6bacee59f5 Add capability to load and unload plugins 2021-08-30 02:56:57 +00:00
Adam Honse bd2334c186 Add enabling and disabling of plugins when clicking checkbox 2021-08-30 02:56:57 +00:00
Adam Honse 28d590b64d First draft of plugin API changes 2021-08-30 02:56:57 +00:00
TheRogueZeta 90788131ae Add ASUS ROG STRIX RTX 2060S O8G Gaming 8G ID 2021-08-29 11:28:31 -07:00
TheRogueZeta d59388a44c Add ASUS ROG Strix GTX 1050 O2G Gaming device ID 2021-08-28 11:03:27 -07:00
Adam Honse 6b9f7129b3 Add HyperX Pulsefire Core (same protocol as HyperX Pulsefire FPS Pro) 2021-08-27 10:44:45 -05:00
Adam Honse 36f961637e Add Razer Core X to RazerController 2021-08-26 12:26:46 -05:00
TheRogueZeta 3db2c077d8 Send software mode for K68 2021-08-24 22:58:40 -07:00
Adam Honse a20405a6ef Add Plugins tab to settings for installing, enabling, disabling, and removing plugins
* Rework Plugin Manager so that plugins can be loaded after initialization
* Use a callback function to add plugin tabs to the dialog
* Install button lets you choose plugin file, copies it to plugins directory, and immediately loads it
* Remove button deletes selected plugin file from plugins directory - need to add a means to unload it first
2021-08-25 02:44:53 +00:00
TheRogueZeta a28badafb9 Add ASUS GTX 1060 Strix Gaming 6G 2021-08-25 00:24:48 +00:00
TheRogueZeta 33448f9b46 Update names to match drivers/i2c/busses/i2c-i801.c 2021-08-24 17:01:23 -07:00
TheRogueZeta b37b13125d Add Intel Sunrize Point-H device ID 2021-08-24 16:56:33 -07:00
Florian Plasun aa6260273c Add support for the SteelSeries Rival 600
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-08-23 14:37:19 -05:00
Arturo Velázquez 470b27fa43 Added another PID of newer version of NZXT RGB & FAN CONTROLLER 2021-08-23 04:55:17 +00:00
Adam Honse d97cf10953 Add Gigabyte RTX3060Ti EAGLE OC 8G V2.0 LHR 2021-08-22 20:51:31 -05:00
Chris d913707258 Adding brightness to the AMD Wraith Prism Controller
Commit amended to fix brightness issue by Adam Honse <[email protected]>
2021-08-22 20:37:11 -05:00
Chris M 4f24250772 Updating libcmmk to call hid_write() with prepended 0x00 resolving #1673 2021-08-23 00:58:33 +00:00
Qwex 02ca3f32a0 Add Corsair K100 keyboard support (direct mode)
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-08-22 19:43:11 -05:00
B Horn e6dd1e4ef4 Use the correct command for Sensei Mouses
0x09 was the command for older steelseries devices, which can break the LEDs [1]
if used on the more recent sensei series.

[1] https://github.com/FFY00/rival310-re

Signed-off-by: B Horn <[email protected]>
2021-08-22 22:54:56 +00:00
Dominic Laumer 5e3ab417bc Added support for NZXT Underglow (300 mm) RGB strips 2021-08-22 21:52:36 +00:00
Adam Honse f98e80fada Change vendor name for AlienwareCotnroller to just Alienware 2021-08-22 16:48:28 -05:00
mhdsallal 6d6c324927 Add Support to Alienware AW510K Keyboard
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-08-22 16:48:13 -05:00
Pol Rius 752f1ebcdc Revert "Implement saving for steelseries rival and sensei mice"
This reverts commit eef55e6d6e.
2021-08-20 22:21:21 +02:00
Adam Honse 7d7d3aaffc Don't draw the LED view or handle mouse events when the selected mode doesn't use per-LED colors 2021-08-20 10:10:44 -05:00
Chris dfcc436472 Removing rising timer on packet intialisation to allow for true Direct mode 2021-08-20 14:08:24 +00:00
Adam Honse ab9a7674bd Initial HyperX Pulsefire Haste support 2021-08-19 19:20:12 -05:00
TheRogueZeta 7e77edb8d6 Fix K70 Mk2 keymap and software direct mode 2021-08-17 21:24:07 -07:00
111 changed files with 8339 additions and 745 deletions
+23 -12
View File
@@ -114,16 +114,19 @@ ACTION=="add", SUBSYSTEM=="platform", KERNEL=="faustus", RUN+="/bin/chmod a+w /s
# Masterkeys SK650 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0101", TAG+="uaccess" #MM711
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0109", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0105", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="1011", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="1000", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="014d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0047", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="003c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0067", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0089", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="008d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0109", TAG+="uaccess" #MP750 XL
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0105", TAG+="uaccess" #MP750 M
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="1011", TAG+="uaccess" #ARGB
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="1000", TAG+="uaccess" #Small ARGB
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="004f", TAG+="uaccess" #RGB
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="014d", TAG+="uaccess" #Radeon 6000
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="003b", TAG+="uaccess" #Masterkeys Pro L
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0047", TAG+="uaccess" #Masterkeys Pro L White
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="003c", TAG+="uaccess" #Masterkeys Pro S
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0067", TAG+="uaccess" #Masterkeys MK750
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0089", TAG+="uaccess" #Masterkeys SK630
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="008d", TAG+="uaccess" #Masterkeys SK650
#---------------------------------------------------------------#
# Corsair Hydro Series Devices #
@@ -189,6 +192,7 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c23", TAG+="uacces
# Corsair K70 RGB MK2 LP #
# Corsair K95 RGB #
# Corsair K95 Platinum #
# Corsair K100 #
# Corsair Strafe #
# Corsair Strafe MK2 #
# #
@@ -223,6 +227,7 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b11", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b20", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b48", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b7c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b34", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b74", TAG+="uaccess"
@@ -343,6 +348,7 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="0cf2", ATTR{idProduct}=="7750", TAG+="uacces
# Logitech G810 #2 #
# Logitech G813 #
# Logitech G815 #
# Logitech G915 #
# #
# Mice: #
# Logitech G203 Prodigy #
@@ -383,6 +389,8 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c337", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c232", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c33f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c335", TAG+="uaccess" #G910
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c541", TAG+="uaccess" #G915 Receiver
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c33e", TAG+="uaccess" #G915 Wired
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c084", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c092", TAG+="uaccess"
@@ -718,8 +726,9 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="054c", ATTR{idProduct}=="0ba0", TAG+="uacces
# SteelSeries Rival 300 Blackops Edition #
# SteelSeries Rival 310 #
# SteelSeries Rival 310 CS:GO Howl Edition #
# SteelSeries Rival 310 PubG Edition #
# SteelSeries Rival 650 Wireless #
# SteelSeries Rival 310 PubG Edition #
# SteelSeries Rival 650 Wireless #
# SteelSeries Rival 3 #
# SteelSeries Rival Sensei Ten #
# SteelSeries Rival Sensei Ten CS:GO Neon Rider #
# SteelSeries Rival Sensei 310 #
@@ -756,6 +765,8 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1834", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1722", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1726", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="172B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1824", TAG+="uaccess" #Rival3_Old
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="184c", TAG+="uaccess" #Rival3
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1229", TAG+="uaccess"
@@ -19,17 +19,20 @@ AMDWraithPrismController::AMDWraithPrismController(hid_device* dev_handle, const
strcpy(device_name, "AMD Wraith Prism");
current_fan_mode = AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC;
current_fan_speed = 0xFF;
current_fan_random_color = false;
current_fan_mode = AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC;
current_fan_speed = 0xFF;
current_fan_random_color = false;
current_fan_brightness = 0xFF;
current_logo_mode = AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC;
current_logo_speed = 0xFF;
current_logo_random_color = false;
current_logo_mode = AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC;
current_logo_speed = 0xFF;
current_logo_random_color = false;
current_logo_brightness = 0xFF;
current_ring_mode = AMD_WRAITH_PRISM_EFFECT_CHANNEL_STATIC;
current_ring_speed = 0xFF;
current_ring_direction = false;
current_ring_mode = AMD_WRAITH_PRISM_EFFECT_CHANNEL_STATIC;
current_ring_speed = 0xFF;
current_ring_direction = false;
current_ring_brightness = 0xFF;
SendEnableCommand();
}
@@ -147,10 +150,11 @@ std::string AMDWraithPrismController::GetFirmwareVersionString()
return(ret_string);
}
void AMDWraithPrismController::SetFanMode(unsigned char mode, unsigned char speed, bool random_color)
void AMDWraithPrismController::SetFanMode(unsigned char mode, unsigned char speed, unsigned char brightness, bool random_color)
{
current_fan_mode = mode;
current_fan_speed = speed_values_fan_logo[mode][speed];
current_fan_brightness = brightness;
current_fan_random_color = random_color;
}
@@ -163,17 +167,18 @@ void AMDWraithPrismController::SetFanColor(unsigned char red, unsigned char gree
false,
current_fan_random_color,
current_fan_mode,
max_brightness_fan_logo[current_fan_mode],
current_fan_brightness,
red,
green,
blue
);
}
void AMDWraithPrismController::SetLogoMode(unsigned char mode, unsigned char speed, bool random_color)
void AMDWraithPrismController::SetLogoMode(unsigned char mode, unsigned char speed, unsigned char brightness, bool random_color)
{
current_logo_mode = mode;
current_logo_speed = speed_values_fan_logo[mode][speed];
current_logo_brightness = brightness;
current_logo_random_color = random_color;
}
@@ -186,18 +191,19 @@ void AMDWraithPrismController::SetLogoColor(unsigned char red, unsigned char gre
false,
current_logo_random_color,
current_logo_mode,
max_brightness_fan_logo[current_logo_mode],
current_logo_brightness,
red,
green,
blue
);
}
void AMDWraithPrismController::SetRingMode(unsigned char mode, unsigned char speed, bool direction, bool random_color)
void AMDWraithPrismController::SetRingMode(unsigned char mode, unsigned char speed, unsigned char brightness, bool direction, bool random_color)
{
current_ring_mode = mode;
current_ring_speed = speed_values_ring[mode][speed];
current_ring_direction = direction;
current_ring_brightness = brightness;
current_ring_random_color = random_color;
}
@@ -212,7 +218,7 @@ void AMDWraithPrismController::SetRingColor(unsigned char red, unsigned char gre
current_ring_direction,
current_ring_random_color,
mode_value_ring[current_ring_mode],
max_brightness_ring[current_ring_mode],
current_ring_brightness,
red,
green,
blue
@@ -12,13 +12,8 @@
#pragma once
static const unsigned char max_brightness_fan_logo[] =
{
0x00,
0xFF,
0x7F,
0xFF
};
#define AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX 0xFF
#define AMD_WRAITH_PRISM_FAN_BRIGHTNESS_CYCLE_MAX 0x7F
static const unsigned char speed_values_fan_logo[][5] =
{
@@ -28,22 +23,6 @@ static const unsigned char speed_values_fan_logo[][5] =
{ 0x3C, 0x37, 0x31, 0x2C, 0x26 }, /* Breathing */
};
static const unsigned char max_brightness_ring[] =
{
0xFF,
0xFF,
0x7F,
0x00,
0x00,
0x00,
0x00,
0xFF,
0xFF,
0xFF,
0xFF,
0xFF
};
static const unsigned char mode_value_ring[] =
{
0xFF,
@@ -121,13 +100,13 @@ public:
void SetRingEffectChannel(unsigned char channel);
void SetFanMode(unsigned char mode, unsigned char speed, bool random_color);
void SetFanMode(unsigned char mode, unsigned char speed, unsigned char brightness, bool random_color);
void SetFanColor(unsigned char red, unsigned char green, unsigned char blue);
void SetLogoMode(unsigned char mode, unsigned char speed, bool random_color);
void SetLogoMode(unsigned char mode, unsigned char speed, unsigned char brightness, bool random_color);
void SetLogoColor(unsigned char red, unsigned char green, unsigned char blue);
void SetRingMode(unsigned char mode, unsigned char speed, bool direction, bool random_color);
void SetRingMode(unsigned char mode, unsigned char speed, unsigned char brightness, bool direction, bool random_color);
void SetRingColor(unsigned char red, unsigned char green, unsigned char blue);
private:
@@ -137,14 +116,17 @@ private:
unsigned char current_fan_mode;
unsigned char current_fan_speed;
unsigned char current_fan_brightness;
bool current_fan_random_color;
unsigned char current_logo_mode;
unsigned char current_logo_speed;
unsigned char current_logo_brightness;
bool current_logo_random_color;
unsigned char current_ring_mode;
unsigned char current_ring_speed;
unsigned char current_ring_brightness;
bool current_ring_direction;
bool current_ring_random_color;
@@ -26,70 +26,91 @@ RGBController_AMDWraithPrism::RGBController_AMDWraithPrism(AMDWraithPrismControl
serial = "";//wraith->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_STATIC;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
Direct.name = "Direct";
Direct.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_STATIC;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Direct.brightness_min = 0;
Direct.brightness_max = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX;
Direct.brightness = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Breathing.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST;
Breathing.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed = AMD_WRAITH_PRISM_SPEED_NORMAL;
Breathing.name = "Breathing";
Breathing.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST;
Breathing.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST;
Breathing.brightness_min = 0;
Breathing.brightness_max = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX;
Breathing.brightness = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed = AMD_WRAITH_PRISM_SPEED_NORMAL;
modes.push_back(Breathing);
mode ColorCycle;
ColorCycle.name = "Color Cycle";
ColorCycle.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_COLOR_CYCLE;
ColorCycle.flags = MODE_FLAG_HAS_SPEED;
ColorCycle.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST;
ColorCycle.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST;
ColorCycle.color_mode = MODE_COLORS_NONE;
ColorCycle.speed = AMD_WRAITH_PRISM_SPEED_NORMAL;
ColorCycle.name = "Color Cycle";
ColorCycle.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_COLOR_CYCLE;
ColorCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
ColorCycle.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST;
ColorCycle.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST;
ColorCycle.brightness_min = 0;
ColorCycle.brightness_max = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_CYCLE_MAX;
ColorCycle.brightness = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_CYCLE_MAX;
ColorCycle.color_mode = MODE_COLORS_NONE;
ColorCycle.speed = AMD_WRAITH_PRISM_SPEED_NORMAL;
modes.push_back(ColorCycle);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED;
Rainbow.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST;
Rainbow.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST;
Rainbow.color_mode = MODE_COLORS_NONE;
Rainbow.speed = AMD_WRAITH_PRISM_SPEED_NORMAL;
Rainbow.name = "Rainbow";
Rainbow.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Rainbow.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST;
Rainbow.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST;
Rainbow.brightness_min = 0;
Rainbow.brightness_max = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX;
Rainbow.brightness = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX; //The Ring zone can not get brighter but Logo / Fan can
Rainbow.color_mode = MODE_COLORS_NONE;
Rainbow.speed = AMD_WRAITH_PRISM_SPEED_NORMAL;
modes.push_back(Rainbow);
mode Bounce;
Bounce.name = "Bounce";
Bounce.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_BOUNCE;
Bounce.flags = MODE_FLAG_HAS_SPEED;
Bounce.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST;
Bounce.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST;
Bounce.color_mode = MODE_COLORS_NONE;
Bounce.speed = AMD_WRAITH_PRISM_SPEED_NORMAL;
Bounce.name = "Bounce";
Bounce.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_BOUNCE;
Bounce.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Bounce.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST;
Bounce.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST;
Bounce.brightness_min = 0;
Bounce.brightness_max = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX;
Bounce.brightness = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX; //The Ring zone can not get brighter but Logo / Fan can
Bounce.color_mode = MODE_COLORS_NONE;
Bounce.speed = AMD_WRAITH_PRISM_SPEED_NORMAL;
modes.push_back(Bounce);
mode Chase;
Chase.name = "Chase";
Chase.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_CHASE;
Chase.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Chase.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST;
Chase.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST;
Chase.color_mode = MODE_COLORS_PER_LED;
Chase.speed = AMD_WRAITH_PRISM_SPEED_NORMAL;
Chase.name = "Chase";
Chase.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_CHASE;
Chase.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Chase.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST;
Chase.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST;
Chase.brightness_min = 0;
Chase.brightness_max = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX;
Chase.brightness = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX;
Chase.color_mode = MODE_COLORS_PER_LED;
Chase.speed = AMD_WRAITH_PRISM_SPEED_NORMAL;
modes.push_back(Chase);
mode Swirl;
Swirl.name = "Swirl";
Swirl.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_SWIRL;
Swirl.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Swirl.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST;
Swirl.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST;
Swirl.color_mode = MODE_COLORS_PER_LED;
Swirl.speed = AMD_WRAITH_PRISM_SPEED_NORMAL;
Swirl.name = "Swirl";
Swirl.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_SWIRL;
Swirl.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Swirl.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST;
Swirl.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST;
Swirl.brightness_min = 0;
Swirl.brightness_max = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX;
Swirl.brightness = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX;
Swirl.color_mode = MODE_COLORS_PER_LED;
Swirl.speed = AMD_WRAITH_PRISM_SPEED_NORMAL;
modes.push_back(Swirl);
SetupZones();
@@ -210,32 +231,36 @@ void RGBController_AMDWraithPrism::DeviceUpdateMode()
{
bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
wraith->SetRingMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].direction, random);
wraith->SetRingMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, modes[active_mode].direction, random);
switch(modes[active_mode].value)
{
case AMD_WRAITH_PRISM_EFFECT_CHANNEL_COLOR_CYCLE:
wraith->SetFanMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, modes[active_mode].brightness, random);
wraith->SetLogoMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, modes[active_mode].brightness, random);
break;
case AMD_WRAITH_PRISM_EFFECT_CHANNEL_RAINBOW:
case AMD_WRAITH_PRISM_EFFECT_CHANNEL_BOUNCE:
wraith->SetFanMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, random);
wraith->SetLogoMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, random);
wraith->SetFanMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, (modes[active_mode].brightness >> 1), random);
wraith->SetLogoMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, (modes[active_mode].brightness >> 1), random);
break;
case AMD_WRAITH_PRISM_EFFECT_CHANNEL_BREATHING:
wraith->SetFanMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_BREATHING, modes[active_mode].speed, random);
wraith->SetLogoMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_BREATHING, modes[active_mode].speed, random);
wraith->SetFanMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_BREATHING, modes[active_mode].speed, modes[active_mode].brightness, random);
wraith->SetLogoMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_BREATHING, modes[active_mode].speed, modes[active_mode].brightness, random);
break;
default:
if(random)
{
wraith->SetFanMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, random);
wraith->SetLogoMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, random);
wraith->SetFanMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, modes[active_mode].brightness, random);
wraith->SetLogoMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, modes[active_mode].brightness, random);
}
else
{
wraith->SetFanMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC, modes[active_mode].speed, random);
wraith->SetLogoMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC, modes[active_mode].speed, random);
wraith->SetFanMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC, modes[active_mode].speed, modes[active_mode].brightness, random);
wraith->SetLogoMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC, modes[active_mode].speed, modes[active_mode].brightness, random);
}
break;
}
@@ -54,11 +54,11 @@ void DetectPolychromeSMBusControllers(std::vector<i2c_smbus_interface*>& busses)
{
IF_MOBO_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
{
LOG_TRACE("%s Bus %02d is an Motherboard, checking for for a device at 0x6A", ASROCK_DETECTOR_NAME, bus);
LOG_TRACE("%s Bus %02d is a motherboard, checking for a device at 0x6A", ASROCK_DETECTOR_NAME, bus);
// Check for Polychrome controller at 0x6A
if (TestForPolychromeSMBusController(busses[bus], 0x6A))
{
LOG_TRACE("%s Detected a device at address 0x6A, Testing for a known controller", ASROCK_DETECTOR_NAME);
LOG_TRACE("%s Detected a device at address 0x6A, testing for a known controller", ASROCK_DETECTOR_NAME);
new_polychrome = new PolychromeController(busses[bus], 0x6A);
if(new_polychrome->GetASRockType() != ASROCK_TYPE_UNKNOWN)
@@ -80,7 +80,7 @@ void DetectPolychromeSMBusControllers(std::vector<i2c_smbus_interface*>& busses)
}
else
{
LOG_TRACE("%s Bus %02d not a Motherboard", ASROCK_DETECTOR_NAME, bus);
LOG_TRACE("%s Bus %02d not a motherboard", ASROCK_DETECTOR_NAME, bus);
}
}
@@ -17,7 +17,7 @@ RGBController_Alienware::RGBController_Alienware(AlienwareController* alienware_
alienware = alienware_ptr;
name = alienware->GetDeviceName();
vendor = "Alienware Corporation";
vendor = "Alienware";
type = DEVICE_TYPE_KEYBOARD;
description = "Alienware USB Device";
location = alienware->GetDeviceLocation();
@@ -0,0 +1,442 @@
/*-----------------------------------------*\
| AlienwareAW510KController.cpp |
| |
| Driver for Alienware AW510K |
| keyboard light controller |
| |
| Mohamad Sallal - msallal 05/22/2021 |
\*-----------------------------------------*/
#include "AlienwareAW510KController.h"
#include <cstring>
AlienwareAW510KController::AlienwareAW510KController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
SendCommit();
}
AlienwareAW510KController::~AlienwareAW510KController()
{
hid_close(dev);
}
std::string AlienwareAW510KController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string AlienwareAW510KController::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, serial_string, 128);
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void AlienwareAW510KController::SendCommit()
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x05;
usb_buf[0x02] = 0x01;
usb_buf[0x0A] = 0x10;
usb_buf[0x0B] = 0x0A;
usb_buf[0x0C] = 0x01;
usb_buf[0x0D] = 0x02;
usb_buf[0x0E] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
/*-----------------------------------------------------*\
| Delay 20 milliseconds |
\*-----------------------------------------------------*/
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
void AlienwareAW510KController::SendfeatureReport
(
unsigned char first_byte,
unsigned char second_byte,
unsigned char third_byte,
unsigned char forth_byte
)
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Feature report packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = first_byte;
usb_buf[0x02] = second_byte;
usb_buf[0x03] = third_byte;
usb_buf[0x04] = forth_byte;
/*-----------------------------------------------------*\
| Send Feature report packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, (unsigned char *)usb_buf, 65);
/*-----------------------------------------------------*\
| Delay 10 milliseconds |
\*-----------------------------------------------------*/
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
void AlienwareAW510KController::SendEdit()
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Edit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x01;
usb_buf[0x02] = 0x00;
usb_buf[0x03] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
/*-----------------------------------------------------*\
| Delay 2 milliseconds |
\*-----------------------------------------------------*/
std::this_thread::sleep_for(std::chrono::milliseconds(2));
}
void AlienwareAW510KController::SendInitialize()
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x0E;
usb_buf[0x02] = 0x01;
usb_buf[0x03] = 0x00;
usb_buf[0x04] = 0x01;
usb_buf[0x05] = 0xAD;
usb_buf[0x06] = 0x80;
usb_buf[0x07] = 0x10;
usb_buf[0x08] = 0xA5;
usb_buf[0x0A] = 0x0A;
usb_buf[0x12] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
/*-----------------------------------------------------*\
| Delay 2 milliseconds |
\*-----------------------------------------------------*/
std::this_thread::sleep_for(std::chrono::milliseconds(2));
}
void AlienwareAW510KController::SetDirect
(
unsigned char zone,
unsigned char r,
unsigned char g,
unsigned char b
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x05;
usb_buf[0x02] = 0x01;
usb_buf[0x03] = 0x01;
usb_buf[0x04] = r;
usb_buf[0x05] = g;
usb_buf[0x06] = b;
usb_buf[0x0B] = 0x0A;
usb_buf[0x0D] = 0x01;
usb_buf[0x0E] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
/*-----------------------------------------------------*\
| Delay 2 milliseconds |
\*-----------------------------------------------------*/
std::this_thread::sleep_for(std::chrono::milliseconds(2));
}
void AlienwareAW510KController::SendDirectOn
(
std::vector<SelectedKeys> &frame_data
)
{
SendfeatureReport(0x0E, frame_data.size(), 0x00, 0x01);
/*-----------------------------------------------*\
| To Guarantee the data are always %4 =0 append |
| zeros at end of last packet |
\*-----------------------------------------------*/
for(int i = 0; i < (frame_data.size() % 4); i++)
{
SelectedKeys key;
key.idx = 0x00;
key.red = 0x00;
key.green = 0x00;
key.blue = 0x00;
frame_data.push_back(key);
}
unsigned char usb_buf[65];
unsigned int frame_idx = 0;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, 65);
for(unsigned int packet_idx = 0; packet_idx < frame_data.size(); packet_idx++)
{
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x0E;
usb_buf[0x02] = 0x01;
usb_buf[0x03] = 0x00;
usb_buf[0x04] = ++frame_idx;
usb_buf[0x05] = frame_data[packet_idx].idx;
usb_buf[0x06] = 0x81;
usb_buf[0x07] = 0x00;
usb_buf[0x08] = 0xA5;
usb_buf[0x0A] = 0x0A;
usb_buf[0x0B] = frame_data[packet_idx].red;
usb_buf[0x0C] = frame_data[packet_idx].green;
usb_buf[0x0D] = frame_data[packet_idx].blue;
usb_buf[0x12] = 0x01;
usb_buf[0x14] = frame_data[++packet_idx].idx;
usb_buf[0x15] = 0x81;
usb_buf[0x16] = 0x00;
usb_buf[0x17] = 0xA5;
usb_buf[0x19] = 0x0A;
usb_buf[0x1A] = frame_data[packet_idx].red;
usb_buf[0x1B] = frame_data[packet_idx].green;
usb_buf[0x1C] = frame_data[packet_idx].blue;
usb_buf[0x21] = 0x01;
usb_buf[0x23] = frame_data[++packet_idx].idx;
usb_buf[0x24] = 0x81;
usb_buf[0x25] = 0x00;
usb_buf[0x26] = 0xA5;
usb_buf[0x28] = 0x0A;
usb_buf[0x29] = frame_data[packet_idx].red;
usb_buf[0x2A] = frame_data[packet_idx].green;
usb_buf[0x2B] = frame_data[packet_idx].blue;
usb_buf[0x30] = 0x01;
usb_buf[0x32] = frame_data[++packet_idx].idx;
usb_buf[0x33] = 0x81;
usb_buf[0x34] = 0x00;
usb_buf[0x35] = 0xA5;
usb_buf[0x37] = 0x0A;
usb_buf[0x38] = frame_data[packet_idx].red;
usb_buf[0x39] = frame_data[packet_idx].green;
usb_buf[0x3A] = frame_data[packet_idx].blue;
usb_buf[0x3F] = 0x01;
hid_write(dev, (unsigned char *)usb_buf, 65);
}
}
void AlienwareAW510KController::SetMode
(
unsigned char mode,
unsigned short speed,
unsigned char direction,
unsigned char colorMode,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
SendMode(ALIENWARE_AW510K_ZONE_MODE_KEYBOARD, mode, speed, direction, colorMode, red, green, blue);
SendCommit();
}
void AlienwareAW510KController::UpdateSingleLED
(
unsigned char led,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
SendfeatureReport(0x0E, 0x01, 0x00, 0x01);
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Single LED packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x0E;
usb_buf[0x02] = 0x01;
usb_buf[0x03] = 0x00;
usb_buf[0x04] = 0x01;
usb_buf[0x05] = led;
usb_buf[0x06] = 0x81;
usb_buf[0x07] = 0x00;
usb_buf[0x08] = 0xA5;
usb_buf[0x09] = 0x00;
usb_buf[0x0A] = 0x0A;
usb_buf[0x0B] = red;
usb_buf[0x0C] = green;
usb_buf[0x0D] = blue;
usb_buf[0x12] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
/*-----------------------------------------------------*\
| Delay 20 milliseconds |
\*-----------------------------------------------------*/
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
void AlienwareAW510KController::SendMode
(
unsigned char zone,
unsigned char mode,
unsigned short speed,
unsigned char direction,
unsigned char colorMode,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Mode Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x05;
usb_buf[0x02] = 0x01;
usb_buf[0x03] = mode;
usb_buf[0x04] = red;
usb_buf[0x05] = green;
usb_buf[0x06] = blue;
usb_buf[0x0A] = speed;
usb_buf[0x0B] = 0x0A;
usb_buf[0x0D] = 0x01;
usb_buf[0x0E] = colorMode;
usb_buf[0x0F] = direction;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void AlienwareAW510KController::SetMorphMode
(
unsigned char mode,
unsigned short speed,
unsigned char red1,
unsigned char green1,
unsigned char blue1,
unsigned char red2,
unsigned char green2,
unsigned char blue2
)
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Morph Mode packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x05;
usb_buf[0x02] = 0x01;
usb_buf[0x03] = mode;
usb_buf[0x04] = red1;
usb_buf[0x05] = green1;
usb_buf[0x06] = blue1;
usb_buf[0x07] = red2;
usb_buf[0x08] = green2;
usb_buf[0x09] = blue2;
usb_buf[0x0E] = 0x02;
usb_buf[0x0A] = speed;
usb_buf[0x0B] = 0x0A;
usb_buf[0x0D] = 0x01;
usb_buf[0x0E] = ALIENWARE_AW510K_TWO_USER_DEFINED_COLOR_MODE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
@@ -0,0 +1,156 @@
/*-----------------------------------------*\
| AlienwareAW510KController.h |
| |
| Definitions and types for alienware |
| AW510K Keyboard |
| |
| Mohamad Sallal - msallal 05/22/2021 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
ALIENWARE_AW510K_ZONE_MODE_KEYBOARD = 0x01,
ALIENWARE_AW510K_ZONE_MODE_LOGO = 0x07, /* logo is only need key value, which equal 07 */
};
enum
{
ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD = 0x01,
ALIENWARE_AW510K_ZONE_DIRECT_MEDIA = 0x02,
ALIENWARE_AW510K_ZONE_DIRECT_LOGO = 0x07,
ALIENWARE_AW510K_ZONE_DIRECT_INDICATORS = 0x40,
};
enum
{
ALIENWARE_AW510K_MODE_OFF = 0x00,
ALIENWARE_AW510K_MODE_DIRECT_PER_LED = 0x01,
ALIENWARE_AW510K_MODE_DIRECT = 0x01,
ALIENWARE_AW510K_MODE_PULSE = 0x02,
ALIENWARE_AW510K_MODE_MORPH = 0x03,
ALIENWARE_AW510K_MODE_BREATHING = 0x07,
ALIENWARE_AW510K_MODE_SPECTRUM = 0x08,
ALIENWARE_AW510K_MODE_SINGLE_WAVE = 0x0F,
ALIENWARE_AW510K_MODE_RAINBOW_WAVE = 0x10,
ALIENWARE_AW510K_MODE_SCANNER = 0x11,
ALIENWARE_AW510K_MODE_STATIC = 0x13,
};
enum
{
ALIENWARE_AW510K_SPEED_SLOWEST = 0x2D, /* Slowest speed */
ALIENWARE_AW510K_SPEED_NORMAL = 0x19, /* Normal speed */
ALIENWARE_AW510K_SPEED_FASTEST = 0x0A, /* Fastest speed */
};
enum
{
ALIENWARE_AW510K_DIRECTION_LEFT_TO_RIGHT = 0x01,
ALIENWARE_AW510K_DIRECTION_RIGHT_TO_LEFT = 0x02,
ALIENWARE_AW510K_DIRECTION_TOP_TO_BOTTOM = 0x03,
ALIENWARE_AW510K_DIRECTION_BOTTOM_TO_TOP = 0x04,
};
enum
{
ALIENWARE_AW510K_SINGLE_COLOR_MODE = 0x01,
ALIENWARE_AW510K_TWO_USER_DEFINED_COLOR_MODE= 0x02,
ALIENWARE_AW510K_RANBOW_COLOR_MODE = 0x03,
};
struct SelectedKeys
{
unsigned char idx;
unsigned char red;
unsigned char green;
unsigned char blue;
};
class AlienwareAW510KController
{
public:
AlienwareAW510KController(hid_device* dev_handle, const char* path);
~AlienwareAW510KController();
std::string GetDeviceLocation();
std::string GetSerialString();
void SendInitialize();
void SendCommit();
void SendfeatureReport
(
unsigned char first_byte,
unsigned char second_byte,
unsigned char third_byte,
unsigned char forth_byte
);
void SendEdit();
void SetDirect
(
unsigned char zone,
unsigned char r,
unsigned char g,
unsigned char b
);
void SendDirectOn
(
std::vector<SelectedKeys> &frame_data
);
void SetMode
(
unsigned char mode,
unsigned short speed,
unsigned char direction,
unsigned char colorMode,
unsigned char red,
unsigned char green,
unsigned char blue
);
void SetMorphMode
(
unsigned char mode,
unsigned short speed,
unsigned char red1,
unsigned char green1,
unsigned char blue1,
unsigned char red2,
unsigned char green2,
unsigned char blue2
);
void UpdateSingleLED
(
unsigned char led,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
hid_device* dev;
std::string location;
void SendMode
(
unsigned char zone,
unsigned char mode,
unsigned short speed,
unsigned char direction,
unsigned char colorMode,
unsigned char red,
unsigned char green,
unsigned char blue
);
};
@@ -0,0 +1,38 @@
#include "Detector.h"
#include "AlienwareAW510KController.h"
#include "RGBController.h"
#include "RGBController_AlienwareAW510K.h"
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| Alienware vendor ID |
\*-----------------------------------------------------*/
#define ALIENWARE_VID 0x04F2
/*-----------------------------------------------------*\
| Keyboard product IDs |
\*-----------------------------------------------------*/
#define ALIENWARE_AW510K_PID 0x1830
/******************************************************************************************\
* *
* DetectAlienwareKeyboardControllers *
* *
* Tests the USB address to see if a Alienware RGB Keyboard controller exists there. *
* *
\******************************************************************************************/
void DetectAlienwareAW510KControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if( dev )
{
AlienwareAW510KController* controller = new AlienwareAW510KController(dev, info->path);
RGBController_AlienwareAW510K* rgb_controller = new RGBController_AlienwareAW510K(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
} /* DetectAlienwareKeyboardControllers() */
REGISTER_HID_DETECTOR_IPU("Alienware AW510K", DetectAlienwareAW510KControllers, ALIENWARE_VID, ALIENWARE_AW510K_PID, 0x02, 0xFF00, 0x01);
@@ -0,0 +1,488 @@
/*-----------------------------------------*\
| RGBController_AlienwareAW510K.cpp |
| |
| Generic RGB Interface for alienware |
| AW510K Keyboard |
| |
| Mohamad Sallal - msallal 05/22/2021 |
\*-----------------------------------------*/
#include "RGBController_AlienwareAW510K.h"
#include <iterator>
//0xFFFFFFFF indicates an unused entry in matrix
#define NA 0xFFFFFFFF
int GetAW520K_WaveDirection(int input);
static unsigned int matrix_map[7][24] =
{ { 0, NA, 1, 2, 3, 4, NA, 5, 6, 7, 8, 9, 10, 11, 12, NA, 13, 14, 15, NA, 16, NA, NA, NA },
{ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, NA, NA, 31, 32, 33, NA, 34, 35, 36, 37 },
{ 38, NA, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, NA, 52, 53, 54, NA, 55, 56, 57, 74 },
{ 58, NA, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, NA, 70, NA, NA, NA, NA, NA, 71, 72, 73, NA },
{ 75, NA, NA, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, NA, NA, NA, 87, NA, NA, 88, 89, 90, 104 },
{ 91, NA, 92, 93, NA, 94, NA, NA, NA, NA, NA, 95, 96, 97, 98, NA, 99, 100, 101, NA, 102, NA, 103, NA },
{ NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 105, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA }};
static const char* zone_names[] =
{
"AW510K",
};
static zone_type zone_types[] =
{
ZONE_TYPE_MATRIX,
};
static const unsigned int zone_sizes[] =
{
106,
};
typedef struct
{
const char * name;
const unsigned char zone;
const unsigned char idx;
} led_type;
static const led_type led_names[] =
{
/* Key Label Zone, Index */
{ "Key: Escape", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0xB0 },
{ "Key: F1", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x98 },
{ "Key: F2", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x90 },
{ "Key: F3", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x88 },
{ "Key: F4", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x80 },
{ "Key: F5", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x70 },
{ "Key: F6", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x68 },
{ "Key: F7", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x60 },
{ "Key: F8", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x58 },
{ "Key: F9", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x50 },
{ "Key: F10", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x48 },
{ "Key: F11", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x40 },
{ "Key: F12", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x38 },
{ "Key: Print Screen", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x30 },
{ "Key: Scroll Lock", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x28 },
{ "Key: Pause/Break", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x20 },
{ "Key: Media Mute", ALIENWARE_AW510K_ZONE_DIRECT_MEDIA, 0x18 },
{ "Key: `", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0xB1 },
{ "Key: 1", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0xA1 },
{ "Key: 2", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x99 },
{ "Key: 3", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x91 },
{ "Key: 4", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x89 },
{ "Key: 5", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x81 },
{ "Key: 6", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x79 },
{ "Key: 7", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x71 },
{ "Key: 8", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x69 },
{ "Key: 9", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x61 },
{ "Key: 0", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x59 },
{ "Key: -", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x51 },
{ "Key: =", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x49 },
{ "Key: Backspace", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x39 },
{ "Key: Insert", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x31 },
{ "Key: Home", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x29 },
{ "Key: Page Up", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x21 },
{ "Key: Num Lock", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x19 },
{ "Key: Number Pad /", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x11 },
{ "Key: Number Pad *", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x09 },
{ "Key: Number Pad -", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x01 },
{ "Key: Tab", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0xB2 },
{ "Key: Q", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0xA2 },
{ "Key: W", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x9A },
{ "Key: E", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x92 },
{ "Key: R", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x8A },
{ "Key: T", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x82 },
{ "Key: Y", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x7A },
{ "Key: U", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x72 },
{ "Key: I", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x6A },
{ "Key: O", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x62 },
{ "Key: P", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x5A },
{ "Key: [", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x52 },
{ "Key: ]", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x4A },
{ "Key: \\ (ANSI)", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x42 },//ANSI only
{ "Key: Delete", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x32 },
{ "Key: End", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x2A },
{ "Key: Page Down", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x22 },
{ "Key: Number Pad 7", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x1A },
{ "Key: Number Pad 8", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x12 },
{ "Key: Number Pad 9", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x0A },
{ "Key: Caps Lock", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0xB3 },
{ "Key: A", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0xA3 },
{ "Key: S", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x9B },
{ "Key: D", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x93 },
{ "Key: F", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x8B },
{ "Key: G", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x83 },
{ "Key: H", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x7B },
{ "Key: J", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x73 },
{ "Key: K", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x6B },
{ "Key: L", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x63 },
{ "Key: ;", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x5B },
{ "Key: '", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x53 },
{ "Key: Enter", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x43 },
{ "Key: Number Pad 4", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x1B },
{ "Key: Number Pad 5", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x13 },
{ "Key: Number Pad 6", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x0B },
{ "Key: Number Pad +", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x03 },
{ "Key: Left Shift", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0xB4 },
{ "Key: Z", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0xA4 },
{ "Key: X", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x9C },
{ "Key: C", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x94 },
{ "Key: V", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x8C },
{ "Key: B", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x84 },
{ "Key: N", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x7C },
{ "Key: M", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x74 },
{ "Key: ,", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x6C },
{ "Key: .", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x64 },
{ "Key: /", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x5C },
{ "Key: Right Shift", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x4C },
{ "Key: Up Arrow", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x2C },
{ "Key: Number Pad 1", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x1C },
{ "Key: Number Pad 2", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x14 },
{ "Key: Number Pad 3", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x0C },
{ "Key: Left Control", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0xB5 },
{ "Key: Left Windows", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0xAD },
{ "Key: Left Alt", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0xA5 },
{ "Key: Space", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x85 },
{ "Key: Right Alt", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x65 },
{ "Key: Right Fn", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x5D },
{ "Key: Menu", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x55 },
{ "Key: Right Control", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x4D },
{ "Key: Left Arrow", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x35 },
{ "Key: Down Arrow", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x2D },
{ "Key: Right Arrow", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x25 },
{ "Key: Number Pad 0", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x1D },
{ "Key: Number Pad .", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x0D },
{ "Key: Number Pad Enter", ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0x05 },
{ "Logo", ALIENWARE_AW510K_ZONE_DIRECT_LOGO, 0x07 }
};
RGBController_AlienwareAW510K::RGBController_AlienwareAW510K(AlienwareAW510KController* alienware_ptr)
{
alienware = alienware_ptr;
name = "Alienware AW510K Keyboard Device";
vendor = "Alienware";
type = DEVICE_TYPE_KEYBOARD;
description = "Alienware AW510K Keyboard Device";
location = alienware->GetDeviceLocation();
serial = alienware->GetSerialString();
mode Direct_Per_LED;
Direct_Per_LED.name = "Direct";
Direct_Per_LED.value = ALIENWARE_AW510K_MODE_DIRECT_PER_LED;
Direct_Per_LED.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct_Per_LED.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct_Per_LED);
mode Static;
Static.name = "Static";
Static.value = ALIENWARE_AW510K_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.colors_min = 1;
Static.colors_max = 1;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors.resize(1);
modes.push_back(Static);
mode Pulse;
Pulse.name = "Pulse";
Pulse.value = ALIENWARE_AW510K_MODE_PULSE;
Pulse.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Pulse.color_mode = MODE_COLORS_MODE_SPECIFIC;
Pulse.speed_min = ALIENWARE_AW510K_SPEED_SLOWEST;
Pulse.speed_max = ALIENWARE_AW510K_SPEED_NORMAL;
Pulse.speed = ALIENWARE_AW510K_SPEED_NORMAL;
Pulse.colors_min = 1;
Pulse.colors_max = 1;
Pulse.colors.resize(1);
modes.push_back(Pulse);
mode Morph;
Morph.name = "Morph";
Morph.value = ALIENWARE_AW510K_MODE_MORPH;
Morph.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Morph.color_mode = MODE_COLORS_MODE_SPECIFIC;
Morph.speed_min = ALIENWARE_AW510K_SPEED_SLOWEST;
Morph.speed_max = ALIENWARE_AW510K_SPEED_NORMAL;
Morph.speed = ALIENWARE_AW510K_SPEED_NORMAL;
Morph.colors_min = 2;
Morph.colors_max = 2;
Morph.colors.resize(2);
modes.push_back(Morph);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = ALIENWARE_AW510K_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors.resize(1);
Breathing.speed_min = ALIENWARE_AW510K_SPEED_SLOWEST;
Breathing.speed_max = ALIENWARE_AW510K_SPEED_FASTEST;
Breathing.speed = ALIENWARE_AW510K_SPEED_NORMAL;
modes.push_back(Breathing);
mode SingleWave;
SingleWave.name = "Single Wave";
SingleWave.value = ALIENWARE_AW510K_MODE_SINGLE_WAVE;
SingleWave.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD;
SingleWave.speed_min = ALIENWARE_AW510K_SPEED_SLOWEST;
SingleWave.speed_max = ALIENWARE_AW510K_SPEED_FASTEST;
SingleWave.speed = ALIENWARE_AW510K_SPEED_NORMAL;
SingleWave.color_mode = MODE_COLORS_MODE_SPECIFIC;
SingleWave.colors_min = 1;
SingleWave.colors_max = 1;
SingleWave.colors.resize(1);
modes.push_back(SingleWave);
mode RainbowWave;
RainbowWave.name = "Rainbow Wave";
RainbowWave.value = ALIENWARE_AW510K_MODE_RAINBOW_WAVE;
RainbowWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD;
RainbowWave.speed_min = ALIENWARE_AW510K_SPEED_SLOWEST;
RainbowWave.speed_max = ALIENWARE_AW510K_SPEED_FASTEST;
RainbowWave.speed = ALIENWARE_AW510K_SPEED_NORMAL;
RainbowWave.colors_min = 1;
RainbowWave.colors_max = 1;
RainbowWave.color_mode = MODE_COLORS_MODE_SPECIFIC;
RainbowWave.colors.resize(1);
modes.push_back(RainbowWave);
mode Off;
Off.name = "Off";
Off.value = ALIENWARE_AW510K_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
SetupZones();
std::copy(colors.begin(), colors.end(),std::back_inserter(current_colors));
}
RGBController_AlienwareAW510K::~RGBController_AlienwareAW510K()
{
/*---------------------------------------------------------*\
| 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 alienware;
}
void RGBController_AlienwareAW510K::SetupZones()
{
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
unsigned int total_led_count = 0;
for(unsigned int zone_idx = 0; zone_idx < 1; zone_idx++)
{
zone new_zone;
new_zone.name = zone_names[zone_idx];
new_zone.type = zone_types[zone_idx];
new_zone.leds_min = zone_sizes[zone_idx];
new_zone.leds_max = zone_sizes[zone_idx];
new_zone.leds_count = zone_sizes[zone_idx];
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
{
new_zone.matrix_map = new matrix_map_type;
new_zone.matrix_map->height = 7;
new_zone.matrix_map->width = 24;
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
}
else
{
new_zone.matrix_map = NULL;
}
zones.push_back(new_zone);
total_led_count += zone_sizes[zone_idx];
}
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
{
led new_led;
new_led.name = led_names[led_idx].name;
new_led.value = led_names[led_idx].idx;
leds.push_back(new_led);
}
SetupColors();
}
void RGBController_AlienwareAW510K::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_AlienwareAW510K::DeviceUpdateLEDs()
{
std::vector<SelectedKeys> frame_buf_keys;
std::vector<RGBColor> new_colors;
std::copy(colors.begin(), colors.end(),std::back_inserter(new_colors));
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
if (current_colors[led_idx]==new_colors[led_idx])
{
/*-------------------------------------------------*\
| Don't send if key color is not changed |
\*-------------------------------------------------*/
continue;
}
if(RGBGetRValue(colors[led_idx]) != 0x00 || RGBGetBValue(colors[led_idx]) != 0x00 || RGBGetBValue(colors[led_idx]) != 0x00)
{
SelectedKeys key;
key.idx = (unsigned char)leds[led_idx].value;
key.red = RGBGetRValue(colors[led_idx]);
key.green = RGBGetGValue(colors[led_idx]);
key.blue = RGBGetBValue(colors[led_idx]);
frame_buf_keys.push_back(key);
}
else
{
SelectedKeys key;
key.idx = (unsigned char)leds[led_idx].value;
key.red = RGBGetRValue(colors[led_idx]);
key.green = RGBGetGValue(colors[led_idx]);
key.blue = RGBGetBValue(colors[led_idx]);
frame_buf_keys.push_back(key);
}
}
alienware->SendInitialize();
alienware->SendfeatureReport(0x05, 0x01, 0x51, 0x00);
alienware->SendCommit();
if(frame_buf_keys.size() > 0)
{
alienware->SendDirectOn(frame_buf_keys);
}
std::copy(new_colors.begin(), new_colors.end(),current_colors.begin());
}
void RGBController_AlienwareAW510K::UpdateZoneLEDs(int zone)
{
alienware->SetDirect((unsigned char) zone, RGBGetRValue(zones[zone].colors[0]), RGBGetGValue(zones[zone].colors[0]), RGBGetBValue(zones[zone].colors[0]));
}
void RGBController_AlienwareAW510K::UpdateSingleLED(int led)
{
alienware->UpdateSingleLED(leds[led].value, RGBGetRValue(colors[led]), RGBGetGValue(colors[led]), RGBGetBValue(colors[led]));
}
void RGBController_AlienwareAW510K::SetCustomMode()
{
active_mode = 0;
}
void RGBController_AlienwareAW510K::DeviceUpdateMode()
{
if(active_mode == 0xFFFF)
{
UpdateLEDs();
return;
}
alienware->SendfeatureReport(0x05, 0x01, 0x51, 0x00);
unsigned char red = 0;
unsigned char grn = 0;
unsigned char blu = 0;
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
red = RGBGetRValue(modes[active_mode].colors[0]);
grn = RGBGetGValue(modes[active_mode].colors[0]);
blu = RGBGetBValue(modes[active_mode].colors[0]);
}
switch(modes[active_mode].value)
{
case ALIENWARE_AW510K_MODE_MORPH:
/*-------------------------------------------------------------*\
| In case of morph it requires two colors (color1 and color2) |
\*-------------------------------------------------------------*/
{
unsigned char red2 = RGBGetRValue(modes[active_mode].colors[1]);
unsigned char grn2 = RGBGetGValue(modes[active_mode].colors[1]);
unsigned char blu2 = RGBGetBValue(modes[active_mode].colors[1]);
alienware->SetMorphMode(modes[active_mode].value, modes[active_mode].speed, red, grn, blu, red2, grn2, blu2);
}
break;
case ALIENWARE_AW510K_MODE_SPECTRUM:
/*-------------------------------------------------------------*\
| Spectrum only set mode, speed and colorMode |
\*-------------------------------------------------------------*/
alienware->SetMode(modes[active_mode].value, modes[active_mode].speed, 0x00, ALIENWARE_AW510K_RANBOW_COLOR_MODE, 0x00, 0x00, 0x00);
break;
case ALIENWARE_AW510K_MODE_SINGLE_WAVE:
/*-------------------------------------------------------------*\
| Wave only set mode, speed, direction and colorMode |
\*-------------------------------------------------------------*/
{
int waveDirection = GetAW520K_WaveDirection(modes[active_mode].direction);
alienware->SetMode(modes[active_mode].value, modes[active_mode].speed, waveDirection, ALIENWARE_AW510K_SINGLE_COLOR_MODE, red, grn, blu);
}
break;
case ALIENWARE_AW510K_MODE_RAINBOW_WAVE:
/*-------------------------------------------------------------*\
| Wave only set mode, speed, direction and colorMode |
\*-------------------------------------------------------------*/
{
int waveDirection = GetAW520K_WaveDirection(modes[active_mode].direction);
alienware->SetMode(modes[active_mode].value, modes[active_mode].speed, waveDirection, ALIENWARE_AW510K_RANBOW_COLOR_MODE, 0x00, 0x00, 0x00);
}
break;
default:
alienware->SetMode(modes[active_mode].value, modes[active_mode].speed, 0x00, ALIENWARE_AW510K_SINGLE_COLOR_MODE, red, grn, blu);
break;
}
}
int GetAW520K_WaveDirection(int input)
{
switch(input)
{
case MODE_DIRECTION_LEFT:
return(ALIENWARE_AW510K_DIRECTION_RIGHT_TO_LEFT);
case MODE_DIRECTION_RIGHT:
return(ALIENWARE_AW510K_DIRECTION_LEFT_TO_RIGHT);
case MODE_DIRECTION_UP:
return(ALIENWARE_AW510K_DIRECTION_BOTTOM_TO_TOP);
case MODE_DIRECTION_DOWN:
return(ALIENWARE_AW510K_DIRECTION_TOP_TO_BOTTOM);
default:
return(ALIENWARE_AW510K_DIRECTION_RIGHT_TO_LEFT);
}
}
@@ -0,0 +1,35 @@
/*-----------------------------------------*\
| RGBController_AlienwareAW510K.h |
| |
| Generic RGB Interface for Alienware |
| AW510K keyboard |
| |
| Mohamad Sallal - msallal 05/22/2021 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "AlienwareAW510KController.h"
class RGBController_AlienwareAW510K : public RGBController
{
public:
RGBController_AlienwareAW510K(AlienwareAW510KController* alienware_ptr);
~RGBController_AlienwareAW510K();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
AlienwareAW510KController* alienware;
std::vector<RGBColor> current_colors;
};
@@ -32,6 +32,8 @@ typedef struct
static const gpu_pci_device device_list[] =
{
{ NVIDIA_VEN, NVIDIA_GTX1050_DEV, ASUS_SUB_VEN, ASUS_GTX1050_STRIX_O2G_GAMING, 0x29, "ASUS ROG Strix GTX 1050 O2G Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1060_DEV, ASUS_SUB_VEN, ASUS_GTX1060_STRIX_6G_GAMING, 0x29, "ASUS GTX 1060 Strix 6G Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1060_DEV, ASUS_SUB_VEN, ASUS_GTX1060_STRIX, 0x29, "ASUS GTX 1060 Strix" },
{ NVIDIA_VEN, NVIDIA_GTX1070_DEV, ASUS_SUB_VEN, ASUS_GTX1070_STRIX_GAMING, 0x29, "ASUS GTX 1070 Strix Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1070_DEV, ASUS_SUB_VEN, ASUS_GTX1070_STRIX_OC, 0x29, "ASUS GTX 1070 Strix OC" },
@@ -42,9 +44,11 @@ static const gpu_pci_device device_list[] =
{ NVIDIA_VEN, NVIDIA_GTX1080TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080TI_GAMING, 0x29, "ASUS ROG Strix GTX1080 Ti Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1080TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080TI_11G_GAMING, 0x29, "ASUS ROG Strix GTX1080 Ti 11G Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1650S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1650S_OC, 0x2A, "ASUS ROG Strix GTX 1650S OC 4G" },
{ NVIDIA_VEN, NVIDIA_GTX1660S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1660S_O6G_GAMING, 0x2A, "ASUS ROG Strix GTX 1660S O6G Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1660TI_DEV, ASUS_SUB_VEN, ASUS_ROG_GTX1660TI_OC, 0x2A, "ASUS ROG GTX 1660 Ti OC 6G" },
{ NVIDIA_VEN, NVIDIA_RTX2060_TU106_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2060_EVO_GAMING, 0x2A, "ASUS ROG STRIX RTX 2060 EVO Gaming 6G" },
{ NVIDIA_VEN, NVIDIA_RTX2060S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2060S_A8G_EVO_GAMING, 0x2A, "ASUS ROG STRIX RTX 2060S A8G EVO Gaming 6G"},
{ NVIDIA_VEN, NVIDIA_RTX2060S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2060S_A8G_EVO_GAMING, 0x2A, "ASUS ROG STRIX RTX 2060S A8G EVO Gaming 8G"},
{ NVIDIA_VEN, NVIDIA_RTX2060S_OC_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2060S_O8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2060S O8G Gaming 8G" },
{ NVIDIA_VEN, NVIDIA_RTX2070_OC_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2070_A8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2070 A8G Gaming 8G" },
{ NVIDIA_VEN, NVIDIA_RTX2070_OC_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2070_O8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2070 O8G Gaming 8G" },
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2070S_A8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2070S A8G Gaming 8G" },
@@ -83,12 +83,12 @@ AuraSMBusController::AuraSMBusController(i2c_smbus_interface* bus, aura_dev_id d
effect_reg = AURA_REG_COLORS_EFFECT_V2;
channel_cfg = AURA_CONFIG_CHANNEL_V2;
}
// AUMA0-E8K4-0101 - Second generation motherboard controller
// AUMA0-E8K4-0101 - First generation motherboard controller
else if (strcmp(device_name, "AUMA0-E8K4-0101") == 0)
{
direct_reg = AURA_REG_COLORS_DIRECT_V2;
effect_reg = AURA_REG_COLORS_EFFECT_V2;
channel_cfg = AURA_CONFIG_CHANNEL_V2;
direct_reg = AURA_REG_COLORS_DIRECT;
effect_reg = AURA_REG_COLORS_EFFECT;
channel_cfg = AURA_CONFIG_CHANNEL_V1;
}
// Assume first generation controller if string does not match
else
@@ -12,24 +12,44 @@
CMMKController::CMMKController(hid_device* dev, hid_device_info* dev_info)
{
location = dev_info->path;
location = dev_info->path;
const int szTemp = 256;
const int szTemp = 256;
wchar_t tmpName[szTemp];
hid_get_manufacturer_string(dev, tmpName, szTemp);
std::wstring wName = std::wstring(tmpName);
device_name = std::string(wName.begin(), wName.end());
std::wstring wName = std::wstring(tmpName);
vendor_name = std::string(wName.begin(), wName.end());
hid_get_product_string(dev, tmpName, szTemp);
wName = std::wstring(tmpName);
device_name.append(" ").append(std::string(wName.begin(), wName.end()));
device_name = std::string(wName.begin(), wName.end());
cmmk_attach_path(&cmmk_handle, dev_info->path, dev_info->product_id, -1);
char buf[32] = {0};
cmmk_get_firmware_version(&cmmk_handle, buf, 32);
/*--------------------------------------------------------------*\
| Adjust the row count for keyboards without the front light bar |
| Adjust the column count for TKL keyboards (i.e. x30 vs x50) |
\*--------------------------------------------------------------*/
enum cmmk_product_type kb_type = cmmk_get_device_model(&cmmk_handle);
row_count = (kb_type == CMMK_PRODUCT_MASTERKEYS_MK750) ? CMMK_ROWS_MAX : CMMK_ROWS_MAX - 1;
switch(kb_type)
{
case CMMK_PRODUCT_MASTERKEYS_PRO_S:
case CMMK_PRODUCT_MASTERKEYS_SK630:
column_count = CMMK_COLS_MAX - 4;
break;
case CMMK_PRODUCT_MASTERKEYS_PRO_L:
case CMMK_PRODUCT_MASTERKEYS_MK750:
case CMMK_PRODUCT_MASTERKEYS_SK650:
default:
column_count = CMMK_COLS_MAX;
}
firmware_version = buf;
}
@@ -43,6 +63,11 @@ std::string CMMKController::GetDeviceName()
return device_name;
}
std::string CMMKController::GetDeviceVendor()
{
return vendor_name;
}
std::string CMMKController::GetLocation()
{
return location;
@@ -53,6 +78,16 @@ std::string CMMKController::GetFirmwareVersion()
return firmware_version;
}
uint8_t CMMKController::GetRowCount()
{
return row_count;
}
uint8_t CMMKController::GetColumnCount()
{
return column_count;
}
void CMMKController::SetFirmwareControl()
{
ActivateMode(CMMK_FIRMWARE);
@@ -20,8 +20,11 @@ public:
~CMMKController();
std::string GetDeviceName();
std::string GetDeviceVendor();
std::string GetLocation();
std::string GetFirmwareVersion();
uint8_t GetRowCount();
uint8_t GetColumnCount();
void SetFirmwareControl();
void SetManualControl();
@@ -51,8 +54,11 @@ private:
int current_effect = -1;
std::string device_name;
std::string vendor_name;
std::string location;
std::string firmware_version;
uint8_t row_count;
uint8_t column_count;
mutable struct cmmk cmmk_handle;
};
@@ -25,7 +25,7 @@
#define COOLERMASTER_SMALL_ARGB_PID 0x1000
#define COOLERMASTER_RGB_PID 0x004F
#define COOLERMASTER_RADEON_6000_PID 0x014D
#define COOLERMASTER_MASTERKEYS_PRO_L_PID CMMK_USB_MASTERKEYS_MK750
#define COOLERMASTER_MASTERKEYS_PRO_L_PID CMMK_USB_MASTERKEYS_PRO_L
#define COOLERMASTER_MASTERKEYS_PRO_L_WHITE_PID CMMK_USB_MASTERKEYS_PRO_L_WHITE
#define COOLERMASTER_MASTERKEYS_PRO_S_PID CMMK_USB_MASTERKEYS_PRO_S
#define COOLERMASTER_MASTERKEYS_MK750_PID CMMK_USB_MASTERKEYS_MK750
@@ -14,141 +14,158 @@
using namespace std::chrono_literals;
#define CMMK_SPEED_MIN CMMK_SPEED0
#define CMMK_SPEED_MID CMMK_SPEED2
#define CMMK_SPEED_MAX CMMK_SPEED4
#define CMMK_MODE_FIRMWARE 0xFF
#define CMMK_MODE_MANUAL 0x7F
#define CMMK_SPEED_MIN CMMK_SPEED0
#define CMMK_SPEED_MID CMMK_SPEED2
#define CMMK_SPEED_MAX CMMK_SPEED4
#define CMMK_MODE_FIRMWARE 0xFF
#define CMMK_MODE_MANUAL 0x7F
RGBController_CMMKController::RGBController_CMMKController(CMMKController* cmmk_ctrl)
{
cmmk = cmmk_ctrl;
cmmk = cmmk_ctrl;
name = cmmk->GetDeviceName();
type = DEVICE_TYPE_KEYBOARD;
description = "Cooler Master MasterKeys Device";
version = cmmk->GetFirmwareVersion();
serial = "";
location = cmmk->GetLocation();
name = cmmk->GetDeviceName();
vendor = cmmk->GetDeviceVendor();
type = DEVICE_TYPE_KEYBOARD;
description = "Cooler Master MasterKeys Device";
version = cmmk->GetFirmwareVersion();
serial = "";
location = cmmk->GetLocation();
mode Direct;
Direct.name = "Direct";
Direct.value = CMMK_MODE_MANUAL;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
Direct.name = "Direct";
Direct.value = CMMK_MODE_MANUAL;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Static;
Static.name = "Static";
Static.value = CMMK_EFFECT_FULLY_LIT;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors_min = 1;
Static.colors_max = 1;
Static.name = "Static";
Static.value = CMMK_EFFECT_FULLY_LIT;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(1);
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CMMK_EFFECT_BREATHE;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Breathing.speed_min = 0x20;
Breathing.speed_max = 0x20;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.name = "Breathing";
Breathing.value = CMMK_EFFECT_BREATHE;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.speed_min = CMMK_SPEED_MIN;
Breathing.speed_max = CMMK_SPEED_MAX;
Breathing.speed = CMMK_SPEED_MID;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(1);
modes.push_back(Breathing);
mode Cycle;
Cycle.name = "Spectrum Cycle";
Cycle.value = CMMK_EFFECT_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED;
Cycle.speed_min = CMMK_SPEED_MIN;
Cycle.speed_max = CMMK_SPEED_MAX;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.name = "Spectrum Cycle";
Cycle.value = CMMK_EFFECT_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.speed_min = 2 * CMMK_SPEED_MIN; //Spectrum Cycle uses a unique speed range
Cycle.speed_max = 2 * CMMK_SPEED_MAX;
Cycle.speed = 2 * CMMK_SPEED_MID;
modes.push_back(Cycle);
mode Reactive;
Reactive.name = "Reactive";
Reactive.value = CMMK_EFFECT_SINGLE;
Reactive.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Reactive.speed_min = CMMK_SPEED_MIN;
Reactive.speed_max = CMMK_SPEED_MAX;
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
Reactive.colors_min = 2;
Reactive.colors_max = 2;
Reactive.name = "Reactive";
Reactive.value = CMMK_EFFECT_SINGLE;
Reactive.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
Reactive.speed_min = CMMK_SPEED_MIN;
Reactive.speed_max = CMMK_SPEED_MAX;
Reactive.speed = CMMK_SPEED_MID;
Reactive.colors_min = 2;
Reactive.colors_max = 2;
Reactive.colors.resize(2);
modes.push_back(Reactive);
mode Wave;
Wave.name = "Rainbow Wave";
Wave.value = CMMK_EFFECT_WAVE;
Wave.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD;
Wave.speed_min = CMMK_SPEED_MIN;
Wave.speed_max = CMMK_SPEED_MAX;
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
Wave.colors_min = 1;
Wave.colors_max = 1;
Wave.name = "Rainbow Wave";
Wave.value = CMMK_EFFECT_WAVE;
Wave.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD;
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
Wave.speed_min = CMMK_SPEED_MIN;
Wave.speed_max = CMMK_SPEED_MAX;
Wave.speed = CMMK_SPEED_MID;
Wave.direction = MODE_DIRECTION_LEFT;
Wave.colors_min = 1;
Wave.colors_max = 1;
Wave.colors.resize(1);
modes.push_back(Wave);
mode Ripple;
Ripple.name = "Ripple Effect";
Ripple.value = CMMK_EFFECT_RIPPLE;
Ripple.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED;
Ripple.speed_min = CMMK_SPEED_MIN;
Ripple.speed_max = CMMK_SPEED_MAX;
Ripple.colors_min = 2;
Ripple.colors_max = 2;
Ripple.name = "Ripple Effect";
Ripple.value = CMMK_EFFECT_RIPPLE;
Ripple.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED;
Ripple.color_mode = MODE_COLORS_MODE_SPECIFIC;
Ripple.speed_min = CMMK_SPEED_MIN;
Ripple.speed_max = CMMK_SPEED_MAX;
Ripple.speed = CMMK_SPEED_MID;
Ripple.colors_min = 2;
Ripple.colors_max = 2;
Ripple.colors.resize(2);
modes.push_back(Ripple);
mode Cross;
Cross.name = "Cross";
Cross.value = CMMK_EFFECT_CROSS;
Cross.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Cross.speed_min = CMMK_SPEED_MIN;
Cross.speed_max = CMMK_SPEED_MAX;
Cross.colors_min = 2;
Cross.colors_max = 2;
Cross.name = "Cross";
Cross.value = CMMK_EFFECT_CROSS;
Cross.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Cross.color_mode = MODE_COLORS_MODE_SPECIFIC;
Cross.speed_min = CMMK_SPEED_MIN;
Cross.speed_max = CMMK_SPEED_MAX;
Cross.speed = CMMK_SPEED_MID;
Cross.colors_min = 2;
Cross.colors_max = 2;
Cross.colors.resize(2);
modes.push_back(Cross);
mode Raindrops;
Raindrops.name = "Raindrops";
Raindrops.value = CMMK_EFFECT_RAINDROPS;
Raindrops.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Raindrops.speed_min = CMMK_SPEED_MIN;
Raindrops.speed_max = CMMK_SPEED_MAX;
Raindrops.colors_min = 2;
Raindrops.colors_max = 2;
Raindrops.name = "Raindrops";
Raindrops.value = CMMK_EFFECT_RAINDROPS;
Raindrops.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Raindrops.color_mode = MODE_COLORS_MODE_SPECIFIC;
Raindrops.speed_min = CMMK_SPEED_MIN;
Raindrops.speed_max = CMMK_SPEED_MAX;
Raindrops.speed = CMMK_SPEED_MID;
Raindrops.colors_min = 2;
Raindrops.colors_max = 2;
Raindrops.colors.resize(2);
modes.push_back(Raindrops);
mode Stars;
Stars.name = "Starfield";
Stars.value = CMMK_EFFECT_STARS;
Stars.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Stars.speed_min = CMMK_SPEED_MIN;
Stars.speed_max = CMMK_SPEED_MAX;
Stars.colors_min = 2;
Stars.name = "Starfield";
Stars.value = CMMK_EFFECT_STARS;
Stars.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Stars.color_mode = MODE_COLORS_MODE_SPECIFIC;
Stars.speed_min = CMMK_SPEED_MIN;
Stars.speed_max = CMMK_SPEED_MAX;
Stars.speed = CMMK_SPEED_MID;
Stars.colors_min = 2;
Stars.colors_max = 2;
Stars.colors.resize(2);
modes.push_back(Stars);
mode Snake;
Snake.name = "Snake";
Snake.value = CMMK_EFFECT_SNAKE;
Snake.flags = MODE_FLAG_HAS_SPEED;
Snake.speed_min = CMMK_SPEED_MIN;
Snake.speed_max = CMMK_SPEED_MAX;
Snake.name = "Snake";
Snake.value = CMMK_EFFECT_SNAKE;
Snake.flags = MODE_FLAG_HAS_SPEED;
Snake.color_mode = MODE_COLORS_NONE;
Snake.speed_min = CMMK_SPEED_MIN;
Snake.speed_max = CMMK_SPEED_MAX;
Snake.speed = CMMK_SPEED_MID;
modes.push_back(Snake);
mode FirmwareControl;
FirmwareControl.name = "Firmware Controlled";
FirmwareControl.value = 0xFF;
FirmwareControl.flags = 0;
FirmwareControl.name = "Firmware Controlled";
FirmwareControl.value = 0xFF;
FirmwareControl.flags = 0;
FirmwareControl.color_mode = MODE_COLORS_NONE;
modes.push_back(FirmwareControl);
SetupZones();
@@ -182,9 +199,12 @@ void RGBController_CMMKController::SetupMatrixMap()
void RGBController_CMMKController::SetupZones()
{
for(int y = 0; y < CMMK_ROWS_MAX; y++)
uint8_t row_count = cmmk->GetRowCount();
uint8_t column_count = cmmk->GetColumnCount();
for(int y = 0; y < row_count; y++)
{
for(int x = 0; x < CMMK_COLS_MAX; x++)
for(int x = 0; x < column_count; x++)
{
if(!cmmk->PositionValid(y, x))
{
@@ -211,8 +231,8 @@ void RGBController_CMMKController::SetupZones()
KeyboardZone.leds_max = leds.size();
KeyboardZone.leds_count = leds.size();
KeyboardZone.matrix_map = new matrix_map_type;
KeyboardZone.matrix_map->height = CMMK_ROWS_MAX;
KeyboardZone.matrix_map->width = CMMK_COLS_MAX;
KeyboardZone.matrix_map->height = row_count;
KeyboardZone.matrix_map->width = column_count;
KeyboardZone.matrix_map->map = (unsigned int *)&matrix_map;
zones.push_back(KeyboardZone);
@@ -0,0 +1,136 @@
/*-----------------------------------------*\
| CorsairK100Controller.cpp |
| |
| Driver for Corsair K100 Keyboard |
\*-----------------------------------------*/
#include "CorsairK100Controller.h"
#include "LogManager.h"
static unsigned int keys_k100[] = {0x25, 0x31, 0x27, 0x35, 0x66, 0x65, 0x41, 0x2A, 0x6E, 0x5B, 0x36, 0x1A, 0x10, 0x00, 0x68, 0x42,
0x62, 0x5C, 0x37, 0x1B, 0x16, 0x12, 0x19, 0x67, 0x43, 0x26, 0x77, 0x5D, 0x38, 0x1C, 0x04, 0x03,
0x17, 0x44, 0x48, 0x7A, 0x39, 0x1D, 0x11, 0x05, 0x02, 0x28, 0x45, 0x49, 0x78, 0x58, 0x3A, 0x1E,
0x13, 0x06, 0x15, 0x46, 0x4A, 0x79, 0x59, 0x3B, 0x1F, 0x18, 0x07, 0x01, 0x47, 0x6A, 0x4F, 0x5A,
0x3C, 0x20, 0x14, 0x09, 0x0D, 0x6B, 0x2C, 0x69, 0x50, 0x55, 0x3D, 0x21, 0x08, 0x0A, 0x0C, 0x76,
0x2D, 0x4E, 0x51, 0x56, 0x3E, 0x22, 0x0E, 0x0B, 0x32, 0x61, 0x4C, 0x52, 0x57, 0x3F, 0x23, 0x0F,
0x2F, 0x33, 0x24, 0x4D, 0x53, 0x5E, 0x40, 0x29, 0x2B, 0x30, 0x34, /*Brightness,*/
0x4B, 0x54, 0x5F, 114 , 99, 0x7C, //114 and 99 is not conformed it just a guess
0x7F, 0x80, 0x81, 0x82, 0x83, 0x84,//Macro
0xA6, 0xA5, 0xA4, 0xA3, 0xA2, 0xA1, 0xA0, 0x9F, 0x9E, 0x9D, 0x9C, 0x86, 0x87, 0x88, 0x89, 0x8A,
0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
0x9B, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,0xB0, 0xB1, //Light Bar
0x85, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,//Nameplate
0xBA, 0xBB, 0xBC/*Logo*/};
CorsairK100Controller::CorsairK100Controller(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
keyboard_type = CORSAIR_TYPE_K100;
LightingControl();
}
CorsairK100Controller::~CorsairK100Controller()
{
hid_close(dev);
}
std::string CorsairK100Controller::GetDeviceLocation()
{
return("HID: " + location);
}
std::string CorsairK100Controller::GetFirmwareString()
{
return "";
}
std::string CorsairK100Controller::GetName()
{
return name;
}
void CorsairK100Controller::SetName(std::string device_name)
{
name = device_name;
}
CorsairKeyboardType CorsairK100Controller::GetKeyboardType()
{
return keyboard_type;
}
std::string CorsairK100Controller::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void CorsairK100Controller::LightingControl()
{
unsigned char usb_buf[65];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x01] = 0x08;
usb_buf[0x02] = 0x05;
usb_buf[0x03] = 0x01;
hid_write(dev, (unsigned char *)usb_buf, 5);
memset(usb_buf, 0x00, sizeof(usb_buf));
int res = hid_read_timeout(dev, usb_buf, 50, 1000);
if (res == 0 || usb_buf[1] != 0x05)
{
LOG_INFO("[Corsair-K100] This device did not allow to take control over it.");
keyboard_type = CORSAIR_TYPE_UNKNOWN;
}
}
void CorsairK100Controller::SetLEDs(std::vector<RGBColor>colors)
{
switch(keyboard_type)
{
case CORSAIR_TYPE_K100:
SetLEDsKeyboardFull(colors);
break;
case CORSAIR_TYPE_UNKNOWN:
break;
}
}
void CorsairK100Controller::SetLEDsKeyboardFull(std::vector<RGBColor> colors)
{
unsigned char usb_buf[600];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x08;
usb_buf[0x02] = 0x06;
usb_buf[0x03] = 0x01;
usb_buf[0x04] = 0x45;
usb_buf[0x05] = 0x02;
usb_buf[0x08] = 0x12;
for(std::size_t color_idx = 0; color_idx < colors.size(); color_idx++)
{
RGBColor color = colors[color_idx];
usb_buf[0x16 + keys_k100[color_idx]*3] = RGBGetRValue(color);
usb_buf[0x17 + keys_k100[color_idx]*3] = RGBGetGValue(color);
usb_buf[0x18 + keys_k100[color_idx]*3] = RGBGetBValue(color);
}
hid_write(dev, (unsigned char *)usb_buf, 600);
}
@@ -0,0 +1,49 @@
/*-----------------------------------------*\
| CorsairK100Controller.h |
| |
| Driver for Corsair K100 Keyboard |
\*-----------------------------------------*/
#ifndef CORSAIRK100CONTROLLER_H
#define CORSAIRK100CONTROLLER_H
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
typedef enum
{
CORSAIR_TYPE_UNKNOWN = 0,
CORSAIR_TYPE_K100 = 1
} CorsairKeyboardType;
class CorsairK100Controller
{
public:
CorsairK100Controller(hid_device* dev_handle, const char* path);
~CorsairK100Controller();
CorsairKeyboardType GetKeyboardType();
std::string GetDeviceLocation();
std::string GetFirmwareString();
std::string GetName();
std::string GetSerialString();
void SetLEDs(std::vector<RGBColor> colors);
void SetLEDsKeyboardLimited(std::vector<RGBColor> colors);
void SetName(std::string device_name);
private:
hid_device* dev;
std::string firmware_version;
std::string location;
std::string name;
device_type type;
CorsairKeyboardType keyboard_type;
void LightingControl();
void SetLEDsKeyboardFull(std::vector<RGBColor> colors);
};
#endif // CORSAIRK100CONTROLLER_H
@@ -22,6 +22,15 @@ static unsigned int keys[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x
116, 117, 120, 121, 122, 123, 124, 126, 127, 128, 129, 132, 133, 134, 135,
136, 137, 139, 140, 141, 0x10, 114};
static unsigned int keys_k70_mk2[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12,
0x14, 0x15, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x24, 0x25, 0x26,
0x27, 0x28, 0x2A, 0x2B, 0x2C, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x42, 0x43, 0x44, 0x45, 0x48, 73, 74, 75, 76, 78,
79, 80, 81, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 96, 97,
98, 99, 100, 101, 102, 103, 104, 105, 108, 109, 110, 111, 112, 113, 115,
116, 117, 120, 121, 122, 123, 124, 126, 127, 128, 129, 132, 133, 134, 135,
136, 137, 139, 140, 141, 16, 114, 47, 59, 125 };
static unsigned int keys_k95_plat[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12,
0x14, 0x15, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x24, 0x25, 0x26,
@@ -61,14 +70,14 @@ CorsairPeripheralController::CorsairPeripheralController(hid_device* dev_handle,
/*-----------------------------------------------------*\
| K55 and K95 Platinum require additional steps |
\*-----------------------------------------------------*/
if (logical_layout == CORSAIR_TYPE_K55 || logical_layout == CORSAIR_TYPE_K95_PLAT)
if (logical_layout == CORSAIR_TYPE_K55 || logical_layout == CORSAIR_TYPE_K95_PLAT || logical_layout == CORSAIR_TYPE_K70_MK2 || logical_layout == CORSAIR_TYPE_K68)
{
SpecialFunctionControl();
}
LightingControl();
if (logical_layout == CORSAIR_TYPE_K55 || logical_layout == CORSAIR_TYPE_K95_PLAT)
if (logical_layout == CORSAIR_TYPE_K55 || logical_layout == CORSAIR_TYPE_K95_PLAT || logical_layout == CORSAIR_TYPE_K70_MK2 || logical_layout == CORSAIR_TYPE_K68)
{
SetupK55AndK95LightingControl();
}
@@ -204,6 +213,12 @@ void CorsairPeripheralController::SetLEDsKeyboardFull(std::vector<RGBColor> colo
blu_val[keys_k95[color_idx]] = RGBGetBValue(color);
data_sz = 48; //untested
}
else if (logical_layout = CORSAIR_TYPE_K70_MK2)
{
red_val[keys_k70_mk2[color_idx]] = RGBGetRValue(color);
grn_val[keys_k70_mk2[color_idx]] = RGBGetGValue(color);
blu_val[keys_k70_mk2[color_idx]] = RGBGetBValue(color);
}
else
{
red_val[keys[color_idx]] = RGBGetRValue(color);
@@ -541,6 +556,17 @@ void CorsairPeripheralController::ReadFirmwareInfo()
logical_layout = CORSAIR_TYPE_K55;
break;
case 0x1B38:
case 0x1B49:
case 0x1B6B:
case 0x1B55:
logical_layout = CORSAIR_TYPE_K70_MK2;
break;
case 0x1B4F:
logical_layout = CORSAIR_TYPE_K68;
break;
default:
logical_layout = CORSAIR_TYPE_NORMAL;
}
@@ -62,7 +62,9 @@ enum
CORSAIR_TYPE_NORMAL = 0,
CORSAIR_TYPE_K95_PLAT = 1,
CORSAIR_TYPE_K95 = 2,
CORSAIR_TYPE_K55 = 3
CORSAIR_TYPE_K55 = 3,
CORSAIR_TYPE_K70_MK2 = 4,
CORSAIR_TYPE_K68 = 5
};
class CorsairPeripheralController
@@ -1,7 +1,9 @@
#include "Detector.h"
#include "CorsairPeripheralController.h"
#include "CorsairK100Controller.h"
#include "RGBController.h"
#include "RGBController_CorsairPeripheral.h"
#include "RGBController_CorsairK100.h"
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
@@ -60,6 +62,33 @@
\*-----------------------------------------------------*/
#define CORSAIR_ST100_PID 0x0A34
/*-----------------------------------------------------*\
| Corsair K100 Keyboard product ID |
| This keyboard uses a separate driver |
\*-----------------------------------------------------*/
#define CORSAIR_K100_PID 0x1B7C
void DetectCorsairK100Controllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CorsairK100Controller* controller = new CorsairK100Controller(dev, info->path);
controller->SetName(name);
if(controller->GetKeyboardType() != CORSAIR_TYPE_UNKNOWN)
{
RGBController_CorsairK100* rgb_controller = new RGBController_CorsairK100(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
else
{
delete controller;
}
}
} /* DetectCorsairPeripheralControllers() */
/******************************************************************************************\
* *
* DetectCorsairPeripheralControllers *
@@ -67,11 +96,11 @@
* Tests the USB address to see if a Corsair RGB Keyboard controller exists there. *
* *
\******************************************************************************************/
void DetectCorsairPeripheralControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if( dev )
if(dev)
{
CorsairPeripheralController* controller = new CorsairPeripheralController(dev, info->path);
controller->SetName(name);
@@ -134,3 +163,8 @@ REGISTER_HID_DETECTOR_P("Corsair ST100 RGB", DetectCorsairPeriphe
#else
REGISTER_HID_DETECTOR_I("Corsair ST100 RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_ST100_PID, 0);
#endif
/*-----------------------------------------------------------------------------------------------------*\
| Corsair K100 Keyboard |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("Corsair K100", DetectCorsairK100Controllers, CORSAIR_VID, CORSAIR_K100_PID, 1, 0xFF42);
@@ -0,0 +1,338 @@
/*-----------------------------------------*\
| RGBController_CorsairK100.cpp |
| |
| Driver for Corsair K100 Keyboard |
\*-----------------------------------------*/
#include "RGBController_CorsairK100.h"
#include "LogManager.h"
#define NA 0xFFFFFFFF
static unsigned int matrix_map_k100[7][24] =
{ { NA, 112, NA, 8, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 16, NA, NA, NA,},
{ 113, 0, NA, 10, 18, 28, 36, NA, 46, 55, 64, 74, NA, 84, 93, 102, 6, 15, 24, 33, 26, 35, 44, 53 },
{ 114, 1, 11, 19, 29, 37, 47, 56, 65, 75, 85, 94, NA, 103, 7, 25, NA, 42, 51, 60, 62, 72, 82, 91 },
{ 115, 2, NA, 12, 20, 30, 38, NA, 48, 57, 66, 76, 86, 95, 104, 70, 80, 34, 43, 52, 9, 17, 27, 100 },
{ 116, 3, NA, 13, 21, 31, 39, NA, 49, 58, 67, 77, 87, 96, 105, 98, 111, NA, NA, NA, 45, 54, 63, NA },
{ 117, 4, 110, 22, 32, 40, 50, NA, 59, NA, 68, 78, 88, 97, 106, 61, NA, NA, 81, NA, 73, 83, 92, 108 },
{ 118, 5, 14, 23, NA, NA, NA, NA, 41, NA, NA, NA, NA, 69, 79, 89, 71, 90, 99, 107, 101, NA, 109, NA } };
static const char* led_names_k100[] =
{
"Key: Escape", //0
"Key: `", //1
"Key: Tab", //2
"Key: Caps Lock", //3
"Key: Left Shift", //4
"Key: Left Control", //5
"Key: F12", //6
"Key: =", //7
"Key: Lock", //8
"Key: Number Pad 7", //9
"Key: F1", //12
"Key: 1", //13
"Key: Q", //14
"Key: A", //15
"Key: Left Windows", //17
"Key: Print Screen", //18
"Key: Media Mute", //20
"Key: Number Pad 8", //21
"Key: F2", //24
"Key: 2", //25
"Key: W", //26
"Key: S", //27
"Key: Z", //28
"Key: Left Alt", //29
"Key: Scroll Lock", //30
"Key: Backspace", //31
"Key: Media Stop", //32
"Key: Number Pad 9", //33
"Key: F3", //36
"Key: 3", //37
"Key: E", //38
"Key: D", //39
"Key: X", //40
"Key: Pause/Break", //42
"Key: Delete", //43
"Key: Media Previous", //44
"Key: F4", //48
"Key: 4", //49
"Key: R", //50
"Key: F", //51
"Key: C", //52
"Key: Space", //53
"Key: Insert", //54
"Key: End", //55
"Key: Media Play/Pause",//56
"Key: Number Pad 4", //57
"Key: F5", //60
"Key: 5", //61
"Key: T", //62
"Key: G", //63
"Key: V", //64
"Key: Home", //66
"Key: Page Down", //67
"Key: Media Next", //68
"Key: Number Pad 5", //69
"Key: F6", //72
"Key: 6", //73
"Key: Y", //74
"Key: H", //75
"Key: B", //76
"Key: Page Up", //78
"Key: Right Shift", //79
"Key: Num Lock", //80
"Key: Number Pad 6", //81
"Key: F7", //84
"Key: 7", //85
"Key: U", //86
"Key: J", //87
"Key: N", //88
"Key: Right Alt", //89
"Key: ]", //90
"Key: Right Control", //91
"Key: Number Pad /", //92
"Key: Number Pad 1", //93
"Key: F8", //96
"Key: 8", //97
"Key: I", //98
"Key: K", //99
"Key: M", //100
"Key: Right Windows", //101
"Key: \\ (ANSI)", //102
"Key: Up Arrow", //103
"Key: Number Pad *", //104
"Key: Number Pad 2", //105
"Key: F9", //108
"Key: 9", //109
"Key: O", //110
"Key: L", //111
"Key: ,", //112
"Key: Menu", //113
"Key: Left Arrow", //115
"Key: Number Pad -", //116
"Key: Number Pad 3", //117
"Key: F10", //120
"Key: 0", //121
"Key: P", //122
"Key: ;", //123
"Key: .", //124
"Key: Enter", //126
"Key: Down Arrow", //127
"Key: Number Pad +", //128
"Key: Number Pad 0", //129
"Key: F11", //132
"Key: -", //133
"Key: [", //134
"Key: '", //135
"Key: /", //136
// "Key: Brightness", //137
"Key: Right Arrow", //139
"Key: Number Pad Enter",//140
"Key: Number Pad .", //141
"Key: / (ISO)",
"Key: \\ (ISO)",
"Key: Preset",
"Key: G1",
"Key: G2",
"Key: G3",
"Key: G4",
"Key: G5",
"Key: G6",
};
static const char* led_names_lightbar[] =
{
"Underglow 1",
"Underglow 2",
"Underglow 3",
"Underglow 4",
"Underglow 5",
"Underglow 6",
"Underglow 7",
"Underglow 8",
"Underglow 9",
"Underglow 10",
"Underglow 11",
"Underglow 12",
"Underglow 13",
"Underglow 14",
"Underglow 15",
"Underglow 16",
"Underglow 17",
"Underglow 18",
"Underglow 19",
"Underglow 20",
"Underglow 21",
"Underglow 22",
"Underglow 23",
"Underglow 24",
"Underglow 25",
"Underglow 26",
"Underglow 27",
"Underglow 28",
"Underglow 29",
"Underglow 30",
"Underglow 31",
"Underglow 32",
"Underglow 33",
"Underglow 34",
"Underglow 35",
"Underglow 36",
"Underglow 37",
"Underglow 38",
"Underglow 39",
"Underglow 40",
"Underglow 41",
"Underglow 42",
"Underglow 43",
"Underglow 44",
};
static const char* led_names_nameplate[] =
{
"Nameplate 1",
"Nameplate 2",
"Nameplate 3",
"Nameplate 4",
"Nameplate 5",
"Nameplate 6",
"Nameplate 7",
"Nameplate 8",
"Nameplate 9",
};
static const char* led_names_logo[] =
{
"Logo",
"Logo",
"Logo",
};
typedef struct
{
const char* name;
const unsigned int size;
const zone_type type;
const char** led_names;
matrix_map_type* matrix;
} led_zone_layout;
RGBController_CorsairK100::RGBController_CorsairK100(CorsairK100Controller* corsair_ptr)
{
corsair = corsair_ptr;
name = corsair->GetName();
vendor = "Corsair";
description = "Corsair K100 Keyboard Device";
type = DEVICE_TYPE_KEYBOARD;
version = corsair->GetFirmwareString();
location = corsair->GetDeviceLocation();
serial = corsair->GetSerialString();
logical_layout = corsair->GetKeyboardType();
mode Direct;
Direct.name = "Direct";
Direct.value = 0;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
SetupZones();
}
RGBController_CorsairK100::~RGBController_CorsairK100()
{
/*---------------------------------------------------------*\
| Delete the matrix map |
\*---------------------------------------------------------*/
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
{
if(zones[zone_index].type == ZONE_TYPE_MATRIX)
{
delete zones[zone_index].matrix_map;
}
}
delete corsair;
}
void RGBController_CorsairK100::SetupZones()
{
std::vector<led_zone_layout> selected_zone;
switch(logical_layout)
{
case CORSAIR_TYPE_K100:
selected_zone.push_back({"Keyboard", 119, ZONE_TYPE_MATRIX, led_names_k100, new matrix_map_type{7, 24, (unsigned int *)&matrix_map_k100}});
selected_zone.push_back({"Underglow", 44, ZONE_TYPE_LINEAR, led_names_lightbar});
selected_zone.push_back({"Nameplate", 9, ZONE_TYPE_LINEAR, led_names_nameplate});
selected_zone.push_back({"Logo", 3, ZONE_TYPE_LINEAR, led_names_logo});
break;
}
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < selected_zone.size(); zone_idx++)
{
zone new_zone;
new_zone.name = selected_zone[zone_idx].name;
new_zone.type = selected_zone[zone_idx].type;
new_zone.leds_min = selected_zone[zone_idx].size;
new_zone.leds_max = selected_zone[zone_idx].size;
new_zone.leds_count = selected_zone[zone_idx].size;
if (new_zone.type == ZONE_TYPE_MATRIX)
{
new_zone.matrix_map = selected_zone[zone_idx].matrix;
}
else
{
new_zone.matrix_map = NULL;
}
zones.push_back(new_zone);
for(unsigned int led_idx = 0; led_idx < selected_zone[zone_idx].size; led_idx++)
{
led new_led;
new_led.name = selected_zone[zone_idx].led_names[led_idx];
leds.push_back(new_led);
}
}
SetupColors();
}
void RGBController_CorsairK100::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_CorsairK100::DeviceUpdateLEDs()
{
corsair->SetLEDs(colors);
}
void RGBController_CorsairK100::UpdateZoneLEDs(int /*zone*/)
{
corsair->SetLEDs(colors);
}
void RGBController_CorsairK100::UpdateSingleLED(int /*led*/)
{
corsair->SetLEDs(colors);
}
void RGBController_CorsairK100::SetCustomMode()
{
active_mode = 0;
}
void RGBController_CorsairK100::DeviceUpdateMode()
{
}
@@ -0,0 +1,34 @@
/*-----------------------------------------*\
| RGBController_CorsairK100.cpp |
| |
| Driver for Corsair K100 Keyboard |
\*-----------------------------------------*/
#ifndef RGBCONTROLLER_CORSAIRK100_H
#define RGBCONTROLLER_CORSAIRK100_H
#include "RGBController.h"
#include "CorsairK100Controller.h"
class RGBController_CorsairK100 : public RGBController
{
public:
RGBController_CorsairK100(CorsairK100Controller* corsair_ptr);
~RGBController_CorsairK100();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
void SetCustomMode();
private:
CorsairK100Controller* corsair;
CorsairKeyboardType logical_layout;
};
#endif // RGBCONTROLLER_CORSAIRK100_H
@@ -20,6 +20,15 @@ static unsigned int matrix_map[6][23] =
{ 4, 111, 22, 32, 40, 50, NA, 59, NA, 68, 78, 88, 97, 106, 61, NA, NA, 81, NA, 73, 83, 92, 109 },
{ 5, 14, 23, NA, NA, NA, NA, 41, NA, NA, NA, NA, 69, 79, 89, 71, 90, 99, 108, 101, NA, 110, NA } };
static unsigned int matrix_map_k70_mk2[7][23] =
{ { NA, NA, NA, 115, 107, 8, NA, NA, NA, NA, NA, 113, 114, NA, NA, NA, NA, NA, NA, 16, NA, NA, NA,},
{ 0, NA, 10, 18, 28, 36, NA, 46, 55, 64, 74, NA, 84, 93, 102, 6, 15, 24, 33, 26, 35, 44, 53 },
{ 1, 11, 19, 29, 37, 47, 56, 65, 75, 85, 94, NA, 103, 7, 25, NA, 42, 51, 60, 62, 72, 82, 91 },
{ 2, NA, 12, 20, 30, 38, NA, 48, 57, 66, 76, 86, 95, 104, 70, 80, 34, 43, 52, 9, 17, 27, 100 },
{ 3, NA, 13, 21, 31, 39, NA, 49, 58, 67, 77, 87, 96, 105, 98, 112, NA, NA, NA, 45, 54, 63, NA },
{ 4, 111, 22, 32, 40, 50, NA, 59, NA, 68, 78, 88, 97, 106, 61, NA, NA, 81, NA, 73, 83, 92, 109 },
{ 5, 14, 23, NA, NA, NA, NA, 41, NA, NA, NA, NA, 69, 79, 89, 71, 90, 99, 108, 101, NA, 110, NA } };
static unsigned int matrix_map_k95_platinum[7][24] =
{ { NA, NA, NA, 119, 107, 8, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 16, NA, NA, NA,},
{ 113, 0, NA, 10, 18, 28, 36, NA, 46, 55, 64, 74, NA, 84, 93, 102, 6, 15, 24, 33, 26, 35, 44, 53 },
@@ -56,6 +65,24 @@ static const zone_type zone_types[] =
ZONE_TYPE_MATRIX,
};
/*---------------------------------------------------------*\
| K70 MK2 Corsair Layout |
\*---------------------------------------------------------*/
static const char* zone_names_k70_mk2[] =
{
"Keyboard",
};
static const unsigned int zone_sizes_k70_mk2[] =
{
116
};
static const zone_type zone_types_k70_mk2[] =
{
ZONE_TYPE_MATRIX,
};
/*---------------------------------------------------------*\
| K95 Platinum |
\*---------------------------------------------------------*/
@@ -236,6 +263,131 @@ static const char* led_names[] =
"Key: \\ (ISO)",
};
static const char* led_names_k70_mk2[] =
{
"Key: Escape", //0
"Key: `", //1
"Key: Tab", //2
"Key: Caps Lock", //3
"Key: Left Shift", //4
"Key: Left Control", //5
"Key: F12", //6
"Key: =", //7
"Key: Lock", //8
"Key: Number Pad 7", //9
"Key: F1", //12
"Key: 1", //13
"Key: Q", //14
"Key: A", //15
//"Key: / (ISO)", //16
"Key: Left Windows", //17
"Key: Print Screen", //18
"Key: Media Mute", //20
"Key: Number Pad 8", //21
"Key: F2", //24
"Key: 2", //25
"Key: W", //26
"Key: S", //27
"Key: Z", //28
"Key: Left Alt", //29
"Key: Scroll Lock", //30
"Key: Backspace", //31
"Key: Media Stop", //32
"Key: Number Pad 9", //33
"Key: F3", //36
"Key: 3", //37
"Key: E", //38
"Key: D", //39
"Key: X", //40
"Key: Pause/Break", //42
"Key: Delete", //43
"Key: Media Previous", //44
//"Key: Logo Left", //047
"Key: F4", //48
"Key: 4", //49
"Key: R", //50
"Key: F", //51
"Key: C", //52
"Key: Space", //53
"Key: Insert", //54
"Key: End", //55
"Key: Media Play/Pause",//56
"Key: Number Pad 4", //57
//"Key: Logo Right", //059
"Key: F5", //60
"Key: 5", //61
"Key: T", //62
"Key: G", //63
"Key: V", //64
"Key: Home", //66
"Key: Page Down", //67
"Key: Media Next", //68
"Key: Number Pad 5", //69
"Key: F6", //72
"Key: 6", //73
"Key: Y", //74
"Key: H", //75
"Key: B", //76
"Key: Page Up", //78
"Key: Right Shift", //79
"Key: Num Lock", //80
"Key: Number Pad 6", //81
"Key: F7", //84
"Key: 7", //85
"Key: U", //86
"Key: J", //87
"Key: N", //88
"Key: Right Alt", //89
"Key: ]", //90
"Key: Right Control", //91
"Key: Number Pad /", //92
"Key: Number Pad 1", //93
"Key: F8", //96
"Key: 8", //97
"Key: I", //98
"Key: K", //99
"Key: M", //100
"Key: Right Windows", //101
"Key: \\ (ANSI)", //102
"Key: Up Arrow", //103
"Key: Number Pad *", //104
"Key: Number Pad 2", //105
"Key: F9", //108
"Key: 9", //109
"Key: O", //110
"Key: L", //111
"Key: ,", //112
"Key: Menu", //113
//"Key: \\ (ISO)", //114
"Key: Left Arrow", //115
"Key: Number Pad -", //116
"Key: Number Pad 3", //117
"Key: F10", //120
"Key: 0", //121
"Key: P", //122
"Key: ;", //123
//"Key: Profile", //125
"Key: .", //124
"Key: Enter", //126
"Key: Down Arrow", //127
"Key: Number Pad +", //128
"Key: Number Pad 0", //129
"Key: F11", //132
"Key: -", //133
"Key: [", //134
"Key: '", //135
"Key: /", //136
"Key: Brightness", //137
"Key: Right Arrow", //139
"Key: Number Pad Enter",//140
"Key: Number Pad .", //141
"Key: / (ISO)", //16
"Key: \\ (ISO)", //114
"Key: Logo Left", //047
"Key: Logo Right", //059
"Key: Profile", //125
};
static const char* led_names_k95_plat[] =
{
"Key: Escape", //0
@@ -735,6 +887,26 @@ void RGBController_CorsairPeripheral::SetupZones()
new_zone.leds_count = zone_sizes_k55[zone_idx];
new_zone.matrix_map = NULL;
}
else if (logical_layout == CORSAIR_TYPE_K70_MK2)
{
new_zone.name = zone_names_k70_mk2[zone_idx];
new_zone.type = zone_types_k70_mk2[zone_idx];
new_zone.leds_min = zone_sizes_k70_mk2[zone_idx];
new_zone.leds_max = zone_sizes_k70_mk2[zone_idx];
new_zone.leds_count = zone_sizes_k70_mk2[zone_idx];
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
{
new_zone.matrix_map = new matrix_map_type;
new_zone.matrix_map->height = 7;
new_zone.matrix_map->width = 23;
new_zone.matrix_map->map = (unsigned int *)&matrix_map_k70_mk2;
}
else
{
new_zone.matrix_map = NULL;
}
}
else //default layout
{
new_zone.name = zone_names[zone_idx];
@@ -822,6 +994,10 @@ void RGBController_CorsairPeripheral::SetupZones()
{
new_led.name = led_names_k55[led_idx];
}
else if(logical_layout == CORSAIR_TYPE_K70_MK2)
{
new_led.name = led_names_k70_mk2[led_idx];
}
else
{
new_led.name = led_names[led_idx];
@@ -362,42 +362,32 @@ void RGBFusion2USBController::SetLEDEffect(unsigned int led, int mode, unsigned
pkt.e.effect_type = mode;
pkt.e.color0 = r << 16 | g << 8 | b;
if(speed < speeds.size())
{
const std::array<int, 3>& s = speeds[speed];
pkt.e.period0 = s[0];
pkt.e.period1 = s[1];
pkt.e.period2 = s[2];
}
pkt.e.max_brightness = brightness;
switch(mode)
{
case 0:
case 0: // Direct
case 1: // Static
break;
// Static
case 1:
break;
case 2: //Breathing
case 3: //Blink
case 4: // Color Cycle
if(speed < speeds.size())
{
const std::array<int, 3>& s = speeds[speed];
// Breathing
case 2:
pkt.e.period0 = s[0];
pkt.e.period1 = s[1];
pkt.e.period2 = s[2];
}
// Blink
case 3:
if(random)
{
pkt.e.effect_param0 = 7; // cycle through up to 7 (max?) colors
}
break;
// Color Cycle
case 4:
pkt.e.effect_param0 = 7; // cycle through up to 7 (max?) colors
break;
// "Fake" effects
case 10: // flashing, flashing color cycle
pkt.e.period0 = 200;
@@ -175,7 +175,7 @@ union PktEffect
e.max_brightness = 100;
e.min_brightness = 0;
e.color0 = 0x00FF2100; //orange
e.period0 = 1200;
e.period0 = 0; //Rising Timer - Needs to be 0 for "Direct"
e.period1 = 1200;
e.period2 = 200;
e.period3 = 200;
@@ -533,8 +533,8 @@ void RGBController_RGBFusion2USB::UpdateZoneLEDs(int zone)
/*---------------------------------------------------------*\
| Get mode parameters |
\*---------------------------------------------------------*/
bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
int mode_value = (modes[active_mode].value);
bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM || mode_value == EFFECT_COLORCYCLE);
/*---------------------------------------------------------*\
| Set motherboard LEDs |
@@ -50,6 +50,7 @@ static const gpu_pci_device device_list[] =
{ NVIDIA_VEN, NVIDIA_RTX3060_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX3060_GAMING_OC_12GB_SUB_DEV, 0x62, "Gigabyte RTX3060 Gaming OC 12G" },
{ NVIDIA_VEN, NVIDIA_RTX3060_V2_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX3060_GAMING_OC_12GB_SUB_DEV, 0x62, "Gigabyte RTX3060 Gaming OC 12G" },
{ NVIDIA_VEN, NVIDIA_RTX3060TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX3060TI_EAGLE_OC_SUB_DEV, 0x63, "Gigabyte RTX3060 Ti EAGLE OC 8G" },
{ NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX3060TI_EAGLE_OC_SUB_DEV, 0x63, "Gigabyte RTX3060 Ti EAGLE OC 8G V2.0 LHR" },
{ NVIDIA_VEN, NVIDIA_RTX3060TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX3060TI_GAMING_OC_SUB_DEV, 0x62, "Gigabyte RTX3060 Ti Gaming OC 8G" },
{ NVIDIA_VEN, NVIDIA_RTX3070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX3070_GAMING_OC_SUB_DEV, 0x62, "Gigabyte RTX3070 Gaming OC 8G" },
{ NVIDIA_VEN, NVIDIA_RTX3070_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX3070_VISION_OC_SUB_DEV, 0x63, "Gigabyte RTX3070 Vision 8G" },
@@ -4,6 +4,7 @@
#include "HyperXPulsefireDartController.h"
#include "RGBController.h"
#include "RGBController_HyperXPulsefireFPSPro.h"
#include "RGBController_HyperXPulsefireHaste.h"
#include "RGBController_HyperXPulsefireSurge.h"
#include "RGBController_HyperXPulsefireDart.h"
#include <hidapi/hidapi.h>
@@ -14,8 +15,10 @@
#define HYPERX_VID 0x0951
#define HYPERX_PULSEFIRE_SURGE_PID 0x16D3
#define HYPERX_PULSEFIRE_FPS_PRO_PID 0x16D7
#define HYPERX_PULSEFIRE_CORE_PID 0x16DE
#define HYPERX_PULSEFIRE_DART_WIRELESS_PID 0x16E1
#define HYPERX_PULSEFIRE_DART_WIRED_PID 0x16E2
#define HYPERX_PULSEFIRE_HASTE_PID 0x1727
void DetectHyperXPulsefireSurgeControllers(hid_device_info* info, const std::string& name)
{
@@ -41,6 +44,19 @@ void DetectHyperXPulsefireFPSProControllers(hid_device_info* info, const std::st
}
} /* DetectHyperXPulsefireFPSProControllers() */
void DetectHyperXPulsefireHasteControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if( dev )
{
printf( "pulsefire haste usage %X, usage page %X\r\n", info->usage, info->usage_page);
HyperXPulsefireHasteController* controller = new HyperXPulsefireHasteController(dev, info->path);
RGBController_HyperXPulsefireHaste* rgb_controller = new RGBController_HyperXPulsefireHaste(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
} /* DetectHyperXPulsefireFPSProControllers() */
void DetectHyperXPulsefireDartControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
@@ -53,7 +69,14 @@ void DetectHyperXPulsefireDartControllers(hid_device_info* info, const std::stri
}
} /* DetectHyperXPulsefireDartControllers() */
REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Surge", DetectHyperXPulsefireSurgeControllers, HYPERX_VID, HYPERX_PULSEFIRE_SURGE_PID, 1, 0xFF01);
REGISTER_HID_DETECTOR_IP("HyperX Pulsefire FPS Pro", DetectHyperXPulsefireFPSProControllers, HYPERX_VID, HYPERX_PULSEFIRE_FPS_PRO_PID, 1, 0xFF01);
REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Dart (Wireless)", DetectHyperXPulsefireDartControllers, HYPERX_VID, HYPERX_PULSEFIRE_DART_WIRELESS_PID, 2, 0xFF00);
REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Dart (Wired)", DetectHyperXPulsefireDartControllers, HYPERX_VID, HYPERX_PULSEFIRE_DART_WIRED_PID, 1, 0xFF13);
REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Surge", DetectHyperXPulsefireSurgeControllers, HYPERX_VID, HYPERX_PULSEFIRE_SURGE_PID, 1, 0xFF01);
REGISTER_HID_DETECTOR_IP("HyperX Pulsefire FPS Pro", DetectHyperXPulsefireFPSProControllers, HYPERX_VID, HYPERX_PULSEFIRE_FPS_PRO_PID, 1, 0xFF01);
REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Core", DetectHyperXPulsefireFPSProControllers, HYPERX_VID, HYPERX_PULSEFIRE_CORE_PID, 1, 0xFF01);
REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Dart (Wireless)", DetectHyperXPulsefireDartControllers, HYPERX_VID, HYPERX_PULSEFIRE_DART_WIRELESS_PID, 2, 0xFF00);
REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Dart (Wired)", DetectHyperXPulsefireDartControllers, HYPERX_VID, HYPERX_PULSEFIRE_DART_WIRED_PID, 1, 0xFF13);
#ifdef _WIN32
REGISTER_HID_DETECTOR_IP("HyperX Pulsefire Haste", DetectHyperXPulsefireHasteControllers, HYPERX_VID, HYPERX_PULSEFIRE_HASTE_PID, 3, 0xFF90);
#else
REGISTER_HID_DETECTOR_PU("HyperX Pulsefire Haste", DetectHyperXPulsefireHasteControllers, HYPERX_VID, HYPERX_PULSEFIRE_HASTE_PID, 1, 2);
#endif
@@ -0,0 +1,111 @@
/*-----------------------------------------*\
| HyperXPulsefireHasteController.cpp |
| |
| Driver for HyperX Pulsefire Haste |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 8/19/2021 |
\*-----------------------------------------*/
#include "HyperXPulsefireHasteController.h"
#include <cstring>
HyperXPulsefireHasteController::HyperXPulsefireHasteController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
HyperXPulsefireHasteController::~HyperXPulsefireHasteController()
{
hid_close(dev);
}
std::string HyperXPulsefireHasteController::GetDeviceLocation()
{
return("HID " + location);
}
std::string HyperXPulsefireHasteController::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void HyperXPulsefireHasteController::SendDirect
(
RGBColor* color_data
)
{
SendDirectSetup();
SendDirectColor(color_data);
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void HyperXPulsefireHasteController::SendDirectSetup()
{
unsigned char buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Direct Mode Setup packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x00;
buf[0x01] = HYPERX_PULSEFIRE_HASTE_PACKET_ID_SETUP;
buf[0x02] = 0xF2;
buf[0x08] = 0x02;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 65);
}
void HyperXPulsefireHasteController::SendDirectColor
(
RGBColor* color_data
)
{
unsigned char buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(buf, 0x00, sizeof(buf));
/*-----------------------------------------------------*\
| Set up Direct Mode packet |
\*-----------------------------------------------------*/
buf[0x00] = 0x00;
buf[0x01] = HYPERX_PULSEFIRE_HASTE_PACKET_ID_COLOR;
buf[0x02] = RGBGetRValue(color_data[0]);
buf[0x03] = RGBGetGValue(color_data[0]);
buf[0x04] = RGBGetBValue(color_data[0]);
buf[0x08] = 0x02;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_send_feature_report(dev, buf, 65);
}
@@ -0,0 +1,46 @@
/*-----------------------------------------*\
| HyperXPulsefireHasteController.h |
| |
| Definitions and types for HyperX |
| Pulsefire FPS Pro lighting controller |
| |
| Adam Honse (CalcProgrammer1) 8/19/2021 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
HYPERX_PULSEFIRE_HASTE_PACKET_ID_SETUP = 0x04, /* Direct setup packet */
HYPERX_PULSEFIRE_HASTE_PACKET_ID_COLOR = 0x81, /* Direct color packet */
};
class HyperXPulsefireHasteController
{
public:
HyperXPulsefireHasteController(hid_device* dev_handle, const char* path);
~HyperXPulsefireHasteController();
std::string GetDeviceLocation();
std::string GetSerialString();
void SendDirect
(
RGBColor* color_data
);
private:
hid_device* dev;
std::string location;
void SendDirectSetup();
void SendDirectColor
(
RGBColor* color_data
);
};
@@ -0,0 +1,139 @@
/*-----------------------------------------*\
| RGBController_HyperXPulsefireHaste.cpp |
| |
| Generic RGB Interface for HyperX |
| Pulsefire Haste |
| |
| Adam Honse (CalcProgrammer1) 8/19/2021 |
\*-----------------------------------------*/
#include "RGBController_HyperXPulsefireHaste.h"
using namespace std::chrono_literals;
RGBController_HyperXPulsefireHaste::RGBController_HyperXPulsefireHaste(HyperXPulsefireHasteController* hyperx_ptr)
{
hyperx = hyperx_ptr;
name = "HyperX Pulsefire Haste Device";
vendor = "HyperX";
type = DEVICE_TYPE_MOUSE;
description = "HyperX Pulsefire Haste Device";
location = hyperx->GetDeviceLocation();
serial = hyperx->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = 0xFFFF;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
SetupZones();
/*-----------------------------------------------------*\
| The Corsair Lighting Node Pro requires a packet within|
| 20 seconds of sending the lighting change in order |
| to not revert back into rainbow mode. Start a thread |
| to continuously send a keepalive packet every 5s |
\*-----------------------------------------------------*/
keepalive_thread_run = 1;
keepalive_thread = new std::thread(&RGBController_HyperXPulsefireHaste::KeepaliveThread, this);
};
RGBController_HyperXPulsefireHaste::~RGBController_HyperXPulsefireHaste()
{
keepalive_thread_run = 0;
keepalive_thread->join();
delete keepalive_thread;
delete hyperx;
}
void RGBController_HyperXPulsefireHaste::SetupZones()
{
zone logo;
logo.name = "Logo";
logo.type = ZONE_TYPE_SINGLE;
logo.leds_min = 1;
logo.leds_max = 1;
logo.leds_count = 1;
logo.matrix_map = NULL;
zones.push_back(logo);
for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
for(unsigned int led_idx = 0; led_idx < zones[zone_idx].leds_count; led_idx++)
{
led new_led;
new_led.name = zones[zone_idx].name;
if(zones[zone_idx].leds_count > 1)
{
new_led.name.append(" LED ");
new_led.name.append(std::to_string(led_idx + 1));
}
leds.push_back(new_led);
}
}
SetupColors();
}
void RGBController_HyperXPulsefireHaste::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_HyperXPulsefireHaste::DeviceUpdateLEDs()
{
last_update_time = std::chrono::steady_clock::now();
if(active_mode == 0)
{
hyperx->SendDirect(&colors[0]);
}
else
{
}
}
void RGBController_HyperXPulsefireHaste::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_HyperXPulsefireHaste::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_HyperXPulsefireHaste::SetCustomMode()
{
active_mode = 0;
}
void RGBController_HyperXPulsefireHaste::DeviceUpdateMode()
{
DeviceUpdateLEDs();
}
void RGBController_HyperXPulsefireHaste::KeepaliveThread()
{
while(keepalive_thread_run.load())
{
if(active_mode == 0)
{
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(50))
{
UpdateLEDs();
}
}
std::this_thread::sleep_for(10ms);
}
}
@@ -0,0 +1,40 @@
/*-----------------------------------------*\
| RGBController_HyperXPulsefireHaste.h |
| |
| Generic RGB Interface for HyperX |
| Pulsefire Haste |
| |
| Adam Honse (CalcProgrammer1) 8/19/2021 |
\*-----------------------------------------*/
#pragma once
#include <chrono>
#include "RGBController.h"
#include "HyperXPulsefireHasteController.h"
class RGBController_HyperXPulsefireHaste : public RGBController
{
public:
RGBController_HyperXPulsefireHaste(HyperXPulsefireHasteController* hyperx_ptr);
~RGBController_HyperXPulsefireHaste();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
void KeepaliveThread();
private:
HyperXPulsefireHasteController* hyperx;
std::thread* keepalive_thread;
std::atomic<bool> keepalive_thread_run;
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
};
@@ -8,6 +8,7 @@
#include "LogitechG810Controller.h"
#include "LogitechG910Controller.h"
#include "LogitechG815Controller.h"
#include "LogitechG915Controller.h"
#include "LogitechGLightsyncController.h"
#include "LogitechLightspeedController.h"
#include "LogitechX56Controller.h"
@@ -19,6 +20,7 @@
#include "RGBController_LogitechG810.h"
#include "RGBController_LogitechG910.h"
#include "RGBController_LogitechG815.h"
#include "RGBController_LogitechG915.h"
#include "RGBController_LogitechGLightsync.h"
#include "RGBController_LogitechGLightsync1zone.h"
#include "RGBController_LogitechLightspeed.h"
@@ -49,6 +51,8 @@ using namespace std::chrono_literals;
#define LOGITECH_G810_2_PID 0xC337
#define LOGITECH_G813_PID 0xC232
#define LOGITECH_G815_PID 0xC33F
#define LOGITECH_G915_WIRED_PID 0xC33E
#define LOGITECH_G915_RECEIVER_PID 0xC541
#define LOGITECH_G910_ORION_SPARK_PID 0xC32B
#define LOGITECH_G910_PID 0xC335
@@ -314,6 +318,32 @@ void DetectLogitechKeyboardG815(hid_device_info* info, const std::string& name)
#endif
}
void DetectLogitechKeyboardG915(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LogitechG915Controller* controller = new LogitechG915Controller(dev, false);
RGBController_LogitechG915* rgb_controller = new RGBController_LogitechG915(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectLogitechKeyboardG915Wired(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LogitechG915Controller* controller = new LogitechG915Controller(dev, true);
RGBController_LogitechG915* rgb_controller = new RGBController_LogitechG915(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
/*-----------------------------------------------------*\
| Logitech Mice |
\*-----------------------------------------------------*/
@@ -525,44 +555,46 @@ void DetectLogitechX56(hid_device_info* info, const std::string& name)
}
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Logitech G213", DetectLogitechKeyboardG213, LOGITECH_VID, LOGITECH_G213_PID, 1, 0xFF43, 0x0602);
REGISTER_HID_DETECTOR_IP ("Logitech G512", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G512_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G512 RGB", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G512_RGB_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G610 Orion", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G610_1_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G610 Orion", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G610_2_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G810 Orion Spectrum", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G810_1_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G810 Orion Spectrum", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G810_2_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G813 RGB Mechanical Gaming Keyboard", DetectLogitechKeyboardG815, LOGITECH_VID, LOGITECH_G813_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G815 RGB Mechanical Gaming Keyboard", DetectLogitechKeyboardG815, LOGITECH_VID, LOGITECH_G815_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G910 Orion Spark", DetectLogitechKeyboardG910, LOGITECH_VID, LOGITECH_G910_ORION_SPARK_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G910 Orion Spectrum", DetectLogitechKeyboardG910, LOGITECH_VID, LOGITECH_G910_PID, 1, 0xFF43);
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Mice |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP ("Logitech G203 Prodigy", DetectLogitechMouseG203, LOGITECH_VID, LOGITECH_G203_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IPU("Logitech G203 Lightsync", DetectLogitechMouseG203L, LOGITECH_VID, LOGITECH_G203_LIGHTSYNC_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IP ("Logitech G303 Daedalus Apex", DetectLogitechMouseG303, LOGITECH_VID, LOGITECH_G303_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP ("Logitech G403 Hero", DetectLogitechMouseG403, LOGITECH_VID, LOGITECH_G403_HERO_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP ("Logitech G502 Proteus Spectrum Gaming Mouse", DetectLogitechMouseG502PS, LOGITECH_VID, LOGITECH_G502_PROTEUS_SPECTRUM_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP ("Logitech G502 Hero Gaming Mouse", DetectLogitechMouseG502PS, LOGITECH_VID, LOGITECH_G502_HERO_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP ("Logitech G Pro Gaming Mouse", DetectLogitechMouseGPRO, LOGITECH_VID, LOGITECH_G_PRO_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP ("Logitech G Pro (HERO) Gaming Mouse", DetectLogitechMouseGPRO, LOGITECH_VID, LOGITECH_G_PRO_HERO_PID, 1, 0xFF00);
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Speakers |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Logitech G560 Lightsync Speaker", DetectLogitechG560, LOGITECH_VID, LOGITECH_G560_PID, 2, 0xFF43, 514);
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Headsets |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Logitech G933 Lightsync Headset", DetectLogitechG933, LOGITECH_VID, LOGITECH_G933_PID, 3, 0xFF43, 514);
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Joysticks |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("Logitech X56 Rhino Hotas Joystick", DetectLogitechX56, LOGITECH_X56_VID, LOGITECH_X56_JOYSTICK_PID, 2, 0xFF00);
REGISTER_HID_DETECTOR_IP("Logitech X56 Rhino Hotas Throttle", DetectLogitechX56, LOGITECH_X56_VID, LOGITECH_X56_THROTTLE_PID, 2, 0xFF00);
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Logitech G213", DetectLogitechKeyboardG213, LOGITECH_VID, LOGITECH_G213_PID, 1, 0xFF43, 0x0602);
REGISTER_HID_DETECTOR_IP ("Logitech G512", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G512_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G512 RGB", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G512_RGB_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G610 Orion", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G610_1_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G610 Orion", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G610_2_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G810 Orion Spectrum", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G810_1_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G810 Orion Spectrum", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G810_2_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G813 RGB Mechanical Gaming Keyboard", DetectLogitechKeyboardG815, LOGITECH_VID, LOGITECH_G813_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G815 RGB Mechanical Gaming Keyboard", DetectLogitechKeyboardG815, LOGITECH_VID, LOGITECH_G815_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G910 Orion Spark", DetectLogitechKeyboardG910, LOGITECH_VID, LOGITECH_G910_ORION_SPARK_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G910 Orion Spectrum", DetectLogitechKeyboardG910, LOGITECH_VID, LOGITECH_G910_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IPU("Logitech G915 Wireless RGB Mechanical Gaming Keyboard", DetectLogitechKeyboardG915, LOGITECH_VID, LOGITECH_G915_RECEIVER_PID, 2, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G915 Wireless RGB Mechanical Gaming Keyboard (Wired)", DetectLogitechKeyboardG915Wired, LOGITECH_VID, LOGITECH_G915_WIRED_PID, 2, 0xFF00, 2);
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*\
| Mice |
\*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP ("Logitech G203 Prodigy", DetectLogitechMouseG203, LOGITECH_VID, LOGITECH_G203_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IPU("Logitech G203 Lightsync", DetectLogitechMouseG203L, LOGITECH_VID, LOGITECH_G203_LIGHTSYNC_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IP ("Logitech G303 Daedalus Apex", DetectLogitechMouseG303, LOGITECH_VID, LOGITECH_G303_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP ("Logitech G403 Hero", DetectLogitechMouseG403, LOGITECH_VID, LOGITECH_G403_HERO_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP ("Logitech G502 Proteus Spectrum Gaming Mouse", DetectLogitechMouseG502PS, LOGITECH_VID, LOGITECH_G502_PROTEUS_SPECTRUM_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP ("Logitech G502 Hero Gaming Mouse", DetectLogitechMouseG502PS, LOGITECH_VID, LOGITECH_G502_HERO_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP ("Logitech G Pro Gaming Mouse", DetectLogitechMouseGPRO, LOGITECH_VID, LOGITECH_G_PRO_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP ("Logitech G Pro (HERO) Gaming Mouse", DetectLogitechMouseGPRO, LOGITECH_VID, LOGITECH_G_PRO_HERO_PID, 1, 0xFF00);
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*\
| Speakers |
\*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Logitech G560 Lightsync Speaker", DetectLogitechG560, LOGITECH_VID, LOGITECH_G560_PID, 2, 0xFF43, 514);
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*\
| Headsets |
\*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Logitech G933 Lightsync Headset", DetectLogitechG933, LOGITECH_VID, LOGITECH_G933_PID, 3, 0xFF43, 514);
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*\
| Joysticks |
\*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("Logitech X56 Rhino Hotas Joystick", DetectLogitechX56, LOGITECH_X56_VID, LOGITECH_X56_JOYSTICK_PID, 2, 0xFF00);
REGISTER_HID_DETECTOR_IP("Logitech X56 Rhino Hotas Throttle", DetectLogitechX56, LOGITECH_X56_VID, LOGITECH_X56_THROTTLE_PID, 2, 0xFF00);
/*---------------------------------------------------------------------------------------------------------*\
| Windows and MacOS Lightspeed Detection |
@@ -0,0 +1,320 @@
/*-----------------------------------------*\
| LogitechG915Controller.cpp |
| |
| Generic RGB Interface for Logitech G915 |
| RGB Mechanical Gaming Keyboard |
| |
| Cheerpipe 3/20/2021 |
\*-----------------------------------------*/
#include "LogitechG915Controller.h"
#include <cstring>
LogitechG915Controller::LogitechG915Controller(hid_device* dev_handle, bool wired)
{
this->dev_handle = dev_handle;
if(wired)
{
feature_4522_idx = 0x0E;
feature_8040_idx = 0x13;
feature_8071_idx = 0x09;
feature_8081_idx = 0x0A;
}
else
{
feature_4522_idx = 0x0F;
feature_8040_idx = 0x14;
feature_8071_idx = 0x0A;
feature_8081_idx = 0x0B;
}
}
LogitechG915Controller::~LogitechG915Controller()
{
}
std::string LogitechG915Controller::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev_handle, serial_string, 128);
if(ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void LogitechG915Controller::Commit()
{
SendCommit();
}
void LogitechG915Controller::SetDirect
(
unsigned char frame_type,
unsigned char * frame_data
)
{
SendDirectFrame(frame_type, frame_data);
}
void LogitechG915Controller::SetMode
(
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
SendMode(LOGITECH_G915_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
SendMode(LOGITECH_G915_ZONE_MODE_LOGO, mode, speed, red, green, blue);
SendCommit();
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void LogitechG915Controller::SendCommit()
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x02] = feature_8081_idx;
usb_buf[0x03] = LOGITECH_G915_COMMIT_BYTE;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_handle, (unsigned char *)usb_buf, 20);
hid_read_timeout(dev_handle, (unsigned char *)usb_buf, 20, LOGITECH_READ_TIMEOUT);
}
void LogitechG915Controller::InitializeDirect()
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x02] = feature_4522_idx;
usb_buf[0x03] = 0x3E;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_handle, (unsigned char *)usb_buf, 20);
hid_read(dev_handle, (unsigned char *)usb_buf, 20);
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x02] = feature_4522_idx;
usb_buf[0x03] = 0x1E;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_handle, (unsigned char *)usb_buf, 20);
hid_read(dev_handle, (unsigned char *)usb_buf, 20);
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x02] = feature_8071_idx;
usb_buf[0x03] = 0x1E;
usb_buf[0x10] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_handle, (unsigned char *)usb_buf, 20);
hid_read(dev_handle, (unsigned char *)usb_buf, 20);
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x02] = feature_8071_idx;
usb_buf[0x03] = 0x1E;
usb_buf[0x04] = 0x01;
usb_buf[0x10] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_handle, (unsigned char *)usb_buf, 20);
hid_read(dev_handle, (unsigned char *)usb_buf, 20);
}
void LogitechG915Controller::SendSingleLed
(
unsigned char keyCode,
unsigned char r,
unsigned char g,
unsigned char b
)
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up a 6F packet with a single color |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x02] = feature_8081_idx;
usb_buf[0x03] = LOGITECH_G915_ZONE_FRAME_TYPE_LITTLE;
usb_buf[0x04] = keyCode;
usb_buf[0x05] = r;
usb_buf[0x06] = g;
usb_buf[0x07] = b;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_handle, (unsigned char *)usb_buf, 20);
hid_read(dev_handle, (unsigned char *)usb_buf, 20);
}
void LogitechG915Controller::SendDirectFrame
(
unsigned char frame_type,
unsigned char * frame_data
)
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x02] = feature_8081_idx;
usb_buf[0x03] = frame_type;
/*-----------------------------------------------------*\
| Copy in frame data |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x04], frame_data, 16);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_handle, (unsigned char *)usb_buf, 20);
hid_read_timeout(dev_handle, (unsigned char *)usb_buf, 20, LOGITECH_READ_TIMEOUT);
}
void LogitechG915Controller::SendMode
(
unsigned char zone,
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x02] = feature_8040_idx;
usb_buf[0x03] = 0x3D; //TODO: Check if it is the correct value for G915
usb_buf[0x04] = zone;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 100 * speed;
if(mode == LOGITECH_G915_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = 0x64;
}
else if(mode == LOGITECH_G915_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = 0x64;
}
else
{
return;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_handle, (unsigned char *)usb_buf, 20);
hid_read(dev_handle, (unsigned char *)usb_buf, 20);
}
@@ -0,0 +1,117 @@
/*-----------------------------------------*\
| LogitechG915Controller.h |
| |
| Generic RGB Interface for Logitech G915 |
| RGB Mechanical Gaming Keyboard |
| |
| Cheerpipe 3/20/2021 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#define LOGITECH_G915_COMMIT_BYTE 0x7F
#define LOGITECH_READ_TIMEOUT 300 //Timeout in ms
#pragma once
enum
{
LOGITECH_G915_ZONE_MODE_KEYBOARD = 0x00,
LOGITECH_G915_ZONE_MODE_LOGO = 0x01,
LOGITECH_G915_ZONE_MODE_MULTIMEDIA = 0X02,
LOGITECH_G915_ZONE_MODE_GKEYS = 0x03,
LOGITECH_G915_ZONE_MODE_MODIFIERS = 0x04
};
enum
{
LOGITECH_G915_ZONE_FRAME_TYPE_LITTLE = 0x1F,
LOGITECH_G915_ZONE_FRAME_TYPE_BIG = 0x6F
};
enum
{
LOGITECH_G915_ZONE_DIRECT_KEYBOARD = 0x01,
LOGITECH_G915_ZONE_DIRECT_MEDIA = 0x02,
LOGITECH_G915_ZONE_DIRECT_LOGO = 0x10,
LOGITECH_G915_ZONE_DIRECT_INDICATORS = 0x40,
};
enum
{
LOGITECH_G915_MODE_OFF = 0x00,
LOGITECH_G915_MODE_STATIC = 0x01,
LOGITECH_G915_MODE_BREATHING = 0x02,
LOGITECH_G915_MODE_CYCLE = 0x03,
LOGITECH_G915_MODE_WAVE = 0x04,
LOGITECH_G915_MODE_DIRECT = 0x05,
};
/*---------------------------------------------------------------------------------------------*\
| Speed is 1000 for fast and 20000 for slow. |
| Values are multiplied by 100 later to give lots of GUI steps. |
\*---------------------------------------------------------------------------------------------*/
enum
{
LOGITECH_G915_SPEED_SLOWEST = 0xC8, /* Slowest speed */
LOGITECH_G915_SPEED_NORMAL = 0x32, /* Normal speed */
LOGITECH_G915_SPEED_FASTEST = 0x0A, /* Fastest speed */
};
class LogitechG915Controller
{
public:
LogitechG915Controller(hid_device* dev_handle, bool wired);
~LogitechG915Controller();
std::string GetSerialString();
void Commit();
void InitializeDirect();
void SetDirect
(
unsigned char frame_type,
unsigned char * frame_data
);
void SendSingleLed
(
unsigned char keyCode,
unsigned char r,
unsigned char g,
unsigned char b
);
void SetMode
(
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
hid_device* dev_handle;
char feature_4522_idx;
char feature_8040_idx;
char feature_8071_idx;
char feature_8081_idx;
void SendDirectFrame
(
unsigned char frame_type,
unsigned char * frame_data
);
void SendMode
(
unsigned char zone,
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
void SendCommit();
};
@@ -0,0 +1,526 @@
/*-----------------------------------------*\
| RGBController_LogitechG915.cpp |
| |
| Generic RGB Interface for Logitech G915 |
| RGB Mechanical Gaming Keyboard |
| |
| Cheerpipe 3/20/2021 |
\*-----------------------------------------*/
#include "RGBController_LogitechG915.h"
#include <cstring>
#include <iterator>
#include <map>
#define NA 0xFFFFFFFF
const size_t max_key_per_color = 13;
const size_t data_size = 16;
static unsigned int matrix_map[7][27] =
{ { 110, NA, NA, NA, NA, NA, NA, NA, NA, NA, 111, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA },
{ NA, NA, 37, NA, 54, 55, 56, 57, NA, 58, 59, 60, 61, NA, 62, 63, 64, 65, NA, 66, 67, 68, NA, 106, 107, 108, 109 },
{ 112, NA, 49, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, NA, 41, 42, 38, NA, NA, 69, 70, 71, NA, 79, 80, 81, 82 },
{ 113, NA, 39, NA, 16, 22, 4, 17, NA, 19, 24, 20, 8, 14, 15, 43, 44, 45, NA, 72, 73, 74, NA, 91, 92, 93, 83 },
{ 114, NA, 53, NA, 0, 18, 3, 5, NA, 6, 7, 9, 10, 11, 47, 48, 46, 36, NA, NA, NA, NA, NA, 88, 89, 90, NA },
{ 115, NA, 99, NA, 25, 23, 2, 21, NA, 1, NA, 13, 12, 50, 51, 52, 103, NA, NA, NA, 78, NA, NA, 85, 86, 87, 84 },
{ 116, NA, 98, 101, 100, NA, NA, NA, NA, 40, NA, NA, NA, NA, 104, 105, 97, 102, NA, 76, 77, 75, NA, 94, NA, 95, NA } };
static const char* zone_names[] =
{
"Keyboard",
};
static zone_type zone_types[] =
{
ZONE_TYPE_MATRIX,
};
static const unsigned int zone_sizes[] =
{
117,
};
typedef struct
{
const char * name;
const unsigned char zone;
const unsigned char idx;
} led_type;
static const led_type led_names[] =
{
/* Key Label Zone, Index */
{ "Key: A", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x04 },
{ "Key: B", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x05 },
{ "Key: C", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x06 },
{ "Key: D", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x07 },
{ "Key: E", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x08 },
{ "Key: F", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x09 },
{ "Key: G", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x0A },
{ "Key: H", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x0B },
{ "Key: I", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x0C },
{ "Key: J", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x0D },
{ "Key: K", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x0E },
{ "Key: L", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x0F },
{ "Key: M", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x10 },
{ "Key: N", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x11 },
{ "Key: O", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x12 },
{ "Key: P", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x13 },
{ "Key: Q", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x14 },
{ "Key: R", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x15 },
{ "Key: S", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x16 },
{ "Key: T", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x17 },
{ "Key: U", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x18 },
{ "Key: V", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x19 },
{ "Key: W", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x1A },
{ "Key: X", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x1B },
{ "Key: Y", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x1C },
{ "Key: Z", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x1D },
{ "Key: 1", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x1E },
{ "Key: 2", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x1F },
{ "Key: 3", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x20 },
{ "Key: 4", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x21 },
{ "Key: 5", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x22 },
{ "Key: 6", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x23 },
{ "Key: 7", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x24 },
{ "Key: 8", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x25 },
{ "Key: 9", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x26 },
{ "Key: 0", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x27 },
{ "Key: Enter", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x28 },
{ "Key: Escape", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x29 },
{ "Key: Backspace", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x2A },
{ "Key: Tab", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x2B },
{ "Key: Space", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x2C },
{ "Key: -", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x2D },
{ "Key: =", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x2E },
{ "Key: [", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x2F },
{ "Key: ]", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x30 },
{ "Key: \\ (ANSI)", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x31 },//ANSI only
{ "Key: #", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x32 },//ISO only
{ "Key: ;", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x33 },
{ "Key: '", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x34 },
{ "Key: `", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x35 },
{ "Key: ,", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x36 },
{ "Key: .", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x37 },
{ "Key: /", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x38 },
{ "Key: Caps Lock", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x39 },
{ "Key: F1", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x3A },
{ "Key: F2", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x3B },
{ "Key: F3", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x3C },
{ "Key: F4", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x3D },
{ "Key: F5", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x3E },
{ "Key: F6", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x3F },
{ "Key: F7", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x40 },
{ "Key: F8", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x41 },
{ "Key: F9", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x42 },
{ "Key: F10", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x43 },
{ "Key: F11", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x44 },
{ "Key: F12", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x45 },
{ "Key: Print Screen", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x46 },
{ "Key: Scroll Lock", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x47 },
{ "Key: Pause/Break", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x48 },
{ "Key: Insert", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x49 },
{ "Key: Home", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x4A },
{ "Key: Page Up", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x4B },
{ "Key: Delete", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x4C },
{ "Key: End", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x4D },
{ "Key: Page Down", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x4E },
{ "Key: Right Arrow", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x4F },
{ "Key: Left Arrow", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x50 },
{ "Key: Down Arrow", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x51 },
{ "Key: Up Arrow", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x52 },
{ "Key: Num Lock", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x53 },
{ "Key: Number Pad /", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x54 },
{ "Key: Number Pad *", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x55 },
{ "Key: Number Pad -", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x56 },
{ "Key: Number Pad +", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x57 },
{ "Key: Number Pad Enter", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x58 },
{ "Key: Number Pad 1", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x59 },
{ "Key: Number Pad 2", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x5A },
{ "Key: Number Pad 3", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x5B },
{ "Key: Number Pad 4", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x5C },
{ "Key: Number Pad 5", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x5D },
{ "Key: Number Pad 6", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x5E },
{ "Key: Number Pad 7", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x5F },
{ "Key: Number Pad 8", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x60 },
{ "Key: Number Pad 9", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x61 },
{ "Key: Number Pad 0", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x62 },
{ "Key: Number Pad .", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x63 },
{ "Key: \\ (ISO)", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x64 },//ISO only
{ "Key: Menu", LOGITECH_G915_ZONE_DIRECT_KEYBOARD, 0x65 },
{ "Key: Left Control", LOGITECH_G915_ZONE_MODE_MODIFIERS, 0xE0 },
{ "Key: Left Shift", LOGITECH_G915_ZONE_MODE_MODIFIERS, 0xE1 },
{ "Key: Left Alt", LOGITECH_G915_ZONE_MODE_MODIFIERS, 0xE2 },
{ "Key: Left Windows", LOGITECH_G915_ZONE_MODE_MODIFIERS, 0xE3 },
{ "Key: Right Control", LOGITECH_G915_ZONE_MODE_MODIFIERS, 0xE4 },
{ "Key: Right Shift", LOGITECH_G915_ZONE_MODE_MODIFIERS, 0xE5 },
{ "Key: Right Alt", LOGITECH_G915_ZONE_MODE_MODIFIERS, 0xE6 },
{ "Key: Right Windows", LOGITECH_G915_ZONE_MODE_MODIFIERS, 0xE7 },
{ "Key: Media Previous", LOGITECH_G915_ZONE_DIRECT_MEDIA, 0x9E },
{ "Key: Media Play/Pause", LOGITECH_G915_ZONE_DIRECT_MEDIA, 0x9B },
{ "Key: Media Next", LOGITECH_G915_ZONE_DIRECT_MEDIA, 0x9D },
{ "Key: Media Mute", LOGITECH_G915_ZONE_DIRECT_MEDIA, 0x9C },
{ "Logo", LOGITECH_G915_ZONE_DIRECT_LOGO, 0x01 },
{ "Lighting", LOGITECH_G915_ZONE_DIRECT_INDICATORS, 0x99 },
{ "Key: G1", LOGITECH_G915_ZONE_MODE_GKEYS, 0x01 },
{ "Key: G2", LOGITECH_G915_ZONE_MODE_GKEYS, 0x02 },
{ "Key: G3", LOGITECH_G915_ZONE_MODE_GKEYS, 0x03 },
{ "Key: G4", LOGITECH_G915_ZONE_MODE_GKEYS, 0x04 },
{ "Key: G5", LOGITECH_G915_ZONE_MODE_GKEYS, 0x05 },
};
RGBController_LogitechG915::RGBController_LogitechG915(LogitechG915Controller* logitech_ptr)
{
logitech = logitech_ptr;
name = "Logitech G915 Keyboard Device";
vendor = "Logitech";
type = DEVICE_TYPE_KEYBOARD;
description = "Logitech G915 Keyboard Device";
serial = logitech->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = LOGITECH_G915_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Static;
Static.name = "Static";
Static.value = LOGITECH_G915_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.colors_min = 1;
Static.colors_max = 1;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors.resize(1);
modes.push_back(Static);
mode Off;
Off.name = "Off";
Off.value = LOGITECH_G915_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Cycle;
Cycle.name = "Cycle";
Cycle.value = LOGITECH_G915_MODE_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.speed_min = LOGITECH_G915_SPEED_SLOWEST;
Cycle.speed_max = LOGITECH_G915_SPEED_FASTEST;
Cycle.speed = LOGITECH_G915_SPEED_NORMAL;
modes.push_back(Cycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = LOGITECH_G915_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors.resize(1);
Breathing.speed_min = LOGITECH_G915_SPEED_SLOWEST;
Breathing.speed_max = LOGITECH_G915_SPEED_FASTEST;
Breathing.speed = LOGITECH_G915_SPEED_NORMAL;
modes.push_back(Breathing);
SetupZones();
std::copy(colors.begin(), colors.end(),std::back_inserter(current_colors));
}
RGBController_LogitechG915::~RGBController_LogitechG915()
{
/*---------------------------------------------------------*\
| 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;
}
}
}
void RGBController_LogitechG915::SetupZones()
{
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
unsigned int total_led_count = 0;
for(unsigned int zone_idx = 0; zone_idx < 1; zone_idx++)
{
zone new_zone;
new_zone.name = zone_names[zone_idx];
new_zone.type = zone_types[zone_idx];
new_zone.leds_min = zone_sizes[zone_idx];
new_zone.leds_max = zone_sizes[zone_idx];
new_zone.leds_count = zone_sizes[zone_idx];
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
{
new_zone.matrix_map = new matrix_map_type;
new_zone.matrix_map->height = 7;
new_zone.matrix_map->width = 27;
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
}
else
{
new_zone.matrix_map = NULL;
}
zones.push_back(new_zone);
total_led_count += zone_sizes[zone_idx];
}
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
{
led new_led;
new_led.name = led_names[led_idx].name;
new_led.value = ( led_names[led_idx].zone << 8 ) + led_names[led_idx].idx;
leds.push_back(new_led);
}
SetupColors();
}
void RGBController_LogitechG915::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_LogitechG915::DeviceUpdateLEDs()
{
std::map<RGBColor, std::vector<char>> ledsByColors;
std::vector<RGBColor> new_colors;
unsigned char zone = 0;
unsigned char idx = 0;
unsigned char frame_buffer_big_mode[data_size];
unsigned char frame_buffer_little_mode[data_size];
RGBColor colorkey;
/*---------------------------------------------------------*\
| Freeze colors array because prepare framebuffers |
| may take some time. |
\*---------------------------------------------------------*/
std::copy(colors.begin(), colors.end(),std::back_inserter(new_colors));
/*---------------------------------------------------------*\
| Get unique colors to create mode 1F and 6F frame_buffers |
\*---------------------------------------------------------*/
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
zone = ( leds[led_idx].value >> 8 );
idx = ( leds[led_idx].value );
if (current_colors[led_idx]==new_colors[led_idx])
{
/*-------------------------------------------------*\
| Don't send if key color is not changed |
\*-------------------------------------------------*/
continue;
}
switch (zone)
{
case LOGITECH_G915_ZONE_MODE_GKEYS:
idx = ((idx & 0x00ff) + 0xb3);
break;
case LOGITECH_G915_ZONE_MODE_MODIFIERS:
idx = ((idx & 0x00ff) - 0x78);
break;
case LOGITECH_G915_ZONE_DIRECT_KEYBOARD:
idx = ((idx & 0x00ff) - 0x03);
break;
case LOGITECH_G915_ZONE_DIRECT_LOGO:
idx = ((idx & 0x00ff) + 0xd1);
break;
default:
idx = (idx & 0x00ff);
break;
}
colorkey = new_colors[led_idx];
if (ledsByColors.count(colorkey) == 0)
{
ledsByColors.insert(std::pair<RGBColor, std::vector<char>>(colorkey, {}));
}
ledsByColors[colorkey].push_back(idx);
}
uint8_t led_in_little_frame = 0;
uint8_t bi = 0;
size_t frame_pos = 3;
uint8_t li = 0;
/*---------------------------------------------------------*\
| Create frame_buffers of type 1F (Little, up to 4 leds |
| per packet) and 6F (big, up to 13 leds per packet). |
\*---------------------------------------------------------*/
for(std::pair<const RGBColor, std::vector<char>>& x: ledsByColors)
{
/*-----------------------------------------------------*\
| For colors with more than 4 keys. Better to use big |
| (6F) packets to save USB transfers. |
\*-----------------------------------------------------*/
if(x.second.size() > 4)
{
bi = 0;
while(bi < x.second.size())
{
frame_buffer_big_mode[0] = RGBGetRValue(x.first);
frame_buffer_big_mode[1] = RGBGetGValue(x.first);
frame_buffer_big_mode[2] = RGBGetBValue(x.first);
frame_pos = 3;
for(uint8_t i = 0; i < max_key_per_color; i++)
{
if(bi + i < x.second.size())
{
frame_buffer_big_mode[frame_pos] = x.second[bi+i];
frame_pos++;
}
}
if (frame_pos < data_size)
{
/*-----------------------------------------*\
| Zeroing just what is needed and if needed |
\*-----------------------------------------*/
memset(frame_buffer_big_mode + frame_pos, 0x00, sizeof(frame_buffer_big_mode) - frame_pos);
/*-----------------------------------------*\
| End of Data byte |
\*-----------------------------------------*/
frame_buffer_big_mode[frame_pos] = 0xFF;
}
/*-----------------------------------------------------*\
| Zeroing just what is needed |
\*-----------------------------------------------------*/
logitech->SetDirect(LOGITECH_G915_ZONE_FRAME_TYPE_BIG, frame_buffer_big_mode);
bi = bi + max_key_per_color;
}
}
/*-----------------------------------------------------*\
| For colors with up to 4 keys. Use 1F packet to send |
| up to 4 colors-keys combinations per packet. |
\*-----------------------------------------------------*/
else
{
li = 0;
while(li < x.second.size())
{
frame_buffer_little_mode[led_in_little_frame*4 + 0] = x.second[li];
frame_buffer_little_mode[led_in_little_frame*4 + 1] = RGBGetRValue(x.first);
frame_buffer_little_mode[led_in_little_frame*4 + 2] = RGBGetGValue(x.first);
frame_buffer_little_mode[led_in_little_frame*4 + 3] = RGBGetBValue(x.first);
li++;
led_in_little_frame++;
if (led_in_little_frame == 4)
{
/*-----------------------------------------*\
| No End of Data byte if the packet is full |
\*-----------------------------------------*/
logitech->SetDirect(LOGITECH_G915_ZONE_FRAME_TYPE_LITTLE, frame_buffer_little_mode);
led_in_little_frame=0;
}
}
}
}
/*---------------------------------------------------------*\
| If there is a left 1F packet with less than 4 keys, send |
| it and add an End of Data byte. |
\*---------------------------------------------------------*/
if(led_in_little_frame > 0)
{
/*-----------------------------------------------------*\
| Zeroing just what is needed |
\*-----------------------------------------------------*/
memset(frame_buffer_little_mode + (led_in_little_frame * 4 + 1), 0x00, sizeof(frame_buffer_little_mode) - led_in_little_frame * 4);
/*-----------------------------------------------------*\
| Data byte |
\*-----------------------------------------------------*/
frame_buffer_little_mode[led_in_little_frame*4 + 0] = 0xFF;
/*-----------------------------------------------------*\
| Send little frame and clear little frame buffer |
\*-----------------------------------------------------*/
logitech->SetDirect(LOGITECH_G915_ZONE_FRAME_TYPE_LITTLE, frame_buffer_little_mode);
}
if(ledsByColors.size() > 0)
{
/*-----------------------------------------------------*\
| Copy the current color vector to avoid set keys that |
| has not being |
\*-----------------------------------------------------*/
logitech->Commit();
std::copy(new_colors.begin(), new_colors.end(),current_colors.begin());
}
}
void RGBController_LogitechG915::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_LogitechG915::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_LogitechG915::SetCustomMode()
{
active_mode = 0;
}
void RGBController_LogitechG915::DeviceUpdateMode()
{
/*---------------------------------------------------------*\
| Direct mode does not send a mode packet |
| Call UpdateLEDs to send direct packet |
\*---------------------------------------------------------*/
if(modes[active_mode].value == LOGITECH_G915_MODE_DIRECT)
{
/*-----------------------------------------------------*\
| Send real direct mode initialization. I used same |
| sequence as GHUB for screen capture. |
\*-----------------------------------------------------*/
logitech->InitializeDirect();
/*-----------------------------------------------------*\
| Set one key to get direct mode engaged. |
\*-----------------------------------------------------*/
logitech->SendSingleLed(0x29,0,0,0);
logitech->Commit();
return;
}
unsigned char red = 0;
unsigned char grn = 0;
unsigned char blu = 0;
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
red = RGBGetRValue(modes[active_mode].colors[0]);
grn = RGBGetGValue(modes[active_mode].colors[0]);
blu = RGBGetBValue(modes[active_mode].colors[0]);
}
logitech->SetMode(modes[active_mode].value, modes[active_mode].speed, red, grn, blu);
}
@@ -0,0 +1,34 @@
/*-----------------------------------------*\
| RGBController_LogitechG915.h |
| |
| Generic RGB Interface for Logitech G915 |
| RGB Mechanical Gaming Keyboard |
| |
| Cheerpipe 3/20/2021 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "LogitechG915Controller.h"
class RGBController_LogitechG915 : public RGBController
{
public:
RGBController_LogitechG915(LogitechG915Controller* logitech_ptr);
~RGBController_LogitechG915();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
LogitechG915Controller* logitech;
std::vector<RGBColor> current_colors;
};
@@ -174,7 +174,11 @@ void NZXTHue2Controller::UpdateDeviceList()
case 0x06: //Hue 2 strip (6 LEDs)
num_leds_on_channel += 6;
break;
case 0x09: //Hue 2 Underglow (300mm) (15 LEDs)
num_leds_on_channel += 15;
break;
case 0x0A: //Hue 2 Underglow (200mm) (10 LEDs)
num_leds_on_channel += 10;
break;
@@ -4,14 +4,15 @@
#include "RGBController_NZXTHue2.h"
#include <hidapi/hidapi.h>
#define NZXT_VID 0x1E71
#define NZXT_HUE_2_PID 0x2001
#define NZXT_HUE_2_AMBIENT_PID 0x2002
#define NZXT_MOTHERBOARD_DEVICE_PID 0x2005
#define NZXT_SMART_DEVICE_V2_PID 0x2006
#define NZXT_KRAKEN_X3_PID 0x2007
#define NZXT_RGB_FAN_CONTROLLER_PID 0x2009
#define NZXT_SMART_DEVICE_V2_1_PID 0x200D
#define NZXT_VID 0x1E71
#define NZXT_HUE_2_PID 0x2001
#define NZXT_HUE_2_AMBIENT_PID 0x2002
#define NZXT_MOTHERBOARD_DEVICE_PID 0x2005
#define NZXT_SMART_DEVICE_V2_PID 0x2006
#define NZXT_KRAKEN_X3_PID 0x2007
#define NZXT_RGB_FAN_CONTROLLER_PID 0x2009
#define NZXT_RGB_FAN_CONTROLLER2_PID 0x2010
#define NZXT_SMART_DEVICE_V2_1_PID 0x200D
static void spawn_hue(hid_device_info* info, const std::string& name, int rgb_channels, int fan_channels)
{
@@ -61,4 +62,5 @@ REGISTER_HID_DETECTOR("NZXT Hue 2 Motherboard", DetectNZXTHue2Motherboard, NZ
REGISTER_HID_DETECTOR("NZXT Smart Device V2", DetectNZXTSmartDeviceV2, NZXT_VID, NZXT_SMART_DEVICE_V2_PID);
REGISTER_HID_DETECTOR("NZXT Kraken X3", DetectNZXTKrakenX3, NZXT_VID, NZXT_KRAKEN_X3_PID);
REGISTER_HID_DETECTOR("NZXT RGB & Fan Controller", DetectNZXTFanController, NZXT_VID, NZXT_RGB_FAN_CONTROLLER_PID);
REGISTER_HID_DETECTOR("NZXT RGB & Fan Controller", DetectNZXTFanController, NZXT_VID, NZXT_RGB_FAN_CONTROLLER2_PID);
REGISTER_HID_DETECTOR("NZXT Smart Device V2", DetectNZXTSmartDeviceV2, NZXT_VID, NZXT_SMART_DEVICE_V2_1_PID);
@@ -16,6 +16,7 @@
#include "RGBController.h"
#include "RGBController_QMKOpenRGBRev9.h"
#include "RGBController_QMKOpenRGBRevB.h"
#include "LogManager.h"
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
@@ -23,6 +24,7 @@
\*-----------------------------------------------------*/
#define QMK_OPENRGB_PROTOCOL_VERSION_9 0x09
#define QMK_OPENRGB_PROTOCOL_VERSION_B 0x0B
#define QMK_OPENRGB_PROTOCOL_VERSION_C 0x0C
/*-----------------------------------------------------*\
| Usage and Usage Page |
@@ -77,14 +79,36 @@ void DetectQMKOpenRGBControllers(hid_device_info *info, const std::string&)
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
break;
case QMK_OPENRGB_PROTOCOL_VERSION_B:
{
QMKOpenRGBRevBController* controller = new QMKOpenRGBRevBController(dev, info->path);
RGBController_QMKOpenRGBRevB* rgb_controller = new RGBController_QMKOpenRGBRevB(controller);
RGBController_QMKOpenRGBRevB* rgb_controller = new RGBController_QMKOpenRGBRevB(controller, false);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
break;
case QMK_OPENRGB_PROTOCOL_VERSION_C:
{
QMKOpenRGBRevBController* controller = new QMKOpenRGBRevBController(dev, info->path);
RGBController_QMKOpenRGBRevB* rgb_controller = new RGBController_QMKOpenRGBRevB(controller, true);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
break;
default:
if (version == 0)
{
LOG_WARNING("[QMK OpenRGB] Detection failed - the detected keyboard does not have the OpenRGB protocol feature enabled! \n"
"Please make sure your keyboard supports RGB Matrix, add OPENRGB_ENABLE = yes to the rules.mk inside your keymap folder, compile and flash again!");
}
else if (version < QMK_OPENRGB_PROTOCOL_VERSION_9)
{
LOG_WARNING("[QMK OpenRGB] Detection failed - the detected keyboard is using an outdated protocol version %i. Please update to to the update to the latest version of QMK-OpenRGB! \n"
"For officaly supported QMK boards grab <a href=\"https://github.com/Kasper24/QMK-OpenRGB\">url</a> \n"
"For Sonix boards grab <a href=\"https://github.com/SonixQMK/qmk_firmware/tree/sn32_openrgb\">url</a>", version);
}
else if (version > QMK_OPENRGB_PROTOCOL_VERSION_C)
{
LOG_WARNING("[QMK OpenRGB] Detection failed - the detected keyboard is using version protocol %i which is not supported by this OpenRGB build. Please update OpenRGB!", version);
}
}
}
}
@@ -11,6 +11,8 @@
#include "QMKOpenRGBRev9Controller.h"
using namespace std::chrono_literals;
static std::map<uint8_t, std::string> QMKKeycodeToKeynameMap
{
{ 0, "" }, { 1, "Right Fn" }, { 2, "" }, { 3, "" },
@@ -85,6 +87,15 @@ QMKOpenRGBRev9Controller::QMKOpenRGBRev9Controller(hid_device *dev_handle, const
leds_per_update = 20;
}
if(qmk_settings.contains("delay"))
{
delay = (unsigned int)qmk_settings["delay"] * 1ms;
}
else
{
delay = 0ms;
}
dev = dev_handle;
location = path;
@@ -451,6 +462,11 @@ void QMKOpenRGBRev9Controller::DirectModeSetLEDs(std::vector<RGBColor> colors, u
hid_write(dev, usb_buf, 65);
if(delay > 0ms)
{
std::this_thread::sleep_for(delay);
}
leds_sent += tmp_leds_per_update;
}
}
@@ -56,6 +56,8 @@ private:
std::string device_name;
std::string device_vendor;
std::chrono::milliseconds delay;
unsigned int total_number_of_leds;
unsigned int total_number_of_leds_with_empty_space;
unsigned int mode;
@@ -9,6 +9,8 @@
#include "QMKOpenRGBRevBController.h"
using namespace std::chrono_literals;
static std::map<uint8_t, std::string> QMKKeycodeToKeynameMap
{
{ 0, "" }, { 1, "Right Fn" }, { 2, "" }, { 3, "" },
@@ -83,6 +85,15 @@ QMKOpenRGBRevBController::QMKOpenRGBRevBController(hid_device *dev_handle, const
leds_per_update = 20;
}
if(qmk_settings.contains("delay"))
{
delay = (unsigned int)qmk_settings["delay"] * 1ms;
}
else
{
delay = 0ms;
}
dev = dev_handle;
location = path;
@@ -382,7 +393,7 @@ std::vector<unsigned int> QMKOpenRGBRevBController::GetEnabledModes()
return enabled_modes;
}
void QMKOpenRGBRevBController::SetMode(hsv_t hsv_color, unsigned char mode, unsigned char speed)
void QMKOpenRGBRevBController::SetMode(hsv_t hsv_color, unsigned char mode, unsigned char speed, bool save)
{
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
@@ -401,6 +412,7 @@ void QMKOpenRGBRevBController::SetMode(hsv_t hsv_color, unsigned char mode, unsi
usb_buf[0x04] = hsv_color.value;
usb_buf[0x05] = mode;
usb_buf[0x06] = speed;
usb_buf[0x07] = save;
/*-----------------------------------------------------*\
| Send packet |
@@ -472,6 +484,11 @@ void QMKOpenRGBRevBController::DirectModeSetLEDs(std::vector<RGBColor> colors, u
hid_write(dev, usb_buf, 65);
if(delay > 0ms)
{
std::this_thread::sleep_for(delay);
}
leds_sent += tmp_leds_per_update;
}
}
}
@@ -39,7 +39,7 @@ public:
void GetLEDInfo(unsigned int leds_count);
std::vector<unsigned int> GetEnabledModes();
void SetMode(hsv_t hsv_color, unsigned char mode, unsigned char speed);
void SetMode(hsv_t hsv_color, unsigned char mode, unsigned char speed, bool save);
void DirectModeSetSingleLED(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
void DirectModeSetLEDs(std::vector<RGBColor> colors, unsigned int num_colors);
@@ -54,6 +54,8 @@ private:
std::string device_name;
std::string device_vendor;
std::chrono::milliseconds delay;
unsigned int total_number_of_leds;
unsigned int total_number_of_leds_with_empty_space;
unsigned int mode;
@@ -8,9 +8,10 @@
\*-------------------------------------------------------------------*/
#include "hsv.h"
#include "LogManager.h"
#include "RGBController_QMKOpenRGBRevB.h"
RGBController_QMKOpenRGBRevB::RGBController_QMKOpenRGBRevB(QMKOpenRGBRevBController* controller_ptr)
RGBController_QMKOpenRGBRevB::RGBController_QMKOpenRGBRevB(QMKOpenRGBRevBController* controller_ptr, bool save)
{
controller = controller_ptr;
@@ -26,212 +27,212 @@ RGBController_QMKOpenRGBRevB::RGBController_QMKOpenRGBRevB(QMKOpenRGBRevBControl
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_COLOR) != enabled_modes.end())
{
InitializeMode("Static", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Static", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_ALPHA_MOD) != enabled_modes.end())
{
InitializeMode("Alpha Mod", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Alpha Mod", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_GRADIENT_UP_DOWN) != enabled_modes.end())
{
InitializeMode("Gradient Up Down", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Gradient Up Down", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_GRADIENT_LEFT_RIGHT) != enabled_modes.end())
{
InitializeMode("Gradient Left Right", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Gradient Left Right", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BREATHING) != enabled_modes.end())
{
InitializeMode("Breathing", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Breathing", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_SAT) != enabled_modes.end())
{
InitializeMode("Band Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Band Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_VAL) != enabled_modes.end())
{
InitializeMode("Band Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Band Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_PINWHEEL_SAT) != enabled_modes.end())
{
InitializeMode("Band Pinwheel Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Band Pinwheel Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_PINWHEEL_VAL) != enabled_modes.end())
{
InitializeMode("Band Pinwheel Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Band Pinwheel Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_SPIRAL_SAT) != enabled_modes.end())
{
InitializeMode("Band Spiral Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Band Spiral Saturation", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_BAND_SPIRAL_VAL) != enabled_modes.end())
{
InitializeMode("Band Spiral Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Band Spiral Value", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_ALL) != enabled_modes.end())
{
InitializeMode("Cycle All", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Cycle All", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_LEFT_RIGHT) != enabled_modes.end())
{
InitializeMode("Cycle Left Right", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Cycle Left Right", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_UP_DOWN) != enabled_modes.end())
{
InitializeMode("Cycle Up Down", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Cycle Up Down", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_OUT_IN) != enabled_modes.end())
{
InitializeMode("Cycle Out In", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Cycle Out In", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_OUT_IN_DUAL) != enabled_modes.end())
{
InitializeMode("Cycle Out In Dual", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Cycle Out In Dual", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINBOW_MOVING_CHEVRON) != enabled_modes.end())
{
InitializeMode("Rainbow Moving Chevron", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Rainbow Moving Chevron", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_PINWHEEL) != enabled_modes.end())
{
InitializeMode("Cycle Pinwheel", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Cycle Pinwheel", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_CYCLE_SPIRAL) != enabled_modes.end())
{
InitializeMode("Cycle Spiral", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Cycle Spiral", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_DUAL_BEACON) != enabled_modes.end())
{
InitializeMode("Dual Beacon", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Dual Beacon", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINBOW_BEACON) != enabled_modes.end())
{
InitializeMode("Rainbow Beacon", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Rainbow Beacon", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINBOW_PINWHEELS) != enabled_modes.end())
{
InitializeMode("Rainbow Pinwheels", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Rainbow Pinwheels", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_RAINDROPS) != enabled_modes.end())
{
InitializeMode("Raindrops", current_mode, 0, MODE_COLORS_NONE);
InitializeMode("Raindrops", current_mode, 0, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_JELLYBEAN_RAINDROPS) != enabled_modes.end())
{
InitializeMode("Jellybean Raindrops", current_mode, 0, MODE_COLORS_NONE);
InitializeMode("Jellybean Raindrops", current_mode, 0, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_HUE_BREATHING) != enabled_modes.end())
{
InitializeMode("Hue Breathing", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Hue Breathing", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_HUE_PENDULUM) != enabled_modes.end())
{
InitializeMode("Hue Pendulum", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Hue Pendulum", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_HUE_WAVE) != enabled_modes.end())
{
InitializeMode("Hue Wave", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Hue Wave", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_TYPING_HEATMAP) != enabled_modes.end())
{
InitializeMode("Typing Heatmap", current_mode, 0, MODE_COLORS_NONE);
InitializeMode("Typing Heatmap", current_mode, 0, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_DIGITAL_RAIN) != enabled_modes.end())
{
InitializeMode("Digital Rain", current_mode, 0, MODE_COLORS_NONE);
InitializeMode("Digital Rain", current_mode, 0, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_SIMPLE) != enabled_modes.end())
{
InitializeMode("Solid Reactive Simple", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Solid Reactive Simple", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE) != enabled_modes.end())
{
InitializeMode("Solid Reactive", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Solid Reactive", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_WIDE) != enabled_modes.end())
{
InitializeMode("Solid Reactive Wide", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Solid Reactive Wide", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTIWIDE) != enabled_modes.end())
{
InitializeMode("Solid Reactive Multi Wide", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Solid Reactive Multi Wide", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_CROSS) != enabled_modes.end())
{
InitializeMode("Solid Reactive Cross", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Solid Reactive Cross", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTICROSS) != enabled_modes.end())
{
InitializeMode("Solid Reactive Multi Cross", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Solid Reactive Multi Cross", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_NEXUS) != enabled_modes.end())
{
InitializeMode("Solid Reactive Nexus", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Solid Reactive Nexus", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_REACTIVE_MULTINEXUS) != enabled_modes.end())
{
InitializeMode("Solid Reactive Multi Nexus", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Solid Reactive Multi Nexus", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SPLASH) != enabled_modes.end())
{
InitializeMode("Rainbow Reactive Splash", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Rainbow Reactive Splash", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_MULTISPLASH) != enabled_modes.end())
{
InitializeMode("Rainbow Reactive Multi Splash", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE);
InitializeMode("Rainbow Reactive Multi Splash", current_mode, MODE_FLAG_HAS_SPEED, MODE_COLORS_NONE, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_SPLASH) != enabled_modes.end())
{
InitializeMode("Solid Reactive Splash", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Solid Reactive Splash", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_SOLID_MULTISPLASH) != enabled_modes.end())
{
InitializeMode("Solid Reactive Multi Splash", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC);
InitializeMode("Solid Reactive Multi Splash", current_mode, MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED, MODE_COLORS_MODE_SPECIFIC, save);
}
if(std::find(enabled_modes.begin(), enabled_modes.end(), QMK_OPENRGB_MODE_OPENRGB_DIRECT) != enabled_modes.end())
{
InitializeMode("Direct", current_mode, MODE_FLAG_HAS_PER_LED_COLOR, MODE_COLORS_PER_LED);
InitializeMode("Direct", current_mode, MODE_FLAG_HAS_PER_LED_COLOR, MODE_COLORS_PER_LED, save);
}
/*-----------------------------------------------------*\
@@ -430,11 +431,11 @@ void RGBController_QMKOpenRGBRevB::DeviceUpdateMode()
{
if(modes[active_mode].color_mode == MODE_COLORS_PER_LED)
{
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, 127);
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, 127, false);
}
else if(modes[active_mode].color_mode == MODE_COLORS_NONE)
{
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, modes[active_mode].speed);
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, modes[active_mode].speed, false);
}
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
@@ -444,11 +445,34 @@ void RGBController_QMKOpenRGBRevB::DeviceUpdateMode()
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
{
controller->SetMode(hsv_color, modes[active_mode].value, modes[active_mode].speed);
controller->SetMode(hsv_color, modes[active_mode].value, modes[active_mode].speed, false);
}
else
{
controller->SetMode(hsv_color, modes[active_mode].value, 127);
controller->SetMode(hsv_color, modes[active_mode].value, 127, false);
}
}
}
void RGBController_QMKOpenRGBRevB::DeviceSaveMode()
{
if(modes[active_mode].color_mode == MODE_COLORS_NONE)
{
controller->SetMode({ 0, 255, 255 }, modes[active_mode].value, modes[active_mode].speed, true);
}
else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
RGBColor rgb_color = modes[active_mode].colors[0];
hsv_t hsv_color;
rgb2hsv(rgb_color, &hsv_color);
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
{
controller->SetMode(hsv_color, modes[active_mode].value, modes[active_mode].speed, true);
}
else
{
controller->SetMode(hsv_color, modes[active_mode].value, 127, true);
}
}
}
@@ -458,7 +482,8 @@ void RGBController_QMKOpenRGBRevB::InitializeMode
std::string name,
unsigned int &current_mode,
unsigned int flags,
unsigned int color_mode
unsigned int color_mode,
bool save
)
{
mode qmk_mode;
@@ -491,6 +516,13 @@ void RGBController_QMKOpenRGBRevB::InitializeMode
}
else
{
/*-----------------------------------------------------*\
| Every mode apart from direct is save-able |
\*-----------------------------------------------------*/
if(save == true)
{
qmk_mode.flags = flags | MODE_FLAG_MANUAL_SAVE;
}
modes.push_back(qmk_mode);
}
}
@@ -23,7 +23,7 @@ typedef std::vector<std::vector<unsigned int>> VectorMatrix;
class RGBController_QMKOpenRGBRevB : public RGBController
{
public:
RGBController_QMKOpenRGBRevB(QMKOpenRGBRevBController* controller_ptr);
RGBController_QMKOpenRGBRevB(QMKOpenRGBRevBController* controller_ptr, bool save);
~RGBController_QMKOpenRGBRevB();
void SetupZones();
@@ -35,6 +35,7 @@ public:
void SetCustomMode();
void DeviceUpdateMode();
void DeviceSaveMode();
private:
QMKOpenRGBRevBController* controller;
@@ -46,7 +47,8 @@ private:
std::string name,
unsigned int &current_mode,
unsigned int flags,
unsigned int color_mode
unsigned int color_mode,
bool save
);
unsigned int CalculateDivisor
@@ -81,6 +81,7 @@ RazerController::RazerController(hid_device* dev_handle, hid_device* dev_argb_ha
case RAZER_BASE_STATION_CHROMA_PID:
case RAZER_CHROMA_HDK_PID:
case RAZER_CORE_PID:
case RAZER_CORE_X_PID:
case RAZER_FIREFLY_PID:
case RAZER_FIREFLY_HYPERFLUX_PID:
case RAZER_FIREFLY_V2_PID:
@@ -104,6 +105,7 @@ RazerController::RazerController(hid_device* dev_handle, hid_device* dev_argb_ha
case RAZER_BASE_STATION_V2_CHROMA_PID:
case RAZER_CHARGING_PAD_CHROMA_PID:
case RAZER_CHROMA_HDK_PID:
case RAZER_CORE_X_PID:
case RAZER_FIREFLY_V2_PID:
dev_led_id = RAZER_LED_ID_ZERO;
break;
@@ -121,6 +123,7 @@ RazerController::RazerController(hid_device* dev_handle, hid_device* dev_argb_ha
case RAZER_HUNTSMAN_TE_PID:
case RAZER_ORNATA_CHROMA_PID:
case RAZER_ORNATA_CHROMA_V2_PID:
case RAZER_CORE_PID:
case RAZER_FIREFLY_PID:
default:
dev_led_id = RAZER_LED_ID_BACKLIGHT;
@@ -166,6 +169,7 @@ RazerController::RazerController(hid_device* dev_handle, hid_device* dev_argb_ha
case RAZER_BLADE_STEALTH_LATE_2020_PID:
case RAZER_BOOK_13_2020_PID:
case RAZER_NAGA_HEX_V2_PID:
case RAZER_CORE_PID:
matrix_type = RAZER_MATRIX_TYPE_STANDARD;
break;
@@ -184,6 +188,7 @@ RazerController::RazerController(hid_device* dev_handle, hid_device* dev_argb_ha
case RAZER_CHARGING_PAD_CHROMA_PID:
case RAZER_CHROMA_HDK_PID:
case RAZER_CHROMA_PC_CASE_LIGHTING_KIT_PID:
case RAZER_CORE_X_PID:
case RAZER_CYNOSA_CHROMA_PID:
case RAZER_CYNOSA_V2_PID:
case RAZER_DEATHADDER_ELITE_PID:
@@ -477,6 +482,7 @@ bool RazerController::SupportsWave()
case RAZER_CHROMA_HDK_PID:
case RAZER_CHROMA_PC_CASE_LIGHTING_KIT_PID:
case RAZER_CORE_PID:
case RAZER_CORE_X_PID:
case RAZER_FIREFLY_PID:
case RAZER_FIREFLY_V2_PID:
case RAZER_MOUSE_BUNGEE_V3_CHROMA_PID:
@@ -93,14 +93,20 @@ void DetectRazerARGBControllers(hid_device_info* info, const std::string& name)
/*-------------------------------------------------------------------------------------------------*\
| Razer's ARGB controller uses two different interfaces, one for 90-byte Razer report packets and |
| one for 320-byte ARGB packets. Interface 0 for 90-byte and interface 1 for 320-byte. |
| |
| Create a local copy of the HID enumerations for the Razer ARGB controller VID/PID and iterate |
| through it. This prevents detection from failing if interface 1 comes before interface 0 in the |
| main info list. |
\*-------------------------------------------------------------------------------------------------*/
hid_device* dev_interface_0 = nullptr;
hid_device* dev_interface_1 = nullptr;
hid_device_info* info_temp = info;
hid_device_info* info_full = hid_enumerate(RAZER_VID, RAZER_CHROMA_ADDRESSABLE_RGB_CONTROLLER_PID);
hid_device_info* info_temp = info_full;
while(info_temp)
{
if(info_temp->vendor_id == info->vendor_id // constant LOGITECH_VID
&& info_temp->product_id == info->product_id ) // NON-constant
if(info_temp->vendor_id == info->vendor_id
&& info_temp->product_id == info->product_id )
{
if(info_temp->interface_number == 0)
{
@@ -117,6 +123,9 @@ void DetectRazerARGBControllers(hid_device_info* info, const std::string& name)
}
info_temp = info_temp->next;
}
hid_free_enumeration(info_full);
if(dev_interface_0 && dev_interface_1)
{
RazerController* controller = new RazerController(dev_interface_0, dev_interface_1, info->path, info->product_id, name);
@@ -329,6 +338,7 @@ REGISTER_HID_DETECTOR_IPU("Razer Chroma HDK", Det
REGISTER_HID_DETECTOR_IPU("Razer Chroma Mug Holder", DetectRazerControllers, RAZER_VID, RAZER_CHROMA_MUG_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Chroma PC Case Lighting Kit", DetectRazerControllers, RAZER_VID, RAZER_CHROMA_PC_CASE_LIGHTING_KIT_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Core", DetectRazerControllers, RAZER_VID, RAZER_CORE_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Core X", DetectRazerControllers, RAZER_VID, RAZER_CORE_X_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Mouse Bungee V3 Chroma", DetectRazerControllers, RAZER_VID, RAZER_MOUSE_BUNGEE_V3_CHROMA_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Mouse Dock Chroma", DetectRazerControllers, RAZER_VID, RAZER_MOUSE_DOCK_CHROMA_PID, 0x00, 0x01, 0x02);
REGISTER_HID_DETECTOR_IPU("Razer Nommo Chroma", DetectRazerControllers, RAZER_VID, RAZER_NOMMO_CHROMA_PID, 0x00, 0x01, 0x03);
@@ -158,6 +158,7 @@
#define RAZER_CHROMA_MUG_PID 0x0F07
#define RAZER_CHROMA_PC_CASE_LIGHTING_KIT_PID 0x0F0E
#define RAZER_CORE_PID 0x0215
#define RAZER_CORE_X_PID 0x0F1A
#define RAZER_FIREFLY_HYPERFLUX_PID 0x0068
#define RAZER_FIREFLY_PID 0x0C00
#define RAZER_FIREFLY_V2_PID 0x0C04
@@ -5678,6 +5679,53 @@ static const razer_device core_device =
0
};
/*-------------------------------------------------------------*\
| Razer Core X |
| |
| Zone "Side Window Lights" |
| Single |
| 1 LED |
| |
| Zone "LED Strip" |
| Linear |
| 15 LEDs |
\*-------------------------------------------------------------*/
static const razer_zone core_x_side_zone =
{
"Side Window Lights",
ZONE_TYPE_SINGLE,
1,
1
};
static const razer_zone core_x_led_strip_zone =
{
"LED Strip",
ZONE_TYPE_LINEAR,
1,
15
};
static const razer_device core_x_device =
{
"Razer Core X",
RAZER_CORE_X_PID,
DEVICE_TYPE_UNKNOWN,
true,
1,
16,
{
&core_x_side_zone,
&core_x_led_strip_zone,
NULL,
NULL,
NULL,
NULL
},
NULL,
0
};
/*-------------------------------------------------------------*\
| Razer Chroma Mug Holder |
| |
@@ -6292,6 +6340,7 @@ static const razer_device* device_list[] =
&chromahdk_device,
&chroma_pc_case_lighting_kit_device,
&core_device,
&core_x_device,
&mug_holder_device,
&mouse_dock_chroma_device,
&nommo_chroma_device,
@@ -0,0 +1,465 @@
/*------------------------------------------*\
| 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 "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: Escape",
"",
"Key: F1",
"Key: F2",
"Key: F3",
"Key: F4",
"",
"Key: F5",
"Key: F6",
"Key: F7",
"Key: F8",
"Key: F9",
"Key: F10",
"Key: F11",
"Key: F12",
"Key: Print Screen",
"Key: Scroll Lock",
"Key: Pause/Break",
"",
"",
"",
"",
"Key: `",
"Key: 1",
"Key: 2",
"Key: 3",
"Key: 4",
"Key: 5",
"Key: 6",
"Key: 7",
"Key: 8",
"Key: 9",
"Key: 0",
"Key: -",
"Key: =",
"Undefined",
"Key: Backspace",
"Key: Insert",
"Key: Home",
"Key: Page Up",
"Key: Num Lock",
"Key: Number Pad /",
"Key: Number Pad *",
"Key: Number Pad -",
"Key: Tab",
"Key: Q",
"Key: W",
"Key: E",
"Key: R",
"Key: T",
"Key: Y",
"Key: U",
"Key: I",
"Key: O",
"Key: P",
"Key: [",
"Key: ]",
"Key: \\ (ANSI)",
"",
"Key: Delete",
"Key: End",
"Key: Page Down",
"Key: Number Pad 7",
"Key: Number Pad 8",
"Key: Number Pad 9",
"Key: Number Pad +",
"Key: Caps Lock",
"Key: A",
"Key: S",
"Key: D",
"Key: F",
"Key: G",
"Key: H",
"Key: J",
"Key: K",
"Key: L",
"Key: ;",
"Key: '",
"",
"Key: Enter",
"",
"",
"",
"",
"Key: Number Pad 4",
"Key: Number Pad 5",
"Key: Number Pad 6",
"Key: Number Pad +",
"Key: Left Shift",
"",
"Key: Z",
"Key: X",
"Key: C",
"Key: V",
"Key: B",
"Key: N",
"Key: M",
"Key: ,",
"Key: .",
"Key: /",
"",
"",
"Key: Right Shift",
"",
"Key: Up Arrow",
"",
"Key: Number Pad 1",
"Key: Number Pad 2",
"Key: Number Pad 3",
"Key: Number Pad Enter",
"Key: Left Control",
"Key: Left Windows",
"Key: Left Alt",
"",
"",
"Key: Space",
"","",
"Key: Right Alt",
"Key: Right Fn",
"Key: Right Windows",
"",
"Key: Right Control",
"",
"",
"Key: Left Arrow",
"Key: Down Arrow",
"Key: Right Arrow",
"Key: Number Pad 0",
"Key: Number Pad 0",
"Key: Number Pad .",
"Key: Number Pad Enter"
};
RGBController_SinowealthKeyboard16::RGBController_SinowealthKeyboard16(SinowealthKeyboard16Controller* sinowealth_ptr)
{
sinowealth = sinowealth_ptr;
name = "Sinowealth Keyboard";
type = DEVICE_TYPE_KEYBOARD;
description = "Generic Sinowealth Keyboard";
location = sinowealth->GetLocation();
serial = sinowealth->GetSerialString();
std::vector<ModeCfg> modes_cfg = sinowealth->GetDeviceModes();
std::vector<ModeColorCfg> color_presets = sinowealth->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 = sinowealth->GetCurrentMode();
if(device_mode >= MODE_PER_KEY1)
{
device_mode = mode_id+(device_mode & 0x0F);
colors = sinowealth->GetPerLedColors();
}
active_mode = device_mode;
}
RGBController_SinowealthKeyboard16::~RGBController_SinowealthKeyboard16()
{
delete sinowealth;
}
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 = "Keyboard";
new_zone.type = ZONE_TYPE_MATRIX;
new_zone.leds_count = sinowealth->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()
{
sinowealth->SetLEDsDirect(colors);
}
void RGBController_SinowealthKeyboard16::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_SinowealthKeyboard16::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_SinowealthKeyboard16::SetCustomMode()
{
/*---------------------------------------------------------*\
| Search the mode list and find Custom mode |
\*---------------------------------------------------------*/
for(unsigned int mode_idx = 0; mode_idx < modes.size(); mode_idx++)
{
if(modes[mode_idx].name == "Custom")
{
active_mode = mode_idx;
break;
}
}
}
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;
}
sinowealth->ClearMode();
if(ActiveMode.colors.size())
{
sinowealth->SetColorsForMode(ActiveMode.value, &ActiveMode.colors[0]);
}
sinowealth->SetMode(ActiveMode.value, ActiveMode.brightness, ActiveMode.speed, ActiveMode.direction, color_mode);
if(ActiveMode.value >= MODE_PER_KEY1)
{
colors = sinowealth->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();
}
@@ -0,0 +1,41 @@
/*------------------------------------------*\
| 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* sinowealth_ptr);
~RGBController_SinowealthKeyboard16();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
SinowealthKeyboard16Controller* sinowealth;
mode getModeItem(unsigned int mode_id);
};
@@ -1,10 +1,13 @@
#include "Detector.h"
#include "SinowealthController.h"
#include "SinowealthKeyboardController.h"
#include "SinowealthKeyboard16Controller.h"
#include "RGBController.h"
#include "RGBController_Sinowealth.h"
#include "RGBController_SinowealthKeyboard.h"
#include "RGBController_SinowealthKeyboard16.h"
#include <hidapi/hidapi.h>
#include "LogManager.h"
#define SINOWEALTH_VID 0x258A
@@ -12,6 +15,7 @@
#define Glorious_Model_D_PID 0x0033
#define Everest_GT100_PID 0x0029
#define Fl_Esports_F11_PID 0x0049
#define RGB_KEYBOARD_0016PID 0x0016
/******************************************************************************************\
* *
@@ -93,7 +97,55 @@ void DetectSinowealthMouse(hid_device_info* info, const std::string& name)
#endif
}
void DetectSinowealthKeyboard(hid_device_info* info, const std::string& name)
bool DetectCmdAndDataUsages(hid_device* usages[], int usage_count, std::string name, hid_device** dev_cmd, hid_device** dev_data)
{
unsigned char tmp_buf[1032];
// Try to find which device allow us to send ReportID 0x05
for(int i = 0; i < usage_count; i++)
{
memset(tmp_buf, 0x00, sizeof(tmp_buf));
tmp_buf[0] = 0x05;
tmp_buf[1] = 0x83;
if(hid_send_feature_report(usages[i], tmp_buf, 6) != -1)
{
*dev_cmd = usages[i];
break;
}
}
if(*dev_cmd == nullptr)
{
LOG_ERROR("[%s] Can't find working hid_device for ReportId 0x05", name.c_str());
return false;
}
// Try other devices for support ReportID 0x06
for(int i = 0; i < usage_count; i++)
{
if(usages[i] == *dev_cmd)
{
continue;
}
memset(tmp_buf, 0x00, sizeof(tmp_buf));
tmp_buf[0] = 0x06;
if(hid_get_feature_report(usages[i], tmp_buf, 1032) != -1)
{
*dev_data = usages[i];
break;
}
}
if(*dev_data == nullptr)
{
LOG_ERROR("[%s] Can't find working hid_device for ReportId 0x06", name.c_str());
return false;
}
return true;
}
void DetectSinowealthKeyboard(hid_device_info* info, const std::string& name, unsigned int pid)
{
#ifdef USE_HID_USAGE
hid_device* usages[3];
@@ -102,8 +154,24 @@ void DetectSinowealthKeyboard(hid_device_info* info, const std::string& name)
if(usage_count == 3)
{
SinowealthKeyboardController* controller = new SinowealthKeyboardController(usages[1], usages[2], info->path);
RGBController_SinowealthKeyboard* rgb_controller = new RGBController_SinowealthKeyboard(controller);
RGBController *rgb_controller;
if(pid == RGB_KEYBOARD_0016PID)
{
hid_device* dev_cmd = nullptr;
hid_device* dev_data = nullptr;
if(!DetectCmdAndDataUsages(usages, usage_count, name, &dev_cmd, &dev_data))
{
return;
}
SinowealthKeyboard16Controller* controller = new SinowealthKeyboard16Controller(dev_cmd, dev_data, info->path, name);
rgb_controller = new RGBController_SinowealthKeyboard16(controller);
}
else
{
SinowealthKeyboardController* controller = new SinowealthKeyboardController(usages[1], usages[2], info->path);
rgb_controller = new RGBController_SinowealthKeyboard(controller);
}
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
@@ -121,23 +189,45 @@ void DetectSinowealthKeyboard(hid_device_info* info, const std::string& name)
hid_device* dev = hid_open_path(info->path);
if(dev)
{
SinowealthController* controller = new SinowealthController(dev, dev, info->path);
RGBController_Sinowealth* rgb_controller = new RGBController_Sinowealth(controller);
RGBController *rgb_controller;
if(pid == RGB_KEYBOARD_0016PID)
{
SinowealthKeyboard16Controller* controller = new SinowealthKeyboard16Controller(dev, dev, info->path, name);
rgb_controller = new RGBController_SinowealthKeyboard16(controller);
}
else
{
SinowealthController* controller = new SinowealthController(dev, dev, info->path);
rgb_controller = new RGBController_Sinowealth(controller);
}
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
#endif
}
void DetectSinowealthKeyboard49(hid_device_info* info, const std::string& name)
{
DetectSinowealthKeyboard(info, name, Fl_Esports_F11_PID);
}
void DetectSinowealthKeyboard16(hid_device_info* info, const std::string& name)
{
DetectSinowealthKeyboard(info, name, RGB_KEYBOARD_0016PID);
}
#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_P("FL ESPORTS F11", DetectSinowealthKeyboard, SINOWEALTH_VID, Fl_Esports_F11_PID, 0xFF00);
REGISTER_HID_DETECTOR_P("FL ESPORTS F11", DetectSinowealthKeyboard49, 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("FL ESPORTS F11", DetectSinowealthKeyboard, SINOWEALTH_VID, Fl_Esports_F11_PID, 1);
REGISTER_HID_DETECTOR_I("FL ESPORTS F11", DetectSinowealthKeyboard49, SINOWEALTH_VID, Fl_Esports_F11_PID, 1);
REGISTER_HID_DETECTOR_I("Sinowealth Keyboard", DetectSinowealthKeyboard16, SINOWEALTH_VID, RGB_KEYBOARD_0016PID, 1);
#endif
@@ -0,0 +1,337 @@
/*------------------------------------------*\
| 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 "SinowealthKeyboard16Controller.h"
#include "LogManager.h"
#include <cstring>
#include <chrono>
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);
}
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("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_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);
}
@@ -0,0 +1,162 @@
/*------------------------------------------*\
| 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/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 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();
};
@@ -25,6 +25,16 @@ static const steelseries_rival_led_info rival_650_leds[]=
{"Right 3", 0x17},
};
static const steelseries_rival_led_info rival_600_leds[]=
{
{"Left top", 0x02},
{"Left mid", 0x04},
{"Left bottom", 0x06},
{"Right top", 0x03},
{"Right mid", 0x05},
{"Right bottom", 0x07},
};
RGBController_SteelSeriesRival::RGBController_SteelSeriesRival(SteelSeriesRivalController* rival_ptr)
{
rival = rival_ptr;
@@ -39,20 +49,22 @@ RGBController_SteelSeriesRival::RGBController_SteelSeriesRival(SteelSeriesRivalC
mode Direct;
Direct.name = "Direct";
Direct.value = STEELSERIES_RIVAL_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Pulsate;
Pulsate.name = "Pulsate";
Pulsate.value = STEELSERIES_RIVAL_PULSATE;
Pulsate.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE;
Pulsate.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Pulsate.color_mode = MODE_COLORS_PER_LED;
Pulsate.speed_min = STEELSERIES_RIVAL_EFFECT_PULSATE_MIN;
Pulsate.speed_max = STEELSERIES_RIVAL_EFFECT_PULSATE_MAX;
Pulsate.speed = STEELSERIES_RIVAL_EFFECT_PULSATE_MID;
modes.push_back(Pulsate);
SetupZones();
}
@@ -130,8 +142,44 @@ void RGBController_SteelSeriesRival::SetupZones()
mouse_led.value = led_info.value;
leds.push_back(mouse_led);
}
}
/* Rival 600 is simular to Rival 650 */
else if(rival->GetMouseType() == RIVAL_600)
{
leds[0].value = 0x01;
zone wheel_zone;
wheel_zone.name = "Scroll Wheel";
wheel_zone.type = ZONE_TYPE_SINGLE;
wheel_zone.leds_min = 1;
wheel_zone.leds_max = 1;
wheel_zone.leds_count = 1;
wheel_zone.matrix_map = NULL;
zones.push_back(wheel_zone);
led wheel_led;
wheel_led.name = "Scroll Wheel";
wheel_led.value = 0x00;
leds.push_back(wheel_led);
zone mouse_zone;
mouse_zone.name = "Mouse";
mouse_zone.type = ZONE_TYPE_LINEAR;
mouse_zone.leds_min = 6;
mouse_zone.leds_max = 6;
mouse_zone.leds_count = 6;
mouse_zone.matrix_map = NULL;
zones.push_back(mouse_zone);
for(const steelseries_rival_led_info led_info: rival_600_leds)
{
led mouse_led;
mouse_led.name = led_info.name;
mouse_led.value = led_info.value;
leds.push_back(mouse_led);
}
}
SetupColors();
}
@@ -194,8 +242,3 @@ void RGBController_SteelSeriesRival::DeviceUpdateMode()
DeviceUpdateLEDs();
}
void RGBController_SteelSeriesRival::DeviceSaveMode()
{
rival->Save();
}
@@ -28,7 +28,6 @@ public:
void SetCustomMode();
void DeviceUpdateMode();
void DeviceSaveMode();
private:
SteelSeriesRivalController* rival;
@@ -0,0 +1,164 @@
/*-----------------------------------------*\
| RGBController_SteelSeriesRival.cpp |
| |
| Generic RGB Interface SteelSeriesRival3 |
| Class |
| |
| B Horn (bahorn) 29/08/2021 |
\*-----------------------------------------*/
#include "RGBController_SteelSeriesRival3.h"
typedef struct
{
const char* name;
const int value;
} steelseries_rival_led_info;
static const steelseries_rival_led_info rival_3_leds[]=
{
{"Front", 0x01},
{"Middle", 0x02},
{"Rear", 0x03},
{"Logo", 0x04}
};
RGBController_SteelSeriesRival3::RGBController_SteelSeriesRival3(SteelSeriesRival3Controller* rival_ptr)
{
rival = rival_ptr;
name = rival->GetDeviceName();
vendor = "SteelSeries";
type = DEVICE_TYPE_MOUSE;
description = "SteelSeries Rival 3 Device";
location = rival->GetDeviceLocation();
serial = rival->GetSerialString();
version = rival->GetFirmwareVersion();
mode Direct;
Direct.name = "Direct";
Direct.value = STEELSERIES_RIVAL_3_EFFECT_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
Direct.color_mode = MODE_COLORS_PER_LED;
Direct.brightness_min = 0x00;
Direct.brightness_max = STEELSERIES_RIVAL_3_BRIGHTNESS_MAX;
Direct.brightness = STEELSERIES_RIVAL_3_BRIGHTNESS_MAX;
modes.push_back(Direct);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = STEELSERIES_RIVAL_3_EFFECT_BREATHING_MIN;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed_min = 0;
Breathing.speed_max = 2;
Breathing.speed = 1;
modes.push_back(Breathing);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = STEELSERIES_RIVAL_3_EFFECT_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_MANUAL_SAVE;
modes.push_back(SpectrumCycle);
mode RainbowBreathing;
RainbowBreathing.name = "Rainbow Breathing";
RainbowBreathing.value = STEELSERIES_RIVAL_3_EFFECT_RAINBOW_BREATHING;
RainbowBreathing.flags = MODE_FLAG_MANUAL_SAVE;
modes.push_back(RainbowBreathing);
/*------------------------------------------------------------------------*\
| This is a pretty cool mode where it flashes random colors. |
| |
| However, the flashes are in the frequency range where it probably needs |
| a proper warning for it to be compiled in by default. |
| |
| It is disabled in the vendor software, and is only known about as it is |
| documented in rivalcfg. |
| |
| If this does get re-enabled, worth noting it has an issue where this |
| mode is black if you come directly from one of the pulsating modes. |
\*------------------------------------------------------------------------*/
/*
mode Disco;
Disco.name = "Disco";
Disco.value = STEELSERIES_RIVAL_3_EFFECT_DISCO;
Disco.flags = MODE_FLAG_MANUAL_SAVE;
modes.push_back(Disco);
*/
SetupZones();
}
void RGBController_SteelSeriesRival3::DeviceSaveMode()
{
rival->Save();
}
RGBController_SteelSeriesRival3::~RGBController_SteelSeriesRival3()
{
delete rival;
}
void RGBController_SteelSeriesRival3::SetupZones()
{
for(const steelseries_rival_led_info led_info: rival_3_leds)
{
zone zone;
zone.name = led_info.name;
zone.type = ZONE_TYPE_SINGLE;
zone.leds_min = 1;
zone.leds_max = 1;
zone.leds_count = 1;
zone.matrix_map = NULL;
zones.push_back(zone);
led mouse_led;
mouse_led.name = led_info.name;
mouse_led.value = led_info.value;
leds.push_back(mouse_led);
}
SetupColors();
}
void RGBController_SteelSeriesRival3::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_SteelSeriesRival3::DeviceUpdateLEDs()
{
for(unsigned int i = 0; i < zones.size(); i++)
{
UpdateZoneLEDs(i);
}
DeviceUpdateMode();
}
void RGBController_SteelSeriesRival3::UpdateZoneLEDs(int zone)
{
/*--------------------------------------------------*\
| Subtracting one as the zone and led indexes differ |
\*--------------------------------------------------*/
UpdateSingleLED(zones[zone].leds[0].value - 1);
}
void RGBController_SteelSeriesRival3::UpdateSingleLED(int led)
{
unsigned char red = RGBGetRValue(colors[led]);
unsigned char grn = RGBGetGValue(colors[led]);
unsigned char blu = RGBGetBValue(colors[led]);
rival->SetColor(leds[led].value, red, grn, blu, modes[active_mode].brightness);
}
void RGBController_SteelSeriesRival3::SetCustomMode()
{
active_mode = 0;
}
void RGBController_SteelSeriesRival3::DeviceUpdateMode()
{
rival->SetLightEffectAll(modes[active_mode].value - modes[active_mode].speed);
}
@@ -0,0 +1,36 @@
/*-----------------------------------------*\
| RGBController_SteelSeriesRival.h |
| |
| Generic RGB Interface SteelSeriesRival3 |
| Class |
| |
| B Horn (bahorn) 29/08/2021 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "SteelSeriesRival3Controller.h"
class RGBController_SteelSeriesRival3 : public RGBController
{
public:
RGBController_SteelSeriesRival3(SteelSeriesRival3Controller* rival_ptr);
~RGBController_SteelSeriesRival3();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
void DeviceSaveMode();
private:
SteelSeriesRival3Controller* rival;
};
@@ -23,14 +23,14 @@ RGBController_SteelSeriesSensei::RGBController_SteelSeriesSensei(SteelSeriesSens
mode Direct;
Direct.name = "Direct";
Direct.value = STEELSERIES_SENSEI_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = STEELSERIES_SENSEI_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed_min = STEELSERIES_SENSEI_EFFECT_BREATHING_MIN;
Breathing.speed_max = STEELSERIES_SENSEI_EFFECT_BREATHING_MAX;
@@ -40,7 +40,7 @@ RGBController_SteelSeriesSensei::RGBController_SteelSeriesSensei(SteelSeriesSens
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = STEELSERIES_SENSEI_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE;
Rainbow.flags = MODE_FLAG_HAS_SPEED;
Rainbow.color_mode = MODE_COLORS_NONE;
Rainbow.speed_min = STEELSERIES_SENSEI_EFFECT_RAINBOW_MIN;
Rainbow.speed_max = STEELSERIES_SENSEI_EFFECT_RAINBOW_MAX;
@@ -141,8 +141,3 @@ void RGBController_SteelSeriesSensei::DeviceUpdateMode()
\*---------------------------------------------------------*/
DeviceUpdateLEDs();
}
void RGBController_SteelSeriesSensei::DeviceSaveMode()
{
sensei->Save();
}
@@ -28,7 +28,6 @@ public:
void SetCustomMode();
void DeviceUpdateMode();
void DeviceSaveMode();
private:
SteelSeriesSenseiController* sensei;
@@ -1,5 +1,6 @@
#include "Detector.h"
#include "SteelSeriesRivalController.h"
#include "SteelSeriesRival3Controller.h"
#include "SteelSeriesSiberiaController.h"
#include "SteelSeriesQCKMatController.h"
#include "SteelSeriesApexController.h"
@@ -9,6 +10,7 @@
#include "SteelSeriesGeneric.h"
#include "RGBController.h"
#include "RGBController_SteelSeriesRival.h"
#include "RGBController_SteelSeriesRival3.h"
#include "RGBController_SteelSeriesSiberia.h"
#include "RGBController_SteelSeriesQCKMat.h"
#include "RGBController_SteelSeriesApex.h"
@@ -38,8 +40,12 @@
#define STEELSERIES_RIVAL_310_PID 0x1720
#define STEELSERIES_RIVAL_310_CSGO_HOWL_PID 0x171e
#define STEELSERIES_RIVAL_310_PUBG_PID 0x1736
#define STEELSERIES_RIVAL_600_PID 0x1724
#define STEELSERIES_RIVAL_600_DOTA_2_PID 0x172E
#define STEELSERIES_RIVAL_650_PID 0x172B
#define STEELSERIES_RIVAL_650_WIRELESS_PID 0x1726
#define STEELSERIES_RIVAL_3_OLD_PID 0x1824
#define STEELSERIES_RIVAL_3_PID 0x184C
#define STEELSERIES_SENSEI_TEN_PID 0x1832
#define STEELSERIES_SENSEI_TEN_CSGO_NEON_RIDER_PID 0x1834
#define STEELSERIES_SENSEI_310_PID 0x1722
@@ -159,6 +165,20 @@ void DetectSteelSeriesRival300(hid_device_info* info, const std::string& name)
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectSteelSeriesRival600(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
SteelSeriesRivalController* controller = new SteelSeriesRivalController(dev, RIVAL_600, info->path);
RGBController_SteelSeriesRival* rgb_controller = new RGBController_SteelSeriesRival(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectSteelSeriesRival650(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
@@ -171,6 +191,18 @@ void DetectSteelSeriesRival650(hid_device_info* info, const std::string& name)
}
}
void DetectSteelSeriesRival3(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
SteelSeriesRival3Controller* controller = new SteelSeriesRival3Controller(dev, RIVAL_3, info->path);
RGBController_SteelSeriesRival3* rgb_controller = new RGBController_SteelSeriesRival3(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectSteelSeriesSensei(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
@@ -201,8 +233,12 @@ REGISTER_HID_DETECTOR_I("SteelSeries Rival 300 Black Ops Edition", Dete
REGISTER_HID_DETECTOR_I("SteelSeries Rival 310", DetectSteelSeriesSensei, STEELSERIES_VID, STEELSERIES_RIVAL_310_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Rival 310 CS:GO Howl Edition", DetectSteelSeriesSensei, STEELSERIES_VID, STEELSERIES_RIVAL_310_CSGO_HOWL_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Rival 310 PUBG Edition", DetectSteelSeriesSensei, STEELSERIES_VID, STEELSERIES_RIVAL_310_PUBG_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Rival 600", DetectSteelSeriesRival600, STEELSERIES_VID, STEELSERIES_RIVAL_600_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Rival 600 Dota 2 Edition", DetectSteelSeriesRival600, STEELSERIES_VID, STEELSERIES_RIVAL_600_DOTA_2_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Rival 650", DetectSteelSeriesRival650, STEELSERIES_VID, STEELSERIES_RIVAL_650_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Rival 650 Wireless", DetectSteelSeriesRival650, STEELSERIES_VID, STEELSERIES_RIVAL_650_WIRELESS_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Rival 3 (Old Firmware)", DetectSteelSeriesRival3, STEELSERIES_VID, STEELSERIES_RIVAL_3_OLD_PID, 3);
REGISTER_HID_DETECTOR_I("SteelSeries Rival 3", DetectSteelSeriesRival3, STEELSERIES_VID, STEELSERIES_RIVAL_3_PID, 3);
REGISTER_HID_DETECTOR_I("SteelSeries Sensei TEN", DetectSteelSeriesSensei, STEELSERIES_VID, STEELSERIES_SENSEI_TEN_PID, 0 );
REGISTER_HID_DETECTOR_I("SteelSeries Sensei TEN CS:GO Neon Rider Edition", DetectSteelSeriesSensei, STEELSERIES_VID, STEELSERIES_SENSEI_TEN_CSGO_NEON_RIDER_PID,0 );
REGISTER_HID_DETECTOR_I("SteelSeries Sensei 310", DetectSteelSeriesSensei, STEELSERIES_VID, STEELSERIES_SENSEI_310_PID, 0 );
@@ -26,5 +26,7 @@ typedef enum
APEX_M = 0x06,
APEX_OLD = 0x07,
SENSEI = 0x08,
RIVAL_600 = 0x09,
RIVAL_3 = 0x0a,
} steelseries_type;
@@ -0,0 +1,116 @@
/*-----------------------------------------*\
| SteelSeriesRival3Controller.h |
| |
| Definitions and types for SteelSeries |
| Rival 3 lighting controller |
| |
| B Horn (bahorn) 29/8/2021 |
\*-----------------------------------------*/
#include "SteelSeriesRival3Controller.h"
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
SteelSeriesRival3Controller::SteelSeriesRival3Controller
(
hid_device* dev_handle,
steelseries_type proto_type,
const char* path
)
{
dev = dev_handle;
location = path;
proto = proto_type;
}
SteelSeriesRival3Controller::~SteelSeriesRival3Controller()
{
hid_close(dev);
}
std::string SteelSeriesRival3Controller::GetDeviceLocation()
{
return("HID: " + location);
}
char* SteelSeriesRival3Controller::GetDeviceName()
{
return device_name;
}
std::string SteelSeriesRival3Controller::GetSerialString()
{
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if (ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
std::string SteelSeriesRival3Controller::GetFirmwareVersion()
{
const uint8_t FW_BUFFER_SIZE = 3;
uint8_t usb_buf[FW_BUFFER_SIZE] = { 0x00, 0x10, 0x00 };
uint16_t version;
std::string return_string;
hid_write(dev, usb_buf, FW_BUFFER_SIZE);
hid_read(dev, (unsigned char *)&version, 2);
return_string = std::to_string(version);
return return_string;
}
steelseries_type SteelSeriesRival3Controller::GetMouseType()
{
return proto;
}
void SteelSeriesRival3Controller::Save()
{
const uint8_t SAVE_BUFFER_SIZE = 10;
uint8_t usb_buf[SAVE_BUFFER_SIZE] = { 0x00, 0x09 };
hid_write(dev, usb_buf, SAVE_BUFFER_SIZE);
}
void SteelSeriesRival3Controller::SetLightEffectAll(uint8_t effect)
{
const uint8_t EFFECT_BUFFER_SIZE = 4;
uint8_t usb_buf[EFFECT_BUFFER_SIZE] = { 0x00, 0x06, 0x00, effect };
hid_write(dev, usb_buf, EFFECT_BUFFER_SIZE);
}
void SteelSeriesRival3Controller::SetColor
(
unsigned char zone_id,
unsigned char red,
unsigned char green,
unsigned char blue,
unsigned char brightness
)
{
const uint8_t COLOR_BUFFER_SIZE = 8;
uint8_t usb_buf[COLOR_BUFFER_SIZE];
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x05;
usb_buf[0x02] = 0x00;
usb_buf[0x03] = zone_id;
usb_buf[0x04] = red;
usb_buf[0x05] = green;
usb_buf[0x06] = blue;
usb_buf[0x07] = brightness;
hid_write(dev, usb_buf, COLOR_BUFFER_SIZE);
}
@@ -0,0 +1,70 @@
/*-----------------------------------------*\
| SteelSeriesRival3Controller.h |
| |
| Definitions and types for SteelSeries |
| Rival 3 lighting controller |
| |
| B Horn (bahorn) 29/8/2021 |
\*-----------------------------------------*/
#include <string>
#include <hidapi/hidapi.h>
#include "SteelSeriesGeneric.h"
#pragma once
#define STEELSERIES_RIVAL_3_BRIGHTNESS_MAX 0x64
/*-----------------------------------------------------------*\
| Theses are the specific values that get sent to set a mode |
\*-----------------------------------------------------------*/
enum
{
STEELSERIES_RIVAL_3_EFFECT_SPECTRUM_CYCLE = 0x00,
STEELSERIES_RIVAL_3_EFFECT_BREATHING_MAX = 0x01,
STEELSERIES_RIVAL_3_EFFECT_BREATHING_MID = 0x02,
STEELSERIES_RIVAL_3_EFFECT_BREATHING_MIN = 0x03,
STEELSERIES_RIVAL_3_EFFECT_DIRECT = 0x04,
STEELSERIES_RIVAL_3_EFFECT_RAINBOW_BREATHING = 0x05,
STEELSERIES_RIVAL_3_EFFECT_DISCO = 0x06
};
class SteelSeriesRival3Controller
{
public:
SteelSeriesRival3Controller
(
hid_device* dev_handle,
steelseries_type proto_type,
const char* path
);
~SteelSeriesRival3Controller();
std::string GetDeviceLocation();
char* GetDeviceName();
std::string GetSerialString();
std::string GetFirmwareVersion();
steelseries_type GetMouseType();
void Save();
void SetLightEffectAll(uint8_t effect);
void SetColor
(
unsigned char zone_id,
unsigned char red,
unsigned char green,
unsigned char blue,
unsigned char brightness
);
private:
char device_name[32];
hid_device* dev;
std::string location;
steelseries_type proto;
};
@@ -24,7 +24,7 @@ static void send_usb_msg(hid_device* dev, char * data_pkt, unsigned int size)
hid_write(dev, (unsigned char *)usb_pkt, size + 1);
delete usb_pkt;
delete[] usb_pkt;
}
SteelSeriesRivalController::SteelSeriesRivalController
@@ -84,7 +84,6 @@ void SteelSeriesRivalController::Save()
send_usb_msg(dev, usb_buf, 9);
}
void SteelSeriesRivalController::SetLightEffect
(
unsigned char zone_id,
@@ -112,7 +111,6 @@ void SteelSeriesRivalController::SetLightEffect
send_usb_msg(dev, usb_buf, 9);
}
void SteelSeriesRivalController::SetLightEffectAll
(
unsigned char effect
@@ -162,13 +160,13 @@ void SteelSeriesRivalController::SetRival650Color
usb_buf[0x1F] = red;
usb_buf[0x20] = green;
usb_buf[0x21] = blue;
usb_buf[0x22] = 0xff;
usb_buf[0x27] = 0xff;
usb_buf[0x22] = 0xFF;
usb_buf[0x27] = 0xFF;
usb_buf[0x29] = 0x54;
usb_buf[0x2c] = 0xff;
usb_buf[0x2d] = 0x54;
usb_buf[0x2e] = red;
usb_buf[0x2f] = green;
usb_buf[0x2C] = 0xFF;
usb_buf[0x2D] = 0x54;
usb_buf[0x2E] = red;
usb_buf[0x2F] = green;
usb_buf[0x30] = blue;
usb_buf[0x31] = 0x56;
@@ -177,26 +175,73 @@ void SteelSeriesRivalController::SetRival650Color
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x00] = 0x03;
usb_buf[0x02] = 0x30;
usb_buf[0x04] = 0x2c;
usb_buf[0x04] = 0x2C;
send_usb_msg(dev, usb_buf, 60);
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x00] = 0x05;
usb_buf[0x02] = zone_id;//mousekey 0x10-0x17
usb_buf[0x03] = 0xff;
usb_buf[0x08] = 0x5c;
usb_buf[0x03] = 0xFF;
usb_buf[0x08] = 0x5C;
send_usb_msg(dev, usb_buf, 60);
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x00] = 0x1c;
usb_buf[0x00] = 0x1C;
usb_buf[0x02] = 0x55;
usb_buf[0x04] = 0x46;
send_usb_msg(dev, usb_buf, 60);
}
void SteelSeriesRivalController::SetRival600Color
(
unsigned char zone_id,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
char usb_buf[0x25];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x00] = 0x05;
memset(usb_buf+0x2, zone_id, 6);
usb_buf[0x08] = 0xE8; //set time to 1000
usb_buf[0x09] = 0x3;
usb_buf[0x18] = 1; //set trigger flag
usb_buf[0x1D] = 1; //set number of colors
usb_buf[0x1E] = red;
usb_buf[0x1F] = green;
usb_buf[0x20] = blue;
usb_buf[0x21] = red;
usb_buf[0x22] = green;
usb_buf[0x23] = blue;
unsigned char* usb_pkt = new unsigned char[0x25 + 1];
usb_pkt[0] = 0x00;
for(unsigned int i = 1; i < 0x25 + 1; i++)
{
usb_pkt[i] = usb_buf[i-1];
}
hid_write(dev, (unsigned char *)usb_pkt, 0x25 + 1);
hid_send_feature_report(dev, (unsigned char *)usb_pkt, 0x25 + 1);
delete [] usb_pkt;
usb_buf[0x00] = 0x09;
usb_buf[0x01] = 0x00;
send_usb_msg(dev, usb_buf, 0x02);
}
void SteelSeriesRivalController::SetColor
(
unsigned char zone_id,
@@ -213,7 +258,7 @@ void SteelSeriesRivalController::SetColor
usb_buf[0x00] = 0x05;
usb_buf[0x01] = 0x00;
break;
case RIVAL_300:
usb_buf[0x00] = 0x08;
usb_buf[0x01] = zone_id + 1;
@@ -223,6 +268,10 @@ void SteelSeriesRivalController::SetColor
SetRival650Color(zone_id, red, green, blue);
return;
case RIVAL_600:
SetRival600Color(zone_id, red, green, blue);
return;
default:
break;
}
@@ -88,4 +88,12 @@ private:
unsigned char green,
unsigned char blue
);
void SetRival600Color
(
unsigned char zone_id,
unsigned char red,
unsigned char green,
unsigned char blue
);
};
@@ -90,7 +90,7 @@ void SteelSeriesSenseiController::Save()
/*-----------------------------------------------------*\
| Set up Save packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x09;
usb_buf[0x00] = 0x59;
/*-----------------------------------------------------*\
| Send packet |
+1 -1
View File
@@ -9,7 +9,7 @@
#include "filesystem.h"
static const char* log_codes[] = {"FATAL:", "ERROR:", "Warning:", "Info:", "[verbose]", "Debug:", "Trace:"};
static const char* log_codes[] = {"FATAL:", "ERROR:", "Warning:", "Info:", "Verbose:", "Debug:", "Trace:"};
LogManager::LogManager()
{
+59 -1
View File
@@ -20,6 +20,15 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
greaterThan(QT_MAJOR_VERSION, 5): DEFINES += _QT6
#-----------------------------------------------------------------------------------------------#
# pkg-config Configuration #
#-----------------------------------------------------------------------------------------------#
greaterThan(QT_MAJOR_VERSION, 4) {
PKG_CONFIG = $$pkgConfigExecutable()
} else {
PKG_CONFIG = "pkgconf"
}
#-----------------------------------------------------------------------------------------------#
# Application Configuration #
#-----------------------------------------------------------------------------------------------#
@@ -63,6 +72,7 @@ INCLUDEPATH +=
super_io/ \
AutoStart/ \
Controllers/AlienwareController/ \
Controllers/AlienwareKeyboardController/ \
Controllers/AMDWraithPrismController/ \
Controllers/ASRockPolychromeSMBusController/ \
Controllers/ASRockPolychromeUSBController/ \
@@ -165,6 +175,9 @@ HEADERS +=
qt/DeviceView.h \
qt/OpenRGBDialog2.h \
qt/OpenRGBPluginContainer.h \
qt/OpenRGBPluginsPage/OpenRGBPluginsEntry.h \
qt/OpenRGBPluginsPage/OpenRGBPluginsList.h \
qt/OpenRGBPluginsPage/OpenRGBPluginsPage.h \
qt/OpenRGBProfileSaveDialog.h \
qt/OpenRGBServerInfoPage.h \
qt/OpenRGBSettingsPage.h \
@@ -174,10 +187,15 @@ HEADERS +=
qt/OpenRGBZoneResizeDialog.h \
qt/OpenRGBE131SettingsPage/OpenRGBE131SettingsEntry.h \
qt/OpenRGBE131SettingsPage/OpenRGBE131SettingsPage.h \
qt/OpenRGBPhilipsWizSettingsPage/OpenRGBPhilipsWizSettingsEntry.h \
qt/OpenRGBPhilipsWizSettingsPage/OpenRGBPhilipsWizSettingsPage.h \
qt/OpenRGBQMKORGBSettingsPage/OpenRGBQMKORGBSettingsEntry.h \
qt/OpenRGBQMKORGBSettingsPage/OpenRGBQMKORGBSettingsPage.h \
qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsEntry.h \
qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsPage.h \
qt/OpenRGBYeelightSettingsPage/OpenRGBYeelightSettingsEntry.h \
qt/OpenRGBYeelightSettingsPage/OpenRGBYeelightSettingsPage.h \
qt/OpenRGBZonesBulkResizer.h \
qt/TabLabel.h \
serial_port/find_usb_serial_port.h \
serial_port/serial_port.h \
@@ -185,6 +203,8 @@ HEADERS +=
AutoStart/AutoStart.h \
Controllers/AlienwareController/AlienwareController.h \
Controllers/AlienwareController/RGBController_Alienware.h \
Controllers/AlienwareKeyboardController/AlienwareAW510KController.h \
Controllers/AlienwareKeyboardController/RGBController_AlienwareAW510K.h \
Controllers/AMDWraithPrismController/AMDWraithPrismController.h \
Controllers/AMDWraithPrismController/RGBController_AMDWraithPrism.h \
Controllers/AnnePro2Controller/AnnePro2Controller.h \
@@ -239,7 +259,9 @@ HEADERS +=
Controllers/CorsairLightingNodeController/CorsairLightingNodeController.h \
Controllers/CorsairLightingNodeController/RGBController_CorsairLightingNode.h \
Controllers/CorsairPeripheralController/CorsairPeripheralController.h \
Controllers/CorsairPeripheralController/CorsairK100Controller.h \
Controllers/CorsairPeripheralController/RGBController_CorsairPeripheral.h \
Controllers/CorsairPeripheralController/RGBController_CorsairK100.h \
Controllers/CorsairVengeanceController/CorsairVengeanceController.h \
Controllers/CorsairVengeanceController/RGBController_CorsairVengeance.h \
Controllers/CorsairVengeanceProController/CorsairVengeanceProController.h \
@@ -304,9 +326,11 @@ HEADERS +=
Controllers/HyperXKeyboardController/RGBController_HyperXAlloyOriginsCore.h \
Controllers/HyperXKeyboardController/RGBController_HyperXKeyboard.h \
Controllers/HyperXMouseController/HyperXPulsefireFPSProController.h \
Controllers/HyperXMouseController/HyperXPulsefireHasteController.h \
Controllers/HyperXMouseController/HyperXPulsefireSurgeController.h \
Controllers/HyperXMouseController/HyperXPulsefireDartController.h \
Controllers/HyperXMouseController/RGBController_HyperXPulsefireFPSPro.h \
Controllers/HyperXMouseController/RGBController_HyperXPulsefireHaste.h \
Controllers/HyperXMouseController/RGBController_HyperXPulsefireSurge.h \
Controllers/HyperXMouseController/RGBController_HyperXPulsefireDart.h \
Controllers/HyperXMousematController/HyperXMousematController.h \
@@ -323,6 +347,7 @@ HEADERS +=
Controllers/LogitechController/LogitechG810Controller.h \
Controllers/LogitechController/LogitechG910Controller.h \
Controllers/LogitechController/LogitechG815Controller.h \
Controllers/LogitechController/LogitechG915Controller.h \
Controllers/LogitechController/LogitechGLightsyncController.h \
Controllers/LogitechController/LogitechLightspeedController.h \
Controllers/LogitechController/LogitechX56Controller.h \
@@ -333,6 +358,7 @@ HEADERS +=
Controllers/LogitechController/RGBController_LogitechG810.h \
Controllers/LogitechController/RGBController_LogitechG910.h \
Controllers/LogitechController/RGBController_LogitechG815.h \
Controllers/LogitechController/RGBController_LogitechG915.h \
Controllers/LogitechController/RGBController_LogitechGLightsync.h \
Controllers/LogitechController/RGBController_LogitechGLightsync1zone.h \
Controllers/LogitechController/RGBController_LogitechGPowerPlay.h \
@@ -383,8 +409,10 @@ HEADERS +=
Controllers/SapphireGPUController/RGBController_SapphireNitroGlowV3.h \
Controllers/SinowealthController/SinowealthController.h \
Controllers/SinowealthController/SinowealthKeyboardController.h \
Controllers/SinowealthController/SinowealthKeyboard16Controller.h \
Controllers/SinowealthController/RGBController_Sinowealth.h \
Controllers/SinowealthController/RGBController_SinowealthKeyboard.h \
Controllers/SinowealthController/RGBController_SinowealthKeyboard16.h \
Controllers/SonyDS4Controller/SonyDS4Controller.h \
Controllers/SonyDS4Controller/RGBController_SonyDS4.h \
Controllers/SteelSeriesController/color32.h \
@@ -394,12 +422,14 @@ HEADERS +=
Controllers/SteelSeriesController/SteelSeriesGeneric.h \
Controllers/SteelSeriesController/SteelSeriesOldApexController.h \
Controllers/SteelSeriesController/SteelSeriesRivalController.h \
Controllers/SteelSeriesController/SteelSeriesRival3Controller.h \
Controllers/SteelSeriesController/SteelSeriesSenseiController.h \
Controllers/SteelSeriesController/SteelSeriesSiberiaController.h \
Controllers/SteelSeriesController/SteelSeriesQCKMatController.h \
Controllers/SteelSeriesController/RGBController_SteelSeriesApex.h \
Controllers/SteelSeriesController/RGBController_SteelSeriesOldApex.h \
Controllers/SteelSeriesController/RGBController_SteelSeriesRival.h \
Controllers/SteelSeriesController/RGBController_SteelSeriesRival3.h \
Controllers/SteelSeriesController/RGBController_SteelSeriesSiberia.h \
Controllers/SteelSeriesController/RGBController_SteelSeriesQCKMat.h \
Controllers/SteelSeriesController/RGBController_SteelSeriesSensei.h \
@@ -478,6 +508,9 @@ SOURCES +=
qt/DeviceView.cpp \
qt/OpenRGBDialog2.cpp \
qt/OpenRGBPluginContainer.cpp \
qt/OpenRGBPluginsPage/OpenRGBPluginsEntry.cpp \
qt/OpenRGBPluginsPage/OpenRGBPluginsList.cpp \
qt/OpenRGBPluginsPage/OpenRGBPluginsPage.cpp \
qt/OpenRGBProfileSaveDialog.cpp \
qt/OpenRGBServerInfoPage.cpp \
qt/OpenRGBSettingsPage.cpp \
@@ -485,20 +518,28 @@ SOURCES +=
qt/OpenRGBSupportedDevicesPage.cpp \
qt/OpenRGBSystemInfoPage.cpp \
qt/OpenRGBZoneResizeDialog.cpp \
qt/OpenRGBZonesBulkResizer.cpp \
qt/TabLabel.cpp \
qt/hsv.cpp \
qt/OpenRGBE131SettingsPage/OpenRGBE131SettingsEntry.cpp \
qt/OpenRGBE131SettingsPage/OpenRGBE131SettingsPage.cpp \
qt/OpenRGBPhilipsWizSettingsPage/OpenRGBPhilipsWizSettingsEntry.cpp \
qt/OpenRGBPhilipsWizSettingsPage/OpenRGBPhilipsWizSettingsPage.cpp \
qt/OpenRGBQMKORGBSettingsPage/OpenRGBQMKORGBSettingsEntry.cpp \
qt/OpenRGBQMKORGBSettingsPage/OpenRGBQMKORGBSettingsPage.cpp \
qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsEntry.cpp \
qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsPage.cpp \
qt/OpenRGBYeelightSettingsPage/OpenRGBYeelightSettingsEntry.cpp \
qt/OpenRGBYeelightSettingsPage/OpenRGBYeelightSettingsPage.cpp \
serial_port/serial_port.cpp \
super_io/super_io.cpp \
AutoStart/AutoStart.cpp \
Controllers/AlienwareController/AlienwareController.cpp \
Controllers/AlienwareController/AlienwareControllerDetect.cpp \
Controllers/AlienwareController/RGBController_Alienware.cpp \
Controllers/AlienwareKeyboardController/AlienwareAW510KController.cpp \
Controllers/AlienwareKeyboardController/AlienwareKeyboardControllerDetect.cpp \
Controllers/AlienwareKeyboardController/RGBController_AlienwareAW510K.cpp \
Controllers/AMDWraithPrismController/AMDWraithPrismController.cpp \
Controllers/AMDWraithPrismController/AMDWraithPrismControllerDetect.cpp \
Controllers/AMDWraithPrismController/RGBController_AMDWraithPrism.cpp \
@@ -568,7 +609,9 @@ SOURCES +=
Controllers/CorsairLightingNodeController/RGBController_CorsairLightingNode.cpp \
Controllers/CorsairPeripheralController/CorsairPeripheralController.cpp \
Controllers/CorsairPeripheralController/CorsairPeripheralControllerDetect.cpp \
Controllers/CorsairPeripheralController/CorsairK100Controller.cpp \
Controllers/CorsairPeripheralController/RGBController_CorsairPeripheral.cpp \
Controllers/CorsairPeripheralController/RGBController_CorsairK100.cpp \
Controllers/CorsairVengeanceController/CorsairVengeanceController.cpp \
Controllers/CorsairVengeanceController/CorsairVengeanceControllerDetect.cpp \
Controllers/CorsairVengeanceController/RGBController_CorsairVengeance.cpp \
@@ -660,9 +703,11 @@ SOURCES +=
Controllers/HyperXKeyboardController/RGBController_HyperXKeyboard.cpp \
Controllers/HyperXMouseController/HyperXMouseControllerDetect.cpp \
Controllers/HyperXMouseController/HyperXPulsefireFPSProController.cpp \
Controllers/HyperXMouseController/HyperXPulsefireHasteController.cpp \
Controllers/HyperXMouseController/HyperXPulsefireSurgeController.cpp \
Controllers/HyperXMouseController/HyperXPulsefireDartController.cpp \
Controllers/HyperXMouseController/RGBController_HyperXPulsefireFPSPro.cpp \
Controllers/HyperXMouseController/RGBController_HyperXPulsefireHaste.cpp \
Controllers/HyperXMouseController/RGBController_HyperXPulsefireSurge.cpp \
Controllers/HyperXMouseController/RGBController_HyperXPulsefireDart.cpp \
Controllers/HyperXMousematController/HyperXMousematController.cpp \
@@ -683,6 +728,7 @@ SOURCES +=
Controllers/LogitechController/LogitechG810Controller.cpp \
Controllers/LogitechController/LogitechG910Controller.cpp \
Controllers/LogitechController/LogitechG815Controller.cpp \
Controllers/LogitechController/LogitechG915Controller.cpp \
Controllers/LogitechController/LogitechGLightsyncController.cpp \
Controllers/LogitechController/LogitechLightspeedController.cpp \
Controllers/LogitechController/LogitechX56Controller.cpp \
@@ -693,6 +739,7 @@ SOURCES +=
Controllers/LogitechController/RGBController_LogitechG810.cpp \
Controllers/LogitechController/RGBController_LogitechG910.cpp \
Controllers/LogitechController/RGBController_LogitechG815.cpp \
Controllers/LogitechController/RGBController_LogitechG915.cpp \
Controllers/LogitechController/RGBController_LogitechGLightsync.cpp \
Controllers/LogitechController/RGBController_LogitechGLightsync1zone.cpp \
Controllers/LogitechController/RGBController_LogitechGPowerPlay.cpp \
@@ -756,9 +803,11 @@ SOURCES +=
Controllers/SapphireGPUController/RGBController_SapphireNitroGlowV3.cpp \
Controllers/SinowealthController/SinowealthController.cpp \
Controllers/SinowealthController/SinowealthKeyboardController.cpp \
Controllers/SinowealthController/SinowealthKeyboard16Controller.cpp \
Controllers/SinowealthController/SinowealthControllerDetect.cpp \
Controllers/SinowealthController/RGBController_Sinowealth.cpp \
Controllers/SinowealthController/RGBController_SinowealthKeyboard.cpp \
Controllers/SinowealthController/RGBController_SinowealthKeyboard16.cpp \
Controllers/SonyDS4Controller/SonyDS4Controller.cpp \
Controllers/SonyDS4Controller/SonyDS4ControllerDetect.cpp \
Controllers/SonyDS4Controller/RGBController_SonyDS4.cpp \
@@ -766,6 +815,7 @@ SOURCES +=
Controllers/SteelSeriesController/SteelSeriesApexMController.cpp \
Controllers/SteelSeriesController/SteelSeriesOldApexController.cpp \
Controllers/SteelSeriesController/SteelSeriesRivalController.cpp \
Controllers/SteelSeriesController/SteelSeriesRival3Controller.cpp \
Controllers/SteelSeriesController/SteelSeriesSenseiController.cpp \
Controllers/SteelSeriesController/SteelSeriesSiberiaController.cpp \
Controllers/SteelSeriesController/SteelSeriesQCKMatController.cpp \
@@ -773,6 +823,7 @@ SOURCES +=
Controllers/SteelSeriesController/RGBController_SteelSeriesApex.cpp \
Controllers/SteelSeriesController/RGBController_SteelSeriesOldApex.cpp \
Controllers/SteelSeriesController/RGBController_SteelSeriesRival.cpp \
Controllers/SteelSeriesController/RGBController_SteelSeriesRival3.cpp \
Controllers/SteelSeriesController/RGBController_SteelSeriesSensei.cpp \
Controllers/SteelSeriesController/RGBController_SteelSeriesSiberia.cpp \
Controllers/SteelSeriesController/RGBController_SteelSeriesQCKMat.cpp \
@@ -812,6 +863,8 @@ FORMS +=
qt/OpenRGBDialog.ui \
qt/OpenRGBDialog2.ui \
qt/OpenRGBPluginContainer.ui \
qt/OpenRGBPluginsPage/OpenRGBPluginsEntry.ui \
qt/OpenRGBPluginsPage/OpenRGBPluginsPage.ui \
qt/OpenRGBProfileSaveDialog.ui \
qt/OpenRGBServerInfoPage.ui \
qt/OpenRGBSettingsPage.ui \
@@ -821,10 +874,15 @@ FORMS +=
qt/OpenRGBZoneResizeDialog.ui \
qt/OpenRGBE131SettingsPage/OpenRGBE131SettingsEntry.ui \
qt/OpenRGBE131SettingsPage/OpenRGBE131SettingsPage.ui \
qt/OpenRGBPhilipsWizSettingsPage/OpenRGBPhilipsWizSettingsEntry.ui \
qt/OpenRGBPhilipsWizSettingsPage/OpenRGBPhilipsWizSettingsPage.ui \
qt/OpenRGBQMKORGBSettingsPage/OpenRGBQMKORGBSettingsEntry.ui \
qt/OpenRGBQMKORGBSettingsPage/OpenRGBQMKORGBSettingsPage.ui \
qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsEntry.ui \
qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsPage.ui \
qt/OpenRGBYeelightSettingsPage/OpenRGBYeelightSettingsEntry.ui \
qt/OpenRGBYeelightSettingsPage/OpenRGBYeelightSettingsPage.ui \
qt/OpenRGBZonesBulkResizer.ui \
qt/TabLabel.ui \
#-----------------------------------------------------------------------------------------------#
@@ -1068,7 +1126,7 @@ unix:!macx {
# hidapi-hidraw >= 0.10.1 supports USAGE/USAGE_PAGE #
# Define USE_HID_USAGE if hidapi-hidraw supports it #
#---------------------------------------------------------------------------------------#
HIDAPI_HIDRAW_VERSION = $$system(pkgconf --modversion hidapi-hidraw)
HIDAPI_HIDRAW_VERSION = $$system($$PKG_CONFIG --modversion hidapi-hidraw)
if(versionAtLeast(HIDAPI_HIDRAW_VERSION, "0.10.1")) {
DEFINES += USE_HID_USAGE
}
+45 -10
View File
@@ -13,17 +13,44 @@
#include <QtPlugin>
#include <QLabel>
#include <QMenu>
#define OpenRGBPluginInterface_IID "com.OpenRGBPluginInterface"
#define OpenRGBPluginInterface_IID "com.OpenRGBPluginInterface"
#define OPENRGB_PLUGIN_API_VERSION 1
/*-----------------------------------------------------------------------------------------------------*\
| Plugin Tab Location Values |
\*-----------------------------------------------------------------------------------------------------*/
enum
{
OPENRGB_PLUGIN_LOCATION_TOP = 0, /* Top-level tab (no icon) */
OPENRGB_PLUGIN_LOCATION_DEVICES = 1, /* Devices tab */
OPENRGB_PLUGIN_LOCATION_INFORMATION = 2, /* Information tab */
OPENRGB_PLUGIN_LOCATION_SETTINGS = 3, /* Settings tab */
};
struct OpenRGBPluginInfo
{
std::string PluginName;
std::string PluginDescription;
std::string PluginLocation;
/*-------------------------------------------------------------------------------------------------*\
| Plugin Details |
\*-------------------------------------------------------------------------------------------------*/
std::string Name; /* Plugin name string */
std::string Description; /* Plugin description string */
std::string Version; /* Plugin version string */
std::string Commit; /* Plugin commit (git or otherwise) string */
std::string URL; /* Plugin project URL string */
QImage Icon; /* Icon image (displayed 64x64) */
bool HasCustom;
QLabel *PluginLabel;
/*-------------------------------------------------------------------------------------------------*\
| Plugin Tab Configuration |
\*-------------------------------------------------------------------------------------------------*/
unsigned int Location; /* Plugin tab location from Plugin Tab Location enum */
/* This field is mandatory, an invalid value will */
/* prevent plugin tab from being displayed */
std::string Label; /* Plugin tab label string */
std::string TabIconString; /* Plugin tab icon string, leave empty to use custom */
QImage TabIcon; /* Custom tab icon image (displayed 16x16) */
};
class OpenRGBPluginInterface
@@ -31,11 +58,19 @@ class OpenRGBPluginInterface
public:
virtual ~OpenRGBPluginInterface() {}
virtual OpenRGBPluginInfo Initialize(bool dark_theme, ResourceManager* resource_manager_ptr) = 0;
/*-------------------------------------------------------------------------------------------------*\
| Plugin Information |
\*-------------------------------------------------------------------------------------------------*/
virtual OpenRGBPluginInfo GetPluginInfo() = 0;
virtual unsigned int GetPluginAPIVersion() = 0;
virtual QWidget *CreateGUI(QWidget* parent) = 0;
OpenRGBPluginInfo info;
/*-------------------------------------------------------------------------------------------------*\
| Plugin Functionality |
\*-------------------------------------------------------------------------------------------------*/
virtual void Load(bool dark_theme, ResourceManager* resource_manager_ptr) = 0;
virtual QWidget* GetWidget() = 0;
virtual QMenu* GetTrayMenu() = 0;
virtual void Unload() = 0;
};
Q_DECLARE_INTERFACE(OpenRGBPluginInterface, OpenRGBPluginInterface_IID)
+309 -35
View File
@@ -1,57 +1,331 @@
#include "LogManager.h"
#include "PluginManager.h"
void PluginManager::ScanAndLoadPlugins(bool dark_theme)
PluginManager::PluginManager(bool dark_theme_val)
{
/*---------------------------------------------------------*\
| Initialize plugin manager class variables |
\*---------------------------------------------------------*/
dark_theme = dark_theme_val;
AddPluginCallbackVal = nullptr;
AddPluginCallbackArg = nullptr;
RemovePluginCallbackVal = nullptr;
RemovePluginCallbackArg = nullptr;
}
void PluginManager::RegisterAddPluginCallback(AddPluginCallback new_callback, void * new_callback_arg)
{
AddPluginCallbackVal = new_callback;
AddPluginCallbackArg = new_callback_arg;
}
void PluginManager::RegisterRemovePluginCallback(RemovePluginCallback new_callback, void * new_callback_arg)
{
RemovePluginCallbackVal = new_callback;
RemovePluginCallbackArg = new_callback_arg;
}
void PluginManager::ScanAndLoadPlugins()
{
LOG_INFO("Loading plugins");
std::string OpenRGBConfigDir = ResourceManager::get()->GetConfigurationDirectory();
std::string PluginPath = OpenRGBConfigDir + "/Plugins";
/*--------------------------------------------------------------------------------------*\
| I used https://github.com/krf/cmake-qtqml-plugin-example to figure out how to do this |
| So BIG credit to krf |
\*--------------------------------------------------------------------------------------*/
OpenRGBPluginInterface *OpenRGBPlugin = nullptr;
const QDir pluginsDir = QString().fromStdString(ResourceManager::get()->GetConfigurationDirectory()) + "plugins/";
/*---------------------------------------------------------*\
| Get the plugins directory |
| |
| The plugins directory is a directory named "plugins" in |
| the configuration directory |
\*---------------------------------------------------------*/
const QDir plugins_dir = QString().fromStdString(ResourceManager::get()->GetConfigurationDirectory()) + "plugins/";
/*---------------------------------------------------------*\
| Get a list of all files in the plugins directory |
\*---------------------------------------------------------*/
std::vector<std::string> FileList;
for(int i = 0; i < QDir(pluginsDir).entryList(QDir::Files).size(); i++)
for(int i = 0; i < QDir(plugins_dir).entryList(QDir::Files).size(); i++)
{
/*--------------------------------------*\
| Add all of the Plugin Files to a list |
\*--------------------------------------*/
FileList.push_back(QDir(pluginsDir).entryList(QDir::Files)[i].toStdString());
FileList.push_back(QDir(plugins_dir).entryList(QDir::Files)[i].toStdString());
}
for(const std::string &fileName : FileList)
/*---------------------------------------------------------*\
| Attempt to load each file in the plugins directory |
\*---------------------------------------------------------*/
for(const std::string &plugin_name : FileList)
{
const std::string filePath = pluginsDir.absoluteFilePath(QString().fromStdString(fileName)).toStdString();
const std::string plugin_path = plugins_dir.absoluteFilePath(QString().fromStdString(plugin_name)).toStdString();
LOG_VERBOSE("Attempting to load: %s", filePath.c_str());
AddPlugin(plugin_path);
}
}
QPluginLoader loader(pluginsDir.absoluteFilePath(QString().fromStdString(fileName)));
void PluginManager::AddPlugin(std::string path)
{
OpenRGBPluginInterface* plugin = nullptr;
if (QObject *instance = loader.instance())
unsigned int plugin_idx;
/*---------------------------------------------------------------------*\
| Search active plugins to see if this path already exists |
\*---------------------------------------------------------------------*/
for(plugin_idx = 0; plugin_idx < ActivePlugins.size(); plugin_idx++)
{
if(path == ActivePlugins[plugin_idx].path)
{
if ((OpenRGBPlugin = qobject_cast<OpenRGBPluginInterface*>(instance)))
{
/*-----------------------------------------------------*\
| Initialize the plugin |
\*-----------------------------------------------------*/
OpenRGBPlugin->info = OpenRGBPlugin->Initialize(dark_theme, ResourceManager::get());
LOG_VERBOSE("Loaded plugin %s", OpenRGBPlugin->info.PluginName.c_str());
PluginManager::ActivePlugins.push_back(OpenRGBPlugin);
}
break;
}
else
}
/*---------------------------------------------------------------------*\
| If the path does not match an existing entry, create a new entry |
\*---------------------------------------------------------------------*/
if(plugin_idx == ActivePlugins.size())
{
/*-----------------------------------------------------------------*\
| Create a QPluginLoader and load the plugin |
\*-----------------------------------------------------------------*/
QPluginLoader* loader = new QPluginLoader(QString().fromStdString(path));
QObject* instance = loader->instance();
/*-----------------------------------------------------------------*\
| Check that the plugin is valid, then check the API version |
\*-----------------------------------------------------------------*/
if(instance)
{
std::cout << loader.errorString().toStdString() << std::endl;
plugin = qobject_cast<OpenRGBPluginInterface*>(instance);
if(plugin)
{
if(plugin->GetPluginAPIVersion() == OPENRGB_PLUGIN_API_VERSION)
{
/*-----------------------------------------------------*\
| Get the plugin information |
\*-----------------------------------------------------*/
OpenRGBPluginInfo info = plugin->GetPluginInfo();
/*-----------------------------------------------------*\
| Search the settings to see if it is enabled |
\*-----------------------------------------------------*/
std::string name = "";
std::string description = "";
bool enabled = true;
bool found = false;
unsigned int plugin_ct = 0;
/*-----------------------------------------------------*\
| Open plugin list and check if plugin is in the list |
\*-----------------------------------------------------*/
json plugin_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("Plugins");
if(plugin_settings.contains("plugins"))
{
plugin_ct = plugin_settings["plugins"].size();
for(unsigned int plugin_idx = 0; plugin_idx < plugin_settings["plugins"].size(); plugin_idx++)
{
if(plugin_settings["plugins"][plugin_idx].contains("name"))
{
name = plugin_settings["plugins"][plugin_idx]["name"];
}
if(plugin_settings["plugins"][plugin_idx].contains("description"))
{
description = plugin_settings["plugins"][plugin_idx]["description"];
}
if(plugin_settings["plugins"][plugin_idx].contains("enabled"))
{
enabled = plugin_settings["plugins"][plugin_idx]["enabled"];
}
if((info.Name == name)
&&(info.Description == description))
{
found = true;
break;
}
}
}
/*-----------------------------------------------------*\
| If the plugin was not in the list, add it to the list |
| and default it to enabled, then save the settings |
\*-----------------------------------------------------*/
if(!found)
{
plugin_settings["plugins"][plugin_ct]["name"] = info.Name;
plugin_settings["plugins"][plugin_ct]["description"] = info.Description;
plugin_settings["plugins"][plugin_ct]["enabled"] = enabled;
ResourceManager::get()->GetSettingsManager()->SetSettings("Plugins", plugin_settings);
ResourceManager::get()->GetSettingsManager()->SaveSettings();
}
LOG_VERBOSE("Loaded plugin %s", info.Name.c_str());
/*-----------------------------------------------------*\
| Add the plugin to the PluginManager active plugins |
\*-----------------------------------------------------*/
OpenRGBPluginEntry entry;
entry.info = info;
entry.plugin = plugin;
entry.loader = loader;
entry.loaded = false;
entry.path = path;
entry.enabled = enabled;
entry.widget = nullptr;
loader->unload();
PluginManager::ActivePlugins.push_back(entry);
if(entry.enabled)
{
LoadPlugin(path);
}
}
}
}
}
}
void PluginManager::RemovePlugin(std::string path)
{
unsigned int plugin_idx;
/*---------------------------------------------------------------------*\
| Search active plugins to see if this path already exists |
\*---------------------------------------------------------------------*/
for(plugin_idx = 0; plugin_idx < ActivePlugins.size(); plugin_idx++)
{
if(path == ActivePlugins[plugin_idx].path)
{
break;
}
}
/*---------------------------------------------------------------------*\
| If the plugin path does not exist in the active plugins list, return |
\*---------------------------------------------------------------------*/
if(plugin_idx == ActivePlugins.size())
{
return;
}
/*---------------------------------------------------------------------*\
| If the selected plugin is in the list and loaded, unload it |
\*---------------------------------------------------------------------*/
if(ActivePlugins[plugin_idx].loaded)
{
UnloadPlugin(path);
}
/*---------------------------------------------------------------------*\
| Remove the plugin from the active plugins list |
\*---------------------------------------------------------------------*/
ActivePlugins.erase(ActivePlugins.begin() + plugin_idx);
}
void PluginManager::LoadPlugin(std::string path)
{
unsigned int plugin_idx;
/*---------------------------------------------------------------------*\
| Search active plugins to see if this path already exists |
\*---------------------------------------------------------------------*/
for(plugin_idx = 0; plugin_idx < ActivePlugins.size(); plugin_idx++)
{
if(path == ActivePlugins[plugin_idx].path)
{
break;
}
}
/*---------------------------------------------------------------------*\
| If the plugin path does not exist in the active plugins list, return |
\*---------------------------------------------------------------------*/
if(plugin_idx == ActivePlugins.size())
{
return;
}
/*---------------------------------------------------------------------*\
| If the selected plugin is in the list but not loaded, load it |
\*---------------------------------------------------------------------*/
if(!ActivePlugins[plugin_idx].loaded)
{
ActivePlugins[plugin_idx].loader->load();
ActivePlugins[plugin_idx].loaded = true;
QObject* instance = ActivePlugins[plugin_idx].loader->instance();
if(instance)
{
OpenRGBPluginInterface* plugin = qobject_cast<OpenRGBPluginInterface*>(instance);
if(plugin)
{
if(plugin->GetPluginAPIVersion() == OPENRGB_PLUGIN_API_VERSION)
{
ActivePlugins[plugin_idx].plugin = plugin;
plugin->Load(dark_theme, ResourceManager::get());
/*-------------------------------------------------*\
| Call the Add Plugin callback |
\*-------------------------------------------------*/
if(AddPluginCallbackArg != nullptr)
{
AddPluginCallbackVal(AddPluginCallbackArg, &ActivePlugins[plugin_idx]);
}
}
}
}
}
}
void PluginManager::UnloadPlugin(std::string path)
{
unsigned int plugin_idx;
/*---------------------------------------------------------------------*\
| Search active plugins to see if this path already exists |
\*---------------------------------------------------------------------*/
for(plugin_idx = 0; plugin_idx < ActivePlugins.size(); plugin_idx++)
{
if(path == ActivePlugins[plugin_idx].path)
{
break;
}
}
/*---------------------------------------------------------------------*\
| If the plugin path does not exist in the active plugins list, return |
\*---------------------------------------------------------------------*/
if(plugin_idx == ActivePlugins.size())
{
return;
}
/*---------------------------------------------------------------------*\
| If the selected plugin is in the list and loaded, unload it |
\*---------------------------------------------------------------------*/
if(ActivePlugins[plugin_idx].loaded)
{
/*-------------------------------------------------*\
| Call plugin's Unload function before GUI removal |
\*-------------------------------------------------*/
ActivePlugins[plugin_idx].plugin->Unload();
/*-------------------------------------------------*\
| Call the Remove Plugin callback |
\*-------------------------------------------------*/
if(RemovePluginCallbackVal != nullptr)
{
RemovePluginCallbackVal(RemovePluginCallbackArg, &ActivePlugins[plugin_idx]);
}
ActivePlugins[plugin_idx].loader->unload();
ActivePlugins[plugin_idx].loaded = false;
}
}
+37 -2
View File
@@ -11,10 +11,45 @@
#include <string>
#include <iostream>
typedef struct
{
OpenRGBPluginInfo info;
OpenRGBPluginInterface* plugin;
QPluginLoader* loader;
bool loaded;
QWidget* widget;
QMenu* traymenu;
std::string path;
bool enabled;
} OpenRGBPluginEntry;
typedef void (*AddPluginCallback)(void *, OpenRGBPluginEntry* plugin);
typedef void (*RemovePluginCallback)(void *, OpenRGBPluginEntry* plugin);
class PluginManager
{
public:
std::vector<OpenRGBPluginInterface*> ActivePlugins;
PluginManager(bool dark_theme);
void ScanAndLoadPlugins(bool dark_theme);
void RegisterAddPluginCallback(AddPluginCallback new_callback, void * new_callback_arg);
void RegisterRemovePluginCallback(RemovePluginCallback new_callback, void * new_callback_arg);
void ScanAndLoadPlugins();
void AddPlugin(std::string path);
void RemovePlugin(std::string path);
void LoadPlugin(std::string path);
void UnloadPlugin(std::string path);
std::vector<OpenRGBPluginEntry> ActivePlugins;
private:
bool dark_theme;
AddPluginCallback AddPluginCallbackVal;
void * AddPluginCallbackArg;
RemovePluginCallback RemovePluginCallbackVal;
void * RemovePluginCallbackArg;
};
+1
View File
@@ -196,6 +196,7 @@ There have been two instances of hardware damage in OpenRGB's development and we
* Scheduler Plugin (by morg): https://gitlab.com/OpenRGBDevelopers/OpenRGBSchedulerPlugin
* Skin Plugin (by morg): https://gitlab.com/OpenRGBDevelopers/openrgbskinplugin
* Hardware Sync Plugin (by morg): https://gitlab.com/OpenRGBDevelopers/OpenRGBHardwareSyncPlugin
* Http Hook Plugin (by morg): https://gitlab.com/OpenRGBDevelopers/OpenRGBHttpHookPlugin
## Projects Used
+6 -6
View File
@@ -105,7 +105,7 @@ std::vector<i2c_smbus_interface*> & ResourceManager::GetI2CBusses()
void ResourceManager::RegisterRGBController(RGBController *rgb_controller)
{
LOG_INFO("Registering RGB controller: %s", rgb_controller->name.c_str());
LOG_INFO("[%s] Registering RGB controller", rgb_controller->name.c_str());
rgb_controllers_hw.push_back(rgb_controller);
UpdateDeviceList();
@@ -113,7 +113,7 @@ void ResourceManager::RegisterRGBController(RGBController *rgb_controller)
void ResourceManager::UnregisterRGBController(RGBController* rgb_controller)
{
LOG_INFO("Unregistering RGB controller: %s", rgb_controller->name.c_str());
LOG_INFO("[%s] Unregistering RGB controller", rgb_controller->name.c_str());
/*-------------------------------------------------------------------------*\
| Clear callbacks from the controller before removal |
@@ -746,7 +746,7 @@ void ResourceManager::DetectDevicesThreadFunction()
this_device_enabled = detector_settings["detectors"][detection_string];
}
LOG_DEBUG("[%s] is %s", detection_string, ((this_device_enabled == true) ? "Enabled" : "Disabled"));
LOG_DEBUG("[%s] is %s", detection_string, ((this_device_enabled == true) ? "enabled" : "disabled"));
if(this_device_enabled)
{
DetectionProgressChanged();
@@ -845,7 +845,7 @@ void ResourceManager::DetectDevicesThreadFunction()
this_device_enabled = detector_settings["detectors"][detection_string];
}
LOG_DEBUG("[%s] is %s", detection_string, ((this_device_enabled == true) ? "Enabled" : "Disabled"));
LOG_DEBUG("[%s] is %s", detection_string, ((this_device_enabled == true) ? "enabled" : "disabled"));
if(this_device_enabled)
{
@@ -940,7 +940,7 @@ void ResourceManager::DetectDevicesThreadFunction()
this_device_enabled = detector_settings["detectors"][detection_string];
}
LOG_DEBUG("[%s] is %s", detection_string, ((this_device_enabled == true) ? "Enabled" : "Disabled"));
LOG_DEBUG("[%s] is %s", detection_string, ((this_device_enabled == true) ? "enabled" : "disabled"));
if(this_device_enabled)
{
@@ -1001,7 +1001,7 @@ void ResourceManager::DetectDevicesThreadFunction()
this_device_enabled = detector_settings["detectors"][detection_string];
}
LOG_DEBUG("[%s] is %s", detection_string, ((this_device_enabled == true) ? "Enabled" : "Disabled"));
LOG_DEBUG("[%s] is %s", detection_string, ((this_device_enabled == true) ? "enabled" : "disabled"));
if(this_device_enabled)
{
+4 -1
View File
@@ -25,10 +25,13 @@
extern "C" {
#endif
#define BYTE_SIZE 8
#define CMMK_ROWS_MAX 7
#define CMMK_COLS_MAX 22
#define CMMK_KEYLIST_SIZE 256
#define CMMK_BUFFER_SIZE 65
/*
* If we have C99 support (which we do, because libusb-1.0 requires it...), define some handy
@@ -65,7 +68,7 @@ enum cmmk_product {
CMMK_USB_MASTERKEYS_PRO_L = 0x003b,
CMMK_USB_MASTERKEYS_PRO_L_WHITE = 0x0047,
CMMK_USB_MASTERKEYS_PRO_S = 0x003c,
CMMK_USB_MASTERKEYS_MK750 = 0x0067,
CMMK_USB_MASTERKEYS_MK750 = 0x0067,
CMMK_USB_MASTERKEYS_SK630 = 0x0089,
CMMK_USB_MASTERKEYS_SK650 = 0x008d,
};
+99 -82
View File
@@ -387,10 +387,10 @@ int cmmk_force_layout(struct cmmk *dev, int layout)
int cmmk_get_firmware_version(struct cmmk *dev, char *fw, size_t fwsiz)
{
unsigned char data[65] = { 0x01, 0x02 };
unsigned char data[CMMK_BUFFER_SIZE] = {0x00, 0x01, 0x02};
int r;
if ((r = send_command(dev->dev, data, sizeof(data))) != 0) {
if ((r = send_command(dev->dev, data, CMMK_BUFFER_SIZE)) != 0) {
return r;
}
@@ -483,25 +483,25 @@ const char * cmmk_layout_to_str(int layout)
*/
int cmmk_set_control_mode(struct cmmk *dev, int mode)
{
unsigned char data[64] = {0x41, mode};
unsigned char data[CMMK_BUFFER_SIZE] = {0x00, 0x41, mode};
return send_command(dev->dev, data, sizeof(data));
return send_command(dev->dev, data, CMMK_BUFFER_SIZE);
}
int cmmk_set_active_profile(struct cmmk *dev, int prof)
{
unsigned char setprof[64] = {0x51, 0x00, 0x00, 0x00, prof};
unsigned char setprof[CMMK_BUFFER_SIZE] = {0x00, 0x51, 0x00, 0x00, 0x00, prof};
return send_command(dev->dev, setprof, sizeof(setprof));
return send_command(dev->dev, setprof, CMMK_BUFFER_SIZE);
}
int cmmk_get_active_profile(struct cmmk *dev, int *prof)
{
int r;
unsigned char getprof[64] = {0x52, 0x00};
unsigned char getprof[CMMK_BUFFER_SIZE] = {0x00, 0x52, 0x00};
if ((r = send_command(dev->dev, getprof, sizeof(getprof))) != 0)
if ((r = send_command(dev->dev, getprof, CMMK_BUFFER_SIZE)) != 0)
return r;
*prof = getprof[4];
@@ -511,17 +511,17 @@ int cmmk_get_active_profile(struct cmmk *dev, int *prof)
int cmmk_save_active_profile(struct cmmk *dev)
{
unsigned char saveprof[64] = {0x50, 0x55};
unsigned char saveprof[CMMK_BUFFER_SIZE] = {0x00, 0x50, 0x55};
return send_command(dev->dev, saveprof, sizeof(saveprof));
return send_command(dev->dev, saveprof, CMMK_BUFFER_SIZE);
}
static int set_effect1(struct cmmk *dev, int eff)
{
unsigned char data[64] = {0x51, 0x28, 0x00, 0x00, eff};
unsigned char data[CMMK_BUFFER_SIZE] = {0x00, 0x51, 0x28, 0x00, 0x00, eff};
return send_command(dev->dev, data, sizeof(data));
return send_command(dev->dev, data, CMMK_BUFFER_SIZE);
}
@@ -532,25 +532,25 @@ static int set_effect(
struct rgb const *col1,
struct rgb const *col2)
{
unsigned char data[64] = {
0x51, 0x2c, dev->multilayer_mode, 0x00, eff, p1, p2, p3,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
unsigned char data[CMMK_BUFFER_SIZE] = {
0x00, 0x51, 0x2c, dev->multilayer_mode, 0x00, eff, p1,
p2, p3, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
if (col1 != NULL) {
data[10] = col1->R;
data[11] = col1->G;
data[12] = col1->B;
data[11] = col1->R;
data[12] = col1->G;
data[13] = col1->B;
}
if (col2 != NULL) {
data[13] = col2->R;
data[14] = col2->G;
data[15] = col2->B;
data[14] = col2->R;
data[15] = col2->G;
data[16] = col2->B;
}
memset(data + 16, 0xff, 48);
memset(data + 17, 0xff, 48);
return send_command(dev->dev, data, sizeof(data));
return send_command(dev->dev, data, CMMK_BUFFER_SIZE);
}
static int get_effect(
@@ -562,13 +562,13 @@ static int get_effect(
{
int r;
unsigned char data[64] = {
0x52, 0x2c, dev->multilayer_mode, 0x00, eff
unsigned char data[CMMK_BUFFER_SIZE] = {
0x00, 0x52, 0x2c, dev->multilayer_mode, 0x00, eff
};
memset(data + 5, 0xff, 59);
memset(data + 6, 0xff, 59);
if ((r = send_command(dev->dev, data, sizeof(data))) != 0) {
if ((r = send_command(dev->dev, data, CMMK_BUFFER_SIZE)) != 0) {
return r;
}
@@ -612,10 +612,10 @@ int cmmk_set_active_effect(struct cmmk *dev, enum cmmk_effect_id eff)
int cmmk_get_active_effect(struct cmmk *dev, enum cmmk_effect_id *eff)
{
unsigned char data[64] = {0x52, 0x28};
unsigned char data[CMMK_BUFFER_SIZE] = {0x00, 0x52, 0x28};
int r;
if ((r = send_command(dev->dev, data, sizeof(data))) != 0) {
if ((r = send_command(dev->dev, data, CMMK_BUFFER_SIZE)) != 0) {
return r;
}
@@ -640,14 +640,14 @@ int cmmk_get_enabled_effects(
size_t siz,
size_t *n)
{
unsigned char data[64] = {0x52, 0x29};
unsigned char data[CMMK_BUFFER_SIZE] = {0x00, 0x52, 0x29};
size_t i;
size_t j = 0;
int r;
if ((r = send_command(dev->dev, data, sizeof(data))) != 0) {
if ((r = send_command(dev->dev, data, CMMK_BUFFER_SIZE)) != 0) {
return r;
}
@@ -664,16 +664,16 @@ int cmmk_set_enabled_effects(
enum cmmk_effect_id const *effs,
size_t n)
{
unsigned char data[64] = {0x51, 0x29};
unsigned char data[CMMK_BUFFER_SIZE] = {0x00, 0x51, 0x29};
size_t i;
for (i = 0; i < n; ++i) {
data[4 + i] = effs[i];
data[5 + i] = effs[i];
}
while (i < 18) {
data[4 + i] = 0xff;
data[5 + i] = 0xff;
++i;
}
@@ -808,7 +808,8 @@ int cmmk_set_effect_snake(struct cmmk *dev, struct cmmk_effect_snake const *eff)
int cmmk_set_customized_leds(struct cmmk *dev, struct cmmk_color_matrix const *colmap)
{
unsigned char data[64] = {0x51, 0xa8};
const unsigned char HEADER_SIZE = 5;
unsigned char data[CMMK_BUFFER_SIZE] = {0x00, 0x51, 0xa8};
int i;
int j;
@@ -823,10 +824,10 @@ int cmmk_set_customized_leds(struct cmmk *dev, struct cmmk_color_matrix const *c
transpose_reverse(dev, colmap, linear);
for (i = 0; i < 8; ++i) {
data[2] = i*2;
data[3] = i*2;
for (j = 0; j < 16; ++j) {
int const offset = 4 + (j * 3);
int const offset = HEADER_SIZE + (j * 3);
data[offset] = nextcol->R;
data[offset + 1] = nextcol->G;
@@ -835,7 +836,7 @@ int cmmk_set_customized_leds(struct cmmk *dev, struct cmmk_color_matrix const *c
++nextcol;
}
send_command(dev->dev, data, sizeof(data));
send_command(dev->dev, data, CMMK_BUFFER_SIZE);
}
return CMMK_OK;
@@ -844,12 +845,13 @@ int cmmk_set_customized_leds(struct cmmk *dev, struct cmmk_color_matrix const *c
int cmmk_get_customized_leds(struct cmmk *dev, struct cmmk_color_matrix *colmap)
{
#ifdef _MSC_VER
struct rgb linear[CMMK_KEYLIST_SIZE] = { 0 };
struct rgb linear[CMMK_KEYLIST_SIZE] = { 0 };
#else
struct rgb linear[CMMK_KEYLIST_SIZE] = {};
struct rgb linear[CMMK_KEYLIST_SIZE] = {};
#endif
unsigned char data[64] = {0x52, 0xa8};
const unsigned char HEADER_SIZE = 5;
unsigned char data[CMMK_BUFFER_SIZE] = {0x00, 0x52, 0xa8};
int i;
int j;
@@ -857,12 +859,12 @@ int cmmk_get_customized_leds(struct cmmk *dev, struct cmmk_color_matrix *colmap)
struct rgb *ptr = linear;
for (i = 0; i < 8; ++i) {
data[2] = i * 2;
data[3] = i * 2;
send_command(dev->dev, data, sizeof(data));
send_command(dev->dev, data, CMMK_BUFFER_SIZE);
for (j = 0; j < 16; ++j) {
int const offset = 4 + (j * 3);
int const offset = (HEADER_SIZE - 1) + (j * 3);
ptr->R = data[offset];
ptr->G = data[offset + 1];
@@ -886,40 +888,47 @@ int cmmk_switch_multilayer(struct cmmk *dev, int active)
int cmmk_get_multilayer_map(struct cmmk *dev, struct cmmk_effect_matrix *effmap)
{
int r;
const unsigned char HEADER_SIZE = 9;
unsigned char data_size = CMMK_BUFFER_SIZE - HEADER_SIZE;
unsigned char data_size_in_bytes = data_size / BYTE_SIZE;
int r;
unsigned char data[64] = {0x52, 0xa0, 0x01, 0x00};
uint8_t linear[CMMK_KEYLIST_SIZE];
unsigned char data[CMMK_BUFFER_SIZE];
unsigned char header[CMMK_BUFFER_SIZE] = {0x00, 0x51, 0xa0, 0x01, 0x00};
uint8_t linear[CMMK_KEYLIST_SIZE];
/* Call 1 */
data[4] = 0x00;
data[5] = 0x07;
memcpy(data, header, HEADER_SIZE);
data[5] = 0x00;
data[6] = 0x07;
if ((r = send_command(dev->dev, data, sizeof(data))) != 0) {
if ((r = send_command(dev->dev, data, CMMK_BUFFER_SIZE)) != 0) {
return r;
}
memcpy(linear, data + 8, 56);
memcpy(linear, data + HEADER_SIZE - 1, data_size);
/* Call 2 */
data[4] = 0x07;
data[5] = 0x07;
memcpy(data, header, HEADER_SIZE);
data[5] = 0x07;
data[6] = 0x07;
if ((r = send_command(dev->dev, data, sizeof(data))) != 0) {
if ((r = send_command(dev->dev, data, CMMK_BUFFER_SIZE)) != 0) {
return r;
}
memcpy(linear + 56, data + 8, 56);
memcpy(linear + 56, data + HEADER_SIZE - 1, data_size);
/* Call 3 */
data[4] = 0x0e;
data[5] = 0x01;
memcpy(data, header, HEADER_SIZE);
data[5] = 0x0e;
data[6] = 0x01;
if ((r = send_command(dev->dev, data, sizeof(data))) != 0) {
if ((r = send_command(dev->dev, data, CMMK_BUFFER_SIZE)) != 0) {
return r;
}
memcpy(linear + 112, data + 8, 8);
memcpy(linear + 112, data + HEADER_SIZE - 1, data_size);
transpose_effects(dev, linear, effmap);
@@ -928,40 +937,47 @@ int cmmk_get_multilayer_map(struct cmmk *dev, struct cmmk_effect_matrix *effmap)
int cmmk_set_multilayer_map(struct cmmk *dev, struct cmmk_effect_matrix const *effmap)
{
const unsigned char HEADER_SIZE = 9;
unsigned char data_size = CMMK_BUFFER_SIZE - HEADER_SIZE;
unsigned char data_size_in_bytes = data_size / BYTE_SIZE;
int r;
unsigned char data[64] = {0x51, 0xa0, 0x01, 0x00};
uint8_t linear[CMMK_KEYLIST_SIZE] = {0};
unsigned char data[CMMK_BUFFER_SIZE];
unsigned char header[CMMK_BUFFER_SIZE] = {0x00, 0x51, 0xa0, 0x01, 0x00};
uint8_t linear[CMMK_KEYLIST_SIZE] = {0};
transpose_effects_reverse(dev, effmap, linear);
/* Call 1 */
data[4] = 0x00;
data[5] = 0x07;
memcpy(data, header, HEADER_SIZE);
data[5] = 0x00;
data[6] = 0x07;
memcpy(data + 8, linear, 56);
memcpy(data + HEADER_SIZE, linear, data_size);
if ((r = send_command(dev->dev, data, sizeof(data))) != 0) {
if ((r = send_command(dev->dev, data, CMMK_BUFFER_SIZE)) != 0) {
return r;
}
/* Call 2 */
data[4] = 0x07;
data[5] = 0x07;
memcpy(data, header, HEADER_SIZE);
data[5] = 0x07;
data[6] = 0x07;
memcpy(data + 8, linear + 56, 56);
memcpy(data + HEADER_SIZE, linear + 56, data_size);
if ((r = send_command(dev->dev, data, sizeof(data))) != 0) {
if ((r = send_command(dev->dev, data, CMMK_BUFFER_SIZE)) != 0) {
return r;
}
/* Call 3 */
data[4] = 0x0e;
data[5] = 0x01;
memcpy(data, header, HEADER_SIZE);
data[5] = 0x0e;
data[6] = 0x01;
memcpy(data + 8, linear + 112, 8);
memcpy(data + HEADER_SIZE, linear + 112, data_size);
if ((r = send_command(dev->dev, data, sizeof(data))) != 0) {
if ((r = send_command(dev->dev, data, CMMK_BUFFER_SIZE)) != 0) {
return r;
}
@@ -980,7 +996,7 @@ int cmmk_lookup_key_id(struct cmmk *dev, int row, int col)
*/
int cmmk_set_single_key_by_id(struct cmmk *dev, int key, struct rgb const *color)
{
unsigned char data[64] = {0xc0, 0x01, 0x01, 0x00, key, color->R, color->G, color->B};
unsigned char data[CMMK_BUFFER_SIZE] = {0x00, 0xc0, 0x01, 0x01, 0x00, key, color->R, color->G, color->B};
return send_command(dev->dev, data, sizeof(data));
}
@@ -1001,7 +1017,7 @@ int cmmk_set_single_key(struct cmmk *dev, int row, int col, struct rgb const *co
*/
int cmmk_set_all_single(struct cmmk *dev, struct rgb const *col)
{
unsigned char data[64] = {0xc0, 0x00, 0x00, 0x00, col->R, col->G, col->B};
unsigned char data[CMMK_BUFFER_SIZE] = {0x00, 0xc0, 0x00, 0x00, 0x00, col->R, col->G, col->B};
return send_command(dev->dev, data, sizeof(data));
}
@@ -1019,7 +1035,7 @@ int cmmk_set_all_single(struct cmmk *dev, struct rgb const *col)
*/
int cmmk_set_leds(struct cmmk *dev, struct cmmk_color_matrix const *colmap)
{
unsigned char data[64];
unsigned char data[CMMK_BUFFER_SIZE];
int i;
int j;
@@ -1034,13 +1050,14 @@ int cmmk_set_leds(struct cmmk *dev, struct cmmk_color_matrix const *colmap)
transpose_reverse(dev, colmap, linear);
for (i = 0; i < 8; ++i) {
data[0] = 0xc0;
data[1] = 0x02;
data[2] = i*2;
data[3] = 0x00;
data[0] = 0x00;
data[1] = 0xc0;
data[2] = 0x02;
data[3] = i*2;
data[4] = 0x00;
for (j = 0; j < 16; ++j) {
int const offset = 4 + (j * 3);
int const offset = 5 + (j * 3);
data[offset] = nextcol->R;
data[offset + 1] = nextcol->G;
@@ -1049,7 +1066,7 @@ int cmmk_set_leds(struct cmmk *dev, struct cmmk_color_matrix const *colmap)
++nextcol;
}
send_command(dev->dev, data, sizeof(data));
send_command(dev->dev, data, CMMK_BUFFER_SIZE);
}
return CMMK_OK;
+17 -9
View File
@@ -30,14 +30,16 @@
| Intel Device IDs |
\*-----------------------------------------------------*/
#define INTEL_ICH10_SMBUS_DEV 0x3A30
#define INTEL_COFFEE_LAKE_SMBUS_DEV 0xA2A3
#define INTEL_COFFEE_LAKE_S_SMBUS_DEV 0xA323
#define INTEL_SUNRISE_POINT_H_SMBUS_DEV 0xA123
#define INTEL_KABY_LAKE_H_SMBUS_DEV 0xA2A3
#define INTEL_CANNON_LAKE_H_SMBUS_DEV 0xA323
#define INTEL_COMET_LAKE_H_SMBUS_DEV 0x06A3
#define INTEL_ROCKET_LAKE_SMBUS_DEV 0x43A3
#define INTEL_TIGER_LAKE_SMBUS_DEV 0x43A3
/*-----------------------------------------------------*\
| nVidia Device IDs |
\*-----------------------------------------------------*/
#define NVIDIA_GTX1050_DEV 0x1C81
#define NVIDIA_GTX1050TI_DEV 0x1C82
#define NVIDIA_GTX1060_DEV 0x1C03
#define NVIDIA_GTX1070_DEV 0x1B81
@@ -88,6 +90,8 @@
/*-----------------------------------------------------*\
| ASUS Sub-Device IDs |
\*-----------------------------------------------------*/
#define ASUS_GTX1050_STRIX_O2G_GAMING 0x85D8
#define ASUS_GTX1060_STRIX_6G_GAMING 0x85A4
#define ASUS_GTX1060_STRIX 0x85AC
#define ASUS_GTX1070_STRIX_GAMING 0x8598
#define ASUS_GTX1070_STRIX_OC 0x8599
@@ -98,9 +102,11 @@
#define ASUS_ROG_STRIX_GTX1080TI_11G_GAMING 0x85F1
#define ASUS_ROG_STRIX_GTX1080TI_GAMING 0x85EA
#define ASUS_ROG_STRIX_GTX1650S_OC 0x874F
#define ASUS_ROG_STRIX_GTX1660S_O6G_GAMING 0x8752
#define ASUS_ROG_GTX1660TI_OC 0x86A5
#define ASUS_ROG_STRIX_RTX2060_EVO_GAMING 0x86D3
#define ASUS_ROG_STRIX_RTX2060S_A8G_EVO_GAMING 0x8703
#define ASUS_ROG_STRIX_RTX2060S_O8G_GAMING 0x86FB
#define ASUS_ROG_STRIX_RTX2070_A8G_GAMING 0x8671
#define ASUS_ROG_STRIX_RTX2070_O8G_GAMING 0x8670
#define ASUS_ROG_STRIX_RTX2070S_A8G_GAMING 0x8728
@@ -235,16 +241,18 @@
#define IF_DRAM_SMBUS(ven, dev) \
if(((ven == AMD_VEN) && (dev == AMD_FCH_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_ICH10_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_COFFEE_LAKE_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_COFFEE_LAKE_S_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_SUNRISE_POINT_H_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_KABY_LAKE_H_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_CANNON_LAKE_H_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_COMET_LAKE_H_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_ROCKET_LAKE_SMBUS_DEV)))
((ven == INTEL_VEN) && (dev == INTEL_TIGER_LAKE_SMBUS_DEV)))
#define IF_MOBO_SMBUS(ven, dev) \
if((ven == 0) || \
((ven == AMD_VEN) && (dev == AMD_FCH_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_ICH10_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_COFFEE_LAKE_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_COFFEE_LAKE_S_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_SUNRISE_POINT_H_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_KABY_LAKE_H_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_CANNON_LAKE_H_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_COMET_LAKE_H_SMBUS_DEV)) || \
((ven == INTEL_VEN) && (dev == INTEL_ROCKET_LAKE_SMBUS_DEV)))
((ven == INTEL_VEN) && (dev == INTEL_TIGER_LAKE_SMBUS_DEV)))
+76 -60
View File
@@ -22,6 +22,7 @@ DeviceView::DeviceView(QWidget *parent) :
{
controller = NULL;
numerical_labels = false;
per_led = true;
setMouseTracking(1);
size = width();
@@ -342,6 +343,12 @@ void DeviceView::setNumericalLabels(bool enable)
numerical_labels = enable;
}
void DeviceView::setPerLED(bool per_led_mode)
{
per_led = per_led_mode;
update();
}
QSize DeviceView::sizeHint () const
{
return QSize(height() - 1, height() - 1);
@@ -354,88 +361,97 @@ QSize DeviceView::minimumSizeHint () const
void DeviceView::mousePressEvent(QMouseEvent *event)
{
ctrlDown = event->modifiers().testFlag(Qt::ControlModifier);
mouseDown = true;
mouseMoved = false;
if(ctrlDown)
if(per_led)
{
previousFlags = selectionFlags;
previousSelection = selectedLeds;
ctrlDown = event->modifiers().testFlag(Qt::ControlModifier);
mouseDown = true;
mouseMoved = false;
if(ctrlDown)
{
previousFlags = selectionFlags;
previousSelection = selectedLeds;
}
/*-----------------------------------------------------*\
| It's okay if the size becomes negative |
\*-----------------------------------------------------*/
selectionRect.setLeft(event->x());
selectionRect.setTop(event->y());
selectionRect.setRight(event->x());
selectionRect.setBottom(event->y());
updateSelection();
update();
}
/*-----------------------------------------------------*\
| It's okay if the size becomes negative |
\*-----------------------------------------------------*/
selectionRect.setLeft(event->x());
selectionRect.setTop(event->y());
selectionRect.setRight(event->x());
selectionRect.setBottom(event->y());
updateSelection();
update();
}
void DeviceView::mouseMoveEvent(QMouseEvent *event)
{
lastMousePos = event->pos();
selectionRect.setRight(event->x());
selectionRect.setBottom(event->y());
if(mouseDown)
if(per_led)
{
mouseMoved = true;
ctrlDown = event->modifiers().testFlag(Qt::ControlModifier);
lastMousePos = event->pos();
selectionRect.setRight(event->x());
selectionRect.setBottom(event->y());
/*-----------------------------------------------------*\
| Clear the previous selection in case ctrl is released |
\*-----------------------------------------------------*/
if(!ctrlDown)
if(mouseDown)
{
previousSelection.clear();
previousFlags.clear();
previousFlags.resize(controller->leds.size());
mouseMoved = true;
ctrlDown = event->modifiers().testFlag(Qt::ControlModifier);
/*-----------------------------------------------------*\
| Clear the previous selection in case ctrl is released |
\*-----------------------------------------------------*/
if(!ctrlDown)
{
previousSelection.clear();
previousFlags.clear();
previousFlags.resize(controller->leds.size());
}
updateSelection();
}
updateSelection();
update();
}
update();
}
void DeviceView::mouseReleaseEvent(QMouseEvent* event)
{
selectionRect = selectionRect.normalized();
mouseDown = false;
/*-----------------------------------------------------*\
| Check if the user clicked a zone name & select it |
\*-----------------------------------------------------*/
if(!mouseMoved)
if(per_led)
{
int size = width();
int offset_x = 0;
selectionRect = selectionRect.normalized();
mouseDown = false;
if(height() < size * matrix_h)
/*-----------------------------------------------------*\
| Check if the user clicked a zone name & select it |
\*-----------------------------------------------------*/
if(!mouseMoved)
{
size = height() / matrix_h;
offset_x = (width() - size) / 2;
}
int size = width();
int offset_x = 0;
for(std::size_t zone_idx = 0; zone_idx < controller->zones.size(); zone_idx++)
{
int posx = zone_pos[zone_idx].matrix_x * size + offset_x;
int posy = zone_pos[zone_idx].matrix_y * size;
int posw = zone_pos[zone_idx].matrix_w * size;
int posh = zone_pos[zone_idx].matrix_h * size;
QRect rect = {posx, posy, posw, posh};
if(rect.contains(event->pos()))
if(height() < size * matrix_h)
{
selectZone(zone_idx, ctrlDown);
size = height() / matrix_h;
offset_x = (width() - size) / 2;
}
for(std::size_t zone_idx = 0; zone_idx < controller->zones.size(); zone_idx++)
{
int posx = zone_pos[zone_idx].matrix_x * size + offset_x;
int posy = zone_pos[zone_idx].matrix_y * size;
int posw = zone_pos[zone_idx].matrix_w * size;
int posh = zone_pos[zone_idx].matrix_h * size;
QRect rect = {posx, posy, posw, posh};
if(rect.contains(event->pos()))
{
selectZone(zone_idx, ctrlDown);
}
}
}
update();
}
update();
}
void DeviceView::resizeEvent(QResizeEvent* /*event*/)
@@ -459,7 +475,7 @@ void DeviceView::paintEvent(QPaintEvent* /* event */)
/*-----------------------------------------------------*\
| If Device View is hidden, don't paint |
\*-----------------------------------------------------*/
if(isHidden())
if(isHidden() || !per_led)
{
return;
}
+2
View File
@@ -23,6 +23,7 @@ public:
void setController(RGBController * controller_ptr);
void setNumericalLabels(bool enable);
void setPerLED(bool per_led_mode);
protected:
void mousePressEvent(QMouseEvent *event);
@@ -44,6 +45,7 @@ private:
QVector<int> selectedLeds;
QVector<bool> selectionFlags;
QVector<bool> previousFlags;
bool per_led;
std::vector<matrix_pos_size_type> zone_pos;
std::vector<matrix_pos_size_type> led_pos;
+2
View File
@@ -600,6 +600,7 @@ void Ui::OpenRGBDevicePage::UpdateModeUi()
{
ui->PerLEDCheck->setEnabled(true);
ui->PerLEDCheck->setChecked(per_led);
ui->DeviceViewBox->setPerLED(true);
}
else
{
@@ -607,6 +608,7 @@ void Ui::OpenRGBDevicePage::UpdateModeUi()
ui->PerLEDCheck->setAutoExclusive(false);
ui->PerLEDCheck->setChecked(false);
ui->PerLEDCheck->setAutoExclusive(true);
ui->DeviceViewBox->setPerLED(false);
}
if(supports_mode_specific)
+259 -58
View File
@@ -7,6 +7,7 @@
#include "OpenRGBProfileSaveDialog.h"
#include "ResourceManager.h"
#include "TabLabel.h"
#include "OpenRGBZonesBulkResizer.h"
#include <QLabel>
#include <QTabBar>
#include <QMessageBox>
@@ -96,6 +97,27 @@ static void UpdateDetectionProgressCallback(void * this_ptr)
QMetaObject::invokeMethod(this_obj, "onDetectionProgressUpdated", Qt::QueuedConnection);
}
static void CreatePluginCallback(void * this_ptr, OpenRGBPluginEntry* plugin)
{
OpenRGBDialog2 * this_obj = (OpenRGBDialog2 *)this_ptr;
this_obj->AddPlugin(plugin);
}
static void DeletePluginCallback(void * this_ptr, OpenRGBPluginEntry* plugin)
{
OpenRGBDialog2 * this_obj = (OpenRGBDialog2 *)this_ptr;
this_obj->RemovePlugin(plugin);
}
static void DetectionEndedCallback(void * this_ptr)
{
OpenRGBDialog2 * this_obj = (OpenRGBDialog2 *)this_ptr;
QMetaObject::invokeMethod(this_obj, "onDetectionEnded", Qt::QueuedConnection);
}
bool OpenRGBDialog2::IsDarkTheme()
{
#ifdef _WIN32
@@ -244,6 +266,7 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op
\*-----------------------------------------------------*/
ResourceManager::get()->RegisterDetectionProgressCallback(UpdateDetectionProgressCallback, this);
ResourceManager::get()->RegisterDeviceListChangeCallback(UpdateDeviceListCallback, this);
ResourceManager::get()->RegisterDetectionEndCallback(DetectionEndedCallback, this);
/*-----------------------------------------------------*\
| Initialize page pointers |
@@ -272,7 +295,7 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op
/*-----------------------------------------------------*\
| Set up tray icon menu |
\*-----------------------------------------------------*/
QMenu* trayIconMenu = new QMenu( this );
trayIconMenu = new QMenu( this );
trayIcon = new QSystemTrayIcon(this);
@@ -320,7 +343,7 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op
connect(actionLightsOff, SIGNAL(triggered()), this, SLOT(on_LightsOff()));
trayIconMenu->addAction(actionLightsOff);
QAction* actionExit = new QAction( "Exit", this );
actionExit = new QAction( "Exit", this );
connect( actionExit, SIGNAL( triggered() ), this, SLOT( on_Exit() ));
trayIconMenu->addAction(actionExit);
@@ -402,6 +425,19 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op
\*-----------------------------------------------------*/
AddSettingsPage();
/*-----------------------------------------------------*\
| Initialize the plugin manager |
\*-----------------------------------------------------*/
plugin_manager = new PluginManager(IsDarkTheme());
plugin_manager->RegisterAddPluginCallback(&CreatePluginCallback, this);
plugin_manager->RegisterRemovePluginCallback(&DeletePluginCallback, this);
plugin_manager->ScanAndLoadPlugins();
/*-----------------------------------------------------*\
| Add the Plugins page |
\*-----------------------------------------------------*/
AddPluginsPage(plugin_manager);
/*-----------------------------------------------------*\
| Add the E1.31 settings page |
\*-----------------------------------------------------*/
@@ -417,6 +453,16 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op
\*-----------------------------------------------------*/
AddQMKORGBSettingsPage();
/*-----------------------------------------------------*\
| Add the Philips Wiz settings page |
\*-----------------------------------------------------*/
AddPhilipsWizSettingsPage();
/*-----------------------------------------------------*\
| Add the Yeelight settings page |
\*-----------------------------------------------------*/
AddYeelightSettingsPage();
/*-----------------------------------------------------*\
| Add the SMBus Tools page if enabled |
\*-----------------------------------------------------*/
@@ -424,24 +470,6 @@ OpenRGBDialog2::OpenRGBDialog2(QWidget *parent) : QMainWindow(parent), ui(new Op
{
AddI2CToolsPage();
}
/*-----------------------------------------------------*\
| Add the various plugins tabs |
\*-----------------------------------------------------*/
plugin_manager = new PluginManager;
plugin_manager->ScanAndLoadPlugins(IsDarkTheme());
if(plugin_manager->ActivePlugins.size() > 0)
{
for(int i = 0; i < int(plugin_manager->ActivePlugins.size()); i++)
{
/*---------------------------------------------------------------------------*\
| Start by getting location and then placing the widget where it needs to go |
\*---------------------------------------------------------------------------*/
AddPluginTab(plugin_manager, i);
}
}
}
OpenRGBDialog2::~OpenRGBDialog2()
@@ -492,6 +520,34 @@ void OpenRGBDialog2::closeEvent(QCloseEvent *event)
}
}
void OpenRGBDialog2::AddPluginsPage(PluginManager* plugin_manager)
{
/*-----------------------------------------------------*\
| Create the Plugins page |
\*-----------------------------------------------------*/
PluginsPage = new OpenRGBPluginsPage(plugin_manager);
ui->SettingsTabBar->addTab(PluginsPage, "");
QString PluginsLabelString;
if(IsDarkTheme())
{
PluginsLabelString = "plugin_dark.png";
}
else
{
PluginsLabelString = "plugin.png";
}
/*-----------------------------------------------------*\
| Create the tab label |
\*-----------------------------------------------------*/
TabLabel* PluginTabLabel = new TabLabel(PluginsLabelString, "Plugins");
ui->SettingsTabBar->tabBar()->setTabButton(ui->SettingsTabBar->tabBar()->count() - 1, QTabBar::LeftSide, PluginTabLabel);
}
void OpenRGBDialog2::AddSoftwareInfoPage()
{
/*-----------------------------------------------------*\
@@ -605,6 +661,34 @@ void OpenRGBDialog2::AddE131SettingsPage()
ui->SettingsTabBar->tabBar()->setTabButton(ui->SettingsTabBar->tabBar()->count() - 1, QTabBar::LeftSide, SettingsTabLabel);
}
void OpenRGBDialog2::AddPhilipsWizSettingsPage()
{
/*-----------------------------------------------------*\
| Create the Settings page |
\*-----------------------------------------------------*/
PhilipsWizSettingsPage = new OpenRGBPhilipsWizSettingsPage();
ui->SettingsTabBar->addTab(PhilipsWizSettingsPage, "");
QString SettingsLabelString;
if(IsDarkTheme())
{
SettingsLabelString = "light_dark.png";
}
else
{
SettingsLabelString = "light.png";
}
/*-----------------------------------------------------*\
| Create the tab label |
\*-----------------------------------------------------*/
TabLabel* SettingsTabLabel = new TabLabel(SettingsLabelString, "Philips Wiz Devices");
ui->SettingsTabBar->tabBar()->setTabButton(ui->SettingsTabBar->tabBar()->count() - 1, QTabBar::LeftSide, SettingsTabLabel);
}
void OpenRGBDialog2::AddQMKORGBSettingsPage()
{
/*-----------------------------------------------------*\
@@ -661,7 +745,35 @@ void OpenRGBDialog2::AddSerialSettingsPage()
ui->SettingsTabBar->tabBar()->setTabButton(ui->SettingsTabBar->tabBar()->count() - 1, QTabBar::LeftSide, SettingsTabLabel);
}
void OpenRGBDialog2::AddPluginTab(PluginManager* plugin_manager, int plugin_index)
void OpenRGBDialog2::AddYeelightSettingsPage()
{
/*-----------------------------------------------------*\
| Create the Settings page |
\*-----------------------------------------------------*/
YeelightSettingsPage = new OpenRGBYeelightSettingsPage();
ui->SettingsTabBar->addTab(YeelightSettingsPage, "");
QString SettingsLabelString;
if(IsDarkTheme())
{
SettingsLabelString = "light_dark.png";
}
else
{
SettingsLabelString = "light.png";
}
/*-----------------------------------------------------*\
| Create the tab label |
\*-----------------------------------------------------*/
TabLabel* SettingsTabLabel = new TabLabel(SettingsLabelString, "Yeelight Devices");
ui->SettingsTabBar->tabBar()->setTabButton(ui->SettingsTabBar->tabBar()->count() - 1, QTabBar::LeftSide, SettingsTabLabel);
}
void OpenRGBDialog2::AddPlugin(OpenRGBPluginEntry* plugin)
{
/*-----------------------------------------------------*\
| Create Label for the Tab |
@@ -672,54 +784,43 @@ void OpenRGBDialog2::AddPluginTab(PluginManager* plugin_manager, int plugin_inde
| If the plugin has custom information, use it, |
| otherwise generate it |
\*-----------------------------------------------------*/
if(plugin_manager->ActivePlugins[plugin_index]->info.HasCustom)
QString PluginLabelString;
if(IsDarkTheme())
{
PluginTabLabel = plugin_manager->ActivePlugins[plugin_index]->info.PluginLabel;
PluginLabelString = "plugin_dark.png";
}
else
{
QLabel *TabLabelText = plugin_manager->ActivePlugins[plugin_index]->info.PluginLabel;
QString PluginLabelString;
if(IsDarkTheme())
{
PluginLabelString = "plugin_dark.png";
}
else
{
PluginLabelString = "plugin.png";
}
/*-----------------------------------------------------*\
| Create the tab label |
\*-----------------------------------------------------*/
PluginTabLabel = (QLabel*)new TabLabel(PluginLabelString, TabLabelText->text());
PluginLabelString = "plugin.png";
}
/*-----------------------------------------------------*\
| Determine plugin location |
| Create the tab label |
\*-----------------------------------------------------*/
std::string Location = plugin_manager->ActivePlugins[plugin_index]->info.PluginLocation;
PluginTabLabel = (QLabel*)new TabLabel(PluginLabelString, QString::fromStdString(plugin->info.Label));
/*-----------------------------------------------------*\
| InformationTab - Place plugin in the Information tab |
| Place plugin as its own top level tab |
\*-----------------------------------------------------*/
if(Location == "InformationTab")
if(plugin->info.Location == OPENRGB_PLUGIN_LOCATION_TOP)
{
QWidget* NewPluginTab = plugin_manager->ActivePlugins[plugin_index]->CreateGUI(this);
QWidget* NewPluginTab = plugin->plugin->GetWidget();
plugin->widget = NewPluginTab;
OpenRGBPluginContainer* NewPluginContainer = new OpenRGBPluginContainer(NewPluginTab);
ui->InformationTabBar->addTab(NewPluginContainer," ");
ui->InformationTabBar->tabBar()->setTabButton((ui->InformationTabBar->count() - 1),QTabBar::LeftSide , PluginTabLabel);
ui->MainTabBar->addTab(NewPluginContainer,QString().fromStdString(plugin->info.Label));
}
/*-----------------------------------------------------*\
| DevicesTab - Place plugin in the Devices tab |
| Place plugin in the Devices tab |
\*-----------------------------------------------------*/
else if(Location == "DevicesTab")
else if(plugin->info.Location == OPENRGB_PLUGIN_LOCATION_DEVICES)
{
QWidget* NewPluginTab = plugin_manager->ActivePlugins[plugin_index]->CreateGUI(this);
QWidget* NewPluginTab = plugin->plugin->GetWidget();
plugin->widget = NewPluginTab;
OpenRGBPluginContainer* NewPluginContainer = new OpenRGBPluginContainer(NewPluginTab);
@@ -728,22 +829,28 @@ void OpenRGBDialog2::AddPluginTab(PluginManager* plugin_manager, int plugin_inde
ui->DevicesTabBar->tabBar()->setTabButton((ui->DevicesTabBar->count() - 1),QTabBar::LeftSide , PluginTabLabel);
}
/*-----------------------------------------------------*\
| TopTabBar - Place plugin as its own top level tab |
| Place plugin in the Information tab |
\*-----------------------------------------------------*/
else if(Location == "TopTabBar")
else if(plugin->info.Location == OPENRGB_PLUGIN_LOCATION_INFORMATION)
{
QWidget* NewPluginTab = plugin_manager->ActivePlugins[plugin_index]->CreateGUI(this);
QWidget* NewPluginTab = plugin->plugin->GetWidget();
plugin->widget = NewPluginTab;
OpenRGBPluginContainer* NewPluginContainer = new OpenRGBPluginContainer(NewPluginTab);
ui->MainTabBar->addTab(NewPluginContainer,QString().fromStdString(plugin_manager->ActivePlugins[plugin_index]->info.PluginName));
ui->InformationTabBar->addTab(NewPluginContainer," ");
ui->InformationTabBar->tabBar()->setTabButton((ui->InformationTabBar->count() - 1),QTabBar::LeftSide , PluginTabLabel);
}
/*-----------------------------------------------------*\
| SettingsTabBar - Place plugin in the Settings tab |
| Place plugin in the Settings tab |
\*-----------------------------------------------------*/
else if(Location == "SettingsTabBar")
else if(plugin->info.Location == OPENRGB_PLUGIN_LOCATION_SETTINGS)
{
QWidget* NewPluginTab = plugin_manager->ActivePlugins[plugin_index]->CreateGUI(this);
QWidget* NewPluginTab = plugin->plugin->GetWidget();
plugin->widget = NewPluginTab;
OpenRGBPluginContainer* NewPluginContainer = new OpenRGBPluginContainer(NewPluginTab);
@@ -757,7 +864,93 @@ void OpenRGBDialog2::AddPluginTab(PluginManager* plugin_manager, int plugin_inde
\*-----------------------------------------------------*/
else
{
std::cout << ("Cannot load plugin '" + plugin_manager->ActivePlugins[plugin_index]->info.PluginName + "' as it does not specify a valid location: " + Location + "\n");
std::cout << ("Cannot load plugin '" + plugin->info.Name + "' as it does not specify a valid location.\n");
}
QMenu* NewTrayMenu = plugin->plugin->GetTrayMenu();
plugin->traymenu = NewTrayMenu;
if(NewTrayMenu)
{
trayIconMenu->insertMenu(actionExit, NewTrayMenu);
}
}
void OpenRGBDialog2::RemovePlugin(OpenRGBPluginEntry* plugin)
{
/*-----------------------------------------------------*\
| Place plugin as its own top level tab |
\*-----------------------------------------------------*/
if(plugin->info.Location == OPENRGB_PLUGIN_LOCATION_TOP)
{
for(int tab_idx = 0; tab_idx < ui->MainTabBar->count(); tab_idx++)
{
if(dynamic_cast<OpenRGBPluginContainer*>(ui->MainTabBar->widget(tab_idx)) != nullptr)
{
if(dynamic_cast<OpenRGBPluginContainer*>(ui->MainTabBar->widget(tab_idx))->plugin_widget == plugin->widget)
{
ui->MainTabBar->removeTab(tab_idx);
delete plugin->widget;
}
}
}
}
/*-----------------------------------------------------*\
| Place plugin in the Devices tab |
\*-----------------------------------------------------*/
else if(plugin->info.Location == OPENRGB_PLUGIN_LOCATION_DEVICES)
{
for(int tab_idx = 0; tab_idx < ui->DevicesTabBar->count(); tab_idx++)
{
if(dynamic_cast<OpenRGBPluginContainer*>(ui->DevicesTabBar->widget(tab_idx)) != nullptr)
{
if(dynamic_cast<OpenRGBPluginContainer*>(ui->DevicesTabBar->widget(tab_idx))->plugin_widget == plugin->widget)
{
ui->DevicesTabBar->removeTab(tab_idx);
delete plugin->widget;
}
}
}
}
/*-----------------------------------------------------*\
| Place plugin in the Information tab |
\*-----------------------------------------------------*/
else if(plugin->info.Location == OPENRGB_PLUGIN_LOCATION_INFORMATION)
{
for(int tab_idx = 0; tab_idx < ui->InformationTabBar->count(); tab_idx++)
{
if(dynamic_cast<OpenRGBPluginContainer*>(ui->InformationTabBar->widget(tab_idx)) != nullptr)
{
if(dynamic_cast<OpenRGBPluginContainer*>(ui->InformationTabBar->widget(tab_idx))->plugin_widget == plugin->widget)
{
ui->InformationTabBar->removeTab(tab_idx);
delete plugin->widget;
}
}
}
}
/*-----------------------------------------------------*\
| Place plugin in the Settings tab |
\*-----------------------------------------------------*/
else if(plugin->info.Location == OPENRGB_PLUGIN_LOCATION_SETTINGS)
{
for(int tab_idx = 0; tab_idx < ui->SettingsTabBar->count(); tab_idx++)
{
if(dynamic_cast<OpenRGBPluginContainer*>(ui->SettingsTabBar->widget(tab_idx)) != nullptr)
{
if(dynamic_cast<OpenRGBPluginContainer*>(ui->SettingsTabBar->widget(tab_idx))->plugin_widget == plugin->widget)
{
ui->SettingsTabBar->removeTab(tab_idx);
delete plugin->widget;
}
}
}
}
if(plugin->traymenu)
{
trayIconMenu->removeAction(plugin->traymenu->menuAction());
}
}
@@ -1118,6 +1311,14 @@ void OpenRGBDialog2::onDetectionProgressUpdated()
}
}
void OpenRGBDialog2::onDetectionEnded()
{
/*-----------------------------------------------------*\
| Detect unconfigured zones and prompt for resizing |
\*-----------------------------------------------------*/
OpenRGBZonesBulkResizer::RunChecks(this);
}
void OpenRGBDialog2::on_SetAllDevices(unsigned char red, unsigned char green, unsigned char blue)
{
for(int device = 0; device < ui->DevicesTabBar->count(); device++)
+16 -1
View File
@@ -4,13 +4,16 @@
#include "ui_OpenRGBDialog2.h"
#include "OpenRGBClientInfoPage.h"
#include "OpenRGBPluginsPage/OpenRGBPluginsPage.h"
#include "OpenRGBSoftwareInfoPage.h"
#include "OpenRGBSystemInfoPage.h"
#include "OpenRGBSupportedDevicesPage.h"
#include "OpenRGBSettingsPage.h"
#include "OpenRGBE131SettingsPage/OpenRGBE131SettingsPage.h"
#include "OpenRGBPhilipsWizSettingsPage/OpenRGBPhilipsWizSettingsPage.h"
#include "OpenRGBQMKORGBSettingsPage/OpenRGBQMKORGBSettingsPage.h"
#include "OpenRGBSerialSettingsPage/OpenRGBSerialSettingsPage.h"
#include "OpenRGBYeelightSettingsPage/OpenRGBYeelightSettingsPage.h"
#include "PluginManager.h"
#include <vector>
@@ -44,6 +47,9 @@ public:
void AddI2CToolsPage();
void AddServerTab();
void AddPlugin(OpenRGBPluginEntry* plugin);
void RemovePlugin(OpenRGBPluginEntry* plugin);
void setMode(unsigned char mode_val);
static bool IsDarkTheme();
@@ -54,13 +60,16 @@ private:
| Page pointers |
\*-------------------------------------*/
OpenRGBClientInfoPage *ClientInfoPage;
OpenRGBPluginsPage *PluginsPage;
OpenRGBSystemInfoPage *SMBusToolsPage;
OpenRGBSoftwareInfoPage *SoftInfoPage;
OpenRGBSupportedDevicesPage *SupportedPage;
OpenRGBSettingsPage *SettingsPage;
OpenRGBE131SettingsPage *E131SettingsPage;
OpenRGBPhilipsWizSettingsPage *PhilipsWizSettingsPage;
OpenRGBQMKORGBSettingsPage *QMKORGBSettingsPage;
OpenRGBSerialSettingsPage *SerialSettingsPage;
OpenRGBYeelightSettingsPage *YeelightSettingsPage;
bool ShowI2CTools = false;
@@ -68,6 +77,7 @@ private:
| System tray icon and menu |
\*-------------------------------------*/
QSystemTrayIcon* trayIcon;
QMenu* trayIconMenu;
QMenu* profileMenu;
/*-------------------------------------*\
@@ -79,9 +89,11 @@ private:
void AddSupportedDevicesPage();
void AddSettingsPage();
void AddE131SettingsPage();
void AddPhilipsWizSettingsPage();
void AddQMKORGBSettingsPage();
void AddSerialSettingsPage();
void AddPluginTab(PluginManager* plugin_manager,int plugin_index);
void AddYeelightSettingsPage();
void AddPluginsPage(PluginManager* plugin_manager);
void ClearDevicesList();
void UpdateDevicesList();
@@ -98,6 +110,8 @@ private:
PluginManager* plugin_manager = nullptr;
QAction* actionExit;
private slots:
void on_Exit();
void on_LightsOff();
@@ -110,6 +124,7 @@ private slots:
void on_QuickWhite();
void onDeviceListUpdated();
void onDetectionProgressUpdated();
void onDetectionEnded();
void on_SetAllDevices(unsigned char red, unsigned char green, unsigned char blue);
void on_SaveSizeProfile();
void on_ShowHide();
@@ -0,0 +1,16 @@
#include "OpenRGBPhilipsWizSettingsEntry.h"
#include "ui_OpenRGBPhilipsWizSettingsEntry.h"
using namespace Ui;
OpenRGBPhilipsWizSettingsEntry::OpenRGBPhilipsWizSettingsEntry(QWidget *parent) :
QWidget(parent),
ui(new Ui::OpenRGBPhilipsWizSettingsEntryUi)
{
ui->setupUi(this);
}
OpenRGBPhilipsWizSettingsEntry::~OpenRGBPhilipsWizSettingsEntry()
{
delete ui;
}
@@ -0,0 +1,21 @@
#ifndef OPENRGBPHILIPSWIZSETTINGSENTRY_H
#define OPENRGBPHILIPSWIZSETTINGSENTRY_H
#include "ui_OpenRGBPhilipsWizSettingsEntry.h"
#include <QWidget>
namespace Ui {
class OpenRGBPhilipsWizSettingsEntry;
}
class Ui::OpenRGBPhilipsWizSettingsEntry : public QWidget
{
Q_OBJECT
public:
explicit OpenRGBPhilipsWizSettingsEntry(QWidget *parent = nullptr);
~OpenRGBPhilipsWizSettingsEntry();
Ui::OpenRGBPhilipsWizSettingsEntryUi *ui;
};
#endif // OPENRGBPHILIPSWIZSETTINGSENTRY_H
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OpenRGBPhilipsWizSettingsEntryUi</class>
<widget class="QWidget" name="OpenRGBPhilipsWizSettingsEntryUi">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>190</width>
<height>59</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="3">
<widget class="QLineEdit" name="IPEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="IPLabel">
<property name="text">
<string>IP:</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>IPEdit</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,105 @@
#include "OpenRGBPhilipsWizSettingsPage.h"
#include "ui_OpenRGBPhilipsWizSettingsPage.h"
#include "ResourceManager.h"
using namespace Ui;
OpenRGBPhilipsWizSettingsPage::OpenRGBPhilipsWizSettingsPage(QWidget *parent) :
QWidget(parent),
ui(new Ui::OpenRGBPhilipsWizSettingsPageUi)
{
ui->setupUi(this);
json wiz_settings;
/*-------------------------------------------------*\
| Get Philips Wiz settings |
\*-------------------------------------------------*/
wiz_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("PhilipsWizDevices");
/*-------------------------------------------------*\
| If the Wiz settings contains devices, process |
\*-------------------------------------------------*/
if(wiz_settings.contains("devices"))
{
for(unsigned int device_idx = 0; device_idx < wiz_settings["devices"].size(); device_idx++)
{
OpenRGBPhilipsWizSettingsEntry* entry = new OpenRGBPhilipsWizSettingsEntry;
if(wiz_settings["devices"][device_idx].contains("ip"))
{
entry->ui->IPEdit->setText(QString::fromStdString(wiz_settings["devices"][device_idx]["ip"]));
}
entries.push_back(entry);
QListWidgetItem* item = new QListWidgetItem;
item->setSizeHint(entry->sizeHint());
ui->PhilipsWizDeviceList->addItem(item);
ui->PhilipsWizDeviceList->setItemWidget(item, entry);
ui->PhilipsWizDeviceList->show();
}
}
}
OpenRGBPhilipsWizSettingsPage::~OpenRGBPhilipsWizSettingsPage()
{
delete ui;
}
void Ui::OpenRGBPhilipsWizSettingsPage::on_AddPhilipsWizDeviceButton_clicked()
{
OpenRGBPhilipsWizSettingsEntry* entry = new OpenRGBPhilipsWizSettingsEntry;
entries.push_back(entry);
QListWidgetItem* item = new QListWidgetItem;
item->setSizeHint(entry->sizeHint());
ui->PhilipsWizDeviceList->addItem(item);
ui->PhilipsWizDeviceList->setItemWidget(item, entry);
ui->PhilipsWizDeviceList->show();
}
void Ui::OpenRGBPhilipsWizSettingsPage::on_RemovePhilipsWizDeviceButton_clicked()
{
int cur_row = ui->PhilipsWizDeviceList->currentRow();
if(cur_row < 0)
{
return;
}
QListWidgetItem* item = ui->PhilipsWizDeviceList->takeItem(cur_row);
ui->PhilipsWizDeviceList->removeItemWidget(item);
delete item;
delete entries[cur_row];
entries.erase(entries.begin() + cur_row);
}
void Ui::OpenRGBPhilipsWizSettingsPage::on_SavePhilipsWizConfigurationButton_clicked()
{
json wiz_settings;
/*-------------------------------------------------*\
| Get Philips Wiz settings |
\*-------------------------------------------------*/
wiz_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("PhilipsWizDevices");
wiz_settings["devices"].clear();
for(unsigned int device_idx = 0; device_idx < entries.size(); device_idx++)
{
/*-------------------------------------------------*\
| Required parameters |
\*-------------------------------------------------*/
wiz_settings["devices"][device_idx]["ip"] = entries[device_idx]->ui->IPEdit->text().toStdString();
}
ResourceManager::get()->GetSettingsManager()->SetSettings("PhilipsWizDevices", wiz_settings);
ResourceManager::get()->GetSettingsManager()->SaveSettings();
}
@@ -0,0 +1,34 @@
#ifndef OPENRGBPHILIPSWIZSETTINGSPAGE_H
#define OPENRGBPHILIPSWIZSETTINGSPAGE_H
#include "ui_OpenRGBPhilipsWizSettingsPage.h"
#include <QWidget>
#include "OpenRGBPhilipsWizSettingsEntry.h"
namespace Ui {
class OpenRGBPhilipsWizSettingsPage;
}
class Ui::OpenRGBPhilipsWizSettingsPage : public QWidget
{
Q_OBJECT
public:
explicit OpenRGBPhilipsWizSettingsPage(QWidget *parent = nullptr);
~OpenRGBPhilipsWizSettingsPage();
private slots:
void on_AddPhilipsWizDeviceButton_clicked();
void on_RemovePhilipsWizDeviceButton_clicked();
void on_SavePhilipsWizConfigurationButton_clicked();
private:
Ui::OpenRGBPhilipsWizSettingsPageUi *ui;
std::vector<OpenRGBPhilipsWizSettingsEntry*> entries;
};
#endif // OPENRGBPHILIPSWIZSETTINGSPAGE_H
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OpenRGBPhilipsWizSettingsPageUi</class>
<widget class="QWidget" name="OpenRGBPhilipsWizSettingsPageUi">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QPushButton" name="AddPhilipsWizDeviceButton">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="RemovePhilipsWizDeviceButton">
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="SavePhilipsWizConfigurationButton">
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QListWidget" name="PhilipsWizDeviceList">
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
+2 -1
View File
@@ -20,9 +20,10 @@ public:
void Hide();
void Show();
QWidget* plugin_widget;
private:
Ui::OpenRGBPluginContainerUi *ui;
QWidget* plugin_widget;
};
#endif // OPENRGBPLUGINCONTAINER_H
@@ -0,0 +1,37 @@
#include "OpenRGBPluginsEntry.h"
#include "ui_OpenRGBPluginsEntry.h"
using namespace Ui;
OpenRGBPluginsEntry::OpenRGBPluginsEntry(QWidget *parent) :
QWidget(parent),
ui(new Ui::OpenRGBPluginsEntryUi)
{
ui->setupUi(this);
EnableClickCallbackVal = nullptr;
EnableClickCallbackArg = nullptr;
}
OpenRGBPluginsEntry::~OpenRGBPluginsEntry()
{
delete ui;
}
void OpenRGBPluginsEntry::RegisterEnableClickCallback(EnableClickCallback new_callback, void * new_callback_arg)
{
EnableClickCallbackVal = new_callback;
EnableClickCallbackArg = new_callback_arg;
}
void Ui::OpenRGBPluginsEntry::on_EnabledCheckBox_stateChanged(int /*checked*/)
{
/*-------------------------------------------------*\
| Call the callbacks |
\*-------------------------------------------------*/
if(EnableClickCallbackVal != nullptr)
{
EnableClickCallbackVal(EnableClickCallbackArg, this);
}
}
@@ -0,0 +1,33 @@
#ifndef OPENRGBPLUGINSENTRY_H
#define OPENRGBPLUGINSENTRY_H
#include "ui_OpenRGBPluginsEntry.h"
#include <QWidget>
namespace Ui
{
class OpenRGBPluginsEntry;
}
typedef void (*EnableClickCallback)(void *, void *);
class Ui::OpenRGBPluginsEntry : public QWidget
{
Q_OBJECT
public:
explicit OpenRGBPluginsEntry(QWidget *parent = nullptr);
~OpenRGBPluginsEntry();
Ui::OpenRGBPluginsEntryUi *ui;
void RegisterEnableClickCallback(EnableClickCallback new_callback, void * new_callback_arg);
private slots:
void on_EnabledCheckBox_stateChanged(int checked);
private:
EnableClickCallback EnableClickCallbackVal;
void * EnableClickCallbackArg;
};
#endif // OPENRGBPLUGINSENTRY_H
@@ -0,0 +1,183 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OpenRGBPluginsEntryUi</class>
<widget class="QWidget" name="OpenRGBPluginsEntryUi">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>478</width>
<height>238</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="3" column="1">
<widget class="QLabel" name="VersionLabel">
<property name="text">
<string>Version:</string>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QCheckBox" name="EnabledCheckBox">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLabel" name="PathValue">
<property name="text">
<string>Path Value</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="DescriptionValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Description Value</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="NameLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="DescriptionLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Description:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="URLLabel">
<property name="text">
<string>URL:</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="NameValue">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Name Value</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QLabel" name="VersionValue">
<property name="text">
<string>Version Value</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QLabel" name="CommitValue">
<property name="text">
<string>Commit Value</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="PathLabel">
<property name="text">
<string>Path:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QLabel" name="EnabledLabel">
<property name="text">
<string>Enabled</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="CommitLabel">
<property name="text">
<string>Commit:</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLabel" name="URLValue">
<property name="text">
<string>URL Value</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="7">
<widget class="QLabel" name="IconView">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="text">
<string>Icon</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,45 @@
#include "OpenRGBPluginsList.h"
#include <QMimeData>
#include <QUrl>
OpenRGBPluginsList::OpenRGBPluginsList(QWidget *parent) : QListWidget (parent)
{
setAcceptDrops(true);
}
void OpenRGBPluginsList::dropEvent(QDropEvent *event)
{
const QMimeData* mimeData = event->mimeData();
if (mimeData->hasUrls())
{
std::vector<std::string> path_list;
QList<QUrl> urls = mimeData->urls();
for(const QUrl& url: urls)
{
path_list.push_back(url.toLocalFile().toStdString());
}
emit PluginsDropped(path_list);
}
}
void OpenRGBPluginsList::dragEnterEvent(QDragEnterEvent *event)
{
if (event->mimeData()->hasUrls())
{
event->acceptProposedAction();
}
else
{
event->ignore();
}
}
void OpenRGBPluginsList::dragMoveEvent(QDragMoveEvent *event)
{
event->acceptProposedAction();
}
@@ -0,0 +1,24 @@
#ifndef OPENRGBPLUGINSLIST_H
#define OPENRGBPLUGINSLIST_H
#include <QListWidget>
#include <QDropEvent>
#include <QDragEnterEvent>
class OpenRGBPluginsList : public QListWidget
{
Q_OBJECT
public:
OpenRGBPluginsList(QWidget *parent = nullptr);
signals:
void PluginsDropped(std::vector<std::string>);
protected:
void dropEvent(QDropEvent *event) override;
void dragEnterEvent(QDragEnterEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
};
#endif // OPENRGBPLUGINSLIST_H
@@ -0,0 +1,336 @@
#include <QFileDialog>
#include <QMessageBox>
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include "filesystem.h"
#include "OpenRGBPluginsPage.h"
#include "ui_OpenRGBPluginsPage.h"
void EnableClickCallbackFunction(void* this_ptr, void* entry_ptr)
{
Ui::OpenRGBPluginsPage* this_page = (Ui::OpenRGBPluginsPage*)this_ptr;
this_page->on_EnableButton_clicked((Ui::OpenRGBPluginsEntry*)entry_ptr);
}
Ui::OpenRGBPluginsPage::OpenRGBPluginsPage(PluginManager* plugin_manager_ptr, QWidget *parent) :
QWidget(parent),
ui(new Ui::OpenRGBPluginsPageUi)
{
plugin_manager = plugin_manager_ptr;
ui->setupUi(this);
RefreshList();
}
Ui::OpenRGBPluginsPage::~OpenRGBPluginsPage()
{
delete ui;
}
void Ui::OpenRGBPluginsPage::RefreshList()
{
ui->PluginsList->clear();
entries.clear();
for(unsigned int plugin_idx = 0; plugin_idx < plugin_manager->ActivePlugins.size(); plugin_idx++)
{
OpenRGBPluginsEntry* entry = new OpenRGBPluginsEntry();
/*---------------------------------------------------------*\
| Fill in plugin information fields |
\*---------------------------------------------------------*/
entry->ui->NameValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.Name));
entry->ui->DescriptionValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.Description));
entry->ui->VersionValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.Version));
entry->ui->CommitValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.Commit));
entry->ui->URLValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].info.URL));
/*---------------------------------------------------------*\
| Fill in plugin icon |
\*---------------------------------------------------------*/
QPixmap pixmap(QPixmap::fromImage(plugin_manager->ActivePlugins[plugin_idx].info.Icon));
entry->ui->IconView->setPixmap(pixmap);
entry->ui->IconView->setScaledContents(true);
/*---------------------------------------------------------*\
| Fill in plugin path |
\*---------------------------------------------------------*/
entry->ui->PathValue->setText(QString::fromStdString(plugin_manager->ActivePlugins[plugin_idx].path));
/*---------------------------------------------------------*\
| Fill in plugin enabled status |
\*---------------------------------------------------------*/
entry->ui->EnabledCheckBox->setChecked((plugin_manager->ActivePlugins[plugin_idx].enabled));
entry->RegisterEnableClickCallback(EnableClickCallbackFunction, this);
/*---------------------------------------------------------*\
| Add the entry to the plugin list |
\*---------------------------------------------------------*/
QListWidgetItem* item = new QListWidgetItem;
item->setSizeHint(entry->sizeHint());
ui->PluginsList->addItem(item);
ui->PluginsList->setItemWidget(item, entry);
entries.push_back(entry);
}
}
void Ui::OpenRGBPluginsPage::on_InstallPluginButton_clicked()
{
/*-----------------------------------------------------*\
| Open a file selection prompt to choose the plugin file|
\*-----------------------------------------------------*/
QString install_file = QFileDialog::getOpenFileName(this, "Install OpenRGB Plugin", "", "DLL Files (*.dll; *.dylib; *.so; *.so.*)");
bool installed = InstallPlugin(install_file.toStdString());
if(installed)
{
RefreshList();
}
}
bool Ui::OpenRGBPluginsPage::InstallPlugin(std::string install_file)
{
std::string from_path = install_file;
std::string to_path = ResourceManager::get()->GetConfigurationDirectory() + "plugins/";
std::string to_file = to_path + filesystem::path(from_path).filename().string();
bool match = false;
/*-----------------------------------------------------*\
| Check if a plugin with this path already exists |
\*-----------------------------------------------------*/
for(unsigned int plugin_idx = 0; plugin_idx < plugin_manager->ActivePlugins.size(); plugin_idx++)
{
if(to_file == plugin_manager->ActivePlugins[plugin_idx].path)
{
match = true;
break;
}
}
/*-----------------------------------------------------*\
| If this plugin already exists, prompt to replace it |
\*-----------------------------------------------------*/
if(match == true)
{
QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, "Replace Plugin", "A plugin with this filename is already installed. Are you sure you want to replace this plugin?", QMessageBox::Yes | QMessageBox::No);
if(reply != QMessageBox::Yes)
{
return false;
}
}
/*-----------------------------------------------------*\
| When replacing, remove the existing plugin before |
| copying the file and adding the new one |
\*-----------------------------------------------------*/
try
{
plugin_manager->RemovePlugin(to_file);
filesystem::copy(from_path, to_path, filesystem::copy_options::update_existing);
plugin_manager->AddPlugin(to_file);
return true;
}
catch(std::exception& e)
{
}
return false;
}
void Ui::OpenRGBPluginsPage::on_RemovePluginButton_clicked()
{
QMessageBox::StandardButton reply;
/*-----------------------------------------------------*\
| Confirm plugin removal with message box |
\*-----------------------------------------------------*/
reply = QMessageBox::question(this, "Remove Plugin", "Are you sure you want to remove this plugin?", QMessageBox::Yes | QMessageBox::No);
if(reply != QMessageBox::Yes)
{
return;
}
/*-----------------------------------------------------*\
| Get index of selected plugin entry |
\*-----------------------------------------------------*/
int cur_row = ui->PluginsList->currentRow();
if(cur_row < 0)
{
return;
}
/*-----------------------------------------------------*\
| Open plugin settings |
\*-----------------------------------------------------*/
json plugin_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("Plugins");
/*-----------------------------------------------------*\
| Find plugin's entry in settings and remove it |
\*-----------------------------------------------------*/
if(plugin_settings.contains("plugins"))
{
for(unsigned int plugin_idx = 0; plugin_idx < plugin_settings["plugins"].size(); plugin_idx++)
{
if((plugin_settings["plugins"][plugin_idx].contains("name"))
&&(plugin_settings["plugins"][plugin_idx].contains("description")))
{
if((plugin_settings["plugins"][plugin_idx]["name"] == entries[cur_row]->ui->NameValue->text().toStdString())
&&(plugin_settings["plugins"][plugin_idx]["description"] == entries[cur_row]->ui->DescriptionValue->text().toStdString()))
{
plugin_settings["plugins"].erase(plugin_idx);
ResourceManager::get()->GetSettingsManager()->SetSettings("Plugins", plugin_settings);
ResourceManager::get()->GetSettingsManager()->SaveSettings();
break;
}
}
}
}
/*-----------------------------------------------------*\
| Remove plugin entry from GUI plugin entries list |
\*-----------------------------------------------------*/
QListWidgetItem* item = ui->PluginsList->takeItem(cur_row);
ui->PluginsList->removeItemWidget(item);
delete item;
/*-----------------------------------------------------*\
| Command plugin manager to unload and remove the plugin|
\*-----------------------------------------------------*/
plugin_manager->RemovePlugin(entries[cur_row]->ui->PathValue->text().toStdString());
/*-----------------------------------------------------*\
| Delete the plugin file and refresh the GUI |
\*-----------------------------------------------------*/
filesystem::remove(entries[cur_row]->ui->PathValue->text().toStdString());
RefreshList();
}
void Ui::OpenRGBPluginsPage::on_EnableButton_clicked(OpenRGBPluginsEntry* entry)
{
/*-----------------------------------------------------*\
| Open plugin list and check if plugin is in the list |
\*-----------------------------------------------------*/
json plugin_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("Plugins");
/*-----------------------------------------------------*\
| Search the settings to find the correct index |
\*-----------------------------------------------------*/
std::string name = "";
std::string description = "";
bool enabled = true;
bool found = false;
unsigned int plugin_ct = 0;
unsigned int plugin_idx = 0;
std::string entry_name = entry->ui->NameValue->text().toStdString();
std::string entry_desc = entry->ui->DescriptionValue->text().toStdString();
std::string entry_path = entry->ui->PathValue->text().toStdString();
if(entry->ui->EnabledCheckBox->isChecked())
{
enabled = true;
}
else
{
enabled = false;
}
if(plugin_settings.contains("plugins"))
{
plugin_ct = plugin_settings["plugins"].size();
for(plugin_idx = 0; plugin_idx < plugin_settings["plugins"].size(); plugin_idx++)
{
if(plugin_settings["plugins"][plugin_idx].contains("name"))
{
name = plugin_settings["plugins"][plugin_idx]["name"];
}
if(plugin_settings["plugins"][plugin_idx].contains("description"))
{
description = plugin_settings["plugins"][plugin_idx]["description"];
}
if((entry_name == name)
&&(entry_desc == description))
{
found = true;
break;
}
}
}
/*-----------------------------------------------------*\
| If the plugin was not in the list, add it to the list |
| and default it to enabled, then save the settings |
\*-----------------------------------------------------*/
if(!found)
{
plugin_settings["plugins"][plugin_ct]["name"] = entry_name;
plugin_settings["plugins"][plugin_ct]["description"] = entry_desc;
plugin_settings["plugins"][plugin_ct]["enabled"] = enabled;
ResourceManager::get()->GetSettingsManager()->SetSettings("Plugins", plugin_settings);
ResourceManager::get()->GetSettingsManager()->SaveSettings();
}
else
{
plugin_settings["plugins"][plugin_idx]["enabled"] = enabled;
ResourceManager::get()->GetSettingsManager()->SetSettings("Plugins", plugin_settings);
ResourceManager::get()->GetSettingsManager()->SaveSettings();
}
if(enabled)
{
plugin_manager->LoadPlugin(entry_path);
}
else
{
plugin_manager->UnloadPlugin(entry_path);
}
}
void Ui::OpenRGBPluginsPage::on_PluginsList_itemSelectionChanged()
{
/*-----------------------------------------------------*\
| Enable the remove button when there's a selected item |
\*-----------------------------------------------------*/
ui->RemovePluginButton->setEnabled(!ui->PluginsList->selectedItems().empty());
}
void Ui::OpenRGBPluginsPage::on_PluginsList_PluginsDropped(std::vector<std::string> path_list)
{
bool installed = false;
for(const std::string& file_path: path_list)
{
installed |= InstallPlugin(file_path);
}
if(installed)
{
RefreshList();
}
}
@@ -0,0 +1,42 @@
#ifndef OPENRGBPLUGINSPAGE_H
#define OPENRGBPLUGINSPAGE_H
#include <QWidget>
#include "OpenRGBPluginsEntry.h"
#include "ui_OpenRGBPluginsPage.h"
#include "PluginManager.h"
namespace Ui
{
class OpenRGBPluginsPage;
}
class Ui::OpenRGBPluginsPage : public QWidget
{
Q_OBJECT
public:
explicit OpenRGBPluginsPage(PluginManager* plugin_manager_ptr, QWidget *parent = nullptr);
~OpenRGBPluginsPage();
void on_EnableButton_clicked(OpenRGBPluginsEntry* entry);
private slots:
void on_InstallPluginButton_clicked();
void on_RemovePluginButton_clicked();
void on_PluginsList_itemSelectionChanged();
void on_PluginsList_PluginsDropped(std::vector<std::string>);
private:
Ui::OpenRGBPluginsPageUi* ui;
PluginManager* plugin_manager;
std::vector<OpenRGBPluginsEntry*> entries;
bool InstallPlugin(std::string path);
void RefreshList();
};
#endif // OPENRGBPLUGINSPAGE_H
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>OpenRGBPluginsPageUi</class>
<widget class="QWidget" name="OpenRGBPluginsPageUi">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QPushButton" name="InstallPluginButton">
<property name="text">
<string>Install Plugin</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="RemovePluginButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Remove Plugin</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="OpenRGBPluginsList" name="PluginsList">
<property name="verticalScrollMode">
<enum>QAbstractItemView::ScrollPerPixel</enum>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>OpenRGBPluginsList</class>
<extends>QListWidget</extends>
<header>qt/OpenRGBPluginsPage/OpenRGBPluginsList.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
+17
View File
@@ -58,6 +58,15 @@ OpenRGBSettingsPage::OpenRGBSettingsPage(QWidget *parent) :
}
}
if(ui_settings.contains("RunZoneChecks"))
{
ui->CheckboxRunZoneChecks->setChecked(ui_settings["RunZoneChecks"]);
}
else
{ // default value
ui->CheckboxRunZoneChecks->setChecked(true);
}
/*---------------------------------------------------------*\
| Load AutoStart settings |
\*---------------------------------------------------------*/
@@ -156,6 +165,14 @@ void Ui::OpenRGBSettingsPage::on_CheckboxSaveGeometry_clicked()
SaveSettings();
}
void Ui::OpenRGBSettingsPage::on_CheckboxRunZoneChecks_clicked()
{
json ui_settings = ResourceManager::get()->GetSettingsManager()->GetSettings("UserInterface");
ui_settings["RunZoneChecks"] = ui->CheckboxRunZoneChecks->isChecked();
ResourceManager::get()->GetSettingsManager()->SetSettings("UserInterface", ui_settings);
SaveSettings();
}
void Ui::OpenRGBSettingsPage::on_CheckboxAutoStart_clicked()
{
if(autostart_initialized)

Some files were not shown because too many files have changed in this diff Show More