Compare commits

...
Author SHA1 Message Date
Adam Honse 0cfc5a12b1 Remove unused string 2023-10-19 20:05:46 -05:00
Adam Honse 6d8fb3348a Hack to get ENE SMBus settings added to the list 2023-10-19 20:03:45 -05:00
Adam Honse 0fd6893ee5 Enable saving of integer and string settings 2023-10-19 20:03:45 -05:00
Adam Honse 60d42b118e Enable saving of boolean settings 2023-10-19 20:03:45 -05:00
Adam Honse bb4c56af2d Enable group, integer, and string types but changing settings does not work 2023-10-19 20:03:45 -05:00
Adam Honse 67ae1a2078 Implement dynamic Settings Manager UI 2023-10-19 20:03:45 -05:00
Chris M d4b2d3c381 Initial commit for the Corsair K70 Pro TKL keyboard
* Adding key layout and metadata to CorsairPeripheralV2Devices.cpp
* Adding lighting control endpoint check
* Adding new detector
* Small style fixes
* Resolves #3260
2023-10-20 07:16:01 +11:00
Bernhard M. Wiedemann dfff062bc6 Avoid corruption in 60-openrgb.rules
Due to the missing line-break before DUMMY_LIST
it would replace whatever was the first entry in there.

* Resolves #3675

This patch was done while working on reproducible builds for openSUSE.
2023-10-19 16:40:31 +00:00
Bernhard M. Wiedemann cd4004dce2 Reduce use of grep
because find can return us the same 240 wanted files.
2023-10-19 16:36:43 +00:00
Bernhard M. Wiedemann 9ac44192bc Skip empty detectors
Without this patch, output had ugly messages

    Usage: grep [OPTION]... PATTERNS [FILE]...
    Try 'grep --help' for more information.

and with the patch, the rule file is more readable
because it omits

-# Logitech Powerplay Mat -
-#---------------------------------------------------------------#
-#---------------------------------------------------------------#

-# Quantum Mechanical Keyboard (QMK) -
-#---------------------------------------------------------------#
-#---------------------------------------------------------------#
2023-10-19 16:36:43 +00:00
Bernhard M. Wiedemann a7920c01d7 Avoid grep warning
without this patch, output contained

    grep: warning: stray \ before white space
2023-10-19 16:36:43 +00:00
morg 56da121746 GigabyteRGBFusion2GPUController: fix a snprintf call 2023-10-19 16:30:17 +00:00
Bernhard M. Wiedemann 679e69be89 Ensure functions return a value
otherwise, gcc errored out
because non-void functions are supposed to return a value.

Alternatively, we could change the declaration to `void`.
2023-10-19 06:03:05 +02:00
morg c8c5f77595 Add support for Bloody W90 MAX. Closes #3500 2023-10-18 22:43:17 +00:00
Adam Honse 5ce430c062 Fix image links in README to point to the standalone wiki repo 2023-10-18 11:37:59 -05:00
Adolfo R. Brandes a1ee0d39b8 Add another variant of the Asus TUF Gaming RTX 4090 O24G 2023-10-18 06:56:43 -03:00
Bryan Perry 48f78f18d4 Support MSI RTX 4060Ti 8GB Gaming X - Closes #3677 2023-10-17 19:12:57 -05:00
Marek Sapota b91fb9c322 Fix TP-Link Kasa Smart Bulbs on some 64bit systems 2023-10-17 23:53:16 +00:00
Adolfo R. Brandes de08b82ebe debian: update packaging instructions 2023-10-17 22:28:33 +00:00
Adolfo R. Brandes 6308e06586 debian: Don't fail udevadm trigger 2023-10-17 22:27:59 +00:00
morg f34f8e1bb6 RGBFusion2GPUController: eliminate dead code + code guidelines 2023-10-15 17:56:08 +02:00
thombo 00c92d74a7 Support for MSI board 7E12 added 2023-10-15 09:13:43 +00:00
Nathaniel Fung 306b1ddcb3 Add Sapphire NITRO+ AMD Radeon RX 7800 XT 2023-10-15 06:06:54 +00:00
Chris M 33db866d04 Initial commit for Razer Razer Blackwidow V4 Pro
+ Adding PID for the Razer Blackwidow V4 Pro
+ Registered detectors
+ Added metadata to RazerDevices.cpp
+ Added capabilities to RazerController.cpp
+ Resolves #3636
2023-10-15 10:33:48 +11:00
morg 7827a184f7 AlienWare controller: add alternate platform id for G15 5511. #437 2023-10-14 20:14:37 +00:00
morg af73e63d7a Add support for LG 27GN950-B monitor. Closes #1008 2023-10-13 08:43:51 +02:00
Adam Honse d0b76760f4 Remove unnecessary SettingsManager.h includes 2023-10-12 23:37:48 -05:00
Chris M d7c8ac2f8d Initial commit for Razer Deathstalker V2 Pro TKL
+ Adding PID for the Deathstalker V2 Pro TKL
+ Registered detectors
+ Added metadata to RazerDevices.cpp
+ Added capabilities to RazerController.cpp
+ Resolves #3327
2023-10-13 06:49:56 +11:00
Mark Hermeling f3d9877598 Copy paste fixes 2023-10-12 13:31:36 +00:00
Adam Honse 8d19ceff95 Remove OpenRazer/OpenRazer-Win32 support as it is unmaintained and replaced by RazerController 2023-10-11 22:22:48 -05:00
Adam Honse f76e8f65a5 Add Razer Mamba Hyperflux (Wired) 2023-10-11 12:37:16 -05:00
Adam Honse 447ed4cef7 Fix various issues with Razer Firefly Hyperflux 2023-10-11 01:21:28 +00:00
misaka10032w 8955d69a11 Add colorful igame 4090adoc OC mode bios config 2023-10-10 16:38:33 +08:00
Lucas Mindêllo de Andrade f7eb61614e iGame Turing GPU with Direct mode without persistence 2023-10-07 02:24:13 +00:00
Chris M 9e75a68008 Fixed mode declaration in RGBController_MSIVigorGK30.cpp
* Resolves #3651
2023-10-06 19:13:35 +11:00
Adam Honse 0b787ebb3c Add serial implementation of HYTE CNVS mousemat controller for Windows and leave libusb implementation for Linux 2023-10-06 00:36:30 -05:00
Adam Honse 1b7cff78eb Limit HYTE CNVS brightness to 72% of maximum brightness according to V1.1 of protocol documentation. It could be reworked in the future to only limit brightness when the sum exceeds the value, but that would require significantly more math during update 2023-10-05 19:24:40 -05:00
Jonathan Guzmán 6e0358d6ea Add Lenovo legion 5 udev rules detection 2023-10-03 13:09:57 +00:00
Fan Yu 9f653577cd Initial commit for PNY_RTX_4090_XLR8_SUB_DEV 2023-10-03 04:11:01 +00:00
Adam Honse 362a31abbd Update wiki links in the README 2023-10-01 23:55:03 -05:00
Adam Honse d7ed55b264 Use size when parsing received buffers into strings in NetworkServer 2023-10-01 22:43:32 -05:00
Mola19 af53230244 Disable "Apply All Devices" button, if mode is not a custom mode 2023-10-02 02:41:22 +00:00
Jonathan Guzmán 16b5768736 fix "LENOVO_USEAGE" typo 2023-09-30 05:05:26 +00:00
Jonathan Guzmán caf26cc315 add new legion 5 devices 2023-09-29 05:57:45 +00:00
Chris M 2f0d722b83 Adjusting the Keyrox TKL layout
* Accounting for the KLM change in commit f6940640
2023-09-28 21:14:00 +10:00
morg fc14cf102f Add support for MSI GeForce RTX 3060 Ti 8GB Gaming X Trio 2023-09-27 19:44:26 +00:00
Ilkka Jylhä 4c7f92b491 Initial commit for Asus ROG Strix LC RTX 3090Ti OC 2023-09-27 17:55:30 +00:00
morg f8c20128ef Plugin manager: simplifies code, fixes a crash on exit 2023-09-27 15:31:54 +02:00
Adam Honse 41b7dc3102 Show incompatible plugins in the Plugins settings page with a note that it is incompatible, allow it to be removed 2023-09-26 23:41:33 -05:00
Adam Honse c6408eb752 Add SDK Version and Plugin API Version to Information Settings tab 2023-09-26 21:14:27 -05:00
Ilkka Jylhä 12166cbe93 Initial commit for Asus RX 7800 XT White OC 2023-09-26 19:48:34 +00:00
morg 0c6944bb8d CoolerMaster ARGB controller: fix crash on rescan 2023-09-26 15:45:29 +00:00
morg 22b8cdbe01 GigabyteAorusLaptopController: Add brightness support for custom mode 2023-09-26 15:38:26 +02:00
SHISEN 0f41d7443a Initial commit for MSI GeForce RTX 3060 Ti 8GB SUPER 3X OC 2023-09-25 14:37:11 +00:00
morg 46a8c06bfe CMMonitor driver udpates 2023-09-24 22:09:11 +00:00
Martin Nygaard Jensen e83ca276c0 Update AnnePro2ControllerDetect.cpp missing PID 0xA297 2023-09-22 20:37:26 +00:00
morg e2874a64a1 Add support for TUF RTX 4070 O12G GAMING variant 2023-09-22 17:40:58 +02:00
Jefemy 39d4afac20 Add support for alternative ASUS TUF 4070ti OC + non OC device ids 2023-09-22 13:10:28 +00:00
morg 86ba18595f Add support for CoolerMaster GM27. Closes #3627 2023-09-21 16:23:45 +00:00
morg 3c7a24c4c1 Add support for Gainward GeForce RTX3070 Phantom 2023-09-21 17:11:08 +02:00
Mola19 ddc2b7f5e8 Fix duplicate destructor in AsusAuraMainboard 2023-09-21 03:00:27 +02:00
morg 8addcde754 Add support for Gigabyte AORUS laptops. #3403 2023-09-20 01:23:13 +00:00
Adam Honse 85d6225a7c Add NZXT F140 RGB fan (140mm) device with ID 0x18 2023-09-19 22:30:22 +00:00
Codename-Antares 0cebf42857 Initial Commit for MSI RTX 3060 Ti Gaming X 2023-09-19 18:27:47 +00:00
Adam Honse 340083bc33 Initial commit for ASUS ROG Arion external NVMe SSD enclosure 2023-09-19 04:37:51 +00:00
Ilkka Jylhä 30b12c67b2 Initial commit for ASUS ROG Strix NVIDIA GeForce RTX 3090 OC EVA EDITION 2023-09-18 14:39:50 -05:00
Ilkka Jylhä 3199f33efb Initial commit for Asus TUF RTX 3080 V2 10GB 2023-09-18 18:42:03 +00:00
Chris M af673e7ec0 Fix missing include in Arctic controller from 4e14f035
* Missing standard library `algorithm` preventing Windows CI/CD builds
from completing.
2023-09-18 23:14:21 +10:00
Ilkka Jylhä d16ec6f0b1 Initial commit for Asus TUF Gaming Geforce RTX 4060 Ti OC 2023-09-17 19:32:40 +00:00
Ilkka Jylhä 2799e9435d Initial commit for ASUS TUF Gaming Radeon RX 7800 XT 2023-09-17 19:10:59 +00:00
Adam Honse 53d2321698 Fix issue in ArcticController where it was trying to create a variable-length buffer and breaking Windows build 2023-09-16 23:37:54 -05:00
Armin Wolf 4e14f0359d Add support for Arctic RGB Controller
The Arctic RGB controller support 4 RGB channel and can be controlled
over a CH341 USB-to-serial chip. The controller support two commands,
one for identifying the controller on a serial port and one for setting
the RGB values for each RGB channel. Since the controllers disables the
RGB channels after ~1s, a keepalive thread is used.
2023-09-16 23:21:21 -05:00
Armin Wolf fa52f4d7e0 Disable input and output processing on Unix serial ports
Disabling output processing is necessary since otherwise
sending a LF character (ASCII 0x0A) will automatically insert
a CR character (ASCII 0x0D).
Disabling input processing should prevent this when
receiving data.
2023-09-16 23:14:49 -05:00
Armin Wolf 0279aafb97 Allow for setting DTR on a serial port 2023-09-16 23:14:49 -05:00
Chris M 1996d34650 Updated Debug Keyboard to process KLM Opcodes
* Added InsertRow, RemoveRow and RemoveKey opcodes.
* Adjusted iterator for style and formatting.
2023-09-17 10:36:29 +10:00
Le Philousophe ccb20f3930 Add Champion's Bane and Ironclad suport 2023-09-16 16:29:46 +00:00
Chris M 3d8c11ea88 Initial commit for Razer Razer Blackwidow V4 X
+ Adding PID for the Razer Blackwidow V4 X
+ Registered detectors
+ Added metadata to RazerDevices.cpp
+ Added capabilities to RazerController.cpp
+ Resolves #3602
2023-09-16 16:13:16 +00:00
Chris M 197d19a070 Corrected KLM log messages
* Moved SwapOnly opcode message to cover "unused" case
* Adjusted Size switch statement to account for non standard sizes
* Fixed InsertRow opcode insertion index
* Corrected RemoveRow opcode to ensure removal didn't skip keys
* Small formatting and style fixes
2023-09-16 23:45:18 +10:00
Beebles 4d73e0264a Add Support for SteelSeries QCK Prism XL Neo Noir Ed 2023-09-15 23:14:21 -05:00
Michal Stawinski a30323f22f Fix "--client" option not working
This fixes "Error: Invalid option: 172.17.0.1" error
that made it impossible to use openrgb with remote
servers.
2023-09-15 21:49:20 -05:00
rytypete e55da57f46 Add Asus USB Motherboard save and shutdown effect support 2023-09-14 22:01:52 +00:00
rytypete 479b8e8ea4 Treat Gainward GeForce RTX 3060 Ti Ghost as RGB 2023-09-13 14:04:18 +02:00
Martin 1fbbbb00ba Add support for the ASUS TUF RTX 4090 O24G OG OC
Added support for the ASUS TUF RTX 4090 O24G OG OC and tested it with my own card.
2023-09-12 18:39:53 -05:00
Sandipan Das a934c4c034 i2c-smbus: linux: Remove stray whitespaces
Remove stray whitespaces in newlines.

Signed-off-by: Sandipan Das <[email protected]>
2023-09-12 08:43:28 -05:00
Sandipan Das 49a6905ab5 i2c-smbus: linux: Fix interface detection
There are cases where detection of an interface fails due to lack of
permissions when accessing /dev/i2c-*. In some instances, the current
code will perform a double readdir() and skip what should have been
the next interface to be enumerated.

E.g. consider a system with the following configuration

  $ ls -l /sys/bus/i2c/devices

  total 0
  lrwxrwxrwx. 1 root 0 Sep  4 07:19 i2c-0 -> ../../../devices/platform/AMDI0010:03/i2c-0/
  lrwxrwxrwx. 1 root 0 Sep  4 01:49 i2c-1 -> ../../../devices/pci0000:00/0000:00:08.1/0000:03:00.0/i2c-1/
  lrwxrwxrwx. 1 root 0 Sep  4 01:50 i2c-10 -> ../../../devices/pci0000:00/0000:00:14.0/i2c-10/
  lrwxrwxrwx. 1 root 0 Sep  4 01:49 i2c-2 -> ../../../devices/pci0000:00/0000:00:08.1/0000:03:00.0/i2c-2/
  lrwxrwxrwx. 1 root 0 Sep  4 01:49 i2c-3 -> ../../../devices/pci0000:00/0000:00:08.1/0000:03:00.0/i2c-3/
  lrwxrwxrwx. 1 root 0 Sep  4 01:49 i2c-4 -> ../../../devices/pci0000:00/0000:00:08.1/0000:03:00.0/i2c-4/
  lrwxrwxrwx. 1 root 0 Sep  4 01:49 i2c-5 -> ../../../devices/pci0000:00/0000:00:08.1/0000:03:00.0/drm/card1/card1-eDP-1/i2c-5/
  lrwxrwxrwx. 1 root 0 Sep  4 01:49 i2c-6 -> ../../../devices/pci0000:00/0000:00:08.1/0000:03:00.0/drm/card1/card1-DP-1/i2c-6/
  lrwxrwxrwx. 1 root 0 Sep  4 01:49 i2c-7 -> ../../../devices/pci0000:00/0000:00:08.1/0000:03:00.0/drm/card1/card1-DP-2/i2c-7/
  lrwxrwxrwx. 1 root 0 Sep  4 01:50 i2c-8 -> ../../../devices/pci0000:00/0000:00:14.0/i2c-8/
  lrwxrwxrwx. 1 root 0 Sep  4 01:50 i2c-9 -> ../../../devices/pci0000:00/0000:00:14.0/i2c-9/
  lrwxrwxrwx. 1 root 0 Sep  4 07:19 i2c-PNP0C50:0e -> ../../../devices/platform/AMDI0010:03/i2c-0/i2c-PNP0C50:0e/

  $ openrgb --verbose --list-devices

Before:

  ...
  Registering I2C interface: /dev/i2c-3 Device 1002:164C Subsystem: 1462:130C
  Registering I2C interface: /dev/i2c-10 Device 1022:790B Subsystem: 1462:130C
  Registering I2C interface: /dev/i2c-1 Device 1002:164C Subsystem: 1462:130C
  Registering I2C interface: /dev/i2c-8 Device 1022:790B Subsystem: 1462:130C
  [i2c_smbus_linux] Failed to read i2c device PCI device ID
  Registering I2C interface: /dev/i2c-6 Device 0000:0000 Subsystem: 0000:0000
  Registering I2C interface: /dev/i2c-4 Device 1002:164C Subsystem: 1462:130C
  [i2c_smbus_linux] Failed to read i2c device PCI device ID
  Registering I2C interface: /dev/i2c-PNP0C50:0e Device 0000:0000 Subsystem: 0000:0000
  Registering I2C interface: /dev/i2c-0 Device 0000:0000 Subsystem: 0000:0000
  Registering I2C interface: /dev/i2c-9 Device 1022:790B Subsystem: 1462:130C
  [i2c_smbus_linux] Failed to read i2c device PCI device ID
  Registering I2C interface: /dev/i2c-7 Device 0000:0000 Subsystem: 0000:0000
  [i2c_smbus_linux] Failed to read i2c device PCI device ID
  Registering I2C interface: /dev/i2c-5 Device 0000:0000 Subsystem: 0000:0000
  ...

After:

  ...
  Registering I2C interface: /dev/i2c-3 Device 1002:164C Subsystem: 1462:130C
  Registering I2C interface: /dev/i2c-10 Device 1022:790B Subsystem: 1462:130C
  Registering I2C interface: /dev/i2c-1 Device 1002:164C Subsystem: 1462:130C
  Registering I2C interface: /dev/i2c-8 Device 1022:790B Subsystem: 1462:130C
  [i2c_smbus_linux] Failed to read i2c device PCI device ID
  Registering I2C interface: /dev/i2c-6 Device 0000:0000 Subsystem: 0000:0000
  Registering I2C interface: /dev/i2c-4 Device 1002:164C Subsystem: 1462:130C
  [i2c_smbus_linux] Failed to read i2c device PCI device ID
  Registering I2C interface: /dev/i2c-PNP0C50:0e Device 0000:0000 Subsystem: 0000:0000
  Registering I2C interface: /dev/i2c-2 Device 1002:164C Subsystem: 1462:130C
  Registering I2C interface: /dev/i2c-0 Device 0000:0000 Subsystem: 0000:0000
  Registering I2C interface: /dev/i2c-9 Device 1022:790B Subsystem: 1462:130C
  [i2c_smbus_linux] Failed to read i2c device PCI device ID
  Registering I2C interface: /dev/i2c-7 Device 0000:0000 Subsystem: 0000:0000
  [i2c_smbus_linux] Failed to read i2c device PCI device ID
  Registering I2C interface: /dev/i2c-5 Device 0000:0000 Subsystem: 0000:0000
  ...

Signed-off-by: Sandipan Das <[email protected]>
2023-09-12 08:43:28 -05:00
foul11 f5dc4a62c4 allow editing individual keys for ASUS ROG Strix SCAR 17 2023-09-11 21:00:42 +00:00
Pedro Martello 10e53074b2 Support for ASUS TUF RTX 4070 12G Gaming graphics card 2023-09-08 23:03:25 +00:00
Peter Repukat 96dd52a5e9 Fix k95_plat iso key mapping 2023-09-07 02:52:44 +02:00
thombo a42b55f391 Support for MSI board 7D40 added 2023-09-05 21:10:28 +02:00
c10l 7471dad28f Add missing build dependency to README 2023-09-05 01:08:46 +00:00
MmAaXx500 824cd7e3fa Fix Corsair Hydro udev rules 2023-09-04 17:05:07 +00:00
Arcitec b452110b43 Fix serial numbers from buggy ASUS keyboard firmwares
* ASUS firmware bugs sometimes return trailing garbage after the serial number. This new algorithm cleans up the garbage by only allowing legal, lower-ASCII characters, so that OpenRGB can accurately identify keyboards that have buggy firmwares.
2023-09-03 17:15:12 +02:00
Arcitec 21092ef7e0 Rename ASUS keyboard matrix layouts to language-independent identifiers
* Makes it clearer which layouts people should be using when contributing new languages or new ASUS hardware.
2023-09-03 17:15:12 +02:00
Arcitec d6bccc42e4 Add support for ASUS ROG Strix Scope II 96 Wireless
* USB Mode: Keyboard is fully mapped out and accurately represented in the LED matrix. Supports US, UK and Nordic layouts.

* Bluetooth Mode: Hardware does not support RGB control via Bluetooth, nothing can be done about that.

* 2.4GHz Mode: This keyboard uses the new "ASUS Omni Receiver" hardware, which is a new multi-device dongle which can pair with multiple keyboards and mice. Requires separate reverse engineering in the future. Not supported at the moment.
2023-09-03 17:15:12 +02:00
Arcitec a909818406 Accurate character labels in Nordic KBD layout
* The previous layout was not the real Nordic layout. Every character has now been fixed to use the correct, technical terms and accurate key legends. It now correctly represents the Nordic ISO layout standard.
2023-09-03 17:15:12 +02:00
chrabonschcz 1d30f2674a Fixed OpenRGB not building for Debian Buster 2023-09-02 18:00:56 +00:00
rytypete 74e1df4cd1 Indicate effects and save support for Asus ROG Ally 2023-09-02 13:09:14 +02:00
misaka10032w f3e5757295 Add support for Colorful iGame GeForce RTX 4090 Advanced OC 2023-09-02 00:24:14 +00:00
Cooper Hall 4c5f5c408f fixed a compiler error on some compiler instances related to KeyboardLayoutManager 2023-09-02 00:21:35 +00:00
Chris 348d2d8241 Fixed typo regression introduced in 479c2b2d
* Combined definition of ZET_FURY_PRO_PID & GENESIS_XENON_200_PID
* Adjusted formatting and style of detectors
2023-08-31 02:19:08 +00:00
TheRogueZeta 16f471db69 Add alternate ID for ROG-STRIX-RTX4090-O24G 2023-08-30 04:48:43 +00:00
Tam D 879153d478 Coolermaster keyboard device view 2023-08-30 03:57:45 +00:00
YaketyYakumo 962d2e8449 Fixed 1080Ti FTW3 backplate 2023-08-30 01:18:33 +00:00
Chris M de0437e164 Initial commit for the Corsair Dark Core SE mouse
* Adding LED layout and metadata to CorsairPeripheralV2Devices
* Adding new detector
* Resolves #1009
2023-08-29 12:21:04 +10:00
chrabonschcz 479c2b2dae Added Controller for Genesis Xenon 200 Mouse 2023-08-29 00:54:56 +00:00
Ben Miller 6c8da3a04f Implement Global Corsair Mutex 2023-08-28 13:48:17 +00:00
Perroboc 6b9aef10a9 Fix: [Epomaker TH80 Pro] Windows compat fix 2023-08-28 13:20:03 +00:00
Mola19 0969b5d24e support for Roccat Sense Aimo Mousepad (Mid and XXL) to resolve #2770 2023-08-24 18:47:12 +02:00
Chris M 9df7023b73 Adjusted Razer Basilisk V3 Pro metadata to light all LEDs
* Resolves #3537
2023-08-22 13:47:53 +10:00
Dmitry K c98464d9df Sinowealth detector cleaned and broken down to atomic units 2023-08-21 05:16:23 +00:00
Mola19 f3763a1b5c fix crash on rescan with Asus ROG Spatha X 2023-08-20 20:32:07 +00:00
Fn Eh eaff85af92 More ZOTAC stuff. Crash fix, and add a new card. 2023-08-20 20:22:51 +00:00
Mola19 756ceb2471 Add support for Asus ROG Sagaris GK1100 (only for non-modifier keys) 2023-08-20 22:14:25 +02:00
Pornvibool Tippayawat 100e954cef Add Support for ASUS TUF RX 7900XTX O24G GAMING 2023-08-18 10:55:27 +00:00
Peter Vazny 839701fcf8 Adds support for ANSI Lenovo Legion 7 Gen 7 2023-08-16 15:35:58 +00:00
Fn Eh e4c0979951 Zotac Metadata 2023-08-16 04:02:41 +00:00
Mola19 16b4235758 fix brightness of some Asus Aura Mice 2023-08-15 23:56:40 +00:00
morg e6b16ff7c4 Add support for Logitech G203 mouse variant 2023-08-14 15:03:56 +00:00
morg de21aca3ef LegoDimensionsToypad: fix crash when changing hw mode to direct 2023-08-14 08:08:20 +02:00
Chris M 2777c05907 Adding OPCODE "Insert Row" to KLM
* Insert Row OPCODE requires a row taken from the provided key
* Insert Row will insert provided key if the row insert was successful.
* Provide "UNUSED" key for an empty row insert.
2023-08-13 09:42:53 +10:00
TheRogueZeta a276ceedb3 Add additional ASUS TUF 4090 O24G Gaming device ID for PN: 90YV0IE-MVAA00 2023-08-11 05:25:22 +00:00
Fn Eh 2082283646 Adds support for three additional Zotac card... 2023-08-10 16:59:40 +00:00
Chris 593506219c Initial commit for the Corsair M65 Ultra RGB mouse
* Adding key layout and metadata to CorsairPeripheralV2Devices.cpp
* Adding new detector
* Resolves #3261
2023-08-09 17:57:06 +10:00
Chris 4fbcf883fe Initial commit for the Corsair Dark Core Pro SE mouse
* Reworked wireless Corsair Slipstream detection to be generic for all devices
* Adding key layout and metadata to CorsairPeripheralV2Devices.cpp
* Adding new detector
2023-08-09 04:15:09 +00:00
Mola19 64c2cc579f fix Asus ROG Spatha X Dock 2023-08-09 03:43:03 +00:00
morg c3b7d4ac1d Add support for ASUS ROG STRIX RTX 4080 O16G GAMING variant 2023-08-08 17:10:42 +00:00
Adam Honse 7fc3e297f1 Add NZXT F120 fan (0x13) 2023-08-08 11:39:41 -05:00
Quentin Ormancey 72ebc26baa Initial commit for ROG Strix GeForce RTX 4070 Ti 12GB GDDR6X OC Edition 2023-08-03 04:09:46 +00:00
Mola19 cd000218b1 move Asus ROG Strix Scope and Scope RX to AsusAuraTUFKeyboardController to add missing features 2023-08-02 02:27:55 +02:00
morg 4835739198 Make sure Colorful GPUs are detected on both Windows and Linux 2023-08-01 16:26:22 +00:00
Mola19 0057df0efb move Asus ROG Strix Flare to AsusAuraTUFKeyboardController to add missing features (resolves #3415) 2023-08-01 03:40:16 +00:00
morg b7747a37d1 Add support for iGame GeForce RTX 3070 Ultra W OC-V 2023-07-31 04:50:07 +00:00
Adam Honse 888b292d73 Fix Razer matrix map initialization for non-keyboard zones 2023-07-30 13:26:34 -05:00
Peter Vazny 9c01593ba8 Fixes some Y740 15" keys 2023-07-30 07:45:03 +00:00
Adam Honse 9cf453008d Initial commit for scsiapi and Seagate FireCuda Gaming External HDD controller 2023-07-30 06:12:21 +00:00
morg f6e0996250 Fix crash on save for AsusAuraCoreLaptop. Closes #3174 2023-07-25 13:21:50 +02:00
Adam Honse deeb8a84b7 Initial HYTE CNVS controller implementation 2023-07-22 20:10:14 +00:00
TheRogueZeta 92992c0a9b Add additional device ID for Asus TUF RTX4080-16G-GAMING 2023-07-21 15:15:33 -07:00
Sergey004 652d1f606e Add PALIT RTX 3060 LHR (GA104) to detection 2023-07-21 17:26:42 +04:00
Mola19 35c5d99a80 add support for Asus ROG Strix Flare II Animate 2023-07-20 02:26:19 +00:00
morg 653f025635 Add support for iGame GeForce RTX 3060 Ti Advanced OC-V variant 2023-07-18 13:02:49 +00:00
Adam Honse 606355955d Fill in missing modes for Razer Mamba 2012 2023-07-17 17:05:40 -05:00
Martin Hartl a98b0c1b62 Asus mainboard: Fix addressable only mainboard 2023-07-17 19:57:06 +00:00
Adam Honse 5dd9459561 Fix non-NULL matrix map pointer in Intel Arc A770 LE controller 2023-07-16 19:49:39 -05:00
Chris M 4dae7b6b85 Updated includes to fully cover dependencies 2023-07-16 22:56:38 +00:00
Mike Wang 5caf1e1b85 Fix RGB Fusion 2 pulse mode not working #3489 2023-07-16 22:55:32 +00:00
Alexey Sokolov 125b1ab134 Warn if dlopen() failed 2023-07-16 15:44:36 +01:00
Milan Cermak 9d962ded6a ViewSonic Elite XG270QG detected twice #3486 2023-07-15 14:59:53 +02:00
Mike Wang f414029910 Add Gigabyte GeForce RTX­4070 GAMING OC 12G #3477 2023-07-14 13:36:47 +00:00
Adam Honse 3629ba1f09 Remove old keymap entries from RazerDevices structures as they've all been converted to KLM layouts 2023-07-13 22:22:30 -05:00
Mike Wang 3678262404 Fix compilation failure caused by some non-ascii characters #3481 2023-07-13 13:29:52 +00:00
Mola19 16d8c8e962 fix AsusAuraTUFKeyboard quicksand mode direction 2023-07-13 05:39:32 +00:00
Dmitry K 51712f08b5 Removed include directives from ResourceManager.h to speed up build process 2023-07-12 14:51:47 +00:00
Dmitry K 0714920a9a Simplified detector blocks for HID 2023-07-12 14:49:27 +00:00
Anders Nikolai Fuglseth edea9f6bec Add ASUS TUF RTX 4070 O12G Gaming 2023-07-12 00:05:45 +00:00
morg 65fc57cb69 Add support for ASUS TUF RTX4080 16G GAMING GPU 2023-07-11 16:36:06 +00:00
Rollbacke 1480b23838 Added another NZXT Fan & Controller 6 channels 2023-07-11 16:34:01 +00:00
morg 7b38a6a8d6 Add support for ASUS TUF RTX 3090Ti 24G GAMING GPU 2023-07-11 14:41:02 +02:00
Göktuğ Korkmaz 0b776269ea Added another PID for HyperX QuadCast S microphone 2023-07-11 06:27:25 +03:00
Cooper Hall 14c74248dd fixed OpenRazer compiling error on windows 2023-07-10 19:51:27 +00:00
KerJoe 3ee6af0dfd Added "MSI PRO B550M-P GEN3" motherboard ID. 2023-07-10 18:46:38 +00:00
Cooper Hall 9fab4110d7 fixed one definition rule warnings 2023-07-10 18:13:47 +00:00
TheRogueZeta 9c2a648d09 Set custom width for HardwareID colums and auto expand list 2023-07-10 16:23:09 +00:00
Adam Honse c44d87e24d Increment version number post-release 2023-07-10 11:19:52 -05:00
284 changed files with 14565 additions and 11357 deletions
-1
View File
@@ -74,7 +74,6 @@ CODEOWNERS @Calcprogrammer1
/Controllers/NZXTHue2Controller/
/Controllers/NZXTHuePlusController/
/Controllers/NZXTKrakenController/
/Controllers/OpenRazerController/
/Controllers/PNYGPUController/
/Controllers/PatriotViperController/
/Controllers/PhilipsHueController/
@@ -3,7 +3,6 @@
\*-----------------------------------------------------*/
#include <hidapi/hidapi.h>
#include "Detector.h"
#include "LogManager.h"
#include "RGBController.h"
/*-----------------------------------------------------*\
@@ -31,4 +30,5 @@ void DetectA4TechMouseControllers(hid_device_info* info, const std::string& name
}
REGISTER_HID_DETECTOR_IPU("Bloody W60 Pro", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_W60_PRO_PID, 2, 0xFF33, 0x0529);
REGISTER_HID_DETECTOR_IPU("Bloody W90 Max", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_W90_MAX_PID, 2, 0xFF33, 0x053D);
REGISTER_HID_DETECTOR_IPU("Bloody MP 50RS", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_MP_50RS_PID, 2, 0xFFF2, 0x6009);
@@ -8,6 +8,7 @@
\*---------------------------------------------------------------------*/
#include "BloodyMouseController.h"
#include "LogManager.h"
BloodyMouseController::BloodyMouseController(hid_device* dev_handle, const char* path, uint16_t product_id)
{
@@ -9,7 +9,6 @@
#include <string>
#include <hidapi/hidapi.h>
#include "LogManager.h"
#include "RGBController.h"
#pragma once
@@ -18,6 +17,7 @@
| Mouse product IDs |
\*-----------------------------------------------------*/
#define BLOODY_W60_PRO_PID 0x37EA
#define BLOODY_W90_MAX_PID 0x3666
/*-----------------------------------------------------*\
| Mousemat product IDs |
@@ -25,6 +25,19 @@ static const mouse_layout w60_pro
}
};
static const mouse_layout w90_max
{
{
"Scroll Wheel", { 14 }
},
{
"Logo", { 7 }
},
{
"Rear", { 13, 12, 11, 10, 9, 8, 6, 5, 4, 3, 2, 1, 0 }
}
};
static const mouse_layout mp_50rs
{
{
@@ -56,7 +69,6 @@ RGBController_BloodyMouse::RGBController_BloodyMouse(BloodyMouseController *cont
type = DEVICE_TYPE_MOUSE;
}
name = "BloodyMouse";
vendor = "Bloody";
description = "Controller compatible with the Bloody W60 Pro and MP 50RS";
serial = controller->GetSerial();
@@ -89,11 +101,15 @@ void RGBController_BloodyMouse::SetupZones()
| Select layout from PID |
\*-------------------------------------------------*/
mouse_layout layout;
switch(controller->GetPid())
{
case BLOODY_W60_PRO_PID:
layout = w60_pro;
break;
case BLOODY_W90_MAX_PID:
layout = w90_max;
break;
case BLOODY_MP_50RS_PID:
layout = mp_50rs;
break;
@@ -9,7 +9,6 @@
#pragma once
#include <vector>
#include "LogManager.h"
#include "RGBController.h"
#include "BloodyMouseController.h"
@@ -12,6 +12,7 @@
#include "RGBController.h"
#include "ResourceManager.h"
#include "SettingsManager.h"
#include "ASRockPolychromeUSBController.h"
#include "dependencies/dmiinfo.h"
@@ -15,6 +15,7 @@
#include <chrono>
#include <algorithm>
#include <sstream>
#include "LogManager.h"
typedef uint32_t alienware_platform_id;
@@ -24,8 +25,10 @@ typedef uint32_t alienware_platform_id;
\*---------------------------------------------------------*/
static const std::map<alienware_platform_id, uint8_t> zone_quirks_table =
{
{ 0x0C01, 4 }, // Dell G5 SE 5505
{ 0x0A01, 16 } // Dell G7 15 7500
{ 0x0C01, 4 }, // Dell G5 SE 5505
{ 0x0A01, 16 }, // Dell G7 15 7500
{ 0x0E03, 4 } // Dell G15 5511
};
/*---------------------------------------------------------*\
@@ -39,7 +42,8 @@ static const std::map<alienware_platform_id, std::vector<const char*>> zone_name
"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" } }
"Light Bar 10", "Light Bar 11", "Light Bar 12" } },
{ 0x0E03, { "Left", "Middle", "Right", "Numpad" } }
};
static void SendHIDReport(hid_device *dev, const unsigned char* usb_buf, size_t usb_buf_size)
@@ -113,10 +117,13 @@ AlienwareController::AlienwareController(hid_device* dev_handle, const hid_devic
if(zone_names_table.count(platform_id))
{
LOG_INFO("[%s] Known platform: %8X, Number of zones: %d", ALIENWARE_CONTROLLER_NAME, platform_id, number_of_zones);
zone_names = zone_names_table.at(platform_id);
}
else
{
LOG_WARNING("[%s] Unknown platform: %8X, Number of zones: %d", ALIENWARE_CONTROLLER_NAME, platform_id, number_of_zones);
/*-------------------------------------------------*\
| If this is an unknown controller, set the name of |
| all regions to "Unknown" |
@@ -19,7 +19,7 @@
#define ALIENWARE_REPORT_SIZE 33
#define HIDAPI_ALIENWARE_REPORT_SIZE (ALIENWARE_REPORT_SIZE + 1)
#define ALIENWARE_CONTROLLER_NAME "AlienWare Controller"
enum
{
ALIENWARE_COMMAND_REPORT = 0x20, /* Set report type to get */
@@ -45,9 +45,9 @@ typedef struct
const char * name;
const unsigned char zone;
const unsigned char idx;
} led_type;
} aw510k_led_type;
static const led_type led_names[] =
static const aw510k_led_type led_names[] =
{
/* Key Label Zone, Index */
{ KEY_EN_ESCAPE, ALIENWARE_AW510K_ZONE_DIRECT_KEYBOARD, 0xB0 },
@@ -9,6 +9,7 @@
#define ANNE_PRO_2_PID_2 0x8009
#define ANNE_PRO_2_PID_3 0xA292
#define ANNE_PRO_2_PID_4 0xA293
#define ANNE_PRO_2_PID_5 0xA297
/******************************************************************************************\
* *
@@ -34,3 +35,4 @@ REGISTER_HID_DETECTOR_I("Anne Pro 2", DetectAnnePro2Controllers, ANNE_PRO_2_VID,
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);
REGISTER_HID_DETECTOR_I("Anne Pro 2", DetectAnnePro2Controllers, ANNE_PRO_2_VID, ANNE_PRO_2_PID_5, 1);
@@ -40,9 +40,9 @@ typedef struct
{
const char * name;
const unsigned char idx;
} led_type;
} annepro2_led_type;
static const led_type led_names[] =
static const annepro2_led_type led_names[] =
{
/* Key Label Index */
{ KEY_EN_ESCAPE, 0 },
@@ -0,0 +1,155 @@
/*-----------------------------------------*\
| ArcticController.h |
| |
| Controller Interface for Arctic devices |
| |
| Armin Wolf (Wer-Wolf) 01/09/2023 |
\*-----------------------------------------*/
#include "ArcticController.h"
#include <cstring>
using namespace std::chrono_literals;
#define ARCTIC_COMMAND_SET_RGB 0x00
#define ARCTIC_COMMAND_IDENTIFY 0x5C
#define ARCTIC_RESPONSE_BUFFER_LENGTH 15
#define ARCTIC_RESPONSE_COMMAND_OFFSET 0
#define ARCTIC_RESPONSE_DATA_OFFSET 1
#define ARCTIC_RESPONSE_DATA_LENGTH 12
#define ARCTIC_RESPONSE_XOR_CSUM_OFFSET 13
#define ARCTIC_RESPONSE_ADD_CSUM_OFFSET 14
#define ARCTIC_COMMAND_BUFFER_LENGTH(payload_size) (sizeof(header) + 1 + payload_size)
#define ARCTIC_COMMAND_COMMAND_OFFSET (sizeof(header))
#define ARCTIC_COMMAND_PAYLOAD_OFFSET (sizeof(header) + 1)
const unsigned char header[] =
{
0x01,
0x02,
0x03,
0xFF,
0x05,
0xFF,
0x02,
0x03
};
const unsigned char identify_payload[] =
{
0x01,
0xFE,
0x01,
0xFE
};
ArcticController::ArcticController(const std::string &portname)
: serialport(portname.c_str(), 250000, SERIAL_PORT_PARITY_NONE, SERIAL_PORT_SIZE_8, SERIAL_PORT_STOP_BITS_2, false)
{
port_name = portname;
serialport.serial_set_dtr(true);
}
ArcticController::~ArcticController()
{
serialport.serial_set_dtr(false);
}
static void FormatCommandBuffer(char *buffer, char command)
{
std::memcpy(buffer, header, sizeof(header));
buffer[ARCTIC_COMMAND_COMMAND_OFFSET] = command;
}
void ArcticController::SetChannels(std::vector<RGBColor> colors)
{
char* buffer = new char[ARCTIC_COMMAND_BUFFER_LENGTH(colors.size() * 3)];
FormatCommandBuffer(buffer, ARCTIC_COMMAND_SET_RGB);
for(unsigned int channel = 0; channel < colors.size(); channel++)
{
const unsigned int offset = ARCTIC_COMMAND_PAYLOAD_OFFSET + channel * 3;
buffer[offset + 0x00] = std::min<unsigned int>(254, RGBGetRValue(colors[channel]));
buffer[offset + 0x01] = std::min<unsigned int>(254, RGBGetGValue(colors[channel]));
buffer[offset + 0x02] = std::min<unsigned int>(254, RGBGetBValue(colors[channel]));
}
serialport.serial_write(buffer, sizeof(buffer));
delete[] buffer;
}
static char XORChecksum(char *data, int length)
{
char sum = 0;
for(int i = 0; i < length; i++)
{
sum ^= data[i];
}
return sum;
}
static char AddChecksum(char *data, int length)
{
char sum = 0;
for(int i = 0; i < length; i++)
{
sum = (char)(sum + data[i]);
}
return sum;
}
bool ArcticController::IsPresent()
{
char buffer[ARCTIC_COMMAND_BUFFER_LENGTH(sizeof(identify_payload))];
char response[ARCTIC_RESPONSE_BUFFER_LENGTH];
int ret;
FormatCommandBuffer(buffer, ARCTIC_COMMAND_IDENTIFY);
std::memcpy(buffer + ARCTIC_COMMAND_PAYLOAD_OFFSET, identify_payload, sizeof(identify_payload));
serialport.serial_flush_rx();
ret = serialport.serial_write(buffer, sizeof(buffer));
if(ret != sizeof(buffer))
{
return false;
}
std::this_thread::sleep_for(100ms);
ret = serialport.serial_read(response, sizeof(response));
if(ret != sizeof(response))
{
return false;
}
if(response[ARCTIC_RESPONSE_COMMAND_OFFSET] != ARCTIC_COMMAND_IDENTIFY)
{
return false;
}
if(response[ARCTIC_RESPONSE_XOR_CSUM_OFFSET] != XORChecksum(&response[ARCTIC_RESPONSE_DATA_OFFSET], ARCTIC_RESPONSE_DATA_LENGTH))
{
return false;
}
if(response[ARCTIC_RESPONSE_ADD_CSUM_OFFSET] != AddChecksum(&response[ARCTIC_RESPONSE_DATA_OFFSET], ARCTIC_RESPONSE_DATA_LENGTH))
{
return false;
}
return true;
}
std::string ArcticController::GetLocation()
{
return port_name;
}
@@ -0,0 +1,29 @@
/*-----------------------------------------*\
| ArcticController.h |
| |
| Controller Interface for Arctic devices |
| |
| Armin Wolf (Wer-Wolf) 01/09/2023 |
\*-----------------------------------------*/
#pragma once
#include <algorithm>
#include "RGBController.h"
#include "serial_port.h"
class ArcticController
{
public:
ArcticController(const std::string &portname);
~ArcticController();
void SetChannels(std::vector<RGBColor> colors);
bool IsPresent();
std::string GetLocation();
private:
std::string port_name;
serial_port serialport;
};
@@ -0,0 +1,48 @@
/*-----------------------------------------*\
| ArcticControllerDetect.cpp |
| |
| Detect Arctic RGB controllers |
| |
| Armin Wolf (Wer-Wolf) 01/09/2023 |
\*-----------------------------------------*/
#include "Detector.h"
#include "ArcticController.h"
#include "RGBController.h"
#include "RGBController_Arctic.h"
#include "find_usb_serial_port.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#define CH341_VID 0x1A86
#define CH341_PID 0x7523
void DetectArcticControllers()
{
std::vector<std::string *> ports = find_usb_serial_port(CH341_VID, CH341_PID);
for(unsigned int device = 0; device < ports.size(); device++)
{
ArcticController *controller = new ArcticController(*ports[device]);
if(controller->IsPresent())
{
RGBController_Arctic *rgb_controller = new RGBController_Arctic(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
else
{
delete controller;
}
delete ports[device];
}
}
REGISTER_DETECTOR("Arctic RGB controller", DetectArcticControllers);
/*---------------------------------------------------------------------------------------------------------*\
| Entries for dynamic UDEV rules |
| |
| DUMMY_DEVICE_DETECTOR("Arctic RGB controller", DetectArcticControllers, 0x1a86, 0x7523 ) |
\*---------------------------------------------------------------------------------------------------------*/
@@ -0,0 +1,131 @@
/*-----------------------------------------*\
| RGBController_Arctic.h |
| |
| Generic RGB Interface for Arctic devices |
| |
| Armin Wolf (Wer-Wolf) 01/09/2023 |
\*-----------------------------------------*/
#include "RGBController_Arctic.h"
#include <math.h>
using namespace std::chrono_literals;
#define ARCTIC_NUM_CHANNELS 4
#define ARCTIC_SLEEP_THRESHOLD 100ms
#define ARCTIC_KEEPALIVE_PERIOD 500ms /* Device requires at least 1s */
/**------------------------------------------------------------------*\
@name Arctic RGB Controller Devices
@category LEDStrip
@type Serial
@save :x:
@direct :white_check_mark:
@effects :x:
@detectors DetectArcticControllers
@comment
\*-------------------------------------------------------------------*/
RGBController_Arctic::RGBController_Arctic(ArcticController* controller_ptr)
{
controller = controller_ptr;
name = "Arctic RGB Controller";
vendor = "Arctic";
description = "Arctic 4-Channel RGB Controller";
location = controller->GetLocation();
type = DEVICE_TYPE_LEDSTRIP;
mode DirectMode;
DirectMode.name = "Direct";
DirectMode.value = 0;
DirectMode.flags = MODE_FLAG_HAS_PER_LED_COLOR;
DirectMode.color_mode = MODE_COLORS_PER_LED;
modes.push_back(DirectMode);
SetupZones();
keepalive_thread_run = true;
keepalive_thread = std::thread(&RGBController_Arctic::KeepaliveThreadFunction, this);
}
RGBController_Arctic::~RGBController_Arctic()
{
keepalive_thread_run = false;
keepalive_thread.join();
delete controller;
}
void RGBController_Arctic::SetupZones()
{
for(int channel = 0; channel < ARCTIC_NUM_CHANNELS; channel++)
{
zone LedZone;
LedZone.name = "LED Strip " + std::to_string(channel);
LedZone.type = ZONE_TYPE_SINGLE;
LedZone.leds_count = 1;
LedZone.leds_min = 1;
LedZone.leds_max = 1;
LedZone.matrix_map = nullptr;
led Led;
Led.name = LedZone.name + " LED";
Led.value = channel;
zones.push_back(LedZone);
leds.push_back(Led);
}
SetupColors();
}
void RGBController_Arctic::ResizeZone(int /* zone */, int /* new_size */)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_Arctic::DeviceUpdateLEDs()
{
last_update_time = std::chrono::steady_clock::now();
controller->SetChannels(colors);
}
void RGBController_Arctic::UpdateZoneLEDs(int /* zone */)
{
DeviceUpdateLEDs();
}
void RGBController_Arctic::UpdateSingleLED(int /* led */)
{
DeviceUpdateLEDs();
}
void RGBController_Arctic::DeviceUpdateMode()
{
/*---------------------------------------------------------*\
| This device does not support mode updates |
\*---------------------------------------------------------*/
}
void RGBController_Arctic::KeepaliveThreadFunction()
{
std::chrono::nanoseconds sleep_time;
while(keepalive_thread_run.load())
{
sleep_time = ARCTIC_KEEPALIVE_PERIOD - (std::chrono::steady_clock::now() - last_update_time);
if(sleep_time <= ARCTIC_SLEEP_THRESHOLD)
{
UpdateLEDs(); // Already protected thru a device update thread
std::this_thread::sleep_for(ARCTIC_KEEPALIVE_PERIOD);
}
else
{
std::this_thread::sleep_for(sleep_time);
}
}
}
@@ -0,0 +1,40 @@
/*-----------------------------------------*\
| RGBController_Arctic.h |
| |
| Generic RGB Interface for Arctic devices |
| |
| Armin Wolf (Wer-Wolf) 27/08/2023 |
\*-----------------------------------------*/
#pragma once
#include "ArcticController.h"
#include "RGBController.h"
#include "serial_port.h"
#include <chrono>
#include <thread>
class RGBController_Arctic : public RGBController
{
public:
RGBController_Arctic(ArcticController* controller_ptr);
~RGBController_Arctic();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
void KeepaliveThreadFunction();
private:
ArcticController* controller;
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
std::atomic<bool> keepalive_thread_run;
std::thread keepalive_thread;
};
@@ -55,3 +55,4 @@ REGISTER_HID_DETECTOR ("ASUS Aura Core", DetectAsusAuraCoreContro
REGISTER_HID_DETECTOR ("ASUS Aura Core", DetectAsusAuraCoreControllers, AURA_CORE_VID, 0x1866);
REGISTER_HID_DETECTOR ("ASUS Aura Core", DetectAsusAuraCoreControllers, AURA_CORE_VID, 0x1869);
REGISTER_HID_DETECTOR_PU("ASUS ROG Strix SCAR 15", DetectAsusAuraCoreLaptopControllers, AURA_CORE_VID, AURA_STRIX_SCAR_15_PID, 0xFF31, 0x79);
REGISTER_HID_DETECTOR_PU("ASUS ROG Strix SCAR 17", DetectAsusAuraCoreLaptopControllers, AURA_CORE_VID, 0x1866, 0xFF31, 0x79);
@@ -9,6 +9,8 @@
#include "AsusAuraCoreLaptopController.h"
#include "SettingsManager.h"
static uint8_t packet_map[ASUSAURACORELAPTOP_KEYCOUNT +
ASUSAURACORELAPTOP_LIGHTBARCOUNT +
ASUSAURACORELAPTOP_LIDCOUNT ] =
@@ -13,7 +13,6 @@
#include "LogManager.h"
#include "RGBController.h"
#include "ResourceManager.h"
#include "SettingsManager.h"
#include "RGBControllerKeyNames.h"
#pragma once
@@ -406,6 +406,8 @@ void RGBController_AsusAuraCoreLaptop::Init_Controller()
lightbar.leds_min = ASUSAURACORELAPTOP_LIGHTBARCOUNT;
lightbar.leds_max = ASUSAURACORELAPTOP_LIGHTBARCOUNT;
lightbar.leds_count = ASUSAURACORELAPTOP_LIGHTBARCOUNT;
lightbar.matrix_map = NULL;
zones.push_back(lightbar);
zone lid;
@@ -414,6 +416,8 @@ void RGBController_AsusAuraCoreLaptop::Init_Controller()
lid.leds_min = ASUSAURACORELAPTOP_LIDCOUNT;
lid.leds_max = ASUSAURACORELAPTOP_LIDCOUNT;
lid.leds_count = ASUSAURACORELAPTOP_LIDCOUNT;
lid.matrix_map = NULL;
zones.push_back(lid);
}
@@ -15,6 +15,7 @@ AuraMainboardController::AuraMainboardController(hid_device* dev_handle, const c
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];
unsigned char effect_channel = 0;
if(num_total_mainboard_leds < num_rgb_headers)
{
@@ -24,14 +25,18 @@ AuraMainboardController::AuraMainboardController(hid_device* dev_handle, const c
/*-----------------------------------------------------*\
| Add mainboard device |
\*-----------------------------------------------------*/
device_info.push_back({0x00, 0x04, num_total_mainboard_leds, num_rgb_headers, AuraDeviceType::FIXED});
if(num_total_mainboard_leds > 0)
{
device_info.push_back({effect_channel, 0x04, num_total_mainboard_leds, num_rgb_headers, AuraDeviceType::FIXED});
effect_channel++;
}
/*-----------------------------------------------------*\
| Add addressable devices |
\*-----------------------------------------------------*/
for(int i = 0; i < num_addressable_headers; i++)
{
device_info.push_back({0x01, (unsigned char)i, 0x01, 0, AuraDeviceType::ADDRESSABLE});
device_info.push_back({effect_channel, (unsigned char)i, 0x01, 0, AuraDeviceType::ADDRESSABLE});
}
}
@@ -81,11 +86,24 @@ void AuraMainboardController::SetMode
unsigned char grn,
unsigned char blu
)
{
SetMode(channel, mode, red, grn, blu, false);
}
void AuraMainboardController::SetMode
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu,
bool shutdown_effect
)
{
this->mode = mode;
RGBColor color = ToRGBColor(red, grn, blu);
SendEffect(device_info[channel].effect_channel, mode);
SendEffect(device_info[channel].effect_channel, mode, shutdown_effect);
if(mode == AURA_MODE_DIRECT)
{
return;
@@ -111,7 +129,8 @@ void AuraMainboardController::SetMode
channel,
start_led,
device_info[channel].num_leds,
led_data
led_data,
shutdown_effect
);
}
@@ -123,7 +142,8 @@ unsigned short AuraMainboardController::GetMask(int start, int size)
void AuraMainboardController::SendEffect
(
unsigned char channel,
unsigned char mode
unsigned char mode,
bool shutdown_effect
)
{
unsigned char usb_buf[65];
@@ -140,7 +160,7 @@ void AuraMainboardController::SendEffect
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_EFFECT;
usb_buf[0x02] = channel;
usb_buf[0x03] = 0x00;
usb_buf[0x04] = 0x00;
usb_buf[0x04] = shutdown_effect ? 0x01 : 0x00;
usb_buf[0x05] = mode;
/*-----------------------------------------------------*\
@@ -154,7 +174,8 @@ void AuraMainboardController::SendColor
unsigned char /*channel*/,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data
unsigned char* led_data,
bool shutdown_effect
)
{
unsigned short mask = GetMask(start_led, led_count);
@@ -172,7 +193,7 @@ void AuraMainboardController::SendColor
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_EFFECT_COLOR;
usb_buf[0x02] = mask >> 8;
usb_buf[0x03] = mask & 0xff;
usb_buf[0x04] = 0x00;
usb_buf[0x04] = shutdown_effect ? 0x01 : 0x00;
/*-----------------------------------------------------*\
| Copy in color data bytes |
@@ -44,15 +44,28 @@ public:
unsigned char blu
);
void SetMode
(
unsigned char channel,
unsigned char mode,
unsigned char red,
unsigned char grn,
unsigned char blu,
bool shutdown_effect
);
void SendCommit();
private:
unsigned int mode;
unsigned short GetMask(int start, int size);
void SendEffect
(
unsigned char channel,
unsigned char mode
unsigned char mode,
bool shutdown_effect
);
void SendColor
@@ -60,8 +73,7 @@ private:
unsigned char channel,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data
unsigned char* led_data,
bool shutdown_effect
);
void SendCommit();
};
@@ -29,6 +29,7 @@
#define AURA_ROG_CHAKRAM_X_2_4_PID 0x1A1A
#define AURA_ROG_SPATHA_X_USB_PID 0x1977
#define AURA_ROG_SPATHA_X_2_4_PID 0x1979
#define AURA_ROG_SPATHA_X_DOCK_PID 0x1979
#define AURA_ROG_PUGIO_PID 0x1846
#define AURA_ROG_PUGIO_II_WIRED_PID 0x1906
#define AURA_ROG_PUGIO_II_WIRELESS_PID 0x1908
@@ -188,7 +189,7 @@ static std::map<int,mouse_type> aura_mouse_devices =
255,
1,
0,
64,
100,
false,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
@@ -201,7 +202,7 @@ static std::map<int,mouse_type> aura_mouse_devices =
255,
1,
0,
64,
100,
false,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
@@ -214,7 +215,7 @@ static std::map<int,mouse_type> aura_mouse_devices =
255,
1,
0,
64,
100,
true,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
@@ -227,7 +228,7 @@ static std::map<int,mouse_type> aura_mouse_devices =
255,
1,
0,
64,
100,
true,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
@@ -279,7 +280,7 @@ static std::map<int,mouse_type> aura_mouse_devices =
15, // technically until 255, but unusably slow after 15
1,
0,
64,
100,
false,
2,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
@@ -292,7 +293,7 @@ static std::map<int,mouse_type> aura_mouse_devices =
15, // technically until 255, but unusably slow after 15
1,
0,
64,
100,
true,
2,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
@@ -305,7 +306,7 @@ static std::map<int,mouse_type> aura_mouse_devices =
15, // technically until 255, but unusably slow after 15
1,
0,
64,
100,
false,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
@@ -318,7 +319,7 @@ static std::map<int,mouse_type> aura_mouse_devices =
15, // technically until 255, but unusably slow after 15
1,
0,
64,
100,
true,
1,
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL, AURA_MOUSE_ZONE_UNDERGLOW },
@@ -37,6 +37,26 @@ std::string AuraTUFKeyboardController::GetDeviceLocation()
return("HID: " + location);
}
std::string clean_serial(const std::wstring& wstr)
{
// Skip non-ASCII, trailing garbage in serial numbers. Required by the
// Scope II 96, whose original firmware outputs garbage, which even differs
// after computer reboots and therefore breaks OpenRGB profile matching.
std::string result;
for(auto c : wstr)
{
// Forbid control chars and anything above final printable low-ASCII.
if(c < 32 || c > 126)
{
break;
}
result += c;
}
return(result);
}
std::string AuraTUFKeyboardController::GetSerialString()
{
wchar_t serial_string[128];
@@ -47,8 +67,8 @@ std::string AuraTUFKeyboardController::GetSerialString()
return("");
}
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
std::wstring serial_wstring = serial_string;
std::string return_string = clean_serial(serial_wstring);
return(return_string);
}
@@ -72,13 +92,16 @@ std::string AuraTUFKeyboardController::GetVersion()
hid_read(dev, usb_buf_out, 65);
char version[9];
if(device_pid == AURA_TUF_K3_GAMING_PID)
switch(device_pid)
{
snprintf(version, 9, "%02X.%02X.%02X", usb_buf_out[6], usb_buf_out[5], usb_buf_out[4]);
}
else
{
snprintf(version, 9, "%02X.%02X.%02X", usb_buf_out[5], usb_buf_out[6], usb_buf_out[7]);
case AURA_TUF_K3_GAMING_PID:
case AURA_ROG_STRIX_FLARE_II_ANIMATE_PID:
case AURA_ROG_STRIX_SCOPE_II_96_WIRELESS_USB_PID:
snprintf(version, 9, "%02X.%02X.%02X", usb_buf_out[6], usb_buf_out[5], usb_buf_out[4]);
break;
default:
snprintf(version, 9, "%02X.%02X.%02X", usb_buf_out[5], usb_buf_out[6], usb_buf_out[7]);
}
return std::string(version);
@@ -33,13 +33,20 @@ enum
enum
{
AURA_ROG_FALCHION_WIRED_PID = 0x193C,
AURA_ROG_FALCHION_WIRELESS_PID = 0x193E,
AURA_TUF_K1_GAMING_PID = 0x1945,
AURA_TUF_K3_GAMING_PID = 0x194B,
AURA_TUF_K5_GAMING_PID = 0x1899,
AURA_TUF_K7_GAMING_PID = 0x18AA,
AURA_ROG_CLAYMORE_PID = 0x184D,
AURA_ROG_STRIX_FLARE_PID = 0x1875,
AURA_ROG_STRIX_FLARE_PNK_LTD_PID = 0x18CF,
AURA_ROG_STRIX_FLARE_COD_BO4_PID = 0x18AF,
AURA_ROG_FALCHION_WIRED_PID = 0x193C,
AURA_ROG_FALCHION_WIRELESS_PID = 0x193E,
AURA_ROG_STRIX_SCOPE_PID = 0x18F8,
AURA_ROG_STRIX_SCOPE_RX_PID = 0x1951,
AURA_ROG_STRIX_SCOPE_II_96_WIRELESS_USB_PID = 0x1AAE,
AURA_ROG_STRIX_FLARE_II_ANIMATE_PID = 0x19FC,
AURA_TUF_K1_GAMING_PID = 0x1945,
AURA_TUF_K3_GAMING_PID = 0x194B,
AURA_TUF_K5_GAMING_PID = 0x1899,
AURA_TUF_K7_GAMING_PID = 0x18AA,
AURA_ROG_CLAYMORE_PID = 0x184D,
};
struct led_color
File diff suppressed because it is too large Load Diff
@@ -15,6 +15,7 @@
#include "RGBController_AsusAuraHeadsetStand.h"
#include "RGBController_AsusAuraKeyboard.h"
#include "RGBController_AsusAuraTUFKeyboard.h"
#include "RGBController_AsusAuraMainboard.h"
#include "RGBController_AsusAuraMouse.h"
#include "RGBController_AsusAuraMousemat.h"
#include "RGBController_AsusROGAlly.h"
@@ -26,85 +27,82 @@
#include <hidapi/hidapi.h>
#include "dependencies/dmiinfo.h"
#define AURA_USB_VID 0x0B05
#define AURA_USB_VID 0x0B05
/*-----------------------------------------------------------------*\
| 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_MOTHERBOARD_3_PID 0x19AF
#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_MOTHERBOARD_3_PID 0x19AF
/*-----------------------------------------------------------------*\
| 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_FLARE_COD_BO4_PID 0x18AF
#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_ROG_STRIX_SCOPE_RX_TKL_DELUXE_PID 0x1A05
#define AURA_ROG_STRIX_SCOPE_TKL_PNK_LTD_PID 0x1954
#define AURA_ROG_CLAYMORE_PID 0x184D
#define AURA_TUF_K1_GAMING_PID 0x1945
#define AURA_TUF_K3_GAMING_PID 0x194B
#define AURA_TUF_K5_GAMING_PID 0x1899
#define AURA_TUF_K7_GAMING_PID 0x18AA
#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_FLARE_COD_BO4_PID 0x18AF
#define AURA_ROG_STRIX_FLARE_II_ANIMATE_PID 0x19FC
#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_ROG_STRIX_SCOPE_RX_TKL_DELUXE_PID 0x1A05
#define AURA_ROG_STRIX_SCOPE_TKL_PNK_LTD_PID 0x1954
#define AURA_ROG_STRIX_SCOPE_II_96_WIRELESS_USB_PID 0x1AAE
#define AURA_ROG_CLAYMORE_PID 0x184D
#define AURA_TUF_K1_GAMING_PID 0x1945
#define AURA_TUF_K3_GAMING_PID 0x194B
#define AURA_TUF_K5_GAMING_PID 0x1899
#define AURA_TUF_K7_GAMING_PID 0x18AA
/*-----------------------------------------------------------------*\
| MICE - defined in AsusAuraMouseDevices.h |
\*-----------------------------------------------------------------*/
#define AURA_ROG_STRIX_EVOLVE_PID 0x185B
#define AURA_ROG_STRIX_EVOLVE_PID 0x185B
/*-----------------------------------------------------------------*\
| MOUSEMATS |
\*-----------------------------------------------------------------*/
#define AURA_ROG_BALTEUS_PID 0x1891
#define AURA_ROG_BALTEUS_QI_PID 0x1890
#define AURA_ROG_BALTEUS_PID 0x1891
#define AURA_ROG_BALTEUS_QI_PID 0x1890
/*-----------------------------------------------------------------*\
| MONITORS |
\*-----------------------------------------------------------------*/
#define AURA_ROG_STRIX_XG27AQ_PID 0x198C
#define AURA_ROG_STRIX_XG27AQM_PID 0x19BB
#define AURA_ROG_STRIX_XG279Q_PID 0x1919
#define AURA_ROG_STRIX_XG27W_PID 0x1933
#define AURA_ROG_PG32UQ_PID 0x19B9
#define AURA_ROG_STRIX_XG27AQ_PID 0x198C
#define AURA_ROG_STRIX_XG27AQM_PID 0x19BB
#define AURA_ROG_STRIX_XG279Q_PID 0x1919
#define AURA_ROG_STRIX_XG27W_PID 0x1933
#define AURA_ROG_PG32UQ_PID 0x19B9
/*-----------------------------------------------------------------*\
| HEADSETSTANDS |
\*-----------------------------------------------------------------*/
#define AURA_ROG_THRONE_PID 0x18D9
#define AURA_ROG_THRONE_QI_PID 0x18C5
#define AURA_ROG_THRONE_QI_GUNDAM_PID 0x1994
#define AURA_ROG_THRONE_PID 0x18D9
#define AURA_ROG_THRONE_QI_PID 0x18C5
#define AURA_ROG_THRONE_QI_GUNDAM_PID 0x1994
/*-----------------------------------------------------------------*\
| OTHER |
\*-----------------------------------------------------------------*/
#define AURA_TERMINAL_PID 0x1889
#define ROG_STRIX_LC120_PID 0x879E
#define AURA_RYUO_AIO_PID 0x1887
#define ASUS_ROG_ALLY_PID 0x1ABE
#define AURA_TERMINAL_PID 0x1889
#define ROG_STRIX_LC120_PID 0x879E
#define AURA_RYUO_AIO_PID 0x1887
#define ASUS_ROG_ALLY_PID 0x1ABE
AuraKeyboardMappingLayoutType GetKeyboardMappingLayoutType(int pid)
{
switch(pid)
{
case AURA_ROG_STRIX_FLARE_PID:
case AURA_ROG_STRIX_FLARE_PNK_LTD_PID:
case AURA_ROG_STRIX_FLARE_COD_BO4_PID:
return FLARE_LAYOUT;
case AURA_ROG_STRIX_SCOPE_PID:
return SCOPE_LAYOUT;
@@ -158,7 +156,7 @@ void DetectAsusAuraUSBMotherboards(hid_device_info* info, const std::string& /*n
{
DMIInfo dmi;
AuraMainboardController* controller = new AuraMainboardController(dev, info->path);
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
RGBController_AuraMainboard* rgb_controller = new RGBController_AuraMainboard(controller);
rgb_controller->name = "ASUS " + dmi.getMainboard();
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
@@ -190,19 +188,11 @@ void DetectAsusAuraUSBMice(hid_device_info* info, const std::string& name)
if(dev)
{
AuraMouseController* controller = new AuraMouseController(dev, info->path, info->product_id);
uint16_t pid = (name == "Asus ROG Spatha X Dock") ? AURA_ROG_SPATHA_X_DOCK_FAKE_PID : info->product_id;
AuraMouseController* controller = new AuraMouseController(dev, info->path, pid);
RGBController_AuraMouse* rgb_controller = new RGBController_AuraMouse(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
// adding the mouse dock for the ASUS ROG Spatha X
if(info->product_id == AURA_ROG_SPATHA_X_2_4_PID)
{
AuraMouseController* dock_controller = new AuraMouseController(dev, info->path, AURA_ROG_SPATHA_X_DOCK_FAKE_PID);
RGBController_AuraMouse* rgb_controller_dock = new RGBController_AuraMouse(dock_controller);
rgb_controller_dock->name = "Asus ROG Spatha X Dock";
ResourceManager::get()->RegisterRGBController(rgb_controller_dock);
}
}
}
@@ -324,21 +314,23 @@ REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAs
/*-----------------------------------------------------------------*\
| KEYBOARDS |
\*-----------------------------------------------------------------*/
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 Flare CoD Black Ops 4 Edition",DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_FLARE_COD_BO4_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_IP("ASUS ROG Strix Scope RX TKL Wireless Deluxe", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_SCOPE_RX_TKL_DELUXE_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Scope TKL PNK LTD", DetectAsusAuraUSBKeyboards, AURA_USB_VID, AURA_ROG_STRIX_SCOPE_TKL_PNK_LTD_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Claymore", DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_ROG_CLAYMORE_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Flare", DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_ROG_STRIX_FLARE_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Flare PNK LTD", DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_ROG_STRIX_FLARE_PNK_LTD_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Flare CoD Black Ops 4 Edition",DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_ROG_STRIX_FLARE_COD_BO4_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Falchion (Wired)", DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_ROG_FALCHION_WIRED_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Falchion (Wireless)", DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_ROG_FALCHION_WIRELESS_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Flare II Animate", DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_ROG_STRIX_FLARE_II_ANIMATE_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS TUF Gaming K1", DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_TUF_K1_GAMING_PID, 2, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS TUF Gaming K3", DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_TUF_K3_GAMING_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS TUF Gaming K5", DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_TUF_K5_GAMING_PID, 2, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Scope", DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_ROG_STRIX_SCOPE_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Scope RX", DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_ROG_STRIX_SCOPE_RX_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS TUF Gaming K7", DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_TUF_K7_GAMING_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("ASUS ROG Strix Scope II 96 Wireless USB", DetectAsusAuraTUFUSBKeyboard, AURA_USB_VID, AURA_ROG_STRIX_SCOPE_II_96_WIRELESS_USB_PID, 1, 0xFF00);
/*-----------------------------------------------------------------*\
| MICE |
@@ -361,6 +353,7 @@ REGISTER_HID_DETECTOR_IP("Asus ROG Chakram X USB", DetectAs
REGISTER_HID_DETECTOR_IP("Asus ROG Chakram X 2.4GHz", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_CHAKRAM_X_2_4_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("Asus ROG Spatha X USB", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_SPATHA_X_USB_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("Asus ROG Spatha X 2.4GHz", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_SPATHA_X_2_4_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("Asus ROG Spatha X Dock", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_SPATHA_X_DOCK_PID, 0, 0xFF01);
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, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Pugio II (Wireless)", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_PUGIO_II_WIRELESS_PID, 0, 0xFF01);
@@ -44,7 +44,7 @@ static unsigned int falchion_matrix_map[5][16] =
{ 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 } };
static const std::vector<led_type> default_led_names =
static const std::vector<aura_keyboard_led> default_led_names =
{
/* Key Label Index */
{ KEY_EN_ESCAPE, 0x00 },
@@ -153,7 +153,7 @@ static const std::vector<led_type> default_led_names =
{ KEY_EN_NUMPAD_ENTER, 0xB4 },
};
static const std::vector<led_type> default_tkl_led_names =
static const std::vector<aura_keyboard_led> default_tkl_led_names =
{
/* Key Label Index */
{ KEY_EN_ESCAPE, 0x00 },
@@ -270,7 +270,7 @@ static const std::vector<led_type> default_tkl_led_names =
{ "Underglow 26", 0xCE },
};
static const std::vector<led_type> default_65pct_led_names =
static const std::vector<aura_keyboard_led> default_65pct_led_names =
{
/* Key Label Index */
{ KEY_EN_ESCAPE, 0x00 },
@@ -395,7 +395,7 @@ void RGBController_AuraKeyboard::SetupZones()
| Set up zones |
\*---------------------------------------------------------*/
std::vector<led_zone> led_zones;
std::vector<led_type> led_names;
std::vector<aura_keyboard_led> led_names;
switch(layout)
{
@@ -24,7 +24,7 @@ typedef struct
{
const char* name;
unsigned char idx;
} led_type;
} aura_keyboard_led;
typedef struct
{
@@ -0,0 +1,78 @@
/*-----------------------------------------*\
| RGBController_AsusAuraMainboard.cpp |
| |
| RGB controller for Asus Aura USB |
| mainboards |
| |
| rytypete 8/30/2023 |
| based on RGBController_AsusAuraUSB.cpp |
| code |
\*-----------------------------------------*/
#include "RGBController_AsusAuraMainboard.h"
/**------------------------------------------------------------------*\
@name Asus Aura USB Mainboard
@category Motherboard
@type USB
@save :white_check_mark:
@direct :white_check_mark:
@effects :white_check_mark:
@detectors DetectAsusAuraUSBMotherboards
@comment The Asus Aura USB Mainboard controller applies to most
AMD and Intel mainboards from the x570 chipset onwards.
\*-------------------------------------------------------------------*/
RGBController_AuraMainboard::RGBController_AuraMainboard(AuraMainboardController* controller_ptr) :
RGBController_AuraUSB(controller_ptr)
{
name = "ASUS Aura USB Mainboard";
description = "ASUS Aura USB Mainboard Device";
/*-------------------------------------------------------*\
| Add manual save flag to all modes except direct mode |
\*-------------------------------------------------------*/
for(unsigned int mode_idx = 0; mode_idx < modes.size(); mode_idx++)
{
mode Mode = modes[mode_idx];
if(Mode.value != AURA_MODE_DIRECT)
{
Mode.flags |= MODE_FLAG_MANUAL_SAVE;
modes[mode_idx] = Mode;
}
}
}
void RGBController_AuraMainboard::DeviceUpdateShutdownEffect()
{
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]);
}
for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
{
AuraDeviceInfo device_info = controller->GetAuraDevices()[zone_idx];
/*---------------------------------------------------*\
| Shutdown effect only works with onboard lighting |
\*---------------------------------------------------*/
if(device_info.device_type == AuraDeviceType::FIXED && zones[zone_idx].leds_count > 0)
{
((AuraMainboardController*) controller)->SetMode(zone_idx, modes[active_mode].value, red, grn, blu, true);
}
}
}
void RGBController_AuraMainboard::DeviceSaveMode()
{
DeviceUpdateMode();
DeviceUpdateShutdownEffect();
((AuraMainboardController*) controller)->SendCommit();
}
@@ -0,0 +1,25 @@
/*-----------------------------------------*\
| RGBController_AsusAuraMainboard.h |
| |
| RGB controller for Asus Aura USB |
| mainboards |
| |
| rytypete 8/30/2023 |
| based on RGBController_AsusAuraUSB.h |
| code |
\*-----------------------------------------*/
#pragma once
#include "RGBController_AsusAuraUSB.h"
#include "AsusAuraMainboardController.h"
class RGBController_AuraMainboard : public RGBController_AuraUSB
{
public:
RGBController_AuraMainboard(AuraMainboardController* controller_ptr);
void DeviceSaveMode();
private:
void DeviceUpdateShutdownEffect();
};
@@ -9,11 +9,12 @@
#include "RGBController_AsusAuraMouse.h"
static std::string aura_mouse_zone_names[4]
static std::string aura_mouse_zone_names[5]
{
"Logo",
"Scroll Wheel",
"Underglow",
"All",
"Dock"
};
@@ -49,22 +49,25 @@ RGBController_AuraTUFKeyboard::RGBController_AuraTUFKeyboard(AuraTUFKeyboardCont
AURA_KEYBOARD_SPEED_MAX = 2;
AURA_KEYBOARD_SPEED_DEFAULT = 1;
break;
case AURA_ROG_STRIX_FLARE_PID:
case AURA_ROG_STRIX_FLARE_PNK_LTD_PID:
case AURA_ROG_STRIX_FLARE_COD_BO4_PID:
case AURA_TUF_K3_GAMING_PID:
case AURA_TUF_K7_GAMING_PID:
AURA_KEYBOARD_SPEED_MIN = 15;
AURA_KEYBOARD_SPEED_MAX = 0;
AURA_KEYBOARD_SPEED_DEFAULT = 8;
break;
case AURA_TUF_K5_GAMING_PID:
AURA_KEYBOARD_SPEED_MIN = 63;
AURA_KEYBOARD_SPEED_MAX = 0;
AURA_KEYBOARD_SPEED_DEFAULT = 31;
break;
case AURA_ROG_FALCHION_WIRED_PID:
case AURA_ROG_FALCHION_WIRELESS_PID:
case AURA_ROG_STRIX_FLARE_II_ANIMATE_PID:
case AURA_ROG_STRIX_SCOPE_RX_PID:
case AURA_ROG_STRIX_SCOPE_PID:
case AURA_ROG_STRIX_SCOPE_II_96_WIRELESS_USB_PID:
case AURA_TUF_K5_GAMING_PID:
AURA_KEYBOARD_SPEED_MIN = 255;
AURA_KEYBOARD_SPEED_MAX = 0;
AURA_KEYBOARD_SPEED_DEFAULT = 8;
AURA_KEYBOARD_SPEED_DEFAULT = 30;
break;
default:
AURA_KEYBOARD_SPEED_MIN = 15;
@@ -396,10 +399,25 @@ void RGBController_AuraTUFKeyboard::SetupZones()
switch(pid)
{
case AURA_ROG_STRIX_FLARE_PID:
case AURA_ROG_STRIX_FLARE_PNK_LTD_PID:
case AURA_ROG_STRIX_FLARE_COD_BO4_PID:
keyboard_ptr = &AsusROGStrixFlareLayouts;
break;
case AURA_TUF_K3_GAMING_PID:
case AURA_TUF_K7_GAMING_PID:
keyboard_ptr = &AsusTUFK7Layouts;
break;
case AURA_ROG_STRIX_SCOPE_PID:
case AURA_ROG_STRIX_SCOPE_RX_PID:
keyboard_ptr = &AsusROGStrixScopeLayouts;
break;
case AURA_ROG_STRIX_SCOPE_II_96_WIRELESS_USB_PID:
keyboard_ptr = &AsusROGStrixScopeII96WirelessLayouts;
break;
case AURA_ROG_STRIX_FLARE_II_ANIMATE_PID:
keyboard_ptr = &AsusROGStrixFlareIILayouts;
break;
case AURA_ROG_FALCHION_WIRED_PID:
case AURA_ROG_FALCHION_WIRELESS_PID:
keyboard_ptr = &AsusFalchionLayouts;
@@ -564,7 +582,7 @@ void RGBController_AuraTUFKeyboard::DeviceUpdateMode()
color_mode = 1;
}
if(modes[active_mode].value == AURA_KEYBOARD_MODE_WAVE)
if(modes[active_mode].value == AURA_KEYBOARD_MODE_WAVE || modes[active_mode].value == AURA_KEYBOARD_MODE_QUICKSAND)
{
/*----------------------------------------------------------*\
| converting openrgb direction value to keyboard directions |
@@ -16,9 +16,9 @@
@save :x:
@direct :white_check_mark:
@effects :white_check_mark:
@detectors DetectAsusAuraUSBTerminal,DetectAsusAuraUSBAddressable,DetectAsusAuraUSBMotherboards
@detectors DetectAsusAuraUSBTerminal,DetectAsusAuraUSBAddressable
@comment The Asus Aura USB controller applies to most AMD and
Intel mainboards from the x470 and z390 chipsets onwards.
Intel mainboards from the x470 and z390 chipset generations.
\*-------------------------------------------------------------------*/
RGBController_AuraUSB::RGBController_AuraUSB(AuraUSBController* controller_ptr) :
@@ -29,8 +29,10 @@ public:
void DeviceUpdateMode();
private:
protected:
AuraUSBController* controller;
private:
std::vector<unsigned int> leds_channel;
std::vector<unsigned int> zones_channel;
bool initializedMode;
@@ -13,9 +13,9 @@
@name Asus ROG Ally
@category Gamepad
@type USB
@save :x:
@save :white_check_mark:
@direct :white_check_mark:
@effects :x:
@effects :white_check_mark:
@detectors DetectAsusROGAlly
@comment
\*-------------------------------------------------------------------*/
@@ -1,16 +1,20 @@
#include "Detector.h"
#include "AsusCerberusKeyboardController.h"
#include "AsusSagarisKeyboardController.h"
#include "AsusStrixClawController.h"
#include "RGBController.h"
#include "RGBController_AsusCerberusKeyboard.h"
#include "RGBController_AsusSagarisKeyboard.h"
#include "RGBController_AsusStrixClaw.h"
#include <stdexcept>
#include <hidapi/hidapi.h>
#include "dependencies/dmiinfo.h"
#define ASUS_LEGACY_USB_VID 0x195D
#define ASUS_USB_VID 0x0B05
#define ASUS_CERBERUS_MECH_PID 0x2047
#define ASUS_SAGARIS_GK1100_PID 0x1835
#define ASUS_ROG_STRIX_CLAW_PID 0x1016
void DetectAsusCerberusMech(hid_device_info* info, const std::string& name)
@@ -26,6 +30,19 @@ void DetectAsusCerberusMech(hid_device_info* info, const std::string& name)
}
}
void DetectAsusSagarisKeyboard(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
AsusSagarisKeyboardController* controller = new AsusSagarisKeyboardController(dev, info->path, info->release_number);
RGBController_AsusSagarisKeyboard* rgb_controller = new RGBController_AsusSagarisKeyboard(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectAsusStrixClaw(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
@@ -40,5 +57,6 @@ void DetectAsusStrixClaw(hid_device_info* info, const std::string& name)
}
REGISTER_HID_DETECTOR_IPU("ASUS Cerberus Mech", DetectAsusCerberusMech, ASUS_LEGACY_USB_VID, ASUS_CERBERUS_MECH_PID, 1, 0xFF01, 1);
REGISTER_HID_DETECTOR_IPU("ASUS Sagaris GK1100", DetectAsusSagarisKeyboard, ASUS_USB_VID, ASUS_SAGARIS_GK1100_PID, 1, 0xFF02, 2);
REGISTER_HID_DETECTOR_IPU("ASUS ROG Strix Claw", DetectAsusStrixClaw, ASUS_LEGACY_USB_VID, ASUS_ROG_STRIX_CLAW_PID, 0, 0xFF01, 1);
@@ -0,0 +1,197 @@
/*-----------------------------------------*\
| AsusSagarisKeyboardController.cpp |
| |
| Driver for ASUS Sagaris USB lighting |
| controller |
| |
| Mola19 08/20/2023 |
\*-----------------------------------------*/
#include "AsusSagarisKeyboardController.h"
#include <cstring>
#include <string>
#include <math.h>
#include <vector>
#include <string.h>
#include "LogManager.h"
#define ASUS_SAGARIS_KB_PACKET_SIZE 65
AsusSagarisKeyboardController::AsusSagarisKeyboardController(hid_device* dev_handle, const char* path, unsigned short rev_version)
{
dev = dev_handle;
location = path;
version = rev_version;
}
AsusSagarisKeyboardController::~AsusSagarisKeyboardController()
{
hid_close(dev);
}
std::string AsusSagarisKeyboardController::GetVersion()
{
return std::to_string((int) floor(version / 0x100)) + "." + std::to_string(version % 0x100);
}
std::string AsusSagarisKeyboardController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string AsusSagarisKeyboardController::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);
}
sagaris_mode AsusSagarisKeyboardController::GetMode()
{
ClearResponses();
uint8_t usb_buf_out[ASUS_SAGARIS_KB_PACKET_SIZE];
memset(usb_buf_out, 0x00, sizeof(usb_buf_out));
usb_buf_out[0x00] = 0x06;
usb_buf_out[0x01] = 0x0B;
usb_buf_out[0x02] = 0x03;
hid_write(dev, usb_buf_out, ASUS_SAGARIS_KB_PACKET_SIZE);
unsigned char usb_buf_in[ASUS_SAGARIS_KB_PACKET_SIZE];
memset(usb_buf_in, 0x00, sizeof(usb_buf_in));
int return_length = hid_read_timeout(dev, usb_buf_in, ASUS_SAGARIS_KB_PACKET_SIZE, 100);
if(return_length == -1)
{
LOG_DEBUG("[Asus Sagaris GK1100]: Could not fetch mode");
sagaris_mode default_mode;
default_mode.mode = SAGARIS_KEYBOARD_MODE_STATIC;
default_mode.brightness = SAGARIS_KEYBOARD_BRIGHTNESS_DEFAULT;
default_mode.speed = 0;
default_mode.colorIndex = 0;
return default_mode;
}
sagaris_mode current_mode;
current_mode.mode = usb_buf_in[3];
current_mode.brightness = usb_buf_in[4];
current_mode.speed = usb_buf_in[5];
current_mode.colorIndex = usb_buf_in[6];
return current_mode;
}
std::vector<RGBColor> AsusSagarisKeyboardController::GetColors()
{
ClearResponses();
uint8_t usb_buf_out[ASUS_SAGARIS_KB_PACKET_SIZE];
memset(usb_buf_out, 0x00, sizeof(usb_buf_out));
usb_buf_out[0x00] = 0x06;
usb_buf_out[0x01] = 0x0B;
usb_buf_out[0x02] = 0x05;
hid_write(dev, usb_buf_out, ASUS_SAGARIS_KB_PACKET_SIZE);
std::vector<RGBColor> colors;
colors.resize(7);
for(int i = 0; i < 7; i++)
{
unsigned char usb_buf_in[ASUS_SAGARIS_KB_PACKET_SIZE];
memset(usb_buf_in, 0x00, sizeof(usb_buf_in));
int return_length = hid_read_timeout(dev, usb_buf_in, ASUS_SAGARIS_KB_PACKET_SIZE, 100);
if(return_length == -1)
{
LOG_DEBUG("[Asus Sagaris GK1100]: Could not fetch color %i", i);
colors[i] = ToRGBColor(0, 0, 0);
continue;
}
colors[i] = ToRGBColor(usb_buf_in[4] * 16, usb_buf_in[5] * 16, usb_buf_in[6] * 16);
}
return colors;
}
void AsusSagarisKeyboardController::SetColor
(
uint8_t index,
uint8_t red,
uint8_t green,
uint8_t blue
)
{
uint8_t usb_buf[ASUS_SAGARIS_KB_PACKET_SIZE];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x00] = 0x06;
usb_buf[0x01] = 0x0B;
usb_buf[0x02] = 0x04;
usb_buf[0x03] = 0x00;
usb_buf[0x04] = index;
usb_buf[0x05] = red;
usb_buf[0x06] = green;
usb_buf[0x07] = blue;
hid_write(dev, usb_buf, ASUS_SAGARIS_KB_PACKET_SIZE);
}
void AsusSagarisKeyboardController::SetMode
(
uint8_t mode,
uint8_t brightness,
uint8_t speed,
uint8_t colorIndex
)
{
ClearResponses();
uint8_t usb_buf[ASUS_SAGARIS_KB_PACKET_SIZE];
memset(usb_buf, 0x00, sizeof(usb_buf));
usb_buf[0x00] = 0x06;
usb_buf[0x01] = 0x0B;
usb_buf[0x02] = 0x01;
usb_buf[0x03] = mode;
usb_buf[0x04] = brightness;
usb_buf[0x05] = speed;
usb_buf[0x06] = colorIndex;
hid_write(dev, usb_buf, ASUS_SAGARIS_KB_PACKET_SIZE);
AwaitResponse(20);
}
void AsusSagarisKeyboardController::AwaitResponse(int ms)
{
unsigned char usb_buf[ASUS_SAGARIS_KB_PACKET_SIZE];
hid_read_timeout(dev, usb_buf, ASUS_SAGARIS_KB_PACKET_SIZE, ms);
}
void AsusSagarisKeyboardController::ClearResponses()
{
int result = 1;
unsigned char usb_buf_flush[65];
while(result > 0)
{
result = hid_read_timeout(dev, usb_buf_flush, 65, 0);
}
}
@@ -0,0 +1,76 @@
/*-----------------------------------------*\
| AsusSagarisKeyboardController.h |
| |
| Definitions and types for ASUS Sagaris |
| USB RGB lighting controller |
| |
| Mola19 08/20/2023 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <vector>
#include <hidapi/hidapi.h>
#pragma once
enum
{
SAGARIS_KEYBOARD_MODE_OFF = 0,
SAGARIS_KEYBOARD_MODE_STATIC = 1,
SAGARIS_KEYBOARD_MODE_SPRIAL = 2,
SAGARIS_KEYBOARD_MODE_CUSTOM = 3,
SAGARIS_KEYBOARD_MODE_BREATHING = 4,
SAGARIS_KEYBOARD_MODE_REACTIVE = 5,
SAGARIS_KEYBOARD_MODE_STARRY_NIGHT = 6,
SAGARIS_KEYBOARD_MODE_LASER = 7,
};
enum
{
SAGARIS_KEYBOARD_BRIGHTNESS_MIN = 0,
SAGARIS_KEYBOARD_BRIGHTNESS_MAX = 3,
SAGARIS_KEYBOARD_BRIGHTNESS_DEFAULT = 3
};
enum
{
SAGARIS_KEYBOARD_SPEED_MIN = 0,
SAGARIS_KEYBOARD_SPEED_MAX = 3,
SAGARIS_KEYBOARD_SPEED_DEFAULT = 2
};
typedef struct
{
uint8_t mode;
uint8_t brightness;
uint8_t speed;
uint8_t colorIndex;
} sagaris_mode;
class AsusSagarisKeyboardController
{
public:
AsusSagarisKeyboardController(hid_device* dev_handle, const char* path, unsigned short rev_version);
~AsusSagarisKeyboardController();
std::string GetVersion();
std::string GetDeviceLocation();
std::string GetSerialString();
sagaris_mode GetMode();
std::vector<RGBColor> GetColors();
void SetMode(uint8_t mode, uint8_t brightness, uint8_t speed, uint8_t colorIndex);
void SetColor(uint8_t index, uint8_t red, uint8_t green, uint8_t blue);
void AwaitResponse(int ms);
void ClearResponses();
private:
hid_device* dev;
std::string location;
unsigned short version;
};
@@ -0,0 +1,246 @@
/*-----------------------------------------*\
| RGBController_AsusSagarisKeyboard.cpp |
| |
| Generic RGB Interface for Asus Sagaris |
| USB controller driver |
| |
| Mola19 08/20/2023 |
\*-----------------------------------------*/
#include "RGBController_AsusSagarisKeyboard.h"
#include <vector>
/**------------------------------------------------------------------*\
@name Asus Sagaris Keyboard
@category Keyboard
@type USB
@save :robot:
@direct :x:
@effects :white_check_mark:
@detectors DetectAsusSagarisKeyboard
@comment Missing controls for modifier keys, as they have independent lighting
\*-------------------------------------------------------------------*/
#include <iostream>
RGBController_AsusSagarisKeyboard::RGBController_AsusSagarisKeyboard(AsusSagarisKeyboardController* controller_ptr)
{
controller = controller_ptr;
name = "ASUS Sagaris Keyboard";
vendor = "ASUS";
type = DEVICE_TYPE_KEYBOARD;
description = "ASUS Sagaris Keyboard Device";
version = controller->GetVersion();
location = controller->GetDeviceLocation();
serial = controller->GetSerialString();
mode Off;
Off.name = "Off";
Off.value = SAGARIS_KEYBOARD_MODE_OFF;
Off.flags = MODE_FLAG_AUTOMATIC_SAVE;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = SAGARIS_KEYBOARD_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS;
Static.brightness_min = SAGARIS_KEYBOARD_BRIGHTNESS_MIN;
Static.brightness_max = SAGARIS_KEYBOARD_BRIGHTNESS_MAX;
Static.brightness = SAGARIS_KEYBOARD_BRIGHTNESS_DEFAULT;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(1);
modes.push_back(Static);
mode Spiral;
Spiral.name = "Spiral";
Spiral.value = SAGARIS_KEYBOARD_MODE_SPRIAL;
Spiral.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Spiral.brightness_min = SAGARIS_KEYBOARD_BRIGHTNESS_MIN;
Spiral.brightness_max = SAGARIS_KEYBOARD_BRIGHTNESS_MAX;
Spiral.brightness = SAGARIS_KEYBOARD_BRIGHTNESS_DEFAULT;
Spiral.speed_min = SAGARIS_KEYBOARD_SPEED_MIN;
Spiral.speed_max = SAGARIS_KEYBOARD_SPEED_MAX;
Spiral.speed = SAGARIS_KEYBOARD_SPEED_DEFAULT;
Spiral.color_mode = MODE_COLORS_MODE_SPECIFIC;
Spiral.colors_min = 7;
Spiral.colors_max = 7;
Spiral.colors.resize(7);
modes.push_back(Spiral);
mode Custom;
Custom.name = "Custom";
Custom.value = SAGARIS_KEYBOARD_MODE_CUSTOM;
Custom.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS;
Custom.brightness_min = SAGARIS_KEYBOARD_BRIGHTNESS_MIN;
Custom.brightness_max = SAGARIS_KEYBOARD_BRIGHTNESS_MAX;
Custom.brightness = SAGARIS_KEYBOARD_BRIGHTNESS_DEFAULT;
Custom.color_mode = MODE_COLORS_MODE_SPECIFIC;
Custom.colors_min = 7;
Custom.colors_max = 7;
Custom.colors.resize(7);
modes.push_back(Custom);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = SAGARIS_KEYBOARD_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED;
Breathing.speed_min = SAGARIS_KEYBOARD_BRIGHTNESS_MIN;
Breathing.speed_max = SAGARIS_KEYBOARD_BRIGHTNESS_MAX;
Breathing.speed = SAGARIS_KEYBOARD_BRIGHTNESS_DEFAULT;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors_min = 7;
Breathing.colors_max = 7;
Breathing.colors.resize(7);
modes.push_back(Breathing);
mode Reactive;
Reactive.name = "Reactive";
Reactive.value = SAGARIS_KEYBOARD_MODE_REACTIVE;
Reactive.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Reactive.brightness_min = SAGARIS_KEYBOARD_BRIGHTNESS_MIN;
Reactive.brightness_max = SAGARIS_KEYBOARD_BRIGHTNESS_MAX;
Reactive.brightness = SAGARIS_KEYBOARD_BRIGHTNESS_DEFAULT;
Reactive.speed_min = SAGARIS_KEYBOARD_SPEED_MIN;
Reactive.speed_max = SAGARIS_KEYBOARD_SPEED_MAX;
Reactive.speed = SAGARIS_KEYBOARD_SPEED_DEFAULT;
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
Reactive.colors_min = 1;
Reactive.colors_max = 1;
Reactive.colors.resize(1);
modes.push_back(Reactive);
mode Starry_Night;
Starry_Night.name = "Starry Night";
Starry_Night.value = SAGARIS_KEYBOARD_MODE_STARRY_NIGHT;
Starry_Night.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Starry_Night.brightness_min = SAGARIS_KEYBOARD_SPEED_MIN;
Starry_Night.brightness_max = SAGARIS_KEYBOARD_SPEED_MAX;
Starry_Night.brightness = SAGARIS_KEYBOARD_SPEED_DEFAULT;
Starry_Night.speed_min = SAGARIS_KEYBOARD_BRIGHTNESS_MIN;
Starry_Night.speed_max = SAGARIS_KEYBOARD_BRIGHTNESS_MAX;
Starry_Night.speed = SAGARIS_KEYBOARD_BRIGHTNESS_DEFAULT;
Starry_Night.color_mode = MODE_COLORS_MODE_SPECIFIC;
Starry_Night.colors_min = 7;
Starry_Night.colors_max = 7;
Starry_Night.colors.resize(7);
modes.push_back(Starry_Night);
mode Laser;
Laser.name = "Laser";
Laser.value = SAGARIS_KEYBOARD_MODE_LASER;
Laser.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
Laser.brightness_min = SAGARIS_KEYBOARD_SPEED_MIN;
Laser.brightness_max = SAGARIS_KEYBOARD_SPEED_MAX;
Laser.brightness = SAGARIS_KEYBOARD_SPEED_DEFAULT;
Laser.speed_min = SAGARIS_KEYBOARD_BRIGHTNESS_MIN;
Laser.speed_max = SAGARIS_KEYBOARD_BRIGHTNESS_MAX;
Laser.speed = SAGARIS_KEYBOARD_BRIGHTNESS_DEFAULT;
Laser.color_mode = MODE_COLORS_MODE_SPECIFIC;
Laser.colors_min = 7;
Laser.colors_max = 7;
Laser.colors.resize(7);
modes.push_back(Laser);
SetupZones();
sagaris_mode current_mode = controller->GetMode();
active_mode = current_mode.mode;
last_mode = current_mode.mode;
modes[active_mode].brightness = current_mode.brightness;
modes[active_mode].speed = current_mode.speed;
current_colors = controller->GetColors();
for(int i = 0; i < modes[active_mode].colors.size(); i++)
{
modes[active_mode].colors[i] = current_colors[i];
}
}
RGBController_AsusSagarisKeyboard::~RGBController_AsusSagarisKeyboard()
{
delete controller;
}
void RGBController_AsusSagarisKeyboard::SetupZones()
{
zone keyboard;
keyboard.name = "Keyboard";
keyboard.type = ZONE_TYPE_SINGLE;
keyboard.leds_min = 1;
keyboard.leds_max = 1;
keyboard.leds_count = 1;
keyboard.matrix_map = nullptr;
SetupColors();
}
void RGBController_AsusSagarisKeyboard::ResizeZone(int /*zone*/, int /*new_size*/)
{
}
void RGBController_AsusSagarisKeyboard::DeviceUpdateLEDs()
{
}
void RGBController_AsusSagarisKeyboard::UpdateZoneLEDs(int /*zone*/)
{
}
void RGBController_AsusSagarisKeyboard::UpdateSingleLED(int led)
{
}
void RGBController_AsusSagarisKeyboard::DeviceUpdateMode()
{
if(last_mode != active_mode)
{
last_mode = active_mode;
for(int i = 0; i < modes[active_mode].colors.size(); i++)
{
modes[active_mode].colors[i] = current_colors[i];
}
}
else
{
for(int i = 0; i < modes[active_mode].colors.size(); i++)
{
current_colors[i] = modes[active_mode].colors[i];
}
for(int i = 0; i < modes[active_mode].colors.size(); i++)
{
/*-----------------------------------------*\
| This device uses 4bit colorValues (0-16) |
\*-----------------------------------------*/
uint8_t red = RGBGetRValue(modes[active_mode].colors[i]) / 16;
uint8_t green = RGBGetGValue(modes[active_mode].colors[i]) / 16;
uint8_t blue = RGBGetBValue(modes[active_mode].colors[i]) / 16;
controller->SetColor(i, red, green, blue);
}
}
/*------------------------------------------------------------------------------------------------------*\
| This device uses a global color storage for 7 colors, |
| each time a mode is selected, it is specified which color is chosen (some use all). |
| As OpenRGB doesn't support selecting the color index, color 1 is used for single color modes. |
\*------------------------------------------------------------------------------------------------------*/
uint8_t colorIndex = 0;
uint8_t mode = modes[active_mode].value;
if(mode == SAGARIS_KEYBOARD_MODE_STARRY_NIGHT) colorIndex = 7;
controller->SetMode(mode, modes[active_mode].brightness, modes[active_mode].speed, colorIndex);
}
@@ -0,0 +1,34 @@
/*-----------------------------------------*\
| RGBController_AsusSagarisKeyboard.h |
| |
| Generic RGB Interface for Asus Sagaris |
| USB controller driver |
| |
| Mola19 08/20/2023 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "AsusSagarisKeyboardController.h"
class RGBController_AsusSagarisKeyboard : public RGBController
{
public:
RGBController_AsusSagarisKeyboard(AsusSagarisKeyboardController* controller_ptr);
~RGBController_AsusSagarisKeyboard();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
private:
AsusSagarisKeyboardController* controller;
std::vector<RGBColor> current_colors;
uint8_t last_mode;
};
@@ -2,7 +2,6 @@
#include "BlinkyTapeController.h"
#include "RGBController.h"
#include "RGBController_BlinkyTape.h"
#include "SettingsManager.h"
#include "find_usb_serial_port.h"
#include <vector>
#include <stdio.h>
@@ -1,4 +1,5 @@
#include "Detector.h"
#include "LogManager.h"
#include "ColorfulGPUController.h"
#include "RGBController.h"
#include "RGBController_ColorfulGPU.h"
@@ -22,7 +23,9 @@ bool TestForColorfulGPU(i2c_smbus_interface* bus, uint8_t i2c_addr)
int res = bus->i2c_read_block(i2c_addr, &pktsz, read_pkt);
return res == 0 && (read_pkt[0] == 0xAA && read_pkt[1] == 0xEF && read_pkt[2] == 0x81);
LOG_DEBUG("[ColorfulGPUController] Handshake: res: %d. Expected 0xAA, 0xEF, 0x81. Received: 0x%02X, 0x%02X, 0x%02X.", res, read_pkt[0], read_pkt[1], read_pkt[2]);
return res >= 0 && (read_pkt[0] == 0xAA && read_pkt[1] == 0xEF && read_pkt[2] == 0x81);
}
void DetectColorfulGPUControllers(i2c_smbus_interface* bus, uint8_t i2c_addr, const std::string& name)
@@ -42,11 +45,15 @@ REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ultra W OC 12G L-V", DetectCo
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ultra W OC 12G L-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G_2, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Ultra W OC LHR-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G_2, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3070_ADVANCED_OCV, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_TI_ADVANCED_OC, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3070 Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3070_ADVANCED_OCV, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3070 Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3070_ADVANCED_OCV2, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3070 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3070_ULTRAW_OC, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3070 Ultra W OC LHR", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3070_ULTRAW_OC, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3070 Ti Ultra W OC LHR", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3070_TI_ULTRAW_OC, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3070 Ti Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3070_TI_ADVANCED_OCV2, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3080 Ti Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3080_TI_ADVANCED_OCV2, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 Ti Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070_TI_ADVANCED_OCV, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4080 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4080_ULTRAW_OCV2, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4090 Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4090_ADVANCED_OCV, 0x61);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4090 Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4090_ADVANCED_OCV2, 0x61);
@@ -65,12 +65,19 @@ void ColorfulTuringGPUController::SetStateDisplay(RGBColor color)
bus->i2c_write_block(dev, COLORFUL_COLOR_PACKET_LENGTH, data_pkt);
}
void ColorfulTuringGPUController::SetDirect(RGBColor color)
void ColorfulTuringGPUController::SetDirect(RGBColor color, bool save)
{
uint8_t r = RGBGetRValue(color);
uint8_t g = RGBGetGValue(color);
uint8_t b = RGBGetBValue(color);
uint8_t data_pkt[COLORFUL_COLOR_PACKET_LENGTH] = { 0x88, 0x02, 0x32, 0x02, r, g, b};
uint8_t data_pkt[COLORFUL_COLOR_PACKET_LENGTH] = { 0x08, 0x0, 0x20, 0x10, r, g, b};
if(save)
{
data_pkt[0] = 0x88;
data_pkt[1] = 0x02;
data_pkt[2] = 0x32;
data_pkt[3] = 0x02;
}
int crc = 1;
@@ -28,7 +28,7 @@ public:
std::string GetDeviceLocation();
int GetMode();
RGBColor GetColor();
void SetDirect(RGBColor color);
void SetDirect(RGBColor color, bool save);
void SetStateDisplay(RGBColor color);
void SetBreathing(RGBColor color);
void SetOff();
@@ -20,4 +20,5 @@ void DetectColorfulTuringGPUControllers(i2c_smbus_interface* bus, uint8_t i2c_ad
}
}
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 2070 SUPER Advanced OC-V", DetectColorfulTuringGPUControllers, NVIDIA_VEN, NVIDIA_RTX2070S_OC_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_2070_SUPER_ADVANCED_OCV, 0x50);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 2070 SUPER Advanced OC-V", DetectColorfulTuringGPUControllers, NVIDIA_VEN, NVIDIA_RTX2070S_OC_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_2070_SUPER_ADVANCED_OCV, 0x50);
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 2070 SUPER Advanced OC-V", DetectColorfulTuringGPUControllers, NVIDIA_VEN, NVIDIA_RTX2070S_OC_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_2070_SUPER_ADVANCED_OCV2, 0x50);
@@ -31,7 +31,7 @@ RGBController_ColorfulTuringGPU::RGBController_ColorfulTuringGPU(ColorfulTuringG
mode Direct;
Direct.name = "Direct";
Direct.value = COLORFUL_TURING_GPU_RGB_MODE_STATIC;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_MANUAL_SAVE;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
@@ -86,7 +86,7 @@ void RGBController_ColorfulTuringGPU::SetupZones()
zone new_zone;
new_zone.name = "GPU";
new_zone.type = ZONE_TYPE_LINEAR;
new_zone.type = ZONE_TYPE_SINGLE;
new_zone.leds_min = 1;
new_zone.leds_max = 1;
new_zone.leds_count = 1;
@@ -122,10 +122,10 @@ void RGBController_ColorfulTuringGPU::DeviceUpdateLEDs()
controller->SetStateDisplay(colors[0]);
break;
case COLORFUL_TURING_GPU_RGB_MODE_STATIC:
controller->SetDirect(colors[0]);
controller->SetDirect(colors[0], false);
break;
default:
controller->SetDirect(colors[0]);
controller->SetDirect(colors[0], false);
}
}
@@ -143,3 +143,15 @@ void RGBController_ColorfulTuringGPU::DeviceUpdateMode()
{
DeviceUpdateLEDs();
}
void RGBController_ColorfulTuringGPU::DeviceSaveMode()
{
switch(modes[active_mode].value)
{
case COLORFUL_TURING_GPU_RGB_MODE_STATIC:
controller->SetDirect(colors[0], true);
break;
default:
DeviceUpdateLEDs();
}
}
@@ -15,6 +15,7 @@ public:
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
void DeviceSaveMode();
private:
ColorfulTuringGPUController* controller;
@@ -36,7 +36,10 @@ CMARGBController::CMARGBController(hid_device* dev_handle, char *_path, unsigned
CMARGBController::~CMARGBController()
{
hid_close(dev);
if(mutex_ptr.use_count() <= 1)
{
hid_close(dev);
}
}
void CMARGBController::GetStatus()
@@ -1,10 +1,8 @@
/*-------------------------------------------------------------------*\
| CMMKController.cpp |
| |
| Driver for Coolermaster MasterKeys Keyboards |
| |
| Lukas N (chmod222) 28th Jun 2020 |
| Tam D (too.manyhobbies) 25th Apr 2021 |
| Lukas N (chmod222) 28th Jun 2020 |
| Tam D (too.manyhobbies) 25th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
@@ -29,28 +27,128 @@ CMMKController::CMMKController(hid_device* dev, hid_device_info* dev_info)
char buf[32] = {0};
cmmk_get_firmware_version(&cmmk_handle, buf, 32);
firmware_version = std::string(buf);
/*--------------------------------------------------------------*\
| 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:
kb_size = KEYBOARD_SIZE_TKL;
row_count = CMMK_ROWS_MAX - 1;
column_count = CMMK_COLS_MAX - 4;
break;
case CMMK_PRODUCT_MASTERKEYS_PRO_L:
case CMMK_PRODUCT_MASTERKEYS_MK750:
case CMMK_PRODUCT_MASTERKEYS_SK650:
kb_size = KEYBOARD_SIZE_FULL;
row_count = CMMK_ROWS_MAX - 1;
column_count = CMMK_COLS_MAX;
break;
case CMMK_PRODUCT_MASTERKEYS_MK750:
default:
kb_size = KEYBOARD_SIZE_FULL;
row_count = CMMK_ROWS_MAX;
column_count = CMMK_COLS_MAX;
}
firmware_version = buf;
/*--------------------------------------------------------------*\
| Detect the keyboard version and set the appropriate layout. |
\*--------------------------------------------------------------*/
switch(firmware_version[0])
{
case '1':
kb_layout_type = KEYBOARD_LAYOUT_ANSI_QWERTY;
break;
/*--------------------------------------------------------------*\
| In case we need to handle different versions in the future. |
\*--------------------------------------------------------------*/
default:
kb_layout_type = KEYBOARD_LAYOUT_ISO_QWERTY;
break;
}
/*--------------------------------------------------------------*\
| Populate key offsets. |
\*--------------------------------------------------------------*/
keyboard_layout* kb_layout;
if(KEYBOARD_LAYOUT_ANSI_QWERTY == kb_layout_type)
{
switch (kb_type)
{
case CMMK_PRODUCT_MASTERKEYS_PRO_L:
kb_layout = &layout_ansi_pro_l;
break;
case CMMK_PRODUCT_MASTERKEYS_PRO_S:
kb_layout = &layout_ansi_pro_s;
break;
case CMMK_PRODUCT_MASTERKEYS_MK750:
kb_layout = &layout_ansi_mk750;
break;
case CMMK_PRODUCT_MASTERKEYS_SK630:
kb_layout = &layout_ansi_sk630;
break;
case CMMK_PRODUCT_MASTERKEYS_SK650:
kb_layout = &layout_ansi_sk650;
break;
default:
kb_layout = 0;
break;
}
}
else
{
switch (kb_type)
{
case CMMK_PRODUCT_MASTERKEYS_PRO_L:
kb_layout = &layout_iso_pro_l;
break;
case CMMK_PRODUCT_MASTERKEYS_PRO_S:
kb_layout = &layout_iso_pro_s;
break;
case CMMK_PRODUCT_MASTERKEYS_MK750:
kb_layout = &layout_iso_mk750;
break;
case CMMK_PRODUCT_MASTERKEYS_SK630:
kb_layout = &layout_iso_sk630;
break;
case CMMK_PRODUCT_MASTERKEYS_SK650:
kb_layout = &layout_iso_sk650;
break;
default:
kb_layout = 0;
break;
}
}
std::vector<int> keys_fn, keys_main, keys_num, keys_extra;
memset(&kb_transform, -1, row_count*column_count);
int key_idx = 0;
if(kb_layout)
{
for(int row = 0; row < row_count; row++)
{
for(int col = 0; col < column_count; col++)
{
int val = (*kb_layout)[row][col];
if (-1 != val)
{
kb_offsets.ansi.push_back(val);
kb_transform[row][col] = key_idx;
key_idx++;
}
}
}
}
}
CMMKController::~CMMKController()
@@ -88,6 +186,26 @@ uint8_t CMMKController::GetColumnCount()
return column_count;
}
KEYBOARD_LAYOUT CMMKController::GetLayout()
{
return kb_layout_type;
}
keyboard_layout * CMMKController::GetTransform()
{
return &kb_transform;
}
KEYBOARD_SIZE CMMKController::GetSize()
{
return kb_size;
}
layout_values CMMKController::GetLayoutValues()
{
return kb_offsets;
}
void CMMKController::SetFirmwareControl()
{
ActivateMode(CMMK_FIRMWARE);
@@ -146,31 +264,31 @@ void CMMKController::SetMode(cmmk_effect_wave eff)
void CMMKController::SetMode(cmmk_effect_ripple eff)
{
ActivateEffect(CMMK_EFFECT_RIPPLE);
cmmk_set_effect_ripple(&cmmk_handle, &eff);
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);
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);
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);
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);
cmmk_set_effect_snake(&cmmk_handle, &eff);
}
bool CMMKController::PositionValid(int y, int x)
@@ -7,10 +7,31 @@
| |
\*-------------------------------------------------------------------*/
#include <string>
#include <cstring>
#include <KeyboardLayoutManager.h>
#include <hidapi/hidapi.h>
#include <libcmmk/libcmmk.h>
typedef int16_t keyboard_layout[CMMK_ROWS_MAX][CMMK_COLS_MAX];
/*---------------------------------------------------------*\
| i'm not thrilled with the include path, but this will |
| work for now. fixing this would need to happen in libcmmk |
\*---------------------------------------------------------*/
#pragma GCC push
#pragma GCC diagnostic ignored "-Wunused-variable"
#include <ansi/pro_s.h>
#include <ansi/pro_l.h>
#include <ansi/mk750.h>
#include <ansi/sk630.h>
#include <ansi/sk650.h>
#include <iso/pro_s.h>
#include <iso/pro_l.h>
#include <iso/mk750.h>
#include <iso/sk630.h>
#include <iso/sk650.h>
#pragma GCC pop
#pragma once
class CMMKController
@@ -19,12 +40,17 @@ 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();
std::string GetDeviceName();
std::string GetDeviceVendor();
std::string GetLocation();
std::string GetFirmwareVersion();
uint8_t GetRowCount();
uint8_t GetColumnCount();
KEYBOARD_LAYOUT GetLayout();
KEYBOARD_SIZE GetSize();
layout_values GetLayoutValues();
keyboard_layout* GetTransform();
void SetFirmwareControl();
void SetManualControl();
@@ -57,6 +83,13 @@ private:
std::string vendor_name;
std::string location;
std::string firmware_version;
KEYBOARD_SIZE kb_size;
KEYBOARD_LAYOUT kb_layout_type;
layout_values kb_offsets;
keyboard_layout kb_transform;
keyboard_layout* kb_layout;
uint8_t row_count;
uint8_t column_count;
@@ -0,0 +1,204 @@
/*-------------------------------------------------------------------*\
| CMMonitorController.cpp |
| |
| Driver for Coolermaster Gaming Monitor |
| |
| morg (Morgan Guimard) 9/18/2023 |
| |
\*-------------------------------------------------------------------*/
#include "CMMonitorController.h"
#include <cstring>
using namespace std::chrono_literals;
CMMonitorController::CMMonitorController(hid_device* dev_handle, const hid_device_info& info)
{
dev = dev_handle;
location = info.path;
wchar_t serial_string[128];
int ret = hid_get_serial_number_string(dev, serial_string, 128);
if(ret != 0)
{
serial_number = "";
}
else
{
std::wstring return_wstring = serial_string;
serial_number = std::string(return_wstring.begin(), return_wstring.end());
}
}
CMMonitorController::~CMMonitorController()
{
hid_close(dev);
}
std::string CMMonitorController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string CMMonitorController::GetSerialString()
{
return(serial_number);
}
void CMMonitorController::SetMode(uint8_t mode_value, const RGBColor& color, uint8_t speed, uint8_t brightness)
{
if(software_mode_enabled)
{
SetSoftwareModeEnabled(false);
}
uint8_t usb_buf[CM_MONITOR_PACKET_LENGTH];
memset(usb_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
usb_buf[1] = 0x80;
usb_buf[2] = (mode_value == CM_MONITOR_OFF_MODE) ? 0x0F : 0x0B;
usb_buf[3] = 0x02;
usb_buf[4] = 0x02;
usb_buf[5] = mode_value;
usb_buf[6] = (mode_value == CM_MONITOR_OFF_MODE) ? 0x00 : 0x08;
usb_buf[7] = speed;
usb_buf[8] = brightness;
usb_buf[9] = RGBGetRValue(color);
usb_buf[10] = RGBGetGValue(color);
usb_buf[11] = RGBGetBValue(color);
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
}
void CMMonitorController::SetCustomMode(const std::vector<RGBColor>& colors, uint8_t brightnesss)
{
if(software_mode_enabled)
{
SetSoftwareModeEnabled(false);
}
/*---------------------------------------------------------*\
| Creates the color buffer |
\*---------------------------------------------------------*/
uint8_t color_data[CM_MONITOR_COLOR_DATA_LENGTH];
memset(color_data, 0x00, CM_MONITOR_COLOR_DATA_LENGTH);
uint8_t offset = 0;
for(const RGBColor& color: colors)
{
color_data[offset++] = RGBGetRValue(color);
color_data[offset++] = RGBGetGValue(color);
color_data[offset++] = RGBGetBValue(color);
}
/*---------------------------------------------------------*\
| Sends the 7 sequence packets |
\*---------------------------------------------------------*/
uint8_t usb_buf[CM_MONITOR_PACKET_LENGTH];
offset = 0;
for(unsigned int i = 0; i < 7; i++)
{
memset(usb_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
usb_buf[1] = i < 6 ? i : 0x86;
/*---------------------------------------------------------*\
| First packet contains static data |
\*---------------------------------------------------------*/
if(i == 0)
{
usb_buf[2] = 0x10;
usb_buf[3] = 0x02;
usb_buf[4] = 0x02;
usb_buf[5] = 0x80;
usb_buf[6] = brightnesss;
memcpy(&usb_buf[7], &color_data[offset], CM_MONITOR_PACKET_LENGTH - 7);
offset += CM_MONITOR_PACKET_LENGTH - 7;
}
else
{
memcpy(&usb_buf[2], &color_data[offset], CM_MONITOR_PACKET_LENGTH - 2);
offset += (CM_MONITOR_PACKET_LENGTH - 2);
}
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
}
}
void CMMonitorController::SendDirect(const std::vector<RGBColor>& colors)
{
if(!software_mode_enabled)
{
SetSoftwareModeEnabled(true);
}
/*---------------------------------------------------------*\
| Creates the color buffer |
\*---------------------------------------------------------*/
uint8_t color_data[CM_MONITOR_COLOR_DATA_LENGTH];
memset(color_data, 0x00, CM_MONITOR_COLOR_DATA_LENGTH);
unsigned int offset = 0;
for(const RGBColor& color: colors)
{
color_data[offset++] = RGBGetRValue(color);
color_data[offset++] = RGBGetGValue(color);
color_data[offset++] = RGBGetBValue(color);
}
/*---------------------------------------------------------*\
| Sends the 7 sequence packets |
\*---------------------------------------------------------*/
uint8_t usb_buf[CM_MONITOR_PACKET_LENGTH];
offset = 0;
for(unsigned int i = 0; i < 7; i++)
{
memset(usb_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
usb_buf[1] = i < 6 ? i : 0x86;
if(i == 0)
{
usb_buf[2] = 0x07;
usb_buf[3] = 0x02;
usb_buf[4] = 0x02;
usb_buf[5] = 0x01;
usb_buf[6] = 0x80;
memcpy(&usb_buf[7], &color_data[offset], CM_MONITOR_PACKET_LENGTH - 7);
offset += CM_MONITOR_PACKET_LENGTH - 7;
}
else
{
memcpy(&usb_buf[2], &color_data[offset], CM_MONITOR_PACKET_LENGTH - 2);
offset += (CM_MONITOR_PACKET_LENGTH - 2);
}
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
}
}
void CMMonitorController::SetSoftwareModeEnabled(bool value)
{
uint8_t usb_buf[CM_MONITOR_PACKET_LENGTH];
memset(usb_buf, 0x00, CM_MONITOR_PACKET_LENGTH);
usb_buf[1] = 0x80;
usb_buf[2] = 0x07;
usb_buf[3] = 0x02;
usb_buf[4] = 0x02;
usb_buf[6] = value;
hid_write(dev, usb_buf, CM_MONITOR_PACKET_LENGTH);
software_mode_enabled = value;
}
@@ -0,0 +1,56 @@
/*-------------------------------------------------------------------*\
| CMMonitorController.cpp |
| |
| Driver for Coolermaster Gaming Monitor |
| |
| morg (Morgan Guimard) 9/18/2023 |
| |
\*-------------------------------------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
#define CM_MONITOR_PACKET_LENGTH 65
#define CM_MONITOR_COLOR_DATA_LENGTH 436
enum
{
CM_MONITOR_DIRECT_MODE = 0xFF,
CM_MONITOR_CUSTOM_MODE = 0xFE,
CM_MONITOR_SPECTRUM_MODE = 0x00,
CM_MONITOR_RELOAD_MODE = 0x01,
CM_MONITOR_RECOIL_MODE = 0x02,
CM_MONITOR_BREATHING_MODE = 0x03,
CM_MONITOR_REFILL_MODE = 0x04,
CM_MONITOR_OFF_MODE = 0x06
};
enum
{
CM_MONITOR_BRIGHTNESS_MAX = 0xFF,
CM_MONITOR_BRIGHTNESS_MIN = 0x00,
CM_MONITOR_SPEED_MAX = 0x04,
CM_MONITOR_SPEED_MIN = 0x00,
};
class CMMonitorController
{
public:
CMMonitorController(hid_device* dev_handle, const hid_device_info& info);
~CMMonitorController();
std::string GetSerialString();
std::string GetDeviceLocation();
void SendDirect(const std::vector<RGBColor>& colors);
void SetMode(uint8_t mode_value, const RGBColor& color, uint8_t speed, uint8_t brightness);
void SetCustomMode(const std::vector<RGBColor>& colors, uint8_t brightnesss);
private:
std::string serial_number;
std::string location;
hid_device* dev;
bool software_mode_enabled = false;
void SetSoftwareModeEnabled(bool value);
};
@@ -18,7 +18,7 @@
#include "RGBController_CMRGBController.h"
#include "RGBController_CMR6000Controller.h"
#include "RGBController_CMMKController.h"
#include "RGBController_CMMonitorController.h"
/*-----------------------------------------------------*\
| Coolermaster USB vendor ID |
\*-----------------------------------------------------*/
@@ -64,6 +64,11 @@
#define COOLERMASTER_MP750_L_PID 0x0107
#define COOLERMASTER_MP750_MEDIUM_PID 0x0105
/*-----------------------------------------------------*\
| Coolermaster Monitors |
\*-----------------------------------------------------*/
#define COOLERMASTER_GM27_FQS_PID 0x01BB
/******************************************************************************************\
* *
* DetectCoolerMasterControllers *
@@ -207,6 +212,19 @@ void DetectCoolerMasterSmallARGB(hid_device_info* info, const std::string&)
}
}
void DetectCoolerMasterMonitor(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CMMonitorController* controller = new CMMonitorController(dev, *info);
RGBController_CMMonitorController* rgb_controller = new RGBController_CMMonitorController(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
/*-----------------------------------------------------*\
| Coolermaster Keyboards |
\*-----------------------------------------------------*/
@@ -248,3 +266,8 @@ REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Medium", DetectCooler
\*-----------------------------------------------------*/
REGISTER_HID_DETECTOR_I ("Cooler Master Radeon 6000 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6000_PID, 1 );
REGISTER_HID_DETECTOR_I ("Cooler Master Radeon 6900 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6900_PID, 1 );
/*-----------------------------------------------------*\
| Coolermaster Monitors |
\*-----------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Cooler Master GM27-FQS ARGB Monitor", DetectCoolerMasterMonitor, COOLERMASTER_VID, COOLERMASTER_GM27_FQS_PID, 0, 0xFF00, 1);
@@ -34,7 +34,6 @@ using namespace std::chrono_literals;
RGBController_CMMKController::RGBController_CMMKController(CMMKController* controller_ptr)
{
controller = controller_ptr;
name = controller->GetDeviceName();
vendor = controller->GetDeviceVendor();
type = DEVICE_TYPE_KEYBOARD;
@@ -187,68 +186,48 @@ RGBController_CMMKController::~RGBController_CMMKController()
delete controller;
}
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 = controller->GetRowCount();
uint8_t column_count = controller->GetColumnCount();
/*---------------------------------------------------------*\
| Create the keyboard zone usiung Keyboard Layout Manager |
\*---------------------------------------------------------*/
zone new_zone;
new_zone.name = ZONE_EN_KEYBOARD;
new_zone.type = ZONE_TYPE_MATRIX;
for(int y = 0; y < row_count; y++)
layoutManager = new KeyboardLayoutManager(controller->GetLayout(), controller->GetSize(), controller->GetLayoutValues());
matrix_map_type * new_map = new matrix_map_type;
new_zone.matrix_map = new_map;
new_zone.matrix_map->height = layoutManager->GetRowCount();
new_zone.matrix_map->width = layoutManager->GetColumnCount();
new_zone.matrix_map->map = new unsigned int[new_map->height * new_map->width];
new_zone.leds_count = layoutManager->GetKeyCount();
new_zone.leds_min = new_zone.leds_count;
new_zone.leds_max = new_zone.leds_count;
/*---------------------------------------------------------*\
| Matrix map still uses declared zone rows and columns |
| as the packet structure depends on the matrix map |
\*---------------------------------------------------------*/
layoutManager->GetKeyMap(new_map->map, KEYBOARD_MAP_FILL_TYPE_COUNT, new_map->height, new_map->width);
/*---------------------------------------------------------*\
| Create LEDs for the Matrix zone |
| Place keys in the layout to populate the matrix |
\*---------------------------------------------------------*/
for(size_t led_idx = 0; led_idx < new_zone.leds_count; led_idx++)
{
for(int x = 0; x < column_count; x++)
{
if(!controller->PositionValid(y, x))
{
continue;
}
led new_led;
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);
}
new_led.name = layoutManager->GetKeyNameAt(led_idx);
new_led.value = layoutManager->GetKeyValueAt(led_idx);
leds.push_back(new_led);
}
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(new_zone);
zones.push_back(KeyboardZone);
SetupMatrixMap();
SetupColors();
}
@@ -290,32 +269,40 @@ enum cmmk_wave_direction map_to_cmmk_dir(int input)
}
}
void copy_buffers(led* buf, RGBColor* colbuf, size_t n, struct cmmk_color_matrix& mat, std::atomic<bool>& dirty)
void RGBController_CMMKController::copy_buffers(std::vector<RGBColor> &in_colors, struct cmmk_color_matrix& mat, std::atomic<bool>& dirty)
{
dirty.store(false);
for(size_t i = 0; i < n; i++)
keyboard_layout * transform = controller->GetTransform();
if(0 == transform)
{
led const& selected_led = buf[i];
return;
}
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)
for(int row = 0; row < controller->GetRowCount(); row++)
{
for(int col = 0; col < controller->GetColumnCount(); col++)
{
dirty.store(true);
int key_idx = (*transform)[row][col];
mat.data[y][x] = col;
if(-1 == key_idx)
{
continue;
}
struct rgb color = map_to_cmmk_rgb(in_colors[key_idx]);
dirty.store(true);
mat.data[row][col] = color;
}
}
}
void RGBController_CMMKController::DeviceUpdateLEDs()
{
copy_buffers(leds.data(), colors.data(), leds.size(), current_matrix, dirty);
copy_buffers(colors, current_matrix, dirty);
if(force_update.load() || dirty.load())
{
@@ -327,29 +314,47 @@ void RGBController_CMMKController::DeviceUpdateLEDs()
void RGBController_CMMKController::UpdateZoneLEDs(int zone_idx)
{
zone& z = zones[zone_idx];
/*---------------------------------------------------------*\
| This device only supports a single zone, as a result we |
| update all LEDs. |
\*---------------------------------------------------------*/
DeviceUpdateLEDs();
}
copy_buffers(z.leds, z.colors, z.leds_count, current_matrix, dirty);
void RGBController_CMMKController::UpdateSingleLED(int led_idx, RGBColor color)
{
keyboard_layout * transform = controller->GetTransform();
led selected_led = leds[led_idx];
if(force_update.load() || dirty.load())
if(0 == transform)
{
controller->SetAll(current_matrix);
force_update.store(false);
return;
}
// this is really expensive
for(int row = 0; row < controller->GetRowCount(); row++)
{
for(int col = 0; col < controller->GetColumnCount(); col++)
{
int val = (*transform)[row][col];
if(val != (int)selected_led.value)
{
continue;
}
controller->SetSingle(row, col, map_to_cmmk_rgb(color));
dirty.store(false);
return;
}
}
}
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]);
controller->SetSingle(y, x, map_to_cmmk_rgb(colors[led_idx]));
dirty.store(false);
UpdateSingleLED(led_idx, colors[led_idx]);
}
void RGBController_CMMKController::SetCustomMode()
@@ -1,42 +1,46 @@
/*-------------------------------------------------------------------*\
| 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* controller_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* controller;
int matrix_map[CMMK_ROWS_MAX][CMMK_COLS_MAX];
struct cmmk_color_matrix current_matrix;
std::atomic<bool> dirty;
std::atomic<bool> force_update;
};
/*-------------------------------------------------------------------*\
| RGBController_CMMKController.h |
| |
| Driver for Coolermaster MasterKeys keyboards |
| |
| Lukas N (chmod222) 28th Jun 2020 |
| Tam D (too.manyhobbies) 25th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
#pragma once
#include <cstring>
#include "RGBController.h"
#include "CMMKController.h"
#include "RGBControllerKeyNames.h"
#include "KeyboardLayoutManager.h"
class RGBController_CMMKController : public RGBController
{
public:
RGBController_CMMKController(CMMKController* controller_ptr);
~RGBController_CMMKController();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateSingleLED(int led, RGBColor color);
void UpdateSingleLED(int led);
void UpdateZoneLEDs(int zone_idx);
void SetCustomMode();
void DeviceUpdateMode();
private:
void copy_buffers(std::vector<RGBColor> &in_colors, struct cmmk_color_matrix& mat, std::atomic<bool>& dirty);
CMMKController* controller;
KeyboardLayoutManager* layoutManager;
struct cmmk_color_matrix current_matrix;
std::atomic<bool> dirty;
std::atomic<bool> force_update;
};
@@ -0,0 +1,225 @@
/*-------------------------------------------------------------------*\
| RGBController_CMMonitorController.cpp |
| |
| Driver for Coolermaster Gaming Monitor USB Controller |
| |
| morg (Morgan Guimard) 9/18/2023 |
| |
\*-------------------------------------------------------------------*/
#include "RGBController_CMMonitorController.h"
#include <thread>
#include <chrono>
/**------------------------------------------------------------------*\
@name Coolermaster Gaming Monitor
@category LEDStrip
@type USB
@save :robot:
@direct :white_check_mark:
@effects :white_check_mark:
@detectors DetectCoolerMasterMonitor
@comment
\*-------------------------------------------------------------------*/
RGBController_CMMonitorController::RGBController_CMMonitorController(CMMonitorController* controller_ptr)
{
controller = controller_ptr;
name = "CoolerMaster LED Controller A1";
vendor = "CoolerMaster";
type = DEVICE_TYPE_LEDSTRIP;
description = name;
location = controller->GetDeviceLocation();
serial = controller->GetSerialString();
version = "";
mode Direct;
Direct.name = "Direct";
Direct.value = CM_MONITOR_DIRECT_MODE;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Spectrum;
Spectrum.name = "Spectrum cycle";
Spectrum.value = CM_MONITOR_SPECTRUM_MODE;
Spectrum.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Spectrum.color_mode = MODE_COLORS_NONE;
Spectrum.speed_min = CM_MONITOR_SPEED_MIN;
Spectrum.speed_max = CM_MONITOR_SPEED_MAX;
Spectrum.speed = CM_MONITOR_SPEED_MAX/2;
Spectrum.brightness_min = CM_MONITOR_BRIGHTNESS_MIN;
Spectrum.brightness_max = CM_MONITOR_BRIGHTNESS_MAX;
Spectrum.brightness = CM_MONITOR_BRIGHTNESS_MAX;
modes.push_back(Spectrum);
mode Reload;
Reload.name = "Reload";
Reload.value = CM_MONITOR_RELOAD_MODE;
Reload.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Reload.color_mode = MODE_COLORS_MODE_SPECIFIC;
Reload.colors_min = 1;
Reload.colors_max = 1;
Reload.colors.resize(1);
Reload.speed_min = CM_MONITOR_SPEED_MIN;
Reload.speed_max = CM_MONITOR_SPEED_MAX;
Reload.speed = CM_MONITOR_SPEED_MAX/2;
Reload.brightness_min = CM_MONITOR_BRIGHTNESS_MIN;
Reload.brightness_max = CM_MONITOR_BRIGHTNESS_MAX;
Reload.brightness = CM_MONITOR_BRIGHTNESS_MAX;
modes.push_back(Reload);
mode Recoil;
Recoil.name = "Recoil";
Recoil.value = CM_MONITOR_RECOIL_MODE;
Recoil.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Recoil.color_mode = MODE_COLORS_MODE_SPECIFIC;
Recoil.colors_min = 1;
Recoil.colors_max = 1;
Recoil.colors.resize(1);
Recoil.speed_min = CM_MONITOR_SPEED_MIN;
Recoil.speed_max = CM_MONITOR_SPEED_MAX;
Recoil.speed = CM_MONITOR_SPEED_MAX/2;
Recoil.brightness_min = CM_MONITOR_BRIGHTNESS_MIN;
Recoil.brightness_max = CM_MONITOR_BRIGHTNESS_MAX;
Recoil.brightness = CM_MONITOR_BRIGHTNESS_MAX;
modes.push_back(Recoil);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CM_MONITOR_BREATHING_MODE;
Breathing.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(1);
Breathing.speed_min = CM_MONITOR_SPEED_MIN;
Breathing.speed_max = CM_MONITOR_SPEED_MAX;
Breathing.speed = CM_MONITOR_SPEED_MAX/2;
Breathing.brightness_min = CM_MONITOR_BRIGHTNESS_MIN;
Breathing.brightness_max = CM_MONITOR_BRIGHTNESS_MAX;
Breathing.brightness = CM_MONITOR_BRIGHTNESS_MAX;
modes.push_back(Breathing);
mode Refill;
Refill.name = "Refill";
Refill.value = CM_MONITOR_REFILL_MODE;
Refill.flags = MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Refill.color_mode = MODE_COLORS_MODE_SPECIFIC;
Refill.colors_min = 1;
Refill.colors_max = 1;
Refill.colors.resize(1);
Refill.speed_min = CM_MONITOR_SPEED_MIN;
Refill.speed_max = CM_MONITOR_SPEED_MAX;
Refill.speed = CM_MONITOR_SPEED_MAX/2;
Refill.brightness_min = CM_MONITOR_BRIGHTNESS_MIN;
Refill.brightness_max = CM_MONITOR_BRIGHTNESS_MAX;
Refill.brightness = CM_MONITOR_BRIGHTNESS_MAX;
modes.push_back(Refill);
mode Custom;
Custom.name = "Custom";
Custom.value = CM_MONITOR_CUSTOM_MODE;
Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_AUTOMATIC_SAVE | MODE_FLAG_HAS_BRIGHTNESS;
Custom.color_mode = MODE_COLORS_PER_LED;
Custom.brightness_min = CM_MONITOR_BRIGHTNESS_MIN;
Custom.brightness_max = CM_MONITOR_BRIGHTNESS_MAX;
Custom.brightness = CM_MONITOR_BRIGHTNESS_MAX;
modes.push_back(Custom);
mode Off;
Off.name = "Off";
Off.value = CM_MONITOR_SPECTRUM_MODE;
Off.flags = MODE_FLAG_AUTOMATIC_SAVE;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
SetupZones();
}
RGBController_CMMonitorController::~RGBController_CMMonitorController()
{
delete controller;
}
void RGBController_CMMonitorController::SetupZones()
{
zone z;
z.name = "Monitor";
z.type = ZONE_TYPE_LINEAR;
z.leds_min = 47;
z.leds_max = 47;
z.leds_count = 47;
z.matrix_map = NULL;
zones.push_back(z);
for(unsigned int i = 0; i < 47; i++)
{
led l;
l.name = std::to_string(i + 1);
l.value = i;
leds.push_back(l);
}
SetupColors();
}
void RGBController_CMMonitorController::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_CMMonitorController::DeviceUpdateLEDs()
{
if(modes[active_mode].value == CM_MONITOR_DIRECT_MODE)
{
controller->SendDirect(colors);
}
else if(modes[active_mode].value == CM_MONITOR_CUSTOM_MODE)
{
controller->SetCustomMode(colors, modes[active_mode].brightness);
}
}
void RGBController_CMMonitorController::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_CMMonitorController::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_CMMonitorController::SetCustomMode()
{
active_mode = 0;
}
void RGBController_CMMonitorController::DeviceUpdateMode()
{
switch(modes[active_mode].value)
{
case CM_MONITOR_OFF_MODE:
case CM_MONITOR_SPECTRUM_MODE:
controller->SetMode(modes[active_mode].value, 0, modes[active_mode].speed, modes[active_mode].brightness);
break;
case CM_MONITOR_RELOAD_MODE:
case CM_MONITOR_RECOIL_MODE:
case CM_MONITOR_BREATHING_MODE:
case CM_MONITOR_REFILL_MODE:
controller->SetMode(modes[active_mode].value, modes[active_mode].colors[0], modes[active_mode].speed, modes[active_mode].brightness);
break;
case CM_MONITOR_CUSTOM_MODE:
DeviceUpdateLEDs();
break;
default: break;
}
}
@@ -0,0 +1,30 @@
/*-------------------------------------------------------------------*\
| RGBController_CMMonitorController.cpp |
| |
| Driver for Coolermaster Gaming Monitor USB Controller |
| |
| morg (Morgan Guimard) 9/18/2023 |
| |
\*-------------------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CMMonitorController.h"
#include <vector>
class RGBController_CMMonitorController : public RGBController
{
public:
RGBController_CMMonitorController(CMMonitorController* controller_ptr);
~RGBController_CMMonitorController();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
CMMonitorController* controller;
};
@@ -87,7 +87,7 @@ RGBController_CMR6000Controller::RGBController_CMR6000Controller(CMR6000Controll
Rainbow.speed = MR6000_RAINBOW_SPEED_NORMAL;
Rainbow.speed_max = MR6000_RAINBOW_SPEED_FASTEST;
Rainbow.color_mode = MODE_COLORS_NONE;
Rainbow.speed = MR6000_CYCLE_SPEED_NORMAL;
Rainbow.speed = MR6000_RAINBOW_SPEED_NORMAL;
Rainbow.brightness_min = 0x00;
Rainbow.brightness_max = 0xFF;
Rainbow.brightness = 0xFF;
@@ -23,6 +23,9 @@ CorsairCommanderCoreController::CorsairCommanderCoreController(hid_device* dev_h
packet_size = CORSAIR_COMMANDER_CORE_PACKET_SIZE_V2;
command_res_size = packet_size - 4;
this->pid = pid;
#ifdef _WIN32
global_corsair_access_handle = CreateMutexA(NULL, FALSE, GLOBAL_CORSAIR_MUTEX_NAME);
#endif
/*-----------------------------------------------------*\
| Initialize controller |
@@ -40,6 +43,12 @@ CorsairCommanderCoreController::~CorsairCommanderCoreController()
/*-----------------------------------------------------*\
| Close keepalive thread |
\*-----------------------------------------------------*/
#ifdef _WIN32
if(global_corsair_access_handle != NULL)
{
CloseHandle(global_corsair_access_handle);
}
#endif
keepalive_thread_run = 0;
keepalive_thread->join();
delete keepalive_thread;
@@ -57,18 +66,19 @@ void CorsairCommanderCoreController::InitController()
\*-----------------------------------------------------*/
unsigned char command[2] = {0x02, 0x13};
unsigned char* res = new unsigned char[command_res_size];
SendCommand(command, NULL, 0, res);
version[0] = res[0];
version[1] = res[1];
version[2] = res[2];
delete[] res;
if (pid == 0x0C1C && version[0] == 1)
if(pid == 0x0C1C && version[0] == 1)
{
packet_size = CORSAIR_COMMANDER_CORE_PACKET_SIZE_V1;
command_res_size = packet_size - 4;
}
else if (pid == 0x0C32)
else if(pid == 0x0C32)
{
packet_size = CORSAIR_COMMANDER_CORE_PACKET_SIZE_V3;
}
@@ -98,7 +108,7 @@ void CorsairCommanderCoreController::KeepaliveThread()
{
while(keepalive_thread_run.load())
{
if (controller_ready)
if(controller_ready)
{
if((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::seconds(10))
{
@@ -143,6 +153,13 @@ void CorsairCommanderCoreController::SendCommand(unsigned char command[2], unsig
\*---------------------------------------------------------*/
unsigned char* buf = new unsigned char[packet_size];
#ifdef _WIN32
if(global_corsair_access_handle != NULL)
{
WaitForSingleObject(global_corsair_access_handle, INFINITE);
}
#endif
memset(buf, 0, packet_size);
buf[0] = 0x00;
buf[1] = 0x08;
@@ -165,6 +182,13 @@ void CorsairCommanderCoreController::SendCommand(unsigned char command[2], unsig
memcpy(res, &buf[3], command_res_size);
}
#ifdef _WIN32
if(global_corsair_access_handle != NULL)
{
ReleaseMutex(global_corsair_access_handle);
}
#endif
delete[] buf;
}
@@ -177,6 +201,13 @@ void CorsairCommanderCoreController::WriteData(unsigned char endpoint[2], unsign
/*---------------------------------------------------------*\
| Open endpoint |
\*---------------------------------------------------------*/
#ifdef _WIN32
if(global_corsair_access_handle != NULL)
{
WaitForSingleObject(global_corsair_access_handle, INFINITE);
}
#endif
unsigned char command[2] = {0x0d, 0x00};
SendCommand(command, endpoint, 2, NULL);
@@ -240,6 +271,13 @@ void CorsairCommanderCoreController::WriteData(unsigned char endpoint[2], unsign
command[0] = 0x05;
command[1] = 0x01;
SendCommand(command, NULL, 0, NULL);
#ifdef _WIN32
if(global_corsair_access_handle != NULL)
{
ReleaseMutex(global_corsair_access_handle);
}
#endif
}
void CorsairCommanderCoreController::SetDirectColor
@@ -9,10 +9,15 @@
\*---------------------------------------------------------*/
#include "RGBController.h"
#include <vector>
#include <chrono>
#include <hidapi/hidapi.h>
#ifdef _WIN32
#include <Windows.h>
#endif
#pragma once
#define CORSAIR_COMMANDER_CORE_PACKET_SIZE_V1 1025 // First bit is the report bit
@@ -23,6 +28,10 @@
#define CORSAIR_QL_FAN_ZONE_OFFSET 102
#define CORSAIR_COMMANDER_CORE_NUM_CHANNELS 6
#ifdef _WIN32
#define GLOBAL_CORSAIR_MUTEX_NAME "Global\\CorsairLinkReadWriteGuardMutex"
#endif
enum
{
CORSAIR_COMMANDER_CORE_MODE_DIRECT = 0x00,
@@ -60,6 +69,10 @@ private:
int pid;
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
#ifdef _WIN32
HANDLE global_corsair_access_handle = NULL;
#endif
void SendCommand(unsigned char command[2], unsigned char data[], unsigned short int data_len, unsigned char res[]);
void WriteData(unsigned char endpoint[2], unsigned char data_type[2], unsigned char data[], unsigned short int data_len);
@@ -2,9 +2,11 @@
#include "CorsairDominatorPlatinumController.h"
#include "RGBController.h"
#include "RGBController_CorsairDominatorPlatinum.h"
#include "SettingsManager.h"
#include "LogManager.h"
#include "i2c_smbus.h"
#include "pci_ids.h"
#include "LogManager.h"
#include <vector>
#include <stdio.h>
#include <stdlib.h>
@@ -80,7 +80,7 @@ REGISTER_DETECTOR("Corsair Hydro Series", DetectCorsairHydroControllers);
/*---------------------------------------------------------------------------------------------------------*\
| Entries for dynamic UDEV rules |
| |
| DUMMY_DEVICE_DETECTOR("Corsair Hydro Series", DetectCorsairHydroControllers, 0x1B1C, x0C12 ) |
| DUMMY_DEVICE_DETECTOR("Corsair Hydro Series", DetectCorsairHydroControllers, 0x1B1C, x0C13 ) |
| DUMMY_DEVICE_DETECTOR("Corsair Hydro Series", DetectCorsairHydroControllers, 0x1B1C, x0C15 ) |
| DUMMY_DEVICE_DETECTOR("Corsair Hydro Series", DetectCorsairHydroControllers, 0x1B1C, 0x0C12 ) |
| DUMMY_DEVICE_DETECTOR("Corsair Hydro Series", DetectCorsairHydroControllers, 0x1B1C, 0x0C13 ) |
| DUMMY_DEVICE_DETECTOR("Corsair Hydro Series", DetectCorsairHydroControllers, 0x1B1C, 0x0C15 ) |
\*---------------------------------------------------------------------------------------------------------*/
@@ -59,7 +59,7 @@ static unsigned int keys_k95[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
static unsigned int st100[] = { 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x04 };
static unsigned int key_mapping_k95_plat_ansi[] = { 0x31, 0x3f, 0x41, 0x42, 0x51, 0x53, 0x55, 0x6f, 0x7e, 0x7f, 0x80, 0x81 };
static unsigned int key_mapping_k95_plat_iso[] = { 0x3f, 0x41, 0x42, 0x48, 0x50, 0x53, 0x55, 0x6f, 0x7e, 0x7f, 0x80, 0x81 };
static unsigned int key_mapping_k95_plat_iso[] = { 0x3f, 0x41, 0x42, 0x50, 0x53, 0x55, 0x6f, 0x78, 0x7e, 0x7f, 0x80, 0x81 };
static unsigned int key_mapping_k70_mk2_plat_iso[] = { 0x3f, 0x41, 0x42, 0x50, 0x53, 0x55, 0x6f, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81 };
#define CORSAIR_PERIPHERAL_CONTROLLER_NAME "Corsair peripheral"
@@ -11,7 +11,7 @@
using namespace std::chrono_literals;
CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_handle, const char* path, std::string /*name*/, uint16_t pid)
CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_handle, const char* path, std::string /*name*/)
{
const uint8_t sz = HID_MAX_STR;
wchar_t tmp[sz];
@@ -27,37 +27,83 @@ CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_han
wName = std::wstring(tmp);
device_name.append(" ").append(std::string(wName.begin(), wName.end()));
for(size_t i = 0; i < CORSAIR_V2_DEVICE_COUNT; i++)
/*---------------------------------------------------------*\
| Get PID |
| If the PID is in the know wireless receivers list |
| switch the write_cmd to talk to the device and retry |
\*---------------------------------------------------------*/
unsigned int pid = GetAddress(0x12);
switch(pid)
{
case CORSAIR_SLIPSTREAM_WIRELESS_PID:
write_cmd = CORSAIR_V2_WRITE_WIRELESS_ID;
pid = GetAddress(0x12);
break;
}
/*---------------------------------------------------------*\
| If the hid_pid passed in from the detector does not match |
| the pid reported by the device then it is likey |
| behind a wireless receiver. |
\*---------------------------------------------------------*/
LOG_DEBUG("[%s] Setting write CMD to %02X for %s mode for PID %04X", device_name.c_str(),
write_cmd, (write_cmd == CORSAIR_V2_WRITE_WIRELESS_ID) ? "wireless" : "wired", pid);
/*---------------------------------------------------------*\
| Get VID |
| NB: this can be achieved with GetAddress(0x11) but we |
| also need to set the packet length capabilities for |
| the device being set up. |
\*---------------------------------------------------------*/
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
buffer[1] = write_cmd;
buffer[2] = CORSAIR_V2_CMD_GET;
buffer[3] = 0x11;
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
uint16_t result = hid_read_timeout(dev, buffer, CORSAIR_V2_PACKET_SIZE, CORSAIR_V2_TIMEOUT);
result++;
pkt_sze = result;
LOG_DEBUG("[%s] Packet length set to %d", device_name.c_str(), pkt_sze);
/*---------------------------------------------------------*\
| NB: If the device is not found in the device list |
| then wireless mode may not work reliably |
\*---------------------------------------------------------*/
bool not_found = true;
for(uint16_t i = 0; i < CORSAIR_V2_DEVICE_COUNT; i++)
{
if(corsair_v2_device_list[i]->pid == pid)
{
/*---------------------------------------------------------*\
| Set device ID |
\*---------------------------------------------------------*/
not_found = false;
device_index = i;
break;
}
}
/*---------------------------------------------------------*\
| NB: If the device is not found in the device list |
| then wireless mode may not work reliably |
\*---------------------------------------------------------*/
bool wireless = corsair_v2_device_list[device_index]->wireless;
if(wireless)
if(not_found)
{
write_cmd = CORSAIR_V2_WRITE_WIRELESS_ID;
LOG_ERROR("[%s] device capabilities not found. Please creata a new device request.",
device_name.c_str());
}
LOG_DEBUG("[%s] Setting write CMD to %02X for %s mode", device_name.c_str(),
write_cmd, (wireless) ? "wireless" : "wired" );
/*---------------------------------------------------------*\
| Get VID |
| Check lighting control endpoints |
| If lighting control endpoint 2 is unavailable |
| then use endpoint 1. |
\*---------------------------------------------------------*/
GetAddress(0x11);
/*---------------------------------------------------------*\
| Get PID |
\*---------------------------------------------------------*/
GetAddress(0x12);
result = StartTransaction(0);
if(result > 0)
{
light_ctrl = CORSAIR_V2_LIGHT_CTRL1;
StartTransaction(0);
}
StopTransaction(0);
LOG_DEBUG("[%s] Lighting Endpoint set to %02X", device_name.c_str(), light_ctrl);
}
CorsairPeripheralV2Controller::~CorsairPeripheralV2Controller()
@@ -75,6 +121,21 @@ std::string CorsairPeripheralV2Controller::GetDeviceLocation()
return("HID: " + location);
}
std::string CorsairPeripheralV2Controller::GetErrorString(uint8_t err)
{
switch(err)
{
case 1:
return "Invalid Value";
case 3:
return "Failed";
case 5:
return "Unsupported";
default:
return "Protocol Error (Unknown)";
}
}
std::string CorsairPeripheralV2Controller::GetFirmwareString()
{
return "";
@@ -122,7 +183,7 @@ void CorsairPeripheralV2Controller::SetRenderMode(corsair_v2_device_mode mode)
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
}
void CorsairPeripheralV2Controller::LightingControl(uint8_t opt1, uint8_t opt2)
void CorsairPeripheralV2Controller::LightingControl(uint8_t opt1)
{
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
@@ -140,17 +201,6 @@ void CorsairPeripheralV2Controller::LightingControl(uint8_t opt1, uint8_t opt2)
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
/*---------------------------------------------------------*\
| Open a RGB lighting handle |
\*---------------------------------------------------------*/
buffer[2] = 0x0D;
buffer[3] = 0x00;
buffer[4] = 0x01;
buffer[5] = opt2;
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
}
unsigned int CorsairPeripheralV2Controller::GetKeyboardLayout()
@@ -181,13 +231,13 @@ unsigned int CorsairPeripheralV2Controller::GetAddress(uint8_t address)
if(result > 0)
{
LOG_DEBUG("[%s] An error occurred! Get Address %02X failed - %d %s", device_name.c_str(),
address, result, (result == 5) ? "unsupported" : "");
address, result, GetErrorString(result).c_str());
return -1;
}
return temp;
}
void CorsairPeripheralV2Controller::StartTransaction(uint8_t opt1)
unsigned char CorsairPeripheralV2Controller::StartTransaction(uint8_t opt1)
{
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
@@ -196,10 +246,12 @@ void CorsairPeripheralV2Controller::StartTransaction(uint8_t opt1)
buffer[1] = write_cmd;
buffer[2] = CORSAIR_V2_CMD_START_TX;
buffer[3] = opt1;
buffer[4] = 0x01;
buffer[4] = light_ctrl;
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
return buffer[2];
}
void CorsairPeripheralV2Controller::StopTransaction(uint8_t opt1)
@@ -217,15 +269,28 @@ void CorsairPeripheralV2Controller::StopTransaction(uint8_t opt1)
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
}
void CorsairPeripheralV2Controller::ClearPacketBuffer()
{
uint8_t result = 0;
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
do
{
result = hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
}
while(result > 0);
}
void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
{
const uint8_t offset1 = 8;
const uint8_t offset2 = 4;
uint16_t remaining = data_size;
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
memset(buffer, 0, CORSAIR_V2_PACKET_SIZE);
ClearPacketBuffer();
StartTransaction(0);
/*---------------------------------------------------------*\
| Set the data header in packet 1 with the data length |
@@ -239,7 +304,7 @@ void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
/*---------------------------------------------------------*\
| Check if the data needs more than 1 packet |
\*---------------------------------------------------------*/
uint16_t copy_bytes = CORSAIR_V2_WRITE_SIZE - offset1;
uint16_t copy_bytes = pkt_sze - offset1;
if(remaining < copy_bytes)
{
copy_bytes = remaining;
@@ -247,12 +312,12 @@ void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
memcpy(&buffer[offset1], &data[0], copy_bytes);
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT_SHORT);
hid_write(dev, buffer, pkt_sze);
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
remaining -= copy_bytes;
buffer[2] = CORSAIR_V2_CMD_BLK_WN;
copy_bytes = CORSAIR_V2_WRITE_SIZE - offset2;
copy_bytes = pkt_sze - offset2;
/*---------------------------------------------------------*\
| Send the remaining packets |
@@ -268,8 +333,8 @@ void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
memcpy(&buffer[offset2], &data[index], copy_bytes);
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT_SHORT);
hid_write(dev, buffer, pkt_sze);
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
remaining -= copy_bytes;
}
@@ -25,6 +25,12 @@
#define CORSAIR_V2_WRITE_WIRED_ID 8
#define CORSAIR_V2_WRITE_WIRELESS_ID 9
#define CORSAIR_V2_WRITE_SIZE 65
#define CORSAIR_V2_PACKET_SIZE 1024
#define CORSAIR_V2_LIGHT_CTRL1 1
#define CORSAIR_V2_LIGHT_CTRL2 34 /* 0x22 */
#define CORSAIR_V2_UPDATE_PERIOD 30000
#define CORSAIR_V2_SLEEP_PERIOD 12500ms
#define CORSAIR_V2_BRIGHTNESS_MIN 0
#define CORSAIR_V2_BRIGHTNESS_MAX 0xFF
@@ -67,10 +73,11 @@ enum corsair_v2_color
class CorsairPeripheralV2Controller
{
public:
CorsairPeripheralV2Controller(hid_device* dev_handle, const char* path, std::string name, uint16_t pid);
CorsairPeripheralV2Controller(hid_device* dev_handle, const char* path, std::string name);
virtual ~CorsairPeripheralV2Controller();
std::string GetDeviceLocation();
std::string GetErrorString(uint8_t err);
std::string GetFirmwareString();
std::string GetName();
std::string GetSerialString();
@@ -78,7 +85,7 @@ public:
unsigned int GetKeyboardLayout();
void SetRenderMode(corsair_v2_device_mode mode);
void LightingControl(uint8_t opt1, uint8_t opt2);
void LightingControl(uint8_t opt1);
void SetLEDs(uint8_t *data, uint16_t data_size);
void UpdateHWMode(uint16_t mode, corsair_v2_color color_mode, uint8_t speed,
uint8_t direction, uint8_t brightness, std::vector<RGBColor> colors);
@@ -88,15 +95,18 @@ public:
protected:
uint16_t device_index;
std::string device_name;
uint8_t light_ctrl = CORSAIR_V2_LIGHT_CTRL2;
private:
void ClearPacketBuffer();
unsigned int GetAddress(uint8_t address);
void StartTransaction(uint8_t opt1);
unsigned char StartTransaction(uint8_t opt1);
void StopTransaction(uint8_t opt1);
hid_device* dev;
uint8_t write_cmd = CORSAIR_V2_WRITE_WIRED_ID;
uint16_t pkt_sze = CORSAIR_V2_WRITE_SIZE;
std::string firmware_version;
std::string location;
};
@@ -26,12 +26,19 @@ void DetectCorsairV2HardwareControllers(hid_device_info* info, const std::string
if(dev)
{
CorsairPeripheralV2HWController* controller = new CorsairPeripheralV2HWController(dev, info->path, name, info->product_id);
CorsairPeripheralV2HWController* controller = new CorsairPeripheralV2HWController(dev, info->path, name);
RGBController_CorsairV2HW* rgb_controller = new RGBController_CorsairV2HW(controller);
rgb_controller->name = name;
if(info->product_id == CORSAIR_SLIPSTREAM_WIRELESS_PID)
{
rgb_controller->name = controller->GetName();
}
else
{
rgb_controller->name = name;
}
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
} /* DetectCorsairV2SoftwareControllers() */
} /* DetectCorsairV2HardwareControllers() */
void DetectCorsairV2SoftwareControllers(hid_device_info* info, const std::string& name)
{
@@ -39,7 +46,7 @@ void DetectCorsairV2SoftwareControllers(hid_device_info* info, const std::string
if(dev)
{
CorsairPeripheralV2SWController* controller = new CorsairPeripheralV2SWController(dev, info->path, name, info->product_id);
CorsairPeripheralV2SWController* controller = new CorsairPeripheralV2SWController(dev, info->path, name);
RGBController_CorsairV2SW* rgb_controller = new RGBController_CorsairV2SW(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
@@ -50,18 +57,23 @@ void DetectCorsairV2SoftwareControllers(hid_device_info* info, const std::string
/*-----------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("Corsair K55 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K55_RGB_PRO_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO Low Profile", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_LP_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair K55 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K55_RGB_PRO_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO Low Profile", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_LP_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB TKL", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K70_RGB_TKL_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB TKL Champion Series", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K70_RGB_TKL_CS_PID, 1, 0xFF42);
/*-----------------------------------------------------------------------------------------------------*\
| Mice |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("Corsair Ironclaw Wireless", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_IRONCLAW_WIRELESS_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair Ironclaw Wireless (Wired)", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_IRONCLAW_WIRELESS_WIRED_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair M55 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_M55_RGB_PRO_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair Dark Core RGB SE (Wired)", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_DARK_CORE_RGB_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair Dark Core RGB Pro SE (Wired)", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_DARK_CORE_RGB_PRO_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair Ironclaw Wireless (Wired)", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_IRONCLAW_WIRELESS_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair M55 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_M55_RGB_PRO_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair M65 Ultra RGB (Wired)", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_M65_ULTRA_RGB_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair Slipstream Wireless Receiver", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_SLIPSTREAM_WIRELESS_PID, 1, 0xFF42);
/*-----------------------------------------------------------------------------------------------------*\
| Mousemat |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("Corsair MM700", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_MM700_PID, 1, 0xFF42);
REGISTER_HID_DETECTOR_IP("Corsair MM700", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_MM700_PID, 1, 0xFF42);
@@ -4,6 +4,22 @@
| Corsair Key Values |
\*-------------------------------------------------------------------------*/
std::vector<unsigned int> corsair_tkl_values =
{
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
41, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BSPC INS HOME PGUP */
53, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 45, 46, 42, 73, 74, 75,
/* TAB Q W E R T Y U I O P [ ] \ DEL END PGDN */
43, 20, 26, 8, 21, 23, 28, 24, 12, 18, 19, 47, 48, 49, 76, 77, 78,
/* CPLK A S D F G H J K L ; " # ENTR */
57, 4, 22, 7, 9, 10, 11, 13, 14, 15, 51, 52, 50, 40,
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU */
106, 100, 29, 27, 6, 25, 5, 17, 16, 54, 55, 56, 110, 82,
/* LCTL LWIN LALT SPC RALT RFNC RMNU RCTL ARWR ARWD ARWR */
105, 108, 107, 44, 111, 122, 101, 109, 80, 81, 79,
};
std::vector<unsigned int> corsair_full_size_values =
{
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
@@ -12,10 +28,10 @@ std::vector<unsigned int> corsair_full_size_values =
53, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 45, 46, 42, 73, 74, 75, 83, 84, 85, 86,
/* TAB Q W E R T Y U I O P [ ] \ DEL END PGDN NM7 NM8 NM9 NMPL */
43, 20, 26, 8, 21, 23, 28, 24, 12, 18, 19, 47, 48, 49, 76, 77, 78, 95, 96, 97, 87,
/* CPLK A S D F G H J K L ; " ENTR NM4 NM5 NM6 */
57, 4, 22, 7, 9, 10, 11, 13, 14, 15, 51, 52, 40, 92, 93, 94,
/* LSFT Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER */
106, 29, 27, 6, 25, 5, 17, 16, 54, 55, 56, 110, 82, 89, 90, 91, 88,
/* CPLK A S D F G H J K L ; " # ENTR NM4 NM5 NM6 */
57, 4, 22, 7, 9, 10, 11, 13, 14, 15, 51, 52, 50, 40, 92, 93, 94,
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER */
106, 100, 29, 27, 6, 25, 5, 17, 16, 54, 55, 56, 110, 82, 89, 90, 91, 88,
/* LCTL LWIN LALT SPC RALT RFNC RMNU RCTL ARWR ARWD ARWR NM0 NMPD */
105, 108, 107, 44, 111, 122, 101, 109, 80, 81, 79, 98, 99,
};
@@ -29,17 +45,6 @@ keyboard_keymap_overlay_values corsair_K60_layout
{
corsair_full_size_values,
{
{
KEYBOARD_LAYOUT_ISO_QWERTY,
{
/*---------------------------------------------------------------------------------------------------------*\
| Edit Keys |
| Zone, Row, Column, Value, Key, OpCode, |
\*---------------------------------------------------------------------------------------------------------*/
{ 0, 3, 12, 50, KEY_EN_POUND, KEYBOARD_OPCODE_SWAP_ONLY, },
{ 0, 4, 1, 100, KEY_EN_ISO_BACK_SLASH, KEYBOARD_OPCODE_SWAP_ONLY, },
}
},
/* Add more regional layout fixes here */
}
},
@@ -51,13 +56,215 @@ keyboard_keymap_overlay_values corsair_K60_layout
}
};
keyboard_keymap_overlay_values corsair_K70_TKL_cs_layout
{
KEYBOARD_SIZE::KEYBOARD_SIZE_TKL,
{
corsair_tkl_values,
{
/* Add more regional layout fixes here */
}
},
{
/*---------------------------------------------------------------------------------------------------------*\
| Edit Keys |
| Zone, Row, Column, Value, Key, OpCode, |
\*---------------------------------------------------------------------------------------------------------*/
{ 0, 0, 1, 123, KEY_EN_MEDIA_STOP, KEYBOARD_OPCODE_INSERT_ROW, }, // Insert Stop Key into new media keys row
{ 0, 0, 2, 126, KEY_EN_MEDIA_PREVIOUS, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Previous Track Key
{ 0, 0, 3, 124, KEY_EN_MEDIA_PLAY_PAUSE, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Play Pause Key
{ 0, 0, 4, 125, KEY_EN_MEDIA_NEXT, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Next Tack Key
{ 0, 0, 7, 1, "Logo L", KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert 'Logo Left'
{ 0, 0, 8, 3, "Logo R", KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert 'Logo Right'
{ 0, 0, 11, 128, "Profile", KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Profile
{ 0, 0, 12, 113, "Light", KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Light key
{ 0, 0, 13, 114, "Lock", KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Lock Key
{ 0, 0, 14, 102, KEY_EN_MEDIA_MUTE, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Mute Key
}
};
/*-------------------------------------------------------------------------*\
| CORSAIR DEVICES |
\*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------*\
| Corsair Ironclaw Wireless 1B1C:1B66 |
| Corsair Ironclaw Wireless (Wired) 1B1C:1B4C |
| Corsair Dark Core SE 1B1C:1B4B |
| |
| Zone "Scroll Wheel" |
| Single |
| |
| Zone "Side Buttons" |
| Linear |
| 1 Row, 4 Columns |
| |
| Zone "Rear Left" |
| Single |
| |
| Zone "Logo" |
| Single |
| |
| Zone "Rear Right" |
| Single |
| |
| Zone "DPI & Indicator" |
| Linear |
| 1 Row, 4 Columns |
\*-------------------------------------------------------------*/
static const corsair_v2_zone dark_core_se_scroll_zone =
{
"Scroll Wheel",
ZONE_TYPE_SINGLE,
1,
1
};
static const corsair_v2_zone dark_core_se_button_zone =
{
"Side Buttons",
ZONE_TYPE_LINEAR,
1,
4
};
static const corsair_v2_zone dark_core_se_left_zone =
{
"Rear Left",
ZONE_TYPE_SINGLE,
1,
1
};
static const corsair_v2_zone dark_core_se_logo_zone =
{
"Logo",
ZONE_TYPE_SINGLE,
1,
1
};
static const corsair_v2_zone dark_core_se_right_zone =
{
"Rear Right",
ZONE_TYPE_SINGLE,
1,
1
};
static const corsair_v2_zone dark_core_se_dpi_zone =
{
"DPI & Indicator Zone",
ZONE_TYPE_LINEAR,
1,
4
};
static const corsair_v2_device dark_core_se_device =
{
CORSAIR_DARK_CORE_RGB_PID,
DEVICE_TYPE_MOUSE,
1,
12,
{
&dark_core_se_scroll_zone,
&dark_core_se_button_zone,
&dark_core_se_left_zone,
&dark_core_se_logo_zone,
&dark_core_se_right_zone,
&dark_core_se_dpi_zone
},
nullptr
};
/*-------------------------------------------------------------*\
| Corsair Dark Core Pro SE 1B1C:1B7E |
| |
| Zone "Scroll Wheel" |
| Single |
| |
| Zone "Side Buttons" |
| Linear |
| 1 Row, 4 Columns |
| |
| Zone "Rear Left" |
| Single |
| |
| Zone "Logo" |
| Single |
| |
| Zone "Rear Right" |
| Single |
| |
| Zone "DPI & Indicator" |
| Linear |
| 1 Row, 4 Columns |
\*-------------------------------------------------------------*/
static const corsair_v2_zone dark_core_pro_se_scroll_zone =
{
"Scroll Wheel",
ZONE_TYPE_SINGLE,
1,
1
};
static const corsair_v2_zone dark_core_pro_se_button_zone =
{
"Side Buttons",
ZONE_TYPE_LINEAR,
1,
4
};
static const corsair_v2_zone dark_core_pro_se_left_zone =
{
"Rear Left",
ZONE_TYPE_SINGLE,
1,
1
};
static const corsair_v2_zone dark_core_pro_se_logo_zone =
{
"Logo",
ZONE_TYPE_SINGLE,
1,
1
};
static const corsair_v2_zone dark_core_pro_se_right_zone =
{
"Rear Right",
ZONE_TYPE_SINGLE,
1,
1
};
static const corsair_v2_zone dark_core_pro_se_dpi_zone =
{
"DPI & Indicator Zone",
ZONE_TYPE_LINEAR,
1,
4
};
static const corsair_v2_device dark_core_pro_se_device =
{
CORSAIR_DARK_CORE_RGB_PRO_PID,
DEVICE_TYPE_MOUSE,
1,
12,
{
&dark_core_pro_se_scroll_zone,
&dark_core_pro_se_button_zone,
&dark_core_pro_se_left_zone,
&dark_core_pro_se_logo_zone,
&dark_core_pro_se_right_zone,
&dark_core_pro_se_dpi_zone
},
nullptr
};
/*-------------------------------------------------------------*\
| Corsair Ironclaw Wireless 1B1C:1B4C |
| |
| Zone "Logo" |
| Single |
@@ -104,31 +311,10 @@ static const corsair_v2_zone ironclaw_side_zone =
3
};
static const corsair_v2_device ironclaw_wired_device =
{
CORSAIR_IRONCLAW_WIRELESS_WIRED_PID,
false,
DEVICE_TYPE_MOUSE,
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK,
1,
6,
{
&ironclaw_logo_zone,
&ironclaw_scroll_zone,
&ironclaw_button_zone,
&ironclaw_side_zone,
nullptr,
nullptr
},
nullptr
};
static const corsair_v2_device ironclaw_wireless_device =
{
CORSAIR_IRONCLAW_WIRELESS_PID,
true,
DEVICE_TYPE_MOUSE,
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK,
1,
6,
{
@@ -160,9 +346,7 @@ static const corsair_v2_zone k55_rgb_pro_zone =
static const corsair_v2_device k55_rgb_pro_device =
{
CORSAIR_K55_RGB_PRO_PID,
false,
DEVICE_TYPE_KEYBOARD,
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK,
1,
6,
{
@@ -194,9 +378,7 @@ static const corsair_v2_zone k60_rgb_pro_zone =
static const corsair_v2_device k60_rgb_pro_device =
{
CORSAIR_K60_RGB_PRO_PID,
false,
DEVICE_TYPE_KEYBOARD,
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK,
6,
21,
{
@@ -228,9 +410,7 @@ static const corsair_v2_zone k60_rgb_pro_lp_zone =
static const corsair_v2_device k60_rgb_pro_lp_device =
{
CORSAIR_K60_RGB_PRO_LP_PID,
false,
DEVICE_TYPE_KEYBOARD,
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK,
6,
21,
{
@@ -244,6 +424,70 @@ static const corsair_v2_device k60_rgb_pro_lp_device =
&corsair_K60_layout
};
/*-------------------------------------------------------------*\
| Corsair K70 RGB TKL 1B1C:1B73 |
| |
| Zone "Keyboard" |
| Matrix |
| 7 Rows, 17 Columns |
\*-------------------------------------------------------------*/
static const corsair_v2_zone k70_rgb_tkl_zone =
{
ZONE_EN_KEYBOARD,
ZONE_TYPE_MATRIX,
7,
17
};
static const corsair_v2_device k70_rgb_tkl_device =
{
CORSAIR_K70_RGB_TKL_PID,
DEVICE_TYPE_KEYBOARD,
7,
17,
{
&k70_rgb_tkl_zone,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr
},
&corsair_K70_TKL_cs_layout
};
/*-------------------------------------------------------------*\
| Corsair K70 RGB TKL Champion Series 1B1C:1BB9 |
| |
| Zone "Keyboard" |
| Matrix |
| 7 Rows, 17 Columns |
\*-------------------------------------------------------------*/
static const corsair_v2_zone k70_rgb_tkl_cs_zone =
{
ZONE_EN_KEYBOARD,
ZONE_TYPE_MATRIX,
7,
17
};
static const corsair_v2_device k70_rgb_tkl_cs_device =
{
CORSAIR_K70_RGB_TKL_CS_PID,
DEVICE_TYPE_KEYBOARD,
7,
17,
{
&k70_rgb_tkl_cs_zone,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr
},
&corsair_K70_TKL_cs_layout
};
/*-------------------------------------------------------------*\
| Corsair M55 1B1C:1B70 |
| |
@@ -273,9 +517,7 @@ static const corsair_v2_zone m55_logo_zone =
static const corsair_v2_device m55_device =
{
CORSAIR_M55_RGB_PRO_PID,
false,
DEVICE_TYPE_MOUSE,
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK,
1,
2,
{
@@ -289,6 +531,48 @@ static const corsair_v2_device m55_device =
nullptr
};
/*-------------------------------------------------------------*\
| Corsair M65 Ultra RGB 1B1C:1BB5 |
| |
| Zone "Logo" |
| Single |
| |
| Zone "DPI" |
| Single |
\*-------------------------------------------------------------*/
static const corsair_v2_zone m65_ultra_rgb_logo_zone =
{
"Logo",
ZONE_TYPE_SINGLE,
1,
1
};
static const corsair_v2_zone m65_ultra_rgb_dpi_zone =
{
"DPI",
ZONE_TYPE_SINGLE,
1,
1
};
static const corsair_v2_device m65_ultra_rgb_device =
{
CORSAIR_M65_ULTRA_RGB_PID,
DEVICE_TYPE_MOUSE,
1,
2,
{
&m65_ultra_rgb_logo_zone,
&m65_ultra_rgb_dpi_zone,
nullptr,
nullptr,
nullptr,
nullptr
},
nullptr
};
/*-------------------------------------------------------------*\
| Corsair MM700 1B1C:1B9B |
| |
@@ -326,9 +610,7 @@ static const corsair_v2_zone mm700_left_zone =
static const corsair_v2_device mm700_device =
{
CORSAIR_MM700_PID,
false,
DEVICE_TYPE_MOUSEMAT,
CORSAIR_V2_TYPE_SW_COLOUR_BLOCK,
1,
3,
{
@@ -353,13 +635,17 @@ const corsair_v2_device* corsair_v2_device_list_data[] =
&k55_rgb_pro_device,
&k60_rgb_pro_device,
&k60_rgb_pro_lp_device,
&k70_rgb_tkl_device,
&k70_rgb_tkl_cs_device,
/*-----------------------------------------------------------------*\
| MICE |
\*-----------------------------------------------------------------*/
&ironclaw_wired_device,
&dark_core_se_device,
&dark_core_pro_se_device,
&ironclaw_wireless_device,
&m55_device,
&m65_ultra_rgb_device,
/*-----------------------------------------------------------------*\
| MOUSEMATS |
@@ -49,9 +49,7 @@ typedef struct
typedef struct
{
uint16_t pid;
bool wireless;
device_type type;
corsair_v2_supports protocol;
uint8_t rows;
uint8_t cols;
const corsair_v2_zone* zones[CORSAIR_ZONES_MAX];
@@ -64,13 +62,18 @@ typedef struct
#define CORSAIR_K55_RGB_PRO_PID 0x1BA4
#define CORSAIR_K60_RGB_PRO_PID 0x1BA0
#define CORSAIR_K60_RGB_PRO_LP_PID 0x1BAD
#define CORSAIR_K70_RGB_TKL_PID 0x1B73
#define CORSAIR_K70_RGB_TKL_CS_PID 0x1BB9
/*-----------------------------------------------------*\
| Corsair V2 Protocol Mice |
\*-----------------------------------------------------*/
#define CORSAIR_IRONCLAW_WIRELESS_PID 0x1BA6
#define CORSAIR_IRONCLAW_WIRELESS_WIRED_PID 0x1B4C
#define CORSAIR_DARK_CORE_RGB_PID 0x1B4B
#define CORSAIR_DARK_CORE_RGB_PRO_PID 0x1B7E
#define CORSAIR_IRONCLAW_WIRELESS_PID 0x1B4C
#define CORSAIR_M55_RGB_PRO_PID 0x1B70
#define CORSAIR_M65_ULTRA_RGB_PID 0x1BB5
#define CORSAIR_SLIPSTREAM_WIRELESS_PID 0x1BA6
/*-----------------------------------------------------*\
| Corsair V2 Protocol Mousemats |
@@ -10,10 +10,10 @@
#include "LogManager.h"
#include "CorsairPeripheralV2HardwareController.h"
CorsairPeripheralV2HWController::CorsairPeripheralV2HWController(hid_device* dev_handle, const char* path, std::string name, uint16_t pid) : CorsairPeripheralV2Controller(dev_handle, path, name, pid)
CorsairPeripheralV2HWController::CorsairPeripheralV2HWController(hid_device* dev_handle, const char* path, std::string name) : CorsairPeripheralV2Controller(dev_handle, path, name)
{
SetRenderMode(CORSAIR_V2_MODE_SW);
LightingControl(0x5F, 0x00);
LightingControl(0x5F);
}
CorsairPeripheralV2HWController::~CorsairPeripheralV2HWController()
@@ -23,17 +23,17 @@ CorsairPeripheralV2HWController::~CorsairPeripheralV2HWController()
void CorsairPeripheralV2HWController::SetLedsDirect(std::vector<RGBColor *>colors)
{
switch(corsair_v2_device_list[device_index]->protocol)
switch(light_ctrl)
{
case CORSAIR_V2_TYPE_HW_TRIPLETS:
SetLedsDirectTriplets(colors);
break;
case CORSAIR_V2_TYPE_HW_COLOUR_BLOCK:
case CORSAIR_V2_LIGHT_CTRL1:
SetLedsDirectColourBlocks(colors);
break;
case CORSAIR_V2_LIGHT_CTRL2:
SetLedsDirectTriplets(colors);
break;
default:
LOG_ERROR("[%s] Error setting Direct mode: Device supportes returned %i", device_name.c_str(),
corsair_v2_device_list[device_index]->protocol);
LOG_ERROR("[%s] Error setting Direct mode: Device supportes returned %i",
device_name.c_str(), light_ctrl);
break;
}
}
@@ -41,23 +41,20 @@ void CorsairPeripheralV2HWController::SetLedsDirect(std::vector<RGBColor *>color
void CorsairPeripheralV2HWController::SetLedsDirectColourBlocks(std::vector<RGBColor *>colors)
{
uint16_t count = colors.size();
uint16_t green = count + CORSAIR_V2HW_DATA_OFFSET;
uint16_t blue = (count * 2) + CORSAIR_V2HW_DATA_OFFSET;
uint16_t length = (count * 3) + CORSAIR_V2HW_DATA_OFFSET;
uint16_t green = count;
uint16_t blue = (count * 2);
uint16_t length = (count * 3);
uint8_t* buffer = new uint8_t[length];
memset(buffer, 0, length);
buffer[0] = CORSAIR_V2_MODE_DIRECT & 0xFF;
buffer[1] = CORSAIR_V2_MODE_DIRECT >> 8;
for(std::size_t i = 0; i < count; i++)
{
RGBColor color = *colors[i];
std::size_t idx = i + CORSAIR_V2HW_DATA_OFFSET;
buffer[idx] = RGBGetRValue(color);
buffer[idx + green] = RGBGetGValue(color);
buffer[idx + blue] = RGBGetBValue(color);
buffer[i] = RGBGetRValue(color);
buffer[i + green] = RGBGetGValue(color);
buffer[i + blue] = RGBGetBValue(color);
}
SetLEDs(buffer, length);
@@ -21,7 +21,7 @@
class CorsairPeripheralV2HWController : public CorsairPeripheralV2Controller
{
public:
CorsairPeripheralV2HWController(hid_device* dev_handle, const char* path, std::string name, uint16_t pid);
CorsairPeripheralV2HWController(hid_device* dev_handle, const char* path, std::string name);
~CorsairPeripheralV2HWController();
void SetLedsDirect(std::vector<RGBColor *> colors);
@@ -10,10 +10,10 @@
#include "LogManager.h"
#include "CorsairPeripheralV2SoftwareController.h"
CorsairPeripheralV2SWController::CorsairPeripheralV2SWController(hid_device* dev_handle, const char* path, std::string name, uint16_t pid) : CorsairPeripheralV2Controller(dev_handle, path, name, pid)
CorsairPeripheralV2SWController::CorsairPeripheralV2SWController(hid_device* dev_handle, const char* path, std::string name) : CorsairPeripheralV2Controller(dev_handle, path, name)
{
SetRenderMode(CORSAIR_V2_MODE_SW);
LightingControl(0x5F, 0x00);
LightingControl(0x5F);
}
CorsairPeripheralV2SWController::~CorsairPeripheralV2SWController()
@@ -17,7 +17,7 @@
class CorsairPeripheralV2SWController : public CorsairPeripheralV2Controller
{
public:
CorsairPeripheralV2SWController(hid_device* dev_handle, const char* path, std::string name, uint16_t pid);
CorsairPeripheralV2SWController(hid_device* dev_handle, const char* path, std::string name);
~CorsairPeripheralV2SWController();
void SetLedsDirect(std::vector<RGBColor *> colors);
@@ -145,7 +145,6 @@ void RGBController_CorsairV2HW::SetupZones()
/*---------------------------------------------------------*\
| Minor adjustments to keyboard layout |
\*---------------------------------------------------------*/
new_zone.leds_count = new_kb.GetKeyCount();
keyboard_keymap_overlay_values* temp = corsair->layout_new;
new_kb.ChangeKeys(*temp);
@@ -159,6 +158,10 @@ void RGBController_CorsairV2HW::SetupZones()
| Create LEDs for the Matrix zone |
| Place keys in the layout to populate the matrix |
\*---------------------------------------------------------*/
new_zone.leds_count = new_kb.GetKeyCount();
LOG_DEBUG("[%s] Created KB matrix with %d rows and %d columns containing %d keys",
controller->GetName().c_str(), new_kb.GetRowCount(), new_kb.GetColumnCount(), new_zone.leds_count);
for(size_t led_idx = 0; led_idx < new_zone.leds_count; led_idx++)
{
led new_led;
@@ -197,7 +200,10 @@ void RGBController_CorsairV2HW::SetupZones()
max_led_value = std::max(max_led_value, (unsigned int)leds.size());
}
LOG_DEBUG("[%s] Creating a %s zone: %s with %d LEDs", name.c_str(),
/*---------------------------------------------------------*\
| name is not set yet so description is used instead |
\*---------------------------------------------------------*/
LOG_DEBUG("[%s] Creating a %s zone: %s with %d LEDs", description.c_str(),
((new_zone.type == ZONE_TYPE_MATRIX) ? "matrix": "linear"),
new_zone.name.c_str(), new_zone.leds_count);
new_zone.leds_min = new_zone.leds_count;
@@ -258,11 +264,12 @@ void RGBController_CorsairV2HW::KeepaliveThread()
{
if(active_mode == 0)
{
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(50000))
if((std::chrono::steady_clock::now() - last_update_time) >
std::chrono::milliseconds(CORSAIR_V2_UPDATE_PERIOD))
{
DeviceUpdateLEDs();
}
}
std::this_thread::sleep_for(30000ms);
std::this_thread::sleep_for(CORSAIR_V2_SLEEP_PERIOD);
}
}
@@ -35,28 +35,12 @@ RGBController_CorsairV2SW::RGBController_CorsairV2SW(CorsairPeripheralV2Controll
location = controller->GetDeviceLocation();
serial = controller->GetSerialString();
if(corsair->protocol & CORSAIR_V2_TYPE_SW_COLOUR_BLOCK)
{
mode Direct;
Direct.name = "Direct";
Direct.value = CORSAIR_V2_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Static;
Static.name = "Static";
Static.value = CORSAIR_V2_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(Static.colors_max);
Static.brightness_min = CORSAIR_V2_BRIGHTNESS_MIN;
Static.brightness_max = CORSAIR_V2_BRIGHTNESS_MAX;
Static.brightness = CORSAIR_V2_BRIGHTNESS_MAX;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
modes.push_back(Static);
}
mode Direct;
Direct.name = "Direct";
Direct.value = CORSAIR_V2_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
SetupZones();
/*-----------------------------------------------------*\
@@ -149,7 +133,6 @@ void RGBController_CorsairV2SW::SetupZones()
/*---------------------------------------------------------*\
| Minor adjustments to keyboard layout |
\*---------------------------------------------------------*/
new_zone.leds_count = new_kb.GetKeyCount();
keyboard_keymap_overlay_values* temp = corsair->layout_new;
new_kb.ChangeKeys(*temp);
@@ -163,6 +146,10 @@ void RGBController_CorsairV2SW::SetupZones()
| Create LEDs for the Matrix zone |
| Place keys in the layout to populate the matrix |
\*---------------------------------------------------------*/
new_zone.leds_count = new_kb.GetKeyCount();
LOG_DEBUG("[%s] Created KB matrix with %d rows and %d columns containing %d keys",
controller->GetName().c_str(), new_kb.GetRowCount(), new_kb.GetColumnCount(), new_zone.leds_count);
for(size_t led_idx = 0; led_idx < new_zone.leds_count; led_idx++)
{
led new_led;
@@ -201,7 +188,10 @@ void RGBController_CorsairV2SW::SetupZones()
max_led_value = std::max(max_led_value, (unsigned int)leds.size());
}
LOG_DEBUG("[%s] Creating a %s zone: %s with %d LEDs", name.c_str(),
/*---------------------------------------------------------*\
| name is not set yet so description is used instead |
\*---------------------------------------------------------*/
LOG_DEBUG("[%s] Creating a %s zone: %s with %d LEDs", description.c_str(),
((new_zone.type == ZONE_TYPE_MATRIX) ? "matrix": "linear"),
new_zone.name.c_str(), new_zone.leds_count);
new_zone.leds_min = new_zone.leds_count;
@@ -262,11 +252,12 @@ void RGBController_CorsairV2SW::KeepaliveThread()
{
if(active_mode == 0)
{
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(50000))
if((std::chrono::steady_clock::now() - last_update_time) >
std::chrono::milliseconds(CORSAIR_V2_UPDATE_PERIOD))
{
DeviceUpdateLEDs();
}
}
std::this_thread::sleep_for(30000ms);
std::this_thread::sleep_for(CORSAIR_V2_SLEEP_PERIOD);
}
}
@@ -309,37 +309,53 @@ void DetectDebugControllers()
| Check for custom key inserts and swaps |
\*---------------------------------------------------------*/
std::vector<keyboard_led> change;
const char* change_keys = "change_keys";
if(json_kbd.contains("insert"))
const char* ins_key = "ins_key";
const char* ins_row = "ins_row";
const char* rmv_key = "rmv_key";
const char* rmv_row = "rmv_row";
const char* swp_key = "swp_key";
const char* dbg_zone = "Zone";
const char* dbg_row = "Row";
const char* dbg_col = "Col";
const char* dbg_val = "Val";
const char* dbg_name = "Name";
const char* dbg_opcode = "Opcode";
if(json_kbd.contains(change_keys))
{
for(size_t i = 0; i < json_kbd["insert"].size(); i++)
for(size_t i = 0; i < json_kbd[change_keys].size(); i++)
{
keyboard_led* key = new keyboard_led;
key->zone = json_kbd["insert"][i]["Zone"];
key->row = json_kbd["insert"][i]["Row"];
key->col = json_kbd["insert"][i]["Col"];
key->value = json_kbd["insert"][i]["Val"];
key->name = json_kbd["insert"][i]["Name"].get_ref<const std::string&>().c_str();
key->opcode = KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT;
key->zone = json_kbd[change_keys][i][dbg_zone];
key->row = json_kbd[change_keys][i][dbg_row];
key->col = json_kbd[change_keys][i][dbg_col];
key->value = json_kbd[change_keys][i][dbg_val];
key->name = json_kbd[change_keys][i][dbg_name].get_ref<const std::string&>().c_str();
change.push_back(*key);
}
}
if(json_kbd.contains("swap"))
{
for(size_t i = 0; i < json_kbd["swap"].size(); i++)
{
keyboard_led* key = new keyboard_led;
key->zone = json_kbd["swap"][i]["Zone"];
key->row = json_kbd["swap"][i]["Row"];
key->col = json_kbd["swap"][i]["Col"];
key->value = json_kbd["swap"][i]["Val"];
key->name = json_kbd["swap"][i]["Name"].get_ref<const std::string&>().c_str();
key->opcode = KEYBOARD_OPCODE_SWAP_ONLY;
if(json_kbd[change_keys][i][dbg_opcode] == ins_row)
{
key->opcode = KEYBOARD_OPCODE_INSERT_ROW;
}
else if(json_kbd[change_keys][i][dbg_opcode] == rmv_key)
{
key->opcode = KEYBOARD_OPCODE_REMOVE_SHIFT_LEFT;
}
else if(json_kbd[change_keys][i][dbg_opcode] == rmv_row)
{
key->opcode = KEYBOARD_OPCODE_REMOVE_ROW;
}
else if(json_kbd[change_keys][i][dbg_opcode] == swp_key)
{
key->opcode = KEYBOARD_OPCODE_SWAP_ONLY;
}
else
{
key->opcode = KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT;
}
change.push_back(*key);
}
@@ -26,6 +26,7 @@ static const char* ene_channels[] = /* ENE channel strings
"RGB Header",
"RGB Header 2",
"RGB Header",
"SSD",
"Unknown",
};
@@ -35,40 +36,51 @@ ENESMBusController::ENESMBusController(ENESMBusInterface* interface, ene_dev_id
this->dev = dev;
supports_mode_14 = false;
UpdateDeviceName();
// Read the device configuration table
for (int i = 0; i < 64; i++)
if(interface->GetInterfaceType() != ENE_INTERFACE_TYPE_ROG_ARION)
{
config_table[i] = ENERegisterRead(ENE_REG_CONFIG_TABLE + i);
UpdateDeviceName();
// Read the device configuration table
for (int i = 0; i < 64; i++)
{
config_table[i] = ENERegisterRead(ENE_REG_CONFIG_TABLE + i);
}
/*-----------------------------------------------------------------*\
| If this is running with TRACE or higher loglevel then |
| dump the entire Feature list to log |
\*-----------------------------------------------------------------*/
if(LogManager::get()->getLoglevel() >= LL_TRACE)
{
LOG_TRACE("[ENE SMBus] ENE config table for 0x%02X:", dev);
LOG_TRACE(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", config_table[0], config_table[1], config_table[2], config_table[3],
config_table[4], config_table[5], config_table[6], config_table[7],
config_table[8], config_table[9], config_table[10], config_table[11],
config_table[12], config_table[13], config_table[14], config_table[15]);
LOG_TRACE(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", config_table[16], config_table[17], config_table[18], config_table[19],
config_table[20], config_table[21], config_table[22], config_table[23],
config_table[24], config_table[25], config_table[26], config_table[27],
config_table[28], config_table[29], config_table[30], config_table[31]);
LOG_TRACE(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", config_table[32], config_table[33], config_table[34], config_table[35],
config_table[36], config_table[37], config_table[38], config_table[39],
config_table[40], config_table[41], config_table[42], config_table[43],
config_table[44], config_table[45], config_table[46], config_table[47]);
LOG_TRACE(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", config_table[48], config_table[49], config_table[50], config_table[51],
config_table[52], config_table[53], config_table[54], config_table[55],
config_table[56], config_table[57], config_table[58], config_table[59],
config_table[60], config_table[61], config_table[62], config_table[63]);
}
}
/*-----------------------------------------------------------------*\
| If this is running with TRACE or higher loglevel then |
| dump the entire Feature list to log |
\*-----------------------------------------------------------------*/
if(LogManager::get()->getLoglevel() >= LL_TRACE)
else
{
LOG_TRACE("[ENE SMBus] ENE config table for 0x%02X:", dev);
LOG_TRACE(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", config_table[0], config_table[1], config_table[2], config_table[3],
config_table[4], config_table[5], config_table[6], config_table[7],
config_table[8], config_table[9], config_table[10], config_table[11],
config_table[12], config_table[13], config_table[14], config_table[15]);
LOG_TRACE(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", config_table[16], config_table[17], config_table[18], config_table[19],
config_table[20], config_table[21], config_table[22], config_table[23],
config_table[24], config_table[25], config_table[26], config_table[27],
config_table[28], config_table[29], config_table[30], config_table[31]);
LOG_TRACE(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", config_table[32], config_table[33], config_table[34], config_table[35],
config_table[36], config_table[37], config_table[38], config_table[39],
config_table[40], config_table[41], config_table[42], config_table[43],
config_table[44], config_table[45], config_table[46], config_table[47]);
LOG_TRACE(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X", config_table[48], config_table[49], config_table[50], config_table[51],
config_table[52], config_table[53], config_table[54], config_table[55],
config_table[56], config_table[57], config_table[58], config_table[59],
config_table[60], config_table[61], config_table[62], config_table[63]);
LOG_TRACE("[ENE SMBus] ROG STRIX ARION detected, filling in hard coded config table entries.", dev);
memset(config_table, 0, sizeof(config_table));
config_table[ENE_CONFIG_LED_COUNT] = 4;
config_table[0x03] = 4;
strcpy(device_name, "ROG STRIX ARION");
}
// Read LED count from configuration table
@@ -166,6 +178,15 @@ ENESMBusController::ENESMBusController(ENESMBusInterface* interface, ene_dev_id
// Read LED count from configuration table
led_count = config_table[ENE_CONFIG_LED_COUNT_0107];
}
// ROG ARION - ASUS ROG Arion external SSD enclosure
// This device does not support ENE read, so we fake the device name string
// if the interface is ROG Arion type. It uses second generation registers.
else if(strcmp(device_name, "ROG STRIX ARION") == 0)
{
direct_reg = ENE_REG_COLORS_DIRECT_V2;
effect_reg = ENE_REG_COLORS_EFFECT_V2;
channel_cfg = ENE_CONFIG_CHANNEL_V2;
}
// Assume first generation controller if string does not match
else
{
@@ -201,53 +222,60 @@ const char * ENESMBusController::GetChannelName(unsigned int cfg_zone)
{
LOG_TRACE("[%s] Config table for zone %02d: %02d", device_name, cfg_zone, config_table[channel_cfg + cfg_zone]);
switch(config_table[channel_cfg + cfg_zone])
if(interface->GetInterfaceType() == ENE_INTERFACE_TYPE_ROG_ARION)
{
case (unsigned char)ENE_LED_CHANNEL_AUDIO:
return(ene_channels[0]);
break;
case (unsigned char)ENE_LED_CHANNEL_BACKPLATE:
return(ene_channels[1]);
break;
case (unsigned char)ENE_LED_CHANNEL_BACK_IO:
return(ene_channels[2]);
break;
case (unsigned char)ENE_LED_CHANNEL_CENTER:
return(ene_channels[3]);
break;
case (unsigned char)ENE_LED_CHANNEL_CENTER_START:
return(ene_channels[4]);
break;
case (unsigned char)ENE_LED_CHANNEL_DRAM:
case (unsigned char)ENE_LED_CHANNEL_DRAM_2:
case (unsigned char)ENE_LED_CHANNEL_DRAM_3:
return(ene_channels[5]);
break;
case (unsigned char)ENE_LED_CHANNEL_PCIE:
return(ene_channels[6]);
break;
case (unsigned char)ENE_LED_CHANNEL_RGB_HEADER:
return(ene_channels[7]);
break;
case (unsigned char)ENE_LED_CHANNEL_RGB_HEADER_2:
return(ene_channels[8]);
break;
case (unsigned char)ENE_LED_CHANNEL_RGB_HEADER_3:
return(ene_channels[9]);
break;
default:
return(ene_channels[10]);
break;
}
else
{
switch(config_table[channel_cfg + cfg_zone])
{
case (unsigned char)ENE_LED_CHANNEL_AUDIO:
return(ene_channels[0]);
break;
case (unsigned char)ENE_LED_CHANNEL_BACKPLATE:
return(ene_channels[1]);
break;
case (unsigned char)ENE_LED_CHANNEL_BACK_IO:
return(ene_channels[2]);
break;
case (unsigned char)ENE_LED_CHANNEL_CENTER:
return(ene_channels[3]);
break;
case (unsigned char)ENE_LED_CHANNEL_CENTER_START:
return(ene_channels[4]);
break;
case (unsigned char)ENE_LED_CHANNEL_DRAM:
case (unsigned char)ENE_LED_CHANNEL_DRAM_2:
case (unsigned char)ENE_LED_CHANNEL_DRAM_3:
return(ene_channels[5]);
break;
case (unsigned char)ENE_LED_CHANNEL_PCIE:
return(ene_channels[6]);
break;
case (unsigned char)ENE_LED_CHANNEL_RGB_HEADER:
return(ene_channels[7]);
break;
case (unsigned char)ENE_LED_CHANNEL_RGB_HEADER_2:
return(ene_channels[8]);
break;
case (unsigned char)ENE_LED_CHANNEL_RGB_HEADER_3:
return(ene_channels[9]);
break;
default:
return(ene_channels[11]);
break;
}
}
}
@@ -3,8 +3,10 @@
#include "ENESMBusInterface_i2c_smbus.h"
#include "ENESMBusInterface_SpectrixS40G.h"
#include "LogManager.h"
#include "ResourceManager.h"
#include "RGBController.h"
#include "RGBController_ENESMBus.h"
#include "SettingsManager.h"
#include "i2c_smbus.h"
#include "pci_ids.h"
#include <vector>
@@ -329,6 +331,22 @@ void DetectENESMBusGPUControllers(i2c_smbus_interface* bus, uint8_t i2c_addr, co
}
} /* DetectENESMBusGPUControllers() */
void RegisterENESettings()
{
/*-----------------------------------------------------*\
| Create ENESMBusSettings settings prototype |
\*-----------------------------------------------------*/
std::string ene_smbus_string = "ENESMBusSettings";
json ene_smbus_proto;
ene_smbus_proto["enable_save"]["name"] = "Enable Save";
ene_smbus_proto["enable_save"]["type"] = "boolean";
ResourceManager::get()->GetSettingsManager()->RegisterSettingsPrototype(ene_smbus_string, ene_smbus_proto);
}
REGISTER_DYNAMIC_DETECTOR("ENE Devices", RegisterENESettings);
REGISTER_I2C_DETECTOR("ENE SMBus DRAM", DetectENESMBusDRAMControllers);
REGISTER_I2C_DETECTOR("ASUS Aura SMBus Motherboard", DetectENESMBusMotherboardControllers);
@@ -375,11 +393,13 @@ REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX 3080 10G V2 GAMING", DetectEN
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX 3080 O10G V2 GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_O10G_V2_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX 3080 O10G V2 WHITE", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_O10G_V2_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 3080 O10G V2 GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080_O10G_V2_GAMING_8822, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 3080 O10G V2 GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080_O10G_V2_GAMING_882B, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 3080 O10G V2 GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080_O10G_V2_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 3080 O12G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX RTX 3080 12G", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_12G, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX RTX 3080 O12G", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_O12G_OC, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX RTX 3080 O12G EVA EDITION", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_O12G_EVA, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX RTX 3080 O12G EVA EDITION", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080_O12G_EVA, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX 3090 O24G EVA", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3090_O24G_EVA, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 3080Ti 12G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080TI_12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 3080Ti O12G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3080TI_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX 3080Ti O12G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3080TI_O12G_GAMING, 0x67);
@@ -389,17 +409,33 @@ REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX 3090 O24G GAMING", DetectEN
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX 3090 O24G GAMING White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_3090_O24G_GAMING_WHITE, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 3090 O24G", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3090_O24G, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 3090 O24G OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3090_O24G_OC, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 3090Ti 24G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3090TI_24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 3090Ti O24G OC GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_3090TI_O24G_OC_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX LC RTX 3090Ti O24G OC GAMING",DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX3090TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_LC_RTX_3090TI_O24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4060 Ti 8G Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4060TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4060TI_O8G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4070 12G Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070_12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4070 O12G Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4070 O12G Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070_O12G_GAMING_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4070 Ti 12G Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070TI_12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4070 Ti 12G Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070TI_12G_GAMING_88DD, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4070 Ti O12G Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070TI_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4070 Ti O12G Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4070TI_O12G_GAMING_88DC, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX RTX 4070 Ti O12G Gaming", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4070TI_O12G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX RTX 4080 16G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4080_16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX RTX 4080 O16G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4080_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX RTX 4080 O16G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4080_O16G_GAMING_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4080 16G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4080_16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4080 16G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4080_16G_GAMING_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4080 O16G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4080_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4080 O16G OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4080_O16G_OC_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4090 O24G OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4090_O24G_OC_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4090 O24G OG OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4090_O24G_OG_OC_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4090 O24G", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4090_O24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX RTX 4090 O24G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_O24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4090 O24G", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4090_O24G_GAMING_2, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RTX 4090 O24G", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_4090_O24G_GAMING_3, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX RTX 4090 24G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX RTX 4090 O24G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_O24G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX RTX 4090 O24G GAMING", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_O24G_GAMING_213S, 0x67);
/*-----------------------------------------*\
| AMD GPUs |
@@ -418,3 +454,6 @@ REGISTER_I2C_PCI_DETECTOR("ASUS TUF RX 6900XT O16G GAMING", DetectEN
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RX 6900XT T16G GAMING", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV2, ASUS_SUB_VEN, ASUS_TUF_RX_6900XT_T16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RX 6950XT O16G GAMING", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV3, ASUS_SUB_VEN, ASUS_TUF_RX_6950XT_016G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX LC RX 6950XT O16G GAMING", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV3, ASUS_SUB_VEN, ASUS_ROG_STRIX_LC_RX_6950XT_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RX 7800XT GAMING OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI32_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7800XT_O16G_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RX 7800XT GAMING WHITE OC", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI32_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7800XT_O16G_WHITE_GAMING, 0x67);
REGISTER_I2C_PCI_DETECTOR("ASUS TUF RX 7900XTX O24G GAMING", DetectENESMBusGPUControllers, AMD_GPU_VEN, AMD_NAVI31_DEV, ASUS_SUB_VEN, ASUS_TUF_RX_7900XTX_O24G_GAMING, 0x67);
@@ -12,15 +12,27 @@
typedef unsigned short ene_register;
typedef unsigned char ene_dev_id;
typedef unsigned int ene_interface_type;
/*-----------------------------------------*\
| Known interface types |
\*-----------------------------------------*/
enum
{
ENE_INTERFACE_TYPE_I2C_SMBUS,
ENE_INTERFACE_TYPE_SPECTRIX_S40G,
ENE_INTERFACE_TYPE_ROG_ARION,
};
class ENESMBusInterface
{
public:
virtual ~ENESMBusInterface() = default;
virtual ~ENESMBusInterface() = default;
virtual std::string GetLocation() = 0;
virtual int GetMaxBlock() = 0;
virtual unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg) = 0;
virtual void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val) = 0;
virtual void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz) = 0;
virtual ene_interface_type GetInterfaceType() = 0;
virtual std::string GetLocation() = 0;
virtual int GetMaxBlock() = 0;
virtual unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg) = 0;
virtual void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val) = 0;
virtual void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz) = 0;
};
@@ -0,0 +1,93 @@
/*-----------------------------------------*\
| ENESMBusInterface_ROGArion.cpp |
| |
| Code for ENE ASUS ROG Arion interface |
| |
| Adam Honse (CalcProgrammer1) 9/17/2023 |
\*-----------------------------------------*/
#include "ENESMBusInterface_ROGArion.h"
ENESMBusInterface_ROGArion::ENESMBusInterface_ROGArion(scsi_device* dev_handle, char* dev_path)
{
scsi_dev = dev_handle;
path = dev_path;
}
ENESMBusInterface_ROGArion::~ENESMBusInterface_ROGArion()
{
}
ene_interface_type ENESMBusInterface_ROGArion::GetInterfaceType()
{
return(ENE_INTERFACE_TYPE_ROG_ARION);
}
std::string ENESMBusInterface_ROGArion::GetLocation()
{
std::string str(path.begin(), path.end());
return("SCSI: " + str);
}
int ENESMBusInterface_ROGArion::GetMaxBlock()
{
return(24);
}
unsigned char ENESMBusInterface_ROGArion::ENERegisterRead(ene_dev_id dev, ene_register reg)
{
/*-----------------------------------------------------------------------------*\
| This interface does not support reading |
\*-----------------------------------------------------------------------------*/
return( 0 );
}
void ENESMBusInterface_ROGArion::ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val)
{
SendPacket(reg, &val, sizeof(unsigned char));
}
void ENESMBusInterface_ROGArion::ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz)
{
SendPacket(reg, data, sz);
}
void ENESMBusInterface_ROGArion::SendPacket
(
ene_register reg,
unsigned char * packet,
unsigned char packet_sz
)
{
/*-----------------------------------------------------------------------------*\
| Create buffer to hold CDB |
\*-----------------------------------------------------------------------------*/
unsigned char cdb[16] = {0};
cdb[0] = 0xEC;
cdb[1] = 0x41;
cdb[2] = 0x53;
cdb[3] = ((reg >> 8) & 0x00FF);
cdb[4] = ( reg & 0x00FF );
cdb[5] = 0x00;
cdb[6] = 0x00;
cdb[7] = 0x00;
cdb[8] = 0x00;
cdb[9] = 0x00;
cdb[10] = 0x00;
cdb[11] = 0x00;
cdb[12] = 0x00;
cdb[13] = packet_sz;
cdb[14] = 0x00;
cdb[15] = 0x00;
/*-----------------------------------------------------------------------------*\
| Create buffer to hold sense data |
\*-----------------------------------------------------------------------------*/
unsigned char sense[32] = {0};
/*-----------------------------------------------------------------------------*\
| Write SCSI packet |
\*-----------------------------------------------------------------------------*/
scsi_write(scsi_dev, packet, packet_sz, cdb, 16, sense, 32);
}
@@ -0,0 +1,38 @@
/*-----------------------------------------*\
| ENESMBusInterface_ROGArion.h |
| |
| Definitions and types for ENE ASUS ROG |
| Arion interface |
| |
| Adam Honse (CalcProgrammer1) 9/17/2023 |
\*-----------------------------------------*/
#pragma once
#include "ENESMBusInterface.h"
#include "scsiapi.h"
class ENESMBusInterface_ROGArion : public ENESMBusInterface
{
public:
ENESMBusInterface_ROGArion(scsi_device* dev_handle, char* dev_path);
~ENESMBusInterface_ROGArion();
ene_interface_type GetInterfaceType();
std::string GetLocation();
int GetMaxBlock();
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
private:
scsi_device* scsi_dev;
std::string path;
void SendPacket
(
ene_register reg,
unsigned char * packet,
unsigned char packet_sz
);
};
@@ -110,6 +110,11 @@ ENESMBusInterface_SpectrixS40G::~ENESMBusInterface_SpectrixS40G()
}
ene_interface_type ENESMBusInterface_SpectrixS40G::GetInterfaceType()
{
return(ENE_INTERFACE_TYPE_SPECTRIX_S40G);
}
std::string ENESMBusInterface_SpectrixS40G::GetLocation()
{
return("NVMe: " + path);
@@ -17,11 +17,12 @@ public:
ENESMBusInterface_SpectrixS40G(int fd, char* path);
~ENESMBusInterface_SpectrixS40G();
std::string GetLocation();
int GetMaxBlock();
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
ene_interface_type GetInterfaceType();
std::string GetLocation();
int GetMaxBlock();
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
private:
int nvme_fd;
@@ -25,6 +25,11 @@ ENESMBusInterface_SpectrixS40G::~ENESMBusInterface_SpectrixS40G()
}
ene_interface_type ENESMBusInterface_SpectrixS40G::GetInterfaceType()
{
return(ENE_INTERFACE_TYPE_SPECTRIX_S40G);
}
std::string ENESMBusInterface_SpectrixS40G::GetLocation()
{
std::string str(path.begin(), path.end());
@@ -19,11 +19,12 @@ public:
ENESMBusInterface_SpectrixS40G(HANDLE fd, wchar_t* path);
~ENESMBusInterface_SpectrixS40G();
std::string GetLocation();
int GetMaxBlock();
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
ene_interface_type GetInterfaceType();
std::string GetLocation();
int GetMaxBlock();
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
private:
HANDLE nvme_fd;
@@ -18,6 +18,11 @@ ENESMBusInterface_i2c_smbus::~ENESMBusInterface_i2c_smbus()
}
ene_interface_type ENESMBusInterface_i2c_smbus::GetInterfaceType()
{
return(ENE_INTERFACE_TYPE_I2C_SMBUS);
}
std::string ENESMBusInterface_i2c_smbus::GetLocation()
{
std::string return_string(bus->device_name);
@@ -18,11 +18,12 @@ public:
ENESMBusInterface_i2c_smbus(i2c_smbus_interface* bus);
~ENESMBusInterface_i2c_smbus();
std::string GetLocation();
int GetMaxBlock();
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
ene_interface_type GetInterfaceType();
std::string GetLocation();
int GetMaxBlock();
unsigned char ENERegisterRead(ene_dev_id dev, ene_register reg);
void ENERegisterWrite(ene_dev_id dev, ene_register reg, unsigned char val);
void ENERegisterWriteBlock(ene_dev_id dev, ene_register reg, unsigned char * data, unsigned char sz);
private:
i2c_smbus_interface * bus;
@@ -8,6 +8,7 @@
#include "RGBController_ENESMBus.h"
#include "LogManager.h"
#include "SettingsManager.h"
#include "ResourceManager.h"
/**------------------------------------------------------------------*\
@@ -55,6 +56,12 @@ RGBController_ENESMBus::RGBController_ENESMBus(ENESMBusController * controller_p
name = "ENE DRAM";
vendor = "ENE";
}
else if(version.find("ROG STRIX ARION") != std::string::npos)
{
type = DEVICE_TYPE_STORAGE;
name = "ASUS ROG Strix Arion";
vendor = "ASUS";
}
else
{
type = DEVICE_TYPE_MOTHERBOARD;
@@ -0,0 +1,45 @@
#include "Detector.h"
#include "ENESMBusController.h"
#include "ENESMBusInterface_ROGArion.h"
#include "LogManager.h"
#include "RGBController.h"
#include "RGBController_ENESMBus.h"
#include <vector>
#include "scsiapi.h"
/******************************************************************************************\
* *
* DetectROGArionControllers *
* *
* Detects ENE SMBus controllers on ASUS ROG Arion devices *
* *
\******************************************************************************************/
void DetectROGArionControllers()
{
scsi_device_info * info = scsi_enumerate(NULL, NULL);
while(info)
{
if(strncmp(info->vendor, "ROG", 3) == 0 && strncmp(info->product, "ESD-S1C", 7) == 0)
{
scsi_device * dev = scsi_open_path(info->path);
if(dev)
{
ENESMBusInterface_ROGArion* interface = new ENESMBusInterface_ROGArion(dev, info->path);
ENESMBusController* controller = new ENESMBusController(interface, 0x67);
RGBController_ENESMBus* rgb_controller = new RGBController_ENESMBus(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
info = info->next;
}
scsi_free_enumeration(info);
} /* DetectROGArionControllers() */
REGISTER_DETECTOR("ASUS ROG Arion", DetectROGArionControllers);
@@ -130,7 +130,7 @@ EVGAv3_config EVGAGPUv3Controller::GetZoneConfig(uint8_t zone, uint8_t mode)
}
}
break;
case EVGA_GPU_V3_MODE_BREATHING:
{
uint8_t result = bus->i2c_smbus_read_i2c_block_data(dev, EVGA_GPU_V3_REG_BREATHING + zone, 10, data_pkt);
@@ -147,8 +147,8 @@ EVGAv3_config EVGAGPUv3Controller::GetZoneConfig(uint8_t zone, uint8_t mode)
uint8_t blue2 = data_pkt[7];
zone_config.colors[1] = ToRGBColor(red2, green2, blue2);
zone_config.numberOfColors= (zone_config.colors[1] != 0 ) ? 2 : 1 ;
speed16.LSB = data_pkt[8];
speed16.MSB = data_pkt[9];
speed16.lsb = data_pkt[8];
speed16.msb = data_pkt[9];
zone_config.speed = speed16.u16;
zone_config.direction = 0;
}
@@ -169,8 +169,8 @@ EVGAv3_config EVGAGPUv3Controller::GetZoneConfig(uint8_t zone, uint8_t mode)
//Load data
zone_config.brightness = data_pkt[1];
zone_config.numberOfColors = 0;
speed16.LSB = data_pkt[2];
speed16.MSB = data_pkt[3];
speed16.lsb = data_pkt[2];
speed16.msb = data_pkt[3];
zone_config.speed = speed16.u16;
}
else
@@ -192,8 +192,8 @@ EVGAv3_config EVGAGPUv3Controller::GetZoneConfig(uint8_t zone, uint8_t mode)
uint8_t blue = data_pkt[4];
zone_config.colors[0] = ToRGBColor(red, green, blue);
zone_config.numberOfColors = 1;
speed16.LSB = data_pkt[5];
speed16.MSB = data_pkt[6];
speed16.lsb = data_pkt[5];
speed16.msb = data_pkt[6];
zone_config.speed = speed16.u16;
}
else
@@ -230,7 +230,7 @@ EVGAv3_config EVGAGPUv3Controller::GetZoneConfig(uint8_t zone, uint8_t mode)
{
readFail = true;
}
}
else
{
@@ -257,11 +257,11 @@ EVGAv3_config EVGAGPUv3Controller::GetZoneConfig(uint8_t zone, uint8_t mode)
uint8_t blue = data_pkt[(color_index * 4) + 4];
zone_config.colors[color_index] = ToRGBColor(red, green, blue);
}
speed16.LSB = data_pkt[29];
speed16.MSB = data_pkt[30];
speed16.lsb = data_pkt[29];
speed16.msb = data_pkt[30];
zone_config.speed = speed16.u16;
}
else
else
{
readFail = true;
}
@@ -288,7 +288,7 @@ EVGAv3_config EVGAGPUv3Controller::GetZoneConfig(uint8_t zone, uint8_t mode)
for(uint8_t i = 0; i < 7; i++)
{
zone_config.colors[i] = 0;
}
}
LOG_DEBUG("[%s] Failed while loading Zone %1d configuration from HW", evgaGPUName, zone);
}
return zone_config;
@@ -423,8 +423,8 @@ void EVGAGPUv3Controller::SetZone(uint8_t zone, uint8_t mode, EVGAv3_config zone
zone_pkt[5] = RGBGetRValue(zone_config.colors[1]);
zone_pkt[6] = RGBGetGValue(zone_config.colors[1]);
zone_pkt[7] = RGBGetBValue(zone_config.colors[1]);
zone_pkt[8] = speed16.LSB;
zone_pkt[9] = speed16.MSB;
zone_pkt[8] = speed16.lsb;
zone_pkt[9] = speed16.msb;
bus->i2c_smbus_write_i2c_block_data(dev, EVGA_GPU_V3_REG_STATIC + ((mode -1) * 4) + zone, sizeof(zone_pkt), zone_pkt);
}
@@ -439,8 +439,8 @@ void EVGAGPUv3Controller::SetZone(uint8_t zone, uint8_t mode, EVGAv3_config zone
zone_pkt[0] = sizeof(zone_pkt) - 1;
zone_pkt[1] = zone_config.brightness;
zone_pkt[2] = speed16.LSB;
zone_pkt[3] = speed16.MSB;
zone_pkt[2] = speed16.lsb;
zone_pkt[3] = speed16.msb;
bus->i2c_smbus_write_i2c_block_data(dev, EVGA_GPU_V3_REG_STATIC + ((mode -1) * 4) + zone, sizeof(zone_pkt), zone_pkt);
}
@@ -456,8 +456,8 @@ void EVGAGPUv3Controller::SetZone(uint8_t zone, uint8_t mode, EVGAv3_config zone
zone_pkt[2] = RGBGetRValue(zone_config.colors[0]);
zone_pkt[3] = RGBGetGValue(zone_config.colors[0]);
zone_pkt[4] = RGBGetBValue(zone_config.colors[0]);
zone_pkt[5] = speed16.LSB;
zone_pkt[6] = speed16.MSB;
zone_pkt[5] = speed16.lsb;
zone_pkt[6] = speed16.msb;
bus->i2c_smbus_write_i2c_block_data(dev, EVGA_GPU_V3_REG_STATIC + ((mode -1) * 4) + zone, sizeof(zone_pkt), zone_pkt);
}
@@ -480,8 +480,8 @@ void EVGAGPUv3Controller::SetZone(uint8_t zone, uint8_t mode, EVGAv3_config zone
zone_pkt[3 + color_index * 4] = RGBGetGValue(zone_config.colors[color_index]);
zone_pkt[4 + color_index * 4] = RGBGetBValue(zone_config.colors[color_index]);
}
zone_pkt[29] = speed16.LSB;
zone_pkt[30] = speed16.MSB;
zone_pkt[29] = speed16.lsb;
zone_pkt[30] = speed16.msb;
// Color Count packet construction
color_cnt_pkt[0] = sizeof(color_cnt_pkt) - 1;
@@ -27,8 +27,8 @@ union u16_to_u8
uint16_t u16;
struct
{
uint8_t LSB;
uint8_t MSB;
uint8_t lsb;
uint8_t msb;
};
};
@@ -67,7 +67,7 @@ enum //Control registers and offsets
enum //Mode values for EVGA_GPU_V3_REG_MODE
{
EVGA_GPU_V3_MODE_OFF = 0x00,
EVGA_GPU_V3_MODE_STATIC = 0x01,
EVGA_GPU_V3_MODE_STATIC = 0x01,
EVGA_GPU_V3_MODE_BREATHING = 0x02,
EVGA_GPU_V3_MODE_RAINBOW = 0x03,
EVGA_GPU_V3_MODE_COLOR_CYCLE = 0x04,
@@ -62,8 +62,8 @@ bool EVGAGP102Controller::IsValid()
{
for (int i = 0; i < 3; i++)
{
char res = bus->i2c_smbus_read_byte_data(zi.dev_addr, EVGA_GP102_REG_VALID);
if (res == 0x1F)
unsigned char res = bus->i2c_smbus_read_byte_data(zi.dev_addr, EVGA_GP102_REG_VALID);
if (res == 0x1F || res == 0x91)
{
LOG_TRACE("[%s] Zone discovery successful on address: 0x%02X.", EVGA_GP102_CONTROLLER_NAME, zi.dev_addr);
return true;
@@ -63,12 +63,19 @@ const static zoneinfo gpuzoneinfos[]
0x00
},
{
"Backplate",
"Backplate", // for 1080Ti K|NGP|N
0x2A,
{0x30, 0x31, 0x32},
0xE9,
0xE0
}
},
{
"Backplate", // for 1080Ti FTW3
0x4F,
{0x30, 0x31, 0x32},
0x03,
0x00
},
};
class EVGAGP102Controller
@@ -70,7 +70,7 @@ unsigned char EVGAGPUv2Controller::GetMode()
return_mode = EVGA_GPU_V2_RGB_MODE_OFF;
}
break;
case EVGA_GPU_V2_MODE_STATIC:
{
return_mode = EVGA_GPU_V2_RGB_MODE_STATIC;
@@ -87,8 +87,8 @@ unsigned char EVGAGPUv2Controller::GetMode()
{
u16_to_u8 speed_16 = { (uint16_t) 0 };
speed_16.LSB = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_B_TO_A_SPEED_LSB);
speed_16.MSB = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_B_TO_A_SPEED_MSB);
speed_16.lsb = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_B_TO_A_SPEED_LSB);
speed_16.msb = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_B_TO_A_SPEED_MSB);
if (speed_16.u16 == 0)
{
@@ -112,8 +112,8 @@ unsigned char EVGAGPUv2Controller::GetSpeed()
{
u16_to_u8 speed_16 = { (uint16_t) 0 };
speed_16.LSB = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_ONTIME_LSB);
speed_16.MSB = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_ONTIME_MSB);
speed_16.lsb = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_ONTIME_LSB);
speed_16.msb = bus->i2c_smbus_read_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_ONTIME_MSB);
speed_16.u16 /= SPEED_MULTIPLIER;
@@ -235,16 +235,16 @@ void EVGAGPUv2Controller::SendMode(uint8_t mode)
void EVGAGPUv2Controller::SendSpeed(u16_to_u8 aOnTime, u16_to_u8 bOnTime, u16_to_u8 b2a, u16_to_u8 a2b, u16_to_u8 speed_un)
{
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_UN_LSB, (unsigned char) speed_un.LSB );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_UN_MSB, (unsigned char) speed_un.MSB );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_B_TO_A_SPEED_LSB, (unsigned char) b2a.LSB );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_B_TO_A_SPEED_MSB, (unsigned char) b2a.MSB );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_ONTIME_LSB, (unsigned char) bOnTime.LSB );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_ONTIME_MSB, (unsigned char) bOnTime.MSB );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_A_TO_B_SPEED_LSB, (unsigned char) a2b.LSB );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_A_TO_B_SPEED_MSB, (unsigned char) a2b.MSB );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_ONTIME_LSB, (unsigned char) aOnTime.LSB );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_ONTIME_MSB, (unsigned char) aOnTime.MSB );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_UN_LSB, (unsigned char) speed_un.lsb );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_UN_MSB, (unsigned char) speed_un.msb );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_B_TO_A_SPEED_LSB, (unsigned char) b2a.lsb );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_B_TO_A_SPEED_MSB, (unsigned char) b2a.msb );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_ONTIME_LSB, (unsigned char) bOnTime.lsb );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_B_ONTIME_MSB, (unsigned char) bOnTime.msb );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_A_TO_B_SPEED_LSB, (unsigned char) a2b.lsb );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_A_TO_B_SPEED_MSB, (unsigned char) a2b.msb );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_ONTIME_LSB, (unsigned char) aOnTime.lsb );
bus->i2c_smbus_write_byte_data(dev, EVGA_GPU_V2_REG_COLOR_A_ONTIME_MSB, (unsigned char) aOnTime.msb );
}
void EVGAGPUv2Controller::SetColor(RGBColor colorA, RGBColor colorB, uint8_t brightness)
@@ -26,8 +26,8 @@ union u16_to_u8
uint16_t u16;
struct
{
uint8_t LSB;
uint8_t MSB;
uint8_t lsb;
uint8_t msb;
};
};
@@ -66,7 +66,7 @@ enum
enum
{
EVGA_GPU_V2_MODE_OFF = 0x00,
EVGA_GPU_V2_MODE_STATIC = 0x01,
EVGA_GPU_V2_MODE_STATIC = 0x01,
EVGA_GPU_V2_MODE_RAINBOW = 0x0F,
EVGA_GPU_V2_MODE_BREATHING = 0x22,
};
@@ -1,25 +1,29 @@
#include "Detector.h"
#include "EVisionKeyboardController.h"
#include "EVisionV2KeyboardController.h"
#include "RGBController.h"
#include "RGBController_EVisionKeyboard.h"
#include "RGBController_EVisionV2Keyboard.h"
#include "SettingsManager.h"
#include <vector>
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| Keyboard product IDs |
\*-----------------------------------------------------*/
#define EVISION_KEYBOARD_VID 0x0C45
#define EVISION_KEYBOARD2_VID 0x320F
#define EVISION_KEYBOARD_USAGE_PAGE 0xFF1C
#define GLORIOUS_GMMK_TKL_PID 0x5064
#define REDRAGON_K550_PID 0x5204
#define REDRAGON_K552_PID 0x5104
#define REDRAGON_K552_V2_PID 0x5000
#define REDRAGON_K556_PID 0x5004
#define TECWARE_PHANTOM_ELITE_PID 0x652F
#define WARRIOR_KANE_TC235 0x8520
#define WOMIER_K87_PID 0x502A
#define WOMIER_K66_PID 0x7698
#define EVISION_KEYBOARD_VID 0x0C45
#define EVISION_KEYBOARD2_VID 0x320F
#define EVISION_KEYBOARD_USAGE_PAGE 0xFF1C
#define GLORIOUS_GMMK_TKL_PID 0x5064
#define REDRAGON_K550_PID 0x5204
#define REDRAGON_K552_PID 0x5104
#define REDRAGON_K552_V2_PID 0x5000
#define REDRAGON_K556_PID 0x5004
#define TECWARE_PHANTOM_ELITE_PID 0x652F
#define WARRIOR_KANE_TC235 0x8520
#define WOMIER_K87_PID 0x502A
#define WOMIER_K66_PID 0x7698
#define BYGG_CSB_ICL01_PID 0x5041
/******************************************************************************************\
* *
@@ -35,22 +39,51 @@ void DetectEVisionKeyboards(hid_device_info* info, const std::string& /*name*/)
if(dev)
{
EVisionKeyboardController* controller = new EVisionKeyboardController(dev, info->path);
EVisionKeyboardController* controller = new EVisionKeyboardController(dev, info->path);
RGBController_EVisionKeyboard* rgb_controller = new RGBController_EVisionKeyboard(controller);
rgb_controller->name = "EVision Keyboard";
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectEVisionV2Keyboards(hid_device_info* info, const std::string& name)
{
json settings = ResourceManager::get()->GetSettingsManager()->GetSettings("EVision2Settings");
hid_device* dev = hid_open_path(info->path);
if(dev)
{
EVisionV2KeyboardController* controller = new EVisionV2KeyboardController(dev, info->path);
RGBController_EVisionV2Keyboard* rgb_controller = new RGBController_EVisionV2Keyboard(controller, EVISION_V2_KEYBOARD_PART_KEYBOARD);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
if(!settings.contains("AdditionalZones") || settings["AdditionalZones"] == true)
{
rgb_controller = new RGBController_EVisionV2Keyboard(controller, EVISION_V2_KEYBOARD_PART_LOGO);
rgb_controller->name = name;
rgb_controller->name += " Logo";
ResourceManager::get()->RegisterRGBController(rgb_controller);
rgb_controller = new RGBController_EVisionV2Keyboard(controller, EVISION_V2_KEYBOARD_PART_EDGE);
rgb_controller->name = name;
rgb_controller->name += " Edge";
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
}
/*---------------------------------------------------------------------------------------------------------------------------------------------*\
| Keyboards |
\*---------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:5204", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, REDRAGON_K550_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:5104", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, REDRAGON_K552_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:5000", DetectEVisionKeyboards, EVISION_KEYBOARD2_VID, REDRAGON_K552_V2_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:5004", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, REDRAGON_K556_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:652F", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, TECWARE_PHANTOM_ELITE_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:8520", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, WARRIOR_KANE_TC235, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:502A", DetectEVisionKeyboards, EVISION_KEYBOARD2_VID, WOMIER_K87_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:7698", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, WOMIER_K66_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:5064", DetectEVisionKeyboards, EVISION_KEYBOARD2_VID, GLORIOUS_GMMK_TKL_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:5204", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, REDRAGON_K550_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:5104", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, REDRAGON_K552_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:5000", DetectEVisionKeyboards, EVISION_KEYBOARD2_VID, REDRAGON_K552_V2_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:5004", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, REDRAGON_K556_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:652F", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, TECWARE_PHANTOM_ELITE_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:8520", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, WARRIOR_KANE_TC235, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:502A", DetectEVisionKeyboards, EVISION_KEYBOARD2_VID, WOMIER_K87_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:7698", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, WOMIER_K66_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("EVision Keyboard 320F:5064", DetectEVisionKeyboards, EVISION_KEYBOARD2_VID, GLORIOUS_GMMK_TKL_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
REGISTER_HID_DETECTOR_IP("CSB/ICL01 Keyboard", DetectEVisionV2Keyboards, EVISION_KEYBOARD2_VID, BYGG_CSB_ICL01_PID, 1, EVISION_KEYBOARD_USAGE_PAGE);
@@ -0,0 +1,443 @@
/*-------------------------------------------------------------------*\
| EVisionV2KeyboardController.cpp |
| |
| Driver for recent EVision RGB keyboard lighting controller |
| |
| Le Philousophe 25 Dec 2022 |
\*-------------------------------------------------------------------*/
#include <cstring>
#include "LogManager.h"
#include "EVisionV2KeyboardController.h"
#define BLANK_SPACE 6
#define query_check_buffer(c) \
do \
{ \
if(!(c)) \
{ \
return -256; \
} \
} while(0)
using namespace std::chrono_literals;
static uint8_t keyvalue_map[EVISION_V2_MATRIX_WIDTH * EVISION_V2_MATRIX_HEIGHT] =
{
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 19 19 20 */
0, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96,
1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, 67, 73, 79, 85, 91, 97, 103, 109, 115, 121,
2, 8, 14, 20, 26, 32, 38, 44, 50, 56, 62, 68, 74, 80, 86, 92, 98, 104, 110, 116, 122,
3, 9, 15, 21, 27, 33, 39, 45, 51, 57, 63, 69, 75, 81, 105, 111, 117,
4, 10, 16, 22, 28, 34, 40, 46, 52, 58, 64, 70, 82, 94, 106, 112, 118, 124,
5, 11, 17, 41, 65, 71, 77, 83, 89, 95, 101, 113, 119,
};
EVisionV2KeyboardController::EVisionV2KeyboardController(hid_device* dev_handle, const char* path)
{
const uint8_t sz = HID_MAX_STR;
wchar_t tmp[sz];
dev = dev_handle;
location = path;
hid_get_manufacturer_string(dev, tmp, sz);
std::wstring wName = std::wstring(tmp);
device_name = std::string(wName.begin(), wName.end());
hid_get_product_string(dev, tmp, sz);
wName = std::wstring(tmp);
device_name.append(" ").append(std::string(wName.begin(), wName.end()));
uint8_t buffer[7];
if(Read(EVISION_V2_CMD_READ_CAPABILITIES, 0, sizeof(buffer), buffer) < 0)
{
return;
}
if(buffer[0] != 0xaa && buffer[1] != 0x55)
{
return;
}
map_size = buffer[5];
macros_size = buffer[6] * 0x80;
}
EVisionV2KeyboardController::~EVisionV2KeyboardController()
{
hid_close(dev);
}
std::string EVisionV2KeyboardController::GetDeviceName()
{
return device_name;
}
std::string EVisionV2KeyboardController::GetSerial()
{
const uint8_t sz = HID_MAX_STR;
wchar_t tmp[sz];
int ret = hid_get_serial_number_string(dev, tmp, sz);
if(ret != 0)
{
return("");
}
std::wstring w_tmp = std::wstring(tmp);
std::string serial = std::string(w_tmp.begin(), w_tmp.end());
return serial;
}
std::string EVisionV2KeyboardController::GetLocation()
{
return("HID: " + location);
}
int EVisionV2KeyboardController::Query(uint8_t cmd, uint16_t offset, const uint8_t* idata, uint8_t size, uint8_t* odata)
{
uint8_t buffer[EVISION_V2_PACKET_SIZE];
memset(buffer, 0, sizeof(buffer));
buffer[0] = EVISION_V2_REPORT_ID;
buffer[3] = cmd;
buffer[4] = size;
buffer[5] = offset & 0xff;
buffer[6] = (offset >> 8) & 0xff;
if(idata)
{
memcpy(buffer + 8, idata, size);
}
uint16_t chksum = 0;
for(uint8_t* p = &buffer[3]; p != &buffer[EVISION_V2_PACKET_SIZE]; p++)
{
chksum += *p;
}
buffer[1] = chksum & 0xff;
buffer[2] = (chksum >> 8) & 0xff;
int bytes_read;
{
const std::lock_guard<std::mutex> lock(query_mutex);
hid_write(dev, buffer, sizeof(buffer));
do
{
bytes_read = hid_read(dev, buffer, sizeof(buffer));
} while(bytes_read != 0 && buffer[0] != EVISION_V2_REPORT_ID);
}
query_check_buffer(bytes_read == sizeof(buffer));
query_check_buffer(buffer[0] == EVISION_V2_REPORT_ID);
query_check_buffer(buffer[1] == (chksum & 0xff));
query_check_buffer(buffer[2] == ((chksum >> 8) & 0xff));
query_check_buffer(buffer[3] == cmd);
query_check_buffer(buffer[5] == (offset & 0xff));
query_check_buffer(buffer[6] == ((offset >> 8) & 0xff));
if(buffer[7] != 0)
{
return -buffer[7];
}
size = buffer[4];
if(size > EVISION_V2_PACKET_SIZE - 8)
{
return -256;
}
if(odata)
{
memcpy(odata, buffer + 8, size);
}
return size;
}
int EVisionV2KeyboardController::BeginConfigure()
{
return Query(EVISION_V2_CMD_BEGIN_CONFIGURE);
}
int EVisionV2KeyboardController::EndConfigure()
{
return Query(EVISION_V2_CMD_END_CONFIGURE);
}
int EVisionV2KeyboardController::Read(uint8_t cmd, uint16_t offset, uint16_t size, uint8_t* odata)
{
while(size > 0)
{
uint8_t pktsz = std::min<size_t>(size, EVISION_V2_PACKET_SIZE - 8);
int result = Query(cmd, offset, nullptr, pktsz, odata);
if(result <= 0)
{
return result;
}
else if(result > size)
{
return -256;
}
offset += result;
odata += result;
size -= result;
}
return 0;
}
int EVisionV2KeyboardController::Write(uint8_t cmd, uint16_t offset, const uint8_t* idata, uint16_t size)
{
while(size > 0)
{
uint8_t pktsz = std::min<size_t>(size, EVISION_V2_PACKET_SIZE - 8);
int result = Query(cmd, offset, idata, pktsz);
if(result <= 0)
{
return result;
}
offset += pktsz;
idata += pktsz;
size -= pktsz;
}
return 0;
}
int EVisionV2KeyboardController::GetMode(EVisionV2KeyboardPart part, EvisionV2ModeConfig& config)
{
uint8_t buffer[18];
memset(buffer, 0, sizeof(buffer));
uint8_t current_profile;
int ret = Read(EVISION_V2_CMD_READ_CONFIG, EVISION_V2_OFFSET_CURRENT_PROFILE, 1, &current_profile);
if(ret < 0)
{
return ret;
}
if(current_profile > 2)
{
current_profile = 0;
}
uint16_t offset;
uint8_t size;
offset = current_profile * 0x40 + EVISION_V2_OFFSET_FIRST_PROFILE;
switch(part)
{
case EVISION_V2_KEYBOARD_PART_KEYBOARD:
size = sizeof(buffer);
break;
case EVISION_V2_KEYBOARD_PART_LOGO:
offset += EVISION_V2_PARAMETER_LOGO;
size = EVISION_V2_PARAMETER_LOGO_ON_OFF - EVISION_V2_PARAMETER_LOGO + 1;
break;
case EVISION_V2_KEYBOARD_PART_EDGE:
offset += EVISION_V2_PARAMETER_EDGE;
size = EVISION_V2_PARAMETER_END - EVISION_V2_PARAMETER_EDGE;
break;
}
ret = Read(EVISION_V2_CMD_READ_CONFIG, offset, size, buffer);
if(ret < 0)
{
return ret;
}
config.mode = buffer[EVISION_V2_PARAMETER_MODE];
config.brightness = buffer[EVISION_V2_PARAMETER_BRIGHTNESS];
config.speed = buffer[EVISION_V2_PARAMETER_SPEED];
config.direction = buffer[EVISION_V2_PARAMETER_DIRECTION];
config.random_colours = buffer[EVISION_V2_PARAMETER_RANDOM_COLOR_FLAG] != 0;
config.colour = ToRGBColor(buffer[EVISION_V2_PARAMETER_MODE_COLOR + 0],
buffer[EVISION_V2_PARAMETER_MODE_COLOR + 1], buffer[EVISION_V2_PARAMETER_MODE_COLOR + 2]);
if(part == EVISION_V2_KEYBOARD_PART_KEYBOARD)
{
config.ledmode = buffer[EVISION_V2_PARAMETER_LED_MODE_COLOR];
if(config.mode == EVISION_V2_MODE_CUSTOM)
{
ret = Read(EVISION_V2_CMD_READ_CONFIG, current_profile * 0x40 + EVISION_V2_OFFSET_FIRST_PROFILE + EVISION_V2_PARAMETER_CURRENT_CUSTOM_MODE, sizeof(config.ledmode), &config.ledmode);
if(ret < 0)
{
return ret;
}
}
}
else if(part == EVISION_V2_KEYBOARD_PART_LOGO)
{
// Use ledmode for logo on/off
config.ledmode = buffer[EVISION_V2_PARAMETER_LOGO_ON_OFF - EVISION_V2_PARAMETER_LOGO];
}
return 0;
}
void EVisionV2KeyboardController::SetMode(EVisionV2KeyboardPart part, const EvisionV2ModeConfig& config)
{
uint8_t buffer[18];
memset(buffer, 0, sizeof(buffer));
buffer[EVISION_V2_PARAMETER_MODE] = config.mode;
buffer[EVISION_V2_PARAMETER_BRIGHTNESS] = config.brightness;
buffer[EVISION_V2_PARAMETER_SPEED] = config.speed;
buffer[EVISION_V2_PARAMETER_DIRECTION] = config.direction;
buffer[EVISION_V2_PARAMETER_RANDOM_COLOR_FLAG] = (config.random_colours) ? 255 : 0;
buffer[EVISION_V2_PARAMETER_MODE_COLOR + 0] = RGBGetRValue(config.colour);
buffer[EVISION_V2_PARAMETER_MODE_COLOR + 1] = RGBGetGValue(config.colour);
buffer[EVISION_V2_PARAMETER_MODE_COLOR + 2] = RGBGetBValue(config.colour);
if(part == EVISION_V2_KEYBOARD_PART_KEYBOARD)
{
buffer[EVISION_V2_PARAMETER_COLOR_OFFSET] = 0;
if(config.mode != EVISION_V2_MODE_CUSTOM)
{
buffer[EVISION_V2_PARAMETER_LED_MODE_COLOR] = config.ledmode;
}
}
else if(part == EVISION_V2_KEYBOARD_PART_LOGO)
{
// Use ledmode for logo on/off
buffer[EVISION_V2_PARAMETER_LOGO_ON_OFF - EVISION_V2_PARAMETER_LOGO] = config.ledmode;
}
BeginConfigure();
uint8_t current_profile;
int ret = Read(EVISION_V2_CMD_READ_CONFIG, EVISION_V2_OFFSET_CURRENT_PROFILE, 1, &current_profile);
if(ret < 0)
{
return;
}
if(current_profile > 2)
{
current_profile = 0;
Write(EVISION_V2_CMD_WRITE_CONFIG, EVISION_V2_OFFSET_CURRENT_PROFILE, &current_profile, 1);
}
uint16_t offset;
uint8_t size;
offset = current_profile * 0x40 + EVISION_V2_OFFSET_FIRST_PROFILE;
switch(part)
{
case EVISION_V2_KEYBOARD_PART_KEYBOARD:
size = sizeof(buffer);
break;
case EVISION_V2_KEYBOARD_PART_LOGO:
offset += EVISION_V2_PARAMETER_LOGO;
size = EVISION_V2_PARAMETER_LOGO_ON_OFF - EVISION_V2_PARAMETER_LOGO + 1;
break;
case EVISION_V2_KEYBOARD_PART_EDGE:
offset += EVISION_V2_PARAMETER_EDGE;
size = EVISION_V2_PARAMETER_END - EVISION_V2_PARAMETER_EDGE;
break;
}
Write(EVISION_V2_CMD_WRITE_CONFIG, offset, buffer, size);
if((part == EVISION_V2_KEYBOARD_PART_KEYBOARD) && (config.mode == EVISION_V2_MODE_CUSTOM))
{
Write(EVISION_V2_CMD_WRITE_CONFIG, current_profile * 0x40 + EVISION_V2_OFFSET_FIRST_PROFILE + EVISION_V2_PARAMETER_CURRENT_CUSTOM_MODE, &config.ledmode, sizeof(config.ledmode));
}
EndConfigure();
}
void EVisionV2KeyboardController::SetLedsDirect(const std::vector<RGBColor>& colours)
{
const size_t colours_num = std::min(colours.size(), sizeof(keyvalue_map) / sizeof(keyvalue_map[0]));
uint8_t* buffer = new uint8_t[3 * map_size];
memset(buffer, 0, 3 * map_size);
for(size_t i = 0; i < colours_num; i++)
{
size_t j = (size_t)keyvalue_map[i] * 3;
buffer[j + 0] = RGBGetRValue(colours[i]);
buffer[j + 1] = RGBGetGValue(colours[i]);
buffer[j + 2] = RGBGetBValue(colours[i]);
}
Write(EVISION_V2_CMD_SEND_DYNAMIC_COLORS, 0, buffer, 3 * map_size);
delete[] buffer;
}
void EVisionV2KeyboardController::SetLedDirect(int led, RGBColor colour)
{
uint8_t buffer[3];
buffer[0] = RGBGetRValue(colour);
buffer[1] = RGBGetGValue(colour);
buffer[2] = RGBGetBValue(colour);
Write(EVISION_V2_CMD_SEND_DYNAMIC_COLORS, keyvalue_map[led] * 3, buffer, sizeof(buffer));
}
void EVisionV2KeyboardController::RefreshLedDirect()
{
// Write one zero byte in the first blank space
Query(EVISION_V2_CMD_SEND_DYNAMIC_COLORS, BLANK_SPACE * 3, nullptr, 1, nullptr);
}
void EVisionV2KeyboardController::EndLedsDirect()
{
Query(EVISION_V2_CMD_END_DYNAMIC_COLORS);
}
int EVisionV2KeyboardController::GetLedsCustom(uint8_t colorset, std::vector<RGBColor>& colours)
{
if(colorset > 9)
{
return -256;
}
const size_t colours_num = std::min(colours.size(), sizeof(keyvalue_map) / sizeof(keyvalue_map[0]));
uint8_t* buffer = new uint8_t[3 * map_size];
memset(buffer, 0, 3 * map_size);
int ret = Read(EVISION_V2_CMD_READ_CUSTOM_COLORS, 512 * colorset, 3 * map_size, buffer);
if(ret < 0)
{
return ret;
}
for(size_t i = 0; i < colours_num; i++)
{
size_t j = (size_t)keyvalue_map[i] * 3;
colours[i] = ToRGBColor(buffer[j + 0], buffer[j + 1], buffer[j + 2]);
}
delete[] buffer;
return 0;
}
void EVisionV2KeyboardController::SetLedsCustom(uint8_t colorset, const std::vector<RGBColor>& colours)
{
if(colorset > 9)
{
return;
}
const size_t colours_num = std::min(colours.size(), sizeof(keyvalue_map) / sizeof(keyvalue_map[0]));
uint8_t* buffer = new uint8_t[3 * map_size];
memset(buffer, 0, 3 * map_size);
for(size_t i = 0; i < colours_num; i++)
{
size_t j = (size_t)keyvalue_map[i] * 3;
buffer[j + 0] = RGBGetRValue(colours[i]);
buffer[j + 1] = RGBGetGValue(colours[i]);
buffer[j + 2] = RGBGetBValue(colours[i]);
}
BeginConfigure();
Write(EVISION_V2_CMD_WRITE_CUSTOM_COLORS, 512 * colorset, buffer, 3 * map_size);
EndConfigure();
delete[] buffer;
}
@@ -0,0 +1,171 @@
/*-------------------------------------------------------------------*\
| EVisionV2KeyboardController.h |
| |
| Definitions and types for EVision RGB keyboard lighting controller |
| |
| Le Philousophe 25 Dec 2022 |
\*-------------------------------------------------------------------*/
#include <string>
#include <hidapi/hidapi.h>
#include "RGBController.h"
#pragma once
#define EVISION_V2_PACKET_SIZE 64
#define HID_MAX_STR 255
#define EVISION_V2_REPORT_ID 4
#define EVISION_V2_MATRIX_HEIGHT 6
#define EVISION_V2_MATRIX_WIDTH 21
enum
{
EVISION_V2_MODE_COLOR_WAVE_SHORT = 0x01, /* "Go with the stream" */
EVISION_V2_MODE_COLOR_WAVE_LONG = 0x02, /* "Clouds fly" */
EVISION_V2_MODE_COLOR_WHEEL = 0x03, /* "Winding paths" */
EVISION_V2_MODE_SPECTRUM_CYCLE = 0x04, /* "Spectrum" */
EVISION_V2_MODE_BREATHING = 0x05, /* "Breath" */
EVISION_V2_MODE_STATIC = 0x06, /* "Normal" */
EVISION_V2_MODE_REACTIVE = 0x07, /* "Pass without trace" */
EVISION_V2_MODE_REACTIVE_RIPPLE = 0x08, /* "Ripples" */
EVISION_V2_MODE_REACTIVE_LINE = 0x09, /* "Stream" */
EVISION_V2_MODE_STARLIGHT_FAST = 0x0A, /* "Stars" */
EVISION_V2_MODE_BLOOMING = 0x0B, /* "Flowers" */
EVISION_V2_MODE_RAINBOW_WAVE_VERTICAL = 0x0C, /* "Swift action" */
EVISION_V2_MODE_HURRICANE = 0x0D, /* "Hurricane" */
EVISION_V2_MODE_ACCUMULATE = 0x0E, /* "Cartoon" */
EVISION_V2_MODE_STARLIGHT_SLOW = 0x0F, /* "Digital times" */
EVISION_V2_MODE_VISOR = 0x10, /* "Both ways" */
EVISION_V2_MODE_SURMOUNT = 0x11, /* "Surmount" */
EVISION_V2_MODE_RAINBOW_WAVE_CIRCLE = 0x12, /* "Speed" */
EVISION_V2_MODE_CUSTOM = 0x14, /* "Custom" */
EVISION_V2_MODE_DIRECT = 0xFF, /* Software controlled mode */
};
enum
{
EVISION_V2_MODE2_COLOR_WAVE = 0x00, /* "Pulsation" */
EVISION_V2_MODE2_BREATHING = 0x01, /* "Breath" */
EVISION_V2_MODE2_YOYO = 0x02, /* "Yoyo" */
EVISION_V2_MODE2_BLINK = 0x03, /* "Blink" */
EVISION_V2_MODE2_STATIC = 0x04, /* "Normal" */
EVISION_V2_MODE2_OFF = 0x05, /* "Off" */
};
enum
{
EVISION_V2_CMD_BEGIN_CONFIGURE = 0x01,
EVISION_V2_CMD_END_CONFIGURE = 0x02,
EVISION_V2_CMD_READ_CAPABILITIES = 0x03,
//EVISION_V2_CMD_WRITE_CAPABILITIES = 0x04,
EVISION_V2_CMD_READ_CONFIG = 0x05,
EVISION_V2_CMD_WRITE_CONFIG = 0x06,
EVISION_V2_CMD_READ_CUSTOM_COLORS = 0x0A,
EVISION_V2_CMD_WRITE_CUSTOM_COLORS = 0x0B,
EVISION_V2_CMD_SEND_DYNAMIC_COLORS = 0x12,
EVISION_V2_CMD_END_DYNAMIC_COLORS = 0x13,
};
enum
{
EVISION_V2_OFFSET_CURRENT_PROFILE = 0x00,
EVISION_V2_OFFSET_FIRST_PROFILE = 0x01,
EVISION_V2_OFFSET_SECOND_PROFILE = 0x41,
EVISION_V2_OFFSET_THIRD_PROFILE = 0x81,
};
enum
{
EVISION_V2_PARAMETER_MODE = 0x00, /* Mode parameter */
EVISION_V2_PARAMETER_BRIGHTNESS = 0x01, /* Brightness parameter */
EVISION_V2_PARAMETER_SPEED = 0x02, /* Speed parameter */
EVISION_V2_PARAMETER_DIRECTION = 0x03, /* Direction parameter */
EVISION_V2_PARAMETER_RANDOM_COLOR_FLAG = 0x04, /* Random color parameter */
EVISION_V2_PARAMETER_MODE_COLOR = 0x05, /* Mode color (RGB) */
EVISION_V2_PARAMETER_COLOR_OFFSET = 0x08, /* Unknown color offset */
EVISION_V2_PARAMETER_LED_MODE_COLOR = 0x11, /* Led mode color */
EVISION_V2_PARAMETER_CURRENT_CUSTOM_MODE = 0x19, /* Custom mode current colorset */
EVISION_V2_PARAMETER_LOGO = 0x1a, /* Logo parameters */
EVISION_V2_PARAMETER_LOGO_ON_OFF = 0x23, /* Logo on/off */
EVISION_V2_PARAMETER_EDGE = 0x24, /* Edge parameters */
EVISION_V2_PARAMETER_END = 0x2b, /* Address after last parameter */
};
enum
{
EVISION_V2_BRIGHTNESS_LOWEST = 0x00, /* Lowest brightness (off) */
EVISION_V2_BRIGHTNESS_HIGHEST = 0x04, /* Highest brightness */
};
enum
{
EVISION_V2_SPEED_SLOWEST = 0x05, /* Slowest speed setting */
EVISION_V2_SPEED_NORMAL = 0x03, /* Normal speed setting */
EVISION_V2_SPEED_FASTEST = 0x00, /* Fastest speed setting */
};
enum
{
EVISION_V2_SURMOUNT_MODE_COLOR_RED = 0x00, /* Red surmount color */
EVISION_V2_SURMOUNT_MODE_COLOR_YELLOW = 0x01, /* Yellow surmount color */
EVISION_V2_SURMOUNT_MODE_COLOR_GREEN = 0x02, /* Green surmount color */
EVISION_V2_SURMOUNT_MODE_COLOR_CYAN = 0x03, /* Cyan surmount color */
};
enum EVisionV2KeyboardPart
{
EVISION_V2_KEYBOARD_PART_KEYBOARD,
EVISION_V2_KEYBOARD_PART_LOGO,
EVISION_V2_KEYBOARD_PART_EDGE,
};
struct EvisionV2ModeConfig
{
uint8_t mode;
uint8_t brightness;
uint8_t speed;
uint8_t direction;
bool random_colours;
RGBColor colour;
uint8_t ledmode;
};
class EVisionV2KeyboardController
{
public:
EVisionV2KeyboardController(hid_device* dev_handle, const char* path);
~EVisionV2KeyboardController();
std::string GetDeviceName();
std::string GetSerial();
std::string GetLocation();
int Query(uint8_t cmd, uint16_t offset = 0, const uint8_t* idata = nullptr, uint8_t size = 0, uint8_t* odata = nullptr);
int BeginConfigure();
int EndConfigure();
int Read(uint8_t cmd, uint16_t offset, uint16_t size, uint8_t* odata);
int Write(uint8_t cmd, uint16_t offset, const uint8_t* idata, uint16_t size);
int GetMode(EVisionV2KeyboardPart part, EvisionV2ModeConfig& config);
void SetMode(EVisionV2KeyboardPart part, const EvisionV2ModeConfig& config);
void SetLedsDirect(const std::vector<RGBColor>& colours);
void SetLedDirect(int led, RGBColor colours);
void RefreshLedDirect();
void EndLedsDirect();
int GetLedsCustom(uint8_t colorset, std::vector<RGBColor>& colours);
void SetLedsCustom(uint8_t colorset, const std::vector<RGBColor>& colours);
private:
std::string device_name;
std::string serial;
std::string location;
hid_device* dev;
size_t map_size;
size_t macros_size;
std::mutex query_mutex;
};
@@ -0,0 +1,857 @@
/*-------------------------------------------------------------------*\
| RGBController_EVisionV2Keyboard.cpp |
| |
| Generic RGB Interface for EVision V2 RGB Keyboard |
| |
| Le Philousophe 25 Dec 2022 |
\*-------------------------------------------------------------------*/
#define NA 0xFFFFFFFF
#include <chrono>
#include "hsv.h"
#include "RGBControllerKeyNames.h"
#include "RGBController_EVisionV2Keyboard.h"
using namespace std::chrono_literals;
static unsigned int matrix_map[EVISION_V2_MATRIX_HEIGHT][EVISION_V2_MATRIX_WIDTH] =
{
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 19 19 20 */
{ 0, NA, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, NA, NA, NA, NA },
{ 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, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57 },
{ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, NA, NA, NA, 72, 73, 74, NA },
{ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, NA, 87, NA, 88, NA, 89, 90, 91, 92 },
{ 93, 94, 95, NA, NA, NA, 96, NA, NA, NA, 97, 98, 99, 100, 101, 102, 103, NA, 104, 105, NA }
};
static const char *led_names[] =
{
KEY_EN_ESCAPE, //00
KEY_EN_F1,
KEY_EN_F2,
KEY_EN_F3,
KEY_EN_F4,
KEY_EN_F5,
KEY_EN_F6,
KEY_EN_F7,
KEY_EN_F8,
KEY_EN_F9,
KEY_EN_F10, //10
KEY_EN_F11,
KEY_EN_F12,
KEY_EN_PRINT_SCREEN,
KEY_EN_SCROLL_LOCK,
KEY_EN_PAUSE_BREAK,
KEY_EN_BACK_TICK, //16
KEY_EN_1,
KEY_EN_2,
KEY_EN_3,
KEY_EN_4, //20
KEY_EN_5,
KEY_EN_6,
KEY_EN_7,
KEY_EN_8,
KEY_EN_9,
KEY_EN_0,
KEY_EN_MINUS,
KEY_EN_EQUALS,
KEY_EN_BACKSPACE,
KEY_EN_INSERT,
KEY_EN_HOME, //30
KEY_EN_PAGE_UP,
KEY_EN_NUMPAD_LOCK,
KEY_EN_NUMPAD_DIVIDE,
KEY_EN_NUMPAD_TIMES,
KEY_EN_NUMPAD_MINUS,
KEY_EN_TAB, //37
KEY_EN_Q,
KEY_EN_W,
KEY_EN_E, //40
KEY_EN_R,
KEY_EN_T,
KEY_EN_Y,
KEY_EN_U,
KEY_EN_I,
KEY_EN_O,
KEY_EN_P,
KEY_EN_LEFT_BRACKET,
KEY_EN_RIGHT_BRACKET,
KEY_EN_ANSI_BACK_SLASH, //50
KEY_EN_DELETE,
KEY_EN_END,
KEY_EN_PAGE_DOWN,
KEY_EN_NUMPAD_7,
KEY_EN_NUMPAD_8,
KEY_EN_NUMPAD_9,
KEY_EN_NUMPAD_PLUS,
KEY_EN_CAPS_LOCK, //58
KEY_EN_A,
KEY_EN_S,
KEY_EN_D,
KEY_EN_F,
KEY_EN_G,
KEY_EN_H,
KEY_EN_J,
KEY_EN_K,
KEY_EN_L,
KEY_EN_SEMICOLON,
KEY_EN_QUOTE,
KEY_EN_POUND, //70
KEY_EN_ISO_ENTER,
KEY_EN_NUMPAD_4,
KEY_EN_NUMPAD_5,
KEY_EN_NUMPAD_6,
KEY_EN_LEFT_SHIFT, //75
KEY_EN_ISO_BACK_SLASH,
KEY_EN_Z,
KEY_EN_X,
KEY_EN_C,
KEY_EN_V, //80
KEY_EN_B,
KEY_EN_N,
KEY_EN_M,
KEY_EN_COMMA,
KEY_EN_PERIOD,
KEY_EN_FORWARD_SLASH,
KEY_EN_RIGHT_SHIFT,
KEY_EN_UP_ARROW,
KEY_EN_NUMPAD_1,
KEY_EN_NUMPAD_2, //90
KEY_EN_NUMPAD_3,
KEY_EN_NUMPAD_ENTER,
KEY_EN_LEFT_CONTROL, //93
KEY_EN_LEFT_WINDOWS,
KEY_EN_LEFT_ALT,
KEY_EN_SPACE,
KEY_EN_RIGHT_ALT,
KEY_EN_RIGHT_WINDOWS,
KEY_EN_RIGHT_FUNCTION,
KEY_EN_RIGHT_CONTROL, //100
KEY_EN_LEFT_ARROW,
KEY_EN_DOWN_ARROW,
KEY_EN_RIGHT_ARROW,
KEY_EN_NUMPAD_0,
KEY_EN_NUMPAD_PERIOD,
};
/**------------------------------------------------------------------*\
@name EVision V2 Keyboard
@category Keyboard
@type USB
@save :white_check_mark:
@direct :white_check_mark:
@effects :white_check_mark:
@detectors DetectEVisionV2Keyboard
@comment The Evision V2 controller implements all hardware modes
found in the OEM software. Some options may not be named correctly
like directions for some modes.
\*-------------------------------------------------------------------*/
RGBController_EVisionV2Keyboard::RGBController_EVisionV2Keyboard(EVisionV2KeyboardController* controller_ptr, EVisionV2KeyboardPart part_)
{
controller = controller_ptr;
part = part_;
name = "EVision Keyboard Device";
vendor = "Evision";
type = DEVICE_TYPE_KEYBOARD;
description = "EVision Keyboard Device";
location = controller->GetLocation();
serial = controller->GetSerial();
switch(part)
{
case EVISION_V2_KEYBOARD_PART_KEYBOARD:
SetupKeyboardModes();
break;
case EVISION_V2_KEYBOARD_PART_LOGO:
case EVISION_V2_KEYBOARD_PART_EDGE:
SetupLogoEdgeModes();
break;
}
SetupZones();
LoadConfig();
keepalive_thread_run = false;
keepalive_thread = nullptr;
if(part == EVISION_V2_KEYBOARD_PART_KEYBOARD)
{
keepalive_thread_run = true;
keepalive_thread = new std::thread(&RGBController_EVisionV2Keyboard::KeepaliveThread, this);
}
}
RGBController_EVisionV2Keyboard::~RGBController_EVisionV2Keyboard()
{
if(keepalive_thread)
{
keepalive_thread_run = false;
keepalive_thread->join();
delete keepalive_thread;
}
delete controller;
}
void RGBController_EVisionV2Keyboard::SetupKeyboardModes()
{
mode Direct;
Direct.name = "Direct";
Direct.value = EVISION_V2_MODE_DIRECT;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode ColorWave;
ColorWave.name = "Color Wave short";
ColorWave.value = EVISION_V2_MODE_COLOR_WAVE_SHORT;
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.speed_min = EVISION_V2_SPEED_SLOWEST;
ColorWave.speed_max = EVISION_V2_SPEED_FASTEST;
ColorWave.speed = EVISION_V2_SPEED_NORMAL;
ColorWave.colors_min = 1;
ColorWave.colors_max = 1;
ColorWave.color_mode = MODE_COLORS_RANDOM;
ColorWave.colors.resize(1);
ColorWave.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
ColorWave.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
ColorWave.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(ColorWave);
mode ColorWaveLong;
ColorWaveLong.name = "Color Wave long";
ColorWaveLong.value = EVISION_V2_MODE_COLOR_WAVE_LONG;
ColorWaveLong.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;
ColorWaveLong.speed_min = EVISION_V2_SPEED_SLOWEST;
ColorWaveLong.speed_max = EVISION_V2_SPEED_FASTEST;
ColorWaveLong.speed = EVISION_V2_SPEED_NORMAL;
ColorWaveLong.colors_min = 1;
ColorWaveLong.colors_max = 1;
ColorWaveLong.color_mode = MODE_COLORS_RANDOM;
ColorWaveLong.colors.resize(1);
ColorWaveLong.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
ColorWaveLong.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
ColorWaveLong.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(ColorWaveLong);
mode ColorWheel;
ColorWheel.name = "Color Wheel";
ColorWheel.value = EVISION_V2_MODE_COLOR_WHEEL;
ColorWheel.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;
ColorWheel.speed_min = EVISION_V2_SPEED_SLOWEST;
ColorWheel.speed_max = EVISION_V2_SPEED_FASTEST;
ColorWheel.speed = EVISION_V2_SPEED_NORMAL;
ColorWheel.colors_min = 1;
ColorWheel.colors_max = 1;
ColorWheel.color_mode = MODE_COLORS_RANDOM;
ColorWheel.colors.resize(1);
ColorWheel.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
ColorWheel.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
ColorWheel.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(ColorWheel);
mode SpectrumCycle;
SpectrumCycle.name = "Spectrum Cycle";
SpectrumCycle.value = EVISION_V2_MODE_SPECTRUM_CYCLE;
SpectrumCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
SpectrumCycle.speed_min = EVISION_V2_SPEED_SLOWEST;
SpectrumCycle.speed_max = EVISION_V2_SPEED_FASTEST;
SpectrumCycle.speed = EVISION_V2_SPEED_NORMAL;
SpectrumCycle.color_mode = MODE_COLORS_NONE;
SpectrumCycle.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
SpectrumCycle.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
SpectrumCycle.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(SpectrumCycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = EVISION_V2_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Breathing.speed_min = EVISION_V2_SPEED_SLOWEST;
Breathing.speed_max = EVISION_V2_SPEED_FASTEST;
Breathing.speed = EVISION_V2_SPEED_NORMAL;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.color_mode = MODE_COLORS_RANDOM;
Breathing.colors.resize(1);
Breathing.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
Breathing.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
Breathing.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(Breathing);
mode Static;
Static.name = "Static";
Static.value = EVISION_V2_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Static.colors_min = 1;
Static.colors_max = 1;
Static.color_mode = MODE_COLORS_RANDOM;
Static.colors.resize(1);
Static.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
Static.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
Static.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(Static);
mode Reactive;
Reactive.name = "Reactive";
Reactive.value = EVISION_V2_MODE_REACTIVE;
Reactive.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Reactive.speed_min = EVISION_V2_SPEED_SLOWEST;
Reactive.speed_max = EVISION_V2_SPEED_FASTEST;
Reactive.speed = EVISION_V2_SPEED_NORMAL;
Reactive.colors_min = 1;
Reactive.colors_max = 1;
Reactive.color_mode = MODE_COLORS_RANDOM;
Reactive.colors.resize(1);
Reactive.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
Reactive.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
Reactive.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(Reactive);
mode ReactiveRipple;
ReactiveRipple.name = "Reactive Ripple";
ReactiveRipple.value = EVISION_V2_MODE_REACTIVE_RIPPLE;
ReactiveRipple.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
ReactiveRipple.speed_min = EVISION_V2_SPEED_SLOWEST;
ReactiveRipple.speed_max = EVISION_V2_SPEED_FASTEST;
ReactiveRipple.speed = EVISION_V2_SPEED_NORMAL;
ReactiveRipple.colors_min = 1;
ReactiveRipple.colors_max = 1;
ReactiveRipple.color_mode = MODE_COLORS_RANDOM;
ReactiveRipple.colors.resize(1);
ReactiveRipple.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
ReactiveRipple.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
ReactiveRipple.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(ReactiveRipple);
mode ReactiveLine;
ReactiveLine.name = "Reactive Line";
ReactiveLine.value = EVISION_V2_MODE_REACTIVE_LINE;
ReactiveLine.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
ReactiveLine.speed_min = EVISION_V2_SPEED_SLOWEST;
ReactiveLine.speed_max = EVISION_V2_SPEED_FASTEST;
ReactiveLine.speed = EVISION_V2_SPEED_NORMAL;
ReactiveLine.colors_min = 1;
ReactiveLine.colors_max = 1;
ReactiveLine.color_mode = MODE_COLORS_RANDOM;
ReactiveLine.colors.resize(1);
ReactiveLine.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
ReactiveLine.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
ReactiveLine.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(ReactiveLine);
mode Starlight;
Starlight.name = "Starlight";
Starlight.value = EVISION_V2_MODE_STARLIGHT_FAST;
Starlight.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Starlight.speed_min = EVISION_V2_SPEED_SLOWEST;
Starlight.speed_max = EVISION_V2_SPEED_FASTEST;
Starlight.speed = EVISION_V2_SPEED_NORMAL;
Starlight.colors_min = 1;
Starlight.colors_max = 1;
Starlight.color_mode = MODE_COLORS_RANDOM;
Starlight.colors.resize(1);
Starlight.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
Starlight.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
Starlight.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(Starlight);
mode Blooming;
Blooming.name = "Blooming";
Blooming.value = EVISION_V2_MODE_BLOOMING;
Blooming.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Blooming.speed_min = EVISION_V2_SPEED_SLOWEST;
Blooming.speed_max = EVISION_V2_SPEED_FASTEST;
Blooming.speed = EVISION_V2_SPEED_NORMAL;
Blooming.color_mode = MODE_COLORS_NONE;
Blooming.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
Blooming.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
Blooming.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(Blooming);
mode RainbowWaveVertical;
RainbowWaveVertical.name = "Rainbow Wave vertical";
RainbowWaveVertical.value = EVISION_V2_MODE_RAINBOW_WAVE_VERTICAL;
RainbowWaveVertical.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
RainbowWaveVertical.speed_min = EVISION_V2_SPEED_SLOWEST;
RainbowWaveVertical.speed_max = EVISION_V2_SPEED_FASTEST;
RainbowWaveVertical.speed = EVISION_V2_SPEED_NORMAL;
RainbowWaveVertical.color_mode = MODE_COLORS_NONE;
RainbowWaveVertical.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
RainbowWaveVertical.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
RainbowWaveVertical.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(RainbowWaveVertical);
mode Hurricane;
Hurricane.name = "Hurricane";
Hurricane.value = EVISION_V2_MODE_HURRICANE;
Hurricane.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Hurricane.speed_min = EVISION_V2_SPEED_SLOWEST;
Hurricane.speed_max = EVISION_V2_SPEED_FASTEST;
Hurricane.speed = EVISION_V2_SPEED_NORMAL;
Hurricane.colors_min = 1;
Hurricane.colors_max = 1;
Hurricane.color_mode = MODE_COLORS_RANDOM;
Hurricane.colors.resize(1);
Hurricane.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
Hurricane.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
Hurricane.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(Hurricane);
mode Accumulate;
Accumulate.name = "Accumulate";
Accumulate.value = EVISION_V2_MODE_ACCUMULATE;
Accumulate.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Accumulate.speed_min = EVISION_V2_SPEED_SLOWEST;
Accumulate.speed_max = EVISION_V2_SPEED_FASTEST;
Accumulate.speed = EVISION_V2_SPEED_NORMAL;
Accumulate.colors_min = 1;
Accumulate.colors_max = 1;
Accumulate.color_mode = MODE_COLORS_RANDOM;
Accumulate.colors.resize(1);
Accumulate.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
Accumulate.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
Accumulate.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(Accumulate);
mode StarlightSlow;
StarlightSlow.name = "Starlight slow";
StarlightSlow.value = EVISION_V2_MODE_STARLIGHT_FAST;
StarlightSlow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
StarlightSlow.speed_min = EVISION_V2_SPEED_SLOWEST;
StarlightSlow.speed_max = EVISION_V2_SPEED_FASTEST;
StarlightSlow.speed = EVISION_V2_SPEED_NORMAL;
StarlightSlow.colors_min = 1;
StarlightSlow.colors_max = 1;
StarlightSlow.color_mode = MODE_COLORS_RANDOM;
StarlightSlow.colors.resize(1);
StarlightSlow.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
StarlightSlow.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
StarlightSlow.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(StarlightSlow);
mode Visor;
Visor.name = "Visor";
Visor.value = EVISION_V2_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.speed_min = EVISION_V2_SPEED_SLOWEST;
Visor.speed_max = EVISION_V2_SPEED_FASTEST;
Visor.speed = EVISION_V2_SPEED_NORMAL;
Visor.colors_min = 1;
Visor.colors_max = 1;
Visor.color_mode = MODE_COLORS_RANDOM;
Visor.colors.resize(1);
Visor.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
Visor.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
Visor.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(Visor);
mode Surmount;
Surmount.name = "Surmount";
Surmount.value = EVISION_V2_MODE_SURMOUNT;
Surmount.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Surmount.colors_min = 1;
Surmount.colors_max = 1;
Surmount.color_mode = MODE_COLORS_MODE_SPECIFIC;
Surmount.colors.resize(1);
Surmount.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
Surmount.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
Surmount.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(Surmount);
mode RainbowCircle;
RainbowCircle.name = "Rainbow Circle";
RainbowCircle.value = EVISION_V2_MODE_RAINBOW_WAVE_CIRCLE;
RainbowCircle.flags = MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
RainbowCircle.color_mode = MODE_COLORS_NONE;
RainbowCircle.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
RainbowCircle.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
RainbowCircle.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(RainbowCircle);
for(unsigned int i = 0; i < 10; i++)
{
mode Custom;
Custom.name = "Custom ";
Custom.name += std::to_string(i+1);
Custom.value = EVISION_V2_MODE_CUSTOM | i << 8;
Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
Custom.color_mode = MODE_COLORS_PER_LED;
Custom.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
Custom.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
Custom.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(Custom);
}
}
void RGBController_EVisionV2Keyboard::SetupLogoEdgeModes()
{
mode ColorWave;
ColorWave.name = "Color Wave";
ColorWave.value = EVISION_V2_MODE2_COLOR_WAVE;
ColorWave.flags = MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
ColorWave.speed_min = EVISION_V2_SPEED_SLOWEST;
ColorWave.speed_max = EVISION_V2_SPEED_FASTEST;
ColorWave.speed = EVISION_V2_SPEED_NORMAL;
ColorWave.colors_min = 1;
ColorWave.colors_max = 1;
ColorWave.color_mode = MODE_COLORS_RANDOM;
ColorWave.colors.resize(1);
ColorWave.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
ColorWave.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
ColorWave.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(ColorWave);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = EVISION_V2_MODE2_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Breathing.speed_min = EVISION_V2_SPEED_SLOWEST;
Breathing.speed_max = EVISION_V2_SPEED_FASTEST;
Breathing.speed = EVISION_V2_SPEED_NORMAL;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.color_mode = MODE_COLORS_RANDOM;
Breathing.colors.resize(1);
Breathing.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
Breathing.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
Breathing.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(Breathing);
mode Yoyo;
Yoyo.name = "Yoyo";
Yoyo.value = EVISION_V2_MODE2_YOYO;
Yoyo.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Yoyo.speed_min = EVISION_V2_SPEED_SLOWEST;
Yoyo.speed_max = EVISION_V2_SPEED_FASTEST;
Yoyo.speed = EVISION_V2_SPEED_NORMAL;
Yoyo.colors_min = 1;
Yoyo.colors_max = 1;
Yoyo.color_mode = MODE_COLORS_RANDOM;
Yoyo.colors.resize(1);
Yoyo.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
Yoyo.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
Yoyo.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(Yoyo);
mode Blink;
Blink.name = "Blink";
Blink.value = EVISION_V2_MODE2_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.speed_min = EVISION_V2_SPEED_SLOWEST;
Blink.speed_max = EVISION_V2_SPEED_FASTEST;
Blink.speed = EVISION_V2_SPEED_NORMAL;
Blink.colors_min = 1;
Blink.colors_max = 1;
Blink.color_mode = MODE_COLORS_RANDOM;
Blink.colors.resize(1);
Blink.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
Blink.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
Blink.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(Blink);
mode Static;
Static.name = "Static";
Static.value = EVISION_V2_MODE2_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
Static.colors_min = 1;
Static.colors_max = 1;
Static.color_mode = MODE_COLORS_RANDOM;
Static.colors.resize(1);
Static.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST;
Static.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST;
Static.brightness = EVISION_V2_BRIGHTNESS_HIGHEST;
modes.push_back(Static);
mode Off;
Off.name = "Off";
Off.value = EVISION_V2_MODE2_OFF;
Off.flags = MODE_FLAG_AUTOMATIC_SAVE;
modes.push_back(Off);
}
void RGBController_EVisionV2Keyboard::SetupZones()
{
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
zone KB_zone;
KB_zone.name = ZONE_EN_KEYBOARD;
KB_zone.type = ZONE_TYPE_MATRIX;
KB_zone.leds_count = 106;
KB_zone.leds_min = KB_zone.leds_count;
KB_zone.leds_max = KB_zone.leds_count;
KB_zone.matrix_map = new matrix_map_type;
KB_zone.matrix_map->height = EVISION_V2_MATRIX_HEIGHT;
KB_zone.matrix_map->width = EVISION_V2_MATRIX_WIDTH;
KB_zone.matrix_map->map = (unsigned int *)&matrix_map;
zones.push_back(KB_zone);
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
leds.clear();
colors.clear();
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
for(std::size_t zone_index = 0; zone_index < zones.size(); zone_index++)
{
for(unsigned int led_index = 0; led_index < zones[zone_index].leds_count; led_index++)
{
led new_led;
new_led.name = led_names[led_index];
new_led.value = led_index;
leds.push_back(new_led);
}
}
SetupColors();
}
void RGBController_EVisionV2Keyboard::LoadConfig()
{
EvisionV2ModeConfig config;
controller->GetMode(part, config);
int mode = config.mode;
if((part == EVISION_V2_KEYBOARD_PART_KEYBOARD) && (mode == EVISION_V2_MODE_CUSTOM))
{
mode |= config.ledmode << 8;
}
config.direction = (config.direction == 0) ? 0 : 1;
// Define default colors
for(std::size_t mode_index = 0; mode_index < modes.size(); mode_index++)
{
if(config.random_colours)
{
if(modes[mode_index].flags & MODE_FLAG_HAS_RANDOM_COLOR)
{
modes[mode_index].color_mode = MODE_COLORS_RANDOM;
}
if(modes[mode_index].colors.size() > 0)
{
modes[mode_index].colors[0] = 0xffffff;
}
}
else
{
if(modes[mode_index].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
{
modes[mode_index].color_mode = MODE_COLORS_MODE_SPECIFIC;
}
if(modes[mode_index].colors.size() > 0)
{
modes[mode_index].colors[0] = config.colour;
}
}
if(modes[mode_index].value == mode)
{
modes[mode_index].brightness = config.brightness;
modes[mode_index].speed = config.speed;
if(modes[mode_index].flags & MODE_FLAG_HAS_DIRECTION_LR)
{
modes[mode_index].direction = (1 - config.direction) + MODE_DIRECTION_LEFT;
}
else if(modes[mode_index].flags & MODE_FLAG_HAS_DIRECTION_UD)
{
modes[mode_index].direction = (1 - config.direction) + MODE_DIRECTION_UP;
}
else if(modes[mode_index].flags & MODE_FLAG_HAS_DIRECTION_HV)
{
modes[mode_index].direction = (1 - config.direction) + MODE_DIRECTION_HORIZONTAL;
}
if(part == EVISION_V2_KEYBOARD_PART_KEYBOARD)
{
if(mode == EVISION_V2_MODE_SURMOUNT)
{
switch(config.ledmode)
{
case EVISION_V2_SURMOUNT_MODE_COLOR_RED:
modes[mode_index].colors[0] = ToRGBColor(0xff, 0, 0);
break;
case EVISION_V2_SURMOUNT_MODE_COLOR_YELLOW:
modes[mode_index].colors[0] = ToRGBColor(0xff, 0xff, 0);
break;
case EVISION_V2_SURMOUNT_MODE_COLOR_GREEN:
modes[mode_index].colors[0] = ToRGBColor(0, 0xff, 0);
break;
case EVISION_V2_SURMOUNT_MODE_COLOR_CYAN:
modes[mode_index].colors[0] = ToRGBColor(0, 0xff, 0xff);
break;
default:
break;
}
}
else if(config.mode == EVISION_V2_MODE_CUSTOM)
{
controller->GetLedsCustom(config.ledmode, colors);
}
}
active_mode = mode_index;
}
}
}
void RGBController_EVisionV2Keyboard::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_EVisionV2Keyboard::DeviceUpdateLEDs()
{
if(part != EVISION_V2_KEYBOARD_PART_KEYBOARD)
{
return;
}
controller->SetLedsDirect(colors);
has_color_set = true;
last_update_time = std::chrono::steady_clock::now();
}
void RGBController_EVisionV2Keyboard::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_EVisionV2Keyboard::UpdateSingleLED(int led)
{
if(part != EVISION_V2_KEYBOARD_PART_KEYBOARD)
{
return;
}
controller->SetLedDirect(led, colors[led]);
has_color_set = true;
last_update_time = std::chrono::steady_clock::now();
}
void RGBController_EVisionV2Keyboard::SetCustomMode()
{
if(part == EVISION_V2_KEYBOARD_PART_KEYBOARD)
{
active_mode = EVISION_V2_MODE_DIRECT;
}
else
{
active_mode = EVISION_V2_MODE2_STATIC;
}
}
void RGBController_EVisionV2Keyboard::DeviceUpdateMode()
{
mode set_mode = modes[active_mode];
// No mode set packets required for Direct mode
if((part == EVISION_V2_KEYBOARD_PART_KEYBOARD) && (set_mode.value == EVISION_V2_MODE_DIRECT))
{
return;
}
EvisionV2ModeConfig config;
config.mode = set_mode.value & 0xff;
config.brightness = set_mode.brightness;
config.speed = set_mode.speed;
config.direction = 1 - (set_mode.direction & 0x1);
config.random_colours = (set_mode.color_mode == MODE_COLORS_RANDOM);
config.colour = 0;
if(modes[active_mode].colors.size() > 0)
{
config.colour = set_mode.colors[0];
}
config.ledmode = 0;
if(part == EVISION_V2_KEYBOARD_PART_KEYBOARD)
{
if(config.mode == EVISION_V2_MODE_SURMOUNT)
{
hsv_t temp;
rgb2hsv(config.colour, &temp);
if(temp.hue <= 30 || temp.hue > 300)
{
config.ledmode = EVISION_V2_SURMOUNT_MODE_COLOR_RED;
}
else if(temp.hue > 30 && temp.hue <= 90)
{
config.ledmode = EVISION_V2_SURMOUNT_MODE_COLOR_YELLOW;
}
else if(temp.hue > 90 && temp.hue <= 150)
{
config.ledmode = EVISION_V2_SURMOUNT_MODE_COLOR_GREEN;
}
else if(temp.hue > 150 && temp.hue <= 300)
{
config.ledmode = EVISION_V2_SURMOUNT_MODE_COLOR_CYAN;
}
}
else if(config.mode == EVISION_V2_MODE_CUSTOM)
{
config.ledmode = (set_mode.value >> 8) & 0xff;
}
}
controller->SetMode(part, config);
if((part == EVISION_V2_KEYBOARD_PART_KEYBOARD) && (config.mode == EVISION_V2_MODE_CUSTOM))
{
controller->GetLedsCustom(config.ledmode, colors);
SignalUpdate();
}
}
void RGBController_EVisionV2Keyboard::DeviceSaveMode()
{
if(part != EVISION_V2_KEYBOARD_PART_KEYBOARD)
{
return;
}
int value = modes[active_mode].value;
if((value & 0xff) == EVISION_V2_MODE_CUSTOM)
{
controller->SetLedsCustom((value >> 8) & 0xff, colors);
}
}
void RGBController_EVisionV2Keyboard::KeepaliveThread()
{
bool was_active = false;
while(keepalive_thread_run.load())
{
if(modes[active_mode].value == EVISION_V2_MODE_DIRECT && has_color_set)
{
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(200))
{
controller->RefreshLedDirect();
last_update_time = std::chrono::steady_clock::now();
was_active = true;
}
}
else if(was_active)
{
controller->EndLedsDirect();
was_active = false;
}
std::this_thread::sleep_for(100ms);
}
controller->EndLedsDirect();
}

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