Compare commits
259
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c1ec2f187 | ||
|
|
7dadc8d9ee | ||
|
|
cd7146d611 | ||
|
|
853833d18a | ||
|
|
c500803d95 | ||
|
|
68a92d0219 | ||
|
|
5221d93fc0 | ||
|
|
22deb13ac0 | ||
|
|
58b875d5ed | ||
|
|
12f5d6070f | ||
|
|
5e0b1fa3cc | ||
|
|
1ee3a7c3e2 | ||
|
|
43c13db970 | ||
|
|
b5818d22af | ||
|
|
fd7a5fc057 | ||
|
|
5af1ca9363 | ||
|
|
c4d096e60c | ||
|
|
174b0743a9 | ||
|
|
4b50533560 | ||
|
|
1555dae1c8 | ||
|
|
8b5717470a | ||
|
|
38b2cf03b0 | ||
|
|
1293b07c9e | ||
|
|
aa4c41ddf7 | ||
|
|
628f423171 | ||
|
|
a9d179f93a | ||
|
|
4955dc0844 | ||
|
|
3f66f0d67a | ||
|
|
bc7ab5170a | ||
|
|
d61649f748 | ||
|
|
9a33a78574 | ||
|
|
030c0c60f3 | ||
|
|
19ff834d99 | ||
|
|
400a078a05 | ||
|
|
618bebc46b | ||
|
|
dee23ec52e | ||
|
|
baca85b8cd | ||
|
|
00b1cfcb3b | ||
|
|
a9dbf5ef70 | ||
|
|
a0b1153ec3 | ||
|
|
39a5e0eba0 | ||
|
|
308bb6f9b8 | ||
|
|
86d96848a2 | ||
|
|
98100a9bad | ||
|
|
e66562bb25 | ||
|
|
902ebc2e83 | ||
|
|
403d60e214 | ||
|
|
1c5130e78a | ||
|
|
481a5dea2e | ||
|
|
320129633d | ||
|
|
0dea21a53e | ||
|
|
79625e9c8a | ||
|
|
0cff1734ce | ||
|
|
e1d8f48cb9 | ||
|
|
752737034b | ||
|
|
ecf1d2ce98 | ||
|
|
bb743c6b62 | ||
|
|
f02223d6ba | ||
|
|
b87980965d | ||
|
|
2255eea14e | ||
|
|
0ccf2d0c33 | ||
|
|
5ce6ec9ea7 | ||
|
|
97e1c3e913 | ||
|
|
9937731ad8 | ||
|
|
bd4f3728f6 | ||
|
|
009a6ccd2a | ||
|
|
6606ab92bd | ||
|
|
595248cc10 | ||
|
|
ffc02e6c98 | ||
|
|
ac2d911566 | ||
|
|
633dfdbddd | ||
|
|
54cd8408e8 | ||
|
|
384011aab3 | ||
|
|
95ded7b871 | ||
|
|
607d83b795 | ||
|
|
f4872c52bd | ||
|
|
505e2d2aa4 | ||
|
|
77ecfc3b46 | ||
|
|
8107288838 | ||
|
|
05e76cc733 | ||
|
|
816eabb1d1 | ||
|
|
9b6e24947d | ||
|
|
5778d344e0 | ||
|
|
b785f2efbf | ||
|
|
224f59450e | ||
|
|
b80cbe931e | ||
|
|
87adb0bdb7 | ||
|
|
78c7572a2c | ||
|
|
bbed1f64a7 | ||
|
|
ac071902c0 | ||
|
|
62a4cd31c5 | ||
|
|
751961b3b3 | ||
|
|
30625548e5 | ||
|
|
9451771ccb | ||
|
|
12442046e2 | ||
|
|
47baeb6b6b | ||
|
|
263561868c | ||
|
|
9bc58b039b | ||
|
|
82c0ff8452 | ||
|
|
2d7e996e4b | ||
|
|
0ae76e40c2 | ||
|
|
343c285321 | ||
|
|
6492852627 | ||
|
|
acc032a69c | ||
|
|
950a3be01d | ||
|
|
6626321e80 | ||
|
|
7276f5e1d5 | ||
|
|
5f9c4f8432 | ||
|
|
a1cd324731 | ||
|
|
c2c5e6666d | ||
|
|
f7d6ede033 | ||
|
|
25f9e2a110 | ||
|
|
8ef6888a28 | ||
|
|
78a7be63ef | ||
|
|
f108515a6e | ||
|
|
ad4e198aea | ||
|
|
5aad79135f | ||
|
|
5fc6981c16 | ||
|
|
942df26432 | ||
|
|
b3860be638 | ||
|
|
8ecabb0789 | ||
|
|
d3fc88b24f | ||
|
|
dfb2e52e7b | ||
|
|
96af869d79 | ||
|
|
4c6429ae76 | ||
|
|
7d2877a8e9 | ||
|
|
a25f3ef2fc | ||
|
|
15ace9d094 | ||
|
|
58aba0a147 | ||
|
|
199db16ec0 | ||
|
|
c364fabf57 | ||
|
|
15a2d5beaf | ||
|
|
5b956f7ff1 | ||
|
|
dc42248a88 | ||
|
|
eeeab399be | ||
|
|
39d451793b | ||
|
|
5db888fba0 | ||
|
|
1b91687fac | ||
|
|
7d38cd4a78 | ||
|
|
899b90decc | ||
|
|
8dcb1f075d | ||
|
|
5588f9b7a9 | ||
|
|
717620e8dd | ||
|
|
877d462dbc | ||
|
|
d3cf315175 | ||
|
|
f47129902a | ||
|
|
5a3c69ec32 | ||
|
|
392c547b87 | ||
|
|
38527a5122 | ||
|
|
77412a959f | ||
|
|
3a5ebe387e | ||
|
|
1db412e970 | ||
|
|
a3c931392a | ||
|
|
b94f701db8 | ||
|
|
b79ff124e6 | ||
|
|
60baf6d05f | ||
|
|
cb9b22804a | ||
|
|
d2dfd03551 | ||
|
|
f3bdee9bd2 | ||
|
|
7a3de1edbb | ||
|
|
0464fbcbe2 | ||
|
|
12226804f3 | ||
|
|
f06d71bd0c | ||
|
|
112d5a1cb2 | ||
|
|
b70658e37d | ||
|
|
80a2770263 | ||
|
|
765ef62858 | ||
|
|
0e58fcc236 | ||
|
|
4bf0330974 | ||
|
|
6d585d3eeb | ||
|
|
0286a5dd58 | ||
|
|
b3cadbae5d | ||
|
|
e26e874d1c | ||
|
|
c9c214267d | ||
|
|
6957c1ca03 | ||
|
|
f5aafda340 | ||
|
|
f1fe428f59 | ||
|
|
614c9768ad | ||
|
|
5828c4df8d | ||
|
|
6cf32b8a94 | ||
|
|
bc6487505a | ||
|
|
d1e8104442 | ||
|
|
91414084d6 | ||
|
|
372ff746ad | ||
|
|
ab297281d3 | ||
|
|
2cbba19bf9 | ||
|
|
b5001c983e | ||
|
|
7d4d6152ab | ||
|
|
f2c1022c7f | ||
|
|
771e362a63 | ||
|
|
3eba2c3dd3 | ||
|
|
305f66ad3d | ||
|
|
3191a87f46 | ||
|
|
a9493d46aa | ||
|
|
6499ee4312 | ||
|
|
f26897df71 | ||
|
|
8ae07ea9e2 | ||
|
|
cb94b4fe28 | ||
|
|
f51f222fb4 | ||
|
|
d3162ea2e8 | ||
|
|
fa1f0b05ce | ||
|
|
c7bb002b7c | ||
|
|
b1de039f21 | ||
|
|
e086ecd0bb | ||
|
|
f612ca8bdc | ||
|
|
5b8441c57d | ||
|
|
919d89d52f | ||
|
|
479d51df87 | ||
|
|
687424e732 | ||
|
|
a2a613f22d | ||
|
|
a34d0f93a3 | ||
|
|
8e62be0b9e | ||
|
|
95bcc5e0fd | ||
|
|
19ef8afe70 | ||
|
|
5fdea9d34f | ||
|
|
32938ec2af | ||
|
|
8d29a40954 | ||
|
|
a75a2bbf8b | ||
|
|
f96a4c3557 | ||
|
|
1d426f109a | ||
|
|
8827d0e0c2 | ||
|
|
edfb4f8d4e | ||
|
|
13ce388e9a | ||
|
|
316902b2c3 | ||
|
|
6667cdeed9 | ||
|
|
de44c57081 | ||
|
|
30a1bc9893 | ||
|
|
cf4b421abd | ||
|
|
1a9e1c2430 | ||
|
|
bde9e7ea6b | ||
|
|
fc9c6585af | ||
|
|
be9711a021 | ||
|
|
bfa7f63486 | ||
|
|
8f19267886 | ||
|
|
fab6e41810 | ||
|
|
c3ceac1ed9 | ||
|
|
bb01790d71 | ||
|
|
9cf7bdea29 | ||
|
|
6da6ff6cc0 | ||
|
|
baa04913c3 | ||
|
|
64c0861097 | ||
|
|
522016137b | ||
|
|
40d0f17ae2 | ||
|
|
c88e71d52a | ||
|
|
c3d284c97b | ||
|
|
19b572da30 | ||
|
|
e6c4017ad0 | ||
|
|
b862912fb1 | ||
|
|
02f7f57130 | ||
|
|
c6b3d7c675 | ||
|
|
1b2a5a4b14 | ||
|
|
c0190d35d1 | ||
|
|
4d0219b184 | ||
|
|
85fc72232a | ||
|
|
cbb13b0d22 | ||
|
|
bd6ec4c41e | ||
|
|
d843b3d619 | ||
|
|
ca9c40f084 | ||
|
|
6a85729f10 |
@@ -1 +1,8 @@
|
||||
*.pro.user*
|
||||
*.o
|
||||
ui_*
|
||||
moc_*
|
||||
qrc_*
|
||||
OpenRGB
|
||||
Makefile
|
||||
OpenRGB-x86_64.AppImage
|
||||
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
# swy: some useful references; the MSVC part of the CI script is based on the one from bind9, by Michał Kępień:
|
||||
# https://gitlab.com/gitlab-org/ci-cd/shared-runners/images/gcp/windows-containers/blob/master/cookbooks/preinstalled-software/README.md
|
||||
# https://gitlab.isc.org/isc-projects/bind9/commit/facc6a051fcac70fbbc61cb92a37be8c3e4db5ec#587d266bb27a4dc3022bbed44dfa19849df3044c_718_731
|
||||
# https://www.kittell.net/code/powershell-unix-sed-equivalent-change-text-file/
|
||||
# https://powershell.org/forums/topic/how-to-use-ansi-vt100-formatting-in-powershell-ooh-pretty-colors/
|
||||
|
||||
#-----------------------------------------------------------------------#
|
||||
# OpenRGB GitLab CI Configuration #
|
||||
#-----------------------------------------------------------------------#
|
||||
|
||||
.shared_windows_runners:
|
||||
tags:
|
||||
- shared-windows
|
||||
- windows
|
||||
- windows-1809
|
||||
|
||||
stages:
|
||||
- build
|
||||
|
||||
before_script:
|
||||
- echo "started by ${GITLAB_USER_NAME}"
|
||||
|
||||
#-----------------------------------------------------------------------#
|
||||
# Linux (AppImage) Build Target #
|
||||
#-----------------------------------------------------------------------#
|
||||
build_linux:
|
||||
image: ubuntu:bionic
|
||||
stage: build
|
||||
script:
|
||||
- apt update
|
||||
- apt install -y build-essential qtcreator qt5-default libusb-1.0-0-dev libhidapi-dev pkgconf wget git
|
||||
- ./scripts/build-appimage.sh
|
||||
|
||||
artifacts:
|
||||
paths:
|
||||
- OpenRGB-x86_64.AppImage
|
||||
expire_in: 1337 years
|
||||
|
||||
#-----------------------------------------------------------------------#
|
||||
# Windows (32-bit) Build Target #
|
||||
#-----------------------------------------------------------------------#
|
||||
build_windows_32:
|
||||
extends:
|
||||
- .shared_windows_runners
|
||||
stage: build
|
||||
script:
|
||||
- $esc = "$([char]27)"
|
||||
- $count = 0
|
||||
- function _unix_tmsec_ { [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds }
|
||||
- function _fold_start_ { param( [string]$TEXT_TAG ) $t=_unix_tmsec_; $global:count += 1; Write-Host -NoNewLine "`r`n`r`nsection_start:${t}:sect_${count}`r${esc}[0K${esc}[33m${TEXT_TAG}${esc}[39m`r`n"; }
|
||||
- function _fold_final_ { $t=_unix_tmsec_; Write-Host -NoNewLine "`r`n`r`nsection_end:${t}:sect_${count}`r${esc}[0K`r`n" ; }
|
||||
|
||||
|
||||
- _fold_start_ 'configuring the msvc environment variables'
|
||||
- Push-Location "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Auxiliary/Build"
|
||||
- '& cmd.exe /C "vcvarsall.bat x86 & set" | Foreach-Object { if ($_ -match "(.*?)=(.*)") { Set-Item -force -path "Env:\$($matches[1])" -value "$($matches[2])" } }'
|
||||
- Pop-Location
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'downloading precompiled versions of qtbase, qttools (for windeployqt) and jom (for a more parallel nmake)'
|
||||
- mkdir _qt
|
||||
- mkdir _qt_download
|
||||
- Push-Location _qt_download
|
||||
- curl.exe -LJ -o qt-base.7z 'https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win32_msvc2019/5.15.0-0-202005150700qtbase-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86.7z'
|
||||
- curl.exe -LJ -o qt-tools.7z 'https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win32_msvc2019/5.15.0-0-202005150700qttools-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86.7z'
|
||||
- curl.exe -LJ -o qt-jom.zip 'https://download.qt.io/official_releases/jom/jom.zip'
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'extracting the downloaded qt binaries'
|
||||
- 7z x qt-base.7z '-o../_qt' -y
|
||||
- 7z x qt-tools.7z '-o../_qt' -y
|
||||
- 7z x qt-jom.zip '-o../_qt' -y
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'turn the qt install from enterprise to foss; remove the licensing checks'
|
||||
- ${qconfig-pri-folder} = '..\_qt\5.15.0\msvc2019\mkspecs\qconfig.pri'
|
||||
- (Get-Content ${qconfig-pri-folder}).replace('QT_EDITION = Enterprise', 'QT_EDITION = OpenSource') | Set-Content ${qconfig-pri-folder}
|
||||
- (Get-Content ${qconfig-pri-folder}).replace('QT_LICHECK = licheck.exe', '') | Set-Content ${qconfig-pri-folder}
|
||||
- Pop-Location
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'run qmake and generate the msvc nmake makefile'
|
||||
- mkdir _build; cd _build
|
||||
- ..\_qt\5.15.0\msvc2019\bin\qmake ..\OpenRGB.pro
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'start the actual build with jom instead of nmake; for speed'
|
||||
- ..\_qt\jom
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'run windeployqt to automatically copy the needed dll files'
|
||||
- ..\_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_final_
|
||||
# cache:
|
||||
# key: same-key
|
||||
# paths:
|
||||
# - C:\vcpkg\installed\
|
||||
artifacts:
|
||||
paths:
|
||||
- _build/*.7z
|
||||
expire_in: 1337 years
|
||||
|
||||
#-----------------------------------------------------------------------#
|
||||
# Windows (64-bit) Build Target #
|
||||
#-----------------------------------------------------------------------#
|
||||
build_windows_64:
|
||||
extends:
|
||||
- .shared_windows_runners
|
||||
stage: build
|
||||
script:
|
||||
- $esc = "$([char]27)"
|
||||
- $count = 0
|
||||
- function _unix_tmsec_ { [int64](([datetime]::UtcNow)-(get-date "1/1/1970")).TotalSeconds }
|
||||
- function _fold_start_ { param( [string]$TEXT_TAG ) $t=_unix_tmsec_; $global:count += 1; Write-Host -NoNewLine "`r`n`r`nsection_start:${t}:sect_${count}`r${esc}[0K${esc}[33m${TEXT_TAG}${esc}[39m`r`n"; }
|
||||
- function _fold_final_ { $t=_unix_tmsec_; Write-Host -NoNewLine "`r`n`r`nsection_end:${t}:sect_${count}`r${esc}[0K`r`n" ; }
|
||||
|
||||
|
||||
- _fold_start_ 'configuring the msvc environment variables'
|
||||
- Push-Location "C:/Program Files (x86)/Microsoft Visual Studio/2019/BuildTools/VC/Auxiliary/Build"
|
||||
- '& cmd.exe /C "vcvarsall.bat x64 & set" | Foreach-Object { if ($_ -match "(.*?)=(.*)") { Set-Item -force -path "Env:\$($matches[1])" -value "$($matches[2])" } }'
|
||||
- Pop-Location
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'downloading precompiled versions of qtbase, qttools (for windeployqt) and jom (for a more parallel nmake)'
|
||||
- mkdir _qt
|
||||
- mkdir _qt_download
|
||||
- Push-Location _qt_download
|
||||
- curl.exe -LJ -o qt-base.7z 'https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win64_msvc2019_64/5.15.0-0-202005150700qtbase-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86_64.7z'
|
||||
- curl.exe -LJ -o qt-tools.7z 'https://download.qt.io/online/qtsdkrepository/windows_x86/desktop/qt5_5150/qt.qt5.5150.win64_msvc2019_64/5.15.0-0-202005150700qttools-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86_64.7z'
|
||||
- curl.exe -LJ -o qt-jom.zip 'https://download.qt.io/official_releases/jom/jom.zip'
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'extracting the downloaded qt binaries'
|
||||
- 7z x qt-base.7z '-o../_qt' -y
|
||||
- 7z x qt-tools.7z '-o../_qt' -y
|
||||
- 7z x qt-jom.zip '-o../_qt' -y
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'turn the qt install from enterprise to foss; remove the licensing checks'
|
||||
- ${qconfig-pri-folder} = '..\_qt\5.15.0\msvc2019_64\mkspecs\qconfig.pri'
|
||||
- (Get-Content ${qconfig-pri-folder}).replace('QT_EDITION = Enterprise', 'QT_EDITION = OpenSource') | Set-Content ${qconfig-pri-folder}
|
||||
- (Get-Content ${qconfig-pri-folder}).replace('QT_LICHECK = licheck.exe', '') | Set-Content ${qconfig-pri-folder}
|
||||
- Pop-Location
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'run qmake and generate the msvc nmake makefile'
|
||||
- mkdir _build; cd _build
|
||||
- ..\_qt\5.15.0\msvc2019_64\bin\qmake ..\OpenRGB.pro
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'start the actual build with jom instead of nmake; for speed'
|
||||
- ..\_qt\jom
|
||||
- _fold_final_
|
||||
|
||||
- _fold_start_ 'run windeployqt to automatically copy the needed dll files'
|
||||
- ..\_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_final_
|
||||
# cache:
|
||||
# key: same-key
|
||||
# paths:
|
||||
# - C:\vcpkg\installed\
|
||||
artifacts:
|
||||
paths:
|
||||
- _build/*.7z
|
||||
expire_in: 1337 years
|
||||
@@ -0,0 +1,262 @@
|
||||
#---------------------------------------------------------------#
|
||||
# OpenRGB udev rules #
|
||||
# #
|
||||
# Adam Honse (CalcProgrammer1) 5/29/2020 #
|
||||
#---------------------------------------------------------------#
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# User I2C/SMBus Access #
|
||||
#---------------------------------------------------------------#
|
||||
KERNEL=="i2c-[0-99]*", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# User hidraw Access #
|
||||
#---------------------------------------------------------------#
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# AMD Wraith Prism #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0051", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# ASUS Aura Core Devices #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1854", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1869", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1866", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# ASUS Aura USB Devices #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1867", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0b05", ATTR{idProduct}=="1872", TAG+="uaccess"
|
||||
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"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# Cooler Master Peripheral Devices #
|
||||
# #
|
||||
# Mousemats: #
|
||||
# Cooler Master MP750 #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="2516", ATTR{idProduct}=="0109", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# Corsair Lighting Node Devices #
|
||||
# #
|
||||
# Corsair Lighting Node Core #
|
||||
# Corsair Lighting Node Pro #
|
||||
# Corsair Commander Pro #
|
||||
# Corsair LS100 #
|
||||
# Corsair 1000D Obsidian #
|
||||
# Corsair Spec Omega RGB #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c1a", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c0b", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0c10", TAG+="uaccess"
|
||||
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"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# Corsair Peripheral Devices #
|
||||
# #
|
||||
# Keyboards: #
|
||||
# Corsair K55 RGB #
|
||||
# Corsair K65 RGB #
|
||||
# Corsair K65 RGB Lux #
|
||||
# Corsair K65 RGB Rapidfire #
|
||||
# Corsair K68 RGB #
|
||||
# Corsair K70 RGB #
|
||||
# Corsair K70 RGB Lux #
|
||||
# Corsair K70 RGB Rapidfire #
|
||||
# Corsair K70 RGB MK2 #
|
||||
# Corsair K70 RGB MK2 SE #
|
||||
# Corsair K70 RGB MK2 LP #
|
||||
# Corsair K95 RGB #
|
||||
# Corsair K95 Platinum #
|
||||
# Corsair Strafe #
|
||||
# Corsair Strafe MK2 #
|
||||
# #
|
||||
# Mice: #
|
||||
# Corsair M65 Pro #
|
||||
# Corsair M65 RGB Elite #
|
||||
# #
|
||||
# Mousemats: #
|
||||
# Corsair MM800 RGB Polaris #
|
||||
# #
|
||||
# Headset Stands: #
|
||||
# Corsair ST100 #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3d", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b17", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b37", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b39", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b4f", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b13", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b33", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b38", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b49", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b6b", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b55", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b11", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2d", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b20", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b48", TAG+="uaccess"
|
||||
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b2e", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b5a", TAG+="uaccess"
|
||||
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="1b3b", TAG+="uaccess"
|
||||
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1b1c", ATTR{idProduct}=="0a34", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# HyperX Peripheral Devices #
|
||||
# #
|
||||
# Keyboards: #
|
||||
# HyperX Alloy Elite #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0951", ATTR{idProduct}=="16be", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# Logitech Peripheral Devices #
|
||||
# #
|
||||
# Mice: #
|
||||
# Logitech G203 Prodigy #
|
||||
# Logitech G403 Prodigy #
|
||||
# Logitech G403 Hero #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c084", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c083", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c08f", 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}=="7B10", 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"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C34", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C35", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C36", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C37", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C42", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C56", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C59", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C60", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C67", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C70", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C71", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C73", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C75", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C76", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C77", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C79", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C80", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C81", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C82", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C83", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C84", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C85", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C86", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C87", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C88", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C89", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C90", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C91", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C92", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C94", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1462", ATTR{idProduct}=="7C95", TAG+="uaccess"
|
||||
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}=="905D", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# MSI/SteelSeries 3-Zone Laptop Keyboard #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1770", ATTR{idProduct}=="FF00", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# NZXT Hue 2 Devices #
|
||||
# #
|
||||
# NZXT Hue 2 #
|
||||
# NZXT Smart Device V2 #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2001", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="2006", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# NZXT Kraken #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="1e71", ATTR{idProduct}=="170e", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# Redragon Peripheral Devices #
|
||||
# #
|
||||
# Keyboards: #
|
||||
# Redragon K550 Yama #
|
||||
# Redragon K552 Kumara #
|
||||
# Redragon K556 Devarajas #
|
||||
# Tecware Phantom Elite #
|
||||
# #
|
||||
# Mice: #
|
||||
# Redragon M711 Cobra #
|
||||
# Redragon M715 Dagger #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="5204", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="5104", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="5004", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="0c45", ATTR{idProduct}=="652f", TAG+="uaccess"
|
||||
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc30", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="fc39", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# Gigabyte/Aorus RGB Fusion 2 USB #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="048d", ATTR{idProduct}=="8297", TAG+="uaccess"
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="048d", ATTR{idProduct}=="5702", TAG+="uaccess"
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# SteelSeries Peripheral Devices #
|
||||
# #
|
||||
# Mice: #
|
||||
# SteelSeries Rival 100 #
|
||||
# SteelSeries Rival 100 DotA 2 Edition #
|
||||
# SteelSeries Rival 105 #
|
||||
# SteelSeries Rival 110 #
|
||||
# SteelSeries Rival 300 #
|
||||
# Acer Predator Gaming Mouse (Rival 300) #
|
||||
# SteelSeries Rival 300 CS:GO Fade Edition #
|
||||
# SteelSeries Rival 300 CS:GO Fade Edition (stm32) #
|
||||
# SteelSeries Rival 300 CS:GO Hyperbeast Edition #
|
||||
# SteelSeries Rival 300 Dota 2 Edition #
|
||||
# SteelSeries Rival 300 HP Omen Edition #
|
||||
# Headsets: #
|
||||
# SteelSeries Siberia 350 #
|
||||
#---------------------------------------------------------------#
|
||||
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}=="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}=="1229", TAG+="uaccess"
|
||||
|
||||
|
||||
#---------------------------------------------------------------#
|
||||
# Thermaltake Poseidon Z RGB Keyboard #
|
||||
#---------------------------------------------------------------#
|
||||
SUBSYSTEMS=="usb", ATTR{idVendor}=="264a", ATTR{idProduct}=="3006", TAG+="uaccess"
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
AMDWraithPrismController::AMDWraithPrismController(libusb_device_handle* dev_handle)
|
||||
AMDWraithPrismController::AMDWraithPrismController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
@@ -49,6 +49,7 @@ std::string AMDWraithPrismController::GetEffectChannelString(unsigned char chann
|
||||
|
||||
unsigned char usb_buf[] =
|
||||
{
|
||||
0x00,
|
||||
0x40, 0x21, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
@@ -67,12 +68,10 @@ std::string AMDWraithPrismController::GetEffectChannelString(unsigned char chann
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
int actual;
|
||||
usb_buf[0x03] = channel;
|
||||
|
||||
usb_buf[0x02] = channel;
|
||||
|
||||
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
|
||||
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 64);
|
||||
|
||||
ret_string.append((char *)&usb_buf[0x08]);
|
||||
|
||||
@@ -85,6 +84,7 @@ std::string AMDWraithPrismController::GetFirmwareVersionString()
|
||||
|
||||
unsigned char usb_buf[] =
|
||||
{
|
||||
0x00,
|
||||
0x12, 0x20, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
@@ -103,11 +103,10 @@ std::string AMDWraithPrismController::GetFirmwareVersionString()
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
int actual;
|
||||
unsigned char fw_buf[16] = {0x00};
|
||||
|
||||
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
|
||||
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 64);
|
||||
|
||||
for(int char_idx = 0; char_idx < 16; char_idx+=2)
|
||||
{
|
||||
@@ -209,6 +208,7 @@ void AMDWraithPrismController::SendEnableCommand()
|
||||
{
|
||||
unsigned char usb_buf[] =
|
||||
{
|
||||
0x00,
|
||||
0x41, 0x80, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
@@ -227,16 +227,15 @@ void AMDWraithPrismController::SendEnableCommand()
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
int actual;
|
||||
|
||||
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
|
||||
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
void AMDWraithPrismController::SendApplyCommand()
|
||||
{
|
||||
unsigned char usb_buf[] =
|
||||
{
|
||||
0x00,
|
||||
0x51, 0x28, 0x00, 0x00,
|
||||
0xE0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
@@ -255,10 +254,8 @@ void AMDWraithPrismController::SendApplyCommand()
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
int actual;
|
||||
|
||||
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
|
||||
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
void AMDWraithPrismController::SendEffectChannelUpdate
|
||||
@@ -276,6 +273,7 @@ void AMDWraithPrismController::SendEffectChannelUpdate
|
||||
{
|
||||
unsigned char usb_buf[] =
|
||||
{
|
||||
0x00,
|
||||
0x51, 0x2C, 0x01, 0x00,
|
||||
0x05, 0xFF, 0x00, 0x01,
|
||||
0xFF, 0xFF, 0x00, 0xFF,
|
||||
@@ -294,27 +292,26 @@ void AMDWraithPrismController::SendEffectChannelUpdate
|
||||
0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
int actual;
|
||||
usb_buf[0x05] = effect_channel;
|
||||
usb_buf[0x06] = speed;
|
||||
usb_buf[0x07] = (direction ? 0x01 : 0x00) | (random_color ? 0x80 : 0x00);
|
||||
usb_buf[0x08] = mode;
|
||||
|
||||
usb_buf[0x04] = effect_channel;
|
||||
usb_buf[0x05] = speed;
|
||||
usb_buf[0x06] = (direction ? 0x01 : 0x00) | (random_color ? 0x80 : 0x00);
|
||||
usb_buf[0x07] = mode;
|
||||
usb_buf[0x0A] = brightness;
|
||||
|
||||
usb_buf[0x09] = brightness;
|
||||
usb_buf[0x0B] = red;
|
||||
usb_buf[0x0C] = green;
|
||||
usb_buf[0x0D] = blue;
|
||||
|
||||
usb_buf[0x0A] = red;
|
||||
usb_buf[0x0B] = green;
|
||||
usb_buf[0x0C] = blue;
|
||||
|
||||
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
|
||||
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
void AMDWraithPrismController::SendChannelRemap(unsigned char ring_channel, unsigned char logo_channel, unsigned char fan_channel)
|
||||
{
|
||||
unsigned char usb_buf[] =
|
||||
{
|
||||
0x00,
|
||||
0x51, 0xA0, 0x01, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00,
|
||||
0x05, 0x06, 0x07, 0x07,
|
||||
@@ -333,16 +330,14 @@ void AMDWraithPrismController::SendChannelRemap(unsigned char ring_channel, unsi
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
int actual;
|
||||
usb_buf[0x09] = logo_channel;
|
||||
usb_buf[0x0A] = fan_channel;
|
||||
|
||||
usb_buf[0x08] = logo_channel;
|
||||
usb_buf[0x09] = fan_channel;
|
||||
|
||||
for(int led = 0x0A; led <= 0x18; led++)
|
||||
for(int led = 0x0B; led <= 0x19; led++)
|
||||
{
|
||||
usb_buf[led] = ring_channel;
|
||||
}
|
||||
|
||||
libusb_interrupt_transfer(dev, 0x04, usb_buf, 64, &actual, 0);
|
||||
libusb_interrupt_transfer(dev, 0x83, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -109,7 +109,7 @@ enum
|
||||
class AMDWraithPrismController
|
||||
{
|
||||
public:
|
||||
AMDWraithPrismController(libusb_device_handle* dev_handle);
|
||||
AMDWraithPrismController(hid_device* dev_handle);
|
||||
~AMDWraithPrismController();
|
||||
|
||||
char* GetDeviceName();
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
|
||||
private:
|
||||
char device_name[32];
|
||||
libusb_device_handle* dev;
|
||||
hid_device* dev;
|
||||
|
||||
unsigned char current_fan_mode;
|
||||
unsigned char current_fan_speed;
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_AMDWraithPrism.h"
|
||||
#include <vector>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
|
||||
#include <hidapi/hidapi.h>
|
||||
#define AMD_WRAITH_PRISM_VID 0x2516
|
||||
#define AMD_WRAITH_PRISM_PID 0x0051
|
||||
|
||||
@@ -17,21 +16,36 @@
|
||||
|
||||
void DetectAMDWraithPrismControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
libusb_context * ctx;
|
||||
libusb_init(&ctx);
|
||||
hid_device_info* info;
|
||||
hid_device* dev = NULL;
|
||||
|
||||
hid_init();
|
||||
|
||||
info = hid_enumerate(AMD_WRAITH_PRISM_VID, AMD_WRAITH_PRISM_PID);
|
||||
|
||||
//Look for AMD Wraith Prism
|
||||
libusb_device_handle * dev = libusb_open_device_with_vid_pid(ctx, AMD_WRAITH_PRISM_VID, AMD_WRAITH_PRISM_PID);
|
||||
|
||||
if( dev )
|
||||
while(info)
|
||||
{
|
||||
libusb_detach_kernel_driver(dev, 1);
|
||||
libusb_claim_interface(dev, 1);
|
||||
if((info->vendor_id == AMD_WRAITH_PRISM_VID)
|
||||
&&(info->product_id == AMD_WRAITH_PRISM_PID)
|
||||
#if USE_HID_USAGE
|
||||
&&(info->interface_number == 1)
|
||||
&&(info->usage_page == 0xFF00))
|
||||
#else
|
||||
&&(info->interface_number == 1))
|
||||
#endif
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
AMDWraithPrismController* controller = new AMDWraithPrismController(dev);
|
||||
|
||||
AMDWraithPrismController* controller = new AMDWraithPrismController(dev);
|
||||
RGBController_AMDWraithPrism* rgb_controller = new RGBController_AMDWraithPrism(controller);
|
||||
|
||||
RGBController_AMDWraithPrism* rgb_controller = new RGBController_AMDWraithPrism(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,16 +14,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
||||
static void Sleep(unsigned int milliseconds)
|
||||
{
|
||||
usleep(1000 * milliseconds);
|
||||
}
|
||||
#endif
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| This list contains the available I2C addresses for Aura GPUs |
|
||||
@@ -88,7 +79,7 @@ void DetectAuraGPUControllers(std::vector<i2c_smbus_interface*> &busses, std::ve
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
}
|
||||
} /* DetectAuraGPUControllers() */
|
||||
@@ -6,21 +6,12 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
||||
static void Sleep(unsigned int milliseconds)
|
||||
{
|
||||
usleep(1000 * milliseconds);
|
||||
}
|
||||
#endif
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/*----------------------------------------------------------------------*\
|
||||
| This list contains the available SMBus addresses for mapping Aura RAM |
|
||||
\*----------------------------------------------------------------------*/
|
||||
#define AURA_RAM_ADDRESS_COUNT 22
|
||||
#define AURA_RAM_ADDRESS_COUNT 23
|
||||
|
||||
static const unsigned char aura_ram_addresses[] =
|
||||
{
|
||||
@@ -43,6 +34,7 @@ static const unsigned char aura_ram_addresses[] =
|
||||
0x66,
|
||||
0x67,
|
||||
0x39,
|
||||
0x3A,
|
||||
0x3B,
|
||||
0x3C,
|
||||
0x3D
|
||||
@@ -178,7 +170,7 @@ void DetectAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses, std::
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
|
||||
// Add Aura-enabled motherboard controllers
|
||||
@@ -191,7 +183,7 @@ void DetectAuraSMBusControllers(std::vector<i2c_smbus_interface*> &busses, std::
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,13 @@
|
||||
|
||||
AuraAddressableController::AuraAddressableController(hid_device* dev_handle) : AuraUSBController(dev_handle)
|
||||
{
|
||||
channel_count = config_table[2];
|
||||
/*-----------------------------------------------------*\
|
||||
| Add addressable devices |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int i = 0; i < config_table[0x02]; ++i)
|
||||
{
|
||||
device_info.push_back({0x01, (unsigned char)i, 0x01, AuraDeviceType::ADDRESSABLE});
|
||||
}
|
||||
}
|
||||
|
||||
AuraAddressableController::~AuraAddressableController()
|
||||
@@ -112,41 +118,6 @@ void AuraAddressableController::SendEffect
|
||||
hid_write(dev, usb_buf, 65);
|
||||
}
|
||||
|
||||
void AuraAddressableController::SendDirect
|
||||
(
|
||||
unsigned char device,
|
||||
unsigned char start_led,
|
||||
unsigned char led_count,
|
||||
unsigned char* led_data
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0xEC;
|
||||
usb_buf[0x01] = AURA_ADDRESSABLE_CONTROL_MODE_DIRECT;
|
||||
usb_buf[0x02] = device;
|
||||
usb_buf[0x03] = start_led;
|
||||
usb_buf[0x04] = led_count;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x05], led_data, led_count * 3);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
}
|
||||
|
||||
void AuraAddressableController::SendDirectApply
|
||||
(
|
||||
unsigned char channel
|
||||
@@ -163,7 +134,7 @@ void AuraAddressableController::SendDirectApply
|
||||
| Set up message packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0xEC;
|
||||
usb_buf[0x01] = AURA_ADDRESSABLE_CONTROL_MODE_DIRECT;
|
||||
usb_buf[0x01] = AURA_CONTROL_MODE_DIRECT;
|
||||
usb_buf[0x02] = 0x80 | channel;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
enum
|
||||
{
|
||||
AURA_ADDRESSABLE_CONTROL_MODE_EFFECT = 0x3B, /* Effect control mode */
|
||||
AURA_ADDRESSABLE_CONTROL_MODE_DIRECT = 0x40, /* Direct control mode */
|
||||
};
|
||||
|
||||
class AuraAddressableController : public AuraUSBController
|
||||
@@ -54,14 +53,6 @@ private:
|
||||
unsigned char blu
|
||||
);
|
||||
|
||||
void SendDirect
|
||||
(
|
||||
unsigned char device,
|
||||
unsigned char start_led,
|
||||
unsigned char led_count,
|
||||
unsigned char* led_data
|
||||
);
|
||||
|
||||
void SendDirectApply
|
||||
(
|
||||
unsigned char channel
|
||||
|
||||
@@ -12,7 +12,18 @@
|
||||
|
||||
AuraMainboardController::AuraMainboardController(hid_device* dev_handle) : AuraUSBController(dev_handle), mode(AURA_MODE_DIRECT)
|
||||
{
|
||||
channel_count = 5;
|
||||
/*-----------------------------------------------------*\
|
||||
| Add mainboard device |
|
||||
\*-----------------------------------------------------*/
|
||||
device_info.push_back({0x00, 0x04, config_table[0x1B], AuraDeviceType::FIXED});
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Add addressable devices |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int i = 0; i < config_table[0x02]; ++i)
|
||||
{
|
||||
device_info.push_back({0x01, (unsigned char)i, 0x01, AuraDeviceType::ADDRESSABLE});
|
||||
}
|
||||
}
|
||||
|
||||
AuraMainboardController::~AuraMainboardController()
|
||||
@@ -24,8 +35,6 @@ void AuraMainboardController::SetChannelLEDs(unsigned char channel, RGBColor * c
|
||||
unsigned char led_data[60];
|
||||
unsigned int leds_sent = 0;
|
||||
|
||||
SendEffect(channel, mode);
|
||||
|
||||
while(leds_sent < num_colors)
|
||||
{
|
||||
unsigned int leds_to_send = 20;
|
||||
@@ -44,10 +53,11 @@ void AuraMainboardController::SetChannelLEDs(unsigned char channel, RGBColor * c
|
||||
|
||||
SendDirect
|
||||
(
|
||||
channel,
|
||||
device_info[channel].direct_channel,
|
||||
leds_sent,
|
||||
leds_to_send,
|
||||
led_data
|
||||
led_data,
|
||||
leds_sent + leds_to_send >= num_colors
|
||||
);
|
||||
|
||||
leds_sent += leds_to_send;
|
||||
@@ -66,23 +76,38 @@ void AuraMainboardController::SetMode
|
||||
)
|
||||
{
|
||||
this->mode = mode;
|
||||
unsigned char led_data[3];
|
||||
led_data[0] = red;
|
||||
led_data[1] = grn;
|
||||
led_data[2] = blu;
|
||||
RGBColor color = ToRGBColor(red, grn, blu);
|
||||
|
||||
SendEffect
|
||||
SendEffect(device_info[channel].effect_channel, mode);
|
||||
if(mode == AURA_MODE_DIRECT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char led_data[60];
|
||||
unsigned char start_led = 0;
|
||||
|
||||
for(std::size_t i = 0; i < channel; ++i)
|
||||
{
|
||||
start_led += device_info[i].num_leds;
|
||||
}
|
||||
|
||||
for(std::size_t led_idx = 0; led_idx < device_info[channel].num_leds; led_idx++)
|
||||
{
|
||||
led_data[(led_idx * 3) + 0] = RGBGetRValue(color);
|
||||
led_data[(led_idx * 3) + 1] = RGBGetGValue(color);
|
||||
led_data[(led_idx * 3) + 2] = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
SendColor
|
||||
(
|
||||
channel,
|
||||
mode
|
||||
);
|
||||
SendDirect
|
||||
(
|
||||
channel,
|
||||
0,
|
||||
1,
|
||||
led_data
|
||||
start_led,
|
||||
device_info[channel].num_leds,
|
||||
led_data,
|
||||
device_info[channel].device_type == AuraDeviceType::FIXED
|
||||
);
|
||||
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
@@ -94,9 +119,6 @@ void AuraMainboardController::SendEffect
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
if(mode == AURA_MODE_DIRECT) {
|
||||
mode = AURA_MODE_STATIC;
|
||||
}
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
@@ -107,9 +129,9 @@ void AuraMainboardController::SendEffect
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0xEC;
|
||||
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_EFFECT;
|
||||
usb_buf[0x02] = 0x00;
|
||||
usb_buf[0x02] = channel;
|
||||
usb_buf[0x03] = 0x00;
|
||||
usb_buf[0x04] = channel;
|
||||
usb_buf[0x04] = 0x00;
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
@@ -118,12 +140,13 @@ void AuraMainboardController::SendEffect
|
||||
hid_write(dev, usb_buf, 65);
|
||||
}
|
||||
|
||||
void AuraMainboardController::SendDirect
|
||||
void AuraMainboardController::SendColor
|
||||
(
|
||||
unsigned char device,
|
||||
unsigned char channel,
|
||||
unsigned char start_led,
|
||||
unsigned char led_count,
|
||||
unsigned char* led_data
|
||||
unsigned char* led_data,
|
||||
bool fixed
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
@@ -137,15 +160,15 @@ void AuraMainboardController::SendDirect
|
||||
| Set up message packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0xEC;
|
||||
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_DIRECT;
|
||||
usb_buf[0x02] = start_led;
|
||||
usb_buf[0x03] = 0xff;
|
||||
usb_buf[0x01] = AURA_MAINBOARD_CONTROL_MODE_EFFECT_COLOR;
|
||||
usb_buf[0x02] = channel;
|
||||
usb_buf[0x03] = fixed ? 0xFF : 0x00;
|
||||
usb_buf[0x04] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x05], led_data, led_count * 3);
|
||||
memcpy(&usb_buf[0x05 + 3 * start_led], led_data, led_count * 3);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
enum
|
||||
{
|
||||
AURA_MAINBOARD_CONTROL_MODE_EFFECT = 0x35, /* Effect control mode */
|
||||
AURA_MAINBOARD_CONTROL_MODE_DIRECT = 0x36, /* Direct control mode */
|
||||
AURA_MAINBOARD_CONTROL_MODE_COMMIT = 0x3F, /* Direct control mode */
|
||||
AURA_MAINBOARD_CONTROL_MODE_EFFECT_COLOR = 0x36, /* Effect color control mode */
|
||||
AURA_MAINBOARD_CONTROL_MODE_COMMIT = 0x3F, /* Commit mode */
|
||||
};
|
||||
|
||||
class AuraMainboardController : public AuraUSBController
|
||||
@@ -53,12 +53,13 @@ private:
|
||||
unsigned char mode
|
||||
);
|
||||
|
||||
void SendDirect
|
||||
void SendColor
|
||||
(
|
||||
unsigned char device,
|
||||
unsigned char channel,
|
||||
unsigned char start_led,
|
||||
unsigned char led_count,
|
||||
unsigned char* led_data
|
||||
unsigned char* led_data,
|
||||
bool fixed
|
||||
);
|
||||
|
||||
void SendCommit();
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "AuraUSBController.h"
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
AuraUSBController::AuraUSBController(hid_device* dev_handle)
|
||||
{
|
||||
@@ -25,7 +26,7 @@ AuraUSBController::~AuraUSBController()
|
||||
|
||||
unsigned int AuraUSBController::GetChannelCount()
|
||||
{
|
||||
return( channel_count );
|
||||
return(device_info.size());
|
||||
}
|
||||
|
||||
std::string AuraUSBController::GetDeviceName()
|
||||
@@ -33,6 +34,11 @@ std::string AuraUSBController::GetDeviceName()
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
const std::vector<AuraDeviceInfo>& AuraUSBController::GetAuraDevices() const
|
||||
{
|
||||
return(device_info);
|
||||
}
|
||||
|
||||
void AuraUSBController::GetConfigTable()
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
@@ -71,6 +77,14 @@ void AuraUSBController::GetConfigTable()
|
||||
config_table[i + 5]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dev)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
throw std::runtime_error("Could not read config table");
|
||||
}
|
||||
}
|
||||
|
||||
void AuraUSBController::GetFirmwareVersion()
|
||||
@@ -102,3 +116,40 @@ void AuraUSBController::GetFirmwareVersion()
|
||||
memcpy(device_name, &usb_buf[2], 16);
|
||||
}
|
||||
}
|
||||
|
||||
void AuraUSBController::SendDirect
|
||||
(
|
||||
unsigned char device,
|
||||
unsigned char start_led,
|
||||
unsigned char led_count,
|
||||
unsigned char* led_data,
|
||||
bool apply /* = false */
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0xEC;
|
||||
usb_buf[0x01] = AURA_CONTROL_MODE_DIRECT;
|
||||
usb_buf[0x02] = apply ? 0x80 : 0x00;
|
||||
usb_buf[0x02] |= device;
|
||||
usb_buf[0x03] = start_led;
|
||||
usb_buf[0x04] = led_count;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x05], led_data, led_count * 3);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
@@ -38,6 +39,21 @@ enum
|
||||
{
|
||||
AURA_REQUEST_FIRMWARE_VERSION = 0x82, /* Request firmware string */
|
||||
AURA_REQUEST_CONFIG_TABLE = 0xB0, /* Request configuration table */
|
||||
AURA_CONTROL_MODE_DIRECT = 0x40, /* Direct control mode */
|
||||
};
|
||||
|
||||
enum class AuraDeviceType
|
||||
{
|
||||
FIXED,
|
||||
ADDRESSABLE,
|
||||
};
|
||||
|
||||
struct AuraDeviceInfo
|
||||
{
|
||||
unsigned char effect_channel;
|
||||
unsigned char direct_channel;
|
||||
unsigned char num_leds;
|
||||
AuraDeviceType device_type;
|
||||
};
|
||||
|
||||
class AuraUSBController
|
||||
@@ -50,6 +66,8 @@ public:
|
||||
|
||||
std::string GetDeviceName();
|
||||
|
||||
const std::vector<AuraDeviceInfo>& GetAuraDevices() const;
|
||||
|
||||
virtual void SetChannelLEDs
|
||||
(
|
||||
unsigned char channel,
|
||||
@@ -67,13 +85,21 @@ public:
|
||||
) = 0;
|
||||
|
||||
protected:
|
||||
hid_device* dev;
|
||||
unsigned int channel_count;
|
||||
unsigned char config_table[60];
|
||||
hid_device* dev;
|
||||
unsigned char config_table[60];
|
||||
std::vector<AuraDeviceInfo> device_info;
|
||||
|
||||
void SendDirect
|
||||
(
|
||||
unsigned char device,
|
||||
unsigned char start_led,
|
||||
unsigned char led_count,
|
||||
unsigned char* led_data,
|
||||
bool apply = false
|
||||
);
|
||||
private:
|
||||
char device_name[16];
|
||||
unsigned int led_count;
|
||||
char device_name[16];
|
||||
unsigned int led_count;
|
||||
|
||||
void GetConfigTable();
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_AuraUSB.h"
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define AURA_USB_VID 0x0B05
|
||||
@@ -16,10 +17,11 @@ static const unsigned short addressable_pid_table[] =
|
||||
0x18A3
|
||||
};
|
||||
|
||||
#define NUM_MAINBOARD_PIDS 1
|
||||
#define NUM_MAINBOARD_PIDS 2
|
||||
static const unsigned short mainboard_pid_table[] =
|
||||
{
|
||||
0x18f3
|
||||
0x18f3,
|
||||
0x1939
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
@@ -58,11 +60,18 @@ void DetectAuraUSBControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
|
||||
if( dev )
|
||||
{
|
||||
AuraMainboardController* controller = new AuraMainboardController(dev);
|
||||
try
|
||||
{
|
||||
AuraMainboardController* controller = new AuraMainboardController(dev);
|
||||
|
||||
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
|
||||
RGBController_AuraUSB* rgb_controller = new RGBController_AuraUSB(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
catch(std::runtime_error&)
|
||||
{
|
||||
// reading the config table failed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,33 +8,56 @@
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#include "CMMP750Controller.h"
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
CMMP750Controller::CMMP750Controller(libusb_device_handle* dev_handle, unsigned int _inAddr, unsigned int _outAddr, int _interface)
|
||||
CMMP750Controller::CMMP750Controller(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
inAddr = _inAddr;
|
||||
outAddr = _outAddr;
|
||||
interface = _interface;
|
||||
int tmp_size = wcslen(_vendor);
|
||||
dev = dev_handle;
|
||||
location = _path;
|
||||
|
||||
libusb_device* device = libusb_get_device(dev);
|
||||
int bus = libusb_get_bus_number(device);
|
||||
int bus_addr = libusb_get_device_address(device);
|
||||
int port = libusb_get_port_number(device);
|
||||
location = "Bus: " + std::to_string(bus) + " Addr: " + std::to_string(bus_addr) + " Port: " + std::to_string(port);
|
||||
for (int i=0; ( i<tmp_size && i<CM_DEVICE_NAME_SIZE); i++)
|
||||
{
|
||||
device_name[i] = (char)_vendor[i];
|
||||
}
|
||||
for (int j=0; ( j<wcslen(_vendor) && tmp_size+j<CM_DEVICE_NAME_SIZE); j++)
|
||||
device_name[tmp_size+j] = (char)_device_name[j];
|
||||
|
||||
strcpy(device_name, "Cooler Master MP750");
|
||||
|
||||
current_mode = MP750_MODE_STATIC;
|
||||
current_speed = MP750_SPEED_NORMAL;
|
||||
GetStatus(); //When setting up device get current status
|
||||
}
|
||||
|
||||
CMMP750Controller::~CMMP750Controller()
|
||||
{
|
||||
libusb_release_interface(dev, interface);
|
||||
libusb_attach_kernel_driver(dev, interface);
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
void CMMP750Controller::GetStatus()
|
||||
{
|
||||
unsigned char buffer[0x40] = { 0x00 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
buffer[0] = 0x07;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
hid_read(dev, buffer, buffer_size);
|
||||
|
||||
if( buffer[0] == 0x80 && buffer[1] == 0x05 )
|
||||
{
|
||||
current_mode = buffer[2] - 1;
|
||||
current_red = buffer[3];
|
||||
current_green = buffer[4];
|
||||
current_blue = buffer[5];
|
||||
|
||||
for( int i = 0; speed_mode_data[current_mode][i] >= buffer[6]; i++)
|
||||
current_speed = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
//Code should never reach here however just in case there is a failure set something
|
||||
current_mode = MP750_MODE_COLOR_CYCLE; //Unicorn Spew
|
||||
current_red = 0xFF;
|
||||
current_green = 0xFF;
|
||||
current_blue = 0xFF;
|
||||
current_speed = MP750_SPEED_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
char* CMMP750Controller::GetDeviceName()
|
||||
@@ -52,6 +75,31 @@ std::string CMMP750Controller::GetLocation()
|
||||
return location;
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetMode()
|
||||
{
|
||||
return current_mode;
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetLedRed()
|
||||
{
|
||||
return current_red;
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetLedGreen()
|
||||
{
|
||||
return current_green;
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetLedBlue()
|
||||
{
|
||||
return current_blue;
|
||||
}
|
||||
|
||||
unsigned char CMMP750Controller::GetLedSpeed()
|
||||
{
|
||||
return current_speed;
|
||||
}
|
||||
|
||||
void CMMP750Controller::SetMode(unsigned char mode, unsigned char speed)
|
||||
{
|
||||
current_mode = mode;
|
||||
@@ -71,7 +119,6 @@ void CMMP750Controller::SetColor(unsigned char red, unsigned char green, unsigne
|
||||
|
||||
void CMMP750Controller::SendUpdate()
|
||||
{
|
||||
int actual = 0;
|
||||
unsigned char buffer[0x40] = { 0x00 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
|
||||
@@ -94,7 +141,5 @@ void CMMP750Controller::SendUpdate()
|
||||
buffer[CM_SPEED_BYTE] = speed_mode_data[current_mode][current_speed];
|
||||
}
|
||||
|
||||
//Nothing will be done with the "actual" transfer length
|
||||
libusb_interrupt_transfer(dev, outAddr, buffer, buffer_size, nullptr, CM_INTERRUPT_TIMEOUT);
|
||||
}
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
}
|
||||
@@ -16,12 +16,15 @@
|
||||
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
#define CM_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data) / sizeof(colour_mode_data[0]))
|
||||
#define CM_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
|
||||
#define CM_INTERRUPT_TIMEOUT 250
|
||||
#define CM_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
|
||||
#define CM_SERIAL_SIZE (sizeof(serial) / sizeof(serial[ 0 ]))
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -53,10 +56,10 @@ static unsigned char colour_mode_data[][6] =
|
||||
static unsigned char speed_mode_data[][9] =
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },/* Static */
|
||||
{ 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, 0xFF },/* Blinking */
|
||||
{ 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, 0xFF },/* Breathing */
|
||||
{ 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, 0xFF },/* Colour Cycle */
|
||||
{ 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, 0xFF } /* Colour Breath */
|
||||
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 },/* Blinking */
|
||||
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 },/* Breathing */
|
||||
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 },/* Colour Cycle */
|
||||
{ 0xFF, 0xE0, 0xC0, 0xA0, 0x80, 0x60, 0x40, 0x20, 0x00 } /* Colour Breath */
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -75,13 +78,18 @@ enum
|
||||
class CMMP750Controller
|
||||
{
|
||||
public:
|
||||
CMMP750Controller(libusb_device_handle *dev_handle, unsigned int _inAddr, unsigned int _outAddr, int _interface);
|
||||
CMMP750Controller(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path);
|
||||
~CMMP750Controller();
|
||||
|
||||
char* GetDeviceName();
|
||||
char* GetSerial();
|
||||
std::string GetLocation();
|
||||
|
||||
unsigned char GetMode();
|
||||
unsigned char GetLedRed();
|
||||
unsigned char GetLedGreen();
|
||||
unsigned char GetLedBlue();
|
||||
unsigned char GetLedSpeed();
|
||||
void SetMode(unsigned char mode, unsigned char speed);
|
||||
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
@@ -89,10 +97,7 @@ private:
|
||||
char device_name[32];
|
||||
char serial[32];
|
||||
std::string location;
|
||||
libusb_device_handle* dev;
|
||||
unsigned char inAddr;
|
||||
unsigned char outAddr;
|
||||
int interface;
|
||||
hid_device* dev;
|
||||
|
||||
unsigned char current_mode;
|
||||
unsigned char current_speed;
|
||||
@@ -101,5 +106,6 @@ private:
|
||||
unsigned char current_green;
|
||||
unsigned char current_blue;
|
||||
|
||||
void GetStatus();
|
||||
void SendUpdate();
|
||||
};
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
#include "CMMP750Controller.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_CMMP750Controller.h"
|
||||
#include <vector>
|
||||
#include <libusb-1.0/libusb.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_NUM_DEVICES (sizeof(cm_pids) / sizeof(cm_pids[ 0 ]))
|
||||
|
||||
enum
|
||||
{
|
||||
CM_PID = 0,
|
||||
CM_INADDR = 1,
|
||||
CM_OUTADDR = 2,
|
||||
CM_INTERFACE = 3
|
||||
CM_INTERFACE = 1
|
||||
};
|
||||
|
||||
static const unsigned int cm_pids[][4] =
|
||||
{ //PID, inAddr, outAddr, interface
|
||||
{ 0x0109, 0x82, 0x03, 0x00 } //Coolermaster MP750
|
||||
{ // PID, Interface
|
||||
{ COOLERMASTER_MP750_XL_PID, 0x00 }, //Coolermaster MP750 (Extra Large)
|
||||
{ COOLERMASTER_MP750_MEDIUM_PID, 0x00 } //Coolermaster MP750 (Medium)
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
@@ -31,27 +32,35 @@ static const unsigned int cm_pids[][4] =
|
||||
|
||||
void DetectCoolerMasterControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
libusb_context * context;
|
||||
libusb_init(&context);
|
||||
hid_device_info* info;
|
||||
|
||||
for(int cm_pid_idx = 0; cm_pid_idx < COOLERMASTER_NUM_DEVICES; cm_pid_idx++)
|
||||
//Look for the passed in cm_pids
|
||||
hid_init();
|
||||
info = hid_enumerate(COOLERMASTER_VID, 0x0);
|
||||
|
||||
while(info)
|
||||
{
|
||||
//Look for the passed in cm_pids
|
||||
libusb_device_handle * dev = libusb_open_device_with_vid_pid(context, COOLERMASTER_VID, cm_pids[cm_pid_idx][CM_PID]);
|
||||
hid_device* dev = NULL;
|
||||
if(info->vendor_id == COOLERMASTER_VID)
|
||||
{
|
||||
for(int cm_pid_idx = 0; cm_pid_idx < COOLERMASTER_NUM_DEVICES; cm_pid_idx++)
|
||||
{
|
||||
if((info->product_id == cm_pids[cm_pid_idx][CM_PID])
|
||||
&&(info->interface_number == cm_pids[cm_pid_idx][CM_INTERFACE]))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(dev)
|
||||
{
|
||||
int status = libusb_detach_kernel_driver(dev, cm_pids[cm_pid_idx][CM_INTERFACE]);
|
||||
status = libusb_claim_interface(dev, cm_pids[cm_pid_idx][CM_INTERFACE]);
|
||||
|
||||
if(status == 0)
|
||||
{
|
||||
// Success: Device has been claimed
|
||||
CMMP750Controller* controller = new CMMP750Controller(dev, cm_pids[cm_pid_idx][CM_INADDR], cm_pids[cm_pid_idx][CM_OUTADDR], cm_pids[cm_pid_idx][CM_INTERFACE]);
|
||||
RGBController_CMMP750Controller* rgb_controller = new RGBController_CMMP750Controller(controller);
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
CMMP750Controller* controller = new CMMP750Controller(dev, info->manufacturer_string, info->product_string, info->path);
|
||||
RGBController_CMMP750Controller* rgb_controller = new RGBController_CMMP750Controller(controller);
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
|
||||
hid_free_enumeration(info);
|
||||
}
|
||||
|
||||
@@ -28,16 +28,7 @@
|
||||
#define THREADRETURN return(NULL);
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
||||
static void Sleep(unsigned int milliseconds)
|
||||
{
|
||||
usleep(1000 * milliseconds);
|
||||
}
|
||||
#endif
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
THREAD keepalive_thread(void *param)
|
||||
{
|
||||
@@ -46,10 +37,9 @@ THREAD keepalive_thread(void *param)
|
||||
THREADRETURN
|
||||
}
|
||||
|
||||
CorsairLightingNodeController::CorsairLightingNodeController(libusb_device_handle* dev_handle, unsigned int dev_endpoint)
|
||||
CorsairLightingNodeController::CorsairLightingNodeController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
endpoint = dev_endpoint;
|
||||
|
||||
SendFirmwareRequest();
|
||||
|
||||
@@ -75,8 +65,11 @@ void CorsairLightingNodeController::KeepaliveThread()
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
SendCommit();
|
||||
Sleep(5000);
|
||||
if((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::seconds(5))
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
std::this_thread::sleep_for(1s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,7 +198,7 @@ void CorsairLightingNodeController::SetChannelLEDs(unsigned char channel, RGBCol
|
||||
void CorsairLightingNodeController::SendFirmwareRequest()
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[64];
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -215,13 +208,14 @@ void CorsairLightingNodeController::SendFirmwareRequest()
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Firmware Version Request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_FIRMWARE;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
libusb_interrupt_transfer(dev, endpoint, usb_buf, 64, &actual, 0);
|
||||
libusb_interrupt_transfer(dev, 0x80 + endpoint, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
actual = hid_read(dev, usb_buf, 17);
|
||||
|
||||
if(actual > 0)
|
||||
{
|
||||
@@ -238,8 +232,7 @@ void CorsairLightingNodeController::SendDirect
|
||||
unsigned char* color_data
|
||||
)
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[64];
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -249,43 +242,51 @@ void CorsairLightingNodeController::SendDirect
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Direct packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_DIRECT;
|
||||
usb_buf[0x01] = channel;
|
||||
usb_buf[0x02] = start;
|
||||
usb_buf[0x03] = count;
|
||||
usb_buf[0x04] = color_channel;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_DIRECT;
|
||||
usb_buf[0x02] = channel;
|
||||
usb_buf[0x03] = start;
|
||||
usb_buf[0x04] = count;
|
||||
usb_buf[0x05] = color_channel;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x05], color_data, count);
|
||||
memcpy(&usb_buf[0x06], color_data, count);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
libusb_interrupt_transfer(dev, endpoint, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendCommit()
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[64];
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Update last commit time |
|
||||
\*-----------------------------------------------------*/
|
||||
last_commit_time = std::chrono::steady_clock::now();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Commit packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_COMMIT;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_COMMIT;
|
||||
usb_buf[0x02] = 0xFF;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
libusb_interrupt_transfer(dev, endpoint, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendBegin
|
||||
@@ -293,8 +294,7 @@ void CorsairLightingNodeController::SendBegin
|
||||
unsigned char channel
|
||||
)
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[64];
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -304,13 +304,15 @@ void CorsairLightingNodeController::SendBegin
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Begin packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_BEGIN;
|
||||
usb_buf[0x01] = channel;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_BEGIN;
|
||||
usb_buf[0x02] = channel;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
libusb_interrupt_transfer(dev, endpoint, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendEffectConfig
|
||||
@@ -336,8 +338,7 @@ void CorsairLightingNodeController::SendEffectConfig
|
||||
unsigned short temperature_2
|
||||
)
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[64];
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -347,47 +348,49 @@ void CorsairLightingNodeController::SendEffectConfig
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Effect Config packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_EFFECT_CONFIG;
|
||||
usb_buf[0x01] = channel;
|
||||
usb_buf[0x02] = count * 10;
|
||||
usb_buf[0x03] = led_type;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_EFFECT_CONFIG;
|
||||
usb_buf[0x02] = channel;
|
||||
usb_buf[0x03] = count;
|
||||
usb_buf[0x04] = led_type;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up mode parameters |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x04] = mode;
|
||||
usb_buf[0x05] = speed;
|
||||
usb_buf[0x06] = direction;
|
||||
usb_buf[0x07] = change_style;
|
||||
usb_buf[0x08] = 0;
|
||||
usb_buf[0x05] = mode;
|
||||
usb_buf[0x06] = speed;
|
||||
usb_buf[0x07] = direction;
|
||||
usb_buf[0x08] = change_style;
|
||||
usb_buf[0x09] = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up mode colors |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x09] = color_0_red;
|
||||
usb_buf[0x10] = color_0_green;
|
||||
usb_buf[0x11] = color_0_blue;
|
||||
usb_buf[0x12] = color_1_red;
|
||||
usb_buf[0x13] = color_1_green;
|
||||
usb_buf[0x14] = color_1_blue;
|
||||
usb_buf[0x15] = color_2_red;
|
||||
usb_buf[0x16] = color_2_green;
|
||||
usb_buf[0x17] = color_2_blue;
|
||||
usb_buf[0x0A] = color_0_red;
|
||||
usb_buf[0x0B] = color_0_green;
|
||||
usb_buf[0x0C] = color_0_blue;
|
||||
usb_buf[0x0D] = color_1_red;
|
||||
usb_buf[0x0E] = color_1_green;
|
||||
usb_buf[0x0F] = color_1_blue;
|
||||
usb_buf[0x10] = color_2_red;
|
||||
usb_buf[0x11] = color_2_green;
|
||||
usb_buf[0x12] = color_2_blue;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up temperatures |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x12] = (temperature_0 >> 8);
|
||||
usb_buf[0x13] = (temperature_0 & 0xFF);
|
||||
usb_buf[0x14] = (temperature_1 >> 8);
|
||||
usb_buf[0x15] = (temperature_1 & 0xFF);
|
||||
usb_buf[0x16] = (temperature_2 >> 8);
|
||||
usb_buf[0x17] = (temperature_2 & 0xFF);
|
||||
usb_buf[0x13] = (temperature_0 >> 8);
|
||||
usb_buf[0x14] = (temperature_0 & 0xFF);
|
||||
usb_buf[0x15] = (temperature_1 >> 8);
|
||||
usb_buf[0x16] = (temperature_1 & 0xFF);
|
||||
usb_buf[0x17] = (temperature_2 >> 8);
|
||||
usb_buf[0x18] = (temperature_2 & 0xFF);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
libusb_interrupt_transfer(dev, endpoint, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendTemperature()
|
||||
@@ -400,8 +403,7 @@ void CorsairLightingNodeController::SendReset
|
||||
unsigned char channel
|
||||
)
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[64];
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -411,13 +413,15 @@ void CorsairLightingNodeController::SendReset
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Reset packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_RESET;
|
||||
usb_buf[0x01] = channel;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_RESET;
|
||||
usb_buf[0x02] = channel;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
libusb_interrupt_transfer(dev, endpoint, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendPortState
|
||||
@@ -426,8 +430,7 @@ void CorsairLightingNodeController::SendPortState
|
||||
unsigned char state
|
||||
)
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[64];
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -437,14 +440,16 @@ void CorsairLightingNodeController::SendPortState
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Port State packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_LIGHTING_NODE_PACKET_ID_PORT_STATE;
|
||||
usb_buf[0x01] = channel;
|
||||
usb_buf[0x02] = state;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_LIGHTING_NODE_PACKET_ID_PORT_STATE;
|
||||
usb_buf[0x02] = channel;
|
||||
usb_buf[0x03] = state;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
libusb_interrupt_transfer(dev, endpoint, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 17);
|
||||
}
|
||||
|
||||
void CorsairLightingNodeController::SendBrightness()
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -78,7 +79,7 @@ enum
|
||||
class CorsairLightingNodeController
|
||||
{
|
||||
public:
|
||||
CorsairLightingNodeController(libusb_device_handle* dev_handle, unsigned int dev_endpoint);
|
||||
CorsairLightingNodeController(hid_device* dev_handle);
|
||||
~CorsairLightingNodeController();
|
||||
|
||||
std::string GetFirmwareString();
|
||||
@@ -107,9 +108,9 @@ public:
|
||||
void KeepaliveThread();
|
||||
|
||||
private:
|
||||
libusb_device_handle* dev;
|
||||
unsigned int endpoint;
|
||||
hid_device* dev;
|
||||
std::string firmware_version;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_commit_time;
|
||||
|
||||
void SendFirmwareRequest();
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_CorsairLightingNode.h"
|
||||
#include <vector>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define CORSAIR_VID 0x1B1C
|
||||
#define CORSAIR_LIGHTING_NODE_CORE_PID 0x0C1A
|
||||
@@ -16,20 +16,20 @@ typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned char usb_endpoint;
|
||||
unsigned char channel_count;
|
||||
const char * name;
|
||||
} corsair_node_device;
|
||||
|
||||
static const corsair_node_device device_list[6] =
|
||||
{
|
||||
{ CORSAIR_VID, CORSAIR_LIGHTING_NODE_CORE_PID, 1, 1, "Corsair Lighting Node Core" },
|
||||
{ CORSAIR_VID, CORSAIR_LIGHTING_NODE_PRO_PID, 1, 2, "Corsair Lighting Node Pro" },
|
||||
{ CORSAIR_VID, CORSAIR_COMMANDER_PRO_PID, 2, 2, "Corsair Commander Pro" },
|
||||
{ CORSAIR_VID, CORSAIR_LS100_PID, 1, 1, "Corsair LS100 Lighting Kit" },
|
||||
{ CORSAIR_VID, CORSAIR_1000D_OBSIDIAN_PID, 2, 2, "Corsair 1000D Obsidian" },
|
||||
{ CORSAIR_VID, CORSAIR_SPEC_OMEGA_RGB_PID, 1, 2, "Corsair SPEC OMEGA RGB" }
|
||||
#define CORSAIR_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const corsair_node_device device_list[] =
|
||||
{
|
||||
{ CORSAIR_VID, CORSAIR_LIGHTING_NODE_CORE_PID, 1, "Corsair Lighting Node Core" },
|
||||
{ CORSAIR_VID, CORSAIR_LIGHTING_NODE_PRO_PID, 2, "Corsair Lighting Node Pro" },
|
||||
{ CORSAIR_VID, CORSAIR_COMMANDER_PRO_PID, 2, "Corsair Commander Pro" },
|
||||
{ CORSAIR_VID, CORSAIR_LS100_PID, 1, "Corsair LS100 Lighting Kit" },
|
||||
{ CORSAIR_VID, CORSAIR_1000D_OBSIDIAN_PID, 2, "Corsair 1000D Obsidian" },
|
||||
{ CORSAIR_VID, CORSAIR_SPEC_OMEGA_RGB_PID, 2, "Corsair SPEC OMEGA RGB" }
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
@@ -37,31 +37,43 @@ static const corsair_node_device device_list[6] =
|
||||
* DetectCorsairLightingNodeControllers *
|
||||
* *
|
||||
* Detect devices supported by the Corsair Lighting Node Pro driver *
|
||||
* * *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectCorsairLightingNodeControllers(std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
libusb_context * ctx;
|
||||
libusb_init(&ctx);
|
||||
hid_device_info* info;
|
||||
hid_device* dev;
|
||||
|
||||
for(int device_idx = 0; device_idx < 6; device_idx++)
|
||||
hid_init();
|
||||
|
||||
for(std::size_t device_idx = 0; device_idx < CORSAIR_NUM_DEVICES; device_idx++)
|
||||
{
|
||||
//Look for Corsair Lighting Node Device
|
||||
libusb_device_handle * dev = libusb_open_device_with_vid_pid(ctx, device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
dev = NULL;
|
||||
|
||||
if( dev )
|
||||
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
//Look for Corsair Lighting Node Devices
|
||||
while(info)
|
||||
{
|
||||
libusb_detach_kernel_driver(dev, 0);
|
||||
libusb_claim_interface(dev, 0);
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
CorsairLightingNodeController* controller = new CorsairLightingNodeController(dev, device_list[device_idx].usb_endpoint);
|
||||
if( dev )
|
||||
{
|
||||
CorsairLightingNodeController* controller = new CorsairLightingNodeController(dev);
|
||||
|
||||
RGBController_CorsairLightingNode* rgb_controller = new RGBController_CorsairLightingNode(controller);
|
||||
RGBController_CorsairLightingNode* rgb_controller = new RGBController_CorsairLightingNode(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
} /* DetectCorsairLightingNodeControllers() */
|
||||
|
||||
@@ -11,16 +11,7 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
||||
static void Sleep(unsigned int milliseconds)
|
||||
{
|
||||
usleep(1000 * milliseconds);
|
||||
}
|
||||
#endif
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
static unsigned int keys[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12,
|
||||
0x14, 0x15, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x24, 0x25, 0x26,
|
||||
@@ -31,19 +22,7 @@ static unsigned int keys[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x
|
||||
116, 117, 120, 121, 122, 123, 124, 126, 127, 128, 129, 132, 133, 134, 135,
|
||||
136, 137, 139, 140, 141};
|
||||
|
||||
static void send_usb_msg(hid_device* dev, char * data_pkt)
|
||||
{
|
||||
char usb_pkt[65];
|
||||
usb_pkt[0] = 0x00;
|
||||
for(int i = 1; i < 65; i++)
|
||||
{
|
||||
usb_pkt[i] = data_pkt[i-1];
|
||||
}
|
||||
int bytes = hid_send_feature_report(dev, (unsigned char *)usb_pkt, 65);
|
||||
bytes++;
|
||||
|
||||
Sleep(2);
|
||||
}
|
||||
static unsigned int st100[] = { 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x04 };
|
||||
|
||||
CorsairPeripheralController::CorsairPeripheralController(hid_device* dev_handle)
|
||||
{
|
||||
@@ -51,7 +30,6 @@ CorsairPeripheralController::CorsairPeripheralController(hid_device* dev_handle)
|
||||
|
||||
ReadFirmwareInfo();
|
||||
|
||||
SpecialFunctionControl();
|
||||
LightingControl();
|
||||
}
|
||||
|
||||
@@ -85,6 +63,26 @@ void CorsairPeripheralController::SetLEDs(std::vector<RGBColor>colors)
|
||||
case DEVICE_TYPE_MOUSEMAT:
|
||||
SetLEDsMousemat(colors);
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_HEADSET_STAND:
|
||||
/*-----------------------------------------------------*\
|
||||
| The logo zone of the ST100 is in the middle of the |
|
||||
| base LED strip, so remap the colors so that the logo |
|
||||
| is the last LED in the sequence. |
|
||||
\*-----------------------------------------------------*/
|
||||
std::vector<RGBColor> remap_colors;
|
||||
remap_colors.resize(colors.size());
|
||||
|
||||
for(int i = 0; i < 9; i++)
|
||||
{
|
||||
remap_colors[st100[i]] = colors[i];
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The ST100 uses the mousemat protocol |
|
||||
\*-----------------------------------------------------*/
|
||||
SetLEDsMousemat(remap_colors);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,7 +218,7 @@ void CorsairPeripheralController::SetLEDsKeyboardLimited(std::vector<RGBColor> c
|
||||
|
||||
void CorsairPeripheralController::LightingControl()
|
||||
{
|
||||
char usb_buf[64];
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -230,39 +228,44 @@ void CorsairPeripheralController::LightingControl()
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x01] = CORSAIR_PROPERTY_LIGHTING_CONTROL;
|
||||
usb_buf[0x02] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_LIGHTING_CONTROL;
|
||||
usb_buf[0x03] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Lighting control byte needs to be 3 for keyboards, 1 |
|
||||
| for mice and mousepads |
|
||||
| Lighting control byte needs to be 3 for keyboards and |
|
||||
| headset stand, 1 for mice and mousepads |
|
||||
\*-----------------------------------------------------*/
|
||||
switch(type)
|
||||
{
|
||||
default:
|
||||
case DEVICE_TYPE_KEYBOARD:
|
||||
usb_buf[0x04] = 0x03;
|
||||
usb_buf[0x05] = 0x03;
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_MOUSE:
|
||||
usb_buf[0x04] = 0x01;
|
||||
usb_buf[0x05] = 0x01;
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_MOUSEMAT:
|
||||
usb_buf[0x04] = 0x04;
|
||||
usb_buf[0x05] = 0x04;
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_HEADSET_STAND:
|
||||
usb_buf[0x05] = 0x03;
|
||||
break;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
send_usb_msg(dev, usb_buf);
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SpecialFunctionControl()
|
||||
{
|
||||
char usb_buf[64];
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -272,19 +275,22 @@ void CorsairPeripheralController::SpecialFunctionControl()
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x01] = CORSAIR_PROPERTY_SPECIAL_FUNCTION;
|
||||
usb_buf[0x02] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_SPECIAL_FUNCTION;
|
||||
usb_buf[0x03] = CORSAIR_LIGHTING_CONTROL_SOFTWARE;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
send_usb_msg(dev, usb_buf);
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::ReadFirmwareInfo()
|
||||
{
|
||||
char usb_buf[64];
|
||||
int actual;
|
||||
char usb_buf[65];
|
||||
char offset = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -294,22 +300,44 @@ void CorsairPeripheralController::ReadFirmwareInfo()
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Read Firmware Info packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_COMMAND_READ;
|
||||
usb_buf[0x01] = CORSAIR_PROPERTY_FIRMWARE_INFO;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_READ;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
| Send packet and try reading it using an HID read |
|
||||
| If that fails, repeat the send and read the reply as |
|
||||
| a feature report. |
|
||||
\*-----------------------------------------------------*/
|
||||
send_usb_msg(dev, usb_buf);
|
||||
hid_get_feature_report(dev, (unsigned char*)usb_buf, 64);
|
||||
hid_write(dev, (unsigned char*)usb_buf, 65);
|
||||
actual = hid_read_timeout(dev, (unsigned char*)usb_buf, 65, 1000);
|
||||
|
||||
if(actual == 0)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Set up Read Firmware Info packet |
|
||||
\*-------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_READ;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
|
||||
|
||||
hid_send_feature_report(dev, (unsigned char*)usb_buf, 65);
|
||||
actual = hid_get_feature_report(dev, (unsigned char*)usb_buf, 65);
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get device type |
|
||||
| 0xC0 Device is a keyboard |
|
||||
| 0xC1 Device is a mouse |
|
||||
| 0xC2 Device is a mousepad |
|
||||
| 0xC2 Device is a mousepad or headset stand |
|
||||
\*-----------------------------------------------------*/
|
||||
switch((unsigned char)usb_buf[0x14])
|
||||
switch((unsigned char)usb_buf[0x14 + offset])
|
||||
{
|
||||
case 0xC0:
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
@@ -317,10 +345,26 @@ void CorsairPeripheralController::ReadFirmwareInfo()
|
||||
|
||||
case 0xC1:
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
SpecialFunctionControl();
|
||||
break;
|
||||
|
||||
case 0xC2:
|
||||
type = DEVICE_TYPE_MOUSEMAT;
|
||||
{
|
||||
unsigned short pid = (unsigned short)(usb_buf[0x0F] << 8) + (unsigned char)(usb_buf[0x0E]);
|
||||
|
||||
switch(pid)
|
||||
{
|
||||
case 0x0A34:
|
||||
type = DEVICE_TYPE_HEADSET_STAND;
|
||||
SpecialFunctionControl();
|
||||
break;
|
||||
|
||||
default:
|
||||
type = DEVICE_TYPE_MOUSEMAT;
|
||||
SpecialFunctionControl();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -333,7 +377,7 @@ void CorsairPeripheralController::ReadFirmwareInfo()
|
||||
\*-----------------------------------------------------*/
|
||||
if(type != DEVICE_TYPE_UNKNOWN)
|
||||
{
|
||||
firmware_version = std::to_string(usb_buf[0x09]) + "." + std::to_string(usb_buf[0x08]);
|
||||
firmware_version = std::to_string(usb_buf[0x09 + offset]) + "." + std::to_string(usb_buf[0x08 + offset]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,7 +388,7 @@ void CorsairPeripheralController::StreamPacket
|
||||
unsigned char* data_ptr
|
||||
)
|
||||
{
|
||||
char usb_buf[64];
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -354,19 +398,20 @@ void CorsairPeripheralController::StreamPacket
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Stream packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_COMMAND_STREAM;
|
||||
usb_buf[0x01] = packet_id;
|
||||
usb_buf[0x02] = data_sz;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_STREAM;
|
||||
usb_buf[0x02] = packet_id;
|
||||
usb_buf[0x03] = data_sz;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x04], data_ptr, data_sz);
|
||||
memcpy(&usb_buf[0x05], data_ptr, data_sz);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
send_usb_msg(dev, usb_buf);
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SubmitKeyboardFullColors
|
||||
@@ -376,7 +421,7 @@ void CorsairPeripheralController::SubmitKeyboardFullColors
|
||||
unsigned char finish_val
|
||||
)
|
||||
{
|
||||
char usb_buf[64];
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -386,16 +431,17 @@ void CorsairPeripheralController::SubmitKeyboardFullColors
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Submit Keyboard 24-Bit Colors packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x01] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_24;
|
||||
usb_buf[0x02] = color_channel;
|
||||
usb_buf[0x03] = packet_count;
|
||||
usb_buf[0x04] = finish_val;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_24;
|
||||
usb_buf[0x03] = color_channel;
|
||||
usb_buf[0x04] = packet_count;
|
||||
usb_buf[0x05] = finish_val;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
send_usb_msg(dev, usb_buf);
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SubmitKeyboardLimitedColors
|
||||
@@ -403,7 +449,7 @@ void CorsairPeripheralController::SubmitKeyboardLimitedColors
|
||||
unsigned char byte_count
|
||||
)
|
||||
{
|
||||
char usb_buf[64];
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -413,14 +459,15 @@ void CorsairPeripheralController::SubmitKeyboardLimitedColors
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Submit Keyboard 9-Bit Colors packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x01] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_9;
|
||||
usb_buf[0x04] = byte_count;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_KEYBOARD_COLOR_9;
|
||||
usb_buf[0x05] = byte_count;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
send_usb_msg(dev, usb_buf);
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SubmitMouseColors
|
||||
@@ -429,7 +476,7 @@ void CorsairPeripheralController::SubmitMouseColors
|
||||
RGBColor * color_data
|
||||
)
|
||||
{
|
||||
char usb_buf[64];
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -439,26 +486,27 @@ void CorsairPeripheralController::SubmitMouseColors
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Submit Mouse Colors packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x01] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
|
||||
usb_buf[0x02] = num_zones;
|
||||
usb_buf[0x03] = 0x00;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
|
||||
usb_buf[0x03] = num_zones;
|
||||
usb_buf[0x04] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in colors in <ZONE> <RED> <GREEN> <BLUE> order |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int zone_idx = 0; zone_idx < num_zones; zone_idx++)
|
||||
{
|
||||
usb_buf[(zone_idx * 4) + 4] = zone_idx;
|
||||
usb_buf[(zone_idx * 4) + 5] = RGBGetRValue(color_data[zone_idx]);
|
||||
usb_buf[(zone_idx * 4) + 6] = RGBGetGValue(color_data[zone_idx]);
|
||||
usb_buf[(zone_idx * 4) + 7] = RGBGetBValue(color_data[zone_idx]);
|
||||
usb_buf[(zone_idx * 4) + 5] = zone_idx;
|
||||
usb_buf[(zone_idx * 4) + 6] = RGBGetRValue(color_data[zone_idx]);
|
||||
usb_buf[(zone_idx * 4) + 7] = RGBGetGValue(color_data[zone_idx]);
|
||||
usb_buf[(zone_idx * 4) + 8] = RGBGetBValue(color_data[zone_idx]);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
send_usb_msg(dev, usb_buf);
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
void CorsairPeripheralController::SubmitMousematColors
|
||||
@@ -467,7 +515,7 @@ void CorsairPeripheralController::SubmitMousematColors
|
||||
RGBColor * color_data
|
||||
)
|
||||
{
|
||||
char usb_buf[64];
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -477,24 +525,25 @@ void CorsairPeripheralController::SubmitMousematColors
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Submit Mouse Colors packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x01] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
|
||||
usb_buf[0x02] = num_zones;
|
||||
usb_buf[0x03] = 0x00;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_WRITE;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_SUBMIT_MOUSE_COLOR;
|
||||
usb_buf[0x03] = num_zones;
|
||||
usb_buf[0x04] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in colors in <ZONE> <RED> <GREEN> <BLUE> order |
|
||||
| Copy in colors in <RED> <GREEN> <BLUE> order |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int zone_idx = 0; zone_idx < num_zones; zone_idx++)
|
||||
{
|
||||
//usb_buf[(zone_idx * 4) + 4] = zone_idx;
|
||||
usb_buf[(zone_idx * 3) + 4] = RGBGetRValue(color_data[zone_idx]);
|
||||
usb_buf[(zone_idx * 3) + 5] = RGBGetGValue(color_data[zone_idx]);
|
||||
usb_buf[(zone_idx * 3) + 6] = RGBGetBValue(color_data[zone_idx]);
|
||||
usb_buf[(zone_idx * 3) + 5] = RGBGetRValue(color_data[zone_idx]);
|
||||
usb_buf[(zone_idx * 3) + 6] = RGBGetGValue(color_data[zone_idx]);
|
||||
usb_buf[(zone_idx * 3) + 7] = RGBGetBValue(color_data[zone_idx]);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
| Send packet using feature reports, as headset stand |
|
||||
| seems to not update completely using HID writes |
|
||||
\*-----------------------------------------------------*/
|
||||
send_usb_msg(dev, usb_buf);
|
||||
}
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#define CORSAIR_K70_RGB_PID 0x1B13
|
||||
#define CORSAIR_K70_LUX_RGB_PID 0x1B33
|
||||
#define CORSAIR_K70_RGB_RAPIDFIRE_PID 0x1B38
|
||||
#define CORSAIR_K70_RGB_MK2_PID 0x1B38
|
||||
#define CORSAIR_K70_RGB_MK2_PID 0x1B49
|
||||
#define CORSAIR_K70_RGB_MK2_SE_PID 0x1B6B
|
||||
#define CORSAIR_K70_RGB_MK2_LP_PID 0x1B55
|
||||
|
||||
@@ -39,6 +39,9 @@
|
||||
| Mouse product IDs |
|
||||
| List taken from ckb-next |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_GLAIVE_RGB_PRO_PID 0x1B74
|
||||
#define CORSAIR_HARPOON_RGB_PID 0x1B3C
|
||||
#define CORSAIR_HARPOON_RGB_PRO_PID 0x1B75
|
||||
#define CORSAIR_M65_PRO_PID 0x1B2E
|
||||
#define CORSAIR_M65_RGB_ELITE_PID 0x1B5A
|
||||
|
||||
@@ -48,6 +51,12 @@
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_MM800_RGB_POLARIS_PID 0x1B3B
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Headset Stand product IDs |
|
||||
| List taken from ckb-next |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_ST100_PID 0x0A34
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
@@ -63,6 +72,10 @@ static const corsair_node_device device_list[] =
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
// { CORSAIR_VID, CORSAIR_K55_RGB_PID, 1, "Corsair K55 RGB" }, //Not per-key, disabled for now
|
||||
{ CORSAIR_VID, CORSAIR_K65_RGB_PID, 1, "Corsair K65 RGB" },
|
||||
{ CORSAIR_VID, CORSAIR_K65_LUX_RGB_PID, 1, "Corsair K65 LUX RGB" },
|
||||
{ CORSAIR_VID, CORSAIR_K65_RGB_RAPIDFIRE_PID, 1, "Corsair K65 RGB RAPIDFIRE" },
|
||||
{ CORSAIR_VID, CORSAIR_K68_RGB, 1, "Corsair K68 RGB" },
|
||||
{ CORSAIR_VID, CORSAIR_K70_RGB_PID, 1, "Corsair K70 RGB" },
|
||||
{ CORSAIR_VID, CORSAIR_K70_LUX_RGB_PID, 1, "Corsair K70 LUX RGB" },
|
||||
@@ -72,15 +85,24 @@ static const corsair_node_device device_list[] =
|
||||
{ CORSAIR_VID, CORSAIR_K70_RGB_MK2_LP_PID, 1, "Corsair K70 RGB MK.2 Low Profile" },
|
||||
{ CORSAIR_VID, CORSAIR_K95_RGB_PID, 1, "Corsair K95 RGB" },
|
||||
{ CORSAIR_VID, CORSAIR_K95_PLATINUM_PID, 1, "Corsair K95 RGB PLATINUM" },
|
||||
{ CORSAIR_VID, CORSAIR_STRAFE_PID, 1, "Corsair Strafe" },
|
||||
{ CORSAIR_VID, CORSAIR_STRAFE_MK2_PID, 1, "Corsair Strafe MK.2" },
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Mice |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ CORSAIR_VID, CORSAIR_GLAIVE_RGB_PRO_PID, 1, "Corsair Glaive RGB PRO" },
|
||||
{ CORSAIR_VID, CORSAIR_HARPOON_RGB_PID, 1, "Corsair Harpoon RGB" },
|
||||
{ CORSAIR_VID, CORSAIR_HARPOON_RGB_PRO_PID, 1, "Corsair Harpoon RGB PRO" },
|
||||
{ CORSAIR_VID, CORSAIR_M65_PRO_PID, 1, "Corsair M65 PRO" },
|
||||
{ CORSAIR_VID, CORSAIR_M65_RGB_ELITE_PID, 1, "Corsair M65 RGB Elite" },
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Mousemats |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ CORSAIR_VID, CORSAIR_MM800_RGB_POLARIS_PID, 0, "Corsair MM800 RGB Polaris" }
|
||||
{ CORSAIR_VID, CORSAIR_MM800_RGB_POLARIS_PID, 0, "Corsair MM800 RGB Polaris" },
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Headset Stands |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ CORSAIR_VID, CORSAIR_ST100_PID, 0, "Corsair ST100 RGB" }
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
@@ -108,30 +130,31 @@ void DetectCorsairPeripheralControllers(std::vector<RGBController*>& rgb_control
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
#ifdef USE_HID_USAGE
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
&&(info->usage_page == 0xFFC2))
|
||||
#else
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
#endif
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
|
||||
if( dev )
|
||||
{
|
||||
CorsairPeripheralController* controller = new CorsairPeripheralController(dev);
|
||||
if( dev )
|
||||
{
|
||||
CorsairPeripheralController* controller = new CorsairPeripheralController(dev);
|
||||
|
||||
if(controller->GetDeviceType() != DEVICE_TYPE_UNKNOWN)
|
||||
{
|
||||
RGBController_CorsairPeripheral* rgb_controller = new RGBController_CorsairPeripheral(controller);
|
||||
if(controller->GetDeviceType() != DEVICE_TYPE_UNKNOWN)
|
||||
{
|
||||
RGBController_CorsairPeripheral* rgb_controller = new RGBController_CorsairPeripheral(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,16 +10,7 @@
|
||||
#include "CorsairVengeanceProController.h"
|
||||
#include <cstring>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
||||
static void Sleep(unsigned int milliseconds)
|
||||
{
|
||||
usleep(1000 * milliseconds);
|
||||
}
|
||||
#endif
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
CorsairVengeanceProController::CorsairVengeanceProController(i2c_smbus_interface* bus, corsair_dev_id dev)
|
||||
{
|
||||
@@ -89,9 +80,9 @@ void CorsairVengeanceProController::SetLEDColor(unsigned int led, unsigned char
|
||||
void CorsairVengeanceProController::ApplyColors()
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x26, 0x02);
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x21, 0x00);
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
@@ -119,9 +110,9 @@ void CorsairVengeanceProController::SetEffect(unsigned char mode,
|
||||
effect_mode = mode;
|
||||
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x26, 0x01);
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
bus->i2c_smbus_write_byte_data(dev, 0x21, 0x00);
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
|
||||
unsigned char random_byte;
|
||||
|
||||
@@ -165,7 +156,7 @@ bool CorsairVengeanceProController::WaitReady()
|
||||
while (bus->i2c_smbus_read_byte_data(dev, 0x41) != 0x00)
|
||||
{
|
||||
i++;
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -6,16 +6,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
||||
static void Sleep(unsigned int milliseconds)
|
||||
{
|
||||
usleep(1000 * milliseconds);
|
||||
}
|
||||
#endif
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
@@ -50,7 +41,7 @@ bool TestForCorsairVengeanceProController(i2c_smbus_interface* bus, unsigned cha
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(10);
|
||||
std::this_thread::sleep_for(10ms);
|
||||
|
||||
return(pass);
|
||||
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
/*-----------------------------------------*\
|
||||
| DuckyKeyboardController.cpp |
|
||||
| |
|
||||
| Driver for Ducky RGB keyboardlighting |
|
||||
| controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 7/4/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "DuckyKeyboardController.h"
|
||||
|
||||
DuckyKeyboardController::DuckyKeyboardController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
SendInitialize();
|
||||
}
|
||||
|
||||
DuckyKeyboardController::~DuckyKeyboardController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DuckyKeyboardController::SendColors
|
||||
(
|
||||
unsigned char* color_data,
|
||||
unsigned int color_data_size
|
||||
)
|
||||
{
|
||||
unsigned int bytes_sent;
|
||||
unsigned char* color_data_ptr = color_data;
|
||||
|
||||
SendInitializeColorPacket();
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
bytes_sent = SendColorDataPacket(i, color_data_ptr, color_data_size);
|
||||
|
||||
color_data_ptr += bytes_sent;
|
||||
color_data_size -= bytes_sent;
|
||||
}
|
||||
|
||||
SendTerminateColorPacket();
|
||||
}
|
||||
|
||||
void DuckyKeyboardController::SendInitialize()
|
||||
{
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Initialize Direct Mode packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x41;
|
||||
usb_buf[0x02] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
void DuckyKeyboardController::SendInitializeColorPacket()
|
||||
{
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Initialize Color packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x56;
|
||||
usb_buf[0x02] = 0x81;
|
||||
usb_buf[0x05] = 0x01;
|
||||
usb_buf[0x09] = 0x08;
|
||||
usb_buf[0x0D] = 0xAA;
|
||||
usb_buf[0x0E] = 0xAA;
|
||||
usb_buf[0x0F] = 0xAA;
|
||||
usb_buf[0x10] = 0xAA;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
|
||||
unsigned int DuckyKeyboardController::SendColorDataPacket
|
||||
(
|
||||
unsigned char packet_id,
|
||||
unsigned char* color_data,
|
||||
unsigned int color_size
|
||||
)
|
||||
{
|
||||
unsigned int bytes_sent;
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Color Data packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x56;
|
||||
usb_buf[0x02] = 0x83;
|
||||
usb_buf[0x03] = packet_id;
|
||||
|
||||
if(packet_id == 0x00)
|
||||
{
|
||||
usb_buf[0x05] = 0x01;
|
||||
usb_buf[0x09] = 0x80;
|
||||
usb_buf[0x0A] = 0x01;
|
||||
usb_buf[0x0C] = 0xC1;
|
||||
usb_buf[0x11] = 0xFF;
|
||||
usb_buf[0x12] = 0xFF;
|
||||
usb_buf[0x13] = 0xFF;
|
||||
usb_buf[0x14] = 0xFF;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
if(packet_id == 0x00)
|
||||
{
|
||||
bytes_sent = 65 - 0x19;
|
||||
|
||||
if(color_size < bytes_sent)
|
||||
{
|
||||
bytes_sent = color_size;
|
||||
}
|
||||
|
||||
memcpy(&usb_buf[0x19], color_data, bytes_sent);
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_sent = 65 - 0x05;
|
||||
|
||||
if(color_size < bytes_sent)
|
||||
{
|
||||
bytes_sent = color_size;
|
||||
}
|
||||
|
||||
memcpy(&usb_buf[0x05], color_data, bytes_sent);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
|
||||
return(bytes_sent);
|
||||
}
|
||||
|
||||
void DuckyKeyboardController::SendTerminateColorPacket()
|
||||
{
|
||||
char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Terminate Color packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x51;
|
||||
usb_buf[0x02] = 0x28;
|
||||
usb_buf[0x05] = 0xFF;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, (unsigned char *)usb_buf, 65);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*-----------------------------------------*\
|
||||
| DuckyKeyboardController.h |
|
||||
| |
|
||||
| Definitions and types for Ducky RGB |
|
||||
| keyboard lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 7/4/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
class DuckyKeyboardController
|
||||
{
|
||||
public:
|
||||
DuckyKeyboardController(hid_device* dev_handle);
|
||||
~DuckyKeyboardController();
|
||||
|
||||
void SendColors
|
||||
(
|
||||
unsigned char* color_data,
|
||||
unsigned int color_data_size
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
|
||||
void SendInitialize();
|
||||
void SendInitializeColorPacket();
|
||||
unsigned int SendColorDataPacket
|
||||
(
|
||||
unsigned char packet_id,
|
||||
unsigned char* color_data,
|
||||
unsigned int color_size
|
||||
);
|
||||
void SendTerminateColorPacket();
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
#include "DuckyKeyboardController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_DuckyKeyboard.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Ducky vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define DUCKY_VID 0x04D9
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define DUCKY_SHINE_7_ONE_2_RGB_PID 0x0348
|
||||
#define DUCKY_ONE_2_RGB_TKL_PID 0x0356
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned char usb_interface;
|
||||
const char * name;
|
||||
} ducky_device;
|
||||
|
||||
#define DUCKY_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const ducky_device device_list[] =
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ DUCKY_VID, DUCKY_SHINE_7_ONE_2_RGB_PID, 1, "Ducky Shine 7/Ducky One 2 RGB" },
|
||||
{ DUCKY_VID, DUCKY_ONE_2_RGB_TKL_PID, 1, "Ducky One 2 RGB TKL" },
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectDuckyKeyboardControllers *
|
||||
* *
|
||||
* Tests the USB address to see if a Ducky RGB Keyboard controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectDuckyKeyboardControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev;
|
||||
|
||||
hid_init();
|
||||
|
||||
for(std::size_t device_idx = 0; device_idx < DUCKY_NUM_DEVICES; device_idx++)
|
||||
{
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
//Look for Ducky RGB Peripheral
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
DuckyKeyboardController* controller = new DuckyKeyboardController(dev);
|
||||
|
||||
RGBController_DuckyKeyboard* rgb_controller = new RGBController_DuckyKeyboard(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*-------------------------------------------------------------------*\
|
||||
| EKController.cpp |
|
||||
| |
|
||||
| Driver for EK Loop Connect |
|
||||
| |
|
||||
| Chris M (Dr_No) 16th Jul 2020 |
|
||||
| |
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#include "EKController.h"
|
||||
|
||||
EKController::EKController(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path)
|
||||
{
|
||||
int tmp_size = wcslen(_vendor);
|
||||
|
||||
dev = dev_handle;
|
||||
|
||||
for(int i=0; (i < tmp_size) && (i < EK_DEVICE_NAME_SIZE); i++)
|
||||
{
|
||||
device_name[i] = (char)_vendor[i];
|
||||
}
|
||||
|
||||
for(int j=0; (j < wcslen(_vendor)) && ((tmp_size + j) < EK_DEVICE_NAME_SIZE); j++)
|
||||
{
|
||||
device_name[tmp_size+j] = (char)_device_name[j];
|
||||
}
|
||||
|
||||
location = _path;
|
||||
|
||||
current_mode = EK_MODE_STATIC;
|
||||
current_speed = EK_SPEED_NORMAL;
|
||||
}
|
||||
|
||||
EKController::~EKController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
char* EKController::GetDeviceName()
|
||||
{
|
||||
return device_name;
|
||||
}
|
||||
|
||||
char* EKController::GetSerial()
|
||||
{
|
||||
return serial;
|
||||
}
|
||||
|
||||
std::string EKController::GetLocation()
|
||||
{
|
||||
return location;
|
||||
}
|
||||
|
||||
void EKController::SetMode(unsigned char mode, unsigned char speed)
|
||||
{
|
||||
current_mode = mode;
|
||||
current_speed = speed;
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void EKController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
current_red = red;
|
||||
current_green = green;
|
||||
current_blue = blue;
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void EKController::SendUpdate()
|
||||
{
|
||||
unsigned char buffer[EK_PACKET_LENGTH] = { 0x00 };
|
||||
int buffer_size = (sizeof(buffer) / sizeof(buffer[0]));
|
||||
|
||||
for(int i = 0; i < EK_COLOUR_MODE_DATA_SIZE; i++)
|
||||
{
|
||||
buffer[i] = colour_mode_data[current_mode][i];
|
||||
}
|
||||
|
||||
//Set the relevant colour info
|
||||
buffer[EK_RED_BYTE] = current_red;
|
||||
buffer[EK_GREEN_BYTE] = current_green;
|
||||
buffer[EK_BLUE_BYTE] = current_blue;
|
||||
buffer[EK_SPEED_BYTE] = speed_mode_data[current_mode][current_speed];
|
||||
|
||||
buffer[10] = 0x10;
|
||||
buffer[47] = 0xFF;
|
||||
buffer[48] = 0x00;
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*-------------------------------------------------------------------*\
|
||||
| EKController.h |
|
||||
| |
|
||||
| Driver for EK Loop Connect |
|
||||
| |
|
||||
| Chris M (Dr_No) 16th Jul 2020 |
|
||||
| |
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#ifndef EKCONTROLLER_H
|
||||
#define EKCONTROLLER_H
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define EK_COLOUR_MODE_DATA_SIZE (sizeof(colour_mode_data[0]) / sizeof(colour_mode_data[0][0]))
|
||||
#define EK_DEVICE_NAME_SIZE (sizeof(device_name) / sizeof(device_name[ 0 ]))
|
||||
#define EK_PACKET_LENGTH 0x3F
|
||||
|
||||
enum
|
||||
{
|
||||
EK_MODE_BYTE = 12,
|
||||
EK_SPEED_BYTE = 14,
|
||||
EK_RED_BYTE = 16,
|
||||
EK_GREEN_BYTE = 17,
|
||||
EK_BLUE_BYTE = 18
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EK_MODE_STATIC = 0x00, //Static Mode
|
||||
EK_MODE_BREATHING = 0x01, //Breathing Mode
|
||||
EK_MODE_FADING = 0x02, //Fading Mode
|
||||
EK_MODE_MARQUEE = 0x03, //Marquee Mode
|
||||
EK_MODE_COVERING_MARQUEE = 0x04, //Covering Marquee Mode
|
||||
EK_MODE_PULSE = 0x05, //Pulse Mode
|
||||
EK_MODE_SPECTRUM_WAVE = 0x06, //Spectrum Wave Mode
|
||||
EK_MODE_ALTERNATING = 0x07, //Alternating Mode
|
||||
EK_MODE_CANDLE = 0x08 //Candle Mode
|
||||
};
|
||||
|
||||
static unsigned char colour_mode_data[][16] =
|
||||
{
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x01, 0x00, 0xFF, 0x64}, // Static
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x02, 0x00, 0xFF, 0x64}, // Breathing
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x03, 0xFF, 0xFF, 0x64}, // Fading
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x04, 0x00, 0xFF, 0x64}, // Marquee
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x05, 0x00, 0xFF, 0x64}, // Covering Marquee
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x06, 0x00, 0xFF, 0x64}, // Pulse
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x07, 0x00, 0xFF, 0x64}, // Wave
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x08, 0x00, 0xFF, 0x64}, // Alternating
|
||||
{ 0x10, 0x12, 0x29, 0xAA, 0x01, 0x10, 0xA2, 0x60,
|
||||
0x00, 0x10, 0x20, 0x01, 0x09, 0x00, 0xFF, 0x64}, // Candle
|
||||
};
|
||||
|
||||
static unsigned char speed_mode_data[][9] =
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // Static
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Breathing
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Fading
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Marquee
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Covering Marquee
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Pulse
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Wave
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 }, // Alternating
|
||||
{ 0x00, 0x0C, 0x19, 0x25, 0x32, 0x3E, 0x4B, 0x57, 0x64 } // Candle
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EK_SPEED_SLOWEST = 0x00, // Slowest speed
|
||||
EK_SPEED_SLOWER = 0x01, // Slower speed
|
||||
EK_SPEED_SLOW = 0x02, // Slow speed
|
||||
EK_SPEED_SLOWISH = 0x03, // Slowish speed
|
||||
EK_SPEED_NORMAL = 0x04, // Normal speed
|
||||
EK_SPEED_FASTISH = 0x05, // Fastish speed
|
||||
EK_SPEED_FAST = 0x06, // Fast speed
|
||||
EK_SPEED_FASTER = 0x07, // Faster speed
|
||||
EK_SPEED_FASTEST = 0x08, // Fastest speed
|
||||
};
|
||||
|
||||
class EKController
|
||||
{
|
||||
public:
|
||||
EKController(hid_device* dev_handle, wchar_t *_vendor, wchar_t *_device_name, char *_path);
|
||||
~EKController();
|
||||
|
||||
char* GetDeviceName();
|
||||
char* GetSerial();
|
||||
std::string GetLocation();
|
||||
|
||||
void SetMode(unsigned char mode, unsigned char speed);
|
||||
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
private:
|
||||
char device_name[32];
|
||||
char serial[32];
|
||||
std::string location;
|
||||
hid_device* dev;
|
||||
|
||||
unsigned char current_mode;
|
||||
unsigned char current_speed;
|
||||
|
||||
unsigned char current_red;
|
||||
unsigned char current_green;
|
||||
unsigned char current_blue;
|
||||
|
||||
void SendUpdate();
|
||||
};
|
||||
|
||||
#endif // EKCONTROLLER_H
|
||||
@@ -0,0 +1,64 @@
|
||||
#include "EKController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_EKController.h"
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define EK_VID 0x0483
|
||||
|
||||
#define EK_LOOP_CONNECT 0x5750
|
||||
|
||||
#define EK_NUM_DEVICES (sizeof(ek_pids) / sizeof(ek_pids[ 0 ]))
|
||||
|
||||
enum
|
||||
{
|
||||
EK_PID = 0,
|
||||
EK_INTERFACE = 1
|
||||
};
|
||||
|
||||
static const unsigned int ek_pids[][2] =
|
||||
{ // PID, Interface
|
||||
{ EK_LOOP_CONNECT, 0x00 } //EK Loop Connect
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectEKControllers *
|
||||
* *
|
||||
* Tests the USB address to see if any EK Controllers exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectEKControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
|
||||
//Look for the passed in cm_pids
|
||||
hid_init();
|
||||
info = hid_enumerate(0x0, 0x0);
|
||||
|
||||
while(info)
|
||||
{
|
||||
hid_device* dev = NULL;
|
||||
if(info->vendor_id == EK_VID)
|
||||
{
|
||||
for(int ek_pid_idx = 0; ek_pid_idx < EK_NUM_DEVICES; ek_pid_idx++)
|
||||
{
|
||||
if((info->product_id == ek_pids[ek_pid_idx][EK_PID])
|
||||
&&(info->interface_number == ek_pids[ek_pid_idx][EK_INTERFACE]))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EKController* controller = new EKController(dev, info->manufacturer_string, info->product_string, info->path);
|
||||
RGBController_EKController* rgb_controller = new RGBController_EKController(controller);
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
hid_free_enumeration(info);
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*-----------------------------------------*\
|
||||
| GalaxGPUController.cpp |
|
||||
| |
|
||||
| Driver for Galax / KFA2 RGB on GPUs |
|
||||
| |
|
||||
| Niels Westphal (crashniels) 12.07.2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "GalaxGPUController.h"
|
||||
#include <cstring>
|
||||
|
||||
GalaxGPUController::GalaxGPUController(i2c_smbus_interface* bus, galax_gpu_dev_id dev)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
|
||||
strcpy(device_name, "Galax RTX GPU"); // Would be nice to get the actual GPU name. Using this as a placeholder.
|
||||
}
|
||||
|
||||
GalaxGPUController::~GalaxGPUController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string GalaxGPUController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string GalaxGPUController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return(return_string);
|
||||
}
|
||||
|
||||
unsigned char GalaxGPUController::GetLEDRed()
|
||||
{
|
||||
return(GalaxGPURegisterRead(GALAX_RED_REGISTER));
|
||||
}
|
||||
|
||||
unsigned char GalaxGPUController::GetLEDGreen()
|
||||
{
|
||||
return(GalaxGPURegisterRead(GALAX_GREEN_REGISTER));
|
||||
}
|
||||
|
||||
unsigned char GalaxGPUController::GetLEDBlue()
|
||||
{
|
||||
return(GalaxGPURegisterRead(GALAX_BLUE_REGISTER));
|
||||
}
|
||||
|
||||
void GalaxGPUController::SetLEDColorsDirect(unsigned char red, unsigned char green, unsigned char blue) // Direct Mode is just Static Mode without applying color changes
|
||||
{
|
||||
GalaxGPURegisterWrite(GALAX_RED_REGISTER, red);
|
||||
GalaxGPURegisterWrite(GALAX_GREEN_REGISTER, green);
|
||||
GalaxGPURegisterWrite(GALAX_BLUE_REGISTER, blue);
|
||||
}
|
||||
|
||||
void GalaxGPUController::SetLEDColorsEffect(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
GalaxGPURegisterWrite(GALAX_RED_REGISTER, red);
|
||||
GalaxGPURegisterWrite(GALAX_GREEN_REGISTER, green);
|
||||
GalaxGPURegisterWrite(GALAX_BLUE_REGISTER, blue);
|
||||
}
|
||||
|
||||
void GalaxGPUController::SetMode(unsigned char mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case 1:
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_1, GALAX_MODE_STATIC_VALUE_1);
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_2, GALAX_MODE_STATIC_VALUE_2);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_1, GALAX_MODE_BREATHING_VALUE_1);
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_2, GALAX_MODE_BREATHING_VALUE_2);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_1, GALAX_MODE_RAINBOW_VALUE_1);
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_2, GALAX_MODE_RAINBOW_VALUE_2);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_1, GALAX_MODE_CYCLE_BREATHING_VALUE_1);
|
||||
GalaxGPURegisterWrite(GALAX_MODE_REGISTER_2, GALAX_MODE_CYCLE_BREATHING_VALUE_2);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char GalaxGPUController::GalaxGPURegisterRead(unsigned char reg)
|
||||
{
|
||||
return(bus->i2c_smbus_read_byte_data(dev, reg));
|
||||
}
|
||||
|
||||
void GalaxGPUController::GalaxGPURegisterWrite(unsigned char reg, unsigned char val)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, reg, val);
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*-----------------------------------------*\
|
||||
| GalaxGPUController.h |
|
||||
| |
|
||||
| Driver for Galax / KFA2 RGB on GPUs |
|
||||
| |
|
||||
| Niels Westphal (crashniels) 12.07.2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char galax_gpu_dev_id;
|
||||
|
||||
enum
|
||||
{
|
||||
/* RGB Registers */
|
||||
GALAX_RED_REGISTER = 0x02, /* Red Register */
|
||||
GALAX_GREEN_REGISTER = 0x03, /* Green Register */
|
||||
GALAX_BLUE_REGISTER = 0x04, /* Blue Register */
|
||||
/* MODE Registers */
|
||||
GALAX_MODE_REGISTER_1 = 0x05, /* Mode Register 1 */
|
||||
GALAX_MODE_REGISTER_2 = 0x06, /* Mode Register 2 */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
/* Static Mode Values */
|
||||
GALAX_MODE_STATIC_VALUE_1 = 0x00,
|
||||
GALAX_MODE_STATIC_VALUE_2 = 0x01,
|
||||
/* Breathing Mode Values */
|
||||
GALAX_MODE_BREATHING_VALUE_1 = 0x04,
|
||||
GALAX_MODE_BREATHING_VALUE_2 = 0x00,
|
||||
/* Rainbow Mode Values */
|
||||
GALAX_MODE_RAINBOW_VALUE_1 = 0x84,
|
||||
GALAX_MODE_RAINBOW_VALUE_2 = 0x02,
|
||||
/* Cycle Breathing Mode Values */
|
||||
GALAX_MODE_CYCLE_BREATHING_VALUE_1 = 0x84,
|
||||
GALAX_MODE_CYCLE_BREATHING_VALUE_2 = 0x40,
|
||||
};
|
||||
|
||||
class GalaxGPUController
|
||||
{
|
||||
public:
|
||||
GalaxGPUController(i2c_smbus_interface* bus, galax_gpu_dev_id);
|
||||
~GalaxGPUController();
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceLocation();
|
||||
unsigned char GetLEDRed();
|
||||
unsigned char GetLEDGreen();
|
||||
unsigned char GetLEDBlue();
|
||||
void SetLEDColorsDirect(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetLEDColorsEffect(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetMode(unsigned char mode);
|
||||
|
||||
unsigned char GalaxGPURegisterRead(unsigned char reg);
|
||||
void GalaxGPURegisterWrite(unsigned char reg, unsigned char val);
|
||||
|
||||
bool direct = false; // Temporary solution to check if we are in "Direct" mode
|
||||
|
||||
private:
|
||||
char device_name[16];
|
||||
i2c_smbus_interface * bus;
|
||||
galax_gpu_dev_id dev;
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
/*-----------------------------------------*\
|
||||
| GalaxGPUControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for Galax / KFA2 RGB on GPUs |
|
||||
| |
|
||||
| Niels Westphal (crashniels) 12.07.2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "GalaxGPUController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_GalaxGPU.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* TestForGalaxGPUController *
|
||||
* *
|
||||
* Tests the given address to see if a Galax GPU controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
bool TestForGalaxGPUController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
|
||||
unsigned char res = bus->i2c_smbus_read_byte_data(address, 0x00);
|
||||
unsigned char res2 = bus->i2c_smbus_read_byte_data(address, 0x01);
|
||||
if(res == 0x27 && res2 == 0x10)
|
||||
{
|
||||
pass = true;
|
||||
}
|
||||
|
||||
return(pass);
|
||||
|
||||
} /* TestForGalaxGPUController() */
|
||||
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectGalaxGPUControllers *
|
||||
* *
|
||||
* Detect Galax GPU controllers on the enumerated I2C busses. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectGalaxGPUControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
GalaxGPUController* new_GalaxGPU;
|
||||
RGBController_GalaxGPU* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
// Check for GALAX controller at 0x23
|
||||
if (TestForGalaxGPUController(busses[bus], 0x23))
|
||||
{
|
||||
new_GalaxGPU = new GalaxGPUController(busses[bus], 0x23);
|
||||
new_controller = new RGBController_GalaxGPU(new_GalaxGPU);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
|
||||
} /* DetectGalaxGPUControllers() */
|
||||
@@ -0,0 +1,278 @@
|
||||
/*-----------------------------------------*\
|
||||
| RGBController_GloriousModelO.cpp |
|
||||
| |
|
||||
| Definitions and types for Glorious |
|
||||
| and other Mice |
|
||||
| |
|
||||
| Niels Westphal (crashniels) 20/5/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "GloriousModelOController.h"
|
||||
#include <cstring>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
GloriousModelOController::GloriousModelOController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
strcpy(device_name, "Glorious Mouse");
|
||||
led_count = 1;
|
||||
|
||||
current_mode = GLORIOUS_MODE_STATIC;
|
||||
current_speed = GLORIOUS_SPEED_NORMAL;
|
||||
current_direction = GLORIOUS_DIRECTION_UP;
|
||||
|
||||
}
|
||||
|
||||
GloriousModelOController::~GloriousModelOController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string GloriousModelOController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned int GloriousModelOController::GetLEDCount()
|
||||
{
|
||||
return(led_count);
|
||||
}
|
||||
|
||||
void GloriousModelOController::SetLEDColor(RGBColor* color_buf)
|
||||
{
|
||||
unsigned char usb_buf[520] =
|
||||
{
|
||||
0x04, 0x11, 0x00, 0x7b,
|
||||
0x00, 0x00, 0x00, 0x00, 0x64, 0x06, 0x04, 0x24,
|
||||
0xf0, 0x03, 0x07, 0x0f, 0x1f, 0x31, 0x63, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
|
||||
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x02, 0x41, 0x01, 0x40, 0xff, 0xff, 0xff,
|
||||
0x42, 0x07, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||
0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x43,
|
||||
0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x42, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
|
||||
0x42, 0x02, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
usb_buf[0x0B] = 0x24;
|
||||
usb_buf[0x35] = GLORIOUS_MODE_STATIC;
|
||||
usb_buf[0x38] = 0x40; //max brightness
|
||||
usb_buf[0x39] = RGBGetRValue(color_buf[0]);
|
||||
usb_buf[0x3A] = RGBGetBValue(color_buf[0]);
|
||||
usb_buf[0x3B] = RGBGetGValue(color_buf[0]);
|
||||
|
||||
//DPI Button
|
||||
/*
|
||||
usb_buf[0x0B] = 0x44; //third DPI
|
||||
usb_buf[0x26] = red;
|
||||
usb_buf[0x27] = blue;
|
||||
usb_buf[0x28] = green;
|
||||
*/
|
||||
|
||||
hid_send_feature_report(dev, usb_buf, sizeof(usb_buf));
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
|
||||
void GloriousModelOController::SetMode(unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char direction,
|
||||
RGBColor* color_buf)
|
||||
{
|
||||
unsigned char usb_buf[520] =
|
||||
{
|
||||
0x04, 0x11, 0x00, 0x7b,
|
||||
0x00, 0x00, 0x00, 0x00, 0x64, 0x06, 0x04, 0x24,
|
||||
0xf0, 0x03, 0x07, 0x0f, 0x1f, 0x31, 0x63, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
|
||||
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x02, 0x41, 0x01, 0x40, 0xff, 0xff, 0xff,
|
||||
0x42, 0x07, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||
0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x43,
|
||||
0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x42, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
|
||||
0x42, 0x02, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
usb_buf[0x35] = mode;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case GLORIOUS_MODE_OFF:
|
||||
usb_buf[0x81] = 0x00; //mode 0 either 0x00 or 0x03
|
||||
break;
|
||||
case GLORIOUS_MODE_RAINBOW:
|
||||
usb_buf[0x36] = speed;
|
||||
usb_buf[0x37] = direction;
|
||||
break;
|
||||
case GLORIOUS_MODE_SPECTRUM_BREATING:
|
||||
//colours not yet researched
|
||||
usb_buf[0x3C] = speed; //speed for mode 3
|
||||
usb_buf[0x3D] = 0x07; //maybe some kind of bank change?+
|
||||
//usb_buf[0x3D] = 0x06;
|
||||
usb_buf[0x3E] = RGBGetRValue(color_buf[0]); //mode 3 red 1
|
||||
usb_buf[0x3F] = RGBGetBValue(color_buf[0]); //mode 3 blue 1
|
||||
usb_buf[0x40] = RGBGetGValue(color_buf[0]); //mode 3 green 1
|
||||
usb_buf[0x41] = RGBGetRValue(color_buf[1]); //mode 3 red 2
|
||||
usb_buf[0x42] = RGBGetBValue(color_buf[1]); //mode 3 blue 2
|
||||
usb_buf[0x43] = RGBGetGValue(color_buf[1]); //mode 3 green 2
|
||||
usb_buf[0x44] = RGBGetRValue(color_buf[2]); //mode 3 red 3
|
||||
usb_buf[0x45] = RGBGetBValue(color_buf[2]); //mode 3 blue 3
|
||||
usb_buf[0x46] = RGBGetGValue(color_buf[2]); //mode 3 green 3
|
||||
usb_buf[0x47] = RGBGetRValue(color_buf[3]); //mode 3 red 4
|
||||
usb_buf[0x48] = RGBGetBValue(color_buf[3]); //mode 3 blue 4
|
||||
usb_buf[0x49] = RGBGetGValue(color_buf[3]); //mode 3 green 4
|
||||
usb_buf[0x4A] = RGBGetRValue(color_buf[4]); //mode 3 red 5
|
||||
usb_buf[0x4B] = RGBGetBValue(color_buf[4]); //mode 3 blue 5
|
||||
usb_buf[0x4C] = RGBGetGValue(color_buf[4]); //mode 3 green 5
|
||||
usb_buf[0x4D] = RGBGetRValue(color_buf[5]); //mode 3 red 6
|
||||
usb_buf[0x4E] = RGBGetBValue(color_buf[5]); //mode 3 blue 6
|
||||
usb_buf[0x4F] = RGBGetGValue(color_buf[5]); //mode 3 green 6
|
||||
usb_buf[0x50] = RGBGetRValue(color_buf[6]); //mode 3 red 7
|
||||
usb_buf[0x51] = RGBGetBValue(color_buf[6]); //mode 3 blue 7
|
||||
usb_buf[0x52] = RGBGetGValue(color_buf[6]); //mode 3 green 7
|
||||
break;
|
||||
case GLORIOUS_MODE_TAIL:
|
||||
usb_buf[0x53] = speed; //Speed for mode 4
|
||||
break;
|
||||
case GLORIOUS_MODE_SPECTRUM_CYCLE:
|
||||
usb_buf[0x54] = speed; //Speed for mode 1,2,5
|
||||
break;
|
||||
case GLORIOUS_MODE_RAVE:
|
||||
usb_buf[0x74] = speed; //Speed for mode 7
|
||||
usb_buf[0x75] = RGBGetRValue(color_buf[0]); //mode 7 red 1
|
||||
usb_buf[0x76] = RGBGetBValue(color_buf[0]); //mode 7 blue 1
|
||||
usb_buf[0x77] = RGBGetGValue(color_buf[0]); //mode 7 green 1
|
||||
usb_buf[0x78] = RGBGetRValue(color_buf[1]); //mode 7 red 2
|
||||
usb_buf[0x79] = RGBGetBValue(color_buf[1]); //mode 7 blue 2
|
||||
usb_buf[0x7A] = RGBGetGValue(color_buf[1]); //mode 7 green 2
|
||||
break;
|
||||
case GLORIOUS_MODE_WAVE:
|
||||
usb_buf[0x7C] = speed; //Speed for mode 9
|
||||
break;
|
||||
case GLORIOUS_MODE_BREATHING:
|
||||
usb_buf[0x7D] = speed;
|
||||
usb_buf[0x7E] = RGBGetRValue(color_buf[0]); //mode 0a red
|
||||
usb_buf[0x7F] = RGBGetBValue(color_buf[0]); //mode 0a blue
|
||||
usb_buf[0x80] = RGBGetGValue(color_buf[0]); //mode 0a green
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
hid_send_feature_report(dev, usb_buf, sizeof(usb_buf));
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*-----------------------------------------*\
|
||||
| GloriousModelOController.h |
|
||||
| |
|
||||
| Definitions and types for Glorious |
|
||||
| and other Mice |
|
||||
| |
|
||||
| Niels Westphal (crashniels) 20/5/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
GLORIOUS_MODE_OFF = 0x00, //does nothing
|
||||
GLORIOUS_MODE_RAINBOW = 0x01,
|
||||
GLORIOUS_MODE_STATIC = 0x02,
|
||||
GLORIOUS_MODE_SPECTRUM_BREATING = 0x03,
|
||||
GLORIOUS_MODE_TAIL = 0x04,
|
||||
GLORIOUS_MODE_SPECTRUM_CYCLE = 0x05,
|
||||
GLORIOUS_MODE_RAVE = 0x07,
|
||||
GLORIOUS_MODE_EPILEPSY = 0x08, //not in the official software
|
||||
GLORIOUS_MODE_WAVE = 0x09,
|
||||
GLORIOUS_MODE_BREATHING = 0x0a,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GLORIOUS_SPEED_SLOW = 0x41,
|
||||
GLORIOUS_SPEED_NORMAL = 0x42,
|
||||
GLORIOUS_SPEED_FAST = 0x43,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GLORIOUS_DIRECTION_UP = 0x00,
|
||||
GLORIOUS_DIRECTION_DOWN = 0x01,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GLORIOUS_MODE_BREATING_SLOW = 0x01,
|
||||
GLORIOUS_MODE_BREATING_NORMAL = 0x02,
|
||||
GLORIOUS_MODE_BREATING_FAST = 0x03,
|
||||
};
|
||||
|
||||
class GloriousModelOController
|
||||
{
|
||||
public:
|
||||
GloriousModelOController(hid_device* dev_handle);
|
||||
~GloriousModelOController();
|
||||
|
||||
std::string GetDeviceName();
|
||||
unsigned int GetLEDCount();
|
||||
|
||||
void SetLEDColor(RGBColor* color_buf);
|
||||
void SetMode(unsigned char mode, unsigned char speed, unsigned char direction, RGBColor* color_buf);
|
||||
private:
|
||||
hid_device* dev;
|
||||
|
||||
char device_name[32];
|
||||
unsigned int led_count;
|
||||
|
||||
unsigned char current_mode;
|
||||
unsigned char current_speed;
|
||||
unsigned char current_direction;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "GloriousModelOController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_GloriousModelO.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define Glorious_Model_O_VID 0x258A
|
||||
#define Glorious_Model_O_PID 0x0036
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectGloriousModelController *
|
||||
* *
|
||||
* Tests the USB address to see if a Glorious Model O controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectGloriousModelOControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev = NULL;
|
||||
|
||||
hid_init();
|
||||
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(Glorious_Model_O_VID, Glorious_Model_O_PID);
|
||||
|
||||
//Look for Glorious Model O
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == Glorious_Model_O_VID)
|
||||
&&(info->product_id == Glorious_Model_O_PID)
|
||||
#ifdef USE_HID_USAGE
|
||||
&&(info->interface_number == 1)
|
||||
&&(info->usage_page == 0xFF00))
|
||||
#else
|
||||
&&(info->interface_number == 1))
|
||||
#endif
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
|
||||
if( dev )
|
||||
{
|
||||
GloriousModelOController* controller = new GloriousModelOController(dev);
|
||||
|
||||
RGBController_GloriousModelO* rgb_controller = new RGBController_GloriousModelO(controller);
|
||||
|
||||
rgb_controller->name = "Glorious Mouse";
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
#include "Hue2Controller.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_Hue2.h"
|
||||
#include <vector>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
|
||||
#define NZXT_HUE_2_VID 0x1E71
|
||||
#define NZXT_HUE_2_PID 0x2001
|
||||
#define NZXT_SMART_DEVICE_V2_PID 0x2006
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectHue2Controllers *
|
||||
* *
|
||||
* Detect devices supported by the Hue2 driver *
|
||||
* * *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectHue2Controllers(std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
libusb_context * ctx;
|
||||
libusb_init(&ctx);
|
||||
|
||||
//Look for NZXT Hue 2
|
||||
libusb_device_handle * hue_2_dev = libusb_open_device_with_vid_pid(ctx, NZXT_HUE_2_VID, NZXT_HUE_2_PID);
|
||||
|
||||
if( hue_2_dev )
|
||||
{
|
||||
libusb_detach_kernel_driver(hue_2_dev, 0);
|
||||
libusb_claim_interface(hue_2_dev, 0);
|
||||
|
||||
Hue2Controller* controller = new Hue2Controller(hue_2_dev);
|
||||
|
||||
RGBController_Hue2* rgb_controller = new RGBController_Hue2(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
//Look for NZXT Smart Device V2
|
||||
libusb_device_handle * smart_dev_2_dev = libusb_open_device_with_vid_pid(ctx, NZXT_HUE_2_VID, NZXT_SMART_DEVICE_V2_PID);
|
||||
|
||||
if( smart_dev_2_dev )
|
||||
{
|
||||
libusb_detach_kernel_driver(smart_dev_2_dev, 0);
|
||||
libusb_claim_interface(smart_dev_2_dev, 0);
|
||||
|
||||
Hue2Controller* controller = new Hue2Controller(smart_dev_2_dev);
|
||||
|
||||
RGBController_Hue2* rgb_controller = new RGBController_Hue2(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
} /* DetectHuePlusControllers() */
|
||||
@@ -11,16 +11,7 @@
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
||||
static void Sleep(unsigned int milliseconds)
|
||||
{
|
||||
usleep(1000 * milliseconds);
|
||||
}
|
||||
#endif
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
HuePlusController::HuePlusController()
|
||||
{
|
||||
@@ -64,7 +55,7 @@ unsigned int HuePlusController::GetLEDsOnChannel(unsigned int channel)
|
||||
serialport->serial_write((char *)serial_buf, 2);
|
||||
serialport->serial_flush_tx();
|
||||
|
||||
Sleep(50);
|
||||
std::this_thread::sleep_for(50ms);
|
||||
|
||||
int bytes_read = serialport->serial_read((char *)serial_buf, 5);
|
||||
|
||||
@@ -244,5 +235,5 @@ void HuePlusController::SendPacket
|
||||
/*-----------------------------------------------------*\
|
||||
| Delay to allow Hue+ device to ready for next packet |
|
||||
\*-----------------------------------------------------*/
|
||||
Sleep(20);
|
||||
std::this_thread::sleep_for(20ms);
|
||||
}
|
||||
|
||||
@@ -6,16 +6,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
||||
static void Sleep(unsigned int milliseconds)
|
||||
{
|
||||
usleep(1000 * milliseconds);
|
||||
}
|
||||
#endif
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
@@ -76,7 +67,7 @@ void DetectHyperXDRAMControllers(std::vector<i2c_smbus_interface*> &busses, std:
|
||||
{
|
||||
busses[bus]->i2c_smbus_write_byte_data(0x37, 0x00, 0xFF);
|
||||
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
|
||||
for(int slot_addr = 0x50; slot_addr <= 0x57; slot_addr++)
|
||||
{
|
||||
@@ -89,7 +80,7 @@ void DetectHyperXDRAMControllers(std::vector<i2c_smbus_interface*> &busses, std:
|
||||
slots_valid |= (1 << (slot_addr - 0x50));
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
|
||||
if(slots_valid != 0)
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
/*-----------------------------------------*\
|
||||
| HyperXAlloyOriginsController.cpp |
|
||||
| |
|
||||
| Driver for HyperX Alloy Origins RGB |
|
||||
| Keyboard lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 7/11/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "HyperXAlloyOriginsController.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
// Skip these indices in the color output
|
||||
static unsigned int skip_idx[] = { 6, 23, 29, 41, 47, 59, 70, 71, 75, 76, 87, 88, 93, 99, 100, 102, 108, 113, 114, 120, 123, 124 };
|
||||
|
||||
HyperXAlloyOriginsController::HyperXAlloyOriginsController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
}
|
||||
|
||||
HyperXAlloyOriginsController::~HyperXAlloyOriginsController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void HyperXAlloyOriginsController::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Insert color data for unused positions |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int skip_cnt = 0; skip_cnt < (sizeof(skip_idx) / sizeof(skip_idx[0])); skip_cnt++)
|
||||
{
|
||||
colors.insert(colors.begin() + skip_idx[skip_cnt], 0x00000000);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up variables to track progress of color transmit |
|
||||
| Do this after inserting blanks |
|
||||
\*-----------------------------------------------------*/
|
||||
int colors_to_send = colors.size();
|
||||
int colors_sent = 0;
|
||||
|
||||
SendDirectInitialization();
|
||||
|
||||
for(int pkt_idx = 0; pkt_idx < 9; pkt_idx++)
|
||||
{
|
||||
if(colors_to_send > 16)
|
||||
{
|
||||
SendDirectColorPacket(&colors[colors_sent], 16);
|
||||
colors_sent += 16;
|
||||
colors_to_send -= 16;
|
||||
}
|
||||
else if(colors_to_send > 0)
|
||||
{
|
||||
SendDirectColorPacket(&colors[colors_sent], colors_to_send);
|
||||
colors_sent += colors_to_send;
|
||||
colors_to_send -= colors_to_send;
|
||||
}
|
||||
else
|
||||
{
|
||||
RGBColor temp = 0x00000000;
|
||||
SendDirectColorPacket(&temp, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HyperXAlloyOriginsController::SendDirectInitialization()
|
||||
{
|
||||
unsigned char buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Direct Initialization packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x00;
|
||||
buf[0x01] = 0x04;
|
||||
buf[0x02] = 0xF2;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, buf, 65);
|
||||
}
|
||||
|
||||
void HyperXAlloyOriginsController::SendDirectColorPacket
|
||||
(
|
||||
RGBColor* color_data,
|
||||
unsigned int color_count
|
||||
)
|
||||
{
|
||||
unsigned char buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Direct Initialization packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0x00;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The maximum number of colors per packet is 16 |
|
||||
\*-----------------------------------------------------*/
|
||||
if(color_count > 16)
|
||||
{
|
||||
color_count = 16;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int color_idx = 0; color_idx < color_count; color_idx++)
|
||||
{
|
||||
buf[(color_idx * 4) + 1] = 0x81;
|
||||
buf[(color_idx * 4) + 2] = RGBGetRValue(color_data[color_idx]);
|
||||
buf[(color_idx * 4) + 3] = RGBGetGValue(color_data[color_idx]);
|
||||
buf[(color_idx * 4) + 4] = RGBGetBValue(color_data[color_idx]);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, buf, 65);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*-----------------------------------------*\
|
||||
| HyperXAlloyOriginsController.h |
|
||||
| |
|
||||
| Definitions and types for HyperX Alloy |
|
||||
| Origins RGB Keyboard lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 7/11/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
class HyperXAlloyOriginsController
|
||||
{
|
||||
public:
|
||||
HyperXAlloyOriginsController(hid_device* dev_handle);
|
||||
~HyperXAlloyOriginsController();
|
||||
|
||||
void SetLEDsDirect(std::vector<RGBColor> colors);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
|
||||
void SendDirectInitialization();
|
||||
void SendDirectColorPacket
|
||||
(
|
||||
RGBColor* color_data,
|
||||
unsigned int color_count
|
||||
);
|
||||
};
|
||||
@@ -11,26 +11,17 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
||||
static void Sleep(unsigned int milliseconds)
|
||||
{
|
||||
usleep(1000 * milliseconds);
|
||||
}
|
||||
#endif
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
static unsigned int keys[] = {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,
|
||||
0x15, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1D, 0x1E, 0x20, 0x21, 0x22, 0x23, 0x24,
|
||||
0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
|
||||
0x33, 0x34, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3E, 0x3F, 0x41, 0x44, 0x45,
|
||||
0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x51, 0x54, 0x55, 0x58, 0x59,
|
||||
0x5A, 0x5B, 0x5C, 0x5E, 0x5F, 0x61, 0x64, 0x65, 0x68, 0x69, 0x6A, 0x6B, 0x6C,
|
||||
0x6E, 0x6F, 0x74, 0x75, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x81,
|
||||
0x84, 0x85, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x91, 0x94, 0x95 };
|
||||
0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x20, 0x21, 0x22,
|
||||
0x23, 0x24, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
|
||||
0x31, 0x32, 0x33, 0x34, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3E, 0x3F, 0x41,
|
||||
0x44, 0x45, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x51, 0x54, 0x55,
|
||||
0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5E, 0x5F, 0x61, 0x64, 0x65, 0x68, 0x69, 0x6A,
|
||||
0x6B, 0x6C, 0x6E, 0x6F, 0x74, 0x75, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
|
||||
0x7F, 0x81, 0x84, 0x85, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x91,
|
||||
0x94, 0x95 };
|
||||
|
||||
static unsigned int extended_red[] = {0x08, 0x48, 0x88, 0x09, 0x89, 0x0A, 0x8A, 0x0B, 0x8B, 0x0C, 0x8C, 0x0D, 0x8D, 0x0E, 0x8F, 0x8E, 0x0F, 0x4F, 0x92, 0x13, 0x93, 0x12 };
|
||||
static unsigned int extended_grn[] = {0x29, 0x28, 0x78, 0x19, 0x79, 0x1A, 0x7A, 0x1B, 0x7B, 0x1C, 0x7C, 0x1D, 0x7D, 0x1E, 0x6E, 0x7E, 0x1F, 0x6F, 0x82, 0x23, 0x83, 0x22 };
|
||||
@@ -107,17 +98,17 @@ void HyperXKeyboardController::SetMode
|
||||
mode_colors[8]
|
||||
);
|
||||
|
||||
Sleep(100);
|
||||
std::this_thread::sleep_for(100ms);
|
||||
}
|
||||
|
||||
void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
{
|
||||
unsigned char red_color_data[104];
|
||||
unsigned char grn_color_data[104];
|
||||
unsigned char blu_color_data[104];
|
||||
unsigned char red_color_data[106];
|
||||
unsigned char grn_color_data[106];
|
||||
unsigned char blu_color_data[106];
|
||||
unsigned char ext_color_data[150];
|
||||
|
||||
for(std::size_t i = 0; i < 104; i++)
|
||||
for(std::size_t i = 0; i < 106; i++)
|
||||
{
|
||||
red_color_data[i] = RGBGetRValue(colors[i]);
|
||||
grn_color_data[i] = RGBGetGValue(colors[i]);
|
||||
@@ -126,9 +117,9 @@ void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
|
||||
for(std::size_t i = 0; i < 22; i++)
|
||||
{
|
||||
ext_color_data[extended_red[i]] = RGBGetRValue(colors[i + 104]);
|
||||
ext_color_data[extended_grn[i]] = RGBGetGValue(colors[i + 104]);
|
||||
ext_color_data[extended_blu[i]] = RGBGetBValue(colors[i + 104]);
|
||||
ext_color_data[extended_red[i]] = RGBGetRValue(colors[i + 106]);
|
||||
ext_color_data[extended_grn[i]] = RGBGetGValue(colors[i + 106]);
|
||||
ext_color_data[extended_blu[i]] = RGBGetBValue(colors[i + 106]);
|
||||
}
|
||||
|
||||
SendDirect
|
||||
@@ -137,7 +128,7 @@ void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
red_color_data
|
||||
);
|
||||
|
||||
Sleep(5);
|
||||
std::this_thread::sleep_for(5ms);
|
||||
|
||||
SendDirect
|
||||
(
|
||||
@@ -145,7 +136,7 @@ void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
grn_color_data
|
||||
);
|
||||
|
||||
Sleep(5);
|
||||
std::this_thread::sleep_for(5ms);
|
||||
|
||||
SendDirect
|
||||
(
|
||||
@@ -153,7 +144,7 @@ void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
blu_color_data
|
||||
);
|
||||
|
||||
Sleep(5);
|
||||
std::this_thread::sleep_for(5ms);
|
||||
|
||||
SendDirectExtended
|
||||
(
|
||||
@@ -163,12 +154,12 @@ void HyperXKeyboardController::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
|
||||
void HyperXKeyboardController::SetLEDs(std::vector<RGBColor> colors)
|
||||
{
|
||||
unsigned char red_color_data[104];
|
||||
unsigned char grn_color_data[104];
|
||||
unsigned char blu_color_data[104];
|
||||
unsigned char red_color_data[106];
|
||||
unsigned char grn_color_data[106];
|
||||
unsigned char blu_color_data[106];
|
||||
unsigned char ext_color_data[150];
|
||||
|
||||
for(std::size_t i = 0; i < 104; i++)
|
||||
for(std::size_t i = 0; i < 106; i++)
|
||||
{
|
||||
red_color_data[i] = RGBGetRValue(colors[i]);
|
||||
grn_color_data[i] = RGBGetGValue(colors[i]);
|
||||
@@ -177,9 +168,9 @@ void HyperXKeyboardController::SetLEDs(std::vector<RGBColor> colors)
|
||||
|
||||
for(std::size_t i = 0; i < 22; i++)
|
||||
{
|
||||
ext_color_data[extended_red[i]] = RGBGetRValue(colors[i + 104]);
|
||||
ext_color_data[extended_grn[i]] = RGBGetGValue(colors[i + 104]);
|
||||
ext_color_data[extended_blu[i]] = RGBGetBValue(colors[i + 104]);
|
||||
ext_color_data[extended_red[i]] = RGBGetRValue(colors[i + 106]);
|
||||
ext_color_data[extended_grn[i]] = RGBGetGValue(colors[i + 106]);
|
||||
ext_color_data[extended_blu[i]] = RGBGetBValue(colors[i + 106]);
|
||||
}
|
||||
|
||||
SendColor
|
||||
@@ -189,7 +180,7 @@ void HyperXKeyboardController::SetLEDs(std::vector<RGBColor> colors)
|
||||
red_color_data
|
||||
);
|
||||
|
||||
Sleep(5);
|
||||
std::this_thread::sleep_for(5ms);
|
||||
|
||||
SendColor
|
||||
(
|
||||
@@ -198,7 +189,7 @@ void HyperXKeyboardController::SetLEDs(std::vector<RGBColor> colors)
|
||||
grn_color_data
|
||||
);
|
||||
|
||||
Sleep(5);
|
||||
std::this_thread::sleep_for(5ms);
|
||||
|
||||
SendColor
|
||||
(
|
||||
@@ -207,7 +198,7 @@ void HyperXKeyboardController::SetLEDs(std::vector<RGBColor> colors)
|
||||
blu_color_data
|
||||
);
|
||||
|
||||
Sleep(5);
|
||||
std::this_thread::sleep_for(5ms);
|
||||
|
||||
SendExtendedColor
|
||||
(
|
||||
@@ -375,7 +366,7 @@ void HyperXKeyboardController::SendColor
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int i = 0; i < 104; i++)
|
||||
for(int i = 0; i < 106; i++)
|
||||
{
|
||||
buf[keys[i]] = color_data[i];
|
||||
}
|
||||
@@ -440,11 +431,12 @@ void HyperXKeyboardController::SendDirect
|
||||
buf[0x00] = 0x07;
|
||||
buf[0x01] = HYPERX_PACKET_ID_DIRECT;
|
||||
buf[0x02] = color_channel;
|
||||
buf[0x03] = 0xA0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int i = 0; i < 104; i++)
|
||||
for(int i = 0; i < 106; i++)
|
||||
{
|
||||
buf[keys[i]] = color_data[i];
|
||||
}
|
||||
@@ -473,6 +465,7 @@ void HyperXKeyboardController::SendDirectExtended
|
||||
buf[0x00] = 0x07;
|
||||
buf[0x01] = HYPERX_PACKET_ID_DIRECT;
|
||||
buf[0x02] = HYPERX_COLOR_CHANNEL_EXTENDED;
|
||||
buf[0x03] = 0xA0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data |
|
||||
|
||||
@@ -1,11 +1,38 @@
|
||||
#include "HyperXAlloyOriginsController.h"
|
||||
#include "HyperXKeyboardController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_HyperXAlloyOrigins.h"
|
||||
#include "RGBController_HyperXKeyboard.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| HyperX keyboard vendor IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define HYPERX_KEYBOARD_VID 0x0951
|
||||
#define HYPERX_ALLOY_ELITE_PID 0x16BE
|
||||
#define HYPERX_ALLOY_FPS_RGB_PID 0x16DC
|
||||
#define HYPERX_ALLOY_ORIGINS_PID 0x16E5
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned char usb_interface;
|
||||
const char * name;
|
||||
} hyperx_device;
|
||||
|
||||
#define HYPERX_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const hyperx_device device_list[] =
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_PID, 2, "HyperX Alloy Elite RGB" },
|
||||
{ HYPERX_KEYBOARD_VID, HYPERX_ALLOY_FPS_RGB_PID, 2, "HyperX Alloy FPS RGB" },
|
||||
{ HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ORIGINS_PID, 3, "HyperX Alloy Origins" },
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
@@ -22,30 +49,59 @@ void DetectHyperXKeyboardControllers(std::vector<RGBController*>& rgb_controller
|
||||
|
||||
hid_init();
|
||||
|
||||
info = hid_enumerate(HYPERX_KEYBOARD_VID, HYPERX_ALLOY_ELITE_PID);
|
||||
|
||||
//Look for HyperX Keyboard, Interface 2
|
||||
while(info)
|
||||
for(std::size_t device_idx = 0; device_idx < HYPERX_NUM_DEVICES; device_idx++)
|
||||
{
|
||||
if((info->vendor_id == HYPERX_KEYBOARD_VID)
|
||||
&&(info->product_id == HYPERX_ALLOY_ELITE_PID)
|
||||
&&(info->interface_number == 2))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
break;
|
||||
}
|
||||
else
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
//Look for HyperX RGB Peripheral
|
||||
while(info)
|
||||
{
|
||||
if((device_list[device_idx].usb_pid != HYPERX_ALLOY_ORIGINS_PID)
|
||||
&&(info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
#ifdef USE_HID_USAGE
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface)
|
||||
&&(info->usage_page == 0xFF01))
|
||||
#else
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
#endif
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
HyperXKeyboardController* controller = new HyperXKeyboardController(dev);
|
||||
|
||||
RGBController_HyperXKeyboard* rgb_controller = new RGBController_HyperXKeyboard(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
if((device_list[device_idx].usb_pid == HYPERX_ALLOY_ORIGINS_PID)
|
||||
&&(info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
HyperXAlloyOriginsController* controller = new HyperXAlloyOriginsController(dev);
|
||||
|
||||
RGBController_HyperXAlloyOrigins* rgb_controller = new RGBController_HyperXAlloyOrigins(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
|
||||
if( dev )
|
||||
{
|
||||
HyperXKeyboardController* controller = new HyperXKeyboardController(dev);
|
||||
|
||||
RGBController_HyperXKeyboard* rgb_controller = new RGBController_HyperXKeyboard(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "HyperXPulsefireSurgeController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_HyperXPulsefireSurge.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| HyperX keyboard vendor IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define HYPERX_VID 0x0951
|
||||
#define HYPERX_PULSEFIRE_SURGE_PID 0x16D3
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned char usb_interface;
|
||||
const char * name;
|
||||
} hyperx_device;
|
||||
|
||||
#define HYPERX_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const hyperx_device device_list[] =
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Mice |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ HYPERX_VID, HYPERX_PULSEFIRE_SURGE_PID, 1, "HyperX Pulsefire Surge" },
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectHyperXMouseControllers *
|
||||
* *
|
||||
* Tests the USB address to see if a HyperX Mouse controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectHyperXMouseControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev = NULL;
|
||||
|
||||
hid_init();
|
||||
|
||||
for(std::size_t device_idx = 0; device_idx < HYPERX_NUM_DEVICES; device_idx++)
|
||||
{
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
//Look for HyperX RGB Peripheral
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
HyperXPulsefireSurgeController* controller = new HyperXPulsefireSurgeController(dev);
|
||||
|
||||
RGBController_HyperXPulsefireSurge* rgb_controller = new RGBController_HyperXPulsefireSurge(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*-----------------------------------------*\
|
||||
| HyperXPulsefireSurgeController.cpp |
|
||||
| |
|
||||
| Driver for HyperX Pulsefire Surge |
|
||||
| lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 7/25/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "HyperXPulsefireSurgeController.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
HyperXPulsefireSurgeController::HyperXPulsefireSurgeController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
}
|
||||
|
||||
HyperXPulsefireSurgeController::~HyperXPulsefireSurgeController()
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*-----------------------------------------*\
|
||||
| HyperXPulsefireSurgeController.h |
|
||||
| |
|
||||
| Definitions and types for HyperX |
|
||||
| Pulsefire Surge lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 7/25/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
class HyperXPulsefireSurgeController
|
||||
{
|
||||
public:
|
||||
HyperXPulsefireSurgeController(hid_device* dev_handle);
|
||||
~HyperXPulsefireSurgeController();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
};
|
||||
@@ -0,0 +1,196 @@
|
||||
#include "LogitechG203Controller.h"
|
||||
#include "LogitechG403Controller.h"
|
||||
#include "LogitechG810Controller.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_LogitechG203.h"
|
||||
#include "RGBController_LogitechG403.h"
|
||||
#include "RGBController_LogitechG810.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Logitech vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define LOGITECH_VID 0x046D
|
||||
/*-----------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define LOGITECH_G810_1_PID 0xC337
|
||||
#define LOGITECH_G810_2_PID 0xC331
|
||||
#define LOGITECH_G512_PID 0xC342
|
||||
/*-----------------------------------------------------*\
|
||||
| Mouse product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define LOGITECH_G203_PID 0xC084
|
||||
#define LOGITECH_G403_PID 0xC083
|
||||
#define LOGITECH_G403H_PID 0xC08F
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned char usb_interface;
|
||||
device_type type;
|
||||
const char * name;
|
||||
} logitech_device;
|
||||
|
||||
#define LOGITECH_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const logitech_device device_list[] =
|
||||
{
|
||||
/*-------------------------------------------------------------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*-------------------------------------------------------------------------------------------------------------*/
|
||||
{ LOGITECH_VID, LOGITECH_G810_1_PID, 1, DEVICE_TYPE_KEYBOARD, "Logitech G810 Orion Spectrum" },
|
||||
{ LOGITECH_VID, LOGITECH_G810_2_PID, 1, DEVICE_TYPE_KEYBOARD, "Logitech G810 Orion Spectrum" },
|
||||
{ LOGITECH_VID, LOGITECH_G512_PID, 1, DEVICE_TYPE_KEYBOARD, "Logitech G512" },
|
||||
/*-------------------------------------------------------------------------------------------------------------*\
|
||||
| Mice |
|
||||
\*-------------------------------------------------------------------------------------------------------------*/
|
||||
{ LOGITECH_VID, LOGITECH_G203_PID, 1, DEVICE_TYPE_MOUSE, "Logitech G203 Prodigy" },
|
||||
{ LOGITECH_VID, LOGITECH_G403_PID, 1, DEVICE_TYPE_MOUSE, "Logitech G403 Prodigy" },
|
||||
{ LOGITECH_VID, LOGITECH_G403H_PID, 1, DEVICE_TYPE_MOUSE, "Logitech G403 Hero" },
|
||||
/*-------------------------------------------------------------------------------------------------------------*\
|
||||
| Mousemats |
|
||||
\*-------------------------------------------------------------------------------------------------------------*/
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectLogitechControllers *
|
||||
* *
|
||||
* Tests the USB address to see if a Logitech RGB Keyboard controller exists there. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectLogitechControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_init();
|
||||
|
||||
for(int device_idx = 0; device_idx < LOGITECH_NUM_DEVICES; device_idx++)
|
||||
{
|
||||
switch(device_list[device_idx].type)
|
||||
{
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| 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 |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
case DEVICE_TYPE_KEYBOARD:
|
||||
{
|
||||
hid_device_info* info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
#ifdef USE_HID_USAGE
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface)
|
||||
&&(info->usage_page == 0xFF43)
|
||||
&&(info->usage == 0x0602))
|
||||
#else
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
#endif
|
||||
{
|
||||
hid_device* dev_usage_0x0602 = hid_open_path(info->path);
|
||||
|
||||
if(dev_usage_0x0602)
|
||||
{
|
||||
#ifdef USE_HID_USAGE
|
||||
hid_device_info* tmp_info_0x0604 = info;
|
||||
|
||||
while(tmp_info_0x0604)
|
||||
{
|
||||
if((tmp_info_0x0604->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(tmp_info_0x0604->product_id == device_list[device_idx].usb_pid)
|
||||
&&(tmp_info_0x0604->interface_number == device_list[device_idx].usb_interface)
|
||||
&&(tmp_info_0x0604->usage_page == 0xFF43)
|
||||
&&(tmp_info_0x0604->usage == 0x0604))
|
||||
{
|
||||
hid_device* dev_usage_0x0604 = hid_open_path(tmp_info_0x0604->path);
|
||||
|
||||
if(dev_usage_0x0604)
|
||||
{
|
||||
LogitechG810Controller* controller = new LogitechG810Controller(dev_usage_0x0602, dev_usage_0x0604);
|
||||
|
||||
RGBController_LogitechG810* rgb_controller = new RGBController_LogitechG810(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
tmp_info_0x0604 = tmp_info_0x0604->next;
|
||||
}
|
||||
#else
|
||||
LogitechG810Controller* controller = new LogitechG810Controller(dev_usage_0x0602, dev_usage_0x0602);
|
||||
|
||||
RGBController_LogitechG810* rgb_controller = new RGBController_LogitechG810(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
hid_free_enumeration(info);
|
||||
}
|
||||
break;
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Logitech mice use a single usage on page 0xFF00 |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
case DEVICE_TYPE_MOUSE:
|
||||
{
|
||||
hid_device_info* info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
#ifdef USE_HID_USAGE
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface)
|
||||
&&(info->usage_page == 0xFF00)
|
||||
&&(info->usage == 2))
|
||||
#else
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
#endif
|
||||
{
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
switch(device_list[device_idx].usb_pid)
|
||||
{
|
||||
case LOGITECH_G203_PID:
|
||||
{
|
||||
LogitechG203Controller* controller = new LogitechG203Controller(dev);
|
||||
|
||||
RGBController_LogitechG203* rgb_controller = new RGBController_LogitechG203(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
break;
|
||||
|
||||
case LOGITECH_G403_PID:
|
||||
case LOGITECH_G403H_PID:
|
||||
{
|
||||
LogitechG403Controller* controller = new LogitechG403Controller(dev);
|
||||
|
||||
RGBController_LogitechG403* rgb_controller = new RGBController_LogitechG403(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
hid_free_enumeration(info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*-----------------------------------------*\
|
||||
| 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)
|
||||
{
|
||||
dev = dev_handle;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| 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 = 1000 + 4750 * (LOGITECH_G203_SPEED_FASTEST - 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);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*-----------------------------------------*\
|
||||
| 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,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G203_SPEED_SLOWEST = 0x00, /* Slowest speed */
|
||||
LOGITECH_G203_SPEED_SLOW = 0x01, /* Slow speed */
|
||||
LOGITECH_G203_SPEED_NORMAL = 0x02, /* Normal speed */
|
||||
LOGITECH_G203_SPEED_FAST = 0x03, /* Fast speed */
|
||||
LOGITECH_G203_SPEED_FASTEST = 0x04, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG203Controller
|
||||
{
|
||||
public:
|
||||
LogitechG203Controller(hid_device* dev_handle);
|
||||
~LogitechG203Controller();
|
||||
|
||||
void SendMouseMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
/*-----------------------------------------*\
|
||||
| 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)
|
||||
{
|
||||
dev = dev_handle;
|
||||
}
|
||||
|
||||
LogitechG403Controller::~LogitechG403Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
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 = 1000 + 4750 * (LOGITECH_G403_SPEED_FASTEST - 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);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*-----------------------------------------*\
|
||||
| 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,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G403_SPEED_SLOWEST = 0x00, /* Slowest speed */
|
||||
LOGITECH_G403_SPEED_SLOW = 0x01, /* Slow speed */
|
||||
LOGITECH_G403_SPEED_NORMAL = 0x02, /* Normal speed */
|
||||
LOGITECH_G403_SPEED_FAST = 0x03, /* Fast speed */
|
||||
LOGITECH_G403_SPEED_FASTEST = 0x04, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG403Controller
|
||||
{
|
||||
public:
|
||||
LogitechG403Controller(hid_device* dev_handle);
|
||||
~LogitechG403Controller();
|
||||
|
||||
void SendMouseMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char channel,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
};
|
||||
@@ -0,0 +1,169 @@
|
||||
/*-----------------------------------------*\
|
||||
| LogitechG810Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G810 Orion Spectrum |
|
||||
| keyboard light controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 6/11/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "LogitechG810Controller.h"
|
||||
#include <cstring>
|
||||
|
||||
LogitechG810Controller::LogitechG810Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12)
|
||||
{
|
||||
dev_pkt_0x11 = dev_handle_0x11;
|
||||
dev_pkt_0x12 = dev_handle_0x12;
|
||||
}
|
||||
|
||||
LogitechG810Controller::~LogitechG810Controller()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LogitechG810Controller::Commit()
|
||||
{
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
void LogitechG810Controller::SetDirect
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char frame_count,
|
||||
unsigned char * frame_data
|
||||
)
|
||||
{
|
||||
SendDirectFrame(zone, frame_count, frame_data);
|
||||
}
|
||||
|
||||
void LogitechG810Controller::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned short speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
SendMode(LOGITECH_G810_ZONE_MODE_KEYBOARD, mode, speed, red, green, blue);
|
||||
SendMode(LOGITECH_G810_ZONE_MODE_LOGO, mode, speed, red, green, blue);
|
||||
|
||||
SendCommit();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void LogitechG810Controller::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] = 0x0C;
|
||||
usb_buf[0x03] = 0x5D;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
|
||||
hid_read(dev_pkt_0x11, (unsigned char *)usb_buf, 20);
|
||||
}
|
||||
|
||||
void LogitechG810Controller::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] = 0x0C;
|
||||
usb_buf[0x03] = 0x3D;
|
||||
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 LogitechG810Controller::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] = 0x0D;
|
||||
usb_buf[0x03] = 0x3D;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
speed = 1000 + 4750 * (LOGITECH_G810_SPEED_FASTEST - speed);
|
||||
if(mode == LOGITECH_G810_MODE_CYCLE)
|
||||
{
|
||||
usb_buf[0x0B] = speed >> 8;
|
||||
usb_buf[0x0C] = speed & 0xFF;
|
||||
usb_buf[0x0D] = 0x64;
|
||||
}
|
||||
else if(mode == LOGITECH_G810_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,95 @@
|
||||
/*-----------------------------------------*\
|
||||
| LogitechG810Controller.h |
|
||||
| |
|
||||
| Definitions and types for Logitech G810 |
|
||||
| Orion Spectrum keyboard light controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 6/11/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_ZONE_MODE_KEYBOARD = 0x00,
|
||||
LOGITECH_G810_ZONE_MODE_LOGO = 0x01,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_ZONE_DIRECT_KEYBOARD = 0x01,
|
||||
LOGITECH_G810_ZONE_DIRECT_MEDIA = 0x02,
|
||||
LOGITECH_G810_ZONE_DIRECT_LOGO = 0x10,
|
||||
LOGITECH_G810_ZONE_DIRECT_INDICATORS = 0x40,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_MODE_OFF = 0x00,
|
||||
LOGITECH_G810_MODE_STATIC = 0x01,
|
||||
LOGITECH_G810_MODE_BREATHING = 0x02,
|
||||
LOGITECH_G810_MODE_CYCLE = 0x03,
|
||||
LOGITECH_G810_MODE_WAVE = 0x04,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G810_SPEED_SLOWEST = 0x00, /* Slowest speed */
|
||||
LOGITECH_G810_SPEED_SLOW = 0x01, /* Slow speed */
|
||||
LOGITECH_G810_SPEED_NORMAL = 0x02, /* Normal speed */
|
||||
LOGITECH_G810_SPEED_FAST = 0x03, /* Fast speed */
|
||||
LOGITECH_G810_SPEED_FASTEST = 0x04, /* Fastest speed */
|
||||
};
|
||||
|
||||
class LogitechG810Controller
|
||||
{
|
||||
public:
|
||||
LogitechG810Controller(hid_device* dev_handle_0x11, hid_device* dev_handle_0x12);
|
||||
~LogitechG810Controller();
|
||||
|
||||
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,67 @@
|
||||
/*-----------------------------------------*\
|
||||
| MSIGPUController.cpp |
|
||||
| |
|
||||
| Driver for MSI GPUs |
|
||||
| |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "MSIGPUController.h"
|
||||
#include <cstring>
|
||||
|
||||
MSIGPUController::MSIGPUController(i2c_smbus_interface* bus)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = 0x68;
|
||||
}
|
||||
|
||||
MSIGPUController::~MSIGPUController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string MSIGPUController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return(return_string);
|
||||
}
|
||||
|
||||
void MSIGPUController::SetRGB1(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_R1, red);
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_G1, green);
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_B1, blue);
|
||||
}
|
||||
|
||||
void MSIGPUController::SetRGB2(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_R2, red);
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_G2, green);
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_B2, blue);
|
||||
}
|
||||
|
||||
void MSIGPUController::SetRGB3(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_R3, red);
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_G3, green);
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_B3, blue);
|
||||
}
|
||||
|
||||
void MSIGPUController::SetMode(unsigned char mode)
|
||||
{
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_MODE, mode);
|
||||
MSIGPURegisterWrite(MSI_GPU_REG_APPLY, 0x01);
|
||||
}
|
||||
|
||||
unsigned char MSIGPUController::MSIGPURegisterRead(unsigned char reg)
|
||||
{
|
||||
return(bus->i2c_smbus_read_byte_data(dev, reg));
|
||||
}
|
||||
|
||||
void MSIGPUController::MSIGPURegisterWrite(unsigned char reg, unsigned char val)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, reg, val);
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*-----------------------------------------*\
|
||||
| MSIGPUController.h |
|
||||
| |
|
||||
| Definitions for MSI GPUs |
|
||||
| |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char msi_gpu_dev_id;
|
||||
|
||||
enum
|
||||
{
|
||||
MSI_GPU_REG_BRIGHTNESS = 0x36, /* MSI GPU Brightness Register */
|
||||
MSI_GPU_REG_SPEED = 0x38, /* MSI GPU Speed Register */
|
||||
MSI_GPU_REG_UNKNOWN = 0x26, /* MSI GPU Unknown Register */
|
||||
MSI_GPU_REG_R1 = 0x30, /* MSI GPU R1 Register */
|
||||
MSI_GPU_REG_G1 = 0x31, /* MSI GPU G1 Register */
|
||||
MSI_GPU_REG_B1 = 0x32, /* MSI GPU B1 Register */
|
||||
MSI_GPU_REG_R2 = 0x27, /* MSI GPU R2 Register */
|
||||
MSI_GPU_REG_G2 = 0x28, /* MSI GPU G2 Register */
|
||||
MSI_GPU_REG_B2 = 0x29, /* MSI GPU B2 Register */
|
||||
MSI_GPU_REG_R3 = 0x2a, /* MSI GPU R3 Register */
|
||||
MSI_GPU_REG_G3 = 0x2b, /* MSI GPU G3 Register */
|
||||
MSI_GPU_REG_B3 = 0x2c, /* MSI GPU B3 Register */
|
||||
MSI_GPU_REG_MODE = 0x22, /* MSI GPU Mode Selection Register */
|
||||
MSI_GPU_REG_APPLY = 0x3f, /* MSI GPU Apply Changes Register */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MSI_GPU_MODE_OFF = 0x01, /* OFF mode */
|
||||
MSI_GPU_MODE_RAINBOW = 0x08, /* Rainbow effect mode */
|
||||
MSI_GPU_MODE_STATIC = 0x13, /* Static color mode */
|
||||
MSI_GPU_MODE_RAINDROP = 0x1a, /* Raindrop effect mode */
|
||||
MSI_GPU_MODE_MAGIC = 0x07, /* Magic effect mode */
|
||||
MSI_GPU_MODE_PATROLLING = 0x05, /* Patrolling effect mode */
|
||||
MSI_GPU_MODE_STREAMING = 0x06, /* Streaming effect mode */
|
||||
MSI_GPU_MODE_LIGHTNING = 0x15, /* Lightning effect mode */
|
||||
MSI_GPU_MODE_WAVE = 0x1f, /* Wave effect mode */
|
||||
MSI_GPU_MODE_METEOR = 0x16, /* Meteor effect mode */
|
||||
MSI_GPU_MODE_STACK = 0x0d, /* Stack effect mode */
|
||||
MSI_GPU_MODE_RHYTHM = 0x0b, /* Rhythm effect mode */
|
||||
MSI_GPU_MODE_FLOWING = 0x09, /* Flowing effect mode */
|
||||
MSI_GPU_MODE_WHIRLING = 0x0f, /* Whirling effect mode */
|
||||
MSI_GPU_MODE_TWISTING = 0x11, /* Twisting effect mode */
|
||||
MSI_GPU_MODE_LAMINATING = 0x1d, /* Laminating effect mode */
|
||||
MSI_GPU_MODE_FADEIN = 0x14, /* Fadein effect mode */
|
||||
MSI_GPU_MODE_BREATHING = 0x04, /* Breathing effect mode */
|
||||
MSI_GPU_MODE_FLASHING = 0x02, /* Flashing effect mode */
|
||||
MSI_GPU_MODE_DOUBLEFLASHING = 0x03, /* Doubleflashing effect mode */
|
||||
};
|
||||
|
||||
class MSIGPUController
|
||||
{
|
||||
public:
|
||||
MSIGPUController(i2c_smbus_interface* bus);
|
||||
~MSIGPUController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
|
||||
void SetRGB1(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetRGB2(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetRGB3(unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
void SetMode(unsigned char mode);
|
||||
|
||||
unsigned char MSIGPURegisterRead(unsigned char reg);
|
||||
void MSIGPURegisterWrite(unsigned char reg, unsigned char val);
|
||||
|
||||
private:
|
||||
i2c_smbus_interface * bus;
|
||||
msi_gpu_dev_id dev;
|
||||
};
|
||||
@@ -0,0 +1,113 @@
|
||||
/*-----------------------------------------*\
|
||||
| MSIGPUControllerDetect.cpp |
|
||||
| |
|
||||
| Driver for MSI GPUs |
|
||||
| |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "MSIGPUController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_MSIGPU.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| NVidia vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define NVIDIA_VEN 0x10DE
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| NVidia device IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define NVIDIA_RTX2060_DEV 0x1F08
|
||||
#define NVIDIA_RTX2060S_DEV 0x1F06
|
||||
#define NVIDIA_RTX2070_DEV 0x1F02
|
||||
#define NVIDIA_RTX2070S_DEV 0x1E84
|
||||
#define NVIDIA_RTX2080_DEV 0x1E87
|
||||
#define NVIDIA_RTX2080S_DEV 0x1E81
|
||||
#define NVIDIA_RTX2080TI_DEV 0x1E07
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| MSI sub-vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define MSI_SUB_VEN 0x1462
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| MSI sub-device IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define MSI_RTX2060S_GAMING_X_SUB_DEV 0xC752
|
||||
#define MSI_RTX2070S_GAMING_X_SUB_DEV 0x373e
|
||||
#define MSI_RTX2070S_GAMING_X_TRIO_SUB_DEV 0xC726
|
||||
#define MSI_RTX2080_GAMING_X_TRIO_SUB_DEV 0x3726
|
||||
#define MSI_RTX2080S_GAMING_X_TRIO_SUB_DEV 0xC724
|
||||
#define MSI_RTX2080TI_GAMING_X_TRIO_SUB_DEV 0x3715
|
||||
#define MSI_RTX2060_GAMING_Z_6G_SUB_DEV 0x3754
|
||||
#define MSI_RTX2070_ARMOR_SUB_DEV 0x3734
|
||||
#define MSI_RTX2060S_ARMOR_OC_SUB_DEV 0xC754
|
||||
#define MSI_RTX2080_SEA_HAWK_EK_X_SUB_DEV 0x3728
|
||||
#define MSI_RTX2080TI_SEA_HAWK_EK_X_SUB_DEV 0x3717
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int pci_vendor;
|
||||
int pci_device;
|
||||
int pci_subsystem_vendor;
|
||||
int pci_subsystem_device;
|
||||
const char * name;
|
||||
} msi_gpu_pci_device;
|
||||
|
||||
#define MSI_GPU_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const msi_gpu_pci_device device_list[] =
|
||||
{
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060S_DEV, MSI_SUB_VEN, MSI_RTX2060S_GAMING_X_SUB_DEV, "MSI GeForce RTX 2060 Super Gaming X" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, MSI_SUB_VEN, MSI_RTX2070S_GAMING_X_SUB_DEV, "MSI GeForce RTX 2070 Super Gaming X" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070S_DEV, MSI_SUB_VEN, MSI_RTX2070S_GAMING_X_TRIO_SUB_DEV, "MSI GeForce RTX 2070 Super Gaming X Trio" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2080_DEV, MSI_SUB_VEN, MSI_RTX2080_GAMING_X_TRIO_SUB_DEV, "MSI GeForce RTX 2080 Gaming X Trio" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2080S_DEV, MSI_SUB_VEN, MSI_RTX2080S_GAMING_X_TRIO_SUB_DEV, "MSI GeForce RTX 2080 Super Gaming X Trio" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, MSI_SUB_VEN, MSI_RTX2080TI_GAMING_X_TRIO_SUB_DEV, "MSI GeForce RTX 2080Ti Gaming X Trio" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060_DEV, MSI_SUB_VEN, MSI_RTX2060_GAMING_Z_6G_SUB_DEV, "MSI GeForce RTX 2060 Gaming Z 6G" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2060S_DEV, MSI_SUB_VEN, MSI_RTX2060S_ARMOR_OC_SUB_DEV, "MSI GeForce RTX 2060 Super ARMOR OC" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2070_DEV, MSI_SUB_VEN, MSI_RTX2070_ARMOR_SUB_DEV, "MSI GeForce RTX 2070 ARMOR" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2080_DEV, MSI_SUB_VEN, MSI_RTX2080_SEA_HAWK_EK_X_SUB_DEV, "MSI GeForce RTX 2080 Sea Hawk EK X" },
|
||||
{ NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, MSI_SUB_VEN, MSI_RTX2080TI_SEA_HAWK_EK_X_SUB_DEV, "MSI GeForce RTX 2080Ti Sea Hawk EK X" },
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectMSIGPUControllers *
|
||||
* *
|
||||
* Detect MSI GPU controllers on the enumerated I2C busses. *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectMSIGPUControllers(std::vector<i2c_smbus_interface*> &busses, std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
MSIGPUController* new_msi_gpu;
|
||||
RGBController_MSIGPU* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
for(unsigned int dev_idx = 0; dev_idx < MSI_GPU_NUM_DEVICES; dev_idx++)
|
||||
{
|
||||
if (busses[bus]->port_id != 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(busses[bus]->pci_vendor == device_list[dev_idx].pci_vendor &&
|
||||
busses[bus]->pci_device == device_list[dev_idx].pci_device &&
|
||||
busses[bus]->pci_subsystem_vendor == device_list[dev_idx].pci_subsystem_vendor &&
|
||||
busses[bus]->pci_subsystem_device == device_list[dev_idx].pci_subsystem_device)
|
||||
{
|
||||
new_msi_gpu = new MSIGPUController(busses[bus]);
|
||||
new_controller = new RGBController_MSIGPU(new_msi_gpu);
|
||||
new_controller->name = device_list[dev_idx].name;
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* DetectMSIGPUControllers() */
|
||||
@@ -35,25 +35,34 @@ MSIMysticLightController::~MSIMysticLightController()
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int MSIMysticLightController::GetZoneMinLedCount(ZONE /*zone*/)
|
||||
unsigned int MSIMysticLightController::GetZoneMinLedCount
|
||||
(
|
||||
MSI_ZONE /*zone*/
|
||||
)
|
||||
{
|
||||
return 1u;
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int MSIMysticLightController::GetZoneMaxLedCount(ZONE zone)
|
||||
unsigned int MSIMysticLightController::GetZoneMaxLedCount
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
switch (zone)
|
||||
switch(zone)
|
||||
{
|
||||
case J_RAINBOW_1:
|
||||
case J_RAINBOW_2:
|
||||
case J_CORSAIR:
|
||||
return 4u; // TODO: It can be different by zone and by mobo
|
||||
case MSI_ZONE_J_RAINBOW_1:
|
||||
case MSI_ZONE_J_RAINBOW_2:
|
||||
case MSI_ZONE_J_CORSAIR:
|
||||
return 4; // TODO: It can be different by zone and by mobo
|
||||
default:
|
||||
return 1u;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int MSIMysticLightController::GetZoneLedCount(ZONE zone)
|
||||
unsigned int MSIMysticLightController::GetZoneLedCount
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
|
||||
|
||||
@@ -65,7 +74,11 @@ unsigned int MSIMysticLightController::GetZoneLedCount(ZONE zone)
|
||||
return requestedZone->cycle_or_led_num;
|
||||
}
|
||||
|
||||
void MSIMysticLightController::SetZoneLedCount(ZONE zone, unsigned int led_count)
|
||||
void MSIMysticLightController::SetZoneLedCount
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned int led_count
|
||||
)
|
||||
{
|
||||
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
|
||||
|
||||
@@ -78,7 +91,14 @@ void MSIMysticLightController::SetZoneLedCount(ZONE zone, unsigned int led_count
|
||||
requestedZone->cycle_or_led_num = led_count;
|
||||
}
|
||||
|
||||
void MSIMysticLightController::SetMode(ZONE zone, EFFECT mode, SPEED speed, BRIGHTNESS brightness, bool rainbow_color)
|
||||
void MSIMysticLightController::SetMode
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
MSI_MODE mode,
|
||||
MSI_SPEED speed,
|
||||
MSI_BRIGHTNESS brightness,
|
||||
bool rainbow_color
|
||||
)
|
||||
{
|
||||
ZoneData* zoneData = GetZoneData(zone);
|
||||
if(!zoneData)
|
||||
@@ -113,12 +133,18 @@ std::string MSIMysticLightController::GetSerial()
|
||||
|
||||
bool MSIMysticLightController::ReadSettings()
|
||||
{
|
||||
return hid_get_feature_report(dev, reinterpret_cast<unsigned char *>(&data), sizeof data) == sizeof data;
|
||||
/*-----------------------------------------------------*\
|
||||
| Read packet from hardware, return true if successful |
|
||||
\*-----------------------------------------------------*/
|
||||
return(hid_get_feature_report(dev, (unsigned char *)&data, sizeof(data)) == sizeof data);
|
||||
}
|
||||
|
||||
bool MSIMysticLightController::Update()
|
||||
{
|
||||
return hid_send_feature_report(dev, reinterpret_cast<unsigned char *>(&data), sizeof data) == sizeof data;
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet to hardware, return true if successful |
|
||||
\*-----------------------------------------------------*/
|
||||
return(hid_send_feature_report(dev, (unsigned char *)&data, sizeof(data)) == sizeof data);
|
||||
}
|
||||
|
||||
void MSIMysticLightController::SaveOnUpdate(bool save)
|
||||
@@ -126,26 +152,40 @@ void MSIMysticLightController::SaveOnUpdate(bool save)
|
||||
data.save_data = save;
|
||||
}
|
||||
|
||||
void MSIMysticLightController::SetZoneColor(ZONE zone, unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2)
|
||||
void MSIMysticLightController::SetZoneColor
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned char red1,
|
||||
unsigned char grn1,
|
||||
unsigned char blu1,
|
||||
unsigned char red2,
|
||||
unsigned char grn2,
|
||||
unsigned char blu2
|
||||
)
|
||||
{
|
||||
ZoneData* zoneData = GetZoneData(zone);
|
||||
|
||||
if(!zoneData)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
zoneData->color.R = r1;
|
||||
zoneData->color.G = g1;
|
||||
zoneData->color.B = b1;
|
||||
zoneData->color.R = red1;
|
||||
zoneData->color.G = grn1;
|
||||
zoneData->color.B = blu1;
|
||||
|
||||
zoneData->color2.R = r2;
|
||||
zoneData->color2.G = g2;
|
||||
zoneData->color2.B = b2;
|
||||
zoneData->color2.R = red2;
|
||||
zoneData->color2.G = grn2;
|
||||
zoneData->color2.B = blu2;
|
||||
}
|
||||
|
||||
std::pair<Color, Color> MSIMysticLightController::GetZoneColor(ZONE zone)
|
||||
std::pair<Color, Color> MSIMysticLightController::GetZoneColor
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
ZoneData *zoneData = GetZoneData(zone);
|
||||
|
||||
if (!zoneData)
|
||||
{
|
||||
return std::make_pair(Color{}, Color{});
|
||||
@@ -158,61 +198,67 @@ std::pair<Color, Color> MSIMysticLightController::GetZoneColor(ZONE zone)
|
||||
Color{zoneData->color2.R, zoneData->color2.G, zoneData->color2.B});
|
||||
}
|
||||
|
||||
ZoneData *MSIMysticLightController::GetZoneData(ZONE zone)
|
||||
ZoneData *MSIMysticLightController::GetZoneData
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
switch (zone)
|
||||
switch(zone)
|
||||
{
|
||||
case J_RGB_1:
|
||||
case MSI_ZONE_J_RGB_1:
|
||||
return &data.j_rgb_1;
|
||||
case J_RGB_2:
|
||||
case MSI_ZONE_J_RGB_2:
|
||||
return &data.j_rgb_2;
|
||||
case J_RAINBOW_1:
|
||||
case MSI_ZONE_J_RAINBOW_1:
|
||||
return &data.j_rainbow_1;
|
||||
case J_RAINBOW_2:
|
||||
case MSI_ZONE_J_RAINBOW_2:
|
||||
return &data.j_rainbow_2;
|
||||
case J_PIPE_1:
|
||||
case MSI_ZONE_J_PIPE_1:
|
||||
return &data.j_pipe_1;
|
||||
case J_PIPE_2:
|
||||
case MSI_ZONE_J_PIPE_2:
|
||||
return &data.j_pipe_2;
|
||||
case ON_BOARD_LED:
|
||||
case MSI_ZONE_ON_BOARD_LED:
|
||||
return &data.on_board_led;
|
||||
case ON_BOARD_LED_1:
|
||||
case MSI_ZONE_ON_BOARD_LED_1:
|
||||
return &data.on_board_led_1;
|
||||
case ON_BOARD_LED_2:
|
||||
case MSI_ZONE_ON_BOARD_LED_2:
|
||||
return &data.on_board_led_2;
|
||||
case ON_BOARD_LED_3:
|
||||
case MSI_ZONE_ON_BOARD_LED_3:
|
||||
return &data.on_board_led_3;
|
||||
case ON_BOARD_LED_4:
|
||||
case MSI_ZONE_ON_BOARD_LED_4:
|
||||
return &data.on_board_led_4;
|
||||
case ON_BOARD_LED_5:
|
||||
case MSI_ZONE_ON_BOARD_LED_5:
|
||||
return &data.on_board_led_5;
|
||||
case ON_BOARD_LED_6:
|
||||
case MSI_ZONE_ON_BOARD_LED_6:
|
||||
return &data.on_board_led_6;
|
||||
case ON_BOARD_LED_7:
|
||||
case MSI_ZONE_ON_BOARD_LED_7:
|
||||
return &data.on_board_led_7;
|
||||
case ON_BOARD_LED_8:
|
||||
case MSI_ZONE_ON_BOARD_LED_8:
|
||||
return &data.on_board_led_8;
|
||||
case ON_BOARD_LED_9:
|
||||
case MSI_ZONE_ON_BOARD_LED_9:
|
||||
return &data.on_board_led_9;
|
||||
case J_CORSAIR_OUTERLL120:
|
||||
case MSI_ZONE_J_CORSAIR_OUTERLL120:
|
||||
return &data.j_corsair_outerll120;
|
||||
default:
|
||||
case J_CORSAIR:
|
||||
case MSI_ZONE_J_CORSAIR:
|
||||
break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RainbowZoneData *MSIMysticLightController::GetRainbowZoneData(ZONE zone)
|
||||
RainbowZoneData *MSIMysticLightController::GetRainbowZoneData
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
switch (zone)
|
||||
switch(zone)
|
||||
{
|
||||
case J_RAINBOW_1:
|
||||
case MSI_ZONE_J_RAINBOW_1:
|
||||
return &data.j_rainbow_1;
|
||||
case J_RAINBOW_2:
|
||||
case MSI_ZONE_J_RAINBOW_2:
|
||||
return &data.j_rainbow_2;
|
||||
case J_CORSAIR:
|
||||
case MSI_ZONE_J_CORSAIR:
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
@@ -220,39 +266,98 @@ RainbowZoneData *MSIMysticLightController::GetRainbowZoneData(ZONE zone)
|
||||
|
||||
bool MSIMysticLightController::ReadFwVersion()
|
||||
{
|
||||
// First read the APROM
|
||||
// Checksum also available at report ID 180, with highCheksum stored at index 8, and low at 9
|
||||
int num = 1;
|
||||
unsigned char request[64] = {1, 176};
|
||||
unsigned char request[64];
|
||||
unsigned char response[64];
|
||||
int ret_val = 64;
|
||||
|
||||
std::fill_n(request + 2, sizeof request - 2, 204);
|
||||
num &= hid_write(dev, request, 64);
|
||||
num &= hid_read(dev, response, 64);
|
||||
/*-----------------------------------------------------*\
|
||||
| First read the APROM |
|
||||
| Checksum also available at report ID 180, with MSB |
|
||||
| stored at index 0x08 and LSB at 0x09 |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffers |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(request, 0x00, sizeof(request));
|
||||
memset(response, 0x00, sizeof(response));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up APROM Firmware Version Request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
request[0x00] = 0x01;
|
||||
request[0x01] = 0xB0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill request from 0x02 to 0x61 with 0xCC |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(&request[0x02], 0xCC, sizeof(request) - 2);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send request and receive response packets |
|
||||
\*-----------------------------------------------------*/
|
||||
ret_val &= hid_write(dev, request, 64);
|
||||
ret_val &= hid_read(dev, response, 64);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Extract high and low values from response |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char highValue = response[2] >> 4;
|
||||
unsigned char lowValue = response[2] & 15;
|
||||
unsigned char lowValue = response[2] & 0x0F;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Build firmware string <high>.<low> |
|
||||
\*-----------------------------------------------------*/
|
||||
version_APROM = std::to_string(static_cast<int>(highValue)).append(".").append(std::to_string(static_cast<int>(lowValue)));
|
||||
|
||||
// Now read the LDROM
|
||||
// Checksum also available at report ID 184, with highCheksum stored at index 8, and low at 9
|
||||
request[1] = 182u;
|
||||
num &= hid_write(dev, request, 64);
|
||||
num &= hid_read(dev, response, 64);
|
||||
/*-----------------------------------------------------*\
|
||||
| First read the LDROM |
|
||||
| Checksum also available at report ID 184, with MSB |
|
||||
| stored at index 0x08 and LSB at 0x09 |
|
||||
\*-----------------------------------------------------*/
|
||||
|
||||
highValue = response[2] >> 4u;
|
||||
lowValue = response[2] & 15u;
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up LDROM Firmware Version Request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
request[0x00] = 0x01;
|
||||
request[0x01] = 0xB6;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send request and receive response packets |
|
||||
\*-----------------------------------------------------*/
|
||||
ret_val &= hid_write(dev, request, 64);
|
||||
ret_val &= hid_read(dev, response, 64);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Extract high and low values from response |
|
||||
\*-----------------------------------------------------*/
|
||||
highValue = response[2] >> 4;
|
||||
lowValue = response[2] & 0x0F;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Build firmware string <high>.<low> |
|
||||
\*-----------------------------------------------------*/
|
||||
version_LDROM = std::to_string(static_cast<int>(highValue)).append(".").append(std::to_string(static_cast<int>(lowValue)));
|
||||
|
||||
return num == 1;
|
||||
/*-----------------------------------------------------*\
|
||||
| If return value is zero it means an HID transfer |
|
||||
| failed |
|
||||
\*-----------------------------------------------------*/
|
||||
return(ret_val > 0);
|
||||
}
|
||||
|
||||
void MSIMysticLightController::ReadSerial()
|
||||
{
|
||||
wchar_t serial[256];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get the serial number string from HID |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_get_serial_number_string(dev, serial, 256);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Convert wchar_t into std::wstring into std::string |
|
||||
\*-----------------------------------------------------*/
|
||||
std::wstring wserial = std::wstring(serial);
|
||||
chip_id = std::string(wserial.begin(), wserial.end());
|
||||
}
|
||||
@@ -260,27 +365,53 @@ void MSIMysticLightController::ReadSerial()
|
||||
void MSIMysticLightController::ReadName()
|
||||
{
|
||||
wchar_t tname[256];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get the manufacturer string from HID |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_get_manufacturer_string(dev, tname, 256);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Convert wchar_t into std::wstring into std::string |
|
||||
\*-----------------------------------------------------*/
|
||||
std::wstring wname = std::wstring(tname);
|
||||
name = std::string(wname.begin(), wname.end());
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get the product string from HID |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_get_product_string(dev, tname, 256);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Append the product string to the manufacturer string |
|
||||
\*-----------------------------------------------------*/
|
||||
wname = std::wstring(tname);
|
||||
name.append(" ").append(std::string(wname.begin(), wname.end()));
|
||||
}
|
||||
|
||||
void MSIMysticLightController::SetDeviceSettings(bool is_fan, FAN_TYPE fan_type,
|
||||
unsigned char corsair_device_quantity,
|
||||
bool is_LL120Outer_individual)
|
||||
void MSIMysticLightController::SetDeviceSettings
|
||||
(
|
||||
bool is_fan,
|
||||
MSI_FAN_TYPE fan_type,
|
||||
unsigned char corsair_device_quantity,
|
||||
bool is_LL120Outer_individual
|
||||
)
|
||||
{
|
||||
// If is_fan false, it is a stripe
|
||||
CorsairZoneData &settingsZone = data.j_corsair;
|
||||
settingsZone.fan_flags = (settingsZone.fan_flags & 128u) | fan_type << 1u | is_fan;
|
||||
settingsZone.corsair_quantity = corsair_device_quantity << 2u;
|
||||
settingsZone.is_individual = BitSet(settingsZone.is_individual, is_LL120Outer_individual, 0u);
|
||||
/*-----------------------------------------------------*\
|
||||
| If is_fan is false, it is an LED strip |
|
||||
\*-----------------------------------------------------*/
|
||||
CorsairZoneData &settingsZone = data.j_corsair;
|
||||
settingsZone.fan_flags = (settingsZone.fan_flags & 0x80) | fan_type << 1 | is_fan;
|
||||
settingsZone.corsair_quantity = corsair_device_quantity << 2;
|
||||
settingsZone.is_individual = BitSet(settingsZone.is_individual, is_LL120Outer_individual, 0);
|
||||
}
|
||||
|
||||
bool MSIMysticLightController::SetVolume(unsigned char main, unsigned char left, unsigned char right)
|
||||
bool MSIMysticLightController::SetVolume
|
||||
(
|
||||
unsigned char main,
|
||||
unsigned char left,
|
||||
unsigned char right
|
||||
)
|
||||
{
|
||||
unsigned char packet[64];
|
||||
std::fill_n(packet, sizeof packet, 204u);
|
||||
@@ -309,41 +440,78 @@ bool MSIMysticLightController::SetVolume(unsigned char main, unsigned char left,
|
||||
return hid_write(dev, packet, sizeof packet);
|
||||
}
|
||||
|
||||
void MSIMysticLightController::SetBoardSyncSettings(bool onboard_sync, bool combine_JRGB, bool combine_JPIPE1,
|
||||
bool combine_JPIPE2, bool combine_JRAINBOW1, bool combine_JRAINBOW2,
|
||||
bool combine_crossair)
|
||||
void MSIMysticLightController::SetBoardSyncSettings
|
||||
(
|
||||
bool onboard_sync,
|
||||
bool combine_JRGB,
|
||||
bool combine_JPIPE1,
|
||||
bool combine_JPIPE2,
|
||||
bool combine_JRAINBOW1,
|
||||
bool combine_JRAINBOW2,
|
||||
bool combine_crossair
|
||||
)
|
||||
{
|
||||
ZoneData &syncZone = data.on_board_led;
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, onboard_sync, 0u);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JRAINBOW1, 1u);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JRAINBOW2, 2u);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_crossair, 3u);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JPIPE1, 4u);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JPIPE2, 5u);
|
||||
|
||||
syncZone.speedAndBrightnessFlags = BitSet(syncZone.speedAndBrightnessFlags, combine_JRGB, 7u);
|
||||
/*-----------------------------------------------------*\
|
||||
| Set sync flags for on-board LED zone |
|
||||
\*-----------------------------------------------------*/
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, onboard_sync, 0);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JRAINBOW1, 1);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JRAINBOW2, 2);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_crossair, 3);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JPIPE1, 4);
|
||||
syncZone.colorFlags = BitSet(syncZone.colorFlags, combine_JPIPE2, 5);
|
||||
|
||||
syncZone.speedAndBrightnessFlags = BitSet(syncZone.speedAndBrightnessFlags, combine_JRGB, 7);
|
||||
}
|
||||
|
||||
void MSIMysticLightController::GetMode(ZONE zone, EFFECT &mode, SPEED &speed, BRIGHTNESS &brightness, bool &rainbow_color)
|
||||
void MSIMysticLightController::GetMode
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
MSI_MODE &mode,
|
||||
MSI_SPEED &speed,
|
||||
MSI_BRIGHTNESS &brightness,
|
||||
bool &rainbow_color
|
||||
)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Get data for given zone |
|
||||
\*-----------------------------------------------------*/
|
||||
ZoneData *zoneData = GetZoneData(zone);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Return if zone is invalid |
|
||||
\*-----------------------------------------------------*/
|
||||
if (!zoneData)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mode = static_cast<EFFECT>(zoneData->effect);
|
||||
speed = static_cast<SPEED>(zoneData->speedAndBrightnessFlags & 3u);
|
||||
brightness = static_cast<BRIGHTNESS>((zoneData->speedAndBrightnessFlags >> 2u) & 31u);
|
||||
rainbow_color = (zoneData->colorFlags & 128u) >> 7u;
|
||||
/*-----------------------------------------------------*\
|
||||
| Update pointers with data |
|
||||
\*-----------------------------------------------------*/
|
||||
mode = (MSI_MODE)(zoneData->effect);
|
||||
speed = (MSI_SPEED)(zoneData->speedAndBrightnessFlags & 0x03);
|
||||
brightness = (MSI_BRIGHTNESS)((zoneData->speedAndBrightnessFlags >> 2) & 0x1F);
|
||||
rainbow_color = (zoneData->colorFlags & 0x80) >> 7;
|
||||
}
|
||||
|
||||
unsigned char MSIMysticLightController::BitSet(unsigned char value, bool bit, unsigned int position)
|
||||
unsigned char MSIMysticLightController::BitSet
|
||||
(
|
||||
unsigned char value,
|
||||
bool bit,
|
||||
unsigned int position
|
||||
)
|
||||
{
|
||||
return static_cast<unsigned char>(std::bitset<8>(value).set(position, bit).to_ulong());
|
||||
}
|
||||
|
||||
void MSIMysticLightController::SetCycleCount(ZONE zone, unsigned char cycle_num)
|
||||
void MSIMysticLightController::SetCycleCount
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned char cycle_num
|
||||
)
|
||||
{
|
||||
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
|
||||
|
||||
@@ -355,7 +523,10 @@ void MSIMysticLightController::SetCycleCount(ZONE zone, unsigned char cycle_num)
|
||||
requestedZone->cycle_or_led_num = cycle_num;
|
||||
}
|
||||
|
||||
unsigned char MSIMysticLightController::GetCycleCount(ZONE zone)
|
||||
unsigned char MSIMysticLightController::GetCycleCount
|
||||
(
|
||||
MSI_ZONE zone
|
||||
)
|
||||
{
|
||||
RainbowZoneData *requestedZone = GetRainbowZoneData(zone);
|
||||
|
||||
@@ -367,28 +538,43 @@ unsigned char MSIMysticLightController::GetCycleCount(ZONE zone)
|
||||
return requestedZone->cycle_or_led_num;
|
||||
}
|
||||
|
||||
void MSIMysticLightController::GetBoardSyncSettings(bool &onboard_sync, bool &combine_JRGB, bool &combine_JPIPE1,
|
||||
bool &combine_JPIPE2, bool &combine_JRAINBOW1,
|
||||
bool &combine_JRAINBOW2, bool &combine_crossair)
|
||||
void MSIMysticLightController::GetBoardSyncSettings
|
||||
(
|
||||
bool &onboard_sync,
|
||||
bool &combine_JRGB,
|
||||
bool &combine_JPIPE1,
|
||||
bool &combine_JPIPE2,
|
||||
bool &combine_JRAINBOW1,
|
||||
bool &combine_JRAINBOW2,
|
||||
bool &combine_crossair
|
||||
)
|
||||
{
|
||||
ZoneData &syncZone = data.on_board_led;
|
||||
onboard_sync = syncZone.colorFlags & 1u;
|
||||
combine_JRAINBOW1 = syncZone.colorFlags >> 1u & 1u;
|
||||
combine_JRAINBOW2 = syncZone.colorFlags >> 1u & 1u;
|
||||
combine_crossair = syncZone.colorFlags >> 3u & 1u;
|
||||
combine_JPIPE1 = syncZone.colorFlags >> 4u & 1u;
|
||||
combine_JPIPE2 = syncZone.colorFlags >> 5u & 1u;
|
||||
|
||||
combine_JRGB = (syncZone.speedAndBrightnessFlags & 128u) >> 7u;
|
||||
/*-----------------------------------------------------*\
|
||||
| Get sync flags for on-board LED zone |
|
||||
\*-----------------------------------------------------*/
|
||||
onboard_sync = (syncZone.colorFlags >> 0) & 0x01;
|
||||
combine_JRAINBOW1 = (syncZone.colorFlags >> 1) & 0x01;
|
||||
combine_JRAINBOW2 = (syncZone.colorFlags >> 2) & 0x01;
|
||||
combine_crossair = (syncZone.colorFlags >> 3) & 0x01;
|
||||
combine_JPIPE1 = (syncZone.colorFlags >> 4) & 0x01;
|
||||
combine_JPIPE2 = (syncZone.colorFlags >> 5) & 0x01;
|
||||
|
||||
combine_JRGB = (syncZone.speedAndBrightnessFlags & 0x80) >> 7;
|
||||
}
|
||||
|
||||
void MSIMysticLightController::GetDeviceSettings(bool &stripe_or_fan, FAN_TYPE &fan_type,
|
||||
unsigned char &corsair_device_quantity,
|
||||
bool &is_LL120Outer_individual)
|
||||
void MSIMysticLightController::GetDeviceSettings
|
||||
(
|
||||
bool &stripe_or_fan,
|
||||
MSI_FAN_TYPE &fan_type,
|
||||
unsigned char &corsair_device_quantity,
|
||||
bool &is_LL120Outer_individual
|
||||
)
|
||||
{
|
||||
CorsairZoneData &settingsZone = data.j_corsair;
|
||||
stripe_or_fan = settingsZone.fan_flags & 1u;
|
||||
fan_type = static_cast<FAN_TYPE >((settingsZone.fan_flags & 14u) >> 1u);
|
||||
corsair_device_quantity = (settingsZone.corsair_quantity & 252u) >> 2u;
|
||||
is_LL120Outer_individual = settingsZone.is_individual & 1u;
|
||||
CorsairZoneData &settingsZone = data.j_corsair;
|
||||
stripe_or_fan = settingsZone.fan_flags & 0x01;
|
||||
fan_type = (MSI_FAN_TYPE )((settingsZone.fan_flags & 14u) >> 1);
|
||||
corsair_device_quantity = (settingsZone.corsair_quantity & 0xFC) >> 2;
|
||||
is_LL120Outer_individual = settingsZone.is_individual & 0x01;
|
||||
}
|
||||
|
||||
@@ -14,105 +14,105 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
enum ZONE
|
||||
enum MSI_ZONE
|
||||
{
|
||||
J_RGB_1 = 1,
|
||||
J_RGB_2 = 174,
|
||||
J_PIPE_1 = 11,
|
||||
J_PIPE_2 = 21,
|
||||
J_RAINBOW_1 = 31,
|
||||
J_RAINBOW_2 = 42,
|
||||
J_CORSAIR = 53,
|
||||
J_CORSAIR_OUTERLL120 = 64,
|
||||
ON_BOARD_LED = 74,
|
||||
ON_BOARD_LED_1 = 84,
|
||||
ON_BOARD_LED_2 = 94,
|
||||
ON_BOARD_LED_3 = 104,
|
||||
ON_BOARD_LED_4 = 114,
|
||||
ON_BOARD_LED_5 = 124,
|
||||
ON_BOARD_LED_6 = 134,
|
||||
ON_BOARD_LED_7 = 144,
|
||||
ON_BOARD_LED_8 = 154,
|
||||
ON_BOARD_LED_9 = 164
|
||||
MSI_ZONE_J_RGB_1 = 1,
|
||||
MSI_ZONE_J_RGB_2 = 174,
|
||||
MSI_ZONE_J_PIPE_1 = 11,
|
||||
MSI_ZONE_J_PIPE_2 = 21,
|
||||
MSI_ZONE_J_RAINBOW_1 = 31,
|
||||
MSI_ZONE_J_RAINBOW_2 = 42,
|
||||
MSI_ZONE_J_CORSAIR = 53,
|
||||
MSI_ZONE_J_CORSAIR_OUTERLL120 = 64,
|
||||
MSI_ZONE_ON_BOARD_LED = 74,
|
||||
MSI_ZONE_ON_BOARD_LED_1 = 84,
|
||||
MSI_ZONE_ON_BOARD_LED_2 = 94,
|
||||
MSI_ZONE_ON_BOARD_LED_3 = 104,
|
||||
MSI_ZONE_ON_BOARD_LED_4 = 114,
|
||||
MSI_ZONE_ON_BOARD_LED_5 = 124,
|
||||
MSI_ZONE_ON_BOARD_LED_6 = 134,
|
||||
MSI_ZONE_ON_BOARD_LED_7 = 144,
|
||||
MSI_ZONE_ON_BOARD_LED_8 = 154,
|
||||
MSI_ZONE_ON_BOARD_LED_9 = 164
|
||||
};
|
||||
|
||||
struct ZoneDescription
|
||||
{
|
||||
std::string name;
|
||||
ZONE value;
|
||||
MSI_ZONE value;
|
||||
};
|
||||
|
||||
enum EFFECT
|
||||
enum MSI_MODE
|
||||
{
|
||||
DISABLE,
|
||||
STATIC,
|
||||
BREATHING,
|
||||
FLASHING,
|
||||
DOUBLE_FLASHING,
|
||||
LIGHTNING,
|
||||
MSI_MARQUEE,
|
||||
METEOR,
|
||||
WATER_DROP,
|
||||
MSI_RAINBOW,
|
||||
POP,
|
||||
RAP,
|
||||
JAZZ,
|
||||
PLAY,
|
||||
MOVIE,
|
||||
COLOR_RING,
|
||||
PLANETARY,
|
||||
DOUBLE_METEOR,
|
||||
ENERGY,
|
||||
BLINK,
|
||||
CLOCK,
|
||||
COLOR_PULSE,
|
||||
COLOR_SHIFT,
|
||||
COLOR_WAVE,
|
||||
MARQUEE,
|
||||
RAINBOW,
|
||||
RAINBOW_WAVE,
|
||||
VISOR,
|
||||
JRAINBOW,
|
||||
RAINBOW_FLASHING,
|
||||
RAINBOW_DOUBLE_FLASHING,
|
||||
RANDOM,
|
||||
FAN_CONTROL,
|
||||
DISABLE_2,
|
||||
COLOR_RING_FLASHING,
|
||||
COLOR_RING_DOUBLE_FLASHING,
|
||||
STACK,
|
||||
CORSAIR_QUE,
|
||||
FIRE,
|
||||
LAVA
|
||||
MSI_MODE_DISABLE = 0,
|
||||
MSI_MODE_STATIC = 1,
|
||||
MSI_MODE_BREATHING = 2,
|
||||
MSI_MODE_FLASHING = 3,
|
||||
MSI_MODE_DOUBLE_FLASHING = 4,
|
||||
MSI_MODE_LIGHTNING = 5,
|
||||
MSI_MODE_MSI_MARQUEE = 6,
|
||||
MSI_MODE_METEOR = 7,
|
||||
MSI_MODE_WATER_DROP = 8,
|
||||
MSI_MODE_MSI_RAINBOW = 9,
|
||||
MSI_MODE_POP = 10,
|
||||
MSI_MODE_RAP = 11,
|
||||
MSI_MODE_JAZZ = 12,
|
||||
MSI_MODE_PLAY = 13,
|
||||
MSI_MODE_MOVIE = 14,
|
||||
MSI_MODE_COLOR_RING = 15,
|
||||
MSI_MODE_PLANETARY = 16,
|
||||
MSI_MODE_DOUBLE_METEOR = 17,
|
||||
MSI_MODE_ENERGY = 18,
|
||||
MSI_MODE_BLINK = 19,
|
||||
MSI_MODE_CLOCK = 20,
|
||||
MSI_MODE_COLOR_PULSE = 21,
|
||||
MSI_MODE_COLOR_SHIFT = 22,
|
||||
MSI_MODE_COLOR_WAVE = 23,
|
||||
MSI_MODE_MARQUEE = 24,
|
||||
MSI_MODE_RAINBOW = 25,
|
||||
MSI_MODE_RAINBOW_WAVE = 26,
|
||||
MSI_MODE_VISOR = 27,
|
||||
MSI_MODE_JRAINBOW = 28,
|
||||
MSI_MODE_RAINBOW_FLASHING = 29,
|
||||
MSI_MODE_RAINBOW_DOUBLE_FLASHING = 30,
|
||||
MSI_MODE_RANDOM = 31,
|
||||
MSI_MODE_FAN_CONTROL = 32,
|
||||
MSI_MODE_DISABLE_2 = 33,
|
||||
MSI_MODE_COLOR_RING_FLASHING = 34,
|
||||
MSI_MODE_COLOR_RING_DOUBLE_FLASHING = 35,
|
||||
MSI_MODE_STACK = 36,
|
||||
MSI_MODE_CORSAIR_QUE = 37,
|
||||
MSI_MODE_FIRE = 38,
|
||||
MSI_MODE_LAVA = 39,
|
||||
};
|
||||
|
||||
enum SPEED
|
||||
enum MSI_SPEED
|
||||
{
|
||||
LOW,
|
||||
MEDIUM,
|
||||
HIGH
|
||||
MSI_SPEED_LOW = 0,
|
||||
MSI_SPEED_MEDIUM = 1,
|
||||
MSI_SPEED_HIGH = 2,
|
||||
};
|
||||
|
||||
enum FAN_TYPE
|
||||
enum MSI_FAN_TYPE
|
||||
{
|
||||
SP,
|
||||
HD,
|
||||
LL
|
||||
MSI_FAN_TYPE_SP = 0,
|
||||
MSI_FAN_TYPE_HD = 1,
|
||||
MSI_FAN_TYPE_LL = 2,
|
||||
};
|
||||
|
||||
enum BRIGHTNESS
|
||||
enum MSI_BRIGHTNESS
|
||||
{
|
||||
OFF,
|
||||
LEVEL_10,
|
||||
LEVEL_20,
|
||||
LEVEL_30,
|
||||
LEVEL_40,
|
||||
LEVEL_50,
|
||||
LEVEL_60,
|
||||
LEVEL_70,
|
||||
LEVEL_80,
|
||||
LEVEL_90,
|
||||
LEVEL_100
|
||||
MSI_BRIGHTNESS_OFF = 0,
|
||||
MSI_BRIGHTNESS_LEVEL_10 = 1,
|
||||
MSI_BRIGHTNESS_LEVEL_20 = 2,
|
||||
MSI_BRIGHTNESS_LEVEL_30 = 3,
|
||||
MSI_BRIGHTNESS_LEVEL_40 = 4,
|
||||
MSI_BRIGHTNESS_LEVEL_50 = 5,
|
||||
MSI_BRIGHTNESS_LEVEL_60 = 6,
|
||||
MSI_BRIGHTNESS_LEVEL_70 = 7,
|
||||
MSI_BRIGHTNESS_LEVEL_80 = 8,
|
||||
MSI_BRIGHTNESS_LEVEL_90 = 9,
|
||||
MSI_BRIGHTNESS_LEVEL_100 = 10,
|
||||
};
|
||||
|
||||
struct Color
|
||||
@@ -124,54 +124,51 @@ struct Color
|
||||
|
||||
struct CorsairZoneData
|
||||
{
|
||||
unsigned char effect = EFFECT::STATIC;
|
||||
Color color { std::numeric_limits<unsigned char>::max(), 0, 0 };
|
||||
unsigned char fan_flags = 40;
|
||||
unsigned char effect = MSI_MODE_STATIC;
|
||||
Color color { 0, 0, 0 };
|
||||
unsigned char fan_flags = 40;
|
||||
unsigned char corsair_quantity;
|
||||
unsigned char padding[3];
|
||||
|
||||
unsigned char is_individual = 0;
|
||||
unsigned char is_individual = 0;
|
||||
};
|
||||
|
||||
struct ZoneData
|
||||
{
|
||||
unsigned char effect = EFFECT::STATIC;
|
||||
Color color { std::numeric_limits<unsigned char>::max(), 0u, 0u };
|
||||
unsigned char speedAndBrightnessFlags = 40u;
|
||||
Color color2 { 0, std::numeric_limits<unsigned char>::max(), 0u };
|
||||
unsigned char colorFlags = 128u;
|
||||
|
||||
const unsigned char padding = 0u;
|
||||
unsigned char effect = MSI_MODE_STATIC;
|
||||
Color color { 0, 0, 0 };
|
||||
unsigned char speedAndBrightnessFlags = 40;
|
||||
Color color2 { 0, 0, 0 };
|
||||
unsigned char colorFlags = 128;
|
||||
const unsigned char padding = 0;
|
||||
};
|
||||
|
||||
struct RainbowZoneData : ZoneData
|
||||
{
|
||||
unsigned char cycle_or_led_num = 20u;
|
||||
unsigned char cycle_or_led_num = 20;
|
||||
};
|
||||
|
||||
struct FeaturePacket
|
||||
{
|
||||
const unsigned char report_id = 82u; // Report ID
|
||||
ZoneData j_rgb_1; // 1
|
||||
ZoneData j_pipe_1; // 11
|
||||
ZoneData j_pipe_2; // 21
|
||||
RainbowZoneData j_rainbow_1; // 31
|
||||
RainbowZoneData j_rainbow_2; // 42
|
||||
CorsairZoneData j_corsair; // 53
|
||||
ZoneData j_corsair_outerll120; // 64
|
||||
ZoneData on_board_led; // 74
|
||||
ZoneData on_board_led_1; // 84
|
||||
ZoneData on_board_led_2; // 94
|
||||
ZoneData on_board_led_3; // 104
|
||||
ZoneData on_board_led_4; // 114
|
||||
ZoneData on_board_led_5; // 124
|
||||
ZoneData on_board_led_6; // 134
|
||||
ZoneData on_board_led_7; // 144
|
||||
ZoneData on_board_led_8; // 154
|
||||
ZoneData on_board_led_9; // 164
|
||||
ZoneData j_rgb_2; // 174
|
||||
|
||||
unsigned char save_data = 0u; // 184
|
||||
const unsigned char report_id = 0x52; // Report ID
|
||||
ZoneData j_rgb_1; // 1
|
||||
ZoneData j_pipe_1; // 11
|
||||
ZoneData j_pipe_2; // 21
|
||||
RainbowZoneData j_rainbow_1; // 31
|
||||
RainbowZoneData j_rainbow_2; // 42
|
||||
CorsairZoneData j_corsair; // 53
|
||||
ZoneData j_corsair_outerll120; // 64
|
||||
ZoneData on_board_led; // 74
|
||||
ZoneData on_board_led_1; // 84
|
||||
ZoneData on_board_led_2; // 94
|
||||
ZoneData on_board_led_3; // 104
|
||||
ZoneData on_board_led_4; // 114
|
||||
ZoneData on_board_led_5; // 124
|
||||
ZoneData on_board_led_6; // 134
|
||||
ZoneData on_board_led_7; // 144
|
||||
ZoneData on_board_led_8; // 154
|
||||
ZoneData on_board_led_9; // 164
|
||||
ZoneData j_rgb_2; // 174
|
||||
unsigned char save_data = 0; // 184
|
||||
};
|
||||
|
||||
|
||||
@@ -181,25 +178,116 @@ public:
|
||||
MSIMysticLightController(hid_device* handle, const char *path);
|
||||
~MSIMysticLightController();
|
||||
|
||||
unsigned int GetZoneMinLedCount(ZONE zone);
|
||||
unsigned int GetZoneMaxLedCount(ZONE zone);
|
||||
unsigned int GetZoneLedCount(ZONE zone);
|
||||
void SetZoneLedCount(ZONE zone, unsigned int led_count);
|
||||
unsigned int GetZoneMinLedCount
|
||||
(
|
||||
MSI_ZONE zone
|
||||
);
|
||||
|
||||
unsigned int GetZoneMaxLedCount
|
||||
(
|
||||
MSI_ZONE zone
|
||||
);
|
||||
|
||||
unsigned int GetZoneLedCount
|
||||
(
|
||||
MSI_ZONE zone
|
||||
);
|
||||
|
||||
void SetZoneLedCount
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned int led_count
|
||||
);
|
||||
|
||||
void SetMode
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
MSI_MODE mode,
|
||||
MSI_SPEED speed,
|
||||
MSI_BRIGHTNESS brightness,
|
||||
bool rainbow_color
|
||||
);
|
||||
|
||||
void GetMode
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
MSI_MODE &mode,
|
||||
MSI_SPEED &speed,
|
||||
MSI_BRIGHTNESS &brightness,
|
||||
bool &rainbow_color
|
||||
);
|
||||
|
||||
void SetZoneColor
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned char red1,
|
||||
unsigned char grn1,
|
||||
unsigned char blu1,
|
||||
unsigned char red2,
|
||||
unsigned char grn2,
|
||||
unsigned char blu2
|
||||
);
|
||||
|
||||
void SetCycleCount
|
||||
(
|
||||
MSI_ZONE zone,
|
||||
unsigned char cycle_num
|
||||
);
|
||||
|
||||
unsigned char GetCycleCount
|
||||
(
|
||||
MSI_ZONE zone
|
||||
);
|
||||
|
||||
void SetMode(ZONE zone, EFFECT mode, SPEED speed, BRIGHTNESS brightness, bool rainbow_color);
|
||||
void GetMode(ZONE zone, EFFECT &mode, SPEED &speed, BRIGHTNESS &brightness, bool &rainbow_color);
|
||||
void SetZoneColor(ZONE zone, unsigned char r1, unsigned char g1, unsigned char b1, unsigned char r2, unsigned char g2, unsigned char b2);
|
||||
void SetCycleCount(ZONE zone, unsigned char cycle_num);
|
||||
unsigned char GetCycleCount(ZONE zone);
|
||||
std::pair<Color, Color>
|
||||
GetZoneColor(ZONE zone);
|
||||
GetZoneColor(MSI_ZONE zone);
|
||||
|
||||
bool Update();
|
||||
|
||||
void SetDeviceSettings(bool stripe_or_fan, FAN_TYPE fan_type, unsigned char corsair_device_quantity, bool is_LL120Outer_individual);
|
||||
void GetDeviceSettings(bool &stripe_or_fan, FAN_TYPE &fan_type, unsigned char &corsair_device_quantity, bool &is_LL120Outer_individual);
|
||||
bool SetVolume(unsigned char main, unsigned char left, unsigned char right);
|
||||
void SetBoardSyncSettings(bool onboard_sync, bool combine_JRGB, bool combine_JPIPE1, bool combine_JPIPE2, bool combine_JRAINBOW1, bool combine_JRAINBOW2, bool combine_crossair);
|
||||
void GetBoardSyncSettings(bool &onboard_sync, bool &combine_JRGB, bool &combine_JPIPE1, bool &combine_JPIPE2, bool &combine_JRAINBOW1, bool &combine_JRAINBOW2, bool &combine_crossair);
|
||||
void SetDeviceSettings
|
||||
(
|
||||
bool stripe_or_fan,
|
||||
MSI_FAN_TYPE fan_type,
|
||||
unsigned char corsair_device_quantity,
|
||||
bool is_LL120Outer_individual
|
||||
);
|
||||
|
||||
void GetDeviceSettings
|
||||
(
|
||||
bool &stripe_or_fan,
|
||||
MSI_FAN_TYPE &fan_type,
|
||||
unsigned char &corsair_device_quantity,
|
||||
bool &is_LL120Outer_individual
|
||||
);
|
||||
|
||||
bool SetVolume
|
||||
(
|
||||
unsigned char main,
|
||||
unsigned char left,
|
||||
unsigned char right
|
||||
);
|
||||
|
||||
void SetBoardSyncSettings
|
||||
(
|
||||
bool onboard_sync,
|
||||
bool combine_JRGB,
|
||||
bool combine_JPIPE1,
|
||||
bool combine_JPIPE2,
|
||||
bool combine_JRAINBOW1,
|
||||
bool combine_JRAINBOW2,
|
||||
bool combine_crossair
|
||||
);
|
||||
|
||||
void GetBoardSyncSettings
|
||||
(
|
||||
bool &onboard_sync,
|
||||
bool &combine_JRGB,
|
||||
bool &combine_JPIPE1,
|
||||
bool &combine_JPIPE2,
|
||||
bool &combine_JRAINBOW1,
|
||||
bool &combine_JRAINBOW2,
|
||||
bool &combine_crossair
|
||||
);
|
||||
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceLocation();
|
||||
@@ -212,9 +300,9 @@ private:
|
||||
bool ReadFwVersion();
|
||||
void ReadSerial();
|
||||
void ReadName();
|
||||
ZoneData* GetZoneData(ZONE zone);
|
||||
ZoneData* GetZoneData(MSI_ZONE zone);
|
||||
RainbowZoneData*
|
||||
GetRainbowZoneData(ZONE zone);
|
||||
GetRainbowZoneData(MSI_ZONE zone);
|
||||
static unsigned char BitSet(unsigned char value, bool bit, unsigned int position);
|
||||
|
||||
hid_device* dev;
|
||||
|
||||
@@ -1,52 +1,56 @@
|
||||
#include "MSIMysticLightController.h"
|
||||
#include "RGBController_MSIMysticLight.h"
|
||||
#include <algorithm>
|
||||
|
||||
#define MSI_VID 0x1462
|
||||
#define MSI_USB_VID 0x1462
|
||||
|
||||
constexpr unsigned short SupportedPIDs[41] =
|
||||
#define NUM_MSI_PIDS 41
|
||||
|
||||
static const unsigned short msi_pid_table[] =
|
||||
{
|
||||
31847, // MS_7C67
|
||||
31504, // MS_7B10
|
||||
31879, // MS_7C87
|
||||
31635, // MS_7B93
|
||||
31796, // MS_7C34
|
||||
31797, // MS_7C35
|
||||
31798, // MS_7C36
|
||||
31799, // MS_7C37
|
||||
31810, // MS_7C42
|
||||
31876, // MS_7C84
|
||||
31636, // MS_7B94
|
||||
31638, // MS_7B96
|
||||
31833, // MS_7C59
|
||||
31840, // MS_7C60
|
||||
31856, // MS_7C70
|
||||
31857, // MS_7C71
|
||||
31859, // MS_7C73
|
||||
31861, // MS_7C75
|
||||
31862, // MS_7C76
|
||||
31863, // MS_7C77
|
||||
31865, // MS_7C79
|
||||
31872, // MS_7C80
|
||||
31896, // MS_7C98
|
||||
31897, // MS_7C99
|
||||
31873, // MS_7C81
|
||||
31874, // MS_7C82
|
||||
31875, // MS_7C83
|
||||
31877, // MS_7C85
|
||||
31878, // MS_7C86
|
||||
31880, // MS_7C88
|
||||
31881, // MS_7C89
|
||||
17497, // MS_4459
|
||||
16036, // MS_3EA4
|
||||
36957, // MS_905D
|
||||
31888, // MS_7C90
|
||||
31889, // MS_7C91
|
||||
31890, // MS_7C92
|
||||
31892, // MS_7C94
|
||||
31893, // MS_7C95
|
||||
31894, // MS_7C96
|
||||
31830 // MS_7C56
|
||||
0x3EA4, // MS_3EA4
|
||||
0x4559, // MS_4459
|
||||
|
||||
0x7B10, // MS_7B10
|
||||
0x7B93, // MSI B450 Gaming Pro Carbon AC
|
||||
0x7B94, // MS_7B94
|
||||
0x7B96, // MS_7B96
|
||||
|
||||
0x7C34, // MS_7C34
|
||||
0x7C35, // MS_7C35
|
||||
0x7C36, // MS_7C36
|
||||
0x7C37, // MS_7C37
|
||||
0x7C42, // MS_7C42
|
||||
0x7C56, // MS_7C56
|
||||
0x7C59, // MS_7C59
|
||||
0x7C60, // MS_7C60
|
||||
0x7C67, // MS_7C67
|
||||
0x7C70, // MS_7C70
|
||||
0x7C71, // MS_7C71
|
||||
0x7C73, // MS_7C73
|
||||
0x7C75, // MS_7C75
|
||||
0x7C76, // MS_7C76
|
||||
0x7C77, // MS_7C77
|
||||
0x7C79, // MS_7C79
|
||||
0x7C80, // MS_7C80
|
||||
0x7C81, // MS_7C81
|
||||
0x7C82, // MS_7C82
|
||||
0x7C83, // MS_7C83
|
||||
0x7C84, // MS_7C84
|
||||
0x7C85, // MS_7C85
|
||||
0x7C86, // MS_7C86
|
||||
0x7C87, // MS_7C87
|
||||
0x7C88, // MS_7C88
|
||||
0x7C89, // MS_7C89
|
||||
0x7C90, // MS_7C90
|
||||
0x7C91, // MS_7C91
|
||||
0x7C92, // MS_7C92
|
||||
0x7C94, // MS_7C94
|
||||
0x7C95, // MS_7C95
|
||||
0x7C96, // MS_7C96
|
||||
0x7C98, // MS_7C98
|
||||
0x7C99, // MS_7C99
|
||||
|
||||
0x905D // MS_905D
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
@@ -59,32 +63,39 @@ constexpr unsigned short SupportedPIDs[41] =
|
||||
|
||||
void DetectMSIMysticLightControllers(std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
if(hid_init() < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
hid_device_info* info;
|
||||
hid_device* dev;
|
||||
|
||||
hid_device_info * device_list = hid_enumerate(MSI_VID, 0);
|
||||
if(!device_list)
|
||||
{
|
||||
return;
|
||||
}
|
||||
hid_init();
|
||||
|
||||
hid_device_info * device = device_list;
|
||||
while(device)
|
||||
for(int device_idx = 0; device_idx < NUM_MSI_PIDS; device_idx++)
|
||||
{
|
||||
if(std::find(std::begin(SupportedPIDs), std::end(SupportedPIDs), device->product_id) != std::end(SupportedPIDs))
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(MSI_USB_VID, msi_pid_table[device_idx]);
|
||||
|
||||
//Look for MSI Mystic Light Controller
|
||||
while(info)
|
||||
{
|
||||
hid_device * dev = hid_open_path(device->path);
|
||||
if(dev)
|
||||
if((info->vendor_id == MSI_USB_VID)
|
||||
&&(info->product_id == msi_pid_table[device_idx]))
|
||||
{
|
||||
MSIMysticLightController * controller = new MSIMysticLightController(dev, device_list->path);
|
||||
RGBController_MSIMysticLight * rgb_controller = new RGBController_MSIMysticLight(controller);
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
dev = hid_open_path(info->path);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
device = device->next;
|
||||
}
|
||||
|
||||
hid_free_enumeration(device_list);
|
||||
if( dev )
|
||||
{
|
||||
MSIMysticLightController * controller = new MSIMysticLightController(dev, info->path);
|
||||
|
||||
RGBController_MSIMysticLight * rgb_controller = new RGBController_MSIMysticLight(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+175
-44
@@ -4,54 +4,123 @@
|
||||
| Adam Honse (calcprogrammer1@gmail.com), 12/29/2016 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "Hue2Controller.h"
|
||||
#include "NZXTHue2Controller.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
Hue2Controller::Hue2Controller(libusb_device_handle* dev_handle)
|
||||
NZXTHue2Controller::NZXTHue2Controller(hid_device* dev_handle, unsigned int rgb_channels, unsigned int fan_channels)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
GetStripsOnChannel(HUE_2_CHANNEL_1);
|
||||
num_fan_channels = fan_channels;
|
||||
num_rgb_channels = rgb_channels;
|
||||
|
||||
SendFirmwareRequest();
|
||||
UpdateDeviceList();
|
||||
|
||||
fan_cmd.resize(num_fan_channels);
|
||||
fan_rpm.resize(num_fan_channels);
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
Hue2Controller::~Hue2Controller()
|
||||
NZXTHue2Controller::~NZXTHue2Controller()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
unsigned int Hue2Controller::GetStripsOnChannel(unsigned int /*channel*/)
|
||||
unsigned char NZXTHue2Controller::GetFanCommand
|
||||
(
|
||||
unsigned char fan_channel
|
||||
)
|
||||
{
|
||||
unsigned int ret_val = 0;
|
||||
return(fan_cmd[fan_channel]);
|
||||
}
|
||||
|
||||
unsigned char usb_buf[] =
|
||||
unsigned short NZXTHue2Controller::GetFanRPM
|
||||
(
|
||||
unsigned char fan_channel
|
||||
)
|
||||
{
|
||||
return(fan_rpm[fan_channel]);
|
||||
}
|
||||
|
||||
unsigned int NZXTHue2Controller::GetNumFanChannels()
|
||||
{
|
||||
return(num_fan_channels);
|
||||
}
|
||||
|
||||
unsigned int NZXTHue2Controller::GetNumRGBChannels()
|
||||
{
|
||||
return(num_rgb_channels);
|
||||
}
|
||||
|
||||
std::string NZXTHue2Controller::GetFirmwareVersion()
|
||||
{
|
||||
return(firmware_version);
|
||||
}
|
||||
|
||||
void NZXTHue2Controller::SendFan
|
||||
(
|
||||
unsigned char port,
|
||||
unsigned char mode,
|
||||
unsigned char speed
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up RGB packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x62;
|
||||
usb_buf[0x01] = 0x01;
|
||||
usb_buf[0x02] = 1 << port;
|
||||
usb_buf[port + 3] = speed;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 64);
|
||||
hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
void NZXTHue2Controller::UpdateDeviceList()
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
unsigned int ret_val = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Device Information Request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x20;
|
||||
usb_buf[0x01] = 0x03;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 64);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Receive packets until 0x21 0x03 is received |
|
||||
\*-----------------------------------------------------*/
|
||||
do
|
||||
{
|
||||
0x20, 0x03, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
int actual = 0;
|
||||
ret_val = hid_read(dev, usb_buf, sizeof(usb_buf));
|
||||
} while( (ret_val != 64) || (usb_buf[0] != 0x21) || (usb_buf[1] != 0x03) );
|
||||
|
||||
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
|
||||
libusb_interrupt_transfer(dev, 0x81, usb_buf, 64, &actual, 0);
|
||||
|
||||
for(int chan = 0; chan < 4; chan++)
|
||||
for(int chan = 0; chan < num_rgb_channels; chan++)
|
||||
{
|
||||
unsigned int start = 0x0F + (6 * chan);
|
||||
unsigned int num_leds_on_channel = 0;
|
||||
@@ -85,10 +154,46 @@ unsigned int Hue2Controller::GetStripsOnChannel(unsigned int /*channel*/)
|
||||
}
|
||||
channel_leds[chan] = num_leds_on_channel;
|
||||
}
|
||||
return(ret_val);
|
||||
}
|
||||
|
||||
void Hue2Controller::SetChannelEffect
|
||||
void NZXTHue2Controller::UpdateStatus()
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
unsigned int ret_val = 0;
|
||||
|
||||
if(false)//num_fan_channels > 0)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Read packet |
|
||||
\*-----------------------------------------------------*/
|
||||
do
|
||||
{
|
||||
ret_val = hid_read(dev, usb_buf, sizeof(usb_buf));
|
||||
} while( (ret_val != 64) || (usb_buf[0] != 0x67) || (usb_buf[1] != 0x02) );
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Extract fan information |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int fan_idx = 0; fan_idx < num_fan_channels; fan_idx++)
|
||||
{
|
||||
unsigned char cmd;
|
||||
unsigned short rpm;
|
||||
|
||||
cmd = usb_buf[40 + fan_idx];
|
||||
rpm = ( usb_buf[25 + (2 * fan_idx)] << 8 ) | usb_buf[24 + (2 * fan_idx)];
|
||||
|
||||
fan_cmd[fan_idx] = cmd;
|
||||
fan_rpm[fan_idx] = rpm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NZXTHue2Controller::SetChannelEffect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
@@ -118,7 +223,7 @@ void Hue2Controller::SetChannelEffect
|
||||
SendEffect(channel, mode, speed, direction, num_colors, &color_data[0]);
|
||||
}
|
||||
|
||||
void Hue2Controller::SetChannelLEDs
|
||||
void NZXTHue2Controller::SetChannelLEDs
|
||||
(
|
||||
unsigned char channel,
|
||||
RGBColor * colors,
|
||||
@@ -162,12 +267,11 @@ void Hue2Controller::SetChannelLEDs
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void Hue2Controller::SendApply
|
||||
void NZXTHue2Controller::SendApply
|
||||
(
|
||||
unsigned char channel
|
||||
)
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
@@ -190,11 +294,11 @@ void Hue2Controller::SendApply
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
|
||||
libusb_interrupt_transfer(dev, 0x81, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 64);
|
||||
//hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
void Hue2Controller::SendDirect
|
||||
void NZXTHue2Controller::SendDirect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char group,
|
||||
@@ -202,7 +306,6 @@ void Hue2Controller::SendDirect
|
||||
unsigned char* color_data
|
||||
)
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
@@ -226,11 +329,11 @@ void Hue2Controller::SendDirect
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
|
||||
libusb_interrupt_transfer(dev, 0x81, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 64);
|
||||
//hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
void Hue2Controller::SendEffect
|
||||
void NZXTHue2Controller::SendEffect
|
||||
(
|
||||
unsigned char channel,
|
||||
unsigned char mode,
|
||||
@@ -240,7 +343,6 @@ void Hue2Controller::SendEffect
|
||||
unsigned char* color_data
|
||||
)
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
@@ -281,6 +383,35 @@ void Hue2Controller::SendEffect
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x0A], color_data, color_count * 3);
|
||||
|
||||
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
|
||||
libusb_interrupt_transfer(dev, 0x81, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 64);
|
||||
//hid_read(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
void NZXTHue2Controller::SendFirmwareRequest()
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
unsigned int ret_val = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Firmware Request packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x10;
|
||||
usb_buf[0x01] = 0x01;
|
||||
|
||||
hid_write(dev, usb_buf, 64);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Receive packets until 0x11 0x01 is received |
|
||||
\*-----------------------------------------------------*/
|
||||
do
|
||||
{
|
||||
ret_val = hid_read(dev, usb_buf, sizeof(usb_buf));
|
||||
} while( (ret_val != 64) || (usb_buf[0] != 0x11) || (usb_buf[1] != 0x01) );
|
||||
|
||||
snprintf(firmware_version, 16, "%u.%u.%u", usb_buf[0x11], usb_buf[0x12], usb_buf[0x13]);
|
||||
}
|
||||
+39
-7
@@ -5,8 +5,9 @@
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -50,15 +51,33 @@ enum
|
||||
HUE_2_NUM_MODES /* Number of Hue 2 modes */
|
||||
};
|
||||
|
||||
class Hue2Controller
|
||||
class NZXTHue2Controller
|
||||
{
|
||||
public:
|
||||
Hue2Controller(libusb_device_handle* dev_handle);
|
||||
~Hue2Controller();
|
||||
NZXTHue2Controller(hid_device* dev_handle, unsigned int rgb_channels, unsigned int fan_channels);
|
||||
~NZXTHue2Controller();
|
||||
|
||||
unsigned int GetStripsOnChannel
|
||||
std::string GetFirmwareVersion();
|
||||
|
||||
unsigned char GetFanCommand
|
||||
(
|
||||
unsigned int channel
|
||||
unsigned char fan_channel
|
||||
);
|
||||
|
||||
unsigned short GetFanRPM
|
||||
(
|
||||
unsigned char fan_channel
|
||||
);
|
||||
|
||||
unsigned int GetNumFanChannels();
|
||||
|
||||
unsigned int GetNumRGBChannels();
|
||||
|
||||
void SendFan
|
||||
(
|
||||
unsigned char port,
|
||||
unsigned char mode,
|
||||
unsigned char speed
|
||||
);
|
||||
|
||||
void SetChannelEffect
|
||||
@@ -77,11 +96,22 @@ public:
|
||||
RGBColor * colors,
|
||||
unsigned int num_colors
|
||||
);
|
||||
|
||||
void UpdateDeviceList();
|
||||
|
||||
void UpdateStatus();
|
||||
|
||||
unsigned int channel_leds[HUE_2_NUM_CHANNELS];
|
||||
|
||||
private:
|
||||
libusb_device_handle* dev;
|
||||
hid_device* dev;
|
||||
|
||||
std::vector<unsigned char> fan_cmd;
|
||||
std::vector<unsigned short> fan_rpm;
|
||||
|
||||
char firmware_version[16];
|
||||
unsigned int num_fan_channels;
|
||||
unsigned int num_rgb_channels;
|
||||
|
||||
void SendApply
|
||||
(
|
||||
@@ -105,4 +135,6 @@ private:
|
||||
unsigned char color_count,
|
||||
unsigned char* color_data
|
||||
);
|
||||
|
||||
void SendFirmwareRequest();
|
||||
};
|
||||
@@ -0,0 +1,78 @@
|
||||
#include "NZXTHue2Controller.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_NZXTHue2.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define NZXT_VID 0x1E71
|
||||
#define NZXT_HUE_2_PID 0x2001
|
||||
#define NZXT_HUE_2_AMBIENT_PID 0x2002
|
||||
#define NZXT_SMART_DEVICE_V2_PID 0x2006
|
||||
#define NZXT_RGB_FAN_CONTROLLER_PID 0x2009
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned int num_rgb_channels;
|
||||
unsigned int num_fan_channels;
|
||||
const char * name;
|
||||
} nzxt_hue_2_device;
|
||||
|
||||
#define NZXT_HUE_2_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const nzxt_hue_2_device device_list[] =
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| NZXT Hue 2 devices |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ NZXT_VID, NZXT_HUE_2_PID, 4, 0, "NZXT Hue 2" },
|
||||
{ NZXT_VID, NZXT_HUE_2_AMBIENT_PID, 2, 0, "NZXT Hue 2 Ambient" },
|
||||
{ NZXT_VID, NZXT_SMART_DEVICE_V2_PID, 2, 3, "NZXT Smart Device V2" },
|
||||
{ NZXT_VID, NZXT_RGB_FAN_CONTROLLER_PID, 2, 3, "NZXT RGB & Fan Controller" },
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectNZXTHue2Controllers *
|
||||
* *
|
||||
* Detect devices supported by the NZXT Hue 2 driver *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectNZXTHue2Controllers(std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev;
|
||||
|
||||
hid_init();
|
||||
|
||||
for(std::size_t device_idx = 0; device_idx < NZXT_HUE_2_NUM_DEVICES; device_idx++)
|
||||
{
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
//Look for NZXT Hue 2 devices
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
NZXTHue2Controller* controller = new NZXTHue2Controller(dev, device_list[device_idx].num_rgb_channels, device_list[device_idx].num_fan_channels);
|
||||
|
||||
RGBController_NZXTHue2* rgb_controller = new RGBController_NZXTHue2(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
} /* DetectNZXTHue2Controllers() */
|
||||
@@ -10,9 +10,6 @@
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
|
||||
const int NZXT_KRAKEN_READ_ENDPOINT = 0x81;
|
||||
const int NZXT_KRAKEN_WRITE_ENDPOINT = 0x01;
|
||||
|
||||
static void SetColor(const std::vector<RGBColor>& colors, unsigned char* color_data)
|
||||
{
|
||||
for (std::size_t idx = 0; idx < colors.size(); idx++)
|
||||
@@ -30,7 +27,7 @@ static RGBColor ToLogoColor(RGBColor rgb)
|
||||
return ToRGBColor(RGBGetGValue(rgb), RGBGetRValue(rgb), RGBGetBValue(rgb));
|
||||
}
|
||||
|
||||
NZXTKrakenController::NZXTKrakenController(libusb_device_handle* dev_handle)
|
||||
NZXTKrakenController::NZXTKrakenController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
@@ -42,7 +39,7 @@ NZXTKrakenController::NZXTKrakenController(libusb_device_handle* dev_handle)
|
||||
|
||||
NZXTKrakenController::~NZXTKrakenController()
|
||||
{
|
||||
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string NZXTKrakenController::GetFirmwareVersion()
|
||||
@@ -52,11 +49,17 @@ std::string NZXTKrakenController::GetFirmwareVersion()
|
||||
|
||||
void NZXTKrakenController::UpdateStatus()
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0, sizeof(usb_buf));
|
||||
|
||||
libusb_interrupt_transfer(dev, NZXT_KRAKEN_READ_ENDPOINT, usb_buf, sizeof(usb_buf), &actual, 0);
|
||||
/*-----------------------------------------------------*\
|
||||
| Read packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_read(dev, usb_buf, 64);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Extract cooler information |
|
||||
@@ -87,14 +90,28 @@ void NZXTKrakenController::UpdateEffect
|
||||
)
|
||||
{
|
||||
unsigned char color_data[9 * 3];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(color_data, 0, sizeof(color_data));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
if(!colors.empty() && channel != NZXT_KRAKEN_CHANNEL_RING)
|
||||
{
|
||||
colors[0] = ToLogoColor(colors[0]);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Update color data |
|
||||
\*-----------------------------------------------------*/
|
||||
SetColor(colors, color_data);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send update packet |
|
||||
\*-----------------------------------------------------*/
|
||||
SendEffect(channel, mode, direction, color_data, speed, false, seq);
|
||||
}
|
||||
|
||||
@@ -110,8 +127,7 @@ void NZXTKrakenController::SendEffect
|
||||
int size /* = 0 */
|
||||
)
|
||||
{
|
||||
int actual;
|
||||
unsigned char usb_buf[65];
|
||||
unsigned char usb_buf[64];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -154,13 +170,5 @@ void NZXTKrakenController::SendEffect
|
||||
/*-----------------------------------------------------*\
|
||||
| Send effect |
|
||||
\*-----------------------------------------------------*/
|
||||
libusb_interrupt_transfer
|
||||
(
|
||||
dev,
|
||||
NZXT_KRAKEN_WRITE_ENDPOINT,
|
||||
usb_buf,
|
||||
sizeof(usb_buf),
|
||||
&actual,
|
||||
0
|
||||
);
|
||||
hid_write(dev, usb_buf, 64);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "RGBController.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
enum NZXTKrakenChannel_t
|
||||
{
|
||||
@@ -46,7 +46,7 @@ enum
|
||||
class NZXTKrakenController
|
||||
{
|
||||
public:
|
||||
NZXTKrakenController(libusb_device_handle* dev_handle);
|
||||
NZXTKrakenController(hid_device* dev_handle);
|
||||
~NZXTKrakenController();
|
||||
|
||||
std::string GetFirmwareVersion();
|
||||
@@ -76,7 +76,7 @@ private:
|
||||
int size = 0
|
||||
);
|
||||
|
||||
libusb_device_handle* dev;
|
||||
hid_device* dev;
|
||||
|
||||
// -- status
|
||||
std::string firmware_version;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_NZXTKraken.h"
|
||||
#include <vector>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define NZXT_KRAKEN_VID 0x1E71
|
||||
#define NZXT_KRAKEN_PID 0x170E
|
||||
@@ -17,21 +17,35 @@
|
||||
|
||||
void DetectNZXTKrakenControllers(std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
libusb_context * ctx;
|
||||
libusb_init(&ctx);
|
||||
hid_device_info* info;
|
||||
hid_device* dev;
|
||||
|
||||
libusb_device_handle * dev = libusb_open_device_with_vid_pid(ctx, NZXT_KRAKEN_VID, NZXT_KRAKEN_PID);
|
||||
hid_init();
|
||||
|
||||
if( dev )
|
||||
for(std::size_t device_idx = 0; device_idx < 1; device_idx++)
|
||||
{
|
||||
libusb_detach_kernel_driver(dev, 0);
|
||||
libusb_claim_interface(dev, 0);
|
||||
dev = NULL;
|
||||
|
||||
NZXTKrakenController* controller = new NZXTKrakenController(dev);
|
||||
info = hid_enumerate(NZXT_KRAKEN_VID, NZXT_KRAKEN_PID);
|
||||
|
||||
RGBController_NZXTKraken* rgb_controller = new RGBController_NZXTKraken(controller);
|
||||
//Look for NZXT Kraken devices
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == NZXT_KRAKEN_VID)
|
||||
&&(info->product_id == NZXT_KRAKEN_PID))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if( dev )
|
||||
{
|
||||
NZXTKrakenController* controller = new NZXTKrakenController(dev);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
RGBController_NZXTKraken* rgb_controller = new RGBController_NZXTKraken(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,16 +6,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
||||
static void Sleep(unsigned int milliseconds)
|
||||
{
|
||||
usleep(1000 * milliseconds);
|
||||
}
|
||||
#endif
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
@@ -44,13 +35,13 @@ void DetectPatriotViperControllers(std::vector<i2c_smbus_interface*> &busses, st
|
||||
// Tests SPD addresses in order: 0x00, 0x40, 0x41, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68
|
||||
busses[bus]->i2c_smbus_write_byte_data(0x36, 0x00, 0xFF);
|
||||
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
|
||||
if(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x00) == 0x23)
|
||||
{
|
||||
busses[bus]->i2c_smbus_write_byte_data(0x37, 0x00, 0xFF);
|
||||
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
|
||||
if((busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x40) == 0x85)
|
||||
&&(busses[bus]->i2c_smbus_read_byte_data(slot_addr, 0x41) == 0x02)
|
||||
@@ -67,7 +58,7 @@ void DetectPatriotViperControllers(std::vector<i2c_smbus_interface*> &busses, st
|
||||
}
|
||||
}
|
||||
|
||||
Sleep(1);
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
|
||||
if(slots_valid != 0)
|
||||
|
||||
@@ -15,7 +15,9 @@ PolychromeController::PolychromeController(i2c_smbus_interface* bus, polychrome_
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
|
||||
unsigned short fw_version = GetFirmwareVersion();
|
||||
unsigned short fw_version = GetFirmwareVersion();
|
||||
unsigned char major_version = fw_version >> 8;
|
||||
unsigned char minor_version = fw_version & 0xFF;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Determine whether the device uses ASR LED or |
|
||||
@@ -23,15 +25,15 @@ PolychromeController::PolychromeController(i2c_smbus_interface* bus, polychrome_
|
||||
| Versions 1.xx and 2.xx use ASR LED, 3.xx uses |
|
||||
| Polychrome |
|
||||
\*-----------------------------------------------------*/
|
||||
if(((fw_version >> 8) < 0x03) && ((fw_version >> 8) > 0x00))
|
||||
if((major_version < 0x03) && (major_version > 0x00))
|
||||
{
|
||||
snprintf(device_name, 32, "ASRock ASR LED FW %d.%02d", (fw_version >> 8), (fw_version & 0xFF));
|
||||
snprintf(device_name, 32, "ASRock ASR LED FW %d.%02d", major_version, minor_version);
|
||||
led_count = 1;
|
||||
asr_led = true;
|
||||
}
|
||||
else if(fw_version == 0x03)
|
||||
else if(major_version == 0x03)
|
||||
{
|
||||
snprintf(device_name, 32, "ASRock Polychrome FW %d.%02d", (fw_version >> 8), (fw_version & 0xFF));
|
||||
snprintf(device_name, 32, "ASRock Polychrome FW %d.%02d", major_version, minor_version);
|
||||
led_count = 1;
|
||||
asr_led = false;
|
||||
}
|
||||
@@ -84,17 +86,71 @@ bool PolychromeController::IsAsrLed()
|
||||
return(asr_led);
|
||||
}
|
||||
|
||||
void PolychromeController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
void PolychromeController::SetColorsAndSpeed(unsigned char red, unsigned char green, unsigned char blue, unsigned char speed)
|
||||
{
|
||||
unsigned char colors[3] = { red, green, blue };
|
||||
unsigned char color_speed_pkt[4] = { red, green, blue, speed };
|
||||
|
||||
if (asr_led)
|
||||
{
|
||||
bus->i2c_smbus_write_block_data(dev, active_mode, 3, colors);
|
||||
switch(active_mode)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| These modes take 4 bytes in R/G/B/S order |
|
||||
\*-----------------------------------------------------*/
|
||||
case ASRLED_MODE_BREATHING:
|
||||
case ASRLED_MODE_FLASHING:
|
||||
case ASRLED_MODE_SPECTRUM_CYCLE:
|
||||
bus->i2c_smbus_write_block_data(dev, active_mode, 4, color_speed_pkt);
|
||||
break;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| These modes take 3 bytes in R/G/B order |
|
||||
\*-----------------------------------------------------*/
|
||||
default:
|
||||
case ASRLED_MODE_STATIC:
|
||||
case ASRLED_MODE_MUSIC:
|
||||
bus->i2c_smbus_write_block_data(dev, active_mode, 3, color_speed_pkt);
|
||||
break;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| These modes take 1 byte - speed |
|
||||
\*-----------------------------------------------------*/
|
||||
case ASRLED_MODE_RANDOM:
|
||||
case ASRLED_MODE_WAVE:
|
||||
bus->i2c_smbus_write_block_data(dev, active_mode, 1, &speed);
|
||||
break;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| These modes take no bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
case ASRLED_MODE_OFF:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bus->i2c_smbus_write_block_data(dev, POLYCHROME_REG_COLOR, 3, colors);
|
||||
/*-----------------------------------------------------*\
|
||||
| Polychrome firmware always writes color to fixed reg |
|
||||
\*-----------------------------------------------------*/
|
||||
bus->i2c_smbus_write_block_data(dev, POLYCHROME_REG_COLOR, 3, color_speed_pkt);
|
||||
|
||||
switch(active_mode)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| These modes don't take a speed |
|
||||
\*-----------------------------------------------------*/
|
||||
POLYCHROME_MODE_OFF:
|
||||
POLYCHROME_MODE_STATIC:
|
||||
break;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| All other modes, write speed to active mode register |
|
||||
\*-----------------------------------------------------*/
|
||||
default:
|
||||
bus->i2c_smbus_write_block_data(dev, active_mode, 1, &speed);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,4 +166,4 @@ void PolychromeController::SetMode(unsigned char mode)
|
||||
{
|
||||
bus->i2c_smbus_write_block_data(dev, POLYCHROME_REG_MODE, 1, &active_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,13 @@ enum
|
||||
ASRLED_MODE_WAVE = 0x18, /* Wave effect mode */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
ASRLED_SPEED_MIN = 0x05, /* Slowest speed */
|
||||
ASRLED_SPEED_DEFAULT = 0x03, /* Default speed */
|
||||
ASRLED_SPEED_MAX = 0x00, /* Fastest speed */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
POLYCHROME_REG_FIRMWARE_VER = 0x00, /* Firmware version Major.Minor */
|
||||
@@ -61,6 +68,13 @@ enum
|
||||
POLYCHROME_MODE_RAINBOW = 0x1E, /* Rainbow effect mode */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
POLYCHROME_SPEED_MIN = 0x05, /* Slowest speed */
|
||||
POLYCHROME_SPEED_DEFAULT = 0x03, /* Default speed */
|
||||
POLYCHROME_SPEED_MAX = 0x00, /* Fastest speed */
|
||||
};
|
||||
|
||||
class PolychromeController
|
||||
{
|
||||
public:
|
||||
@@ -71,7 +85,7 @@ public:
|
||||
unsigned int GetLEDCount();
|
||||
unsigned int GetMode();
|
||||
bool IsAsrLed();
|
||||
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetColorsAndSpeed(unsigned char red, unsigned char green, unsigned char blue, unsigned char speed);
|
||||
void SetMode(unsigned char mode);
|
||||
unsigned short GetFirmwareVersion();
|
||||
|
||||
|
||||
@@ -11,16 +11,7 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
||||
static void Sleep(unsigned int milliseconds)
|
||||
{
|
||||
usleep(1000 * milliseconds);
|
||||
}
|
||||
#endif
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
static unsigned int keys[] = {0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x15,
|
||||
0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23,
|
||||
@@ -57,7 +48,7 @@ void PoseidonZRGBController::SetMode(unsigned char mode, unsigned char direction
|
||||
active_speed
|
||||
);
|
||||
|
||||
Sleep(200);
|
||||
std::this_thread::sleep_for(200ms);
|
||||
}
|
||||
|
||||
void PoseidonZRGBController::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
@@ -107,7 +98,7 @@ void PoseidonZRGBController::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, red_grn_buf, 264);
|
||||
|
||||
Sleep(5);
|
||||
std::this_thread::sleep_for(5ms);
|
||||
|
||||
hid_send_feature_report(dev, blu_buf, 264);
|
||||
}
|
||||
@@ -132,7 +123,7 @@ void PoseidonZRGBController::SetLEDs(std::vector<RGBColor> colors)
|
||||
red_color_data
|
||||
);
|
||||
|
||||
Sleep(10);
|
||||
std::this_thread::sleep_for(10ms);
|
||||
|
||||
SendColor
|
||||
(
|
||||
@@ -141,7 +132,7 @@ void PoseidonZRGBController::SetLEDs(std::vector<RGBColor> colors)
|
||||
grn_color_data
|
||||
);
|
||||
|
||||
Sleep(10);
|
||||
std::this_thread::sleep_for(10ms);
|
||||
|
||||
SendColor
|
||||
(
|
||||
@@ -150,7 +141,7 @@ void PoseidonZRGBController::SetLEDs(std::vector<RGBColor> colors)
|
||||
blu_color_data
|
||||
);
|
||||
|
||||
Sleep(10);
|
||||
std::this_thread::sleep_for(10ms);
|
||||
|
||||
SendControl
|
||||
(
|
||||
|
||||
@@ -30,23 +30,25 @@ void DetectPoseidonZRGBControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
if((info->vendor_id == TT_POSEIDON_Z_RGB_VID)
|
||||
&&(info->product_id == TT_POSEIDON_Z_RGB_PID)
|
||||
&&(info->interface_number == 2))
|
||||
#ifdef USE_HID_USAGE
|
||||
&&(info->interface_number == 1)
|
||||
&&(info->usage_page == 0xFF01))
|
||||
#else
|
||||
&&(info->interface_number == 1))
|
||||
#endif
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
break;
|
||||
if( dev )
|
||||
{
|
||||
PoseidonZRGBController* controller = new PoseidonZRGBController(dev);
|
||||
|
||||
RGBController_PoseidonZRGB* rgb_controller = new RGBController_PoseidonZRGB(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
|
||||
if( dev )
|
||||
{
|
||||
PoseidonZRGBController* controller = new PoseidonZRGBController(dev);
|
||||
|
||||
RGBController_PoseidonZRGB* rgb_controller = new RGBController_PoseidonZRGB(controller);
|
||||
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*-----------------------------------------*\
|
||||
| RGBFusion2DRAMController.cpp |
|
||||
| |
|
||||
| Driver for Gigabyte Aorus RGB Fusion 2 |
|
||||
| DRAM lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 6/7/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBFusion2DRAMController.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
RGBFusion2DRAMController::RGBFusion2DRAMController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Initialize pointers |
|
||||
\*-----------------------------------------------------*/
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(led_data, 0, sizeof(led_data));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Initialize controller with 6 LEDs and mask 0x3B |
|
||||
| This is hard coded for Aorus RGB RAM |
|
||||
\*-----------------------------------------------------*/
|
||||
led_data[RGB_FUSION_2_DRAM_LED_EN_MASK] = 0x3B;
|
||||
led_count = 6;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Initialize brightness to 100% |
|
||||
\*-----------------------------------------------------*/
|
||||
led_data[RGB_FUSION_2_DRAM_IDX_BRIGHTNESS] = 0x64;
|
||||
}
|
||||
|
||||
unsigned int RGBFusion2DRAMController::GetLEDCount()
|
||||
{
|
||||
return(led_count);
|
||||
}
|
||||
|
||||
std::string RGBFusion2DRAMController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return(return_string);
|
||||
}
|
||||
|
||||
void RGBFusion2DRAMController::Apply()
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, RGB_FUSION_2_DRAM_APPLY_ADDR, RGB_FUSION_2_DRAM_ACTION_APPLY);
|
||||
}
|
||||
|
||||
void RGBFusion2DRAMController::SetLEDEffect
|
||||
(
|
||||
unsigned int led,
|
||||
int mode,
|
||||
unsigned int speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
led_data[RGB_FUSION_2_DRAM_IDX_MODE] = mode;
|
||||
led_data[RGB_FUSION_2_DRAM_IDX_RED] = red;
|
||||
led_data[RGB_FUSION_2_DRAM_IDX_GREEN] = green;
|
||||
led_data[RGB_FUSION_2_DRAM_IDX_BLUE] = blue;
|
||||
|
||||
bus->i2c_smbus_write_block_data(dev, RGB_FUSION_2_DRAM_LED_START_ADDR, 32, led_data);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*-----------------------------------------*\
|
||||
| RGBFusion2DRAMController.h |
|
||||
| |
|
||||
| Definitions and types for Gigabyte Aorus |
|
||||
| RGB Fusion 2 DRAM lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 6/7/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char rgb_fusion_dev_id;
|
||||
|
||||
enum
|
||||
{
|
||||
RGB_FUSION_2_DRAM_LED_EN_MASK = 0x00, /* LED enable bitfield */
|
||||
RGB_FUSION_2_DRAM_IDX_MODE = 0x09, /* Mode index */
|
||||
RGB_FUSION_2_DRAM_IDX_BRIGHTNESS = 0x0A, /* Brightness index */
|
||||
RGB_FUSION_2_DRAM_IDX_BLUE = 0x0C, /* Blue index */
|
||||
RGB_FUSION_2_DRAM_IDX_GREEN = 0x0D, /* Green index */
|
||||
RGB_FUSION_2_DRAM_IDX_RED = 0x0E, /* Red index */
|
||||
// RGB_FUSION_2_DRAM_TIMER_1_LSB = 0x08, /* Timer 1 LSB. Valid timer values [0-65535] */
|
||||
// RGB_FUSION_2_DRAM_TIMER_1_MSB = 0x09, /* Timer 1 MSB. Timer unis are milliseconds */
|
||||
// RGB_FUSION_2_DRAM_TIMER_2_LSB = 0x0A, /* Timer 2 LSB */
|
||||
// RGB_FUSION_2_DRAM_TIMER_2_MSB = 0x0B, /* Timer 2 MSB */
|
||||
// RGB_FUSION_2_DRAM_TIMER_3_LSB = 0x0C, /* Timer 3 LSB */
|
||||
// RGB_FUSION_2_DRAM_TIMER_3_MSB = 0x0D, /* Timer 3 MSB */
|
||||
// RGB_FUSION_2_DRAM_IDX_OPT_1 = 0x0E, /* Option 1. Use case varies by mode */
|
||||
// RGB_FUSION_2_DRAM_IDX_OPT_2 = 0x0F, /* Option 2. Use case varies by mode */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
RGB_FUSION_2_DRAM_LED_START_ADDR = 0x20,
|
||||
RGB_FUSION_2_DRAM_APPLY_ADDR = 0x28,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
RGB_FUSION_2_DRAM_ACTION_APPLY = 0x0F,
|
||||
};
|
||||
|
||||
class RGBFusion2DRAMController
|
||||
{
|
||||
public:
|
||||
RGBFusion2DRAMController(i2c_smbus_interface* bus, rgb_fusion_dev_id dev);
|
||||
~RGBFusion2DRAMController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
unsigned int GetLEDCount();
|
||||
void Apply();
|
||||
|
||||
void SetLEDEffect
|
||||
(
|
||||
unsigned int led,
|
||||
int mode,
|
||||
unsigned int speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
unsigned int led_count;
|
||||
i2c_smbus_interface* bus;
|
||||
rgb_fusion_dev_id dev;
|
||||
|
||||
unsigned char led_data[32];
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
#include "RGBFusion2DRAMController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_RGBFusion2DRAM.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* TestForRGBFusion2DRAMController *
|
||||
* *
|
||||
* Tests the given address to see if an RGB 2 Fusion DRAMcontroller exists there. *
|
||||
* First does a quick write to test for a response *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
bool TestForRGBFusion2DRAMController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
|
||||
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
|
||||
if (res >= 0)
|
||||
{
|
||||
pass = true;
|
||||
|
||||
// res = bus->i2c_smbus_read_byte_data(address, 0xF2);
|
||||
|
||||
// if (res != 0xC4)
|
||||
// {
|
||||
// pass = false;
|
||||
// }
|
||||
}
|
||||
|
||||
return(pass);
|
||||
|
||||
} /* TestForRGBFusion2DRAMController() */
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectRGBFusion2DRAMControllers *
|
||||
* *
|
||||
* Detect RGB Fusion 2 controllers on the enumerated I2C busses at address 0x67. *
|
||||
* *
|
||||
* bus - pointer to i2c_smbus_interface where RGB Fusion device is connected *
|
||||
* dev - I2C address of RGB Fusion device *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectRGBFusion2DRAMControllers(std::vector<i2c_smbus_interface*>& busses, std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
RGBFusion2DRAMController* new_rgb_fusion;
|
||||
RGBController_RGBFusion2DRAM* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
// Check for RGB Fusion 2 DRAM controller at 0x67
|
||||
if (TestForRGBFusion2DRAMController(busses[bus], 0x67))
|
||||
{
|
||||
new_rgb_fusion = new RGBFusion2DRAMController(busses[bus], 0x67);
|
||||
new_controller = new RGBController_RGBFusion2DRAM(new_rgb_fusion);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
|
||||
} /* DetectRGBFusion2DRAMControllers() */
|
||||
@@ -27,16 +27,17 @@ static LEDCount LedCountToEnum(unsigned int c)
|
||||
return(LEDS_1024);
|
||||
}
|
||||
|
||||
RGBFusion2USBController::RGBFusion2USBController(hid_device* handle, const char *path) : dev(handle)
|
||||
RGBFusion2USBController::RGBFusion2USBController(hid_device* handle, const char *path, std::string mb_name) : dev(handle)
|
||||
{
|
||||
int res = 0;
|
||||
char text[64] {};
|
||||
unsigned char buffer[64] {};
|
||||
|
||||
if( dev ) {
|
||||
int res = 0;
|
||||
char text[64] = { 0x00 };
|
||||
unsigned char buffer[64] = { 0x00 };
|
||||
|
||||
if( dev )
|
||||
{
|
||||
SetCalibration();
|
||||
|
||||
name = mb_name;
|
||||
// hid report read needs 0x60 packet or it gives IO error
|
||||
SendPacket(0x60, 0x00);
|
||||
|
||||
@@ -46,8 +47,8 @@ RGBFusion2USBController::RGBFusion2USBController(hid_device* handle, const char
|
||||
{
|
||||
report = *reinterpret_cast<IT8297Report*>(buffer);
|
||||
|
||||
name = std::string(report.str_product, 32);
|
||||
name.erase(std::find(name.begin(), name.end(), '\0'), name.end());
|
||||
description = std::string(report.str_product, 32);
|
||||
//description.erase(std::find(description.begin(), description.end(), '\0'), name.end());
|
||||
|
||||
snprintf(text, 11, "0x%08X", report.fw_ver);
|
||||
version = text;
|
||||
@@ -55,7 +56,6 @@ RGBFusion2USBController::RGBFusion2USBController(hid_device* handle, const char
|
||||
snprintf(text, 11, "0x%08X", report.chip_id);
|
||||
chip_id = text;
|
||||
}
|
||||
|
||||
loc = path;
|
||||
|
||||
EnableBeat(false);
|
||||
@@ -84,13 +84,13 @@ void RGBFusion2USBController::SetCalibration()
|
||||
buffer[0] = report_id;
|
||||
buffer[1] = 0x33;
|
||||
|
||||
// D_LED1 WS2812 GRB, 0x00RRGGBB to 0x00GGRRBB
|
||||
// D_LED1 WS2812 GRB, 0x00RRGGBB to 0x00GGRRBB
|
||||
buffer[2] = 0x02; // B
|
||||
buffer[3] = 0x00; // G
|
||||
buffer[4] = 0x01; // R
|
||||
buffer[5] = 0x00;
|
||||
|
||||
// D_LED2 WS2812 GRB
|
||||
// D_LED2 WS2812 GRB
|
||||
buffer[6] = 0x02;
|
||||
buffer[7] = 0x00;
|
||||
buffer[8] = 0x01;
|
||||
@@ -102,6 +102,12 @@ void RGBFusion2USBController::SetCalibration()
|
||||
buffer[12] = 0x02;
|
||||
buffer[13] = 0x00;
|
||||
|
||||
// Spare set seen in some Motherboard models
|
||||
buffer[14] = 0x00;
|
||||
buffer[15] = 0x01;
|
||||
buffer[16] = 0x02;
|
||||
buffer[17] = 0x00;
|
||||
|
||||
SendPacket(buffer);
|
||||
}
|
||||
|
||||
@@ -135,6 +141,11 @@ std::string RGBFusion2USBController::GetDeviceName()
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string RGBFusion2USBController::GetDeviceDescription()
|
||||
{
|
||||
return(description);
|
||||
}
|
||||
|
||||
std::string RGBFusion2USBController::GetFWVersion()
|
||||
{
|
||||
return(version);
|
||||
|
||||
@@ -157,7 +157,7 @@ struct IT8297Report
|
||||
class RGBFusion2USBController
|
||||
{
|
||||
public:
|
||||
RGBFusion2USBController(hid_device* handle, const char *path);
|
||||
RGBFusion2USBController(hid_device* handle, const char *path, std::string mb_name);
|
||||
~RGBFusion2USBController();
|
||||
|
||||
void SetStripColors
|
||||
@@ -175,6 +175,7 @@ public:
|
||||
bool DisableBuiltinEffect(int enable_bit, int mask);
|
||||
void SetCalibration();
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceDescription();
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetFWVersion();
|
||||
std::string GetSerial();
|
||||
@@ -188,6 +189,7 @@ private:
|
||||
int mode;
|
||||
IT8297Report report;
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string loc;
|
||||
std::string version;
|
||||
std::string chip_id;
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
#include "RGBFusion2USBController.h"
|
||||
#include "RGBController_RGBFusion2USB.h"
|
||||
#include "dependencies/dmiinfo.h"
|
||||
|
||||
#define IT8297_VID 0x048D
|
||||
#define IT8297_PID 0x8297
|
||||
#define IT8297_VID 0x048D
|
||||
#define IT8297_IFC 0
|
||||
#define IT8297_U 0xCC
|
||||
#define IT8297_UPG 0xFF89
|
||||
#define COUNT_RGBFUSION2_PIDS (sizeof(RGBFusion2_pids) / sizeof(RGBFusion2_pids[ 0 ]))
|
||||
|
||||
static const unsigned short RGBFusion2_pids[] =
|
||||
{
|
||||
0x8297, //PID for the ITE 8595 found on the X570
|
||||
0x5702 //PID for the ITE 8595 found on the B550
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
@@ -14,24 +24,47 @@
|
||||
|
||||
void DetectRGBFusion2USBControllers(std::vector<RGBController*> &rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev;
|
||||
DMIInfo MB_info;
|
||||
unsigned short tmpPID;
|
||||
|
||||
if (hid_init() < 0)
|
||||
return;
|
||||
|
||||
hid_device_info * device_list = hid_enumerate(IT8297_VID, IT8297_PID);
|
||||
if (!device_list)
|
||||
return;
|
||||
|
||||
hid_device_info * device = device_list;
|
||||
while (device)
|
||||
{
|
||||
hid_device * dev = hid_open_path(device->path);
|
||||
if (dev) {
|
||||
RGBFusion2USBController * controller = new RGBFusion2USBController(dev, device_list->path);
|
||||
RGBController_RGBFusion2USB * rgb_controller = new RGBController_RGBFusion2USB(controller);
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
device = device->next;
|
||||
return;
|
||||
}
|
||||
|
||||
hid_free_enumeration(device_list);
|
||||
for(int dev_idx = 0; dev_idx < COUNT_RGBFUSION2_PIDS; dev_idx++)
|
||||
{
|
||||
dev = NULL;
|
||||
|
||||
tmpPID = RGBFusion2_pids[dev_idx];
|
||||
info = hid_enumerate(IT8297_VID, tmpPID);
|
||||
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == IT8297_VID)
|
||||
#ifdef USE_HID_USAGE
|
||||
&&(info->product_id == tmpPID)
|
||||
&&(info->usage == IT8297_U) //Usage and usage page required to get the correct interface
|
||||
&&(info->usage_page == IT8297_UPG))
|
||||
#else
|
||||
&&(info->interface_number == IT8297_IFC) //Interface is only valid on Windows where there is > 1 interface
|
||||
&&(info->product_id == tmpPID))
|
||||
#endif
|
||||
{
|
||||
hid_device * dev = hid_open_path(info->path);
|
||||
if (dev)
|
||||
{
|
||||
RGBFusion2USBController * controller = new RGBFusion2USBController(dev, info->path, MB_info.getMainboard());
|
||||
RGBController_RGBFusion2USB * rgb_controller = new RGBController_RGBFusion2USB(controller);
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
break;
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
|
||||
hid_free_enumeration(info);
|
||||
}
|
||||
|
||||
@@ -10,14 +10,18 @@
|
||||
| Keyboard product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define REDRAGON_KEYBOARD_VID 0x0C45
|
||||
#define REDRAGON_KEYBOARD_USAGE_PAGE 0xFF1C
|
||||
#define REDRAGON_K550_PID 0x5204
|
||||
#define REDRAGON_K552_PID 0x5104
|
||||
#define REDRAGON_K556_PID 0x5004
|
||||
|
||||
#define TECWARE_PHANTOM_ELITE_PID 0x652F
|
||||
#define WARRIOR_KANE_TC235 0x8520
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Mouse product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define REDRAGON_MOUSE_VID 0x04D9
|
||||
#define REDRAGON_MOUSE_USAGE_PAGE 0xFFA0
|
||||
#define REDRAGON_M711_PID 0xFC30
|
||||
#define REDRAGON_M715_PID 0xFC39
|
||||
|
||||
@@ -26,6 +30,7 @@ typedef struct
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned char usb_interface;
|
||||
unsigned short usb_usage_page;
|
||||
device_type type;
|
||||
const char * name;
|
||||
} redragon_device;
|
||||
@@ -34,19 +39,22 @@ typedef struct
|
||||
|
||||
static const redragon_device device_list[] =
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ REDRAGON_KEYBOARD_VID, REDRAGON_K550_PID, 1, DEVICE_TYPE_KEYBOARD, "Redragon K550 Yama" },
|
||||
{ REDRAGON_KEYBOARD_VID, REDRAGON_K556_PID, 1, DEVICE_TYPE_KEYBOARD, "Redragon K556 Devarajas" },
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Mice |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
{ REDRAGON_MOUSE_VID, REDRAGON_M711_PID, 2, DEVICE_TYPE_MOUSE, "Redragon M711 Cobra" },
|
||||
{ REDRAGON_MOUSE_VID, REDRAGON_M715_PID, 2, DEVICE_TYPE_MOUSE, "Redragon M715 Dagger" },
|
||||
/*-----------------------------------------------------------------------------------------------------*\
|
||||
| Mousemats |
|
||||
\*-----------------------------------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*---------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
{ REDRAGON_KEYBOARD_VID, REDRAGON_K550_PID, 1, REDRAGON_KEYBOARD_USAGE_PAGE, DEVICE_TYPE_KEYBOARD, "Redragon K550 Yama" },
|
||||
{ REDRAGON_KEYBOARD_VID, REDRAGON_K552_PID, 1, REDRAGON_KEYBOARD_USAGE_PAGE, DEVICE_TYPE_KEYBOARD, "Redragon K552 Kumara" },
|
||||
{ REDRAGON_KEYBOARD_VID, REDRAGON_K556_PID, 1, REDRAGON_KEYBOARD_USAGE_PAGE, DEVICE_TYPE_KEYBOARD, "Redragon K556 Devarajas" },
|
||||
{ REDRAGON_KEYBOARD_VID, TECWARE_PHANTOM_ELITE_PID, 1, REDRAGON_KEYBOARD_USAGE_PAGE, DEVICE_TYPE_KEYBOARD, "Tecware Phantom Elite" },
|
||||
{ REDRAGON_KEYBOARD_VID, WARRIOR_KANE_TC235, 1, REDRAGON_KEYBOARD_USAGE_PAGE, DEVICE_TYPE_KEYBOARD, "Warrior Kane TC235" },
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Mice |
|
||||
\*---------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
{ REDRAGON_MOUSE_VID, REDRAGON_M711_PID, 2, REDRAGON_MOUSE_USAGE_PAGE, DEVICE_TYPE_MOUSE, "Redragon M711 Cobra" },
|
||||
{ REDRAGON_MOUSE_VID, REDRAGON_M715_PID, 2, REDRAGON_MOUSE_USAGE_PAGE, DEVICE_TYPE_MOUSE, "Redragon M715 Dagger" },
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Mousemats |
|
||||
\*---------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
@@ -73,45 +81,46 @@ void DetectRedragonControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
//Look for Redragon RGB Peripheral
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
#ifdef USE_HID_USAGE
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface)
|
||||
&&(info->usage_page == device_list[device_idx].usb_usage_page))
|
||||
#else
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
#endif
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
|
||||
if( dev )
|
||||
{
|
||||
switch(device_list[device_idx].type)
|
||||
{
|
||||
case DEVICE_TYPE_KEYBOARD:
|
||||
if( dev )
|
||||
{
|
||||
switch(device_list[device_idx].type)
|
||||
{
|
||||
RedragonK556Controller* controller = new RedragonK556Controller(dev);
|
||||
case DEVICE_TYPE_KEYBOARD:
|
||||
{
|
||||
RedragonK556Controller* controller = new RedragonK556Controller(dev);
|
||||
|
||||
RGBController_RedragonK556* rgb_controller = new RGBController_RedragonK556(controller);
|
||||
RGBController_RedragonK556* rgb_controller = new RGBController_RedragonK556(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_MOUSE:
|
||||
{
|
||||
RedragonM711Controller* controller = new RedragonM711Controller(dev);
|
||||
|
||||
RGBController_RedragonM711* rgb_controller = new RGBController_RedragonM711(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_MOUSE:
|
||||
{
|
||||
RedragonM711Controller* controller = new RedragonM711Controller(dev);
|
||||
|
||||
RGBController_RedragonM711* rgb_controller = new RGBController_RedragonM711(controller);
|
||||
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ enum
|
||||
enum
|
||||
{
|
||||
REDRAGON_K556_BRIGHTNESS_LOWEST = 0x00, /* Lowest brightness (off) */
|
||||
REDRAGON_K556_BRIGHTNESS_HIGHEST = 0x05, /* Highest brightness */
|
||||
REDRAGON_K556_BRIGHTNESS_HIGHEST = 0x04, /* Highest brightness */
|
||||
};
|
||||
|
||||
enum
|
||||
|
||||
@@ -2,24 +2,66 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
static void send_usb_msg(hid_device* dev, char * data_pkt, unsigned int size)
|
||||
{
|
||||
char* usb_pkt = new char[size + 1];
|
||||
|
||||
usb_pkt[0] = 0x00;
|
||||
for(int i = 1; i < size + 1; i++)
|
||||
{
|
||||
usb_pkt[i] = data_pkt[i-1];
|
||||
}
|
||||
|
||||
hid_send_feature_report(dev, (unsigned char *)usb_pkt, size + 1);
|
||||
|
||||
delete usb_pkt;
|
||||
}
|
||||
|
||||
RedragonM711Controller::RedragonM711Controller(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
unsigned char active_profile = 0x00;
|
||||
|
||||
SendWritePacket(0x002C, 1, &active_profile);
|
||||
SendMouseApply();
|
||||
}
|
||||
|
||||
void RedragonM711Controller::SendMouseColor
|
||||
(
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char color_buf[3];
|
||||
|
||||
color_buf[0] = red;
|
||||
color_buf[1] = green;
|
||||
color_buf[2] = blue;
|
||||
|
||||
SendWritePacket(0x0449, 3, color_buf);
|
||||
}
|
||||
|
||||
void RedragonM711Controller::SendMouseMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned char speed
|
||||
)
|
||||
{
|
||||
unsigned char mode_buf[3];
|
||||
|
||||
mode_buf[0] = 0x01; //On
|
||||
mode_buf[1] = speed;
|
||||
mode_buf[2] = mode;
|
||||
|
||||
SendWritePacket(0x044C, 3, mode_buf);
|
||||
}
|
||||
|
||||
void RedragonM711Controller::SendMouseMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char color_mode_buf[6];
|
||||
|
||||
color_mode_buf[0] = red;
|
||||
color_mode_buf[1] = green;
|
||||
color_mode_buf[2] = blue;
|
||||
color_mode_buf[3] = 0x01; //On
|
||||
color_mode_buf[4] = speed;
|
||||
color_mode_buf[5] = mode;
|
||||
|
||||
SendWritePacket(0x0449, 6, color_mode_buf);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
@@ -46,16 +88,14 @@ void RedragonM711Controller::SendMouseApply()
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
send_usb_msg(dev, usb_buf, 16);
|
||||
hid_send_feature_report(dev, (unsigned char *)usb_buf, 16);
|
||||
}
|
||||
|
||||
void RedragonM711Controller::SendMouseMode
|
||||
void RedragonM711Controller::SendWritePacket
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned char speed,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
unsigned short address,
|
||||
unsigned char data_size,
|
||||
unsigned char * data
|
||||
)
|
||||
{
|
||||
char usb_buf[16];
|
||||
@@ -70,21 +110,17 @@ void RedragonM711Controller::SendMouseMode
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x02;
|
||||
usb_buf[0x01] = 0xF3;
|
||||
usb_buf[0x02] = 0x49;
|
||||
usb_buf[0x03] = 0x04;
|
||||
usb_buf[0x04] = 0x06;
|
||||
|
||||
usb_buf[0x08] = red;
|
||||
usb_buf[0x09] = green;
|
||||
usb_buf[0x0A] = blue;
|
||||
|
||||
usb_buf[0x0B] = 0x01; //on
|
||||
|
||||
usb_buf[0x0C] = speed;
|
||||
usb_buf[0x0D] = mode;
|
||||
usb_buf[0x02] = address & 0xFF;
|
||||
usb_buf[0x03] = address >> 8;
|
||||
usb_buf[0x04] = data_size;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in data bytes |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x08], data, data_size);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
send_usb_msg(dev, usb_buf, 16);
|
||||
hid_send_feature_report(dev, (unsigned char *)usb_buf, 16);
|
||||
}
|
||||
|
||||
@@ -32,6 +32,19 @@ public:
|
||||
|
||||
void SendMouseApply();
|
||||
|
||||
void SendMouseColor
|
||||
(
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
void SendMouseMode
|
||||
(
|
||||
unsigned char mode,
|
||||
unsigned char speed
|
||||
);
|
||||
|
||||
void SendMouseMode
|
||||
(
|
||||
unsigned char mode,
|
||||
@@ -43,4 +56,11 @@ public:
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
|
||||
void SendWritePacket
|
||||
(
|
||||
unsigned short address,
|
||||
unsigned char data_size,
|
||||
unsigned char * data
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*-----------------------------------------*\
|
||||
| SapphireGPUController.cpp |
|
||||
| |
|
||||
| Driver for Sapphire Nitro Glow GPU RGB |
|
||||
| lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 7/15/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "SapphireGPUController.h"
|
||||
|
||||
SapphireGPUController::SapphireGPUController(i2c_smbus_interface* bus, sapphire_dev_id dev)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
}
|
||||
|
||||
SapphireGPUController::~SapphireGPUController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string SapphireGPUController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return(return_string);
|
||||
}
|
||||
|
||||
unsigned char SapphireGPUController::GetRed()
|
||||
{
|
||||
return(bus->i2c_smbus_read_byte_data(dev, SAPPHIRE_GPU_REG_RED));
|
||||
}
|
||||
|
||||
unsigned char SapphireGPUController::GetGreen()
|
||||
{
|
||||
return(bus->i2c_smbus_read_byte_data(dev, SAPPHIRE_GPU_REG_GREEN));
|
||||
}
|
||||
|
||||
unsigned char SapphireGPUController::GetBlue()
|
||||
{
|
||||
return(bus->i2c_smbus_read_byte_data(dev, SAPPHIRE_GPU_REG_BLUE));
|
||||
}
|
||||
|
||||
void SapphireGPUController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, SAPPHIRE_GPU_REG_RED, red);
|
||||
bus->i2c_smbus_write_byte_data(dev, SAPPHIRE_GPU_REG_GREEN, green);
|
||||
bus->i2c_smbus_write_byte_data(dev, SAPPHIRE_GPU_REG_BLUE, blue);
|
||||
}
|
||||
|
||||
void SapphireGPUController::SetMode(unsigned char mode, unsigned char speed)
|
||||
{
|
||||
bus->i2c_smbus_write_byte_data(dev, SAPPHIRE_GPU_REG_MODE, mode);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*-----------------------------------------*\
|
||||
| SapphireGPUController.h |
|
||||
| |
|
||||
| Definitions and types for Sapphire Nitro |
|
||||
| Glow GPU RGB lighting controller |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 7/15/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef unsigned char sapphire_dev_id;
|
||||
|
||||
enum
|
||||
{
|
||||
SAPPHIRE_GPU_REG_MODE = 0x00,
|
||||
SAPPHIRE_GPU_REG_BRIGHTNESS = 0x01,
|
||||
SAPPHIRE_GPU_REG_RED = 0x03,
|
||||
SAPPHIRE_GPU_REG_GREEN = 0x04,
|
||||
SAPPHIRE_GPU_REG_BLUE = 0x05,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SAPPHIRE_GPU_MODE_SAPPHIRE_BLUE = 0x00,
|
||||
SAPPHIRE_GPU_MODE_RAINBOW = 0x01,
|
||||
SAPPHIRE_GPU_MODE_BOARD_TEMPERATURE = 0x02,
|
||||
SAPPHIRE_GPU_MODE_FAN_SPEED = 0x03,
|
||||
SAPPHIRE_GPU_MODE_CUSTOM = 0x04,
|
||||
SAPPHIRE_GPU_MODE_OFF = 0x05,
|
||||
};
|
||||
|
||||
class SapphireGPUController
|
||||
{
|
||||
public:
|
||||
SapphireGPUController(i2c_smbus_interface* bus, sapphire_dev_id dev);
|
||||
~SapphireGPUController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
|
||||
unsigned char GetRed();
|
||||
unsigned char GetGreen();
|
||||
unsigned char GetBlue();
|
||||
|
||||
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetMode(unsigned char mode, unsigned char speed);
|
||||
|
||||
private:
|
||||
i2c_smbus_interface* bus;
|
||||
sapphire_dev_id dev;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "SapphireGPUController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_SapphireGPU.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include <vector>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* TestForSapphireGPUController *
|
||||
* *
|
||||
* Tests the given address to see if a Sapphire GPU controller exists there. First *
|
||||
* does a quick write to test for a response *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
bool TestForSapphireGPUController(i2c_smbus_interface* bus, unsigned char address)
|
||||
{
|
||||
bool pass = false;
|
||||
int res;
|
||||
|
||||
if(bus->i2c_smbus_read_byte_data(address, 0x06) == 0xCC)
|
||||
{
|
||||
pass = true;
|
||||
}
|
||||
|
||||
return(false); //TODO - better detection, leaving disabled for now
|
||||
|
||||
} /* TestForSapphireGPUController() */
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectSapphireGPUControllers *
|
||||
* *
|
||||
* Detect Sapphire GPU controllers on the enumerated I2C busses at address 0x55. *
|
||||
* *
|
||||
* bus - pointer to i2c_smbus_interface where Sapphire GPU device is connected *
|
||||
* dev - I2C address of Sapphire GPU device *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectSapphireGPUControllers(std::vector<i2c_smbus_interface*>& busses, std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
SapphireGPUController* new_sapphire;
|
||||
RGBController_SapphireGPU* new_controller;
|
||||
|
||||
for (unsigned int bus = 0; bus < busses.size(); bus++)
|
||||
{
|
||||
// Check for Sapphire GPU controller at 0x55
|
||||
if (TestForSapphireGPUController(busses[bus], 0x55))
|
||||
{
|
||||
new_sapphire = new SapphireGPUController(busses[bus], 0x55);
|
||||
new_controller = new RGBController_SapphireGPU(new_sapphire);
|
||||
rgb_controllers.push_back(new_controller);
|
||||
}
|
||||
}
|
||||
|
||||
} /* DetectSapphireGPUControllers() */
|
||||
@@ -0,0 +1,104 @@
|
||||
/*-----------------------------------------*\
|
||||
| SteelSeriesApexController.cpp |
|
||||
| |
|
||||
| Driver for SteelSeries Apex 7 RGB |
|
||||
| Keyboard lighting controller |
|
||||
| |
|
||||
| Eric Samuelson (edbgon) 7/5/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "SteelSeriesApexController.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
static unsigned int keys[] = {0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
|
||||
0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
|
||||
0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
|
||||
0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45,
|
||||
0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52,
|
||||
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
|
||||
0xf0 };
|
||||
|
||||
SteelSeriesApexController::SteelSeriesApexController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
}
|
||||
|
||||
SteelSeriesApexController::~SteelSeriesApexController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SteelSeriesApexController::SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
std::vector<RGBColor> colors
|
||||
)
|
||||
{
|
||||
unsigned char mode_colors[9];
|
||||
|
||||
active_mode = mode;
|
||||
|
||||
memset(mode_colors, 0x00, sizeof(mode_colors));
|
||||
|
||||
}
|
||||
|
||||
void SteelSeriesApexController::SetLEDsDirect(std::vector<RGBColor> colors)
|
||||
{
|
||||
unsigned char buf[643];
|
||||
int num_keys = sizeof(keys)/sizeof(*keys);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Direct packet |
|
||||
\*-----------------------------------------------------*/
|
||||
buf[0x00] = 0;
|
||||
buf[0x01] = APEX7_PACKET_ID_DIRECT;
|
||||
buf[0x02] = num_keys;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in color data |
|
||||
\*-----------------------------------------------------*/
|
||||
for(int i = 0; i < num_keys; i++)
|
||||
{
|
||||
buf[(i*4)+3] = keys[i];
|
||||
buf[(i*4)+4] = RGBGetRValue(colors[i]);
|
||||
buf[(i*4)+5] = RGBGetGValue(colors[i]);
|
||||
buf[(i*4)+6] = RGBGetBValue(colors[i]);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, buf, 643);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void SteelSeriesApexController::SelectProfile
|
||||
(
|
||||
unsigned char profile
|
||||
)
|
||||
{
|
||||
unsigned char buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer, set up packet and send |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
buf[0x00] = 0;
|
||||
buf[0x01] = 0x89;
|
||||
buf[0x02] = profile;
|
||||
hid_send_feature_report(dev, buf, 65);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*-----------------------------------------*\
|
||||
| SteelSeriesApexController.h |
|
||||
| |
|
||||
| Definitions and types for SteelSeries |
|
||||
| Apex 7 Keyboard lighting controller |
|
||||
| |
|
||||
| Eric Samuelson (edbgon) 7/5/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
APEX7_PACKET_ID_DIRECT = 0x3a, /* Direct mode */
|
||||
};
|
||||
|
||||
class SteelSeriesApexController
|
||||
{
|
||||
public:
|
||||
SteelSeriesApexController(hid_device* dev_handle);
|
||||
~SteelSeriesApexController();
|
||||
|
||||
void SetMode
|
||||
(
|
||||
unsigned char mode,
|
||||
std::vector<RGBColor> colors
|
||||
);
|
||||
|
||||
void SetLEDsDirect(std::vector<RGBColor> colors);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
unsigned char active_mode;
|
||||
|
||||
void SelectProfile
|
||||
(
|
||||
unsigned char profile
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,156 @@
|
||||
#include "SteelSeriesRivalController.h"
|
||||
#include "SteelSeriesSiberiaController.h"
|
||||
#include "SteelSeriesApexController.h"
|
||||
#include "SteelSeriesGeneric.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_SteelSeriesRival.h"
|
||||
#include "RGBController_SteelSeriesSiberia.h"
|
||||
#include "RGBController_SteelSeriesApex.h"
|
||||
#include <vector>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Vendor ID |
|
||||
\*-----------------------------------------------------*/
|
||||
#define STEELSERIES_VID 0x1038
|
||||
/*-----------------------------------------------------*\
|
||||
| Mouse product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define STEELSERIES_RIVAL_100_PID 0x1702
|
||||
#define STEELSERIES_RIVAL_100_DOTA_PID 0x170c
|
||||
#define STEELSERIES_RIVAL_105_PID 0x1814
|
||||
#define STEELSERIES_RIVAL_110_PID 0x1729
|
||||
#define STEELSERIES_RIVAL_300_PID 0x1710
|
||||
#define ACER_PREDATOR_RIVAL_300_PID 0x1714
|
||||
#define STEELSERIES_RIVAL_300_CSGO_PID 0x1394
|
||||
#define STEELSERIES_RIVAL_300_CSGO_STM32_PID 0x1716
|
||||
#define STEELSERIES_RIVAL_300_CSGO_HYPERBEAST_PID 0x171a
|
||||
#define STEELSERIES_RIVAL_300_DOTA_PID 0x1392
|
||||
#define STEELSERIES_RIVAL_300_HP_PID 0x1718
|
||||
#define STEELSERIES_RIVAL_300_BLACKOPS_PID 0x1710
|
||||
/*-----------------------------------------------------*\
|
||||
| Headset product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define STEELSERIES_SIBERIA_350_PID 0x1229
|
||||
/*-----------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
#define STEELSERIES_APEX_7_PID 0x1612
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usb_vid;
|
||||
unsigned short usb_pid;
|
||||
unsigned char usb_interface;
|
||||
device_type type;
|
||||
steelseries_type proto_type;
|
||||
const char * name;
|
||||
} steelseries_device;
|
||||
|
||||
#define STEELSERIES_NUM_DEVICES (sizeof(device_list) / sizeof(device_list[ 0 ]))
|
||||
|
||||
static const steelseries_device device_list[] =
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Mice |
|
||||
\*-----------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
{ STEELSERIES_VID, STEELSERIES_RIVAL_100_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_100, "SteelSeries Rival 100" },
|
||||
{ STEELSERIES_VID, STEELSERIES_RIVAL_100_DOTA_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_100, "SteelSeries Rival 100 DotA 2 Edition" },
|
||||
{ STEELSERIES_VID, STEELSERIES_RIVAL_105_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_100, "SteelSeries Rival 105" },
|
||||
{ STEELSERIES_VID, STEELSERIES_RIVAL_110_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_100, "SteelSeries Rival 110" },
|
||||
{ STEELSERIES_VID, STEELSERIES_RIVAL_300_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "SteelSeries Rival 300" },
|
||||
{ STEELSERIES_VID, ACER_PREDATOR_RIVAL_300_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "Acer Predator Gaming Mouse (Rival 300)" },
|
||||
{ STEELSERIES_VID, STEELSERIES_RIVAL_300_CSGO_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "SteelSeries Rival 300 CS:GO Fade Edition" },
|
||||
{ STEELSERIES_VID, STEELSERIES_RIVAL_300_CSGO_STM32_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "SteelSeries Rival 300 CS:GO Fade Edition (stm32)" },
|
||||
{ STEELSERIES_VID, STEELSERIES_RIVAL_300_CSGO_HYPERBEAST_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "SteelSeries Rival 300 CS:GO Hyperbeast Edition" },
|
||||
{ STEELSERIES_VID, STEELSERIES_RIVAL_300_DOTA_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "SteelSeries Rival 300 Dota 2 Edition" },
|
||||
{ STEELSERIES_VID, STEELSERIES_RIVAL_300_HP_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "SteelSeries Rival 300 HP Omen Edition" },
|
||||
{ STEELSERIES_VID, STEELSERIES_RIVAL_300_BLACKOPS_PID, 0, DEVICE_TYPE_MOUSE, RIVAL_300, "SteelSeries Rival 300 Black Ops Edition" },
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Headsets |
|
||||
\*-----------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
{ STEELSERIES_VID, STEELSERIES_SIBERIA_350_PID, 3, DEVICE_TYPE_HEADSET, SIBERIA_350, "SteelSeries Siberia 350" },
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*-----------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
{ STEELSERIES_VID, STEELSERIES_APEX_7_PID, 1, DEVICE_TYPE_KEYBOARD, APEX_7, "SteelSeries Apex 7" },
|
||||
};
|
||||
|
||||
/******************************************************************************************\
|
||||
* *
|
||||
* DetectSteelSeriesControllers *
|
||||
* *
|
||||
* Tests the USB address to find a SteelSeries Rival Mouse, Headset or Keyboard *
|
||||
* *
|
||||
\******************************************************************************************/
|
||||
|
||||
void DetectSteelSeriesControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
hid_device_info* info;
|
||||
hid_device* dev;
|
||||
|
||||
hid_init();
|
||||
|
||||
for(int device_idx = 0; device_idx < STEELSERIES_NUM_DEVICES; device_idx++)
|
||||
{
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(device_list[device_idx].usb_vid, device_list[device_idx].usb_pid);
|
||||
|
||||
//Look for SteelSeries RGB Peripheral
|
||||
while(info)
|
||||
{
|
||||
if((info->vendor_id == device_list[device_idx].usb_vid)
|
||||
&&(info->product_id == device_list[device_idx].usb_pid)
|
||||
&&(info->interface_number == device_list[device_idx].usb_interface))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
|
||||
if(dev)
|
||||
{
|
||||
switch(device_list[device_idx].type)
|
||||
{
|
||||
case DEVICE_TYPE_KEYBOARD:
|
||||
{
|
||||
SteelSeriesApexController* controller = new SteelSeriesApexController(dev);
|
||||
|
||||
RGBController_SteelSeriesApex* rgb_controller = new RGBController_SteelSeriesApex(controller);
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_HEADSET:
|
||||
{
|
||||
SteelSeriesSiberiaController* controller = new SteelSeriesSiberiaController(dev);
|
||||
|
||||
RGBController_SteelSeriesSiberia* rgb_controller = new RGBController_SteelSeriesSiberia(controller);
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_MOUSE:
|
||||
{
|
||||
SteelSeriesRivalController* controller = new SteelSeriesRivalController(dev, device_list[device_idx].proto_type);
|
||||
|
||||
RGBController_SteelSeriesRival* rgb_controller = new RGBController_SteelSeriesRival(controller);
|
||||
rgb_controller->name = device_list[device_idx].name;
|
||||
rgb_controllers.push_back(rgb_controller);
|
||||
}
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_MOUSEMAT:
|
||||
/* Not yet supported */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*-----------------------------------------*\
|
||||
| SteelSeriesGeneric.h |
|
||||
| |
|
||||
| Definitions and types for the SteelSeries|
|
||||
| Devices. |
|
||||
| |
|
||||
| B Horn (bahorn) 17/5/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
/* Allows us to handle variation in the protocol.
|
||||
* Defined in a single enum so we can keep the device_list struct the same
|
||||
* for every possible device. */
|
||||
typedef enum
|
||||
{
|
||||
RIVAL_100 = 0x00,
|
||||
RIVAL_300 = 0x01,
|
||||
SIBERIA_350 = 0x03,
|
||||
APEX_7 = 0x04,
|
||||
} steelseries_type;
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
/*-----------------------------------------*\
|
||||
| SteelSeriesRivalController.h |
|
||||
| |
|
||||
| Definitions and types for SteelSeries |
|
||||
| Rival lighting controller |
|
||||
| |
|
||||
| B Horn (bahorn) 13/5/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "SteelSeriesRivalController.h"
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void send_usb_msg(hid_device* dev, char * data_pkt, unsigned int size)
|
||||
{
|
||||
char* usb_pkt = new char[size + 1];
|
||||
|
||||
usb_pkt[0] = 0x00;
|
||||
for(unsigned int i = 1; i < size + 1; i++)
|
||||
{
|
||||
usb_pkt[i] = data_pkt[i-1];
|
||||
}
|
||||
|
||||
hid_write(dev, (unsigned char *)usb_pkt, size + 1);
|
||||
|
||||
delete usb_pkt;
|
||||
}
|
||||
|
||||
SteelSeriesRivalController::SteelSeriesRivalController
|
||||
(
|
||||
hid_device* dev_handle,
|
||||
steelseries_type proto_type
|
||||
)
|
||||
{
|
||||
dev = dev_handle;
|
||||
proto = proto_type;
|
||||
}
|
||||
|
||||
SteelSeriesRivalController::~SteelSeriesRivalController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
char* SteelSeriesRivalController::GetDeviceName()
|
||||
{
|
||||
return device_name;
|
||||
}
|
||||
|
||||
steelseries_type SteelSeriesRivalController::GetMouseType()
|
||||
{
|
||||
return proto;
|
||||
}
|
||||
|
||||
/* Saves to the internal configuration */
|
||||
void SteelSeriesRivalController::Save()
|
||||
{
|
||||
char usb_buf[9];
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
usb_buf[0x00] = 0x09;
|
||||
send_usb_msg(dev, usb_buf, 9);
|
||||
}
|
||||
|
||||
|
||||
void SteelSeriesRivalController::SetLightEffect
|
||||
(
|
||||
unsigned char zone_id,
|
||||
unsigned char effect
|
||||
)
|
||||
{
|
||||
char usb_buf[9];
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
switch (proto) {
|
||||
case RIVAL_100:
|
||||
usb_buf[0x00] = 0x07;
|
||||
usb_buf[0x01] = 0x00;
|
||||
break;
|
||||
case RIVAL_300:
|
||||
usb_buf[0x00] = 0x07;
|
||||
usb_buf[0x01] = zone_id + 1;
|
||||
break;
|
||||
}
|
||||
usb_buf[0x02] = effect;
|
||||
send_usb_msg(dev, usb_buf, 9);
|
||||
}
|
||||
|
||||
|
||||
void SteelSeriesRivalController::SetLightEffectAll
|
||||
(
|
||||
unsigned char effect
|
||||
)
|
||||
{
|
||||
switch(proto)
|
||||
{
|
||||
case RIVAL_100:
|
||||
SetLightEffect(0, effect);
|
||||
break;
|
||||
|
||||
case RIVAL_300:
|
||||
SetLightEffect(0, effect);
|
||||
SetLightEffect(1, effect);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void SteelSeriesRivalController::SetColor
|
||||
(
|
||||
unsigned char zone_id,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
char usb_buf[9];
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
switch (proto)
|
||||
{
|
||||
case RIVAL_100:
|
||||
usb_buf[0x00] = 0x05;
|
||||
usb_buf[0x01] = 0x00;
|
||||
break;
|
||||
|
||||
case RIVAL_300:
|
||||
usb_buf[0x00] = 0x08;
|
||||
usb_buf[0x01] = zone_id + 1;
|
||||
break;
|
||||
}
|
||||
usb_buf[0x02] = red;
|
||||
usb_buf[0x03] = green;
|
||||
usb_buf[0x04] = blue;
|
||||
|
||||
send_usb_msg(dev, usb_buf, 9);
|
||||
}
|
||||
|
||||
void SteelSeriesRivalController::SetColorAll
|
||||
(
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
switch(proto)
|
||||
{
|
||||
case RIVAL_100:
|
||||
SetColor(0, red, green, blue);
|
||||
break;
|
||||
|
||||
case RIVAL_300:
|
||||
SetColor(0, red, green, blue);
|
||||
SetColor(1, red, green, blue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*-----------------------------------------*\
|
||||
| SteelSeriesRivalController.h |
|
||||
| |
|
||||
| Definitions and types for SteelSeries |
|
||||
| Rival lighting controller |
|
||||
| |
|
||||
| B Horn (bahorn) 13/5/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#include "SteelSeriesGeneric.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
/* Mode, we then use these to set actual effect based on speed. */
|
||||
enum
|
||||
{
|
||||
STEELSERIES_RIVAL_STATIC = 0x00,
|
||||
STEELSERIES_RIVAL_PULSATE = 0x01
|
||||
};
|
||||
|
||||
/* Effects */
|
||||
enum
|
||||
{
|
||||
STEELSERIES_RIVAL_EFFECT_STATIC = 0x01,
|
||||
STEELSERIES_RIVAL_EFFECT_PULSATE_MIN = 0x02,
|
||||
STEELSERIES_RIVAL_EFFECT_PULSATE_MID = 0x03,
|
||||
STEELSERIES_RIVAL_EFFECT_PULSATE_MAX = 0x04
|
||||
};
|
||||
|
||||
class SteelSeriesRivalController
|
||||
{
|
||||
public:
|
||||
SteelSeriesRivalController
|
||||
(
|
||||
hid_device* dev_handle,
|
||||
steelseries_type proto_type
|
||||
);
|
||||
|
||||
~SteelSeriesRivalController();
|
||||
|
||||
char* GetDeviceName();
|
||||
|
||||
steelseries_type GetMouseType();
|
||||
|
||||
void Save();
|
||||
|
||||
void SetLightEffect
|
||||
(
|
||||
unsigned char zone_id,
|
||||
unsigned char effect
|
||||
);
|
||||
|
||||
void SetLightEffectAll
|
||||
(
|
||||
unsigned char effect
|
||||
);
|
||||
|
||||
void SetColor
|
||||
(
|
||||
unsigned char zone_id,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
void SetColorAll
|
||||
(
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
char device_name[32];
|
||||
hid_device* dev;
|
||||
steelseries_type proto;
|
||||
};
|
||||
@@ -0,0 +1,92 @@
|
||||
/*-----------------------------------------*\
|
||||
| SteelSeriesSiberiaController.cpp |
|
||||
| |
|
||||
| Definitions and types for SteelSeries |
|
||||
| Siberia lighting controller |
|
||||
| |
|
||||
| E Karlsson (pilophae) 18/6/2020 |
|
||||
|
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include "SteelSeriesSiberiaController.h"
|
||||
#include <cstring>
|
||||
|
||||
static void send_usb_msg(hid_device* dev, char * data_pkt, unsigned int size)
|
||||
{
|
||||
char* usb_pkt = new char[16];
|
||||
memset(usb_pkt, 0x00, sizeof(usb_pkt));
|
||||
|
||||
// Report number
|
||||
usb_pkt[0] = 0x01;
|
||||
// Magic
|
||||
usb_pkt[1] = 0x00;
|
||||
// Command
|
||||
usb_pkt[2] = data_pkt[0];
|
||||
// Payload length
|
||||
usb_pkt[3] = size - 1;
|
||||
|
||||
for(unsigned int i = 0; i < (size - 1); i++)
|
||||
{
|
||||
usb_pkt[4 + i] = data_pkt[1 + i];
|
||||
}
|
||||
|
||||
hid_write(dev, (unsigned char *)usb_pkt, 16);
|
||||
|
||||
delete[] usb_pkt;
|
||||
}
|
||||
|
||||
SteelSeriesSiberiaController::SteelSeriesSiberiaController
|
||||
(
|
||||
hid_device* dev_handle
|
||||
)
|
||||
{
|
||||
dev = dev_handle;
|
||||
}
|
||||
|
||||
SteelSeriesSiberiaController::~SteelSeriesSiberiaController()
|
||||
{
|
||||
}
|
||||
|
||||
char* SteelSeriesSiberiaController::GetDeviceName()
|
||||
{
|
||||
return device_name;
|
||||
}
|
||||
|
||||
void SteelSeriesSiberiaController::SetColor
|
||||
(
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
char usb_buf[4];
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
// Command 1
|
||||
usb_buf[0] = 0x95;
|
||||
usb_buf[1] = 0x80;
|
||||
usb_buf[2] = 0xbf;
|
||||
send_usb_msg(dev, usb_buf, 3);
|
||||
|
||||
// Command 2
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
usb_buf[0] = 0x80;
|
||||
usb_buf[1] = 0x52;
|
||||
usb_buf[2] = 0x20;
|
||||
send_usb_msg(dev, usb_buf, 3);
|
||||
|
||||
// Command 3 (Set color)
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
usb_buf[0] = 0x83;
|
||||
usb_buf[1] = red;
|
||||
usb_buf[2] = green;
|
||||
usb_buf[3] = blue;
|
||||
send_usb_msg(dev, usb_buf, 4);
|
||||
|
||||
// Command 4
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
usb_buf[0] = 0x93;
|
||||
usb_buf[1] = 0x03;
|
||||
usb_buf[2] = 0x80;
|
||||
send_usb_msg(dev, usb_buf, 3);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*-----------------------------------------*\
|
||||
| SteelSeriesSiberiaController.h |
|
||||
| |
|
||||
| Definitions and types for SteelSeries |
|
||||
| Siberia lighting controller |
|
||||
| |
|
||||
| E Karlsson (pilophae) 18/6/2020 |
|
||||
\*-----------------------------------------*/
|
||||
|
||||
#include <string>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
class SteelSeriesSiberiaController
|
||||
{
|
||||
public:
|
||||
SteelSeriesSiberiaController
|
||||
(
|
||||
hid_device* dev_handle
|
||||
);
|
||||
|
||||
~SteelSeriesSiberiaController();
|
||||
|
||||
char* GetDeviceName();
|
||||
|
||||
void SetColor
|
||||
(
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
char device_name[32];
|
||||
hid_device* dev;
|
||||
};
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
ThermaltakeRiingController::ThermaltakeRiingController(libusb_device_handle* dev_handle)
|
||||
ThermaltakeRiingController::ThermaltakeRiingController(hid_device* dev_handle)
|
||||
{
|
||||
dev = dev_handle;
|
||||
|
||||
@@ -52,8 +52,7 @@ void ThermaltakeRiingController::SetMode(unsigned char mode, unsigned char speed
|
||||
|
||||
void ThermaltakeRiingController::SendInit()
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
int actual;
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -63,14 +62,15 @@ void ThermaltakeRiingController::SendInit()
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Init packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0xFE;
|
||||
usb_buf[0x01] = 0x33;
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0xFE;
|
||||
usb_buf[0x02] = 0x33;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
|
||||
libusb_interrupt_transfer(dev, 0x81, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 65);
|
||||
}
|
||||
|
||||
void ThermaltakeRiingController::SendRGB
|
||||
@@ -82,8 +82,7 @@ void ThermaltakeRiingController::SendRGB
|
||||
unsigned char* color_data
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[64];
|
||||
int actual;
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
@@ -93,19 +92,20 @@ void ThermaltakeRiingController::SendRGB
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up RGB packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x32;
|
||||
usb_buf[0x01] = 0x52;
|
||||
usb_buf[0x02] = port;
|
||||
usb_buf[0x03] = mode + ( speed & 0x03 );
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x32;
|
||||
usb_buf[0x02] = 0x52;
|
||||
usb_buf[0x03] = port;
|
||||
usb_buf[0x04] = mode + ( speed & 0x03 );
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in GRB color data |
|
||||
\*-----------------------------------------------------*/
|
||||
memcpy(&usb_buf[0x04], color_data, (num_colors * 3));
|
||||
memcpy(&usb_buf[0x05], color_data, (num_colors * 3));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
libusb_interrupt_transfer(dev, 0x01, usb_buf, 64, &actual, 0);
|
||||
libusb_interrupt_transfer(dev, 0x81, usb_buf, 64, &actual, 0);
|
||||
hid_write(dev, usb_buf, 65);
|
||||
hid_read(dev, usb_buf, 65);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "RGBController.h"
|
||||
#include <vector>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -47,14 +47,14 @@ enum
|
||||
class ThermaltakeRiingController
|
||||
{
|
||||
public:
|
||||
ThermaltakeRiingController(libusb_device_handle* dev_handle);
|
||||
ThermaltakeRiingController(hid_device* dev_handle);
|
||||
~ThermaltakeRiingController();
|
||||
|
||||
void SetChannelLEDs(unsigned char channel, RGBColor * colors, unsigned int num_colors);
|
||||
void SetMode(unsigned char mode, unsigned char speed);
|
||||
|
||||
private:
|
||||
libusb_device_handle* dev;
|
||||
hid_device* dev;
|
||||
|
||||
unsigned char current_mode;
|
||||
unsigned char current_speed;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_ThermaltakeRiing.h"
|
||||
#include <vector>
|
||||
#include <libusb-1.0/libusb.h>
|
||||
#include <hidapi/hidapi.h>
|
||||
|
||||
#define THERMALTAKE_RIING_VID 0x264A
|
||||
#define THERMALTAKE_RIING_PID_BEGIN 0x1FA5
|
||||
@@ -18,19 +18,34 @@
|
||||
|
||||
void DetectThermaltakeRiingControllers(std::vector<RGBController*>& rgb_controllers)
|
||||
{
|
||||
libusb_context * ctx;
|
||||
libusb_init(&ctx);
|
||||
hid_device_info* info;
|
||||
hid_device* dev;
|
||||
|
||||
hid_init();
|
||||
|
||||
for(int pid = THERMALTAKE_RIING_PID_BEGIN; pid <= THERMALTAKE_RIING_PID_END; pid++)
|
||||
{
|
||||
dev = NULL;
|
||||
|
||||
info = hid_enumerate(THERMALTAKE_RIING_VID, pid);
|
||||
|
||||
//Look for Thermaltake Riing device
|
||||
libusb_device_handle * dev = libusb_open_device_with_vid_pid(ctx, THERMALTAKE_RIING_VID, pid);
|
||||
|
||||
if( dev )
|
||||
while(info)
|
||||
{
|
||||
libusb_detach_kernel_driver(dev, 0);
|
||||
libusb_claim_interface(dev, 0);
|
||||
if((info->vendor_id == THERMALTAKE_RIING_VID)
|
||||
&&(info->product_id == pid))
|
||||
{
|
||||
dev = hid_open_path(info->path);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
info = info->next;
|
||||
}
|
||||
}
|
||||
|
||||
if(dev)
|
||||
{
|
||||
ThermaltakeRiingController* controller = new ThermaltakeRiingController(dev);
|
||||
|
||||
RGBController_ThermaltakeRiing* rgb_controller = new RGBController_ThermaltakeRiing(controller);
|
||||
|
||||
+75
-30
@@ -10,24 +10,32 @@
|
||||
#include "RGBController_Network.h"
|
||||
#include <cstring>
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#define MSG_NOSIGNAL 0
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
||||
static void Sleep(unsigned int milliseconds)
|
||||
{
|
||||
usleep(1000 * milliseconds);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <unistd.h>
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
NetworkClient::NetworkClient(std::vector<RGBController *>& control) : controllers(control)
|
||||
{
|
||||
strcpy(port_ip, "127.0.0.1");
|
||||
port_num = 1337;
|
||||
port_num = OPENRGB_SDK_PORT;
|
||||
server_connected = false;
|
||||
server_controller_count = 0;
|
||||
|
||||
ListenThread = NULL;
|
||||
ConnectionThread = NULL;
|
||||
}
|
||||
|
||||
void NetworkClient::ClientInfoChanged()
|
||||
@@ -55,9 +63,14 @@ unsigned short NetworkClient::GetPort()
|
||||
return port_num;
|
||||
}
|
||||
|
||||
bool NetworkClient::GetConnected()
|
||||
{
|
||||
return(server_connected);
|
||||
}
|
||||
|
||||
bool NetworkClient::GetOnline()
|
||||
{
|
||||
return server_connected;
|
||||
return(server_connected && server_initialized);
|
||||
}
|
||||
|
||||
void NetworkClient::RegisterClientInfoChangeCallback(NetClientCallback new_callback, void * new_callback_arg)
|
||||
@@ -100,6 +113,8 @@ void NetworkClient::StartClient()
|
||||
|
||||
port.tcp_client(port_ip, port_str);
|
||||
|
||||
client_active = true;
|
||||
|
||||
//Start the connection thread
|
||||
ConnectionThread = new std::thread(&NetworkClient::ConnectionThreadFunction, this);
|
||||
|
||||
@@ -111,7 +126,19 @@ void NetworkClient::StartClient()
|
||||
|
||||
void NetworkClient::StopClient()
|
||||
{
|
||||
server_connected = false;
|
||||
client_active = false;
|
||||
|
||||
shutdown(client_sock, SD_RECEIVE);
|
||||
closesocket(client_sock);
|
||||
if(ListenThread)
|
||||
ListenThread->join();
|
||||
ConnectionThread->join();
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Client info has changed, call the callbacks |
|
||||
\*-------------------------------------------------*/
|
||||
ClientInfoChanged();
|
||||
}
|
||||
|
||||
void NetworkClient::ConnectionThreadFunction()
|
||||
@@ -119,7 +146,7 @@ void NetworkClient::ConnectionThreadFunction()
|
||||
unsigned int requested_controllers;
|
||||
|
||||
//This thread manages the connection to the server
|
||||
while(1)
|
||||
while(client_active == true)
|
||||
{
|
||||
if(server_connected == false)
|
||||
{
|
||||
@@ -158,7 +185,7 @@ void NetworkClient::ConnectionThreadFunction()
|
||||
server_controller_count = 0;
|
||||
|
||||
//Wait for server to connect
|
||||
Sleep(100);
|
||||
std::this_thread::sleep_for(100ms);
|
||||
|
||||
//Once server is connected, send client string
|
||||
SendData_ClientString();
|
||||
@@ -169,7 +196,7 @@ void NetworkClient::ConnectionThreadFunction()
|
||||
//Wait for server controller count
|
||||
while(server_controller_count == 0)
|
||||
{
|
||||
Sleep(100);
|
||||
std::this_thread::sleep_for(5ms);
|
||||
}
|
||||
|
||||
printf("Client: Received controller count from server: %d\r\n", server_controller_count);
|
||||
@@ -179,12 +206,13 @@ void NetworkClient::ConnectionThreadFunction()
|
||||
{
|
||||
printf("Client: Requesting controller %d\r\n", requested_controllers);
|
||||
|
||||
controller_data_received = false;
|
||||
SendRequest_ControllerData(requested_controllers);
|
||||
|
||||
//Wait until controller is received
|
||||
while(server_controllers.size() == requested_controllers)
|
||||
while(controller_data_received == false)
|
||||
{
|
||||
Sleep(100);
|
||||
std::this_thread::sleep_for(5ms);
|
||||
}
|
||||
|
||||
requested_controllers++;
|
||||
@@ -205,7 +233,7 @@ void NetworkClient::ConnectionThreadFunction()
|
||||
ClientInfoChanged();
|
||||
}
|
||||
|
||||
Sleep(1000);
|
||||
std::this_thread::sleep_for(1s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,11 +241,12 @@ int NetworkClient::recv_select(SOCKET s, char *buf, int len, int flags)
|
||||
{
|
||||
fd_set set;
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&set); /* clear the set */
|
||||
FD_SET(s, &set); /* add our file descriptor to the set */
|
||||
|
||||
@@ -236,6 +265,7 @@ int NetworkClient::recv_select(SOCKET s, char *buf, int len, int flags)
|
||||
// socket has something to read
|
||||
return(recv(s, buf, len, flags));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +273,7 @@ void NetworkClient::ListenThreadFunction()
|
||||
{
|
||||
printf("Network client listener started\n");
|
||||
//This thread handles messages received from the server
|
||||
while(server_connected = true)
|
||||
while(server_connected == true)
|
||||
{
|
||||
NetPacketHeader header;
|
||||
int bytes_read = 0;
|
||||
@@ -322,8 +352,6 @@ void NetworkClient::ListenThreadFunction()
|
||||
|
||||
} while(bytes_read != sizeof(header) - sizeof(header.pkt_magic));
|
||||
|
||||
//printf( "Client: Received header, now receiving data of size %d\r\n", header.pkt_size);
|
||||
|
||||
//Header received, now receive the data
|
||||
if(header.pkt_size > 0)
|
||||
{
|
||||
@@ -346,21 +374,14 @@ void NetworkClient::ListenThreadFunction()
|
||||
} while (bytes_read < header.pkt_size);
|
||||
}
|
||||
|
||||
//printf( "Client: Received header and data\r\n" );
|
||||
//printf( "Client: Packet ID: %d \r\n", header.pkt_id);
|
||||
|
||||
//Entire request received, select functionality based on request ID
|
||||
switch(header.pkt_id)
|
||||
{
|
||||
case NET_PACKET_ID_REQUEST_CONTROLLER_COUNT:
|
||||
printf( "Client: NET_PACKET_ID_REQUEST_CONTROLLER_COUNT\r\n" );
|
||||
|
||||
ProcessReply_ControllerCount(header.pkt_size, data);
|
||||
break;
|
||||
|
||||
case NET_PACKET_ID_REQUEST_CONTROLLER_DATA:
|
||||
printf( "Client: NET_PACKET_ID_REQUEST_CONTROLLER_DATA\r\n");
|
||||
|
||||
ProcessReply_ControllerData(header.pkt_size, data, header.pkt_dev_idx);
|
||||
break;
|
||||
}
|
||||
@@ -395,6 +416,20 @@ listen_done:
|
||||
ClientInfoChanged();
|
||||
}
|
||||
|
||||
void NetworkClient::WaitOnControllerData()
|
||||
{
|
||||
for(int i = 0; i < 1000; i++)
|
||||
{
|
||||
if(controller_data_received)
|
||||
{
|
||||
break;
|
||||
}
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void NetworkClient::ProcessReply_ControllerCount(unsigned int data_size, char * data)
|
||||
{
|
||||
if(data_size == sizeof(unsigned int))
|
||||
@@ -409,9 +444,17 @@ void NetworkClient::ProcessReply_ControllerData(unsigned int data_size, char * d
|
||||
|
||||
new_controller->ReadDeviceDescription((unsigned char *)data);
|
||||
|
||||
printf("Received controller: %s\r\n", new_controller->name.c_str());
|
||||
if(dev_idx >= server_controllers.size())
|
||||
{
|
||||
server_controllers.push_back(new_controller);
|
||||
}
|
||||
else
|
||||
{
|
||||
server_controllers[dev_idx]->active_mode = new_controller->active_mode;
|
||||
delete new_controller;
|
||||
}
|
||||
|
||||
server_controllers.push_back(new_controller);
|
||||
controller_data_received = true;
|
||||
}
|
||||
|
||||
void NetworkClient::SendData_ClientString()
|
||||
@@ -451,6 +494,8 @@ void NetworkClient::SendRequest_ControllerData(unsigned int dev_idx)
|
||||
{
|
||||
NetPacketHeader reply_hdr;
|
||||
|
||||
controller_data_received = false;
|
||||
|
||||
reply_hdr.pkt_magic[0] = 'O';
|
||||
reply_hdr.pkt_magic[1] = 'R';
|
||||
reply_hdr.pkt_magic[2] = 'G';
|
||||
|
||||
@@ -24,6 +24,7 @@ public:
|
||||
|
||||
void ClientInfoChanged();
|
||||
|
||||
bool GetConnected();
|
||||
const char * GetIP();
|
||||
unsigned short GetPort();
|
||||
bool GetOnline();
|
||||
@@ -40,6 +41,8 @@ public:
|
||||
void ConnectionThreadFunction();
|
||||
void ListenThreadFunction();
|
||||
|
||||
void WaitOnControllerData();
|
||||
|
||||
void ProcessReply_ControllerCount(unsigned int data_size, char * data);
|
||||
void ProcessReply_ControllerData(unsigned int data_size, char * data, unsigned int dev_idx);
|
||||
|
||||
@@ -70,6 +73,8 @@ private:
|
||||
net_port port;
|
||||
char port_ip[20];
|
||||
unsigned short port_num;
|
||||
bool client_active;
|
||||
bool controller_data_received;
|
||||
bool server_connected;
|
||||
bool server_initialized;
|
||||
unsigned int server_controller_count;
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
/*-----------------------------------------*\
|
||||
| Default OpenRGB SDK port is 6742 |
|
||||
| This is "ORGB" on a phone keypad |
|
||||
\*-----------------------------------------*/
|
||||
#define OPENRGB_SDK_PORT 6742
|
||||
|
||||
typedef struct NetPacketHeader
|
||||
{
|
||||
char pkt_magic[4]; /* Magic value "ORGB" identifies beginning of packet */
|
||||
|
||||
+77
-40
@@ -28,16 +28,14 @@ const char yes = 1;
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
||||
static void Sleep(unsigned int milliseconds)
|
||||
{
|
||||
usleep(1000 * milliseconds);
|
||||
}
|
||||
#endif
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
|
||||
NetworkServer::NetworkServer(std::vector<RGBController *>& control) : controllers(control)
|
||||
{
|
||||
port_num = 1337;
|
||||
port_num = OPENRGB_SDK_PORT;
|
||||
server_online = false;
|
||||
}
|
||||
|
||||
@@ -73,26 +71,42 @@ unsigned int NetworkServer::GetNumClients()
|
||||
|
||||
const char * NetworkServer::GetClientString(unsigned int client_num)
|
||||
{
|
||||
const char * result;
|
||||
|
||||
ServerClientsMutex.lock();
|
||||
|
||||
if(client_num < ServerClients.size())
|
||||
{
|
||||
return ServerClients[client_num]->client_string.c_str();
|
||||
result = ServerClients[client_num]->client_string.c_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
result = "";
|
||||
}
|
||||
|
||||
ServerClientsMutex.unlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const char * NetworkServer::GetClientIP(unsigned int client_num)
|
||||
{
|
||||
const char * result;
|
||||
|
||||
ServerClientsMutex.lock();
|
||||
|
||||
if(client_num < ServerClients.size())
|
||||
{
|
||||
return ServerClients[client_num]->client_ip;
|
||||
result = ServerClients[client_num]->client_ip;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
result = "";
|
||||
}
|
||||
|
||||
ServerClientsMutex.unlock();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void NetworkServer::RegisterClientInfoChangeCallback(NetServerCallback new_callback, void * new_callback_arg)
|
||||
@@ -134,6 +148,7 @@ void NetworkServer::StartServer()
|
||||
server_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (server_sock == INVALID_SOCKET)
|
||||
{
|
||||
printf("Error: network socket could not be created\n");
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
@@ -150,6 +165,7 @@ void NetworkServer::StartServer()
|
||||
\*-------------------------------------------------*/
|
||||
if (bind(server_sock, (sockaddr*)&myAddress, sizeof(myAddress)) == SOCKET_ERROR)
|
||||
{
|
||||
printf("Error: Could not bind network socket \nIs port %hu already being used?\n", GetPort());
|
||||
WSACleanup();
|
||||
return;
|
||||
}
|
||||
@@ -165,30 +181,26 @@ void NetworkServer::StartServer()
|
||||
| Start the connection thread |
|
||||
\*-------------------------------------------------*/
|
||||
ConnectionThread = new std::thread(&NetworkServer::ConnectionThreadFunction, this);
|
||||
ConnectionThread->detach();
|
||||
}
|
||||
|
||||
void NetworkServer::StopServer()
|
||||
{
|
||||
server_online = false;
|
||||
|
||||
ServerClientsMutex.lock();
|
||||
for(unsigned int client_idx = 0; client_idx < ServerClients.size(); client_idx++)
|
||||
{
|
||||
shutdown(ServerClients[client_idx]->client_sock, SD_RECEIVE);
|
||||
closesocket(ServerClients[client_idx]->client_sock);
|
||||
ServerClients[client_idx]->client_listen_thread->join();
|
||||
delete ServerClients[client_idx];
|
||||
}
|
||||
|
||||
shutdown(server_sock, SD_RECEIVE);
|
||||
closesocket(server_sock);
|
||||
|
||||
ConnectionThread->join();
|
||||
|
||||
for(unsigned int client_idx = 0; client_idx < ServerClients.size(); client_idx++)
|
||||
{
|
||||
delete ServerClients[client_idx];
|
||||
}
|
||||
|
||||
ServerClients.clear();
|
||||
ServerClientsMutex.unlock();
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Client info has changed, call the callbacks |
|
||||
@@ -200,7 +212,7 @@ void NetworkServer::ConnectionThreadFunction()
|
||||
{
|
||||
//This thread handles client connections
|
||||
|
||||
printf("Network connection thread started\n");
|
||||
printf("Network connection thread started on port %hu\n", GetPort());
|
||||
while(server_online == true)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
@@ -248,10 +260,15 @@ void NetworkServer::ConnectionThreadFunction()
|
||||
|
||||
client_info->client_string = "Client";
|
||||
|
||||
/* We need to lock before the thread could possibly finish */
|
||||
ServerClientsMutex.lock();
|
||||
|
||||
//Start a listener thread for the new client socket
|
||||
client_info->client_listen_thread = new std::thread(&NetworkServer::ListenThreadFunction, this, client_info);
|
||||
client_info->client_listen_thread->detach();
|
||||
|
||||
ServerClients.push_back(client_info);
|
||||
ServerClientsMutex.unlock();
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Client info has changed, call the callbacks |
|
||||
@@ -267,13 +284,14 @@ int NetworkServer::accept_select(int sockfd, struct sockaddr *addr, socklen_t *a
|
||||
{
|
||||
fd_set set;
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
FD_ZERO(&set); /* clear the set */
|
||||
FD_SET(sockfd, &set); /* add our file descriptor to the set */
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&set); /* clear the set */
|
||||
FD_SET(sockfd, &set); /* add our file descriptor to the set */
|
||||
|
||||
int rv = select(sockfd + 1, &set, NULL, NULL, &timeout);
|
||||
|
||||
@@ -297,11 +315,12 @@ int NetworkServer::recv_select(SOCKET s, char *buf, int len, int flags)
|
||||
{
|
||||
fd_set set;
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
while(1)
|
||||
{
|
||||
timeout.tv_sec = 5;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
FD_ZERO(&set); /* clear the set */
|
||||
FD_SET(s, &set); /* add our file descriptor to the set */
|
||||
|
||||
@@ -408,8 +427,6 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info)
|
||||
|
||||
} while(bytes_read != sizeof(header) - sizeof(header.pkt_magic));
|
||||
|
||||
//printf( "Server: Received header, now receiving data of size %d\r\n", header.pkt_size);
|
||||
|
||||
//Header received, now receive the data
|
||||
if(header.pkt_size > 0)
|
||||
{
|
||||
@@ -432,29 +449,31 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info)
|
||||
} while (bytes_read < header.pkt_size);
|
||||
}
|
||||
|
||||
//printf( "Server: Received header and data\r\n" );
|
||||
//printf( "Server: Packet ID: %d \r\n", header.pkt_id);
|
||||
|
||||
//Entire request received, select functionality based on request ID
|
||||
switch(header.pkt_id)
|
||||
{
|
||||
case NET_PACKET_ID_REQUEST_CONTROLLER_COUNT:
|
||||
//printf( "NET_PACKET_ID_REQUEST_CONTROLLER_COUNT\r\n" );
|
||||
SendReply_ControllerCount(client_sock);
|
||||
break;
|
||||
|
||||
case NET_PACKET_ID_REQUEST_CONTROLLER_DATA:
|
||||
//printf( "NET_PACKET_ID_REQUEST_CONTROLLER_DATA\r\n" );
|
||||
SendReply_ControllerData(client_sock, header.pkt_dev_idx);
|
||||
break;
|
||||
|
||||
case NET_PACKET_ID_SET_CLIENT_NAME:
|
||||
printf( "NET_PACKET_ID_SET_CLIENT_NAME\r\n" );
|
||||
if(data == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ProcessRequest_ClientString(client_sock, header.pkt_size, data);
|
||||
break;
|
||||
|
||||
case NET_PACKET_ID_RGBCONTROLLER_RESIZEZONE:
|
||||
//printf( "NET_PACKET_ID_RGBCONTROLLER_RESIZEZONE\r\n" );
|
||||
if(data == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if((header.pkt_dev_idx < controllers.size()) && (header.pkt_size == (2 * sizeof(int))))
|
||||
{
|
||||
@@ -469,7 +488,10 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info)
|
||||
break;
|
||||
|
||||
case NET_PACKET_ID_RGBCONTROLLER_UPDATELEDS:
|
||||
//printf( "NET_PACKET_ID_RGBCONTROLLER_UPDATELEDS\r\n" );
|
||||
if(data == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(header.pkt_dev_idx < controllers.size())
|
||||
{
|
||||
@@ -479,7 +501,10 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info)
|
||||
break;
|
||||
|
||||
case NET_PACKET_ID_RGBCONTROLLER_UPDATEZONELEDS:
|
||||
//printf( "NET_PACKET_ID_RGBCONTROLLER_UPDATEZONELEDS\r\n" );
|
||||
if(data == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(header.pkt_dev_idx < controllers.size())
|
||||
{
|
||||
@@ -493,7 +518,10 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info)
|
||||
break;
|
||||
|
||||
case NET_PACKET_ID_RGBCONTROLLER_UPDATESINGLELED:
|
||||
//printf( "NET_PACKET_ID_RGBCONTROLLER_UPDATESINGLELED\r\n" );
|
||||
if(data == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(header.pkt_dev_idx < controllers.size())
|
||||
{
|
||||
@@ -507,8 +535,6 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info)
|
||||
break;
|
||||
|
||||
case NET_PACKET_ID_RGBCONTROLLER_SETCUSTOMMODE:
|
||||
//printf( "NET_PACKET_ID_RGBCONTROLLER_SETCUSTOMMODE\r\n" );
|
||||
|
||||
if(header.pkt_dev_idx < controllers.size())
|
||||
{
|
||||
controllers[header.pkt_dev_idx]->SetCustomMode();
|
||||
@@ -516,7 +542,10 @@ void NetworkServer::ListenThreadFunction(NetworkClientInfo * client_info)
|
||||
break;
|
||||
|
||||
case NET_PACKET_ID_RGBCONTROLLER_UPDATEMODE:
|
||||
//printf( "NET_PACKET_ID_RGBCONTROLLER_UPDATEMODE\r\n" );
|
||||
if(data == NULL)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(header.pkt_dev_idx < controllers.size())
|
||||
{
|
||||
@@ -534,15 +563,21 @@ listen_done:
|
||||
shutdown(client_info->client_sock, SD_RECEIVE);
|
||||
closesocket(client_info->client_sock);
|
||||
|
||||
ServerClientsMutex.lock();
|
||||
|
||||
for(unsigned int this_idx = 0; this_idx < ServerClients.size(); this_idx++)
|
||||
{
|
||||
if(ServerClients[this_idx] == client_info)
|
||||
{
|
||||
delete client_info->client_listen_thread;
|
||||
delete client_info;
|
||||
ServerClients.erase(ServerClients.begin() + this_idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ServerClientsMutex.unlock();
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Client info has changed, call the callbacks |
|
||||
\*-------------------------------------------------*/
|
||||
@@ -551,6 +586,7 @@ listen_done:
|
||||
|
||||
void NetworkServer::ProcessRequest_ClientString(SOCKET client_sock, unsigned int data_size, char * data)
|
||||
{
|
||||
ServerClientsMutex.lock();
|
||||
for(unsigned int this_idx = 0; this_idx < ServerClients.size(); this_idx++)
|
||||
{
|
||||
if(ServerClients[this_idx]->client_sock == client_sock)
|
||||
@@ -559,6 +595,7 @@ void NetworkServer::ProcessRequest_ClientString(SOCKET client_sock, unsigned int
|
||||
break;
|
||||
}
|
||||
}
|
||||
ServerClientsMutex.unlock();
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Client info has changed, call the callbacks |
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -58,6 +59,7 @@ protected:
|
||||
|
||||
std::vector<RGBController *>& controllers;
|
||||
|
||||
std::mutex ServerClientsMutex;
|
||||
std::vector<NetworkClientInfo *> ServerClients;
|
||||
std::thread * ConnectionThread;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user