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
Adam Honse 7327644d26 Use TabLabel for all tab labels and adjust the TabLabel widget layout so that it aligns with the previous HTML label layout. Height is slightly increased for two-line labels. 2021-08-17 19:44:20 -05:00
Adam Honse bbc16a9ae2 Rename DeviceTabHeader to TabLabel, so we can use it for all tabs rather than just device tabs 2021-08-17 19:13:28 -05:00
Harry Kantas 507cece3cc Added Razer Book 13 (2020) under Master Device List 2021-08-17 23:29:15 +00:00
TheRogueZeta 3367892b75 Add EVGA RTX 2080TI XC Hybrid Gaming to detector 2021-08-17 12:33:37 -07:00
Spucknapf 468cf81a61 fix dangling reference in HueEntertainment 2021-08-17 16:42:39 +02:00
Jeffrey Geer 988f56ee5a Added MSI RTX 3080 Ti Gaming X Trio 12G PCI IDs to MSIGPU 2021-08-17 13:12:09 +00:00
Chris 0281274379 Correcting Usage Page for the ROG Gladius II Wireless 2021-08-17 13:08:26 +00:00
Chris 042d4b1240 Correcting Usage Page for the ROG Pugio II to resolve #1706 2021-08-17 13:08:26 +00:00
Spucknapf 959a8350b0 Fix dangling reference 2021-08-17 09:59:49 +02:00
Harry Kantas 0419d1ab84 Add support for Razer Book 13 (2020)
Commit amended for code style by Adam Honse <[email protected]>
2021-08-16 07:25:41 -05:00
Chris a479c424c9 Adding support for the MSI MEG X570 GODLIKE (MS-7C34)
* Requested on Discord by @TheGrandFinale2001
2021-08-15 20:25:35 +00:00
Chris f3c977f5fb Adding the G910 to UDEV rules 2021-08-15 13:29:07 +10:00
Chris 0883a48be3 Reordering zones on the Lancehead Tournament Edition to resolve #1698 2021-08-14 18:14:43 +00:00
Chris c2bc34081e Code Cleanup for the Asus Aura Mouse Controller
* Moved device mapping to separate AsusAuraMouseDevices.h
* Changed map structure from strings to uint8
* Changed RGBController_AsusAuraMouse.cpp code to accomodate new mapping
* Added device_pid to AuraMouseController constructor to ensure cross platform compatibility
* Reversed speed min / max as controller expects 255 as "slow"
* Separated SaveMode() to avoid extra boolean
2021-08-14 18:20:16 +10:00
Mola19 926f62f512 Add more ASUS Mice, make ASUS mouse controller more flexible
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-08-14 00:53:01 -05:00
K900 f735adf956 SapphireGPUController: add RX6700XT Nitro+ 2021-08-13 03:10:14 +00:00
Alex af5006e08f Add abnt / key to the controlled leds 2021-08-12 03:01:20 +00:00
Vova b06f62dddd Add MSI GeForce RTX 3060 Ti 8GB Gaming X Trio LHR 2021-08-10 15:27:10 -05:00
Adam Honse f307250e67 Add MSI Mystic Light 7C83 2021-08-09 13:31:18 -05:00
Adam Honse d5e94c3d60 Add MSI Mystic Light 7C81 2021-08-09 17:18:58 +00:00
Chris b7a0a3b4f7 Updating controller to allow 'Direct' mode for FW0012
+ Adjusted setLedsDirect() for new protocol
2021-08-09 05:37:24 +00:00
Chris 3e6acbd049 Initial commit for the Coolermaster MM711 mouse
* Implemented brightness
* Implemented GetStatus packets for UI set up
2021-08-07 20:12:02 +00:00
TheRogueZeta 1ba3c6adde Add RTX 3060 v2 Device ID & update Gigabyte detector for #1676 2021-08-06 13:15:16 -07:00
Alex 15376d939b Add MSI GeForce RTX 2080 Duke 8G OC to detection 2021-08-05 19:31:49 +00:00
TheRogueZeta 722f819edd Add ASUS ROG STRIX RX480 Gaming OC device ID 2021-08-04 20:04:05 +00:00
Alex 6e0e14260b Add Gigabyte RTX3070 Ti Gaming OC 8G to detection 2021-08-03 04:26:30 +00:00
Auirsblade 7dc2a93c4a Add Mystic Light 7D06 (185-byte) 2021-08-03 04:26:06 +00:00
Adam Honse d13d54fcfd Fix access conflicts in HyperX controllers where keepalive thread was directly accessing hardware 2021-08-02 12:41:24 -05:00
Chris 2d141be356 Adding brightness to the Coolermaster Small ARGB Controller 2021-08-02 12:32:02 +00:00
morg 5efd3e0a20 Make sure to display both line even with scaled resolution. Fix #1666. 2021-08-02 12:30:00 +00:00
Adam Honse dc142f40d3 Add settings tab for QMK OpenRGB protocol devices 2021-08-01 21:27:29 -05:00
Adam Honse bfe8e7a997 Move OpenRGBSerialSettingsPage files to a folder 2021-08-01 21:04:52 -05:00
Adam Honse c8b3c2a2ea Move OpenRGBE131SettingsPage files to a folder 2021-08-01 20:39:12 -05:00
Ferrah Aiko Wolf 8534b3d8dc Add digital modes to RGB Fusion 2 SMBus controller 2021-08-01 20:22:17 -05:00
Erik Hanson 3605e53d83 Add EVGA RTX 2080 SUPER FTW3 Ultra 2021-08-02 01:16:46 +00:00
Santeri Pikarinen e7e311d931 HyperX Pulsefire Dart: Various fixes, feature additions and clean up
* Fixed payload missing the Report ID (caused issues with Windows, issue #1069)
* Fixed an invalid usage page value for wired mode
* Fixed a potential memory leak when rescanning devices (issue #1007)
* Fixed an issue where multiple color changes were sent too fast
* Renamed "Trigger Fade" mode to the [standardized mode name](https://gitlab.com/CalcProgrammer1/OpenRGB/-/wikis/Common-Modes#common-openrgb-modes) "Reactive"
* Added proper brightness control
* Added manual saving functionality
* Cleaned up some indentations
2021-08-02 01:15:07 +00:00
Alexander Acevedo 9f18edf90e Fix Alienware Controller Brightness 2021-07-30 03:39:05 +00:00
morg 762ecbcc1f Display device name on 2 lines if needed. Fix #1480 2021-07-28 23:40:13 +00:00
Adam Honse ac921f8a29 Fix some build warnings 2021-07-28 18:28:16 -05:00
Alexander Acevedo 87ba08602f disable LTO for debian package builds 2021-07-28 20:16:32 +00:00
Pol Rius 8e6e5c1bec Disable lto build (fedora) 2021-07-28 20:15:48 +00:00
Qwex e3b66c7f60 Add Razer Blade 15 (Late 2020) PID to the detection 2021-07-28 16:04:46 +00:00
edbgon 85cd198324 Fix for profile loading Steelseries Apex 2021-07-28 16:02:24 +00:00
Alexander Acevedo 6997017879 Add Dell G7 15 7500 Support
Commit amended by Adam Honse <[email protected]>
2021-07-28 10:52:02 -05:00
Pol Rius eef55e6d6e Implement saving for steelseries rival and sensei mice 2021-07-28 10:28:22 -05:00
morg 057b3d0878 Add some rules to qss for missing targets. Fixes #1651 2021-07-28 11:01:02 +02:00
TheRogueZeta 26259ff863 Fix Gigabyte RTX 2060S Gaming OC 3x White ID 2021-07-26 15:18:35 -07:00
TheRogueZeta 2a9bf67e56 Update ASRock Polychrome SMBus logging messages 2021-07-25 23:54:06 +00:00
TheRogueZeta 755828a337 Add Intel Rocket Lake SMBus ID to PCI IDs 2021-07-25 16:32:23 -07:00
Ksaper 4081cda8df Add QMK OpenRGB Protocol Revision B Controller
* Updates for direct mode initialization to work with the new QMK Update
    * Merge each 8 GetLEDInfo HID calls into one single call
    * Merge all IsEnabledMode HID calls into one single call
    * Update protocol version

Commits squashed and amended by Adam Honse <[email protected]>
2021-07-25 17:01:50 -05:00
Adam Honse cbc07aae0e Re-add unmodified QMK files for merging 2021-07-25 15:16:17 -05:00
Adam Honse 6cee56ac78 Rename QMK OpenRGB controller to QMK OpenRGB Rev9 controller prior to merging new protocol MR 2021-07-25 15:05:01 -05:00
Chris 84de7ebc3e Splitting out the WootingTwoKeyboardController
* Added WootingOneKeyboardController.h
* Added WootingOneKeyboardController.cpp
* Added WootingTwoKeyboardController.h
* Added WootingTwoKeyboardController.cpp
* Unified the WootingKeyboardController as a virtual class
* Modified WootingKeyboardControllerDetect to use the new controllers
* Wooting One & Two use the old controller
* Wooting Two LE & HE use the new controller
* Adding Udev rules for the WootingTwo LE & HE
2021-07-25 18:52:00 +00:00
Chris 41ac14dd41 Adding DEBUG logging & detection fixes to resolve #1592
+ Logitech detection and set up includes debug logging for troubleshooting
+ Adding a pre check to LogitechLightspeedController::GetSerialString()

* Rearranging check logic to ensure that all usages per device are bundled
* Adding PID check to usage bundle to ensure we don't roll into the next device in hid_device_info
- Code cleanup to remove dev_use1 post detection & decoupling the bundled usages for wired lightspeed devices
* Changing wired lightspeed devices to REGISTER_HID_DETECTOR_IPU to target the correct FAP long message usage

+ Adding device validity check isValid() from @cheerpipe
+ Adding wireless check into connected() prior to initialising device
+ Adding the getDeviceFeatureList() back into the Logitech Lightspeed device set up
+ Changed getRGBconfig() for more robust detection

+ Adding Powerplay Mat virtual PID for Linux
+ Adding Logitech G733 for testing @ I=2 P=0xFF43 U=514
+ Adding LOGITECH_POWERPLAY_MAT_VIRTUAL_PID to Linux detection
+ Adding LOGITECH_POWERPLAY_MAT_VIRTUAL_PID and LOGITECH_G733_PID to 60-openrgb.rules
+ Adding LOGITECH_DEVICE_TYPE mapping and extending validity to include new HEADSET type
2021-07-26 00:09:33 +10:00
Youda008 c63aba1066 added OpenRGB-cppSDK to the list of existing SDKs 2021-07-25 08:05:25 +00:00
Adam Honse 6623508757 Update icons for E1.31 settings and Serial settings tabs 2021-07-25 03:04:11 -05:00
Adam Honse 221e332440 Add settings tab for configuring serial LED strip devices. Add the ability to name them. 2021-07-24 02:27:14 -05:00
morg c17b519c08 Update plugins list in README 2021-07-23 11:32:03 +02:00
Chris 06d2a6ce4d Changing _WIN32 definition to the more universal USE_HID_USAGE to correct detection for libhidapi > v10 2021-07-22 12:19:31 +10:00
morg c96d1c24b0 Review plugins list in README. Add Scheduler plugin. 2021-07-21 14:28:51 +00:00
B Horn a1dcf7c1cf Using <chrono> to measure time in the LogManager
`clock()`, which was used previously, behaves differently on various platform.
So switching to this lets us use a standard part of the language which
avoids this.

Signed-off-by: B Horn <[email protected]>
2021-07-21 00:52:01 +00:00
Diogo Trindade d9de79abfe Added Asus Rog Strix 1070 ti 8GB pci id 2021-07-20 19:51:03 -05:00
Adam Honse 952bb6330f Fix swatch adding when clicking black swatch 2021-07-16 22:21:10 -05:00
Adam Honse 18bd9d07b4 Initialize BlinkyTape LED count to zero for consistency with other ARGB controllers 2021-07-16 22:15:14 -05:00
Matt Mets 0db567b8bc Add support for BlinkyTape LED controllers
This adds support for the Blinkinlabs BlinkyTape controller, a
USB-powered digital LED strip controller. Devices are detected
automatically by scanning for their VID/PID, and connected to using
serial.

This code was tested in Windows.

Commit squashed and amended for code style and to fix Linux build by Adam Honse <[email protected]>
2021-07-16 20:07:26 -05:00
Adam Honse dc19fad608 Scroll per-pixel rather than per-item on E131 config page 2021-07-14 23:29:22 -05:00
Adam Honse 6b9a97f78f Add settings page for configuring E1.31 devices 2021-07-14 23:02:58 -05:00
Adam Honse 156ebbc071 Make settings page scrollable 2021-07-14 18:23:16 -05:00
Adam Honse 8af4909621 Add brightness control for Gigabyte GPUs 2021-07-14 17:41:23 -05:00
Chris 5d30d6127b Fix for brightness in Direct mode in Fusion2USB controller
* Added definition for `RGBFUSION2_BRIGHTNESS_MAX`
* Updated modes to reflect new definition
* Added brightness to mode `Direct`
2021-07-13 19:00:09 +00:00
TheRogueZeta b36673bcad Add Gigabyte GTX1060 G1 Gaming 6G OC to detector 2021-07-12 21:48:42 +00:00
Pescu 4dfc515242 Add PCI ID for Gigabyte RTX 3060 TI Gaming OC 2021-07-12 20:54:12 +00:00
TheRogueZeta 49af56eff5 Add PCI ID for Gigabyte RTX 2060S Gaming OC 3X White 8G 2021-07-11 06:11:16 +00:00
Pescu 32ac0c12e0 Add support for GIGABYTE GeForce RTX 2060 SUPER GAMING OC 8G 2021-07-11 06:10:47 +00:00
Jesse Kawell 2f6000c83a Add Razer "Basilisk V2" mouse 2021-07-09 23:48:53 +00:00
Chris f3a840c30d Adding the MSI 7C95 motherboard to 185byte controller
* As requested by @orangejake on Discord
2021-07-09 02:28:10 +10:00
edbgon b14abd9987 Update CMR6000 controller to direct mode and remove unreliable mode detection routine 2021-07-08 11:13:09 +02:00
Chris bd8704a8a6 Adding more DEBUG information
Commit amended for code style by Adam Honse <[email protected]>
2021-07-07 23:33:03 -05:00
Chris 79e1233635 Adding Wooting Two keyboards support
+ Add full matrix map
+ Amend WootingKeyboardController::SendDirect to support extra keys
+ Adjust WootingKeyboardController::wooting_usb_send_buffer to support extra buffer
2021-07-07 23:18:24 -05:00
Chris ad6d605c88 Changing Wooting KB detection to PU
* Simplified detection
* Adding more useful data to `info page`
* Adding DEBUG logging
2021-07-07 23:15:14 -05:00
Shayne Hartford 62906e7f10 Add Wooting LE & HE and fix Wooting initialization on Linux
Commits squashed and amended to remove commented code by Adam Honse <[email protected]>
2021-07-07 23:08:00 -05:00
Nic Wolfe efb19ab6c6 Add support for CoolerMaster RGB Controller
Commits squashed and amended for code style/brightness control by Adam Honse <[email protected]>
2021-07-07 22:55:24 -05:00
Travis Sandmann 85631bfd52 Initial HP Omen 30L Support
Commits squashed and amended for code style/brightness control by Adam Honse <[email protected]>
2021-07-07 22:19:40 -05:00
Cheerpipe e52ba49815 Add Comet Lake H SMBUS PCI ID
From a 10900k with a z490 chipset.

More info on: https://github.com/torvalds/linux/blob/master/drivers/i2c/busses/i2c-i801.c
2021-07-08 02:34:01 +00:00
Cheerpipe 002fc4f2b3 Fix Logitech G815 keyboard freezing
Keyboard may freeze when running GHUB and OpenRGB at the same time. This fixes this.

Commits squashed by Adam Honse <[email protected]>
2021-07-07 17:04:48 -05:00
Adam Demasi a008f14e38 Add ASUS Falchion 65% keyboard. 2021-07-07 21:57:14 +00:00
Cheerpipe 3100f72601 Fix frames skip when using external effects engine 2021-07-07 16:56:02 -05:00
morg c9a1e1bf85 Make sure to load the zones sizes. Fixes #1602 2021-07-06 10:16:35 +02:00
Gabriel Marcano 9062be4462 New device: Dell G5 SE Alienware LED Keyboard
- 4 region keyboard LED controller (tried to keep controller generic
   for other setups as well)
 - Support for Static, Flashing, Morph, Spectrum Cycle, Rainbow Wave,
   and Breathing modes
 - Implemented rate limiting for sending reports since the controller
   crashes if too many reports are sent too quickly. Also implemented
   functionality to prevent sending frivolous update requests
 - Implemented support for setting mode, color, tempo, and period
   independently for each zone (not fully exposed in UI). Morph mode
   exposes 2 colors per zone.

Commit amended for code style by Adam Honse <[email protected]>
2021-07-06 01:51:55 -05:00
Alex 4c41a8834d Fix some logging mistake 2021-07-05 23:07:00 -05:00
John Simons ef36664ef2 Gigabyte 3070 Gaming OC 8G 2021-07-05 22:53:27 +00:00
Adam Honse 1c6a67e056 Add automatic save flag to Corsair Lighting Node hardware modes 2021-07-05 13:39:35 -05:00
Adam Honse aa8c6b6fff Revert "Use block writes for updating all LEDs at once on ASUS Aura SMBus"
This reverts commit 618faf42ec.
2021-07-05 12:43:25 -05:00
Adam Honse 68d27e58f4 Add brightness control for Logitech Lightsync mice (only for Spectrum Cycle and Breathing modes) 2021-07-05 12:39:59 -05:00
morg ec5e71424c Enable/Disable devices checkbox now takes filter into account. Fix #1587 2021-07-05 09:05:40 +00:00
Adam Honse cbee33706f Fix some issues with mode constructor 2021-07-05 04:04:27 -05:00
Adam Honse 811139107e Add automatic save flags to Sinowealth Mouse controller modes 2021-07-05 04:01:33 -05:00
Alex 4af8614fce Add formated loging for device detection
Commits merged and amended for code style by Adam Honse <[email protected]>
2021-07-05 03:23:34 -05:00
Adam Honse 5a7879415f Add automatic save flags to Redragon Mouse controller modes 2021-07-04 21:18:13 -05:00
Adam Honse 25747a6c26 Add automatic save flags to EVision Keyboard controller modes 2021-07-04 21:18:06 -05:00
Adam Honse 5130f07e21 Add saving support to network protocol 2021-07-04 21:17:55 -05:00
Adam Honse eade8fea1a Add save to device support to RGBController 2021-07-04 21:17:45 -05:00
Adam Honse c2a353ec6f Add brightness control to Corsair Lighting Node controller 2021-07-04 21:17:36 -05:00
edbgon b49aeacd18 Added brightness control to CMR6000 device for color cycle mode
Commits merged by Adam Honse <[email protected]>
2021-07-04 21:17:21 -05:00
Chris 3ec91186e8 Add brightness control to Gigabyte RGB Fusion 2 USB Controller
Commit split from original brightness commit by Adam Honse <[email protected]>
2021-07-04 21:17:14 -05:00
Adam Honse f91823c0d5 Add brightness control to RazerController 2021-07-04 21:17:04 -05:00
Chris a46eccef3c Added brightness to profile loading and saving
* Bumped profile version to 3
* Loading a v1/v2 profile onto a device with brightness will work
* Loading a v3 profile onto a device without brightness also works
* Add profile version parameter to Get/SetModeDescription

Commit amended for code style and to update versioning by Adam Honse <[email protected]>
2021-07-04 21:16:56 -05:00
Chris 6fd2ea9276 Initial commit for Brightness in RGBController API
* Added DeviceHasBrightness() = false; to RGBController as overridable
* Added Brightness to Mode struct
* Added BrightnessSlider to the OpenRGBDevicePage ui and the supporting
code to pass to the RGBController

Commit amended for code style and to split API changes and controller changes out by Adam Honse
<[email protected]>
2021-07-04 21:16:49 -05:00
Chris f6c038857a Adding custom swatch widget
* Supports configurable set palette
* Ability to add custom colours
* Can be resized and geometry changed at compile

Commit amended by Adam Honse <[email protected]>

* Ability to add custom colors disabled for now
* Scaling by width, not height
* Fill rows first, then cols
2021-07-04 15:49:19 -05:00
TheRogueZeta 60f189fe06 PCI ID for Coffee Lake S SMBus controller 2021-07-03 17:20:07 -07:00
TheRogueZeta 300a4654a2 PCI ID for Coffee Lake SMBus controller 2021-07-03 17:18:56 -07:00
Jay Schmidek 5a597d4bb2 Add Gigabyte RTX 3090 Gaming OC 24GB 2021-07-03 09:06:36 +00:00
Chris 7e7db6642d Swapping zones on the Naga Trinity
* Swapping Logo zone with the Scroll Wheel zone to correct the zone order as reported by @pbanj on Discord
2021-07-03 13:19:23 +10:00
TheRogueZeta b7c8e9603c Update SteelSeries QCK PID names to match sizes 2021-07-02 19:04:53 +00:00
Adam Honse 06c6ec2196 Add MacOS autostart support 2021-07-02 01:23:50 -05:00
Adam Honse 5a968f5ae6 Fix leds_per_update issue in QMK controller 2021-07-01 22:04:58 -05:00
Matthew Mets 07df6b7a1f Bugfix: Use correct path when opening serial devices on Windows 2021-06-30 19:32:35 +00:00
Chris 22117c7ece Initial commit for the Razer Basilisk Ultimate
* Adding entries for the Razer Basilisk Ultimate in wired and wireless modes
* Adding entry for the Razer Mouse Dock Chroma
* Registered detectors
* Added metadata to RazerDevices.h
* Added capabilities to RazerController.cpp
* Added UDEV rule to 60-openrgb.rules
2021-06-30 12:05:40 -05:00
Jeremy Plsek 3fe27ba27d Update save-as dialog
This moves the label and text input outside of the QDialogButtonBox
(which is mainly meant only for buttons) and into its own layout.

This makes the window resize work slightly better and renders the layout
slightly better.
2021-06-30 16:55:28 +00:00
Thomas greenwood 2e540e2c6f Use consistent concurrency model with CoInitializeEx 2021-06-30 13:40:29 +00:00
Andy Getz 710a079a9a Add a second USB ID for SteelSeries QCK Mousemat
New ID is 1038:150a; I have tested the patch with my mat.
2021-06-30 13:38:24 +00:00
Chris a15dd256dc Initial commit for the Razer Huntsman Mini
* Registered detector
* Added metadata to RazerDevices.h
* Added capabilities to RazerController.cpp
* Added UDEV rule to 60-openrgb.rules
2021-06-30 13:33:49 +00:00
morg e29eb71131 Add QToolButton + QMenu styles. Fixes #1464 2021-06-30 15:00:06 +02:00
Adam Honse bac580dfc5 Add Razer Blade 2021 Advanced to RazerController 2021-06-29 10:32:23 -05:00
TheRogueZeta 92ed4a39aa Add ASUS ROG STRIX 1650S to detector 2021-06-28 04:27:25 +00:00
TheRogueZeta cab77e72ec Correct spelling mistake for Cooler Master Small ARGB detector 2021-06-27 19:45:41 -07:00
Kamil Trzciński 1c172c80b7 Add Gigabyte 2080S GAMING OC 8GB 2021-06-26 20:48:20 +00:00
Alex 1ace5f34e5 Add gigabyte 1070Ti pci id to the detection 2021-06-26 19:18:10 +00:00
Tom Greenwood 7624a70b67 Add Start at Login Option (Windows and Linux implemented, MacOS stubbed)
This merge request adds the following:

1. A new class AutoStart, designed to add login startup entries for Linux (FreeDesktop autostart) and Windows (Shortcut File).
1. CLI options to enable, disable and check for autostart. (--autostart-enable, --autostart-disable and --autostart-check). e.g. OpenRGB.exe --autostart-enable "--startminimized --server --profile Blue" --nodetect --noautoconnect
1. UI options to enable "Start At Login" with several other options (see screenshots in Comments)

Tested on KDE Neon and Windows 10 x64 (x64 build).

Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-06-26 02:45:48 -05:00
no 30d70035fb Update README - nproc instead of -j8
Commits squashed by Adam Honse <[email protected]>
2021-06-26 00:33:50 -05:00
Chris b76265cf7d Convert mode from struct to class, add automatic initialization
* To avoid filtering in the profile manager and to ensure that color_mode is set to MODE_COLORS_RANDOM correctly
for HW that has the mode flags

MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_PER_LED_COLOR

The values for speed_min, speed_max, colors_min and colors_max NEED to be initialised to allow for a saved
profile to load correctly in `ProfileManager::LoadDeviceFromListWithOptions`

Commit amended for code style by Adam Honse <[email protected]>
2021-06-26 00:29:51 -05:00
Alex cdcc2995b9 Add ASUS ROG Strix Scope, Scope RX, and Scope TKL keyboards
Commits merged and amended for code style by Adam Honse <[email protected]>
2021-06-25 23:03:03 -05:00
mike 724fce7051 fix bug with keyboard layout where HOME, END, PGUP, and PGDN keys were in the wrong position 2021-06-25 23:02:55 -05:00
Kasper 6ea3cdb8b7 QMK Improvements - make LEDs per update configurable
* Fix Windows include error that breaks std::min/max if a Windows header is included (tracked down to
net_port.h)

Commit amended by Adam Honse <[email protected]>
2021-06-25 23:02:38 -05:00
LC 3523044a29 Update README.md
- Add an instruction for updating grub for users on Fedora.
- Improve formatting.
- Related to this issue - https://gitlab.com/CalcProgrammer1/OpenRGB/-/issues/1534
2021-06-25 20:23:31 -05:00
Alex 3652624a01 Add Asus 1080TI 11G pci id 2021-06-26 01:57:41 +02:00
Dima-Kal 325169b16b Add support for Sinowealth keyboard
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-06-24 22:51:01 -05:00
edbgon 6b184f2b8c Initial G933 support 2021-06-22 17:19:47 +00:00
Adam Honse 742b477f6f Add keymap for Blade 14 2021 2021-06-21 20:27:58 -05:00
Adam Honse b4b22e2dce Add Razer Blade 14 2021 2021-06-21 12:31:10 -07:00
TheRogueZeta 6a134a1f75 Add logging to ASRock Polychome SMBus detection and fix stack smashing caused by Polychrome block read. 2021-06-21 04:45:48 +00:00
Chris 920542e8b6 Adding "random" to the acceptable inputs for the --color switch to align with GUI
* Allows for the selection of color_mode = MODE_COLORS_RANDOM from the CLI for devices that support it
* For all other implementations will return a random colour from the `human_colors` struct

* To avoid filtering in the profile manager and to ensure that color_mode is set to MODE_COLORS_RANDOM correctly
for HW that has the mode flags

MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_PER_LED_COLOR

The values for speed_min, speed_max, colors_min and colors_max NEED to be initialised to allow for a saved
profile to load correctly in `ProfileManager::LoadDeviceFromListWithOptions`

Commit amended by Adam Honse <[email protected]> to remove Aura SMBus change, will add as its own
commit.
2021-06-20 23:35:37 -05:00
David Lee 09db948f9f fixed typo in SteelSeriesControllerDetect.cpp 2021-06-21 04:12:05 +00:00
Alex fdfe6f764e Update Fedora build instructions in readme
git, make, gcc are pre-installed; qt-creator isn't necessary, qt5-qtbase-devel provides qmake-qt5; libusb is now libusbx; libmbedtls is actually mbedtls
2021-06-20 23:11:10 -05:00
Stefan Silviu 510ac44d27 Fix typo 2021-06-20 23:07:42 -05:00
Stefan Silviu 840aae45a4 Detect Redragon M716 Inquisitor mouse 2021-06-20 23:07:10 -05:00
Alex 9d36d6743a Add Asus Strix rx570 O4G pci id 2021-06-18 22:31:24 +02:00
Adam Honse 50f3c4c4b8 Add Womier K66 to EVision Keyboard controller 2021-06-18 11:01:57 -05:00
Adam Honse bec99489fb Add Womier K87 to EVision Keyboard controller 2021-06-17 21:13:02 -05:00
TheRogueZeta 90338354a6 Update PCI ID Macros to test against device ID 2021-06-17 10:48:06 -05:00
Alex 1053b83782 Fixing wmi issue when device detection thread run nth time 2021-06-17 10:47:59 -05:00
Mola19 b49edaafb0 Added support for ASUS TUF Gaming K7
* Always sends save command when changing modes, this should be reworked to be optional in a future commit

Commit amended for code style by Adam Honse <[email protected]>
2021-06-17 10:47:50 -05:00
Alex ba3aae8780 Fix Razer Ornata V2 Detection 2021-06-16 21:22:44 +02:00
Dave 518c05976e * Fix Smart Device V2 in H710i, bought in June 2021 - it uses a new PID 2021-06-16 13:20:36 -05:00
Alex 276895359a Add UK layout support for HyperX Alloy 2021-06-16 13:13:39 -05:00
mike 4a333e9b50 Fixed HyperX Alloy Origins Core HID communication on Windows
* Added serial number support
  * Amended to pass in HID device information for version number rather than enumerate a second time

Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-06-13 16:00:05 -05:00
Vavooon a20a19e570 Add HyperX Origins Core support (direct mode)
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-06-13 00:02:32 -05:00
Roman Stingler c665c877fa Bad deallocator in AsusAuraSMBusController.cpp 2021-06-13 04:43:35 +00:00
Adam Honse 3ccab3d949 Fix Logitech common files out of order in project file 2021-06-12 00:18:00 -05:00
Mola19 fcb617ee47 Add support for ASUS ROG Throne Qi headset stand
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-06-12 00:16:40 -05:00
Alex ce7478737c Add Steelseries Rival 650 wireless support
* Also reworks the LED update functions to handle zones with more than one LED
  * Some other minor code style cleanup in the Rival code

Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-06-11 18:12:40 -05:00
edbgon 8736f1b169 Initial support for Logitech X56 Rhino Hotas
Commit amended for code style by Adam Honse <[email protected]>
2021-06-11 17:01:42 -05:00
Alex 18939e6754 Add ASUS ROG Gladius II Wireless
Commit amended for code style by Adam Honse <[email protected]>
2021-06-10 23:13:26 -05:00
TheRogueZeta 806d77d2d6 Convert Polychrome read to i2c_smbus_read_block_data 2021-06-10 22:33:50 -05:00
TheRogueZeta b17b6340bd Test to see if Patriot Viper DRAM modules exist before performing writes
Amended to use read check as quick check doesn't work for SPD addresses by Adam Honse <[email protected]>
2021-06-10 21:09:26 -05:00
TheRogueZeta 46d353bc66 Fix missing % that got lost in transfer 2021-06-10 00:10:28 -05:00
TheRogueZeta b72de2fe5e Update README.md for Hue build requirements 2021-06-07 10:49:52 -07:00
TheRogueZeta 24d1c5f2ae Update HID device log prints to use caps 2021-06-06 16:44:05 -07:00
DrZlo13 bf99a5f250 New device: Obinslab Anne Pro 2
* Renamed "Obins Lab" to "Obinslab" as that is the name that I saw used most frequently in store listings.

Commit amended for code style and to update the name by Adam Honse <[email protected]>
2021-06-06 14:17:57 -05:00
Thomas greenwood 0755959741 Implement modes for Logitech G213 Keyboard 2021-06-06 02:41:56 +01:00
Jeff P fe11115f32 Add support for Corsair Commander Core / Elite Capellix
Amended for code style by Adam Honse <[email protected]>
2021-06-04 22:45:36 -05:00
Adam Honse 9a00f1d6d8 Fix CI for Philips Hue changes
* Debian builder has been upgraded to buster due to incompatible mbedtls package on stretch
  * Mint 19, Ubuntu 18.04 have been disabled for testing as they use incompatible mbedtls packages
2021-06-05 03:18:12 +00:00
Adam Honse b7e2103f41 Disable parsing certificate, it doesn't appear to be necessary to control Hue and prevents build on older mbedtls releases 2021-06-05 03:18:12 +00:00
Adam Honse 87043cde65 Fix issue with Windows in hueplusplus library 2021-06-05 03:18:12 +00:00
Adam Honse 2aaf7017ee Philips Hue (Standard and Entertainment Mode) Support using hueplusplus library
* Dependency hueplusplus-1.0.0 added from https://github.com/enwi/hueplusplus/releases/tag/v1.0.0
* Dependency mbedtls-2.24.0 added (Windows-only) from https://github.com/ARMmbed/mbedtls/releases/tag/mbedtls-2.24.0
2021-06-05 03:18:12 +00:00
mike 22acdd1fed Check return code from hid_get_serial_number_string() in GetSerialString()
Amended for code style by Adam Honse <[email protected]>
2021-06-04 22:14:05 -05:00
Thomas greenwood 4e4eade335 Pad commands for 0x62 with 4 zero bytes 2021-06-05 02:52:37 +00:00
Joe Smith 9f7812bc7b No more qt5-default package in debian
[Looks](https://askubuntu.com/questions/1335184/qt5-default-not-in-ubuntu-21-04) like this [was removed](https://bugs.launchpad.net/ubuntu/+source/qtbase-opensource-src/+bug/1926802) in Debian `bullseye` + Ubuntu `21.04`.
2021-06-05 02:18:02 +00:00
TheRogueZeta 6029a5b0c5 Add Non OC 2060S PCIe ID, correct RAM 2021-06-04 15:51:15 -07:00
TheRogueZeta 74a49ec3e6 Add ASUS ROG Strix RTX 2060S A8G Evo to detector 2021-06-04 15:50:17 -07:00
Short_String_Dev 21dd2ee66a Add ASUS ROG STRIX 2070 A8G Gaming 2021-06-04 08:57:23 -04:00
Short_String_Dev f76d78775c Add ASUS ROG STRIX 2070 O8G Gaming 2021-06-04 08:25:15 -04:00
TheRogueZeta af01ff5de3 Add ASUS ROG Strix 1080 O8G to detector 2021-06-03 17:53:40 +00:00
Tom Greenwood f2f84fc7e3 Add support for Gigabyte RTX3060 Gaming OC 12GB 2021-06-03 17:07:48 +00:00
TheRogueZeta 939f46c025 G Pro Wired are only 1 zone devices 2021-06-03 08:31:37 -07:00
TheRogueZeta a1469041e5 Add ASUS ROG Strix 1070 Gaming to detector 2021-06-03 02:27:14 +00:00
TheRogueZeta f39b57fadc Add Gigabyte RTX 2060 Gaming OC Pro to the detector 2021-06-03 02:26:00 +00:00
Dennis Piecha 08a985a216 Add ASUS ROG STRIX RTX 2070S O8G Gaming 8G 2021-06-02 22:01:52 +02:00
Harry Kane 7054badf4f Update URL to HTTPS 2021-06-02 03:30:01 +00:00
SR_team 332a04f94c Add missing key for ANSI layout of Logitech G815 into LED View 2021-06-01 20:41:57 +00:00
TheRogueZeta ae88771e79 Correct G502 Wireless (wired) PID in linux builds 2021-06-01 00:19:50 -07:00
TheRogueZeta 09e524314f Correct G502 PS and G502 Hero detector changes. 2021-05-31 23:47:37 -07:00
Adam Honse 8e8573e7d0 Increment version number post-release 2021-06-01 01:35:51 -05:00
Adam Honse 405ff7f6a5 OpenRGB version 0.6 2021-06-01 00:05:08 -05:00
Adam Honse 563ff31fe3 Wait up to 5 seconds for the local server connection to retrieve all controllers before continuing, so that CLI mode has all controllers available for applying changes 2021-05-31 23:44:33 -05:00
Chris 4a6c4f0e52 Adding test stages to Linux builds
* Build based on new OpenRGB docker image (Debian Stretch)
* Adapting AppImage build scripts to new docker image
* Changing postinstall script to avoid error

+ Adding test stage keyword
+ Adding needs keyword
+ Debian 10       Buster 32bit & 64bit
+ Debian 11       Bullseye 32bit & 64bit
+ Fedora 34       v34 64bit only
+ Ubuntu 18.04LTS Bionic 32bit & 64bit
+ Ubuntu 20.04LTS Focal 64bit only
+ Ubuntu 20.10    Groovy 64bit only
+ Mint   20.1     Ulyssa 32bit & 64bit

Amended to leave Bullseye builds in place by Adam Honse <[email protected]>
2021-05-31 23:32:09 -05:00
TheRogueZeta be838aa1d6 Update Logitech Lightspeed detector names 2021-06-01 04:13:46 +00:00
Adam Honse 68b0287cdd Make detectors for QMK OpenRGB controller configurable 2021-05-31 18:35:07 -05:00
Adam Honse d18f66f995 Implement dynamic detectors - run-once functions that can register detectors dynamically 2021-05-31 13:55:22 -05:00
Chris 259ba898b0 Enumerate Wireless connected Logitech Lightspeed (Unifying) devices
+ Added common library for Logitech Protocol
    + Moved wireless detection to the LogitechProtocolCommon.cpp
    + Adding Direct Mode to the wireless control
    + Copying the mutex from Lightsync controller to avoid interference
    + Adding LED count info to controller constructor

+ Created a new Logitech class
    + Added Feature list enumeration
    + Added DeviceName detection from device

* Changed LogitechGProWirelessController to accomodate generic devices
    * LED count from device is now used in RGBController setup

+ Adding Windows specific detection as Linux Kernel handles this already.
+ Adding virtual PIDS for wireless detection
    * LOGITECH G403
    * LOGITECH G502
    * LOGITECH G703
    * LOGITECH G900
    * LOGITECH G903
    * LOGITECH GPRO
+ Adding Logitech G900 Wired Gaming Mouse PID
+ Adding other all lightspeed mice to wired detector for testing
    * Genericised and optimised code paths
    * Speed up wireless detection

Commit amended for code style by Adam Honse <[email protected]>
2021-05-31 10:59:04 -07:00
Adam Honse d8252281ce Prevent theme box from saving theme setting until initialized 2021-05-30 21:08:23 -07:00
Kasper a5928518c1 Implement QMK OpenRGB Procotol
This commit squashes commits by:

    Kasper <[email protected]>
    jath03 <[email protected]>
    Adam Honse <[email protected]>

Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-05-30 18:41:55 -05:00
Felipe Guaycuru b3b392b3e2 Make Corsair K55 behavior be closer to iCue's 2021-05-30 22:33:31 +00:00
Adam Honse 1df6e8f559 Add geometry settings to settings page 2021-05-28 12:07:38 -05:00
morg c1b9f79052 Add settings page under settings tab 2021-05-28 16:37:41 +00:00
Adam Honse 4764198df7 Add Logitech G910 Orion Spark 2021-05-27 10:25:20 -05:00
Kasper f04da17e4e Corsair hydro platinum fix soft brick once again by increasing delay to 5ms 2021-05-27 14:31:43 +00:00
Adam Honse 6dda941d97 Add debug logging for Aura SMBus DRAM detection 2021-05-26 00:41:57 -05:00
harre b2be4a9411 Added include needed by arch #1427 2021-05-26 02:09:50 +00:00
Adam Honse 9b974d7108 Update Logitech G910 LED list to add G keys and second Logo, update matrix 2021-05-25 19:15:45 -05:00
Adam Honse 4509b9d2e9 Initial support for Logitech G910 Orion Spectrum - G Keys and G910 bottom logo not working yet 2021-05-25 15:38:53 -05:00
Adam Honse 4287128fb4 Attempt to implement !513 using shared mutex pointer for each detected mouse/mousemat combo 2021-05-25 11:48:16 -05:00
Adam Honse a2a93daaab Add numerical_labels setting to UserInterface settings 2021-05-24 23:08:39 -05:00
Kasper f9c7df21f1 Add a number as a label for LEDs that otherwise would be nameless in DeviceView 2021-05-24 22:51:37 -05:00
k1-801 65623d3978 Autoclose updated
Commit amended for code style by Adam Honse <[email protected]>
2021-05-24 22:45:24 -05:00
k1-801 abfb6ea22d Tiny fixups (server conn info leak closed, log va leak closed, config dir optimized)
Commit amended for code style by Adam Honse <[email protected]>
2021-05-24 22:41:12 -05:00
Adam Honse 33b840b2b9 Revert change disabling redetection of i2c interfaces and fix disconnected WMI failure by always reconnecting before query 2021-05-24 18:38:26 -05:00
Adam Honse 2a3a736f09 Don't delete i2c bus list on redetect, as WMI query issues prevent them from being redetected 2021-05-24 17:00:18 -05:00
Adam Honse 8ada7cd6da Add MSI Mystic Light 185 7D13 (MSI MEG B550 Unify), tested on Discord by Markellus 2021-05-23 23:25:47 -05:00
Adam Honse cb656ebdf7 Don't print Running standalone message when local server connection succeeds 2021-05-23 23:22:46 -05:00
TheRogueZeta 707df85d1f DMI Info for MSI-RGB boards 2021-05-23 00:08:43 -07:00
TheRogueZeta 78955de65f Get DMI info for MSI USB boards 2021-05-23 00:08:43 -07:00
edbgon a8e2feddbe New controller for SteelSeries QCK Mousemat 2021-05-22 23:49:20 -05:00
TheRogueZeta fd31b4db7d Fixed Dev and Feature index for PowerPlay 2021-05-22 15:48:06 -07:00
TheRogueZeta a87d2aead7 PowerPlay mat should only be 1 zone. 2021-05-22 15:45:34 -07:00
Adam Honse 2afddf9bbf Only join/delete E1.31 keepalive thread if it has actually been created 2021-05-21 20:43:14 -05:00
TheRogueZeta 1f2d298e14 Add ASUS ROG-STRIX-RTX2080-O8G-GAMING 2021-05-22 00:42:52 +00:00
Adam Honse cdae9b1e78 Fix client registration for auto-detected local server 2021-05-21 19:25:12 -05:00
Diogo Trindade 4c6653bdb4 Asus ROG Strix Flare - Added ISO LEDs 2021-05-22 00:01:32 +00:00
Adam Honse e5d16dedcc Add option in settings file to pass client controllers through to server 2021-05-21 16:58:42 -05:00
Adam Honse d103906c75 Override UpdateLEDs() for RGBController_Network to always process synchronously 2021-05-21 16:39:03 -05:00
Adam Honse 5e959f6bc3 Add Pipeline Status badge to README 2021-05-20 20:56:40 +00:00
Adam Honse 618faf42ec Use block writes for updating all LEDs at once on ASUS Aura SMBus 2021-05-19 21:49:22 -05:00
edbgon 961fbc2585 Update rules file in accordance to detectors 2021-05-19 09:44:15 +02:00
Adam Honse eb9710ee26 Fix name change 2021-05-18 23:21:56 -05:00
Adam Honse 39de6fc175 Code style cleanup for Logitech G Lightsync RGBController 2021-05-18 22:57:45 -05:00
Adam Honse 39d989891e Code style cleanup for Logitech detector 2021-05-18 22:53:38 -05:00
TheRogueZeta 734912732c Rework individual Logitech mouse controllers into a single shared controller and add Direct mode.
Squashes all commits from Merge Request !495
2021-05-19 03:25:55 +00:00
Adam Honse 47160ac7cd Add visitors badge to README 2021-05-18 18:26:14 +00:00
Daniel Augustin 9f0fa7eb67 Add Asus Aura on Asus H570-PRO Motherboards 2021-05-17 18:42:22 -05:00
TheRogueZeta a6cfcdeb1d Retrieve motherboard name for ASUS boards via DMI
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-05-17 18:34:21 -05:00
Cheerpipe cf922db7d5 G815 performance tweaks
* Remove some unnecessary operations on the G815 controller
* Use reserved memory for key color array to avoid excessive memory copy on vector pushback

Commits squashed and commit message amended by Adam Honse <[email protected]>
2021-05-17 18:29:17 -05:00
Cheerpipe 8a56a5103c Packet read size fix. Should be 20, not 200
This bug causes rare unwanted volume changes.
2021-05-17 17:41:59 +00:00
TheRogueZeta 3026a10ff8 Add ASUS ROG STRIX RTX 2080 Ti O11G Gaming 2021-05-17 13:17:44 +00:00
morg f54ecd8b1b Add detection start and end callbacks 2021-05-17 08:14:00 -05:00
Adam Honse d88f9979a9 Rework network client callback pipeline - route callbacks from clients through ResourceManager so that device list callbacks get called. Fixes remote devices not showing up in plugins. 2021-05-14 23:29:34 -05:00
Martin Hartl 94370c24a8 cli: Fix mode specific colors for range 2021-05-14 15:14:11 +02:00
nightsky30 c29a38a8c9 Fix the number of LEDs for Lancehead devices; 16 LEDs, not 18 #6 2021-05-13 23:03:06 -05:00
Artur Pieniążek 651a8d2f2a Handle K95 Platinum ANSI and ISO layouts
Commits merged by Adam Honse <[email protected]>
2021-05-13 22:51:03 -05:00
silas a51e2f8ac8 Make device list change warning callback
This will be helpful for keeping plugins from crashing

Commit amended to change callback function name for consistency by Adam Honse <[email protected]>
2021-05-13 22:30:38 -05:00
k1-801 02ba8a799e Server freed from ResourceManager
Commit amended to revert OpenRGBInterfaces.h header (may reconsider in the future) by Adam Honse
<[email protected]>
2021-05-13 22:10:41 -05:00
alpemwarrior a6bc30a31c Add 64-bit .rpm package build to CI for Fedora. 2021-05-14 02:02:28 +00:00
Chris 81bf61867f Amending QTwindow geometry config to resovle #1245
+ Code to initialise config values.
    + Added "load_geometry" variable so that you can load set values but not have to "save_on_exit"

Commit amended for code style by Adam Honse <[email protected]>
2021-05-13 20:59:32 -05:00
Martin Hartl 1f21d9ad62 Asus mainboard: Rename RGB headers
There is currently no difference in naming for the integrated
motherboard LEDs and the motherboard non-addressable RGB headers. This
commit renames the RGB headers in the RGB controller. The number of RGB
headers is read from the configuration table.

Commit amended for code style by Adam Honse <[email protected]>
2021-05-12 22:35:21 -05:00
Pol Rius 658eb3a1f7 Initialize profile_loaded properly 2021-05-12 18:27:22 +02:00
edbgon a567aa1e62 Update Ducky to support ISO layouts 2021-05-12 07:44:41 +02:00
Adam Honse d3ee9911b5 Change UI_Settings key to UserInterface 2021-05-10 22:17:11 -05:00
Chris 166bc13dec Adding ability to save QTwindow geometry to config solving #1245
+ Load window geometry from config added to constructor
+ Save window geometry to config added to destructor
+ Added an opt out boolean to allow for saving / not saving geometry
+ Consolidated the Minimize settings into the "UI_Settings" in config
+ Code to initialise config values.

Amended for code style by Adam Honse <[email protected]>
2021-05-10 22:15:20 -05:00
Adam Honse 47e4dc7431 Add MSI Mystic Light 7D09 PID to 185 byte controllers list 2021-05-10 08:47:10 -05:00
Adam Honse 20b149aeef Implement direct mode for Corsair K57, only in wired mode. 2021-05-09 15:09:29 -05:00
Adam Honse 91dd39f3f3 Start implementing Corsair Wireless (K57) controller. Detects both keyboard and dongle, no other functionality implemented yet 2021-05-08 13:40:19 -05:00
Dmitry K 647670a04a Skip Inpout-dependent detection when inpout is not available 2021-05-06 23:11:30 +00:00
morg 23db961be3 Refactor OpenRGBDialog2 + add SettingsTab as plugin location 2021-05-06 17:57:28 +02:00
morg 59a0bec399 Toggle plugins visibility for all locations 2021-05-06 01:16:06 +00:00
morg 3543218722 Automatically create the plugins folder 2021-05-06 01:02:08 +00:00
morg 0fbe96f8ec Add button to open settings folder 2021-05-06 01:00:34 +00:00
Gabriel Marcano 30f88d5fcf Fix mismatched new[] / delete
- The device description buffer was allocated using new[] in
   RGBController. Make sure to free it using delete[].
2021-05-05 02:07:19 -07:00
Adam Honse 198a246af1 Add timeouts to prevent lockup of Razer Naga Epic Chroma 2021-05-02 12:02:46 -05:00
silas 827c78da13 Fix window getting larger when spamming toggle LED view
Commit amended to only implement size hint change by Adam Honse <[email protected]>
2021-05-02 11:33:20 -05:00
Adam Honse 08d495941e Add effect handling for per-LED Razer devices 2021-05-02 01:50:19 -05:00
morg 8ee0b12ef8 Auto hide/show plugin containers
Commit amended for code style and to add comments by Adam Honse <[email protected]>
2021-05-02 00:01:52 -05:00
TheRogueZeta 84371c3cd8 Add Asus Strix 2070S A8G Gaming PCIe ID 2021-05-02 02:16:24 +00:00
morg 0b4a8ffce2 Software info: add website link, make links clickable 2021-04-30 21:02:35 +02:00
Bernhard Held 2df555d864 Add support for Gainward RTX 2070 Super Phantom 2021-04-30 16:06:34 +00:00
Adam Honse 429068760d Fix more warnings 2021-04-30 10:56:40 -05:00
Tam Do 47877193a7 rename mode to reactive, behavior is that key changes from color1 to color2 when pressed, and fades back to color1 after some time configured by the speed parameter 2021-04-30 01:42:49 +00:00
Tam Do 7952a035b5 Continued the work started by !62 with respect to adding support for Cooler Master keyboards using the libcmmk library.
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-04-30 01:42:49 +00:00
Lukas Niederbremer 7e4b9c0cb0 Add experimental Cooler Master MasterKeys support 2021-04-30 01:42:49 +00:00
shawnc722 b3e1cc6552 Fix invalid serial numbers crashing the python interface.
(cherry picked from commit a5ff98940cbe2e91ecaf2445febd87e373f35723)
2021-04-29 19:17:09 +00:00
shawnc722 13b1da9d64 Removed various brightness modes and made highest brightness into Direct mode. Can use relative intensity to set brightness, ie RGB(255,0,255) (magenta) at ~60% brightness is RGB(150,0,150)
(cherry picked from commit b43cfd3b04e9faf980e319c596be5de49140f9b0)
2021-04-29 19:14:54 +00:00
Adam Honse 5616f547e4 Fix a bunch of warnings 2021-04-29 13:42:49 -05:00
shawnc722 37d58ee1a6 Add support for ASUS GTX 1080 2021-04-29 00:17:10 +00:00
TheRogueZeta 74b05f17fd Add ASUS ROG STRIX RTX 2060 EVO Gaming 6G 2021-04-26 12:31:44 -07:00
Chris 6a8524f371 Adding ASUS GTX 1070 Strix OC
* As per yozukiRR adding 0x8599 for the ASUS GTX 1070 Strix OC
2021-04-26 09:42:38 -05:00
k1-801 ad2cd89128 Add filesystem header to select between std::filesystem and std::experimental::filesystem depending on system availability.
Commit amended by Adam Honse <[email protected]>
2021-04-25 22:55:49 -05:00
shawnc722 05d72ba96f Fixed detection of Apex 350 and tweaked display names of OG Apex 2021-04-25 17:06:57 -05:00
k1-801 402423e338 Fix a memory leak in NetworkClient 2021-04-25 16:55:15 -05:00
Adam Honse dd4865c3e0 Add initial version of the Plugin Container, which prevents plugins from resizing the window unless shown 2021-04-23 22:45:30 -05:00
Adam Honse 30623b36fd Use Debian Bullseye for CI builds 2021-04-23 22:37:39 -05:00
Chris 9b8d2c38d3 Changed "Set All Devices"
* Changed `Set All Devices` to `Apply To All Devices`
* Added a tooltip to `Apply to All`
* Added Black and White quick colour swatches and left them "not flat" to
ensure visibility in Light and Dark mode.

Commit amended to fix display issues on Windows and to group buttons in layout by Adam Honse <[email protected]>
2021-04-23 11:44:59 -05:00
1777 changed files with 413398 additions and 4713 deletions
+268 -10
View File
@@ -16,6 +16,7 @@
stages:
- build
- test
before_script:
- echo "started by ${GITLAB_USER_NAME}"
@@ -23,15 +24,15 @@ before_script:
#reusable templates
.ccache_init: &ccache_init
before_script:
- apt update
- apt install -y build-essential qtcreator qt5-default libusb-1.0-0-dev libhidapi-dev pkgconf wget git
- export QT_SELECT=qt5
- export APPIMAGE_EXTRACT_AND_RUN=1
#-----------------------------------------------------------------------#
# Linux (AppImage) 32-bit Build Target #
#-----------------------------------------------------------------------#
"Linux 32 AppImage":
<<: *ccache_init
image: i386/ubuntu:bionic
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:buster-32
stage: build
script:
- export $(dpkg-architecture)
@@ -50,7 +51,7 @@ before_script:
#-----------------------------------------------------------------------#
"Linux 64 AppImage":
<<: *ccache_init
image: ubuntu:bionic
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:buster-64
stage: build
script:
- export $(dpkg-architecture)
@@ -69,13 +70,12 @@ before_script:
#-----------------------------------------------------------------------#
"Linux 32 deb":
<<: *ccache_init
image: i386/ubuntu:bionic
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:buster-32
stage: build
script:
- apt install -y debhelper
- dpkg-architecture -l
- dpkg-buildpackage --target-arch i386 -us -B
- rm -v ../openrgb-dbgsym*.ddeb
- rm -v ../openrgb-dbgsym*.deb
- mv -v ../openrgb*.deb ./
artifacts:
@@ -91,13 +91,12 @@ before_script:
#-----------------------------------------------------------------------#
"Linux 64 deb":
<<: *ccache_init
image: ubuntu:bionic
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:buster-64
stage: build
script:
- apt install -y debhelper
- dpkg-architecture -l
- dpkg-buildpackage -us -B
- rm -v ../openrgb-dbgsym*.ddeb
- rm -v ../openrgb-dbgsym*.deb
- mv -v ../openrgb*.deb ./
artifacts:
@@ -108,6 +107,265 @@ before_script:
- openrgb-dbgsym*.deb
expire_in: 30 days
#-----------------------------------------------------------------------#
# Linux (.rpm) 64-bit Build Target #
#-----------------------------------------------------------------------#
"Linux 64 rpm":
image: fedora:34
stage: build
script:
- dnf install rpmdevtools dnf-plugins-core -y
- rpmdev-setuptree
- ls /root/
- cp fedora/OpenRGB.spec /root/rpmbuild/SPECS
- cp ../OpenRGB /root/rpmbuild/SOURCES/ -r
- cd /root/rpmbuild/SOURCES
- tar -cf OpenRGB.tar.gz OpenRGB/
- cd ..
- dnf builddep SPECS/OpenRGB.spec -y
- rpmbuild -ba SPECS/OpenRGB.spec
- cd RPMS/x86_64/
- mv openrgb*.rpm ${CI_PROJECT_DIR}/
- cd ${CI_PROJECT_DIR}
artifacts:
name: "${CI_PROJECT_NAME}_Linux_64_rpm_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.rpm
expire_in: 30 days
#-----------------------------------------------------------------------#
# Linux (.deb) Debian Bullseye 32-bit Build Target #
#-----------------------------------------------------------------------#
"Linux 32 deb Bullseye":
<<: *ccache_init
image: i386/debian:bullseye
stage: build
script:
- apt update
- apt install -y build-essential qtcreator qtbase5-dev libusb-1.0-0-dev libhidapi-dev libmbedtls-dev pkgconf wget git file debhelper
- dpkg-architecture -l
- dpkg-buildpackage --target-arch i386 -us -B
- rm -v ../openrgb-dbgsym*.deb
- mv -v ../openrgb*.deb ./
artifacts:
name: "${CI_PROJECT_NAME}_Linux_32_deb_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.deb
exclude:
- openrgb-dbgsym*.deb
expire_in: 30 days
#-----------------------------------------------------------------------#
# Linux (.deb) Debian Bullseye 64-bit Build Target #
#-----------------------------------------------------------------------#
"Linux 64 deb Bullseye":
<<: *ccache_init
image: debian:bullseye
stage: build
script:
- apt update
- apt install -y build-essential qtcreator qtbase5-dev libusb-1.0-0-dev libhidapi-dev libmbedtls-dev pkgconf wget git file debhelper
- dpkg-architecture -l
- dpkg-buildpackage -us -B
- rm -v ../openrgb-dbgsym*.deb
- mv -v ../openrgb*.deb ./
artifacts:
name: "${CI_PROJECT_NAME}_Linux_64_deb_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.deb
exclude:
- openrgb-dbgsym*.deb
expire_in: 30 days
#-----------------------------------------------------------------------#
# Debian 32 Buster test #
#-----------------------------------------------------------------------#
"Debian 32 Buster":
image: i386/debian:buster
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 32 deb"
needs:
- "Linux 32 deb"
#-----------------------------------------------------------------------#
# Debian 32 Bullseye test #
#-----------------------------------------------------------------------#
"Debian 32 Bullseye":
image: i386/debian:bullseye
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 32 deb"
needs:
- "Linux 32 deb"
# #-----------------------------------------------------------------------#
# # Ubuntu 32 18.04LTS test #
# #-----------------------------------------------------------------------#
# "Ubuntu 32 18.04LTS":
# image: i386/ubuntu:bionic
# stage: test
# script:
# - apt update
# - DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
# - openrgb --version
# - openrgb -l
# - apt remove -y openrgb
# dependencies:
# - "Linux 32 deb"
# needs:
# - "Linux 32 deb"
# #-----------------------------------------------------------------------#
# # Mint 32 19.3 test #
# #-----------------------------------------------------------------------#
# "Mint 32 20.1":
# image: linuxmintd/mint19.3-i386
# stage: test
# script:
# - apt update
# - DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
# - openrgb --version
# - openrgb -l
# - apt remove -y openrgb
# dependencies:
# - "Linux 32 deb"
# needs:
# - "Linux 32 deb"
#-----------------------------------------------------------------------#
# Debian 64 Buster test #
#-----------------------------------------------------------------------#
"Debian 64 Buster":
image: debian:buster
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Debian 64 Bullseye test #
#-----------------------------------------------------------------------#
"Debian 64 Bullseye":
image: debian:bullseye
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Fedora 64 v34 test #
#-----------------------------------------------------------------------#
"Fedora 64 v34":
image: fedora:34
stage: test
script:
- yum -y localinstall ./openrgb*64.rpm
- openrgb --version
- openrgb -l
- yum -y remove openrgb
dependencies:
- "Linux 64 rpm"
needs:
- "Linux 64 rpm"
# #-----------------------------------------------------------------------#
# # Ubuntu 64 18.04LTS test #
# #-----------------------------------------------------------------------#
# "Ubuntu 64 18.04LTS":
# image: ubuntu:bionic
# stage: test
# script:
# - apt update
# - DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
# - openrgb --version
# - openrgb -l
# - apt remove -y openrgb
# dependencies:
# - "Linux 64 deb"
# needs:
# - "Linux 64 deb"
#-----------------------------------------------------------------------#
# Ubuntu 64 20.04LTS test #
#-----------------------------------------------------------------------#
"Ubuntu 64 20.04LTS":
image: ubuntu:focal
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Ubuntu 64 20.10 test #
#-----------------------------------------------------------------------#
"Ubuntu 64 20.10":
image: ubuntu:groovy
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Mint 64 20.1 test #
#-----------------------------------------------------------------------#
"Mint 64 20.1":
image: linuxmintd/mint20.1-amd64
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Windows (32-bit) Build Target #
#-----------------------------------------------------------------------#
+443 -7
View File
@@ -53,6 +53,34 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1872", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1889", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18a3", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18f3", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18a5", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1939", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18af", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="193c", TAG+="uaccess" #ROG Falchion Wired
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="193e", TAG+="uaccess" #ROG Falchion Wireless
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1875", TAG+="uaccess" #ROG Strix Flare
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18cf", TAG+="uaccess" #ROG Strix Flare Pink
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18f8", TAG+="uaccess" #ROG Strix Scope
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1951", TAG+="uaccess" #ROG Strix Scope RX
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="190c", TAG+="uaccess" #ROG Strix Scope TKL
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18a0", TAG+="uaccess" #TUF K7 Gaming
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18dd", TAG+="uaccess" #ROG Gladius II Core
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1845", TAG+="uaccess" #ROG Gladius II
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1877", TAG+="uaccess" #ROG Gladius II Origin
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18cd", TAG+="uaccess" #ROG Gladius II Origin Pink
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18b1", TAG+="uaccess" #ROG Gladius II Origin COD
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="189e", TAG+="uaccess" #ROG Gladius II Wireless1
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18a0", TAG+="uaccess" #ROG Gladius II Wireless2
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18e5", TAG+="uaccess" #ROG Chakram Wireless
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18e3", TAG+="uaccess" #ROG Chakram Wired1
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1958", TAG+="uaccess" #ROG Chakram Wired2
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1846", TAG+="uaccess" #ROG Pugio
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1906", TAG+="uaccess" #ROG Pugio II Wired
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1908", TAG+="uaccess" #ROG Pugio II Wireless
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18e1", TAG+="uaccess" #ROG Strix Impact II
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1910", TAG+="uaccess" #TUF M3 & M7
#---------------------------------------------------------------#
# ASUS TUF Laptops (faustus) #
@@ -68,10 +96,37 @@ ACTION=="add", SUBSYSTEM=="platform", KERNEL=="faustus", RUN+="/bin/chmod a+w /s
#---------------------------------------------------------------#
# Cooler Master Peripheral Devices #
# #
# Mice: #
# Cooler Master MM711 #
# Mousemats: #
# Cooler Master MP750 #
# Controllers: #
# ARGB Device #
# Small ARGB Device #
# Graphics Cards: #
# Radeon RX6000 Series Reference Cards #
# Keyboards: #
# Masterkeys Pro L #
# Masterkeys Pro L White #
# Masterkeys Pro S #
# Masterkeys MK750 #
# Masterkeys SK630 #
# Masterkeys SK650 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0109", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0101", TAG+="uaccess" #MM711
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 #
@@ -84,6 +139,23 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c15", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c13", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c12", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Hydro Platinum Series Devices #
# #
# Corsair H100i Platinum RGB #
# Corsair H100i Platinum SE RGB #
# Corsair H115i Platinum RGB #
# Corsair H100i Pro XT RGB #
# Corsair H115i Pro XT RGB #
# Corsair H150i Pro XT RGB #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c18", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c19", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c17", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c20", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c21", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c22", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Lighting Node Devices #
# #
@@ -101,7 +173,7 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c10", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c1e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1d00", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1d04", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0a32", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c23", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Peripheral Devices #
@@ -120,12 +192,19 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0a32", TAG+="uacces
# Corsair K70 RGB MK2 LP #
# Corsair K95 RGB #
# Corsair K95 Platinum #
# Corsair K100 #
# Corsair Strafe #
# Corsair Strafe MK2 #
# #
# Mice: #
# Corsair M65 Pro #
# Corsair M65 RGB Elite #
# Corsair Glaive RGB #
# Corsair Glaive RGB Pro #
# Corsair Harpoon RGB #
# Corsair Harpoon RGB Pro #
# Corsair Scimitar Pro RGB #
# Corsair Sabre RGB #
# #
# Mousemats: #
# Corsair MM800 RGB Polaris #
@@ -148,28 +227,107 @@ 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"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b75", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b5a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3b", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0a34", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Wireless Devices #
# #
# Keyboards: #
# Corsair K57 RGB Wired #
# Corsair K57 RGB Wireless #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b6e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b62", TAG+="uaccess"
#---------------------------------------------------------------#
# Creative Devices #
# #
# Devices: #
# Creative SoundblasterX G6 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="041e", ATTR{idProduct}=="3256", TAG+="uaccess"
#---------------------------------------------------------------#
# Dell G Series Devices #
# #
# #
# Controllers: #
# Dell G Series LED Controller #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="187c", ATTR{idProduct}=="0550", TAG+="uaccess"
#---------------------------------------------------------------#
# Ducky Keyboard Devices #
# #
# Keyboards: #
# Ducky Shine 7 One 2 RGB #
# Ducky One 2 RGB TKL #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="0348", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="0356", TAG+="uaccess"
#---------------------------------------------------------------#
# EK Controller Devices #
# #
# Controllers: #
# EK Loop Connect #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="5750", TAG+="uaccess"
#---------------------------------------------------------------#
# Holtek Devices #
# #
# Mice: #
# Holtek A070 #
# Mousemats: #
# Holtek A1FA #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="a070", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="a1fa", TAG+="uaccess"
#---------------------------------------------------------------#
# HyperX Peripheral Devices #
# #
# Keyboards: #
# HyperX Alloy Elite #
# HyperX Alloy Elite 2 #
# HyperX Alloy FPS RGB #
# HyperX Alloy Origins #
# HyperX Alloy Origins Core #
# #
# Mice: #
# HyperX Pulsefire Surge #
# HyperX Pulsefire FPS Pro #
# HyperX Pulsefire Dart Wireless #
# HyperX Pulsefire Dart Wired #
# #
# Mousemats: #
# HyperX Fury Ultra #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16be", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="1711", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16dc", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16e5", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16e6", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16d3", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16d7", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16e1", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16e2", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="1705", TAG+="uaccess"
#---------------------------------------------------------------#
@@ -184,53 +342,104 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="0cf2", ATTR{idProduct}=="7750", TAG+="uacces
# Logitech G213 #
# Logitech G512 #
# Logitech G512 RGB #
# Logitech G610 #
# Logitech G610 #1 #
# Logitech G610 #2 #
# Logitech G810 #1 #
# Logitech G810 #2 #
# Logitech G813 #
# Logitech G815 #
# Logitech G915 #
# #
# Mice: #
# Logitech G203 Prodigy #
# Logitech G203 Lightsync #
# Logitech G303 #
# Logitech G403 Prodigy #
# Logitech G403 Hero #
# Logitech G502 Proteus Spectrum #
# Logitech G502 Hero #
# Logitech G502 Wireless #
# Logitech G703 Wireless #
# Logitech G900 Wireless #
# Logitech G903 Wireless #
# Logitech G Lightspeed Wireless Gaming Mouse #
# Logitech G Pro Wireless Gaming Mouse (Wired) #
# Logitech G Pro Hero Gaming Mouse (Wired) #
# #
# Mousemats: #
# Logitech G Powerplay Mousepad with Lightspeed #
# #
# Speakers: #
# Logitech G560 #
# #
# Headsets: #
# Logitech G933 #
# #
# Joysticks: #
# Logitech Rhino X56 Hotas (Throttle and Stick) #
# #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c336", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c342", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c33c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c333", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c338", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c331", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c337", TAG+="uaccess"
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"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c083", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c082", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="405d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c332", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08b", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="407f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c087", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="4070", TAG+="uaccess" #G703 Virtual PID
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c081", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="4053", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c086", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="4067", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c539", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c085", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c088", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="4079", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c53a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c53a", TAG+="uaccess" #Powerplay Mat Reciever
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="405F", TAG+="uaccess" #Powerplay Mat Virtual PID
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="0a78", TAG+="uaccess" #G560
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="0a5b", TAG+="uaccess" #G933
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="0ab5", TAG+="uaccess" #G733
SUBSYSTEMS=="usb", ATTR{idVendor}=="0738", ATTR{idProduct}=="2221", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0738", ATTR{idProduct}=="A221", TAG+="uaccess"
#---------------------------------------------------------------#
# Metadot Das Keyboard 4Q + 5Q #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="24f0", ATTR{idProduct}=="2037", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="24f0", ATTR{idProduct}=="202b", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="24f0", ATTR{idProduct}=="2020", TAG+="uaccess"
#---------------------------------------------------------------#
# MSI Mysticlight #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="3EA4", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="4559", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="4459", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B10", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B12", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B17", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B85", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B93", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B94", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B96", TAG+="uaccess"
@@ -268,6 +477,8 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C95", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C96", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C98", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C99", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7D06", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7D09", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="905D", TAG+="uaccess"
#---------------------------------------------------------------#
@@ -284,15 +495,171 @@ KERNEL=="ttyACM[0-9]*", ATTR{idVendor}=="04D8", ATTR{idProduct}=="00DF", TAG+="u
# NZXT Hue 2 Devices #
# #
# NZXT Hue 2 #
# NZXT Hue 2 Ambient #
# NZXT Motherboard #
# NZXT Smart Device V2 #
# NZXT Kraken X3 #
# NZXT RGB Fan Controller #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2001", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2002", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2005", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2006", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2007", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2009", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="200D", TAG+="uaccess"
#---------------------------------------------------------------#
# NZXT Kraken #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="170e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="1715", TAG+="uaccess"
#---------------------------------------------------------------#
# Razer Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0241", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0203", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0209", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0221", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0228", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0237", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0235", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0211", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0216", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="021A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="020F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0224", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0233", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="023B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0240", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="023A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0246", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0245", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="024D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0253", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0255", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="026A", TAG+="uaccess" # Razer Book 13 (2020)
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="026F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0210", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0225", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="022F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0234", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="024C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0205", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0220", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="022D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0232", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0239", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="024A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0252", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0259", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="022A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="023F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="025E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0204", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0226", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0227", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0257", TAG+="uaccess" #Huntsman Mini
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0243", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0207", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="021E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="025D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0208", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="022B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0020", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="005E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0042", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="005B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0062", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0064", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0065", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0086", TAG+="uaccess" #Basilisk Ultimate
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0088", TAG+="uaccess" #Basilisk Ultimate (Wireless)
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0083", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0083", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0085", TAG+="uaccess" #Basilisk V2
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0038", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="004F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0037", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0016", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0054", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0043", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="005C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0071", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="008C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0084", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="007C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="007D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="004C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="002F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0060", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0059", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="005A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0070", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0024", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0025", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0044", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0045", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0073", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0072", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0046", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="002E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0040", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0053", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="003F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="003E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0041", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0036", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0050", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0067", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0013", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0039", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0048", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0032", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0034", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="008A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0078", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="007A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="007B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0506", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0501", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F19", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0504", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0527", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0510", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F03", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F08", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F20", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F26", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F1F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F09", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F07", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F0E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0215", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0068", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0C00", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0C04", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0C02", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0C01", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F1D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="007E", TAG+="uaccess" #Razer Mouse Dock Chroma
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0517", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0518", TAG+="uaccess"
#---------------------------------------------------------------#
# Roccat Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e7d", ATTR{idProduct}=="2e2c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e7d", ATTR{idProduct}=="2e27", TAG+="uaccess"
#---------------------------------------------------------------#
# Redragon Peripheral Devices #
@@ -306,6 +673,7 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="170e", TAG+="uacces
# Mice: #
# Redragon M711 Cobra #
# Redragon M715 Dagger #
# Redragon M716 Inquisitor #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="5204", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="5104", TAG+="uaccess"
@@ -314,6 +682,7 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="652f", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc30", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc39", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc3a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc4d", TAG+="uaccess"
#---------------------------------------------------------------#
@@ -332,6 +701,13 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="258a", ATTR{idProduct}=="0036", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="258a", ATTR{idProduct}=="0033", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="258a", ATTR{idProduct}=="0029", TAG+="uaccess"
#---------------------------------------------------------------#
# Sony Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="054c", ATTR{idProduct}=="05c4", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="054c", ATTR{idProduct}=="09cc", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="054c", ATTR{idProduct}=="0ba0", TAG+="uaccess"
#---------------------------------------------------------------#
# SteelSeries Peripheral Devices #
# #
@@ -347,22 +723,69 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="258a", ATTR{idProduct}=="0029", TAG+="uacces
# SteelSeries Rival 300 CS:GO Hyperbeast Edition #
# SteelSeries Rival 300 Dota 2 Edition #
# SteelSeries Rival 300 HP Omen Edition #
# 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 3 #
# SteelSeries Rival Sensei Ten #
# SteelSeries Rival Sensei Ten CS:GO Neon Rider #
# SteelSeries Rival Sensei 310 #
# Headsets: #
# SteelSeries Siberia 350 #
# Keyboards: #
# SteelSeries Apex 5 #
# SteelSeries Apex 7 #
# SteelSeries Apex 7 TKL #
# SteelSeries Apex Pro #
# SteelSeries Apex Pro TKL #
# SteelSeries Apex M750 #
# SteelSeries Apex OG #
# SteelSeries Apex 350 #
# Mousemats: #
# SteelSeries QCK Prism Cloth #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1702", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="170c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1814", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1729", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1384", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1710", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1714", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1394", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1716", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="171a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1392", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1718", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1720", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="171e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1736", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1832", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1834", TAG+="uaccess"
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"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="161c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1612", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1618", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1610", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1614", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="0616", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1202", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1206", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="150a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="150d", TAG+="uaccess"
#---------------------------------------------------------------#
# Tecknet Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc05", TAG+="uaccess"
#---------------------------------------------------------------#
# Thermaltake Poseidon Z RGB Keyboard #
@@ -376,3 +799,16 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="1FA[5-9]", TAG+="ua
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="1FA[A-F]", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="1FB[0-5]", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="226[0-3]", TAG+="uaccess"
#---------------------------------------------------------------#
# Wooting Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="03eb", ATTR{idProduct}=="ff01", TAG+="uaccess" #WootingOne
SUBSYSTEMS=="usb", ATTR{idVendor}=="03eb", ATTR{idProduct}=="ff02", TAG+="uaccess" #WootingTwo
SUBSYSTEMS=="usb", ATTR{idVendor}=="31e3", ATTR{idProduct}=="1210", TAG+="uaccess" #WootingTwo LE
SUBSYSTEMS=="usb", ATTR{idVendor}=="31e3", ATTR{idProduct}=="1220", TAG+="uaccess" #WootingTwo HE
#---------------------------------------------------------------#
# Zalman ZSync Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1c57", ATTR{idProduct}=="7ed0", TAG+="uaccess"
+212
View File
@@ -0,0 +1,212 @@
#include "AutoStart-Linux.h"
#include "LogManager.h"
#include "filesystem.h"
#include <fstream>
#include <iostream>
#include <unistd.h>
#include <linux/limits.h>
/*-----------------------------------------------------*\
| Linux AutoStart Implementation |
| Public Methods |
\*-----------------------------------------------------*/
AutoStart::AutoStart(std::string name)
{
InitAutoStart(name);
}
bool AutoStart::DisableAutoStart()
{
std::error_code autostart_file_remove_errcode;
bool success = false;
/*-------------------------------------------------*\
| Check if the filename is valid |
\*-------------------------------------------------*/
if(autostart_file != "")
{
/*---------------------------------------------*\
| If file doesn't exist, disable is successful |
\*---------------------------------------------*/
if(!filesystem::exists(autostart_file))
{
success = true;
}
/*---------------------------------------------*\
| Otherwise, delete the file |
\*---------------------------------------------*/
else
{
success = filesystem::remove(autostart_file, autostart_file_remove_errcode);
if(!success)
{
LOG_ERROR("[AutoStart] An error occurred removing the auto start file.");
}
}
}
else
{
LOG_ERROR("Could not establish correct autostart file path.");
}
return(success);
}
bool AutoStart::EnableAutoStart(AutoStartInfo autostart_info)
{
bool success = false;
/*-------------------------------------------------*\
| Check if the filename is valid |
\*-------------------------------------------------*/
if(autostart_file != "")
{
std::string desktop_file = GenerateDesktopFile(autostart_info);
std::ofstream autostart_file_stream(autostart_file, std::ios::out | std::ios::trunc);
/*---------------------------------------------*\
| Error out if the file could not be opened |
\*---------------------------------------------*/
if(!autostart_file_stream)
{
LOG_ERROR("Could not open %s for writing.", autostart_file.c_str());
success = false;
}
/*---------------------------------------------*\
| Otherwise, write the file |
\*---------------------------------------------*/
else
{
autostart_file_stream << desktop_file;
autostart_file_stream.close();
success = !autostart_file_stream.fail();
if (!success)
{
LOG_ERROR("An error occurred writing the auto start file.");
}
}
}
else
{
LOG_ERROR("Could not establish correct autostart file path.");
}
return(success);
}
bool AutoStart::IsAutoStartEnabled()
{
/*-------------------------------------------------*\
| Check if the filename is valid |
\*-------------------------------------------------*/
if(autostart_file != "")
{
return(filesystem::exists(autostart_file));
}
else
{
return(false);
}
}
std::string AutoStart::GetExePath()
{
/*-------------------------------------------------*\
| Create the OpenRGB executable path |
\*-------------------------------------------------*/
char exepath[ PATH_MAX ];
ssize_t count = readlink("/proc/self/exe", exepath, PATH_MAX);
return(std::string(exepath, (count > 0) ? count : 0));
}
/*-----------------------------------------------------*\
| Linux AutoStart Implementation |
| Private Methods |
\*-----------------------------------------------------*/
std::string AutoStart::GenerateDesktopFile(AutoStartInfo autostart_info)
{
/*-------------------------------------------------*\
| Generate a .desktop file from the AutoStart |
| parameters |
\*-------------------------------------------------*/
std::stringstream fileContents;
fileContents << "[Desktop Entry]" << std::endl;
fileContents << "Categories=" << autostart_info.category << std::endl;
fileContents << "Comment=" << autostart_info.desc << std::endl;
fileContents << "Icon=" << autostart_info.icon << std::endl;
fileContents << "Name=" << GetAutoStartName() << std::endl;
fileContents << "StartupNotify=true" << std::endl;
fileContents << "Terminal=false" << std::endl;
fileContents << "Type=Application" << std::endl;
/*-------------------------------------------------*\
| Add the executable path and arguments |
\*-------------------------------------------------*/
fileContents << "Exec=" << autostart_info.path;
if (autostart_info.args != "")
{
fileContents << " " << autostart_info.args;
}
fileContents << std::endl;
return(fileContents.str());
}
void AutoStart::InitAutoStart(std::string name)
{
std::string autostart_dir;
autostart_name = name;
/*-------------------------------------------------*\
| Get home and config paths |
\*-------------------------------------------------*/
const char *xdg_config_home = getenv("XDG_CONFIG_HOME");
const char *home = getenv("HOME");
/*-------------------------------------------------*\
| Determine where the autostart .desktop files are |
| kept |
\*-------------------------------------------------*/
if(xdg_config_home != NULL)
{
autostart_dir = xdg_config_home;
autostart_dir = autostart_dir + "/autostart/";
}
else if(home != NULL)
{
autostart_dir = home;
autostart_dir = autostart_dir + "/.config/autostart/";
}
/*-------------------------------------------------*\
| Check if the filename is valid |
\*-------------------------------------------------*/
if(autostart_dir != "")
{
std::error_code ec;
bool success = true;
if(!filesystem::exists(autostart_dir))
{
success = filesystem::create_directories(autostart_dir, ec);
}
if(success)
{
autostart_file = autostart_dir + autostart_name + ".desktop";
}
}
}
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include <string>
#include "AutoStart.h"
class AutoStart: public AutoStartInterface
{
public:
AutoStart(std::string name);
bool DisableAutoStart();
bool EnableAutoStart(AutoStartInfo autostart_info);
bool IsAutoStartEnabled();
std::string GetExePath();
private:
void InitAutoStart(std::string name);
std::string GenerateDesktopFile(AutoStartInfo autostart_info);
};
+208
View File
@@ -0,0 +1,208 @@
#include "AutoStart-MacOS.h"
#include "LogManager.h"
#include "filesystem.h"
#include <fstream>
#include <sstream>
#include <iostream>
#include <unistd.h>
#include <mach-o/dyld.h>
/*-----------------------------------------------------*\
| MacOS AutoStart Implementation |
| Public Methods |
\*-----------------------------------------------------*/
AutoStart::AutoStart(std::string name)
{
InitAutoStart(name);
}
bool AutoStart::DisableAutoStart()
{
std::error_code autostart_file_remove_errcode;
bool success = false;
/*-------------------------------------------------*\
| Check if the filename is valid |
\*-------------------------------------------------*/
if(autostart_file != "")
{
/*---------------------------------------------*\
| If file doesn't exist, disable is successful |
\*---------------------------------------------*/
if(!filesystem::exists(autostart_file))
{
success = true;
}
/*---------------------------------------------*\
| Otherwise, delete the file |
\*---------------------------------------------*/
else
{
success = filesystem::remove(autostart_file, autostart_file_remove_errcode);
if(!success)
{
LOG_ERROR("[AutoStart] An error occurred removing the auto start file.");
}
}
}
else
{
LOG_ERROR("Could not establish correct autostart file path.");
}
return(success);
}
bool AutoStart::EnableAutoStart(AutoStartInfo autostart_info)
{
bool success = false;
/*-------------------------------------------------*\
| Check if the filename is valid |
\*-------------------------------------------------*/
if(autostart_file != "")
{
std::string desktop_file = GenerateLaunchAgentFile(autostart_info);
std::ofstream autostart_file_stream(autostart_file, std::ios::out | std::ios::trunc);
/*---------------------------------------------*\
| Error out if the file could not be opened |
\*---------------------------------------------*/
if(!autostart_file_stream)
{
LOG_ERROR("Could not open %s for writing.", autostart_file.c_str());
success = false;
}
/*---------------------------------------------*\
| Otherwise, write the file |
\*---------------------------------------------*/
else
{
autostart_file_stream << desktop_file;
autostart_file_stream.close();
success = !autostart_file_stream.fail();
if (!success)
{
LOG_ERROR("An error occurred writing the auto start file.");
}
}
}
else
{
LOG_ERROR("Could not establish correct autostart file path.");
}
return(success);
}
bool AutoStart::IsAutoStartEnabled()
{
/*-------------------------------------------------*\
| Check if the filename is valid |
\*-------------------------------------------------*/
if(autostart_file != "")
{
return(filesystem::exists(autostart_file));
}
else
{
return(false);
}
}
std::string AutoStart::GetExePath()
{
/*-------------------------------------------------*\
| Create the OpenRGB executable path |
\*-------------------------------------------------*/
char exepath[ PATH_MAX ];
uint32_t exesize = PATH_MAX;
int ret_val = _NSGetExecutablePath(exepath, &exesize);
return(std::string(exepath, (ret_val == 0) ? strlen(exepath) : 0));
return("");
}
/*-----------------------------------------------------*\
| MacOS AutoStart Implementation |
| Private Methods |
\*-----------------------------------------------------*/
std::string AutoStart::GenerateLaunchAgentFile(AutoStartInfo autostart_info)
{
/*-------------------------------------------------*\
| Generate a .plist file from the AutoStart |
| parameters |
\*-------------------------------------------------*/
std::stringstream fileContents;
fileContents << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
fileContents << "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">" << std::endl;
fileContents << "<plist version=\"1.0\">" << std::endl;
fileContents << "<dict>" << std::endl;
fileContents << " <key>Label</key>" << std::endl;
fileContents << " <string>org.openrgb</string>" << std::endl;
fileContents << " <key>ProgramArguments</key>" << std::endl;
fileContents << " <array>" << std::endl;
fileContents << " <string>" << autostart_info.path << "</string>" << std::endl;
if(autostart_info.args != "")
{
std::istringstream arg_parser(autostart_info.args);
std::string arg;
while(arg_parser >> arg)
{
fileContents << " <string>" << arg << "</string>" << std::endl;
}
}
fileContents << " </array>" << std::endl;
fileContents << " <key>RunAtLoad</key><true/>" << std::endl;
fileContents << "</dict>" << std::endl;
fileContents << "</plist>" << std::endl;
return(fileContents.str());
}
void AutoStart::InitAutoStart(std::string name)
{
std::string autostart_dir;
autostart_name = name;
/*-------------------------------------------------*\
| Determine where the autostart .desktop files are |
| kept |
\*-------------------------------------------------*/
autostart_dir = getenv("HOME");
autostart_dir = autostart_dir + "/Library/LaunchAgents/";
/*-------------------------------------------------*\
| Check if the filename is valid |
\*-------------------------------------------------*/
if(autostart_dir != "")
{
std::error_code ec;
bool success = true;
if(!filesystem::exists(autostart_dir))
{
success = filesystem::create_directories(autostart_dir, ec);
}
if(success)
{
autostart_file = autostart_dir + autostart_name + ".plist";
}
}
}
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include <string>
#include "AutoStart.h"
class AutoStart: public AutoStartInterface
{
public:
AutoStart(std::string name);
bool DisableAutoStart();
bool EnableAutoStart(AutoStartInfo autostart_info);
bool IsAutoStartEnabled();
std::string GetExePath();
private:
void InitAutoStart(std::string name);
std::string GenerateLaunchAgentFile(AutoStartInfo autostart_info);
};
+204
View File
@@ -0,0 +1,204 @@
#include "AutoStart-Windows.h"
#include "LogManager.h"
#include "filesystem.h"
#include <fstream>
#include <iostream>
#include "windows.h"
#include <shlobj.h>
/*-----------------------------------------------------*\
| Windows AutoStart Implementation |
| Public Methods |
\*-----------------------------------------------------*/
AutoStart::AutoStart(std::string name)
{
InitAutoStart(name);
}
bool AutoStart::DisableAutoStart()
{
std::error_code autostart_file_remove_errcode;
bool success = false;
/*-------------------------------------------------*\
| Check if the filename is valid |
\*-------------------------------------------------*/
if(autostart_file != "")
{
/*---------------------------------------------*\
| If file doesn't exist, disable is successful |
\*---------------------------------------------*/
if(!filesystem::exists(autostart_file))
{
success = true;
}
/*---------------------------------------------*\
| Otherwise, delete the file |
\*---------------------------------------------*/
else
{
success = filesystem::remove(autostart_file, autostart_file_remove_errcode);
if(!success)
{
LOG_ERROR("An error occurred removing the auto start file.");
}
}
}
else
{
LOG_ERROR("Could not establish correct autostart file path.");
}
return(success);
}
bool AutoStart::EnableAutoStart(AutoStartInfo autostart_info)
{
bool success = false;
/*-------------------------------------------------*\
| Check if the filename is valid |
\*-------------------------------------------------*/
if(autostart_file != "")
{
bool weInitialised = false;
HRESULT result;
IShellLinkW* shellLink = NULL;
std::wstring exepathw = utf8_decode(autostart_info.path);
std::wstring argumentsw = utf8_decode(autostart_info.args);
std::wstring startupfilepathw = utf8_decode(autostart_file);
std::wstring descriptionw = utf8_decode(autostart_info.desc);
std::wstring iconw = utf8_decode(autostart_info.path);
result = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL, IID_IShellLinkW, (void**)&shellLink);
/*---------------------------------------------*\
| If not initialized, initialize |
\*---------------------------------------------*/
if(result == CO_E_NOTINITIALIZED)
{
weInitialised = true;
CoInitializeEx(NULL, COINIT_MULTITHREADED);
result = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL, IID_IShellLinkW, (void**)&shellLink);
}
/*---------------------------------------------*\
| If successfully initialized, save a shortcut |
| from the AutoStart parameters |
\*---------------------------------------------*/
if(SUCCEEDED(result))
{
shellLink->SetPath(exepathw.c_str());
shellLink->SetArguments(argumentsw.c_str());
shellLink->SetDescription(descriptionw.c_str());
shellLink->SetIconLocation(iconw.c_str(), 0);
IPersistFile* persistFile;
result = shellLink->QueryInterface(IID_IPersistFile, (void**)&persistFile);
if(SUCCEEDED(result))
{
result = persistFile->Save(startupfilepathw.c_str(), TRUE);
success = SUCCEEDED(result);
persistFile->Release();
}
shellLink->Release();
}
/*---------------------------------------------*\
| Uninitialize when done |
\*---------------------------------------------*/
if(weInitialised)
{
CoUninitialize();
}
}
else
{
LOG_ERROR("Could not establish correct autostart file path.");
}
return success;
}
bool AutoStart::IsAutoStartEnabled()
{
/*-------------------------------------------------*\
| Check if the filename is valid |
\*-------------------------------------------------*/
if(autostart_file != "")
{
return(filesystem::exists(autostart_file));
}
else
{
return(false);
}
}
std::string AutoStart::GetExePath()
{
/*-------------------------------------------------*\
| Create the OpenRGB executable path |
\*-------------------------------------------------*/
char exepath[MAX_PATH] = "";
DWORD count = GetModuleFileNameA(NULL, exepath, MAX_PATH);
return(std::string(exepath, (count > 0) ? count : 0));
}
/*-----------------------------------------------------*\
| Windows AutoStart Implementation |
| Private Methods |
\*-----------------------------------------------------*/
void AutoStart::InitAutoStart(std::string name)
{
char startMenuPath[MAX_PATH];
autostart_name = name;
/*-------------------------------------------------*\
| Get startup applications path |
\*-------------------------------------------------*/
HRESULT result = SHGetFolderPathA(NULL, CSIDL_PROGRAMS, NULL, 0, startMenuPath);
if(SUCCEEDED(result))
{
autostart_file = std::string(startMenuPath);
autostart_file += "\\Startup\\" + autostart_name + ".lnk";
}
else
{
autostart_file.clear();
}
}
/*-----------------------------------------------------*\
| Convert an UTF8 string to a wide Unicode String |
| (from wmi.cpp) |
\*-----------------------------------------------------*/
std::wstring AutoStart::utf8_decode(const std::string& str)
{
if(str.empty())
{
return std::wstring();
}
int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int) str.size(), nullptr, 0);
std::wstring wstrTo(size_needed, 0);
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int) str.size(), &wstrTo[0], size_needed);
return(wstrTo);
}
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include <string>
#include "AutoStart.h"
class AutoStart: public AutoStartInterface
{
public:
AutoStart(std::string name);
bool DisableAutoStart();
bool EnableAutoStart(AutoStartInfo autostart_info);
bool IsAutoStartEnabled();
std::string GetExePath();
private:
void InitAutoStart(std::string name);
std::wstring utf8_decode(const std::string& str);
};
+16
View File
@@ -0,0 +1,16 @@
#include "AutoStart.h"
/*-----------------------------------------------------*\
| Common AutoStart Implementation |
| Public Methods |
\*-----------------------------------------------------*/
std::string AutoStartInterface::GetAutoStartFile()
{
return(autostart_file);
}
std::string AutoStartInterface::GetAutoStartName()
{
return(autostart_name);
}
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include <string>
struct AutoStartInfo
{
std::string path;
std::string args;
std::string desc;
std::string icon;
std::string category;
};
class AutoStartInterface
{
public:
virtual bool DisableAutoStart() = 0;
virtual bool EnableAutoStart(AutoStartInfo autostart_info) = 0;
virtual bool IsAutoStartEnabled() = 0;
virtual std::string GetExePath() = 0;
std::string GetAutoStartFile();
std::string GetAutoStartName();
protected:
std::string autostart_file;
std::string autostart_name;
};
#ifdef _WIN32
#include "AutoStart-Windows.h"
#endif
#ifdef __linux__
#include "AutoStart-Linux.h"
#endif
#ifdef __APPLE__
#include "AutoStart-MacOS.h"
#endif
@@ -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();
}
@@ -52,7 +55,12 @@ char* AMDWraithPrismController::GetDeviceName()
std::string AMDWraithPrismController::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, 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());
@@ -142,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;
}
@@ -158,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;
}
@@ -181,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;
}
@@ -207,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;
}
@@ -10,6 +10,7 @@
#include "ASRockPolychromeSMBusController.h"
#include <cstring>
#include "dependencies/dmiinfo.h"
#include "LogManager.h"
using namespace std::chrono_literals;
@@ -20,36 +21,39 @@ PolychromeController::PolychromeController(i2c_smbus_interface* bus, polychrome_
DMIInfo dmi;
unsigned short fw_version = ReadFirmwareVersion();
unsigned char major_version = fw_version >> 8;
device_name = "ASRock " + dmi.getMainboard();
fw_version = ReadFirmwareVersion();
unsigned char major_version = fw_version >> 8;
/*-----------------------------------------------------*\
| Determine whether the device uses ASR LED or |
| Polychrome protocol by checking firmware version. |
| Versions 1.xx and 2.xx use ASR LED, 3.xx uses |
| Polychrome |
| Versions: 1.xx are ASR RGB LED |
| 2.xx are Polychrome v1 |
| 3.xx are Polychrome v2 |
\*-----------------------------------------------------*/
switch(major_version)
{
case ASROCK_TYPE_ASRLED:
device_name = "ASRock " + dmi.getMainboard();
LOG_TRACE("%s Device type is ASR RGB LED", ASROCK_CONTROLLER_NAME);
asrock_type = ASROCK_TYPE_ASRLED;
memset(zone_led_count, 0, sizeof(zone_led_count));
break;
case ASROCK_TYPE_POLYCHROME_V1:
device_name = "ASRock " + dmi.getMainboard();
LOG_TRACE("%s Device type is Polychrome v1", ASROCK_CONTROLLER_NAME);
asrock_type = ASROCK_TYPE_POLYCHROME_V1;
ReadLEDConfiguration();
break;
case ASROCK_TYPE_POLYCHROME_V2:
device_name = "ASRock " + dmi.getMainboard();
LOG_TRACE("%s Device type is Polychrome v2", ASROCK_CONTROLLER_NAME);
asrock_type = ASROCK_TYPE_POLYCHROME_V2;
ReadLEDConfiguration();
break;
default:
LOG_TRACE("%s Got Unknown version!", ASROCK_CONTROLLER_NAME);
asrock_type = ASROCK_TYPE_UNKNOWN;
break;
}
@@ -82,7 +86,6 @@ std::string PolychromeController::GetDeviceName()
std::string PolychromeController::GetFirmwareVersion()
{
unsigned short fw_version = ReadFirmwareVersion();
unsigned char major_version = fw_version >> 8;
unsigned char minor_version = fw_version & 0xFF;
@@ -93,17 +96,20 @@ unsigned short PolychromeController::ReadFirmwareVersion()
{
// The firmware register holds two bytes, so the first read should return 2
// If not, report invalid firmware revision FFFF
if (bus->i2c_smbus_read_byte_data(dev, ASROCK_REG_FIRMWARE_VER) == 0x02)
LOG_DEBUG("%s Reading back device firmware version", ASROCK_CONTROLLER_NAME);
// Version response array needs to be 32 bytes to prevent non ASRock board from stack smashing
unsigned char asrock_version[I2C_SMBUS_BLOCK_MAX] = { 0x00, 0x00 };
if (bus->i2c_smbus_read_block_data(dev, ASROCK_REG_FIRMWARE_VER, asrock_version) == 0x02)
{
std::this_thread::sleep_for(1ms);
unsigned char major = bus->i2c_smbus_read_byte(dev);
std::this_thread::sleep_for(1ms);
unsigned char minor = bus->i2c_smbus_read_byte(dev);
unsigned char major = asrock_version[0];
unsigned char minor = asrock_version[1];
LOG_DEBUG("%s Device firmware version: v%02d.%02d", ASROCK_CONTROLLER_NAME, major, minor);
return((major << 8) | minor);
}
else
{
LOG_WARNING("%s Firmware readback failed; Returning 0xFFFF", ASROCK_CONTROLLER_NAME);
return(0xFFFF);
}
}
@@ -114,23 +120,26 @@ void PolychromeController::ReadLEDConfiguration()
| The LED configuration register holds 6 bytes, so the first read should return 6 |
| If not, set all zone sizes to zero |
\*---------------------------------------------------------------------------------*/
if (bus->i2c_smbus_read_byte_data(dev, POLYCHROME_REG_LED_CONFIG) == 0x06)
LOG_DEBUG("%s Reading LED config from controller", ASROCK_CONTROLLER_NAME);
unsigned char asrock_zone_count[I2C_SMBUS_BLOCK_MAX] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
if (bus->i2c_smbus_read_block_data(dev, POLYCHROME_REG_LED_CONFIG, asrock_zone_count) == 0x06)
{
std::this_thread::sleep_for(1ms);
zone_led_count[POLYCHROME_ZONE_1] = bus->i2c_smbus_read_byte(dev);
std::this_thread::sleep_for(1ms);
zone_led_count[POLYCHROME_ZONE_2] = bus->i2c_smbus_read_byte(dev);
std::this_thread::sleep_for(1ms);
zone_led_count[POLYCHROME_ZONE_3] = bus->i2c_smbus_read_byte(dev);
std::this_thread::sleep_for(1ms);
zone_led_count[POLYCHROME_ZONE_4] = bus->i2c_smbus_read_byte(dev);
std::this_thread::sleep_for(1ms);
zone_led_count[POLYCHROME_ZONE_5] = bus->i2c_smbus_read_byte(dev);
std::this_thread::sleep_for(1ms);
zone_led_count[POLYCHROME_ZONE_ADDRESSABLE] = bus->i2c_smbus_read_byte(dev);
zone_led_count[POLYCHROME_ZONE_1] = asrock_zone_count[0];
zone_led_count[POLYCHROME_ZONE_2] = asrock_zone_count[1];
zone_led_count[POLYCHROME_ZONE_3] = asrock_zone_count[2];
zone_led_count[POLYCHROME_ZONE_4] = asrock_zone_count[3];
zone_led_count[POLYCHROME_ZONE_5] = asrock_zone_count[4];
zone_led_count[POLYCHROME_ZONE_ADDRESSABLE] = asrock_zone_count[5];
LOG_DEBUG("%s Zone 1 LED count: %02d", ASROCK_CONTROLLER_NAME, zone_led_count[POLYCHROME_ZONE_1]);
LOG_DEBUG("%s Zone 2 LED count: %02d", ASROCK_CONTROLLER_NAME, zone_led_count[POLYCHROME_ZONE_2]);
LOG_DEBUG("%s Zone 3 LED count: %02d", ASROCK_CONTROLLER_NAME, zone_led_count[POLYCHROME_ZONE_3]);
LOG_DEBUG("%s Zone 4 LED count: %02d", ASROCK_CONTROLLER_NAME, zone_led_count[POLYCHROME_ZONE_4]);
LOG_DEBUG("%s Zone 5 LED count: %02d", ASROCK_CONTROLLER_NAME, zone_led_count[POLYCHROME_ZONE_5]);
LOG_DEBUG("%s Addressable Zone LED count: %02d", ASROCK_CONTROLLER_NAME, zone_led_count[POLYCHROME_ZONE_ADDRESSABLE]);
}
else
{
LOG_WARNING("%s LED config read failed", ASROCK_CONTROLLER_NAME);
memset(zone_led_count, 0, sizeof(zone_led_count));
}
}
@@ -15,6 +15,9 @@
typedef unsigned char polychrome_dev_id;
#define ASROCK_CONTROLLER_NAME "[ASRock Polychrome SMBus Controller]"
#define ASROCK_DETECTOR_NAME "[ASRock Polychrome SMBus Detect]"
enum
{
ASROCK_TYPE_UNKNOWN = 0x00, /* Unknown Type or Not ASRock Device */
@@ -209,6 +212,7 @@ public:
private:
unsigned int asrock_type;
unsigned short fw_version;
std::string device_name;
unsigned char active_zone;
unsigned char active_mode;
@@ -1,5 +1,6 @@
#include "Detector.h"
#include "ASRockPolychromeSMBusController.h"
#include "LogManager.h"
#include "RGBController.h"
#include "RGBController_ASRockPolychromeSMBus.h"
#include "i2c_smbus.h"
@@ -53,21 +54,33 @@ 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 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);
new_polychrome = new PolychromeController(busses[bus], 0x6A);
if(new_polychrome->GetASRockType() != ASROCK_TYPE_UNKNOWN)
{
LOG_TRACE("%s Found a known Polychrome device", ASROCK_DETECTOR_NAME);
new_controller = new RGBController_Polychrome(new_polychrome);
ResourceManager::get()->RegisterRGBController(new_controller);
}
else
{
LOG_TRACE("%s Not a Polychrome device or unknown type", ASROCK_DETECTOR_NAME);
delete new_polychrome;
}
}
else
{
LOG_TRACE("%s Bus %02d no response at 0x6A", ASROCK_DETECTOR_NAME, bus);
}
}
else
{
LOG_TRACE("%s Bus %02d not a motherboard", ASROCK_DETECTOR_NAME, bus);
}
}
@@ -46,7 +46,7 @@ RGBController_Polychrome::RGBController_Polychrome(PolychromeController* polychr
{
case ASROCK_TYPE_ASRLED:
{
description = "ASRock ASR LED Device";
description = "ASRock ASR RGB LED Device";
mode Off;
Off.name = "Off";
@@ -54,8 +54,13 @@ std::string PolychromeUSBController::GetDeviceName()
std::string PolychromeUSBController::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, 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());
@@ -179,7 +184,8 @@ void PolychromeUSBController::WriteRGSwap
void PolychromeUSBController::WriteHeader
(
unsigned char cfg,
unsigned char configstring[]
unsigned char* configstring,
unsigned int configsize
)
{
unsigned char usb_buf[65];
@@ -194,7 +200,7 @@ void PolychromeUSBController::WriteHeader
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_WRITE_HEADER;
usb_buf[0x03] = cfg;
memcpy(&usb_buf[4], configstring, sizeof(configstring));
memcpy(&usb_buf[4], configstring, configsize);
/*-----------------------------------------------------*\
| Send packet |
@@ -207,7 +213,7 @@ PolychromeZoneInfo PolychromeUSBController::GetZoneConfig(unsigned char zone)
{
unsigned char usb_buf[65];
PolychromeZoneInfo zoneinfo;
unsigned char all;
//unsigned char all;
unsigned char r;
unsigned char g;
unsigned char b;
@@ -242,7 +248,7 @@ PolychromeZoneInfo PolychromeUSBController::GetZoneConfig(unsigned char zone)
zoneinfo.color = ToRGBColor(r,g,b);
zoneinfo.speed = usb_buf[0x08];
zoneinfo.zone = usb_buf[0x03];
all = usb_buf[0x10];
//all = usb_buf[0x10];
return(zoneinfo);
}
@@ -128,8 +128,9 @@ public:
void WriteHeader
(
unsigned char cfg,
unsigned char configstring []
unsigned char cfg,
unsigned char* configstring,
unsigned int configsize
);
protected:
@@ -20,7 +20,7 @@
#define ASROCK_MOTHERBOARD_1_PID 0x01A2
#define ASROCK_DESKMINI_ADDRESSABLE_LED_STRIP_PID 0x01A6
void DetectPolychromeUSBControllers(hid_device_info* info, const std::string& name)
void DetectPolychromeUSBControllers(hid_device_info* info, const std::string& /*name*/)
{
hid_device* dev = hid_open_path(info->path);
@@ -33,4 +33,4 @@ void DetectPolychromeUSBControllers(hid_device_info* info, const std::string& na
}
REGISTER_HID_DETECTOR("ASRock Polychrome USB", DetectPolychromeUSBControllers, ASROCK_VID, ASROCK_MOTHERBOARD_1_PID);
REGISTER_HID_DETECTOR("ASRock Deskmini Addressable LED Strip", DetectPolychromeUSBControllers, ASROCK_VID, ASROCK_DESKMINI_ADDRESSABLE_LED_STRIP_PID);
REGISTER_HID_DETECTOR("ASRock Deskmini Addressable LED Strip", DetectPolychromeUSBControllers, ASROCK_VID, ASROCK_DESKMINI_ADDRESSABLE_LED_STRIP_PID);
@@ -171,16 +171,6 @@ RGBController_PolychromeUSB::RGBController_PolychromeUSB(PolychromeUSBController
void RGBController_PolychromeUSB::SetupZones()
{
/*-------------------------------------------------*\
| Only set LED count on the first run |
\*-------------------------------------------------*/
bool first_run = false;
if(zones.size() == 0)
{
first_run = true;
}
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
@@ -191,7 +181,6 @@ void RGBController_PolychromeUSB::SetupZones()
/*-------------------------------------------------*\
| Set zones and leds |
\*-------------------------------------------------*/
int addressableCounter = 1;
for(unsigned int channel_idx = 0; channel_idx < zones.size(); channel_idx++)
{
PolychromeDeviceInfo device_info = polychrome->GetPolychromeDevices()[channel_idx];
@@ -269,8 +258,8 @@ void RGBController_PolychromeUSB::ResizeZone(int zone, int new_size)
zonecfg[i]=zones[i].leds_count;
}
unsigned char zonecmd = POLYCHROME_USB_LEDCOUNT_CFG;
// WriteHeader(zonecmd, zonecfg);
// unsigned char zonecmd = POLYCHROME_USB_LEDCOUNT_CFG;
// WriteHeader(zonecmd, zonecfg, sizeof(zonecfg));
}
void RGBController_PolychromeUSB::DeviceUpdateLEDs()
@@ -316,7 +305,6 @@ void RGBController_PolychromeUSB::UpdateSingleLED(int led)
unsigned char RGBController_PolychromeUSB::GetDeviceMode(unsigned char zone)
{
int dev_mode;
int color_mode = MODE_COLORS_PER_LED;
dev_mode = polychrome->GetZoneConfig(zone).mode;
active_mode = dev_mode;
@@ -0,0 +1,826 @@
/*-----------------------------------------*\
| AlienwareController.cpp |
| |
| Driver for Alienware lighting controller |
| |
| Gabriel Marcano (gemarcano) 4/21/2021 |
\*-----------------------------------------*/
#include "RGBController.h"
#include "AlienwareController.h"
#include <cstring>
#include <cstdint>
#include <map>
#include <thread>
#include <chrono>
#include <algorithm>
#include <sstream>
typedef uint32_t alienware_platform_id;
/*---------------------------------------------------------*\
| Some devices appear to report the wrong number of zones. |
| Record that here. |
\*---------------------------------------------------------*/
static const std::map<alienware_platform_id, uint8_t> zone_quirks_table =
{
{ 0x0C01, 4 }, // Dell G5 SE 5505
{ 0x0A01, 16 } // Dell G7 15 7500
};
/*---------------------------------------------------------*\
| Add zones for devices here, mapping the platform ID to |
| the zone names |
\*---------------------------------------------------------*/
static const std::map<alienware_platform_id, std::vector<const char*>> zone_names_table =
{
{ 0x0C01, { "Left", "Middle", "Right", "Numpad" } },
{ 0x0A01, { "Left", "Center Left", "Center Right", "Right",
"Light Bar 1", "Light Bar 2", "Light Bar 3",
"Light Bar 4", "Light Bar 5", "Light Bar 6",
"Light Bar 7", "Light Bar 8", "Light Bar 9",
"Light Bar 10", "Light Bar 11", "Light Bar 12" } }
};
static void SendHIDReport(hid_device *dev, const unsigned char* usb_buf, size_t usb_buf_size)
{
using namespace std::chrono_literals;
hid_send_feature_report(dev, usb_buf, usb_buf_size);
/*-----------------------------------------------------*\
| The controller really doesn't like really spammed by |
| too many commands at once... the delay may be command |
| dependent also. Delay for longer if the command is |
| changing animation state |
\*-----------------------------------------------------*/
unsigned char command = usb_buf[2];
unsigned char subcommand = usb_buf[3];
if( ( command == ALIENWARE_COMMAND_USER_ANIM )
&& ( ( subcommand == ALIENWARE_COMMAND_USER_ANIM_FINISH_PLAY )
|| ( subcommand == ALIENWARE_COMMAND_USER_ANIM_FINISH_SAVE ) ) )
{
std::this_thread::sleep_for(1s);
}
else
{
std::this_thread::sleep_for(60ms);
}
}
AlienwareController::AlienwareController(hid_device* dev_handle, const hid_device_info& info, std::string name)
{
HidapiAlienwareReport report;
dev = dev_handle;
device_name = name;
location = info.path;
/*-----------------------------------------------------*\
| Get serial number |
\*-----------------------------------------------------*/
std::wstring tmp_serial_number;
tmp_serial_number = info.serial_number;
serial_number = std::string(tmp_serial_number.begin(), tmp_serial_number.end());
/*-----------------------------------------------------*\
| Get zone information by checking firmware |
| configuration |
\*-----------------------------------------------------*/
report = Report(ALIENWARE_COMMAND_REPORT_CONFIG);
alienware_platform_id platform_id = report.data[4] << 8 | report.data[5];
/*-----------------------------------------------------*\
| Get firmware version |
\*-----------------------------------------------------*/
report = Report(ALIENWARE_COMMAND_REPORT_FIRMWARE);
std::stringstream fw_string;
fw_string << static_cast<unsigned>(report.data[4]) << '.' << static_cast<unsigned>(report.data[5]) << '.' << static_cast<unsigned>(report.data[6]);
version = fw_string.str();
/*-----------------------------------------------------*\
| Check if the device reports the wrong number of zones |
\*-----------------------------------------------------*/
unsigned number_of_zones = zone_quirks_table.count(platform_id) ? zone_quirks_table.at(platform_id) : report.data[6];
/*-----------------------------------------------------*\
| Initialize Alienware zones |
\*-----------------------------------------------------*/
zones.resize(number_of_zones);
if(zone_names_table.count(platform_id))
{
zone_names = zone_names_table.at(platform_id);
}
else
{
/*-------------------------------------------------*\
| If this is an unknown controller, set the name of |
| all regions to "Unknown" |
\*-------------------------------------------------*/
for(size_t i = 0; i < number_of_zones; i++)
{
zone_names.emplace_back("Unknown");
}
}
/*-----------------------------------------------------*\
| Set defaults for all zones |
| It doesn't seem possible to read the controller's |
| current state, hence the default value being set here.|
\*-----------------------------------------------------*/
for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
zones[zone_idx].color[0] = 0x000000;
zones[zone_idx].color[1] = 0x000000;
zones[zone_idx].mode = ALIENWARE_MODE_COLOR;
/*-------------------------------------------------*\
| Default period value from ACC |
\*-------------------------------------------------*/
zones[zone_idx].period = 2000;
zones[zone_idx].tempo = ALIENWARE_TEMPO_MAX;
zones[zone_idx].dim = 0;
}
/*-----------------------------------------------------*\
| Initialize dirty flags |
\*-----------------------------------------------------*/
dirty = true;
dirty_dim = true;
}
AlienwareController::~AlienwareController()
{
}
unsigned int AlienwareController::GetZoneCount()
{
return(zones.size());
}
std::vector<const char*> AlienwareController::GetZoneNames()
{
return(zone_names);
}
std::string AlienwareController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string AlienwareController::GetDeviceName()
{
return(device_name);
}
std::string AlienwareController::GetSerialString()
{
return(serial_number);
}
std::string AlienwareController::GetFirmwareVersion()
{
return(version);
}
AlienwareController::HidapiAlienwareReport AlienwareController::GetResponse()
{
/*-----------------------------------------------------*\
| Zero init. This is not updated if there's a problem. |
\*-----------------------------------------------------*/
HidapiAlienwareReport result;
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(result.data, 0x00, sizeof(result.data));
hid_get_feature_report(dev, result.data, HIDAPI_ALIENWARE_REPORT_SIZE);
return(result);
}
AlienwareController::HidapiAlienwareReport AlienwareController::Report(uint8_t subcommand)
{
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet with leading 00, per hidapi |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x03;
usb_buf[0x02] = ALIENWARE_COMMAND_REPORT;
usb_buf[0x03] = subcommand;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
SendHIDReport(dev, usb_buf, sizeof(usb_buf));
return(GetResponse());
}
AlienwareReport AlienwareController::GetStatus(uint8_t subcommand)
{
HidapiAlienwareReport data = Report(subcommand);
AlienwareReport result = AlienwareReport{};
/*-----------------------------------------------------*\
| Skip first byte, as that's the report number, which |
| should be 0 |
\*-----------------------------------------------------*/
memcpy(result.data, &data.data[1], sizeof(result.data));
return(result);
}
bool AlienwareController::Dim(std::vector<uint8_t> zones, double percent)
{
/*-----------------------------------------------------*\
| Bail out if there are no zones to update |
\*-----------------------------------------------------*/
if(!zones.size())
{
return(true);
}
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet with leading 00, per hidapi |
\*-----------------------------------------------------*/
uint16_t num_zones = zones.size();
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x03;
usb_buf[0x02] = ALIENWARE_COMMAND_DIM;
usb_buf[0x03] = static_cast<uint8_t>(percent);
usb_buf[0x04] = num_zones >> 8;
usb_buf[0x05] = num_zones & 0xFF;
for(size_t i = 0; i < num_zones; i++)
{
usb_buf[0x06+i] = zones[i];
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
SendHIDReport(dev, usb_buf, sizeof(usb_buf));
HidapiAlienwareReport response = GetResponse();
/*-----------------------------------------------------*\
| For this command, error is if the output equals the |
| input |
\*-----------------------------------------------------*/
return((response.data[1] == 0x03) && memcmp(usb_buf, response.data, HIDAPI_ALIENWARE_REPORT_SIZE));
}
bool AlienwareController::UserAnimation(uint16_t subcommand, uint16_t animation, uint16_t duration)
{
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet with leading 00 per hidapi |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x03;
usb_buf[0x02] = ALIENWARE_COMMAND_USER_ANIM;
usb_buf[0x03] = subcommand >> 8;
usb_buf[0x04] = subcommand & 0xFF;
usb_buf[0x05] = animation >> 8;
usb_buf[0x06] = animation & 0xFF;
usb_buf[0x07] = duration >> 8;
usb_buf[0x08] = duration & 0xFF;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
SendHIDReport(dev, usb_buf, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Every subcommand appears to report its result on a |
| different byte |
\*-----------------------------------------------------*/
HidapiAlienwareReport response = GetResponse();
/*-----------------------------------------------------*\
| The only time the 0x03 byte is zero is if the |
| controller has crashed |
\*-----------------------------------------------------*/
if(response.data[1] == 0)
{
return(false);
}
switch(subcommand)
{
case ALIENWARE_COMMAND_USER_ANIM_FINISH_SAVE:
return(!response.data[7]);
case ALIENWARE_COMMAND_USER_ANIM_FINISH_PLAY:
return(!response.data[5]);
case ALIENWARE_COMMAND_USER_ANIM_PLAY:
return(!response.data[7]);
default:
return(true);
}
}
bool AlienwareController::SelectZones(const std::vector<uint8_t>& zones)
{
/*-----------------------------------------------------*\
| Bail if zones is empty, and return false to indicate |
| nothing has changed |
\*-----------------------------------------------------*/
if(!zones.size())
{
return(false);
}
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet with leading 00, per hidapi |
\*-----------------------------------------------------*/
uint16_t num_zones = zones.size();
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x03;
usb_buf[0x02] = ALIENWARE_COMMAND_SELECT_ZONES;
usb_buf[0x03] = 1; // loop?
usb_buf[0x04] = num_zones >> 8;
usb_buf[0x05] = num_zones & 0xFF;
for(size_t i = 0; i < num_zones; i++)
{
usb_buf[0x06+i] = zones[i];
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
SendHIDReport(dev, usb_buf, sizeof(usb_buf));
HidapiAlienwareReport response = GetResponse();
/*-----------------------------------------------------*\
| For this command, error is if the output equals the |
| input |
\*-----------------------------------------------------*/
return((response.data[1] == 0x03) && memcmp(usb_buf, response.data, HIDAPI_ALIENWARE_REPORT_SIZE));
}
bool AlienwareController::ModeAction(uint8_t mode, uint16_t duration, uint16_t tempo, RGBColor color)
{
return(ModeAction(&mode, &duration, &tempo, &color, 1));
}
bool AlienwareController::ModeAction
(
const uint8_t* mode,
const uint16_t* duration,
const uint16_t* tempo,
const RGBColor* color,
unsigned amount
)
{
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Amount must be 3 or less, as that's how many |
| subcommands can fit into one report |
\*-----------------------------------------------------*/
if(amount > 3)
{
return(false);
}
/*-----------------------------------------------------*\
| Set up message packet with leading 00, per hidapi |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x03;
usb_buf[0x02] = ALIENWARE_COMMAND_ADD_ACTION;
for(unsigned int i = 0; i < amount; i++)
{
usb_buf[0x03 + (8 * i)] = mode[i];
usb_buf[0x04 + (8 * i)] = duration[i] >> 8;
usb_buf[0x05 + (8 * i)] = duration[i] & 0xFF;
usb_buf[0x06 + (8 * i)] = tempo[i] >> 8;
usb_buf[0x07 + (8 * i)] = tempo[i] & 0xFF;
usb_buf[0x08 + (8 * i)] = RGBGetRValue(color[i]);
usb_buf[0x09 + (8 * i)] = RGBGetGValue(color[i]);
usb_buf[0x0A + (8 * i)] = RGBGetBValue(color[i]);
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
SendHIDReport(dev, usb_buf, sizeof(usb_buf));
HidapiAlienwareReport response = GetResponse();
/*-----------------------------------------------------*\
| For this command, error is if the output equals the |
| input |
\*-----------------------------------------------------*/
return((response.data[1] == 0x03) && memcmp(usb_buf, response.data, HIDAPI_ALIENWARE_REPORT_SIZE));
}
bool AlienwareController::MultiModeAction
(
const uint8_t* mode,
const uint16_t* duration,
const uint16_t* tempo,
const RGBColor* color,
unsigned amount
)
{
bool result = true;
unsigned int left = amount;
while(left && result)
{
unsigned int tmp_amount;
tmp_amount = std::min(left, 3u);
result &= ModeAction(mode, duration, tempo, color, tmp_amount);
mode += tmp_amount;
duration += tmp_amount;
tempo += tmp_amount;
color += tmp_amount;
left -= tmp_amount;
}
return(result);
}
bool AlienwareController::SetColorDirect(RGBColor color, std::vector<uint8_t> zones)
{
/*-----------------------------------------------------*\
| Bail if zones is empty |
\*-----------------------------------------------------*/
if(zones.empty())
{
return(true);
}
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet with leading 00, per hidapi |
\*-----------------------------------------------------*/
uint16_t num_zones = zones.size();
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x03;
usb_buf[0x02] = ALIENWARE_COMMAND_SET_COLOR;
usb_buf[0x03] = RGBGetRValue(color);
usb_buf[0x04] = RGBGetGValue(color);
usb_buf[0x05] = RGBGetBValue(color);
usb_buf[0x06] = num_zones >> 8;
usb_buf[0x07] = num_zones & 0xFF;
for(size_t i = 0; i < num_zones; i++)
{
usb_buf[0x08 + i] = zones[i];
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
SendHIDReport(dev, usb_buf, sizeof(usb_buf));
HidapiAlienwareReport response = GetResponse();
/*-----------------------------------------------------*\
| For this command, error is if the output equals the |
| input |
\*-----------------------------------------------------*/
return((response.data[1] == 0x03) && memcmp(usb_buf, response.data, HIDAPI_ALIENWARE_REPORT_SIZE));
}
bool AlienwareController::Reset()
{
/*-----------------------------------------------------*\
| Bail if zones is empty |
\*-----------------------------------------------------*/
if(zones.empty())
{
return(true);
}
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up message packet with leading 00, per hidapi |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x03;
usb_buf[0x02] = ALIENWARE_COMMAND_RESET;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
SendHIDReport(dev, usb_buf, sizeof(usb_buf));
HidapiAlienwareReport response = GetResponse();
/*-----------------------------------------------------*\
| For this command, error is if the output equals the |
| input |
\*-----------------------------------------------------*/
return(response.data[1] == 0x03);
}
void AlienwareController::SetMode(uint8_t zone, uint8_t mode)
{
if(mode != zones[zone].mode)
{
zones[zone].mode = mode;
dirty = true;
}
}
void AlienwareController::SetColor(uint8_t zone, RGBColor color)
{
SetColor(zone, color, zones[zone].color[1]);
}
void AlienwareController::SetColor(uint8_t zone, RGBColor color1, RGBColor color2)
{
dirty = ((color1 != zones[zone].color[0]) || (color2 != zones[zone].color[1]));
if(dirty)
{
zones[zone].color[0] = color1;
zones[zone].color[1] = color2;
}
}
void AlienwareController::SetPeriod(uint8_t zone, uint16_t period)
{
if(period != zones[zone].period)
{
zones[zone].period = period;
dirty = true;
}
}
void AlienwareController::SetTempo(uint8_t zone, uint16_t tempo)
{
if(tempo != zones[zone].tempo)
{
zones[zone].tempo = tempo;
dirty = true;
}
}
void AlienwareController::SetDim(uint8_t zone, uint8_t dim)
{
if(dim != zones[zone].dim)
{
zones[zone].dim = dim;
dirty_dim = true;
}
}
void AlienwareController::UpdateDim()
{
if(!dirty_dim)
{
return;
}
/*-----------------------------------------------------*\
| Collect all zones that share dim settings, and update |
| them together |
\*-----------------------------------------------------*/
std::map<uint8_t, std::vector<uint8_t>> dim_zone_map;
for(size_t i = 0; i < zones.size(); i++)
{
dim_zone_map[zones[i].dim].emplace_back(i);
}
for(std::pair<const uint8_t, std::vector<uint8_t>> &pair : dim_zone_map)
{
/*-------------------------------------------------*\
| Bail on an error... |
\*-------------------------------------------------*/
if(!Dim(pair.second, pair.first))
{
return;
}
}
dirty_dim = false;
}
bool AlienwareController::UpdateDirect()
{
/*-----------------------------------------------------*\
| Collect all zones that share dim settings, and update |
| them together |
\*-----------------------------------------------------*/
std::map<RGBColor, std::vector<uint8_t>> color_zone_map;
for(size_t i = 0; i < zones.size(); i++)
{
color_zone_map[zones[i].color[0]].emplace_back(i);
}
for(std::pair<const RGBColor, std::vector<uint8_t>> &pair : color_zone_map)
{
/*-------------------------------------------------*\
| Bail on an error... |
\*-------------------------------------------------*/
if(!SetColorDirect(pair.first, pair.second))
{
return false;
}
}
return true;
}
static const RGBColor rainbow_colors[4][7] =
{
{ 0xFF0000, 0xFFA500, 0xFFFF00, 0x008000, 0x00BFFF, 0x0000FF, 0x800080 },
{ 0x800080, 0xFF0000, 0xFFA500, 0xFFFF00, 0x008000, 0x00BFFF, 0x0000FF },
{ 0x0000FF, 0x800080, 0xFF0000, 0xFFA500, 0xFFFF00, 0x008000, 0x00BFFF },
{ 0x00BFFF, 0x0000FF, 0x800080, 0xFF0000, 0xFFA500, 0xFFFF00, 0x008000 }
};
void AlienwareController::UpdateMode()
{
/*-----------------------------------------------------*\
| If there are no updates, don't bother running this |
\*-----------------------------------------------------*/
if(!dirty)
{
return;
}
bool result = UserAnimation(ALIENWARE_COMMAND_USER_ANIM_NEW, ALIENWARE_COMMAND_USER_ANIM_KEYBOARD, 0);
if(!result)
{
return;
}
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
alienware_zone zone = zones[zone_idx];
result = SelectZones({static_cast<uint8_t>(zone_idx)});
if(!result)
{
return;
}
/*-------------------------------------------------*\
| Some modes use 0x07D0 for their duration as sent |
| by AWCC traces, maybe 2000ms? |
\*-------------------------------------------------*/
switch (zone.mode)
{
case ALIENWARE_MODE_COLOR:
result = ModeAction(zone.mode, 2000, ALIENWARE_TEMPO_MAX, zone.color[0]);
break;
case ALIENWARE_MODE_PULSE:
result = ModeAction(zone.mode, zone.period, zone.tempo, zone.color[0]);
break;
case ALIENWARE_MODE_MORPH:
{
uint8_t zones[2] = { zone.mode, zone.mode };
uint16_t periods[2] = { zone.period, zone.period };
uint16_t tempos[2] = { zone.tempo, zone.tempo };
RGBColor colors[2] = { zone.color[0], zone.color[1] };
result = MultiModeAction(zones, periods, tempos, colors, 2);
}
break;
case ALIENWARE_MODE_SPECTRUM:
{
uint8_t zones[7] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
ALIENWARE_MODE_MORPH };
uint16_t periods[7] = { zone.period, zone.period,
zone.period, zone.period,
zone.period, zone.period,
zone.period };
uint16_t tempos[7] = { zone.tempo, zone.tempo,
zone.tempo, zone.tempo,
zone.tempo, zone.tempo,
zone.tempo };
result = MultiModeAction(zones, periods, tempos, rainbow_colors[0], 7);
}
break;
case ALIENWARE_MODE_RAINBOW:
{
uint8_t zones[7] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
ALIENWARE_MODE_MORPH };
uint16_t periods[7] = { zone.period, zone.period,
zone.period, zone.period,
zone.period, zone.period,
zone.period };
uint16_t tempos[7] = { zone.tempo, zone.tempo,
zone.tempo, zone.tempo,
zone.tempo, zone.tempo,
zone.tempo };
result = MultiModeAction(zones, periods, tempos, rainbow_colors[zone_idx], 7);
}
break;
case ALIENWARE_MODE_BREATHING:
{
uint8_t zones[2] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH };
uint16_t periods[2] = { zone.period, zone.period };
uint16_t tempos[2] = { zone.tempo, zone.tempo };
RGBColor colors[2] = { zone.color[0], 0x0 };
result = MultiModeAction(zones, periods, tempos, colors, 2);
}
break;
default:
result = false;
}
if(!result)
{
return;
}
}
result = UserAnimation(ALIENWARE_COMMAND_USER_ANIM_FINISH_PLAY, ALIENWARE_COMMAND_USER_ANIM_KEYBOARD, 0);
/*-------------------------------------------------*\
| Don't update dirty flag if there's an error |
\*-------------------------------------------------*/
if(!result)
{
return;
}
dirty = false;
}
void AlienwareController::UpdateController()
{
UpdateMode();
UpdateDim();
}
@@ -0,0 +1,161 @@
/*-----------------------------------------*\
| AlienwareController.h |
| |
| Driver for Dell Alienware RGB USB |
| controller |
| |
| Gabriel Marcano (gemarcano) 4/19/2021 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <hidapi/hidapi.h>
#include <string>
#pragma once
/*----------------------------------------------------------------------------------------------*\
| Definitions for Alienware Controller |
\*----------------------------------------------------------------------------------------------*/
#define ALIENWARE_REPORT_SIZE 33
#define HIDAPI_ALIENWARE_REPORT_SIZE (ALIENWARE_REPORT_SIZE + 1)
enum
{
ALIENWARE_COMMAND_REPORT = 0x20, /* Set report type to get */
ALIENWARE_COMMAND_USER_ANIM = 0x21, /* Set user animation settings */
ALIENWARE_COMMAND_POWER_ANIM = 0x22, /* Set power animation settings */
ALIENWARE_COMMAND_SELECT_ZONES = 0x23, /* Select zones to apply actions to */
ALIENWARE_COMMAND_ADD_ACTION = 0x24, /* Set actions to apply */
ALIENWARE_COMMAND_UNKNOWN1 = 0x25, /* Supposedly set event? */
ALIENWARE_COMMAND_DIM = 0x26, /* Set dim percentage */
ALIENWARE_COMMAND_SET_COLOR = 0x27, /* Unclear (causes color flash) */
ALIENWARE_COMMAND_RESET = 0x28, /* Reset */
ALIENWARE_COMMAND_ERASE_FLASH = 0xFF, /* Erases flash memory on controller */
};
enum
{
ALIENWARE_COMMAND_REPORT_FIRMWARE = 0x00, /* Get firmware verion */
ALIENWARE_COMMAND_REPORT_STATUS = 0x01, /* Get status */
ALIENWARE_COMMAND_REPORT_CONFIG = 0x02, /* Get firmware config */
ALIENWARE_COMMAND_REPORT_ANIMATION = 0x03, /* Get animation count and last id */
ALIENWARE_COMMAND_REPORT_UNKNOWN1 = 0x04, /* Get ELC animation by ID */
ALIENWARE_COMMAND_REPORT_UNKNOWN2 = 0x05, /* Read series??? */
ALIENWARE_COMMAND_REPORT_UNKNOWN3 = 0x06, /* Get action??? */
ALIENWARE_COMMAND_REPORT_UNKNOWN4 = 0x07, /* Get Caldera status??? */
};
enum
{
ALIENWARE_COMMAND_USER_ANIM_NEW = 0x0001, /* Start new animation */
ALIENWARE_COMMAND_USER_ANIM_FINISH_SAVE = 0x0002, /* Finish and save animation */
ALIENWARE_COMMAND_USER_ANIM_FINISH_PLAY = 0x0003, /* Finish and play animation */
ALIENWARE_COMMAND_USER_ANIM_REMOVE = 0x0004, /* Remove/erase animation */
ALIENWARE_COMMAND_USER_ANIM_PLAY = 0x0005, /* Play animation */
ALIENWARE_COMMAND_USER_ANIM_DEFAULT = 0x0006, /* Set default animation */
ALIENWARE_COMMAND_USER_ANIM_STARTUP = 0x0007, /* Set startup animation */
};
enum
{
ALIENWARE_ANIM_DEFAULT_STARTUP = 0x0008, /* Default slot for startup */
ALIENWARE_ANIM_DEFAULT = 0x0061, /* Default slot */
ALIENWARE_COMMAND_USER_ANIM_KEYBOARD = 0xFFFF, /* Non-saved animation slot */
};
enum
{
ALIENWARE_MODE_COLOR = 0x00, /* Action to set color mode */
ALIENWARE_MODE_PULSE = 0x01, /* Action to set pulse mode */
ALIENWARE_MODE_MORPH = 0x02, /* Action to set morph mode */
ALIENWARE_MODE_SPECTRUM, /* Abitrary code for spectrum mode */
ALIENWARE_MODE_RAINBOW, /* Arbitrary code for rainbow wave mode */
ALIENWARE_MODE_BREATHING, /* Arbitrary code for rainbow wave mode */
};
enum
{
ALIENWARE_TEMPO_MIN = 0x0064, /* Min tempo (as used by AWCC) */
ALIENWARE_TEMPO_MAX = 0x00FA, /* Max tempo (as used by AWCC) */
ALIENWARE_TEMPO_SPECTRUM = 0x000F, /* Used by Spectrum mode */
};
enum
{
ALIENWARE_DURATION_LONG = 0x09C4, /* Min tempo (as used by AWCC) */
ALIENWARE_DURATION_MED = 0x05DC, /* Max tempo (as used by AWCC) */
ALIENWARE_DURATION_SHORT = 0x01F3, /* Max tempo (as used by AWCC) */
ALIENWARE_DURATION_SPECTRUM = 0x01AC, /* Used by Spectrum mode */
};
typedef struct
{
unsigned char data[ALIENWARE_REPORT_SIZE];
} AlienwareReport;
class AlienwareController
{
public:
AlienwareController(hid_device* dev_handle, const hid_device_info& info, std::string name);
~AlienwareController();
std::string GetSerialString();
std::string GetDeviceLocation();
std::string GetDeviceName();
std::string GetFirmwareVersion();
unsigned GetZoneCount();
std::vector<const char*> GetZoneNames();
void SetColor(uint8_t zone, RGBColor color);
void SetColor(uint8_t zone, RGBColor color1, RGBColor color2);
void SetMode(uint8_t zone, uint8_t mode);
void SetPeriod(uint8_t zone, uint16_t period);
void SetTempo(uint8_t zone, uint16_t tempo);
void SetDim(uint8_t zone, uint8_t dim);
AlienwareReport GetStatus(uint8_t subcommand);
void UpdateDim();
void UpdateMode();
void UpdateController();
protected:
hid_device* dev;
private:
typedef struct
{
RGBColor color[2];
uint8_t mode;
uint16_t period;
uint16_t tempo;
uint8_t dim;
} alienware_zone;
typedef struct
{
unsigned char data[HIDAPI_ALIENWARE_REPORT_SIZE];
} HidapiAlienwareReport;
std::string device_name;
std::string location;
std::vector<alienware_zone> zones;
std::string serial_number;
std::string version;
std::vector<const char*> zone_names;
bool dirty;
bool dirty_dim;
HidapiAlienwareReport GetResponse();
HidapiAlienwareReport Report(uint8_t subcommand);
bool Dim(std::vector<uint8_t> zones, double percent);
bool UserAnimation(uint16_t subcommand, uint16_t animation, uint16_t duration);
bool SelectZones(const std::vector<uint8_t>& zones);
bool ModeAction(uint8_t mode, uint16_t duration, uint16_t tempo, RGBColor color);
bool ModeAction(const uint8_t *mode, const uint16_t *duration, const uint16_t *tempo, const RGBColor *color, unsigned amount);
bool MultiModeAction(const uint8_t *mode, const uint16_t *duration, const uint16_t *tempo, const RGBColor *color, unsigned amount);
bool SetColorDirect(RGBColor color, std::vector<uint8_t> zones);
bool UpdateDirect();
bool Reset();
};
@@ -0,0 +1,29 @@
#include "Detector.h"
#include "AlienwareController.h"
#include "RGBController.h"
#include "RGBController_Alienware.h"
/*---------------------------------------------------------*\
| Alienware vendor ID |
\*---------------------------------------------------------*/
#define ALIENWARE_VID 0x187C
/*---------------------------------------------------------*\
| Alienware product ID |
\*---------------------------------------------------------*/
#define ALIENWARE_G_SERIES_PID 0x0550
void DetectAlienwareControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
AlienwareController* controller = new AlienwareController(dev, *info, name);
RGBController_Alienware* rgb_controller = new RGBController_Alienware(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR("Dell G Series LED Controller", DetectAlienwareControllers, ALIENWARE_VID, ALIENWARE_G_SERIES_PID);
@@ -0,0 +1,278 @@
/*-----------------------------------------*\
| RGBController_Alienware.cpp |
| |
| Generic RGB Interface for OpenRGB |
| Alienware USB Driver |
| |
| Gabriel Marcano (gemarcano) 4/19/2021 |
\*-----------------------------------------*/
#include "RGBController_Alienware.h"
#include <thread>
#include <chrono>
RGBController_Alienware::RGBController_Alienware(AlienwareController* alienware_ptr)
{
alienware = alienware_ptr;
name = alienware->GetDeviceName();
vendor = "Alienware";
type = DEVICE_TYPE_KEYBOARD;
description = "Alienware USB Device";
location = alienware->GetDeviceLocation();
serial = alienware->GetSerialString();
version = alienware->GetFirmwareVersion();
mode Color;
Color.name = "Static";
Color.value = ALIENWARE_MODE_COLOR;
Color.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Color.color_mode = MODE_COLORS_PER_LED;
Color.colors_min = 1;
Color.colors_max = 1;
Color.brightness_min = 100;
Color.brightness_max = 0;
Color.brightness = 0;
modes.push_back(Color);
mode Pulse;
Pulse.name = "Flashing";
Pulse.value = ALIENWARE_MODE_PULSE;
Pulse.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Pulse.color_mode = MODE_COLORS_PER_LED;
Pulse.colors_min = 1;
Pulse.colors_max = 1;
Pulse.speed_min = ALIENWARE_TEMPO_MIN;
Pulse.speed_max = ALIENWARE_TEMPO_MAX;
Pulse.speed = ALIENWARE_TEMPO_MIN;
Pulse.brightness_min = 100;
Pulse.brightness_max = 0;
Pulse.brightness = 0;
modes.push_back(Pulse);
mode Morph;
Morph.name = "Morph";
Morph.value = ALIENWARE_MODE_MORPH;
Morph.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Morph.color_mode = MODE_COLORS_MODE_SPECIFIC;
Morph.colors_min = 2 * alienware->GetZoneCount();
Morph.colors_max = Morph.colors_min;
Morph.colors.resize(Morph.colors_max);
Morph.speed_min = ALIENWARE_TEMPO_MIN;
Morph.speed_max = ALIENWARE_TEMPO_MAX;
Morph.speed = ALIENWARE_TEMPO_MIN;
Morph.brightness_min = 100;
Morph.brightness_max = 0;
Morph.brightness = 0;
modes.push_back(Morph);
mode Spectrum;
Spectrum.name = "Spectrum Cycle";
Spectrum.value = ALIENWARE_MODE_SPECTRUM;
Spectrum.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Spectrum.color_mode = MODE_COLORS_NONE;
Spectrum.speed_min = ALIENWARE_TEMPO_SPECTRUM;
Spectrum.speed_max = ALIENWARE_TEMPO_MAX;
Spectrum.speed = ALIENWARE_TEMPO_SPECTRUM;
Spectrum.brightness_min = 100;
Spectrum.brightness_max = 0;
Spectrum.brightness = 0;
modes.push_back(Spectrum);
mode Rainbow;
Rainbow.name = "Rainbow Wave";
Rainbow.value = ALIENWARE_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Rainbow.color_mode = MODE_COLORS_NONE;
Rainbow.speed_min = ALIENWARE_TEMPO_SPECTRUM;
Rainbow.speed_max = ALIENWARE_TEMPO_MAX;
Rainbow.speed = ALIENWARE_TEMPO_SPECTRUM;
Rainbow.brightness_min = 100;
Rainbow.brightness_max = 0;
Rainbow.brightness = 0;
modes.push_back(Rainbow);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = ALIENWARE_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.speed_min = ALIENWARE_TEMPO_MIN;
Breathing.speed_max = ALIENWARE_TEMPO_MAX;
Breathing.speed = ALIENWARE_TEMPO_MIN;
Breathing.brightness_min = 100;
Breathing.brightness_max = 0;
Breathing.brightness = 0;
modes.push_back(Breathing);
SetupZones();
alienware->UpdateDim();
}
void RGBController_Alienware::SetupZones()
{
/*-------------------------------------------------*\
| Set zones and leds |
\*-------------------------------------------------*/
std::vector<const char*> zone_names = alienware->GetZoneNames();
for(unsigned int zone_idx = 0; zone_idx < alienware->GetZoneCount(); zone_idx++)
{
zone new_zone;
new_zone.name = zone_names[zone_idx];
new_zone.type = ZONE_TYPE_SINGLE;
new_zone.leds_min = 1;
new_zone.leds_max = 1;
new_zone.leds_count = 1;
new_zone.matrix_map = nullptr;
zones.emplace_back(new_zone);
}
for(unsigned int led_idx = 0; led_idx < zones.size(); led_idx++)
{
led new_led;
new_led.name = zones[led_idx].name + std::string(" LED");
leds.emplace_back(new_led);
}
SetupColors();
}
void RGBController_Alienware::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_Alienware::DeviceUpdateLEDs()
{
DeviceUpdateMode();
}
void RGBController_Alienware::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_Alienware::UpdateSingleLED(int led)
{
UpdateZoneLEDs(led);
}
void RGBController_Alienware::SetCustomMode()
{
active_mode = 0;
}
static bool modes_eq(const mode& mode1, const mode& mode2)
{
return( ( mode1.name == mode2.name )
&& ( mode1.value == mode2.value )
&& ( mode1.flags == mode2.flags )
&& ( mode1.speed_min == mode2.speed_min )
&& ( mode1.speed_max == mode2.speed_max )
&& ( mode1.colors_min == mode2.colors_min )
&& ( mode1.colors_max == mode2.colors_max )
&& ( mode1.speed == mode2.speed )
&& ( mode1.direction == mode2.direction )
&& ( mode1.color_mode == mode2.color_mode )
&& ( mode1.colors == mode2.colors )
&& ( mode1.brightness == mode2.brightness )
&& ( mode1.brightness_min == mode2.brightness_min )
&& ( mode1.brightness_max == mode2.brightness_max ) );
}
void RGBController_Alienware::DeviceUpdateMode()
{
/*---------------------------------------------------------*\
| Copy mode to get the current state-- this is racy, as the |
| UI thread can be actively modifying this variable |
\*---------------------------------------------------------*/
int current_mode_idx = active_mode;
mode current_mode = modes[current_mode_idx];
bool done = false;
while(!done)
{
/*-----------------------------------------------------*\
| Setup state per zone |
\*-----------------------------------------------------*/
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
zone current_zone = zones[zone_idx];
/*-------------------------------------------------*\
| Some modes use 2000ms (0x07D0) for their duration,|
| per traces |
\*-------------------------------------------------*/
uint16_t period = 0x07d0;
alienware->SetMode(zone_idx, current_mode.value);
switch(current_mode_idx)
{
case ALIENWARE_MODE_COLOR:
alienware->SetPeriod(zone_idx, period);
alienware->SetColor( zone_idx, colors[current_zone.start_idx]);
alienware->SetTempo( zone_idx, ALIENWARE_TEMPO_MAX);
alienware->SetDim( zone_idx, modes[current_mode_idx].brightness);
break;
case ALIENWARE_MODE_PULSE:
alienware->SetPeriod(zone_idx, period);
alienware->SetColor( zone_idx, colors[current_zone.start_idx]);
alienware->SetTempo( zone_idx, current_mode.speed);
alienware->SetDim( zone_idx, modes[current_mode_idx].brightness);
break;
case ALIENWARE_MODE_MORPH:
alienware->SetPeriod(zone_idx, period);
alienware->SetColor( zone_idx, current_mode.colors[zone_idx * 2], current_mode.colors[(zone_idx * 2) + 1]);
alienware->SetTempo( zone_idx, current_mode.speed);
alienware->SetDim( zone_idx, modes[current_mode_idx].brightness);
break;
case ALIENWARE_MODE_SPECTRUM:
case ALIENWARE_MODE_RAINBOW:
alienware->SetPeriod(zone_idx, ALIENWARE_DURATION_SPECTRUM);
alienware->SetTempo( zone_idx, current_mode.speed);
alienware->SetDim( zone_idx, modes[current_mode_idx].brightness);
break;
case ALIENWARE_MODE_BREATHING:
alienware->SetPeriod(zone_idx, period);
alienware->SetColor( zone_idx, colors[current_zone.start_idx], 0x0);
alienware->SetTempo( zone_idx, current_mode.speed);
alienware->SetDim( zone_idx, modes[current_mode_idx].brightness);
break;
}
}
/*-----------------------------------------------------*\
| Due to rate-limiting, this can take more than one |
| second to execute |
\*-----------------------------------------------------*/
alienware->UpdateController();
/*-----------------------------------------------------*\
| Re-run update if there's anything that's changed from |
| under us... |
\*-----------------------------------------------------*/
int new_current_mode_idx = active_mode;
mode new_current_mode = modes[current_mode_idx];
done = (current_mode_idx == new_current_mode_idx && modes_eq(new_current_mode, current_mode));
current_mode_idx = new_current_mode_idx;
current_mode = new_current_mode;
}
}
@@ -0,0 +1,37 @@
/*-----------------------------------------*\
| RGBController_Alienware.h |
| |
| Generic RGB Interface for OpenRGB |
| Alienware RGB USB Driver |
| |
| Gabriel Marcano (gemarcano) 4/19/2021 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "AlienwareController.h"
#include <chrono>
class RGBController_Alienware : public RGBController
{
public:
RGBController_Alienware(AlienwareController* alienware_ptr);
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
void SetCustomMode();
private:
AlienwareController* alienware;
std::chrono::steady_clock::time_point last_packet_ts;
};
@@ -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;
};
@@ -0,0 +1,122 @@
/*-----------------------------------------*\
| AnnePro2Controller.cpp |
| |
| Driver for Obins Lab AnnePro2 keyboard |
| |
| Sergey Gavrilov (DrZlo13) 06/06/2021 |
\*-----------------------------------------*/
#include "AnnePro2Controller.h"
using namespace std::chrono_literals;
AnnePro2Controller::AnnePro2Controller(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
AnnePro2Controller::~AnnePro2Controller()
{
hid_close(dev);
}
std::string AnnePro2Controller::GetDeviceLocation()
{
return("HID: " + location);
}
std::string AnnePro2Controller::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 AnnePro2Controller::SendDirect(unsigned char frame_count, unsigned char * frame_data)
{
/*-------------------------------------------------------------*\
| Reverse engineered by https://github.com/manualmanul/Annemone |
\*-------------------------------------------------------------*/
const unsigned char hid_cmd_service_data_length = 4;
const unsigned char hid_cmd_service_data[hid_cmd_service_data_length] = {0, 123, 16, 65};
const unsigned char hid_cmd_static_message_length = 3;
const unsigned char hid_cmd_static_message[hid_cmd_static_message_length] = {0, 0, 125};
const unsigned char hid_cmd_command_info_length = 3;
const unsigned char hid_cmd_command_info[hid_cmd_command_info_length] = {32, 3, 255};
const unsigned char real_command_info_length = hid_cmd_command_info_length + 1;
const unsigned char max_hid_length = 64;
const unsigned char max_command_length = max_hid_length - hid_cmd_service_data_length - 2 - hid_cmd_static_message_length;
const unsigned char max_message_length = max_command_length - real_command_info_length;
const unsigned char messages_to_send_amount = frame_count / max_message_length + 1;
const unsigned char val_1 = frame_count % max_message_length;
const unsigned char val_2 = (0 == val_1) ? max_message_length : val_1;
unsigned char hid_command[max_hid_length];
unsigned char led_data = 0;
for(unsigned char p = 0; p < messages_to_send_amount; p++)
{
const unsigned char e = (messages_to_send_amount << 4) + p;
const unsigned char a = ((messages_to_send_amount - 1) == p) ? val_2 + real_command_info_length : max_message_length + real_command_info_length;
/*---------------------------------------------------------*\
| Service data |
\*---------------------------------------------------------*/
hid_command[0] = hid_cmd_service_data[0];
hid_command[1] = hid_cmd_service_data[1];
hid_command[2] = hid_cmd_service_data[2];
hid_command[3] = hid_cmd_service_data[3];
hid_command[4] = e;
hid_command[5] = a;
/*---------------------------------------------------------*\
| Static message |
\*---------------------------------------------------------*/
hid_command[6] = hid_cmd_static_message[0];
hid_command[7] = hid_cmd_static_message[1];
hid_command[8] = hid_cmd_static_message[2];
/*---------------------------------------------------------*\
| Command info |
\*---------------------------------------------------------*/
hid_command[9] = hid_cmd_command_info[0];
hid_command[10] = hid_cmd_command_info[1];
hid_command[11] = hid_cmd_command_info[2];
hid_command[12] = 2;
/*---------------------------------------------------------*\
| LED data |
\*---------------------------------------------------------*/
for(uint8_t i = 0; i < max_message_length; i++)
{
hid_command[13 + i] = frame_data[led_data];
led_data++;
}
hid_write(dev, hid_command, max_hid_length);
/*---------------------------------------------------------*\
| Needed due to Anne Pro 2 ignoring commands when they're |
| sent faster than 50ms apart from each other. |
\*---------------------------------------------------------*/
std::this_thread::sleep_for(50ms);
}
}
@@ -0,0 +1,36 @@
/*-----------------------------------------*\
| AnnePro2Controller.h |
| |
| Driver for Obins Lab AnnePro2 keyboard |
| |
| Sergey Gavrilov (DrZlo13) 06/06/2021 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include <string>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
class AnnePro2Controller
{
public:
AnnePro2Controller(hid_device* dev_handle, const char* path);
~AnnePro2Controller();
std::string GetDeviceLocation();
std::string GetSerialString();
void SendDirect
(
unsigned char frame_count,
unsigned char * frame_data
);
private:
hid_device* dev;
std::string location;
};
@@ -0,0 +1,36 @@
#include "Detector.h"
#include "AnnePro2Controller.h"
#include "RGBController.h"
#include "RGBController_AnnePro2.h"
#include <hidapi/hidapi.h>
#define ANNE_PRO_2_VID 0x04D9
#define ANNE_PRO_2_PID_1 0x8008
#define ANNE_PRO_2_PID_2 0x8009
#define ANNE_PRO_2_PID_3 0xA292
#define ANNE_PRO_2_PID_4 0xA293
/******************************************************************************************\
* *
* DetectAnnePro2Controllers *
* *
* Tests the USB address to see if an Obins Lab AnnePro2 keyboard exists there. *
* *
\******************************************************************************************/
void DetectAnnePro2Controllers(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if( dev )
{
AnnePro2Controller* controller = new AnnePro2Controller(dev, info->path);
RGBController_AnnePro2* rgb_controller = new RGBController_AnnePro2(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR_I("Anne Pro 2", DetectAnnePro2Controllers, ANNE_PRO_2_VID, ANNE_PRO_2_PID_1, 1);
REGISTER_HID_DETECTOR_I("Anne Pro 2", DetectAnnePro2Controllers, ANNE_PRO_2_VID, ANNE_PRO_2_PID_2, 1);
REGISTER_HID_DETECTOR_I("Anne Pro 2", DetectAnnePro2Controllers, ANNE_PRO_2_VID, ANNE_PRO_2_PID_3, 1);
REGISTER_HID_DETECTOR_I("Anne Pro 2", DetectAnnePro2Controllers, ANNE_PRO_2_VID, ANNE_PRO_2_PID_4, 1);
@@ -0,0 +1,235 @@
/*-----------------------------------------*\
| RGBController_AnnePro2.cpp |
| |
| Generic RGB Interface for Obins Lab |
| AnnePro2 keyboard |
| |
| Sergey Gavrilov (DrZlo13) 06/06/2021 |
\*-----------------------------------------*/
#include "RGBController_AnnePro2.h"
#define NA 0xFFFFFFFF
#define LED_REAL_COUNT (5*14)
#define LED_COUNT (LED_REAL_COUNT - 9)
static unsigned int matrix_map[5][14] =
{ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 },
{ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27 },
{ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, NA },
{ 41, NA, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, NA },
{ 53, NA, 54, 55, NA, NA, 56, NA, NA, 57, 58, 59, 60, NA } };
static const char* zone_names[] =
{
"Keyboard",
};
static zone_type zone_types[] =
{
ZONE_TYPE_MATRIX
};
static const unsigned int zone_sizes[] =
{
LED_COUNT,
};
typedef struct
{
const char * name;
const unsigned char idx;
} led_type;
static const led_type led_names[] =
{
/* Key Label Index */
{ "Key: Escape", 0 },
{ "Key: 1", 1 },
{ "Key: 2", 2 },
{ "Key: 3", 3 },
{ "Key: 4", 4 },
{ "Key: 5", 5 },
{ "Key: 6", 6 },
{ "Key: 7", 7 },
{ "Key: 8", 8 },
{ "Key: 9", 9 },
{ "Key: 0", 10 },
{ "Key: -", 11 },
{ "Key: =", 12 },
{ "Key: Backspace", 13 },
{ "Key: Tab", 14 },
{ "Key: Q", 15 },
{ "Key: W", 16 },
{ "Key: E", 17 },
{ "Key: R", 18 },
{ "Key: T", 19 },
{ "Key: Y", 20 },
{ "Key: U", 21 },
{ "Key: I", 22 },
{ "Key: O", 23 },
{ "Key: P", 24 },
{ "Key: [", 25 },
{ "Key: ]", 26 },
{ "Key: \\ (ANSI)", 27 },
{ "Key: Caps Lock", 28 },
{ "Key: A", 29 },
{ "Key: S", 30 },
{ "Key: D", 31 },
{ "Key: F", 32 },
{ "Key: G", 33 },
{ "Key: H", 34 },
{ "Key: J", 35 },
{ "Key: K", 36 },
{ "Key: L", 37 },
{ "Key: ;", 38 },
{ "Key: '", 39 },
{ "Key: Enter", 40 },
{ "Key: Left Shift", 41 },
{ "Key: Z", 42 },
{ "Key: X", 43 },
{ "Key: C", 44 },
{ "Key: V", 45 },
{ "Key: B", 46 },
{ "Key: N", 47 },
{ "Key: M", 48 },
{ "Key: ,", 49 },
{ "Key: .", 50 },
{ "Key: /", 51 },
{ "Key: Right Shift", 52 },
{ "Key: Left Control", 53 },
{ "Key: Left Windows", 54 },
{ "Key: Left Alt", 55 },
{ "Key: Space", 56 },
{ "Key: Right Alt", 57 },
{ "Key: Right Fn", 58 },
{ "Key: Menu", 59 },
{ "Key: Right Control", 60 },
};
RGBController_AnnePro2::RGBController_AnnePro2(AnnePro2Controller* annepro2_ptr)
{
annepro2 = annepro2_ptr;
name = "Anne Pro 2";
vendor = "Obinslab";
type = DEVICE_TYPE_KEYBOARD;
description = "Obinslab Anne Pro 2 Device";
location = annepro2->GetDeviceLocation();
serial = annepro2->GetSerialString();
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_AnnePro2::~RGBController_AnnePro2()
{
delete annepro2;
}
void RGBController_AnnePro2::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 = 5;
new_zone.matrix_map->width = 14;
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_AnnePro2::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_AnnePro2::DeviceUpdateLEDs()
{
const unsigned char frame_buf_length = LED_REAL_COUNT * 3;
unsigned char frame_buf[frame_buf_length];
/*---------------------------------------------------------*\
| TODO: Send packets with multiple LED frames |
\*---------------------------------------------------------*/
std::size_t led_real_idx = 0;
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
frame_buf[(led_real_idx * 3) + 0] = RGBGetRValue(colors[led_idx]);
frame_buf[(led_real_idx * 3) + 1] = RGBGetGValue(colors[led_idx]);
frame_buf[(led_real_idx * 3) + 2] = RGBGetBValue(colors[led_idx]);
if(led_idx == 40 || led_idx == 41 || led_idx == 52 || led_idx == 53 || led_idx == 60)
{
led_real_idx++;
}
else if(led_idx == 55 || led_idx == 56)
{
led_real_idx++;
led_real_idx++;
}
led_real_idx++;
}
annepro2->SendDirect(frame_buf_length, frame_buf);
}
void RGBController_AnnePro2::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_AnnePro2::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_AnnePro2::SetCustomMode()
{
active_mode = 0;
}
void RGBController_AnnePro2::DeviceUpdateMode()
{
}
@@ -0,0 +1,32 @@
/*-----------------------------------------*\
| RGBController_AnnePro2.h |
| |
| Generic RGB Interface for Obins Lab |
| AnnePro2 keyboard |
| |
| Sergey Gavrilov (DrZlo13) 06/06/2021 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "AnnePro2Controller.h"
class RGBController_AnnePro2 : public RGBController
{
public:
RGBController_AnnePro2(AnnePro2Controller* annepro2_ptr);
~RGBController_AnnePro2();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
AnnePro2Controller* annepro2;
};
@@ -40,7 +40,12 @@ std::string AuraCoreController::GetDeviceLocation()
std::string AuraCoreController::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, 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());
@@ -32,14 +32,35 @@ typedef struct
static const gpu_pci_device device_list[] =
{
{ NVIDIA_VEN, NVIDIA_GTX1060_DEV, ASUS_SUB_VEN, ASUS_GTX1060_STRIX, 0x29, "ASUS GTX 1060 Strix" },
{ NVIDIA_VEN, NVIDIA_GTX1660TI_DEV, ASUS_SUB_VEN, ASUS_ROG_GTX1660TI_OC, 0x2A, "ASUS ROG GTX 1660 Ti OC 6G" },
{ NVIDIA_VEN, NVIDIA_GTX1080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080_A8G_GAMING, 0x29, "ASUS ROG Strix GTX1080 A8G Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1080TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080TI_GAMING, 0x29, "ASUS ROG Strix GTX1080 Ti Gaming" },
{ AMD_GPU_VEN, AMD_VEGA10_DEV, ASUS_SUB_VEN, ASUS_VEGA64_STRIX, 0x29, "ASUS Vega 64 Strix" },
{ AMD_GPU_VEN, AMD_NAVI10_DEV, ASUS_SUB_VEN, ASUS_RX5700XT_STRIX_GAMING_OC, 0x2A, "ASUS RX 5700XT Strix Gaming OC" },
{ AMD_GPU_VEN, AMD_POLARIS_DEV, ASUS_SUB_VEN, ASUS_RX580_STRIX_GAMING_OC, 0x29, "ASUS RX 580 Strix Gaming OC" }
};
{ 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" },
{ NVIDIA_VEN, NVIDIA_GTX1070TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1070TI_A8G_GAMING, 0x29, "ASUS ROG Strix GTX1070 Ti A8G Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1080_DEV, ASUS_SUB_VEN, ASUS_GTX1080_STRIX, 0x29, "ASUS GTX 1080 Strix OC" },
{ NVIDIA_VEN, NVIDIA_GTX1080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080_A8G_GAMING, 0x29, "ASUS ROG Strix GTX1080 A8G Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080_O8G_GAMING, 0x29, "ASUS ROG Strix GTX1080 O8G Gaming" },
{ 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 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" },
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2070S_O8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2070S O8G Gaming 8G" },
{ NVIDIA_VEN, NVIDIA_RTX2080_A_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2080_O8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2080 O8G Gaming" },
{ NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2080TI_O11G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2080 Ti O11G Gaming" },
{ AMD_GPU_VEN, AMD_VEGA10_DEV, ASUS_SUB_VEN, ASUS_VEGA64_STRIX, 0x29, "ASUS Vega 64 Strix" },
{ AMD_GPU_VEN, AMD_NAVI10_DEV, ASUS_SUB_VEN, ASUS_RX5700XT_STRIX_GAMING_OC, 0x2A, "ASUS RX 5700XT Strix Gaming OC" },
{ AMD_GPU_VEN, AMD_POLARIS_DEV, ASUS_SUB_VEN, ASUS_RX480_STRIX_GAMING_OC, 0x29, "ASUS ROG STRIX RX480 Gaming OC" },
{ AMD_GPU_VEN, AMD_POLARIS_DEV, ASUS_SUB_VEN, ASUS_RX570_STRIX_O4G_GAMING_OC, 0x29, "ASUS RX 570 Strix O4G Gaming OC" },
{ AMD_GPU_VEN, AMD_POLARIS_DEV, ASUS_SUB_VEN, ASUS_RX580_STRIX_GAMING_OC, 0x29, "ASUS RX 580 Strix Gaming OC" }
};
/******************************************************************************************\
* *
@@ -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
@@ -207,7 +207,7 @@ void AuraSMBusController::SetAllColorsDirect(unsigned char red, unsigned char gr
AuraRegisterWriteBlock(direct_reg, colors, led_count * 3);
delete colors;
delete[] colors;
}
void AuraSMBusController::SetAllColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
@@ -1,5 +1,6 @@
#include "Detector.h"
#include "AsusAuraSMBusController.h"
#include "LogManager.h"
#include "RGBController.h"
#include "RGBController_AsusAuraSMBus.h"
#include "i2c_smbus.h"
@@ -7,6 +8,7 @@
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include "dependencies/dmiinfo.h"
using namespace std::chrono_literals;
@@ -87,21 +89,32 @@ bool TestForAsusAuraSMBusController(i2c_smbus_interface* bus, unsigned char addr
{
bool pass = false;
LOG_DEBUG("[Aura SMBus] looking for devices at 0x%02X...", address);
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
if (res >= 0)
{
pass = true;
LOG_DEBUG("[Aura SMBus] Detected an I2C device at address %02X, testing register range", address);
for (int i = 0xA0; i < 0xB0; i++)
{
res = bus->i2c_smbus_read_byte_data(address, i);
if (res != (i - 0xA0))
{
LOG_VERBOSE("[Aura SMBus] Detection failed testing register %02X. Expected %02X, got %02X.", i, (i - 0xA0), res);
pass = false;
}
}
if(pass)
{
LOG_VERBOSE("[Aura SMBus] Detection successful, address %02X", address);
}
}
return(pass);
@@ -122,24 +135,24 @@ bool TestForAsusAuraSMBusController(i2c_smbus_interface* bus, unsigned char addr
* *
\******************************************************************************************/
void DetectAsusAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses)
void DetectAsusAuraSMBusDRAMControllers(std::vector<i2c_smbus_interface*> &busses)
{
AuraSMBusController* new_aura;
RGBController_AuraSMBus* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
int address_list_idx = -1;
IF_DRAM_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
{
// Remap Aura-enabled RAM modules on 0x77
LOG_DEBUG("[ASUS Aura SMBus DRAM] Remapping Aura SMBus RAM modules on 0x77");
for (unsigned int slot = 0; slot < 8; slot++)
{
int res = busses[bus]->i2c_smbus_write_quick(0x77, I2C_SMBUS_WRITE);
if (res < 0)
{
LOG_DEBUG("[ASUS Aura SMBus DRAM] No device detected at 0x77, aborting remap");
break;
}
@@ -149,6 +162,8 @@ void DetectAsusAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses)
if(address_list_idx < AURA_RAM_ADDRESS_COUNT)
{
LOG_DEBUG("[ASUS Aura SMBus DRAM] Testing address %02X to see if there is a device there", aura_ram_addresses[address_list_idx]);
res = busses[bus]->i2c_smbus_write_quick(aura_ram_addresses[address_list_idx], I2C_SMBUS_WRITE);
}
else
@@ -159,6 +174,8 @@ void DetectAsusAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses)
if(address_list_idx < AURA_RAM_ADDRESS_COUNT)
{
LOG_DEBUG("[ASUS Aura SMBus DRAM] Remapping slot %d to address %02X", slot, aura_ram_addresses[address_list_idx]);
AsusAuraRegisterWrite(busses[bus], 0x77, AURA_REG_SLOT_INDEX, slot);
AsusAuraRegisterWrite(busses[bus], 0x77, AURA_REG_I2C_ADDRESS, (aura_ram_addresses[address_list_idx] << 1));
}
@@ -169,15 +186,21 @@ void DetectAsusAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses)
{
if (TestForAsusAuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]))
{
new_aura = new AuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]);
new_controller = new RGBController_AuraSMBus(new_aura);
ResourceManager::get()->RegisterRGBController(new_controller);
AuraSMBusController* controller = new AuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]);
RGBController_AuraSMBus* rgb_controller = new RGBController_AuraSMBus(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
std::this_thread::sleep_for(1ms);
}
}
}
} /* DetectAuraSMBusDRAMControllers() */
void DetectAsusAuraSMBusMotherboardControllers(std::vector<i2c_smbus_interface*> &busses)
{
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
// Add Aura-enabled motherboard controllers
IF_MOBO_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
{
@@ -185,9 +208,11 @@ void DetectAsusAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses)
{
if (TestForAsusAuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]))
{
new_aura = new AuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]);
new_controller = new RGBController_AuraSMBus(new_aura);
ResourceManager::get()->RegisterRGBController(new_controller);
DMIInfo dmi;
AuraSMBusController* controller = new AuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]);
RGBController_AuraSMBus* rgb_controller = new RGBController_AuraSMBus(controller);
rgb_controller->name = "ASUS " + dmi.getMainboard();
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
std::this_thread::sleep_for(1ms);
@@ -195,6 +220,7 @@ void DetectAsusAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses)
}
}
} /* DetectAuraSMBusControllers() */
} /* DetectAuraSMBusMotherboardControllers() */
REGISTER_I2C_DETECTOR("ASUS Aura SMBus", DetectAsusAuraSMBusControllers);
REGISTER_I2C_DETECTOR("ASUS Aura SMBus DRAM", DetectAsusAuraSMBusDRAMControllers);
REGISTER_I2C_DETECTOR("ASUS Aura SMBus Motherboard", DetectAsusAuraSMBusMotherboardControllers);
@@ -17,7 +17,7 @@ AuraAddressableController::AuraAddressableController(hid_device* dev_handle, con
\*-----------------------------------------------------*/
for(int i = 0; i < config_table[0x02]; ++i)
{
device_info.push_back({0x01, (unsigned char)i, 0x01, AuraDeviceType::ADDRESSABLE});
device_info.push_back({0x01, (unsigned char)i, 0x01, 0, AuraDeviceType::ADDRESSABLE});
}
}
@@ -0,0 +1,133 @@
/*-----------------------------------------*\
| AsusAuraHeadsetStandController.cpp |
| |
| Driver for ASUS Aura RGB USB |
| lighting controller |
| |
| Mola19 06/04/2021 |
\*-----------------------------------------*/
#include "AsusAuraHeadsetStandController.h"
#include <cstring>
AuraHeadsetStandController::AuraHeadsetStandController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
AuraHeadsetStandController::~AuraHeadsetStandController()
{
hid_close(dev);
}
std::string AuraHeadsetStandController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string AuraHeadsetStandController::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 AuraHeadsetStandController::UpdateLeds
(
std::vector<RGBColor> colors
)
{
unsigned char usb_buf_0[365];
memset(usb_buf_0, 0x00, sizeof(usb_buf_0));
usb_buf_0[0x00] = 0x00;
usb_buf_0[0x01] = 0xC0;
usb_buf_0[0x02] = 0x81;
usb_buf_0[0x03] = 0x00;
usb_buf_0[0x04] = 0x00;
for(unsigned int i = 0; i < 60; i += 4)
{
usb_buf_0[5 + i] = 0x00;
usb_buf_0[6 + i] = RGBGetRValue(colors[i / 4]);
usb_buf_0[7 + i] = RGBGetGValue(colors[i / 4]);
usb_buf_0[8 + i] = RGBGetBValue(colors[i / 4]);
}
hid_write(dev, usb_buf_0, 65);
unsigned char usb_buf_1[65];
memset(usb_buf_1, 0x00, sizeof(usb_buf_1));
usb_buf_1[0x00] = 0x00;
usb_buf_1[0x01] = 0xC0;
usb_buf_1[0x02] = 0x81;
usb_buf_1[0x03] = 0x01;
usb_buf_1[0x04] = 0x00;
for(unsigned int i = 0; i < 12; i += 4)
{
usb_buf_1[5 + i] = 0x00;
usb_buf_1[6 + i] = RGBGetRValue(colors[(i / 4) + 15]);
usb_buf_1[7 + i] = RGBGetGValue(colors[(i / 4) + 15]);
usb_buf_1[8 + i] = RGBGetBValue(colors[(i / 4) + 15]);
}
hid_write(dev, usb_buf_1, 65);
}
void AuraHeadsetStandController::UpdateDevice
(
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu,
unsigned char speed,
bool save
)
{
unsigned char usb_buf[65];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x51;
usb_buf[0x02] = 0x28;
usb_buf[0x03] = 0x00;
usb_buf[0x04] = 0x00;
usb_buf[0x05] = mode;
usb_buf[0x06] = speed;
usb_buf[0x07] = 0x04;
usb_buf[0x08] = 0x00;
usb_buf[0x09] = 0x00;
usb_buf[0x0a] = red;
usb_buf[0x0b] = grn;
usb_buf[0x0c] = blu;
hid_write(dev, usb_buf, 65);
if(save)
{
unsigned char usb_save_buf[65];
memset(usb_save_buf, 0x00, sizeof(usb_save_buf));
usb_save_buf[0x00] = 0x00;
usb_save_buf[0x01] = 0x50;
usb_save_buf[0x02] = 0x55;
hid_write(dev, usb_save_buf, 65);
}
}
@@ -0,0 +1,59 @@
/*-----------------------------------------*\
| AsusAuraHeadsetStandController.h |
| |
| Definitions and types for ASUS Aura |
| USB RGB lighting controller |
| |
| Mola19 06/04/2021 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <hidapi/hidapi.h>
#pragma once
enum
{
AURA_HEADSET_STAND_ZONE_UNDERGLOW = 0,
AURA_HEADSET_STAND_ZONE_LOGO = 1
};
enum
{
AURA_HEADSET_STAND_MODE_DIRECT = 0,
AURA_HEADSET_STAND_MODE_STATIC = 1,
AURA_HEADSET_STAND_MODE_BREATHING = 2,
AURA_HEADSET_STAND_MODE_STROBING = 3,
AURA_HEADSET_STAND_MODE_COLOR_CYCLE = 4,
AURA_HEADSET_STAND_MODE_RAINBOW = 5
};
class AuraHeadsetStandController
{
public:
AuraHeadsetStandController(hid_device* dev_handle, const char* path);
virtual ~AuraHeadsetStandController();
std::string GetDeviceLocation();
std::string GetSerialString();
void UpdateLeds
(
std::vector<RGBColor> colors
);
void UpdateDevice
(
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu,
unsigned char speed,
bool save
);
private:
hid_device* dev;
std::string location;
};
@@ -30,7 +30,12 @@ std::string AuraKeyboardController::GetDeviceLocation()
std::string AuraKeyboardController::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, 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());
@@ -12,17 +12,26 @@
AuraMainboardController::AuraMainboardController(hid_device* dev_handle, const char* path) : AuraUSBController(dev_handle, path), mode(AURA_MODE_DIRECT)
{
unsigned char num_total_mainboard_leds = config_table[0x1B];
unsigned char num_rgb_headers = config_table[0x1D];
unsigned char num_addressable_headers = config_table[0x02];
if(num_total_mainboard_leds < num_rgb_headers)
{
num_rgb_headers = 0;
}
/*-----------------------------------------------------*\
| Add mainboard device |
\*-----------------------------------------------------*/
device_info.push_back({0x00, 0x04, config_table[0x1B], AuraDeviceType::FIXED});
device_info.push_back({0x00, 0x04, num_total_mainboard_leds, num_rgb_headers, AuraDeviceType::FIXED});
/*-----------------------------------------------------*\
| Add addressable devices |
\*-----------------------------------------------------*/
for(int i = 0; i < config_table[0x02]; ++i)
for(int i = 0; i < num_addressable_headers; i++)
{
device_info.push_back({0x01, (unsigned char)i, 0x01, AuraDeviceType::ADDRESSABLE});
device_info.push_back({0x01, (unsigned char)i, 0x01, 0, AuraDeviceType::ADDRESSABLE});
}
}
@@ -142,7 +151,7 @@ void AuraMainboardController::SendEffect
void AuraMainboardController::SendColor
(
unsigned char channel,
unsigned char /*channel*/,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data
@@ -196,4 +205,4 @@ void AuraMainboardController::SendCommit()
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
}
@@ -11,10 +11,11 @@
#include <cstring>
AuraMouseController::AuraMouseController(hid_device* dev_handle, const char* path)
AuraMouseController::AuraMouseController(hid_device* dev_handle, const char* path, uint16_t pid)
{
dev = dev_handle;
location = path;
device_pid = pid;
}
AuraMouseController::~AuraMouseController()
@@ -29,8 +30,13 @@ std::string AuraMouseController::GetDeviceLocation()
std::string AuraMouseController::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, serial_string, 128);
wchar_t serial_string[HID_MAX_STR];
int ret = hid_get_serial_number_string(dev, serial_string, HID_MAX_STR);
if(ret != 0)
{
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
@@ -38,21 +44,31 @@ std::string AuraMouseController::GetSerialString()
return(return_string);
}
void AuraMouseController::SaveMode()
{
unsigned char usb_save_buf[ASUS_AURA_MOUSE_PACKET_SIZE] = { 0x00, 0x50, 0x03 };
hid_write(dev, usb_save_buf, ASUS_AURA_MOUSE_PACKET_SIZE);
}
void AuraMouseController::SendUpdate
(
unsigned char zone,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
unsigned char blu,
unsigned char dir,
bool random,
unsigned char speed
)
{
unsigned char usb_buf[65];
unsigned char usb_buf[ASUS_AURA_MOUSE_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
memset(usb_buf, 0x00, ASUS_AURA_MOUSE_PACKET_SIZE);
/*-----------------------------------------------------*\
| Set up message packet |
@@ -67,9 +83,24 @@ void AuraMouseController::SendUpdate
usb_buf[0x07] = red;
usb_buf[0x08] = grn;
usb_buf[0x09] = blu;
if (device_pid == AURA_ROG_GLADIUS_II_ORIGIN_PNK_LTD_PID)
{
usb_buf[0x0A] = 0;
usb_buf[0x0B] = 0;
usb_buf[0x0C] = 0;
usb_buf[0x0D] = dir;
usb_buf[0x0E] = random;
usb_buf[0x0F] = speed;
}
else
{
usb_buf[0x0A] = dir;
usb_buf[0x0B] = random;
usb_buf[0x0C] = speed;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_write(dev, usb_buf, ASUS_AURA_MOUSE_PACKET_SIZE);
}
@@ -8,46 +8,39 @@
\*-----------------------------------------*/
#include "RGBController.h"
#include "AsusAuraMouseDevices.h"
#include <string>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
enum
{
AURA_MOUSE_ZONE_LOGO = 0,
AURA_MOUSE_ZONE_SCROLL = 1,
AURA_MOUSE_ZONE_UNDERGLOW = 2,
AURA_MOUSE_ZONE_ALL = 3,
};
enum
{
AURA_MOUSE_MODE_STATIC = 0,
AURA_MOUSE_MODE_BREATHING = 1,
AURA_MOUSE_MODE_COLOR_CYCLE = 2,
AURA_MOUSE_MODE_REACTIVE = 3,
};
#define ASUS_AURA_MOUSE_PACKET_SIZE 65
#define HID_MAX_STR 255
class AuraMouseController
{
public:
AuraMouseController(hid_device* dev_handle, const char* path);
AuraMouseController(hid_device* dev_handle, const char* path, uint16_t pid);
virtual ~AuraMouseController();
std::string GetDeviceLocation();
std::string GetSerialString();
void SaveMode();
void SendUpdate
(
unsigned char zone,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu
);
unsigned char blu,
unsigned char dir,
bool random,
unsigned char speed
);
uint16_t device_pid;
private:
hid_device* dev;
@@ -0,0 +1,212 @@
/*-------------------------------------------------------------------*\
| AsusAuraMouseDevices.h |
| |
| Asus Aura Mouse definitions and mapping |
| |
| Chris M (Dr_No) 11th July 2021 |
\*-------------------------------------------------------------------*/
#include <vector>
#include <map>
#pragma once
#define AURA_ROG_GLADIUS_II_CORE_PID 0x18DD
#define AURA_ROG_GLADIUS_II_PID 0x1845
#define AURA_ROG_GLADIUS_II_ORIGIN_PID 0x1877
#define AURA_ROG_GLADIUS_II_ORIGIN_PNK_LTD_PID 0x18CD
#define AURA_ROG_GLADIUS_II_ORIGIN_COD_PID 0x18B1
#define AURA_ROG_GLADIUS_II_WIRELESS_1_PID 0x189E
#define AURA_ROG_GLADIUS_II_WIRELESS_2_PID 0x18A0
#define AURA_ROG_CHAKRAM_WIRELESS_PID 0x18E5
#define AURA_ROG_CHAKRAM_WIRED_1_PID 0x18E3
#define AURA_ROG_CHAKRAM_WIRED_2_PID 0x1958
#define AURA_ROG_PUGIO_PID 0x1846
#define AURA_ROG_PUGIO_II_WIRED_PID 0x1906
#define AURA_ROG_PUGIO_II_WIRELESS_PID 0x1908
#define AURA_ROG_STRIX_IMPACT_II_PID 0x18E1
#define AURA_TUF_M3_PID 0x1910
#define AURA_TUF_M5_PID 0x1910
enum
{
AURA_MOUSE_ZONE_LOGO = 0,
AURA_MOUSE_ZONE_SCROLL = 1,
AURA_MOUSE_ZONE_UNDERGLOW = 2,
AURA_MOUSE_ZONE_ALL = 3,
};
enum
{
AURA_MOUSE_MODE_STATIC = 0,
AURA_MOUSE_MODE_BREATHING = 1,
AURA_MOUSE_MODE_SPECTRUM = 2,
AURA_MOUSE_MODE_WAVE = 3,
AURA_MOUSE_MODE_REACTIVE = 4,
AURA_MOUSE_MODE_COMET = 5,
AURA_MOUSE_MODE_BATTERY = 6
};
typedef struct
{
uint8_t speed_min;
uint8_t speed_max;
std::vector<uint8_t> mouse_zones;
std::vector<uint8_t> mouse_modes;
} mouse_type;
/*-----------------------------------------------------------------*\
| DEVICE MAP |
| |
| This structure maps the OpenRGB modes to the mode values |
| sent to each mouse. As not all modes are present on each |
| mouse the "mode index" is different. Eg. "Reactive" is mode |
| 4 on the Gladius II and mode 3 on the Gladius II wireless |
\*-----------------------------------------------------------------*/
static std::map<int,mouse_type> aura_mouse_devices =
{
{
AURA_ROG_GLADIUS_II_CORE_PID, // ROG Gladius II Core
{
255, //Speed Min - The Asus Mouse protocol defines larger numbers as slow
1, //Speed Max
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_REACTIVE }
}
},
{
AURA_ROG_GLADIUS_II_PID, // ROG Gladius II
{
255,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_WAVE, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_COMET }
}
},
{
AURA_ROG_GLADIUS_II_ORIGIN_PID, // ROG Gladius II Origin
{
255,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_WAVE, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_COMET }
}
},
{
AURA_ROG_GLADIUS_II_ORIGIN_COD_PID, // ROG Gladius II COD
{
255,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_WAVE, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_COMET }
}
},
{
AURA_ROG_GLADIUS_II_ORIGIN_PNK_LTD_PID, // ROG Gladius II PNK LTD
{
255,
1,
{ AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_WAVE, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_COMET }
}
},
{
AURA_ROG_GLADIUS_II_WIRELESS_1_PID, // ROG Gladius II Wireless
{
255,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_WAVE, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_COMET }
}
},
{
AURA_ROG_GLADIUS_II_WIRELESS_2_PID, // ROG Gladius II Wireless
{
255,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_BATTERY }
}
},
{
AURA_ROG_CHAKRAM_WIRELESS_PID, // ROG Chakram Wireless
{
255,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_WAVE, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_COMET, AURA_MOUSE_MODE_BATTERY }
}
},
{
AURA_ROG_CHAKRAM_WIRED_1_PID, // ROG Chakram Wired 1
{
255,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_WAVE, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_COMET, AURA_MOUSE_MODE_BATTERY }
}
},
{
AURA_ROG_CHAKRAM_WIRED_2_PID, // ROG Chakram Wired 2
{
255,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_WAVE, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_COMET, AURA_MOUSE_MODE_BATTERY }
}
},
{
AURA_ROG_PUGIO_PID, // ROG Pugio
{
255,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_WAVE, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_COMET, AURA_MOUSE_MODE_BATTERY }
}
},
{
AURA_ROG_PUGIO_II_WIRED_PID, // ROG Pugio II Wired
{
255,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_WAVE, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_COMET, AURA_MOUSE_MODE_BATTERY }
}
},
{
AURA_ROG_PUGIO_II_WIRELESS_PID, // ROG Pugio II Wireless
{
255,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_WAVE, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_COMET, AURA_MOUSE_MODE_BATTERY }
}
},
{
AURA_ROG_STRIX_IMPACT_II_PID, // ROG Strix Impact II
{
255,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_REACTIVE }
}
},
{
AURA_TUF_M3_PID, // TUF M3
{
255,
1,
{ AURA_MOUSE_ZONE_LOGO },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_REACTIVE }
}
},
{
AURA_TUF_M5_PID, // TUF M5
{
255,
1,
{ AURA_MOUSE_ZONE_LOGO },
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_REACTIVE }
}
},
};
@@ -0,0 +1,218 @@
/*-----------------------------------------*\
| AsusAuraTUFKeyboardController.cpp |
| |
| Driver for ASUS Aura RGB USB |
| lighting controller |
| |
| Mola19 03/03/2021 |
\*-----------------------------------------*/
#include "AsusAuraTUFKeyboardController.h"
#include <cstring>
#include <string>
#include <vector>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
AuraTUFKeyboardController::AuraTUFKeyboardController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
AuraTUFKeyboardController::~AuraTUFKeyboardController()
{
hid_close(dev);
}
std::string AuraTUFKeyboardController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string AuraTUFKeyboardController::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 AuraTUFKeyboardController::UpdateSingleLed
(
int led,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
/*-----------------------------------------------------*\
| Set up message packet for single LED |
\*-----------------------------------------------------*/
unsigned char usb_buf[65];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0] = 0x00;
usb_buf[1] = 0xc0;
usb_buf[2] = 0x81;
usb_buf[3] = 0x01;
usb_buf[4] = 0x00;
/*-----------------------------------------------------*\
| Convert LED index |
\*-----------------------------------------------------*/
usb_buf[5] = floor(led/6)*8 + led%6;
usb_buf[6] = red;
usb_buf[7] = green;
usb_buf[8] = blue;
hid_write(dev, usb_buf, 65);
}
void AuraTUFKeyboardController::UpdateLeds
(
std::vector<RGBColor> colors
)
{
/*-----------------------------------------------------*\
| Loop over every column (optimisation needed) |
\*-----------------------------------------------------*/
for(unsigned int i = 0; i < 192; i += 16)
{
unsigned char usb_buf[69];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0] = 0x00;
usb_buf[1] = 0xc0;
usb_buf[2] = 0x81;
usb_buf[3] = (138 - i / 16 * 12);
usb_buf[4] = 0x00;
for(unsigned int n = 0; n < 6; n++)
{
usb_buf[n * 4 + 5] = i + n;
usb_buf[n * 4 + 6] = RGBGetRValue(colors[i/16*12+n]);
usb_buf[n * 4 + 7] = RGBGetGValue(colors[i/16*12+n]);
usb_buf[n * 4 + 8] = RGBGetBValue(colors[i/16*12+n]);
}
for(unsigned int n = 6; n < 8; n++)
{
usb_buf[n * 4 + 5] = i + n;
usb_buf[n * 4 + 6] = 0;
usb_buf[n * 4 + 7] = 0;
usb_buf[n * 4 + 8] = 0;
}
if(i != 176)
{
for(unsigned int n = 8; n < 14; n++)
{
usb_buf[n * 4 + 5] = i + n;
usb_buf[n * 4 + 6] = RGBGetRValue(colors[i/16*12+n-2]);
usb_buf[n * 4 + 7] = RGBGetGValue(colors[i/16*12+n-2]);
usb_buf[n * 4 + 8] = RGBGetBValue(colors[i/16*12+n-2]);
}
for(unsigned int n = 14; n < 16; n++)
{
usb_buf[n * 4 + 5] = i + n;
usb_buf[n * 4 + 6] = 0;
usb_buf[n * 4 + 7] = 0;
usb_buf[n * 4 + 8] = 0;
}
}
hid_write(dev, usb_buf, 69);
}
}
void AuraTUFKeyboardController::UpdateDevice
(
unsigned char mode,
std::vector<RGBColor> colors,
unsigned char dir,
unsigned char color_mode,
unsigned char speed
)
{
unsigned char usb_buf[65];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x51;
usb_buf[0x02] = 0x2C;
usb_buf[0x03] = mode;
usb_buf[0x04] = 0x00;
usb_buf[0x05] = speed;
usb_buf[0x06] = 0x64;
usb_buf[0x07] = color_mode;
usb_buf[0x08] = dir;
usb_buf[0x09] = 0x02;
if(mode == 4 || mode == 5)
{
/*-----------------------------------------------------*\
| If mode is Rainbow or Ripple |
\*-----------------------------------------------------*/
usb_buf[0x0A] = colors.size();
/*-----------------------------------------------------*\
| Loop over every color given |
\*-----------------------------------------------------*/
for(unsigned int i = 0; i / 4 < colors.size(); i += 4)
{
if(colors[i / 4])
{
usb_buf[11 + i] = 100/(double)colors.size()*(i/4+1);
usb_buf[12 + i] = RGBGetRValue(colors[i/4]);
usb_buf[13 + i] = RGBGetGValue(colors[i/4]);
usb_buf[14 + i] = RGBGetBValue(colors[i/4]);
}
}
}
else
{
/*-----------------------------------------------------*\
| Loop over Color1, Color2 and Background if there |
\*-----------------------------------------------------*/
for(unsigned int i = 0; i / 3 != colors.size(); i += 3)
{
if(colors[i / 3])
{
usb_buf[10 + i] = RGBGetRValue(colors[i/3]);
usb_buf[11 + i] = RGBGetGValue(colors[i/3]);
usb_buf[12 + i] = RGBGetBValue(colors[i/3]);
}
}
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
/*-----------------------------------------------------*\
| Set up and send packet save Packet |
\*-----------------------------------------------------*/
unsigned char usb_save_buf[65];
memset(usb_save_buf, 0x00, sizeof(usb_save_buf));
usb_save_buf[0x00] = 0x00;
usb_save_buf[0x01] = 0x50;
usb_save_buf[0x02] = 0x55;
hid_write(dev, usb_save_buf, 65);
}
@@ -0,0 +1,76 @@
/*-----------------------------------------*\
| AsusAuraTUFKeyboardController.h |
| |
| Definitions and types for ASUS Aura |
| USB RGB lighting controller |
| |
| Mola19 03/03/2021 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
enum
{
AURA_KEYBOARD_ZONE_LOGO = 0,
AURA_KEYBOARD_ZONE_SCROLL = 1,
AURA_KEYBOARD_ZONE_UNDERGLOW = 2,
AURA_KEYBOARD_ZONE_ALL = 3,
};
enum
{
AURA_KEYBOARD_MODE_STATIC = 0,
AURA_KEYBOARD_MODE_BREATHING = 1,
AURA_KEYBOARD_MODE_COLOR_CYCLE = 2,
AURA_KEYBOARD_MODE_REACTIVE = 3,
AURA_KEYBOARD_MODE_WAVE = 4,
AURA_KEYBOARD_MODE_RIPPLE = 5,
AURA_KEYBOARD_MODE_STARRY_NIGHT = 6,
AURA_KEYBOARD_MODE_QUICKSAND = 7,
AURA_KEYBOARD_MODE_CURRENT = 8,
AURA_KEYBOARD_MODE_RAIN_DROP = 9,
AURA_KEYBOARD_MODE_DIRECT = 15,
};
class AuraTUFKeyboardController
{
public:
AuraTUFKeyboardController(hid_device* dev_handle, const char* path);
~AuraTUFKeyboardController();
std::string GetDeviceLocation();
std::string GetSerialString();
void UpdateSingleLed
(
int led,
unsigned char red,
unsigned char green,
unsigned char blue
);
void UpdateLeds
(
std::vector<RGBColor> colors
);
void UpdateDevice
(
unsigned char mode,
std::vector<RGBColor> colors,
unsigned char dir,
unsigned char color_mode,
unsigned char speed
);
private:
hid_device* dev;
std::string location;
};
@@ -42,7 +42,12 @@ std::string AuraUSBController::GetDeviceName()
std::string AuraUSBController::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, 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());
@@ -53,6 +53,7 @@ struct AuraDeviceInfo
unsigned char effect_channel;
unsigned char direct_channel;
unsigned char num_leds;
unsigned char num_headers;
AuraDeviceType device_type;
};
@@ -1,34 +1,84 @@
#include "Detector.h"
#include "AsusAuraAddressableController.h"
#include "AsusAuraHeadsetStandController.h"
#include "AsusAuraKeyboardController.h"
#include "AsusAuraTUFKeyboardController.h"
#include "AsusAuraMainboardController.h"
#include "AsusAuraMouseController.h"
#include "RGBController.h"
#include "RGBController_AsusAuraUSB.h"
#include "RGBController_AsusAuraHeadsetStand.h"
#include "RGBController_AsusAuraKeyboard.h"
#include "RGBController_AsusAuraTUFKeyboard.h"
#include "RGBController_AsusAuraMouse.h"
#include <stdexcept>
#include <hidapi/hidapi.h>
#include "dependencies/dmiinfo.h"
#define AURA_USB_VID 0x0B05
#define AURA_TERMINAL_PID 0x1889
/*-----------------------------------------------------------------*\
| MOTHERBOARDS |
\*-----------------------------------------------------------------*/
#define AURA_ADDRESSABLE_1_PID 0x1867
#define AURA_ADDRESSABLE_2_PID 0x1872
#define AURA_ADDRESSABLE_3_PID 0x18A3
#define AURA_ADDRESSABLE_4_PID 0x18A5
#define AURA_MOTHERBOARD_1_PID 0x18F3
#define AURA_MOTHERBOARD_2_PID 0x1939
#define AURA_ROG_GLADIUS_II_CORE_PID 0x18DD
#define AURA_ROG_GLADIUS_II_PID 0x1845
#define AURA_ROG_STRIX_FLARE_PID 0x1875
#define AURA_ROG_GLADIUS_II_ORIGIN_PID 0x1877
#define AURA_ROG_GLADIUS_II_ORIGIN_PNK_LTD_PID 0x18CD
#define AURA_ROG_STRIX_FLARE_PNK_LTD_PID 0x18CF
#define AURA_ROG_CHAKRAM_WIRELESS_PID 0x18E5
#define AURA_ROG_CHAKRAM_WIRED_1_PID 0x18E3
#define AURA_ROG_CHAKRAM_WIRED_2_PID 0x1958
#define AURA_MOTHERBOARD_3_PID 0x19AF
void DetectAsusAuraUSBAddressable(hid_device_info* info, const std::string& name)
/*-----------------------------------------------------------------*\
| KEYBOARDS |
\*-----------------------------------------------------------------*/
#define AURA_ROG_FALCHION_WIRED_PID 0x193C
#define AURA_ROG_FALCHION_WIRELESS_PID 0x193E
#define AURA_ROG_STRIX_FLARE_PID 0x1875
#define AURA_ROG_STRIX_FLARE_PNK_LTD_PID 0x18CF
#define AURA_ROG_STRIX_SCOPE_PID 0x18F8
#define AURA_ROG_STRIX_SCOPE_RX_PID 0x1951
#define AURA_ROG_STRIX_SCOPE_TKL_PID 0x190C
#define AURA_TUF_K7_GAMING_PID 0x18AA
/*-----------------------------------------------------------------*\
| MICE - defined in AsusAuraMouseDevices.h |
\*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*\
| OTHER |
\*-----------------------------------------------------------------*/
#define AURA_TERMINAL_PID 0x1889
#define AURA_ROG_THRONE_QI_PID 0x18C5
AuraKeyboardMappingLayoutType GetKeyboardMappingLayoutType(int pid)
{
switch(pid)
{
case AURA_ROG_STRIX_FLARE_PID:
case AURA_ROG_STRIX_FLARE_PNK_LTD_PID:
return FLARE_LAYOUT;
case AURA_ROG_STRIX_SCOPE_PID:
return SCOPE_LAYOUT;
case AURA_ROG_STRIX_SCOPE_RX_PID:
return SCOPE_RX_LAYOUT;
case AURA_ROG_STRIX_SCOPE_TKL_PID:
return SCOPE_TKL_LAYOUT;
case AURA_ROG_FALCHION_WIRED_PID:
case AURA_ROG_FALCHION_WIRELESS_PID:
return FALCHION_LAYOUT;
default:
return FLARE_LAYOUT;
}
}
void DetectAsusAuraUSBTerminal(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
@@ -41,16 +91,31 @@ void DetectAsusAuraUSBAddressable(hid_device_info* info, const std::string& name
}
}
void DetectAsusAuraUSBMotherboards(hid_device_info* info, const std::string& name)
void DetectAsusAuraUSBAddressable(hid_device_info* info, const std::string& /*name*/)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
DMIInfo dmi;
AuraAddressableController* controller = new AuraAddressableController(dev, info->path);
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
rgb_controller->name = "ASUS " + dmi.getMainboard() + " Addressable";
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectAsusAuraUSBMotherboards(hid_device_info* info, const std::string& /*name*/)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
try
{
DMIInfo dmi;
AuraMainboardController* controller = new AuraMainboardController(dev, info->path);
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
rgb_controller->name = name;
rgb_controller->name = "ASUS " + dmi.getMainboard();
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
catch(std::runtime_error&)
@@ -65,8 +130,9 @@ void DetectAsusAuraUSBKeyboards(hid_device_info* info, const std::string& name)
hid_device* dev = hid_open_path(info->path);
if(dev)
{
AuraKeyboardController* controller = new AuraKeyboardController(dev, info->path);
RGBController_AuraKeyboard* rgb_controller = new RGBController_AuraKeyboard(controller);
AuraKeyboardController* controller = new AuraKeyboardController(dev, info->path);
AuraKeyboardMappingLayoutType layout = GetKeyboardMappingLayoutType(info->product_id);
RGBController_AuraKeyboard* rgb_controller = new RGBController_AuraKeyboard(controller, layout);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
@@ -77,26 +143,82 @@ void DetectAsusAuraUSBMice(hid_device_info* info, const std::string& name)
hid_device* dev = hid_open_path(info->path);
if(dev)
{
AuraMouseController* controller = new AuraMouseController(dev, info->path);
AuraMouseController* controller = new AuraMouseController(dev, info->path, info->product_id);
RGBController_AuraMouse* rgb_controller = new RGBController_AuraMouse(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR ("ASUS ROG AURA Terminal", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_TERMINAL_PID);
void DetectAsusAuraUSBHeadsetStand(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
AuraHeadsetStandController* controller = new AuraHeadsetStandController(dev, info->path);
RGBController_AuraHeadsetStand* rgb_controller = new RGBController_AuraHeadsetStand(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectAsusAuraTUFUSBKeyboard(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
AuraTUFKeyboardController* controller = new AuraTUFKeyboardController(dev, info->path);
RGBController_AuraTUFKeyboard* rgb_controller = new RGBController_AuraTUFKeyboard(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
/*-----------------------------------------------------------------*\
| MOTHERBOARDS |
\*-----------------------------------------------------------------*/
REGISTER_HID_DETECTOR ("ASUS Aura Addressable", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_ADDRESSABLE_1_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Addressable", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_ADDRESSABLE_2_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Addressable", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_ADDRESSABLE_3_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Addressable", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_ADDRESSABLE_4_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_1_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_2_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_3_PID);
/*-----------------------------------------------------------------*\
| KEYBOARDS |
\*-----------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("ASUS ROG Falchion (Wired)", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_FALCHION_WIRED_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Falchion (Wireless)", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_FALCHION_WIRELESS_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Flare", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_FLARE_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Flare PNK LTD", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_FLARE_PNK_LTD_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Scope", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_SCOPE_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Scope RX", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_SCOPE_RX_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Scope TKL", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_SCOPE_TKL_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_I ("ASUS TUF Gaming K7", DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_TUF_K7_GAMING_PID, 1);
/*-----------------------------------------------------------------*\
| MICE |
\*-----------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Core", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_CORE_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_PID, 2, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Origin", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_ORIGIN_PID, 2, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Origin PNK LTD", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_ORIGIN_PNK_LTD_PID, 2, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Origin COD", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_ORIGIN_COD_PID, 1, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Wireless", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_WIRELESS_1_PID, 1, 0xFF13);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Wireless", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_WIRELESS_2_PID, 2, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Chakram (Wireless)", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_CHAKRAM_WIRELESS_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("Asus ROG Chakram (Wired)", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_CHAKRAM_WIRED_1_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("Asus ROG Chakram (Wired)", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_CHAKRAM_WIRED_2_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Flare", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_FLARE_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Flare PNK LTD", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_FLARE_PNK_LTD_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Pugio", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_PUGIO_PID, 2, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Pugio II (Wired)", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_PUGIO_II_WIRED_PID, 1, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Pugio II (Wireless)", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_PUGIO_II_WIRELESS_PID, 1, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Impact II", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_STRIX_IMPACT_II_PID, 1, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS TUF Gaming M3", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_TUF_M3_PID, 1, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS TUF Gaming M5", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_TUF_M5_PID, 1, 0xFF01);
/*-----------------------------------------------------------------*\
| OTHER |
\*-----------------------------------------------------------------*/
REGISTER_HID_DETECTOR ("ASUS ROG AURA Terminal", DetectAsusAuraUSBTerminal, AURA_USB_VID, AURA_TERMINAL_PID);
REGISTER_HID_DETECTOR_I ("ASUS ROG Throne QI", DetectAsusAuraUSBHeadsetStand, AURA_USB_VID, AURA_ROG_THRONE_QI_PID, 0);
@@ -0,0 +1,182 @@
/*-----------------------------------------*\
| RGBController_AsusAuraHeadsetStand.cpp |
| |
| Generic RGB Interface for Asus Aura |
| USB controller driver |
| |
| Mola19 06/04/2021 |
\*-----------------------------------------*/
#include "RGBController_AsusAuraHeadsetStand.h"
RGBController_AuraHeadsetStand::RGBController_AuraHeadsetStand(AuraHeadsetStandController* aura_ptr)
{
aura = aura_ptr;
name = "ASUS Aura Headset Stand";
vendor = "ASUS";
type = DEVICE_TYPE_HEADSET_STAND;
description = "ASUS Aura Headset Stand Device";
location = aura->GetDeviceLocation();
serial = aura->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = AURA_HEADSET_STAND_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 = AURA_HEADSET_STAND_MODE_STATIC;
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 = AURA_HEADSET_STAND_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.speed_min = 0;
Breathing.speed_max = 255;
Breathing.speed = 127;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(1);
modes.push_back(Breathing);
mode Strobing;
Strobing.name = "Strobing";
Strobing.value = AURA_HEADSET_STAND_MODE_STROBING;
Strobing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Strobing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Strobing.colors_min = 1;
Strobing.colors_max = 1;
Strobing.colors.resize(1);
modes.push_back(Strobing);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = AURA_HEADSET_STAND_MODE_COLOR_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED;
SpectrumCycle.speed_min = 0;
SpectrumCycle.speed_max = 255;
SpectrumCycle.speed = 127;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = AURA_HEADSET_STAND_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED;
Rainbow.speed_min = 0;
Rainbow.speed_max = 255;
Rainbow.speed = 127;
modes.push_back(Rainbow);
SetupZones();
}
RGBController_AuraHeadsetStand::~RGBController_AuraHeadsetStand()
{
delete aura;
}
void RGBController_AuraHeadsetStand::SetupZones()
{
zone underglow_zone;
underglow_zone.name = "Underglow";
underglow_zone.type = ZONE_TYPE_LINEAR;
underglow_zone.leds_min = 17;
underglow_zone.leds_max = 17;
underglow_zone.leds_count = 17;
underglow_zone.matrix_map = NULL;
zones.push_back(underglow_zone);
for(unsigned int i = 0; i < 17; i++)
{
led underglow_led;
underglow_led.name = "Underglow LED " + std::to_string(i);
leds.push_back(underglow_led);
}
zone logo_zone;
logo_zone.name = "Logo";
logo_zone.type = ZONE_TYPE_SINGLE;
logo_zone.leds_min = 1;
logo_zone.leds_max = 1;
logo_zone.leds_count = 1;
logo_zone.matrix_map = NULL;
zones.push_back(logo_zone);
led logo_led;
logo_led.name = "Logo LED";
leds.push_back(logo_led);
SetupColors();
}
void RGBController_AuraHeadsetStand::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_AuraHeadsetStand::DeviceUpdateLEDs()
{
aura->UpdateLeds(std::vector<RGBColor>(colors));
}
void RGBController_AuraHeadsetStand::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_AuraHeadsetStand::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_AuraHeadsetStand::SetCustomMode()
{
active_mode = 0;
}
void RGBController_AuraHeadsetStand::DeviceUpdateMode()
{
unsigned char red = 0;
unsigned char grn = 0;
unsigned char blu = 0;
switch(modes[active_mode].value)
{
case 0:
aura->UpdateLeds(std::vector<RGBColor>(colors));
break;
case 1:
case 2:
case 3:
red = RGBGetRValue(modes[active_mode].colors[0]);
grn = RGBGetGValue(modes[active_mode].colors[0]);
blu = RGBGetBValue(modes[active_mode].colors[0]);
aura->UpdateDevice(modes[active_mode].value, red, grn, blu, modes[active_mode].speed, false);
break;
case 4:
case 5:
aura->UpdateDevice(modes[active_mode].value, red, grn, blu, modes[active_mode].speed, false);
break;
}
}
@@ -0,0 +1,33 @@
/*-----------------------------------------*\
| RGBController_AsusAuraHeadsetStand.h |
| |
| Generic RGB Interface for Asus Aura |
| USB controller driver |
| |
| Mola19 06/04/2021 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "AsusAuraHeadsetStandController.h"
class RGBController_AuraHeadsetStand : public RGBController
{
public:
RGBController_AuraHeadsetStand(AuraHeadsetStandController* aura_ptr);
~RGBController_AuraHeadsetStand();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
AuraHeadsetStandController* aura;
};
@@ -12,42 +12,38 @@
//0xFFFFFFFF indicates an unused entry in matrix
#define NA 0xFFFFFFFF
static unsigned int matrix_map[6][22] =
{ { 0, NA, 12, 17, 22, 27, 37, 42, 48, 53, 59, 64, 67, 68, NA, 74, 78, 83, NA, NA, NA, NA },
{ 1, 7, 13, 18, 23, 28, 33, 38, 43, 49, 54, 60, 65, 69, NA, 75, 79, 84, 87, 92, 96, 101 },
{ 2, NA, 8, 14, 19, 24, 29, 34, 39, 44, 50, 55, 61, 66, 70, 76, 80, 85, 88, 93, 97, 102 },
{ 3, NA, 9, 15, 20, 25, 30, 35, 40, 45, 51, 56, 62, 71, NA, NA, NA, NA, 89, 94, 98, NA },
{ 4, NA, 10, 16, 21, 26, 31, 36, 41, 46, 52, 57, NA, NA, 72, NA, 81, NA, 90, 95, 99, 103 },
{ 5, 6, 11, NA, NA, NA, NA, 32, NA, 47, NA, 58, 63, 73, NA, 77, 82, 86, 91, NA, 100, NA } };
static unsigned int flare_matrix_map[6][22] =
{ { 0, NA, 13, 18, 23, 28, 38, 43, 49, 54, 60, 65, 69, 70, NA, 76, 80, 85, NA, NA, NA, NA },
{ 1, 8, 14, 19, 24, 29, 34, 39, 44, 50, 55, 61, 66, 71, NA, 77, 81, 86, 89, 94, 98, 103 },
{ 2, NA, 9, 15, 20, 25, 30, 35, 40, 45, 51, 56, 62, 67, 72, 78, 82, 87, 90, 95, 99, 104 },
{ 3, NA, 10, 16, 21, 26, 31, 36, 41, 46, 52, 57, 63, 68, 73, NA, NA, NA, 91, 96, 100, NA },
{ 4, 6, 11, 17, 22, 27, 32, 37, 42, 47, 53, 58, 74, NA, NA, NA, 83, NA, 92, 97, 101, 105 },
{ 5, 7, 12, NA, NA, NA, NA, 33, NA, 48, NA, 59, 64, 75, NA, 79, 84, 88, 93, NA, 102, NA } };
static const char* zone_names[] =
{
"Keyboard",
"Logo",
"Underglow"
};
static unsigned int scope_matrix_map[6][22] =
{ { 0, NA, 13, 18, 23, 28, 38, 43, 49, 54, 60, 65, 69, 70, NA, 76, 80, 85, NA, NA, NA, NA },
{ 1, 8, 14, 19, 24, 29, 34, 39, 44, 50, 55, 61, 66, 71, NA, 77, 81, 86, 89, 94, 98, 103 },
{ 2, NA, 9, 15, 20, 25, 30, 35, 40, 45, 51, 56, 62, 67, 72, 78, 82, 87, 90, 95, 99, 104 },
{ 3, NA, 10, 16, 21, 26, 31, 36, 41, 46, 52, 57, 63, 68, 73, NA, NA, NA, 91, 96, 100, NA },
{ 4, 6, 11, 17, 22, 27, 32, 37, 42, 47, 53, 58, 74, NA, NA, NA, 83, NA, 92, 97, 101, 105 },
{ 5, NA, 7, 12, NA, NA, NA, 33, NA, 48, NA, 59, 64, 75, NA, 79, 84, 88, 93, NA, 102, NA } };
static zone_type zone_types[] =
{
ZONE_TYPE_MATRIX,
ZONE_TYPE_SINGLE,
ZONE_TYPE_SINGLE
};
static unsigned int scope_tkl_matrix_map[6][18] =
{ { 0, NA, 13, 18, 23, 28, 38, 43, 49, 54, 60, 65, 69, 70, NA, NA, NA, NA },
{ 1, 8, 14, 19, 24, 29, 34, 39, 44, 50, 55, 61, 66, 71, NA, 76, 79, 83 },
{ 2, NA, 9, 15, 20, 25, 30, 35, 40, 45, 51, 56, 62, 67, 72, 77, 80, 84 },
{ 3, NA, 10, 16, 21, 26, 31, 36, 41, 46, 52, 57, 63, 68, 73, NA, NA, NA },
{ 4, 6, 11, 17, 22, 27, 32, 37, 42, 47, 53, 58, 74, NA, NA, NA, 81, NA },
{ 5, NA, 7, 12, NA, NA, NA, 33, NA, 48, NA, 59, 64, 75, NA, 78, 82, 85 } };
static const unsigned int zone_sizes[] =
{
104,
1,
2,
};
static unsigned int falchion_matrix_map[5][16] =
{ { 0, 5, 9, 14, 18, 22, 26, 31, 35, 39, 44, 49, 54, 58, NA, 63 },
{ 1, NA, 6, 10, 15, 19, 23, 27, 32, 36, 40, 45, 50, 55, 59, 64 },
{ 2, NA, 7, 11, 16, 20, 24, 28, 33, 37, 41, 46, 51, 60, NA, 65 },
{ 3, NA, 12, 17, 21, 25, 29, 34, 38, 42, 47, 52, 56, NA, 61, 66 },
{ 4, 8, 13, NA, NA, NA, 30, NA, NA, NA, 43, 48, 53, 57, 62, 67 } };
typedef struct
{
const char * name;
const unsigned char idx;
} led_type;
static const led_type led_names[] =
static const std::vector<led_type> default_led_names =
{
/* Key Label Index */
{ "Key: Escape", 0x00 },
@@ -56,12 +52,11 @@ static const led_type led_names[] =
{ "Key: Caps Lock", 0x03 },
{ "Key: Left Shift", 0x04 },
{ "Key: Left Control", 0x05 },
{ "Key: Left Windows", 0x0D },
{ "Key: \\ (ISO)", 0x0C },
{ "Key: 1", 0x11 },
{ "Key: Q", 0x12 },
{ "Key: A", 0x13 },
{ "Key: Z", 0x14 },
{ "Key: Left Alt", 0x15 },
{ "Key: F1", 0x18 },
{ "Key: 2", 0x19 },
{ "Key: W", 0x1A },
@@ -117,6 +112,7 @@ static const led_type led_names[] =
{ "Key: F10", 0x68 },
{ "Key: =", 0x69 },
{ "Key: ]", 0x6A },
{ "Key: #", 0x6B },
{ "Key: F11", 0x70 },
{ "Key: F12", 0x78 },
{ "Key: Backspace", 0x79 },
@@ -154,14 +150,202 @@ static const led_type led_names[] =
{ "Key: Number Pad -", 0xB1 },
{ "Key: Number Pad +", 0xB2 },
{ "Key: Number Pad Enter", 0xB4 },
{ "Logo", 0xB8 },
{ "Left Underglow", 0xB9 },
{ "Right Underglow", 0xBA },
};
RGBController_AuraKeyboard::RGBController_AuraKeyboard(AuraKeyboardController* aura_ptr)
static const std::vector<led_type> default_tkl_led_names =
{
aura = aura_ptr;
/* Key Label Index */
{ "Key: Escape", 0x00 },
{ "Key: `", 0x01 },
{ "Key: Tab", 0x02 },
{ "Key: Caps Lock", 0x03 },
{ "Key: Left Shift", 0x04 },
{ "Key: Left Control", 0x05 },
{ "Key: \\ (ISO)", 0x0C },
{ "Key: 1", 0x11 },
{ "Key: Q", 0x12 },
{ "Key: A", 0x13 },
{ "Key: Z", 0x14 },
{ "Key: F1", 0x18 },
{ "Key: 2", 0x19 },
{ "Key: W", 0x1A },
{ "Key: S", 0x1B },
{ "Key: X", 0x1C },
{ "Key: F2", 0x20 },
{ "Key: 3", 0x21 },
{ "Key: E", 0x22 },
{ "Key: D", 0x23 },
{ "Key: C", 0x24 },
{ "Key: F3", 0x28 },
{ "Key: 4", 0x29 },
{ "Key: R", 0x2A },
{ "Key: F", 0x2B },
{ "Key: V", 0x2C },
{ "Key: F4", 0x30 },
{ "Key: 5", 0x31 },
{ "Key: T", 0x32 },
{ "Key: G", 0x33 },
{ "Key: B", 0x34 },
{ "Key: Space", 0x35 },
{ "Key: 6", 0x39 },
{ "Key: Y", 0x3A },
{ "Key: H", 0x3B },
{ "Key: N", 0x3C },
{ "Key: F5", 0x40 },
{ "Key: 7", 0x41 },
{ "Key: U", 0x42 },
{ "Key: J", 0x43 },
{ "Key: M", 0x44 },
{ "Key: F6", 0x48 },
{ "Key: 8", 0x49 },
{ "Key: I", 0x4A },
{ "Key: K", 0x4B },
{ "Key: ,", 0x4C },
{ "Key: Right Alt", 0x4D },
{ "Key: F7", 0x50 },
{ "Key: 9", 0x51 },
{ "Key: O", 0x52 },
{ "Key: L", 0x53 },
{ "Key: .", 0x54 },
{ "Key: F8", 0x58 },
{ "Key: 0", 0x59 },
{ "Key: P", 0x5A },
{ "Key: ;", 0x5B },
{ "Key: /", 0x5C },
{ "Key: Right Fn", 0x5D },
{ "Key: F9", 0x60 },
{ "Key: -", 0x61 },
{ "Key: [", 0x62 },
{ "Key: '", 0x63 },
{ "Key: Menu", 0x65 },
{ "Key: F10", 0x68 },
{ "Key: =", 0x69 },
{ "Key: ]", 0x6A },
{ "Key: #", 0x6B },
{ "Key: F11", 0x70 },
{ "Key: F12", 0x78 },
{ "Key: Backspace", 0x79 },
{ "Key: \\ (ANSI)", 0x7A },
{ "Key: Enter", 0x7B },
{ "Key: Right Shift", 0x7C },
{ "Key: Right Control", 0x7D },
{ "Key: Insert", 0x81 },
{ "Key: Delete", 0x82 },
{ "Key: Left Arrow", 0x85 },
{ "Key: Home", 0x89 },
{ "Key: End", 0x8A },
{ "Key: Up Arrow", 0x8C },
{ "Key: Down Arrow", 0x8D },
{ "Key: Page Up", 0x91 },
{ "Key: Page Down", 0x92 },
{ "Key: Right Arrow", 0x95 },
{ "Logo 1", 0x80 },
{ "Logo 2", 0x90 },
{ "Underglow 1", 0x06 },
{ "Underglow 2", 0x0E },
{ "Underglow 3", 0x16 },
{ "Underglow 4", 0x1E },
{ "Underglow 5", 0x26 },
{ "Underglow 6", 0x2E },
{ "Underglow 7", 0x36 },
{ "Underglow 8", 0x3E },
{ "Underglow 9", 0x46 },
{ "Underglow 10", 0x4E },
{ "Underglow 11", 0x56 },
{ "Underglow 12", 0x5E },
{ "Underglow 13", 0x66 },
{ "Underglow 14", 0x6E },
{ "Underglow 15", 0x76 },
{ "Underglow 16", 0x7E },
{ "Underglow 17", 0x86 },
{ "Underglow 18", 0x8E },
{ "Underglow 19", 0x96 },
{ "Underglow 20", 0x9E },
{ "Underglow 21", 0xA6 },
{ "Underglow 22", 0xAE },
{ "Underglow 23", 0xB6 },
{ "Underglow 24", 0xBE },
{ "Underglow 25", 0xC6 },
{ "Underglow 26", 0xCE },
};
static const std::vector<led_type> default_65pct_led_names =
{
/* Key Label Index */
{ "Key: Escape", 0x00 },
{ "Key: Tab", 0x01 },
{ "Key: Caps Lock", 0x02 },
{ "Key: Left Shift", 0x03 },
{ "Key: Left Control", 0x04 },
{ "Key: 1", 0x08 },
{ "Key: Q", 0x09 },
{ "Key: A", 0x0A },
{ "Key: Left Windows", 0x0C },
{ "Key: 2", 0x10 },
{ "Key: W", 0x11 },
{ "Key: S", 0x12 },
{ "Key: Z", 0x13 },
{ "Key: Left Alt", 0x14 },
{ "Key: 3", 0x18 },
{ "Key: E", 0x19 },
{ "Key: D", 0x1A },
{ "Key: X", 0x1B },
{ "Key: 4", 0x20 },
{ "Key: R", 0x21 },
{ "Key: F", 0x22 },
{ "Key: C", 0x23 },
{ "Key: 5", 0x28 },
{ "Key: T", 0x29 },
{ "Key: G", 0x2A },
{ "Key: V", 0x2B },
{ "Key: 6", 0x30 },
{ "Key: Y", 0x31 },
{ "Key: H", 0x32 },
{ "Key: B", 0x33 },
{ "Key: Space", 0x34 },
{ "Key: 7", 0x38 },
{ "Key: U", 0x39 },
{ "Key: J", 0x3A },
{ "Key: N", 0x3B },
{ "Key: 8", 0x40 },
{ "Key: I", 0x41 },
{ "Key: K", 0x42 },
{ "Key: M", 0x43 },
{ "Key: 9", 0x48 },
{ "Key: O", 0x49 },
{ "Key: L", 0x4A },
{ "Key: ,", 0x4B },
{ "Key: Right Alt", 0x4C },
{ "Key: 0", 0x50 },
{ "Key: P", 0x51 },
{ "Key: ;", 0x52 },
{ "Key: .", 0x53 },
{ "Key: Right Fn", 0x54 },
{ "Key: -", 0x58 },
{ "Key: [", 0x59 },
{ "Key: '", 0x5A },
{ "Key: /", 0x5B },
{ "Key: Right Control", 0x5C },
{ "Key: =", 0x60 },
{ "Key: ]", 0x61 },
{ "Key: Right Shift", 0x63 },
{ "Key: Left Arrow", 0x64 },
{ "Key: Backspace", 0x68 },
{ "Key: \\ (ANSI)", 0x69 },
{ "Key: Enter", 0x6A },
{ "Key: Up Arrow", 0x6B },
{ "Key: Down Arrow", 0x6C },
{ "Key: Insert", 0x70 },
{ "Key: Delete", 0x71 },
{ "Key: Page Up", 0x72 },
{ "Key: Page Down", 0x73 },
{ "Key: Right Arrow", 0x74 },
};
RGBController_AuraKeyboard::RGBController_AuraKeyboard(AuraKeyboardController* aura_ptr, AuraKeyboardMappingLayoutType keyboard_layout)
{
aura = aura_ptr;
layout = keyboard_layout;
name = "ASUS Aura Keyboard";
vendor = "ASUS";
@@ -182,6 +366,13 @@ RGBController_AuraKeyboard::RGBController_AuraKeyboard(AuraKeyboardController* a
RGBController_AuraKeyboard::~RGBController_AuraKeyboard()
{
for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
if(zones[zone_idx].type == ZONE_TYPE_MATRIX)
{
delete zones[zone_idx].matrix_map;
}
}
delete aura;
}
@@ -190,22 +381,76 @@ void RGBController_AuraKeyboard::SetupZones()
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
std::vector<led_zone> led_zones;
std::vector<led_type> led_names;
switch(layout)
{
/*-----------------------------------------------------*\
| On the ROG Scope keyboards Ctrl key is double sized, |
| so there is a layout shift |
\*-----------------------------------------------------*/
case SCOPE_LAYOUT:
led_names = default_led_names;
led_zones.push_back({"Keyboard", ZONE_TYPE_MATRIX, 106, new matrix_map_type{6, 22, (unsigned int *)&scope_matrix_map}});
led_names.insert(led_names.begin() + 7, {"Key: Left Windows", 0x15});
led_names.insert(led_names.begin() + 12, {"Key: Left Alt", 0x1D});
break;
case SCOPE_RX_LAYOUT:
led_names = default_led_names;
led_zones.push_back({"Keyboard", ZONE_TYPE_MATRIX, 106, new matrix_map_type{6, 22, (unsigned int *)&scope_matrix_map}});
led_zones.push_back({"Logo", ZONE_TYPE_SINGLE, 1});
led_names.insert(led_names.begin() + 7, {"Key: Left Windows", 0x15});
led_names.insert(led_names.begin() + 12, {"Key: Left Alt", 0x1D});
led_names.push_back({ "Logo", 0xB0});
break;
case SCOPE_TKL_LAYOUT:
led_names = default_tkl_led_names;
led_zones.push_back({"Keyboard", ZONE_TYPE_MATRIX, 86, new matrix_map_type{6, 18, (unsigned int *)&scope_tkl_matrix_map}});
led_zones.push_back({"Logo", ZONE_TYPE_LINEAR, 2});
led_zones.push_back({"Underglow", ZONE_TYPE_LINEAR, 26});
led_names.insert(led_names.begin() + 7, {"Key: Left Windows", 0x15});
led_names.insert(led_names.begin() + 12, {"Key: Left Alt", 0x1D});
break;
case FLARE_LAYOUT:
led_names = default_led_names;
led_zones.push_back({"Keyboard", ZONE_TYPE_MATRIX, 106, new matrix_map_type{6, 22, (unsigned int *)&flare_matrix_map}});
led_zones.push_back({"Logo", ZONE_TYPE_SINGLE, 1});
led_zones.push_back({"Underglow", ZONE_TYPE_SINGLE, 2});
led_names.insert(led_names.begin() + 7, {"Key: Left Windows", 0x0D});
led_names.insert(led_names.begin() + 12, {"Key: Left Alt", 0x15});
led_names.push_back({ "Logo", 0xB8});
led_names.push_back({ "Left Underglow", 0xB9});
led_names.push_back({ "Right Underglow", 0xBA});
break;
case FALCHION_LAYOUT:
led_names = default_65pct_led_names;
led_zones.push_back({"Keyboard", ZONE_TYPE_MATRIX, 68, new matrix_map_type{5, 16, (unsigned int *)&falchion_matrix_map}});
break;
}
unsigned int total_led_count = 0;
for(unsigned int zone_idx = 0; zone_idx < 3; zone_idx++)
for(unsigned int zone_idx = 0; zone_idx < led_zones.size(); 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];
new_zone.name = led_zones[zone_idx].name;
new_zone.type = led_zones[zone_idx].type;
new_zone.leds_min = led_zones[zone_idx].size;
new_zone.leds_max = led_zones[zone_idx].size;
new_zone.leds_count = led_zones[zone_idx].size;
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
if(led_zones[zone_idx].type == ZONE_TYPE_MATRIX)
{
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;
new_zone.matrix_map = led_zones[zone_idx].matrix;
}
else
{
@@ -214,7 +459,7 @@ void RGBController_AuraKeyboard::SetupZones()
zones.push_back(new_zone);
total_led_count += zone_sizes[zone_idx];
total_led_count += led_zones[zone_idx].size;
}
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
@@ -222,6 +467,7 @@ void RGBController_AuraKeyboard::SetupZones()
led new_led;
new_led.name = led_names[led_idx].name;
new_led.value = led_names[led_idx].idx;
leds.push_back(new_led);
}
@@ -237,20 +483,25 @@ void RGBController_AuraKeyboard::ResizeZone(int /*zone*/, int /*new_size*/)
void RGBController_AuraKeyboard::DeviceUpdateLEDs()
{
unsigned char frame_buf[107 * 4];
std::vector<unsigned char> frame_buf;
/*---------------------------------------------------------*\
| TODO: Send packets with multiple LED frames |
\*---------------------------------------------------------*/
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
frame_buf[(led_idx * 4) + 0] = leds[led_idx].value;
frame_buf[(led_idx * 4) + 1] = RGBGetRValue(colors[led_idx]);
frame_buf[(led_idx * 4) + 2] = RGBGetGValue(colors[led_idx]);
frame_buf[(led_idx * 4) + 3] = RGBGetBValue(colors[led_idx]);
}
/*---------------------------------------------------------*\
| Resize the frame buffer, 4 bytes per LED |
\*---------------------------------------------------------*/
frame_buf.resize(leds.size() * 4);
aura->SendDirect(107, frame_buf);
/*---------------------------------------------------------*\
| TODO: Send packets with multiple LED frames |
\*---------------------------------------------------------*/
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
frame_buf[(led_idx * 4) + 0] = leds[led_idx].value;
frame_buf[(led_idx * 4) + 1] = RGBGetRValue(colors[led_idx]);
frame_buf[(led_idx * 4) + 2] = RGBGetGValue(colors[led_idx]);
frame_buf[(led_idx * 4) + 3] = RGBGetBValue(colors[led_idx]);
}
aura->SendDirect(leds.size(), frame_buf.data());
}
void RGBController_AuraKeyboard::UpdateZoneLEDs(int /*zone*/)
@@ -11,10 +11,33 @@
#include "RGBController.h"
#include "AsusAuraKeyboardController.h"
enum AuraKeyboardMappingLayoutType
{
FLARE_LAYOUT,
SCOPE_LAYOUT,
SCOPE_RX_LAYOUT,
SCOPE_TKL_LAYOUT,
FALCHION_LAYOUT,
};
typedef struct
{
const char* name;
unsigned char idx;
} led_type;
typedef struct
{
const char* name;
const zone_type type;
const unsigned int size;
matrix_map_type* matrix;
} led_zone;
class RGBController_AuraKeyboard : public RGBController
{
public:
RGBController_AuraKeyboard(AuraKeyboardController* aura_ptr);
RGBController_AuraKeyboard(AuraKeyboardController* aura_ptr, AuraKeyboardMappingLayoutType keyboard_layout);
~RGBController_AuraKeyboard();
void SetupZones();
@@ -29,5 +52,6 @@ public:
void DeviceUpdateMode();
private:
AuraKeyboardController* aura;
AuraKeyboardController* aura;
AuraKeyboardMappingLayoutType layout;
};
@@ -9,44 +9,117 @@
#include "RGBController_AsusAuraMouse.h"
static std::string aura_mouse_zone_names[3]
{
"Logo",
"Scroll Wheel",
"Underglow"
};
RGBController_AuraMouse::RGBController_AuraMouse(AuraMouseController* aura_ptr)
{
aura = aura_ptr;
aura = aura_ptr;
name = "ASUS Aura Mouse";
vendor = "ASUS";
type = DEVICE_TYPE_MOUSE;
description = "ASUS Aura Mouse Device";
location = aura->GetDeviceLocation();
serial = aura->GetSerialString();
name = "ASUS Aura Mouse";
vendor = "ASUS";
type = DEVICE_TYPE_MOUSE;
description = "ASUS Aura Mouse Device";
location = aura->GetDeviceLocation();
serial = aura->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = AURA_MOUSE_MODE_STATIC;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
uint16_t pid = aura->device_pid;
std::vector<uint8_t> mm = aura_mouse_devices[pid].mouse_modes;
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = AURA_MOUSE_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
for(std::vector<uint8_t>::iterator it = mm.begin(); it != mm.end(); it++)
{
switch(*it)
{
case AURA_MOUSE_MODE_STATIC:
{
mode Direct;
Direct.name = "Direct";
Direct.value = AURA_MOUSE_MODE_STATIC;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
}
break;
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = AURA_MOUSE_MODE_COLOR_CYCLE;
SpectrumCycle.flags = 0;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(SpectrumCycle);
case AURA_MOUSE_MODE_BREATHING:
{
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = AURA_MOUSE_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
}
break;
mode Reactive;
Reactive.name = "Reactive";
Reactive.value = AURA_MOUSE_MODE_REACTIVE;
Reactive.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Reactive.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Reactive);
case AURA_MOUSE_MODE_SPECTRUM:
{
mode ColorCycle;
ColorCycle.name = "Spectrum Cycle";
ColorCycle.value = AURA_MOUSE_MODE_SPECTRUM;
ColorCycle.flags = 0;
ColorCycle.color_mode = MODE_COLORS_NONE;
modes.push_back(ColorCycle);
}
break;
case AURA_MOUSE_MODE_WAVE:
{
mode Wave;
Wave.name = "Wave";
Wave.value = AURA_MOUSE_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR;
Wave.direction = 0;
Wave.speed_min = aura_mouse_devices[pid].speed_min;
Wave.speed_max = aura_mouse_devices[pid].speed_max;
Wave.speed = 128;
Wave.color_mode = MODE_COLORS_NONE;
modes.push_back(Wave);
}
break;
case AURA_MOUSE_MODE_REACTIVE:
{
mode Reactive;
Reactive.name = "Reactive";
Reactive.value = AURA_MOUSE_MODE_REACTIVE;
Reactive.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Reactive.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Reactive);
}
break;
case AURA_MOUSE_MODE_COMET:
{
mode Comet;
Comet.name = "Comet";
Comet.value = AURA_MOUSE_MODE_COMET;
Comet.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_DIRECTION_LR;
Comet.color_mode = MODE_COLORS_MODE_SPECIFIC;
Comet.direction = 0;
Comet.colors_min = 1;
Comet.colors_max = 1;
Comet.colors.resize(1);
modes.push_back(Comet);
}
break;
case AURA_MOUSE_MODE_BATTERY:
{
mode BatteryMode;
BatteryMode.name = "Battery";
BatteryMode.value = AURA_MOUSE_MODE_BATTERY;
BatteryMode.flags = 0;
BatteryMode.color_mode = MODE_COLORS_NONE;
modes.push_back(BatteryMode);
}
break;
}
}
SetupZones();
}
@@ -58,56 +131,29 @@ RGBController_AuraMouse::~RGBController_AuraMouse()
void RGBController_AuraMouse::SetupZones()
{
zone logo_zone;
logo_zone.name = "Logo";
logo_zone.type = ZONE_TYPE_SINGLE;
logo_zone.leds_min = 1;
logo_zone.leds_max = 1;
logo_zone.leds_count = 1;
logo_zone.matrix_map = NULL;
uint16_t pid = aura->device_pid;
zones.push_back(logo_zone);
for(std::vector<uint8_t>::iterator zone_it = aura_mouse_devices[pid].mouse_zones.begin(); zone_it != aura_mouse_devices[pid].mouse_zones.end(); zone_it++)
{
zone mouse_zone;
led logo_led;
mouse_zone.name = aura_mouse_zone_names[*zone_it];
mouse_zone.type = ZONE_TYPE_SINGLE;
mouse_zone.leds_min = 1;
mouse_zone.leds_max = 1;
mouse_zone.leds_count = 1;
mouse_zone.matrix_map = NULL;
logo_led.name = "Logo";
zones.push_back(mouse_zone);
leds.push_back(logo_led);
led mouse_led;
zone scroll_zone;
mouse_led.name = mouse_zone.name + " LED";
mouse_led.value = *zone_it;
scroll_zone.name = "Scroll Wheel";
scroll_zone.type = ZONE_TYPE_SINGLE;
scroll_zone.leds_min = 1;
scroll_zone.leds_max = 1;
scroll_zone.leds_count = 1;
scroll_zone.matrix_map = NULL;
zones.push_back(scroll_zone);
led scroll_led;
scroll_led.name = "Scroll Wheel";
leds.push_back(scroll_led);
zone underglow_zone;
underglow_zone.name = "Underglow";
underglow_zone.type = ZONE_TYPE_SINGLE;
underglow_zone.leds_min = 1;
underglow_zone.leds_max = 1;
underglow_zone.leds_count = 1;
underglow_zone.matrix_map = NULL;
zones.push_back(underglow_zone);
led underglow_led;
underglow_led.name = "Underglow";
leds.push_back(underglow_led);
leds.push_back(mouse_led);
}
SetupColors();
}
@@ -119,7 +165,10 @@ void RGBController_AuraMouse::ResizeZone(int /*zone*/, int /*new_size*/)
void RGBController_AuraMouse::DeviceUpdateLEDs()
{
DeviceUpdateMode();
for(std::vector<led>::iterator led_it = leds.begin(); led_it != leds.end(); led_it++)
{
UpdateSingleLED(led_it->value);
}
}
void RGBController_AuraMouse::UpdateZoneLEDs(int zone)
@@ -129,41 +178,11 @@ void RGBController_AuraMouse::UpdateZoneLEDs(int zone)
void RGBController_AuraMouse::UpdateSingleLED(int led)
{
unsigned char red = 0;
unsigned char grn = 0;
unsigned char blu = 0;
uint8_t red = RGBGetRValue(colors[led]);
uint8_t grn = RGBGetGValue(colors[led]);
uint8_t blu = RGBGetBValue(colors[led]);
if(modes[active_mode].color_mode == MODE_COLORS_PER_LED)
{
if(led == 0)
{
red = RGBGetRValue(colors[led]);
grn = RGBGetGValue(colors[led]);
blu = RGBGetBValue(colors[led]);
aura->SendUpdate(AURA_MOUSE_ZONE_LOGO, modes[active_mode].value, red, grn, blu);
}
else if(led == 1)
{
red = RGBGetRValue(colors[led]);
grn = RGBGetGValue(colors[led]);
blu = RGBGetBValue(colors[led]);
aura->SendUpdate(AURA_MOUSE_ZONE_SCROLL, modes[active_mode].value, red, grn, blu);
}
else
{
red = RGBGetRValue(colors[led]);
grn = RGBGetGValue(colors[led]);
blu = RGBGetBValue(colors[led]);
aura->SendUpdate(AURA_MOUSE_ZONE_UNDERGLOW, modes[active_mode].value, red, grn, blu);
}
}
else
{
aura->SendUpdate(AURA_MOUSE_ZONE_ALL, modes[active_mode].value, red, grn, blu);
}
aura->SendUpdate(leds[led].value, active_mode, red, grn, blu, 0, false, 0);
}
void RGBController_AuraMouse::SetCustomMode()
@@ -173,32 +192,24 @@ void RGBController_AuraMouse::SetCustomMode()
void RGBController_AuraMouse::DeviceUpdateMode()
{
unsigned char red = 0;
unsigned char grn = 0;
unsigned char blu = 0;
if(modes[active_mode].color_mode == MODE_COLORS_PER_LED)
{
red = RGBGetRValue(colors[0]);
grn = RGBGetGValue(colors[0]);
blu = RGBGetBValue(colors[0]);
aura->SendUpdate(AURA_MOUSE_ZONE_LOGO, modes[active_mode].value, red, grn, blu);
red = RGBGetRValue(colors[1]);
grn = RGBGetGValue(colors[1]);
blu = RGBGetBValue(colors[1]);
aura->SendUpdate(AURA_MOUSE_ZONE_SCROLL, modes[active_mode].value, red, grn, blu);
red = RGBGetRValue(colors[2]);
grn = RGBGetGValue(colors[2]);
blu = RGBGetBValue(colors[2]);
aura->SendUpdate(AURA_MOUSE_ZONE_UNDERGLOW, modes[active_mode].value, red, grn, blu);
DeviceUpdateLEDs();
}
else
{
aura->SendUpdate(AURA_MOUSE_ZONE_ALL, modes[active_mode].value, red, grn, blu);
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]);
}
aura->SendUpdate(AURA_MOUSE_ZONE_ALL, active_mode, red, grn, blu, modes[active_mode].direction, modes[active_mode].color_mode == MODE_COLORS_RANDOM, modes[active_mode].speed);
aura->SaveMode();
}
}
@@ -0,0 +1,470 @@
/*-----------------------------------------*\
| RGBController_AsusAuraTUFKeyboard.cpp |
| |
| Generic RGB Interface for Asus Aura |
| USB controller driver |
| |
| Mola19 03/03/2020 |
\*-----------------------------------------*/
#include "RGBController_AsusAuraTUFKeyboard.h"
#include <vector>
#define NA 0xFFFFFFFF
static unsigned int matrix_map[6][23] =
{ { 0, NA, 18, 24, 30, 36, NA, 48, 54, 60, 66, 72, 78, 84, 90, NA, 96, 102, 108, NA, NA, NA, NA },
{ 1, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 91, NA, NA, 97, 103, 109, 115, 121, 127, 133 },
{ 2, NA, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80, NA, NA, 98, 104, 110, 116, 122, 128, 134 },
{ 3, NA, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 93, NA, NA, NA, NA, 117, 123, 129, NA },
{ 4, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70, NA, 94, NA, NA, NA, 106, NA, 118, 124, 130, 136 },
{ 5, 11, 17, NA, NA, NA, 41, NA, NA, NA, 59, 71, 77, NA, 95, NA, 101, 107, 113, 119, NA, 131, NA } };
static const char* zone_names[] =
{
"Keyboard"
};
static zone_type zone_types[] =
{
ZONE_TYPE_MATRIX,
};
static const unsigned int zone_sizes[] =
{
138
};
static const char *led_names[] =
{
"Key: Escape",
"Key: ^",
"Key: Tab",
"Key: Caps Lock",
"Key: Left Shift",
"Key: Left Control",
"Unused",
"Unused",
"Unused",
"Unused",
"Key: <",
"Key: Left Windows",
"Unused",
"Key: 1",
"Key: Q",
"Key: A",
"Key: Y",
"Key: Left Alt",
"Key: F1",
"Key: 2",
"Key: W",
"Key: S",
"Key: X",
"Unused",
"Key: F2",
"Key: 3",
"Key: E",
"Key: D",
"Key: C",
"Unused",
"Key: F3",
"Key: 4",
"Key: R",
"Key: F",
"Key: V",
"Unused",
"Key: F4",
"Key: 5",
"Key: T",
"Key: G",
"Key: B",
"Key: Space",
"Unused",
"Key: 6",
"Key: Z",
"Key: H",
"Key: N",
"Unused",
"Key: F5",
"Key: 7",
"Key: U",
"Key: J",
"Key: M",
"Unused",
"Key: F6",
"Key: 8",
"Key: I",
"Key: K",
"Key: ,",
"Key: Right Alt",
"Key: F7",
"Key: 9",
"Key: O",
"Key: L",
"Key: .",
"Unused",
"Key: F8",
"Key: 0",
"Key: P",
"Key: Ö",
"Key: -",
"Key: Right Fn",
"Key: F9",
"Key: ß",
"Key: Ü",
"Key: Ä",
"Unused",
"Key: Menu",
"Key: F10",
"Key: ´",
"Key: +",
"Key: #",
"Unused",
"Unused",
"Key: F11",
"Unused",
"Unused",
"Unused",
"Unused",
"Unused",
"Key: F12",
"Key: Backspace",
"Unused",
"Key: Enter",
"Key: Right Shift",
"Key: Right Control",
"Key: Print Screen",
"Key: Insert",
"Key: Delete",
"Unused",
"Unused",
"Key: Left Arrow",
"Key: Scroll Lock",
"Key: Home",
"Key: End",
"Unused",
"Key: Up Arrow",
"Key: Down Arrow",
"Key: Pause/Break",
"Key: Page Up",
"Key: Page Down",
"Unused",
"Unused",
"Key: Right Arrow",
"Unused",
"Key: Num Lock",
"Key: Number Pad 7",
"Key: Number Pad 4",
"Key: Number Pad 1",
"Key: Number Pad 0",
"Unused",
"Key: Number Pad /",
"Key: Number Pad 8",
"Key: Number Pad 5",
"Key: Number Pad 2",
"Unused",
"Unused",
"Key: Number Pad *",
"Key: Number Pad 9",
"Key: Number Pad 6",
"Key: Number Pad 3",
"Key: Number Pad ,",
"Unused",
"Key: Number Pad -",
"Key: Number Pad +",
"Unused",
"Key: Number Pad Enter",
"Unused",
};
RGBController_AuraTUFKeyboard::RGBController_AuraTUFKeyboard(AuraTUFKeyboardController* aura_ptr)
{
aura = aura_ptr;
name = "ASUS Aura Keyboard";
vendor = "ASUS";
type = DEVICE_TYPE_KEYBOARD;
description = "ASUS Aura Keyboard Device";
location = aura->GetDeviceLocation();
serial = aura->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = AURA_KEYBOARD_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 = AURA_KEYBOARD_MODE_STATIC;
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 = AURA_KEYBOARD_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.speed_min = 0;
Breathing.speed_max = 15;
Breathing.speed = 8;
Breathing.colors_min = 1;
Breathing.colors_max = 2;
Breathing.colors.resize(1);
modes.push_back(Breathing);
mode Color_Cycle;
Color_Cycle.name = "Color Cycle";
Color_Cycle.value = AURA_KEYBOARD_MODE_COLOR_CYCLE;
Color_Cycle.flags = MODE_FLAG_HAS_SPEED;
Color_Cycle.color_mode = MODE_COLORS_NONE;
Color_Cycle.speed_min = 0;
Color_Cycle.speed_max = 15;
Color_Cycle.speed = 8;
modes.push_back(Color_Cycle);
mode Wave;
Wave.name = "Wave";
Wave.value = AURA_KEYBOARD_MODE_WAVE;
Wave.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_DIRECTION_HV;
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
Wave.speed_min = 0;
Wave.speed_max = 15;
Wave.speed = 8;
Wave.direction = MODE_DIRECTION_LEFT;
Wave.colors_min = 1;
Wave.colors_max = 7;
Wave.colors.resize(7);
modes.push_back(Wave);
mode Ripple;
Ripple.name = "Ripple";
Ripple.value = AURA_KEYBOARD_MODE_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 = 0;
Ripple.speed_max = 15;
Ripple.speed = 8;
Ripple.colors_min = 1;
Ripple.colors_max = 8;
Ripple.colors.resize(7);
modes.push_back(Ripple);
mode Reactive;
Reactive.name = "Reactive";
Reactive.value = AURA_KEYBOARD_MODE_REACTIVE;
Reactive.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED;
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
Reactive.speed_min = 0;
Reactive.speed_max = 15;
Reactive.speed = 8;
Reactive.colors_min = 1;
Reactive.colors_max = 2;
Reactive.colors.resize(1);
modes.push_back(Reactive);
mode Starry_Night;
Starry_Night.name = "Starry Night";
Starry_Night.value = AURA_KEYBOARD_MODE_STARRY_NIGHT;
Starry_Night.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED;
Starry_Night.color_mode = MODE_COLORS_MODE_SPECIFIC;
Starry_Night.speed_min = 0;
Starry_Night.speed_max = 15;
Starry_Night.speed = 8;
Starry_Night.colors_min = 1;
Starry_Night.colors_max = 3;
Starry_Night.colors.resize(1);
modes.push_back(Starry_Night);
mode Quicksand;
Quicksand.name = "Quicksand";
Quicksand.value = AURA_KEYBOARD_MODE_QUICKSAND;
Quicksand.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_UD;
Quicksand.color_mode = MODE_COLORS_MODE_SPECIFIC;
Quicksand.direction = MODE_DIRECTION_DOWN;
Quicksand.speed_min = 0;
Quicksand.speed_max = 15;
Quicksand.speed = 8;
Quicksand.colors_min = 6;
Quicksand.colors_max = 6;
Quicksand.colors.resize(6);
modes.push_back(Quicksand);
mode Current;
Current.name = "Current";
Current.value = AURA_KEYBOARD_MODE_CURRENT;
Current.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED;
Current.color_mode = MODE_COLORS_MODE_SPECIFIC;
Current.speed_min = 0;
Current.speed_max = 15;
Current.speed = 8;
Current.colors_min = 1;
Current.colors_max = 3;
Current.colors.resize(1);
modes.push_back(Current);
mode Rain_Drop;
Rain_Drop.name = "Rain Drop";
Rain_Drop.value = AURA_KEYBOARD_MODE_RAIN_DROP;
Rain_Drop.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED;
Rain_Drop.color_mode = MODE_COLORS_MODE_SPECIFIC;
Rain_Drop.speed_min = 0;
Rain_Drop.speed_max = 15;
Rain_Drop.speed = 8;
Rain_Drop.colors_min = 1;
Rain_Drop.colors_max = 3;
Rain_Drop.colors.resize(1);
modes.push_back(Rain_Drop);
SetupZones();
}
RGBController_AuraTUFKeyboard::~RGBController_AuraTUFKeyboard()
{
delete aura;
}
void RGBController_AuraTUFKeyboard::SetupZones()
{
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];
new_zone.matrix_map = new matrix_map_type;
new_zone.matrix_map->height = 6;
new_zone.matrix_map->width = 23;
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
zones.push_back(new_zone);
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];
leds.push_back(new_led);
}
SetupColors();
}
void RGBController_AuraTUFKeyboard::ResizeZone(int /*zone*/, int /*new_size*/)
{
}
void RGBController_AuraTUFKeyboard::DeviceUpdateLEDs()
{
DeviceUpdateMode();
}
void RGBController_AuraTUFKeyboard::UpdateZoneLEDs(int /*zone*/)
{
aura->UpdateLeds(colors);
}
void RGBController_AuraTUFKeyboard::UpdateSingleLED(int led)
{
unsigned char red = RGBGetRValue(colors[led]);
unsigned char green = RGBGetGValue(colors[led]);
unsigned char blue = RGBGetBValue(colors[led]);
aura->UpdateSingleLed(led, red, green, blue);
}
void RGBController_AuraTUFKeyboard::SetCustomMode()
{
active_mode = 0;
}
void RGBController_AuraTUFKeyboard::DeviceUpdateMode()
{
unsigned char color_mode;
std::vector<RGBColor> mode_colors;
if(modes[active_mode].value == AURA_KEYBOARD_MODE_DIRECT)
{
aura->UpdateLeds(colors);
}
else
{
bool mode_with_double = (modes[active_mode].value == 1 || modes[active_mode].value == 3 || modes[active_mode].value == 6 || modes[active_mode].value == 8 || modes[active_mode].value == 9);
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC && mode_with_double && modes[active_mode].colors.size() > 1)
{
if(modes[active_mode].colors[1] == 000)
{
color_mode = 0;
}
else
{
color_mode = 16;
}
}
else
{
color_mode = modes[active_mode].color_mode == MODE_COLORS_RANDOM ? 1 : 0;
}
int direction = 0;
switch (modes[active_mode].direction)
{
case MODE_DIRECTION_LEFT:
direction = 0;
break;
case MODE_DIRECTION_RIGHT:
direction = 4;
break;
case MODE_DIRECTION_UP:
direction = 6;
break;
case MODE_DIRECTION_DOWN:
direction = 2;
break;
case MODE_DIRECTION_HORIZONTAL:
direction = 8;
break;
case MODE_DIRECTION_VERTICAL:
direction = 1;
break;
}
mode_colors = modes[active_mode].color_mode == MODE_COLORS_PER_LED ? std::vector<RGBColor>(colors) : std::vector<RGBColor>(modes[active_mode].colors);
aura->UpdateDevice(modes[active_mode].value, mode_colors, direction, color_mode, (15 - modes[active_mode].speed));
}
}
@@ -0,0 +1,33 @@
/*-----------------------------------------*\
| RGBController_AsusAuraTUFKeyboard.h |
| |
| Generic RGB Interface for Asus Aura |
| USB controller driver |
| |
| Mola19 03/03/2021 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "AsusAuraTUFKeyboardController.h"
class RGBController_AuraTUFKeyboard : public RGBController
{
public:
RGBController_AuraTUFKeyboard(AuraTUFKeyboardController* aura_ptr);
~RGBController_AuraTUFKeyboard();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
AuraTUFKeyboardController* aura;
};
@@ -159,13 +159,24 @@ void RGBController_AuraUSB::SetupZones()
}
}
unsigned int num_mainboard_leds = device_info.num_leds - device_info.num_headers;
for (unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
{
unsigned led_idx = led_ch_idx + 1;
led new_led;
new_led.name = zones[channel_idx].name;
new_led.name.append(", LED ");
new_led.name.append(std::to_string(led_ch_idx + 1));
if(device_info.device_type == AuraDeviceType::FIXED && led_ch_idx >= num_mainboard_leds)
{
new_led.name.append(", RGB Header ");
led_idx -= num_mainboard_leds;
}
else
{
new_led.name.append(", LED ");
}
new_led.name.append(std::to_string(led_idx));
new_led.value = channel_idx;
leds.push_back(new_led);
@@ -0,0 +1,104 @@
/*---------------------------------------------------------*\
| BlinkyTapeController.cpp |
| |
| BlinkyTape controller interface |
| |
| Matt Mets (matt@blinkinlabs.com), 07/01/2021 |
\*---------------------------------------------------------*/
#include "BlinkyTapeController.h"
#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>
#ifndef WIN32
#define LPSTR char *
#define strtok_s strtok_r
#endif
BlinkyTapeController::BlinkyTapeController()
{
}
BlinkyTapeController::~BlinkyTapeController()
{
if(serialport != nullptr)
{
serialport->serial_close();
delete serialport;
}
}
void BlinkyTapeController::Initialize(const std::string &portname)
{
port_name = portname;
serialport = new serial_port();
if(!serialport->serial_open(port_name.c_str(), 115200))
{
delete serialport;
serialport = nullptr;
}
}
std::string BlinkyTapeController::GetLocation()
{
if(serialport == nullptr)
{
return("");
}
return("COM: " + port_name);
}
char* BlinkyTapeController::GetLEDString()
{
return(led_string);
}
void BlinkyTapeController::SetLEDs(std::vector<RGBColor> colors)
{
if(serialport == nullptr)
{
return;
}
/*-------------------------------------------------------------*\
| BlinkyTape Protocol |
| |
| Packet size: Number of data bytes + 1 |
| |
| 0-n: Data Byte (0-254) |
| n+1: Packet End Byte (0xFF) |
\*-------------------------------------------------------------*/
const unsigned int payload_size = (colors.size() * 3);
const unsigned int packet_size = payload_size + 1;
std::vector<unsigned char> serial_buf(packet_size);
/*-------------------------------------------------------------*\
| Set up end byte |
\*-------------------------------------------------------------*/
serial_buf[packet_size - 1] = 0xFF;
/*-------------------------------------------------------------*\
| Copy in color data in RGB order |
\*-------------------------------------------------------------*/
for(unsigned int color_idx = 0; color_idx < colors.size(); color_idx++)
{
const unsigned int color_offset = color_idx * 3;
serial_buf[0x00 + color_offset] = std::min((unsigned int)254, RGBGetRValue(colors[color_idx]));
serial_buf[0x01 + color_offset] = std::min((unsigned int)254, RGBGetGValue(colors[color_idx]));
serial_buf[0x02 + color_offset] = std::min((unsigned int)254, RGBGetBValue(colors[color_idx]));
}
/*-------------------------------------------------------------*\
| Send the packet |
\*-------------------------------------------------------------*/
serialport->serial_write((char *)serial_buf.data(), packet_size);
}
@@ -0,0 +1,38 @@
/*---------------------------------------------------------*\
| Definitions for BlinkyTape Interface |
| |
| Matt Mets (matt@blinkinlabs.com), 07/01/2021 |
\*---------------------------------------------------------*/
#ifndef BLINKYTAPE_H
#define BLINKYTAPE_H
#include "RGBController.h"
#include "serial_port.h"
struct BlinkyTapeDevice
{
std::string port;
unsigned int num_leds;
};
class BlinkyTapeController
{
public:
BlinkyTapeController();
~BlinkyTapeController();
void Initialize(const std::string &portname);
char* GetLEDString();
std::string GetLocation();
void SetLEDs(std::vector<RGBColor> colors);
private:
char led_string[1024];
std::string port_name;
serial_port *serialport = nullptr;
};
#endif
@@ -0,0 +1,36 @@
#include "Detector.h"
#include "BlinkyTapeController.h"
#include "RGBController.h"
#include "RGBController_BlinkyTape.h"
#include "SettingsManager.h"
#include "find_usb_serial_port.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#define BLINKINLABS_VID 0x1D50
#define BLINKYTAPE_PID 0x605E
/******************************************************************************************\
* *
* DetectBlinkyTapeControllers *
* *
* Detect BlinkyTape devices *
* *
\******************************************************************************************/
void DetectBlinkyTapeControllers(std::vector<RGBController*> &rgb_controllers)
{
std::vector<std::string *> device_locations = find_usb_serial_port(BLINKINLABS_VID, BLINKYTAPE_PID);
for(unsigned int device_idx = 0; device_idx < device_locations.size(); device_idx++)
{
BlinkyTapeController* controller = new BlinkyTapeController();
controller->Initialize(*device_locations[device_idx]);
RGBController_BlinkyTape* rgb_controller = new RGBController_BlinkyTape(controller);
rgb_controllers.push_back(rgb_controller);
}
}
REGISTER_DETECTOR("BlinkyTape", DetectBlinkyTapeControllers);
@@ -0,0 +1,137 @@
/*---------------------------------------------------------*\
| RGBController_BlinkyTape.cpp |
| |
| Generic RGB Interface for BlinkyTape Led controller |
| |
| Matt Mets (matt@blinkinlabs.com), 07/01/2021 |
\*---------------------------------------------------------*/
#include "RGBController_BlinkyTape.h"
RGBController_BlinkyTape::RGBController_BlinkyTape(BlinkyTapeController* controller_ptr)
{
controller = controller_ptr;
name = "BlinkyTape";
vendor = "Blinkinlabs";
type = DEVICE_TYPE_LEDSTRIP;
description = "BlinkyTape Controller Device";
location = controller->GetLocation();
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_BlinkyTape::~RGBController_BlinkyTape()
{
delete controller;
}
void RGBController_BlinkyTape::SetupZones()
{
zones.clear();
leds.clear();
zone led_zone;
led_zone.name = "LED Strip";
led_zone.type = ZONE_TYPE_LINEAR;
led_zone.leds_min = 0;
led_zone.leds_max = 512;
led_zone.leds_count = 0;
led_zone.matrix_map = NULL;
zones.push_back(led_zone);
ResizeZone(0, led_zone.leds_count);
}
void RGBController_BlinkyTape::ResizeZone(int zone, int new_size)
{
/*-------------------------------------------------*\
| Explicitly cast these to avoid compiler warnings |
\*-------------------------------------------------*/
const unsigned int zone_u = static_cast<unsigned int>(zone);
const unsigned int new_size_u = static_cast<unsigned int>(new_size);
/*-------------------------------------------------*\
| Check that the zone is in bounds |
\*-------------------------------------------------*/
if((zone_u > zones.size()) || (zone < 0))
{
return;
}
/*-------------------------------------------------*\
| And that the new size is in bounds |
\*-------------------------------------------------*/
if((new_size_u > zones.at(zone).leds_max) || (new_size_u < zones.at(zone).leds_min))
{
return;
}
/*-------------------------------------------------*\
| And that there's actually a change |
\*-------------------------------------------------*/
if(zones.at(zone).leds_count == new_size_u)
{
return;
}
/*-------------------------------------------------*\
| If the new size is less than the current size, |
| just chop off the end |
\*-------------------------------------------------*/
if(leds.size() > new_size_u)
{
leds.resize(new_size);
}
/*-------------------------------------------------*\
| Otherwise, add new LEDs to the end |
\*-------------------------------------------------*/
if(leds.size() < new_size_u)
{
for(size_t led_idx = leds.size(); led_idx < new_size_u; led_idx++)
{
led new_led;
new_led.name = "LED ";
new_led.name.append(std::to_string(led_idx));
leds.push_back(new_led);
}
}
zones.at(zone).leds_count = new_size;
SetupColors();
}
void RGBController_BlinkyTape::DeviceUpdateLEDs()
{
controller->SetLEDs(colors);
}
void RGBController_BlinkyTape::UpdateZoneLEDs(int /*zone*/)
{
controller->SetLEDs(colors);
}
void RGBController_BlinkyTape::UpdateSingleLED(int /*led*/)
{
controller->SetLEDs(colors);
}
void RGBController_BlinkyTape::SetCustomMode()
{
}
void RGBController_BlinkyTape::DeviceUpdateMode()
{
}
@@ -0,0 +1,33 @@
/*---------------------------------------------------------*\
| RGBController_BlinkyTape.h |
| |
| Generic RGB Interface for BlinkyTape Led controller |
| |
| Matt Mets (matt@blinkinlabs.com), 07/01/2021 |
\*---------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "serial_port.h"
#include "BlinkyTapeController.h"
class RGBController_BlinkyTape : public RGBController
{
public:
RGBController_BlinkyTape(BlinkyTapeController* controller_ptr);
~RGBController_BlinkyTape();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
BlinkyTapeController* controller;
};
@@ -204,7 +204,7 @@ void CMARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_cou
/*---------------------------------------------*\
| Set up the RGB triplets to send |
\*---------------------------------------------*/
for(int i = 0; i < led_count; i++)
for(unsigned int i = 0; i < led_count; i++)
{
RGBColor colour = led_colours[i];
@@ -0,0 +1,202 @@
/*-------------------------------------------------------------------*\
| CMMKController.cpp |
| |
| Driver for Coolermaster MasterKeys Keyboards |
| |
| Lukas N (chmod222) 28th Jun 2020 |
| Tam D (too.manyhobbies) 25th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
#include "CMMKController.h"
CMMKController::CMMKController(hid_device* dev, hid_device_info* dev_info)
{
location = dev_info->path;
const int szTemp = 256;
wchar_t tmpName[szTemp];
hid_get_manufacturer_string(dev, tmpName, szTemp);
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 = 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;
}
CMMKController::~CMMKController()
{
cmmk_detach(&cmmk_handle);
}
std::string CMMKController::GetDeviceName()
{
return device_name;
}
std::string CMMKController::GetDeviceVendor()
{
return vendor_name;
}
std::string CMMKController::GetLocation()
{
return location;
}
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);
}
void CMMKController::SetManualControl()
{
ActivateMode(CMMK_MANUAL);
}
void CMMKController::SetSingle(int row, int col, struct rgb color)
{
cmmk_set_single_key(&cmmk_handle, row, col, &color);
}
void CMMKController::SetAll(struct cmmk_color_matrix const& colors)
{
cmmk_set_leds(&cmmk_handle, &colors);
}
void CMMKController::SetAllSingle(struct rgb color)
{
cmmk_set_all_single(&cmmk_handle, &color);
}
void CMMKController::SetMode(cmmk_effect_fully_lit eff)
{
ActivateEffect(CMMK_EFFECT_FULLY_LIT);
cmmk_set_effect_fully_lit(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_breathe eff)
{
ActivateEffect(CMMK_EFFECT_BREATHE);
cmmk_set_effect_breathe(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_cycle eff)
{
ActivateEffect(CMMK_EFFECT_CYCLE);
cmmk_set_effect_cycle(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_single eff)
{
ActivateEffect(CMMK_EFFECT_SINGLE);
cmmk_set_effect_single(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_wave eff)
{
ActivateEffect(CMMK_EFFECT_WAVE);
cmmk_set_effect_wave(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_ripple eff)
{
ActivateEffect(CMMK_EFFECT_RIPPLE);
cmmk_set_effect_ripple(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_cross eff)
{
ActivateEffect(CMMK_EFFECT_CROSS);
cmmk_set_effect_cross(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_raindrops eff)
{
ActivateEffect(CMMK_EFFECT_RAINDROPS);
cmmk_set_effect_raindrops(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_stars eff)
{
ActivateEffect(CMMK_EFFECT_STARS);
cmmk_set_effect_stars(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_snake eff)
{
ActivateEffect(CMMK_EFFECT_SNAKE);
cmmk_set_effect_snake(&cmmk_handle, &eff);
}
bool CMMKController::PositionValid(int y, int x)
{
return(cmmk_lookup_key_id(&cmmk_handle, y, x) >= 0);
}
void CMMKController::ActivateMode(int mode)
{
if (current_mode != mode)
{
cmmk_set_control_mode(&cmmk_handle, mode);
current_mode = mode;
current_effect = -1;
}
}
void CMMKController::ActivateEffect(int effect)
{
ActivateMode(CMMK_EFFECT);
if (current_effect != effect)
{
cmmk_set_active_effect(&cmmk_handle, (enum cmmk_effect_id)effect);
current_effect = effect;
}
}
@@ -0,0 +1,64 @@
/*-------------------------------------------------------------------*\
| CMMKController.h |
| |
| Driver for Coolermaster MasterKeys keyboards |
| |
| Lukas N (chmod222) 28th Jun 2020 |
| |
\*-------------------------------------------------------------------*/
#include <string>
#include <hidapi/hidapi.h>
#include <libcmmk/libcmmk.h>
#pragma once
class CMMKController
{
public:
CMMKController(hid_device* dev_handle, hid_device_info* dev_info);
~CMMKController();
std::string GetDeviceName();
std::string GetDeviceVendor();
std::string GetLocation();
std::string GetFirmwareVersion();
uint8_t GetRowCount();
uint8_t GetColumnCount();
void SetFirmwareControl();
void SetManualControl();
void SetSingle(int row, int col, struct rgb color);
void SetAll(struct cmmk_color_matrix const& colors);
void SetAllSingle(struct rgb color);
void SetMode(cmmk_effect_fully_lit eff);
void SetMode(cmmk_effect_breathe eff);
void SetMode(cmmk_effect_cycle eff);
void SetMode(cmmk_effect_single eff);
void SetMode(cmmk_effect_wave eff);
void SetMode(cmmk_effect_ripple eff);
void SetMode(cmmk_effect_cross eff);
void SetMode(cmmk_effect_raindrops eff);
void SetMode(cmmk_effect_stars eff);
void SetMode(cmmk_effect_snake eff);
bool PositionValid(int y, int x);
private:
void ActivateMode(int mode);
void ActivateEffect(int effect);
int current_mode = -1;
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;
};
@@ -0,0 +1,180 @@
/*-------------------------------------------------------------------*\
| CMMM711Controller.cpp |
| |
| Driver for Coolermaster Master Mouse 711 |
| |
| Chris M (Dr_No) 14th Feb 2021 |
| |
\*-------------------------------------------------------------------*/
#include "CMMM711Controller.h"
#include <cstring>
CMMM711Controller::CMMM711Controller(hid_device* dev_handle, char *_path)
{
const int szTemp = HID_MAX_STR;
wchar_t tmpName[szTemp];
dev = dev_handle;
location = _path;
current_speed = CM_MM711_SPEED_NORMAL;
hid_get_manufacturer_string(dev, tmpName, szTemp);
std::wstring wName = std::wstring(tmpName);
device_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()));
hid_get_indexed_string(dev, 2, tmpName, szTemp);
wName = std::wstring(tmpName);
serial = std::string(wName.begin(), wName.end());
SendInitPacket();
GetColourStatus();
GetCustomStatus();
GetModeStatus();
}
CMMM711Controller::~CMMM711Controller()
{
hid_close(dev);
}
void CMMM711Controller::GetColourStatus()
{
uint8_t buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x52, 0x2B };
hid_write(dev, buffer, CM_MM711_PACKET_SIZE);
hid_read_timeout(dev, buffer, CM_MM711_PACKET_SIZE, CM_MM711_INTERRUPT_TIMEOUT);
current_brightness = buffer[CM_MM711_BRIGHTNESS_BYTE - 1];
current_red = buffer[CM_MM711_RED_BYTE - 1];
current_green = buffer[CM_MM711_GREEN_BYTE - 1];
current_blue = buffer[CM_MM711_BLUE_BYTE - 1];
}
void CMMM711Controller::GetCustomStatus()
{
uint8_t buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x52, 0xA8 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_MM711_INTERRUPT_TIMEOUT);
wheel_colour = ToRGBColor(buffer[4], buffer[5], buffer[6]);
logo_colour = ToRGBColor(buffer[7], buffer[8], buffer[9]);
}
void CMMM711Controller::GetModeStatus()
{
uint8_t buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x52, 0x28 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_MM711_INTERRUPT_TIMEOUT);
current_mode = buffer[CM_MM711_MODE_BYTE - 1];
}
std::string CMMM711Controller::GetDeviceName()
{
return device_name;
}
std::string CMMM711Controller::GetSerial()
{
return serial;
}
std::string CMMM711Controller::GetLocation()
{
return("HID: " + location);
}
unsigned char CMMM711Controller::GetMode()
{
return current_mode;
}
unsigned char CMMM711Controller::GetLedRed()
{
return current_red;
}
unsigned char CMMM711Controller::GetLedGreen()
{
return current_green;
}
unsigned char CMMM711Controller::GetLedBlue()
{
return current_blue;
}
unsigned char CMMM711Controller::GetLedSpeed()
{
return current_speed;
}
RGBColor CMMM711Controller::GetWheelColour()
{
return wheel_colour;
}
RGBColor CMMM711Controller::GetLogoColour()
{
return logo_colour;
}
void CMMM711Controller::SetLedsDirect(RGBColor wheel_colour, RGBColor logo_colour)
{
unsigned char buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x51, 0xA8, 0x00, 0x00 };
buffer[CM_MM711_MODE_BYTE] = RGBGetRValue(wheel_colour);
buffer[CM_MM711_SPEED_BYTE] = RGBGetGValue(wheel_colour);
buffer[CM_MM711_NFI_1] = RGBGetBValue(wheel_colour);
buffer[CM_MM711_NFI_2] = RGBGetRValue(logo_colour);
buffer[CM_MM711_NFI_3] = RGBGetGValue(logo_colour);
buffer[CM_MM711_BRIGHTNESS_BYTE] = RGBGetBValue(logo_colour);
hid_write(dev, buffer, CM_MM711_PACKET_SIZE);
SendApplyPacket(0xB0); //Apply custom mode
}
void CMMM711Controller::SendUpdate(uint8_t mode, uint8_t speed, RGBColor colour, uint8_t brightness)
{
unsigned char buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x51, 0x2B, 0x00, 0x00 };
buffer[CM_MM711_MODE_BYTE] = mode;
buffer[CM_MM711_SPEED_BYTE] = speed;
buffer[CM_MM711_NFI_1] = 0x20;
buffer[CM_MM711_NFI_2] = 0xFF;
buffer[CM_MM711_NFI_3] = 0xFF;
buffer[CM_MM711_BRIGHTNESS_BYTE] = brightness;
buffer[CM_MM711_RED_BYTE] = RGBGetRValue(colour);
buffer[CM_MM711_GREEN_BYTE] = RGBGetGValue(colour);
buffer[CM_MM711_BLUE_BYTE] = RGBGetBValue(colour);
hid_write(dev, buffer, CM_MM711_PACKET_SIZE);
SendApplyPacket(mode);
}
void CMMM711Controller::SendInitPacket()
{
unsigned char buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x41, 0x80 };
hid_write(dev, buffer, CM_MM711_PACKET_SIZE);
}
void CMMM711Controller::SendApplyPacket(uint8_t mode)
{
unsigned char buffer[CM_MM711_PACKET_SIZE] = { 0x00, 0x51, 0x28, 0x00, 0x00 };
buffer[CM_MM711_MODE_BYTE] = mode;
hid_write(dev, buffer, CM_MM711_PACKET_SIZE);
}
@@ -0,0 +1,100 @@
/*-------------------------------------------------------------------*\
| CMMM711Controller.h |
| |
| Driver for Coolermaster Master Mouse 711 |
| |
| Chris M (Dr_No) 14th Feb 2021 |
| |
\*-------------------------------------------------------------------*/
#include <string>
#include <array>
#include <hidapi/hidapi.h>
#include "RGBController.h"
#pragma once
#define CM_MM711_PACKET_SIZE 65
#define CM_MM711_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
#define CM_MM711_HEADER_DATA_SIZE (sizeof(argb_header_data) / sizeof(argb_headers) )
#define CM_MM711_INTERRUPT_TIMEOUT 250
#define CM_MM711_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
#define HID_MAX_STR 255
enum
{
CM_MM711_REPORT_BYTE = 1,
CM_MM711_COMMAND_BYTE = 2,
CM_MM711_FUNCTION_BYTE = 3,
CM_MM711_ZONE_BYTE = 4,
CM_MM711_MODE_BYTE = 5,
CM_MM711_SPEED_BYTE = 6,
CM_MM711_NFI_1 = 7,
CM_MM711_NFI_2 = 8,
CM_MM711_NFI_3 = 9,
CM_MM711_BRIGHTNESS_BYTE = 10,
CM_MM711_RED_BYTE = 11,
CM_MM711_GREEN_BYTE = 12,
CM_MM711_BLUE_BYTE = 13,
};
enum
{
CM_MM711_MODE_STATIC = 0, //Static Mode
CM_MM711_MODE_BREATHING = 1, //Breathing Mode
CM_MM711_MODE_SPECTRUM_CYCLE = 2, //Spectrum Cycle Mode
CM_MM711_MODE_INDICATOR = 4, //Indicator Mode
CM_MM711_MODE_CUSTOM = 176, //Custom LED Control
CM_MM711_MODE_OFF = 254 //Turn Off
};
enum
{
CM_MM711_SPEED_SLOWEST = 0x5F, // Slowest speed
CM_MM711_SPEED_NORMAL = 0x38, // Normal speed
CM_MM711_SPEED_FASTEST = 0x20, // Fastest speed
};
class CMMM711Controller
{
public:
CMMM711Controller(hid_device* dev_handle, char *_path);
~CMMM711Controller();
std::string GetDeviceName();
std::string GetSerial();
std::string GetLocation();
uint8_t GetZoneIndex();
uint8_t GetMode();
uint8_t GetLedRed();
uint8_t GetLedGreen();
uint8_t GetLedBlue();
uint8_t GetLedSpeed();
RGBColor GetWheelColour();
RGBColor GetLogoColour();
void SendUpdate(uint8_t mode, uint8_t speed, RGBColor colour, uint8_t brightness);
void SetLedsDirect(RGBColor wheel_colour, RGBColor logo_colour);
private:
std::string device_name;
std::string serial;
std::string location;
hid_device* dev;
uint8_t current_mode;
uint8_t current_speed;
uint8_t current_brightness;
uint8_t current_red;
uint8_t current_green;
uint8_t current_blue;
RGBColor wheel_colour;
RGBColor logo_colour;
void GetColourStatus();
void GetCustomStatus();
void GetModeStatus();
void SendInitPacket();
void SendApplyPacket(uint8_t mode);
};
@@ -29,7 +29,6 @@ CMR6000Controller::CMR6000Controller(hid_device* dev_handle, char *_path)
wName = std::wstring(tmpName);
serial = std::string(wName.begin(), wName.end());
GetStatus(); //When setting up device get current status
}
CMR6000Controller::~CMR6000Controller()
@@ -40,30 +39,6 @@ CMR6000Controller::~CMR6000Controller()
}
}
void CMR6000Controller::GetStatus()
{
unsigned char buffer[CM_6K_PACKET_SIZE] = { 0x00, 0x52, 0xA0, 0x01, 0x00, 0x00, 0x03 };
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
// Request mode
hid_write(dev, buffer, buffer_size);
hid_read(dev, buffer, buffer_size);
unsigned char cmdbuffer[CM_6K_PACKET_SIZE] = { 0x00, 0x52, 0x2C, 0x01, 0x00 };
int cmdbuffer_size = (sizeof(cmdbuffer) / sizeof(cmdbuffer[0]));
current_mode = buffer[0x0A];
cmdbuffer[0x05] = current_mode;
hid_write(dev, cmdbuffer, cmdbuffer_size);
hid_read(dev, cmdbuffer, cmdbuffer_size);
current_speed = cmdbuffer[0x05];
current_brightness = cmdbuffer[0x09];
current_red = cmdbuffer[0x0A];
current_green = cmdbuffer[0x0B];
current_blue = cmdbuffer[0x0C];
}
std::string CMR6000Controller::GetDeviceName()
{
return device_name;
@@ -104,12 +79,17 @@ unsigned char CMR6000Controller::GetLedSpeed()
return current_speed;
}
unsigned char CMR6000Controller::GetBrightness()
{
return current_brightness;
}
bool CMR6000Controller::GetRandomColours()
{
return current_random;
}
void CMR6000Controller::SetMode(unsigned char mode, unsigned char speed, unsigned char red, unsigned char green, unsigned char blue, unsigned char random)
void CMR6000Controller::SetMode(unsigned char mode, unsigned char speed, unsigned char red, unsigned char green, unsigned char blue, unsigned char random, unsigned char brightness)
{
current_mode = mode;
current_speed = speed;
@@ -117,7 +97,7 @@ void CMR6000Controller::SetMode(unsigned char mode, unsigned char speed, unsigne
current_green = green;
current_blue = blue;
current_random = random;
current_brightness = (current_mode == CM_MR6000_MODE_COLOR_CYCLE) ? 0x7F : 0xFF; //Color_Cycle brightness needs to be clamped to 0x7F to avoid wash out
current_brightness = brightness;
SendUpdate();
}
@@ -144,7 +124,7 @@ void CMR6000Controller::SendUpdate()
buffer[0x03] = 0x01;
buffer[0x04] = 0x00;
buffer[0x05] = current_mode;
buffer[0x06] = (current_mode == CM_MR6000_MODE_STATIC) ? 0xFF: current_speed;
buffer[0x06] = (current_mode == CM_MR6000_MODE_DIRECT) ? 0xFF: current_speed;
buffer[0x07] = (current_mode == CM_MR6000_MODE_BREATHE)? current_random : 0x00; //random (A0)
buffer[0x08] = (current_mode == CM_MR6000_MODE_BREATHE)? 0x03 : 0xFF;
//buffer[0x09] = 0xFF;
@@ -20,7 +20,7 @@
enum
{
CM_MR6000_MODE_STATIC = 0x00, //Static Mode
CM_MR6000_MODE_DIRECT = 0x00, //Direct Mode
CM_MR6000_MODE_BREATHE = 0x01, //Breathe Mode
CM_MR6000_MODE_COLOR_CYCLE = 0x02, //Color cycle
CM_MR6000_MODE_OFF = 0xFF, //Off
@@ -56,8 +56,9 @@ public:
unsigned char GetLedGreen();
unsigned char GetLedBlue();
unsigned char GetLedSpeed();
unsigned char GetBrightness();
bool GetRandomColours();
void SetMode(unsigned char mode, unsigned char speed, unsigned char red, unsigned char green, unsigned char blue, unsigned char random);
void SetMode(unsigned char mode, unsigned char speed, unsigned char red, unsigned char green, unsigned char blue, unsigned char random, unsigned char brightness);
private:
std::string device_name;
@@ -74,7 +75,6 @@ private:
unsigned char current_blue;
unsigned char current_brightness;
void GetStatus();
void SendUpdate();
void SendEnableCommand();
void SendApplyCommand();
@@ -0,0 +1,367 @@
/*-------------------------------------------------------------------*\
| CMRGBController.cpp |
| |
| Driver for Coolermaster RGB USB Controller |
| |
| Nic W (midgetspy) 13th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
#include "RGBController_CMRGBController.h"
#include "CMRGBController.h"
#include <cstring>
CMRGBController::CMRGBController(hid_device* dev_handle, char* path)
{
const int szTemp = 256;
wchar_t tmpName[szTemp];
dev = dev_handle;
location = path;
hid_get_manufacturer_string(dev, tmpName, szTemp);
std::wstring wName = std::wstring(tmpName);
device_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()));
hid_get_serial_number_string(dev, tmpName, szTemp);
wName = std::wstring(tmpName);
serial = std::string(wName.begin(), wName.end());
ReadCurrentMode();
}
void CMRGBController::SendFlowControl(unsigned char byte_flag)
{
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
unsigned char buffer[buffer_size] = { 0x00, CM_RGBC_OPCODE_OP_FLOW_CONTROL }; //Packets on Windows need a 0x00 if they don't use ReportIDs
buffer[0x02] = byte_flag;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
}
void CMRGBController::SendApply()
{
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
unsigned char buffer[buffer_size] = { 0x00, CM_RGBC_OPCODE_OP_UNKNOWN_50, CM_RGBC_OPCODE_TYPE_UNKNOWN_55 }; //Packets on Windows need a 0x00 if they don't use ReportIDs
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
}
void CMRGBController::SendReadMode()
{
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
unsigned char buffer[buffer_size] = { };
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_OP] = CM_RGBC_OPCODE_OP_READ;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_TYPE] = CM_RGBC_OPCODE_TYPE_MODE;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
current_mode = buffer[CM_RGBC_PACKET_OFFSET_MODE];
}
void CMRGBController::SendSetMode(unsigned char mode)
{
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
unsigned char buffer[buffer_size] = { };
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_OP] = CM_RGBC_OPCODE_OP_WRITE;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_TYPE] = CM_RGBC_OPCODE_TYPE_MODE;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MODE] = mode;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
}
void CMRGBController::SendSetCustomColors(RGBColor color_1, RGBColor color_2, RGBColor color_3, RGBColor color_4)
{
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
unsigned char buffer[buffer_size] = { };
current_port1_color = color_1;
current_port2_color = color_2;
current_port3_color = color_3;
current_port4_color = color_4;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_OP] = CM_RGBC_OPCODE_OP_WRITE;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_TYPE] = CM_RGBC_OPCODE_TYPE_LED_INFO;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_1] = RGBGetRValue(color_1);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_1 + 1] = RGBGetGValue(color_1);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_1 + 2] = RGBGetBValue(color_1);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_2] = RGBGetRValue(color_2);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_2 + 1] = RGBGetGValue(color_2);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_2 + 2] = RGBGetBValue(color_2);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_3] = RGBGetRValue(color_3);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_3 + 1] = RGBGetGValue(color_3);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_3 + 2] = RGBGetBValue(color_3);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_4] = RGBGetRValue(color_4);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_4 + 1] = RGBGetGValue(color_4);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_4 + 2] = RGBGetBValue(color_4);
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
}
void CMRGBController::SendReadCustomColors()
{
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
unsigned char buffer[buffer_size] = { };
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_OP] = CM_RGBC_OPCODE_OP_READ;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_TYPE] = CM_RGBC_OPCODE_TYPE_LED_INFO;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
current_port1_color = ToRGBColor(
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_1],
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_1 + 1],
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_1 + 2]);
current_port2_color = ToRGBColor(
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_2],
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_2 + 1],
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_2 + 2]);
current_port3_color = ToRGBColor(
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_3],
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_3 + 1],
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_3 + 2]);
current_port4_color = ToRGBColor(
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_4],
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_4 + 1],
buffer[CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_4 + 2]);
}
void CMRGBController::SendSetConfig(unsigned char mode, unsigned char speed, unsigned char brightness, RGBColor color_1, RGBColor color_2, bool simplified=false, bool multilayer=false)
{
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
unsigned char buffer[buffer_size] = { };
current_mode = mode;
current_speed = speed;
current_brightness = brightness;
current_mode_color_1 = color_1;
current_mode_color_2 = color_2;
/*---------------------------------------------*\
| Handle special cases |
\*---------------------------------------------*/
switch(mode)
{
case CM_RGBC_MODE_COLOR_CYCLE:
brightness = 0xDF;
color_1 = 0xFFFFFF;
color_2 = 0x000000;
break;
case CM_RGBC_MODE_OFF:
brightness = 0x03;
break;
}
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_OP] = CM_RGBC_OPCODE_OP_WRITE;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_TYPE] = simplified ? CM_RGBC_OPCODE_TYPE_CONFIG_SIMPLIFIED : CM_RGBC_OPCODE_TYPE_CONFIG_FULL;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MODE] = mode;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_SPEED] = speed;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_BRIGHTNESS] = brightness;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_COLOR_1] = RGBGetRValue(color_1);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_COLOR_1 + 1] = RGBGetGValue(color_1);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_COLOR_1 + 2] = RGBGetBValue(color_1);
/*---------------------------------------------*\
| Magic values, meaning unknown |
\*---------------------------------------------*/
buffer[REPORT_ID_OFFSET + 0x06] = (mode == CM_RGBC_MODE_BREATHING) ? 0x20 : 0x00;
buffer[REPORT_ID_OFFSET + 0x07] = (mode == CM_RGBC_MODE_STAR) ? 0x19 : 0xFF;
buffer[REPORT_ID_OFFSET + 0x08] = 0xFF;
if(!simplified)
{
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MULTILAYER] = multilayer ? 0x01 : 0x00;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_COLOR_2] = RGBGetRValue(color_2);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_COLOR_2 + 1] = RGBGetGValue(color_2);
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_COLOR_2 + 2] = RGBGetBValue(color_2);
for(int i = REPORT_ID_OFFSET + 16; i < CM_RGBC_PACKET_SIZE; i++)
{
buffer[i] = 0xFF;
}
}
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
}
void CMRGBController::SendReadConfig(unsigned char mode)
{
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
unsigned char buffer[buffer_size] = { };
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_OP] = CM_RGBC_OPCODE_OP_READ;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_TYPE] = CM_RGBC_OPCODE_TYPE_CONFIG_FULL;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_MODE] = mode;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
current_mode = mode;
current_speed = buffer[CM_RGBC_PACKET_OFFSET_SPEED];
current_brightness = buffer[CM_RGBC_PACKET_OFFSET_BRIGHTNESS];
current_mode_color_1 = ToRGBColor(
buffer[CM_RGBC_PACKET_OFFSET_COLOR_1],
buffer[CM_RGBC_PACKET_OFFSET_COLOR_1 + 1],
buffer[CM_RGBC_PACKET_OFFSET_COLOR_1 + 2]);
current_mode_color_2 = ToRGBColor(
buffer[CM_RGBC_PACKET_OFFSET_COLOR_2],
buffer[CM_RGBC_PACKET_OFFSET_COLOR_2 + 1],
buffer[CM_RGBC_PACKET_OFFSET_COLOR_2 + 2]);
}
void CMRGBController::SendCustomColorStart()
{
const unsigned char buffer_size = CM_RGBC_PACKET_SIZE;
unsigned char buffer[buffer_size] = { };
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_OP] = CM_RGBC_OPCODE_OP_WRITE;
buffer[REPORT_ID_OFFSET + CM_RGBC_PACKET_OFFSET_TYPE] = CM_RGBC_OPCODE_TYPE_UNKNOWN_30;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_RGBC_INTERRUPT_TIMEOUT);
}
void CMRGBController::ReadCurrentMode()
{
SendFlowControl(CM_RGBC_OPCODE_FLOW_01);
SendReadMode();
}
void CMRGBController::ReadModeConfig(unsigned char mode)
{
SendFlowControl(CM_RGBC_OPCODE_FLOW_00);
SendReadConfig(mode);
if(mode == CM_RGBC_MODE_MULTIPLE)
{
SendReadCustomColors();
}
}
void CMRGBController::SetMode(unsigned char mode, unsigned char speed, unsigned char brightness, RGBColor color_1, RGBColor color_2)
{
SendFlowControl(CM_RGBC_OPCODE_FLOW_01);
SendSetConfig(mode, speed, brightness, color_1, color_2, false);
SendSetMode(mode);
SendApply();
SendFlowControl(CM_RGBC_OPCODE_FLOW_00);
}
void CMRGBController::SetLedsDirect(RGBColor color_1, RGBColor color_2, RGBColor color_3, RGBColor color_4)
{
SendFlowControl(CM_RGBC_OPCODE_FLOW_80);
SendCustomColorStart();
SendSetCustomColors(color_1, color_2, color_3, color_4);
SendSetMode(CM_RGBC_MODE_MULTIPLE);
SendCustomColorStart();
SendSetConfig(CM_RGBC_MODE_MULTIPLE, 0x00, 0xFF, color_1, 0x000000, false);
SendApply();
SendFlowControl(CM_RGBC_OPCODE_FLOW_00);
}
std::string CMRGBController::GetDeviceName()
{
return(device_name);
}
std::string CMRGBController::GetSerial()
{
return(serial);
}
std::string CMRGBController::GetLocation()
{
return("HID: " + location);
}
unsigned char CMRGBController::GetMode()
{
return(current_mode);
}
unsigned char CMRGBController::GetSpeed()
{
return(current_speed);
}
unsigned char CMRGBController::GetBrightness()
{
return(current_brightness);
}
RGBColor CMRGBController::GetModeColor(int color_number)
{
switch(color_number)
{
case 0:
return(current_mode_color_1);
case 1:
return(current_mode_color_2);
default:
return(ToRGBColor(0, 0, 0));
}
}
RGBColor CMRGBController::GetPortColor(int port_number)
{
switch(port_number)
{
case 0:
return(current_port1_color);
case 1:
return(current_port2_color);
case 2:
return(current_port3_color);
case 3:
return(current_port4_color);
default:
return(ToRGBColor(0, 0, 0));
}
}
CMRGBController::~CMRGBController()
{
if(dev)
{
hid_close(dev);
}
}
@@ -0,0 +1,149 @@
/*-------------------------------------------------------------------*\
| CMRGBController.h |
| |
| Driver for Coolermaster RGB USB Controller |
| |
| Nic W (midgetspy) 13th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
#include <string>
#include <hidapi/hidapi.h>
#include "RGBController.h"
#pragma once
#define CM_RGBC_NUM_LEDS 4
#define REPORT_ID_OFFSET 1
#define CM_RGBC_PACKET_SIZE 64 + REPORT_ID_OFFSET //This needs to have one byte extra for the report ID thing
#define CM_RGBC_PACKET_OFFSET_OP 0x00
#define CM_RGBC_PACKET_OFFSET_TYPE 0x01
#define CM_RGBC_PACKET_OFFSET_MULTILAYER 0x02
#define CM_RGBC_PACKET_OFFSET_MODE 0x04
#define CM_RGBC_PACKET_OFFSET_SPEED 0x05
#define CM_RGBC_PACKET_OFFSET_BRIGHTNESS 0x09
#define CM_RGBC_PACKET_OFFSET_COLOR_1 0x0A
#define CM_RGBC_PACKET_OFFSET_COLOR_2 0x0D
#define CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_1 0x04
#define CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_2 0x07
#define CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_3 0x0A
#define CM_RGBC_PACKET_OFFSET_MULTIPLE_COLOR_4 0x0D
#define CM_RGBC_INTERRUPT_TIMEOUT 250
#define CM_RGBC_SPEED_NONE 0x05
#define CM_RGBC_BRIGHTNESS_OFF 0x03
/*-------------------------------------------------*\
| OP OPCODES |
\*-------------------------------------------------*/
enum
{
CM_RGBC_OPCODE_OP_FLOW_CONTROL = 0x41,
CM_RGBC_OPCODE_OP_UNKNOWN_50 = 0x50,
CM_RGBC_OPCODE_OP_WRITE = 0x51,
CM_RGBC_OPCODE_OP_READ = 0x52,
};
/*-------------------------------------------------*\
| CONTROL FLOW OPCODES |
\*-------------------------------------------------*/
enum
{
CM_RGBC_OPCODE_FLOW_00 = 0x00,
CM_RGBC_OPCODE_FLOW_01 = 0x01,
CM_RGBC_OPCODE_FLOW_80 = 0x80,
};
/*-------------------------------------------------*\
| OP TYPE OPCODES |
\*-------------------------------------------------*/
enum
{
CM_RGBC_OPCODE_TYPE_MODE = 0x28,
CM_RGBC_OPCODE_TYPE_CONFIG_SIMPLIFIED = 0x2B,
CM_RGBC_OPCODE_TYPE_CONFIG_FULL = 0x2C,
CM_RGBC_OPCODE_TYPE_UNKNOWN_30 = 0x30,
CM_RGBC_OPCODE_TYPE_UNKNOWN_55 = 0x55,
CM_RGBC_OPCODE_TYPE_LED_INFO = 0xA8,
};
/*-------------------------------------------------*\
| MODES |
\*-------------------------------------------------*/
enum
{
CM_RGBC_MODE_STATIC = 0x00,
CM_RGBC_MODE_BREATHING = 0x01,
CM_RGBC_MODE_COLOR_CYCLE = 0x02,
CM_RGBC_MODE_STAR = 0x03,
CM_RGBC_MODE_MULTIPLE = 0x04,
CM_RGBC_MODE_MULTILAYER = 0xE0,
CM_RGBC_MODE_OFF = 0xFE,
};
/*-------------------------------------------------*\
| SPEED |
\*-------------------------------------------------*/
enum
{
CM_RGBC_SPEED_BREATHING_SLOWEST = 0x3C,
CM_RGBC_SPEED_BREATHING_FASTEST = 0x26,
CM_RGBC_SPEED_COLOR_CYCLE_SLOWEST = 0x96,
CM_RGBC_SPEED_COLOR_CYCLE_FASTEST = 0x68,
CM_RGBC_SPEED_STAR_SLOWEST = 0x46,
CM_RGBC_SPEED_STAR_FASTEST = 0x32,
};
class CMRGBController
{
public:
CMRGBController(hid_device* dev_handle, char* path);
~CMRGBController();
std::string GetDeviceName();
std::string GetSerial();
std::string GetLocation();
unsigned char GetMode();
unsigned char GetSpeed();
unsigned char GetBrightness();
RGBColor GetModeColor(int color_number);
RGBColor GetPortColor(int port_number);
void SetMode(unsigned char mode, unsigned char speed, unsigned char brightness, RGBColor color_1, RGBColor color_2);
void SetLedsDirect(RGBColor color_1, RGBColor color_2, RGBColor color_3, RGBColor color_4);
void ReadCurrentMode();
void ReadModeConfig(unsigned char mode);
private:
std::string device_name;
std::string serial;
std::string location;
hid_device* dev;
unsigned char current_mode;
unsigned char current_speed;
unsigned char current_brightness;
RGBColor current_mode_color_1;
RGBColor current_mode_color_2;
RGBColor current_port1_color;
RGBColor current_port2_color;
RGBColor current_port3_color;
RGBColor current_port4_color;
void SendFlowControl(unsigned char byte_flag);
void SendApply();
void SendCustomColorStart();
void SendReadMode();
void SendSetMode(unsigned char mode);
void SendReadCustomColors();
void SendSetCustomColors(RGBColor color_1, RGBColor color_2, RGBColor color_3, RGBColor color_4);
void SendReadConfig(unsigned char mode);
void SendSetConfig(unsigned char mode, unsigned char speed, unsigned char brightness, RGBColor color_1, RGBColor color_2, bool simplified, bool multilayer);
};
@@ -135,50 +135,47 @@ void CMSmallARGBController::SetLedCount(int zone, int led_count)
hid_write(dev, buffer, buffer_size);
}
void CMSmallARGBController::SetMode(unsigned char mode, unsigned char speed, RGBColor colour, bool random_colours)
void CMSmallARGBController::SetMode(unsigned char mode, unsigned char speed, unsigned char brightness, RGBColor colour, bool random_colours)
{
current_mode = mode;
current_speed = speed;
current_red = RGBGetRValue(colour);
current_green = RGBGetGValue(colour);
current_blue = RGBGetBValue(colour);
bool_random = random_colours;
current_mode = mode;
current_speed = speed;
current_brightness = brightness;
current_red = RGBGetRValue(colour);
current_green = RGBGetGValue(colour);
current_blue = RGBGetBValue(colour);
bool_random = random_colours;
SendUpdate();
}
void CMSmallARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_count)
void CMSmallARGBController::SetLedsDirect(RGBColor* led_colours, unsigned int led_count)
{
// Mode not yet Tested
/*
const unsigned char buffer_size = 0x41;
unsigned char buffer[buffer_size] = { 0x00 };
unsigned char packet_count = 0x00;
std::vector<unsigned char> colours;
const unsigned char buffer_size = CM_SMALL_ARGB_PACKET_SIZE;
unsigned char buffer[buffer_size] = { 0x00, 0x00, 0x10, 0x02 };
unsigned char packet_count = 0;
std::vector<uint8_t> colours;
//Set up the RGB triplets to send
for(int i = 0; i < led_count; i++)
/*---------------------------------------------*\
| Set up the RGB triplets to send |
\*---------------------------------------------*/
for(unsigned int i = 0; i < led_count; i++)
{
RGBColor colour = led_colours[i];
unsigned char r = RGBGetRValue(colour);
unsigned char g = RGBGetGValue(colour);
unsigned char b = RGBGetBValue(colour);
colours.push_back(r);
colours.push_back(g);
colours.push_back(b);
colours.push_back( RGBGetRValue(colour) );
colours.push_back( RGBGetGValue(colour) );
colours.push_back( RGBGetBValue(colour) );
}
//buffer[CM_ARGB_REPORT_BYTE] = packet_count;
buffer[CM_SMALL_ARGB_COMMAND_BYTE] = 0x10;
buffer[CM_SMALL_ARGB_FUNCTION_BYTE] = 0x02;
buffer[CM_SMALL_ARGB_ZONE_BYTE] = small_argb_header_data[zone_index].header;
buffer[CM_SMALL_ARGB_MODE_BYTE] = 0x30; //30 might be the LED count??
unsigned char buffer_idx = CM_SMALL_ARGB_MODE_BYTE + 1; //Start colour info from
buffer[CM_SMALL_ARGB_ZONE_BYTE] = zone_index - 1; //argb_header_data[zone_index].header;
buffer[CM_SMALL_ARGB_MODE_BYTE] = led_count;
unsigned char buffer_idx = CM_SMALL_ARGB_MODE_BYTE + 1;
for (std::vector<unsigned char>::iterator it = colours.begin(); it != colours.end(); buffer_idx = 0)
for(std::vector<unsigned char>::iterator it = colours.begin(); it != colours.end(); buffer_idx = CM_SMALL_ARGB_COMMAND_BYTE)
{
//Fill the write buffer till its full or the colour buffer is empty
/*-----------------------------------------------------------------*\
| Fill the write buffer till its full or the colour buffer is empty |
\*-----------------------------------------------------------------*/
buffer[CM_SMALL_ARGB_REPORT_BYTE] = packet_count;
while (( buffer_idx < buffer_size) && ( it != colours.end() ))
{
@@ -187,24 +184,19 @@ void CMSmallARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int le
it++;
}
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_SMALL_ARGB_INTERRUPT_TIMEOUT);
if(it == colours.end())
{
buffer[CM_SMALL_ARGB_REPORT_BYTE] += 0x80;
}
//reset the write buffer
memset(buffer, 0x00, sizeof(buffer) );
hid_write(dev, buffer, buffer_size);
/*-----------------------------------------------------------------*\
| Reset the write buffer |
\*-----------------------------------------------------------------*/
memset(buffer, 0x00, buffer_size );
packet_count++;
}
buffer[CM_SMALL_ARGB_REPORT_BYTE] = 0x82;
buffer[CM_SMALL_ARGB_COMMAND_BYTE] = 0x62;
buffer[CM_SMALL_ARGB_FUNCTION_BYTE] = 0x00;
buffer[CM_SMALL_ARGB_ZONE_BYTE] = 0x73;
buffer[CM_SMALL_ARGB_MODE_BYTE] = 0x00;
buffer[CM_SMALL_ARGB_SPEED_BYTE] = 0x33;
buffer[CM_SMALL_ARGB_COLOUR_INDEX_BYTE] = 0x18;
hid_write(dev, buffer, buffer_size);
hid_read_timeout(dev, buffer, buffer_size, CM_SMALL_ARGB_INTERRUPT_TIMEOUT);
*/
}
void CMSmallARGBController::SendUpdate()
@@ -227,7 +219,7 @@ void CMSmallARGBController::SendUpdate()
buffer[CM_SMALL_ARGB_MODE_BYTE] = current_mode;
buffer[CM_SMALL_ARGB_SPEED_BYTE] = current_speed;
buffer[CM_SMALL_ARGB_COLOUR_INDEX_BYTE] = (bool_random) ? 0x00 : 0x10; //This looks to still be the colour index and controls random colours
buffer[CM_SMALL_ARGB_BRIGHTNESS_BYTE] = 0xFF;
buffer[CM_SMALL_ARGB_BRIGHTNESS_BYTE] = current_brightness;
buffer[CM_SMALL_ARGB_RED_BYTE] = current_red;
buffer[CM_SMALL_ARGB_GREEN_BYTE] = current_green;
buffer[CM_SMALL_ARGB_BLUE_BYTE] = current_blue;
@@ -16,7 +16,7 @@
#pragma once
#define CM_SMALL_ARGB_PACKET_SIZE 65
#define CM_SMALL_ARGB_PACKET_SIZE 65
#define CM_SMALL_ARGB_INTERRUPT_TIMEOUT 250
enum
@@ -88,7 +88,7 @@ public:
bool GetRandomColours();
void SetLedCount(int zone, int led_count);
void SetMode(unsigned char mode, unsigned char speed, RGBColor colour, bool random_colours);
void SetMode(unsigned char mode, unsigned char speed, unsigned char brightness, RGBColor colour, bool random_colours);
void SetLedsDirect(RGBColor * led_colours, unsigned int led_count);
private:
std::string device_name;
@@ -1,22 +1,36 @@
#include "Detector.h"
#include "CMMM711Controller.h"
#include "CMMP750Controller.h"
#include "CMARGBcontroller.h"
#include "CMSmallARGBController.h"
#include "CMRGBController.h"
#include "CMR6000Controller.h"
#include "CMMKController.h"
#include "RGBController.h"
#include "RGBController_CMMM711Controller.h"
#include "RGBController_CMMP750Controller.h"
#include "RGBController_CMARGBController.h"
#include "RGBController_CMSmallARGBController.h"
#include "RGBController_CMRGBController.h"
#include "RGBController_CMR6000Controller.h"
#include "RGBController_CMMKController.h"
#include <hidapi/hidapi.h>
#define COOLERMASTER_VID 0x2516
#define COOLERMASTER_VID 0x2516
#define COOLERMASTER_MP750_XL_PID 0x0109
#define COOLERMASTER_MP750_MEDIUM_PID 0x0105
#define COOLERMASTER_ARGB_PID 0x1011
#define COOLERMASTER_SMALL_ARGB_PID 0x1000
#define COOLERMASTER_RADEON_6000_PID 0x014D
#define COOLERMASTER_MM711_PID 0x0101
#define COOLERMASTER_MP750_XL_PID 0x0109
#define COOLERMASTER_MP750_MEDIUM_PID 0x0105
#define COOLERMASTER_ARGB_PID 0x1011
#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_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
#define COOLERMASTER_MASTERKEYS_SK630_PID CMMK_USB_MASTERKEYS_SK630
#define COOLERMASTER_MASTERKEYS_SK650_PID CMMK_USB_MASTERKEYS_SK650
/******************************************************************************************\
* *
@@ -26,18 +40,6 @@
* *
\******************************************************************************************/
void DetectCoolerMasterMousemats(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CMMP750Controller* controller = new CMMP750Controller(dev, info->path);
RGBController_CMMP750Controller* rgb_controller = new RGBController_CMMP750Controller(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectCoolerMasterARGB(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
@@ -53,18 +55,6 @@ void DetectCoolerMasterARGB(hid_device_info* info, const std::string&)
}
}
void DetectCoolerMasterSmallARGB(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CMSmallARGBController* controller = new CMSmallARGBController(dev, info->path, 0);
RGBController_CMSmallARGBController* rgb_controller = new RGBController_CMSmallARGBController(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectCoolerMasterGPU(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
@@ -77,8 +67,77 @@ void DetectCoolerMasterGPU(hid_device_info* info, const std::string&)
}
}
REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 XL", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_XL_PID, 0xFF00, 1);
REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Medium", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_MEDIUM_PID, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB", DetectCoolerMasterARGB, COOLERMASTER_VID, COOLERMASTER_ARGB_PID, 0, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master Smalll ARGB", DetectCoolerMasterSmallARGB, COOLERMASTER_VID, COOLERMASTER_SMALL_ARGB_PID, 0, 0xFF00, 1);
REGISTER_HID_DETECTOR_I ("Cooler Master Radeon 6000 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6000_PID, 1);
void DetectCoolerMasterKeyboards(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CMMKController* controller = new CMMKController(dev, info);
RGBController_CMMKController* rgb_controller = new RGBController_CMMKController(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectCoolerMasterMouse(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CMMM711Controller* controller = new CMMM711Controller(dev, info->path);
RGBController_CMMM711Controller* rgb_controller = new RGBController_CMMM711Controller(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectCoolerMasterMousemats(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CMMP750Controller* controller = new CMMP750Controller(dev, info->path);
RGBController_CMMP750Controller* rgb_controller = new RGBController_CMMP750Controller(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectCoolerMasterRGB(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CMRGBController* controller = new CMRGBController(dev, info->path);
RGBController_CMRGBController* rgb_controller = new RGBController_CMRGBController(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectCoolerMasterSmallARGB(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CMSmallARGBController* controller = new CMSmallARGBController(dev, info->path, 0);
RGBController_CMSmallARGBController* rgb_controller = new RGBController_CMSmallARGBController(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR_IPU("Cooler Master MM711", DetectCoolerMasterMouse, COOLERMASTER_VID, COOLERMASTER_MM711_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 XL", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_XL_PID, 0xFF00, 1);
REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Medium", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_MEDIUM_PID, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro L", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_PRO_L_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro L White", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_PRO_L_WHITE_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro S", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_PRO_S_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master MK570", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_MK750_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master SK630", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_SK630_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master SK650", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_SK650_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB", DetectCoolerMasterARGB, COOLERMASTER_VID, COOLERMASTER_ARGB_PID, 0, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master Small ARGB", DetectCoolerMasterSmallARGB, COOLERMASTER_VID, COOLERMASTER_SMALL_ARGB_PID, 0, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master RGB", DetectCoolerMasterRGB, COOLERMASTER_VID, COOLERMASTER_RGB_PID, 0, 0xFF00, 1);
REGISTER_HID_DETECTOR_I ("Cooler Master Radeon 6000 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6000_PID, 1 );
@@ -336,7 +336,7 @@ void RGBController_CMARGBController::DeviceUpdateLEDs()
}
}
void RGBController_CMARGBController::UpdateZoneLEDs(int zone)
void RGBController_CMARGBController::UpdateZoneLEDs(int /*zone*/)
{
//cmargb->SetLedsDirect( zones[zone].colors, zones[zone].leds_count );
}
@@ -0,0 +1,487 @@
/*-------------------------------------------------------------------*\
| RGBController_CMMKController.cpp |
| |
| Driver for Coolermaster MasterKeys keyboards |
| |
| Lukas N (chmod222) 28th Jun 2020 |
| Tam D (too.manyhobbies) 25th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
#include "RGBController_CMMKController.h"
#include <sstream>
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
RGBController_CMMKController::RGBController_CMMKController(CMMKController* cmmk_ctrl)
{
cmmk = cmmk_ctrl;
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;
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.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.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.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.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.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.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.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.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.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.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.color_mode = MODE_COLORS_NONE;
modes.push_back(FirmwareControl);
SetupZones();
}
RGBController_CMMKController::~RGBController_CMMKController()
{
delete cmmk;
}
void RGBController_CMMKController::SetupMatrixMap()
{
for(int y = 0; y < CMMK_ROWS_MAX; y++)
{
for(int x = 0; x < CMMK_COLS_MAX; x++)
{
matrix_map[y][x] = 0xFFFFFFFF;
}
}
for(size_t i = 0; i < leds.size(); i++)
{
led& l = leds[i];
int y = (l.value & 0xFF00) >> 8;
int x = (l.value & 0xFF);
matrix_map[y][x] = i;
}
}
void RGBController_CMMKController::SetupZones()
{
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 < column_count; x++)
{
if(!cmmk->PositionValid(y, x))
{
continue;
}
std::stringstream namestrm;
led key;
namestrm << "Key @ Row " << (y + 1) << ", Column" << (x + 1);
key.name = namestrm.str();
key.value = (y & 0xFF) << 8 | (x & 0xFF);
leds.push_back(key);
}
}
zone KeyboardZone;
KeyboardZone.name = "Keyboard";
KeyboardZone.type = ZONE_TYPE_MATRIX;
KeyboardZone.leds_min = leds.size();
KeyboardZone.leds_max = leds.size();
KeyboardZone.leds_count = leds.size();
KeyboardZone.matrix_map = new matrix_map_type;
KeyboardZone.matrix_map->height = row_count;
KeyboardZone.matrix_map->width = column_count;
KeyboardZone.matrix_map->map = (unsigned int *)&matrix_map;
zones.push_back(KeyboardZone);
SetupMatrixMap();
SetupColors();
}
void RGBController_CMMKController::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
struct rgb map_to_cmmk_rgb(RGBColor input)
{
return rgb
{
(uint8_t)RGBGetRValue(input),
(uint8_t)RGBGetGValue(input),
(uint8_t)RGBGetBValue(input)
};
}
enum cmmk_wave_direction map_to_cmmk_dir(int input)
{
switch(input)
{
case MODE_DIRECTION_LEFT:
return CMMK_RIGHT_TO_LEFT;
case MODE_DIRECTION_RIGHT:
return CMMK_LEFT_TO_RIGHT;
case MODE_DIRECTION_UP:
return CMMK_FRONT_TO_BACK;
case MODE_DIRECTION_DOWN:
return CMMK_BACK_TO_FRONT;
default:
return CMMK_RIGHT_TO_LEFT;
}
}
void copy_buffers(led* buf, RGBColor* colbuf, size_t n, struct cmmk_color_matrix& mat, std::atomic<bool>& dirty)
{
dirty.store(false);
for(size_t i = 0; i < n; i++)
{
led const& selected_led = buf[i];
int y = (selected_led.value & 0xFF00) >> 8;
int x = selected_led.value & 0xFF;
struct rgb col = map_to_cmmk_rgb(colbuf[i]);
struct rgb ecol = mat.data[y][x];
if(ecol.R != col.R || ecol.G != col.G || ecol.B != col.B)
{
dirty.store(true);
mat.data[y][x] = col;
}
}
}
void RGBController_CMMKController::DeviceUpdateLEDs()
{
copy_buffers(leds.data(), colors.data(), leds.size(), current_matrix, dirty);
if(force_update.load() || dirty.load())
{
cmmk->SetAll(current_matrix);
force_update.store(false);
}
}
void RGBController_CMMKController::UpdateZoneLEDs(int zone_idx)
{
zone& z = zones[zone_idx];
copy_buffers(z.leds, z.colors, z.leds_count, current_matrix, dirty);
if(force_update.load() || dirty.load())
{
cmmk->SetAll(current_matrix);
force_update.store(false);
}
}
void RGBController_CMMKController::UpdateSingleLED(int led_idx)
{
led& selected_led = leds[led_idx];
int y = (selected_led.value & 0xFF00) >> 8;
int x = selected_led.value & 0xFF;
current_matrix.data[y][x] = map_to_cmmk_rgb(colors[led_idx]);
cmmk->SetSingle(y, x, map_to_cmmk_rgb(colors[led_idx]));
dirty.store(false);
}
void RGBController_CMMKController::SetCustomMode()
{
active_mode = 1;
}
void RGBController_CMMKController::DeviceUpdateMode()
{
force_update.store(true);
switch(modes[active_mode].value)
{
case CMMK_MODE_FIRMWARE:
cmmk->SetFirmwareControl();
break;
case CMMK_MODE_MANUAL:
cmmk->SetManualControl();
break;
case CMMK_EFFECT_FULLY_LIT:
{
cmmk_effect_fully_lit fully_lit_effect;
fully_lit_effect.color = map_to_cmmk_rgb(modes[active_mode].colors[0]);
cmmk->SetMode(fully_lit_effect);
}
break;
case CMMK_EFFECT_BREATHE:
{
cmmk_effect_breathe breathe_effect;
breathe_effect.speed = (uint8_t)modes[active_mode].speed;
breathe_effect.color = map_to_cmmk_rgb(modes[active_mode].colors[0]);
cmmk->SetMode(breathe_effect);
}
break;
case CMMK_EFFECT_CYCLE:
{
cmmk_effect_cycle cycle_effect;
cycle_effect.speed = (uint8_t)modes[active_mode].speed;
cmmk->SetMode(cycle_effect);
}
break;
case CMMK_EFFECT_SINGLE:
{
cmmk_effect_single single_effect;
single_effect.speed = (uint8_t)modes[active_mode].speed;
single_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
single_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
cmmk->SetMode(single_effect);
}
break;
case CMMK_EFFECT_WAVE:
{
cmmk_effect_wave wave_effect;
wave_effect.speed = (uint8_t)modes[active_mode].speed;
wave_effect.direction = map_to_cmmk_dir(modes[active_mode].direction);
wave_effect.start = map_to_cmmk_rgb(modes[active_mode].colors[0]);
cmmk->SetMode(wave_effect);
}
break;
case CMMK_EFFECT_RIPPLE:
{
cmmk_effect_ripple ripple_effect;
ripple_effect.speed = (uint8_t)modes[active_mode].speed;
ripple_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
ripple_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
if(modes[active_mode].color_mode == MODE_COLORS_RANDOM)
{
ripple_effect.ripple_type = CMMK_RIPPLE_RANDOM_COLOR;
}
else
{
ripple_effect.ripple_type = CMMK_RIPPLE_GIVEN_COLOR;
}
cmmk->SetMode(ripple_effect);
}
break;
case CMMK_EFFECT_CROSS:
{
cmmk_effect_cross cross_effect;
cross_effect.speed = (uint8_t)modes[active_mode].speed;
cross_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
cross_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
cmmk->SetMode(cross_effect);
}
break;
case CMMK_EFFECT_RAINDROPS:
{
cmmk_effect_raindrops raindrops_effect;
raindrops_effect.speed = (uint8_t)modes[active_mode].speed;
raindrops_effect.interval = CMMK_SPEED_MID;
raindrops_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
raindrops_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
cmmk->SetMode(raindrops_effect);
}
break;
case CMMK_EFFECT_STARS:
{
cmmk_effect_stars stars_effect;
stars_effect.speed = (uint8_t)modes[active_mode].speed;
stars_effect.interval = CMMK_SPEED_MID;
stars_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
stars_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
cmmk->SetMode(stars_effect);
}
break;
case CMMK_EFFECT_SNAKE:
{
cmmk_effect_snake snake_effect;
snake_effect.speed = (uint8_t)modes[active_mode].speed;
cmmk->SetMode(snake_effect);
}
break;
}
}
@@ -0,0 +1,42 @@
/*-------------------------------------------------------------------*\
| RGBController_CMMKController.h |
| |
| Driver for Coolermaster MasterKeys keyboards |
| |
| Lukas N (chmod222) 28th Jun 2020 |
| Tam D (too.manyhobbies) 25th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CMMKController.h"
class RGBController_CMMKController : public RGBController
{
public:
RGBController_CMMKController(CMMKController* cmmk_ptr);
~RGBController_CMMKController();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
void SetupMatrixMap();
CMMKController* cmmk;
int matrix_map[CMMK_ROWS_MAX][CMMK_COLS_MAX];
struct cmmk_color_matrix current_matrix;
std::atomic<bool> dirty;
std::atomic<bool> force_update;
};
@@ -0,0 +1,191 @@
/*-------------------------------------------------------------------*\
| RGBController_CMMM711Controller.cpp |
| |
| Driver for Coolermaster MM711 Controller |
| |
| Chris M (Dr_No) 14th Feb 2021 |
| |
\*-------------------------------------------------------------------*/
#include "RGBController_CMMM711Controller.h"
RGBController_CMMM711Controller::RGBController_CMMM711Controller(CMMM711Controller *cmmm711_ptr)
{
cmmm711 = cmmm711_ptr;
uint8_t speed = cmmm711->GetLedSpeed();
name = cmmm711->GetDeviceName();
vendor = "Cooler Master";
type = DEVICE_TYPE_MOUSE;
description = cmmm711->GetDeviceName();
version = "1.0";
serial = cmmm711->GetSerial();
location = cmmm711->GetLocation();
mode Custom;
Custom.name = "Direct";
Custom.value = CM_MM711_MODE_CUSTOM;
Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Custom.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
Custom.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
Custom.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
Custom.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Custom);
mode Static;
Static.name = "Static";
Static.value = CM_MM711_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Static.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
Static.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
Static.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(Static.colors_max);
Static.speed_min = CM_MM711_SPEED_SLOWEST;
Static.speed_max = CM_MM711_SPEED_FASTEST;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.speed = CM_MM711_SPEED_NORMAL;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CM_MM711_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
Breathing.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
Breathing.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(Breathing.colors_max);
Breathing.speed_min = CM_MM711_SPEED_SLOWEST;
Breathing.speed_max = CM_MM711_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.speed = CM_MM711_SPEED_NORMAL;
modes.push_back(Breathing);
mode Spectrum_Cycle;
Spectrum_Cycle.name = "Spectrum Cycle";
Spectrum_Cycle.value = CM_MM711_MODE_SPECTRUM_CYCLE;
Spectrum_Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Spectrum_Cycle.brightness_min = CM_MM_ARGB_BRIGHTNESS_MIN;
Spectrum_Cycle.brightness_max = CM_MM_ARGB_BRIGHTNESS_MAX_SPECTRUM;
Spectrum_Cycle.brightness = CM_MM_ARGB_BRIGHTNESS_MAX_SPECTRUM;
Spectrum_Cycle.speed_min = CM_MM711_SPEED_SLOWEST;
Spectrum_Cycle.speed_max = CM_MM711_SPEED_FASTEST;
Spectrum_Cycle.color_mode = MODE_COLORS_NONE;
Spectrum_Cycle.speed = CM_MM711_SPEED_NORMAL;
modes.push_back(Spectrum_Cycle);
mode Indicator;
Indicator.name = "Indicator";
Indicator.value = CM_MM711_MODE_INDICATOR;
Indicator.color_mode = MODE_COLORS_NONE;
modes.push_back(Indicator);
mode Off;
Off.name = "Turn Off";
Off.value = CM_MM711_MODE_OFF;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
Init_Controller(); //Only processed on first run
SetupZones();
uint8_t temp_mode = cmmm711->GetMode();
for(std::size_t mode_index = 0; mode_index < modes.size(); mode_index++)
{
if (modes[mode_index].value == temp_mode)
{
active_mode = mode_index;
break;
}
}
if (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
modes[active_mode].colors[0] = ToRGBColor(cmmm711->GetLedRed(),cmmm711->GetLedGreen(),cmmm711->GetLedBlue());
}
colors[0] = cmmm711->GetWheelColour();
colors[1] = cmmm711->GetLogoColour();
}
RGBController_CMMM711Controller::~RGBController_CMMM711Controller()
{
delete cmmm711;
}
void RGBController_CMMM711Controller::Init_Controller()
{
zone mouse_zone;
mouse_zone.name = "Master Mouse 711";
mouse_zone.type = ZONE_TYPE_LINEAR;
mouse_zone.leds_min = 2;
mouse_zone.leds_max = 2;
mouse_zone.leds_count = 2;
mouse_zone.matrix_map = NULL;
zones.push_back(mouse_zone);
led wheel_led;
wheel_led.name = "Scroll Wheel LED";
wheel_led.value = 0;
leds.push_back(wheel_led);
led logo_led;
logo_led.name = "Logo LED";
logo_led.value = 1;
leds.push_back(logo_led);
}
void RGBController_CMMM711Controller::SetupZones()
{
SetupColors();
}
void RGBController_CMMM711Controller::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_CMMM711Controller::DeviceUpdateLEDs()
{
cmmm711->SetLedsDirect( colors[0], colors[1] );
}
void RGBController_CMMM711Controller::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_CMMM711Controller::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_CMMM711Controller::SetCustomMode()
{
for(std::size_t mode_index = 0; mode_index < modes.size(); mode_index++)
{
if (modes[mode_index].value == CM_MM711_MODE_CUSTOM)
{
active_mode = mode_index;
break;
}
}
}
void RGBController_CMMM711Controller::DeviceUpdateMode()
{
RGBColor colour = 0;
if (modes[active_mode].value != CM_MM711_MODE_CUSTOM)
{
if( modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC )
{
colour = modes[active_mode].colors[0];
}
cmmm711->SendUpdate(modes[active_mode].value, modes[active_mode].speed, colour, modes[active_mode].brightness);
}
}
@@ -0,0 +1,39 @@
/*-------------------------------------------------------------------*\
| RGBController_CMMM711Controller.h |
| |
| Driver for Coolermaster MM711 Controller |
| |
| Chris M (Dr_No) 14th Feb 2021 |
| |
\*-------------------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CMMM711Controller.h"
#include <vector>
#define CM_MM_ARGB_BRIGHTNESS_MIN 0x00
#define CM_MM_ARGB_BRIGHTNESS_MAX_DEFAULT 0xFF
#define CM_MM_ARGB_BRIGHTNESS_MAX_SPECTRUM 0x7F
class RGBController_CMMM711Controller : public RGBController
{
public:
RGBController_CMMM711Controller(CMMM711Controller* cmargb_ptr);
~RGBController_CMMM711Controller();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
void Init_Controller();
int GetDeviceMode();
CMMM711Controller* cmmm711;
};
@@ -87,7 +87,7 @@ RGBController_CMMP750Controller::~RGBController_CMMP750Controller()
int RGBController_CMMP750Controller::GetDeviceMode()
{
int temp_mode = cmmp750->GetMode();
for( int i = 0; i < modes.size(); i++)
for(unsigned int i = 0; i < modes.size(); i++)
{
if (temp_mode == modes[i].value)
{
@@ -28,35 +28,41 @@ RGBController_CMR6000Controller::RGBController_CMR6000Controller(CMR6000Controll
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = CM_MR6000_MODE_STATIC;
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 Direct;
Direct.name = "Direct";
Direct.value = CM_MR6000_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR| MODE_FLAG_HAS_BRIGHTNESS;
Direct.color_mode = MODE_COLORS_PER_LED;
Direct.colors_min = 1;
Direct.colors_max = 1;
Direct.colors.resize(1);
Direct.brightness_min = 0x00;
Direct.brightness_max = 0xFF;
Direct.brightness = 0xFF;
modes.push_back(Direct);
mode ColorCycle;
ColorCycle.name = "Color Cycle";
ColorCycle.value = CM_MR6000_MODE_COLOR_CYCLE;
ColorCycle.flags = MODE_FLAG_HAS_SPEED;
ColorCycle.speed_min = MR6000_CYCLE_SPEED_SLOWEST;
ColorCycle.speed = MR6000_CYCLE_SPEED_NORMAL;
ColorCycle.speed_max = MR6000_CYCLE_SPEED_FASTEST;
ColorCycle.color_mode = MODE_COLORS_NONE;
ColorCycle.speed = speed;
ColorCycle.name = "Color Cycle";
ColorCycle.value = CM_MR6000_MODE_COLOR_CYCLE;
ColorCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
ColorCycle.speed_min = MR6000_CYCLE_SPEED_SLOWEST;
ColorCycle.speed = MR6000_CYCLE_SPEED_NORMAL;
ColorCycle.speed_max = MR6000_CYCLE_SPEED_FASTEST;
ColorCycle.color_mode = MODE_COLORS_NONE;
ColorCycle.speed = speed;
ColorCycle.brightness_min = 0x00;
ColorCycle.brightness_max = 0xFF;
ColorCycle.brightness = 0x7F;
modes.push_back(ColorCycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CM_MR6000_MODE_BREATHE;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Breathing.speed_min = MR6000_BREATHE_SPEED_SLOWEST;
Breathing.speed = MR6000_BREATHE_SPEED_NORMAL;
Breathing.speed_max = MR6000_BREATHE_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(1);
@@ -64,19 +70,7 @@ RGBController_CMR6000Controller::RGBController_CMR6000Controller(CMR6000Controll
modes.push_back(Breathing);
SetupZones();
active_mode = cmr6000->GetMode();
if (modes[active_mode].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
{
modes[active_mode].colors[0] = ToRGBColor(cmr6000->GetLedRed(), cmr6000->GetLedGreen(), cmr6000->GetLedBlue());
}
if (modes[active_mode].flags & MODE_FLAG_HAS_RANDOM_COLOR)
{
modes[active_mode].color_mode = (cmr6000->GetRandomColours()) ? MODE_COLORS_RANDOM : MODE_COLORS_MODE_SPECIFIC;
}
if (modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
{
modes[active_mode].speed = cmr6000->GetLedSpeed();
}
active_mode = 1;
}
RGBController_CMR6000Controller::~RGBController_CMR6000Controller()
@@ -97,6 +91,7 @@ void RGBController_CMR6000Controller::SetupZones()
led GP_led;
GP_led.name = "Logo";
GP_led.value = 0;
leds.push_back(GP_led);
SetupColors();
@@ -116,16 +111,17 @@ void RGBController_CMR6000Controller::DeviceUpdateLEDs()
unsigned char grn = 0;
unsigned char blu = 0;
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
if(modes[active_mode].color_mode == MODE_COLORS_PER_LED)
{
red = RGBGetRValue(modes[active_mode].colors[0]);
grn = RGBGetGValue(modes[active_mode].colors[0]);
blu = RGBGetBValue(modes[active_mode].colors[0]);
red = RGBGetRValue(colors[0]);
grn = RGBGetGValue(colors[0]);
blu = RGBGetBValue(colors[0]);
}
unsigned char rnd = (modes[active_mode].color_mode == MODE_COLORS_RANDOM) ? 0xA0 : 0x20;
unsigned char bri = (modes[active_mode].flags & MODE_FLAG_HAS_BRIGHTNESS) ? modes[active_mode].brightness : 0xFF;
cmr6000->SetMode(modes[active_mode].value, modes[active_mode].speed, red, grn, blu, rnd);
cmr6000->SetMode(modes[active_mode].value, modes[active_mode].speed, red, grn, blu, rnd, bri);
}
void RGBController_CMR6000Controller::UpdateZoneLEDs(int /*zone*/)
@@ -0,0 +1,274 @@
/*-------------------------------------------------------------------*\
| RGBController_CMRGBController.cpp |
| |
| Driver for Coolermaster RGB USB Controller |
| |
| Nic W (midgetspy) 13th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
#include "RGBController_CMRGBController.h"
/*-----------------------------------------------------------------------------------------------------------------------------------------*\
| This controller has 4 ports, each for a 12v non-addressable LED item. |
| |
| It supports the following modes: |
| Static: All 4 ports a single color. Has brightness option. |
| Breathing: All ports a single color, fading in and out. Has brightness and speed option. |
| Star: Some weird effect using all 4 ports and a single color. Has brightness and speed option. |
| Color Cycle: All ports cycle through the rainbow in unison. Has brightness and speed option. |
| Off: All 4 ports off |
| |
| Plus some "special" modes: |
| Multilayer: Each of the 4 ports can have any of the modes above applied individually |
| Multiple Color/Customize: Each port can be set to its own static color |
| Mirage: A strobe effect that varies the LED pulse frequency which affects any of the above modes |
| |
| Note: |
| Multiple Color/Customize is equivalent to Multilayer + Static, but the device supports both separately |
| Static is equivalent to Multiple Color/Customize with the same color on each port, but the device supports both separately |
| |
| It can be controlled with 2 different pieces of software: MasterPlus+ or "RGB LED Controller". They appear to use different protocols. |
| |
| RGB LED Controller: |
| Sets changes temporarily and then applies them or cancels the changes separately |
| Supports all modes above |
| Has 3 brightness increments |
| Has two different colors for the Star effect (Star/Sky) |
| |
| MasterPlus+: |
| Sets changes permanently as soon as you change anything in the UI |
| Doesn't support Multilayer or Mirage |
| Has 5 brightness increments |
| Single color for Star |
\*-----------------------------------------------------------------------------------------------------------------------------------------*/
RGBController_CMRGBController::RGBController_CMRGBController(CMRGBController *cmrgb_ptr)
{
cmrgb = cmrgb_ptr;
name = "Cooler Master RGB Controller";
vendor = "Cooler Master";
type = DEVICE_TYPE_LEDSTRIP;
description = cmrgb->GetDeviceName();
version = "";
serial = cmrgb->GetSerial();
location = cmrgb->GetLocation();
mode Static;
Static.name = "Static";
Static.value = CM_RGBC_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(Static.colors_max);
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.brightness_min = 0x00;
Static.brightness_max = 0xFF;
Static.brightness = 0xFF;
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CM_RGBC_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(Breathing.colors_max);
Breathing.speed_min = CM_RGBC_SPEED_BREATHING_SLOWEST;
Breathing.speed_max = CM_RGBC_SPEED_BREATHING_FASTEST;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.speed = CM_RGBC_SPEED_BREATHING_SLOWEST;
Breathing.brightness_min = 0x00;
Breathing.brightness_max = 0xFF;
Breathing.brightness = 0xFF;
modes.push_back(Breathing);
mode ColorCycle;
ColorCycle.name = "Spectrum Cycle";
ColorCycle.value = CM_RGBC_MODE_COLOR_CYCLE;
ColorCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_RANDOM_COLOR;
ColorCycle.speed_min = CM_RGBC_SPEED_COLOR_CYCLE_SLOWEST;
ColorCycle.speed_max = CM_RGBC_SPEED_COLOR_CYCLE_FASTEST;
ColorCycle.color_mode = MODE_COLORS_RANDOM;
ColorCycle.speed = CM_RGBC_SPEED_COLOR_CYCLE_SLOWEST;
ColorCycle.brightness_min = 0x00;
ColorCycle.brightness_max = 0xFF;
ColorCycle.brightness = 0xFF;
modes.push_back(ColorCycle);
mode Star;
Star.name = "Star";
Star.value = CM_RGBC_MODE_STAR;
Star.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Star.colors_min = 2;
Star.colors_max = 2;
Star.colors.resize(Star.colors_max);
Star.speed_min = CM_RGBC_SPEED_STAR_SLOWEST;
Star.speed_max = CM_RGBC_SPEED_STAR_FASTEST;
Star.color_mode = MODE_COLORS_MODE_SPECIFIC;
Star.speed = CM_RGBC_SPEED_STAR_SLOWEST;
Star.brightness_min = 0x00;
Star.brightness_max = 0xFF;
Star.brightness = 0xFF;
modes.push_back(Star);
mode Multiple;
Multiple.name = "Custom";
Multiple.value = CM_RGBC_MODE_MULTIPLE;
Multiple.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Multiple.colors_min = 1;
Multiple.colors_max = 1;
Multiple.colors.resize(Multiple.colors_max);
Multiple.color_mode = MODE_COLORS_PER_LED;
Multiple.speed = 0;
Multiple.brightness_min = 0x00;
Multiple.brightness_max = 0xFF;
Multiple.brightness = 0xFF;
modes.push_back(Multiple);
mode Off;
Off.name = "Off";
Off.value = CM_RGBC_MODE_OFF;
Off.color_mode = MODE_COLORS_NONE;
Off.flags = 0;
modes.push_back(Off);
SetupZones();
ReadAllModeConfigsFromDevice();
}
RGBController_CMRGBController::~RGBController_CMRGBController()
{
delete cmrgb;
}
void RGBController_CMRGBController::ReadAllModeConfigsFromDevice()
{
int device_mode = cmrgb->GetMode();
for(std::size_t mode_idx = 0; mode_idx < modes.size(); mode_idx++)
{
if(device_mode == modes[mode_idx].value)
{
active_mode = mode_idx;
continue;
}
if(!modes[mode_idx].flags)
{
continue;
}
cmrgb->ReadModeConfig(modes[mode_idx].value);
LoadConfigFromDeviceController(mode_idx);
}
/*---------------------------------------------------------*\
| Do the active mode last so the device controller state |
| is left with the active mode's config |
\*---------------------------------------------------------*/
if(active_mode != -1)
{
cmrgb->ReadModeConfig(modes[active_mode].value);
LoadConfigFromDeviceController(active_mode);
}
}
void RGBController_CMRGBController::LoadConfigFromDeviceController(int mode_idx)
{
for(std::size_t color_idx = 0; color_idx < modes[mode_idx].colors.size(); color_idx++)
{
modes[mode_idx].colors[0] = cmrgb->GetModeColor(color_idx);
}
if(modes[mode_idx].flags & MODE_FLAG_HAS_PER_LED_COLOR)
{
for (std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
SetLED(led_idx, cmrgb->GetPortColor(led_idx));
}
}
if(modes[mode_idx].flags & MODE_FLAG_HAS_SPEED)
{
modes[mode_idx].speed = cmrgb->GetSpeed();
}
if(modes[mode_idx].flags & MODE_FLAG_HAS_BRIGHTNESS)
{
modes[active_mode].brightness = cmrgb->GetBrightness();
}
}
void RGBController_CMRGBController::SetupZones()
{
leds.clear();
zones.clear();
colors.clear();
/*-----------------------------------------------------*\
| One zone, 4 leds. This might not actually work with |
| the Multilayer mode, but we'll deal with that later |
\*-----------------------------------------------------*/
zone* new_zone = new zone();
new_zone->name = "Controller";
new_zone->type = ZONE_TYPE_SINGLE;
new_zone->leds_min = 1;
new_zone->leds_max = 4;
new_zone->leds_count = 4;
new_zone->matrix_map = NULL;
for(int i = 1; i <= CM_RGBC_NUM_LEDS; i++)
{
led* new_led = new led();
new_led->name = "LED " + std::to_string(i);
leds.push_back(*new_led);
}
zones.push_back(*new_zone);
SetupColors();
}
void RGBController_CMRGBController::ResizeZone(int /*zone*/, int /*new_size*/)
{
}
void RGBController_CMRGBController::DeviceUpdateLEDs()
{
for(size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
UpdateZoneLEDs(zone_idx);
}
}
void RGBController_CMRGBController::UpdateZoneLEDs(int zone)
{
cmrgb->SetLedsDirect(zones[zone].colors[0], zones[zone].colors[1], zones[zone].colors[2], zones[zone].colors[3]);
}
void RGBController_CMRGBController::UpdateSingleLED(int /*led*/)
{
}
void RGBController_CMRGBController::SetCustomMode()
{
for(std::size_t mode_idx = 0; mode_idx < modes.size() ; mode_idx++)
{
if (modes[mode_idx].value == CM_RGBC_MODE_MULTIPLE)
{
active_mode = mode_idx;
break;
}
}
}
void RGBController_CMRGBController::DeviceUpdateMode()
{
RGBColor color_1 = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) ? modes[active_mode].colors[0] : 0;
RGBColor color_2 = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC && modes[active_mode].colors.size() > 1) ? modes[active_mode].colors[1] : 0;
cmrgb->SetMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, color_1, color_2);
}
@@ -0,0 +1,35 @@
/*-------------------------------------------------------------------*\
| RGBController_CMRGBController.h |
| |
| Driver for Coolermaster RGB USB Controller |
| |
| Nic W (midgetspy) 13th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CMRGBController.h"
#include <vector>
class RGBController_CMRGBController : public RGBController
{
public:
RGBController_CMRGBController(CMRGBController* cmrgb_ptr);
~RGBController_CMRGBController();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
CMRGBController* cmrgb;
void LoadConfigFromDeviceController(int device_mode);
void ReadAllModeConfigsFromDevice();
};
@@ -11,106 +11,127 @@
RGBController_CMSmallARGBController::RGBController_CMSmallARGBController(CMSmallARGBController *cmargb_ptr)
{
cmargb = cmargb_ptr;
unsigned char speed = cmargb->GetLedSpeed();
cmargb = cmargb_ptr;
unsigned char speed = cmargb->GetLedSpeed();
name = small_argb_header_data[cmargb->GetZoneIndex()].name;
vendor = "Cooler Master";
type = DEVICE_TYPE_LEDSTRIP;
description = cmargb->GetDeviceName();
version = "1.0";
serial = cmargb->GetSerial();
location = cmargb->GetLocation();
name = small_argb_header_data[cmargb->GetZoneIndex()].name;
vendor = "Cooler Master";
type = DEVICE_TYPE_LEDSTRIP;
description = cmargb->GetDeviceName();
version = "2.0 for FW0012";
serial = cmargb->GetSerial();
location = cmargb->GetLocation();
mode Off;
Off.name = "Turn Off";
Off.value = CM_SMALL_ARGB_MODE_OFF;
Off.color_mode = MODE_COLORS_NONE;
Off.name = "Turn Off";
Off.value = CM_SMALL_ARGB_MODE_OFF;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Reload;
Reload.name = "Reload";
Reload.value = CM_SMALL_ARGB_MODE_RELOAD;
Reload.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Reload.colors_min = 1;
Reload.colors_max = 1;
Reload.name = "Reload";
Reload.value = CM_SMALL_ARGB_MODE_RELOAD;
Reload.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Reload.colors_min = 1;
Reload.colors_max = 1;
Reload.colors.resize(Reload.colors_max);
Reload.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Reload.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Reload.color_mode = MODE_COLORS_RANDOM;
Reload.speed = speed;
Reload.brightness_min = 0;
Reload.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
Reload.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
Reload.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Reload.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Reload.color_mode = MODE_COLORS_RANDOM;
Reload.speed = speed;
modes.push_back(Reload);
mode Recoil;
Recoil.name = "Recoil";
Recoil.value = CM_SMALL_ARGB_MODE_RECOIL;
Recoil.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Recoil.colors_min = 1;
Recoil.colors_max = 1;
Recoil.name = "Recoil";
Recoil.value = CM_SMALL_ARGB_MODE_RECOIL;
Recoil.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Recoil.colors_min = 1;
Recoil.colors_max = 1;
Recoil.colors.resize(Recoil.colors_max);
Recoil.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Recoil.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Recoil.color_mode = MODE_COLORS_RANDOM;
Recoil.speed = speed;
Recoil.brightness_min = 0;
Recoil.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
Recoil.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
Recoil.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Recoil.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Recoil.color_mode = MODE_COLORS_RANDOM;
Recoil.speed = speed;
modes.push_back(Recoil);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CM_SMALL_ARGB_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.name = "Breathing";
Breathing.value = CM_SMALL_ARGB_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(Breathing.colors_max);
Breathing.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Breathing.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_RANDOM;
Breathing.speed = speed;
Breathing.brightness_min = 0;
Breathing.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
Breathing.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
Breathing.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Breathing.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Breathing.color_mode = MODE_COLORS_RANDOM;
Breathing.speed = speed;
modes.push_back(Breathing);
mode Refill;
Refill.name = "Refill";
Refill.value = CM_SMALL_ARGB_MODE_REFILL;
Refill.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Refill.colors_min = 1;
Refill.colors_max = 1;
Refill.name = "Refill";
Refill.value = CM_SMALL_ARGB_MODE_REFILL;
Refill.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Refill.colors_min = 1;
Refill.colors_max = 1;
Refill.colors.resize(Refill.colors_max);
Refill.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Refill.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Refill.color_mode = MODE_COLORS_RANDOM;
Refill.speed = speed;
Refill.brightness_min = 0;
Refill.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
Refill.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
Refill.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Refill.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Refill.color_mode = MODE_COLORS_RANDOM;
Refill.speed = speed;
modes.push_back(Refill);
mode Demo;
Demo.name = "Demo";
Demo.value = CM_SMALL_ARGB_MODE_DEMO;
Demo.flags = MODE_FLAG_HAS_SPEED;
Demo.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Demo.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Demo.color_mode = MODE_COLORS_NONE;
Demo.speed = speed;
Demo.name = "Demo";
Demo.value = CM_SMALL_ARGB_MODE_DEMO;
Demo.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Demo.brightness_min = 0;
Demo.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
Demo.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
Demo.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Demo.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Demo.color_mode = MODE_COLORS_NONE;
Demo.speed = speed;
modes.push_back(Demo);
mode Spectrum;
Spectrum.name = "Spectrum";
Spectrum.value = CM_SMALL_ARGB_MODE_SPECTRUM;
Spectrum.flags = MODE_FLAG_HAS_SPEED;
Spectrum.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Spectrum.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Spectrum.color_mode = MODE_COLORS_NONE;
Spectrum.speed = speed;
Spectrum.name = "Spectrum";
Spectrum.value = CM_SMALL_ARGB_MODE_SPECTRUM;
Spectrum.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Spectrum.brightness_min = 0;
Spectrum.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
Spectrum.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
Spectrum.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
Spectrum.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
Spectrum.color_mode = MODE_COLORS_NONE;
Spectrum.speed = speed;
modes.push_back(Spectrum);
mode Direct;
Direct.name = "Direct";
Direct.value = CM_SMALL_ARGB_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
Direct.name = "Direct";
Direct.value = CM_SMALL_ARGB_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Direct.brightness_min = 0;
Direct.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
Direct.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode PassThru;
PassThru.name = "Pass Thru";
PassThru.value = CM_SMALL_ARGB_MODE_PASSTHRU;
PassThru.color_mode = MODE_COLORS_NONE;
PassThru.name = "Pass Thru";
PassThru.value = CM_SMALL_ARGB_MODE_PASSTHRU;
PassThru.color_mode = MODE_COLORS_NONE;
modes.push_back(PassThru);
Init_Controller(); //Only processed on first run
@@ -226,15 +247,15 @@ void RGBController_CMSmallARGBController::DeviceUpdateLEDs()
void RGBController_CMSmallARGBController::UpdateZoneLEDs(int zone)
{
bool random_colours = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
//cmargb->SetLedsDirect(zones[zone].colors, random_colours);
if(serial >= CM_SMALL_ARGB_FW0012)
{
cmargb->SetLedsDirect( zones[zone].colors, zones[zone].leds_count );
}
}
void RGBController_CMSmallARGBController::UpdateSingleLED(int led)
{
//cmargb->SetMode( modes[active_mode].value, modes[active_mode].speed );
//cmargb->SetLedsDirect( zones[0].colors, zones[0].leds_count );
UpdateZoneLEDs(led);
}
void RGBController_CMSmallARGBController::SetCustomMode()
@@ -247,5 +268,5 @@ void RGBController_CMSmallARGBController::DeviceUpdateMode()
bool random_colours = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
RGBColor colour = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) ? modes[active_mode].colors[0] : 0;
cmargb->SetMode( modes[active_mode].value, modes[active_mode].speed, colour, random_colours );
cmargb->SetMode( modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, colour, random_colours);
}
@@ -12,8 +12,10 @@
#include "CMSmallARGBController.h"
#include <vector>
#define CM_SMALL_ARGB_MIN_LEDS 4
#define CM_SMALL_ARGB_MAX_LEDS 48
#define CM_SMALL_ARGB_MIN_LEDS 4
#define CM_SMALL_ARGB_MAX_LEDS 48
#define CM_SMALL_ARGB_BRIGHTNESS_MAX 0xFF
#define CM_SMALL_ARGB_FW0012 "A202104052336"
class RGBController_CMSmallARGBController : public RGBController
{
@@ -0,0 +1,276 @@
/*---------------------------------------------------------*\
| CorsairCommanderCoreController.cpp |
| |
| Processing Code for Corsair Commander Core |
| |
| Jeff P. |
\*---------------------------------------------------------*/
#include "CorsairCommanderCoreController.h"
#include <cstring>
#include <iomanip>
#include <iostream>
using namespace std::chrono_literals;
CorsairCommanderCoreController::CorsairCommanderCoreController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
keepalive_thread_run = 1;
controller_ready = 0;
/*-----------------------------------------------------*\
| Initialize controller |
\*-----------------------------------------------------*/
InitController();
/*-----------------------------------------------------*\
| Start keepalive thread |
\*-----------------------------------------------------*/
keepalive_thread = new std::thread(&CorsairCommanderCoreController::KeepaliveThread, this);
}
CorsairCommanderCoreController::~CorsairCommanderCoreController()
{
/*-----------------------------------------------------*\
| Close keepalive thread |
\*-----------------------------------------------------*/
keepalive_thread_run = 0;
keepalive_thread->join();
delete keepalive_thread;
/*-----------------------------------------------------*\
| Close HID device |
\*-----------------------------------------------------*/
hid_close(dev);
}
void CorsairCommanderCoreController::InitController()
{
/*-----------------------------------------------------*\
| Packet sequence to put controller into direct mode |
\*-----------------------------------------------------*/
unsigned char buffarray[][5] =
{
{0x08, 0x01, 0x03, 0x00, 0x02},
{0x08, 0x0D, 0x00, 0x22, 0x00},
};
SendMultiPkt(buffarray, sizeof(buffarray) / sizeof(buffarray[0]), sizeof(buffarray)[0] / sizeof(buffarray[0][0]));
SetFanMode();
}
std::string CorsairCommanderCoreController::GetLocationString()
{
return("HID: " + location);
}
void CorsairCommanderCoreController::KeepaliveThread()
{
while(keepalive_thread_run.load())
{
if (controller_ready)
{
if((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::seconds(10))
{
SendCommit();
}
}
std::this_thread::sleep_for(1s);
}
}
void CorsairCommanderCoreController::SendCommit()
{
if(!lastcolors.empty())
{
/*-----------------------------------------------------*\
| If colors remain to be sent, send them |
\*-----------------------------------------------------*/
SetDirectColor(lastcolors, lastzones);
}
else
{
unsigned char usb_buf[1025];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Update last commit time |
\*-----------------------------------------------------*/
last_commit_time = std::chrono::steady_clock::now();
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
memset(usb_buf, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
usb_buf[0] = 0x00;
usb_buf[1] = 0x08;
usb_buf[2] = 0x06;
usb_buf[4] = 0xBD;
usb_buf[5] = 0x02;
usb_buf[8] = 0x12;
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
}
}
void CorsairCommanderCoreController::SendMultiPkt(unsigned char buffarray[][5], int r, int c)
{
/*---------------------------------------------------------*\
| Private function to send multiple packets |
\*---------------------------------------------------------*/
unsigned char* hidtemp = new unsigned char[CORSAIR_COMMANDER_CORE_PACKET_SIZE];
for(unsigned int i = 0; i < r; i++)
{
memset(hidtemp, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
for(unsigned int j = 0; j < c; j++)
{
hidtemp[j+1] = buffarray[i][j];
}
hid_write(dev, hidtemp, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
hid_read(dev, hidtemp, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
}
}
void CorsairCommanderCoreController::SetDirectColor
(
std::vector<RGBColor> colors,
std::vector<zone> zones
)
{
if(controller_ready == 1 && ((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::milliseconds(33)))
{
lastcolors = colors;
lastzones = zones;
int packet_offset = CORSAIR_COMMANDER_CORE_PREAMBLE_OFFSET;
int led_idx = 0;
int channel_idx = 0;
unsigned char* usb_buf = new unsigned char[CORSAIR_COMMANDER_CORE_PACKET_SIZE];
memset(usb_buf, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
/*-----------------------------------------------------*\
| Prepare color information packet |
\*-----------------------------------------------------*/
usb_buf[0] = 0x00;
usb_buf[1] = 0x08;
usb_buf[2] = 0x06;
usb_buf[4] = 0xBD;
usb_buf[5] = 0x02;
usb_buf[8] = 0x12;
for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
/*-------------------------------------------------*\
| Add led colors |
\*-------------------------------------------------*/
for(unsigned int i = led_idx; i < led_idx + zones[zone_idx].leds_count; i++)
{
usb_buf[packet_offset] = RGBGetRValue(colors[i]);
usb_buf[packet_offset+1] = RGBGetGValue(colors[i]);
usb_buf[packet_offset+2] = RGBGetBValue(colors[i]);
packet_offset = packet_offset + 3;
}
led_idx = led_idx + zones[zone_idx].leds_count;
/*-------------------------------------------------*\
| Move offset for pump zone with less than 29 LEDs |
\*-------------------------------------------------*/
if(zone_idx == 0)
{
packet_offset = packet_offset + 3 * (29 - zones[zone_idx].leds_count);
}
/*-------------------------------------------------*\
| Move offset for fans with less than 34 LEDs |
\*-------------------------------------------------*/
if(zone_idx != 0)
{
packet_offset = packet_offset + 3 * (34 - zones[zone_idx].leds_count);
}
channel_idx++;
}
/*-----------------------------------------------------*\
| Sending a direct mode color packet resets the timeout |
\*-----------------------------------------------------*/
last_commit_time = std::chrono::steady_clock::now();
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
}
}
void CorsairCommanderCoreController::SetFanMode()
{
/*--------------------------------------------------------------------------------------------------*\
| Force controller to 6 QL fan mode to expose maximum number of LEDs per rgb port (34 LEDs per port) |
\*--------------------------------------------------------------------------------------------------*/
unsigned char usb_buf[1025];
unsigned char buffarray4[][5] =
{
{0x08, 0x05, 0x01, 0x01, 0x00},
{0x08, 0x0D, 0x01, 0x1E, 0x00},
{0x08, 0x09, 0x01, 0x00, 0x00}
};
SendMultiPkt(buffarray4, sizeof(buffarray4) / sizeof(buffarray4[0]), sizeof(buffarray4)[0] / sizeof(buffarray4[0][0]));
memset(usb_buf, 0, sizeof(usb_buf));
usb_buf[0] = 0x00;
usb_buf[1] = 0x08;
usb_buf[2] = 0x06;
usb_buf[3] = 0x01;
usb_buf[4] = 0x11;
usb_buf[8] = 0x0D;
usb_buf[10] = 0x07;
usb_buf[11] = 0x01;
usb_buf[12] = 0x08;
for(unsigned int i = 13; i < 25; i = i + 2)
{
usb_buf[i] = 0x01;
usb_buf[i + 1] = 0x06;
}
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
hid_read(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
unsigned char buffarray2[][5] =
{
{0x08, 0x05, 0x01, 0x01, 0x00},
{0x08, 0x15, 0x01, 0x00, 0x00}
};
SendMultiPkt(buffarray2, sizeof(buffarray2) / sizeof(buffarray2[0]), sizeof(buffarray2)[0] / sizeof(buffarray2[0][0]));
memset(usb_buf, 0, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
usb_buf[0] = 0x00;
usb_buf[1] = 0x08;
usb_buf[2] = 0x06;
usb_buf[4] = 0xBD;
usb_buf[5] = 0x02;
usb_buf[8] = 0x12;
hid_write(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
hid_read(dev, usb_buf, CORSAIR_COMMANDER_CORE_PACKET_SIZE);
controller_ready = 1;
}
@@ -0,0 +1,65 @@
/*---------------------------------------------------------*\
| CorsairCommanderCoreController.h |
| |
| Definitions for Corsair Commander Core |
| Based on code by: |
| Adam Honse (calcprogrammer1@gmail.com), 8/17/2020 |
| |
| Jeff P. |
\*---------------------------------------------------------*/
#include "RGBController.h"
#include <vector>
#include <chrono>
#include <hidapi/hidapi.h>
#pragma once
#define CORSAIR_COMMANDER_CORE_PACKET_SIZE 1025
#define CORSAIR_COMMANDER_CORE_PREAMBLE_OFFSET 10
#define CORSAIR_ELITE_CAPELLIX_PUMP_LED_OFFSET 87
#define CORSAIR_QL_FAN_ZONE_OFFSET 102
#define CORSAIR_COMMANDER_CORE_NUM_CHANNELS 6
enum
{
CORSAIR_COMMANDER_CORE_MODE_DIRECT = 0x00,
};
class CorsairCommanderCoreController
{
public:
CorsairCommanderCoreController(hid_device* dev_handle, const char* path);
~CorsairCommanderCoreController();
std::string GetLocationString();
void SetDirectColor
(
std::vector<RGBColor>,
std::vector<zone>
);
void KeepaliveThread();
void SetFanMode();
private:
hid_device* dev;
std::thread* keepalive_thread;
std::atomic<bool> keepalive_thread_run;
std::atomic<bool> controller_ready;
std::string location;
std::vector<RGBColor> lastcolors;
std::vector<zone> lastzones;
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
void SendMultiPkt
(
unsigned char buffarray[][5],
int r,
int c
);
void SendCommit();
void InitController();
};
@@ -0,0 +1,41 @@
#include "Detector.h"
#include "CorsairCommanderCoreController.h"
#include "RGBController.h"
#include "RGBController_CorsairCommanderCore.h"
#include <vector>
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| Corsair vendor ID |
\*-----------------------------------------------------*/
#define CORSAIR_VID 0x1B1C
/*-----------------------------------------------------*\
| Commander Core product IDs |
\*-----------------------------------------------------*/
#define CORSAIR_H150I_COMMANDER_CORE_PID 0x0C1C
/******************************************************************************************\
* *
* DetectCorsairCapellixControllers *
* *
* Tests the USB address to see if a Corsair RGB Cooler controller exists there. *
* *
\******************************************************************************************/
void DetectCorsairCapellixHIDControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CorsairCommanderCoreController* controller = new CorsairCommanderCoreController(dev, info->path);
RGBController_CorsairCommanderCore* rgb_controller = new RGBController_CorsairCommanderCore(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR_PU("Corsair Commander Core", DetectCorsairCapellixHIDControllers, CORSAIR_VID, CORSAIR_H150I_COMMANDER_CORE_PID, 0xFF42, 0x01);
@@ -0,0 +1,125 @@
/*-----------------------------------------*\
| RGBController_CorsairCapellix.cpp |
| |
| Generic RGB Interface for Corsair |
| Commander Core |
| |
| Jeff P. |
\*-----------------------------------------*/
#include "RGBController_CorsairCommanderCore.h"
RGBController_CorsairCommanderCore::RGBController_CorsairCommanderCore(CorsairCommanderCoreController* corsair_ptr)
{
corsair = corsair_ptr;
vendor = "Corsair";
description = "Corsair Commander Core";
type = DEVICE_TYPE_COOLER;
location = corsair->GetLocationString();
SetupZones();
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);
}
RGBController_CorsairCommanderCore::~RGBController_CorsairCommanderCore()
{
delete corsair;
}
void RGBController_CorsairCommanderCore::SetupZones()
{
std::atomic<bool> first_run;
first_run = 0;
if(zones.size() == 0)
{
first_run = 1;
}
zones.resize(7);
zones[0].name = "Pump";
zones[0].type = ZONE_TYPE_LINEAR;
zones[0].leds_min = 0;
zones[0].leds_max = 29;
for(unsigned int i = 1; i < (CORSAIR_COMMANDER_CORE_NUM_CHANNELS + 1); i++)
{
zones[i].name = "RGB Port " + std::to_string(i);
zones[i].type = ZONE_TYPE_LINEAR;
zones[i].leds_min = 0;
zones[i].leds_max = 34;
if(first_run)
{
zones[i].leds_count = 0;
}
}
leds.clear();
colors.clear();
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 + " LED " + std::to_string(led_idx+1);
leds.push_back(new_led);
}
}
SetupColors();
}
void RGBController_CorsairCommanderCore::ResizeZone(int zone, int new_size)
{
if((size_t) zone >= zones.size())
{
return;
}
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
{
zones[zone].leds_count = new_size;
SetupZones();
}
}
void RGBController_CorsairCommanderCore::DeviceUpdateLEDs()
{
DeviceUpdateMode();
}
void RGBController_CorsairCommanderCore::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_CorsairCommanderCore::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_CorsairCommanderCore::SetCustomMode()
{
active_mode = 0;
}
void RGBController_CorsairCommanderCore::DeviceUpdateMode()
{
switch(modes[active_mode].value)
{
case CORSAIR_COMMANDER_CORE_MODE_DIRECT:
corsair->SetDirectColor(colors, zones);
break;
}
}
@@ -0,0 +1,33 @@
/*-----------------------------------------*\
| RGBController_CorsairCapellix.h |
| |
| Generic RGB Interface for Corsair |
| Commander Core |
| |
| Jeff P. |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CorsairCommanderCoreController.h"
class RGBController_CorsairCommanderCore : public RGBController
{
public:
RGBController_CorsairCommanderCore(CorsairCommanderCoreController* corsair_ptr);
~RGBController_CorsairCommanderCore();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
CorsairCommanderCoreController* corsair;
std::vector<int> fanleds{0};
};
@@ -15,7 +15,7 @@
#include <hidapi/hidapi.h>
#define CORSAIR_HYDRO_PLATINUM_PACKET_SIZE 65
#define CORSAIR_HYDRO_PLATINUM_PACKET_DELAY 3
#define CORSAIR_HYDRO_PLATINUM_PACKET_DELAY 5
enum
{
@@ -64,7 +64,12 @@ std::string CorsairLightingNodeController::GetLocationString()
std::string CorsairLightingNodeController::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, 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());
@@ -72,6 +77,14 @@ std::string CorsairLightingNodeController::GetSerialString()
return(return_string);
}
void CorsairLightingNodeController::SetBrightness(unsigned char brightness)
{
for(unsigned int channel = 0; channel < CORSAIR_LIGHTING_NODE_NUM_CHANNELS; channel++)
{
SendBrightness(channel, brightness);
}
}
void CorsairLightingNodeController::SetChannelEffect(unsigned char channel,
unsigned char num_leds,
unsigned char mode,
@@ -446,9 +459,40 @@ void CorsairLightingNodeController::SendPortState
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SendBrightness()
void CorsairLightingNodeController::SendBrightness
(
unsigned char channel,
unsigned char brightness
)
{
unsigned char usb_buf[65];
/*-----------------------------------------------------*\
| Brightness goes from 0-100 |
\*-----------------------------------------------------*/
if(brightness > 100)
{
brightness = 100;
}
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Port State packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_BRIGHTNESS;
usb_buf[0x02] = channel;
usb_buf[0x03] = brightness;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read(dev, usb_buf, 17);
}
void CorsairLightingNodeController::SendLEDCount()
@@ -88,6 +88,8 @@ public:
unsigned int GetStripsOnChannel(unsigned int channel);
void SetBrightness(unsigned char brightness);
void SetChannelEffect(unsigned char channel,
unsigned char num_leds,
unsigned char mode,
@@ -171,7 +173,11 @@ private:
unsigned char state
);
void SendBrightness();
void SendBrightness
(
unsigned char channel,
unsigned char brightness
);
void SendLEDCount();
@@ -23,145 +23,178 @@ RGBController_CorsairLightingNode::RGBController_CorsairLightingNode(CorsairLigh
serial = corsair->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = 0xFFFF;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
Direct.name = "Direct";
Direct.value = 0xFFFF;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode RainbowWave;
RainbowWave.name = "Rainbow Wave";
RainbowWave.value = CORSAIR_LIGHTING_NODE_MODE_RAINBOW_WAVE;
RainbowWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR;
RainbowWave.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
RainbowWave.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
RainbowWave.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
RainbowWave.direction = MODE_DIRECTION_RIGHT;
RainbowWave.color_mode = MODE_COLORS_NONE;
RainbowWave.name = "Rainbow Wave";
RainbowWave.value = CORSAIR_LIGHTING_NODE_MODE_RAINBOW_WAVE;
RainbowWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
RainbowWave.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
RainbowWave.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
RainbowWave.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
RainbowWave.direction = MODE_DIRECTION_RIGHT;
RainbowWave.color_mode = MODE_COLORS_NONE;
RainbowWave.brightness_min = 0;
RainbowWave.brightness_max = 100;
RainbowWave.brightness = 100;
modes.push_back(RainbowWave);
mode ColorShift;
ColorShift.name = "Color Shift";
ColorShift.value = CORSAIR_LIGHTING_NODE_MODE_COLOR_SHIFT;
ColorShift.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
ColorShift.colors_min = 2;
ColorShift.colors_max = 2;
ColorShift.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
ColorShift.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
ColorShift.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
ColorShift.color_mode = MODE_COLORS_MODE_SPECIFIC;
ColorShift.name = "Color Shift";
ColorShift.value = CORSAIR_LIGHTING_NODE_MODE_COLOR_SHIFT;
ColorShift.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
ColorShift.colors_min = 2;
ColorShift.colors_max = 2;
ColorShift.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
ColorShift.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
ColorShift.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
ColorShift.color_mode = MODE_COLORS_MODE_SPECIFIC;
ColorShift.colors.resize(2);
ColorShift.brightness_min = 0;
ColorShift.brightness_max = 100;
ColorShift.brightness = 100;
modes.push_back(ColorShift);
mode ColorPulse;
ColorPulse.name = "Color Pulse";
ColorPulse.value = CORSAIR_LIGHTING_NODE_MODE_COLOR_PULSE;
ColorPulse.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
ColorPulse.colors_min = 2;
ColorPulse.colors_max = 2;
ColorPulse.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
ColorPulse.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
ColorPulse.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
ColorPulse.color_mode = MODE_COLORS_MODE_SPECIFIC;
ColorPulse.name = "Color Pulse";
ColorPulse.value = CORSAIR_LIGHTING_NODE_MODE_COLOR_PULSE;
ColorPulse.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
ColorPulse.colors_min = 2;
ColorPulse.colors_max = 2;
ColorPulse.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
ColorPulse.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
ColorPulse.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
ColorPulse.color_mode = MODE_COLORS_MODE_SPECIFIC;
ColorPulse.colors.resize(2);
ColorPulse.brightness_min = 0;
ColorPulse.brightness_max = 100;
ColorPulse.brightness = 100;
modes.push_back(ColorPulse);
mode ColorWave;
ColorWave.name = "Color Wave";
ColorWave.value = CORSAIR_LIGHTING_NODE_MODE_COLOR_WAVE;
ColorWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
ColorWave.colors_min = 2;
ColorWave.colors_max = 2;
ColorWave.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
ColorWave.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
ColorWave.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
ColorWave.direction = MODE_DIRECTION_RIGHT;
ColorWave.color_mode = MODE_COLORS_MODE_SPECIFIC;
ColorWave.name = "Color Wave";
ColorWave.value = CORSAIR_LIGHTING_NODE_MODE_COLOR_WAVE;
ColorWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
ColorWave.colors_min = 2;
ColorWave.colors_max = 2;
ColorWave.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
ColorWave.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
ColorWave.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
ColorWave.direction = MODE_DIRECTION_RIGHT;
ColorWave.color_mode = MODE_COLORS_MODE_SPECIFIC;
ColorWave.colors.resize(2);
ColorWave.brightness_min = 0;
ColorWave.brightness_max = 100;
ColorWave.brightness = 100;
modes.push_back(ColorWave);
mode Static;
Static.name = "Static";
Static.value = CORSAIR_LIGHTING_NODE_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.name = "Static";
Static.value = CORSAIR_LIGHTING_NODE_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Static.colors_min = 1;
Static.colors_max = 1;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors.resize(1);
Static.brightness_min = 0;
Static.brightness_max = 100;
Static.brightness = 100;
modes.push_back(Static);
mode Temperature;
Temperature.name = "Temperature";
Temperature.value = CORSAIR_LIGHTING_NODE_MODE_TEMPERATURE;
Temperature.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Temperature.colors_min = 3;
Temperature.colors_max = 3;
Temperature.color_mode = MODE_COLORS_MODE_SPECIFIC;
Temperature.name = "Temperature";
Temperature.value = CORSAIR_LIGHTING_NODE_MODE_TEMPERATURE;
Temperature.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Temperature.colors_min = 3;
Temperature.colors_max = 3;
Temperature.color_mode = MODE_COLORS_MODE_SPECIFIC;
Temperature.colors.resize(3);
Temperature.brightness_min = 0;
Temperature.brightness_max = 100;
Temperature.brightness = 100;
modes.push_back(Temperature);
mode Visor;
Visor.name = "Visor";
Visor.value = CORSAIR_LIGHTING_NODE_MODE_VISOR;
Visor.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Visor.colors_min = 2;
Visor.colors_max = 2;
Visor.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
Visor.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
Visor.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
Visor.color_mode = MODE_COLORS_MODE_SPECIFIC;
Visor.name = "Visor";
Visor.value = CORSAIR_LIGHTING_NODE_MODE_VISOR;
Visor.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Visor.colors_min = 2;
Visor.colors_max = 2;
Visor.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
Visor.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
Visor.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
Visor.color_mode = MODE_COLORS_MODE_SPECIFIC;
Visor.colors.resize(2);
Visor.brightness_min = 0;
Visor.brightness_max = 100;
Visor.brightness = 100;
modes.push_back(Visor);
mode Marquee;
Marquee.name = "Marquee";
Marquee.value = CORSAIR_LIGHTING_NODE_MODE_MARQUEE;
Marquee.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Marquee.colors_min = 1;
Marquee.colors_max = 1;
Marquee.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
Marquee.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
Marquee.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
Marquee.direction = MODE_DIRECTION_RIGHT;
Marquee.color_mode = MODE_COLORS_MODE_SPECIFIC;
Marquee.name = "Marquee";
Marquee.value = CORSAIR_LIGHTING_NODE_MODE_MARQUEE;
Marquee.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Marquee.colors_min = 1;
Marquee.colors_max = 1;
Marquee.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
Marquee.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
Marquee.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
Marquee.direction = MODE_DIRECTION_RIGHT;
Marquee.color_mode = MODE_COLORS_MODE_SPECIFIC;
Marquee.colors.resize(1);
Marquee.brightness_min = 0;
Marquee.brightness_max = 100;
Marquee.brightness = 100;
modes.push_back(Marquee);
mode Blink;
Blink.name = "Blink";
Blink.value = CORSAIR_LIGHTING_NODE_MODE_BLINK;
Blink.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Blink.colors_min = 2;
Blink.colors_max = 2;
Blink.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
Blink.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
Blink.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
Blink.color_mode = MODE_COLORS_MODE_SPECIFIC;
Blink.name = "Blink";
Blink.value = CORSAIR_LIGHTING_NODE_MODE_BLINK;
Blink.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Blink.colors_min = 2;
Blink.colors_max = 2;
Blink.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
Blink.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
Blink.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
Blink.color_mode = MODE_COLORS_MODE_SPECIFIC;
Blink.colors.resize(2);
Blink.brightness_min = 0;
Blink.brightness_max = 100;
Blink.brightness = 100;
modes.push_back(Blink);
mode Sequential;
Sequential.name = "Sequential";
Sequential.value = CORSAIR_LIGHTING_NODE_MODE_SEQUENTIAL;
Sequential.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
Sequential.colors_min = 1;
Sequential.colors_max = 1;
Sequential.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
Sequential.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
Sequential.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
Sequential.direction = MODE_DIRECTION_RIGHT;
Sequential.color_mode = MODE_COLORS_MODE_SPECIFIC;
Sequential.name = "Sequential";
Sequential.value = CORSAIR_LIGHTING_NODE_MODE_SEQUENTIAL;
Sequential.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Sequential.colors_min = 1;
Sequential.colors_max = 1;
Sequential.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
Sequential.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
Sequential.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
Sequential.direction = MODE_DIRECTION_RIGHT;
Sequential.color_mode = MODE_COLORS_MODE_SPECIFIC;
Sequential.colors.resize(1);
Sequential.brightness_min = 0;
Sequential.brightness_max = 100;
Sequential.brightness = 100;
modes.push_back(Sequential);
mode Rainbow;
Rainbow.name = "Rainbow";
Rainbow.value = CORSAIR_LIGHTING_NODE_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED;
Rainbow.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
Rainbow.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
Rainbow.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
Rainbow.color_mode = MODE_COLORS_NONE;
Rainbow.name = "Rainbow";
Rainbow.value = CORSAIR_LIGHTING_NODE_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Rainbow.speed_min = CORSAIR_LIGHTING_NODE_SPEED_SLOW;
Rainbow.speed_max = CORSAIR_LIGHTING_NODE_SPEED_FAST;
Rainbow.speed = CORSAIR_LIGHTING_NODE_SPEED_MEDIUM;
Rainbow.color_mode = MODE_COLORS_NONE;
Rainbow.brightness_min = 0;
Rainbow.brightness_max = 100;
Rainbow.brightness = 100;
modes.push_back(Rainbow);
SetupZones();
@@ -324,4 +357,13 @@ void RGBController_CorsairLightingNode::DeviceUpdateMode()
mode_colors[8]);
}
}
if(modes[active_mode].flags & MODE_FLAG_HAS_BRIGHTNESS)
{
corsair->SetBrightness(modes[active_mode].brightness);
}
else
{
corsair->SetBrightness(100);
}
}
@@ -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

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