Compare commits

...
Author SHA1 Message Date
Adam Honse 405ff7f6a5 OpenRGB version 0.6 2021-06-01 00:05:08 -05:00
Adam Honse 563ff31fe3 Wait up to 5 seconds for the local server connection to retrieve all controllers before continuing, so that CLI mode has all controllers available for applying changes 2021-05-31 23:44:33 -05:00
Chris 4a6c4f0e52 Adding test stages to Linux builds
* Build based on new OpenRGB docker image (Debian Stretch)
* Adapting AppImage build scripts to new docker image
* Changing postinstall script to avoid error

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

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

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

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

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

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

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

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

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

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

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

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

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

Commit amended to fix display issues on Windows and to group buttons in layout by Adam Honse <[email protected]>
2021-04-23 11:44:59 -05:00
Adam Honse be1fbc27ca Add device type string for virtual device 2021-04-22 16:24:48 -05:00
TheRogueZeta 95f40039eb Correct errant hyphen with underscore and update CI names 2021-04-22 19:44:17 +00:00
TheRogueZeta cd8e455b79 Update CI config to rename artifacts.zip with build info 2021-04-22 00:08:17 -05:00
morg 57db50f642 Fix VisualMap plugin URL in README 2021-04-22 00:11:22 +00:00
TheRogueZeta 9789ac0fde Remove 7z compression on Windows builds 2021-04-21 16:05:48 -07:00
morg c45f864977 Add virtual device type 2021-04-21 21:37:50 +02:00
Gareth Hancock 28af2da1c2 Added support for EVGA 2080Ti FTW3 Ultra 2021-04-21 15:44:44 +00:00
Cheerpipe b32ef76121 Creative Sound BlasterX G6 support
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-04-21 00:03:46 -05:00
edbgon a300e80f47 AMD Reference 6800 cards custom mode set to static 2021-04-21 04:15:32 +00:00
Boothin e098bb5c41 Added Rival 310 and compatible special editions to detector 2021-04-20 22:25:17 -04:00
Adam Honse f06b0ee952 Use NULL (shared) libusb context 2021-04-20 20:30:58 -05:00
Luca Lovisa 0da484bffc Add support for the Lian Li Uni Hub
Commits squashed and amended for code style by Adam Honse <[email protected]>
2021-04-20 20:30:57 -05:00
Adam Honse bea2ae2fdc Add OpenRGB Visual Map plugin link to README 2021-04-20 12:07:19 -05:00
morg 2a6b457324 Add UnregisterRGBController method to ResourceManager
Commit amended by Adam Honse <[email protected]>
2021-04-20 09:21:24 -05:00
TheRogueZeta 50adf9ab51 Correct SetCustomMode() to use virtual mode. 2021-04-18 21:42:54 +00:00
192 changed files with 12554 additions and 2700 deletions
+291 -33
View File
@@ -16,6 +16,7 @@
stages:
- build
- test
before_script:
- echo "started by ${GITLAB_USER_NAME}"
@@ -23,21 +24,22 @@ before_script:
#reusable templates
.ccache_init: &ccache_init
before_script:
- apt update
- apt install -y build-essential qtcreator qt5-default libusb-1.0-0-dev libhidapi-dev pkgconf wget git
- export QT_SELECT=qt5
- export APPIMAGE_EXTRACT_AND_RUN=1
#-----------------------------------------------------------------------#
# Linux (AppImage) 32-bit Build Target #
#-----------------------------------------------------------------------#
build_linux_32:
"Linux 32 AppImage":
<<: *ccache_init
image: i386/ubuntu:bionic
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:stretch-32
stage: build
script:
- export $(dpkg-architecture)
- ./scripts/build-appimage.sh
artifacts:
name: "${CI_PROJECT_NAME}_Linux_32_${CI_COMMIT_SHORT_SHA}"
paths:
- OpenRGB-i386.AppImage
- 60-openrgb.rules
@@ -47,15 +49,16 @@ build_linux_32:
#-----------------------------------------------------------------------#
# Linux (AppImage) 64-bit Build Target #
#-----------------------------------------------------------------------#
build_linux_64:
"Linux 64 AppImage":
<<: *ccache_init
image: ubuntu:bionic
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:stretch-64
stage: build
script:
- export $(dpkg-architecture)
- ./scripts/build-appimage.sh
artifacts:
name: "${CI_PROJECT_NAME}_Linux_64_${CI_COMMIT_SHORT_SHA}"
paths:
- OpenRGB-x86_64.AppImage
- 60-openrgb.rules
@@ -65,18 +68,18 @@ build_linux_64:
#-----------------------------------------------------------------------#
# Linux (.deb) 32-bit Build Target #
#-----------------------------------------------------------------------#
build_linux_deb32:
"Linux 32 deb":
<<: *ccache_init
image: i386/ubuntu:bionic
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:stretch-32
stage: build
script:
- apt install -y debhelper
- dpkg-architecture -l
- dpkg-buildpackage --target-arch i386 -us -B
- rm -v ../openrgb-dbgsym*.ddeb
- rm -v ../openrgb-dbgsym*.deb
- mv -v ../openrgb*.deb ./
artifacts:
name: "${CI_PROJECT_NAME}_Linux_32_deb_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.deb
exclude:
@@ -86,28 +89,287 @@ build_linux_deb32:
#-----------------------------------------------------------------------#
# Linux (.deb) 64-bit Build Target #
#-----------------------------------------------------------------------#
build_linux_deb64:
"Linux 64 deb":
<<: *ccache_init
image: ubuntu:bionic
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:stretch-64
stage: build
script:
- apt install -y debhelper
- dpkg-architecture -l
- dpkg-buildpackage -us -B
- rm -v ../openrgb-dbgsym*.ddeb
- rm -v ../openrgb-dbgsym*.deb
- mv -v ../openrgb*.deb ./
artifacts:
name: "${CI_PROJECT_NAME}_Linux_64_deb_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.deb
exclude:
- openrgb-dbgsym*.deb
expire_in: 30 days
#-----------------------------------------------------------------------#
# Linux (.rpm) 64-bit Build Target #
#-----------------------------------------------------------------------#
"Linux 64 rpm":
image: fedora:34
stage: build
script:
- dnf install rpmdevtools dnf-plugins-core -y
- rpmdev-setuptree
- ls /root/
- cp fedora/OpenRGB.spec /root/rpmbuild/SPECS
- cp ../OpenRGB /root/rpmbuild/SOURCES/ -r
- cd /root/rpmbuild/SOURCES
- tar -cf OpenRGB.tar.gz OpenRGB/
- cd ..
- dnf builddep SPECS/OpenRGB.spec -y
- rpmbuild -ba SPECS/OpenRGB.spec
- cd RPMS/x86_64/
- mv openrgb*.rpm ${CI_PROJECT_DIR}/
- cd ${CI_PROJECT_DIR}
artifacts:
name: "${CI_PROJECT_NAME}_Linux_64_rpm_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.rpm
expire_in: 30 days
#-----------------------------------------------------------------------#
# Linux (.deb) Debian Bullseye 32-bit Build Target #
#-----------------------------------------------------------------------#
"Linux 32 deb Bullseye":
<<: *ccache_init
image: i386/debian:bullseye
stage: build
script:
- apt update
- apt install -y build-essential qtcreator qtbase5-dev libusb-1.0-0-dev libhidapi-dev pkgconf wget git file debhelper
- dpkg-architecture -l
- dpkg-buildpackage --target-arch i386 -us -B
- rm -v ../openrgb-dbgsym*.deb
- mv -v ../openrgb*.deb ./
artifacts:
name: "${CI_PROJECT_NAME}_Linux_32_deb_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.deb
exclude:
- openrgb-dbgsym*.deb
expire_in: 30 days
#-----------------------------------------------------------------------#
# Linux (.deb) Debian Bullseye 64-bit Build Target #
#-----------------------------------------------------------------------#
"Linux 64 deb Bullseye":
<<: *ccache_init
image: debian:bullseye
stage: build
script:
- apt update
- apt install -y build-essential qtcreator qtbase5-dev libusb-1.0-0-dev libhidapi-dev pkgconf wget git file debhelper
- dpkg-architecture -l
- dpkg-buildpackage -us -B
- rm -v ../openrgb-dbgsym*.deb
- mv -v ../openrgb*.deb ./
artifacts:
name: "${CI_PROJECT_NAME}_Linux_64_deb_${CI_COMMIT_SHORT_SHA}"
paths:
- openrgb*.deb
exclude:
- openrgb-dbgsym*.deb
expire_in: 30 days
#-----------------------------------------------------------------------#
# Debian 32 Buster test #
#-----------------------------------------------------------------------#
"Debian 32 Buster":
image: i386/debian:buster
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 32 deb"
needs:
- "Linux 32 deb"
#-----------------------------------------------------------------------#
# Debian 32 Bullseye test #
#-----------------------------------------------------------------------#
"Debian 32 Bullseye":
image: i386/debian:bullseye
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 32 deb"
needs:
- "Linux 32 deb"
#-----------------------------------------------------------------------#
# Ubuntu 32 18.04LTS test #
#-----------------------------------------------------------------------#
"Ubuntu 32 18.04LTS":
image: i386/ubuntu:bionic
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 32 deb"
needs:
- "Linux 32 deb"
#-----------------------------------------------------------------------#
# Mint 32 19.3 test #
#-----------------------------------------------------------------------#
"Mint 32 20.1":
image: linuxmintd/mint19.3-i386
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*i386.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 32 deb"
needs:
- "Linux 32 deb"
#-----------------------------------------------------------------------#
# Debian 64 Buster test #
#-----------------------------------------------------------------------#
"Debian 64 Buster":
image: debian:buster
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Debian 64 Bullseye test #
#-----------------------------------------------------------------------#
"Debian 64 Bullseye":
image: debian:bullseye
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Fedora 64 v34 test #
#-----------------------------------------------------------------------#
"Fedora 64 v34":
image: fedora:34
stage: test
script:
- yum -y localinstall ./openrgb*64.rpm
- openrgb --version
- openrgb -l
- yum -y remove openrgb
dependencies:
- "Linux 64 rpm"
needs:
- "Linux 64 rpm"
#-----------------------------------------------------------------------#
# Ubuntu 64 18.04LTS test #
#-----------------------------------------------------------------------#
"Ubuntu 64 18.04LTS":
image: ubuntu:bionic
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Ubuntu 64 20.04LTS test #
#-----------------------------------------------------------------------#
"Ubuntu 64 20.04LTS":
image: ubuntu:focal
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Ubuntu 64 20.10 test #
#-----------------------------------------------------------------------#
"Ubuntu 64 20.10":
image: ubuntu:groovy
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Mint 64 20.1 test #
#-----------------------------------------------------------------------#
"Mint 64 20.1":
image: linuxmintd/mint20.1-amd64
stage: test
script:
- apt update
- DEBIAN_FRONTEND=noninteractive apt install -yq --no-install-recommends ./openrgb*amd64.deb
- openrgb --version
- openrgb -l
- apt remove -y openrgb
dependencies:
- "Linux 64 deb"
needs:
- "Linux 64 deb"
#-----------------------------------------------------------------------#
# Windows (32-bit) Build Target #
#-----------------------------------------------------------------------#
build_windows_32:
"Windows 32":
extends:
- .shared_windows_runners
stage: build
@@ -160,26 +422,23 @@ build_windows_32:
- ..\_qt\5.15.0\msvc2019\bin\windeployqt --no-angle --no-translations --no-opengl-sw --no-system-d3d-compiler --no-compiler-runtime --no-webkit2 .\release\
- _fold_final_
- _fold_start_ 'compressing the release folder so that we can upload it as artifact'
- mv release 'OpenRGB Windows 32-bit'
- ${datetime} = Get-Date ([datetime]::UtcNow) -Format "yyyy-MM-ddTHH-mm-ss"
- ${revision} = ((git rev-parse --short HEAD) | Out-String).Trim()
- ${rversion} = (((Get-Content '..\OpenRGB.pro' | Select-String -Pattern "VERSION =") | Out-String).Trim().Split("="))[1].Trim()
- 7z a -mx9 -r -y "OpenRGB_${rversion}_32_${revision}_nightly_${datetime}.7z" 'OpenRGB Windows 32-bit'
- _fold_start_ 'Moving results for upload'
- mv release ../'OpenRGB Windows 32-bit'
- _fold_final_
# cache:
# key: same-key
# paths:
# - C:\vcpkg\installed\
artifacts:
name: "${CI_PROJECT_NAME}_Windows_32_${CI_COMMIT_SHORT_SHA}"
paths:
- _build/*.7z
- 'OpenRGB Windows 32-bit'
expire_in: 30 days
#-----------------------------------------------------------------------#
# Windows (64-bit) Build Target #
#-----------------------------------------------------------------------#
build_windows_64:
"Windows 64":
extends:
- .shared_windows_runners
stage: build
@@ -232,26 +491,23 @@ build_windows_64:
- ..\_qt\5.15.0\msvc2019_64\bin\windeployqt --no-angle --no-translations --no-opengl-sw --no-system-d3d-compiler --no-compiler-runtime --no-webkit2 .\release\
- _fold_final_
- _fold_start_ 'compressing the release folder so that we can upload it as artifact'
- mv release 'OpenRGB Windows 64-bit'
- ${datetime} = Get-Date ([datetime]::UtcNow) -Format "yyyy-MM-ddTHH-mm-ss"
- ${revision} = ((git rev-parse --short HEAD) | Out-String).Trim()
- ${rversion} = (((Get-Content '..\OpenRGB.pro' | Select-String -Pattern "VERSION =") | Out-String).Trim().Split("="))[1].Trim()
- 7z a -mx9 -r -y "OpenRGB_${rversion}_64_${revision}_nightly_${datetime}.7z" 'OpenRGB Windows 64-bit'
- _fold_start_ 'Moving results for upload'
- mv release ../'OpenRGB Windows 64-bit'
- _fold_final_
# cache:
# key: same-key
# paths:
# - C:\vcpkg\installed\
artifacts:
name: "${CI_PROJECT_NAME}_Windows_64_${CI_COMMIT_SHORT_SHA}"
paths:
- _build/*.7z
- 'OpenRGB Windows 64-bit'
expire_in: 30 days
#-----------------------------------------------------------------------#
# MacOS Build Target #
#-----------------------------------------------------------------------#
build_macos_arm64:
"MacOS ARM64":
tags:
- macos
stage: build
@@ -262,6 +518,7 @@ build_macos_arm64:
- macdeployqt OpenRGB.app -codesign=OpenRGB
artifacts:
name: "${CI_PROJECT_NAME}_MacOS_ARM64_${CI_COMMIT_SHORT_SHA}"
paths:
- OpenRGB.app
expire_in: 30 days
@@ -272,7 +529,7 @@ build_macos_arm64:
- if: '$BUILD_MACOS =~ /.+/'
when: on_success
build_macos_intel:
"MacOS Intel":
tags:
- macos
stage: build
@@ -283,6 +540,7 @@ build_macos_intel:
- arch -x86_64 macdeployqt OpenRGB.app -codesign=OpenRGB
artifacts:
name: "${CI_PROJECT_NAME}_MacOS_Intel_${CI_COMMIT_SHORT_SHA}"
paths:
- OpenRGB.app
expire_in: 30 days
@@ -291,4 +549,4 @@ build_macos_intel:
- if: '$CI_PROJECT_PATH == "CalcProgrammer1/OpenRGB"'
when: on_success
- if: '$BUILD_MACOS =~ /.+/'
when: on_success
when: on_success
+376 -5
View File
@@ -53,6 +53,18 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1872", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1889", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18a3", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18f3", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18a5", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1939", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18af", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18dd", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1845", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1875", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1877", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18cd", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18cf", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18e5", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="18e3", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1958", TAG+="uaccess"
#---------------------------------------------------------------#
# ASUS TUF Laptops (faustus) #
@@ -70,8 +82,29 @@ ACTION=="add", SUBSYSTEM=="platform", KERNEL=="faustus", RUN+="/bin/chmod a+w /s
# #
# Mousemats: #
# Cooler Master MP750 #
# Controllers: #
# ARGB Device #
# Small ARGB Device #
# Graphics Cards: #
# Radeon RX6000 Series Reference Cards #
# Keyboards: #
# Masterkeys Pro L #
# Masterkeys Pro L White #
# Masterkeys Pro S #
# Masterkeys MK750 #
# Masterkeys SK630 #
# Masterkeys SK650 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0109", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0105", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="1011", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="1000", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="014d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0047", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="003c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0067", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0089", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="008d", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Hydro Series Devices #
@@ -84,6 +117,23 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c15", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c13", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c12", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Hydro Platinum Series Devices #
# #
# Corsair H100i Platinum RGB #
# Corsair H100i Platinum SE RGB #
# Corsair H115i Platinum RGB #
# Corsair H100i Pro XT RGB #
# Corsair H115i Pro XT RGB #
# Corsair H150i Pro XT RGB #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c18", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c19", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c17", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c20", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c21", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c22", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Lighting Node Devices #
# #
@@ -101,7 +151,7 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c10", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c1e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1d00", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1d04", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0a32", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c23", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Peripheral Devices #
@@ -126,6 +176,12 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0a32", TAG+="uacces
# Mice: #
# Corsair M65 Pro #
# Corsair M65 RGB Elite #
# Corsair Glaive RGB #
# Corsair Glaive RGB Pro #
# Corsair Harpoon RGB #
# Corsair Harpoon RGB Pro #
# Corsair Scimitar Pro RGB #
# Corsair Sabre RGB #
# #
# Mousemats: #
# Corsair MM800 RGB Polaris #
@@ -149,29 +205,103 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2d", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b20", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b48", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b34", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b74", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b75", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b5a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3b", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0a34", TAG+="uaccess"
#---------------------------------------------------------------#
# Corsair Wireless Devices #
# #
# Keyboards: #
# Corsair K57 RGB Wired #
# Corsair K57 RGB Wireless #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b6e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b62", TAG+="uaccess"
#---------------------------------------------------------------#
# Creative Devices #
# #
# Devices: #
# Creative SoundblasterX G6 #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="041e", ATTR{idProduct}=="3256", TAG+="uaccess"
#---------------------------------------------------------------#
# Ducky Keyboard Devices #
# #
# Keyboards: #
# Ducky Shine 7 One 2 RGB #
# Ducky One 2 RGB TKL #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="0348", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="0356", TAG+="uaccess"
#---------------------------------------------------------------#
# EK Controller Devices #
# #
# Controllers: #
# EK Loop Connect #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="5750", TAG+="uaccess"
#---------------------------------------------------------------#
# Holtek Devices #
# #
# Mice: #
# Holtek A070 #
# Mousemats: #
# Holtek A1FA #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="a070", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="a1fa", TAG+="uaccess"
#---------------------------------------------------------------#
# HyperX Peripheral Devices #
# #
# Keyboards: #
# HyperX Alloy Elite #
# HyperX Alloy Elite 2 #
# HyperX Alloy FPS RGB #
# HyperX Alloy Origins #
# HyperX Alloy Origins Core #
# #
# Mice: #
# HyperX Pulsefire Surge #
# HyperX Pulsefire FPS Pro #
# HyperX Pulsefire Dart Wireless #
# HyperX Pulsefire Dart Wired #
# #
# Mousemats: #
# HyperX Fury Ultra #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16be", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="1711", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16dc", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16e5", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16e6", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16d3", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16d7", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16e1", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16e2", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="1705", TAG+="uaccess"
#---------------------------------------------------------------#
# Lian Li Uni Hub #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="0cf2", ATTR{idProduct}=="7750", TAG+="uaccess"
#---------------------------------------------------------------#
# Logitech Peripheral Devices #
# #
@@ -179,53 +309,87 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="1705", TAG+="uacces
# Logitech G213 #
# Logitech G512 #
# Logitech G512 RGB #
# Logitech G610 #
# Logitech G610 #1 #
# Logitech G610 #2 #
# Logitech G810 #1 #
# Logitech G810 #2 #
# Logitech G813 #
# Logitech G815 #
# #
# Mice: #
# Logitech G203 Prodigy #
# Logitech G203 Lightsync #
# Logitech G303 #
# Logitech G403 Prodigy #
# Logitech G403 Hero #
# Logitech G502 Proteus Spectrum #
# Logitech G502 Hero #
# Logitech G502 Wireless #
# Logitech G703 Wireless #
# Logitech G900 Wireless #
# Logitech G903 Wireless #
# Logitech G Lightspeed Wireless Gaming Mouse #
# Logitech G Pro Wireless Gaming Mouse (Wired) #
# Logitech G Pro Hero Gaming Mouse (Wired) #
# #
# Mousemats: #
# Logitech G Powerplay Mousepad with Lightspeed #
# #
# Speakers: #
# Logitech G560 #
# #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c336", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c342", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c33c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c333", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c338", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c331", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c337", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c232", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c33f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c084", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c092", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c083", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c082", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="405d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c332", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08b", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08d", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="407f", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c087", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="4070", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c081", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="4053", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c086", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="4067", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c539", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c085", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c088", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="4079", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c53a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="0a78", TAG+="uaccess"
#---------------------------------------------------------------#
# Metadot Das Keyboard 4Q + 5Q #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="24f0", ATTR{idProduct}=="2037", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="24f0", ATTR{idProduct}=="202b", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="24f0", ATTR{idProduct}=="2020", TAG+="uaccess"
#---------------------------------------------------------------#
# MSI Mysticlight #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="3EA4", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="4559", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="4459", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B10", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B12", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B17", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B85", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B93", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B94", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7B96", TAG+="uaccess"
@@ -263,6 +427,7 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C95", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C96", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C98", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C99", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7D09", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="905D", TAG+="uaccess"
#---------------------------------------------------------------#
@@ -279,15 +444,163 @@ KERNEL=="ttyACM[0-9]*", ATTR{idVendor}=="04D8", ATTR{idProduct}=="00DF", TAG+="u
# NZXT Hue 2 Devices #
# #
# NZXT Hue 2 #
# NZXT Hue 2 Ambient #
# NZXT Motherboard #
# NZXT Smart Device V2 #
# NZXT Kraken X3 #
# NZXT RGB Fan Controller #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2001", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2002", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2005", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2006", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2007", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2009", TAG+="uaccess"
#---------------------------------------------------------------#
# NZXT Kraken #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="170e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="1715", TAG+="uaccess"
#---------------------------------------------------------------#
# Razer Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0241", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0203", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0209", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0221", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0228", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0237", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0235", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0211", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0216", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="021A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="020F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0224", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0233", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="023B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0240", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="023A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0246", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0245", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="024D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0253", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0255", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="026F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0210", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0225", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="022F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0234", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="024C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0205", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0220", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="022D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0232", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0239", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="024A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0252", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0259", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="022A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="023F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="025E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0204", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0226", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0227", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0243", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0207", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="021E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="025D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0208", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="022B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0020", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="005E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0042", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="005B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0062", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0064", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0065", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0083", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0038", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="004F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0037", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0016", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0054", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0043", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="005C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0071", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="008C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0084", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="007C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="007D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="004C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="002F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0060", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0059", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="005A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0070", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0024", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0025", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0044", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0045", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0073", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0072", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="006C", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0046", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="002E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0040", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0053", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="003F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="003E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0041", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0036", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0050", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0067", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0013", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0039", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0048", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0032", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0034", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="008A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0078", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="007A", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="007B", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0506", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0501", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F19", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0504", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0527", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0510", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F03", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F08", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F20", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F26", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F1F", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F09", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F07", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F0E", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0215", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0068", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0C00", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0C04", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0C02", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0C01", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0F1D", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0517", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1532", ATTR{idProduct}=="0518", TAG+="uaccess"
#---------------------------------------------------------------#
# Roccat Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e7d", ATTR{idProduct}=="2e2c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e7d", ATTR{idProduct}=="2e27", TAG+="uaccess"
#---------------------------------------------------------------#
# Redragon Peripheral Devices #
@@ -327,6 +640,13 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="258a", ATTR{idProduct}=="0036", TAG+="uacces
SUBSYSTEMS=="usb", ATTR{idVendor}=="258a", ATTR{idProduct}=="0033", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="258a", ATTR{idProduct}=="0029", TAG+="uaccess"
#---------------------------------------------------------------#
# Sony Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="054c", ATTR{idProduct}=="05c4", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="054c", ATTR{idProduct}=="09cc", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="054c", ATTR{idProduct}=="0ba0", TAG+="uaccess"
#---------------------------------------------------------------#
# SteelSeries Peripheral Devices #
# #
@@ -342,22 +662,62 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="258a", ATTR{idProduct}=="0029", TAG+="uacces
# SteelSeries Rival 300 CS:GO Hyperbeast Edition #
# SteelSeries Rival 300 Dota 2 Edition #
# SteelSeries Rival 300 HP Omen Edition #
# SteelSeries Rival 300 Blackops Edition #
# SteelSeries Rival 310 #
# SteelSeries Rival 310 CS:GO Howl Edition #
# SteelSeries Rival 310 PubG Edition #
# SteelSeries Rival Sensei Ten #
# SteelSeries Rival Sensei Ten CS:GO Neon Rider #
# SteelSeries Rival Sensei 310 #
# Headsets: #
# SteelSeries Siberia 350 #
# Keyboards: #
# SteelSeries Apex 5 #
# SteelSeries Apex 7 #
# SteelSeries Apex 7 TKL #
# SteelSeries Apex Pro #
# SteelSeries Apex Pro TKL #
# SteelSeries Apex M750 #
# SteelSeries Apex OG #
# SteelSeries Apex 350 #
# Mousemats: #
# SteelSeries QCK Prism Cloth #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1702", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="170c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1814", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1729", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1384", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1710", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1714", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1394", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1716", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="171a", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1392", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1718", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1720", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="171e", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1736", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1832", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1834", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1722", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1229", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="161c", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1612", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1618", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1610", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1614", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="0616", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1202", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="1206", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="1038", ATTR{idProduct}=="150d", TAG+="uaccess"
#---------------------------------------------------------------#
# Tecknet Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc05", TAG+="uaccess"
#---------------------------------------------------------------#
# Thermaltake Poseidon Z RGB Keyboard #
@@ -371,3 +731,14 @@ SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="1FA[5-9]", TAG+="ua
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="1FA[A-F]", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="1FB[0-5]", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="226[0-3]", TAG+="uaccess"
#---------------------------------------------------------------#
# Wooting Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="03eb", ATTR{idProduct}=="ff01", TAG+="uaccess"
SUBSYSTEMS=="usb", ATTR{idVendor}=="03eb", ATTR{idProduct}=="ff02", TAG+="uaccess"
#---------------------------------------------------------------#
# Zalman ZSync Devices #
#---------------------------------------------------------------#
SUBSYSTEMS=="usb", ATTR{idVendor}=="1c57", ATTR{idProduct}=="7ed0", TAG+="uaccess"
@@ -179,7 +179,8 @@ void PolychromeUSBController::WriteRGSwap
void PolychromeUSBController::WriteHeader
(
unsigned char cfg,
unsigned char configstring[]
unsigned char* configstring,
unsigned int configsize
)
{
unsigned char usb_buf[65];
@@ -194,7 +195,7 @@ void PolychromeUSBController::WriteHeader
\*-----------------------------------------------------*/
usb_buf[0x01] = POLYCHROME_USB_WRITE_HEADER;
usb_buf[0x03] = cfg;
memcpy(&usb_buf[4], configstring, sizeof(configstring));
memcpy(&usb_buf[4], configstring, configsize);
/*-----------------------------------------------------*\
| Send packet |
@@ -207,7 +208,7 @@ PolychromeZoneInfo PolychromeUSBController::GetZoneConfig(unsigned char zone)
{
unsigned char usb_buf[65];
PolychromeZoneInfo zoneinfo;
unsigned char all;
//unsigned char all;
unsigned char r;
unsigned char g;
unsigned char b;
@@ -242,7 +243,7 @@ PolychromeZoneInfo PolychromeUSBController::GetZoneConfig(unsigned char zone)
zoneinfo.color = ToRGBColor(r,g,b);
zoneinfo.speed = usb_buf[0x08];
zoneinfo.zone = usb_buf[0x03];
all = usb_buf[0x10];
//all = usb_buf[0x10];
return(zoneinfo);
}
@@ -128,8 +128,9 @@ public:
void WriteHeader
(
unsigned char cfg,
unsigned char configstring []
unsigned char cfg,
unsigned char* configstring,
unsigned int configsize
);
protected:
@@ -20,7 +20,7 @@
#define ASROCK_MOTHERBOARD_1_PID 0x01A2
#define ASROCK_DESKMINI_ADDRESSABLE_LED_STRIP_PID 0x01A6
void DetectPolychromeUSBControllers(hid_device_info* info, const std::string& name)
void DetectPolychromeUSBControllers(hid_device_info* info, const std::string& /*name*/)
{
hid_device* dev = hid_open_path(info->path);
@@ -33,4 +33,4 @@ void DetectPolychromeUSBControllers(hid_device_info* info, const std::string& na
}
REGISTER_HID_DETECTOR("ASRock Polychrome USB", DetectPolychromeUSBControllers, ASROCK_VID, ASROCK_MOTHERBOARD_1_PID);
REGISTER_HID_DETECTOR("ASRock Deskmini Addressable LED Strip", DetectPolychromeUSBControllers, ASROCK_VID, ASROCK_DESKMINI_ADDRESSABLE_LED_STRIP_PID);
REGISTER_HID_DETECTOR("ASRock Deskmini Addressable LED Strip", DetectPolychromeUSBControllers, ASROCK_VID, ASROCK_DESKMINI_ADDRESSABLE_LED_STRIP_PID);
@@ -171,16 +171,6 @@ RGBController_PolychromeUSB::RGBController_PolychromeUSB(PolychromeUSBController
void RGBController_PolychromeUSB::SetupZones()
{
/*-------------------------------------------------*\
| Only set LED count on the first run |
\*-------------------------------------------------*/
bool first_run = false;
if(zones.size() == 0)
{
first_run = true;
}
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
@@ -191,7 +181,6 @@ void RGBController_PolychromeUSB::SetupZones()
/*-------------------------------------------------*\
| Set zones and leds |
\*-------------------------------------------------*/
int addressableCounter = 1;
for(unsigned int channel_idx = 0; channel_idx < zones.size(); channel_idx++)
{
PolychromeDeviceInfo device_info = polychrome->GetPolychromeDevices()[channel_idx];
@@ -269,8 +258,8 @@ void RGBController_PolychromeUSB::ResizeZone(int zone, int new_size)
zonecfg[i]=zones[i].leds_count;
}
unsigned char zonecmd = POLYCHROME_USB_LEDCOUNT_CFG;
// WriteHeader(zonecmd, zonecfg);
// unsigned char zonecmd = POLYCHROME_USB_LEDCOUNT_CFG;
// WriteHeader(zonecmd, zonecfg, sizeof(zonecfg));
}
void RGBController_PolychromeUSB::DeviceUpdateLEDs()
@@ -316,7 +305,6 @@ void RGBController_PolychromeUSB::UpdateSingleLED(int led)
unsigned char RGBController_PolychromeUSB::GetDeviceMode(unsigned char zone)
{
int dev_mode;
int color_mode = MODE_COLORS_PER_LED;
dev_mode = polychrome->GetZoneConfig(zone).mode;
active_mode = dev_mode;
@@ -32,14 +32,20 @@ typedef struct
static const gpu_pci_device device_list[] =
{
{ NVIDIA_VEN, NVIDIA_GTX1060_DEV, ASUS_SUB_VEN, ASUS_GTX1060_STRIX, 0x29, "ASUS GTX 1060 Strix" },
{ NVIDIA_VEN, NVIDIA_GTX1660TI_DEV, ASUS_SUB_VEN, ASUS_ROG_GTX1660TI_OC, 0x2A, "ASUS ROG GTX 1660 Ti OC 6G" },
{ NVIDIA_VEN, NVIDIA_GTX1080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080_A8G_GAMING, 0x29, "ASUS ROG Strix GTX1080 A8G Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1080TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080TI_GAMING, 0x29, "ASUS ROG Strix GTX1080 Ti Gaming" },
{ AMD_GPU_VEN, AMD_VEGA10_DEV, ASUS_SUB_VEN, ASUS_VEGA64_STRIX, 0x29, "ASUS Vega 64 Strix" },
{ AMD_GPU_VEN, AMD_NAVI10_DEV, ASUS_SUB_VEN, ASUS_RX5700XT_STRIX_GAMING_OC, 0x2A, "ASUS RX 5700XT Strix Gaming OC" },
{ AMD_GPU_VEN, AMD_POLARIS_DEV, ASUS_SUB_VEN, ASUS_RX580_STRIX_GAMING_OC, 0x29, "ASUS RX 580 Strix Gaming OC" }
};
{ NVIDIA_VEN, NVIDIA_GTX1060_DEV, ASUS_SUB_VEN, ASUS_GTX1060_STRIX, 0x29, "ASUS GTX 1060 Strix" },
{ NVIDIA_VEN, NVIDIA_GTX1070_DEV, ASUS_SUB_VEN, ASUS_GTX1070_STRIX, 0x29, "ASUS GTX 1070 Strix OC" },
{ NVIDIA_VEN, NVIDIA_GTX1080_DEV, ASUS_SUB_VEN, ASUS_GTX1080_STRIX, 0x29, "ASUS GTX 1080 Strix OC" },
{ NVIDIA_VEN, NVIDIA_GTX1080_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080_A8G_GAMING, 0x29, "ASUS ROG Strix GTX1080 A8G Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1080TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_GTX1080TI_GAMING, 0x29, "ASUS ROG Strix GTX1080 Ti Gaming" },
{ NVIDIA_VEN, NVIDIA_GTX1660TI_DEV, ASUS_SUB_VEN, ASUS_ROG_GTX1660TI_OC, 0x2A, "ASUS ROG GTX 1660 Ti OC 6G" },
{ NVIDIA_VEN, NVIDIA_RTX2060_TU106_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2060_EVO_GAMING, 0x2A, "ASUS ROG STRIX RTX 2060 EVO Gaming 6G" },
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2070S_A8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2070S A8G Gaming 8G" },
{ NVIDIA_VEN, NVIDIA_RTX2080_A_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2080_O8G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2080 O8G Gaming" },
{ NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX2080TI_O11G_GAMING, 0x2A, "ASUS ROG STRIX RTX 2080 Ti O11G Gaming" },
{ AMD_GPU_VEN, AMD_VEGA10_DEV, ASUS_SUB_VEN, ASUS_VEGA64_STRIX, 0x29, "ASUS Vega 64 Strix" },
{ AMD_GPU_VEN, AMD_NAVI10_DEV, ASUS_SUB_VEN, ASUS_RX5700XT_STRIX_GAMING_OC, 0x2A, "ASUS RX 5700XT Strix Gaming OC" },
{ AMD_GPU_VEN, AMD_POLARIS_DEV, ASUS_SUB_VEN, ASUS_RX580_STRIX_GAMING_OC, 0x29, "ASUS RX 580 Strix Gaming OC" }
};
/******************************************************************************************\
* *
@@ -194,38 +194,38 @@ unsigned char AuraSMBusController::GetLEDBlue(unsigned int led)
return(AuraRegisterRead(direct_reg + ( 3 * led ) + 1));
}
void AuraSMBusController::SetAllColorsDirect(unsigned char red, unsigned char green, unsigned char blue)
void AuraSMBusController::SetAllColorsDirect(RGBColor* colors)
{
unsigned char* colors = new unsigned char[led_count * 3];
unsigned char* color_buf = new unsigned char[led_count * 3];
for (unsigned int i = 0; i < (led_count * 3); i += 3)
{
colors[i + 0] = red;
colors[i + 1] = blue;
colors[i + 2] = green;
color_buf[i + 0] = RGBGetRValue(colors[i / 3]);
color_buf[i + 1] = RGBGetBValue(colors[i / 3]);
color_buf[i + 2] = RGBGetGValue(colors[i / 3]);
}
AuraRegisterWriteBlock(direct_reg, colors, led_count * 3);
AuraRegisterWriteBlock(direct_reg, color_buf, led_count * 3);
delete colors;
delete color_buf;
}
void AuraSMBusController::SetAllColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
void AuraSMBusController::SetAllColorsEffect(RGBColor* colors)
{
unsigned char* colors = new unsigned char[led_count * 3];
unsigned char* color_buf = new unsigned char[led_count * 3];
for (unsigned int i = 0; i < (led_count * 3); i += 3)
{
colors[i + 0] = red;
colors[i + 1] = blue;
colors[i + 2] = green;
color_buf[i + 0] = RGBGetRValue(colors[i / 3]);
color_buf[i + 1] = RGBGetBValue(colors[i / 3]);
color_buf[i + 2] = RGBGetGValue(colors[i / 3]);
}
AuraRegisterWriteBlock(effect_reg, colors, led_count * 3);
AuraRegisterWriteBlock(effect_reg, color_buf, led_count * 3);
AuraRegisterWrite(AURA_REG_APPLY, AURA_APPLY_VAL);
delete[] colors;
delete[] color_buf;
}
void AuraSMBusController::SetDirect(unsigned char direct)
@@ -7,6 +7,8 @@
| Adam Honse (CalcProgrammer1) 8/19/2018 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include "i2c_smbus.h"
@@ -87,8 +89,8 @@ public:
unsigned char GetLEDRed(unsigned int led);
unsigned char GetLEDGreen(unsigned int led);
unsigned char GetLEDBlue(unsigned int led);
void SetAllColorsDirect(unsigned char red, unsigned char green, unsigned char blue);
void SetAllColorsEffect(unsigned char red, unsigned char green, unsigned char blue);
void SetAllColorsDirect(RGBColor* colors);
void SetAllColorsEffect(RGBColor* colors);
void SetDirect(unsigned char direct);
void SetLEDColorDirect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
void SetLEDColorEffect(unsigned int led, unsigned char red, unsigned char green, unsigned char blue);
@@ -1,5 +1,6 @@
#include "Detector.h"
#include "AsusAuraSMBusController.h"
#include "LogManager.h"
#include "RGBController.h"
#include "RGBController_AsusAuraSMBus.h"
#include "i2c_smbus.h"
@@ -7,6 +8,7 @@
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include "dependencies/dmiinfo.h"
using namespace std::chrono_literals;
@@ -87,21 +89,32 @@ bool TestForAsusAuraSMBusController(i2c_smbus_interface* bus, unsigned char addr
{
bool pass = false;
LOG_DEBUG("Testing address %02X for Aura SMBus controller", address);
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
if (res >= 0)
{
pass = true;
LOG_DEBUG("Detected an I2C device at address %02X, testing register range for Aura SMBus", address);
for (int i = 0xA0; i < 0xB0; i++)
{
res = bus->i2c_smbus_read_byte_data(address, i);
if (res != (i - 0xA0))
{
LOG_DEBUG("Detection failed testing register %02X. Expected %02X, got %02X.", i, (i - 0xA0), res);
pass = false;
}
}
if(pass)
{
LOG_DEBUG("Detection successful, address %02X appears to be an Aura SMBus controller", address);
}
}
return(pass);
@@ -122,24 +135,24 @@ bool TestForAsusAuraSMBusController(i2c_smbus_interface* bus, unsigned char addr
* *
\******************************************************************************************/
void DetectAsusAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses)
void DetectAsusAuraSMBusDRAMControllers(std::vector<i2c_smbus_interface*> &busses)
{
AuraSMBusController* new_aura;
RGBController_AuraSMBus* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
int address_list_idx = -1;
IF_DRAM_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
{
// Remap Aura-enabled RAM modules on 0x77
LOG_DEBUG("Remapping Aura SMBus RAM modules on 0x77");
for (unsigned int slot = 0; slot < 8; slot++)
{
int res = busses[bus]->i2c_smbus_write_quick(0x77, I2C_SMBUS_WRITE);
if (res < 0)
{
LOG_DEBUG("No device detected at address 0x77, aborting remap");
break;
}
@@ -149,6 +162,8 @@ void DetectAsusAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses)
if(address_list_idx < AURA_RAM_ADDRESS_COUNT)
{
LOG_DEBUG("Testing address %02X to see if there is a device there", aura_ram_addresses[address_list_idx]);
res = busses[bus]->i2c_smbus_write_quick(aura_ram_addresses[address_list_idx], I2C_SMBUS_WRITE);
}
else
@@ -159,6 +174,8 @@ void DetectAsusAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses)
if(address_list_idx < AURA_RAM_ADDRESS_COUNT)
{
LOG_DEBUG("Remapping slot %d to address %02X", slot, aura_ram_addresses[address_list_idx]);
AsusAuraRegisterWrite(busses[bus], 0x77, AURA_REG_SLOT_INDEX, slot);
AsusAuraRegisterWrite(busses[bus], 0x77, AURA_REG_I2C_ADDRESS, (aura_ram_addresses[address_list_idx] << 1));
}
@@ -169,14 +186,25 @@ void DetectAsusAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses)
{
if (TestForAsusAuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]))
{
new_aura = new AuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]);
new_controller = new RGBController_AuraSMBus(new_aura);
ResourceManager::get()->RegisterRGBController(new_controller);
AuraSMBusController* controller = new AuraSMBusController(busses[bus], aura_ram_addresses[address_list_idx]);
RGBController_AuraSMBus* rgb_controller = new RGBController_AuraSMBus(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
std::this_thread::sleep_for(1ms);
}
}
}
} /* DetectAuraSMBusDRAMControllers() */
void DetectAsusAuraSMBusMotherboardControllers(std::vector<i2c_smbus_interface*> &busses)
{
AuraSMBusController* new_aura;
RGBController_AuraSMBus* new_controller;
for (unsigned int bus = 0; bus < busses.size(); bus++)
{
int address_list_idx = -1;
// Add Aura-enabled motherboard controllers
IF_MOBO_SMBUS(busses[bus]->pci_vendor, busses[bus]->pci_device)
@@ -185,9 +213,11 @@ void DetectAsusAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses)
{
if (TestForAsusAuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]))
{
new_aura = new AuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]);
new_controller = new RGBController_AuraSMBus(new_aura);
ResourceManager::get()->RegisterRGBController(new_controller);
DMIInfo dmi;
AuraSMBusController* controller = new AuraSMBusController(busses[bus], aura_mobo_addresses[address_list_idx]);
RGBController_AuraSMBus* rgb_controller = new RGBController_AuraSMBus(controller);
rgb_controller->name = "ASUS " + dmi.getMainboard();
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
std::this_thread::sleep_for(1ms);
@@ -195,6 +225,7 @@ void DetectAsusAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses)
}
}
} /* DetectAuraSMBusControllers() */
} /* DetectAuraSMBusMotherboardControllers() */
REGISTER_I2C_DETECTOR("ASUS Aura SMBus", DetectAsusAuraSMBusControllers);
REGISTER_I2C_DETECTOR("ASUS Aura SMBus DRAM", DetectAsusAuraSMBusDRAMControllers);
REGISTER_I2C_DETECTOR("ASUS Aura SMBus Motherboard", DetectAsusAuraSMBusMotherboardControllers);
@@ -58,20 +58,13 @@ int RGBController_AuraSMBus::GetDeviceMode()
void RGBController_AuraSMBus::DeviceUpdateLEDs()
{
for(std::size_t led = 0; led < colors.size(); led++)
if(GetMode() == 0)
{
unsigned char red = RGBGetRValue(colors[led]);
unsigned char grn = RGBGetGValue(colors[led]);
unsigned char blu = RGBGetBValue(colors[led]);
if (GetMode() == 0)
{
aura->SetLEDColorDirect(led, red, grn, blu);
}
else
{
aura->SetLEDColorEffect(led, red, grn, blu);
}
aura->SetAllColorsDirect(&colors[0]);
}
else
{
aura->SetAllColorsEffect(&colors[0]);
}
}
@@ -17,7 +17,7 @@ AuraAddressableController::AuraAddressableController(hid_device* dev_handle, con
\*-----------------------------------------------------*/
for(int i = 0; i < config_table[0x02]; ++i)
{
device_info.push_back({0x01, (unsigned char)i, 0x01, AuraDeviceType::ADDRESSABLE});
device_info.push_back({0x01, (unsigned char)i, 0x01, 0, AuraDeviceType::ADDRESSABLE});
}
}
@@ -12,17 +12,26 @@
AuraMainboardController::AuraMainboardController(hid_device* dev_handle, const char* path) : AuraUSBController(dev_handle, path), mode(AURA_MODE_DIRECT)
{
unsigned char num_total_mainboard_leds = config_table[0x1B];
unsigned char num_rgb_headers = config_table[0x1D];
unsigned char num_addressable_headers = config_table[0x02];
if(num_total_mainboard_leds < num_rgb_headers)
{
num_rgb_headers = 0;
}
/*-----------------------------------------------------*\
| Add mainboard device |
\*-----------------------------------------------------*/
device_info.push_back({0x00, 0x04, config_table[0x1B], AuraDeviceType::FIXED});
device_info.push_back({0x00, 0x04, num_total_mainboard_leds, num_rgb_headers, AuraDeviceType::FIXED});
/*-----------------------------------------------------*\
| Add addressable devices |
\*-----------------------------------------------------*/
for(int i = 0; i < config_table[0x02]; ++i)
for(int i = 0; i < num_addressable_headers; i++)
{
device_info.push_back({0x01, (unsigned char)i, 0x01, AuraDeviceType::ADDRESSABLE});
device_info.push_back({0x01, (unsigned char)i, 0x01, 0, AuraDeviceType::ADDRESSABLE});
}
}
@@ -142,7 +151,7 @@ void AuraMainboardController::SendEffect
void AuraMainboardController::SendColor
(
unsigned char channel,
unsigned char /*channel*/,
unsigned char start_led,
unsigned char led_count,
unsigned char* led_data
@@ -196,4 +205,4 @@ void AuraMainboardController::SendCommit()
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
}
}
@@ -53,6 +53,7 @@ struct AuraDeviceInfo
unsigned char effect_channel;
unsigned char direct_channel;
unsigned char num_leds;
unsigned char num_headers;
AuraDeviceType device_type;
};
@@ -9,6 +9,7 @@
#include "RGBController_AsusAuraMouse.h"
#include <stdexcept>
#include <hidapi/hidapi.h>
#include "dependencies/dmiinfo.h"
#define AURA_USB_VID 0x0B05
#define AURA_TERMINAL_PID 0x1889
@@ -18,6 +19,7 @@
#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_ROG_GLADIUS_II_CORE_PID 0x18DD
#define AURA_ROG_GLADIUS_II_PID 0x1845
#define AURA_ROG_STRIX_FLARE_PID 0x1875
@@ -28,7 +30,7 @@
#define AURA_ROG_CHAKRAM_WIRED_1_PID 0x18E3
#define AURA_ROG_CHAKRAM_WIRED_2_PID 0x1958
void DetectAsusAuraUSBAddressable(hid_device_info* info, const std::string& name)
void DetectAsusAuraUSBTerminal(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
@@ -41,6 +43,20 @@ void DetectAsusAuraUSBAddressable(hid_device_info* info, const std::string& name
}
}
void DetectAsusAuraUSBAddressable(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
DMIInfo dmi;
AuraAddressableController* controller = new AuraAddressableController(dev, info->path);
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
rgb_controller->name = "ASUS " + dmi.getMainboard() + " Addressable";
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectAsusAuraUSBMotherboards(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
@@ -48,9 +64,10 @@ void DetectAsusAuraUSBMotherboards(hid_device_info* info, const std::string& nam
{
try
{
DMIInfo dmi;
AuraMainboardController* controller = new AuraMainboardController(dev, info->path);
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
rgb_controller->name = name;
rgb_controller->name = "ASUS " + dmi.getMainboard();
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
catch(std::runtime_error&)
@@ -84,13 +101,14 @@ void DetectAsusAuraUSBMice(hid_device_info* info, const std::string& name)
}
}
REGISTER_HID_DETECTOR ("ASUS ROG AURA Terminal", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_TERMINAL_PID);
REGISTER_HID_DETECTOR ("ASUS ROG AURA Terminal", DetectAsusAuraUSBTerminal, AURA_USB_VID, AURA_TERMINAL_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Addressable", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_ADDRESSABLE_1_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Addressable", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_ADDRESSABLE_2_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Addressable", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_ADDRESSABLE_3_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Addressable", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_ADDRESSABLE_4_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_1_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_2_PID);
REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_3_PID);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Core", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_CORE_PID, 0, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_PID, 2, 0xFF01);
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Origin", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_ORIGIN_PID, 2, 0xFF01);
@@ -13,12 +13,12 @@
#define NA 0xFFFFFFFF
static unsigned int matrix_map[6][22] =
{ { 0, NA, 12, 17, 22, 27, 37, 42, 48, 53, 59, 64, 67, 68, NA, 74, 78, 83, NA, NA, NA, NA },
{ 1, 7, 13, 18, 23, 28, 33, 38, 43, 49, 54, 60, 65, 69, NA, 75, 79, 84, 87, 92, 96, 101 },
{ 2, NA, 8, 14, 19, 24, 29, 34, 39, 44, 50, 55, 61, 66, 70, 76, 80, 85, 88, 93, 97, 102 },
{ 3, NA, 9, 15, 20, 25, 30, 35, 40, 45, 51, 56, 62, 71, NA, NA, NA, NA, 89, 94, 98, NA },
{ 4, NA, 10, 16, 21, 26, 31, 36, 41, 46, 52, 57, NA, NA, 72, NA, 81, NA, 90, 95, 99, 103 },
{ 5, 6, 11, NA, NA, NA, NA, 32, NA, 47, NA, 58, 63, 73, NA, 77, 82, 86, 91, NA, 100, NA } };
{ { 0, NA, 13, 18, 23, 28, 38, 43, 49, 54, 60, 65, 69, 70, NA, 76, 80, 85, NA, NA, NA, NA },
{ 1, 8, 14, 19, 24, 29, 34, 39, 44, 50, 55, 61, 66, 71, NA, 77, 81, 86, 89, 94, 98, 103 },
{ 2, NA, 9, 15, 20, 25, 30, 35, 40, 45, 51, 56, 62, 67, 72, 78, 82, 87, 90, 95, 99, 104 },
{ 3, NA, 10, 16, 21, 26, 31, 36, 41, 46, 52, 57, 63, 68, 73, NA, NA, NA, 91, 96, 100, NA },
{ 4, 6, 11, 17, 22, 27, 32, 37, 42, 47, 53, 58, NA, NA, 74, NA, 83, NA, 92, 97, 101, 105 },
{ 5, 7, 12, NA, NA, NA, NA, 33, NA, 48, NA, 59, 64, 75, NA, 79, 84, 88, 93, NA, 102, NA } };
static const char* zone_names[] =
{
@@ -36,7 +36,7 @@ static zone_type zone_types[] =
static const unsigned int zone_sizes[] =
{
104,
106,
1,
2,
};
@@ -56,6 +56,7 @@ static const led_type led_names[] =
{ "Key: Caps Lock", 0x03 },
{ "Key: Left Shift", 0x04 },
{ "Key: Left Control", 0x05 },
{ "Key: \\ (ISO)", 0x0C },
{ "Key: Left Windows", 0x0D },
{ "Key: 1", 0x11 },
{ "Key: Q", 0x12 },
@@ -117,6 +118,7 @@ static const led_type led_names[] =
{ "Key: F10", 0x68 },
{ "Key: =", 0x69 },
{ "Key: ]", 0x6A },
{ "Key: #", 0x6B },
{ "Key: F11", 0x70 },
{ "Key: F12", 0x78 },
{ "Key: Backspace", 0x79 },
@@ -237,7 +239,7 @@ void RGBController_AuraKeyboard::ResizeZone(int /*zone*/, int /*new_size*/)
void RGBController_AuraKeyboard::DeviceUpdateLEDs()
{
unsigned char frame_buf[107 * 4];
unsigned char frame_buf[109 * 4];
/*---------------------------------------------------------*\
| TODO: Send packets with multiple LED frames |
@@ -250,7 +252,7 @@ for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
frame_buf[(led_idx * 4) + 3] = RGBGetBValue(colors[led_idx]);
}
aura->SendDirect(107, frame_buf);
aura->SendDirect(109, frame_buf);
}
void RGBController_AuraKeyboard::UpdateZoneLEDs(int /*zone*/)
@@ -159,13 +159,24 @@ void RGBController_AuraUSB::SetupZones()
}
}
unsigned int num_mainboard_leds = device_info.num_leds - device_info.num_headers;
for (unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
{
unsigned led_idx = led_ch_idx + 1;
led new_led;
new_led.name = zones[channel_idx].name;
new_led.name.append(", LED ");
new_led.name.append(std::to_string(led_ch_idx + 1));
if(device_info.device_type == AuraDeviceType::FIXED && led_ch_idx >= num_mainboard_leds)
{
new_led.name.append(", RGB Header ");
led_idx -= num_mainboard_leds;
}
else
{
new_led.name.append(", LED ");
}
new_led.name.append(std::to_string(led_idx));
new_led.value = channel_idx;
leds.push_back(new_led);
@@ -204,7 +204,7 @@ void CMARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_cou
/*---------------------------------------------*\
| Set up the RGB triplets to send |
\*---------------------------------------------*/
for(int i = 0; i < led_count; i++)
for(unsigned int i = 0; i < led_count; i++)
{
RGBColor colour = led_colours[i];
@@ -0,0 +1,167 @@
/*-------------------------------------------------------------------*\
| CMMKController.cpp |
| |
| Driver for Coolermaster MasterKeys Keyboards |
| |
| Lukas N (chmod222) 28th Jun 2020 |
| Tam D (too.manyhobbies) 25th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
#include "CMMKController.h"
CMMKController::CMMKController(hid_device* dev, hid_device_info* dev_info)
{
location = dev_info->path;
const int szTemp = 256;
wchar_t tmpName[szTemp];
hid_get_manufacturer_string(dev, tmpName, szTemp);
std::wstring wName = std::wstring(tmpName);
device_name = std::string(wName.begin(), wName.end());
hid_get_product_string(dev, tmpName, szTemp);
wName = std::wstring(tmpName);
device_name.append(" ").append(std::string(wName.begin(), wName.end()));
cmmk_attach_path(&cmmk_handle, dev_info->path, dev_info->product_id, -1);
char buf[32] = {0};
cmmk_get_firmware_version(&cmmk_handle, buf, 32);
firmware_version = buf;
}
CMMKController::~CMMKController()
{
cmmk_detach(&cmmk_handle);
}
std::string CMMKController::GetDeviceName()
{
return device_name;
}
std::string CMMKController::GetLocation()
{
return location;
}
std::string CMMKController::GetFirmwareVersion()
{
return firmware_version;
}
void CMMKController::SetFirmwareControl()
{
ActivateMode(CMMK_FIRMWARE);
}
void CMMKController::SetManualControl()
{
ActivateMode(CMMK_MANUAL);
}
void CMMKController::SetSingle(int row, int col, struct rgb color)
{
cmmk_set_single_key(&cmmk_handle, row, col, &color);
}
void CMMKController::SetAll(struct cmmk_color_matrix const& colors)
{
cmmk_set_leds(&cmmk_handle, &colors);
}
void CMMKController::SetAllSingle(struct rgb color)
{
cmmk_set_all_single(&cmmk_handle, &color);
}
void CMMKController::SetMode(cmmk_effect_fully_lit eff)
{
ActivateEffect(CMMK_EFFECT_FULLY_LIT);
cmmk_set_effect_fully_lit(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_breathe eff)
{
ActivateEffect(CMMK_EFFECT_BREATHE);
cmmk_set_effect_breathe(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_cycle eff)
{
ActivateEffect(CMMK_EFFECT_CYCLE);
cmmk_set_effect_cycle(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_single eff)
{
ActivateEffect(CMMK_EFFECT_SINGLE);
cmmk_set_effect_single(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_wave eff)
{
ActivateEffect(CMMK_EFFECT_WAVE);
cmmk_set_effect_wave(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_ripple eff)
{
ActivateEffect(CMMK_EFFECT_RIPPLE);
cmmk_set_effect_ripple(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_cross eff)
{
ActivateEffect(CMMK_EFFECT_CROSS);
cmmk_set_effect_cross(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_raindrops eff)
{
ActivateEffect(CMMK_EFFECT_RAINDROPS);
cmmk_set_effect_raindrops(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_stars eff)
{
ActivateEffect(CMMK_EFFECT_STARS);
cmmk_set_effect_stars(&cmmk_handle, &eff);
}
void CMMKController::SetMode(cmmk_effect_snake eff)
{
ActivateEffect(CMMK_EFFECT_SNAKE);
cmmk_set_effect_snake(&cmmk_handle, &eff);
}
bool CMMKController::PositionValid(int y, int x)
{
return(cmmk_lookup_key_id(&cmmk_handle, y, x) >= 0);
}
void CMMKController::ActivateMode(int mode)
{
if (current_mode != mode)
{
cmmk_set_control_mode(&cmmk_handle, mode);
current_mode = mode;
current_effect = -1;
}
}
void CMMKController::ActivateEffect(int effect)
{
ActivateMode(CMMK_EFFECT);
if (current_effect != effect)
{
cmmk_set_active_effect(&cmmk_handle, (enum cmmk_effect_id)effect);
current_effect = effect;
}
}
@@ -0,0 +1,58 @@
/*-------------------------------------------------------------------*\
| CMMKController.h |
| |
| Driver for Coolermaster MasterKeys keyboards |
| |
| Lukas N (chmod222) 28th Jun 2020 |
| |
\*-------------------------------------------------------------------*/
#include <string>
#include <hidapi/hidapi.h>
#include <libcmmk/libcmmk.h>
#pragma once
class CMMKController
{
public:
CMMKController(hid_device* dev_handle, hid_device_info* dev_info);
~CMMKController();
std::string GetDeviceName();
std::string GetLocation();
std::string GetFirmwareVersion();
void SetFirmwareControl();
void SetManualControl();
void SetSingle(int row, int col, struct rgb color);
void SetAll(struct cmmk_color_matrix const& colors);
void SetAllSingle(struct rgb color);
void SetMode(cmmk_effect_fully_lit eff);
void SetMode(cmmk_effect_breathe eff);
void SetMode(cmmk_effect_cycle eff);
void SetMode(cmmk_effect_single eff);
void SetMode(cmmk_effect_wave eff);
void SetMode(cmmk_effect_ripple eff);
void SetMode(cmmk_effect_cross eff);
void SetMode(cmmk_effect_raindrops eff);
void SetMode(cmmk_effect_stars eff);
void SetMode(cmmk_effect_snake eff);
bool PositionValid(int y, int x);
private:
void ActivateMode(int mode);
void ActivateEffect(int effect);
int current_mode = -1;
int current_effect = -1;
std::string device_name;
std::string location;
std::string firmware_version;
mutable struct cmmk cmmk_handle;
};
@@ -147,7 +147,7 @@ void CMSmallARGBController::SetMode(unsigned char mode, unsigned char speed, RGB
SendUpdate();
}
void CMSmallARGBController::SetLedsDirect(RGBColor *led_colours, unsigned int led_count)
void CMSmallARGBController::SetLedsDirect(RGBColor* /*led_colours*/, unsigned int /*led_count*/)
{
// Mode not yet Tested
/*
@@ -3,20 +3,28 @@
#include "CMARGBcontroller.h"
#include "CMSmallARGBController.h"
#include "CMR6000Controller.h"
#include "CMMKController.h"
#include "RGBController.h"
#include "RGBController_CMMP750Controller.h"
#include "RGBController_CMARGBController.h"
#include "RGBController_CMSmallARGBController.h"
#include "RGBController_CMR6000Controller.h"
#include "RGBController_CMMKController.h"
#include <hidapi/hidapi.h>
#define COOLERMASTER_VID 0x2516
#define COOLERMASTER_VID 0x2516
#define COOLERMASTER_MP750_XL_PID 0x0109
#define COOLERMASTER_MP750_MEDIUM_PID 0x0105
#define COOLERMASTER_ARGB_PID 0x1011
#define COOLERMASTER_SMALL_ARGB_PID 0x1000
#define COOLERMASTER_RADEON_6000_PID 0x014D
#define COOLERMASTER_MP750_XL_PID 0x0109
#define COOLERMASTER_MP750_MEDIUM_PID 0x0105
#define COOLERMASTER_ARGB_PID 0x1011
#define COOLERMASTER_SMALL_ARGB_PID 0x1000
#define COOLERMASTER_RADEON_6000_PID 0x014D
#define COOLERMASTER_MASTERKEYS_PRO_L_PID CMMK_USB_MASTERKEYS_MK750
#define COOLERMASTER_MASTERKEYS_PRO_L_WHITE_PID CMMK_USB_MASTERKEYS_PRO_L_WHITE
#define COOLERMASTER_MASTERKEYS_PRO_S_PID CMMK_USB_MASTERKEYS_PRO_S
#define COOLERMASTER_MASTERKEYS_MK750_PID CMMK_USB_MASTERKEYS_MK750
#define COOLERMASTER_MASTERKEYS_SK630_PID CMMK_USB_MASTERKEYS_SK630
#define COOLERMASTER_MASTERKEYS_SK650_PID CMMK_USB_MASTERKEYS_SK650
/******************************************************************************************\
* *
@@ -77,8 +85,27 @@ void DetectCoolerMasterGPU(hid_device_info* info, const std::string&)
}
}
REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 XL", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_XL_PID, 0xFF00, 1);
REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Medium", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_MEDIUM_PID, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB", DetectCoolerMasterARGB, COOLERMASTER_VID, COOLERMASTER_ARGB_PID, 0, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master Smalll ARGB", DetectCoolerMasterSmallARGB, COOLERMASTER_VID, COOLERMASTER_SMALL_ARGB_PID, 0, 0xFF00, 1);
REGISTER_HID_DETECTOR_I ("Cooler Master Radeon 6000 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6000_PID, 1);
void DetectCoolerMasterKeyboards(hid_device_info* info, const std::string&)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CMMKController* controller = new CMMKController(dev, info);
RGBController_CMMKController* rgb_controller = new RGBController_CMMKController(controller);
// Constructor sets the name
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 XL", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_XL_PID, 0xFF00, 1 );
REGISTER_HID_DETECTOR_PU ("Cooler Master MP750 Medium", DetectCoolerMasterMousemats, COOLERMASTER_VID, COOLERMASTER_MP750_MEDIUM_PID, 0xFF00, 1 );
REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro L", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_PRO_L_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro L White", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_PRO_L_WHITE_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master MasterKeys Pro S", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_PRO_S_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master MK570", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_MK750_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master SK630", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_SK630_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master SK650", DetectCoolerMasterKeyboards, COOLERMASTER_VID, COOLERMASTER_MASTERKEYS_SK650_PID, 1, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master ARGB", DetectCoolerMasterARGB, COOLERMASTER_VID, COOLERMASTER_ARGB_PID, 0, 0xFF00, 1);
REGISTER_HID_DETECTOR_IPU("Cooler Master Smalll ARGB", DetectCoolerMasterSmallARGB, COOLERMASTER_VID, COOLERMASTER_SMALL_ARGB_PID, 0, 0xFF00, 1);
REGISTER_HID_DETECTOR_I ("Cooler Master Radeon 6000 GPU", DetectCoolerMasterGPU, COOLERMASTER_VID, COOLERMASTER_RADEON_6000_PID, 1 );
@@ -336,7 +336,7 @@ void RGBController_CMARGBController::DeviceUpdateLEDs()
}
}
void RGBController_CMARGBController::UpdateZoneLEDs(int zone)
void RGBController_CMARGBController::UpdateZoneLEDs(int /*zone*/)
{
//cmargb->SetLedsDirect( zones[zone].colors, zones[zone].leds_count );
}
@@ -0,0 +1,467 @@
/*-------------------------------------------------------------------*\
| RGBController_CMMKController.cpp |
| |
| Driver for Coolermaster MasterKeys keyboards |
| |
| Lukas N (chmod222) 28th Jun 2020 |
| Tam D (too.manyhobbies) 25th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
#include "RGBController_CMMKController.h"
#include <sstream>
using namespace std::chrono_literals;
#define CMMK_SPEED_MIN CMMK_SPEED0
#define CMMK_SPEED_MID CMMK_SPEED2
#define CMMK_SPEED_MAX CMMK_SPEED4
#define CMMK_MODE_FIRMWARE 0xFF
#define CMMK_MODE_MANUAL 0x7F
RGBController_CMMKController::RGBController_CMMKController(CMMKController* cmmk_ctrl)
{
cmmk = cmmk_ctrl;
name = cmmk->GetDeviceName();
type = DEVICE_TYPE_KEYBOARD;
description = "Cooler Master MasterKeys Device";
version = cmmk->GetFirmwareVersion();
serial = "";
location = cmmk->GetLocation();
mode Direct;
Direct.name = "Direct";
Direct.value = CMMK_MODE_MANUAL;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Static;
Static.name = "Static";
Static.value = CMMK_EFFECT_FULLY_LIT;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors_min = 1;
Static.colors_max = 1;
Static.colors.resize(1);
modes.push_back(Static);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = CMMK_EFFECT_BREATHE;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Breathing.speed_min = 0x20;
Breathing.speed_max = 0x20;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.colors.resize(1);
modes.push_back(Breathing);
mode Cycle;
Cycle.name = "Spectrum Cycle";
Cycle.value = CMMK_EFFECT_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED;
Cycle.speed_min = CMMK_SPEED_MIN;
Cycle.speed_max = CMMK_SPEED_MAX;
Cycle.color_mode = MODE_COLORS_NONE;
modes.push_back(Cycle);
mode Reactive;
Reactive.name = "Reactive";
Reactive.value = CMMK_EFFECT_SINGLE;
Reactive.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Reactive.speed_min = CMMK_SPEED_MIN;
Reactive.speed_max = CMMK_SPEED_MAX;
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
Reactive.colors_min = 2;
Reactive.colors_max = 2;
Reactive.colors.resize(2);
modes.push_back(Reactive);
mode Wave;
Wave.name = "Rainbow Wave";
Wave.value = CMMK_EFFECT_WAVE;
Wave.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD;
Wave.speed_min = CMMK_SPEED_MIN;
Wave.speed_max = CMMK_SPEED_MAX;
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
Wave.colors_min = 1;
Wave.colors_max = 1;
Wave.colors.resize(1);
modes.push_back(Wave);
mode Ripple;
Ripple.name = "Ripple Effect";
Ripple.value = CMMK_EFFECT_RIPPLE;
Ripple.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_SPEED;
Ripple.speed_min = CMMK_SPEED_MIN;
Ripple.speed_max = CMMK_SPEED_MAX;
Ripple.colors_min = 2;
Ripple.colors_max = 2;
Ripple.colors.resize(2);
modes.push_back(Ripple);
mode Cross;
Cross.name = "Cross";
Cross.value = CMMK_EFFECT_CROSS;
Cross.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Cross.speed_min = CMMK_SPEED_MIN;
Cross.speed_max = CMMK_SPEED_MAX;
Cross.colors_min = 2;
Cross.colors_max = 2;
Cross.colors.resize(2);
modes.push_back(Cross);
mode Raindrops;
Raindrops.name = "Raindrops";
Raindrops.value = CMMK_EFFECT_RAINDROPS;
Raindrops.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Raindrops.speed_min = CMMK_SPEED_MIN;
Raindrops.speed_max = CMMK_SPEED_MAX;
Raindrops.colors_min = 2;
Raindrops.colors_max = 2;
Raindrops.colors.resize(2);
modes.push_back(Raindrops);
mode Stars;
Stars.name = "Starfield";
Stars.value = CMMK_EFFECT_STARS;
Stars.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Stars.speed_min = CMMK_SPEED_MIN;
Stars.speed_max = CMMK_SPEED_MAX;
Stars.colors_min = 2;
Stars.colors_max = 2;
Stars.colors.resize(2);
modes.push_back(Stars);
mode Snake;
Snake.name = "Snake";
Snake.value = CMMK_EFFECT_SNAKE;
Snake.flags = MODE_FLAG_HAS_SPEED;
Snake.speed_min = CMMK_SPEED_MIN;
Snake.speed_max = CMMK_SPEED_MAX;
modes.push_back(Snake);
mode FirmwareControl;
FirmwareControl.name = "Firmware Controlled";
FirmwareControl.value = 0xFF;
FirmwareControl.flags = 0;
modes.push_back(FirmwareControl);
SetupZones();
}
RGBController_CMMKController::~RGBController_CMMKController()
{
delete cmmk;
}
void RGBController_CMMKController::SetupMatrixMap()
{
for(int y = 0; y < CMMK_ROWS_MAX; y++)
{
for(int x = 0; x < CMMK_COLS_MAX; x++)
{
matrix_map[y][x] = 0xFFFFFFFF;
}
}
for(size_t i = 0; i < leds.size(); i++)
{
led& l = leds[i];
int y = (l.value & 0xFF00) >> 8;
int x = (l.value & 0xFF);
matrix_map[y][x] = i;
}
}
void RGBController_CMMKController::SetupZones()
{
for(int y = 0; y < CMMK_ROWS_MAX; y++)
{
for(int x = 0; x < CMMK_COLS_MAX; x++)
{
if(!cmmk->PositionValid(y, x))
{
continue;
}
std::stringstream namestrm;
led key;
namestrm << "Key @ Row " << (y + 1) << ", Column" << (x + 1);
key.name = namestrm.str();
key.value = (y & 0xFF) << 8 | (x & 0xFF);
leds.push_back(key);
}
}
zone KeyboardZone;
KeyboardZone.name = "Keyboard";
KeyboardZone.type = ZONE_TYPE_MATRIX;
KeyboardZone.leds_min = leds.size();
KeyboardZone.leds_max = leds.size();
KeyboardZone.leds_count = leds.size();
KeyboardZone.matrix_map = new matrix_map_type;
KeyboardZone.matrix_map->height = CMMK_ROWS_MAX;
KeyboardZone.matrix_map->width = CMMK_COLS_MAX;
KeyboardZone.matrix_map->map = (unsigned int *)&matrix_map;
zones.push_back(KeyboardZone);
SetupMatrixMap();
SetupColors();
}
void RGBController_CMMKController::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
struct rgb map_to_cmmk_rgb(RGBColor input)
{
return rgb
{
(uint8_t)RGBGetRValue(input),
(uint8_t)RGBGetGValue(input),
(uint8_t)RGBGetBValue(input)
};
}
enum cmmk_wave_direction map_to_cmmk_dir(int input)
{
switch(input)
{
case MODE_DIRECTION_LEFT:
return CMMK_RIGHT_TO_LEFT;
case MODE_DIRECTION_RIGHT:
return CMMK_LEFT_TO_RIGHT;
case MODE_DIRECTION_UP:
return CMMK_FRONT_TO_BACK;
case MODE_DIRECTION_DOWN:
return CMMK_BACK_TO_FRONT;
default:
return CMMK_RIGHT_TO_LEFT;
}
}
void copy_buffers(led* buf, RGBColor* colbuf, size_t n, struct cmmk_color_matrix& mat, std::atomic<bool>& dirty)
{
dirty.store(false);
for(size_t i = 0; i < n; i++)
{
led const& selected_led = buf[i];
int y = (selected_led.value & 0xFF00) >> 8;
int x = selected_led.value & 0xFF;
struct rgb col = map_to_cmmk_rgb(colbuf[i]);
struct rgb ecol = mat.data[y][x];
if(ecol.R != col.R || ecol.G != col.G || ecol.B != col.B)
{
dirty.store(true);
mat.data[y][x] = col;
}
}
}
void RGBController_CMMKController::DeviceUpdateLEDs()
{
copy_buffers(leds.data(), colors.data(), leds.size(), current_matrix, dirty);
if(force_update.load() || dirty.load())
{
cmmk->SetAll(current_matrix);
force_update.store(false);
}
}
void RGBController_CMMKController::UpdateZoneLEDs(int zone_idx)
{
zone& z = zones[zone_idx];
copy_buffers(z.leds, z.colors, z.leds_count, current_matrix, dirty);
if(force_update.load() || dirty.load())
{
cmmk->SetAll(current_matrix);
force_update.store(false);
}
}
void RGBController_CMMKController::UpdateSingleLED(int led_idx)
{
led& selected_led = leds[led_idx];
int y = (selected_led.value & 0xFF00) >> 8;
int x = selected_led.value & 0xFF;
current_matrix.data[y][x] = map_to_cmmk_rgb(colors[led_idx]);
cmmk->SetSingle(y, x, map_to_cmmk_rgb(colors[led_idx]));
dirty.store(false);
}
void RGBController_CMMKController::SetCustomMode()
{
active_mode = 1;
}
void RGBController_CMMKController::DeviceUpdateMode()
{
force_update.store(true);
switch(modes[active_mode].value)
{
case CMMK_MODE_FIRMWARE:
cmmk->SetFirmwareControl();
break;
case CMMK_MODE_MANUAL:
cmmk->SetManualControl();
break;
case CMMK_EFFECT_FULLY_LIT:
{
cmmk_effect_fully_lit fully_lit_effect;
fully_lit_effect.color = map_to_cmmk_rgb(modes[active_mode].colors[0]);
cmmk->SetMode(fully_lit_effect);
}
break;
case CMMK_EFFECT_BREATHE:
{
cmmk_effect_breathe breathe_effect;
breathe_effect.speed = (uint8_t)modes[active_mode].speed;
breathe_effect.color = map_to_cmmk_rgb(modes[active_mode].colors[0]);
cmmk->SetMode(breathe_effect);
}
break;
case CMMK_EFFECT_CYCLE:
{
cmmk_effect_cycle cycle_effect;
cycle_effect.speed = (uint8_t)modes[active_mode].speed;
cmmk->SetMode(cycle_effect);
}
break;
case CMMK_EFFECT_SINGLE:
{
cmmk_effect_single single_effect;
single_effect.speed = (uint8_t)modes[active_mode].speed;
single_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
single_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
cmmk->SetMode(single_effect);
}
break;
case CMMK_EFFECT_WAVE:
{
cmmk_effect_wave wave_effect;
wave_effect.speed = (uint8_t)modes[active_mode].speed;
wave_effect.direction = map_to_cmmk_dir(modes[active_mode].direction);
wave_effect.start = map_to_cmmk_rgb(modes[active_mode].colors[0]);
cmmk->SetMode(wave_effect);
}
break;
case CMMK_EFFECT_RIPPLE:
{
cmmk_effect_ripple ripple_effect;
ripple_effect.speed = (uint8_t)modes[active_mode].speed;
ripple_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
ripple_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
if(modes[active_mode].color_mode == MODE_COLORS_RANDOM)
{
ripple_effect.ripple_type = CMMK_RIPPLE_RANDOM_COLOR;
}
else
{
ripple_effect.ripple_type = CMMK_RIPPLE_GIVEN_COLOR;
}
cmmk->SetMode(ripple_effect);
}
break;
case CMMK_EFFECT_CROSS:
{
cmmk_effect_cross cross_effect;
cross_effect.speed = (uint8_t)modes[active_mode].speed;
cross_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
cross_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
cmmk->SetMode(cross_effect);
}
break;
case CMMK_EFFECT_RAINDROPS:
{
cmmk_effect_raindrops raindrops_effect;
raindrops_effect.speed = (uint8_t)modes[active_mode].speed;
raindrops_effect.interval = CMMK_SPEED_MID;
raindrops_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
raindrops_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
cmmk->SetMode(raindrops_effect);
}
break;
case CMMK_EFFECT_STARS:
{
cmmk_effect_stars stars_effect;
stars_effect.speed = (uint8_t)modes[active_mode].speed;
stars_effect.interval = CMMK_SPEED_MID;
stars_effect.active = map_to_cmmk_rgb(modes[active_mode].colors[0]);
stars_effect.rest = map_to_cmmk_rgb(modes[active_mode].colors[1]);
cmmk->SetMode(stars_effect);
}
break;
case CMMK_EFFECT_SNAKE:
{
cmmk_effect_snake snake_effect;
snake_effect.speed = (uint8_t)modes[active_mode].speed;
cmmk->SetMode(snake_effect);
}
break;
}
}
@@ -0,0 +1,42 @@
/*-------------------------------------------------------------------*\
| RGBController_CMMKController.h |
| |
| Driver for Coolermaster MasterKeys keyboards |
| |
| Lukas N (chmod222) 28th Jun 2020 |
| Tam D (too.manyhobbies) 25th Apr 2021 |
| |
\*-------------------------------------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CMMKController.h"
class RGBController_CMMKController : public RGBController
{
public:
RGBController_CMMKController(CMMKController* cmmk_ptr);
~RGBController_CMMKController();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
void SetupMatrixMap();
CMMKController* cmmk;
int matrix_map[CMMK_ROWS_MAX][CMMK_COLS_MAX];
struct cmmk_color_matrix current_matrix;
std::atomic<bool> dirty;
std::atomic<bool> force_update;
};
@@ -87,7 +87,7 @@ RGBController_CMMP750Controller::~RGBController_CMMP750Controller()
int RGBController_CMMP750Controller::GetDeviceMode()
{
int temp_mode = cmmp750->GetMode();
for( int i = 0; i < modes.size(); i++)
for(unsigned int i = 0; i < modes.size(); i++)
{
if (temp_mode == modes[i].value)
{
@@ -140,7 +140,7 @@ void RGBController_CMR6000Controller::UpdateSingleLED(int /*led*/)
void RGBController_CMR6000Controller::SetCustomMode()
{
active_mode = 1;
}
void RGBController_CMR6000Controller::DeviceUpdateMode()
@@ -224,14 +224,14 @@ void RGBController_CMSmallARGBController::DeviceUpdateLEDs()
}
}
void RGBController_CMSmallARGBController::UpdateZoneLEDs(int zone)
void RGBController_CMSmallARGBController::UpdateZoneLEDs(int /*zone*/)
{
bool random_colours = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
//bool random_colours = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
//cmargb->SetLedsDirect(zones[zone].colors, random_colours);
}
void RGBController_CMSmallARGBController::UpdateSingleLED(int led)
void RGBController_CMSmallARGBController::UpdateSingleLED(int /*led*/)
{
//cmargb->SetMode( modes[active_mode].value, modes[active_mode].speed );
//cmargb->SetLedsDirect( zones[0].colors, zones[0].leds_count );
@@ -47,16 +47,15 @@ static const corsair_hydro_device device_list[] =
void DetectCorsairHydroControllers(std::vector<RGBController*>& rgb_controllers)
{
libusb_context * ctx;
libusb_init(&ctx);
libusb_init(NULL);
#ifdef _WIN32
libusb_set_option(ctx, LIBUSB_OPTION_USE_USBDK);
libusb_set_option(NULL, LIBUSB_OPTION_USE_USBDK);
#endif
for(std::size_t device_idx = 0; device_idx < CORSAIR_NUM_DEVICES; device_idx++)
{
libusb_device_handle * dev = libusb_open_device_with_vid_pid(ctx, device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
libusb_device_handle * dev = libusb_open_device_with_vid_pid(NULL, device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
//Look for Corsair RGB Peripheral
if(dev)
@@ -15,7 +15,7 @@
#include <hidapi/hidapi.h>
#define CORSAIR_HYDRO_PLATINUM_PACKET_SIZE 65
#define CORSAIR_HYDRO_PLATINUM_PACKET_DELAY 3
#define CORSAIR_HYDRO_PLATINUM_PACKET_DELAY 5
enum
{
@@ -48,6 +48,9 @@ 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 };
CorsairPeripheralController::CorsairPeripheralController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
@@ -56,18 +59,18 @@ CorsairPeripheralController::CorsairPeripheralController(hid_device* dev_handle,
ReadFirmwareInfo();
/*-----------------------------------------------------*\
| K95 Platinum requires additional steps |
| K55 and K95 Platinum require additional steps |
\*-----------------------------------------------------*/
if (logical_layout == CORSAIR_TYPE_K95_PLAT)
if (logical_layout == CORSAIR_TYPE_K55 || logical_layout == CORSAIR_TYPE_K95_PLAT)
{
SpecialFunctionControl();
}
LightingControl();
if (logical_layout == CORSAIR_TYPE_K95_PLAT)
if (logical_layout == CORSAIR_TYPE_K55 || logical_layout == CORSAIR_TYPE_K95_PLAT)
{
SetupK95LightingControl();
SetupK55AndK95LightingControl();
}
}
@@ -229,7 +232,6 @@ void CorsairPeripheralController::SetLEDsKeyboardFull(std::vector<RGBColor> colo
SubmitKeyboardFullColors(3, 3, 2);
}
void CorsairPeripheralController::SetLEDsMouse(std::vector<RGBColor> colors)
{
SubmitMouseColors(colors.size(), &colors[0]);
@@ -367,7 +369,7 @@ void CorsairPeripheralController::LightingControl()
| Probably a key mapping packet? |
\*-----------------------------------------------------*/
void CorsairPeripheralController::SetupK95LightingControl()
void CorsairPeripheralController::SetupK55AndK95LightingControl()
{
char usb_buf[65];
@@ -391,7 +393,16 @@ void CorsairPeripheralController::SetupK95LightingControl()
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
int identifier = 0;
unsigned int* skipped_identifiers = key_mapping_k95_plat_ansi;
int skipped_identifiers_count = sizeof(key_mapping_k95_plat_ansi) / sizeof(key_mapping_k95_plat_ansi[0]);
if (physical_layout == CORSAIR_LAYOUT_ISO)
{
skipped_identifiers = key_mapping_k95_plat_iso;
skipped_identifiers_count = sizeof(key_mapping_k95_plat_iso) / sizeof(key_mapping_k95_plat_iso[0]);
}
unsigned int identifier = 0;
for (int i = 0; i < 4; i++)
{
/*-----------------------------------------------------*\
@@ -409,11 +420,12 @@ void CorsairPeripheralController::SetupK95LightingControl()
for (int j = 0; j < 30; j++)
{
while (identifier == 0x31 || identifier == 0x41 || identifier == 0x42 || identifier == 0x48
|| identifier == 0x49 || identifier == 0x51 || identifier == 0x55 || identifier == 0x6f
|| identifier == 0x7e || identifier == 0x7f || identifier == 0x80 || identifier == 0x81)
for (int j = 0; j < skipped_identifiers_count; j++)
{
identifier++;
if (identifier == skipped_identifiers[j])
{
identifier++;
}
}
usb_buf[5 + 2 * j] = identifier++;
@@ -522,7 +534,6 @@ void CorsairPeripheralController::ReadFirmwareInfo()
case 0x1B3D:
logical_layout = CORSAIR_TYPE_K55;
SpecialFunctionControl();
break;
default:
@@ -97,7 +97,7 @@ private:
int logical_layout; //Normal, K95 or K95 Platinum
void LightingControl();
void SetupK95LightingControl();
void SetupK55AndK95LightingControl();
void SpecialFunctionControl();
void ReadFirmwareInfo();
@@ -91,7 +91,7 @@ void DetectCorsairPeripheralControllers(hid_device_info* info, const std::string
/*-----------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("Corsair K55 RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K55_RGB_PID, 1, 0xFFC2); // Not per-key, disabled for now
REGISTER_HID_DETECTOR_IP("Corsair K55 RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K55_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K65 RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K65_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K65 LUX RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K65_LUX_RGB_PID, 1, 0xFFC2);
REGISTER_HID_DETECTOR_IP("Corsair K65 RGB RAPIDFIRE", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K65_RGB_RAPIDFIRE_PID, 1, 0xFFC2);
@@ -0,0 +1,217 @@
/*-----------------------------------------*\
| CorsairWirelessController.cpp |
| |
| Driver for Corsair RGB wireless keyboard |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 5/8/2021 |
\*-----------------------------------------*/
#include "CorsairWirelessController.h"
#include <cstring>
using namespace std::chrono_literals;
CorsairWirelessController::CorsairWirelessController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
type = DEVICE_TYPE_KEYBOARD;
EnterDirectMode();
}
CorsairWirelessController::~CorsairWirelessController()
{
hid_close(dev);
}
device_type CorsairWirelessController::GetDeviceType()
{
return type;
}
std::string CorsairWirelessController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string CorsairWirelessController::GetFirmwareString()
{
return firmware_version;
}
std::string CorsairWirelessController::GetName()
{
return name;
}
std::string CorsairWirelessController::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, serial_string, 128);
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void CorsairWirelessController::SetLEDs(std::vector<RGBColor>colors)
{
unsigned char buf[3 * 137];
for(int color = 0; color < 137; color++)
{
buf[0 + color] = RGBGetRValue(colors[color]);
buf[137 + color] = RGBGetGValue(colors[color]);
buf[274+color] = RGBGetBValue(colors[color]);
}
StartDirectMode();
SendDirectFrame(true, &buf[0]);
SendDirectFrame(false, &buf[57]);
SendDirectFrame(false, &buf[118]);
SendDirectFrame(false, &buf[179]);
SendDirectFrame(false, &buf[240]);
SendDirectFrame(false, &buf[301]);
SendDirectFrame(false, &buf[362]);
}
void CorsairWirelessController::SetLEDsKeyboardFull(std::vector<RGBColor> colors)
{
}
void CorsairWirelessController::SetName(std::string device_name)
{
name = device_name;
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void CorsairWirelessController::EnterDirectMode()
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x80;
usb_buf[0x02] = 0x01;
usb_buf[0x03] = 0x03;
usb_buf[0x04] = 0x00;
usb_buf[0x05] = 0x02;
/*-----------------------------------------------------*\
| Send packet using feature reports, as headset stand |
| seems to not update completely using HID writes |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairWirelessController::StartDirectMode()
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x80;
usb_buf[0x02] = 0x0D;
usb_buf[0x03] = 0x00;
usb_buf[0x04] = 0x01;
/*-----------------------------------------------------*\
| Send packet using feature reports, as headset stand |
| seems to not update completely using HID writes |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairWirelessController::ExitDirectMode()
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x80;
usb_buf[0x02] = 0x01;
usb_buf[0x03] = 0x03;
usb_buf[0x04] = 0x00;
usb_buf[0x05] = 0x01;
/*-----------------------------------------------------*\
| Send packet using feature reports, as headset stand |
| seems to not update completely using HID writes |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
void CorsairWirelessController::SendDirectFrame(bool first_frame, unsigned char* data)
{
char usb_buf[65];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Submit Mouse Colors packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = 0x80;
usb_buf[0x02] = first_frame ? 0x06 : 0x07;
usb_buf[0x03] = 0x00;
if(first_frame)
{
usb_buf[0x04] = 0x9B;
usb_buf[0x05] = 0x01;
}
/*-----------------------------------------------------*\
| Copy in colors in <RED> <GREEN> <BLUE> order |
\*-----------------------------------------------------*/
if(first_frame)
{
memcpy(&usb_buf[0x08], data, 57);
}
else
{
memcpy(&usb_buf[0x04], data, 61);
}
/*-----------------------------------------------------*\
| Send packet using feature reports, as headset stand |
| seems to not update completely using HID writes |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 65);
}
@@ -0,0 +1,45 @@
/*-----------------------------------------*\
| CorsairWirelessController.h |
| |
| Definitions and types for Corsair RGB |
| wireless keyboard lighting controller |
| |
| Adam Honse (CalcProgrammer1) 5/8/2021 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
class CorsairWirelessController
{
public:
CorsairWirelessController(hid_device* dev_handle, const char* path);
~CorsairWirelessController();
device_type GetDeviceType();
std::string GetDeviceLocation();
std::string GetFirmwareString();
std::string GetName();
std::string GetSerialString();
void SetLEDs(std::vector<RGBColor> colors);
void SetLEDsKeyboardFull(std::vector<RGBColor> colors);
void SetName(std::string device_name);
private:
hid_device* dev;
std::string firmware_version;
std::string location;
std::string name;
device_type type;
void EnterDirectMode();
void ExitDirectMode();
void StartDirectMode();
void SendDirectFrame(bool first_frame, unsigned char* data);
};
@@ -0,0 +1,50 @@
#include "Detector.h"
#include "CorsairWirelessController.h"
#include "RGBController.h"
#include "RGBController_CorsairWireless.h"
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| Corsair vendor ID |
\*-----------------------------------------------------*/
#define CORSAIR_VID 0x1B1C
/*-----------------------------------------------------*\
| Keyboard product IDs |
\*-----------------------------------------------------*/
#define CORSAIR_K57_RGB_WIRED_PID 0x1B6E
#define CORSAIR_K57_RGB_WIRELESS_PID 0x1B62
/******************************************************************************************\
* *
* DetectCorsairWirelessControllers *
* *
* Tests the USB address to see if a Corsair RGB Keyboard controller exists there. *
* *
\******************************************************************************************/
void DetectCorsairWirelessControllers(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if( dev )
{
CorsairWirelessController* controller = new CorsairWirelessController(dev, info->path);
controller->SetName(name);
if(controller->GetDeviceType() != DEVICE_TYPE_UNKNOWN)
{
RGBController_CorsairWireless* rgb_controller = new RGBController_CorsairWireless(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
else
{
delete controller;
}
}
} /* DetectCorsairWirelessControllers() */
/*-----------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-----------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Corsair K57 RGB (Wired)", DetectCorsairWirelessControllers, CORSAIR_VID, CORSAIR_K57_RGB_WIRED_PID, 1, 0xFF42, 1);
//REGISTER_HID_DETECTOR_IPU("Corsair K57 RGB (Wireless)", DetectCorsairWirelessControllers, CORSAIR_VID, CORSAIR_K57_RGB_WIRELESS_PID, 1, 0xFF42, 1);
@@ -0,0 +1,326 @@
/*-----------------------------------------*\
| RGBController_CorsairWireless.cpp |
| |
| Generic RGB Interface for Corsair RGB |
| wireless keyboard devices |
| |
| Adam Honse (CalcProgrammer1) 5/8/2021 |
\*-----------------------------------------*/
#include "RGBController_CorsairWireless.h"
using namespace std::chrono_literals;
//0xFFFFFFFF indicates an unused entry in matrix
#define NA 0xFFFFFFFF
static unsigned int matrix_map[7][24] =
{ { NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 0, 1, NA, NA, NA },
{ 131, 41, NA, 58, 59, 60, 61, NA, 62, 63, 64, 65, NA, 66, 67, 68, 69, 70, 71, 72, NA, NA, NA, NA },
{ 132, 53, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, NA, 45, 46, 42, NA, 73, 74, 75, 83, 84, 85, 86 },
{ 133, 43, NA, 20, 26, 8, 21, NA, 23, 28, 24, 12, 18, 19, 47, 48, 49, 76, 77, 78, 95, 96, 97, 87 },
{ 134, 57, NA, 4, 22, 7, 9, NA, 10, 11, 13, 14, 15, 51, 52, NA, 40, NA, NA, NA, 92, 93, 94, NA },
{ 135, 106, NA, 29, 27, 6, 25, NA, 5, NA, 17, 16, 54, 55, 56, 110, NA, NA, 82, NA, 89, 90, 91, 88 },
{ 136, 105, 108, 107, NA, NA, NA, NA, 44, NA, NA, NA, NA, 111, 122, 101, 109, 80, 81, 79, 98, NA, 99, NA } };
static const char* zone_names[] =
{
"Keyboard",
};
static const unsigned int zone_sizes[] =
{
137
};
static const zone_type zone_types[] =
{
ZONE_TYPE_MATRIX,
};
static const char* led_names[] =
{
"Power/Wireless Indicator",
"Lock/Macro Indicator",
"N/A",
"N/A",
"Key: A",
"Key: B",
"Key: C",
"Key: D",
"Key: E",
"Key: F",
"Key: G",
"Key: H",
"Key: I",
"Key: J",
"Key: K",
"Key: L",
"Key: M",
"Key: N",
"Key: O",
"Key: P",
"Key: Q",
"Key: R",
"Key: S",
"Key: T",
"Key: U",
"Key: V",
"Key: W",
"Key: X",
"Key: Y",
"Key: Z",
"Key: 1",
"Key: 2",
"Key: 3",
"Key: 4",
"Key: 5",
"Key: 6",
"Key: 7",
"Key: 8",
"Key: 9",
"Key: 0",
"Key: Enter",
"Key: Escape",
"Key: Backspace",
"Key: Tab",
"Key: Space",
"Key: -",
"Key: =",
"Key: [",
"Key: ]",
"Key: \\ (ANSI)",
"Unused",
"Key: ;",
"Key: '",
"Key: `",
"Key: ,",
"Key: .",
"Key: /",
"Key: Caps Lock",
"Key: F1",
"Key: F2",
"Key: F3",
"Key: F4",
"Key: F5",
"Key: F6",
"Key: F7",
"Key: F8",
"Key: F9",
"Key: F10",
"Key: F11",
"Key: F12",
"Key: Print Screen",
"Key: Scroll Lock",
"Key: Pause/Break",
"Key: Insert",
"Key: Home",
"Key: Page Up",
"Key: Delete",
"Key: End",
"Key: Page Down",
"Key: Right Arrow",
"Key: Left Arrow",
"Key: Down Arrow",
"Key: Up Arrow",
"Key: Num Lock",
"Key: Number Pad /",
"Key: Number Pad *",
"Key: Number Pad -",
"Key: Number Pad +",
"Key: Number Pad Enter",
"Key: Number Pad 1",
"Key: Number Pad 2",
"Key: Number Pad 3",
"Key: Number Pad 4",
"Key: Number Pad 5",
"Key: Number Pad 6",
"Key: Number Pad 7",
"Key: Number Pad 8",
"Key: Number Pad 9",
"Key: Number Pad 0",
"Key: Number Pad .",
"Unused",
"Key: Menu",
"Unused",
"Unused",
"Unused",
"Left Control",
"Left Shift",
"Left Alt",
"Left Windows",
"Right Control",
"Right Shift",
"Right Alt",
"Unused",
"Unused",
"Unused",
"Unused",
"Unused",
"Unused",
"Unused",
"Unused",
"Unused",
"Unused",
"Key: Right Fn",
"Unused",
"Unused",
"Unused",
"Unused",
"Unused",
"Unused",
"Unused",
"Unused",
"Key: G1",
"Key: G2",
"Key: G3",
"Key: G4",
"Key: G5",
"Key: G6",
};
RGBController_CorsairWireless::RGBController_CorsairWireless(CorsairWirelessController* corsair_ptr)
{
corsair = corsair_ptr;
name = corsair->GetName();
vendor = "Corsair";
description = "Corsair RGB Peripheral Device";
type = corsair->GetDeviceType();
version = corsair->GetFirmwareString();
location = corsair->GetDeviceLocation();
serial = corsair->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = 0;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
SetupZones();
/*-----------------------------------------------------*\
| The Corsair Lighting Node Pro requires a packet within|
| 20 seconds of sending the lighting change in order |
| to not revert back into rainbow mode. Start a thread |
| to continuously send a keepalive packet every 5s |
\*-----------------------------------------------------*/
keepalive_thread_run = 1;
keepalive_thread = new std::thread(&RGBController_CorsairWireless::KeepaliveThread, this);
}
RGBController_CorsairWireless::~RGBController_CorsairWireless()
{
/*---------------------------------------------------------*\
| Delete the matrix map |
\*---------------------------------------------------------*/
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
{
if(zones[zone_index].matrix_map != NULL)
{
delete zones[zone_index].matrix_map;
}
}
delete corsair;
}
void RGBController_CorsairWireless::SetupZones()
{
/*---------------------------------------------------------*\
| Determine number of zones |
| For now, keyboard has 2 zones and mousemat has 1 |
\*---------------------------------------------------------*/
unsigned int num_zones = 1;
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
unsigned int total_led_count = 0;
for(unsigned int zone_idx = 0; zone_idx < num_zones; zone_idx++)
{
zone new_zone;
new_zone.name = zone_names[zone_idx];
new_zone.type = zone_types[zone_idx];
new_zone.leds_min = zone_sizes[zone_idx];
new_zone.leds_max = zone_sizes[zone_idx];
new_zone.leds_count = zone_sizes[zone_idx];
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
{
new_zone.matrix_map = new matrix_map_type;
new_zone.matrix_map->height = 7;
new_zone.matrix_map->width = 24;
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
}
else
{
new_zone.matrix_map = NULL;
}
zones.push_back(new_zone);
total_led_count += new_zone.leds_count;
}
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
{
led new_led;
new_led.name = led_names[led_idx];
leds.push_back(new_led);
}
SetupColors();
}
void RGBController_CorsairWireless::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_CorsairWireless::DeviceUpdateLEDs()
{
last_update_time = std::chrono::steady_clock::now();
corsair->SetLEDs(colors);
}
void RGBController_CorsairWireless::UpdateZoneLEDs(int /*zone*/)
{
corsair->SetLEDs(colors);
}
void RGBController_CorsairWireless::UpdateSingleLED(int /*led*/)
{
corsair->SetLEDs(colors);
}
void RGBController_CorsairWireless::SetCustomMode()
{
active_mode = 0;
}
void RGBController_CorsairWireless::DeviceUpdateMode()
{
}
void RGBController_CorsairWireless::KeepaliveThread()
{
while(keepalive_thread_run.load())
{
if(active_mode == 0)
{
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(5000))
{
DeviceUpdateLEDs();
}
}
std::this_thread::sleep_for(1000ms);
}
}
@@ -0,0 +1,41 @@
/*-----------------------------------------*\
| RGBController_CorsairWireless.h |
| |
| Generic RGB Interface for Corsair RGB |
| wireless keyboard devices |
| |
| Adam Honse (CalcProgrammer1) 5/8/2021 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "CorsairWirelessController.h"
class RGBController_CorsairWireless : public RGBController
{
public:
RGBController_CorsairWireless(CorsairWirelessController* corsair_ptr);
~RGBController_CorsairWireless();
int physical_layout;
int logical_layout;
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
void KeepaliveThread();
private:
CorsairWirelessController* corsair;
std::thread* keepalive_thread;
std::atomic<bool> keepalive_thread_run;
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
};
@@ -0,0 +1,30 @@
#include "CreativeSoundBlasterXG6Controller.h"
#include "RGBController_CreativeSoundBlasterXG6.h"
#include "Detector.h"
#include <hidapi/hidapi.h>
/*-----------------------------------------------------*\
| Creative vendor ID |
\*-----------------------------------------------------*/
#define CREATIVE_VID 0x041E
/*-----------------------------------------------------*\
| SoundCards |
\*-----------------------------------------------------*/
#define CREATIVE_SOUNDBLASTERX_G6_PID 0x3256
void DetectCreativeDevice(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
CreativeSoundBlasterXG6Controller* controller = new CreativeSoundBlasterXG6Controller(dev, info->path);
RGBController_CreativeSoundBlasterXG6* rgb_controller = new RGBController_CreativeSoundBlasterXG6(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Sound Cards |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_I("Creative SoundBlasterX G6", DetectCreativeDevice, CREATIVE_VID, CREATIVE_SOUNDBLASTERX_G6_PID, 4);
@@ -0,0 +1,82 @@
#include "CreativeSoundBlasterXG6Controller.h"
CreativeSoundBlasterXG6Controller::CreativeSoundBlasterXG6Controller(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
CreativeSoundBlasterXG6Controller::~CreativeSoundBlasterXG6Controller()
{
hid_close(dev);
}
std::string CreativeSoundBlasterXG6Controller::GetDeviceLocation()
{
return("HID " + location);
}
void CreativeSoundBlasterXG6Controller::SetLedColor (unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
//5A 3A 02 06 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
usb_buf[0x01] = 0x5A;
usb_buf[0x02] = 0x3A;
usb_buf[0x03] = 0x02;
usb_buf[0x04] = 0x06;
usb_buf[0x05] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 64);
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
//5A 3A 06 04 00 03 01 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
usb_buf[0x01] = 0x5A;
usb_buf[0x02] = 0x3A;
usb_buf[0x03] = 0x06;
usb_buf[0x04] = 0x04;
usb_buf[0x06] = 0x03;
usb_buf[0x07] = 0x01;
usb_buf[0x09] = 0x01;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 64);
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
//5A 3A 09 0A 00 03 01 01 FF BB GG RR
usb_buf[0x01] = 0x5A;
usb_buf[0x02] = 0x3A;
usb_buf[0x03] = 0x09;
usb_buf[0x04] = 0x0A;
usb_buf[0x06] = 0x03;
usb_buf[0x07] = 0x01;
usb_buf[0x08] = 0x01;
usb_buf[0x09] = 0x0FF;
usb_buf[0x0A] = blue;
usb_buf[0x0B] = green;
usb_buf[0x0C] = red;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 64);
}
@@ -0,0 +1,20 @@
#include "RGBController.h"
#include <cstring>
#include <hidapi/hidapi.h>
#pragma once
class CreativeSoundBlasterXG6Controller
{
public:
CreativeSoundBlasterXG6Controller(hid_device* dev_handle, const char* path);
~CreativeSoundBlasterXG6Controller();
void SetLedColor (unsigned char red, unsigned char green, unsigned char blue);
std::string GetDeviceLocation();
std::string GetSerialString();
private:
hid_device* dev;
std::string location;
};
@@ -0,0 +1,81 @@
#include "RGBController_CreativeSoundBlasterXG6.h"
RGBController_CreativeSoundBlasterXG6::RGBController_CreativeSoundBlasterXG6(CreativeSoundBlasterXG6Controller* creative_device)
{
creative = creative_device;
name = "Creative SoundBlasterX G6 Device";
vendor = "Creative";
type = DEVICE_TYPE_HEADSET;
description = "Creative SoundBlasterX G6 Device";
location = creative_device->GetDeviceLocation();
serial = "";
mode Static;
Static.name = "Direct";
Static.value = 0;
Static.flags = MODE_COLORS_PER_LED;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
SetupZones();
}
RGBController_CreativeSoundBlasterXG6::~RGBController_CreativeSoundBlasterXG6()
{
delete creative;
}
void RGBController_CreativeSoundBlasterXG6::SetupZones()
{
zone logo_zone;
logo_zone.name = "Logo";
logo_zone.type = ZONE_TYPE_SINGLE;
logo_zone.leds_min = 1;
logo_zone.leds_max = 1;
logo_zone.leds_count = 1;
logo_zone.matrix_map = NULL;
zones.push_back(logo_zone);
led logo_led;
logo_led.name = "Logo";
leds.push_back(logo_led);
SetupColors();
}
void RGBController_CreativeSoundBlasterXG6::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_CreativeSoundBlasterXG6::DeviceUpdateLEDs()
{
unsigned char red = RGBGetRValue(colors[0]);
unsigned char grn = RGBGetGValue(colors[0]);
unsigned char blu = RGBGetBValue(colors[0]);
creative->SetLedColor(red, grn, blu);
}
void RGBController_CreativeSoundBlasterXG6::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_CreativeSoundBlasterXG6::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_CreativeSoundBlasterXG6::SetCustomMode()
{
active_mode = 0;
}
void RGBController_CreativeSoundBlasterXG6::DeviceUpdateMode()
{
DeviceUpdateLEDs();
}
@@ -0,0 +1,24 @@
#pragma once
#include "RGBController.h"
#include "CreativeSoundBlasterXG6Controller.h"
class RGBController_CreativeSoundBlasterXG6: public RGBController
{
public:
RGBController_CreativeSoundBlasterXG6(CreativeSoundBlasterXG6Controller* creative_device);
~RGBController_CreativeSoundBlasterXG6();
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void SetCustomMode();
void DeviceUpdateMode();
private:
CreativeSoundBlasterXG6Controller* creative;
};
@@ -16,8 +16,8 @@ static unsigned int matrix_map[6][23] =
{ { 0, NA, 12, 18, 24, 30, NA, 42, 48, 54, 60, NA, 66, 72, 78, 84, 90, 96, 102, 108, 114, 120, 126 },
{ 1, 7, 13, 19, 25, 31, 37, 43, 49, 55, 61, NA, 67, 73, 85, NA, 91, 97, 103, 109, 115, 121, 127 },
{ 2, NA, 8, 14, 20, 26, NA, 32, 38, 44, 50, 56, 62, 68, 74, 86, 92, 98, 104, 110, 116, 122, 128 },
{ 3, NA, 9, 15, 21, 27, NA, 33, 39, 45, 51, 57, 63, 69, 87, NA, NA, NA, NA, 111, 117, 123, NA },
{ 4, NA, 16, 22, 28, 34, NA, 40, NA, 46, 52, 58, 64, 70, 82, NA, NA, 100, NA, 112, 118, 124, 131 },
{ 3, NA, 9, 15, 21, 27, NA, 33, 39, 45, 51, 57, 63, 69, 75, 87, NA, NA, NA, 111, 117, 123, NA },
{ 4, 10, 16, 22, 28, 34, NA, 40, NA, 46, 52, 58, 64, 70, 82, NA, NA, 100, NA, 112, 118, 124, 131 },
{ 5, 11, 17, NA, NA, NA, NA, 41, NA, NA, NA, NA, 65, 77, 83, 89, 95, 101, 107, 113, NA, 125, NA } };
static const char* zone_names[] =
@@ -47,7 +47,7 @@ static const char *led_names[] =
"Key: 1",
"Key: Q",
"Key: A",
"Unused",
"Key: \\ (ISO)",
"Key: Left Windows",
"Key: F1",
"Key: 2",
@@ -112,7 +112,7 @@ static const char *led_names[] =
"Key: F10",
"Key: =",
"Key: ]",
"Unused",
"Key: #",
"Unused",
"Key: Right Windows",
"Key: F11",
@@ -293,9 +293,13 @@ RGBController_E131::RGBController_E131(std::vector<E131Device> device_list)
RGBController_E131::~RGBController_E131()
{
keepalive_thread_run = 0;
keepalive_thread->join();
delete keepalive_thread;
if(keepalive_thread != nullptr)
{
keepalive_thread_run = 0;
keepalive_thread->join();
delete keepalive_thread;
}
/*---------------------------------------------------------*\
| Delete the matrix map |
\*---------------------------------------------------------*/
@@ -41,6 +41,7 @@ static const gpu_pci_device device_list[] =
{ NVIDIA_VEN, NVIDIA_RTX2080_A_DEV, EVGA_SUB_VEN, EVGA_RTX2080_XC_GAMING_SUB_DEV, EVGA_RGB_V2, "EVGA GeForce RTX 2080 XC Gaming" },
{ NVIDIA_VEN, NVIDIA_RTX2080_A_DEV, EVGA_SUB_VEN, EVGA_RTX2080_XC_ULTRA_GAMING_SUB_DEV, EVGA_RGB_V2, "EVGA GeForce RTX 2080 XC Ultra Gaming" },
{ NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, EVGA_SUB_VEN, EVGA_RTX2080TI_XC_ULTRA_GAMING_SUB_DEV, EVGA_RGB_V2, "EVGA GeForce RTX 2080Ti XC Ultra" },
{ NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, EVGA_SUB_VEN, EVGA_RTX2080TI_FTW3_ULTRA_SUB_DEV , EVGA_RGB_V2, "EVGA GeForce RTX 2080Ti FTW3 Ultra" },
};
@@ -124,6 +124,8 @@ int RGBController_EVGAGPUv2::getModeIndex(unsigned char mode_value)
return mode_index;
}
}
return 0;
}
void RGBController_EVGAGPUv2::SetupZones()
@@ -182,7 +184,7 @@ void RGBController_EVGAGPUv2::UpdateSingleLED(int /*led*/)
void RGBController_EVGAGPUv2::SetCustomMode()
{
active_mode = getModeIndex(EVGA_GPU_V2_MODE_DIRECT);
active_mode = getModeIndex(EVGA_GPU_V2_RGB_MODE_DIRECT);
}
void RGBController_EVGAGPUv2::DeviceUpdateMode()
@@ -24,7 +24,7 @@
* *
\******************************************************************************************/
void DetectEVisionKeyboards(hid_device_info* info, const std::string& name)
void DetectEVisionKeyboards(hid_device_info* info, const std::string& /*name*/)
{
hid_device* dev = hid_open_path(info->path);
if( dev )
@@ -43,4 +43,4 @@ REGISTER_HID_DETECTOR_IP("EVision Keyboard 0C45:5204", DetectEVisionKeyboards,
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 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 0C45:8520", DetectEVisionKeyboards, EVISION_KEYBOARD_VID, WARRIOR_KANE_TC235, 1, EVISION_KEYBOARD_USAGE_PAGE);
@@ -113,7 +113,7 @@ void FanBusInterface::write_queue
{
unsigned char fanbus_msg[] = { 0x00, int_addr, dev_addr, val, 0xFF };
for(int i = 0; i < sizeof(fanbus_msg); i++)
for(unsigned int i = 0; i < sizeof(fanbus_msg); i++)
{
fanbus_msg_queued.push_back(fanbus_msg[i]);
}
@@ -43,7 +43,7 @@ void RGBController_FanBus::SetupZones()
led_zone.matrix_map = NULL;
zones.push_back(led_zone);
for(int led_idx = 0; led_idx < led_zone.leds_count; led_idx++)
for(unsigned int led_idx = 0; led_idx < led_zone.leds_count; led_idx++)
{
led new_led;
new_led.name = "LED ";
@@ -41,6 +41,7 @@ typedef struct
static const gpu_pci_device device_list[] =
{
{ NVIDIA_VEN, NVIDIA_GTX1080_DEV, GAINWARD_SUB_VEN, GAINWARD_GTX_1080_PHOENIX, RGB_V1, "Gainward GTX 1080 Phoenix" },
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, GAINWARD_SUB_VEN, NVIDIA_RTX2070S_DEV, RGB_V2, "Gainward RTX 2070 Super Phantom" },
{ NVIDIA_VEN, NVIDIA_RTX3070_DEV, GAINWARD_SUB_VEN, NVIDIA_RTX3070_DEV, RGB_V2, "Gainward RTX 3070 Phoenix" },
};
@@ -129,7 +129,7 @@ void RGBController_HoltekA1FA::DeviceUpdateMode()
if((active_mode < HOLTEK_A1FA_MODE_NEON) && (previous_mode < HOLTEK_A1FA_MODE_NEON))
{
//If we're switching from and to static and breathing then sync the mode colors
for ( int i = 0; i < modes[active_mode].colors_max; i++)
for(unsigned int i = 0; i < modes[active_mode].colors_max; i++)
{
modes[active_mode].colors[i] = modes[previous_mode].colors[i];
}
@@ -184,7 +184,7 @@ void LEDStripController::SetLEDsKeyboardVisualizer(std::vector<RGBColor> colors)
\*-------------------------------------------------------------*/
unsigned short sum = 0;
for (int i = 0; i < (payload_size + 1); i++)
for(unsigned int i = 0; i < (payload_size + 1); i++)
{
sum += serial_buf[i];
}
@@ -317,4 +317,4 @@ void LEDStripController::SetLEDsTPM2(std::vector<RGBColor> colors)
}
delete[] serial_buf;
}
}
@@ -0,0 +1,75 @@
/*-----------------------------------------*\
| LianLiControllerDetect.cpp |
| |
| Detector for Lian Li Uni Hub USB |
| lighting controller |
| |
| Luca Lovisa 2/20/2021 |
\*-----------------------------------------*/
#include <string>
#include <vector>
#include "Detector.h"
#include "LianLiUniHubController.h"
#include "RGBController_LianLiUniHub.h"
#include "ResourceManager.h"
#include <libusb-1.0/libusb.h>
#define UNI_HUB_VID 0x0CF2
#define UNI_HUB_PID 0x7750
/*----------------------------------------------------------------------------*\
| The Uni Hub is controlled by sending control transfers to various wIndex |
| addresses, allthough it announces some kind of hid interface. Hence it |
| requires libusb as hidapi provides no wIndex customization. |
\*----------------------------------------------------------------------------*/
void DetectLianLiUniHub(std::vector<RGBController*>&)
{
libusb_device** devices = nullptr;
int ret;
ret = libusb_init(NULL);
if(ret < 0)
{
return;
}
ret = libusb_get_device_list(NULL, &devices);
if(ret < 0)
{
return;
}
int deviceCount = ret;
for(int i = 0; i < deviceCount; i++)
{
libusb_device* device = devices[i];
libusb_device_descriptor descriptor;
ret = libusb_get_device_descriptor(device, &descriptor);
if (ret < 0)
{
continue;
}
if( descriptor.idVendor == UNI_HUB_VID
&& descriptor.idProduct == UNI_HUB_PID)
{
LianLiUniHubController* controller = new LianLiUniHubController(device, &descriptor);
RGBController_LianLiUniHub* rgb_controller = new RGBController_LianLiUniHub(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
if(devices != nullptr)
{
libusb_free_device_list(devices, 1);
}
}
REGISTER_DETECTOR("Lian Li Uni Hub", DetectLianLiUniHub);
@@ -0,0 +1,700 @@
/*-----------------------------------------*\
| LianLiUniHubController.cpp |
| |
| Driver for Lian Li Uni Hub USB |
| lighting controller |
| |
| Luca Lovisa 2/20/2021 |
\*-----------------------------------------*/
#include "LianLiUniHubController.h"
#include <cstring>
using namespace std::chrono_literals;
/*----------------------------------------------------------------------------*\
| The Uni Hub is controlled by sending control transfers to various wIndex |
| addresses, allthough it announces some kind of hid interface. Hence it |
| requires libusb as hidapi provides no wIndex customization. |
\*----------------------------------------------------------------------------*/
LianLiUniHubController::LianLiUniHubController
(
libusb_device* device,
libusb_device_descriptor* descriptor
)
{
int ret;
/*--------------------------------------------------------------------*\
| Open the libusb device. |
\*--------------------------------------------------------------------*/
ret = libusb_open(device, &handle);
if(ret < 0)
{
return;
}
/*--------------------------------------------------------------------*\
| Fill in the location string from USB port numbers. |
\*--------------------------------------------------------------------*/
uint8_t ports[7];
ret = libusb_get_port_numbers(device, ports, sizeof(ports));
if(ret > 0)
{
location = "USB: ";
for (int i = 0; i < ret; i ++)
{
location += std::to_string(ports[i]);
location.push_back(':');
}
location.pop_back();
}
/*--------------------------------------------------------------------*\
| Fill in the serial string from the string descriptor |
\*--------------------------------------------------------------------*/
char serialStr[64];
ret = libusb_get_string_descriptor_ascii(handle, descriptor->iSerialNumber, reinterpret_cast<unsigned char*>(serialStr), sizeof(serialStr));
if(ret > 0)
{
serial = std::string(serialStr, ret);
}
/*--------------------------------------------------------------------*\
| Fill in the version string by reading version from device. |
\*--------------------------------------------------------------------*/
version = ReadVersion();
/*--------------------------------------------------------------------*\
| Create channels with their static configuration and "sane" defaults. |
\*--------------------------------------------------------------------*/
Channel channel1;
channel1.index = 0;
channel1.anyFanCountOffset = UNIHUB_ANY_C1_FAN_COUNT_OFFSET;
channel1.anyFanCount = UNIHUB_ANY_FAN_COUNT_001;
channel1.ledActionAddress = UNIHUB_LED_C1_ACTION_ADDRESS;
channel1.ledCommitAddress = UNIHUB_LED_C1_COMMIT_ADDRESS;
channel1.ledModeAddress = UNIHUB_LED_C1_MODE_ADDRESS;
channel1.ledSpeedAddress = UNIHUB_LED_C1_SPEED_ADDRESS;
channel1.ledDirectionAddress = UNIHUB_LED_C1_DIRECTION_ADDRESS;
channel1.ledBrightnessAddress = UNIHUB_LED_C1_BRIGHTNESS_ADDRESS;
channel1.ledMode = UNIHUB_LED_MODE_RAINBOW;
channel1.ledSpeed = UNIHUB_LED_SPEED_100;
channel1.ledDirection = UNIHUB_LED_DIRECTION_LTR;
channel1.ledBrightness = UNIHUB_LED_BRIGHTNESS_100;
channel1.fanHubActionAddress = UNIHUB_FAN_C1_HUB_ACTION_ADDRESS;
channel1.fanHubCommitAddress = UNIHUB_FAN_C1_HUB_COMMIT_ADDRESS;
channel1.fanPwmActionAddress = UNIHUB_FAN_C1_PWM_ACTION_ADDRESS;
channel1.fanPwmCommitAddress = UNIHUB_FAN_C1_PWM_COMMIT_ADDRESS;
channel1.fanRpmActionAddress = UNIHUB_FAN_C1_RPM_ACTION_ADDRESS;
channel1.fanSpeed = UNIHUB_FAN_SPEED_QUIET;
channels[0] = channel1;
Channel channel2;
channel2.index = 1;
channel2.anyFanCountOffset = UNIHUB_ANY_C2_FAN_COUNT_OFFSET;
channel2.anyFanCount = UNIHUB_ANY_FAN_COUNT_001;
channel2.ledActionAddress = UNIHUB_LED_C2_ACTION_ADDRESS;
channel2.ledCommitAddress = UNIHUB_LED_C2_COMMIT_ADDRESS;
channel2.ledModeAddress = UNIHUB_LED_C2_MODE_ADDRESS;
channel2.ledSpeedAddress = UNIHUB_LED_C2_SPEED_ADDRESS;
channel2.ledDirectionAddress = UNIHUB_LED_C2_DIRECTION_ADDRESS;
channel2.ledBrightnessAddress = UNIHUB_LED_C2_BRIGHTNESS_ADDRESS;
channel2.ledMode = UNIHUB_LED_MODE_RAINBOW;
channel2.ledSpeed = UNIHUB_LED_SPEED_100;
channel2.ledDirection = UNIHUB_LED_DIRECTION_LTR;
channel2.ledBrightness = UNIHUB_LED_BRIGHTNESS_100;
channel2.fanHubActionAddress = UNIHUB_FAN_C2_HUB_ACTION_ADDRESS;
channel2.fanHubCommitAddress = UNIHUB_FAN_C2_HUB_COMMIT_ADDRESS;
channel2.fanPwmActionAddress = UNIHUB_FAN_C2_PWM_ACTION_ADDRESS;
channel2.fanPwmCommitAddress = UNIHUB_FAN_C2_PWM_COMMIT_ADDRESS;
channel2.fanRpmActionAddress = UNIHUB_FAN_C2_RPM_ACTION_ADDRESS;
channel2.fanSpeed = UNIHUB_FAN_SPEED_QUIET;
channels[1] = channel2;
Channel channel3;
channel3.index = 2;
channel3.anyFanCountOffset = UNIHUB_ANY_C3_FAN_COUNT_OFFSET;
channel3.anyFanCount = UNIHUB_ANY_FAN_COUNT_001;
channel3.ledActionAddress = UNIHUB_LED_C3_ACTION_ADDRESS;
channel3.ledCommitAddress = UNIHUB_LED_C3_COMMIT_ADDRESS;
channel3.ledModeAddress = UNIHUB_LED_C3_MODE_ADDRESS;
channel3.ledSpeedAddress = UNIHUB_LED_C3_SPEED_ADDRESS;
channel3.ledDirectionAddress = UNIHUB_LED_C3_DIRECTION_ADDRESS;
channel3.ledBrightnessAddress = UNIHUB_LED_C3_BRIGHTNESS_ADDRESS;
channel3.ledMode = UNIHUB_LED_MODE_RAINBOW;
channel3.ledSpeed = UNIHUB_LED_SPEED_100;
channel3.ledDirection = UNIHUB_LED_DIRECTION_LTR;
channel3.ledBrightness = UNIHUB_LED_BRIGHTNESS_100;
channel3.fanHubActionAddress = UNIHUB_FAN_C3_HUB_ACTION_ADDRESS;
channel3.fanHubCommitAddress = UNIHUB_FAN_C3_HUB_COMMIT_ADDRESS;
channel3.fanPwmActionAddress = UNIHUB_FAN_C3_PWM_ACTION_ADDRESS;
channel3.fanPwmCommitAddress = UNIHUB_FAN_C3_PWM_COMMIT_ADDRESS;
channel3.fanRpmActionAddress = UNIHUB_FAN_C3_RPM_ACTION_ADDRESS;
channel3.fanSpeed = UNIHUB_FAN_SPEED_QUIET;
channels[2] = channel3;
Channel channel4;
channel4.index = 3;
channel4.anyFanCountOffset = UNIHUB_ANY_C4_FAN_COUNT_OFFSET;
channel4.anyFanCount = UNIHUB_ANY_FAN_COUNT_001;
channel4.ledActionAddress = UNIHUB_LED_C4_ACTION_ADDRESS;
channel4.ledCommitAddress = UNIHUB_LED_C4_COMMIT_ADDRESS;
channel4.ledModeAddress = UNIHUB_LED_C4_MODE_ADDRESS;
channel4.ledSpeedAddress = UNIHUB_LED_C4_SPEED_ADDRESS;
channel4.ledDirectionAddress = UNIHUB_LED_C4_DIRECTION_ADDRESS;
channel4.ledBrightnessAddress = UNIHUB_LED_C4_BRIGHTNESS_ADDRESS;
channel4.ledMode = UNIHUB_LED_MODE_RAINBOW;
channel4.ledSpeed = UNIHUB_LED_SPEED_100;
channel4.ledDirection = UNIHUB_LED_DIRECTION_LTR;
channel4.ledBrightness = UNIHUB_LED_BRIGHTNESS_100;
channel4.fanHubActionAddress = UNIHUB_FAN_C4_HUB_ACTION_ADDRESS;
channel4.fanHubCommitAddress = UNIHUB_FAN_C4_HUB_COMMIT_ADDRESS;
channel4.fanPwmActionAddress = UNIHUB_FAN_C4_PWM_ACTION_ADDRESS;
channel4.fanPwmCommitAddress = UNIHUB_FAN_C4_PWM_COMMIT_ADDRESS;
channel4.fanRpmActionAddress = UNIHUB_FAN_C4_RPM_ACTION_ADDRESS;
channel4.fanSpeed = UNIHUB_FAN_SPEED_QUIET;
channels[3] = channel4;
}
LianLiUniHubController::~LianLiUniHubController()
{
CloseLibusb();
}
std::string LianLiUniHubController::GetVersion()
{
return version;
}
std::string LianLiUniHubController::GetLocation()
{
return location;
}
std::string LianLiUniHubController::GetSerial()
{
return serial;
}
void LianLiUniHubController::SetAnyFanCount(size_t channel, uint8_t count)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return;
}
channels[channel].anyFanCount = count;
}
void LianLiUniHubController::SetLedColors(size_t channel, RGBColor* colors, size_t count)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return;
}
/*-------------------------------------*\
| Check for invalid count |
\*-------------------------------------*/
if(count > UNIHUB_CHANLED_COUNT)
{
count = UNIHUB_CHANLED_COUNT;
}
size_t i = 0;
for(; i < count; i++)
{
channels[channel].colors[i].r = RGBGetRValue(colors[i]);
channels[channel].colors[i].b = RGBGetBValue(colors[i]);
channels[channel].colors[i].g = RGBGetGValue(colors[i]);
}
/* Set all remaining leds to black */
for(; i < UNIHUB_CHANLED_COUNT; i++)
{
channels[channel].colors[i].r = 0x00;
channels[channel].colors[i].b = 0x00;
channels[channel].colors[i].g = 0x00;
}
}
void LianLiUniHubController::SetLedMode(size_t channel, uint8_t mode)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return;
}
channels[channel].ledMode = mode;
}
void LianLiUniHubController::SetLedSpeed(size_t channel, uint8_t speed)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return;
}
channels[channel].ledSpeed = speed;
}
void LianLiUniHubController::SetLedDirection(size_t channel, uint8_t direction)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return;
}
channels[channel].ledDirection = direction;
}
void LianLiUniHubController::SetLedBrightness(size_t channel, uint8_t brightness)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return;
}
channels[channel].ledBrightness = brightness;
}
uint16_t LianLiUniHubController::GetFanSpeed(size_t channel)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return 0;
}
return channels[channel].fanSpeed;
}
void LianLiUniHubController::SetFanSpeed(size_t channel, uint16_t speed)
{
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel >= UNIHUB_CHANNEL_COUNT)
{
return;
}
channels[channel].fanSpeed = speed;
}
void LianLiUniHubController::EnableRgbhMode()
{
rgbhModeEnabled = true;
}
void LianLiUniHubController::DisableRgbhMode()
{
rgbhModeEnabled = false;
}
void LianLiUniHubController::EnableSyncMode()
{
syncModeEnabled = true;
}
void LianLiUniHubController::DisableSyncMode()
{
syncModeEnabled = false;
}
/*----------------------------------------------------------------------------*\
| The Uni Hub is a PWM and LED controller designed specifically for the Lian |
| Li Uni Fans. It can control them by itself using the built-in effect engine |
| can also be connected to the mainboard via 4-pin PWM and 3-pin RGB cables |
| and forward these signals. The protocol implementation below was build as |
| close a possible to the Lian Li L-Connect software. |
| |
| The commands to control the fan speeds and to switch between controller and |
| mainboard control is already included, but currently deactivated as OpenRGB |
| had no fan control module or controller specific configuration at the time |
| of writing. |
\*----------------------------------------------------------------------------*/
void LianLiUniHubController::Synchronize()
{
/*---------------------------------------------------------------------*\
| Configure common settings. |
\*---------------------------------------------------------------------*/
/*---------------------------------------------------------------------*\
| Still unsure about this. Probably some sort of configuration |
| initialization |
\*---------------------------------------------------------------------*/
uint8_t config_initialization[1] = { 0x34 };
SendConfig(UNIHUB_ACTION_ADDRESS, config_initialization, sizeof(config_initialization));
SendCommit(UNIHUB_COMMIT_ADDRESS);
for(const Channel& channel : channels)
{
/*-------------------------------------*\
| The Uni Hub doesn't know zero fans |
\*-------------------------------------*/
uint8_t anyFanCount = channel.anyFanCount;
if(anyFanCount == UNIHUB_ANY_FAN_COUNT_000)
{
anyFanCount = UNIHUB_ANY_FAN_COUNT_001;
}
/*-------------------------------------*\
| Configure the physical fan count |
\*-------------------------------------*/
uint8_t config_fan_count[2] = { 0x32, (uint8_t)(channel.anyFanCountOffset | anyFanCount) };
SendConfig(UNIHUB_ACTION_ADDRESS, config_fan_count, sizeof(config_fan_count));
SendCommit(UNIHUB_COMMIT_ADDRESS);
}
/*--------------------------------------------------------------------*\
| Configure channels for sync effects |
\*--------------------------------------------------------------------*/
if(syncModeEnabled)
{
uint8_t config_sync[6];
uint8_t config_sync_index = 0;
config_sync[config_sync_index++] = 0x33;
for(const Channel& channel : channels)
{
if(channel.anyFanCount != UNIHUB_ANY_FAN_COUNT_000)
{
config_sync[config_sync_index++] = channel.index;
}
}
config_sync[config_sync_index++] = 0x08;
SendConfig(UNIHUB_ACTION_ADDRESS, config_sync, config_sync_index);
SendCommit(UNIHUB_COMMIT_ADDRESS);
}
/*--------------------------------------------------------------------*\
| Configure led settings. |
\*--------------------------------------------------------------------*/
for(const Channel& channel : channels)
{
if(channel.anyFanCount != UNIHUB_ANY_FAN_COUNT_000)
{
/*-----------------------------*\
| Configure led colors |
\*-----------------------------*/
uint8_t config_colors[192];
memcpy(config_colors, channel.colors, sizeof(config_colors));
/*-----------------------------*\
| No idea what this does ... |
\*-----------------------------*/
if (syncModeEnabled)
{
config_colors[0x06] = 0x66;
config_colors[0x07] = 0x33;
config_colors[0x08] = 0xCC;
memset(config_colors + 0x09, 0x00, sizeof(config_colors) - 0x09);
}
SendConfig(channel.ledActionAddress, config_colors, sizeof(config_colors));
/*-----------------------------*\
| Configure led mode |
\*-----------------------------*/
uint8_t config_mode[1] = { channel.ledMode };
SendConfig(channel.ledModeAddress, config_mode, sizeof(config_mode));
}
/*-----------------------------------------------------------------*\
| The Uni Hub doesn't know zero fans so we set them to black |
\*-----------------------------------------------------------------*/
else
{
/*-----------------------------*\
| Configure led colors |
\*-----------------------------*/
uint8_t config_colors[192];
memset(config_colors, 0x00, sizeof(config_colors));
SendConfig(channel.ledActionAddress, config_colors, sizeof(config_colors));
/*-----------------------------*\
| Configure led mode |
\*-----------------------------*/
uint8_t config_mode[1] = { UNIHUB_LED_MODE_STATIC_COLOR };
SendConfig(channel.ledModeAddress, config_mode, sizeof(config_mode));
}
/*---------------------------------*\
| Configure led speed |
\*---------------------------------*/
uint8_t config_speed[1] = { channel.ledSpeed };
SendConfig(channel.ledSpeedAddress, config_speed, sizeof(config_speed));
/*---------------------------------*\
| Configure led direction |
\*---------------------------------*/
uint8_t config_direction[1] = { channel.ledDirection };
SendConfig(channel.ledDirectionAddress, config_direction, sizeof(config_direction));
/*---------------------------------*\
| Configure led brightness |
\*---------------------------------*/
uint8_t config_brightness[1] = { channel.ledBrightness };
SendConfig(channel.ledBrightnessAddress, config_brightness, sizeof(config_brightness));
/*---------------------------------*\
| Commit only once for all led |
| settings |
\*---------------------------------*/
SendCommit(channel.ledCommitAddress);
}
/*--------------------------------------------------------------------*\
| Configure fan settings. Comment out until enabling fan control |
\*--------------------------------------------------------------------*/
// uint8_t control = 0;
// /*-------------------------------------*\
// | Configure fan settings |
// \*-------------------------------------*/
// for(const Channel& channel : channels)
// {
// if(channel.fanSpeed == UNIHUB_FAN_SPEED_PWM)
// {
// /*-----------------------------*\
// | Configure the fan to pwm |
// | control |
// \*-----------------------------*/
// uint8_t config_pwm[1] = { 0x00 };
// control |= (0x01 << channel.index);
// SendConfig(channel.fanPwmActionAddress, config_pwm, sizeof(config_pwm));
// SendCommit(channel.fanPwmCommitAddress);
// }
// else
// {
// /*-----------------------------*\
// | Configure the fan to hub |
// | control and set speed |
// \*-----------------------------*/
// uint8_t config_hub[2] = { (uint8_t)(channel.fanSpeed >> 0x08), (uint8_t)(channel.fanSpeed & 0xFF) };
// SendConfig(channel.fanHubActionAddress, config_hub, sizeof(config_hub));
// SendCommit(channel.fanHubCommitAddress);
// }
// }
// /*-------------------------------------*\
// | Configure fan control modes |
// \*-------------------------------------*/
// uint8_t config_fan_mode[2] = { 0x31, (uint8_t)(0xF0 | control) };
// SendConfig(UNIHUB_ACTION_ADDRESS, config_fan_mode, sizeof(config_fan_mode));
// SendCommit(UNIHUB_COMMIT_ADDRESS);
/*--------------------------------------------------------------------*\
| Configure led settings. |
\*--------------------------------------------------------------------*/
if(rgbhModeEnabled)
{
/*-------------------------------------*\
| Configure the leds to hdr control. |
\*-------------------------------------*/
uint8_t config_hdr[2] = { 0x30, 0x01 };
SendConfig(UNIHUB_ACTION_ADDRESS, config_hdr, sizeof(config_hdr));
SendCommit(UNIHUB_COMMIT_ADDRESS);
}
else
{
/*-------------------------------------*\
| Configure the leds to hub control |
\*-------------------------------------*/
uint8_t config_hub[2] = { 0x30, 0x00 };
SendConfig(UNIHUB_ACTION_ADDRESS, config_hub, sizeof(config_hub));
SendCommit(UNIHUB_COMMIT_ADDRESS);
}
}
uint16_t LianLiUniHubController::ReadFanSpeed(size_t channel)
{
/*-------------------------------------*\
| Check for invalid handle |
\*-------------------------------------*/
if(handle == nullptr)
{
return(0);
}
/*-------------------------------------*\
| Check for invalid channel |
\*-------------------------------------*/
if(channel > UNIHUB_CHANNEL_COUNT)
{
return(0);
}
uint8_t buffer[2];
uint8_t length = sizeof(buffer);
uint16_t wIndex = channels[channel].fanRpmActionAddress;
/*-------------------------------------*\
| Send packet |
\*-------------------------------------*/
size_t ret = libusb_control_transfer(handle, /* dev_handle */
0xC0, /* bmRequestType */
0x81, /* bRequest */
0x00, /* wValue */
wIndex, /* wIndex */
buffer, /* data */
length, /* wLength */
1000); /* timeout */
/*-------------------------------------*\
| Check for communication error |
\*-------------------------------------*/
if(ret != length)
{
return(0);
}
return(*(uint16_t*)buffer);
}
void LianLiUniHubController::CloseLibusb()
{
if (handle != nullptr)
{
libusb_close(handle);
handle = nullptr;
}
}
std::string LianLiUniHubController::ReadVersion()
{
/*-------------------------------------*\
| Check for invalid handle |
\*-------------------------------------*/
if(handle == nullptr)
{
return("");
}
uint8_t buffer[5];
uint8_t length = sizeof(buffer);
/*-------------------------------------*\
| Send packet |
\*-------------------------------------*/
size_t ret = libusb_control_transfer(handle, /* dev_handle */
0xC0, /* bmRequestType */
0x81, /* bRequest */
0x00, /* wValue */
0xB500, /* wIndex */
buffer, /* data */
length, /* wLength */
1000); /* timeout */
/*-------------------------------------*\
| Check for communication error |
\*-------------------------------------*/
if(ret != length)
{
return("");
}
/*-------------------------------------*\
| Format version string |
\*-------------------------------------*/
char version[14];
int vlength = std::snprintf(version, sizeof(version), "%x.%x.%x.%x.%x", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4]);
return(std::string(version, vlength));
}
void LianLiUniHubController::SendConfig(uint16_t wIndex, uint8_t *config, size_t length)
{
/*-------------------------------------*\
| Check for invalid handle |
\*-------------------------------------*/
if(handle == nullptr)
{
return;
}
/*-------------------------------------*\
| Send packet |
\*-------------------------------------*/
size_t ret = libusb_control_transfer(handle, /* dev_handle */
0x40, /* bmRequestType */
0x80, /* bRequest */
0x00, /* wValue */
wIndex, /* wIndex */
config, /* data */
length, /* wLength */
1000); /* timeout */
/*-------------------------------------*\
| Check for communication error |
\*-------------------------------------*/
if(ret != length)
{
return;
}
}
void LianLiUniHubController::SendCommit(uint16_t wIndex)
{
/*-------------------------------------*\
| Set up config packet |
\*-------------------------------------*/
uint8_t config[1] = { 0x01 };
/*-------------------------------------*\
| Send packet |
\*-------------------------------------*/
SendConfig(wIndex, config, sizeof(config));
std::this_thread::sleep_for(5ms);
}
@@ -0,0 +1,263 @@
/*-----------------------------------------*\
| LianLiUniHubController.h |
| |
| Definitions and types for Lian Li Uni |
| Hub USB RGB lighting controller |
| |
| Luca Lovisa 2/20/2021 |
\*-----------------------------------------*/
#pragma once
#include <cstdint>
#include <mutex>
#include <string>
#include "RGBController.h"
#include <libusb-1.0/libusb.h>
/*----------------------------------------------------------------------------*\
| Global definitions. |
\*----------------------------------------------------------------------------*/
enum
{
UNIHUB_CHANNEL_COUNT = 0x04, /* Channel count */
UNIHUB_CHANLED_COUNT = 0x40, /* Max-LED per channel count */
};
enum
{
UNIHUB_ACTION_ADDRESS = 0xe021, /* Global action address */
UNIHUB_COMMIT_ADDRESS = 0xe02f, /* Global commit address */
};
enum
{
UNIHUB_ANY_C1_FAN_COUNT_OFFSET = 0x00, /* Channel 1 fan count offset */
UNIHUB_ANY_C2_FAN_COUNT_OFFSET = 0x10, /* Channel 2 fan count offset */
UNIHUB_ANY_C3_FAN_COUNT_OFFSET = 0x20, /* Channel 3 fan count offset */
UNIHUB_ANY_C4_FAN_COUNT_OFFSET = 0x30, /* Channel 4 fan count offset */
};
enum
{
UNIHUB_ANY_FAN_COUNT_000 = 0xFF, /* Fan count for 0 fans (dummy value) */
UNIHUB_ANY_FAN_COUNT_001 = 0x00, /* Fan count for 1 fan */
UNIHUB_ANY_FAN_COUNT_002 = 0x01, /* Fan count for 2 fans */
UNIHUB_ANY_FAN_COUNT_003 = 0x02, /* Fan count for 3 fans */
UNIHUB_ANY_FAN_COUNT_004 = 0x03, /* Fan count for 4 fans */
};
/*----------------------------------------------------------------------------*\
| Definitions related to led configuration. |
\*----------------------------------------------------------------------------*/
enum
{
UNIHUB_LED_C1_ACTION_ADDRESS = 0xe300, /* Channel 1 led action address */
UNIHUB_LED_C1_COMMIT_ADDRESS = 0xe02f, /* Channel 1 led commit address */
UNIHUB_LED_C1_MODE_ADDRESS = 0xe021, /* Channel 1 led mode address */
UNIHUB_LED_C1_SPEED_ADDRESS = 0xe022, /* Channel 1 led speed address */
UNIHUB_LED_C1_DIRECTION_ADDRESS = 0xe023, /* Channel 1 led direction address */
UNIHUB_LED_C1_BRIGHTNESS_ADDRESS = 0xe029, /* Channel 1 led brightness address */
UNIHUB_LED_C2_ACTION_ADDRESS = 0xe3c0, /* Channel 2 led action address */
UNIHUB_LED_C2_COMMIT_ADDRESS = 0xe03f, /* Channel 2 led commit address */
UNIHUB_LED_C2_MODE_ADDRESS = 0xe031, /* Channel 2 led mode address */
UNIHUB_LED_C2_SPEED_ADDRESS = 0xe032, /* Channel 2 led speed address */
UNIHUB_LED_C2_DIRECTION_ADDRESS = 0xe033, /* Channel 2 led direction address */
UNIHUB_LED_C2_BRIGHTNESS_ADDRESS = 0xe039, /* Channel 2 led brightness address */
UNIHUB_LED_C3_ACTION_ADDRESS = 0xe480, /* Channel 3 led action address */
UNIHUB_LED_C3_COMMIT_ADDRESS = 0xe04f, /* Channel 3 led commit address */
UNIHUB_LED_C3_MODE_ADDRESS = 0xe041, /* Channel 3 led mode address */
UNIHUB_LED_C3_SPEED_ADDRESS = 0xe042, /* Channel 3 led speed address */
UNIHUB_LED_C3_DIRECTION_ADDRESS = 0xe043, /* Channel 3 led direction address */
UNIHUB_LED_C3_BRIGHTNESS_ADDRESS = 0xe049, /* Channel 3 led brightness address */
UNIHUB_LED_C4_ACTION_ADDRESS = 0xe540, /* Channel 4 led action address */
UNIHUB_LED_C4_COMMIT_ADDRESS = 0xe05f, /* Channel 4 led commit address */
UNIHUB_LED_C4_MODE_ADDRESS = 0xe051, /* Channel 4 led mode address */
UNIHUB_LED_C4_SPEED_ADDRESS = 0xe052, /* Channel 4 led speed address */
UNIHUB_LED_C4_DIRECTION_ADDRESS = 0xe053, /* Channel 4 led direction address */
UNIHUB_LED_C4_BRIGHTNESS_ADDRESS = 0xe059, /* Channel 4 led brightness address */
};
enum
{
UNIHUB_LED_MODE_RAINBOW = 0x05, /* Rainbow mode */
UNIHUB_LED_MODE_STATIC_COLOR = 0x01, /* Static Color mode */
UNIHUB_LED_MODE_BREATHING = 0x02, /* Breathing mode */
UNIHUB_LED_MODE_COLOR_CYCLE = 0x04, /* Color Cycle mode */
UNIHUB_LED_MODE_RUNWAY = 0x1c, /* Runway mode */
UNIHUB_LED_MODE_RUNWAY_SYNC = 0x1c, /* Runway Sync mode */
UNIHUB_LED_MODE_STAGGGERED = 0x18, /* Stagggered mode */
UNIHUB_LED_MODE_MIXING = 0x1a, /* Mixing mode */
UNIHUB_LED_MODE_METEOR = 0x07, /* Meteor mode */
UNIHUB_LED_MODE_METEOR_SYNC = 0x07, /* Meteor Sync mode */
UNIHUB_LED_MODE_FIREWORK = 0x1f, /* Firework mode */
UNIHUB_LED_MODE_STACK = 0x21, /* Stack mode */
UNIHUB_LED_MODE_STACK_MULTI_COLOR = 0x22, /* Stack Multi Color mode */
UNIHUB_LED_MODE_NEON = 0x23, /* Neon mode */
};
enum
{
UNIHUB_LED_SPEED_000 = 0x04, /* Very slow speed */
UNIHUB_LED_SPEED_025 = 0x03, /* Rather slow speed */
UNIHUB_LED_SPEED_050 = 0x02, /* Medium speed */
UNIHUB_LED_SPEED_075 = 0x01, /* Rather fast speed */
UNIHUB_LED_SPEED_100 = 0x00, /* Very fast speed */
};
enum
{
UNIHUB_LED_DIRECTION_LTR = 0x00, /* Left-to-Right direction */
UNIHUB_LED_DIRECTION_RTL = 0x01, /* Right-to-Left direction */
};
enum
{
UNIHUB_LED_BRIGHTNESS_000 = 0x08, /* Very dark (off) */
UNIHUB_LED_BRIGHTNESS_025 = 0x03, /* Rather dark */
UNIHUB_LED_BRIGHTNESS_050 = 0x02, /* Medium bright */
UNIHUB_LED_BRIGHTNESS_075 = 0x01, /* Rather bright */
UNIHUB_LED_BRIGHTNESS_100 = 0x00, /* Very bright */
};
/*----------------------------------------------------------------------------*\
| Definitions related to fan configuration. |
\*----------------------------------------------------------------------------*/
enum
{
UNIHUB_FAN_C1_HUB_ACTION_ADDRESS = 0xe8a0, /* Channel 1 fan action address for hub control */
UNIHUB_FAN_C1_HUB_COMMIT_ADDRESS = 0xe890, /* Channel 1 fan commit address for hub control */
UNIHUB_FAN_C1_PWM_ACTION_ADDRESS = 0xe890, /* Channel 1 fan action address for pwm control */
UNIHUB_FAN_C1_PWM_COMMIT_ADDRESS = 0xe818, /* Channel 1 fan commit address for pwm control */
UNIHUB_FAN_C1_RPM_ACTION_ADDRESS = 0xe800, /* Channel 1 fan pwm read address */
UNIHUB_FAN_C2_HUB_ACTION_ADDRESS = 0xe8a2, /* Channel 2 fan action address for hub control */
UNIHUB_FAN_C2_HUB_COMMIT_ADDRESS = 0xe891, /* Channel 2 fan commit address for hub control */
UNIHUB_FAN_C2_PWM_ACTION_ADDRESS = 0xe891, /* Channel 2 fan action address for pwm control */
UNIHUB_FAN_C2_PWM_COMMIT_ADDRESS = 0xe81a, /* Channel 2 fan commit address for pwm control */
UNIHUB_FAN_C2_RPM_ACTION_ADDRESS = 0xe802, /* Channel 1 fan pwm read address */
UNIHUB_FAN_C3_HUB_ACTION_ADDRESS = 0xe8a4, /* Channel 3 fan action address for hub control */
UNIHUB_FAN_C3_HUB_COMMIT_ADDRESS = 0xe892, /* Channel 3 fan commit address for hub control */
UNIHUB_FAN_C3_PWM_ACTION_ADDRESS = 0xe892, /* Channel 3 fan action address for pwm control */
UNIHUB_FAN_C3_PWM_COMMIT_ADDRESS = 0xe81c, /* Channel 3 fan commit address for pwm control */
UNIHUB_FAN_C3_RPM_ACTION_ADDRESS = 0xe804, /* Channel 1 fan pwm read address */
UNIHUB_FAN_C4_HUB_ACTION_ADDRESS = 0xe8a6, /* Channel 4 fan action address for hub control */
UNIHUB_FAN_C4_HUB_COMMIT_ADDRESS = 0xe893, /* Channel 4 fan commit address for hub control */
UNIHUB_FAN_C4_PWM_ACTION_ADDRESS = 0xe893, /* Channel 4 fan action address for pwm control */
UNIHUB_FAN_C4_PWM_COMMIT_ADDRESS = 0xe81e, /* Channel 4 fan commit address for pwm control */
UNIHUB_FAN_C4_RPM_ACTION_ADDRESS = 0xe806, /* Channel 1 fan pwm read address */
};
enum
{
UNIHUB_FAN_SPEED_QUIET = 0x2003, /* Rather slow */
UNIHUB_FAN_SPEED_HIGH_SPEED = 0x2206, /* Rather fast */
UNIHUB_FAN_SPEED_FULL_SPEED = 0x6c07, /* BRRRRRRRRRR */
UNIHUB_FAN_SPEED_PWM = 0xffff, /* PWM Control */
};
/*----------------------------------------------------------------------------*\
| Uni Hub controller. |
\*----------------------------------------------------------------------------*/
class LianLiUniHubController
{
private:
/* The Uni Hub requires colors in RBG order */
struct Color
{
uint8_t r;
uint8_t b;
uint8_t g;
};
/* The values correspond to the definitions above */
struct Channel
{
uint8_t index;
uint8_t anyFanCountOffset;
uint8_t anyFanCount;
uint16_t ledActionAddress;
uint16_t ledCommitAddress;
uint16_t ledModeAddress;
uint16_t ledSpeedAddress;
uint16_t ledDirectionAddress;
uint16_t ledBrightnessAddress;
Color colors[UNIHUB_CHANLED_COUNT];
uint8_t ledMode;
uint8_t ledSpeed;
uint8_t ledDirection;
uint8_t ledBrightness;
uint16_t fanHubActionAddress;
uint16_t fanHubCommitAddress;
uint16_t fanPwmActionAddress;
uint16_t fanPwmCommitAddress;
uint16_t fanRpmActionAddress;
uint16_t fanSpeed;
};
public:
LianLiUniHubController
(
libusb_device* device,
libusb_device_descriptor* descriptor
);
~LianLiUniHubController();
std::string GetVersion();
std::string GetLocation();
std::string GetSerial();
void SetAnyFanCount(size_t channel, uint8_t count);
void SetLedColors(size_t channel, RGBColor* colors, size_t count);
void SetLedMode(size_t channel, uint8_t mode);
void SetLedSpeed(size_t channel, uint8_t speed);
void SetLedDirection(size_t channel, uint8_t direction);
void SetLedBrightness(size_t channel, uint8_t brightness);
uint16_t GetFanSpeed(size_t channel);
void SetFanSpeed(size_t channel, uint16_t speed);
void EnableRgbhMode();
void DisableRgbhMode();
void EnableSyncMode();
void DisableSyncMode();
uint16_t ReadFanSpeed(size_t channel);
/*-----------------------------------------------------*\
| Synchronize the current configuration to the Uni Hub. |
\*-----------------------------------------------------*/
void Synchronize();
private:
libusb_device_handle* handle = nullptr;
std::string version;
std::string location;
std::string serial;
bool rgbhModeEnabled = false;
bool syncModeEnabled = false;
Channel channels[UNIHUB_CHANNEL_COUNT];
void CloseLibusb();
std::string ReadVersion();
void SendConfig(uint16_t wIndex, uint8_t *config, size_t length);
void SendCommit(uint16_t wIndex);
};
@@ -0,0 +1,475 @@
/*-----------------------------------------*\
| RGBController_LianLiUniHub.cpp |
| |
| Generic RGB Interface for Lian Li Uni |
| Hub USB controller driver |
| |
| Luca Lovisa 2/20/2021 |
\*-----------------------------------------*/
#include "RGBController_LianLiUniHub.h"
#include <string>
mode makeMode()
{
mode Mode;
Mode.value = 0;
Mode.flags = 0;
Mode.speed_min = 0;
Mode.speed_max = 0;
Mode.colors_min = 0;
Mode.colors_max = 0;
Mode.speed = 0;
Mode.direction = 0;
Mode.color_mode = 0;
return Mode;
}
RGBController_LianLiUniHub::RGBController_LianLiUniHub(LianLiUniHubController* uniHub_ptr)
{
uniHub = uniHub_ptr;
name = "Lian Li Uni Hub";
vendor = "Lian Li";
version = uniHub->GetVersion();
type = DEVICE_TYPE_COOLER;
description = "Lian Li Uni Hub";
location = uniHub->GetLocation();
serial = uniHub->GetSerial();
initializedMode = false;
mode StaticColor = makeMode();
StaticColor.name = "Custom";
StaticColor.value = UNIHUB_LED_MODE_STATIC_COLOR;
StaticColor.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_PER_LED_COLOR;
StaticColor.color_mode = MODE_COLORS_PER_LED;
modes.push_back(StaticColor);
mode Rainbow = makeMode();
Rainbow.name = "Rainbow Wave";
Rainbow.value = UNIHUB_LED_MODE_RAINBOW;
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR;
Rainbow.speed_min = 1;
Rainbow.speed_max = 5;
Rainbow.color_mode = MODE_COLORS_NONE;
modes.push_back(Rainbow);
mode Breathing = makeMode();
Breathing.name = "Breathing";
Breathing.value = UNIHUB_LED_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_PER_LED_COLOR;
Breathing.speed_min = 1;
Breathing.speed_max = 5;
Breathing.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Breathing);
mode ColorCycle = makeMode();
ColorCycle.name = "Color Cycle";
ColorCycle.value = UNIHUB_LED_MODE_COLOR_CYCLE;
ColorCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
ColorCycle.speed_min = 1;
ColorCycle.speed_max = 5;
ColorCycle.colors_min = 3;
ColorCycle.colors_max = 3;
ColorCycle.color_mode = MODE_COLORS_MODE_SPECIFIC;
ColorCycle.colors.resize(3);
modes.push_back(ColorCycle);
mode Runway = makeMode();
Runway.name = "Runway";
Runway.value = UNIHUB_LED_MODE_RUNWAY;
Runway.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Runway.speed_min = 1;
Runway.speed_max = 5;
Runway.colors_min = 2;
Runway.colors_max = 2;
Runway.color_mode = MODE_COLORS_MODE_SPECIFIC;
Runway.colors.resize(2);
modes.push_back(Runway);
mode RunwaySync = makeMode();
RunwaySync.name = "Runway Sync";
RunwaySync.value = UNIHUB_LED_MODE_RUNWAY_SYNC | 0x0100;
RunwaySync.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
RunwaySync.speed_min = 1;
RunwaySync.speed_max = 5;
RunwaySync.colors_min = 2;
RunwaySync.colors_max = 2;
RunwaySync.color_mode = MODE_COLORS_MODE_SPECIFIC;
RunwaySync.colors.resize(2);
modes.push_back(RunwaySync);
mode Staggered = makeMode();
Staggered.name = "Staggered";
Staggered.value = UNIHUB_LED_MODE_STAGGGERED;
Staggered.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Staggered.speed_min = 1;
Staggered.speed_max = 5;
Staggered.colors_min = 2;
Staggered.colors_max = 2;
Staggered.color_mode = MODE_COLORS_MODE_SPECIFIC;
Staggered.colors.resize(2);
modes.push_back(Staggered);
mode Mixing = makeMode();
Mixing.name = "Mixing";
Mixing.value = UNIHUB_LED_MODE_MIXING;
Mixing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Mixing.speed_min = 1;
Mixing.speed_max = 5;
Mixing.colors_min = 2;
Mixing.colors_max = 2;
Mixing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Mixing.colors.resize(2);
modes.push_back(Mixing);
mode Meteor = makeMode();
Meteor.name = "Meteor";
Meteor.value = UNIHUB_LED_MODE_METEOR;
Meteor.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Meteor.speed_min = 1;
Meteor.speed_max = 5;
Meteor.colors_min = 2;
Meteor.colors_max = 2;
Meteor.color_mode = MODE_COLORS_MODE_SPECIFIC;
Meteor.colors.resize(2);
modes.push_back(Meteor);
mode MeteorSync = makeMode();
MeteorSync.name = "Meteor Sync";
MeteorSync.value = UNIHUB_LED_MODE_METEOR_SYNC | 0x0100;
MeteorSync.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
MeteorSync.speed_min = 1;
MeteorSync.speed_max = 5;
MeteorSync.colors_min = 2;
MeteorSync.colors_max = 2;
MeteorSync.color_mode = MODE_COLORS_MODE_SPECIFIC;
MeteorSync.colors.resize(2);
modes.push_back(MeteorSync);
mode Firework = makeMode();
Firework.name = "Firework";
Firework.value = UNIHUB_LED_MODE_FIREWORK;
Firework.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Firework.speed_min = 1;
Firework.speed_max = 5;
Firework.colors_min = 2;
Firework.colors_max = 2;
Firework.color_mode = MODE_COLORS_MODE_SPECIFIC;
Firework.colors.resize(2);
modes.push_back(Firework);
mode Stack = makeMode();
Stack.name = "Stack";
Stack.value = UNIHUB_LED_MODE_STACK;
Stack.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Stack.speed_min = 1;
Stack.speed_max = 5;
Stack.colors_min = 1;
Stack.colors_max = 1;
Stack.color_mode = MODE_COLORS_MODE_SPECIFIC;
Stack.colors.resize(1);
modes.push_back(Stack);
mode StackMultiColor = makeMode();
StackMultiColor.name = "Stack Multi Color";
StackMultiColor.value = UNIHUB_LED_MODE_STACK_MULTI_COLOR;
StackMultiColor.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR;
StackMultiColor.speed_min = 1;
StackMultiColor.speed_max = 5;
StackMultiColor.color_mode = MODE_COLORS_NONE;
modes.push_back(StackMultiColor);
mode Neon = makeMode();
Neon.name = "Neon";
Neon.value = UNIHUB_LED_MODE_NEON;
Neon.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Neon.speed_min = 1;
Neon.speed_max = 5;
Neon.color_mode = MODE_COLORS_NONE;
modes.push_back(Neon);
mode Rgbh = makeMode();
Rgbh.name = "RGB Header";
Rgbh.value = UNIHUB_LED_MODE_STATIC_COLOR | 0x0200;
Rgbh.flags = 0;
Rgbh.color_mode = MODE_COLORS_NONE;
modes.push_back(Rgbh);
RGBController_LianLiUniHub::SetupZones();
}
void RGBController_LianLiUniHub::SetupZones()
{
/*-------------------------------------------------*\
| Only set LED count on the first run |
\*-------------------------------------------------*/
bool first_run = false;
if(zones.size() == 0)
{
first_run = true;
}
/*-------------------------------------------------*\
| Clear any existing color/LED configuration |
\*-------------------------------------------------*/
leds.clear();
colors.clear();
zones.resize(UNIHUB_CHANNEL_COUNT);
/*-------------------------------------------------*\
| Set zones and leds |
\*-------------------------------------------------*/
int addressableCounter = 1;
for(unsigned int channel_idx = 0; channel_idx < zones.size(); channel_idx++)
{
zones[channel_idx].name = "Channel ";
zones[channel_idx].name.append(std::to_string(addressableCounter));
addressableCounter++;
zones[channel_idx].type = ZONE_TYPE_LINEAR;
zones[channel_idx].leds_min = 0;
zones[channel_idx].leds_max = UNIHUB_CHANLED_COUNT;
if(first_run)
{
zones[channel_idx].leds_count = zones[channel_idx].leds_min;
}
for(unsigned int led_ch_idx = 0; led_ch_idx < zones[channel_idx].leds_count; led_ch_idx++)
{
led new_led;
new_led.name = zones[channel_idx].name;
new_led.name.append(", LED ");
new_led.name.append(std::to_string(led_ch_idx + 1));
new_led.value = channel_idx;
leds.push_back(new_led);
}
zones[channel_idx].matrix_map = NULL;
}
SetupColors();
}
void RGBController_LianLiUniHub::ResizeZone(int zone, int new_size)
{
if((size_t) zone >= zones.size())
{
return;
}
if(((unsigned int)new_size >= zones[zone].leds_min) && ((unsigned int)new_size <= zones[zone].leds_max))
{
zones[zone].leds_count = new_size;
SetupZones();
}
}
void RGBController_LianLiUniHub::DeviceUpdateLEDs()
{
if(!initializedMode)
{
DeviceUpdateMode();
}
for(size_t channel = 0; channel < zones.size(); channel++)
{
uint8_t fanCount = convertLedCountToFanCount(zones[channel].leds_count);
uniHub->SetAnyFanCount(channel, convertAnyFanCount(fanCount));
uniHub->SetLedColors(channel, zones[channel].colors, zones[channel].leds_count);
}
uniHub->Synchronize();
}
void RGBController_LianLiUniHub::UpdateZoneLEDs(int zone)
{
if(!initializedMode)
{
DeviceUpdateMode();
}
unsigned int channel = zone;
uint8_t fanCount = convertLedCountToFanCount(zones[channel].leds_count);
uniHub->SetAnyFanCount(channel, convertAnyFanCount(fanCount));
uniHub->SetLedColors(channel, zones[channel].colors, zones[channel].leds_count);
uniHub->Synchronize();
}
void RGBController_LianLiUniHub::UpdateSingleLED(int led)
{
if(!initializedMode)
{
DeviceUpdateMode();
}
unsigned int channel = leds[led].value;
uint8_t fanCount = convertLedCountToFanCount(zones[channel].leds_count);
uniHub->SetAnyFanCount(channel, convertAnyFanCount(fanCount));
uniHub->SetLedColors(channel, zones[channel].colors, zones[channel].leds_count);
uniHub->Synchronize();
}
void RGBController_LianLiUniHub::DeviceUpdateMode()
{
initializedMode = true;
for (size_t channel = 0; channel < zones.size(); channel++)
{
uint8_t fanCount = convertLedCountToFanCount(zones[channel].leds_count);
uniHub->SetAnyFanCount(channel, convertAnyFanCount(fanCount));
switch (modes[active_mode].color_mode)
{
case MODE_COLORS_PER_LED:
uniHub->SetLedColors(channel, zones[channel].colors, zones[channel].leds_count);
break;
case MODE_COLORS_MODE_SPECIFIC:
uniHub->SetLedColors(channel, modes[active_mode].colors.data(), modes[active_mode].colors.size());
break;
default:
uniHub->SetLedColors(channel, nullptr, 0);
break;
}
uniHub->SetLedMode(channel, modes[active_mode].value);
if(modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
{
uniHub->SetLedSpeed(channel, convertLedSpeed(modes[active_mode].speed));
}
else
{
uniHub->SetLedSpeed(channel, UNIHUB_LED_SPEED_000);
}
if(modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR)
{
uniHub->SetLedDirection(channel, convertLedDirection(modes[active_mode].direction));
}
else
{
uniHub->SetLedDirection(channel, UNIHUB_LED_DIRECTION_LTR);
}
}
if(modes[active_mode].value & 0x0200)
{
uniHub->EnableRgbhMode();
uniHub->DisableSyncMode();
}
else if (modes[active_mode].value & 0x0100)
{
uniHub->DisableRgbhMode();
uniHub->EnableSyncMode();
}
else
{
uniHub->DisableRgbhMode();
uniHub->DisableSyncMode();
}
uniHub->Synchronize();
}
void RGBController_LianLiUniHub::SetCustomMode()
{
/*-------------------------------------------------*\
| Set mode to Static Color |
\*-------------------------------------------------*/
active_mode = 0;
}
uint8_t RGBController_LianLiUniHub::convertAnyFanCount(uint8_t count)
{
switch (count)
{
case 0:
return UNIHUB_ANY_FAN_COUNT_000;
case 1:
return UNIHUB_ANY_FAN_COUNT_001;
case 2:
return UNIHUB_ANY_FAN_COUNT_002;
case 3:
return UNIHUB_ANY_FAN_COUNT_003;
case 4:
return UNIHUB_ANY_FAN_COUNT_004;
default:
return UNIHUB_ANY_FAN_COUNT_001;
}
}
uint8_t RGBController_LianLiUniHub::convertLedSpeed(uint8_t speed)
{
switch (speed)
{
case 1:
return UNIHUB_LED_SPEED_000;
case 2:
return UNIHUB_LED_SPEED_025;
case 3:
return UNIHUB_LED_SPEED_050;
case 4:
return UNIHUB_LED_SPEED_075;
case 5:
return UNIHUB_LED_SPEED_100;
default:
return UNIHUB_LED_SPEED_050;
}
}
uint8_t RGBController_LianLiUniHub::convertLedDirection(uint8_t direction)
{
switch (direction)
{
case 0:
return UNIHUB_LED_DIRECTION_LTR;
case 1:
return UNIHUB_LED_DIRECTION_RTL;
default:
return UNIHUB_LED_DIRECTION_LTR;
}
}
uint8_t RGBController_LianLiUniHub::convertLedCountToFanCount(uint8_t count)
{
/*-------------------------------------------------*\
| Converts 0 to 0, 1-16 to 1, 17-32 to 2, 33-48 to |
| 3 and 49-64+ to 4 |
\*-------------------------------------------------*/
if (count == 0x00)
{
return 0x00;
}
if (count >= 0x40)
{
count = 0x40;
}
return((count -1) / 16 + 1);
}
@@ -0,0 +1,45 @@
/*-----------------------------------------*\
| RGBController_LianLiUniHub.h |
| |
| Generic RGB Interface for Lian Li Uni |
| Hub USB controller driver |
| |
| Luca Lovisa 2/20/2021 |
\*-----------------------------------------*/
#pragma once
#include <cstdint>
#include <vector>
#include "LianLiUniHubController.h"
#include "RGBController.h"
class RGBController_LianLiUniHub : public RGBController
{
public:
RGBController_LianLiUniHub(LianLiUniHubController* uniHub_ptr);
void SetupZones();
void ResizeZone(int zone, int new_size);
void DeviceUpdateLEDs();
void UpdateZoneLEDs(int zone);
void UpdateSingleLED(int led);
void DeviceUpdateMode();
void SetCustomMode();
private:
uint8_t convertAnyFanCount(uint8_t count);
uint8_t convertLedSpeed(uint8_t speed);
uint8_t convertLedDirection(uint8_t direction);
uint8_t convertLedCountToFanCount(uint8_t count);
private:
LianLiUniHubController* uniHub;
bool initializedMode;
};
@@ -1,26 +1,24 @@
#include "Detector.h"
#include "LogitechG203Controller.h"
#include "LogManager.h"
#include "LogitechProtocolCommon.h"
#include "LogitechG203LController.h"
#include "LogitechG213Controller.h"
#include "LogitechG303Controller.h"
#include "LogitechG403Controller.h"
#include "LogitechG502PSController.h"
#include "LogitechG560Controller.h"
#include "LogitechG810Controller.h"
#include "LogitechG910Controller.h"
#include "LogitechG815Controller.h"
#include "LogitechGProWirelessController.h"
#include "LogitechGPowerPlayController.h"
#include "LogitechGLightsyncController.h"
#include "LogitechLightspeedController.h"
#include "RGBController.h"
#include "RGBController_LogitechG203.h"
#include "RGBController_LogitechG203L.h"
#include "RGBController_LogitechG213.h"
#include "RGBController_LogitechG303.h"
#include "RGBController_LogitechG403.h"
#include "RGBController_LogitechG502PS.h"
#include "RGBController_LogitechG560.h"
#include "RGBController_LogitechG810.h"
#include "RGBController_LogitechG910.h"
#include "RGBController_LogitechG815.h"
#include "RGBController_LogitechGProWireless.h"
#include "RGBController_LogitechGLightsync.h"
#include "RGBController_LogitechGLightsync1zone.h"
#include "RGBController_LogitechLightspeed.h"
#include "RGBController_LogitechGPowerPlay.h"
#include <vector>
#include <hidapi/hidapi.h>
@@ -29,6 +27,7 @@
| Logitech vendor ID |
\*-----------------------------------------------------*/
#define LOGITECH_VID 0x046D
/*-----------------------------------------------------*\
| Keyboard product IDs |
\*-----------------------------------------------------*/
@@ -41,29 +40,72 @@
#define LOGITECH_G810_2_PID 0xC337
#define LOGITECH_G813_PID 0xC232
#define LOGITECH_G815_PID 0xC33F
#define LOGITECH_G910_ORION_SPARK_PID 0xC32B
#define LOGITECH_G910_PID 0xC335
/*-----------------------------------------------------*\
| Mouse product IDs |
\*-----------------------------------------------------*/
#define LOGITECH_G203_PID 0xC084
#define LOGITECH_G203L_PID 0xC092
#define LOGITECH_G203_LIGHTSYNC_PID 0xC092
#define LOGITECH_G303_PID 0xC080
#define LOGITECH_G403_PID 0xC083
#define LOGITECH_G403H_PID 0xC08F
#define LOGITECH_G502_PS_PID 0xC332
#define LOGITECH_G502H_PID 0xC08B
#define LOGITECH_G_LIGHTSPEED_WIRELESS_PID 0xC539
#define LOGITECH_GPRO_WIRED_PID 0xC085
#define LOGITECH_GPRO_HERO_WIRED_PID 0xC08C
#define LOGITECH_GPRO_WIRELESS_PID 0xC088
#define LOGITECH_G403_HERO_PID 0xC08F
#define LOGITECH_G403_LIGHTSPEED_PID 0xC082
#define LOGITECH_G502_PROTEUS_SPECTRUM_PID 0xC332
#define LOGITECH_G502_HERO_PID 0xC08B
#define LOGITECH_G502_LIGHTSPEED_PID 0xC08D
#define LOGITECH_G703_LIGHTSPEED_PID 0xC087
#define LOGITECH_G900_LIGHTSPEED_PID 0xC081
#define LOGITECH_G903_LIGHTSPEED_PID 0xC086
#define LOGITECH_G_PRO_PID 0xC085
#define LOGITECH_G_PRO_HERO_PID 0xC08C
#define LOGITECH_G_PRO_WIRELESS_PID 0xC088
/*-----------------------------------------------------*\
| Mousemat product IDs |
\*-----------------------------------------------------*/
#define LOGITECH_G_LIGHTSPEED_POWERPLAY_PID 0xC53A
/*-----------------------------------------------------*\
| Speaker product IDs |
\*-----------------------------------------------------*/
#define LOGITECH_G560_PID 0x0A78
/*-----------------------------------------------------*\
| Unifying Device IDs (Including Lightspeed receivers) |
| NB: Not used but preserved for debugging |
\*-----------------------------------------------------*/
#define LOGITECH_G_UNIFYING_RECEIVER_1_PID 0xC52B
#define LOGITECH_G_NANO_RECEIVER_PID 0xC52F
#define LOGITECH_G_G700_RECEIVER_PID 0xC531
#define LOGITECH_G_UNIFYING_RECEIVER_2_PID 0xC532
#define LOGITECH_G_G602_RECEIVER_PID 0xC537
#define LOGITECH_G_LIGHTSPEED_RECEIVER_PID 0xC539
#define LOGITECH_G403_LIGHTSPEED_VIRTUAL_PID 0x405D
#define LOGITECH_G502_LIGHTSPEED_VIRTUAL_PID 0x407F
#define LOGITECH_G703_LIGHTSPEED_VIRTUAL_PID 0x4070
#define LOGITECH_G900_LIGHTSPEED_VIRTUAL_PID 0x4053
#define LOGITECH_G903_LIGHTSPEED_VIRTUAL_PID 0x4067
#define LOGITECH_G_PRO_WIRELESS_VIRTUAL_PID 0x4079
/*-----------------------------------------------------*\
| Logitech Keyboards |
\*-----------------------------------------------------*/
void DetectLogitechKeyboardG213(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LogitechG213Controller* controller = new LogitechG213Controller(dev, info->path);
RGBController_LogitechG213* rgb_controller = new RGBController_LogitechG213(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectLogitechKeyboardG810(hid_device_info* info, const std::string& name)
{
/*-------------------------------------------------------------------------------------------------*\
@@ -71,49 +113,51 @@ void DetectLogitechKeyboardG810(hid_device_info* info, const std::string& name)
| Usage 0x0602 for 20 byte, usage 0x0604 for 64 byte, both are on usage page 0xFF43 |
\*-------------------------------------------------------------------------------------------------*/
#ifdef USE_HID_USAGE
hid_device* dev_usage_0x0602 = nullptr;
hid_device* dev_usage_0x0604 = nullptr;
hid_device_info* info_temp = info;
while(info_temp)
{
if(info_temp->vendor_id == info->vendor_id // constant LOGITECH_VID
&& info_temp->product_id == info->product_id // NON-constant
&& info_temp->interface_number == info->interface_number // constant 1
&& info_temp->usage_page == info->usage_page) // constant 0xFF43
{
if(info_temp->usage == 0x0602)
{
hid_device* dev_usage_0x0602 = nullptr;
hid_device* dev_usage_0x0604 = nullptr;
hid_device_info* info_temp = info;
while(info_temp)
{
if(info_temp->vendor_id == info->vendor_id // constant LOGITECH_VID
&& info_temp->product_id == info->product_id // NON-constant
&& info_temp->interface_number == info->interface_number // constant 1
&& info_temp->usage_page == info->usage_page) // constant 0xFF43
{
if(info_temp->usage == 0x0602)
{
dev_usage_0x0602 = hid_open_path(info_temp->path);
}
else if(info_temp->usage == 0x0604)
{
dev_usage_0x0604 = hid_open_path(info_temp->path);
}
}
if(dev_usage_0x0602 && dev_usage_0x0604)
{
break;
}
info_temp = info_temp->next;
}
if(dev_usage_0x0602 && dev_usage_0x0604)
{
LogitechG810Controller* controller = new LogitechG810Controller(dev_usage_0x0602, dev_usage_0x0604);
RGBController_LogitechG810* rgb_controller = new RGBController_LogitechG810(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
else
{
// Not all of them could be opened, do some cleanup
hid_close(dev_usage_0x0602);
hid_close(dev_usage_0x0604);
}
}
else if(info_temp->usage == 0x0604)
{
dev_usage_0x0604 = hid_open_path(info_temp->path);
}
}
if(dev_usage_0x0602 && dev_usage_0x0604)
{
break;
}
info_temp = info_temp->next;
}
if(dev_usage_0x0602 && dev_usage_0x0604)
{
LogitechG810Controller* controller = new LogitechG810Controller(dev_usage_0x0602, dev_usage_0x0604);
RGBController_LogitechG810* rgb_controller = new RGBController_LogitechG810(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
else
{
// Not all of them could be opened, do some cleanup
hid_close(dev_usage_0x0602);
hid_close(dev_usage_0x0604);
}
#else
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LogitechG810Controller* controller = new LogitechG810Controller(dev, dev);
LogitechG810Controller* controller = new LogitechG810Controller(dev, dev);
RGBController_LogitechG810* rgb_controller = new RGBController_LogitechG810(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
@@ -121,120 +165,63 @@ void DetectLogitechKeyboardG810(hid_device_info* info, const std::string& name)
#endif
}
void DetectLogitechKeyboardG213(hid_device_info* info, const std::string& name)
void DetectLogitechKeyboardG910(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
/*-------------------------------------------------------------------------------------------------*\
| Logitech keyboards use two different usages, one for 20-byte packets and one for 64-byte packets |
| Usage 0x0602 for 20 byte, usage 0x0604 for 64 byte, both are on usage page 0xFF43 |
\*-------------------------------------------------------------------------------------------------*/
#ifdef USE_HID_USAGE
hid_device* dev_usage_0x0602 = nullptr;
hid_device* dev_usage_0x0604 = nullptr;
hid_device_info* info_temp = info;
while(info_temp)
{
LogitechG213Controller* controller = new LogitechG213Controller(dev, info->path);
RGBController_LogitechG213* rgb_controller = new RGBController_LogitechG213(controller);
if(info_temp->vendor_id == info->vendor_id // constant LOGITECH_VID
&& info_temp->product_id == info->product_id // NON-constant
&& info_temp->interface_number == info->interface_number // constant 1
&& info_temp->usage_page == info->usage_page) // constant 0xFF43
{
if(info_temp->usage == 0x0602)
{
dev_usage_0x0602 = hid_open_path(info_temp->path);
}
else if(info_temp->usage == 0x0604)
{
dev_usage_0x0604 = hid_open_path(info_temp->path);
}
}
if(dev_usage_0x0602 && dev_usage_0x0604)
{
break;
}
info_temp = info_temp->next;
}
if(dev_usage_0x0602 && dev_usage_0x0604)
{
LogitechG910Controller* controller = new LogitechG910Controller(dev_usage_0x0602, dev_usage_0x0604);
RGBController_LogitechG910* rgb_controller = new RGBController_LogitechG910(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectLogitechMouseG203(hid_device_info* info, const std::string& name)
{
else
{
// Not all of them could be opened, do some cleanup
hid_close(dev_usage_0x0602);
hid_close(dev_usage_0x0604);
}
#else
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LogitechG203Controller* controller = new LogitechG203Controller(dev, info->path);
RGBController_LogitechG203* rgb_controller = new RGBController_LogitechG203(controller);
LogitechG910Controller* controller = new LogitechG910Controller(dev, dev);
RGBController_LogitechG910* rgb_controller = new RGBController_LogitechG910(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectLogitechMouseG203L(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LogitechG203LController* controller = new LogitechG203LController(dev, info->path);
RGBController_LogitechG203L* rgb_controller = new RGBController_LogitechG203L(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectLogitechMouseG303(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LogitechG303Controller* controller = new LogitechG303Controller(dev, info->path);
RGBController_LogitechG303* rgb_controller = new RGBController_LogitechG303(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectLogitechMouseG403(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LogitechG403Controller* controller = new LogitechG403Controller(dev, info->path);
RGBController_LogitechG403* rgb_controller = new RGBController_LogitechG403(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectLogitechMouseG502PS(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LogitechG502PSController* controller = new LogitechG502PSController(dev, info->path);
RGBController_LogitechG502PS* rgb_controller = new RGBController_LogitechG502PS(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectLogitechMouseGPRO(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LogitechGProWirelessController* controller = new LogitechGProWirelessController(dev, info->path);
RGBController_LogitechGProWireless* rgb_controller = new RGBController_LogitechGProWireless(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectLogitechMouseGLS(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
//Add mouse
LogitechGProWirelessController* mouse_controller = new LogitechGProWirelessController(dev, info->path);
RGBController_LogitechGProWireless* mouse_rgb_controller = new RGBController_LogitechGProWireless(mouse_controller);
mouse_rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(mouse_rgb_controller);
//Add Powerplay mousemat
LogitechGPowerPlayController* mousemat_controller = new LogitechGPowerPlayController(dev, info->path);
RGBController_LogitechGPowerPlay* mousemat_rgb_controller = new RGBController_LogitechGPowerPlay(mousemat_controller);
mousemat_rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(mousemat_rgb_controller);
}
}
void DetectLogitechG560(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
//Add G560 Speaker
LogitechG560Controller* speaker_controller = new LogitechG560Controller(dev, info->path);
RGBController_LogitechG560* speaker_rgb_controller = new RGBController_LogitechG560(speaker_controller);
speaker_rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(speaker_rgb_controller);
}
#endif
}
void DetectLogitechKeyboardG815(hid_device_info* info, const std::string& name)
@@ -243,56 +230,60 @@ void DetectLogitechKeyboardG815(hid_device_info* info, const std::string& name)
| Logitech keyboards use two different usages, one for 20-byte packets and one for 64-byte packets |
| Usage 0x0602 for 20 byte, usage 0x0604 for 64 byte, both are on usage page 0xFF43 |
\*-------------------------------------------------------------------------------------------------*/
#ifdef _WIN32
hid_device* dev_usage_0x0602 = nullptr;
hid_device* dev_usage_0x0604 = nullptr;
hid_device_info* info_temp = info;
while(info_temp)
{
if(info_temp->vendor_id == info->vendor_id // constant LOGITECH_VID
&& info_temp->product_id == info->product_id // NON-constant
&& info_temp->interface_number == info->interface_number // constant 1
&& info_temp->usage_page == info->usage_page) // constant 0xFF43
{
if(info_temp->usage == 0x0602)
{
dev_usage_0x0602 = hid_open_path(info_temp->path);
}
else if(info_temp->usage == 0x0604)
{
dev_usage_0x0604 = hid_open_path(info_temp->path);
}
}
if(dev_usage_0x0602 && dev_usage_0x0604)
{
break;
}
info_temp = info_temp->next;
}
if(dev_usage_0x0602 && dev_usage_0x0604)
{
LogitechG815Controller* controller = new LogitechG815Controller(dev_usage_0x0602, dev_usage_0x0604);
RGBController_LogitechG815* rgb_controller = new RGBController_LogitechG815(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
else
{
// Not all of them could be opened, do some cleanup
if(dev_usage_0x0602)
{
hid_close(dev_usage_0x0602);
}
if(dev_usage_0x0604)
{
hid_close(dev_usage_0x0604);
}
}
#ifdef USE_HID_USAGE
hid_device* dev_usage_0x0602 = nullptr;
hid_device* dev_usage_0x0604 = nullptr;
hid_device_info* info_temp = info;
while(info_temp)
{
if(info_temp->vendor_id == info->vendor_id // constant LOGITECH_VID
&& info_temp->product_id == info->product_id // NON-constant
&& info_temp->interface_number == info->interface_number // constant 1
&& info_temp->usage_page == info->usage_page) // constant 0xFF43
{
if(info_temp->usage == 0x0602)
{
dev_usage_0x0602 = hid_open_path(info_temp->path);
}
else if(info_temp->usage == 0x0604)
{
dev_usage_0x0604 = hid_open_path(info_temp->path);
}
}
if(dev_usage_0x0602 && dev_usage_0x0604)
{
break;
}
info_temp = info_temp->next;
}
if(dev_usage_0x0602 && dev_usage_0x0604)
{
LogitechG815Controller* controller = new LogitechG815Controller(dev_usage_0x0602, dev_usage_0x0604);
RGBController_LogitechG815* rgb_controller = new RGBController_LogitechG815(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
else
{
/*-------------------------------------------------*\
| Not all of them could be opened, do some cleanup |
\*-------------------------------------------------*/
if(dev_usage_0x0602)
{
hid_close(dev_usage_0x0602);
}
if(dev_usage_0x0604)
{
hid_close(dev_usage_0x0604);
}
}
#else
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LogitechG815Controller* controller = new LogitechG815Controller(dev, dev);
LogitechG815Controller* controller = new LogitechG815Controller(dev, dev);
RGBController_LogitechG815* rgb_controller = new RGBController_LogitechG815(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
@@ -300,38 +291,378 @@ void DetectLogitechKeyboardG815(hid_device_info* info, const std::string& name)
#endif
}
/*-----------------------------------------------------*\
| Logitech Mice |
\*-----------------------------------------------------*/
static void addLogitechLightsyncMouse1zone(hid_device_info* info, const std::string& name, unsigned char hid_dev_index, unsigned char hid_feature_index, unsigned char hid_fctn_ase_id)
{
#ifdef USE_HID_USAGE
{
hid_device* dev_usage_1 = nullptr;
hid_device* dev_usage_2 = nullptr;
hid_device_info* info_temp = info;
while(info_temp)
{
if(info_temp->vendor_id == info->vendor_id // constant LOGITECH_VID
&& info_temp->product_id == info->product_id // NON-constant
&& info_temp->interface_number == info->interface_number // constant 1
&& info_temp->usage_page == info->usage_page) // constant 0x00FF
{
if (info_temp->usage == 1)
{
dev_usage_1 = hid_open_path(info_temp->path);
}
else if (info_temp->usage == 2)
{
dev_usage_2 = hid_open_path(info_temp->path);
}
}
if (dev_usage_1 && dev_usage_2)
{
break;
}
info_temp = info_temp->next;
}
if(dev_usage_1 && dev_usage_2)
{
LogitechGLightsyncController* controller = new LogitechGLightsyncController(dev_usage_1, dev_usage_2, info->path, hid_dev_index, hid_feature_index, hid_fctn_ase_id);
RGBController_LogitechGLightsync1zone* rgb_controller = new RGBController_LogitechGLightsync1zone (controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
else
{
LOG_NOTICE("Unable to open all device report endpoints, unable to add device");
hid_close(dev_usage_1);
hid_close(dev_usage_2);
}
}
#else
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LogitechGLightsyncController* controller = new LogitechGLightsyncController(dev, dev, info->path, hid_dev_index, hid_feature_index, hid_fctn_ase_id);
RGBController_LogitechGLightsync1zone* rgb_controller = new RGBController_LogitechGLightsync1zone(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
#endif
}
static void addLogitechLightsyncMouse2zone(hid_device_info* info, const std::string& name, unsigned char hid_dev_index, unsigned char hid_feature_index, unsigned char hid_fctn_ase_id)
{
#ifdef USE_HID_USAGE
{
hid_device* dev_usage_1 = nullptr;
hid_device* dev_usage_2 = nullptr;
hid_device_info* info_temp = info;
while(info_temp)
{
if(info_temp->vendor_id == info->vendor_id // constant LOGITECH_VID
&& info_temp->product_id == info->product_id // NON-constant
&& info_temp->interface_number == info->interface_number // constant 1
&& info_temp->usage_page == info->usage_page) // constant 0x00FF
{
if(info_temp->usage == 1)
{
dev_usage_1 = hid_open_path(info_temp->path);
}
else if(info_temp->usage == 2)
{
dev_usage_2 = hid_open_path(info_temp->path);
}
}
if(dev_usage_1 && dev_usage_2)
{
break;
}
info_temp = info_temp->next;
}
if(dev_usage_1 && dev_usage_2)
{
LogitechGLightsyncController* controller = new LogitechGLightsyncController(dev_usage_1, dev_usage_2, info->path, hid_dev_index, hid_feature_index, hid_fctn_ase_id);
RGBController_LogitechGLightsync* rgb_controller = new RGBController_LogitechGLightsync (controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
else
{
LOG_NOTICE("Unable to open all device report endpoints, unable to add device");
hid_close(dev_usage_1);
hid_close(dev_usage_2);
}
}
#else
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LogitechGLightsyncController* controller = new LogitechGLightsyncController(dev, dev, info->path, hid_dev_index, hid_feature_index, hid_fctn_ase_id);
RGBController_LogitechGLightsync* rgb_controller = new RGBController_LogitechGLightsync(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
#endif
}
void DetectLogitechMouseG203(hid_device_info* info, const std::string& name)
{
addLogitechLightsyncMouse1zone(info, name, 0xFF, 0x0E, 0x3A);
}
void DetectLogitechMouseG203L(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
LogitechG203LController* controller = new LogitechG203LController(dev, info->path);
RGBController_LogitechG203L* rgb_controller = new RGBController_LogitechG203L(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectLogitechMouseG303(hid_device_info* info, const std::string& name)
{
addLogitechLightsyncMouse2zone(info, name, 0xFF, 0x0E, 0x3A);
}
void DetectLogitechMouseG403(hid_device_info* info, const std::string& name)
{
addLogitechLightsyncMouse2zone(info, name, 0xFF, 0x0E, 0x3A);
}
void DetectLogitechMouseGPRO(hid_device_info* info, const std::string& name)
{
addLogitechLightsyncMouse2zone(info, name, 0x01, 0x07, 0x3C);
}
/*-----------------------------------------------------*\
| Other Logitech Devices |
\*-----------------------------------------------------*/
void DetectLogitechG560(hid_device_info* info, const std::string& name)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
/*---------------------------------------------*\
| Add G560 Speaker |
\*---------------------------------------------*/
LogitechG560Controller* controller = new LogitechG560Controller(dev, info->path);
RGBController_LogitechG560* rgb_controller = new RGBController_LogitechG560(controller);
rgb_controller->name = name;
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Keyboards |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Logitech G213", DetectLogitechKeyboardG213, LOGITECH_VID, LOGITECH_G213_PID, 1, 0xFF43, 0x0602);
REGISTER_HID_DETECTOR_IP ("Logitech G512", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G512_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G512 RGB", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G512_RGB_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G610 Orion", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G610_1_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G610 Orion", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G610_2_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G810 Orion Spectrum", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G810_1_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G810 Orion Spectrum", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G810_2_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G813 RGB Mechanical Gaming Keyboard", DetectLogitechKeyboardG815, LOGITECH_VID, LOGITECH_G813_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G815 RGB Mechanical Gaming Keyboard", DetectLogitechKeyboardG815, LOGITECH_VID, LOGITECH_G815_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IPU("Logitech G213", DetectLogitechKeyboardG213, LOGITECH_VID, LOGITECH_G213_PID, 1, 0xFF43, 0x0602);
REGISTER_HID_DETECTOR_IP ("Logitech G512", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G512_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G512 RGB", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G512_RGB_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G610 Orion", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G610_1_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G610 Orion", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G610_2_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G810 Orion Spectrum", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G810_1_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G810 Orion Spectrum", DetectLogitechKeyboardG810, LOGITECH_VID, LOGITECH_G810_2_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G813 RGB Mechanical Gaming Keyboard", DetectLogitechKeyboardG815, LOGITECH_VID, LOGITECH_G813_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G815 RGB Mechanical Gaming Keyboard", DetectLogitechKeyboardG815, LOGITECH_VID, LOGITECH_G815_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G910 Orion Spark", DetectLogitechKeyboardG910, LOGITECH_VID, LOGITECH_G910_ORION_SPARK_PID, 1, 0xFF43);
REGISTER_HID_DETECTOR_IP ("Logitech G910 Orion Spectrum", DetectLogitechKeyboardG910, LOGITECH_VID, LOGITECH_G910_PID, 1, 0xFF43);
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Mice |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Logitech G203 Prodigy", DetectLogitechMouseG203, LOGITECH_VID, LOGITECH_G203_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G203 Lightsync", DetectLogitechMouseG203L, LOGITECH_VID, LOGITECH_G203L_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G303 Daedalus Apex", DetectLogitechMouseG303, LOGITECH_VID, LOGITECH_G303_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G403 Prodigy", DetectLogitechMouseG403, LOGITECH_VID, LOGITECH_G403_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G403 Hero", DetectLogitechMouseG403, LOGITECH_VID, LOGITECH_G403H_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G502 Proteus Spectrum", DetectLogitechMouseG502PS, LOGITECH_VID, LOGITECH_G502_PS_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G502 Hero", DetectLogitechMouseG502PS, LOGITECH_VID, LOGITECH_G502H_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G Pro Gaming Mouse", DetectLogitechMouseG203, LOGITECH_VID, LOGITECH_GPRO_WIRED_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G Pro (HERO) Gaming Mouse", DetectLogitechMouseG203, LOGITECH_VID, LOGITECH_GPRO_HERO_WIRED_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G Lightspeed Wireless Gaming Mouse", DetectLogitechMouseGPRO, LOGITECH_VID, LOGITECH_G_LIGHTSPEED_WIRELESS_PID, 2, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G Pro Wireless Gaming Mouse (Wired)", DetectLogitechMouseGPRO, LOGITECH_VID, LOGITECH_GPRO_WIRELESS_PID, 2, 0xFF00, 2);
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Mousemats |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Logitech G Powerplay Mousepad with Lightspeed", DetectLogitechMouseGLS, LOGITECH_VID, LOGITECH_G_LIGHTSPEED_POWERPLAY_PID, 2, 0xFF00, 2);
REGISTER_HID_DETECTOR_IP ("Logitech G203 Prodigy", DetectLogitechMouseG203, LOGITECH_VID, LOGITECH_G203_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IPU("Logitech G203 Lightsync", DetectLogitechMouseG203L, LOGITECH_VID, LOGITECH_G203_LIGHTSYNC_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IP ("Logitech G303 Daedalus Apex", DetectLogitechMouseG303, LOGITECH_VID, LOGITECH_G303_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP ("Logitech G403 Hero", DetectLogitechMouseG403, LOGITECH_VID, LOGITECH_G403_HERO_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP ("Logitech G Pro Gaming Mouse", DetectLogitechMouseGPRO, LOGITECH_VID, LOGITECH_G_PRO_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP ("Logitech G Pro (HERO) Gaming Mouse", DetectLogitechMouseGPRO, LOGITECH_VID, LOGITECH_G_PRO_HERO_PID, 1, 0xFF00);
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Speakers |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Logitech G560 Lightsync Speaker", DetectLogitechG560, LOGITECH_VID, LOGITECH_G560_PID, 2, 0xFF43, 514);
REGISTER_HID_DETECTOR_IPU("Logitech G560 Lightsync Speaker", DetectLogitechG560, LOGITECH_VID, LOGITECH_G560_PID, 2, 0xFF43, 514);
/*---------------------------------------------------------------------------------------------------------*\
| Windows and MacOS Lightspeed Detection |
| |
| The Lightspeed receiver is a unifying receiver that will only accept 1 connection |
| We must probe the receiver to check what is currently connected |
| |
| Hat tip - kernel driver https://github.com/torvalds/linux/blob/master/drivers/hid/hid-logitech-dj.c |
| - ltunify https://github.com/Lekensteyn/ltunify/ |
\*---------------------------------------------------------------------------------------------------------*/
#if defined(_WIN32) || defined(__APPLE__)
usages BundleLogitechUsages(hid_device_info* info)
{
usages temp_usages;
/*-----------------------------------------------------------------*\
| Need a unique ID to group usages for 1 device if multiple exist |
| Grab all usages that you can open. For normal Logitech FAP |
| devices this will be usage 1, 2 and 4 |
\*-----------------------------------------------------------------*/
if(info->usage == 1)
{
while(info)
{
hid_device* dev = hid_open_path(info->path);
if(dev)
{
temp_usages.emplace((uint8_t)info->usage, dev);
}
info = info->next;
}
}
return temp_usages;
}
void CreateLogitechLightspeedDevice(char *path, usages device_usages, uint8_t device_index, bool wireless, std::shared_ptr<std::mutex> mutex_ptr)
{
LogitechLightspeedController* controller = new LogitechLightspeedController(device_usages.find(2)->second, path);
controller->lightspeed = new logitech_device(path, device_usages, device_index, wireless, mutex_ptr);
RGBController_LogitechLightspeed* rgb_controller = new RGBController_LogitechLightspeed(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
void DetectLogitechLightspeedReceiver(hid_device_info* info, const std::string& /*name*/)
{
/*-----------------------------------------------------------------*\
| Need to save the PID and the device path before iterating |
| over "info" in BundleLogitechUsages() |
\*-----------------------------------------------------------------*/
char *path = info->path;
uint16_t dev_pid = info->product_id;
usages device_usages = BundleLogitechUsages(info);
wireless_map wireless_devices;
unsigned int device_count = getWirelessDevice(device_usages, dev_pid, &wireless_devices);
/*-----------------------------------------------------------------*\
| Lightspeed Receivers will only have one paired /connected device |
| Unifying Receivers can have up to 6 devices paired / connected |
\*-----------------------------------------------------------------*/
if(device_count > 0)
{
/*-------------------------------------------------*\
| Create mutex to prevent the controllers sharing a |
| receiver from interfering with each other |
\*-------------------------------------------------*/
std::shared_ptr<std::mutex> logitech_mutex = std::make_shared<std::mutex>();
for(wireless_map::iterator wd = wireless_devices.begin(); wd != wireless_devices.end(); wd++)
{
CreateLogitechLightspeedDevice(path, device_usages, wd->second, true, logitech_mutex);
}
}
}
void DetectLogitechWired(hid_device_info* info, const std::string& /*name*/)
{
/*-----------------------------------------------------------------*\
| Need to save the device path before iterating |
| over "info" in BundleLogitechUsages() |
\*-----------------------------------------------------------------*/
char *path = info->path;
usages device_usages = BundleLogitechUsages(info);
if(device_usages.size() > 0)
{
CreateLogitechLightspeedDevice(path, device_usages, 0xFF, false, nullptr);
}
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Lightspeed Receivers (Windows Wireless) |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("Logitech Lightspeed Receiver", DetectLogitechLightspeedReceiver, LOGITECH_VID, LOGITECH_G_LIGHTSPEED_RECEIVER_PID, 2, 0xFF00);
REGISTER_HID_DETECTOR_IP("Logitech G Powerplay Mousepad", DetectLogitechLightspeedReceiver, LOGITECH_VID, LOGITECH_G_LIGHTSPEED_POWERPLAY_PID, 2, 0xFF00);
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Lightspeed Wireless Devices (Windows Wired) |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IP("Logitech G403 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G403_LIGHTSPEED_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("Logitech G502 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G502_PROTEUS_SPECTRUM_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("Logitech G502 Hero Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G502_HERO_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("Logitech G502 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G502_LIGHTSPEED_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("Logitech G703 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G703_LIGHTSPEED_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("Logitech G900 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G900_LIGHTSPEED_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("Logitech G903 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G903_LIGHTSPEED_PID, 1, 0xFF00);
REGISTER_HID_DETECTOR_IP("Logitech G Pro Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G_PRO_WIRELESS_PID, 2, 0xFF00);
#endif
/*---------------------------------------------------------------------------------------------------------*\
| Linux Lightspeed Detection |
| |
| The Linux kernel handles detecting wireless devices connected to a Unifying Receiver. |
\*---------------------------------------------------------------------------------------------------------*/
#ifdef __linux__
void CreateLogitechLightspeedDevice(hid_device_info* info, bool wireless)
{
usages device_usages;
hid_device* dev = hid_open_path(info->path);
if(dev)
{
device_usages.emplace((uint8_t)info->usage, dev);
}
if(device_usages.size() > 0)
{
LogitechLightspeedController* controller = new LogitechLightspeedController(device_usages.find(0)->second, info->path);
controller->lightspeed = new logitech_device(info->path, device_usages, 0xFF, wireless);
RGBController_LogitechLightspeed* rgb_controller = new RGBController_LogitechLightspeed(controller);
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
}
void DetectLogitechWireless(hid_device_info* info, const std::string& /*name*/)
{
CreateLogitechLightspeedDevice(info, true);
}
void DetectLogitechWired(hid_device_info* info, const std::string& /*name*/)
{
CreateLogitechLightspeedDevice(info, false);
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Lightspeed Devices (Linux Wireless) |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Logitech G403 Wireless Gaming Mouse", DetectLogitechWireless, LOGITECH_VID, LOGITECH_G403_LIGHTSPEED_VIRTUAL_PID, 2, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G502 Wireless Gaming Mouse", DetectLogitechWireless, LOGITECH_VID, LOGITECH_G502_LIGHTSPEED_VIRTUAL_PID, 2, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G703 Wireless Gaming Mouse", DetectLogitechWireless, LOGITECH_VID, LOGITECH_G703_LIGHTSPEED_VIRTUAL_PID, 2, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G900 Wireless Gaming Mouse", DetectLogitechWireless, LOGITECH_VID, LOGITECH_G900_LIGHTSPEED_VIRTUAL_PID, 2, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G903 Wireless Gaming Mouse", DetectLogitechWireless, LOGITECH_VID, LOGITECH_G903_LIGHTSPEED_VIRTUAL_PID, 2, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G Pro Wireless Gaming Mouse", DetectLogitechWireless, LOGITECH_VID, LOGITECH_G_PRO_WIRELESS_VIRTUAL_PID, 2, 0xFF00, 2);
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
| Lightspeed Wireless Devices (Linux Wired) |
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
REGISTER_HID_DETECTOR_IPU("Logitech G403 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G403_LIGHTSPEED_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G502 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G502_PROTEUS_SPECTRUM_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G502 Hero Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G502_LIGHTSPEED_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G502 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G502_HERO_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G703 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G703_LIGHTSPEED_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G900 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G900_LIGHTSPEED_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G903 Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G903_LIGHTSPEED_PID, 1, 0xFF00, 2);
REGISTER_HID_DETECTOR_IPU("Logitech G Pro Wireless Gaming Mouse (wired)", DetectLogitechWired, LOGITECH_VID, LOGITECH_G_PRO_WIRELESS_PID, 2, 0xFF00, 2);
#endif
@@ -1,95 +0,0 @@
/*-----------------------------------------*\
| LogitechG203Controller.cpp |
| |
| Driver for Logitech G203 Prodigy mouse |
| lighting controller |
| |
| Adam Honse (CalcProgrammer1) 5/17/2020 |
\*-----------------------------------------*/
#include "LogitechG203Controller.h"
#include <cstring>
LogitechG203Controller::LogitechG203Controller(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
LogitechG203Controller::~LogitechG203Controller()
{
hid_close(dev);
}
std::string LogitechG203Controller::GetDeviceLocation()
{
return("HID " + location);
}
std::string LogitechG203Controller::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, serial_string, 128);
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void LogitechG203Controller::SendMouseMode
(
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0E;
usb_buf[0x03] = 0x3C;
usb_buf[0x04] = 0x00;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 100 * speed;
if(mode == LOGITECH_G203_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = 0x64;
}
else if(mode == LOGITECH_G203_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = 0x64;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, (unsigned char *)usb_buf, 20);
hid_read(dev, (unsigned char *)usb_buf, 20);
}
@@ -1,57 +0,0 @@
/*-----------------------------------------*\
| LogitechG203Controller.h |
| |
| Definitions and types for Logitech G203 |
| Prodigy mouse lighting controller |
| |
| Adam Honse (CalcProgrammer1) 5/17/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
LOGITECH_G203_MODE_OFF = 0x00,
LOGITECH_G203_MODE_STATIC = 0x01,
LOGITECH_G203_MODE_CYCLE = 0x02,
LOGITECH_G203_MODE_BREATHING = 0x03,
};
/*---------------------------------------------------------------------------------------------*\
| Speed is 1000 for fast and 20000 for slow. |
| Values are multiplied by 100 later to give lots of GUI steps. |
\*---------------------------------------------------------------------------------------------*/
enum
{
LOGITECH_G203_SPEED_SLOWEST = 0xC8, /* Slowest speed */
LOGITECH_G203_SPEED_NORMAL = 0x32, /* Normal speed */
LOGITECH_G203_SPEED_FASTEST = 0x0A, /* Fastest speed */
};
class LogitechG203Controller
{
public:
LogitechG203Controller(hid_device* dev_handle, const char* path);
~LogitechG203Controller();
std::string GetDeviceLocation();
std::string GetSerialString();
void SendMouseMode
(
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
hid_device* dev;
std::string location;
};
@@ -1,81 +0,0 @@
/*-----------------------------------------*\
| LogitechG303Controller.cpp |
| |
| Driver for Logitech G303 Daedalus Apex |
| mouse lighting controller |
| |
| TheRogueZeta 02/14/2021 |
\*-----------------------------------------*/
#include "LogitechG303Controller.h"
#include <cstring>
LogitechG303Controller::LogitechG303Controller(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
LogitechG303Controller::~LogitechG303Controller()
{
hid_close(dev);
}
std::string LogitechG303Controller::GetDeviceLocation()
{
return(location);
}
void LogitechG303Controller::SendMouseMode
(
unsigned char mode,
std::uint16_t speed,
unsigned char channel,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
unsigned char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0E;
usb_buf[0x03] = 0x3C;
usb_buf[0x04] = channel;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 100 * speed;
if(mode == LOGITECH_G303_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = 0x64;
}
else if(mode == LOGITECH_G303_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = 0x64;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 20);
hid_read(dev, usb_buf, 20);
}
@@ -1,57 +0,0 @@
/*-----------------------------------------*\
| LogitechG303Controller.h |
| |
| Definitions and types for Logitech G303 |
| Daedalus Apex mouse lighting controller |
| |
| TheRogueZeta 02/14/2021 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
LOGITECH_G303_MODE_OFF = 0x00,
LOGITECH_G303_MODE_STATIC = 0x01,
LOGITECH_G303_MODE_CYCLE = 0x02,
LOGITECH_G303_MODE_BREATHING = 0x03,
};
/*---------------------------------------------------------------------------------------------*\
| Speed is 1000 for fast and 20000 for slow. |
| Values are mutipled by 100 later to give lots of GUI steps. |
\*---------------------------------------------------------------------------------------------*/
enum
{
LOGITECH_G303_SPEED_SLOWEST = 0xC8, /* Slowest speed */
LOGITECH_G303_SPEED_NORMAL = 0x32, /* Normal speed */
LOGITECH_G303_SPEED_FASTEST = 0x0A, /* Fastest speed */
};
class LogitechG303Controller
{
public:
LogitechG303Controller(hid_device* dev_handle, const char* path);
~LogitechG303Controller();
std::string GetDeviceLocation();
void SendMouseMode
(
unsigned char mode,
unsigned short speed,
unsigned char channel,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
hid_device* dev;
std::string location;
};
@@ -1,92 +0,0 @@
/*-----------------------------------------*\
| LogitechG403Controller.cpp |
| |
| Driver for Logitech G403 Prodigy mouse |
| lighting controller |
| |
| Martin Hartl (inlart) 5/19/2020 |
\*-----------------------------------------*/
#include "LogitechG403Controller.h"
#include <cstring>
LogitechG403Controller::LogitechG403Controller(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
LogitechG403Controller::~LogitechG403Controller()
{
hid_close(dev);
}
std::string LogitechG403Controller::GetDeviceLocation()
{
return("HID: " + location);
}
std::string LogitechG403Controller::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, serial_string, 128);
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void LogitechG403Controller::SendMouseMode
(
unsigned char mode,
std::uint16_t speed,
unsigned char channel,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
unsigned char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0E;
usb_buf[0x03] = 0x3C;
usb_buf[0x04] = channel;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 100 * speed;
if(mode == LOGITECH_G403_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = 0x64;
}
else if(mode == LOGITECH_G403_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = 0x64;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 20);
hid_read(dev, usb_buf, 20);
}
@@ -1,58 +0,0 @@
/*-----------------------------------------*\
| LogitechG403Controller.h |
| |
| Definitions and types for Logitech G403 |
| Prodigy mouse lighting controller |
| |
| Martin Hartl (inlart) 5/19/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
LOGITECH_G403_MODE_OFF = 0x00,
LOGITECH_G403_MODE_STATIC = 0x01,
LOGITECH_G403_MODE_CYCLE = 0x02,
LOGITECH_G403_MODE_BREATHING = 0x03,
};
/*---------------------------------------------------------------------------------------------*\
| Speed is 1000 for fast and 20000 for slow. |
| Values are multiplied by 100 later to give lots of GUI steps. |
\*---------------------------------------------------------------------------------------------*/
enum
{
LOGITECH_G403_SPEED_SLOWEST = 0xC8, /* Slowest speed */
LOGITECH_G403_SPEED_NORMAL = 0x32, /* Normal speed */
LOGITECH_G403_SPEED_FASTEST = 0x0A, /* Fastest speed */
};
class LogitechG403Controller
{
public:
LogitechG403Controller(hid_device* dev_handle, const char* path);
~LogitechG403Controller();
std::string GetDeviceLocation();
std::string GetSerialString();
void SendMouseMode
(
unsigned char mode,
unsigned short speed,
unsigned char channel,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
hid_device* dev;
std::string location;
};
@@ -1,94 +0,0 @@
/*-----------------------------------------*\
| Logitech502PSController.cpp |
| |
| Driver for Logitech G502 Proteus |
| Spectrum mouse lighting controller |
| |
| kernzerfall 07/28/2020 |
\*-----------------------------------------*/
#include "LogitechG502PSController.h"
#include <cstring>
LogitechG502PSController::LogitechG502PSController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
LogitechG502PSController::~LogitechG502PSController()
{
hid_close(dev);
}
std::string LogitechG502PSController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string LogitechG502PSController::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, serial_string, 128);
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void LogitechG502PSController::SendMouseMode
(
unsigned char mode,
std::uint16_t speed,
unsigned char channel,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
unsigned char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x02;
usb_buf[0x03] = 0x3A;
usb_buf[0x04] = channel;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 100 * speed;
if(mode == LOGITECH_G502_PS_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = 0x64;
}
else if(mode == LOGITECH_G502_PS_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = 0x64;
}else if(mode == LOGITECH_G502_PS_MODE_STATIC){
usb_buf[0x09] = 0x02;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 20);
hid_read(dev, usb_buf, 20);
}
@@ -1,59 +0,0 @@
/*-----------------------------------------*\
| Logitech502PSController.h |
| |
| Definitions and types for Logitech |
| G502 Proteus Spectrum mouse lighting |
| controller |
| |
| kernzerfall 07/28/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
LOGITECH_G502_PS_MODE_OFF = 0x00,
LOGITECH_G502_PS_MODE_STATIC = 0x01,
LOGITECH_G502_PS_MODE_CYCLE = 0x03,
LOGITECH_G502_PS_MODE_BREATHING = 0x02
};
/*---------------------------------------------------------------------------------------------*\
| Speed is 1000 for fast and 20000 for slow. |
| Values are multiplied by 100 later to give lots of GUI steps. |
\*---------------------------------------------------------------------------------------------*/
enum
{
LOGITECH_G502_PS_SPEED_SLOWEST = 0xC8, /* Slowest speed */
LOGITECH_G502_PS_SPEED_NORMAL = 0x32, /* Normal speed */
LOGITECH_G502_PS_SPEED_FASTEST = 0x0A, /* Fastest speed */
};
class LogitechG502PSController
{
public:
LogitechG502PSController(hid_device* dev_handle, const char* path);
~LogitechG502PSController();
std::string GetDeviceLocation();
std::string GetSerialString();
void SendMouseMode
(
unsigned char mode,
unsigned short speed,
unsigned char channel,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
hid_device* dev;
std::string location;
};
@@ -134,7 +134,7 @@ void LogitechG560Controller::fail_retry_write(hid_device *device, const unsigned
if(ret == 20)
{
std::this_thread::sleep_for(1ms);
hid_read_timeout(dev, usb_buf_out, LOGI_G560_LED_PACKET_SIZE, 200);
hid_read_timeout(dev, usb_buf_out, LOGI_G560_LED_PACKET_SIZE, 20);
break;
}
else
@@ -0,0 +1,181 @@
/*-----------------------------------------*\
| LogitechG910Controller.cpp |
| |
| Driver for Logitech G910 Orion Spectrum |
| keyboard light controller |
| |
| Adam Honse (CalcProgrammer1) 6/11/2020 |
\*-----------------------------------------*/
#include "LogitechG910Controller.h"
#include <cstring>
LogitechG910Controller::LogitechG910Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12)
{
dev_pkt_0x11 = dev_handle_0x11;
dev_pkt_0x12 = dev_handle_0x12;
}
LogitechG910Controller::~LogitechG910Controller()
{
hid_close(dev_pkt_0x11);
hid_close(dev_pkt_0x12);
}
std::string LogitechG910Controller::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev_pkt_0x11, serial_string, 128);
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void LogitechG910Controller::Commit()
{
SendCommit();
}
void LogitechG910Controller::SetDirect
(
unsigned char zone,
unsigned char frame_count,
unsigned char * frame_data
)
{
SendDirectFrame(zone, frame_count, frame_data);
}
void LogitechG910Controller::SetMode
(
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
SendMode(LOGITECH_G910_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
SendMode(LOGITECH_G910_ZONE_MODE_LOGO, mode, speed, red, green, blue);
SendCommit();
}
/*-------------------------------------------------------------------------------------------------*\
| Private packet sending functions. |
\*-------------------------------------------------------------------------------------------------*/
void LogitechG910Controller::SendCommit()
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Commit packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0F;
usb_buf[0x03] = 0x5F;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
hid_read(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
}
void LogitechG910Controller::SendDirectFrame
(
unsigned char zone,
unsigned char frame_count,
unsigned char * frame_data
)
{
char usb_buf[64];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x12;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x0F;
usb_buf[0x03] = 0x3F;
usb_buf[0x05] = zone;
usb_buf[0x07] = frame_count;
/*-----------------------------------------------------*\
| Copy in frame data |
\*-----------------------------------------------------*/
memcpy(&usb_buf[0x08], frame_data, frame_count * 4);
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_pkt_0x12, (unsigned char *)usb_buf, 64);
hid_read(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
}
void LogitechG910Controller::SendMode
(
unsigned char zone,
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
)
{
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0xFF;
usb_buf[0x02] = 0x10;
usb_buf[0x03] = 0x3B;
usb_buf[0x04] = zone;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 100 * speed;
if(mode == LOGITECH_G910_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = 0x64;
}
else if(mode == LOGITECH_G910_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = 0x64;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
hid_read(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
}
@@ -0,0 +1,99 @@
/*-----------------------------------------*\
| LogitechG910Controller.h |
| |
| Definitions and types for Logitech G910 |
| Orion Spectrum keyboard light controller |
| |
| Adam Honse (CalcProgrammer1) 6/11/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
LOGITECH_G910_ZONE_MODE_KEYBOARD = 0x00,
LOGITECH_G910_ZONE_MODE_LOGO = 0x01,
};
enum
{
LOGITECH_G910_ZONE_DIRECT_KEYBOARD = 0x01,
LOGITECH_G910_ZONE_DIRECT_GKEYS = 0x04,
LOGITECH_G910_ZONE_DIRECT_LOGO = 0x10,
LOGITECH_G910_ZONE_DIRECT_INDICATORS = 0x40,
};
enum
{
LOGITECH_G910_MODE_OFF = 0x00,
LOGITECH_G910_MODE_STATIC = 0x01,
LOGITECH_G910_MODE_BREATHING = 0x02,
LOGITECH_G910_MODE_CYCLE = 0x03,
LOGITECH_G910_MODE_WAVE = 0x04,
};
/*---------------------------------------------------------------------------------------------*\
| Speed is 1000 for fast and 20000 for slow. |
| Values are multiplied by 100 later to give lots of GUI steps. |
\*---------------------------------------------------------------------------------------------*/
enum
{
LOGITECH_G910_SPEED_SLOWEST = 0xC8, /* Slowest speed */
LOGITECH_G910_SPEED_NORMAL = 0x32, /* Normal speed */
LOGITECH_G910_SPEED_FASTEST = 0x0A, /* Fastest speed */
};
class LogitechG910Controller
{
public:
LogitechG910Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12);
~LogitechG910Controller();
std::string GetSerialString();
void Commit();
void SetDirect
(
unsigned char zone,
unsigned char frame_count,
unsigned char * frame_data
);
void SetMode
(
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
private:
hid_device* dev_pkt_0x11;
hid_device* dev_pkt_0x12;
void SendDirectFrame
(
unsigned char zone,
unsigned char frame_count,
unsigned char * frame_data
);
void SendMode
(
unsigned char zone,
unsigned char mode,
unsigned short speed,
unsigned char red,
unsigned char green,
unsigned char blue
);
void SendCommit();
};
@@ -0,0 +1,176 @@
/*-----------------------------------------*\
| LogitechGLightsyncController.cpp |
| |
| Driver for Logitech G Lightsync |
| lighting controllers |
| |
| TheRogueZeta 04/21/2021 |
\*-----------------------------------------*/
#include "LogitechGLightsyncController.h"
#include <cstring>
LogitechGLightsyncController::LogitechGLightsyncController(hid_device* dev_cmd_handle, hid_device *dev_handle, const char *path, unsigned char hid_dev_index, unsigned char hid_feature_index, unsigned char hid_fctn_ase_id)
{
dev = dev_handle;
cmd_dev = dev_cmd_handle;
location = path;
dev_index = hid_dev_index;
feature_index = hid_feature_index;
fctn_ase_id = hid_fctn_ase_id;
mutex = nullptr;
}
LogitechGLightsyncController::LogitechGLightsyncController(hid_device* dev_cmd_handle, hid_device *dev_handle, const char *path, unsigned char hid_dev_index, unsigned char hid_feature_index, unsigned char hid_fctn_ase_id, std::shared_ptr<std::mutex> mutex_ptr)
{
dev = dev_handle;
cmd_dev = dev_cmd_handle;
location = path;
dev_index = hid_dev_index;
feature_index = hid_feature_index;
fctn_ase_id = hid_fctn_ase_id;
mutex = mutex_ptr;
}
LogitechGLightsyncController::~LogitechGLightsyncController()
{
hid_close(dev);
}
std::string LogitechGLightsyncController::GetDeviceLocation()
{
return (location);
}
std::string LogitechGLightsyncController::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, serial_string, 128);
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void LogitechGLightsyncController::UpdateMouseLED(
unsigned char mode,
std::uint16_t speed,
unsigned char zone,
unsigned char red,
unsigned char green,
unsigned char blue,
unsigned char brightness
)
{
unsigned char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = dev_index;
usb_buf[0x02] = feature_index;
usb_buf[0x03] = fctn_ase_id;
usb_buf[0x04] = zone;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 100 * speed;
if (mode == LOGITECH_G_LIGHTSYNC_MODE_STATIC)
{
usb_buf[0x09] = 0x02;
}
if (mode == LOGITECH_G_LIGHTSYNC_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
usb_buf[0x0D] = brightness;
}
else if (mode == LOGITECH_G_LIGHTSYNC_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
usb_buf[0x0C] = brightness;
}
/*-----------------------------------------------------*\
| Send packet |
| This code has to be protected to avoid crashes when |
| this is called at the same time to change a powerplay |
| mat and its paired wireless mouse leds. It will |
| happen when using effects engines with high framerate |
\*-----------------------------------------------------*/
if(mutex)
{
std::lock_guard<std::mutex> guard(*mutex);
hid_write(dev, usb_buf, 20);
hid_read(dev, usb_buf, 20);
}
else
{
hid_write(dev, usb_buf, 20);
hid_read(dev, usb_buf, 20);
}
}
void LogitechGLightsyncController::SetDirectMode(bool direct)
{
char cmd_buf[7];
char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(cmd_buf, 0x00, sizeof(cmd_buf));
/*-----------------------------------------------------*\
| Set up Command Control packet |
\*-----------------------------------------------------*/
cmd_buf[0x00] = 0x10;
cmd_buf[0x01] = dev_index;
cmd_buf[0x02] = feature_index;
cmd_buf[0x03] = 0x8A;
cmd_buf[0x04] = 0x00;
cmd_buf[0x05] = 0x00;
/*-----------------------------------------------------*\
| If direct, disable save to flash |
\*-----------------------------------------------------*/
if(direct)
{
cmd_buf[0x04] = 0x01;
cmd_buf[0x05] = 0x01;
}
/*-----------------------------------------------------*\
| Send packet |
| This code has to be protected to avoid crashes when |
| this is called at the same time to change a powerplay |
| mat and its paired wireless mouse leds. It will |
| happen when using effects engines with high framerate |
\*-----------------------------------------------------*/
if(mutex)
{
std::lock_guard<std::mutex> guard(*mutex);
hid_write(cmd_dev, (unsigned char *)cmd_buf, 7);
hid_read(dev, (unsigned char *)usb_buf, 20);
}
else
{
hid_write(cmd_dev, (unsigned char *)cmd_buf, 7);
hid_read(dev, (unsigned char *)usb_buf, 20);
}
}
@@ -0,0 +1,82 @@
/*-----------------------------------------*\
| LogitechGLightsyncController.h |
| |
| Definitions and types for Logitech |
| Lightsync lighting controllers |
| |
| TheRogueZeta 04/21/2021 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#include <memory>
#pragma once
enum
{
LOGITECH_G_LIGHTSYNC_MODE_OFF = 0x00,
LOGITECH_G_LIGHTSYNC_MODE_STATIC = 0x01,
LOGITECH_G_LIGHTSYNC_MODE_CYCLE = 0x02,
LOGITECH_G_LIGHTSYNC_MODE_BREATHING = 0x03,
};
/*---------------------------------------------------------------------------------------------*\
| Speed is 1000 for fast and 20000 for slow. |
| Values are multiplied by 100 later to give lots of GUI steps. |
\*---------------------------------------------------------------------------------------------*/
enum
{
LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST = 0xC8, /* Slowest speed */
LOGITECH_G_LIGHTSYNC_SPEED_NORMAL = 0x32, /* Normal speed */
LOGITECH_G_LIGHTSYNC_SPEED_FASTEST = 0x0A, /* Fastest speed */
};
class LogitechGLightsyncController
{
public:
LogitechGLightsyncController(
hid_device* dev_cmd_handle,
hid_device* dev_handle,
const char* path,
unsigned char hid_dev_index,
unsigned char hid_feature_index,
unsigned char hid_fctn_ase_id);
LogitechGLightsyncController(
hid_device* dev_cmd_handle,
hid_device* dev_handle,
const char* path,
unsigned char hid_dev_index,
unsigned char hid_feature_index,
unsigned char hid_fctn_ase_id,
std::shared_ptr<std::mutex> mutex_ptr);
~LogitechGLightsyncController();
std::string GetDeviceLocation();
std::string GetSerialString();
void UpdateMouseLED
(
unsigned char mode,
unsigned short speed,
unsigned char zone,
unsigned char red,
unsigned char green,
unsigned char blue,
unsigned char brightness
);
void SetDirectMode(bool direct);
private:
hid_device* dev;
hid_device* cmd_dev;
std::string location;
unsigned char dev_index;
unsigned char feature_index;
unsigned char fctn_ase_id;
bool direct_state;
std::shared_ptr<std::mutex> mutex;
};
@@ -1,99 +0,0 @@
/*-----------------------------------------*\
| LogitechGPowerPlayController.cpp |
| |
| Driver for Logitech G PowerPlay Wireless |
| Charging System |
| |
| TheRogueZeta 8/31/2020 |
\*-----------------------------------------*/
#include "LogitechGPowerPlayController.h"
#include <cstring>
LogitechGPowerPlayController::LogitechGPowerPlayController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
LogitechGPowerPlayController::~LogitechGPowerPlayController()
{
hid_close(dev);
}
std::string LogitechGPowerPlayController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string LogitechGPowerPlayController::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, serial_string, 128);
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void LogitechGPowerPlayController::SendMouseMatMode
(
unsigned char mode,
std::uint16_t speed,
unsigned char zone,
unsigned char red,
unsigned char green,
unsigned char blue
// unsigned char brightness
)
{
unsigned char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x07;
usb_buf[0x02] = 0x0B;
usb_buf[0x03] = 0x3E;
usb_buf[0x04] = zone;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 100 * speed;
if(mode == LOGITECH_G_POWERPLAY_MODE_STATIC)
{
usb_buf[0x09] = 0x02;
}
if(mode == LOGITECH_G_POWERPLAY_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
//usb_buf[0x0D] = brightness;
usb_buf[0x0D] = 0x64;
}
else if(mode == LOGITECH_G_POWERPLAY_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
//usb_buf[0x0C] = brightness;
usb_buf[0x0C] = 0x64;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 20);
hid_read(dev, usb_buf, 20);
}
@@ -1,59 +0,0 @@
/*-----------------------------------------*\
| LogitechGPowerPlayController.h |
| |
| Definitions and types for Logitech G |
| PowerPlay Wireless lighting controller |
| |
| TheRogueZeta 8/31/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include <string>
#include <hidapi/hidapi.h>
#pragma once
enum
{
LOGITECH_G_POWERPLAY_MODE_OFF = 0x00,
LOGITECH_G_POWERPLAY_MODE_STATIC = 0x01,
LOGITECH_G_POWERPLAY_MODE_CYCLE = 0x02,
LOGITECH_G_POWERPLAY_MODE_BREATHING = 0x03,
};
/*---------------------------------------------------------------------------------------------*\
| Speed is 1000 for fast and 20000 for slow. |
| Values are multiplied by 100 later to give lots of GUI steps. |
\*---------------------------------------------------------------------------------------------*/
enum
{
LOGITECH_G_POWERPLAY_SPEED_SLOWEST = 0xC8, /* Slowest speed */
LOGITECH_G_POWERPLAY_SPEED_NORMAL = 0x32, /* Normal speed */
LOGITECH_G_POWERPLAY_SPEED_FASTEST = 0x0A, /* Fastest speed */
};
class LogitechGPowerPlayController
{
public:
LogitechGPowerPlayController(hid_device* dev_handle, const char* path);
~LogitechGPowerPlayController();
std::string GetDeviceLocation();
std::string GetSerialString();
void SendMouseMatMode
(
unsigned char mode,
unsigned short speed,
unsigned char zone,
unsigned char red,
unsigned char green,
unsigned char blue
// unsigned char brightness
);
private:
hid_device* dev;
std::string location;
};
@@ -1,99 +0,0 @@
/*-----------------------------------------*\
| LogitechGProWirelessController.cpp |
| |
| Driver for Logitech G Pro Wireless Gaming|
| Mouse lighting controller |
| |
| TheRogueZeta 8/5/2020 |
\*-----------------------------------------*/
#include "LogitechGProWirelessController.h"
#include <cstring>
LogitechGProWirelessController::LogitechGProWirelessController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
LogitechGProWirelessController::~LogitechGProWirelessController()
{
hid_close(dev);
}
std::string LogitechGProWirelessController::GetDeviceLocation()
{
return("HID: " + location);
}
std::string LogitechGProWirelessController::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, serial_string, 128);
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void LogitechGProWirelessController::SendMouseMode
(
unsigned char mode,
std::uint16_t speed,
unsigned char zone,
unsigned char red,
unsigned char green,
unsigned char blue
// unsigned char brightness
)
{
unsigned char usb_buf[20];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, sizeof(usb_buf));
/*-----------------------------------------------------*\
| Set up Lighting Control packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x11;
usb_buf[0x01] = 0x01;
usb_buf[0x02] = 0x07;
usb_buf[0x03] = 0x3C;
usb_buf[0x04] = zone;
usb_buf[0x05] = mode;
usb_buf[0x06] = red;
usb_buf[0x07] = green;
usb_buf[0x08] = blue;
speed = 100 * speed;
if(mode == LOGITECH_G_PRO_WIRELESS_MODE_STATIC)
{
usb_buf[0x09] = 0x02;
}
if(mode == LOGITECH_G_PRO_WIRELESS_MODE_CYCLE)
{
usb_buf[0x0B] = speed >> 8;
usb_buf[0x0C] = speed & 0xFF;
//usb_buf[0x0D] = brightness;
usb_buf[0x0D] = 0x64;
}
else if(mode == LOGITECH_G_PRO_WIRELESS_MODE_BREATHING)
{
usb_buf[0x09] = speed >> 8;
usb_buf[0x0A] = speed & 0xFF;
//usb_buf[0x0C] = brightness;
usb_buf[0x0C] = 0x64;
}
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 20);
hid_read(dev, usb_buf, 20);
}
@@ -0,0 +1,53 @@
/*-----------------------------------------*\
| LogitechLightspeedController.cpp |
| |
| Driver for Logitech Lightspeed Wireless |
| Gaming Mice lighting controller |
| |
| TheRogueZeta 8/5/2020 |
\*-----------------------------------------*/
#include "LogitechLightspeedController.h"
#include <cstring>
LogitechLightspeedController::LogitechLightspeedController(hid_device* dev_handle, const char* path)
{
dev = dev_handle;
location = path;
}
LogitechLightspeedController::~LogitechLightspeedController()
{
delete lightspeed;
}
std::string LogitechLightspeedController::GetDeviceLocation()
{
return("HID: " + location + " (Receiver) \r\nWireless Index: " + std::to_string(lightspeed->device_index));
}
std::string LogitechLightspeedController::GetSerialString()
{
wchar_t serial_string[128];
hid_get_serial_number_string(dev, serial_string, 128);
std::wstring return_wstring = serial_string;
std::string return_string(return_wstring.begin(), return_wstring.end());
return(return_string);
}
void LogitechLightspeedController::SendMouseMode
(
unsigned char mode,
std::uint16_t speed,
unsigned char zone,
unsigned char red,
unsigned char green,
unsigned char blue
// unsigned char brightness
)
{
lightspeed->setMode(mode, speed, zone, red, green, blue, 0x64);
}
@@ -1,13 +1,15 @@
/*-----------------------------------------*\
| LogitechGProWirelessController.h |
| LogitechLightspeedController.h |
| |
| Definitions and types for Logitech G Pro |
| Wireless Gaming Mouse lighting controller|
| Definitions and types for Logitech G |
| Lightsync Wireless Gaming Mice lighting |
| controller |
| |
| TheRogueZeta 8/5/2020 |
\*-----------------------------------------*/
#include "RGBController.h"
#include "LogitechProtocolCommon.h"
#include <string>
#include <hidapi/hidapi.h>
@@ -33,12 +35,14 @@ enum
LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST = 0x0A, /* Fastest speed */
};
class LogitechGProWirelessController
class LogitechLightspeedController
{
public:
LogitechGProWirelessController(hid_device* dev_handle, const char* path);
~LogitechGProWirelessController();
LogitechLightspeedController(hid_device* dev_handle, const char* path);
~LogitechLightspeedController();
logitech_device* lightspeed;
std::string GetDeviceLocation();
std::string GetSerialString();
@@ -0,0 +1,587 @@
/*-------------------------------------------------------------------*\
| LogitechProtocolCommon.cpp |
| |
| Common Logitech RAP and FAP protocol calls |
| |
| Chris M (Dr_No) 4th May 2021 |
| |
\*-------------------------------------------------------------------*/
#include <LogitechProtocolCommon.h>
static std::vector<uint16_t> logitech_RGB_pages =
{
0x8070,
0x8071
};
int getWirelessDevice(usages device_usages, uint16_t pid, wireless_map *wireless_devices)
{
int result;
hid_device* dev_use1;
usages::iterator find_usage = device_usages.find(1);
if (find_usage == device_usages.end())
{
LOG_NOTICE("Unable get_Wireless_Device due to missing FAP Short Message (0x10) usage");
LOG_DEBUG("Dumping device usages:");
for(usages::iterator dev = device_usages.begin(); dev != device_usages.end(); dev++)
{
LOG_DEBUG("Usage index:\t%i", dev->first);
}
}
else
{
dev_use1 = find_usage->second;
/*-----------------------------------------------------------------*\
| Create a buffer for reads |
\*-----------------------------------------------------------------*/
blankFAPmessage response;
response.init();
shortFAPrequest get_connected_devices;
get_connected_devices.init(LOGITECH_RECEIVER_ADDRESS, LOGITECH_GET_REGISTER_REQUEST);
result = hid_write(dev_use1, get_connected_devices.buffer, get_connected_devices.size());
result = hid_read_timeout(dev_use1, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
bool wireless_notifications = response.data[1] & 1; //Connected devices is a flag
if (!wireless_notifications)
{
response.init(); //zero out the response
get_connected_devices.init(LOGITECH_RECEIVER_ADDRESS, LOGITECH_SET_REGISTER_REQUEST);
get_connected_devices.data[1] = 1;
result = hid_write(dev_use1, get_connected_devices.buffer, get_connected_devices.size());
result = hid_read_timeout(dev_use1, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
if(get_connected_devices.feature_index == 0x8F)
{
LOG_ERROR("Logitech Protocol error: %02X %02X %02X %02X %02X %02X %02X", get_connected_devices.report_id, get_connected_devices.device_index, get_connected_devices.feature_index, get_connected_devices.feature_command, get_connected_devices.data[0], get_connected_devices.data[1], get_connected_devices.data[2]);
}
}
response.init(); //zero out the response
get_connected_devices.init(LOGITECH_RECEIVER_ADDRESS, LOGITECH_GET_REGISTER_REQUEST);
get_connected_devices.feature_command = 0x02; //0x02 Connection State register. Essentially asking for count of paired devices
result = hid_write(dev_use1, get_connected_devices.buffer, get_connected_devices.size());
result = hid_read_timeout(dev_use1, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
unsigned int device_count = response.data[1];
LOG_NOTICE("Count of connected devices to %4X: %i", pid, device_count);
if (device_count > 0)
{
LOG_NOTICE("Faking a reconnect to get device list");
device_count++; //Add 1 to the device_count to include the receiver
response.init();
get_connected_devices.init(LOGITECH_RECEIVER_ADDRESS, LOGITECH_SET_REGISTER_REQUEST);
get_connected_devices.feature_index = LOGITECH_SET_REGISTER_REQUEST;
get_connected_devices.feature_command = 0x02; //0x02 Connection State register
get_connected_devices.data[0] = 0x02; //Writting 0x02 to the connection state register will ask the receiver to fake a reconnect of paired devices
result = hid_write(dev_use1, get_connected_devices.buffer, get_connected_devices.size());
for(size_t i = 0; i < device_count; i++)
{
blankFAPmessage devices;
devices.init();
hid_read_timeout(dev_use1, devices.buffer, devices.size(), LOGITECH_PROTOCOL_TIMEOUT);
unsigned int wireless_PID = (devices.data[2] << 8) | devices.data[1];
LOG_NOTICE("Connected Device Index %i:\tVirtualID=%04X\t\t%02X %02X %02X %02X %02X %02X %02X", i, wireless_PID, devices.buffer[0], devices.buffer[1], devices.buffer[2], devices.buffer[3], devices.buffer[4], devices.buffer[5], devices.buffer[6]);
/*-----------------------------------------------------------------*\
| We need to read the receiver from the HID device queue but |
| there is no need to add it as it's own device |
\*-----------------------------------------------------------------*/
if(devices.device_index != 0xFF)
{
wireless_devices->emplace(wireless_PID, devices.device_index);
}
}
}
else
{
LOG_WARNING("No devices were found connected to receiver!");
}
}
return wireless_devices->size();
}
logitech_device::logitech_device(char *path, usages _usages, uint8_t _device_index, bool _wireless)
{
device_index = _device_index;
location = path;
device_usages = _usages;
wireless = _wireless;
RGB_feature_index = 0;
LED_count = 0;
mutex = nullptr;
initialiseDevice();
}
logitech_device::logitech_device(char *path, usages _usages, uint8_t _device_index, bool _wireless, std::shared_ptr<std::mutex> mutex_ptr)
{
device_index = _device_index;
location = path;
device_usages = _usages;
wireless = _wireless;
RGB_feature_index = 0;
LED_count = 0;
mutex = mutex_ptr;
initialiseDevice();
}
logitech_device::~logitech_device()
{
for(usages::iterator dev = device_usages.begin(); dev != device_usages.end(); dev++)
{
hid_close(dev->second);
}
}
void logitech_device::initialiseDevice()
{
flushReadQueue();
getDeviceName(); //This will get the name of the device if it exists
for(std::vector<uint16_t>::iterator page = logitech_RGB_pages.begin(); page != logitech_RGB_pages.end(); page++)
{
int feature_index = getFeatureIndex(*page);
if(feature_index > 0)
{
feature_list.emplace(*page, feature_index);
RGB_feature_index = feature_index;
}
}
if (RGB_feature_index == 0)
{
/*-----------------------------------------------------------------*\
| If there was no RGB Effect Feature page found |
| dump the entire Feature list to log |
\*-----------------------------------------------------------------*/
getDeviceFeatureList(); //This will populate the feature list
LOG_NOTICE("Unable add this device due to missing RGB Effects Feature");
for(features::iterator feature = feature_list.begin(); feature != feature_list.end(); feature++)
{
LOG_NOTICE("Feature Index: %02X\tFeature Page: %04X", feature->second, feature->first);
}
}
else
{
getRGBconfig();
}
}
bool logitech_device::connected()
{
bool test = false;
hid_device* dev_use1 = getDevice(1);
if(dev_use1)
{
blankFAPmessage response;
response.init(); //zero out the response
shortFAPrequest get_connected_devices;
get_connected_devices.init(device_index, LOGITECH_GET_REGISTER_REQUEST);
get_connected_devices.feature_command = 0x02; //0x02 Connection State register. Essentially asking for count of paired devices
hid_write(dev_use1, get_connected_devices.buffer, get_connected_devices.size());
hid_read_timeout(dev_use1, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
test = (response.data[1] != 0x09); //ERR_RESOURCE_ERROR i.e. not currently connected
}
return test;
}
uint8_t logitech_device::getLEDinfo()
{
/*-----------------------------------------------------------------*\
| Get all info about the LEDs and Zones |
\*-----------------------------------------------------------------*/
return LED_count;
}
void logitech_device::flushReadQueue()
{
/*-----------------------------------------------------------------*\
| Create a buffer for reads |
\*-----------------------------------------------------------------*/
blankFAPmessage response;
response.init();
for(usages::iterator dev = device_usages.begin(); dev != device_usages.end(); dev++)
{
//Flush the buffer
int result = 1;
while( result > 0 )
{
result = hid_read_timeout(dev->second, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
}
}
}
hid_device* logitech_device::getDevice(uint8_t usage_index)
{
/*-----------------------------------------------------------------*\
| Check the usage map for usage_index |
| Return the associated device if found otherwise a nullptr |
\*-----------------------------------------------------------------*/
#ifdef WIN32
usages::iterator find_usage = device_usages.find(usage_index);
#else
usages::iterator find_usage = device_usages.begin();
#endif //WIN32
if (find_usage == device_usages.end())
{
LOG_NOTICE("Unable add this device due to missing FAP Message usage %i", usage_index);
return nullptr;
}
else
{
return find_usage->second;
}
}
uint8_t logitech_device::getFeatureIndex(uint16_t feature_page)
{
/*-----------------------------------------------------------------*\
| Get the feature index from the Root Index |
| Return the mapped feature_index of the given feature page |
| for this device or else return 0 |
\*-----------------------------------------------------------------*/
int result = 0;
uint8_t feature_index = 0;
hid_device* dev_use2 = getDevice(2);
if(dev_use2)
{
blankFAPmessage response;
longFAPrequest get_index;
get_index.init(device_index, LOGITECH_HIDPP_PAGE_ROOT_IDX, LOGITECH_CMD_ROOT_GET_FEATURE);
get_index.data[0] = feature_page >> 8;
get_index.data[1] = feature_page & 0xFF;
result = hid_write(dev_use2, get_index.buffer, get_index.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
feature_index = response.data[0];
}
return feature_index;
}
int logitech_device::getDeviceFeatureList()
{
int result = 0;
/*-----------------------------------------------------------------*\
| Check the usage map for usage1 (0x10 Short FAP Message) & usage2 |
| (0x11 Long FAP Message) then list all features for device |
\*-----------------------------------------------------------------*/
hid_device* dev_use1 = getDevice(1);
hid_device* dev_use2 = getDevice(2);
if(dev_use1 && dev_use2)
{
/*-----------------------------------------------------------------*\
| Create a buffer for reads |
\*-----------------------------------------------------------------*/
blankFAPmessage response;
response.init();
/*-----------------------------------------------------------------*\
| Query the root index for the index of the feature list |
| This is done for safety as it is generaly at feature index 0x01 |
\*-----------------------------------------------------------------*/
shortFAPrequest get_index;
get_index.init(device_index, LOGITECH_HIDPP_PAGE_ROOT_IDX);
get_index.feature_command = LOGITECH_CMD_ROOT_GET_FEATURE;
get_index.data[0] = LOGITECH_HIDPP_PAGE_FEATURE_SET >> 8; //Get feature index of the Feature Set 0x0001
get_index.data[1] = LOGITECH_HIDPP_PAGE_FEATURE_SET & 0xFF;
result = hid_write(dev_use1, get_index.buffer, get_index.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
uint8_t feature_index = response.data[0];
/*-----------------------------------------------------------------*\
| Get the count of Features |
\*-----------------------------------------------------------------*/
shortFAPrequest get_count;
get_count.init(device_index, feature_index);
get_count.feature_command = LOGITECH_CMD_FEATURE_SET_GET_COUNT;
result = hid_write(dev_use1, get_count.buffer, get_count.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
unsigned int feature_count = response.data[0];
shortFAPrequest get_features;
get_features.init(device_index, feature_index);
get_features.feature_command = LOGITECH_CMD_FEATURE_SET_GET_ID;
for(std::size_t i = 1; feature_list.size() < feature_count; i++ )
{
get_features.data[0] = i;
result = hid_write(dev_use1, get_features.buffer, get_features.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
LOG_DEBUG("Reading HID++ Feature %04X at index: %02X", (response.data[0] << 8) | response.data[1], i);
feature_list.emplace((response.data[0] << 8) | response.data[1], i);
}
}
else
{
if(!dev_use1)
{
LOG_NOTICE("Unable add this device due to missing FAP Short Message (0x10) usage");
}
if(!dev_use2)
{
LOG_NOTICE("Unable add this device due to missing FAP Long Message (0x11) usage");
}
}
return feature_list.size();
}
int logitech_device::getDeviceName()
{
/*-----------------------------------------------------------------*\
| Check the usage map for usage2 (0x11 Long FAP Message) |
| Then use it to get the name for this device |
\*-----------------------------------------------------------------*/
hid_device* dev_use2 = getDevice(2);
if(dev_use2)
{
/*-----------------------------------------------------------------*\
| Create a buffer for reads |
\*-----------------------------------------------------------------*/
blankFAPmessage response;
response.init();
int result;
/*-----------------------------------------------------------------*\
| Check if the feature_list contains an index for the Device_name |
| feature otherwise query the root index. If not found return 0 |
\*-----------------------------------------------------------------*/
uint8_t name_feature_index;
features::iterator find_feature = feature_list.find(LOGITECH_HIDPP_PAGE_DEVICE_NAME_TYPE);
if (find_feature == feature_list.end())
{
longFAPrequest get_index;
get_index.init(device_index, LOGITECH_HIDPP_PAGE_ROOT_IDX, LOGITECH_CMD_ROOT_GET_FEATURE);
get_index.data[0] = LOGITECH_HIDPP_PAGE_DEVICE_NAME_TYPE >> 8; //Get feature index of the Feature Set 0x0001
get_index.data[1] = LOGITECH_HIDPP_PAGE_DEVICE_NAME_TYPE & 0xFF;
result = hid_write(dev_use2, get_index.buffer, get_index.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
name_feature_index = response.data[0];
}
else
{
name_feature_index = find_feature->second;
}
/*-----------------------------------------------------------------*\
| Get the device name length |
\*-----------------------------------------------------------------*/
longFAPrequest get_length;
get_length.init(device_index, name_feature_index, LOTITECH_CMD_DEVICE_NAME_TYPE_GET_COUNT);
result = hid_write(dev_use2, get_length.buffer, get_length.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
unsigned int name_length = response.data[0];
longFAPrequest get_name;
get_name.init(device_index, name_feature_index, LOGITECH_CMD_DEVICE_NAME_TYPE_GET_DEVICE_NAME);
while(device_name.length() < name_length)
{
get_name.data[0] = device_name.length(); //This sets the character index to get from the device
result = hid_write(dev_use2, get_name.buffer, get_name.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
std::string temp = (char *)&response.data;
device_name.append(temp);
}
get_name.init(device_index, name_feature_index, LOGITECH_CMD_DEVICE_NAME_TYPE_GET_TYPE);
result = hid_write(dev_use2, get_name.buffer, get_name.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
logitech_device_type = response.data[0];
}
return device_name.length();
}
void logitech_device::getRGBconfig()
{
/*-----------------------------------------------------------------*\
| Check the usage map for usage2 (0x11 Long FAP Message) |
| Then use it to get the name for this device |
\*-----------------------------------------------------------------*/
hid_device* dev_use2 = getDevice(2);
if(dev_use2)
{
/*-----------------------------------------------------------------*\
| Create a buffer for reads |
\*-----------------------------------------------------------------*/
blankFAPmessage response;
response.init();
int result;
longFAPrequest get_count;
get_count.init(device_index, RGB_feature_index, LOGITECH_CMD_RGB_EFFECTS_GET_COUNT);
result = hid_write(dev_use2, get_count.buffer, get_count.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
LED_count = response.data[0];
get_count.feature_command = LOGITECH_CMD_RGB_EFFECTS_GET_INFO;
for(std::size_t i = 0; i < LED_count; i++ )
{
//TODO: Push this info into a vector for later enumeration by the RGBController
get_count.data[0] = i;
result = hid_write(dev_use2, get_count.buffer, get_count.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
}
/*get_count.feature_command = LOGITECH_CMD_RGB_EFFECTS_GET_STATE;
for(std::size_t i = 0; i < feature_count; i++ )
{
get_count.data[0] = i;
result = hid_write(dev_use2, get_count.buffer, get_count.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
}
get_count.feature_command = LOGITECH_CMD_RGB_EFFECTS_GET_CONFIG;
for(std::size_t i = 0; i < feature_count; i++ )
{
get_count.data[0] = i;
result = hid_write(dev_use2, get_count.buffer, get_count.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
}*/
}
}
uint8_t logitech_device::setDirectMode(bool direct)
{
int result = 0;
/*-----------------------------------------------------------------*\
| Check the usage map for usage1 (0x10 Short FAP Message) & usage2 |
| (0x11 Long FAP Message) then set the device into direct mode |
| via register 0x8A |
\*-----------------------------------------------------------------*/
hid_device* dev_use1 = getDevice(1);
hid_device* dev_use2 = getDevice(2);
if(dev_use1 && dev_use2)
{
/*-----------------------------------------------------------------*\
| Create a buffer for reads |
\*-----------------------------------------------------------------*/
blankFAPmessage response;
response.init();
/*-----------------------------------------------------------------*\
| Turn the direct mode on or off via the RGB_feature_index |
\*-----------------------------------------------------------------*/
shortFAPrequest set_direct;
set_direct.init(device_index, RGB_feature_index);
set_direct.feature_command = LOGITECH_CMD_RGB_EFFECTS_UNKNOWN;
set_direct.data[0] = (direct) ? 1 : 0;
set_direct.data[1] = set_direct.data[0];
/*-----------------------------------------------------*\
| Send packet |
| This code has to be protected to avoid crashes when |
| this is called at the same time to change a powerplay |
| mat and its paired wireless mouse leds. It will |
| happen when using effects engines with high framerate |
\*-----------------------------------------------------*/
if(mutex)
{
std::lock_guard<std::mutex> guard(*mutex);
result = hid_write(dev_use1, set_direct.buffer, set_direct.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
}
else
{
result = hid_write(dev_use1, set_direct.buffer, set_direct.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
}
}
return result;
}
uint8_t logitech_device::setMode(uint8_t mode, uint16_t speed, uint8_t zone, uint8_t red, uint8_t green, uint8_t blue, uint8_t brightness)
{
int result = 0;
/*-----------------------------------------------------------------*\
| Check the usage map for usage2 (0x11 Long FAP Message) then |
| set the device mode via LOGITECH_CMD_RGB_EFFECTS_SET_CONTROL |
\*-----------------------------------------------------------------*/
hid_device* dev_use2 = getDevice(2);
if(dev_use2)
{
/*-----------------------------------------------------------------*\
| Create a buffer for reads |
\*-----------------------------------------------------------------*/
blankFAPmessage response;
response.init();
/*-----------------------------------------------------------------*\
| Set the mode via the RGB_feature_index |
\*-----------------------------------------------------------------*/
longFAPrequest set_mode;
set_mode.init(device_index, RGB_feature_index, LOGITECH_CMD_RGB_EFFECTS_SET_CONTROL);
set_mode.data[0] = zone;
set_mode.data[1] = mode;
set_mode.data[2] = red;
set_mode.data[3] = green;
set_mode.data[4] = blue;
speed *= 100;
if(mode == 1) //Static
{
set_mode.data[5] = zone;
}
else if(mode == 2) //Spectrum Cycle
{
set_mode.data[7] = speed >> 8;
set_mode.data[8] = speed & 0xFF;
set_mode.data[9] = brightness;
}
else if(mode == 3) //Breathing
{
set_mode.data[5] = speed >> 8;
set_mode.data[6] = speed & 0xFF;
set_mode.data[8] = brightness;
}
/*-----------------------------------------------------*\
| Send packet |
| This code has to be protected to avoid crashes when |
| this is called at the same time to change a powerplay |
| mat and its paired wireless mouse leds. It will |
| happen when using effects engines with high framerate |
\*-----------------------------------------------------*/
if(mutex)
{
std::lock_guard<std::mutex> guard(*mutex);
result = hid_write(dev_use2, set_mode.buffer, set_mode.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
}
else
{
result = hid_write(dev_use2, set_mode.buffer, set_mode.size());
result = hid_read_timeout(dev_use2, response.buffer, response.size(), LOGITECH_PROTOCOL_TIMEOUT);
}
}
return result;
}
@@ -0,0 +1,218 @@
/*-------------------------------------------------------------------*\
| LogitechProtocolCommon.h |
| |
| Common Logitech RAP and FAP protocol calls |
| |
| Chris M (Dr_No) 4th May 2021 |
| |
\*-------------------------------------------------------------------*/
#include <map>
#include <hidapi/hidapi.h>
#include "LogManager.h"
#pragma once
#define LOGITECH_PROTOCOL_TIMEOUT 300 //Timeout in ms
#define LOGITECH_HEADER_SIZE 3
#define LOGITECH_SHORT_MESSAGE 0x10
#define LOGITECH_SHORT_MESSAGE_LEN 7
#define LOGITECH_LONG_MESSAGE 0x11
#define LOGITECH_LONG_MESSAGE_LEN 20
#define LOGITECH_FAP_RESPONSE_LEN 64 //Define a universal response buffer and allow the hidapi to determine the size
#define LOGITECH_RECEIVER_ADDRESS 0xFF //The Unifying receiver uses RAP or register access protocol
#define LOGITECH_SET_REGISTER_REQUEST 0x80
#define LOGITECH_GET_REGISTER_REQUEST 0x81
#define LOGITECH_HIDPP_PAGE_ROOT_IDX 0x00 //Used for querying the feature index
#define LOGITECH_CMD_ROOT_GET_FEATURE 0x01
#define LOGITECH_CMD_ROOT_GET_PROTOCOL 0x11
#define LOGITECH_HIDPP_PAGE_FEATURE_SET 0x0001
#define LOGITECH_CMD_FEATURE_SET_GET_COUNT 0x01
#define LOGITECH_CMD_FEATURE_SET_GET_ID 0x11
#define LOGITECH_HIDPP_PAGE_DEVICE_NAME_TYPE 0x0005
#define LOTITECH_CMD_DEVICE_NAME_TYPE_GET_COUNT 0x01
#define LOGITECH_CMD_DEVICE_NAME_TYPE_GET_DEVICE_NAME 0x11
#define LOGITECH_CMD_DEVICE_NAME_TYPE_GET_TYPE 0x21
#define LOGITECH_HIDPP_PAGE_RGB_EFFECTS1 0x8070
#define LOGITECH_HIDPP_PAGE_RGB_EFFECTS2 0x8071
#define LOGITECH_CMD_RGB_EFFECTS_GET_COUNT 0x00
#define LOGITECH_CMD_RGB_EFFECTS_GET_INFO 0x10
#define LOGITECH_CMD_RGB_EFFECTS_GET_CONTROL 0x20
#define LOGITECH_CMD_RGB_EFFECTS_SET_CONTROL 0x30
#define LOGITECH_CMD_RGB_EFFECTS_GET_STATE 0x40
#define LOGITECH_CMD_RGB_EFFECTS_SET_STATE 0x50
#define LOGITECH_CMD_RGB_EFFECTS_GET_CONFIG 0x60
#define LOGITECH_CMD_RGB_EFFECTS_SET_CONFIG 0x70
#define LOGITECH_CMD_RGB_EFFECTS_UNKNOWN 0x80 //Used to set "direct" mode
enum LOGITECH_DEVICE_TYPE
{
LOGITECH_DEVICE_TYPE_KEYBOARD = 0,
LOGITECH_DEVICE_TYPE_REMOTECONTROL =1,
LOGITECH_DEVICE_TYPE_NUMPAD = 2,
LOGITECH_DEVICE_TYPE_MOUSE = 3,
LOGITECH_DEVICE_TYPE_TOUCHPAD = 4,
LOGITECH_DEVICE_TYPE_TRACKBALL = 5,
LOGITECH_DEVICE_TYPE_PRESENTER = 6,
LOGITECH_DEVICE_TYPE_RECEIVER = 7
};
// Used for: {GET,SET}_REGISTER_{REQ,RSP}, SET_LONG_REGISTER_RSP, GET_LONG_REGISTER_REQ
struct message_short
{
unsigned char address;
unsigned char data[3];
};
// Used for: SET_LONG_REGISTER_REQ, GET_LONG_REGISTER_RSP
struct message_long
{
unsigned char address;
unsigned char data[16];
};
// Used for: ERROR_MSG
struct message_error
{
unsigned char sub_id;
unsigned char address;
unsigned char error_code;
unsigned char padding; /* set to 0 */
};
union shortFAPrequest
{
uint8_t buffer[LOGITECH_SHORT_MESSAGE_LEN];
struct
{
uint8_t report_id;
uint8_t device_index;
uint8_t feature_index;
uint8_t feature_command;
uint8_t data[LOGITECH_SHORT_MESSAGE_LEN - 4];
};
void init(uint8_t device_index, uint8_t feature_index)
{
this->report_id = LOGITECH_SHORT_MESSAGE;
this->device_index = device_index;
this->feature_index = feature_index;
this->feature_command = 0;
for(size_t i = 0; i < sizeof(data); i++)
{
this->data[i] = 0;
}
};
int size()
{
return LOGITECH_SHORT_MESSAGE_LEN;
};
};
union longFAPrequest
{
uint8_t buffer[LOGITECH_LONG_MESSAGE_LEN];
struct
{
uint8_t report_id;
uint8_t device_index;
uint8_t feature_index;
uint8_t feature_command;
uint8_t data[LOGITECH_LONG_MESSAGE_LEN - 4];
};
void init(uint8_t device_index, uint8_t feature_index, uint8_t feature_command)
{
this->report_id = LOGITECH_LONG_MESSAGE;
this->device_index = device_index;
this->feature_index = feature_index;
this->feature_command = feature_command;
for(size_t i = 0; i < sizeof(data); i++)
{
this->data[i] = 0;
}
};
int size()
{
return LOGITECH_LONG_MESSAGE_LEN;
};
};
union blankFAPmessage
{
uint8_t buffer[LOGITECH_FAP_RESPONSE_LEN];
struct
{
uint8_t command;
uint8_t device_index;
uint8_t feature_index;
uint8_t feature_command;
uint8_t data[LOGITECH_FAP_RESPONSE_LEN - 4];
};
//blank this buffer entirely
void init()
{
for(size_t i = 0; i < sizeof(buffer); i++)
{
this->buffer[i] = 0;
}
};
int size()
{
return LOGITECH_FAP_RESPONSE_LEN;
};
};
typedef std::map<uint8_t, hid_device*> usages;
typedef std::map<uint16_t, uint8_t> features;
typedef std::map<uint16_t, uint8_t> wireless_map;
int getWirelessDevice(usages _usages, uint16_t pid, wireless_map *wireless_devices); //Helper function needed outside of class
class logitech_device
{
public:
logitech_device(char *path, usages _usages, uint8_t _device_index, bool _wireless);
logitech_device(char *path, usages _usages, uint8_t _device_index, bool _wireless, std::shared_ptr<std::mutex> mutex_ptr);
~logitech_device();
/*-----------------------------------------------------------------*\
| usages is a std::map that stores all the devices HID usages |
| This is to ensure that we can communicate to all windows usages |
\*-----------------------------------------------------------------*/
usages device_usages;
features feature_list;
uint8_t device_index;
uint8_t RGB_feature_index; //Stored for quick use
uint8_t logitech_device_type;
bool wireless;
std::string device_name;
std::string location;
std::string protocol_version;
bool connected();
void flushReadQueue();
uint8_t getFeatureIndex(uint16_t feature_page);
uint8_t getLEDinfo();
uint8_t setDirectMode(bool direct);
uint8_t setMode(uint8_t mode, uint16_t speed, uint8_t zone, uint8_t red, uint8_t green, uint8_t blue, uint8_t brightness);
int getDeviceName();
private:
uint8_t LED_count;
std::shared_ptr<std::mutex> mutex;
hid_device* getDevice(uint8_t usage_index);
int getDeviceFeatureList();
void getRGBconfig();
void initialiseDevice();
};
@@ -1,117 +0,0 @@
/*-----------------------------------------*\
| RGBController_LogitechG203.cpp |
| |
| Generic RGB Interface for Logitech G203 |
| Prodigy RGB Mouse |
| |
| Adam Honse (CalcProgrammer1) 5/17/2020 |
\*-----------------------------------------*/
#include "RGBController_LogitechG203.h"
RGBController_LogitechG203::RGBController_LogitechG203(LogitechG203Controller* logitech_ptr)
{
logitech = logitech_ptr;
name = "Logitech Mouse Device";
vendor = "Logitech";
type = DEVICE_TYPE_MOUSE;
description = "Logitech Mouse Device";
location = logitech->GetDeviceLocation();
serial = logitech->GetSerialString();
mode Static;
Static.name = "Static";
Static.value = LOGITECH_G203_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Off;
Off.name = "Off";
Off.value = LOGITECH_G203_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Cycle;
Cycle.name = "Cycle";
Cycle.value = LOGITECH_G203_MODE_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.speed_min = LOGITECH_G203_SPEED_SLOWEST;
Cycle.speed_max = LOGITECH_G203_SPEED_FASTEST;
Cycle.speed = LOGITECH_G203_SPEED_NORMAL;
modes.push_back(Cycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = LOGITECH_G203_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed_min = LOGITECH_G203_SPEED_SLOWEST;
Breathing.speed_max = LOGITECH_G203_SPEED_FASTEST;
Breathing.speed = LOGITECH_G203_SPEED_NORMAL;
modes.push_back(Breathing);
SetupZones();
}
RGBController_LogitechG203::~RGBController_LogitechG203()
{
delete logitech;
}
void RGBController_LogitechG203::SetupZones()
{
zone g203_zone;
g203_zone.name = "Mouse";
g203_zone.type = ZONE_TYPE_SINGLE;
g203_zone.leds_min = 1;
g203_zone.leds_max = 1;
g203_zone.leds_count = 1;
g203_zone.matrix_map = NULL;
zones.push_back(g203_zone);
led g203_led;
g203_led.name = "Mouse";
leds.push_back(g203_led);
SetupColors();
}
void RGBController_LogitechG203::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_LogitechG203::DeviceUpdateLEDs()
{
unsigned char red = RGBGetRValue(colors[0]);
unsigned char grn = RGBGetGValue(colors[0]);
unsigned char blu = RGBGetBValue(colors[0]);
logitech->SendMouseMode(modes[active_mode].value, modes[active_mode].speed, red, grn, blu);
}
void RGBController_LogitechG203::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_LogitechG203::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
void RGBController_LogitechG203::SetCustomMode()
{
}
void RGBController_LogitechG203::DeviceUpdateMode()
{
DeviceUpdateLEDs();
}
@@ -1,129 +0,0 @@
/*-----------------------------------------*\
| RGBController_LogitechG303.cpp |
| |
| Generic RGB Interface for Logitech G303 |
| Daedalus Apex Mouse |
| |
| TheRogueZeta 02/14/2021 |
\*-----------------------------------------*/
#include "RGBController_LogitechG303.h"
RGBController_LogitechG303::RGBController_LogitechG303(LogitechG303Controller* logitech_ptr)
{
logitech = logitech_ptr;
name = "Logitech Mouse Device";
type = DEVICE_TYPE_MOUSE;
description = "Logitech Mouse Device";
location = logitech->GetDeviceLocation();
mode Off;
Off.name = "Off";
Off.value = LOGITECH_G303_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = LOGITECH_G303_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Cycle;
Cycle.name = "Cycle";
Cycle.value = LOGITECH_G303_MODE_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.speed_min = LOGITECH_G303_SPEED_SLOWEST;
Cycle.speed_max = LOGITECH_G303_SPEED_FASTEST;
Cycle.speed = LOGITECH_G303_SPEED_NORMAL;
modes.push_back(Cycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = LOGITECH_G303_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed_min = LOGITECH_G303_SPEED_SLOWEST;
Breathing.speed_max = LOGITECH_G303_SPEED_FASTEST;
Breathing.speed = LOGITECH_G303_SPEED_NORMAL;
modes.push_back(Breathing);
SetupZones();
}
RGBController_LogitechG303::~RGBController_LogitechG303()
{
delete logitech;
}
void RGBController_LogitechG303::SetupZones()
{
zone G303_primary_zone;
G303_primary_zone.name = "Primary";
G303_primary_zone.type = ZONE_TYPE_SINGLE;
G303_primary_zone.leds_min = 1;
G303_primary_zone.leds_max = 1;
G303_primary_zone.leds_count = 1;
G303_primary_zone.matrix_map = NULL;
zones.push_back(G303_primary_zone);
led G303_primary_led;
G303_primary_led.name = "Primary";
leds.push_back(G303_primary_led);
zone G303_logo_zone;
G303_logo_zone.name = "Logo";
G303_logo_zone.type = ZONE_TYPE_SINGLE;
G303_logo_zone.leds_min = 1;
G303_logo_zone.leds_max = 1;
G303_logo_zone.leds_count = 1;
G303_logo_zone.matrix_map = NULL;
zones.push_back(G303_logo_zone);
led G303_logo_led;
G303_logo_led.name = "Logo";
leds.push_back(G303_logo_led);
SetupColors();
}
void RGBController_LogitechG303::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_LogitechG303::DeviceUpdateLEDs()
{
UpdateZoneLEDs(0);
UpdateZoneLEDs(1);
}
void RGBController_LogitechG303::UpdateZoneLEDs(int zone)
{
unsigned char red = RGBGetRValue(colors[zone]);
unsigned char grn = RGBGetGValue(colors[zone]);
unsigned char blu = RGBGetBValue(colors[zone]);
logitech->SendMouseMode(modes[active_mode].value, modes[active_mode].speed, zone, red, grn, blu);
}
void RGBController_LogitechG303::UpdateSingleLED(int led)
{
UpdateZoneLEDs(led);
}
void RGBController_LogitechG303::SetCustomMode()
{
}
void RGBController_LogitechG303::DeviceUpdateMode()
{
DeviceUpdateLEDs();
}
@@ -1,131 +0,0 @@
/*-----------------------------------------*\
| RGBController_LogitechG403.cpp |
| |
| Generic RGB Interface for Logitech G403 |
| Prodigy RGB Mouse |
| |
| Martin Hartl (inlar) 5/19/2020 |
\*-----------------------------------------*/
#include "RGBController_LogitechG403.h"
RGBController_LogitechG403::RGBController_LogitechG403(LogitechG403Controller* logitech_ptr)
{
logitech = logitech_ptr;
name = "Logitech Mouse Device";
vendor = "Logitech";
type = DEVICE_TYPE_MOUSE;
description = "Logitech Mouse Device";
location = logitech->GetDeviceLocation();
serial = logitech->GetSerialString();
mode Static;
Static.name = "Static";
Static.value = LOGITECH_G403_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Off;
Off.name = "Off";
Off.value = LOGITECH_G403_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Cycle;
Cycle.name = "Cycle";
Cycle.value = LOGITECH_G403_MODE_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.speed_min = LOGITECH_G403_SPEED_SLOWEST;
Cycle.speed_max = LOGITECH_G403_SPEED_FASTEST;
Cycle.speed = LOGITECH_G403_SPEED_NORMAL;
modes.push_back(Cycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = LOGITECH_G403_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed_min = LOGITECH_G403_SPEED_SLOWEST;
Breathing.speed_max = LOGITECH_G403_SPEED_FASTEST;
Breathing.speed = LOGITECH_G403_SPEED_NORMAL;
modes.push_back(Breathing);
SetupZones();
}
RGBController_LogitechG403::~RGBController_LogitechG403()
{
delete logitech;
}
void RGBController_LogitechG403::SetupZones()
{
zone G403_wheel_zone;
G403_wheel_zone.name = "Scroll Wheel";
G403_wheel_zone.type = ZONE_TYPE_SINGLE;
G403_wheel_zone.leds_min = 1;
G403_wheel_zone.leds_max = 1;
G403_wheel_zone.leds_count = 1;
G403_wheel_zone.matrix_map = NULL;
zones.push_back(G403_wheel_zone);
led G403_wheel_led;
G403_wheel_led.name = "Scroll Wheel";
leds.push_back(G403_wheel_led);
zone G403_logo_zone;
G403_logo_zone.name = "Logo";
G403_logo_zone.type = ZONE_TYPE_SINGLE;
G403_logo_zone.leds_min = 1;
G403_logo_zone.leds_max = 1;
G403_logo_zone.leds_count = 1;
G403_logo_zone.matrix_map = NULL;
zones.push_back(G403_logo_zone);
led G403_logo_led;
G403_logo_led.name = "Logo";
leds.push_back(G403_logo_led);
SetupColors();
}
void RGBController_LogitechG403::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_LogitechG403::DeviceUpdateLEDs()
{
UpdateZoneLEDs(0);
UpdateZoneLEDs(1);
}
void RGBController_LogitechG403::UpdateZoneLEDs(int zone)
{
unsigned char red = RGBGetRValue(colors[zone]);
unsigned char grn = RGBGetGValue(colors[zone]);
unsigned char blu = RGBGetBValue(colors[zone]);
logitech->SendMouseMode(modes[active_mode].value, modes[active_mode].speed, zone, red, grn, blu);
}
void RGBController_LogitechG403::UpdateSingleLED(int led)
{
UpdateZoneLEDs(led);
}
void RGBController_LogitechG403::SetCustomMode()
{
}
void RGBController_LogitechG403::DeviceUpdateMode()
{
DeviceUpdateLEDs();
}
@@ -1,131 +0,0 @@
/*-----------------------------------------*\
| RGBController_LogitechG403.h |
| |
| Generic RGB Interface for Logitech G502 |
| Proteus Sprectrum Mouse |
| |
| kernzerfall 07/28/2020 |
\*-----------------------------------------*/
#include "RGBController_LogitechG502PS.h"
RGBController_LogitechG502PS::RGBController_LogitechG502PS(LogitechG502PSController* logitech_ptr)
{
logitech = logitech_ptr;
name = "Logitech Mouse Device";
vendor = "Logitech";
type = DEVICE_TYPE_MOUSE;
description = "Logitech Mouse Device";
location = logitech->GetDeviceLocation();
serial = logitech->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = LOGITECH_G502_PS_MODE_STATIC;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Off;
Off.name = "Off";
Off.value = LOGITECH_G502_PS_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Cycle;
Cycle.name = "Cycle";
Cycle.value = LOGITECH_G502_PS_MODE_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.speed_min = LOGITECH_G502_PS_SPEED_SLOWEST;
Cycle.speed_max = LOGITECH_G502_PS_SPEED_FASTEST;
Cycle.speed = LOGITECH_G502_PS_SPEED_NORMAL;
modes.push_back(Cycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = LOGITECH_G502_PS_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed_min = LOGITECH_G502_PS_SPEED_SLOWEST;
Breathing.speed_max = LOGITECH_G502_PS_SPEED_FASTEST;
Breathing.speed = LOGITECH_G502_PS_SPEED_NORMAL;
modes.push_back(Breathing);
SetupZones();
}
RGBController_LogitechG502PS::~RGBController_LogitechG502PS()
{
delete logitech;
}
void RGBController_LogitechG502PS::SetupZones()
{
zone G502_PS_side_zone;
G502_PS_side_zone.name = "DPI";
G502_PS_side_zone.type = ZONE_TYPE_SINGLE;
G502_PS_side_zone.leds_min = 1;
G502_PS_side_zone.leds_max = 1;
G502_PS_side_zone.leds_count = 1;
G502_PS_side_zone.matrix_map = NULL;
zones.push_back(G502_PS_side_zone);
led G502_PS_side_led;
G502_PS_side_led.name = "DPI";
leds.push_back(G502_PS_side_led);
zone G502_logo_zone;
G502_logo_zone.name = "Logo";
G502_logo_zone.type = ZONE_TYPE_SINGLE;
G502_logo_zone.leds_min = 1;
G502_logo_zone.leds_max = 1;
G502_logo_zone.leds_count = 1;
G502_logo_zone.matrix_map = NULL;
zones.push_back(G502_logo_zone);
led G502_logo_led;
G502_logo_led.name = "Logo";
leds.push_back(G502_logo_led);
SetupColors();
}
void RGBController_LogitechG502PS::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_LogitechG502PS::DeviceUpdateLEDs()
{
UpdateZoneLEDs(0);
UpdateZoneLEDs(1);
}
void RGBController_LogitechG502PS::UpdateZoneLEDs(int zone)
{
unsigned char red = RGBGetRValue(colors[zone]);
unsigned char grn = RGBGetGValue(colors[zone]);
unsigned char blu = RGBGetBValue(colors[zone]);
logitech->SendMouseMode(modes[active_mode].value, modes[active_mode].speed, zone, red, grn, blu);
}
void RGBController_LogitechG502PS::UpdateSingleLED(int led)
{
UpdateZoneLEDs(led);
}
void RGBController_LogitechG502PS::SetCustomMode()
{
}
void RGBController_LogitechG502PS::DeviceUpdateMode()
{
DeviceUpdateLEDs();
}
@@ -118,12 +118,12 @@ void RGBController_LogitechG560::DeviceUpdateLEDs()
}
}
void RGBController_LogitechG560::UpdateZoneLEDs(int zone)
void RGBController_LogitechG560::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_LogitechG560::UpdateSingleLED(int led)
void RGBController_LogitechG560::UpdateSingleLED(int /*led*/)
{
DeviceUpdateLEDs();
}
@@ -320,7 +320,7 @@ void RGBController_LogitechG815::DeviceUpdateLEDs()
if (current_colors[led_idx]==new_colors[led_idx])
{
/*-------------------------------------------------*\
| Not ready for prime. |
| Don't send if key color is not changed |
\*-------------------------------------------------*/
continue;
}
@@ -363,16 +363,6 @@ void RGBController_LogitechG815::DeviceUpdateLEDs()
size_t frame_pos = 3;
uint8_t li = 0;
memset(frame_buffer_big_mode, 0x00, sizeof(frame_buffer_big_mode));
memset(frame_buffer_little_mode, 0x00, sizeof(frame_buffer_little_mode));
/*---------------------------------------------------------*\
| Don't ask why but the keyboard needs one 6F |
| packet in order to handle a 1F packet with one single led |
| color. |
\*---------------------------------------------------------*/
//logitech->SetDummyBigPacket();
/*---------------------------------------------------------*\
| Create frame_buffers of type 1F (Little, up to 4 leds |
| per packet) and 6F (big, up to 13 leds per packet). |
@@ -402,19 +392,24 @@ void RGBController_LogitechG815::DeviceUpdateLEDs()
frame_pos++;
}
}
if (frame_pos < data_size)
{
/*-----------------------------------------*\
| Zeroing just what is needed and if needed |
\*-----------------------------------------*/
memset(frame_buffer_big_mode + frame_pos, 0x00, sizeof(frame_buffer_big_mode) - frame_pos);
/*-----------------------------------------*\
| End of Data byte |
\*-----------------------------------------*/
frame_buffer_big_mode[frame_pos] = 0xFF;
frame_pos++;
}
/*-----------------------------------------------------*\
| Zeroing just what is needed |
\*-----------------------------------------------------*/
logitech->SetDirect(LOGITECH_G815_ZONE_FRAME_TYPE_BIG, frame_buffer_big_mode);
memset(frame_buffer_big_mode, 0x00, sizeof(frame_buffer_big_mode));
bi = bi + max_key_per_color;
}
}
@@ -441,7 +436,6 @@ void RGBController_LogitechG815::DeviceUpdateLEDs()
| No End of Data byte if the packet is full |
\*-----------------------------------------*/
logitech->SetDirect(LOGITECH_G815_ZONE_FRAME_TYPE_LITTLE, frame_buffer_little_mode);
memset(frame_buffer_little_mode, 0x00, sizeof(frame_buffer_little_mode));
led_in_little_frame=0;
}
}
@@ -455,7 +449,12 @@ void RGBController_LogitechG815::DeviceUpdateLEDs()
if(led_in_little_frame > 0)
{
/*-----------------------------------------------------*\
| End of Data byte |
| Zeroing just what is needed |
\*-----------------------------------------------------*/
memset(frame_buffer_little_mode + (led_in_little_frame * 4 + 1), 0x00, sizeof(frame_buffer_little_mode) - led_in_little_frame * 4);
/*-----------------------------------------------------*\
| Data byte |
\*-----------------------------------------------------*/
frame_buffer_little_mode[led_in_little_frame*4 + 0] = 0xFF;
@@ -463,7 +462,6 @@ void RGBController_LogitechG815::DeviceUpdateLEDs()
| Send little frame and clear little frame buffer |
\*-----------------------------------------------------*/
logitech->SetDirect(LOGITECH_G815_ZONE_FRAME_TYPE_LITTLE, frame_buffer_little_mode);
memset(frame_buffer_little_mode, 0x00, sizeof(frame_buffer_little_mode));
}
if(ledsByColors.size() > 0)
{
@@ -0,0 +1,394 @@
/*-----------------------------------------*\
| RGBController_LogitechG910.cpp |
| |
| Generic RGB Interface for Logitech G910 |
| Orion Spectrum Keyboard |
| |
| Adam Honse (CalcProgrammer1) 6/12/2020 |
\*-----------------------------------------*/
#include "RGBController_LogitechG910.h"
//0xFFFFFFFF indicates an unused entry in matrix
#define NA 0xFFFFFFFF
static unsigned int matrix_map[8][24] =
{ { NA, 111, 112, 113, 114, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA },
{ 115, 37, NA, 54, 55, 56, 57, NA, 58, 59, 60, 61, NA, 62, 63, 64, 65, 66, 67, 68, NA, NA, NA, NA },
{ 106, 49, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, NA, 41, 42, 38, NA, 69, 70, 71, 79, 80, 81, 82 },
{ 107, 39, NA, 16, 22, 4, 17, NA, 19, 24, 20, 8, 14, 15, 43, 44, 45, 72, 73, 74, 91, 92, 93, 83 },
{ 108, 53, NA, 0, 18, 3, 5, NA, 6, 7, 9, 10, 11, 47, 48, 46, 36, NA, NA, NA, 88, 89, 90, NA },
{ 109, 99, 96, 25, 23, 2, 21, NA, 1, NA, 13, 12, 50, 51, 52, 103, NA, NA, 78, NA, 85, 86, 87, 84 },
{ 110, 98, 101, 100, NA, NA, NA, NA, 40, NA, NA, NA, NA, 104, 105, 97, 102, 76, 77, 75, 94, NA, 95, NA },
{ NA, NA, NA, 116, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA } };
static const char* zone_names[] =
{
"Keyboard",
};
static zone_type zone_types[] =
{
ZONE_TYPE_MATRIX,
};
static const unsigned int zone_sizes[] =
{
117,
};
typedef struct
{
const char * name;
const unsigned char zone;
const unsigned char idx;
} led_type;
static const led_type led_names[] =
{
/* Key Label Zone, Index */
{ "Key: A", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x04 },
{ "Key: B", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x05 },
{ "Key: C", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x06 },
{ "Key: D", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x07 },
{ "Key: E", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x08 },
{ "Key: F", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x09 },
{ "Key: G", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0A },
{ "Key: H", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0B },
{ "Key: I", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0C },
{ "Key: J", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0D },
{ "Key: K", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0E },
{ "Key: L", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x0F },
{ "Key: M", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x10 },
{ "Key: N", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x11 },
{ "Key: O", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x12 },
{ "Key: P", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x13 },
{ "Key: Q", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x14 },
{ "Key: R", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x15 },
{ "Key: S", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x16 },
{ "Key: T", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x17 },
{ "Key: U", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x18 },
{ "Key: V", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x19 },
{ "Key: W", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1A },
{ "Key: X", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1B },
{ "Key: Y", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1C },
{ "Key: Z", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1D },
{ "Key: 1", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1E },
{ "Key: 2", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x1F },
{ "Key: 3", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x20 },
{ "Key: 4", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x21 },
{ "Key: 5", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x22 },
{ "Key: 6", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x23 },
{ "Key: 7", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x24 },
{ "Key: 8", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x25 },
{ "Key: 9", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x26 },
{ "Key: 0", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x27 },
{ "Key: Enter", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x28 },
{ "Key: Escape", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x29 },
{ "Key: Backspace", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2A },
{ "Key: Tab", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2B },
{ "Key: Space", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2C },
{ "Key: -", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2D },
{ "Key: =", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2E },
{ "Key: [", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x2F },
{ "Key: ]", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x30 },
{ "Key: \\ (ANSI)", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x31 },//ANSI only
{ "Key: #", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x32 },//ISO only
{ "Key: ;", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x33 },
{ "Key: '", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x34 },
{ "Key: `", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x35 },
{ "Key: ,", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x36 },
{ "Key: .", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x37 },
{ "Key: /", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x38 },
{ "Key: Caps Lock", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x39 },
{ "Key: F1", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3A },
{ "Key: F2", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3B },
{ "Key: F3", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3C },
{ "Key: F4", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3D },
{ "Key: F5", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3E },
{ "Key: F6", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x3F },
{ "Key: F7", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x40 },
{ "Key: F8", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x41 },
{ "Key: F9", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x42 },
{ "Key: F10", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x43 },
{ "Key: F11", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x44 },
{ "Key: F12", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x45 },
{ "Key: Print Screen", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x46 },
{ "Key: Scroll Lock", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x47 },
{ "Key: Pause/Break", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x48 },
{ "Key: Insert", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x49 },
{ "Key: Home", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4A },
{ "Key: Page Up", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4B },
{ "Key: Delete", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4C },
{ "Key: End", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4D },
{ "Key: Page Down", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4E },
{ "Key: Right Arrow", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x4F },
{ "Key: Left Arrow", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x50 },
{ "Key: Down Arrow", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x51 },
{ "Key: Up Arrow", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x52 },
{ "Key: Num Lock", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x53 },
{ "Key: Number Pad /", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x54 },
{ "Key: Number Pad *", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x55 },
{ "Key: Number Pad -", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x56 },
{ "Key: Number Pad +", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x57 },
{ "Key: Number Pad Enter", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x58 },
{ "Key: Number Pad 1", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x59 },
{ "Key: Number Pad 2", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5A },
{ "Key: Number Pad 3", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5B },
{ "Key: Number Pad 4", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5C },
{ "Key: Number Pad 5", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5D },
{ "Key: Number Pad 6", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5E },
{ "Key: Number Pad 7", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x5F },
{ "Key: Number Pad 8", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x60 },
{ "Key: Number Pad 9", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x61 },
{ "Key: Number Pad 0", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x62 },
{ "Key: Number Pad .", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x63 },
{ "Key: \\ (ISO)", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x64 },//ISO only
{ "Key: Menu", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0x65 },
{ "Key: Left Control", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE0 },
{ "Key: Left Shift", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE1 },
{ "Key: Left Alt", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE2 },
{ "Key: Left Windows", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE3 },
{ "Key: Right Control", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE4 },
{ "Key: Right Shift", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE5 },
{ "Key: Right Alt", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE6 },
{ "Key: Right Windows", LOGITECH_G910_ZONE_DIRECT_KEYBOARD, 0xE7 },
{ "Key: G1", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x01 },
{ "Key: G2", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x02 },
{ "Key: G3", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x03 },
{ "Key: G4", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x04 },
{ "Key: G5", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x05 },
{ "Key: G6", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x06 },
{ "Key: G7", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x07 },
{ "Key: G8", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x08 },
{ "Key: G9", LOGITECH_G910_ZONE_DIRECT_GKEYS, 0x09 },
{ "Logo", LOGITECH_G910_ZONE_DIRECT_LOGO, 0x01 },
{ "Nameplate", LOGITECH_G910_ZONE_DIRECT_LOGO, 0x02 },
};
RGBController_LogitechG910::RGBController_LogitechG910(LogitechG910Controller* logitech_ptr)
{
logitech = logitech_ptr;
name = "Logitech Keyboard Device";
vendor = "Logitech";
type = DEVICE_TYPE_KEYBOARD;
description = "Logitech Keyboard Device";
serial = logitech->GetSerialString();
mode Direct;
Direct.name = "Direct";
Direct.value = 0xFFFF;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Static;
Static.name = "Static";
Static.value = LOGITECH_G910_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
Static.colors_min = 1;
Static.colors_max = 1;
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
Static.colors.resize(1);
modes.push_back(Static);
mode Off;
Off.name = "Off";
Off.value = LOGITECH_G910_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Cycle;
Cycle.name = "Cycle";
Cycle.value = LOGITECH_G910_MODE_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.speed_min = LOGITECH_G910_SPEED_SLOWEST;
Cycle.speed_max = LOGITECH_G910_SPEED_FASTEST;
Cycle.speed = LOGITECH_G910_SPEED_NORMAL;
modes.push_back(Cycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = LOGITECH_G910_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_SPEED;
Breathing.colors_min = 1;
Breathing.colors_max = 1;
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
Breathing.colors.resize(1);
Breathing.speed_min = LOGITECH_G910_SPEED_SLOWEST;
Breathing.speed_max = LOGITECH_G910_SPEED_FASTEST;
Breathing.speed = LOGITECH_G910_SPEED_NORMAL;
modes.push_back(Breathing);
SetupZones();
}
RGBController_LogitechG910::~RGBController_LogitechG910()
{
/*---------------------------------------------------------*\
| Delete the matrix map |
\*---------------------------------------------------------*/
for(unsigned int zone_index = 0; zone_index < zones.size(); zone_index++)
{
if(zones[zone_index].matrix_map != NULL)
{
delete zones[zone_index].matrix_map;
}
}
delete logitech;
}
void RGBController_LogitechG910::SetupZones()
{
/*---------------------------------------------------------*\
| Set up zones |
\*---------------------------------------------------------*/
unsigned int total_led_count = 0;
for(unsigned int zone_idx = 0; zone_idx < 1; zone_idx++)
{
zone new_zone;
new_zone.name = zone_names[zone_idx];
new_zone.type = zone_types[zone_idx];
new_zone.leds_min = zone_sizes[zone_idx];
new_zone.leds_max = zone_sizes[zone_idx];
new_zone.leds_count = zone_sizes[zone_idx];
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
{
new_zone.matrix_map = new matrix_map_type;
new_zone.matrix_map->height = 8;
new_zone.matrix_map->width = 24;
new_zone.matrix_map->map = (unsigned int *)&matrix_map;
}
else
{
new_zone.matrix_map = NULL;
}
zones.push_back(new_zone);
total_led_count += zone_sizes[zone_idx];
}
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
{
led new_led;
new_led.name = led_names[led_idx].name;
new_led.value = ( led_names[led_idx].zone << 8 ) + led_names[led_idx].idx;
leds.push_back(new_led);
}
SetupColors();
}
void RGBController_LogitechG910::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_LogitechG910::DeviceUpdateLEDs()
{
#define MAX_FRAMES_PER_PACKET 0x0E
unsigned char frame_buf[MAX_FRAMES_PER_PACKET * 4];
unsigned char frame_cnt = 0;
unsigned char prev_zone = 0;
unsigned char zone = 0;
unsigned char idx = 0;
/*---------------------------------------------------------*\
| TODO: Send packets with multiple LED frames |
\*---------------------------------------------------------*/
for(std::size_t led_idx = 0; led_idx < leds.size(); led_idx++)
{
zone = ( leds[led_idx].value >> 8 );
idx = ( leds[led_idx].value & 0xFF );
if((zone != prev_zone) && (frame_cnt != 0))
{
logitech->SetDirect(prev_zone, frame_cnt, frame_buf);
frame_cnt = 0;
}
frame_buf[(frame_cnt * 4) + 0] = idx;
frame_buf[(frame_cnt * 4) + 1] = RGBGetRValue(colors[led_idx]);
frame_buf[(frame_cnt * 4) + 2] = RGBGetGValue(colors[led_idx]);
frame_buf[(frame_cnt * 4) + 3] = RGBGetBValue(colors[led_idx]);
frame_cnt++;
prev_zone = zone;
if(frame_cnt == MAX_FRAMES_PER_PACKET)
{
logitech->SetDirect(prev_zone, frame_cnt, frame_buf);
frame_cnt = 0;
}
}
if(frame_cnt != 0)
{
logitech->SetDirect(prev_zone, frame_cnt, frame_buf);
}
logitech->Commit();
}
void RGBController_LogitechG910::UpdateZoneLEDs(int /*zone*/)
{
DeviceUpdateLEDs();
}
void RGBController_LogitechG910::UpdateSingleLED(int led)
{
unsigned char frame[4];
unsigned char zone;
unsigned char idx;
zone = ( leds[led].value >> 8 );
idx = ( leds[led].value & 0xFF );
frame[0] = idx;
frame[1] = RGBGetRValue(colors[led]);
frame[2] = RGBGetGValue(colors[led]);
frame[3] = RGBGetBValue(colors[led]);
logitech->SetDirect(zone, 1, frame);
logitech->Commit();
}
void RGBController_LogitechG910::SetCustomMode()
{
active_mode = 0;
}
void RGBController_LogitechG910::DeviceUpdateMode()
{
/*---------------------------------------------------------*\
| Direct mode does not send a mode packet |
| Call UpdateLEDs to send direct packet |
\*---------------------------------------------------------*/
if(active_mode == 0xFFFF)
{
UpdateLEDs();
return;
}
unsigned char red = 0;
unsigned char grn = 0;
unsigned char blu = 0;
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
{
red = RGBGetRValue(modes[active_mode].colors[0]);
grn = RGBGetGValue(modes[active_mode].colors[0]);
blu = RGBGetBValue(modes[active_mode].colors[0]);
}
logitech->SetMode(modes[active_mode].value, modes[active_mode].speed, red, grn, blu);
}
@@ -1,21 +1,21 @@
/*-----------------------------------------*\
| RGBController_LogitechG203.h |
| RGBController_LogitechG910.h |
| |
| Generic RGB Interface for Logitech G203 |
| Prodigy RGB Mouse |
| Generic RGB Interface for Logitech G910 |
| Orion Spectrum keyboard |
| |
| Adam Honse (CalcProgrammer1) 5/17/2020 |
| Adam Honse (CalcProgrammer1) 6/12/2020 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "LogitechG203Controller.h"
#include "LogitechG910Controller.h"
class RGBController_LogitechG203 : public RGBController
class RGBController_LogitechG910 : public RGBController
{
public:
RGBController_LogitechG203(LogitechG203Controller* logitech_ptr);
~RGBController_LogitechG203();
RGBController_LogitechG910(LogitechG910Controller* logitech_ptr);
~RGBController_LogitechG910();
void SetupZones();
@@ -29,5 +29,5 @@ public:
void DeviceUpdateMode();
private:
LogitechG203Controller* logitech;
LogitechG910Controller* logitech;
};
@@ -0,0 +1,149 @@
/*-----------------------------------------*\
| RGBController_LogitechGLightsync.cpp |
| |
| Generic RGB Interface for |
| Logitech G Lightsync Devices |
| |
| TheRogueZeta 04/21/2021 |
\*-----------------------------------------*/
#include "RGBController_LogitechGLightsync.h"
RGBController_LogitechGLightsync::RGBController_LogitechGLightsync(LogitechGLightsyncController* logitech_ptr)
{
logitech = logitech_ptr;
name = "Logitech G Lightsync Mouse";
vendor = "Logitech";
type = DEVICE_TYPE_MOUSE;
description = "Logitech G Lightsync Mouse";
location = logitech->GetDeviceLocation();
serial = logitech->GetSerialString();
mode Off;
Off.name = "Off";
Off.value = LOGITECH_G_LIGHTSYNC_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Direct;
Direct.name = "Direct";
Direct.value = 0xFF;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Static;
Static.name = "Static";
Static.value = LOGITECH_G_LIGHTSYNC_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Cycle;
Cycle.name = "Spectrum Cycle";
Cycle.value = LOGITECH_G_LIGHTSYNC_MODE_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
Cycle.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
Cycle.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
modes.push_back(Cycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = LOGITECH_G_LIGHTSYNC_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
Breathing.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
Breathing.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
modes.push_back(Breathing);
SetupZones();
}
RGBController_LogitechGLightsync::~RGBController_LogitechGLightsync()
{
delete logitech;
}
void RGBController_LogitechGLightsync::SetupZones()
{
zone GLightsync_primary_zone;
GLightsync_primary_zone.name = "DPI";
GLightsync_primary_zone.type = ZONE_TYPE_SINGLE;
GLightsync_primary_zone.leds_min = 1;
GLightsync_primary_zone.leds_max = 1;
GLightsync_primary_zone.leds_count = 1;
GLightsync_primary_zone.matrix_map = NULL;
zones.push_back(GLightsync_primary_zone);
led GLightsync_primary_led;
GLightsync_primary_led.name = "DPI";
leds.push_back(GLightsync_primary_led);
zone GLightsync_logo_zone;
GLightsync_logo_zone.name = "Logo";
GLightsync_logo_zone.type = ZONE_TYPE_SINGLE;
GLightsync_logo_zone.leds_min = 1;
GLightsync_logo_zone.leds_max = 1;
GLightsync_logo_zone.leds_count = 1;
GLightsync_logo_zone.matrix_map = NULL;
zones.push_back(GLightsync_logo_zone);
led GLightsync_logo_led;
GLightsync_logo_led.name = "Logo";
leds.push_back(GLightsync_logo_led);
SetupColors();
}
void RGBController_LogitechGLightsync::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_LogitechGLightsync::DeviceUpdateLEDs()
{
UpdateZoneLEDs(0);
UpdateZoneLEDs(1);
}
void RGBController_LogitechGLightsync::UpdateZoneLEDs(int zone)
{
unsigned char red = RGBGetRValue(colors[zone]);
unsigned char grn = RGBGetGValue(colors[zone]);
unsigned char blu = RGBGetBValue(colors[zone]);
/*---------------------------------------------------------*\
| Replace direct mode with static when sending to controller|
\*---------------------------------------------------------*/
unsigned char temp_mode = (modes[active_mode].value != 0xFF) ? modes[active_mode].value : LOGITECH_G_LIGHTSYNC_MODE_STATIC;
logitech->UpdateMouseLED(temp_mode, modes[active_mode].speed, zone, red, grn, blu, /* Brightness */ 0x64);
}
void RGBController_LogitechGLightsync::UpdateSingleLED(int led)
{
UpdateZoneLEDs(led);
}
void RGBController_LogitechGLightsync::SetCustomMode()
{
active_mode = 1;
}
void RGBController_LogitechGLightsync::DeviceUpdateMode()
{
/*---------------------------------------------------------*\
| If direct mode is true, then sent the packet to put the |
| mouse in direct mode. This code will only be called when |
| we change modes as to not spam the device. |
\*---------------------------------------------------------*/
logitech->SetDirectMode(modes[active_mode].value == 0xFF);
DeviceUpdateLEDs();
}
@@ -1,21 +1,21 @@
/*-----------------------------------------*\
| RGBController_LogitechG403.h |
| RGBController_LogitechGLightsync.h |
| |
| Generic RGB Interface for Logitech G502 |
| Proteus Sprectrum Mouse |
| Generic RGB Interface for |
| Logitech G Lightsync Devices |
| |
| kernzerfall 07/28/2020 |
| TheRogueZeta 04/21/2021 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "LogitechG502PSController.h"
#include "LogitechGLightsyncController.h"
class RGBController_LogitechG502PS : public RGBController
class RGBController_LogitechGLightsync : public RGBController
{
public:
RGBController_LogitechG502PS(LogitechG502PSController* logitech_ptr);
~RGBController_LogitechG502PS();
RGBController_LogitechGLightsync(LogitechGLightsyncController* logitech_ptr);
~RGBController_LogitechGLightsync();
void SetupZones();
@@ -29,5 +29,5 @@ public:
void DeviceUpdateMode();
private:
LogitechG502PSController* logitech;
LogitechGLightsyncController* logitech;
};
@@ -0,0 +1,135 @@
/*-----------------------------------------*\
| RGBController_LogitechGLightsync1zone.cpp|
| |
| Generic RGB Interface for single zone |
| Logitech G Lightsync Devices |
| |
| TheRogueZeta 04/21/2021 |
\*-----------------------------------------*/
#include "RGBController_LogitechGLightsync1zone.h"
RGBController_LogitechGLightsync1zone::RGBController_LogitechGLightsync1zone(LogitechGLightsyncController* logitech_ptr)
{
logitech = logitech_ptr;
name = "Logitech G Lightsync Mouse Single Zone";
vendor = "Logitech";
type = DEVICE_TYPE_MOUSE;
description = "Logitech G Lightsync Mouse Single Zone";
location = logitech->GetDeviceLocation();
serial = logitech->GetSerialString();
mode Off;
Off.name = "Off";
Off.value = LOGITECH_G_LIGHTSYNC_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Direct;
Direct.name = "Direct";
Direct.value = 0xFF;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Static;
Static.name = "Static";
Static.value = LOGITECH_G_LIGHTSYNC_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Cycle;
Cycle.name = "Spectrum Cycle";
Cycle.value = LOGITECH_G_LIGHTSYNC_MODE_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
Cycle.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
Cycle.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
modes.push_back(Cycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = LOGITECH_G_LIGHTSYNC_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
Breathing.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
Breathing.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
modes.push_back(Breathing);
SetupZones();
}
RGBController_LogitechGLightsync1zone::~RGBController_LogitechGLightsync1zone()
{
delete logitech;
}
void RGBController_LogitechGLightsync1zone::SetupZones()
{
zone GLightsync_logo_zone;
GLightsync_logo_zone.name = "Logo";
GLightsync_logo_zone.type = ZONE_TYPE_SINGLE;
GLightsync_logo_zone.leds_min = 1;
GLightsync_logo_zone.leds_max = 1;
GLightsync_logo_zone.leds_count = 1;
GLightsync_logo_zone.matrix_map = NULL;
zones.push_back(GLightsync_logo_zone);
led GLightsync_logo_led;
GLightsync_logo_led.name = "Logo";
leds.push_back(GLightsync_logo_led);
SetupColors();
}
void RGBController_LogitechGLightsync1zone::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_LogitechGLightsync1zone::DeviceUpdateLEDs()
{
UpdateZoneLEDs(0);
}
void RGBController_LogitechGLightsync1zone::UpdateZoneLEDs(int zone)
{
unsigned char red = RGBGetRValue(colors[zone]);
unsigned char grn = RGBGetGValue(colors[zone]);
unsigned char blu = RGBGetBValue(colors[zone]);
/*---------------------------------------------------------*\
| Replace direct mode with static when sending to controller|
\*---------------------------------------------------------*/
unsigned char temp_mode = (modes[active_mode].value != 0xFF) ? modes[active_mode].value : LOGITECH_G_LIGHTSYNC_MODE_STATIC;
logitech->UpdateMouseLED(temp_mode, modes[active_mode].speed, zone, red, grn, blu, /* Brightness */ 0x64);
}
void RGBController_LogitechGLightsync1zone::UpdateSingleLED(int led)
{
UpdateZoneLEDs(led);
}
void RGBController_LogitechGLightsync1zone::SetCustomMode()
{
active_mode = 1;
}
void RGBController_LogitechGLightsync1zone::DeviceUpdateMode()
{
/*---------------------------------------------------------*\
| If direct mode is true, then sent the packet to put the |
| mouse in direct mode. This code will only be called when |
| we change modes as to not spam the device. |
\*---------------------------------------------------------*/
logitech->SetDirectMode(modes[active_mode].value == 0xFF);
DeviceUpdateLEDs();
}
@@ -1,21 +1,21 @@
/*-----------------------------------------*\
| RGBController_LogitechG403.h |
| RGBController_LogitechGLightsync1zone.h |
| |
| Generic RGB Interface for Logitech G403 |
| Prodigy RGB Mouse |
| Generic RGB Interface for single zone |
| Logitech G Lightsync Devices |
| |
| Martin Hartl (inlar) 5/19/2020 |
| TheRogueZeta 04/21/2021 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "LogitechG403Controller.h"
#include "LogitechGLightsyncController.h"
class RGBController_LogitechG403 : public RGBController
class RGBController_LogitechGLightsync1zone : public RGBController
{
public:
RGBController_LogitechG403(LogitechG403Controller* logitech_ptr);
~RGBController_LogitechG403();
RGBController_LogitechGLightsync1zone(LogitechGLightsyncController* logitech_ptr);
~RGBController_LogitechGLightsync1zone();
void SetupZones();
@@ -29,5 +29,5 @@ public:
void DeviceUpdateMode();
private:
LogitechG403Controller* logitech;
LogitechGLightsyncController* logitech;
};
@@ -9,49 +9,56 @@
#include "RGBController_LogitechGPowerPlay.h"
RGBController_LogitechGPowerPlay::RGBController_LogitechGPowerPlay(LogitechGPowerPlayController* logitech_ptr)
RGBController_LogitechGPowerPlay::RGBController_LogitechGPowerPlay(LogitechGLightsyncController* logitech_ptr)
{
logitech = logitech_ptr;
logitech = logitech_ptr;
name = "Logitech G PowerPlay Wireless Charging System";
vendor = "Logitech";
type = DEVICE_TYPE_MOUSEMAT;
description = "Logitech G PowerPlay Wireless Charging System";
location = logitech->GetDeviceLocation();
serial = logitech->GetSerialString();
name = "Logitech G PowerPlay Wireless Charging System";
vendor = "Logitech";
type = DEVICE_TYPE_MOUSEMAT;
description = "Logitech G PowerPlay Wireless Charging System";
location = logitech->GetDeviceLocation();
serial = logitech->GetSerialString();
mode Off;
Off.name = "Off";
Off.value = LOGITECH_G_POWERPLAY_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_PER_LED;
Off.name = "Off";
Off.value = LOGITECH_G_LIGHTSYNC_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Direct;
Direct.name = "Direct";
Direct.value = 0xFF;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Static;
Static.name = "Static";
Static.value = LOGITECH_G_POWERPLAY_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
Static.name = "Static";
Static.value = LOGITECH_G_LIGHTSYNC_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Cycle;
Cycle.name = "Cycle";
Cycle.value = LOGITECH_G_POWERPLAY_MODE_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Cycle.color_mode = MODE_COLORS_PER_LED;
Cycle.speed_min = LOGITECH_G_POWERPLAY_SPEED_SLOWEST;
Cycle.speed_max = LOGITECH_G_POWERPLAY_SPEED_FASTEST;
Cycle.speed = LOGITECH_G_POWERPLAY_SPEED_NORMAL;
Cycle.name = "Spectrum Cycle";
Cycle.value = LOGITECH_G_LIGHTSYNC_MODE_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
Cycle.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
Cycle.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
modes.push_back(Cycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = LOGITECH_G_POWERPLAY_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed_min = LOGITECH_G_POWERPLAY_SPEED_SLOWEST;
Breathing.speed_max = LOGITECH_G_POWERPLAY_SPEED_FASTEST;
Breathing.speed = LOGITECH_G_POWERPLAY_SPEED_NORMAL;
Breathing.name = "Breathing";
Breathing.value = LOGITECH_G_LIGHTSYNC_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed_min = LOGITECH_G_LIGHTSYNC_SPEED_SLOWEST;
Breathing.speed_max = LOGITECH_G_LIGHTSYNC_SPEED_FASTEST;
Breathing.speed = LOGITECH_G_LIGHTSYNC_SPEED_NORMAL;
modes.push_back(Breathing);
SetupZones();
@@ -98,7 +105,12 @@ void RGBController_LogitechGPowerPlay::UpdateZoneLEDs(int zone)
unsigned char grn = RGBGetGValue(colors[zone]);
unsigned char blu = RGBGetBValue(colors[zone]);
logitech->SendMouseMatMode(modes[active_mode].value, modes[active_mode].speed, zone, red, grn, blu);
/*---------------------------------------------------------*\
| Replace direct mode with static when sending to controller|
\*---------------------------------------------------------*/
unsigned char temp_mode = (modes[active_mode].value != 0xFF) ? modes[active_mode].value : LOGITECH_G_LIGHTSYNC_MODE_STATIC;
logitech->UpdateMouseLED(temp_mode, modes[active_mode].speed, zone, red, grn, blu, /* Brightness */ 0x64);
}
void RGBController_LogitechGPowerPlay::UpdateSingleLED(int led)
@@ -108,10 +120,16 @@ void RGBController_LogitechGPowerPlay::UpdateSingleLED(int led)
void RGBController_LogitechGPowerPlay::SetCustomMode()
{
active_mode = 1;
}
void RGBController_LogitechGPowerPlay::DeviceUpdateMode()
{
/*---------------------------------------------------------*\
| If direct mode is true, then sent the packet to put the |
| mouse in direct mode. This code will only be called when |
| we change modes as to not spam the device. |
\*---------------------------------------------------------*/
logitech->SetDirectMode(modes[active_mode].value == 0xFF);
DeviceUpdateLEDs();
}
}
@@ -9,12 +9,12 @@
#pragma once
#include "RGBController.h"
#include "LogitechGPowerPlayController.h"
#include "LogitechGLightsyncController.h"
class RGBController_LogitechGPowerPlay : public RGBController
{
public:
RGBController_LogitechGPowerPlay(LogitechGPowerPlayController* logitech_ptr);
RGBController_LogitechGPowerPlay(LogitechGLightsyncController* logitech_ptr);
~RGBController_LogitechGPowerPlay();
void SetupZones();
@@ -29,5 +29,5 @@ public:
void DeviceUpdateMode();
private:
LogitechGPowerPlayController* logitech;
LogitechGLightsyncController* logitech;
};
@@ -1,131 +0,0 @@
/*-----------------------------------------*\
| RGBController_LogitechGProWireless.cpp |
| |
| Generic RGB Interface for |
| Logitech G Pro Wireless Gaming Mouse |
| |
| TheRogueZeta 8/5/2020 |
\*-----------------------------------------*/
#include "RGBController_LogitechGProWireless.h"
RGBController_LogitechGProWireless::RGBController_LogitechGProWireless(LogitechGProWirelessController* logitech_ptr)
{
logitech = logitech_ptr;
name = "Logitech G Pro Wireless Gaming Mouse";
vendor = "Logitech";
type = DEVICE_TYPE_MOUSE;
description = "Logitech G Pro Wireless Gaming Mouse";
location = logitech->GetDeviceLocation();
serial = logitech->GetSerialString();
mode Off;
Off.name = "Off";
Off.value = LOGITECH_G_PRO_WIRELESS_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
mode Static;
Static.name = "Static";
Static.value = LOGITECH_G_PRO_WIRELESS_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Cycle;
Cycle.name = "Cycle";
Cycle.value = LOGITECH_G_PRO_WIRELESS_MODE_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.speed_min = LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST;
Cycle.speed_max = LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST;
Cycle.speed = LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL;
modes.push_back(Cycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = LOGITECH_G_PRO_WIRELESS_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed_min = LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST;
Breathing.speed_max = LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST;
Breathing.speed = LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL;
modes.push_back(Breathing);
SetupZones();
}
RGBController_LogitechGProWireless::~RGBController_LogitechGProWireless()
{
delete logitech;
}
void RGBController_LogitechGProWireless::SetupZones()
{
zone GProWireless_primary_zone;
GProWireless_primary_zone.name = "DPI";
GProWireless_primary_zone.type = ZONE_TYPE_SINGLE;
GProWireless_primary_zone.leds_min = 1;
GProWireless_primary_zone.leds_max = 1;
GProWireless_primary_zone.leds_count = 1;
GProWireless_primary_zone.matrix_map = NULL;
zones.push_back(GProWireless_primary_zone);
led GProWireless_primary_led;
GProWireless_primary_led.name = "DPI";
leds.push_back(GProWireless_primary_led);
zone GProWireless_logo_zone;
GProWireless_logo_zone.name = "Logo";
GProWireless_logo_zone.type = ZONE_TYPE_SINGLE;
GProWireless_logo_zone.leds_min = 1;
GProWireless_logo_zone.leds_max = 1;
GProWireless_logo_zone.leds_count = 1;
GProWireless_logo_zone.matrix_map = NULL;
zones.push_back(GProWireless_logo_zone);
led GProWireless_logo_led;
GProWireless_logo_led.name = "Logo";
leds.push_back(GProWireless_logo_led);
SetupColors();
}
void RGBController_LogitechGProWireless::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_LogitechGProWireless::DeviceUpdateLEDs()
{
UpdateZoneLEDs(0);
UpdateZoneLEDs(1);
}
void RGBController_LogitechGProWireless::UpdateZoneLEDs(int zone)
{
unsigned char red = RGBGetRValue(colors[zone]);
unsigned char grn = RGBGetGValue(colors[zone]);
unsigned char blu = RGBGetBValue(colors[zone]);
logitech->SendMouseMode(modes[active_mode].value, modes[active_mode].speed, zone, red, grn, blu);
}
void RGBController_LogitechGProWireless::UpdateSingleLED(int led)
{
UpdateZoneLEDs(led);
}
void RGBController_LogitechGProWireless::SetCustomMode()
{
active_mode = 1;
}
void RGBController_LogitechGProWireless::DeviceUpdateMode()
{
DeviceUpdateLEDs();
}
@@ -0,0 +1,177 @@
/*-----------------------------------------*\
| RGBController_LogitechLightspeed.cpp |
| |
| Generic RGB Interface for |
| Logitech Lightspeed Gaming Mice |
| |
| TheRogueZeta 8/5/2020 |
\*-----------------------------------------*/
#include "RGBController_LogitechLightspeed.h"
RGBController_LogitechLightspeed::RGBController_LogitechLightspeed(LogitechLightspeedController* logitech_ptr)
{
logitech = logitech_ptr;
bool connected = logitech->lightspeed->connected();
mode Off;
Off.name = "Off";
Off.value = LOGITECH_G_PRO_WIRELESS_MODE_OFF;
Off.flags = 0;
Off.color_mode = MODE_COLORS_NONE;
modes.push_back(Off);
if(connected)
{
name = logitech->lightspeed->device_name;
vendor = "Logitech";
description = "Logitech Wireless Lightspeed Device";
location = logitech->GetDeviceLocation();
serial = logitech->GetSerialString();
switch(logitech->lightspeed->logitech_device_type)
{
case LOGITECH_DEVICE_TYPE_KEYBOARD:
type = DEVICE_TYPE_KEYBOARD;
break;
case LOGITECH_DEVICE_TYPE_MOUSE:
type = DEVICE_TYPE_MOUSE;
break;
default:
type = DEVICE_TYPE_UNKNOWN;
LOG_NOTICE("Logitech device type not known: %i", logitech->lightspeed->logitech_device_type);
}
mode Direct;
Direct.name = "Direct";
Direct.value = 0xFF;
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Direct.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Direct);
mode Static;
Static.name = "Static";
Static.value = LOGITECH_G_PRO_WIRELESS_MODE_STATIC;
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
Static.color_mode = MODE_COLORS_PER_LED;
modes.push_back(Static);
mode Cycle;
Cycle.name = "Spectrum Cycle";
Cycle.value = LOGITECH_G_PRO_WIRELESS_MODE_CYCLE;
Cycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Cycle.color_mode = MODE_COLORS_NONE;
Cycle.speed_min = LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST;
Cycle.speed_max = LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST;
Cycle.speed = LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL;
modes.push_back(Cycle);
mode Breathing;
Breathing.name = "Breathing";
Breathing.value = LOGITECH_G_PRO_WIRELESS_MODE_BREATHING;
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
Breathing.color_mode = MODE_COLORS_PER_LED;
Breathing.speed_min = LOGITECH_G_PRO_WIRELESS_SPEED_SLOWEST;
Breathing.speed_max = LOGITECH_G_PRO_WIRELESS_SPEED_FASTEST;
Breathing.speed = LOGITECH_G_PRO_WIRELESS_SPEED_NORMAL;
modes.push_back(Breathing);
SetupZones();
}
else
{
name = "Idle Lightspeed Device";
vendor = "Logitech";
type = DEVICE_TYPE_UNKNOWN;
description = "Idle Logitech Wireless Lightspeed Device";
location = logitech->GetDeviceLocation();
serial = logitech->GetSerialString();
}
}
RGBController_LogitechLightspeed::~RGBController_LogitechLightspeed()
{
delete logitech;
}
void RGBController_LogitechLightspeed::SetupZones()
{
uint8_t LED_count = logitech->lightspeed->getLEDinfo();
if(LED_count > 0)
{
for(size_t i = 0; i < LED_count; i++)
{
zone Lightspeed_logo_zone;
Lightspeed_logo_zone.name = "Zone " + std::to_string(i);
Lightspeed_logo_zone.type = ZONE_TYPE_SINGLE;
Lightspeed_logo_zone.leds_min = 1;
Lightspeed_logo_zone.leds_max = 1;
Lightspeed_logo_zone.leds_count = 1;
Lightspeed_logo_zone.matrix_map = NULL;
zones.push_back(Lightspeed_logo_zone);
led Lightspeed_logo_led;
Lightspeed_logo_led.name = "LED " + std::to_string(i);
Lightspeed_logo_led.value = i;
leds.push_back(Lightspeed_logo_led);
}
}
SetupColors();
}
void RGBController_LogitechLightspeed::ResizeZone(int /*zone*/, int /*new_size*/)
{
/*---------------------------------------------------------*\
| This device does not support resizing zones |
\*---------------------------------------------------------*/
}
void RGBController_LogitechLightspeed::DeviceUpdateLEDs()
{
for(std::vector<led>::iterator led_index = leds.begin(); led_index != leds.end(); led_index++)
{
UpdateZoneLEDs(led_index->value);
}
}
void RGBController_LogitechLightspeed::UpdateZoneLEDs(int zone)
{
unsigned char red = RGBGetRValue(colors[zone]);
unsigned char grn = RGBGetGValue(colors[zone]);
unsigned char blu = RGBGetBValue(colors[zone]);
/*---------------------------------------------------------*\
| Replace direct mode with static when sending to controller|
\*---------------------------------------------------------*/
unsigned char temp_mode = (modes[active_mode].value == 0xFF) ? LOGITECH_G_PRO_WIRELESS_MODE_STATIC : modes[active_mode].value;
logitech->SendMouseMode(temp_mode, modes[active_mode].speed, zone, red, grn, blu);
}
void RGBController_LogitechLightspeed::UpdateSingleLED(int led)
{
UpdateZoneLEDs(led);
}
void RGBController_LogitechLightspeed::SetCustomMode()
{
if(logitech->lightspeed->connected())
{
active_mode = 1;
}
}
void RGBController_LogitechLightspeed::DeviceUpdateMode()
{
/*---------------------------------------------------------*\
| If direct mode is true, then sent the packet to put the |
| mouse in direct mode. This code will only be called when |
| we change modes as to not spam the device. |
\*---------------------------------------------------------*/
logitech->lightspeed->setDirectMode(modes[active_mode].value == 0xFF);
DeviceUpdateLEDs();
}
@@ -1,21 +1,21 @@
/*-----------------------------------------*\
| RGBController_LogitechGProWireless.h |
| RGBController_LogitechLightspeed.h |
| |
| Generic RGB Interface for |
| Logitech G Pro Wireless Gaming Mouse |
| Logitech Lightspeed Gaming Mice |
| |
| TheRogueZeta 8/5/2020 |
\*-----------------------------------------*/
#pragma once
#include "RGBController.h"
#include "LogitechGProWirelessController.h"
#include "LogitechLightspeedController.h"
class RGBController_LogitechGProWireless : public RGBController
class RGBController_LogitechLightspeed : public RGBController
{
public:
RGBController_LogitechGProWireless(LogitechGProWirelessController* logitech_ptr);
~RGBController_LogitechGProWireless();
RGBController_LogitechLightspeed(LogitechLightspeedController* logitech_ptr);
~RGBController_LogitechLightspeed();
void SetupZones();
@@ -29,5 +29,5 @@ public:
void DeviceUpdateMode();
private:
LogitechGProWirelessController* logitech;
LogitechLightspeedController* logitech;
};
@@ -3,6 +3,7 @@
#include "MSIMysticLight185Controller.h"
#include "RGBController_MSIMysticLight162.h"
#include "RGBController_MSIMysticLight185.h"
#include "dependencies/dmiinfo.h"
#define MSI_USB_VID 0x1462
@@ -23,15 +24,16 @@
* *
\******************************************************************************************/
void DetectMSIMysticLight162Controllers(hid_device_info* info, const std::string& name)
void DetectMSIMysticLight162Controllers(hid_device_info* info, const std::string& /*name*/)
{
hid_device* dev = hid_open_path(info->path);
if( dev )
{
DMIInfo dmi;
MSIMysticLight162Controller* controller = new MSIMysticLight162Controller(dev, info->path);
RGBController_MSIMysticLight162* rgb_controller = new RGBController_MSIMysticLight162(controller);
rgb_controller->name = "MSI " + dmi.getMainboard();
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
} /* DetectMSIMysticLight162Controllers() */
@@ -44,15 +46,16 @@ void DetectMSIMysticLight162Controllers(hid_device_info* info, const std::string
* *
\******************************************************************************************/
void DetectMSIMysticLight185Controllers(hid_device_info* info, const std::string& name)
void DetectMSIMysticLight185Controllers(hid_device_info* info, const std::string& /*name*/)
{
hid_device* dev = hid_open_path(info->path);
if( dev )
{
DMIInfo dmi;
MSIMysticLight185Controller* controller = new MSIMysticLight185Controller(dev, info->path);
RGBController_MSIMysticLight185* rgb_controller = new RGBController_MSIMysticLight185(controller);
rgb_controller->name = "MSI " + dmi.getMainboard();
ResourceManager::get()->RegisterRGBController(rgb_controller);
}
} /* DetectMSIMysticLight185Controllers() */
@@ -82,6 +85,8 @@ REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C90", DetectMSIMysticLight185C
REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C91", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C91, 0x0001, 0x00);
REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C92", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C92, 0x0001, 0x00);
REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7C94", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7C94, 0x0001, 0x00);
REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D09", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7D09, 0x0001, 0x00);
REGISTER_HID_DETECTOR_PU("MSI Mystic Light MS_7D13", DetectMSIMysticLight185Controllers, MSI_USB_VID, 0x7D13, 0x0001, 0x00);
#ifdef ENABLE_UNTESTED_MYSTIC_LIGHT
/*-------------------------------------------------------------*\
@@ -106,7 +106,7 @@ void DetectMSIRGBControllers(std::vector<RGBController*> &rgb_controllers)
{
MSIRGBController* new_msi = new MSIRGBController(sioaddr, compatible_devices[i].invert);
RGBController_MSIRGB* new_rgb = new RGBController_MSIRGB(new_msi);
new_rgb->name = "MSI " + board_dmi;
rgb_controllers.push_back(new_rgb);
break;
}
@@ -3114,11 +3114,11 @@ static const razer_device diamondback_chroma_device =
| |
| Zone "Right" |
| Linear |
| 8 LEDs |
| 7 LEDs |
| |
| Zone "Left" |
| Linear |
| 8 LEDs |
| 7 LEDs |
| |
| Zone "Logo" |
| Single |
@@ -3133,7 +3133,7 @@ static const razer_zone lancehead_te_right_zone =
"Right LED Strip",
ZONE_TYPE_LINEAR,
1,
8
7
};
static const razer_zone lancehead_te_left_zone =
@@ -3141,7 +3141,7 @@ static const razer_zone lancehead_te_left_zone =
"Left LED Strip",
ZONE_TYPE_LINEAR,
1,
8
7
};
static const razer_zone lancehead_te_logo_zone =
@@ -3166,7 +3166,7 @@ static const razer_device lancehead_te_device =
DEVICE_TYPE_MOUSE,
true,
1,
18,
16,
{
&lancehead_te_right_zone,
&lancehead_te_left_zone,
@@ -3184,11 +3184,11 @@ static const razer_device lancehead_te_device =
| |
| Zone "Right" |
| Linear |
| 8 LEDs |
| 7 LEDs |
| |
| Zone "Left" |
| Linear |
| 8 LEDs |
| 7 LEDs |
| |
| Zone "Logo" |
| Single |
@@ -3203,7 +3203,7 @@ static const razer_zone lancehead_v2_wired_right_zone =
"Right LED Strip",
ZONE_TYPE_LINEAR,
1,
8
7
};
static const razer_zone lancehead_v2_wired_left_zone =
@@ -3211,7 +3211,7 @@ static const razer_zone lancehead_v2_wired_left_zone =
"Left LED Strip",
ZONE_TYPE_LINEAR,
1,
8
7
};
static const razer_zone lancehead_v2_wired_logo_zone =
@@ -3236,7 +3236,7 @@ static const razer_device lancehead_v2_wired_device =
DEVICE_TYPE_MOUSE,
true,
1,
18,
16,
{
&lancehead_v2_wired_right_zone,
&lancehead_v2_wired_left_zone,
@@ -3254,11 +3254,11 @@ static const razer_device lancehead_v2_wired_device =
| |
| Zone "Right" |
| Linear |
| 8 LEDs |
| 7 LEDs |
| |
| Zone "Left" |
| Linear |
| 8 LEDs |
| 7 LEDs |
| |
| Zone "Logo" |
| Single |
@@ -3273,7 +3273,7 @@ static const razer_zone lancehead_v2_wireless_right_zone =
"Right LED Strip",
ZONE_TYPE_LINEAR,
1,
8
7
};
static const razer_zone lancehead_v2_wireless_left_zone =
@@ -3281,7 +3281,7 @@ static const razer_zone lancehead_v2_wireless_left_zone =
"Left LED Strip",
ZONE_TYPE_LINEAR,
1,
8
7
};
static const razer_zone lancehead_v2_wireless_logo_zone =
@@ -3306,7 +3306,7 @@ static const razer_device lancehead_v2_wireless_device =
DEVICE_TYPE_MOUSE,
true,
1,
18,
16,
{
&lancehead_v2_wireless_right_zone,
&lancehead_v2_wireless_left_zone,
@@ -0,0 +1,430 @@
/*-------------------------------------------------------------------*\
| QMKOpenRGBController.cpp |
| |
| Driver for QMK keyboards using OpenRGB Protocol |
| |
| Kasper 10th Octobber 2020 |
| Jath03 28th May 2021 |
\*-------------------------------------------------------------------*/
#include "QMKOpenRGBController.h"
static std::map<uint8_t, std::string> QMKKeycodeToKeynameMap
{
{ 0, "" }, { 1, "Right Fn" }, { 2, "" }, { 3, "" },
{ 4, "A" }, { 5, "B" }, { 6, "C" }, { 7, "D" },
{ 8, "E" }, { 9, "F" }, { 10, "G" }, { 11, "H" },
{ 12, "I" }, { 13, "J" }, { 14, "K" }, { 15, "L" },
{ 16, "M" }, { 17, "N" }, { 18, "O" }, { 19, "P" },
{ 20, "Q" }, { 21, "R" }, { 22, "S" }, { 23, "T" },
{ 24, "U" }, { 25, "V" }, { 26, "W" }, { 27, "X" },
{ 28, "Y" }, { 29, "Z" }, { 30, "1" }, { 31, "2" },
{ 32, "3" }, { 33, "4" }, { 34, "5" }, { 35, "6" },
{ 36, "7" }, { 37, "8" }, { 38, "9" }, { 39, "0" },
{ 40, "Enter" }, { 41, "Escape" }, { 42, "Backspace" }, { 43, "Tab" },
{ 44, "Space" }, { 45, "-" }, { 46, "=" }, { 47, "[" },
{ 48, "]" }, { 49, "\\ (ANSI)" }, { 50, "" }, { 51, ";" },
{ 52, "'" }, { 53, "`" }, { 54, "," }, { 55, "." },
{ 56, "/" }, { 57, "Caps Lock" }, { 58, "F1" }, { 59, "F2" },
{ 60, "F3" }, { 61, "F4" }, { 62, "F5" }, { 63, "F6" },
{ 64, "F7" }, { 65, "F8" }, { 66, "F9" }, { 67, "F10" },
{ 68, "F11" }, { 69, "F12" }, { 70, "Print Screen" }, { 71, "Scroll Lock" },
{ 72, "Pause/Break" }, { 73, "Insert" }, { 74, "Home" }, { 75, "Page Up" },
{ 76, "Delete" }, { 77, "End" }, { 78, "Page Down" }, { 79, "Right Arrow" },
{ 80, "Left Arrow" }, { 81, "Down Arrow" }, { 82, "Up Arrow" }, { 83, "Num Lock" },
{ 84, "Number Pad /" }, { 85, "Number Pad *" }, { 86, "Number Pad -" }, { 87, "Number Pad +" },
{ 88, "Number Pad Enter" }, { 89, "Number Pad 1" }, { 90, "Number Pad 2" }, { 91, "Number Pad 3" },
{ 92, "Number Pad 4" }, { 93, "Number Pad 5" }, { 94, "Number Pad 6" }, { 95, "Number Pad 7" },
{ 96, "Number Pad 8" }, { 97, "Number Pad 9" }, { 98, "Number Pad 0" }, { 99, "Number Pad ." },
{ 100, "" }, { 101, "Menu" }, { 102, "" }, { 103, "" },
{ 104, "" }, { 105, "" }, { 106, "" }, { 107, "" },
{ 108, "" }, { 109, "" }, { 110, "" }, { 111, "" },
{ 112, "" }, { 113, "" }, { 114, "" }, { 115, "" },
{ 116, "" }, { 117, "" }, { 118, "" }, { 119, "" },
{ 120, "" }, { 121, "" }, { 122, "" }, { 123, "" },
{ 124, "" }, { 125, "" }, { 126, "" }, { 127, "" },
{ 128, "" }, { 129, "" }, { 130, "" }, { 131, "" },
{ 132, "" }, { 133, "" }, { 134, "" }, { 135, "" },
{ 136, "" }, { 137, "" }, { 138, "" }, { 139, "" },
{ 140, "" }, { 141, "" }, { 142, "" }, { 143, "" },
{ 144, "" }, { 145, "" }, { 146, "" }, { 147, "" },
{ 148, "" }, { 149, "" }, { 150, "" }, { 151, "" },
{ 152, "" }, { 153, "" }, { 154, "" }, { 155, "" },
{ 156, "" }, { 157, "" }, { 158, "" }, { 159, "" },
{ 160, "" }, { 161, "" }, { 162, "" }, { 163, "" }, { 164, "" },
/*Space Cadet Left Shift*/ { 216, "Left Shift"}, /*Space Cadet Right Shift*/ { 217, "Right Shift"},
{ 224, "Left Control" }, { 225, "Left Shift" }, { 226, "Left Alt" }, { 227, "Left Windows" },
{ 228, "Right Control" }, { 229, "Right Shift" }, { 230, "Right Alt" }, { 231, "Right Windows" },
};
QMKOpenRGBController::QMKOpenRGBController(hid_device *dev_handle, const char *path)
{
dev = dev_handle;
location = path;
GetDeviceInfo();
GetModeInfo();
}
QMKOpenRGBController::~QMKOpenRGBController()
{
hid_close(dev);
}
std::string QMKOpenRGBController::GetLocation()
{
return location;
}
std::string QMKOpenRGBController::GetDeviceName()
{
return device_name;
}
std::string QMKOpenRGBController::GetDeviceVendor()
{
return device_vendor;
}
unsigned int QMKOpenRGBController::GetTotalNumberOfLEDs()
{
return total_number_of_leds;
}
unsigned int QMKOpenRGBController::GetTotalNumberOfLEDsWithEmptySpace()
{
return total_number_of_leds_with_empty_space;
}
unsigned int QMKOpenRGBController::GetMode()
{
return mode;
}
unsigned int QMKOpenRGBController::GetModeSpeed()
{
return mode_speed;
}
unsigned int QMKOpenRGBController::GetModeColor()
{
return mode_color;
}
std::vector<point_t> QMKOpenRGBController::GetLEDPoints()
{
return led_points;
}
std::vector<unsigned int> QMKOpenRGBController::GetLEDFlags()
{
return led_flags;
}
std::vector<std::string> QMKOpenRGBController::GetLEDNames()
{
return led_names;
}
std::vector<RGBColor> QMKOpenRGBController::GetLEDColors()
{
return led_colors;
}
unsigned int QMKOpenRGBController::GetProtocolVersion()
{
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = QMK_OPENRGB_GET_PROTOCOL_VERSION;
int bytes_read = 0;
do
{
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_HID_READ_TIMEOUT);
} while(bytes_read <= 0);
return usb_buf[1];
}
std::string QMKOpenRGBController::GetQMKVersion()
{
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = QMK_OPENRGB_GET_QMK_VERSION;
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
hid_read(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
std::string qmk_version;
int i = 1;
while (usb_buf[i] != 0)
{
qmk_version.push_back(usb_buf[i]);
i++;
}
return qmk_version;
}
void QMKOpenRGBController::GetDeviceInfo()
{
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = QMK_OPENRGB_GET_DEVICE_INFO;
int bytes_read = 0;
do
{
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_HID_READ_TIMEOUT);
} while(bytes_read <= 0);
total_number_of_leds = usb_buf[QMK_OPENRGB_TOTAL_NUMBER_OF_LEDS_BYTE];
total_number_of_leds_with_empty_space = usb_buf[QMK_OPENRGB_TOTAL_NUMBER_OF_LEDS_WITH_EMPTY_SPACE_BYTE];
int i = QMK_OPENRGB_TOTAL_NUMBER_OF_LEDS_WITH_EMPTY_SPACE_BYTE + 1;
while (usb_buf[i] != 0)
{
device_name.push_back(usb_buf[i]);
i++;
}
i++;
while (usb_buf[i] != 0)
{
device_vendor.push_back(usb_buf[i]);
i++;
}
}
void QMKOpenRGBController::GetModeInfo()
{
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = QMK_OPENRGB_GET_MODE_INFO;
int bytes_read = 0;
do
{
hid_write(dev, usb_buf, 65);
bytes_read = hid_read_timeout(dev, usb_buf, 65, QMK_HID_READ_TIMEOUT);
} while(bytes_read <= 0);
mode = usb_buf[QMK_OPENRGB_MODE_BYTE];
mode_speed = usb_buf[QMK_OPENRGB_SPEED_BYTE];
/*-----------------------------------------------------*\
| QMK hue range is between 0-255 so hue needs to be |
| converted |
\*-----------------------------------------------------*/
unsigned int oldRange = 255;
unsigned int newRange = 359;
unsigned int convertedHue = (usb_buf[QMK_OPENRGB_HUE_BYTE] * newRange / oldRange);
hsv_t hsv;
hsv.hue = convertedHue;
hsv.saturation = usb_buf[QMK_OPENRGB_SATURATION_BYTE];
hsv.value = usb_buf[QMK_OPENRGB_VALUE_BYTE];
mode_color = hsv2rgb(&hsv);
}
void QMKOpenRGBController::GetLEDInfo(unsigned int led)
{
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = QMK_OPENRGB_GET_LED_INFO;
usb_buf[0x02] = led;
int bytes_read = 0;
do
{
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_HID_READ_TIMEOUT);
} while(bytes_read <= 0);
if(usb_buf[62] != QMK_OPENRGB_FAILURE)
{
led_points.push_back(point_t{usb_buf[QMK_OPENRGB_POINT_X_BYTE], usb_buf[QMK_OPENRGB_POINT_Y_BYTE]});
led_flags.push_back(usb_buf[QMK_OPENRGB_FLAG_BYTE]);
led_colors.push_back(ToRGBColor(usb_buf[QMK_OPENRGB_R_COLOR_BYTE], usb_buf[QMK_OPENRGB_G_COLOR_BYTE], usb_buf[QMK_OPENRGB_B_COLOR_BYTE]));
}
if(usb_buf[QMK_OPENRGB_KEYCODE_BYTE] != 0)
{
if (QMKKeycodeToKeynameMap.count(usb_buf[QMK_OPENRGB_KEYCODE_BYTE]) > 0)
{
led_names.push_back("Key: " + QMKKeycodeToKeynameMap[usb_buf[QMK_OPENRGB_KEYCODE_BYTE]]);
}
else
{
led_names.push_back("Key: ");
}
}
}
bool QMKOpenRGBController::GetIsModeEnabled(unsigned int mode)
{
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = QMK_OPENRGB_GET_IS_MODE_ENABLED;
usb_buf[0x02] = mode;
int bytes_read = 0;
do
{
hid_write(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE);
bytes_read = hid_read_timeout(dev, usb_buf, QMK_OPENRGB_PACKET_SIZE, QMK_HID_READ_TIMEOUT);
} while(bytes_read <= 0);
return usb_buf[1] == QMK_OPENRGB_SUCCESS ? true : false;
}
void QMKOpenRGBController::SetMode(hsv_t hsv_color, unsigned char mode, unsigned char speed)
{
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = QMK_OPENRGB_SET_MODE;
usb_buf[0x02] = hsv_color.hue * 255 / 359;
usb_buf[0x03] = hsv_color.saturation;
usb_buf[0x04] = hsv_color.value;
usb_buf[0x05] = mode;
usb_buf[0x06] = speed;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read_timeout(dev, usb_buf, 65, QMK_HID_READ_TIMEOUT);
}
void QMKOpenRGBController::DirectModeSetSingleLED(unsigned int led, unsigned char red, unsigned char green, unsigned char blue)
{
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = QMK_OPENRGB_DIRECT_MODE_SET_SINGLE_LED;
usb_buf[0x02] = led;
usb_buf[0x03] = red;
usb_buf[0x04] = green;
usb_buf[0x05] = blue;
/*-----------------------------------------------------*\
| Send packet |
\*-----------------------------------------------------*/
hid_write(dev, usb_buf, 65);
hid_read_timeout(dev, usb_buf, 65, QMK_HID_READ_TIMEOUT);
}
void QMKOpenRGBController::DirectModeSetLEDs(std::vector<RGBColor> colors, unsigned int leds_count)
{
unsigned int leds_sent = 0;
unsigned int leds_per_update = 20;
while (leds_sent < leds_count)
{
if ((leds_count - leds_sent) < leds_per_update)
{
leds_per_update = leds_count - leds_sent;
}
unsigned char usb_buf[QMK_OPENRGB_PACKET_SIZE];
/*-----------------------------------------------------*\
| Zero out buffer |
\*-----------------------------------------------------*/
memset(usb_buf, 0x00, QMK_OPENRGB_PACKET_SIZE);
/*-----------------------------------------------------*\
| Set up config table request packet |
\*-----------------------------------------------------*/
usb_buf[0x00] = 0x00;
usb_buf[0x01] = QMK_OPENRGB_DIRECT_MODE_SET_LEDS;
usb_buf[0x02] = leds_sent;
usb_buf[0x03] = leds_per_update;
for (unsigned int led_idx = 0; led_idx < leds_per_update; led_idx++)
{
usb_buf[(led_idx * 3) + 4] = RGBGetRValue(colors[led_idx + leds_sent]);
usb_buf[(led_idx * 3) + 5] = RGBGetGValue(colors[led_idx + leds_sent]);
usb_buf[(led_idx * 3) + 6] = RGBGetBValue(colors[led_idx + leds_sent]);
}
hid_write(dev, usb_buf, 65);
leds_sent += leds_per_update;
}
}

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