Compare commits
209
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1538936758 | ||
|
|
255cfcf422 | ||
|
|
c029bb2b1d | ||
|
|
e958e0132e | ||
|
|
51daeed585 | ||
|
|
60e4309eec | ||
|
|
31247bacd4 | ||
|
|
2c23fd6ace | ||
|
|
61fcdd1a1c | ||
|
|
dc0e9b2fd3 | ||
|
|
c90eafbe72 | ||
|
|
b087a65f3c | ||
|
|
c31c6088ac | ||
|
|
b14342d9ee | ||
|
|
849e725b11 | ||
|
|
b23da372ad | ||
|
|
a96b5e0f1a | ||
|
|
6315c79afa | ||
|
|
ee8d24bac6 | ||
|
|
d9a726d97f | ||
|
|
1a55da8ac4 | ||
|
|
5c8baf47f8 | ||
|
|
249c22082d | ||
|
|
02237aeb4d | ||
|
|
5d7090b5fd | ||
|
|
f70c3bf8d4 | ||
|
|
dc0d2e2d2f | ||
|
|
fa91a11964 | ||
|
|
ecf0bfc847 | ||
|
|
41b7087e20 | ||
|
|
046a1bae65 | ||
|
|
a9a1856b9c | ||
|
|
d7f452e542 | ||
|
|
799113942c | ||
|
|
206ef9aca5 | ||
|
|
603714f749 | ||
|
|
49e1687141 | ||
|
|
6d07573fff | ||
|
|
2a0222bde1 | ||
|
|
725d0ec1f5 | ||
|
|
f14b6cb49d | ||
|
|
2b60e9ac37 | ||
|
|
693332ff50 | ||
|
|
a678f3bb25 | ||
|
|
b80ac45d99 | ||
|
|
20a8bc611b | ||
|
|
77a474b993 | ||
|
|
853074d80c | ||
|
|
5df989c7a0 | ||
|
|
f3b9f1c3fd | ||
|
|
061bae9546 | ||
|
|
679635afd9 | ||
|
|
7854c491f7 | ||
|
|
9695f9d00b | ||
|
|
b26df0f67e | ||
|
|
88fa92fd8d | ||
|
|
430501408b | ||
|
|
19d3f8884e | ||
|
|
3b4a66096a | ||
|
|
b93fe2a058 | ||
|
|
7332c6a7ea | ||
|
|
d91dae8f15 | ||
|
|
02979dc209 | ||
|
|
c1cbbfc207 | ||
|
|
2631b5c0b2 | ||
|
|
5795280b49 | ||
|
|
2b834c9ee4 | ||
|
|
444a748411 | ||
|
|
58238c048b | ||
|
|
c5befc354b | ||
|
|
33854f8886 | ||
|
|
8121ee29f4 | ||
|
|
15b784f6c6 | ||
|
|
2df162408e | ||
|
|
10d06298ce | ||
|
|
eebe4dd0dd | ||
|
|
0459df64c1 | ||
|
|
b635f0c2fd | ||
|
|
770e40596e | ||
|
|
2e990ba3ce | ||
|
|
ea5d7c6c4c | ||
|
|
779514a6fc | ||
|
|
f027b7a312 | ||
|
|
da31501087 | ||
|
|
140aa96aff | ||
|
|
671f0a66f5 | ||
|
|
5b1e782b9b | ||
|
|
b222dfeceb | ||
|
|
5db5678c1d | ||
|
|
433cbc1837 | ||
|
|
bf99c32e72 | ||
|
|
c2ec44c0b7 | ||
|
|
550fa1046e | ||
|
|
cf910d2616 | ||
|
|
2d32510008 | ||
|
|
4d8fd55206 | ||
|
|
c852af2a2c | ||
|
|
ae22e1e8ea | ||
|
|
02620313f6 | ||
|
|
bbccdc2de0 | ||
|
|
bc54e18e48 | ||
|
|
8e4859688d | ||
|
|
967bb51313 | ||
|
|
51d46849fb | ||
|
|
74bb119a05 | ||
|
|
ae038bc8e9 | ||
|
|
433788cc49 | ||
|
|
5e6d627f51 | ||
|
|
f9897ef99a | ||
|
|
5c1a2c4d13 | ||
|
|
f987bc3199 | ||
|
|
0c1a73accc | ||
|
|
1fb75b66dd | ||
|
|
790e1485f6 | ||
|
|
400faabb21 | ||
|
|
684b74ca9e | ||
|
|
6069a3c0cb | ||
|
|
606f5f6c86 | ||
|
|
bfccc1a95d | ||
|
|
e33a56001a | ||
|
|
0afc4c752f | ||
|
|
834fc6a8f7 | ||
|
|
da824ccfa8 | ||
|
|
2c397c5110 | ||
|
|
4a4f04825c | ||
|
|
2ac41813fa | ||
|
|
422414737b | ||
|
|
d45d9a31be | ||
|
|
5f297a62ba | ||
|
|
7605c14d89 | ||
|
|
bad23f7574 | ||
|
|
ee4886512b | ||
|
|
8a87befeda | ||
|
|
44b37c57c1 | ||
|
|
0b59ccfb42 | ||
|
|
3c8f05982e | ||
|
|
a7a6b241e0 | ||
|
|
d6de563178 | ||
|
|
ee62b14384 | ||
|
|
712df22b95 | ||
|
|
a0d063e78f | ||
|
|
5a2712750b | ||
|
|
320f755e5e | ||
|
|
f1d4a7c045 | ||
|
|
710f97bb62 | ||
|
|
454344185c | ||
|
|
b25250db7b | ||
|
|
009156994e | ||
|
|
6f21dd884c | ||
|
|
5dfa33320e | ||
|
|
2147291c52 | ||
|
|
e971c619b1 | ||
|
|
6e832b337f | ||
|
|
6ec5a955df | ||
|
|
71cd411ffc | ||
|
|
1be9097852 | ||
|
|
a8a848a259 | ||
|
|
15d008a169 | ||
|
|
2e09228568 | ||
|
|
bfaef77719 | ||
|
|
02d0e16a72 | ||
|
|
6ebf3573af | ||
|
|
5aef451e81 | ||
|
|
1880961afa | ||
|
|
fb5a723193 | ||
|
|
88002a4abf | ||
|
|
289dbc675a | ||
|
|
bcfaa7e8a7 | ||
|
|
bf62ead713 | ||
|
|
8a7cda7495 | ||
|
|
84cf974d70 | ||
|
|
afc54314b5 | ||
|
|
bd8db75106 | ||
|
|
9da692b12f | ||
|
|
4ee39b0dc8 | ||
|
|
286514b509 | ||
|
|
c7140baa33 | ||
|
|
2a9889b194 | ||
|
|
2afbd64c8e | ||
|
|
8be6aba43a | ||
|
|
565f1dad74 | ||
|
|
67a81f219d | ||
|
|
ccd103a29f | ||
|
|
c5d088b69d | ||
|
|
6362054368 | ||
|
|
2dab17f5dc | ||
|
|
c545305825 | ||
|
|
578c81784b | ||
|
|
1cd9b63c3e | ||
|
|
7b1817a0b8 | ||
|
|
fb0e4f3ad9 | ||
|
|
09a5b414b6 | ||
|
|
e5dc869c9b | ||
|
|
2687ff57aa | ||
|
|
52138b4cbd | ||
|
|
b3a2cccfed | ||
|
|
15a8abf2c9 | ||
|
|
d16b474aa8 | ||
|
|
760758230a | ||
|
|
358fc7b007 | ||
|
|
069eeccb60 | ||
|
|
da77b63bea | ||
|
|
791d8820d6 | ||
|
|
05fbe381dd | ||
|
|
3b2466ba10 | ||
|
|
acc7fa6754 | ||
|
|
394a5c8eb0 | ||
|
|
ac6d89b611 | ||
|
|
46cdd6fbe1 |
+55
-19
@@ -14,9 +14,9 @@
|
||||
# run only if manually started to save CI minutes if #
|
||||
# GitLab hosted runners #
|
||||
# * For commits to the CalcProgrammer1/OpenRGB repository, #
|
||||
# automatically run all jobs on the default branch, #
|
||||
# otherwise run them if the source is part of a merge #
|
||||
# request #
|
||||
# automatically run all jobs on the default branch or #
|
||||
# tag builds, otherwise run them if the source is part #
|
||||
# of a merge request #
|
||||
#-----------------------------------------------------------#
|
||||
.downstream_rules:
|
||||
rules:
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
.upstream_rules:
|
||||
rules:
|
||||
- if: '$CI_PROJECT_PATH == "CalcProgrammer1/OpenRGB" && ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_PIPELINE_SOURCE == "merge_request_event")'
|
||||
- if: '$CI_PROJECT_PATH == "CalcProgrammer1/OpenRGB" && ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_TAG || $CI_PIPELINE_SOURCE == "merge_request_event")'
|
||||
when: on_success
|
||||
- !reference [.downstream_rules, rules]
|
||||
|
||||
@@ -51,7 +51,7 @@ before_script:
|
||||
# Supported Devices Build Target #
|
||||
#-----------------------------------------------------------#
|
||||
"Supported Devices":
|
||||
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:bookworm-amd64
|
||||
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:trixie-amd64
|
||||
tags:
|
||||
- linux
|
||||
- amd64
|
||||
@@ -71,10 +71,10 @@ before_script:
|
||||
- !reference [.upstream_rules, rules]
|
||||
|
||||
#-----------------------------------------------------------#
|
||||
# OpenRGB Common Appimage Build Steps #
|
||||
# OpenRGB Common AppImage Build Steps #
|
||||
#-----------------------------------------------------------#
|
||||
.hidden_appimage_script: &appimage_script_steps
|
||||
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:bookworm-${TGT_ARCH}
|
||||
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:trixie-${TGT_ARCH}
|
||||
tags:
|
||||
- linux
|
||||
- ${TGT_ARCH}
|
||||
@@ -87,8 +87,6 @@ before_script:
|
||||
name: "${CI_PROJECT_NAME}_Linux_${TGT_NAME}_${CI_COMMIT_SHORT_SHA}"
|
||||
paths:
|
||||
- OpenRGB-${TGT_PATH}.AppImage
|
||||
- 60-openrgb.rules
|
||||
- README.md
|
||||
expire_in: 30 days
|
||||
|
||||
rules:
|
||||
@@ -290,13 +288,13 @@ before_script:
|
||||
<<: *debian_script_steps
|
||||
|
||||
#-----------------------------------------------------------#
|
||||
# Linux (.rpm, F43) 64-bit Build Target #
|
||||
# Linux (.rpm) Fedora 44 amd64 Build Target #
|
||||
#-----------------------------------------------------------#
|
||||
"Linux 64 F43 rpm":
|
||||
image: fedora:43
|
||||
"Linux amd64 .rpm (Fedora 44)":
|
||||
image: fedora:44
|
||||
stage: build
|
||||
script:
|
||||
- dnf install rpmdevtools dnf-plugins-core libcurl-devel qt5-qtbase-devel git wget -y
|
||||
- dnf install rpmdevtools dnf-plugins-core libcurl-devel qt6-qtbase-devel git wget -y
|
||||
- 'wget -O hidapi-hotplug.zip https://gitlab.com/OpenRGBDevelopers/hidapi-hotplug/-/jobs/artifacts/master/download?job=Linux+64+F43+rpm'
|
||||
- unzip hidapi-hotplug.zip
|
||||
- dnf install ./*.rpm -y
|
||||
@@ -312,7 +310,7 @@ before_script:
|
||||
- cd ${CI_PROJECT_DIR}
|
||||
|
||||
artifacts:
|
||||
name: "${CI_PROJECT_NAME}_Linux_64_rpm_${CI_COMMIT_SHORT_SHA}"
|
||||
name: "${CI_PROJECT_NAME}_Linux_amd64_rpm_${CI_COMMIT_SHORT_SHA}"
|
||||
paths:
|
||||
- openrgb*.rpm
|
||||
expire_in: 30 days
|
||||
@@ -320,6 +318,44 @@ before_script:
|
||||
rules:
|
||||
- !reference [.upstream_rules, rules]
|
||||
|
||||
#-----------------------------------------------------------#
|
||||
# OpenRGB Common Flatpak Build Steps #
|
||||
#-----------------------------------------------------------#
|
||||
.hidden_flatpak_script: &flatpak_script_steps
|
||||
image: ghcr.io/flathub-infra/flatpak-github-actions:kde-6.10
|
||||
stage: build
|
||||
tags:
|
||||
- linux
|
||||
- ${TGT_ARCH}
|
||||
script:
|
||||
- flatpak-builder --user --disable-rofiles-fuse --repo=build/repo build/flatpak-build flatpak/org.openrgb.OpenRGB.yaml
|
||||
- flatpak build-bundle build/repo org.openrgb.OpenRGB.flatpak org.openrgb.OpenRGB
|
||||
|
||||
artifacts:
|
||||
name: "${CI_PROJECT_NAME}_Linux_${TGT_ARCH}_Flatpak_${CI_COMMIT_SHORT_SHA}"
|
||||
paths:
|
||||
- org.openrgb.OpenRGB.flatpak
|
||||
expire_in: 30 days
|
||||
|
||||
rules:
|
||||
- !reference [.upstream_rules, rules]
|
||||
|
||||
#-----------------------------------------------------------#
|
||||
# Linux Flatpak amd64 Build Target #
|
||||
#-----------------------------------------------------------#
|
||||
"Linux amd64 Flatpak":
|
||||
variables:
|
||||
TGT_ARCH: "amd64"
|
||||
<<: *flatpak_script_steps
|
||||
|
||||
#-----------------------------------------------------------#
|
||||
# Linux Flatpak arm64 Build Target #
|
||||
#-----------------------------------------------------------#
|
||||
"Linux arm64 Flatpak":
|
||||
variables:
|
||||
TGT_ARCH: "arm64"
|
||||
<<: *flatpak_script_steps
|
||||
|
||||
#-----------------------------------------------------------#
|
||||
# Debian i386 Bookworm test #
|
||||
#-----------------------------------------------------------#
|
||||
@@ -387,10 +423,10 @@ before_script:
|
||||
- !reference [.upstream_rules, rules]
|
||||
|
||||
#-----------------------------------------------------------#
|
||||
# Fedora 64 v43 test #
|
||||
# Fedora amd64 44 test #
|
||||
#-----------------------------------------------------------#
|
||||
"Fedora 64 v43":
|
||||
image: fedora:43
|
||||
"Fedora 64 44":
|
||||
image: fedora:44
|
||||
stage: test
|
||||
script:
|
||||
- dnf install unzip wget -y
|
||||
@@ -401,9 +437,9 @@ before_script:
|
||||
- openrgb --version
|
||||
- dnf5 -y remove openrgb
|
||||
dependencies:
|
||||
- "Linux 64 F43 rpm"
|
||||
- "Linux amd64 .rpm (Fedora 44)"
|
||||
needs:
|
||||
- "Linux 64 F43 rpm"
|
||||
- "Linux amd64 .rpm (Fedora 44)"
|
||||
rules:
|
||||
- !reference [.upstream_rules, rules]
|
||||
|
||||
|
||||
@@ -119,6 +119,21 @@ bool AutoStart::IsAutoStartEnabled()
|
||||
|
||||
std::string AutoStart::GetExePath()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| When running from an AppImage, the AppImage runtime |
|
||||
| sets the APPIMAGE environment variable to the path of |
|
||||
| the AppImage file itself. /proc/self/exe would |
|
||||
| instead point at the extracted binary inside the |
|
||||
| temporary squashfs mount, which disappears once the |
|
||||
| AppImage is closed, so prefer APPIMAGE when it is set |
|
||||
\*-----------------------------------------------------*/
|
||||
const char* appimage_path = getenv("APPIMAGE");
|
||||
|
||||
if(appimage_path != NULL)
|
||||
{
|
||||
return(std::string(appimage_path));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Create the OpenRGB executable path |
|
||||
\*-----------------------------------------------------*/
|
||||
@@ -134,6 +149,64 @@ std::string AutoStart::GetExePath()
|
||||
| Private Methods |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Escape a single argument for use in a .desktop Exec= |
|
||||
| field, per the Desktop Entry Specification. |
|
||||
| |
|
||||
| Reserved characters must be escaped by wrapping the whole |
|
||||
| argument in double quotes and backslash-escaping the |
|
||||
| quote/backquote/backslash/dollar characters, and any |
|
||||
| literal '%' must be doubled to '%%'. |
|
||||
\*---------------------------------------------------------*/
|
||||
static std::string DesktopExecEscape(const std::string& arg)
|
||||
{
|
||||
static const std::string reserved = " \t\n\"'`\\><~|&;$*?#()%";
|
||||
|
||||
bool needs_quotes = false;
|
||||
for(char c : arg)
|
||||
{
|
||||
if(reserved.find(c) != std::string::npos)
|
||||
{
|
||||
needs_quotes = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string escaped;
|
||||
|
||||
if(needs_quotes)
|
||||
{
|
||||
escaped += '"';
|
||||
}
|
||||
|
||||
for(char c : arg)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case '"':
|
||||
case '`':
|
||||
case '\\':
|
||||
case '$':
|
||||
escaped += '\\';
|
||||
escaped += c;
|
||||
break;
|
||||
case '%':
|
||||
escaped += "%%";
|
||||
break;
|
||||
default:
|
||||
escaped += c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(needs_quotes)
|
||||
{
|
||||
escaped += '"';
|
||||
}
|
||||
|
||||
return(escaped);
|
||||
}
|
||||
|
||||
std::string AutoStart::GenerateDesktopFile(AutoStartInfo autostart_info)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
@@ -154,11 +227,17 @@ std::string AutoStart::GenerateDesktopFile(AutoStartInfo autostart_info)
|
||||
/*-----------------------------------------------------*\
|
||||
| Add the executable path and arguments |
|
||||
\*-----------------------------------------------------*/
|
||||
fileContents << "Exec=" << autostart_info.path;
|
||||
fileContents << "Exec=" << DesktopExecEscape(autostart_info.path);
|
||||
|
||||
if (autostart_info.args != "")
|
||||
{
|
||||
fileContents << " " << autostart_info.args;
|
||||
std::istringstream arg_parser(autostart_info.args);
|
||||
std::string arg;
|
||||
|
||||
while(arg_parser >> arg)
|
||||
{
|
||||
fileContents << " " << DesktopExecEscape(arg);
|
||||
}
|
||||
}
|
||||
|
||||
fileContents << std::endl;
|
||||
|
||||
@@ -137,6 +137,43 @@ std::string AutoStart::GetExePath()
|
||||
| Private Methods |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Escape a string for embedding inside an XML element |
|
||||
| (used by the .plist generator) to avoid producing |
|
||||
| malformed property list files. |
|
||||
\*---------------------------------------------------------*/
|
||||
static std::string XmlEscape(const std::string& input)
|
||||
{
|
||||
std::string escaped;
|
||||
|
||||
for(char c : input)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case '&':
|
||||
escaped += "&";
|
||||
break;
|
||||
case '<':
|
||||
escaped += "<";
|
||||
break;
|
||||
case '>':
|
||||
escaped += ">";
|
||||
break;
|
||||
case '"':
|
||||
escaped += """;
|
||||
break;
|
||||
case '\'':
|
||||
escaped += "'";
|
||||
break;
|
||||
default:
|
||||
escaped += c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(escaped);
|
||||
}
|
||||
|
||||
std::string AutoStart::GenerateLaunchAgentFile(AutoStartInfo autostart_info)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
@@ -153,7 +190,8 @@ std::string AutoStart::GenerateLaunchAgentFile(AutoStartInfo autostart_info)
|
||||
fileContents << " <string>org.openrgb</string>" << std::endl;
|
||||
fileContents << " <key>ProgramArguments</key>" << std::endl;
|
||||
fileContents << " <array>" << std::endl;
|
||||
fileContents << " <string>" << autostart_info.path << "</string>" << std::endl;
|
||||
fileContents << " <string>" << XmlEscape(autostart_info.path) << "</string>"
|
||||
<< std::endl;
|
||||
|
||||
if(autostart_info.args != "")
|
||||
{
|
||||
@@ -162,7 +200,8 @@ std::string AutoStart::GenerateLaunchAgentFile(AutoStartInfo autostart_info)
|
||||
|
||||
while(arg_parser >> arg)
|
||||
{
|
||||
fileContents << " <string>" << arg << "</string>" << std::endl;
|
||||
fileContents << " <string>" << XmlEscape(arg) << "</string>"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <shlobj.h>
|
||||
#include "AutoStart-Windows.h"
|
||||
#include "LogManager.h"
|
||||
#include "StringUtils.h"
|
||||
#include "filesystem.h"
|
||||
#include "windows.h"
|
||||
|
||||
@@ -71,11 +72,11 @@ bool AutoStart::EnableAutoStart(AutoStartInfo autostart_info)
|
||||
HRESULT result;
|
||||
IShellLinkW* shellLink = NULL;
|
||||
|
||||
std::wstring exepathw = utf8_decode(autostart_info.path);
|
||||
std::wstring argumentsw = utf8_decode(autostart_info.args);
|
||||
std::wstring startupfilepathw = utf8_decode(autostart_file);
|
||||
std::wstring descriptionw = utf8_decode(autostart_info.desc);
|
||||
std::wstring iconw = utf8_decode(autostart_info.path);
|
||||
std::wstring exepathw = StringUtils::string_to_wstring(autostart_info.path);
|
||||
std::wstring argumentsw = StringUtils::string_to_wstring(autostart_info.args);
|
||||
std::wstring startupfilepathw = StringUtils::string_to_wstring(autostart_file);
|
||||
std::wstring descriptionw = StringUtils::string_to_wstring(autostart_info.desc);
|
||||
std::wstring iconw = StringUtils::string_to_wstring(autostart_info.path);
|
||||
|
||||
result = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL, IID_IShellLinkW, (void**)&shellLink);
|
||||
|
||||
@@ -150,11 +151,16 @@ std::string AutoStart::GetExePath()
|
||||
/*-----------------------------------------------------*\
|
||||
| Create the OpenRGB executable path |
|
||||
\*-----------------------------------------------------*/
|
||||
char exepath[MAX_PATH] = "";
|
||||
wchar_t exepath[MAX_PATH] = L"";
|
||||
|
||||
DWORD count = GetModuleFileNameA(NULL, exepath, MAX_PATH);
|
||||
DWORD count = GetModuleFileNameW(NULL, exepath, MAX_PATH);
|
||||
|
||||
return(std::string(exepath, (count > 0) ? count : 0));
|
||||
if(count == 0)
|
||||
{
|
||||
return(std::string());
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(std::wstring(exepath, count)));
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
@@ -164,43 +170,39 @@ std::string AutoStart::GetExePath()
|
||||
|
||||
void AutoStart::InitAutoStart(std::string name)
|
||||
{
|
||||
char startMenuPath[MAX_PATH];
|
||||
wchar_t startMenuPath[MAX_PATH];
|
||||
|
||||
autostart_name = name;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get startup applications path |
|
||||
\*-----------------------------------------------------*/
|
||||
HRESULT result = SHGetFolderPathA(NULL, CSIDL_PROGRAMS, NULL, 0, startMenuPath);
|
||||
HRESULT result = SHGetFolderPathW(NULL, CSIDL_PROGRAMS, NULL, 0, startMenuPath);
|
||||
|
||||
if(SUCCEEDED(result))
|
||||
{
|
||||
autostart_file = std::string(startMenuPath);
|
||||
std::string autostart_dir = StringUtils::wstring_to_string(startMenuPath);
|
||||
autostart_dir += "\\Startup\\";
|
||||
|
||||
autostart_file += "\\Startup\\" + autostart_name + ".lnk";
|
||||
/*-------------------------------------------------*\
|
||||
| Create the directory if it doesn't exist |
|
||||
\*-------------------------------------------------*/
|
||||
std::error_code ec;
|
||||
|
||||
bool success = true;
|
||||
|
||||
if(!filesystem::exists(autostart_dir))
|
||||
{
|
||||
success = filesystem::create_directories(autostart_dir, ec);
|
||||
}
|
||||
|
||||
if(success)
|
||||
{
|
||||
autostart_file = autostart_dir + autostart_name + ".lnk";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
autostart_file.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Convert an UTF8 string to a wide Unicode String |
|
||||
| (from wmi.cpp) |
|
||||
\*---------------------------------------------------------*/
|
||||
std::wstring AutoStart::utf8_decode(const std::string& str)
|
||||
{
|
||||
if(str.empty())
|
||||
{
|
||||
return std::wstring();
|
||||
}
|
||||
|
||||
int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int) str.size(), nullptr, 0);
|
||||
|
||||
std::wstring wstrTo(size_needed, 0);
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int) str.size(), &wstrTo[0], size_needed);
|
||||
|
||||
return(wstrTo);
|
||||
}
|
||||
|
||||
@@ -24,5 +24,4 @@ public:
|
||||
|
||||
private:
|
||||
void InitAutoStart(std::string name);
|
||||
std::wstring utf8_decode(const std::string& str);
|
||||
};
|
||||
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ASRockGPUSMBusController.cpp |
|
||||
| |
|
||||
| Driver for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| Based on SignalRGB ASRock GPU.js plugin |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "ASRockGPUSMBusController.h"
|
||||
#include "LogManager.h"
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
ASRockGPUSMBusController::ASRockGPUSMBusController(i2c_smbus_interface* bus, asrock_gpu_dev_id dev, std::string name)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
this->device_name = name;
|
||||
this->num_channels = 0;
|
||||
|
||||
memset(enabled_channels, 0, sizeof(enabled_channels));
|
||||
memset(led_counts, 0, sizeof(led_counts));
|
||||
}
|
||||
|
||||
ASRockGPUSMBusController::~ASRockGPUSMBusController()
|
||||
{
|
||||
}
|
||||
|
||||
std::string ASRockGPUSMBusController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->info.device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return("I2C: " + return_string);
|
||||
}
|
||||
|
||||
std::string ASRockGPUSMBusController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
bool ASRockGPUSMBusController::WriteBlock(uint8_t command, uint8_t subcommand, const uint8_t* data, uint8_t len)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| SignalRGB packet format |
|
||||
| [command, 0, subcommand, data...] |
|
||||
| Uses pure I2C rather than SMBus |
|
||||
\*-----------------------------------------------------*/
|
||||
uint8_t packet[12];
|
||||
memset(packet, 0, sizeof(packet));
|
||||
|
||||
packet[0] = command;
|
||||
packet[1] = 0x00;
|
||||
packet[2] = subcommand;
|
||||
|
||||
if(data != nullptr && len > 0)
|
||||
{
|
||||
uint8_t copy_len = (len > 9) ? 9 : len;
|
||||
memcpy(&packet[3], data, copy_len);
|
||||
}
|
||||
|
||||
int size = 12;
|
||||
int result = bus->i2c_write_block(dev, size, packet);
|
||||
|
||||
if(result < 0)
|
||||
{
|
||||
LOG_DEBUG("[ASRock GPU] Write block failed: %d", result);
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool ASRockGPUSMBusController::ReadBlock(uint8_t* response, uint8_t len)
|
||||
{
|
||||
memset(response, 0, len);
|
||||
int size = len;
|
||||
int result = bus->i2c_read_block(dev, &size, response);
|
||||
|
||||
if(result < 0)
|
||||
{
|
||||
LOG_DEBUG("[ASRock GPU] Read block failed: %d", result);
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool ASRockGPUSMBusController::DetectChannels()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Get enabled channels |
|
||||
| Command 0x14, subcommand 0x01 |
|
||||
\*-----------------------------------------------------*/
|
||||
if(!WriteBlock(0x14, 0x01, nullptr, 0))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to request enabled channels");
|
||||
return(false);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(20ms);
|
||||
|
||||
uint8_t response[I2C_SMBUS_BLOCK_MAX];
|
||||
if(!ReadBlock(response, sizeof(response)))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to read enabled channels");
|
||||
return(false);
|
||||
}
|
||||
|
||||
LOG_TRACE("[ASRock GPU] Enabled channels response: %02X %02X %02X %02X %02X %02X", response[0], response[1], response[2], response[3], response[4], response[5]);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Response format |
|
||||
| Bytes 4-5 contain the channel bitmap |
|
||||
\*-----------------------------------------------------*/
|
||||
uint16_t channel_bits = response[4] | (response[5] << 8);
|
||||
LOG_TRACE("[ASRock GPU] Channel bits: 0x%04X", channel_bits);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get LED counts |
|
||||
| Command 0x14, subcommand 0x02 |
|
||||
\*-----------------------------------------------------*/
|
||||
if(!WriteBlock(0x14, 0x02, nullptr, 0))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to request LED counts");
|
||||
return(false);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(20ms);
|
||||
|
||||
if(!ReadBlock(response, sizeof(response)))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to read LED counts");
|
||||
return(false);
|
||||
}
|
||||
|
||||
num_channels = 0;
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
if(channel_bits & (1 << i))
|
||||
{
|
||||
enabled_channels[num_channels] = i;
|
||||
led_counts[num_channels] = response[4 + i];
|
||||
|
||||
const char* name = "Unknown";
|
||||
if(i == ASROCK_GPU_CHANNEL_ARGB_HEADER)
|
||||
{
|
||||
name = "ARGB Header";
|
||||
}
|
||||
else if(i == ASROCK_GPU_CHANNEL_TOP_SIDE)
|
||||
{
|
||||
name = "Top Side";
|
||||
}
|
||||
else if(i == ASROCK_GPU_CHANNEL_FAN)
|
||||
{
|
||||
name = "Fan";
|
||||
}
|
||||
|
||||
LOG_DEBUG("[ASRock GPU] Channel %d (%s) active with %d LEDs", i, name, response[4 + i]);
|
||||
num_channels++;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("[ASRock GPU] Found %d active channels", num_channels);
|
||||
return(num_channels > 0);
|
||||
}
|
||||
|
||||
void ASRockGPUSMBusController::SetChannelColor(uint8_t channel_idx, uint8_t red, uint8_t green, uint8_t blue)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| SignalRGB color packet |
|
||||
| Command 0x10, subcommand is the channel index |
|
||||
\*-----------------------------------------------------*/
|
||||
uint8_t data[8] =
|
||||
{
|
||||
0x01, // Mode: direct/static
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
0x80, // Brightness
|
||||
0xFF, // Effect speed
|
||||
0x00, // Effect direction
|
||||
0x1A // Unknown constant
|
||||
};
|
||||
|
||||
if(!WriteBlock(0x10, channel_idx, data, sizeof(data)))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to set color for channel %d", channel_idx);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ASRockGPUSMBusController.h |
|
||||
| |
|
||||
| Driver for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| Based on SignalRGB ASRock GPU.js plugin |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
typedef uint8_t asrock_gpu_dev_id;
|
||||
|
||||
#define ASROCK_GPU_CONTROLLER_NAME "ASRock GPU SMBus Controller"
|
||||
#define ASROCK_GPU_SMBUS_ADDRESS 0x36
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| ASRock GPU Channel Names (from SignalRGB) |
|
||||
\*-----------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
ASROCK_GPU_CHANNEL_ARGB_HEADER = 3,
|
||||
ASROCK_GPU_CHANNEL_TOP_SIDE = 6,
|
||||
ASROCK_GPU_CHANNEL_FAN = 7,
|
||||
};
|
||||
|
||||
class ASRockGPUSMBusController
|
||||
{
|
||||
public:
|
||||
ASRockGPUSMBusController(i2c_smbus_interface* bus, asrock_gpu_dev_id dev, std::string name);
|
||||
~ASRockGPUSMBusController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
|
||||
void SetChannelColor(uint8_t channel_idx, uint8_t red, uint8_t green, uint8_t blue);
|
||||
bool DetectChannels();
|
||||
|
||||
uint8_t enabled_channels[16];
|
||||
uint8_t led_counts[16];
|
||||
uint8_t num_channels;
|
||||
|
||||
private:
|
||||
i2c_smbus_interface* bus;
|
||||
asrock_gpu_dev_id dev;
|
||||
std::string device_name;
|
||||
|
||||
bool WriteBlock(uint8_t command, uint8_t subcommand, const uint8_t* data, uint8_t len);
|
||||
bool ReadBlock(uint8_t* response, uint8_t len);
|
||||
};
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ASRockGPUSMBusControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "DetectionManager.h"
|
||||
#include "ASRockGPUSMBusController.h"
|
||||
#include "LogManager.h"
|
||||
#include "RGBController_ASRockGPUSMBus.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include "pci_ids.h"
|
||||
|
||||
DetectedControllers DetectASRockGPUSMBusControllers(i2c_smbus_interface* bus, uint8_t address, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
|
||||
LOG_DEBUG("[ASRock GPU] Checking GPU I2C bus for RGB controller at 0x%02X", address);
|
||||
|
||||
if(bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE) < 0)
|
||||
{
|
||||
LOG_DEBUG("[ASRock GPU] No response at address 0x%02X", address);
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
LOG_DEBUG("[ASRock GPU] Device responded at 0x%02X, creating controller", address);
|
||||
|
||||
ASRockGPUSMBusController* controller = new ASRockGPUSMBusController(bus, address, name);
|
||||
|
||||
if(controller->DetectChannels())
|
||||
{
|
||||
detected_controllers.push_back(new RGBController_ASRockGPUSMBus(controller));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] No active channels found, device not registered");
|
||||
delete controller;
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_I2C_PCI_DETECTOR("ASRock Radeon RX 9070 XT Steel Legend", DetectASRockGPUSMBusControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, ASROCK_SUB_VEN, 0x5403, ASROCK_GPU_SMBUS_ADDRESS);
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_ASRockGPUSMBus.cpp |
|
||||
| |
|
||||
| RGBController for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| Based on SignalRGB ASRock GPU.js plugin |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_ASRockGPUSMBus.h"
|
||||
|
||||
RGBController_ASRockGPUSMBus::RGBController_ASRockGPUSMBus(ASRockGPUSMBusController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "ASRock";
|
||||
type = DEVICE_TYPE_GPU;
|
||||
description = "ASRock GPU RGB Controller";
|
||||
location = controller->GetDeviceLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_ASRockGPUSMBus::~RGBController_ASRockGPUSMBus()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::SetupZones()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up zones - one zone per channel |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < controller->num_channels; i++)
|
||||
{
|
||||
uint8_t channel_idx = controller->enabled_channels[i];
|
||||
|
||||
zone new_zone;
|
||||
new_zone.type = ZONE_TYPE_SINGLE;
|
||||
new_zone.leds_min = 1;
|
||||
new_zone.leds_max = 1;
|
||||
new_zone.leds_count = 1;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Channel names from SignalRGB |
|
||||
\*-----------------------------------------------------*/
|
||||
if(channel_idx == ASROCK_GPU_CHANNEL_ARGB_HEADER)
|
||||
{
|
||||
new_zone.name = "ARGB Header";
|
||||
}
|
||||
else if(channel_idx == ASROCK_GPU_CHANNEL_TOP_SIDE)
|
||||
{
|
||||
new_zone.name = "Top Side";
|
||||
}
|
||||
else if(channel_idx == ASROCK_GPU_CHANNEL_FAN)
|
||||
{
|
||||
new_zone.name = "Fan";
|
||||
}
|
||||
else
|
||||
{
|
||||
new_zone.name = "Channel " + std::to_string(channel_idx);
|
||||
}
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up LED for this zone |
|
||||
\*-----------------------------------------------------*/
|
||||
led new_led;
|
||||
new_led.name = new_zone.name;
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*-----------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::DeviceUpdateLEDs()
|
||||
{
|
||||
for(unsigned int i = 0; i < controller->num_channels; i++)
|
||||
{
|
||||
uint8_t channel_idx = controller->enabled_channels[i];
|
||||
RGBColor color = colors[i];
|
||||
|
||||
controller->SetChannelColor(channel_idx,
|
||||
RGBGetRValue(color),
|
||||
RGBGetGValue(color),
|
||||
RGBGetBValue(color));
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
uint8_t channel_idx = controller->enabled_channels[zone];
|
||||
RGBColor color = colors[zone];
|
||||
|
||||
controller->SetChannelColor(channel_idx,
|
||||
RGBGetRValue(color),
|
||||
RGBGetGValue(color),
|
||||
RGBGetBValue(color));
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::UpdateSingleLED(int led)
|
||||
{
|
||||
UpdateZoneLEDs(led);
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_ASRockGPUSMBus.h |
|
||||
| |
|
||||
| RGBController for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| Based on SignalRGB ASRock GPU.js plugin |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "ASRockGPUSMBusController.h"
|
||||
|
||||
class RGBController_ASRockGPUSMBus : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_ASRockGPUSMBus(ASRockGPUSMBusController* controller_ptr);
|
||||
~RGBController_ASRockGPUSMBus();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
ASRockGPUSMBusController* controller;
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| Detector for Acer Nitro HID Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <vector>
|
||||
#include "DetectionManager.h"
|
||||
#include "AcerNitroHidKeyboardController.h"
|
||||
#include "RGBController_AcerNitroHidKeyboard.h"
|
||||
#include "RGBController_AcerNitroHidLed.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HID vendor and product IDs for ENEK EC in Acer Nitro |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#define ACER_ENEC_VID 0x0CF2
|
||||
#define ACER_ENEC_PID 0x5130
|
||||
#define ACER_ENEC_USAGE_PAGE 0xFF5A
|
||||
#define ACER_ENEC_USAGE 0x01
|
||||
|
||||
DetectedControllers DetectAcerHIDControllers(hid_device_info* info, const std::string&)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
if(dev)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Controller is shared between keyboard and onboard |
|
||||
| led |
|
||||
\*-------------------------------------------------*/
|
||||
std::shared_ptr<AcerNitroHidKeyboardController> controller = std::make_shared<AcerNitroHidKeyboardController>(dev, info->path);
|
||||
RGBController_AcerNitroHidKeyboard* rgb_kb_controller = new RGBController_AcerNitroHidKeyboard(controller);
|
||||
RGBController_AcerNitroHidLed* rgb_led_controller = new RGBController_AcerNitroHidLed(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_kb_controller);
|
||||
detected_controllers.push_back(rgb_led_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_PU("AcerNitroHidKeyboardController", DetectAcerHIDControllers, ACER_ENEC_VID, ACER_ENEC_PID, ACER_ENEC_USAGE_PAGE, ACER_ENEC_USAGE);
|
||||
@@ -0,0 +1,80 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| Driver for Acer Nitro Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "AcerNitroHidKeyboardController.h"
|
||||
|
||||
AcerNitroHidKeyboardController::AcerNitroHidKeyboardController(hid_device *dev_handle, const char *path)
|
||||
{
|
||||
this->location = path;
|
||||
this->dev = dev_handle;
|
||||
|
||||
device_name = "Acer Nitro HID Keyboard";
|
||||
}
|
||||
|
||||
AcerNitroHidKeyboardController::~AcerNitroHidKeyboardController()
|
||||
{
|
||||
if(dev)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
}
|
||||
|
||||
std::string AcerNitroHidKeyboardController::GetLocation() const
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string AcerNitroHidKeyboardController::GetDeviceName() const
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
void AcerNitroHidKeyboardController::SetLEDs(const std::vector<RGBColor>& colors, unsigned char brightness, unsigned char device_id)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(device_mutex);
|
||||
|
||||
for(unsigned int led_idx = 0; (led_idx < colors.size()) && (led_idx < ACER_HID_NUM_ZONES); led_idx++)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Convert colors to RGB format |
|
||||
\*-------------------------------------------------*/
|
||||
unsigned char r = RGBGetRValue(colors[led_idx]);
|
||||
unsigned char g = RGBGetGValue(colors[led_idx]);
|
||||
unsigned char b = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-------------------------------------------------*/
|
||||
unsigned char zone_select = (unsigned char)(1<<led_idx);
|
||||
unsigned char packet[ACER_HID_PACKET_SIZE] = {0xA4, device_id, ACER_HID_MODE_STATIC, brightness, 0, 1, r, g, b, zone_select, 0};
|
||||
hid_send_feature_report(dev, packet, ACER_HID_PACKET_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void AcerNitroHidKeyboardController::SetAllLEDs(const RGBColor &color, unsigned char brightness, unsigned char speed, unsigned char direction, unsigned char mode, unsigned char device_id)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(device_mutex);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Convert color to RGB format |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char r = RGBGetRValue(color);
|
||||
unsigned char g = RGBGetGValue(color);
|
||||
unsigned char b = RGBGetBValue(color);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
| Zone select = All zones |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char zone_select = 0x0F;
|
||||
unsigned char packet[ACER_HID_PACKET_SIZE] = {0xA4, device_id, mode, brightness, speed, direction, r, g, b, zone_select, 0};
|
||||
hid_send_feature_report(dev, packet, ACER_HID_PACKET_SIZE);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| Driver for Acer Nitro Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
ACER_HID_MODE_DIRECT = 1,
|
||||
ACER_HID_MODE_STATIC = 2,
|
||||
ACER_HID_MODE_BREATHING = 4,
|
||||
ACER_HID_MODE_NEON = 5,
|
||||
ACER_HID_MODE_OPMODE = 6,
|
||||
ACER_HID_MODE_WAVE = 7,
|
||||
ACER_HID_MODE_SHIFTING = 8,
|
||||
ACER_HID_MODE_ZOOM = 9,
|
||||
ACER_HID_MODE_METEOR = 10,
|
||||
ACER_HID_MODE_TWINKLING = 11,
|
||||
};
|
||||
|
||||
#define ACER_HID_NAME_BUFFER_SIZE 255
|
||||
#define ACER_HID_NUM_ZONES 4
|
||||
#define ACER_HID_PACKET_SIZE 11
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "RGBControllerInterface.h"
|
||||
|
||||
class AcerNitroHidKeyboardController
|
||||
{
|
||||
public:
|
||||
AcerNitroHidKeyboardController(hid_device *dev_handle, const char *path);
|
||||
~AcerNitroHidKeyboardController();
|
||||
|
||||
std::string GetDeviceName() const;
|
||||
std::string GetSerial() const;
|
||||
std::string GetLocation() const;
|
||||
|
||||
void SetLEDs(const std::vector<RGBColor> &colors, unsigned char brightness, unsigned char device_id);
|
||||
void SetAllLEDs(const RGBColor &color, unsigned char brightness, unsigned char speed, unsigned char direction, unsigned char mode, unsigned char device_id);
|
||||
|
||||
private:
|
||||
hid_device *dev;
|
||||
std::string device_name;
|
||||
std::string location;
|
||||
std::mutex device_mutex;
|
||||
};
|
||||
@@ -0,0 +1,231 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| RGBController for Acer Nitro HID Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_AcerNitroHidKeyboard.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Acer Nitro HID Keyboard
|
||||
@category Laptop
|
||||
@type HID
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectAcerHIDControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_AcerNitroHidKeyboard::RGBController_AcerNitroHidKeyboard(std::shared_ptr<AcerNitroHidKeyboardController> controller)
|
||||
{
|
||||
this->controller = controller;
|
||||
device_id = 0x21;
|
||||
|
||||
name = "Acer Nitro HID Keyboard";
|
||||
vendor = "Acer";
|
||||
type = DEVICE_TYPE_LAPTOP;
|
||||
description = "Acer Nitro HID Keyboard Device";
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = ACER_HID_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS ;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
Direct.brightness_min = 0;
|
||||
Direct.brightness_max = 100;
|
||||
Direct.brightness = 100;
|
||||
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = ACER_HID_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.brightness_min = 0;
|
||||
Static.brightness_max = 100;
|
||||
Static.brightness = 100;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(1);
|
||||
Static.speed = 0;
|
||||
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = ACER_HID_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = 100;
|
||||
Breathing.brightness = 100;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.speed_min = 1;
|
||||
Breathing.speed_max = 9;
|
||||
Breathing.speed = 4;
|
||||
Breathing.colors.resize(1);
|
||||
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Neon;
|
||||
Neon.name = "Neon";
|
||||
Neon.value = ACER_HID_MODE_NEON;
|
||||
Neon.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Neon.color_mode = MODE_COLORS_NONE;
|
||||
Neon.brightness_min = 0;
|
||||
Neon.brightness_max = 100;
|
||||
Neon.brightness = 100;
|
||||
Neon.speed_min = 1;
|
||||
Neon.speed_max = 9;
|
||||
Neon.speed = 4;
|
||||
|
||||
modes.push_back(Neon);
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = ACER_HID_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR;
|
||||
Wave.color_mode = MODE_COLORS_NONE;
|
||||
Wave.brightness_min = 0;
|
||||
Wave.brightness_max = 100;
|
||||
Wave.brightness = 100;
|
||||
Wave.speed_min = 1;
|
||||
Wave.speed_max = 9;
|
||||
Wave.speed = 4;
|
||||
Wave.direction = 0;
|
||||
|
||||
modes.push_back(Wave);
|
||||
|
||||
mode Shifting;
|
||||
Shifting.name = "Shifting";
|
||||
Shifting.value = ACER_HID_MODE_SHIFTING;
|
||||
Shifting.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Shifting.color_mode = MODE_COLORS_NONE;
|
||||
Shifting.brightness_min = 0;
|
||||
Shifting.brightness_max = 100;
|
||||
Shifting.brightness = 100;
|
||||
Shifting.speed_min = 1;
|
||||
Shifting.speed_max = 9;
|
||||
Shifting.speed = 4;
|
||||
|
||||
modes.push_back(Shifting);
|
||||
|
||||
mode Zoom;
|
||||
Zoom.name = "Zoom";
|
||||
Zoom.value = ACER_HID_MODE_ZOOM;
|
||||
Zoom.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Zoom.color_mode = MODE_COLORS_NONE;
|
||||
Zoom.brightness_min = 0;
|
||||
Zoom.brightness_max = 100;
|
||||
Zoom.brightness = 100;
|
||||
Zoom.speed_min = 1;
|
||||
Zoom.speed_max = 9;
|
||||
Zoom.speed = 4;
|
||||
|
||||
modes.push_back(Zoom);
|
||||
|
||||
mode Meteor;
|
||||
Meteor.name = "Meteor";
|
||||
Meteor.value = ACER_HID_MODE_METEOR;
|
||||
Meteor.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Meteor.color_mode = MODE_COLORS_NONE;
|
||||
Meteor.brightness_min = 0;
|
||||
Meteor.brightness_max = 100;
|
||||
Meteor.brightness = 100;
|
||||
Meteor.speed_min = 1;
|
||||
Meteor.speed_max = 9;
|
||||
Meteor.speed = 4;
|
||||
|
||||
modes.push_back(Meteor);
|
||||
|
||||
mode Twinkling;
|
||||
Twinkling.name = "Twinkling";
|
||||
Twinkling.value = ACER_HID_MODE_TWINKLING;
|
||||
Twinkling.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Twinkling.color_mode = MODE_COLORS_NONE;
|
||||
Twinkling.brightness_min = 0;
|
||||
Twinkling.brightness_max = 100;
|
||||
Twinkling.brightness = 100;
|
||||
Twinkling.colors_min = 1;
|
||||
Twinkling.colors_max = 1;
|
||||
Twinkling.speed_min = 1;
|
||||
Twinkling.speed_max = 9;
|
||||
Twinkling.speed = 4;
|
||||
|
||||
modes.push_back(Twinkling);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_AcerNitroHidKeyboard::~RGBController_AcerNitroHidKeyboard()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::SetupZones()
|
||||
{
|
||||
zone* new_zone = new zone;
|
||||
|
||||
new_zone->name = "Keyboard Backlight Zone";
|
||||
new_zone->type = ZONE_TYPE_LINEAR;
|
||||
new_zone->leds_min = 4;
|
||||
new_zone->leds_max = 4;
|
||||
new_zone->leds_count = 4;
|
||||
|
||||
zones.push_back(*new_zone);
|
||||
|
||||
for(std::size_t zone_idx = 0; zone_idx < ACER_HID_NUM_ZONES; zone_idx++)
|
||||
{
|
||||
led* new_led = new led();
|
||||
new_led->name = "Keyboard Backlight Zone ";
|
||||
new_led->name.append(std::to_string(zone_idx + 1));
|
||||
new_led->value = (unsigned int)leds.size();
|
||||
|
||||
leds.push_back(*new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::DeviceUpdateLEDs()
|
||||
{
|
||||
mode& current_mode = modes[active_mode];
|
||||
if(current_mode.value == ACER_HID_MODE_DIRECT)
|
||||
{
|
||||
controller->SetLEDs(colors, current_mode.brightness, device_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
RGBColor color = current_mode.colors.size()==0? (RGBColor)0 : current_mode.colors[0];
|
||||
unsigned char direction = 1;
|
||||
if((modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR) && modes[active_mode].direction)
|
||||
{
|
||||
direction = 2;
|
||||
}
|
||||
controller->SetAllLEDs(color, current_mode.brightness, current_mode.speed, direction, current_mode.value, device_id);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::DeviceUpdateZoneLEDs(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::DeviceUpdateSingleLED(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| RGBController for Acer Nitro HID Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "AcerNitroHidKeyboardController.h"
|
||||
|
||||
class RGBController_AcerNitroHidKeyboard : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_AcerNitroHidKeyboard(std::shared_ptr<AcerNitroHidKeyboardController> controller);
|
||||
~RGBController_AcerNitroHidKeyboard();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
std::shared_ptr<AcerNitroHidKeyboardController> controller;
|
||||
unsigned int device_id;
|
||||
};
|
||||
@@ -0,0 +1,152 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidLed.cpp |
|
||||
| |
|
||||
| RGBController for Acer Nitro HID LED |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_AcerNitroHidLed.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Acer Nitro HID Led
|
||||
@category Laptop
|
||||
@type HID
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectAcerHIDControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_AcerNitroHidLed::RGBController_AcerNitroHidLed(std::shared_ptr<AcerNitroHidKeyboardController> controller)
|
||||
{
|
||||
this->controller = controller;
|
||||
device_id = 0x65;
|
||||
|
||||
name = "Acer Nitro HID LED Device";
|
||||
vendor = "Acer";
|
||||
type = DEVICE_TYPE_LIGHT;
|
||||
description = "Acer Nitro HID LED Device";
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = ACER_HID_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS ;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
Direct.brightness_min = 0;
|
||||
Direct.brightness_max = 100;
|
||||
Direct.brightness = 100;
|
||||
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = ACER_HID_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.brightness_min = 0;
|
||||
Static.brightness_max = 100;
|
||||
Static.brightness = 100;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(1);
|
||||
Static.speed = 0;
|
||||
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = ACER_HID_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = 100;
|
||||
Breathing.brightness = 100;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.speed_min = 1;
|
||||
Breathing.speed_max = 5;
|
||||
Breathing.speed = 4;
|
||||
Breathing.colors.resize(1);
|
||||
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Neon;
|
||||
Neon.name = "Neon";
|
||||
Neon.value = ACER_HID_MODE_NEON;
|
||||
Neon.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Neon.color_mode = MODE_COLORS_NONE;
|
||||
Neon.brightness_min = 0;
|
||||
Neon.brightness_max = 100;
|
||||
Neon.brightness = 100;
|
||||
Neon.speed_min = 1;
|
||||
Neon.speed_max = 5;
|
||||
Neon.speed = 4;
|
||||
|
||||
modes.push_back(Neon);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_AcerNitroHidLed::~RGBController_AcerNitroHidLed()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::SetupZones()
|
||||
{
|
||||
zone* new_zone = new zone;
|
||||
|
||||
new_zone->name = "LED";
|
||||
new_zone->type = ZONE_TYPE_LINEAR;
|
||||
new_zone->leds_min = 1;
|
||||
new_zone->leds_max = 1;
|
||||
new_zone->leds_count = 1;
|
||||
zones.push_back(*new_zone);
|
||||
|
||||
led* new_led = new led();
|
||||
new_led->name = "LED";
|
||||
new_led->value = (unsigned int)leds.size();
|
||||
leds.push_back(*new_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::DeviceUpdateLEDs()
|
||||
{
|
||||
mode& current_mode = modes[active_mode];
|
||||
if(current_mode.value == ACER_HID_MODE_DIRECT)
|
||||
{
|
||||
controller->SetLEDs(colors, current_mode.brightness, device_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
RGBColor color = current_mode.colors.size()==0? (RGBColor)0 : current_mode.colors[0];
|
||||
unsigned char direction = 1;
|
||||
if((modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR) && modes[active_mode].direction)
|
||||
{
|
||||
direction = 2;
|
||||
}
|
||||
controller->SetAllLEDs(color, current_mode.brightness, current_mode.speed, direction, current_mode.value, device_id);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::DeviceUpdateZoneLEDs(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::DeviceUpdateSingleLED(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidLed.cpp |
|
||||
| |
|
||||
| RGBController for Acer Nitro HID LED |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "AcerNitroHidKeyboardController.h"
|
||||
#include "RGBController_AcerNitroHidKeyboard.h"
|
||||
|
||||
class RGBController_AcerNitroHidLed : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_AcerNitroHidLed(std::shared_ptr<AcerNitroHidKeyboardController> controller);
|
||||
~RGBController_AcerNitroHidLed();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
std::shared_ptr<AcerNitroHidKeyboardController> controller;
|
||||
unsigned int device_id;
|
||||
};
|
||||
@@ -266,42 +266,53 @@ bool AlienwareController::Dim(std::vector<uint8_t> zones, double percent)
|
||||
return(true);
|
||||
}
|
||||
|
||||
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
|
||||
bool result = true;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
| Split the zone list into packet-sized chunks so it |
|
||||
| never overflows usb_buf |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet with leading 00, per hidapi |
|
||||
\*-----------------------------------------------------*/
|
||||
uint16_t num_zones = (uint16_t)zones.size();
|
||||
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x03;
|
||||
usb_buf[0x02] = ALIENWARE_COMMAND_DIM;
|
||||
usb_buf[0x03] = static_cast<uint8_t>(percent);
|
||||
usb_buf[0x04] = num_zones >> 8;
|
||||
usb_buf[0x05] = num_zones & 0xFF;
|
||||
|
||||
for(size_t i = 0; i < num_zones; i++)
|
||||
for(size_t offset = 0; offset < zones.size(); offset += ALIENWARE_MAX_ZONES_PER_PACKET)
|
||||
{
|
||||
usb_buf[0x06+i] = zones[i];
|
||||
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Set up message packet with leading 00, per hidapi |
|
||||
\*-------------------------------------------------*/
|
||||
uint16_t num_zones = (uint16_t)std::min<size_t>(ALIENWARE_MAX_ZONES_PER_PACKET, zones.size() - offset);
|
||||
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x03;
|
||||
usb_buf[0x02] = ALIENWARE_COMMAND_DIM;
|
||||
usb_buf[0x03] = static_cast<uint8_t>(percent);
|
||||
usb_buf[0x04] = num_zones >> 8;
|
||||
usb_buf[0x05] = num_zones & 0xFF;
|
||||
|
||||
for(size_t i = 0; i < num_zones; i++)
|
||||
{
|
||||
usb_buf[0x06+i] = zones[offset + i];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-------------------------------------------------*/
|
||||
SendHIDReport(dev, usb_buf, sizeof(usb_buf));
|
||||
|
||||
HidapiAlienwareReport response = GetResponse();
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| For this command, error is if the output equals |
|
||||
| the input |
|
||||
\*-------------------------------------------------*/
|
||||
result &= (response.data[1] == 0x03) && memcmp(usb_buf, response.data, HIDAPI_ALIENWARE_REPORT_SIZE);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
SendHIDReport(dev, usb_buf, sizeof(usb_buf));
|
||||
|
||||
HidapiAlienwareReport response = GetResponse();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| For this command, error is if the output equals the |
|
||||
| input |
|
||||
\*-----------------------------------------------------*/
|
||||
return((response.data[1] == 0x03) && memcmp(usb_buf, response.data, HIDAPI_ALIENWARE_REPORT_SIZE));
|
||||
return(result);
|
||||
}
|
||||
|
||||
bool AlienwareController::UserAnimation(uint16_t subcommand, uint16_t animation, uint16_t duration)
|
||||
@@ -370,42 +381,53 @@ bool AlienwareController::SelectZones(const std::vector<uint8_t>& zones)
|
||||
return(false);
|
||||
}
|
||||
|
||||
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
|
||||
bool result = true;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
| Split the zone list into packet-sized chunks so it |
|
||||
| never overflows usb_buf |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet with leading 00, per hidapi |
|
||||
\*-----------------------------------------------------*/
|
||||
uint16_t num_zones = (uint16_t)zones.size();
|
||||
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x03;
|
||||
usb_buf[0x02] = ALIENWARE_COMMAND_SELECT_ZONES;
|
||||
usb_buf[0x03] = 1; // loop?
|
||||
usb_buf[0x04] = num_zones >> 8;
|
||||
usb_buf[0x05] = num_zones & 0xFF;
|
||||
|
||||
for(size_t i = 0; i < num_zones; i++)
|
||||
for(size_t offset = 0; offset < zones.size(); offset += ALIENWARE_MAX_ZONES_PER_PACKET)
|
||||
{
|
||||
usb_buf[0x06+i] = zones[i];
|
||||
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Set up message packet with leading 00, per hidapi |
|
||||
\*-------------------------------------------------*/
|
||||
uint16_t num_zones = (uint16_t)std::min<size_t>(ALIENWARE_MAX_ZONES_PER_PACKET, zones.size() - offset);
|
||||
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x03;
|
||||
usb_buf[0x02] = ALIENWARE_COMMAND_SELECT_ZONES;
|
||||
usb_buf[0x03] = 1; // loop?
|
||||
usb_buf[0x04] = num_zones >> 8;
|
||||
usb_buf[0x05] = num_zones & 0xFF;
|
||||
|
||||
for(size_t i = 0; i < num_zones; i++)
|
||||
{
|
||||
usb_buf[0x06+i] = zones[offset + i];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-------------------------------------------------*/
|
||||
SendHIDReport(dev, usb_buf, sizeof(usb_buf));
|
||||
|
||||
HidapiAlienwareReport response = GetResponse();
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| For this command, error is if the output equals |
|
||||
| the input |
|
||||
\*-------------------------------------------------*/
|
||||
result &= (response.data[1] == 0x03) && memcmp(usb_buf, response.data, HIDAPI_ALIENWARE_REPORT_SIZE);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
SendHIDReport(dev, usb_buf, sizeof(usb_buf));
|
||||
|
||||
HidapiAlienwareReport response = GetResponse();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| For this command, error is if the output equals the |
|
||||
| input |
|
||||
\*-----------------------------------------------------*/
|
||||
return((response.data[1] == 0x03) && memcmp(usb_buf, response.data, HIDAPI_ALIENWARE_REPORT_SIZE));
|
||||
return(result);
|
||||
}
|
||||
|
||||
bool AlienwareController::ModeAction(uint8_t mode, uint16_t duration, uint16_t tempo, RGBColor color)
|
||||
@@ -509,44 +531,55 @@ bool AlienwareController::SetColorDirect(RGBColor color, std::vector<uint8_t> zo
|
||||
return(true);
|
||||
}
|
||||
|
||||
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
|
||||
bool result = true;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
| Split the zone list into packet-sized chunks so it |
|
||||
| never overflows usb_buf |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up message packet with leading 00, per hidapi |
|
||||
\*-----------------------------------------------------*/
|
||||
uint16_t num_zones = (uint16_t)zones.size();
|
||||
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x03;
|
||||
usb_buf[0x02] = ALIENWARE_COMMAND_SET_COLOR;
|
||||
usb_buf[0x03] = RGBGetRValue(color);
|
||||
usb_buf[0x04] = RGBGetGValue(color);
|
||||
usb_buf[0x05] = RGBGetBValue(color);
|
||||
usb_buf[0x06] = num_zones >> 8;
|
||||
usb_buf[0x07] = num_zones & 0xFF;
|
||||
|
||||
for(size_t i = 0; i < num_zones; i++)
|
||||
for(size_t offset = 0; offset < zones.size(); offset += ALIENWARE_MAX_ZONES_PER_PACKET)
|
||||
{
|
||||
usb_buf[0x08 + i] = zones[i];
|
||||
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Set up message packet with leading 00, per hidapi |
|
||||
\*-------------------------------------------------*/
|
||||
uint16_t num_zones = (uint16_t)std::min<size_t>(ALIENWARE_MAX_ZONES_PER_PACKET, zones.size() - offset);
|
||||
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x03;
|
||||
usb_buf[0x02] = ALIENWARE_COMMAND_SET_COLOR;
|
||||
usb_buf[0x03] = RGBGetRValue(color);
|
||||
usb_buf[0x04] = RGBGetGValue(color);
|
||||
usb_buf[0x05] = RGBGetBValue(color);
|
||||
usb_buf[0x06] = num_zones >> 8;
|
||||
usb_buf[0x07] = num_zones & 0xFF;
|
||||
|
||||
for(size_t i = 0; i < num_zones; i++)
|
||||
{
|
||||
usb_buf[0x08 + i] = zones[offset + i];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-------------------------------------------------*/
|
||||
SendHIDReport(dev, usb_buf, sizeof(usb_buf));
|
||||
|
||||
HidapiAlienwareReport response = GetResponse();
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| For this command, error is if the output equals |
|
||||
| the input |
|
||||
\*-------------------------------------------------*/
|
||||
result &= (response.data[1] == 0x03) && memcmp(usb_buf, response.data, HIDAPI_ALIENWARE_REPORT_SIZE);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
SendHIDReport(dev, usb_buf, sizeof(usb_buf));
|
||||
|
||||
HidapiAlienwareReport response = GetResponse();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| For this command, error is if the output equals the |
|
||||
| input |
|
||||
\*-----------------------------------------------------*/
|
||||
return((response.data[1] == 0x03) && memcmp(usb_buf, response.data, HIDAPI_ALIENWARE_REPORT_SIZE));
|
||||
return(result);
|
||||
}
|
||||
|
||||
bool AlienwareController::Reset()
|
||||
|
||||
@@ -22,6 +22,14 @@
|
||||
#define ALIENWARE_REPORT_SIZE 33
|
||||
#define HIDAPI_ALIENWARE_REPORT_SIZE (ALIENWARE_REPORT_SIZE + 1)
|
||||
#define ALIENWARE_CONTROLLER_NAME "AlienWare Controller"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Max zone IDs that fit in one report after the command |
|
||||
| header. Selections larger than this must be split across |
|
||||
| multiple packets; writing them into a single report |
|
||||
| overflows usb_buf (e.g. desktops with ~100 zones). |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ALIENWARE_MAX_ZONES_PER_PACKET 25
|
||||
enum
|
||||
{
|
||||
ALIENWARE_COMMAND_REPORT = 0x20, /* Set report type to get */
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| AlienwareAW3423DWFControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Alienware AW3423DWF monitor |
|
||||
| |
|
||||
| Ferréol DUBOIS COLI (Fefe_du_973) 23 Jan 2025 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "AlienwareAW3423DWFController.h"
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_AlienwareAW3423DWF.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Alienware Vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ALIENWARE_VID 0x187C
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Alienware Vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ALIENWARE_AW3423DWF_PID 0x100E
|
||||
#define ALIENWARE_USAGE_PAGE 0xFFDA
|
||||
#define ALIENWARE_USAGE 0x00DA
|
||||
|
||||
DetectedControllers DetectAlienwareAW3423DWFControllers(hid_device_info* info, const std::string&)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
AlienwareAW3423DWFController* controller = new AlienwareAW3423DWFController(dev, info->path);
|
||||
RGBController_AlienwareAW3423DWF* rgb_controller = new RGBController_AlienwareAW3423DWF(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR("Alienware AW3423DWF", DetectAlienwareAW3423DWFControllers, ALIENWARE_VID, ALIENWARE_AW3423DWF_PID);
|
||||
-22
@@ -10,10 +10,8 @@
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "AlienwareAW3423DWFController.h"
|
||||
#include "AlienwareMonitorController.h"
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_AlienwareAW3423DWF.h"
|
||||
#include "RGBController_AlienwareMonitor.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
@@ -24,29 +22,10 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| Alienware Vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ALIENWARE_AW3423DWF_PID 0x100E
|
||||
#define ALIENWARE_AW3225QF_PID 0x1013
|
||||
#define ALIENWARE_USAGE_PAGE 0xFFDA
|
||||
#define ALIENWARE_USAGE 0x00DA
|
||||
|
||||
DetectedControllers DetectAlienwareAW3423DWFControllers(hid_device_info* info, const std::string&)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
AlienwareAW3423DWFController* controller = new AlienwareAW3423DWFController(dev, info->path);
|
||||
RGBController_AlienwareAW3423DWF* rgb_controller = new RGBController_AlienwareAW3423DWF(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectAlienwareMonitorControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
@@ -65,5 +44,4 @@ DetectedControllers DetectAlienwareMonitorControllers(hid_device_info* info, con
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR("Alienware AW3423DWF", DetectAlienwareAW3423DWFControllers, ALIENWARE_VID, ALIENWARE_AW3423DWF_PID);
|
||||
REGISTER_HID_DETECTOR("Alienware AW3225QF", DetectAlienwareMonitorControllers, ALIENWARE_VID, ALIENWARE_AW3225QF_PID);
|
||||
@@ -44,8 +44,4 @@ DetectedControllers DetectArcticControllers()
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("Arctic RGB controller", DetectArcticControllers);
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Entries for dynamic UDEV rules |
|
||||
| |
|
||||
| DUMMY_DEVICE_DETECTOR("Arctic RGB controller", DetectArcticControllers, 0x1A86, 0x7523 ) |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_CUSTOM_UDEV_RULE(arctic, "Arctic RGB controller", "SUBSYSTEMS==\"serial|hidraw\", ATTRS{idVendor}==\"1a86\", ATTRS{idProduct}==\"7523\", TAG+=\"uaccess\", TAG+=\"Arctic_RGB_controller\"");
|
||||
|
||||
+3
-27
@@ -4,18 +4,15 @@
|
||||
| Detector for ASUS ROG Aura Core |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 13 Apr 2020 |
|
||||
| Chris M (Dr_No) 28 Jul 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "DetectionManager.h"
|
||||
#include "AsusAuraCoreController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_AsusAuraCore.h"
|
||||
#include "RGBController_AsusAuraCoreLaptop.h"
|
||||
#include <hidapi.h>
|
||||
#include "AsusAuraCoreController.h"
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_AsusAuraCore.h"
|
||||
|
||||
#define AURA_CORE_VID 0x0B05
|
||||
|
||||
@@ -44,27 +41,6 @@ DetectedControllers DetectAsusAuraCoreControllers(hid_device_info* info, const s
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectAsusAuraCoreLaptopControllers(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
AsusAuraCoreLaptopController* controller = new AsusAuraCoreLaptopController(dev, info->path);
|
||||
RGBController_AsusAuraCoreLaptop* rgb_controller = new RGBController_AsusAuraCoreLaptop(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
|
||||
REGISTER_HID_DETECTOR ("ASUS Aura Core", DetectAsusAuraCoreControllers, AURA_CORE_VID, 0x1854);
|
||||
REGISTER_HID_DETECTOR ("ASUS Aura Core", DetectAsusAuraCoreControllers, AURA_CORE_VID, 0x1866);
|
||||
REGISTER_HID_DETECTOR ("ASUS Aura Core", DetectAsusAuraCoreControllers, AURA_CORE_VID, 0x1869);
|
||||
REGISTER_HID_DETECTOR_PU("ASUS ROG Strix SCAR 15", DetectAsusAuraCoreLaptopControllers, AURA_CORE_VID, AURA_STRIX_SCAR_15_PID, 0xFF31, 0x79);
|
||||
REGISTER_HID_DETECTOR_PU("ASUS ROG Strix SCAR 17", DetectAsusAuraCoreLaptopControllers, AURA_CORE_VID, 0x1866, 0xFF31, 0x79);
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| AsusAuraCoreLaptopControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for ASUS ROG Aura Core Laptop |
|
||||
| |
|
||||
| Chris M (Dr_No) 28 Jul 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "AsusAuraCoreLaptopController.h"
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_AsusAuraCoreLaptop.h"
|
||||
|
||||
#define AURA_CORE_VID 0x0B05
|
||||
|
||||
DetectedControllers DetectAsusAuraCoreLaptopControllers(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
AsusAuraCoreLaptopController* controller = new AsusAuraCoreLaptopController(dev, info->path);
|
||||
RGBController_AsusAuraCoreLaptop* rgb_controller = new RGBController_AsusAuraCoreLaptop(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_PU("ASUS ROG Strix SCAR 15", DetectAsusAuraCoreLaptopControllers, AURA_CORE_VID, AURA_STRIX_SCAR_15_PID, 0xFF31, 0x79);
|
||||
REGISTER_HID_DETECTOR_PU("ASUS ROG Strix SCAR 17", DetectAsusAuraCoreLaptopControllers, AURA_CORE_VID, 0x1866, 0xFF31, 0x79);
|
||||
+20
@@ -940,6 +940,25 @@ static const aura_core_laptop_device g814jv_device =
|
||||
}
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| ASUS ROG Strix G18 (G814JIR) |
|
||||
| |
|
||||
| G814JIR uses the same Aura Core keyboard and lightbar |
|
||||
| layout as the G814JV G18 profile. |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const aura_core_laptop_device g814jir_device =
|
||||
{
|
||||
"G814JIR",
|
||||
{
|
||||
&g814rw_keyboard_zone,
|
||||
&g814jv_lightbar_zone,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
}
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| DEVICE MASTER LIST |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
@@ -954,6 +973,7 @@ const aura_core_laptop_device* aura_core_laptop_device_list_data[] =
|
||||
&g713rw_device,
|
||||
&g733qr_device,
|
||||
&g814jv_device,
|
||||
&g814jir_device,
|
||||
};
|
||||
|
||||
const unsigned int AURA_CORE_LAPTOP_DEVICE_COUNT = (sizeof(aura_core_laptop_device_list_data) / sizeof(aura_core_laptop_device_list_data[ 0 ]));
|
||||
|
||||
+1
-1
@@ -428,7 +428,6 @@ void RGBController_AuraTUFKeyboard::SetupZones()
|
||||
break;
|
||||
case AURA_TUF_K3_GAMING_PID:
|
||||
case AURA_TUF_K7_GAMING_PID:
|
||||
case AURA_TUF_K3_GENII_MIKU_EDITION_PID:
|
||||
keyboard_ptr = &AsusTUFK7Layouts;
|
||||
break;
|
||||
case AURA_ROG_STRIX_SCOPE_PID:
|
||||
@@ -485,6 +484,7 @@ void RGBController_AuraTUFKeyboard::SetupZones()
|
||||
keyboard_ptr = &AsusTufK1Layouts;
|
||||
break;
|
||||
case AURA_TUF_K3_GAMING_GEN_II_PID:
|
||||
case AURA_TUF_K3_GENII_MIKU_EDITION_PID:
|
||||
keyboard_ptr = &AsusTUFK3GamingGen2Layouts;
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
| Product ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ASUS_ROG_STRIX_XG27AQDMG_PID 0x1BA3
|
||||
#define ASUS_ROG_SWIFT_XG27UCG_PID 0x1BB4
|
||||
#define ASUS_ROG_STRIX_XG27UCG_PID 0x1BB4
|
||||
#define ASUS_ROG_SWIFT_PG32UCDM_PID 0x1B2B
|
||||
#define ASUS_ROG_SWIFT_PG32UCDMR_PID 0x1C9B
|
||||
|
||||
DetectedControllers DetectAsusMonitorControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
@@ -44,5 +45,7 @@ DetectedControllers DetectAsusMonitorControllers(hid_device_info* info, const st
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Asus ROG STRIX XG27AQDMG", DetectAsusMonitorControllers, ASUS_VID, ASUS_ROG_STRIX_XG27AQDMG_PID, 1, 0xFF72, 0x00A1);
|
||||
REGISTER_HID_DETECTOR_IPU("Asus ROG STRIX XG27UCG", DetectAsusMonitorControllers, ASUS_VID, ASUS_ROG_SWIFT_XG27UCG_PID, 1, 0xFF72, 0x00A1);
|
||||
REGISTER_HID_DETECTOR_IPU("Asus ROG STRIX PG32UCDM", DetectAsusMonitorControllers, ASUS_VID, ASUS_ROG_SWIFT_PG32UCDM_PID, 1, 0xFF72, 0x00A1);
|
||||
REGISTER_HID_DETECTOR_IPU("Asus ROG STRIX XG27UCG", DetectAsusMonitorControllers, ASUS_VID, ASUS_ROG_STRIX_XG27UCG_PID, 1, 0xFF72, 0x00A1);
|
||||
REGISTER_HID_DETECTOR_IPU("Asus ROG SWIFT PG32UCDM", DetectAsusMonitorControllers, ASUS_VID, ASUS_ROG_SWIFT_PG32UCDM_PID, 1, 0xFF72, 0x00A1);
|
||||
REGISTER_HID_DETECTOR_IPU("Asus ROG SWIFT PG32UCDMR", DetectAsusMonitorControllers, ASUS_VID, ASUS_ROG_SWIFT_PG32UCDMR_PID, 1, 0xFF72, 0x00A1);
|
||||
|
||||
|
||||
@@ -36,3 +36,5 @@ DetectedControllers DetectAsusTUFLaptopLinuxControllers()
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("ASUS TUF Laptop", DetectAsusTUFLaptopLinuxControllers);
|
||||
|
||||
REGISTER_CUSTOM_UDEV_RULE(asus_wmi, "ASUS TUF Laptops (asus-wmi)", "ACTION==\"add\", SUBSYSTEM==\"leds\", KERNEL==\"asus::kbd_backlight\", RUN+=\"/usr/bin/env chmod a+w /sys%p/kbd_rgb_mode\"\nACTION==\"add\", SUBSYSTEM==\"leds\", KERNEL==\"asus::kbd_backlight\", RUN+=\"/usr/bin/env chmod a+w /sys%p/brightness\"");
|
||||
|
||||
@@ -40,8 +40,4 @@ DetectedControllers DetectBlinkyTapeControllers()
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("BlinkyTape", DetectBlinkyTapeControllers);
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Entries for dynamic UDEV rules |
|
||||
| |
|
||||
| DUMMY_DEVICE_DETECTOR("BlinkyTape", DetectBlinkyTapeControllers, 0x1D50, 0x605E ) |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_CUSTOM_UDEV_RULE(blinky_tape, "BlinkyTape", "SUBSYSTEMS==\"serial|hidraw\", ATTRS{idVendor}==\"1d50\", ATTRS{idProduct}==\"605e\", TAG+=\"uaccess\", TAG+=\"BlinkyTape\"");
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardController.cpp |
|
||||
| |
|
||||
| Driver for Clevo laptop per-key RGB keyboard (ITE 8291) |
|
||||
| Protocol based on tuxedo-drivers ite_8291 module |
|
||||
| Driver for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| |
|
||||
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
|
||||
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include "ClevoKeyboardController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
ClevoKeyboardController::ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info)
|
||||
ClevoKeyboardController::ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info, clevo_keyboard_type kb_type)
|
||||
{
|
||||
dev = dev_handle;
|
||||
type = kb_type;
|
||||
location = info.path;
|
||||
version = info.release_number;
|
||||
}
|
||||
@@ -26,6 +29,31 @@ ClevoKeyboardController::~ClevoKeyboardController()
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
clevo_keyboard_type ClevoKeyboardController::GetType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
int ClevoKeyboardController::GetNumRows()
|
||||
{
|
||||
return(type == CLEVO_KB_ITE829X) ? CLEVO_829X_NUM_ROWS : CLEVO_8291_NUM_ROWS;
|
||||
}
|
||||
|
||||
int ClevoKeyboardController::GetNumCols()
|
||||
{
|
||||
return(type == CLEVO_KB_ITE829X) ? CLEVO_829X_NUM_COLS : CLEVO_8291_NUM_COLS;
|
||||
}
|
||||
|
||||
int ClevoKeyboardController::GetNumLEDs()
|
||||
{
|
||||
return GetNumRows() * GetNumCols();
|
||||
}
|
||||
|
||||
unsigned char ClevoKeyboardController::GetBrightnessMax()
|
||||
{
|
||||
return(type == CLEVO_KB_ITE829X) ? CLEVO_829X_BRIGHTNESS_MAX : CLEVO_8291_BRIGHTNESS_MAX;
|
||||
}
|
||||
|
||||
std::string ClevoKeyboardController::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
@@ -51,147 +79,355 @@ std::string ClevoKeyboardController::GetFirmwareVersion()
|
||||
return(version_string);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::WriteControl(unsigned char* data)
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291: 8-byte feature report, no report ID |
|
||||
\*---------------------------------------------------------*/
|
||||
void ClevoKeyboardController::WriteControl8291(unsigned char* data)
|
||||
{
|
||||
hid_send_feature_report(dev, data, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
hid_send_feature_report(dev, data, CLEVO_8291_REPORT_SIZE);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::WriteRowData(unsigned char* data)
|
||||
{
|
||||
hid_write(dev, data, CLEVO_KEYBOARD_ROW_DATA_SIZE);
|
||||
hid_write(dev, data, CLEVO_8291_ROW_DATA_SIZE);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x: 6-byte feature report with report ID 0xCC |
|
||||
\*---------------------------------------------------------*/
|
||||
void ClevoKeyboardController::SendCommand829x(unsigned char cmd, unsigned char d0, unsigned char d1, unsigned char d2, unsigned char d3)
|
||||
{
|
||||
unsigned char buf[CLEVO_829X_REPORT_SIZE];
|
||||
|
||||
buf[0] = CLEVO_829X_REPORT_ID;
|
||||
buf[1] = cmd;
|
||||
buf[2] = d0;
|
||||
buf[3] = d1;
|
||||
buf[4] = d2;
|
||||
buf[5] = d3;
|
||||
|
||||
hid_send_feature_report(dev, buf, CLEVO_829X_REPORT_SIZE);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::TurnOff()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Turn off: 08 01 00 00 00 00 00 00 |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char buf[CLEVO_KEYBOARD_REPORT_SIZE];
|
||||
if(type == CLEVO_KB_ITE829X)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_BRIGHTNESS);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
buf[0] = 0x08;
|
||||
buf[1] = 0x01;
|
||||
|
||||
WriteControl(buf);
|
||||
unsigned char buf[CLEVO_8291_REPORT_SIZE];
|
||||
memset(buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
buf[0] = CLEVO_8291_CMD_MODE;
|
||||
buf[1] = CLEVO_8291_POWER_OFF;
|
||||
WriteControl8291(buf);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SetMode(unsigned char mode, unsigned char brightness, unsigned char speed, unsigned char behaviour)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set params: 08 [power] [mode] [speed] [brightness] 08 |
|
||||
| [behaviour] 00 |
|
||||
| power: 01=off, 02=on |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char buf[CLEVO_KEYBOARD_REPORT_SIZE];
|
||||
if(type == CLEVO_KB_ITE829X)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_BRIGHTNESS, brightness, speed);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
buf[0] = 0x08;
|
||||
buf[1] = 0x02; // Power on
|
||||
unsigned char buf[CLEVO_8291_REPORT_SIZE];
|
||||
memset(buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
buf[0] = CLEVO_8291_CMD_MODE;
|
||||
buf[1] = CLEVO_8291_POWER_ON;
|
||||
buf[2] = mode;
|
||||
buf[3] = speed;
|
||||
buf[4] = brightness;
|
||||
buf[5] = 0x08;
|
||||
buf[5] = CLEVO_8291_MODE_FLAG;
|
||||
buf[6] = behaviour;
|
||||
|
||||
WriteControl(buf);
|
||||
WriteControl8291(buf);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SetModeColor(unsigned char color_idx, unsigned char red, unsigned char green, unsigned char blue)
|
||||
void ClevoKeyboardController::SetModeColor(unsigned char color_idx, RGBColor color)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Set color define: 14 00 [index] R G B 00 00 |
|
||||
| index: 1-7 for built-in effects |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char buf[CLEVO_KEYBOARD_REPORT_SIZE];
|
||||
|
||||
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
buf[0] = 0x14;
|
||||
buf[1] = 0x00;
|
||||
buf[2] = color_idx;
|
||||
buf[3] = red;
|
||||
buf[4] = green;
|
||||
buf[5] = blue;
|
||||
|
||||
WriteControl(buf);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SendColors(unsigned char* color_data, unsigned char brightness)
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Per-key RGB mode (mode 0x33) |
|
||||
| 1. Set params with mode 0x33 and brightness |
|
||||
| 2. For each row 0-5: |
|
||||
| - Announce row: 16 00 [row] 00 00 00 00 00 |
|
||||
| - Send 65 bytes row data via output report |
|
||||
| |
|
||||
| Row data format (65 bytes): |
|
||||
| [0x00 padding][0x00 padding] |
|
||||
| [B0..B20][G0..G20][R0..R20] |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char ctrl_buf[CLEVO_KEYBOARD_REPORT_SIZE];
|
||||
unsigned char row_buf[CLEVO_KEYBOARD_ROW_DATA_SIZE];
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Clamp brightness |
|
||||
\*---------------------------------------------------------*/
|
||||
if(brightness > CLEVO_KEYBOARD_BRIGHTNESS_MAX)
|
||||
if(type == CLEVO_KB_ITE829X)
|
||||
{
|
||||
brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char buf[CLEVO_8291_REPORT_SIZE];
|
||||
memset(buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
buf[0] = CLEVO_8291_CMD_COLOR;
|
||||
buf[2] = color_idx;
|
||||
buf[3] = RGBGetRValue(color);
|
||||
buf[4] = RGBGetGValue(color);
|
||||
buf[5] = RGBGetBValue(color);
|
||||
WriteControl8291(buf);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SetBrightnessSpeed829x(unsigned char brightness, unsigned char speed)
|
||||
{
|
||||
if(brightness > CLEVO_829X_BRIGHTNESS_MAX)
|
||||
{
|
||||
brightness = CLEVO_829X_BRIGHTNESS_MAX;
|
||||
}
|
||||
|
||||
if(brightness != current_brightness_829x || speed != current_speed_829x)
|
||||
{
|
||||
current_brightness_829x = brightness;
|
||||
current_speed_829x = speed;
|
||||
SendCommand829x(CLEVO_829X_CMD_BRIGHTNESS, brightness, speed);
|
||||
}
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SendColorSlot829x(unsigned char cmd, unsigned char slot, RGBColor color)
|
||||
{
|
||||
SendCommand829x(cmd, slot, RGBGetRValue(color), RGBGetGValue(color), RGBGetBValue(color));
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x: Save/Clear BIOS keyboard state |
|
||||
\*---------------------------------------------------------*/
|
||||
void ClevoKeyboardController::SaveToBios829x()
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_SAVE_BIOS, 0x01);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::ClearBiosSave829x()
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_SAVE_BIOS, 0x00);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::StopAnimation829x()
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_ANIM, CLEVO_829X_CMD_STOP_ANIM);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SetEffect829x(unsigned char mode_value, const std::vector<RGBColor>& colors, unsigned int direction, unsigned int color_mode)
|
||||
{
|
||||
bool mode_changed = (mode_value != current_mode_829x);
|
||||
current_mode_829x = mode_value;
|
||||
bool use_custom_color = (color_mode != MODE_COLORS_RANDOM) && !colors.empty();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Animation modes: send [CC, 00, mode_id] on mode change |
|
||||
\*---------------------------------------------------------*/
|
||||
struct anim_entry { unsigned char mode; unsigned char anim_id; };
|
||||
static const anim_entry anim_modes[] =
|
||||
{
|
||||
{ CLEVO_829X_MODE_WAVE, 0x04 },
|
||||
{ CLEVO_829X_MODE_RANDOM, 0x09 },
|
||||
{ CLEVO_829X_MODE_SCAN, 0x0A },
|
||||
{ CLEVO_829X_MODE_SNAKE, 0x0B },
|
||||
{ CLEVO_829X_MODE_RAINBOW_CYCLE, 0x02 },
|
||||
{ CLEVO_829X_MODE_RAINBOW_GRAD, 0x04 },
|
||||
};
|
||||
|
||||
const anim_entry* anim_it = std::find_if(std::begin(anim_modes), std::end(anim_modes),
|
||||
[mode_value](const anim_entry& e) { return e.mode == mode_value; });
|
||||
|
||||
if(anim_it != std::end(anim_modes) && mode_changed)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_ANIM, anim_it->anim_id);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set params for per-key mode |
|
||||
| Direction-based effects (Wave/Snake) |
|
||||
| Slot = base + direction_index |
|
||||
| Custom color: base = 0xA1, Preset: base = 0x71 |
|
||||
\*---------------------------------------------------------*/
|
||||
memset(ctrl_buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
ctrl_buf[0] = 0x08;
|
||||
ctrl_buf[1] = 0x02; // Power on
|
||||
ctrl_buf[2] = CLEVO_KEYBOARD_MODE_DIRECT; // Per-key mode
|
||||
ctrl_buf[3] = 0x00; // Speed (unused)
|
||||
ctrl_buf[4] = brightness;
|
||||
ctrl_buf[5] = 0x00;
|
||||
ctrl_buf[6] = 0x00;
|
||||
/*---------------------------------------------------------*\
|
||||
| Map OpenRGB direction enum to firmware slot index |
|
||||
\*---------------------------------------------------------*/
|
||||
static const unsigned char dir_to_wave_idx[] =
|
||||
{
|
||||
6, /* MODE_DIRECTION_LEFT */
|
||||
7, /* MODE_DIRECTION_RIGHT */
|
||||
4, /* MODE_DIRECTION_UP */
|
||||
5, /* MODE_DIRECTION_DOWN */
|
||||
6, /* MODE_DIRECTION_HORIZONTAL */
|
||||
4, /* MODE_DIRECTION_VERTICAL */
|
||||
0, /* MODE_DIRECTION_UP_LEFT */
|
||||
1, /* MODE_DIRECTION_UP_RIGHT */
|
||||
2, /* MODE_DIRECTION_DOWN_LEFT */
|
||||
3, /* MODE_DIRECTION_DOWN_RIGHT */
|
||||
};
|
||||
|
||||
WriteControl(ctrl_buf);
|
||||
static const unsigned char dir_to_snake_idx[] =
|
||||
{
|
||||
0, /* MODE_DIRECTION_LEFT */
|
||||
0, /* MODE_DIRECTION_RIGHT */
|
||||
0, /* MODE_DIRECTION_UP */
|
||||
0, /* MODE_DIRECTION_DOWN */
|
||||
0, /* MODE_DIRECTION_HORIZONTAL */
|
||||
0, /* MODE_DIRECTION_VERTICAL */
|
||||
0, /* MODE_DIRECTION_UP_LEFT */
|
||||
1, /* MODE_DIRECTION_UP_RIGHT */
|
||||
2, /* MODE_DIRECTION_DOWN_LEFT */
|
||||
3, /* MODE_DIRECTION_DOWN_RIGHT */
|
||||
};
|
||||
|
||||
if((mode_value == CLEVO_829X_MODE_WAVE || mode_value == CLEVO_829X_MODE_RAINBOW_GRAD) && direction < sizeof(dir_to_wave_idx))
|
||||
{
|
||||
unsigned char base = use_custom_color ? CLEVO_829X_COLOR_SLOT_BASE : CLEVO_829X_PRESET_SLOT_BASE;
|
||||
unsigned char idx = dir_to_wave_idx[direction];
|
||||
unsigned char slot = base + idx;
|
||||
|
||||
if(use_custom_color)
|
||||
{
|
||||
SendColorSlot829x(CLEVO_829X_CMD_WAVE_COLOR, slot, colors[0]);
|
||||
}
|
||||
|
||||
if(!use_custom_color)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_WAVE_COLOR, slot);
|
||||
}
|
||||
}
|
||||
|
||||
if(mode_value == CLEVO_829X_MODE_SNAKE && direction < sizeof(dir_to_snake_idx))
|
||||
{
|
||||
unsigned char base = use_custom_color ? CLEVO_829X_COLOR_SLOT_BASE : CLEVO_829X_PRESET_SLOT_BASE;
|
||||
unsigned char idx = dir_to_snake_idx[direction];
|
||||
unsigned char slot = base + idx;
|
||||
|
||||
if(use_custom_color)
|
||||
{
|
||||
SendColorSlot829x(CLEVO_829X_CMD_SNAKE_COLOR, slot, colors[0]);
|
||||
}
|
||||
|
||||
if(!use_custom_color)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_SNAKE_COLOR, slot);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Send each row |
|
||||
| Breathing/Flashing: random or custom color |
|
||||
\*---------------------------------------------------------*/
|
||||
for(int row = 0; row < CLEVO_KEYBOARD_NUM_ROWS; row++)
|
||||
if(mode_value == CLEVO_829X_MODE_BREATH && use_custom_color)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Announce row data |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(ctrl_buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
ctrl_buf[0] = 0x16;
|
||||
ctrl_buf[1] = 0x00;
|
||||
ctrl_buf[2] = row;
|
||||
SendColorSlot829x(0x0A, CLEVO_829X_COLOR_CUSTOM, colors[0]);
|
||||
}
|
||||
|
||||
WriteControl(ctrl_buf);
|
||||
if(mode_value == CLEVO_829X_MODE_BREATH && !use_custom_color)
|
||||
{
|
||||
SendCommand829x(0x0A);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Build row data buffer |
|
||||
| Format: [pad][pad][B0..B20][G0..G20][R0..R20] |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(row_buf, 0x00, CLEVO_KEYBOARD_ROW_DATA_SIZE);
|
||||
if(mode_value == CLEVO_829X_MODE_BLINK && use_custom_color)
|
||||
{
|
||||
SendColorSlot829x(0x0B, CLEVO_829X_COLOR_CUSTOM, colors[0]);
|
||||
}
|
||||
|
||||
for(int col = 0; col < CLEVO_KEYBOARD_NUM_COLS; col++)
|
||||
if(mode_value == CLEVO_829X_MODE_BLINK && !use_custom_color)
|
||||
{
|
||||
SendCommand829x(0x0B);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Random: custom color only (multicolor is the default) |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == CLEVO_829X_MODE_RANDOM && use_custom_color)
|
||||
{
|
||||
SendColorSlot829x(CLEVO_829X_CMD_RANDOM_COLOR, CLEVO_829X_COLOR_SLOT_BASE, colors[0]);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Scan: 2 custom color bands |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == CLEVO_829X_MODE_SCAN)
|
||||
{
|
||||
for(size_t i = 0; i < colors.size() && i < 2; i++)
|
||||
{
|
||||
int led_idx = (row * CLEVO_KEYBOARD_NUM_COLS) + col;
|
||||
int color_offset = led_idx * 3;
|
||||
SendColorSlot829x(CLEVO_829X_CMD_SCAN_COLOR, CLEVO_829X_COLOR_SLOT_BASE + i, colors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char red = color_data[color_offset + 0];
|
||||
unsigned char green = color_data[color_offset + 1];
|
||||
unsigned char blue = color_data[color_offset + 2];
|
||||
/*---------------------------------------------------------*\
|
||||
| Fn Highlight: per-key color on function keys |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == CLEVO_829X_MODE_FN_COLOR && !colors.empty())
|
||||
{
|
||||
static const unsigned char fn_keys[] =
|
||||
{
|
||||
0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x09,
|
||||
0x0A, 0x0B, 0x0C, 0x21, 0x23, 0x31, 0x32, 0x33,
|
||||
0x53, 0x73, 0xA2
|
||||
};
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Row data layout (after 2-byte padding): |
|
||||
| Bytes 2-22: Blue values for columns 0-20 |
|
||||
| Bytes 23-43: Green values for columns 0-20 |
|
||||
| Bytes 44-64: Red values for columns 0-20 |
|
||||
\*-------------------------------------------------*/
|
||||
row_buf[2 + col] = blue;
|
||||
row_buf[2 + CLEVO_KEYBOARD_NUM_COLS + col] = green;
|
||||
row_buf[2 + CLEVO_KEYBOARD_NUM_COLS*2 + col] = red;
|
||||
SendCommand829x(CLEVO_829X_CMD_ANIM, CLEVO_829X_CMD_CLEAR);
|
||||
|
||||
for(unsigned char key : fn_keys)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_SET_LED, key,
|
||||
RGBGetRValue(colors[0]),
|
||||
RGBGetGValue(colors[0]),
|
||||
RGBGetBValue(colors[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SendColors(const unsigned char* color_data, unsigned char brightness, unsigned char speed)
|
||||
{
|
||||
int num_rows = GetNumRows();
|
||||
int num_cols = GetNumCols();
|
||||
|
||||
if(type == CLEVO_KB_ITE829X)
|
||||
{
|
||||
if(brightness > CLEVO_829X_BRIGHTNESS_MAX)
|
||||
{
|
||||
brightness = CLEVO_829X_BRIGHTNESS_MAX;
|
||||
}
|
||||
|
||||
SendCommand829x(CLEVO_829X_CMD_BRIGHTNESS, brightness, speed);
|
||||
|
||||
for(int row = 0; row < num_rows; row++)
|
||||
{
|
||||
for(int col = 0; col < num_cols; col++)
|
||||
{
|
||||
int idx = (row * num_cols + col) * 3;
|
||||
|
||||
SendCommand829x(CLEVO_829X_CMD_SET_LED,
|
||||
CLEVO_829X_LED_ID(row, col),
|
||||
color_data[idx + 0],
|
||||
color_data[idx + 1],
|
||||
color_data[idx + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291: row-based color transfer |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char ctrl_buf[CLEVO_8291_REPORT_SIZE];
|
||||
unsigned char row_buf[CLEVO_8291_ROW_DATA_SIZE];
|
||||
|
||||
if(brightness > CLEVO_8291_BRIGHTNESS_MAX)
|
||||
{
|
||||
brightness = CLEVO_8291_BRIGHTNESS_MAX;
|
||||
}
|
||||
|
||||
memset(ctrl_buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
ctrl_buf[0] = CLEVO_8291_CMD_MODE;
|
||||
ctrl_buf[1] = CLEVO_8291_POWER_ON;
|
||||
ctrl_buf[2] = CLEVO_KEYBOARD_MODE_DIRECT;
|
||||
ctrl_buf[4] = brightness;
|
||||
WriteControl8291(ctrl_buf);
|
||||
|
||||
for(int row = 0; row < num_rows; row++)
|
||||
{
|
||||
memset(ctrl_buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
ctrl_buf[0] = CLEVO_8291_CMD_ROW;
|
||||
ctrl_buf[2] = row;
|
||||
WriteControl8291(ctrl_buf);
|
||||
|
||||
memset(row_buf, 0x00, CLEVO_8291_ROW_DATA_SIZE);
|
||||
|
||||
for(int col = 0; col < num_cols; col++)
|
||||
{
|
||||
int idx = (row * num_cols + col) * 3;
|
||||
|
||||
row_buf[2 + col] = color_data[idx + 2];
|
||||
row_buf[2 + num_cols + col] = color_data[idx + 1];
|
||||
row_buf[2 + num_cols * 2 + col] = color_data[idx + 0];
|
||||
}
|
||||
|
||||
WriteRowData(row_buf);
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardController.h |
|
||||
| |
|
||||
| Driver for Clevo laptop per-key RGB keyboard (ITE 8291) |
|
||||
| Driver for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| |
|
||||
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
|
||||
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -12,27 +14,75 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| ITE 8291 keyboard defines |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CLEVO_KEYBOARD_REPORT_SIZE 8
|
||||
#define CLEVO_KEYBOARD_ROW_DATA_SIZE 65
|
||||
/*---------------------------------------------------------*\
|
||||
| Device type enumeration |
|
||||
\*---------------------------------------------------------*/
|
||||
enum clevo_keyboard_type
|
||||
{
|
||||
CLEVO_KB_ITE8291,
|
||||
CLEVO_KB_ITE829X,
|
||||
};
|
||||
|
||||
#define CLEVO_KEYBOARD_NUM_ROWS 6
|
||||
#define CLEVO_KEYBOARD_NUM_COLS 21
|
||||
#define CLEVO_KEYBOARD_NUM_LEDS (CLEVO_KEYBOARD_NUM_ROWS * CLEVO_KEYBOARD_NUM_COLS)
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291 keyboard defines (PID 0x600B) |
|
||||
| 8 bytes, no report ID, row-based color data |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CLEVO_8291_REPORT_SIZE 8
|
||||
#define CLEVO_8291_ROW_DATA_SIZE 65
|
||||
#define CLEVO_8291_NUM_ROWS 6
|
||||
#define CLEVO_8291_NUM_COLS 21
|
||||
#define CLEVO_8291_NUM_LEDS (CLEVO_8291_NUM_ROWS * CLEVO_8291_NUM_COLS)
|
||||
#define CLEVO_8291_BRIGHTNESS_MAX 0x32
|
||||
#define CLEVO_8291_CMD_MODE 0x08
|
||||
#define CLEVO_8291_CMD_COLOR 0x14
|
||||
#define CLEVO_8291_CMD_ROW 0x16
|
||||
#define CLEVO_8291_POWER_OFF 0x01
|
||||
#define CLEVO_8291_POWER_ON 0x02
|
||||
#define CLEVO_8291_MODE_FLAG 0x08
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x keyboard defines (PID 0x8910) |
|
||||
| 6 bytes with report ID 0xCC, per-key color commands |
|
||||
| Protocol: [0xCC, cmd, d0, d1, d2, d3] |
|
||||
| LED ID: ((row & 0x07) << 5) | (col & 0x1F) |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CLEVO_829X_REPORT_ID 0xCC
|
||||
#define CLEVO_829X_REPORT_SIZE 6
|
||||
#define CLEVO_829X_NUM_ROWS 6
|
||||
#define CLEVO_829X_NUM_COLS 20
|
||||
#define CLEVO_829X_NUM_LEDS (CLEVO_829X_NUM_ROWS * CLEVO_829X_NUM_COLS)
|
||||
#define CLEVO_829X_BRIGHTNESS_MAX 0x0A
|
||||
#define CLEVO_829X_LED_ID(row, col) (unsigned char)((((row) & 0x07) << 5) | ((col) & 0x1F))
|
||||
|
||||
#define CLEVO_829X_CMD_SET_LED 0x01
|
||||
#define CLEVO_829X_CMD_BRIGHTNESS 0x09
|
||||
#define CLEVO_829X_CMD_ANIM 0x00
|
||||
#define CLEVO_829X_CMD_CLEAR 0x0C
|
||||
#define CLEVO_829X_CMD_WAVE_COLOR 0x15
|
||||
#define CLEVO_829X_CMD_SNAKE_COLOR 0x16
|
||||
#define CLEVO_829X_CMD_SCAN_COLOR 0x17
|
||||
#define CLEVO_829X_CMD_RANDOM_COLOR 0x18
|
||||
#define CLEVO_829X_COLOR_CUSTOM 0xAA
|
||||
#define CLEVO_829X_COLOR_SLOT_BASE 0xA1
|
||||
#define CLEVO_829X_PRESET_SLOT_BASE 0x71
|
||||
#define CLEVO_829X_CMD_SAVE_BIOS 0x20
|
||||
#define CLEVO_829X_CMD_STOP_ANIM 0x03
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Shared defines |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CLEVO_KEYBOARD_BRIGHTNESS_MIN 0x00
|
||||
#define CLEVO_KEYBOARD_BRIGHTNESS_MAX 0x32
|
||||
|
||||
#define CLEVO_KEYBOARD_SPEED_MIN 0x01
|
||||
#define CLEVO_KEYBOARD_SPEED_MIN 0x00
|
||||
#define CLEVO_KEYBOARD_SPEED_MAX 0x0A
|
||||
#define CLEVO_KEYBOARD_SPEED_DEFAULT 0x00
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| ITE 8291 modes |
|
||||
\*-----------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291 modes |
|
||||
\*---------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CLEVO_KEYBOARD_MODE_DIRECT = 0x33,
|
||||
@@ -47,9 +97,36 @@ enum
|
||||
CLEVO_KEYBOARD_MODE_SPARK = 0x11,
|
||||
};
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Wave/reactive behaviour |
|
||||
\*-----------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x firmware modes |
|
||||
| Two command styles: |
|
||||
| cmd=0x00, d0=mode_id (animation select) |
|
||||
| cmd=mode_id, d0=0x00 (standalone effects) |
|
||||
\*---------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CLEVO_829X_MODE_DIRECT = 0xFD,
|
||||
CLEVO_829X_MODE_WAVE = 0xA0,
|
||||
CLEVO_829X_MODE_WAVE_COLOR = 0xB0,
|
||||
CLEVO_829X_MODE_BREATH = 0xA1,
|
||||
CLEVO_829X_MODE_BREATH_COLOR = 0xB1,
|
||||
CLEVO_829X_MODE_BLINK = 0xA2,
|
||||
CLEVO_829X_MODE_BLINK_COLOR = 0xB2,
|
||||
CLEVO_829X_MODE_RANDOM = 0xA3,
|
||||
CLEVO_829X_MODE_RANDOM_COLOR = 0xA9,
|
||||
CLEVO_829X_MODE_SCAN = 0xA4,
|
||||
/* Ripple (0x07) requires Insyde BIOS EC config, not supported */
|
||||
CLEVO_829X_MODE_SNAKE = 0xA6,
|
||||
CLEVO_829X_MODE_SNAKE_COLOR = 0xB6,
|
||||
CLEVO_829X_MODE_RAINBOW_CYCLE = 0xA7,
|
||||
CLEVO_829X_MODE_RAINBOW_GRAD = 0xA8,
|
||||
CLEVO_829X_MODE_FN_COLOR = 0xAF,
|
||||
CLEVO_829X_MODE_OFF = 0xFF,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Wave/reactive behaviour |
|
||||
\*---------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CLEVO_KEYBOARD_DIRECTION_LEFT = 0x01,
|
||||
@@ -67,23 +144,40 @@ enum
|
||||
class ClevoKeyboardController
|
||||
{
|
||||
public:
|
||||
ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info);
|
||||
ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info, clevo_keyboard_type kb_type);
|
||||
~ClevoKeyboardController();
|
||||
|
||||
clevo_keyboard_type GetType();
|
||||
int GetNumRows();
|
||||
int GetNumCols();
|
||||
int GetNumLEDs();
|
||||
unsigned char GetBrightnessMax();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetSerialString();
|
||||
std::string GetFirmwareVersion();
|
||||
|
||||
void TurnOff();
|
||||
void SetMode(unsigned char mode, unsigned char brightness, unsigned char speed, unsigned char behaviour);
|
||||
void SetModeColor(unsigned char color_idx, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SendColors(unsigned char* color_data, unsigned char brightness);
|
||||
void SetModeColor(unsigned char color_idx, RGBColor color);
|
||||
void SendColors(const unsigned char* color_data, unsigned char brightness, unsigned char speed);
|
||||
void SetEffect829x(unsigned char mode_value, const std::vector<RGBColor>& colors, unsigned int direction = 0, unsigned int color_mode = 0);
|
||||
void SetBrightnessSpeed829x(unsigned char brightness, unsigned char speed);
|
||||
void SaveToBios829x();
|
||||
void ClearBiosSave829x();
|
||||
void StopAnimation829x();
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
unsigned short version;
|
||||
hid_device* dev;
|
||||
clevo_keyboard_type type;
|
||||
std::string location;
|
||||
unsigned short version;
|
||||
unsigned char current_mode_829x = 0xFF;
|
||||
unsigned char current_brightness_829x = 0xFF;
|
||||
unsigned char current_speed_829x = 0xFF;
|
||||
|
||||
void WriteControl(unsigned char* data);
|
||||
void WriteControl8291(unsigned char* data);
|
||||
void WriteRowData(unsigned char* data);
|
||||
void SendCommand829x(unsigned char cmd, unsigned char d0 = 0, unsigned char d1 = 0, unsigned char d2 = 0, unsigned char d3 = 0);
|
||||
void SendColorSlot829x(unsigned char cmd, unsigned char slot, RGBColor color);
|
||||
};
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Clevo per-key RGB keyboard (ITE 8291) |
|
||||
| Detector for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| |
|
||||
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
|
||||
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -22,11 +24,12 @@
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Clevo Keyboard product IDs |
|
||||
| These are ITE 8291 per-key RGB keyboard controllers |
|
||||
| ITE 8291 and ITE 829x per-key RGB keyboard controllers |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CLEVO_KEYBOARD_PID_600B 0x600B
|
||||
#define CLEVO_KEYBOARD_PID_8291 0x600B
|
||||
#define CLEVO_KEYBOARD_PID_829X 0x8910
|
||||
|
||||
DetectedControllers DetectClevoKeyboardControllers(hid_device_info* info, const std::string& /*name*/)
|
||||
static DetectedControllers DetectClevoKeyboard(hid_device_info* info, clevo_keyboard_type kb_type)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
@@ -35,7 +38,7 @@ DetectedControllers DetectClevoKeyboardControllers(hid_device_info* info, const
|
||||
|
||||
if(dev)
|
||||
{
|
||||
ClevoKeyboardController* controller = new ClevoKeyboardController(dev, *info);
|
||||
ClevoKeyboardController* controller = new ClevoKeyboardController(dev, *info, kb_type);
|
||||
RGBController_ClevoKeyboard* rgb_controller = new RGBController_ClevoKeyboard(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
@@ -44,4 +47,15 @@ DetectedControllers DetectClevoKeyboardControllers(hid_device_info* info, const
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_PU("CLEVO Keyboard", DetectClevoKeyboardControllers, 0x048D, 0x600B, 0xFF03, 0x01);
|
||||
DetectedControllers DetectClevoKeyboard8291(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
return(DetectClevoKeyboard(info, CLEVO_KB_ITE8291));
|
||||
}
|
||||
|
||||
DetectedControllers DetectClevoKeyboard829x(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
return(DetectClevoKeyboard(info, CLEVO_KB_ITE829X));
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_PU("Clevo Keyboard (ITE 8291)", DetectClevoKeyboard8291, ITE_VID, CLEVO_KEYBOARD_PID_8291, 0xFF03, 0x01);
|
||||
REGISTER_HID_DETECTOR_PU("Clevo Keyboard (ITE 829x)", DetectClevoKeyboard829x, ITE_VID, CLEVO_KEYBOARD_PID_829X, 0xFF89, 0xCC);
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardDevices.cpp |
|
||||
| |
|
||||
| Device list for Clevo per-key RGB keyboards (ITE 8291) |
|
||||
| Device list for Clevo per-key RGB keyboards |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| |
|
||||
| Kyle Cascade (kyle@cascade.family) 21 Jan 2026 |
|
||||
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -112,6 +114,48 @@ static const std::vector<unsigned int> clevo_tkl_values =
|
||||
15, // Right
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x LED value mapping |
|
||||
| LED ID = ((row & 7) << 5) | col |
|
||||
| Row 5 (F-keys) = 0xA0+, Row 4 (numbers) = 0x80+ |
|
||||
| Row 3 (QWERTY) = 0x60+, Row 2 (home) = 0x40+ |
|
||||
| Row 1 (Z row) = 0x20+, Row 0 (mods) = 0x00+ |
|
||||
\*---------------------------------------------------------*/
|
||||
static const std::vector<unsigned int> clevo_829x_full_values =
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Values in FULL layout visual order (same as CM keyboard) |
|
||||
| LED ID = ((row & 7) << 5) | col |
|
||||
| Row counts: 16, 21, 21, 17, 18, 13 |
|
||||
\*---------------------------------------------------------*/
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0, 0,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BSPC INS HOME PGUP NMLK NMDV NMTM NMMI */
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2D, 0x2E, 0x0E, 0x10, 0x12, 0x30, 0x31, 0x32, 0x33,
|
||||
/* TAB Q W E R T Y U I O P [ ] ANSI\ DEL END PGDN NM7 NM8 NM9 NMPL */
|
||||
0x40, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x0F, 0x11, 0x13, 0x50, 0x51, 0x52, 0x53,
|
||||
/* CPLK A S D F G H J K L ; ' # ENTR NM4 NM5 NM6 */
|
||||
0x60, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0, 0x6E, 0x70, 0x71, 0x72,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER */
|
||||
0x80, 0, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8F, 0x90, 0x91, 0x92, 0x93,
|
||||
/* LCTL LFNC LWIN LALT SPACE RALT RMNU RCTL ARWL ARDN ARWR NM0 NMPD */
|
||||
0xA0, 0xA2, 0xA3, 0xA4, 0xA5, 0xAA, 0xAB, 0xAC, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2,
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values clevo_829x_keyboard_layout
|
||||
{
|
||||
KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
clevo_829x_full_values,
|
||||
{
|
||||
/* No regional overlays needed */
|
||||
}
|
||||
},
|
||||
{
|
||||
/* No edit keys needed - all keys defined in full layout */
|
||||
}
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values clevo_keyboard_layout
|
||||
{
|
||||
KEYBOARD_SIZE_TKL,
|
||||
@@ -122,10 +166,9 @@ keyboard_keymap_overlay_values clevo_keyboard_layout
|
||||
}
|
||||
},
|
||||
{
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, Alternate Name, OpCode, |
|
||||
\*-------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Remove keys not present on Clevo keyboard |
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardDevices.h |
|
||||
| |
|
||||
| Device list for Clevo per-key RGB keyboards (ITE 8291) |
|
||||
| Device list for Clevo per-key RGB keyboards |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| |
|
||||
| Kyle Cascade (kyle@cascade.family) 21 Jan 2026 |
|
||||
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -14,7 +16,8 @@
|
||||
#include <string>
|
||||
#include "KeyboardLayoutManager.h"
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Clevo keyboard layout definitions |
|
||||
\*-----------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| Clevo keyboard layout definitions |
|
||||
\*---------------------------------------------------------*/
|
||||
extern keyboard_keymap_overlay_values clevo_keyboard_layout;
|
||||
extern keyboard_keymap_overlay_values clevo_829x_keyboard_layout;
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_ClevoKeyboard.cpp |
|
||||
| |
|
||||
| RGBController for Clevo per-key RGB keyboard (ITE 8291) |
|
||||
| RGBController for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| |
|
||||
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
|
||||
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <vector>
|
||||
#include "RGBController_ClevoKeyboard.h"
|
||||
#include "KeyboardLayoutManager.h"
|
||||
|
||||
@@ -40,152 +43,306 @@ RGBController_ClevoKeyboard::RGBController_ClevoKeyboard(ClevoKeyboardController
|
||||
Direct.value = CLEVO_KEYBOARD_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Direct.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Direct.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Direct.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Direct.brightness_max = controller->GetBrightnessMax();
|
||||
Direct.brightness = controller->GetBrightnessMax();
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = CLEVO_KEYBOARD_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Rainbow.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Rainbow.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Rainbow.speed = 0x05;
|
||||
Rainbow.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Rainbow.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Rainbow.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Rainbow);
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291 built-in effects (not available on ITE 829x) |
|
||||
\*---------------------------------------------------------*/
|
||||
if(controller->GetType() == CLEVO_KB_ITE8291)
|
||||
{
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = CLEVO_KEYBOARD_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Rainbow.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Rainbow.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Rainbow.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Rainbow.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Rainbow.brightness_max = controller->GetBrightnessMax();
|
||||
Rainbow.brightness = controller->GetBrightnessMax();
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = CLEVO_KEYBOARD_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Wave.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Wave.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Wave.speed = 0x05;
|
||||
Wave.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Wave.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Wave.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Wave.direction = MODE_DIRECTION_LEFT;
|
||||
Wave.colors_min = 1;
|
||||
Wave.colors_max = 1;
|
||||
Wave.colors.resize(1);
|
||||
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Wave);
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = CLEVO_KEYBOARD_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Wave.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Wave.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Wave.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Wave.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Wave.brightness_max = controller->GetBrightnessMax();
|
||||
Wave.brightness = controller->GetBrightnessMax();
|
||||
Wave.direction = MODE_DIRECTION_LEFT;
|
||||
Wave.colors_min = 1;
|
||||
Wave.colors_max = 1;
|
||||
Wave.colors.resize(1);
|
||||
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Wave);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CLEVO_KEYBOARD_MODE_BREATH;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Breathing.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Breathing.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Breathing.speed = 0x05;
|
||||
Breathing.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Breathing.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Breathing);
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CLEVO_KEYBOARD_MODE_BREATH;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Breathing.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Breathing.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Breathing.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Breathing.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = controller->GetBrightnessMax();
|
||||
Breathing.brightness = controller->GetBrightnessMax();
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Reactive;
|
||||
Reactive.name = "Reactive";
|
||||
Reactive.value = CLEVO_KEYBOARD_MODE_REACTIVE;
|
||||
Reactive.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Reactive.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Reactive.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Reactive.speed = 0x05;
|
||||
Reactive.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Reactive.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Reactive.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Reactive.colors_min = 1;
|
||||
Reactive.colors_max = 1;
|
||||
Reactive.colors.resize(1);
|
||||
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Reactive);
|
||||
mode Reactive;
|
||||
Reactive.name = "Reactive";
|
||||
Reactive.value = CLEVO_KEYBOARD_MODE_REACTIVE;
|
||||
Reactive.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Reactive.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Reactive.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Reactive.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Reactive.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Reactive.brightness_max = controller->GetBrightnessMax();
|
||||
Reactive.brightness = controller->GetBrightnessMax();
|
||||
Reactive.colors_min = 1;
|
||||
Reactive.colors_max = 1;
|
||||
Reactive.colors.resize(1);
|
||||
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Reactive);
|
||||
|
||||
mode Ripple;
|
||||
Ripple.name = "Ripple";
|
||||
Ripple.value = CLEVO_KEYBOARD_MODE_RIPPLE;
|
||||
Ripple.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Ripple.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Ripple.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Ripple.speed = 0x05;
|
||||
Ripple.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Ripple.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Ripple.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Ripple.colors_min = 1;
|
||||
Ripple.colors_max = 1;
|
||||
Ripple.colors.resize(1);
|
||||
Ripple.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Ripple);
|
||||
mode Ripple;
|
||||
Ripple.name = "Ripple";
|
||||
Ripple.value = CLEVO_KEYBOARD_MODE_RIPPLE;
|
||||
Ripple.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Ripple.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Ripple.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Ripple.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Ripple.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Ripple.brightness_max = controller->GetBrightnessMax();
|
||||
Ripple.brightness = controller->GetBrightnessMax();
|
||||
Ripple.colors_min = 1;
|
||||
Ripple.colors_max = 1;
|
||||
Ripple.colors.resize(1);
|
||||
Ripple.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Ripple);
|
||||
|
||||
mode Marquee;
|
||||
Marquee.name = "Marquee";
|
||||
Marquee.value = CLEVO_KEYBOARD_MODE_MARQUEE;
|
||||
Marquee.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Marquee.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Marquee.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Marquee.speed = 0x05;
|
||||
Marquee.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Marquee.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Marquee.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Marquee.colors_min = 1;
|
||||
Marquee.colors_max = 1;
|
||||
Marquee.colors.resize(1);
|
||||
Marquee.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Marquee);
|
||||
mode Marquee;
|
||||
Marquee.name = "Marquee";
|
||||
Marquee.value = CLEVO_KEYBOARD_MODE_MARQUEE;
|
||||
Marquee.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Marquee.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Marquee.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Marquee.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Marquee.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Marquee.brightness_max = controller->GetBrightnessMax();
|
||||
Marquee.brightness = controller->GetBrightnessMax();
|
||||
Marquee.colors_min = 1;
|
||||
Marquee.colors_max = 1;
|
||||
Marquee.colors.resize(1);
|
||||
Marquee.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Marquee);
|
||||
|
||||
mode Raindrop;
|
||||
Raindrop.name = "Raindrop";
|
||||
Raindrop.value = CLEVO_KEYBOARD_MODE_RAINDROP;
|
||||
Raindrop.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Raindrop.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Raindrop.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Raindrop.speed = 0x05;
|
||||
Raindrop.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Raindrop.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Raindrop.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Raindrop.colors_min = 1;
|
||||
Raindrop.colors_max = 1;
|
||||
Raindrop.colors.resize(1);
|
||||
Raindrop.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Raindrop);
|
||||
mode Raindrop;
|
||||
Raindrop.name = "Raindrop";
|
||||
Raindrop.value = CLEVO_KEYBOARD_MODE_RAINDROP;
|
||||
Raindrop.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Raindrop.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Raindrop.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Raindrop.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Raindrop.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Raindrop.brightness_max = controller->GetBrightnessMax();
|
||||
Raindrop.brightness = controller->GetBrightnessMax();
|
||||
Raindrop.colors_min = 1;
|
||||
Raindrop.colors_max = 1;
|
||||
Raindrop.colors.resize(1);
|
||||
Raindrop.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Raindrop);
|
||||
|
||||
mode Aurora;
|
||||
Aurora.name = "Aurora";
|
||||
Aurora.value = CLEVO_KEYBOARD_MODE_AURORA;
|
||||
Aurora.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Aurora.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Aurora.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Aurora.speed = 0x05;
|
||||
Aurora.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Aurora.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Aurora.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Aurora.colors_min = 1;
|
||||
Aurora.colors_max = 1;
|
||||
Aurora.colors.resize(1);
|
||||
Aurora.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Aurora);
|
||||
mode Aurora;
|
||||
Aurora.name = "Aurora";
|
||||
Aurora.value = CLEVO_KEYBOARD_MODE_AURORA;
|
||||
Aurora.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Aurora.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Aurora.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Aurora.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Aurora.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Aurora.brightness_max = controller->GetBrightnessMax();
|
||||
Aurora.brightness = controller->GetBrightnessMax();
|
||||
Aurora.colors_min = 1;
|
||||
Aurora.colors_max = 1;
|
||||
Aurora.colors.resize(1);
|
||||
Aurora.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Aurora);
|
||||
|
||||
mode Spark;
|
||||
Spark.name = "Spark";
|
||||
Spark.value = CLEVO_KEYBOARD_MODE_SPARK;
|
||||
Spark.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Spark.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Spark.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Spark.speed = 0x05;
|
||||
Spark.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Spark.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Spark.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Spark.colors_min = 1;
|
||||
Spark.colors_max = 1;
|
||||
Spark.colors.resize(1);
|
||||
Spark.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Spark);
|
||||
mode Spark;
|
||||
Spark.name = "Spark";
|
||||
Spark.value = CLEVO_KEYBOARD_MODE_SPARK;
|
||||
Spark.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Spark.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Spark.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Spark.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Spark.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Spark.brightness_max = controller->GetBrightnessMax();
|
||||
Spark.brightness = controller->GetBrightnessMax();
|
||||
Spark.colors_min = 1;
|
||||
Spark.colors_max = 1;
|
||||
Spark.colors.resize(1);
|
||||
Spark.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Spark);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x firmware effects |
|
||||
\*---------------------------------------------------------*/
|
||||
if(controller->GetType() == CLEVO_KB_ITE829X)
|
||||
{
|
||||
unsigned char bmax = controller->GetBrightnessMax();
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = CLEVO_829X_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_DIRECTION_DIAG;
|
||||
Wave.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Wave.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Wave.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Wave.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Wave.brightness_max = bmax;
|
||||
Wave.brightness = bmax;
|
||||
Wave.direction = MODE_DIRECTION_LEFT;
|
||||
Wave.colors_min = 1;
|
||||
Wave.colors_max = 1;
|
||||
Wave.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Wave);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CLEVO_829X_MODE_BREATH;
|
||||
Breathing.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Breathing.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Breathing.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Breathing.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Breathing.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = bmax;
|
||||
Breathing.brightness = bmax;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Flashing;
|
||||
Flashing.name = "Flashing";
|
||||
Flashing.value = CLEVO_829X_MODE_BLINK;
|
||||
Flashing.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Flashing.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Flashing.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Flashing.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Flashing.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Flashing.brightness_max = bmax;
|
||||
Flashing.brightness = bmax;
|
||||
Flashing.colors_min = 1;
|
||||
Flashing.colors_max = 1;
|
||||
Flashing.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Flashing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Flashing);
|
||||
|
||||
mode Random;
|
||||
Random.name = "Random";
|
||||
Random.value = CLEVO_829X_MODE_RANDOM;
|
||||
Random.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Random.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Random.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Random.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Random.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Random.brightness_max = bmax;
|
||||
Random.brightness = bmax;
|
||||
Random.colors_min = 1;
|
||||
Random.colors_max = 1;
|
||||
Random.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Random.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Random);
|
||||
|
||||
mode Scan;
|
||||
Scan.name = "Scan";
|
||||
Scan.value = CLEVO_829X_MODE_SCAN;
|
||||
Scan.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Scan.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Scan.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Scan.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Scan.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Scan.brightness_max = bmax;
|
||||
Scan.brightness = bmax;
|
||||
Scan.colors_min = 2;
|
||||
Scan.colors_max = 2;
|
||||
Scan.colors.resize(2);
|
||||
Scan.colors[0] = ToRGBColor(255, 0, 0);
|
||||
Scan.colors[1] = ToRGBColor(0, 0, 255);
|
||||
Scan.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Scan);
|
||||
|
||||
mode Snake;
|
||||
Snake.name = "Snake";
|
||||
Snake.value = CLEVO_829X_MODE_SNAKE;
|
||||
Snake.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_DIRECTION_DIAG;
|
||||
Snake.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Snake.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Snake.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Snake.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Snake.brightness_max = bmax;
|
||||
Snake.brightness = bmax;
|
||||
Snake.direction = MODE_DIRECTION_UP_LEFT;
|
||||
Snake.colors_min = 1;
|
||||
Snake.colors_max = 1;
|
||||
Snake.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Snake.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Snake);
|
||||
|
||||
mode RainbowCycle;
|
||||
RainbowCycle.name = "Spectrum Cycle";
|
||||
RainbowCycle.value = CLEVO_829X_MODE_RAINBOW_CYCLE;
|
||||
RainbowCycle.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
RainbowCycle.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
RainbowCycle.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
RainbowCycle.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
RainbowCycle.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
RainbowCycle.brightness_max = bmax;
|
||||
RainbowCycle.brightness = bmax;
|
||||
RainbowCycle.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(RainbowCycle);
|
||||
|
||||
mode RainbowGrad;
|
||||
RainbowGrad.name = "Rainbow Wave";
|
||||
RainbowGrad.value = CLEVO_829X_MODE_RAINBOW_GRAD;
|
||||
RainbowGrad.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_DIRECTION_DIAG;
|
||||
RainbowGrad.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
RainbowGrad.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
RainbowGrad.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
RainbowGrad.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
RainbowGrad.brightness_max = bmax;
|
||||
RainbowGrad.brightness = bmax;
|
||||
RainbowGrad.direction = MODE_DIRECTION_LEFT;
|
||||
RainbowGrad.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(RainbowGrad);
|
||||
|
||||
mode FnColor;
|
||||
FnColor.name = "Fn Highlight";
|
||||
FnColor.value = CLEVO_829X_MODE_FN_COLOR;
|
||||
FnColor.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
FnColor.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
FnColor.brightness_max = bmax;
|
||||
FnColor.brightness = bmax;
|
||||
FnColor.colors_min = 1;
|
||||
FnColor.colors_max = 1;
|
||||
FnColor.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
FnColor.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(FnColor);
|
||||
}
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
@@ -207,16 +364,22 @@ RGBController_ClevoKeyboard::~RGBController_ClevoKeyboard()
|
||||
void RGBController_ClevoKeyboard::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Create keyboard layout using KeyboardLayoutManager |
|
||||
| Select layout based on device type |
|
||||
\*---------------------------------------------------------*/
|
||||
KeyboardLayoutManager new_kb(KEYBOARD_LAYOUT_ISO_QWERTY,
|
||||
clevo_keyboard_layout.base_size,
|
||||
clevo_keyboard_layout.key_values);
|
||||
bool is_829x = (controller->GetType() == CLEVO_KB_ITE829X);
|
||||
|
||||
new_kb.ChangeKeys(clevo_keyboard_layout);
|
||||
keyboard_keymap_overlay_values& layout = is_829x
|
||||
? clevo_829x_keyboard_layout
|
||||
: clevo_keyboard_layout;
|
||||
|
||||
KeyboardLayoutManager new_kb(KEYBOARD_LAYOUT_ISO_QWERTY,
|
||||
layout.base_size,
|
||||
layout.key_values);
|
||||
|
||||
new_kb.ChangeKeys(layout);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create a matrix zone for the keyboard |
|
||||
| Create keyboard zone from KLM |
|
||||
\*---------------------------------------------------------*/
|
||||
zone keyboard_zone;
|
||||
|
||||
@@ -233,9 +396,6 @@ void RGBController_ClevoKeyboard::SetupZones()
|
||||
|
||||
zones.push_back(keyboard_zone);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create LEDs from the KeyboardLayoutManager data |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int led_idx = 0; led_idx < keyboard_zone.leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
@@ -249,36 +409,48 @@ void RGBController_ClevoKeyboard::SetupZones()
|
||||
SetupColors();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create buffer map to translate OpenRGB LED order to |
|
||||
| hardware LED order. The hardware expects 126 color values |
|
||||
| indexed by LED position (0-125). |
|
||||
| Build buffer map from LED values to color pointers |
|
||||
| 829x LED IDs have gaps (stride 32), need larger map |
|
||||
\*---------------------------------------------------------*/
|
||||
null_color = 0x00000000;
|
||||
buffer_map.resize(CLEVO_KEYBOARD_NUM_LEDS, &null_color);
|
||||
|
||||
size_t map_size = is_829x
|
||||
? CLEVO_829X_LED_ID(CLEVO_829X_NUM_ROWS - 1, CLEVO_829X_NUM_COLS - 1) + 1
|
||||
: (size_t)controller->GetNumLEDs();
|
||||
|
||||
buffer_map.resize(map_size, &null_color);
|
||||
|
||||
for(size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
buffer_map[leds[led_idx].value] = &colors[led_idx];
|
||||
if(leds[led_idx].value < buffer_map.size())
|
||||
{
|
||||
buffer_map[leds[led_idx].value] = &colors[led_idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_ClevoKeyboard::DeviceUpdateLEDs()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Build color data array using buffer map and send to device|
|
||||
| The buffer_map translates from hardware LED index to the |
|
||||
| corresponding color pointer for that LED. |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char color_data[CLEVO_KEYBOARD_NUM_LEDS * 3];
|
||||
int num_rows = controller->GetNumRows();
|
||||
int num_cols = controller->GetNumCols();
|
||||
bool is_829x = (controller->GetType() == CLEVO_KB_ITE829X);
|
||||
|
||||
for(int i = 0; i < CLEVO_KEYBOARD_NUM_LEDS; i++)
|
||||
std::vector<unsigned char> color_data(num_rows * num_cols * 3);
|
||||
|
||||
for(int row = 0; row < num_rows; row++)
|
||||
{
|
||||
color_data[i * 3 + 0] = RGBGetRValue(*buffer_map[i]);
|
||||
color_data[i * 3 + 1] = RGBGetGValue(*buffer_map[i]);
|
||||
color_data[i * 3 + 2] = RGBGetBValue(*buffer_map[i]);
|
||||
for(int col = 0; col < num_cols; col++)
|
||||
{
|
||||
int seq = row * num_cols + col;
|
||||
int led_id = is_829x ? CLEVO_829X_LED_ID(row, col) : seq;
|
||||
|
||||
color_data[seq * 3 + 0] = RGBGetRValue(*buffer_map[led_id]);
|
||||
color_data[seq * 3 + 1] = RGBGetGValue(*buffer_map[led_id]);
|
||||
color_data[seq * 3 + 2] = RGBGetBValue(*buffer_map[led_id]);
|
||||
}
|
||||
}
|
||||
|
||||
controller->SendColors(color_data, modes[active_mode].brightness);
|
||||
controller->SendColors(color_data.data(), modes[active_mode].brightness, modes[active_mode].speed);
|
||||
}
|
||||
|
||||
void RGBController_ClevoKeyboard::DeviceUpdateZoneLEDs(int /*zone*/)
|
||||
@@ -304,6 +476,16 @@ void RGBController_ClevoKeyboard::DeviceUpdateMode()
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Handle ITE 829x firmware effects |
|
||||
\*---------------------------------------------------------*/
|
||||
if(controller->GetType() == CLEVO_KB_ITE829X && mode_value != CLEVO_KEYBOARD_MODE_DIRECT)
|
||||
{
|
||||
controller->SetEffect829x(mode_value, modes[active_mode].colors, modes[active_mode].direction, modes[active_mode].color_mode);
|
||||
controller->SetBrightnessSpeed829x(modes[active_mode].brightness, modes[active_mode].speed);
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Handle Direct (per-key) mode |
|
||||
\*---------------------------------------------------------*/
|
||||
@@ -318,41 +500,26 @@ void RGBController_ClevoKeyboard::DeviceUpdateMode()
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char brightness = modes[active_mode].brightness;
|
||||
unsigned char speed = modes[active_mode].speed;
|
||||
unsigned char behaviour = 0x00;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set direction for wave mode |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == CLEVO_KEYBOARD_MODE_WAVE)
|
||||
{
|
||||
switch(modes[active_mode].direction)
|
||||
{
|
||||
case MODE_DIRECTION_LEFT:
|
||||
behaviour = CLEVO_KEYBOARD_DIRECTION_LEFT;
|
||||
break;
|
||||
case MODE_DIRECTION_RIGHT:
|
||||
behaviour = CLEVO_KEYBOARD_DIRECTION_RIGHT;
|
||||
break;
|
||||
case MODE_DIRECTION_UP:
|
||||
behaviour = CLEVO_KEYBOARD_DIRECTION_UP;
|
||||
break;
|
||||
case MODE_DIRECTION_DOWN:
|
||||
behaviour = CLEVO_KEYBOARD_DIRECTION_DOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
unsigned char behaviour = (mode_value == CLEVO_KEYBOARD_MODE_WAVE)
|
||||
? modes[active_mode].direction + 1
|
||||
: 0x00;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set mode color if applicable |
|
||||
\*---------------------------------------------------------*/
|
||||
if(modes[active_mode].colors.size() > 0)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
unsigned char green = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
unsigned char blue = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
|
||||
controller->SetModeColor(1, red, green, blue);
|
||||
controller->SetModeColor(1, modes[active_mode].colors[0]);
|
||||
}
|
||||
|
||||
controller->SetMode(mode_value, brightness, speed, behaviour);
|
||||
}
|
||||
|
||||
void RGBController_ClevoKeyboard::DeviceSaveMode()
|
||||
{
|
||||
if(controller->GetType() == CLEVO_KB_ITE829X)
|
||||
{
|
||||
DeviceUpdateMode();
|
||||
controller->SaveToBios829x();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_ClevoKeyboard.h |
|
||||
| |
|
||||
| RGBController for Clevo per-key RGB keyboard (ITE 8291) |
|
||||
| RGBController for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| |
|
||||
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
|
||||
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -18,7 +20,7 @@
|
||||
class RGBController_ClevoKeyboard : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_ClevoKeyboard(ClevoKeyboardController* controller_ptr);
|
||||
explicit RGBController_ClevoKeyboard(ClevoKeyboardController* controller_ptr);
|
||||
~RGBController_ClevoKeyboard();
|
||||
|
||||
void SetupZones();
|
||||
@@ -28,6 +30,7 @@ public:
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
ClevoKeyboardController* controller;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*---------------------------------------------------------*\
|
||||
/*---------------------------------------------------------*\
|
||||
| ColorfulGPUControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Colorful GPU |
|
||||
@@ -51,6 +51,7 @@ DetectedControllers DetectColorfulGPUControllers(i2c_smbus_interface* bus, uint8
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Advanced OC 12G L-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ADVANCED_OC_12G_LV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ultra W OC 12G L-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ultra W OC 12G L-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_GA106_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ultra W OC 12G L-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_GA106_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G_2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ultra W OC 12G L-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G_2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Ultra W OC LHR-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Ultra W OC LHR-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G_2, 0x61);
|
||||
@@ -71,6 +72,7 @@ REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 Ti SUPER Advanced OC-V", Detec
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 Ti SUPER Ultra W", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TIS_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070TI_SUPER_ULTRA_W, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 SUPER Ultra W OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070_SUPER_ULTRA_W_OC, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 Vulcan OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070_VULCAN_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070_ULTRAW_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 SUPER Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070S_ULTRAW_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4080 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4080_ULTRAW_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4080 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4080_ULTRAW_OCV2, 0x61);
|
||||
|
||||
@@ -44,8 +44,4 @@ DetectedControllers DetectCorsairHydro2Controllers()
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("Corsair H100i v2", DetectCorsairHydro2Controllers);
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Entries for dynamic UDEV rules |
|
||||
| |
|
||||
| DUMMY_DEVICE_DETECTOR("Corsair H100i v2", DetectCorsairHydro2Controllers, 0x1B1C, 0x0C09 ) |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_CUSTOM_UDEV_RULE(corsair_h100i_v2, "Corsair H100i v2", "SUBSYSTEMS==\"usb|hidraw\", ATTRS{idVendor}==\"1b1c\", ATTRS{idProduct}==\"0c09\", TAG+=\"uaccess\", TAG+=\"Corsair_H100i_v2\"");
|
||||
|
||||
@@ -77,10 +77,6 @@ DetectedControllers DetectCorsairHydroControllers()
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("Corsair Hydro Series", DetectCorsairHydroControllers);
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Entries for dynamic UDEV rules |
|
||||
| |
|
||||
| DUMMY_DEVICE_DETECTOR("Corsair Hydro Series", DetectCorsairHydroControllers, 0x1B1C, 0x0C12 ) |
|
||||
| DUMMY_DEVICE_DETECTOR("Corsair Hydro Series", DetectCorsairHydroControllers, 0x1B1C, 0x0C13 ) |
|
||||
| DUMMY_DEVICE_DETECTOR("Corsair Hydro Series", DetectCorsairHydroControllers, 0x1B1C, 0x0C15 ) |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_CUSTOM_UDEV_RULE(corsair_hydro_1, "Corsair Hydro Series", "SUBSYSTEMS==\"usb|hidraw\", ATTRS{idVendor}==\"1b1c\", ATTRS{idProduct}==\"0c12\", TAG+=\"uaccess\", TAG+=\"Corsair_Hydro_Series\"");
|
||||
REGISTER_CUSTOM_UDEV_RULE(corsair_hydro_2, "Corsair Hydro Series", "SUBSYSTEMS==\"usb|hidraw\", ATTRS{idVendor}==\"1b1c\", ATTRS{idProduct}==\"0c13\", TAG+=\"uaccess\", TAG+=\"Corsair_Hydro_Series\"");
|
||||
REGISTER_CUSTOM_UDEV_RULE(corsair_hydro_3, "Corsair Hydro Series", "SUBSYSTEMS==\"usb|hidraw\", ATTRS{idVendor}==\"1b1c\", ATTRS{idProduct}==\"0c15\", TAG+=\"uaccess\", TAG+=\"Corsair_Hydro_Series\"");
|
||||
|
||||
@@ -217,7 +217,7 @@ void CorsairPeripheralController::SetLEDsKeyboardFull(std::vector<RGBColor> colo
|
||||
blu_val[keys_k95[color_idx]] = RGBGetBValue(color);
|
||||
data_sz = 48; //untested
|
||||
}
|
||||
else if (logical_layout == CORSAIR_TYPE_K70_MK2)
|
||||
else if (logical_layout == CORSAIR_TYPE_K70_MK2 || logical_layout == CORSAIR_TYPE_K70_LUX_RGB)
|
||||
{
|
||||
red_val[keys_k70_mk2[color_idx]] = RGBGetRValue(color);
|
||||
grn_val[keys_k70_mk2[color_idx]] = RGBGetGValue(color);
|
||||
@@ -447,7 +447,7 @@ void CorsairPeripheralController::SetupK55AndK95LightingControl()
|
||||
|
||||
if (physical_layout == CORSAIR_LAYOUT_ISO)
|
||||
{
|
||||
if(logical_layout == CORSAIR_TYPE_K70_MK2)
|
||||
if(logical_layout == CORSAIR_TYPE_K70_MK2 || logical_layout == CORSAIR_TYPE_K70_LUX_RGB)
|
||||
{
|
||||
skipped_identifiers = key_mapping_k70_mk2_plat_iso;
|
||||
skipped_identifiers_count = sizeof(key_mapping_k70_mk2_plat_iso) / sizeof(key_mapping_k70_mk2_plat_iso[0]);
|
||||
@@ -632,10 +632,15 @@ void CorsairPeripheralController::ReadFirmwareInfo()
|
||||
logical_layout = CORSAIR_TYPE_K55;
|
||||
break;
|
||||
|
||||
case 0x1B33:
|
||||
logical_layout = CORSAIR_TYPE_K70_LUX_RGB;
|
||||
break;
|
||||
|
||||
case 0x1B38:
|
||||
case 0x1B49:
|
||||
case 0x1B6B:
|
||||
case 0x1B55:
|
||||
case 0x1B48:
|
||||
logical_layout = CORSAIR_TYPE_K70_MK2;
|
||||
break;
|
||||
|
||||
|
||||
@@ -67,7 +67,8 @@ enum
|
||||
CORSAIR_TYPE_K95 = 2,
|
||||
CORSAIR_TYPE_K55 = 3,
|
||||
CORSAIR_TYPE_K70_MK2 = 4,
|
||||
CORSAIR_TYPE_K68 = 5
|
||||
CORSAIR_TYPE_K68 = 5,
|
||||
CORSAIR_TYPE_K70_LUX_RGB = 6
|
||||
};
|
||||
|
||||
enum
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
#define CORSAIR_K70_RGB_MK2_PID 0x1B49
|
||||
#define CORSAIR_K70_RGB_MK2_SE_PID 0x1B6B
|
||||
#define CORSAIR_K70_RGB_MK2_LP_PID 0x1B55
|
||||
|
||||
#define CORSAIR_K70_RGB_PRO_OPTO_PID 0x1BC6
|
||||
#define CORSAIR_K95_RGB_PID 0x1B11
|
||||
#define CORSAIR_K95_PLATINUM_PID 0x1B2D
|
||||
#define CORSAIR_K95_PLATINUM_SE_PID 0x1B82
|
||||
@@ -192,6 +192,7 @@ REGISTER_HID_DETECTOR_IP("Corsair K70 RGB RAPIDFIRE", DetectCorsairPeriphe
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB MK.2", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K70_RGB_MK2_PID, 1, 0xFFC2);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB MK.2 SE", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K70_RGB_MK2_SE_PID, 1, 0xFFC2);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB MK.2 Low Profile",DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K70_RGB_MK2_LP_PID, 1, 0xFFC2);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K70 RGB PRO Optomechanical", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K70_RGB_PRO_OPTO_PID, 1, 0xFFC2);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K95 RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K95_RGB_PID, 1, 0xFFC2);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K95 RGB PLATINUM", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K95_PLATINUM_PID, 1, 0xFFC2);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K95 RGB PLATINUM SE", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_K95_PLATINUM_SE_PID, 1, 0xFFC2);
|
||||
|
||||
@@ -23,6 +23,15 @@ static unsigned int matrix_map[6][23] =
|
||||
{ 4, 111, 22, 32, 40, 50, NA, 59, NA, 68, 78, 88, 97, 106, 61, NA, NA, 81, NA, 73, 83, 92, 109 },
|
||||
{ 5, 14, 23, NA, NA, NA, NA, 41, NA, NA, NA, NA, 69, 79, 89, 71, 90, 99, 108, 101, NA, 110, NA } };
|
||||
|
||||
static unsigned int matrix_map_k70_lux_rgb[7][23] =
|
||||
{ { NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 107, 8, NA, NA, 16, NA, NA,},
|
||||
{ 0, NA, 10, 18, 28, 36, NA, 46, 55, 64, 74, NA, 84, 93, 102, 6, 15, 24, 33, 26, 35, 44, 53 },
|
||||
{ 1, 11, 19, 29, 37, 47, NA, 56, 65, 75, 85, 94, 103, 7, 25, NA, 42, 51, 60, 62, 72, 82, 91 },
|
||||
{ 2, NA, 12, 20, 30, 38, 48, 57, 66, 76, 86, NA, 95, 104, 70, 80, 34, 43, 52, 9, 17, 27, 100 },
|
||||
{ 3, NA, 13, 21, 31, 39, 49, 58, 67, 77, 87, NA, 96, 105, 98, 112, NA, NA, NA, 45, 54, 63, NA },
|
||||
{ 4, 111, NA, 22, 32, 40, 50, 59, 68, 78, 88, 97, NA, 106, 61, NA, NA, 81, NA, 73, 83, 92, 109 },
|
||||
{ 5, NA, 14, 23, NA, NA, NA, 41, NA, NA, NA, 69, NA, 79, 89, 71, 90, 99, 108, 101, NA, 110, NA } };
|
||||
|
||||
static unsigned int matrix_map_k70_mk2[7][23] =
|
||||
{ { NA, NA, NA, 115, 107, 8, NA, NA, NA, NA, NA, 113, 114, NA, NA, NA, NA, NA, NA, 16, NA, NA, NA,},
|
||||
{ 0, NA, 10, 18, 28, 36, NA, 46, 55, 64, 74, NA, 84, 93, 102, 6, 15, 24, 33, 26, 35, 44, 53 },
|
||||
@@ -68,6 +77,24 @@ static const zone_type zone_types[] =
|
||||
ZONE_TYPE_MATRIX,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| K70 LUX RGB Corsair Layout |
|
||||
\*---------------------------------------------------------*/
|
||||
static const char* zone_names_k70_lux_rgb[] =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
};
|
||||
|
||||
static const unsigned int zone_sizes_k70_lux_rgb[] =
|
||||
{
|
||||
116
|
||||
};
|
||||
|
||||
static const zone_type zone_types_k70_lux_rgb[] =
|
||||
{
|
||||
ZONE_TYPE_MATRIX,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| K70 MK2 Corsair Layout |
|
||||
\*---------------------------------------------------------*/
|
||||
@@ -159,7 +186,7 @@ static const char* led_names[] =
|
||||
KEY_EN_LEFT_CONTROL, //5
|
||||
KEY_EN_F12, //6
|
||||
KEY_EN_EQUALS, //7
|
||||
"Key: Lock", //8
|
||||
KEY_EN_WINDOWS_LOCK, //8
|
||||
KEY_EN_NUMPAD_7, //9
|
||||
KEY_EN_F1, //12
|
||||
KEY_EN_1, //13
|
||||
@@ -258,7 +285,7 @@ static const char* led_names[] =
|
||||
KEY_EN_LEFT_BRACKET, //134
|
||||
KEY_EN_QUOTE, //135
|
||||
KEY_EN_FORWARD_SLASH, //136
|
||||
"Key: Brightness", //137
|
||||
KEY_EN_BRIGHTNESS, //137
|
||||
KEY_EN_RIGHT_ARROW, //139
|
||||
KEY_EN_NUMPAD_ENTER, //140
|
||||
KEY_EN_NUMPAD_PERIOD, //141
|
||||
@@ -266,7 +293,7 @@ static const char* led_names[] =
|
||||
KEY_EN_ISO_BACK_SLASH,
|
||||
};
|
||||
|
||||
static const char* led_names_k70_mk2[] =
|
||||
static const char* led_names_k70_lux_rgb[] =
|
||||
{
|
||||
KEY_EN_ESCAPE, //0
|
||||
KEY_EN_BACK_TICK, //1
|
||||
@@ -276,7 +303,7 @@ static const char* led_names_k70_mk2[] =
|
||||
KEY_EN_LEFT_CONTROL, //5
|
||||
KEY_EN_F12, //6
|
||||
KEY_EN_EQUALS, //7
|
||||
"Key: Lock", //8
|
||||
KEY_EN_WINDOWS_LOCK, //8
|
||||
KEY_EN_NUMPAD_7, //9
|
||||
KEY_EN_F1, //12
|
||||
KEY_EN_1, //13
|
||||
@@ -380,7 +407,132 @@ static const char* led_names_k70_mk2[] =
|
||||
KEY_EN_LEFT_BRACKET, //134
|
||||
KEY_EN_QUOTE, //135
|
||||
KEY_EN_FORWARD_SLASH, //136
|
||||
"Key: Brightness", //137
|
||||
KEY_EN_BRIGHTNESS, //137
|
||||
KEY_EN_RIGHT_ARROW, //139
|
||||
KEY_EN_NUMPAD_ENTER, //140
|
||||
KEY_EN_NUMPAD_PERIOD, //141
|
||||
"Key: / (ISO)", //16
|
||||
KEY_EN_ISO_BACK_SLASH, //114
|
||||
"Key: Logo Left", //047
|
||||
"Key: Logo Right", //059
|
||||
"Key: Profile", //125
|
||||
};
|
||||
|
||||
static const char* led_names_k70_mk2[] =
|
||||
{
|
||||
KEY_EN_ESCAPE, //0
|
||||
KEY_EN_BACK_TICK, //1
|
||||
KEY_EN_TAB, //2
|
||||
KEY_EN_CAPS_LOCK, //3
|
||||
KEY_EN_LEFT_SHIFT, //4
|
||||
KEY_EN_LEFT_CONTROL, //5
|
||||
KEY_EN_F12, //6
|
||||
KEY_EN_EQUALS, //7
|
||||
KEY_EN_WINDOWS_LOCK, //8
|
||||
KEY_EN_NUMPAD_7, //9
|
||||
KEY_EN_F1, //12
|
||||
KEY_EN_1, //13
|
||||
KEY_EN_Q, //14
|
||||
KEY_EN_A, //15
|
||||
//"Key: / (ISO)", //16
|
||||
KEY_EN_LEFT_WINDOWS, //17
|
||||
KEY_EN_PRINT_SCREEN, //18
|
||||
KEY_EN_MEDIA_MUTE, //20
|
||||
KEY_EN_NUMPAD_8, //21
|
||||
KEY_EN_F2, //24
|
||||
KEY_EN_2, //25
|
||||
KEY_EN_W, //26
|
||||
KEY_EN_S, //27
|
||||
KEY_EN_Z, //28
|
||||
KEY_EN_LEFT_ALT, //29
|
||||
KEY_EN_SCROLL_LOCK, //30
|
||||
KEY_EN_BACKSPACE, //31
|
||||
KEY_EN_MEDIA_STOP, //32
|
||||
KEY_EN_NUMPAD_9, //33
|
||||
KEY_EN_F3, //36
|
||||
KEY_EN_3, //37
|
||||
KEY_EN_E, //38
|
||||
KEY_EN_D, //39
|
||||
KEY_EN_X, //40
|
||||
KEY_EN_PAUSE_BREAK, //42
|
||||
KEY_EN_DELETE, //43
|
||||
KEY_EN_MEDIA_PREVIOUS, //44
|
||||
//"Key: Logo Left", //047
|
||||
KEY_EN_F4, //48
|
||||
KEY_EN_4, //49
|
||||
KEY_EN_R, //50
|
||||
KEY_EN_F, //51
|
||||
KEY_EN_C, //52
|
||||
KEY_EN_SPACE, //53
|
||||
KEY_EN_INSERT, //54
|
||||
KEY_EN_END, //55
|
||||
KEY_EN_MEDIA_PLAY_PAUSE, //56
|
||||
KEY_EN_NUMPAD_4, //57
|
||||
//"Key: Logo Right", //059
|
||||
KEY_EN_F5, //60
|
||||
KEY_EN_5, //61
|
||||
KEY_EN_T, //62
|
||||
KEY_EN_G, //63
|
||||
KEY_EN_V, //64
|
||||
KEY_EN_HOME, //66
|
||||
KEY_EN_PAGE_DOWN, //67
|
||||
KEY_EN_MEDIA_NEXT, //68
|
||||
KEY_EN_NUMPAD_5, //69
|
||||
KEY_EN_F6, //72
|
||||
KEY_EN_6, //73
|
||||
KEY_EN_Y, //74
|
||||
KEY_EN_H, //75
|
||||
KEY_EN_B, //76
|
||||
KEY_EN_PAGE_UP, //78
|
||||
KEY_EN_RIGHT_SHIFT, //79
|
||||
KEY_EN_NUMPAD_LOCK, //80
|
||||
KEY_EN_NUMPAD_6, //81
|
||||
KEY_EN_F7, //84
|
||||
KEY_EN_7, //85
|
||||
KEY_EN_U, //86
|
||||
KEY_EN_J, //87
|
||||
KEY_EN_N, //88
|
||||
KEY_EN_RIGHT_ALT, //89
|
||||
KEY_EN_RIGHT_BRACKET, //90
|
||||
KEY_EN_RIGHT_CONTROL, //91
|
||||
KEY_EN_NUMPAD_DIVIDE, //92
|
||||
KEY_EN_NUMPAD_1, //93
|
||||
KEY_EN_F8, //96
|
||||
KEY_EN_8, //97
|
||||
KEY_EN_I, //98
|
||||
KEY_EN_K, //99
|
||||
KEY_EN_M, //100
|
||||
KEY_EN_RIGHT_WINDOWS, //101
|
||||
KEY_EN_ANSI_BACK_SLASH, //102
|
||||
KEY_EN_UP_ARROW, //103
|
||||
KEY_EN_NUMPAD_TIMES, //104
|
||||
KEY_EN_NUMPAD_2, //105
|
||||
KEY_EN_F9, //108
|
||||
KEY_EN_9, //109
|
||||
KEY_EN_O, //110
|
||||
KEY_EN_L, //111
|
||||
KEY_EN_COMMA, //112
|
||||
KEY_EN_MENU, //113
|
||||
//KEY_EN_ISO_BACK_SLASH, //114
|
||||
KEY_EN_LEFT_ARROW, //115
|
||||
KEY_EN_NUMPAD_MINUS, //116
|
||||
KEY_EN_NUMPAD_3, //117
|
||||
KEY_EN_F10, //120
|
||||
KEY_EN_0, //121
|
||||
KEY_EN_P, //122
|
||||
KEY_EN_SEMICOLON, //123
|
||||
//"Key: Profile", //125
|
||||
KEY_EN_PERIOD, //124
|
||||
KEY_EN_ANSI_ENTER, //126
|
||||
KEY_EN_DOWN_ARROW, //127
|
||||
KEY_EN_NUMPAD_PLUS, //128
|
||||
KEY_EN_NUMPAD_0, //129
|
||||
KEY_EN_F11, //132
|
||||
KEY_EN_MINUS, //133
|
||||
KEY_EN_LEFT_BRACKET, //134
|
||||
KEY_EN_QUOTE, //135
|
||||
KEY_EN_FORWARD_SLASH, //136
|
||||
KEY_EN_BRIGHTNESS, //137
|
||||
KEY_EN_RIGHT_ARROW, //139
|
||||
KEY_EN_NUMPAD_ENTER, //140
|
||||
KEY_EN_NUMPAD_PERIOD, //141
|
||||
@@ -401,7 +553,7 @@ static const char* led_names_k95_plat[] =
|
||||
KEY_EN_LEFT_CONTROL, //5
|
||||
KEY_EN_F12, //6
|
||||
KEY_EN_EQUALS, //7
|
||||
"Key: Lock", //8
|
||||
KEY_EN_WINDOWS_LOCK, //8
|
||||
KEY_EN_NUMPAD_7, //9
|
||||
KEY_EN_F1, //12
|
||||
KEY_EN_1, //13
|
||||
@@ -500,7 +652,7 @@ static const char* led_names_k95_plat[] =
|
||||
KEY_EN_LEFT_BRACKET, //134
|
||||
KEY_EN_QUOTE, //135
|
||||
KEY_EN_FORWARD_SLASH, //136
|
||||
"Key: Brightness", //137
|
||||
KEY_EN_BRIGHTNESS, //137
|
||||
KEY_EN_RIGHT_ARROW, //139
|
||||
KEY_EN_NUMPAD_ENTER, //140
|
||||
KEY_EN_NUMPAD_PERIOD, //141
|
||||
@@ -544,7 +696,7 @@ static const char* led_names_k95[] =
|
||||
KEY_EN_LEFT_CONTROL, //5
|
||||
KEY_EN_F12, //6
|
||||
KEY_EN_EQUALS, //7
|
||||
"Key: Lock", //8
|
||||
KEY_EN_WINDOWS_LOCK, //8
|
||||
KEY_EN_NUMPAD_7, //9
|
||||
KEY_EN_F1, //12
|
||||
KEY_EN_1, //13
|
||||
@@ -643,7 +795,7 @@ static const char* led_names_k95[] =
|
||||
KEY_EN_LEFT_BRACKET, //134
|
||||
KEY_EN_QUOTE, //135
|
||||
KEY_EN_FORWARD_SLASH, //136
|
||||
"Key: Brightness", //137
|
||||
KEY_EN_BRIGHTNESS, //137
|
||||
KEY_EN_RIGHT_ARROW, //139
|
||||
KEY_EN_NUMPAD_ENTER, //140
|
||||
KEY_EN_NUMPAD_PERIOD, //141
|
||||
@@ -1012,6 +1164,19 @@ void RGBController_CorsairPeripheral::SetupZones()
|
||||
new_zone.leds_max = zone_sizes_k55[zone_idx];
|
||||
new_zone.leds_count = zone_sizes_k55[zone_idx];
|
||||
}
|
||||
else if (logical_layout == CORSAIR_TYPE_K70_LUX_RGB)
|
||||
{
|
||||
new_zone.name = zone_names_k70_lux_rgb[zone_idx];
|
||||
new_zone.type = zone_types_k70_lux_rgb[zone_idx];
|
||||
new_zone.leds_min = zone_sizes_k70_lux_rgb[zone_idx];
|
||||
new_zone.leds_max = zone_sizes_k70_lux_rgb[zone_idx];
|
||||
new_zone.leds_count = zone_sizes_k70_lux_rgb[zone_idx];
|
||||
|
||||
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
|
||||
{
|
||||
new_zone.matrix_map.Set(7, 23, (unsigned int *)&matrix_map_k70_lux_rgb);
|
||||
}
|
||||
}
|
||||
else if (logical_layout == CORSAIR_TYPE_K70_MK2)
|
||||
{
|
||||
new_zone.name = zone_names_k70_mk2[zone_idx];
|
||||
@@ -1101,6 +1266,10 @@ void RGBController_CorsairPeripheral::SetupZones()
|
||||
{
|
||||
new_led.name = led_names_k55[led_idx];
|
||||
}
|
||||
else if(logical_layout == CORSAIR_TYPE_K70_LUX_RGB)
|
||||
{
|
||||
new_led.name = led_names_k70_lux_rgb[led_idx];
|
||||
}
|
||||
else if(logical_layout == CORSAIR_TYPE_K70_MK2)
|
||||
{
|
||||
new_led.name = led_names_k70_mk2[led_idx];
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "CorsairPeripheralV2Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
@@ -19,21 +22,24 @@ CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_han
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
device_name = name;
|
||||
device_index = CORSAIR_V2_DEVICE_NOT_FOUND;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get PID |
|
||||
| If the PID is in the know wireless receivers list |
|
||||
| switch the write_cmd to talk to the device and retry |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int pid = GetAddress(0x12);
|
||||
unsigned int pid = GetAddressRetry(0x12);
|
||||
|
||||
switch(pid)
|
||||
{
|
||||
case CORSAIR_SLIPSTREAM_WIRELESS_PID1:
|
||||
case CORSAIR_SLIPSTREAM_WIRELESS_V2_PID1:
|
||||
case CORSAIR_SLIPSTREAM_WIRELESS_PID2:
|
||||
case CORSAIR_SLIPSTREAM_M75_PID:
|
||||
case CORSAIR_SLIPSTREAM_IRONCLAW_SE_PID:
|
||||
write_cmd = CORSAIR_V2_WRITE_WIRELESS_ID;
|
||||
pid = GetAddress(0x12);
|
||||
pid = GetAddressRetry(0x12);
|
||||
break;
|
||||
|
||||
case CORSAIR_K57_RGB_WIRED_PID:
|
||||
@@ -88,10 +94,18 @@ CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_han
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Unknown PID |
|
||||
| Leave device_index at CORSAIR_V2_DEVICE_NOT_FOUND so |
|
||||
| GetDeviceData() returns nullptr and the detector drops |
|
||||
| the device, rather than building an RGBController on |
|
||||
| top of an out of range index. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(not_found)
|
||||
{
|
||||
LOG_ERROR("[%s] device capabilities not found. Please creata a new device request.",
|
||||
device_name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
@@ -119,9 +133,19 @@ CorsairPeripheralV2Controller::~CorsairPeripheralV2Controller()
|
||||
|
||||
const corsair_v2_device* CorsairPeripheralV2Controller::GetDeviceData()
|
||||
{
|
||||
if(!IsDeviceSupported())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return corsair_v2_device_list[device_index];
|
||||
}
|
||||
|
||||
bool CorsairPeripheralV2Controller::IsDeviceSupported()
|
||||
{
|
||||
return device_index < CORSAIR_V2_DEVICE_COUNT;
|
||||
}
|
||||
|
||||
std::string CorsairPeripheralV2Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
@@ -216,6 +240,34 @@ unsigned int CorsairPeripheralV2Controller::GetKeyboardLayout()
|
||||
return GetAddress(0x41);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| GetAddress returns NA when the device answers with a |
|
||||
| protocol error, and a receiver whose device has not |
|
||||
| woken answers zero. Straight after enumeration both |
|
||||
| are normal, so poll before treating either as final. |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int CorsairPeripheralV2Controller::GetAddressRetry(uint8_t address)
|
||||
{
|
||||
unsigned int value = NA;
|
||||
|
||||
for(unsigned int attempt = 0; attempt < CORSAIR_V2_PID_RETRIES; attempt++)
|
||||
{
|
||||
value = GetAddress(address);
|
||||
|
||||
if(value != NA && value != 0)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
if(attempt + 1 < CORSAIR_V2_PID_RETRIES)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(CORSAIR_V2_PID_RETRY_DELAY));
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
unsigned int CorsairPeripheralV2Controller::GetAddress(uint8_t address)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
|
||||
@@ -37,6 +37,19 @@
|
||||
#define CORSAIR_V2_BRIGHTNESS_MIN 0
|
||||
#define CORSAIR_V2_BRIGHTNESS_MAX 0xFF
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| A device that has just enumerated does not answer the PID |
|
||||
| query straight away, so retry before giving up on it. |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CORSAIR_V2_PID_RETRIES 8
|
||||
#define CORSAIR_V2_PID_RETRY_DELAY 120
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| device_index when the PID is not in the device list. |
|
||||
| Never index the device list with it. |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CORSAIR_V2_DEVICE_NOT_FOUND 0xFFFF
|
||||
|
||||
enum corsair_v2_cmd
|
||||
{
|
||||
CORSAIR_V2_CMD_SET = 0x01, /* Command for setting values */
|
||||
@@ -84,6 +97,7 @@ public:
|
||||
std::string GetName();
|
||||
std::string GetSerialString();
|
||||
const corsair_v2_device* GetDeviceData();
|
||||
bool IsDeviceSupported();
|
||||
unsigned int GetKeyboardLayout();
|
||||
|
||||
void SetRenderMode(corsair_v2_device_mode mode);
|
||||
@@ -102,6 +116,7 @@ protected:
|
||||
private:
|
||||
void ClearPacketBuffer();
|
||||
unsigned int GetAddress(uint8_t address);
|
||||
unsigned int GetAddressRetry(uint8_t address);
|
||||
unsigned char StartTransaction(uint8_t opt1);
|
||||
void StopTransaction(uint8_t opt1);
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
\*---------------------------------------------------------*/
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Corsair Peripheral specific includes |
|
||||
@@ -37,6 +38,20 @@ DetectedControllers DetectCorsairV2HardwareControllers(hid_device_info* info, co
|
||||
if(dev)
|
||||
{
|
||||
CorsairPeripheralV2HWController* controller = new CorsairPeripheralV2HWController(dev, info->path, name);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| A device whose PID is not in the device list has no |
|
||||
| zone or LED data to build an RGBController from. |
|
||||
| Drop it here: building one anyway indexes the device |
|
||||
| list with an index that was never set. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(!controller->IsDeviceSupported())
|
||||
{
|
||||
LOG_WARNING("[%s] not registering device, capabilities unknown.", name.c_str());
|
||||
delete controller;
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
RGBController_CorsairV2HW* rgb_controller = new RGBController_CorsairV2HW(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
@@ -55,6 +70,14 @@ DetectedControllers DetectCorsairV2SoftwareControllers(hid_device_info* info, co
|
||||
if(dev)
|
||||
{
|
||||
CorsairPeripheralV2SWController* controller = new CorsairPeripheralV2SWController(dev, info->path, name);
|
||||
|
||||
if(!controller->IsDeviceSupported())
|
||||
{
|
||||
LOG_WARNING("[%s] not registering device, capabilities unknown.", name.c_str());
|
||||
delete controller;
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
RGBController_CorsairV2SW* rgb_controller = new RGBController_CorsairV2SW(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
@@ -91,6 +114,8 @@ REGISTER_HID_DETECTOR_IP("Corsair Dark Core RGB SE (Wired)", DetectCorsai
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Dark Core RGB Pro SE (Wired)", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_DARK_CORE_RGB_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Harpoon Wireless (Wired)", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_HARPOON_WIRELESS_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Ironclaw Wireless (Wired)", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_IRONCLAW_WIRELESS_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Ironclaw Wireless SE (Wired)", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_IRONCLAW_WIRELESS_SE_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Ironclaw Wireless SE", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_SLIPSTREAM_IRONCLAW_SE_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Katar Pro", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_KATAR_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Katar Pro V2", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_KATAR_PRO_V2_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Katar Pro XT", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_KATAR_PRO_XT_PID, 1, 0xFF42);
|
||||
@@ -98,6 +123,8 @@ REGISTER_HID_DETECTOR_IP("Corsair M55 RGB PRO", DetectCorsai
|
||||
REGISTER_HID_DETECTOR_IP("Corsair M65 RGB Ultra Wired", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_M65_RGB_ULTRA_WIRED_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair M65 RGB Ultra Wireless (Wired)", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_M65_RGB_ULTRA_WIRELESS_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair M75 Gaming Mouse", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_M75_GAMING_MOUSE_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair M75 Wireless", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_SLIPSTREAM_M75_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair M75 Wireless (Wired)", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_M75_WIRELESS_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Slipstream Wireless Receiver HW", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_SLIPSTREAM_WIRELESS_PID1, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Slipstream Wireless Receiver SW", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_SLIPSTREAM_WIRELESS_PID2, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Slipstream Wireless Receiver HW", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_SLIPSTREAM_WIRELESS_V2_PID1, 1, 0xFF42);
|
||||
|
||||
@@ -638,6 +638,71 @@ static const corsair_v2_device ironclaw_wireless_device =
|
||||
nullptr
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Corsair Ironclaw Wireless SE 1B1C:2B32 |
|
||||
| |
|
||||
| Zone "Logo" |
|
||||
| Single |
|
||||
| |
|
||||
| Zone "Scroll Wheel" |
|
||||
| Single |
|
||||
| |
|
||||
| Zone "Buttons" |
|
||||
| Single |
|
||||
| |
|
||||
| Zone "Side" |
|
||||
| Linear |
|
||||
| 1 Row, 3 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone ironclaw_se_logo_zone =
|
||||
{
|
||||
"Logo",
|
||||
ZONE_TYPE_SINGLE,
|
||||
1,
|
||||
1
|
||||
};
|
||||
|
||||
static const corsair_v2_zone ironclaw_se_scroll_zone =
|
||||
{
|
||||
"Scroll Wheel",
|
||||
ZONE_TYPE_SINGLE,
|
||||
1,
|
||||
1
|
||||
};
|
||||
|
||||
static const corsair_v2_zone ironclaw_se_button_zone =
|
||||
{
|
||||
"Buttons",
|
||||
ZONE_TYPE_SINGLE,
|
||||
1,
|
||||
1
|
||||
};
|
||||
|
||||
static const corsair_v2_zone ironclaw_se_side_zone =
|
||||
{
|
||||
"Side Zone",
|
||||
ZONE_TYPE_LINEAR,
|
||||
1,
|
||||
3
|
||||
};
|
||||
|
||||
static const corsair_v2_device ironclaw_wireless_se_device =
|
||||
{
|
||||
CORSAIR_IRONCLAW_WIRELESS_SE_PID,
|
||||
DEVICE_TYPE_MOUSE,
|
||||
1,
|
||||
6,
|
||||
{
|
||||
&ironclaw_se_logo_zone,
|
||||
&ironclaw_se_scroll_zone,
|
||||
&ironclaw_se_button_zone,
|
||||
&ironclaw_se_side_zone,
|
||||
nullptr,
|
||||
nullptr
|
||||
},
|
||||
nullptr
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Corsair Katar Pro 1B1C:1B93 |
|
||||
| |
|
||||
@@ -1443,6 +1508,44 @@ static const corsair_v2_device m75_device =
|
||||
nullptr
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Corsair M75 Wireless 1B1C:1BF1 |
|
||||
| |
|
||||
| Reached through the Slipstream receiver 1B1C:1BDC, which |
|
||||
| reports the mouse PID 0x1BF1 once the write command is |
|
||||
| switched to the wireless ID. |
|
||||
| |
|
||||
| Zone "Logo" |
|
||||
| Single |
|
||||
| |
|
||||
| Zone "Bottom" |
|
||||
| Single |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone m75_wireless_bottom_zone =
|
||||
{
|
||||
"Bottom",
|
||||
ZONE_TYPE_SINGLE,
|
||||
1,
|
||||
1
|
||||
};
|
||||
|
||||
static const corsair_v2_device m75_wireless_device =
|
||||
{
|
||||
CORSAIR_M75_WIRELESS_PID,
|
||||
DEVICE_TYPE_MOUSE,
|
||||
1,
|
||||
2,
|
||||
{
|
||||
&m75_logo_zone,
|
||||
&m75_wireless_bottom_zone,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
},
|
||||
nullptr
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Corsair MM700 1B1C:1B9B |
|
||||
| |
|
||||
@@ -1543,6 +1646,7 @@ const corsair_v2_device* corsair_v2_device_list_data[] =
|
||||
&dark_core_pro_se_device,
|
||||
&harpoon_wireless_device,
|
||||
&ironclaw_wireless_device,
|
||||
&ironclaw_wireless_se_device,
|
||||
&katar_pro_device,
|
||||
&katar_pro_v2_device,
|
||||
&katar_pro_xt_device,
|
||||
@@ -1550,6 +1654,7 @@ const corsair_v2_device* corsair_v2_device_list_data[] =
|
||||
&m65_rgb_ultra_wired_device,
|
||||
&m65_ultra_rgb_device,
|
||||
&m75_device,
|
||||
&m75_wireless_device,
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| MOUSEMATS |
|
||||
|
||||
@@ -93,6 +93,8 @@ typedef struct
|
||||
#define CORSAIR_DARK_CORE_RGB_PRO_PID 0x1B7E
|
||||
#define CORSAIR_HARPOON_WIRELESS_PID 0x1B5E
|
||||
#define CORSAIR_IRONCLAW_WIRELESS_PID 0x1B4C
|
||||
#define CORSAIR_IRONCLAW_WIRELESS_SE_PID 0x2B32
|
||||
#define CORSAIR_SLIPSTREAM_IRONCLAW_SE_PID 0x2B00
|
||||
#define CORSAIR_KATAR_PRO_PID 0x1B93
|
||||
#define CORSAIR_KATAR_PRO_V2_PID 0x1BBA
|
||||
#define CORSAIR_KATAR_PRO_XT_PID 0x1BAC
|
||||
@@ -100,6 +102,8 @@ typedef struct
|
||||
#define CORSAIR_M65_RGB_ULTRA_WIRED_PID 0x1B9E
|
||||
#define CORSAIR_M65_RGB_ULTRA_WIRELESS_PID 0x1BB5
|
||||
#define CORSAIR_M75_GAMING_MOUSE_PID 0x1BF0
|
||||
#define CORSAIR_M75_WIRELESS_PID 0x1BF1
|
||||
#define CORSAIR_SLIPSTREAM_M75_PID 0x1BDC
|
||||
#define CORSAIR_SLIPSTREAM_WIRELESS_PID1 0x1BA6
|
||||
#define CORSAIR_SLIPSTREAM_WIRELESS_V2_PID1 0x1B66
|
||||
#define CORSAIR_SLIPSTREAM_WIRELESS_PID2 0x1B65
|
||||
|
||||
-3
@@ -16,13 +16,10 @@ DetectedControllers DetectCreativeAE5Device()
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
|
||||
LOG_INFO("[Creative SoundBlaster AE-5] Windows detection function called");
|
||||
|
||||
CreativeSoundBlasterAE5Controller_Windows* controller = new CreativeSoundBlasterAE5Controller_Windows();
|
||||
|
||||
if(controller->Initialize())
|
||||
{
|
||||
LOG_INFO("[Creative SoundBlaster AE-5] Device initialized successfully, registering controller");
|
||||
RGBController_CreativeSoundBlasterAE5* rgb_controller = new RGBController_CreativeSoundBlasterAE5(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
+10
-10
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CreativeControllerDetect.cpp |
|
||||
| CreativeSoundBlasterXG6ControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Creative devices |
|
||||
| Detector for Creative Sound Blaster XG6 devices |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -15,14 +15,14 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| Creative vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CREATIVE_VID 0x041E
|
||||
#define CREATIVE_VID 0x041E
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| SoundCards |
|
||||
| Creative Sound Blaster XG6 product ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CREATIVE_SOUNDBLASTERX_G6_PID 0x3256
|
||||
#define CREATIVE_SOUNDBLASTERX_G6_PID 0x3256
|
||||
|
||||
DetectedControllers DetectCreativeDevice(hid_device_info* info, const std::string& name)
|
||||
DetectedControllers DetectCreativeSoundBlasterXG6Device(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
@@ -40,7 +40,7 @@ DetectedControllers DetectCreativeDevice(hid_device_info* info, const std::strin
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Sound Cards |
|
||||
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_I("Creative SoundBlasterX G6", DetectCreativeDevice, CREATIVE_VID, CREATIVE_SOUNDBLASTERX_G6_PID, 4);
|
||||
/*---------------------------------------------------------*\
|
||||
| Sound Cards |
|
||||
\*---------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_I("Creative SoundBlasterX G6", DetectCreativeSoundBlasterXG6Device, CREATIVE_VID, CREATIVE_SOUNDBLASTERX_G6_PID, 4);
|
||||
@@ -59,15 +59,57 @@ RGBController_DDP::~RGBController_DDP()
|
||||
|
||||
void RGBController_DDP::SetupZones()
|
||||
{
|
||||
for(unsigned int zone_idx = 0; zone_idx < devices.size(); zone_idx++)
|
||||
/*-----------------------------------------------------*\
|
||||
| Only set LED count on the first run |
|
||||
\------------------------------------------------------*/
|
||||
bool first_run = false;
|
||||
|
||||
if(zones.size() == 0)
|
||||
{
|
||||
zone led_zone;
|
||||
led_zone.name = devices[zone_idx].name;
|
||||
led_zone.type = ZONE_TYPE_LINEAR;
|
||||
led_zone.leds_min = devices[zone_idx].num_leds;
|
||||
led_zone.leds_max = devices[zone_idx].num_leds;
|
||||
led_zone.leds_count = devices[zone_idx].num_leds;
|
||||
zones.push_back(led_zone);
|
||||
first_run = true;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Clear any existing color/LED configuration |
|
||||
\------------------------------------------------------*/
|
||||
leds.clear();
|
||||
colors.clear();
|
||||
zones.resize(devices.size());
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set zones and leds |
|
||||
\------------------------------------------------------*/
|
||||
for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
zones[zone_idx].leds_min = devices[zone_idx].num_leds;
|
||||
zones[zone_idx].leds_max = devices[zone_idx].num_leds;
|
||||
|
||||
if(first_run)
|
||||
{
|
||||
zones[zone_idx].flags = ZONE_FLAG_MANUALLY_CONFIGURABLE_NAME
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_TYPE
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_MATRIX_MAP
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_SEGMENTS;
|
||||
}
|
||||
|
||||
if(!(zones[zone_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_NAME))
|
||||
{
|
||||
zones[zone_idx].name = devices[zone_idx].name;
|
||||
}
|
||||
|
||||
zones[zone_idx].leds_count = devices[zone_idx].num_leds;
|
||||
|
||||
if(!(zones[zone_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_TYPE))
|
||||
{
|
||||
zones[zone_idx].type = ZONE_TYPE_LINEAR;
|
||||
}
|
||||
|
||||
if(!(zones[zone_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_MATRIX_MAP))
|
||||
{
|
||||
zones[zone_idx].matrix_map.width = 0;
|
||||
zones[zone_idx].matrix_map.height = 0;
|
||||
zones[zone_idx].matrix_map.map.resize(0);
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned int zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
@@ -75,14 +117,22 @@ void RGBController_DDP::SetupZones()
|
||||
for(unsigned int led_idx = 0; led_idx < zones[zone_idx].leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = zones[zone_idx].name + " LED " + std::to_string(led_idx + 1);
|
||||
new_led.value = 0;
|
||||
new_led.name = zones[zone_idx].name + " LED " + std::to_string(led_idx + 1);
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_DDP::DeviceConfigureZone(int zone_idx)
|
||||
{
|
||||
if((size_t)zone_idx < zones.size())
|
||||
{
|
||||
SetupZones();
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_DDP::DeviceUpdateLEDs()
|
||||
{
|
||||
std::vector<unsigned int> brightness_adjusted_colors;
|
||||
|
||||
@@ -21,6 +21,8 @@ public:
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceConfigureZone(int zone_idx);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
@@ -40,8 +40,4 @@ DetectedControllers DetectDygmaRaiseControllers()
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("Dygma Raise", DetectDygmaRaiseControllers);
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Entries for dynamic UDEV rules |
|
||||
| |
|
||||
| DUMMY_DEVICE_DETECTOR("Dygma Raise", DetectDygmaRaiseControllers, 0x1209, 0x2201 ) |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_CUSTOM_UDEV_RULE(dygma_raise, "Dygma Raise", "SUBSYSTEMS==\"serial|hidraw\", ATTRS{idVendor}==\"1209\", ATTRS{idProduct}==\"2201\", TAG+=\"uaccess\", TAG+=\"Dygma_Raise\"");
|
||||
|
||||
@@ -223,33 +223,68 @@ RGBController_E131::~RGBController_E131()
|
||||
void RGBController_E131::SetupZones()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Add Zones |
|
||||
| Only set LED count on the first run |
|
||||
\*-----------------------------------------------------*/
|
||||
for(std::size_t zone_idx = 0; zone_idx < devices.size(); zone_idx++)
|
||||
{
|
||||
zone led_zone;
|
||||
led_zone.name = devices[zone_idx].name;
|
||||
led_zone.type = ZONE_TYPE_LINEAR;
|
||||
led_zone.leds_min = devices[zone_idx].num_leds;
|
||||
led_zone.leds_max = devices[zone_idx].num_leds;
|
||||
led_zone.leds_count = devices[zone_idx].num_leds;
|
||||
led_zone.flags = ZONE_FLAG_MANUALLY_CONFIGURABLE_TYPE
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_MATRIX_MAP
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_SEGMENTS;
|
||||
bool first_run = false;
|
||||
|
||||
zones.push_back(led_zone);
|
||||
if(zones.size() == 0)
|
||||
{
|
||||
first_run = true;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Add LEDs |
|
||||
| Clear any existing color/LED configuration |
|
||||
\*-----------------------------------------------------*/
|
||||
leds.clear();
|
||||
colors.clear();
|
||||
zones.resize(devices.size());
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set zones and leds |
|
||||
\*-----------------------------------------------------*/
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
zones[zone_idx].leds_min = devices[zone_idx].num_leds;
|
||||
zones[zone_idx].leds_max = devices[zone_idx].num_leds;
|
||||
|
||||
if(first_run)
|
||||
{
|
||||
zones[zone_idx].flags = ZONE_FLAG_MANUALLY_CONFIGURABLE_NAME
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_TYPE
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_MATRIX_MAP
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_SEGMENTS;
|
||||
}
|
||||
|
||||
if(!(zones[zone_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_NAME))
|
||||
{
|
||||
zones[zone_idx].name = devices[zone_idx].name;
|
||||
}
|
||||
|
||||
zones[zone_idx].leds_count = devices[zone_idx].num_leds;
|
||||
|
||||
if(!(zones[zone_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_TYPE))
|
||||
{
|
||||
zones[zone_idx].type = ZONE_TYPE_LINEAR;
|
||||
}
|
||||
|
||||
if(!(zones[zone_idx].flags & ZONE_FLAG_MANUALLY_CONFIGURED_MATRIX_MAP))
|
||||
{
|
||||
zones[zone_idx].matrix_map.width = 0;
|
||||
zones[zone_idx].matrix_map.height = 0;
|
||||
zones[zone_idx].matrix_map.map.resize(0);
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Add LEDs |
|
||||
\*-----------------------------------------------------*/
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
for(std::size_t led_idx = 0; led_idx < zones[zone_idx].leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
|
||||
new_led.name = zones[zone_idx].name + " LED ";
|
||||
new_led.name = zones[zone_idx].name + " LED ";
|
||||
new_led.name.append(std::to_string(led_idx));
|
||||
|
||||
leds.push_back(new_led);
|
||||
@@ -259,6 +294,14 @@ void RGBController_E131::SetupZones()
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_E131::DeviceConfigureZone(int zone_idx)
|
||||
{
|
||||
if((size_t)zone_idx < zones.size())
|
||||
{
|
||||
SetupZones();
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_E131::DeviceUpdateLEDs()
|
||||
{
|
||||
int color_idx = 0;
|
||||
|
||||
@@ -35,6 +35,8 @@ public:
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceConfigureZone(int zone_idx);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
@@ -411,6 +411,7 @@ REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming White OC",
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG STRIX GeForce RTX 4090 Gaming White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_STRIX_RTX_4090_O24G_GAMING_WHITE_2, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG MATRIX PLATINUM GeForce RTX 4090", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, ASUS_SUB_VEN, ASUS_ROG_MATRIX_PLATINUM_RTX_4090_24G, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5060 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5060_O8G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5060 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5060TI_O16G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070_O12G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Ti Gaming OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070TI_O16G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS TUF GeForce RTX 5070 Ti Gaming BTF White OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, ASUS_SUB_VEN, ASUS_TUF_RTX_5070TI_O16G_GAMING_BTF_WHITE, 0x67);
|
||||
@@ -426,6 +427,7 @@ REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5080 WHITE",
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5090 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5090_O32G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5090", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5090_O32G_GAMING_2, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5090 OC BTF", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5090_O32G_GAMING_BTF, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5090 OC BTF", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5090_O32G_GAMING_BTF_2, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL GeForce RTX 5090 OC WHITE", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_RTX_5090_O32G_GAMING_WHITE, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL LC GeForce RTX 5090 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_LC_RTX_5090_O32G_GAMING, 0x67);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASUS ROG ASTRAL LC OC GeForce RTX 5090 OC", DetectENESMBusGPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, ASUS_SUB_VEN, ASUS_ROG_ASTRAL_LC_OC_RTX_5090_O32G_GAMING, 0x67);
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EVGAX12Controller.cpp |
|
||||
| |
|
||||
| Driver for the EVGA X12 gaming mouse |
|
||||
| |
|
||||
| QuickMythril 08 Aug 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
#include "EVGAX12Controller.h"
|
||||
#include "LogManager.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
#define EVGA_X12_HEADER 0xEA
|
||||
#define EVGA_X12_DIRECTION_GET 0x01
|
||||
#define EVGA_X12_DIRECTION_SET 0x02
|
||||
#define EVGA_X12_COMMAND_MODE 0x01
|
||||
#define EVGA_X12_COMMAND_STATIC 0x02
|
||||
#define EVGA_X12_START_WITH_PROFILE 0x01
|
||||
#define EVGA_X12_READ_ATTEMPTS 5
|
||||
#define EVGA_X12_READ_DELAY_MS 5
|
||||
#define EVGA_X12_WRITE_ATTEMPTS 3
|
||||
|
||||
EVGAX12Controller::EVGAX12Controller(hid_device* dev_handle, const hid_device_info& info, const std::string& dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = info.path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
EVGAX12Controller::~EVGAX12Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string EVGAX12Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string EVGAX12Controller::GetNameString()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
std::string EVGAX12Controller::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
EVGAX12LightingState EVGAX12Controller::GetLightingState()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(device_mutex);
|
||||
EVGAX12LightingState state = {};
|
||||
unsigned char packet[EVGA_X12_REPORT_SIZE];
|
||||
|
||||
state.modes_valid = GetReport(EVGA_X12_COMMAND_MODE, packet);
|
||||
|
||||
if(state.modes_valid)
|
||||
{
|
||||
for(unsigned int led_idx = 0; led_idx < EVGA_X12_LED_COUNT; led_idx++)
|
||||
{
|
||||
state.modes[led_idx] = packet[4 + led_idx];
|
||||
}
|
||||
}
|
||||
|
||||
state.static_valid = GetReport(EVGA_X12_COMMAND_STATIC, packet);
|
||||
|
||||
if(state.static_valid)
|
||||
{
|
||||
for(unsigned int led_idx = 0; led_idx < EVGA_X12_LED_COUNT; led_idx++)
|
||||
{
|
||||
unsigned int offset = 4 + (led_idx * 4);
|
||||
state.brightness[led_idx] = packet[offset];
|
||||
state.colors[led_idx] = ToRGBColor(packet[offset + 1], packet[offset + 2], packet[offset + 3]);
|
||||
}
|
||||
}
|
||||
|
||||
return(state);
|
||||
}
|
||||
|
||||
bool EVGAX12Controller::SetMode(unsigned char mode)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(device_mutex);
|
||||
return(SetModeReport(mode));
|
||||
}
|
||||
|
||||
bool EVGAX12Controller::SetModeReport(unsigned char mode)
|
||||
{
|
||||
unsigned char packet[EVGA_X12_REPORT_SIZE] = {};
|
||||
|
||||
packet[0] = EVGA_X12_REPORT_ID;
|
||||
packet[1] = EVGA_X12_HEADER;
|
||||
packet[2] = EVGA_X12_DIRECTION_SET;
|
||||
packet[3] = EVGA_X12_COMMAND_MODE;
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < EVGA_X12_LED_COUNT; led_idx++)
|
||||
{
|
||||
packet[4 + led_idx] = mode;
|
||||
}
|
||||
|
||||
return(SendReport(packet));
|
||||
}
|
||||
|
||||
bool EVGAX12Controller::SetStatic(const std::vector<RGBColor>& colors, unsigned char brightness)
|
||||
{
|
||||
if(colors.size() < EVGA_X12_LED_COUNT)
|
||||
{
|
||||
LOG_ERROR("[%s] Cannot set static lighting with only %u colors", name.c_str(), (unsigned int)colors.size());
|
||||
return(false);
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(device_mutex);
|
||||
return(SetStaticReport(colors, brightness));
|
||||
}
|
||||
|
||||
bool EVGAX12Controller::SetStaticAndActivate(const std::vector<RGBColor>& colors, unsigned char brightness)
|
||||
{
|
||||
if(colors.size() < EVGA_X12_LED_COUNT)
|
||||
{
|
||||
LOG_ERROR("[%s] Cannot set static lighting with only %u colors", name.c_str(), (unsigned int)colors.size());
|
||||
return(false);
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(device_mutex);
|
||||
|
||||
if(!SetStaticReport(colors, brightness))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(EVGA_X12_READ_DELAY_MS));
|
||||
return(SetModeReport(EVGA_X12_MODE_STATIC));
|
||||
}
|
||||
|
||||
bool EVGAX12Controller::SetStaticReport(const std::vector<RGBColor>& colors, unsigned char brightness)
|
||||
{
|
||||
unsigned char packet[EVGA_X12_REPORT_SIZE] = {};
|
||||
|
||||
packet[0] = EVGA_X12_REPORT_ID;
|
||||
packet[1] = EVGA_X12_HEADER;
|
||||
packet[2] = EVGA_X12_DIRECTION_SET;
|
||||
packet[3] = EVGA_X12_COMMAND_STATIC;
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < EVGA_X12_LED_COUNT; led_idx++)
|
||||
{
|
||||
unsigned int offset = 4 + (led_idx * 4);
|
||||
packet[offset] = brightness;
|
||||
packet[offset + 1] = RGBGetRValue(colors[led_idx]);
|
||||
packet[offset + 2] = RGBGetGValue(colors[led_idx]);
|
||||
packet[offset + 3] = RGBGetBValue(colors[led_idx]);
|
||||
packet[20 + led_idx] = EVGA_X12_START_WITH_PROFILE;
|
||||
}
|
||||
|
||||
for(unsigned int attempt = 0; attempt < EVGA_X12_WRITE_ATTEMPTS; attempt++)
|
||||
{
|
||||
if(!SendReport(packet))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(EVGA_X12_READ_DELAY_MS));
|
||||
|
||||
unsigned char reply[EVGA_X12_REPORT_SIZE];
|
||||
|
||||
if(GetReport(EVGA_X12_COMMAND_STATIC, reply))
|
||||
{
|
||||
bool matches = true;
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < EVGA_X12_LED_COUNT; led_idx++)
|
||||
{
|
||||
unsigned int offset = 4 + (led_idx * 4);
|
||||
|
||||
if(std::memcmp(&packet[offset], &reply[offset], 4) != 0)
|
||||
{
|
||||
matches = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(matches)
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_VERBOSE("[%s] Retries exhausted setting static lighting", name.c_str());
|
||||
return(false);
|
||||
}
|
||||
|
||||
bool EVGAX12Controller::GetReport(unsigned char command, unsigned char* packet)
|
||||
{
|
||||
std::memset(packet, 0, EVGA_X12_REPORT_SIZE);
|
||||
packet[0] = EVGA_X12_REPORT_ID;
|
||||
packet[1] = EVGA_X12_HEADER;
|
||||
packet[2] = EVGA_X12_DIRECTION_GET;
|
||||
packet[3] = command;
|
||||
|
||||
if(!SendReport(packet))
|
||||
{
|
||||
return(false);
|
||||
}
|
||||
|
||||
for(unsigned int attempt = 0; attempt < EVGA_X12_READ_ATTEMPTS; attempt++)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(EVGA_X12_READ_DELAY_MS));
|
||||
std::memset(packet, 0, EVGA_X12_REPORT_SIZE);
|
||||
packet[0] = EVGA_X12_REPORT_ID;
|
||||
|
||||
int bytes_read = hid_get_feature_report(dev, packet, EVGA_X12_REPORT_SIZE);
|
||||
|
||||
if(bytes_read == EVGA_X12_REPORT_SIZE && packet[1] == EVGA_X12_HEADER && packet[3] == command)
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
|
||||
if(bytes_read < 0)
|
||||
{
|
||||
LOG_DEBUG("[%s] Error reading feature report: %ls", name.c_str(), hid_error(dev));
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
LOG_VERBOSE("[%s] Retries exhausted reading command 0x%02X", name.c_str(), command);
|
||||
return(false);
|
||||
}
|
||||
|
||||
bool EVGAX12Controller::SendReport(const unsigned char* packet)
|
||||
{
|
||||
int bytes_written = hid_send_feature_report(dev, packet, EVGA_X12_REPORT_SIZE);
|
||||
|
||||
if(bytes_written != EVGA_X12_REPORT_SIZE)
|
||||
{
|
||||
LOG_DEBUG("[%s] Error writing feature report: %ls", name.c_str(), hid_error(dev));
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EVGAX12Controller.h |
|
||||
| |
|
||||
| Driver for the EVGA X12 gaming mouse |
|
||||
| |
|
||||
| QuickMythril 08 Aug 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define EVGA_X12_REPORT_ID 0x07
|
||||
#define EVGA_X12_REPORT_SIZE 40
|
||||
#define EVGA_X12_LED_COUNT 4
|
||||
#define EVGA_X12_BRIGHTNESS_MIN 0
|
||||
#define EVGA_X12_BRIGHTNESS_MAX 255
|
||||
|
||||
enum
|
||||
{
|
||||
EVGA_X12_MODE_OFF = 0,
|
||||
EVGA_X12_MODE_STATIC = 1,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EVGA_X12_LED_HEAD_LEFT = 0,
|
||||
EVGA_X12_LED_HEAD_RIGHT = 1,
|
||||
EVGA_X12_LED_WHEEL = 2,
|
||||
EVGA_X12_LED_LOGO = 3,
|
||||
};
|
||||
|
||||
struct EVGAX12LightingState
|
||||
{
|
||||
std::array<unsigned char, EVGA_X12_LED_COUNT> modes;
|
||||
std::array<unsigned char, EVGA_X12_LED_COUNT> brightness;
|
||||
std::array<RGBColor, EVGA_X12_LED_COUNT> colors;
|
||||
bool modes_valid;
|
||||
bool static_valid;
|
||||
};
|
||||
|
||||
class EVGAX12Controller
|
||||
{
|
||||
public:
|
||||
EVGAX12Controller(hid_device* dev_handle, const hid_device_info& info, const std::string& dev_name);
|
||||
~EVGAX12Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetNameString();
|
||||
std::string GetSerialString();
|
||||
|
||||
EVGAX12LightingState GetLightingState();
|
||||
bool SetMode(unsigned char mode);
|
||||
bool SetStatic(const std::vector<RGBColor>& colors, unsigned char brightness);
|
||||
bool SetStaticAndActivate(const std::vector<RGBColor>& colors, unsigned char brightness);
|
||||
|
||||
private:
|
||||
bool GetReport(unsigned char command, unsigned char* packet);
|
||||
bool SetModeReport(unsigned char mode);
|
||||
bool SetStaticReport(const std::vector<RGBColor>& colors, unsigned char brightness);
|
||||
bool SendReport(const unsigned char* packet);
|
||||
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
std::mutex device_mutex;
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EVGAX12ControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for the EVGA X12 gaming mouse |
|
||||
| |
|
||||
| QuickMythril 08 Aug 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "DetectionManager.h"
|
||||
#include "EVGAX12Controller.h"
|
||||
#include "RGBController_EVGAX12.h"
|
||||
|
||||
#define EVGA_USB_VID 0x3842
|
||||
#define EVGA_X12_PID 0x2422
|
||||
#define EVGA_X12_INTERFACE 1
|
||||
#define EVGA_X12_USAGE_PAGE 0x0008
|
||||
#define EVGA_X12_USAGE 0x004B
|
||||
|
||||
DetectedControllers DetectEVGAX12(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EVGAX12Controller* controller = new EVGAX12Controller(dev, *info, name);
|
||||
RGBController_EVGAX12* rgb_controller = new RGBController_EVGAX12(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("EVGA X12 Gaming Mouse", DetectEVGAX12, EVGA_USB_VID, EVGA_X12_PID, EVGA_X12_INTERFACE, EVGA_X12_USAGE_PAGE, EVGA_X12_USAGE);
|
||||
@@ -0,0 +1,151 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_EVGAX12.cpp |
|
||||
| |
|
||||
| RGBController for the EVGA X12 gaming mouse |
|
||||
| |
|
||||
| QuickMythril 08 Aug 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_EVGAX12.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name EVGA X12 Gaming Mouse
|
||||
@category Mouse
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectEVGAX12
|
||||
@comment Lighting changes are volatile and revert to the onboard
|
||||
profile when the mouse is reconnected.
|
||||
\*-------------------------------------------------------------------*/
|
||||
RGBController_EVGAX12::RGBController_EVGAX12(EVGAX12Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetNameString();
|
||||
vendor = "EVGA";
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
description = "EVGA X12 Gaming Mouse";
|
||||
serial = controller->GetSerialString();
|
||||
location = controller->GetDeviceLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = EVGA_X12_MODE_STATIC;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Direct.brightness_min = EVGA_X12_BRIGHTNESS_MIN;
|
||||
Direct.brightness_max = EVGA_X12_BRIGHTNESS_MAX;
|
||||
Direct.brightness = EVGA_X12_BRIGHTNESS_MAX;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
direct_mode_index = modes.size();
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
Off.value = EVGA_X12_MODE_OFF;
|
||||
Off.color_mode = MODE_COLORS_NONE;
|
||||
off_mode_index = modes.size();
|
||||
modes.push_back(Off);
|
||||
|
||||
active_mode = direct_mode_index;
|
||||
|
||||
SetupZones();
|
||||
|
||||
EVGAX12LightingState current_state = controller->GetLightingState();
|
||||
|
||||
if(current_state.static_valid)
|
||||
{
|
||||
modes[direct_mode_index].brightness = current_state.brightness[0];
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < EVGA_X12_LED_COUNT; led_idx++)
|
||||
{
|
||||
colors[led_idx] = current_state.colors[led_idx];
|
||||
}
|
||||
}
|
||||
|
||||
if(current_state.modes_valid)
|
||||
{
|
||||
bool all_off = true;
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < EVGA_X12_LED_COUNT; led_idx++)
|
||||
{
|
||||
if(current_state.modes[led_idx] != EVGA_X12_MODE_OFF)
|
||||
{
|
||||
all_off = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(all_off)
|
||||
{
|
||||
active_mode = off_mode_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RGBController_EVGAX12::~RGBController_EVGAX12()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_EVGAX12::SetupZones()
|
||||
{
|
||||
const char* zone_names[EVGA_X12_LED_COUNT] =
|
||||
{
|
||||
"Left Head",
|
||||
"Right Head",
|
||||
"Scroll Wheel",
|
||||
"Logo",
|
||||
};
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < EVGA_X12_LED_COUNT; led_idx++)
|
||||
{
|
||||
zone new_zone;
|
||||
new_zone.name = zone_names[led_idx];
|
||||
new_zone.type = ZONE_TYPE_SINGLE;
|
||||
new_zone.leds_min = 1;
|
||||
new_zone.leds_max = 1;
|
||||
new_zone.leds_count = 1;
|
||||
zones.push_back(new_zone);
|
||||
|
||||
led new_led;
|
||||
new_led.name = std::string(zone_names[led_idx]) + " LED";
|
||||
new_led.value = led_idx;
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_EVGAX12::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetStatic(colors, modes[direct_mode_index].brightness);
|
||||
}
|
||||
|
||||
void RGBController_EVGAX12::DeviceUpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_EVGAX12::DeviceUpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_EVGAX12::DeviceUpdateMode()
|
||||
{
|
||||
if(modes[active_mode].value == EVGA_X12_MODE_OFF)
|
||||
{
|
||||
controller->SetMode(EVGA_X12_MODE_OFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetStaticAndActivate(colors, modes[direct_mode_index].brightness);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_EVGAX12.h |
|
||||
| |
|
||||
| RGBController for the EVGA X12 gaming mouse |
|
||||
| |
|
||||
| QuickMythril 08 Aug 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "EVGAX12Controller.h"
|
||||
#include "RGBController.h"
|
||||
|
||||
class RGBController_EVGAX12 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_EVGAX12(EVGAX12Controller* controller_ptr);
|
||||
~RGBController_EVGAX12();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
void SetupZones();
|
||||
|
||||
EVGAX12Controller* controller;
|
||||
unsigned int direct_mode_index;
|
||||
unsigned int off_mode_index;
|
||||
};
|
||||
@@ -0,0 +1,205 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EdifierHaloController.cpp |
|
||||
| |
|
||||
| Driver for Edifier Halo series USB/HID devices |
|
||||
| |
|
||||
| Bartholomew Ho <qiangqiang101@hotmail.com> 20 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "LogManager.h"
|
||||
#include "EdifierHaloController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
EdifierHaloController::EdifierHaloController(hid_device* dev_handle, const char* path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
|
||||
wchar_t name_string[256];
|
||||
int result;
|
||||
|
||||
result = hid_get_manufacturer_string(dev, name_string, 256);
|
||||
if(result == 0)
|
||||
{
|
||||
device_name = StringUtils::wstring_to_string(name_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
device_name = "Edifier";
|
||||
LOG_WARNING("[EdifierHaloController] Failed to read manufacturer string for %s", path);
|
||||
}
|
||||
|
||||
result = hid_get_product_string(dev, name_string, 256);
|
||||
if(result == 0)
|
||||
{
|
||||
device_name.append(" ").append(StringUtils::wstring_to_string(name_string));
|
||||
}
|
||||
else
|
||||
{
|
||||
device_name.append(" Halo PixelBar");
|
||||
LOG_WARNING("[EdifierHaloController] Failed to read product string for %s", path);
|
||||
}
|
||||
|
||||
wchar_t serial_string[128];
|
||||
result = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
if(result == 0)
|
||||
{
|
||||
serial = StringUtils::wstring_to_string(serial_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
serial = "";
|
||||
LOG_DEBUG("[EdifierHaloController] No serial number available for %s", path);
|
||||
}
|
||||
}
|
||||
|
||||
EdifierHaloController::~EdifierHaloController()
|
||||
{
|
||||
if(dev)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
}
|
||||
|
||||
std::string EdifierHaloController::GetDeviceName() const
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string EdifierHaloController::GetSerial() const
|
||||
{
|
||||
return(serial);
|
||||
}
|
||||
|
||||
std::string EdifierHaloController::GetLocation() const
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
void EdifierHaloController::SetAmbientLightPower(bool enabled)
|
||||
{
|
||||
unsigned char mode = enabled ? 0x01 : 0x00;
|
||||
unsigned char payload[] =
|
||||
{
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
mode,
|
||||
0xFF,
|
||||
0xFF
|
||||
};
|
||||
SendEdifierPacket(0x6b, payload, sizeof(payload));
|
||||
}
|
||||
|
||||
void EdifierHaloController::SetAmbientLight(unsigned char effect, unsigned char r, unsigned char g, unsigned char b, unsigned char brightness, unsigned char speed)
|
||||
{
|
||||
unsigned char raw_brightness = 0x3c;
|
||||
if (brightness == 1) raw_brightness = 0x14;
|
||||
else if (brightness == 2) raw_brightness = 0x28;
|
||||
else if (brightness == 3) raw_brightness = 0x3c;
|
||||
|
||||
if (speed < 1) speed = 1;
|
||||
if (speed > 10) speed = 10;
|
||||
|
||||
unsigned char payload[] =
|
||||
{
|
||||
0x13,
|
||||
effect,
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
raw_brightness,
|
||||
speed
|
||||
};
|
||||
SendEdifierPacket(0x6b, payload, sizeof(payload));
|
||||
}
|
||||
|
||||
void EdifierHaloController::SetPixelScreenColor(unsigned char r, unsigned char g, unsigned char b)
|
||||
{
|
||||
unsigned char payload[] =
|
||||
{
|
||||
0x03,
|
||||
r,
|
||||
g,
|
||||
b
|
||||
};
|
||||
SendEdifierPacket(0xef, payload, sizeof(payload));
|
||||
}
|
||||
|
||||
void EdifierHaloController::SetScreenUIModel(unsigned char model_id, unsigned char r, unsigned char g, unsigned char b)
|
||||
{
|
||||
unsigned char payload[] =
|
||||
{
|
||||
0x02,
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
0x00,
|
||||
0x01,
|
||||
model_id,
|
||||
0xff,
|
||||
0xff
|
||||
};
|
||||
SendEdifierPacket(0xef, payload, sizeof(payload));
|
||||
}
|
||||
|
||||
void EdifierHaloController::SetScreenScene(unsigned char category, unsigned char index, unsigned char r, unsigned char g, unsigned char b)
|
||||
{
|
||||
unsigned char payload[] =
|
||||
{
|
||||
0x01, // group
|
||||
r,
|
||||
g,
|
||||
b,
|
||||
0x00,
|
||||
0x01,
|
||||
category,
|
||||
index,
|
||||
0xff // option
|
||||
};
|
||||
SendEdifierPacket(0xef, payload, sizeof(payload));
|
||||
}
|
||||
|
||||
void EdifierHaloController::SendEdifierPacket(unsigned char commandIndex, const unsigned char* payload, unsigned int payload_size)
|
||||
{
|
||||
if(!dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char packet[64];
|
||||
memset(packet, 0x00, sizeof(packet));
|
||||
|
||||
packet[0] = 0x2e;
|
||||
packet[1] = 0xaa;
|
||||
packet[2] = 0xec;
|
||||
packet[3] = commandIndex;
|
||||
packet[4] = (unsigned char)((payload_size >> 8) & 0xff);
|
||||
packet[5] = (unsigned char)(payload_size & 0xff);
|
||||
|
||||
if(payload_size > 0 && payload != nullptr)
|
||||
{
|
||||
memcpy(&packet[6], payload, payload_size);
|
||||
}
|
||||
|
||||
// Calculate checksum
|
||||
unsigned int sum = 0;
|
||||
for(unsigned int i = 1; i < 6 + payload_size; i++)
|
||||
{
|
||||
sum += packet[i];
|
||||
}
|
||||
packet[6 + payload_size] = (unsigned char)(sum & 0xff);
|
||||
|
||||
std::lock_guard<std::mutex> guard(device_mutex);
|
||||
int bytes_written = hid_write(dev, packet, sizeof(packet));
|
||||
if(bytes_written != sizeof(packet))
|
||||
{
|
||||
LOG_ERROR("[EdifierHaloController] Failed to write HID packet (%d/%d bytes): %ls",
|
||||
bytes_written, (int)sizeof(packet), hid_error(dev));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EdifierHaloController.h |
|
||||
| |
|
||||
| Driver for Edifier Halo series USB/HID devices |
|
||||
| |
|
||||
| Bartholomew Ho <qiangqiang101@hotmail.com> 20 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
|
||||
enum
|
||||
{
|
||||
EDIFIER_HALO_AMBIENT_MODE_BREATHING = 1, // Breathing
|
||||
EDIFIER_HALO_AMBIENT_MODE_TIDE = 2, // Rainbow
|
||||
EDIFIER_HALO_AMBIENT_MODE_STATIC = 3, // Static
|
||||
EDIFIER_HALO_AMBIENT_MODE_RIPPLE = 4, // Glittering and colorful
|
||||
EDIFIER_HALO_AMBIENT_MODE_FLOW = 5, // Light-flow
|
||||
EDIFIER_HALO_AMBIENT_MODE_DYNAMIC = 6 // Dynamic Shadows
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EDIFIER_HALO_AMBIENT_SPEED_SLOWEST = 1,
|
||||
EDIFIER_HALO_AMBIENT_SPEED_FASTEST = 10
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
EDIFIER_HALO_AMBIENT_BRIGHTNESS_LOWEST = 1,
|
||||
EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST = 3
|
||||
};
|
||||
|
||||
class EdifierHaloController
|
||||
{
|
||||
public:
|
||||
EdifierHaloController(hid_device* dev_handle, const char* path);
|
||||
~EdifierHaloController();
|
||||
|
||||
std::string GetDeviceName() const;
|
||||
std::string GetSerial() const;
|
||||
std::string GetLocation() const;
|
||||
|
||||
void SetAmbientLight(unsigned char effect, unsigned char r, unsigned char g, unsigned char b, unsigned char brightness, unsigned char speed);
|
||||
void SetAmbientLightPower(bool enabled);
|
||||
void SetPixelScreenColor(unsigned char r, unsigned char g, unsigned char b);
|
||||
void SetScreenUIModel(unsigned char model_id, unsigned char r, unsigned char g, unsigned char b);
|
||||
void SetScreenScene(unsigned char category, unsigned char index, unsigned char r, unsigned char g, unsigned char b);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string device_name;
|
||||
std::string serial;
|
||||
std::string location;
|
||||
std::mutex device_mutex;
|
||||
|
||||
void SendEdifierPacket(unsigned char commandIndex, const unsigned char* payload, unsigned int payload_size);
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EdifierHaloControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Edifier Halo PixelBar USB/HID devices |
|
||||
| |
|
||||
| Bartholomew Ho <qiangqiang101@hotmail.com> 20 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include <memory>
|
||||
#include "DetectionManager.h"
|
||||
#include "LogManager.h"
|
||||
#include "RGBController_EdifierHaloPixelbarAmbient.h"
|
||||
#include "RGBController_EdifierHaloPixelbarScreen.h"
|
||||
#include "EdifierHaloController.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Edifier HID vendor and product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define EDIFIER_VID 0x2D99
|
||||
#define EDIFIER_PIXELBAR_PID 0xA106
|
||||
#define EDIFIER_PIXELBAR_INTERFACE 4
|
||||
#define EDIFIER_PIXELBAR_USAGE_PAGE 0xFF14
|
||||
#define EDIFIER_PIXELBAR_USAGE 0x01
|
||||
|
||||
DetectedControllers DetectEdifierHaloControllers(hid_device_info* info, const std::string&)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EdifierHaloController* controller = new EdifierHaloController(dev, info->path);
|
||||
|
||||
RGBController_EdifierHaloPixelbarAmbient* ambient_controller = new RGBController_EdifierHaloPixelbarAmbient(controller);
|
||||
RGBController_EdifierHaloPixelbarScreen* screen_controller = new RGBController_EdifierHaloPixelbarScreen(controller);
|
||||
|
||||
detected_controllers.push_back(ambient_controller);
|
||||
detected_controllers.push_back(screen_controller);
|
||||
|
||||
LOG_INFO("[EdifierHaloPixelbarDetect] Detected Edifier Halo PixelBar at %s (Instantiated Ambient & Screen controllers)", info->path);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING("[EdifierHaloPixelbarDetect] Failed to open Edifier Halo PixelBar at %s", info->path);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Edifier Halo Pixelbar", DetectEdifierHaloControllers, EDIFIER_VID, EDIFIER_PIXELBAR_PID, EDIFIER_PIXELBAR_INTERFACE, EDIFIER_PIXELBAR_USAGE_PAGE, EDIFIER_PIXELBAR_USAGE);
|
||||
@@ -0,0 +1,182 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_EdifierHaloPixelbarAmbient.cpp |
|
||||
| |
|
||||
| RGBController for Edifier Halo PixelBar Ambient Light |
|
||||
| |
|
||||
| Bartholomew Ho <qiangqiang101@hotmail.com> 20 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_EdifierHaloPixelbarAmbient.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Edifier Halo Pixelbar
|
||||
@category Speaker
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :x:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectEdifierHaloControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_EdifierHaloPixelbarAmbient::RGBController_EdifierHaloPixelbarAmbient(EdifierHaloController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
first_leds_update_ignored = false;
|
||||
first_mode_update_ignored = false;
|
||||
|
||||
name = "Edifier Halo Pixelbar - Light Effects";
|
||||
vendor = "Edifier";
|
||||
type = DEVICE_TYPE_SPEAKER;
|
||||
description = "Edifier Halo PixelBar Light Effects";
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
// Setup modes
|
||||
mode breathing_mode;
|
||||
breathing_mode.name = "Breathing";
|
||||
breathing_mode.value = EDIFIER_HALO_AMBIENT_MODE_BREATHING;
|
||||
breathing_mode.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
breathing_mode.color_mode = MODE_COLORS_PER_LED;
|
||||
breathing_mode.speed_min = EDIFIER_HALO_AMBIENT_SPEED_SLOWEST;
|
||||
breathing_mode.speed_max = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
breathing_mode.speed = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
breathing_mode.brightness_min = EDIFIER_HALO_AMBIENT_BRIGHTNESS_LOWEST;
|
||||
breathing_mode.brightness_max = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
breathing_mode.brightness = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
modes.push_back(breathing_mode);
|
||||
|
||||
mode tide_mode;
|
||||
tide_mode.name = "Rainbow";
|
||||
tide_mode.value = EDIFIER_HALO_AMBIENT_MODE_TIDE;
|
||||
tide_mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
tide_mode.color_mode = MODE_COLORS_NONE;
|
||||
tide_mode.speed_min = EDIFIER_HALO_AMBIENT_SPEED_SLOWEST;
|
||||
tide_mode.speed_max = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
tide_mode.speed = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
tide_mode.brightness_min = EDIFIER_HALO_AMBIENT_BRIGHTNESS_LOWEST;
|
||||
tide_mode.brightness_max = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
tide_mode.brightness = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
modes.push_back(tide_mode);
|
||||
|
||||
mode static_mode;
|
||||
static_mode.name = "Static";
|
||||
static_mode.value = EDIFIER_HALO_AMBIENT_MODE_STATIC;
|
||||
static_mode.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
static_mode.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
static_mode.brightness_min = EDIFIER_HALO_AMBIENT_BRIGHTNESS_LOWEST;
|
||||
static_mode.brightness_max = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
static_mode.brightness = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
modes.push_back(static_mode);
|
||||
|
||||
mode ripple_mode;
|
||||
ripple_mode.name = "Glittering and colorful";
|
||||
ripple_mode.value = EDIFIER_HALO_AMBIENT_MODE_RIPPLE;
|
||||
ripple_mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
ripple_mode.color_mode = MODE_COLORS_NONE;
|
||||
ripple_mode.speed_min = EDIFIER_HALO_AMBIENT_SPEED_SLOWEST;
|
||||
ripple_mode.speed_max = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
ripple_mode.speed = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
ripple_mode.brightness_min = EDIFIER_HALO_AMBIENT_BRIGHTNESS_LOWEST;
|
||||
ripple_mode.brightness_max = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
ripple_mode.brightness = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
modes.push_back(ripple_mode);
|
||||
|
||||
mode flow_mode;
|
||||
flow_mode.name = "Light-flow";
|
||||
flow_mode.value = EDIFIER_HALO_AMBIENT_MODE_FLOW;
|
||||
flow_mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
flow_mode.color_mode = MODE_COLORS_NONE;
|
||||
flow_mode.speed_min = EDIFIER_HALO_AMBIENT_SPEED_SLOWEST;
|
||||
flow_mode.speed_max = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
flow_mode.speed = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
flow_mode.brightness_min = EDIFIER_HALO_AMBIENT_BRIGHTNESS_LOWEST;
|
||||
flow_mode.brightness_max = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
flow_mode.brightness = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
modes.push_back(flow_mode);
|
||||
|
||||
mode dynamic_mode;
|
||||
dynamic_mode.name = "Dynamic Shadows";
|
||||
dynamic_mode.value = EDIFIER_HALO_AMBIENT_MODE_DYNAMIC;
|
||||
dynamic_mode.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
dynamic_mode.color_mode = MODE_COLORS_NONE;
|
||||
dynamic_mode.speed_min = EDIFIER_HALO_AMBIENT_SPEED_SLOWEST;
|
||||
dynamic_mode.speed_max = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
dynamic_mode.speed = EDIFIER_HALO_AMBIENT_SPEED_FASTEST;
|
||||
dynamic_mode.brightness_min = EDIFIER_HALO_AMBIENT_BRIGHTNESS_LOWEST;
|
||||
dynamic_mode.brightness_max = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
dynamic_mode.brightness = EDIFIER_HALO_AMBIENT_BRIGHTNESS_HIGHEST;
|
||||
modes.push_back(dynamic_mode);
|
||||
|
||||
// Default to Static mode
|
||||
active_mode = 2;
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_EdifierHaloPixelbarAmbient::~RGBController_EdifierHaloPixelbarAmbient()
|
||||
{
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarAmbient::SetupZones()
|
||||
{
|
||||
zone ambient_zone;
|
||||
ambient_zone.name = "Light Effects";
|
||||
ambient_zone.type = ZONE_TYPE_SINGLE;
|
||||
ambient_zone.leds_min = 1;
|
||||
ambient_zone.leds_max = 1;
|
||||
ambient_zone.leds_count = 1;
|
||||
zones.push_back(ambient_zone);
|
||||
|
||||
led ambient_led;
|
||||
ambient_led.name = "Light Effects";
|
||||
leds.push_back(ambient_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarAmbient::DeviceUpdateLEDs()
|
||||
{
|
||||
if(!first_leds_update_ignored)
|
||||
{
|
||||
first_leds_update_ignored = true;
|
||||
return;
|
||||
}
|
||||
|
||||
int active_idx = GetActiveMode();
|
||||
RGBColor color = colors[0];
|
||||
unsigned char r = RGBGetRValue(color);
|
||||
unsigned char g = RGBGetGValue(color);
|
||||
unsigned char b = RGBGetBValue(color);
|
||||
|
||||
unsigned char effect = modes[active_idx].value;
|
||||
unsigned char brightness = modes[active_idx].brightness;
|
||||
unsigned char speed = modes[active_idx].speed;
|
||||
|
||||
controller->SetAmbientLightPower(true);
|
||||
controller->SetAmbientLight(effect, r, g, b, brightness, speed);
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarAmbient::DeviceUpdateZoneLEDs(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarAmbient::DeviceUpdateSingleLED(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarAmbient::DeviceUpdateMode()
|
||||
{
|
||||
if(!first_mode_update_ignored)
|
||||
{
|
||||
first_mode_update_ignored = true;
|
||||
return;
|
||||
}
|
||||
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_EdifierHaloPixelbarAmbient.h |
|
||||
| |
|
||||
| RGBController for Edifier Halo PixelBar Ambient Light |
|
||||
| |
|
||||
| Bartholomew Ho <qiangqiang101@hotmail.com> 20 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "RGBController.h"
|
||||
#include "EdifierHaloController.h"
|
||||
|
||||
class RGBController_EdifierHaloPixelbarAmbient : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_EdifierHaloPixelbarAmbient(EdifierHaloController* controller_ptr);
|
||||
~RGBController_EdifierHaloPixelbarAmbient();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
EdifierHaloController* controller;
|
||||
bool first_leds_update_ignored;
|
||||
bool first_mode_update_ignored;
|
||||
};
|
||||
@@ -0,0 +1,173 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_EdifierHaloPixelbarScreen.cpp |
|
||||
| |
|
||||
| RGBController for Edifier Halo PixelBar Screen Color |
|
||||
| |
|
||||
| Bartholomew Ho <qiangqiang101@hotmail.com> 20 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_EdifierHaloPixelbarScreen.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Edifier Halo Pixelbar - Screen
|
||||
@category Speaker
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :x:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectEdifierHaloControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
struct CategoryDefinition
|
||||
{
|
||||
std::string name;
|
||||
unsigned char category_id;
|
||||
};
|
||||
|
||||
RGBController_EdifierHaloPixelbarScreen::RGBController_EdifierHaloPixelbarScreen(EdifierHaloController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
first_leds_update_ignored = false;
|
||||
first_mode_update_ignored = false;
|
||||
|
||||
name = "Edifier Halo Pixelbar - Pixel Display";
|
||||
vendor = "Edifier";
|
||||
type = DEVICE_TYPE_SPEAKER;
|
||||
description = "Edifier Halo PixelBar Pixel Display Color";
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
// Clock 1 to Clock 11 (11 built-in clock styles)
|
||||
for(unsigned char i = 0; i < 11; ++i)
|
||||
{
|
||||
mode m;
|
||||
m.name = "Clock " + std::to_string(i + 1);
|
||||
m.value = (0 << 8) | i;
|
||||
m.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
m.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(m);
|
||||
}
|
||||
|
||||
// Default built-in layouts for other categories
|
||||
std::vector<CategoryDefinition> categories =
|
||||
{
|
||||
{ "Gaming", 1 },
|
||||
{ "Work", 2 },
|
||||
{ "Study", 3 },
|
||||
{ "Cats", 4 },
|
||||
{ "Dogs", 5 },
|
||||
{ "Buzzwords", 6 },
|
||||
{ "Cyberpunk", 7 },
|
||||
{ "Spectrum", 8 }
|
||||
};
|
||||
|
||||
for(const CategoryDefinition& cat : categories)
|
||||
{
|
||||
mode m;
|
||||
m.name = cat.name;
|
||||
m.value = (cat.category_id << 8) | 0;
|
||||
m.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
m.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(m);
|
||||
}
|
||||
|
||||
// Default to Clock 1 mode
|
||||
active_mode = 0;
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_EdifierHaloPixelbarScreen::~RGBController_EdifierHaloPixelbarScreen()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarScreen::SetupZones()
|
||||
{
|
||||
zone screen_zone;
|
||||
screen_zone.name = "Screen Color";
|
||||
screen_zone.type = ZONE_TYPE_SINGLE;
|
||||
screen_zone.leds_min = 1;
|
||||
screen_zone.leds_max = 1;
|
||||
screen_zone.leds_count = 1;
|
||||
zones.push_back(screen_zone);
|
||||
|
||||
led screen_led;
|
||||
screen_led.name = "Screen Text";
|
||||
leds.push_back(screen_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarScreen::DeviceUpdateLEDs()
|
||||
{
|
||||
if(!first_leds_update_ignored)
|
||||
{
|
||||
first_leds_update_ignored = true;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char r = 255;
|
||||
unsigned char g = 255;
|
||||
unsigned char b = 255;
|
||||
|
||||
if(!colors.empty())
|
||||
{
|
||||
RGBColor color = colors[0];
|
||||
r = RGBGetRValue(color);
|
||||
g = RGBGetGValue(color);
|
||||
b = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
// For all other modes, color updates are sent using SetPixelScreenColor
|
||||
controller->SetPixelScreenColor(r, g, b);
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarScreen::DeviceUpdateZoneLEDs(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarScreen::DeviceUpdateSingleLED(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_EdifierHaloPixelbarScreen::DeviceUpdateMode()
|
||||
{
|
||||
if(!first_mode_update_ignored)
|
||||
{
|
||||
first_mode_update_ignored = true;
|
||||
return;
|
||||
}
|
||||
|
||||
int active_idx = GetActiveMode();
|
||||
unsigned char r = 255;
|
||||
unsigned char g = 255;
|
||||
unsigned char b = 255;
|
||||
|
||||
if(!colors.empty())
|
||||
{
|
||||
RGBColor color = colors[0];
|
||||
r = RGBGetRValue(color);
|
||||
g = RGBGetGValue(color);
|
||||
b = RGBGetBValue(color);
|
||||
}
|
||||
|
||||
unsigned int mode_val = modes[active_idx].value;
|
||||
unsigned char category = (mode_val >> 8) & 0xFF;
|
||||
unsigned char index = mode_val & 0xFF;
|
||||
|
||||
if(category == 0) // Clock category (11 built-in styles)
|
||||
{
|
||||
controller->SetScreenScene(0, index, r, g, b);
|
||||
}
|
||||
else // Other categories (Gaming, Working, etc.) use the default built-in layouts
|
||||
{
|
||||
controller->SetScreenUIModel(category, r, g, b);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_EdifierHaloPixelbarScreen.h |
|
||||
| |
|
||||
| RGBController for Edifier Halo PixelBar Screen Color |
|
||||
| |
|
||||
| Bartholomew Ho <qiangqiang101@hotmail.com> 20 Jul 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "RGBController.h"
|
||||
#include "EdifierHaloController.h"
|
||||
|
||||
class RGBController_EdifierHaloPixelbarScreen : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_EdifierHaloPixelbarScreen(EdifierHaloController* controller_ptr);
|
||||
~RGBController_EdifierHaloPixelbarScreen();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
EdifierHaloController* controller;
|
||||
bool first_leds_update_ignored;
|
||||
bool first_mode_update_ignored;
|
||||
};
|
||||
@@ -1,133 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EpomakerController.cpp |
|
||||
| |
|
||||
| Driver for Epomaker keyboard |
|
||||
| |
|
||||
| Alvaro Munoz (alvaromunoz) 05 Jun 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <math.h>
|
||||
#include "EpomakerController.h"
|
||||
#include "LogManager.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
EpomakerController::EpomakerController(hid_device* dev_handle, char *_path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = _path;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Get device name from HID manufacturer and product strings |
|
||||
\*---------------------------------------------------------*/
|
||||
wchar_t name_string[HID_MAX_STR];
|
||||
|
||||
hid_get_manufacturer_string(dev, name_string, HID_MAX_STR);
|
||||
device_name = StringUtils::wstring_to_string(name_string);
|
||||
|
||||
hid_get_product_string(dev, name_string, HID_MAX_STR);
|
||||
device_name.append(" ").append(StringUtils::wstring_to_string(name_string));
|
||||
|
||||
current_mode = EPOMAKER_MODE_ALWAYS_ON;
|
||||
current_speed = EPOMAKER_SPEED_DEFAULT;
|
||||
current_brightness = EPOMAKER_BRIGHTNESS_DEFAULT;
|
||||
current_dazzle = EPOMAKER_OPTION_DAZZLE_OFF;
|
||||
current_option = EPOMAKER_OPTION_DEFAULT;
|
||||
}
|
||||
|
||||
EpomakerController::~EpomakerController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string EpomakerController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
std::string EpomakerController::GetSerial()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string EpomakerController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
void EpomakerController::SetMode(unsigned char mode, unsigned char speed, unsigned char brightness)
|
||||
{
|
||||
current_mode = mode;
|
||||
current_speed = speed;
|
||||
current_brightness = brightness;
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void EpomakerController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
current_red = red;
|
||||
current_green = green;
|
||||
current_blue = blue;
|
||||
|
||||
SendUpdate();
|
||||
}
|
||||
|
||||
void EpomakerController::SetDazzle(bool is_dazzle)
|
||||
{
|
||||
if(is_dazzle)
|
||||
{
|
||||
current_dazzle = EPOMAKER_OPTION_DAZZLE_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_dazzle = EPOMAKER_OPTION_DAZZLE_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
void EpomakerController::SetOption(unsigned char option)
|
||||
{
|
||||
current_option = option;
|
||||
}
|
||||
|
||||
void EpomakerController::SendUpdate()
|
||||
{
|
||||
unsigned char buffer[EPOMAKER_PACKET_LENGTH + 1] = { 0x00 };
|
||||
|
||||
buffer[EPOMAKER_BYTE_COMMAND] = EPOMAKER_COMMAND_RGB;
|
||||
buffer[EPOMAKER_BYTE_MODE] = current_mode;
|
||||
buffer[EPOMAKER_BYTE_SPEED] = current_speed;
|
||||
buffer[EPOMAKER_BYTE_BRIGHTNESS] = current_brightness;
|
||||
buffer[EPOMAKER_BYTE_FLAGS] = current_option | current_dazzle;
|
||||
buffer[EPOMAKER_BYTE_RED] = current_red;
|
||||
buffer[EPOMAKER_BYTE_GREEN] = current_green;
|
||||
buffer[EPOMAKER_BYTE_BLUE] = current_blue;
|
||||
|
||||
int sum_bits = 0;
|
||||
for(int i = EPOMAKER_BYTE_COMMAND; i <= EPOMAKER_BYTE_BLUE; i++)
|
||||
{
|
||||
sum_bits += buffer[i];
|
||||
}
|
||||
|
||||
int next_pow2 = (int)(pow(2, ceil(log2((double)(sum_bits)))));
|
||||
int filler = next_pow2 - sum_bits - 1;
|
||||
|
||||
buffer[EPOMAKER_BYTE_FILLER] = filler;
|
||||
|
||||
int send_buffer_result = hid_send_feature_report(dev, buffer, (sizeof(buffer) / sizeof(buffer[0])));
|
||||
if(send_buffer_result<0)
|
||||
{
|
||||
LOG_ERROR("[EPOMAKER]: Send Buffer Error. HIDAPI Error: %ls", hid_error(dev));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| EpomakerControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Epomaker keyboard |
|
||||
| |
|
||||
| Alvaro Munoz (alvaromunoz) 05 Jun 2023 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "EpomakerController.h"
|
||||
#include "RGBController_EpomakerController.h"
|
||||
|
||||
#define EPOMAKER_VID 0x3151
|
||||
#define EPOMAKER_TH80_Pro_USB_PID 0x4010
|
||||
#define ATTACKSHARK_K86_USB_PID 0x4015
|
||||
#define EPOMAKER_TH80_Pro_Dongle_PID 0x4011 /* Attack shark's Dongle is the same. */
|
||||
#define EPOMAKER_TH80_Pro_BT_PID 0x4013
|
||||
#define ATTACKSHARK_K86_BT_PID 0x401
|
||||
|
||||
DetectedControllers DetectEpomakerControllers(hid_device_info* info, const std::string&)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
EpomakerController* controller = new EpomakerController(dev, info->path);
|
||||
RGBController_EpomakerController* rgb_controller = new RGBController_EpomakerController(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_I("Epomaker TH80 Pro (USB Cable)", DetectEpomakerControllers, EPOMAKER_VID, EPOMAKER_TH80_Pro_USB_PID, 2);
|
||||
REGISTER_HID_DETECTOR_I("Epomaker TH80 Pro (USB Dongle)", DetectEpomakerControllers, EPOMAKER_VID, EPOMAKER_TH80_Pro_Dongle_PID, 2);
|
||||
REGISTER_HID_DETECTOR_I("Attack Shark K86 (USB Cable)", DetectEpomakerControllers, EPOMAKER_VID, ATTACKSHARK_K86_USB_PID, 2);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Bluetooth Not implemented |
|
||||
\*---------------------------------------------------------*/
|
||||
//REGISTER_HID_DETECTOR("Epomaker TH80 Pro (Bluetooth)", DetectEpomakerControllers, EPOMAKER_VID, EPOMAKER_TH80_Pro_BT_PID);
|
||||
//REGISTER_HID_DETECTOR("Attack Shark K86 (Bluetooth)", DetectEpomakerControllers, EPOMAKER_VID, ATTACKSHARK_K86_BT_PID);
|
||||
@@ -197,3 +197,5 @@ DetectedControllers DetectFaustusControllers()
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("Faustus", DetectFaustusControllers);
|
||||
|
||||
REGISTER_CUSTOM_UDEV_RULE(faustus, "ASUS TUF Laptops (faustus)", "ACTION==\"add\", SUBSYSTEM==\"platform\", KERNEL==\"faustus\", RUN+=\"/usr/bin/env chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_blue\"\nACTION==\"add\", SUBSYSTEM==\"platform\", KERNEL==\"faustus\", RUN+=\"/usr/bin/env chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_flags\"\nACTION==\"add\", SUBSYSTEM==\"platform\", KERNEL==\"faustus\", RUN+=\"/usr/bin/env chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_green\"\nACTION==\"add\", SUBSYSTEM==\"platform\", KERNEL==\"faustus\", RUN+=\"/usr/bin/env chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_mode\"\nACTION==\"add\", SUBSYSTEM==\"platform\", KERNEL==\"faustus\", RUN+=\"/usr/bin/env chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_red\"\nACTION==\"add\", SUBSYSTEM==\"platform\", KERNEL==\"faustus\", RUN+=\"/usr/bin/env chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_set\"\nACTION==\"add\", SUBSYSTEM==\"platform\", KERNEL==\"faustus\", RUN+=\"/usr/bin/env chmod a+w /sys/bus/platform/devices/%k/kbbl/kbbl_speed\"");
|
||||
|
||||
@@ -109,5 +109,6 @@ REGISTER_I2C_PCI_DETECTOR("GALAX GeForce RTX 2070 SUPER EX Gamer Black", Dete
|
||||
REGISTER_I2C_PCI_DETECTOR("KFA2 GeForce RTX 2080 EX OC", DetectGalaxGPUControllers, NVIDIA_VEN, NVIDIA_RTX2080_DEV, NVIDIA_SUB_VEN, KFA2_RTX_2080_EX_OC_SUB_DEV, 0x23);
|
||||
REGISTER_I2C_PCI_DETECTOR("KFA2 GeForce RTX 2080 SUPER EX OC", DetectGalaxGPUControllers, NVIDIA_VEN, NVIDIA_RTX2080S_DEV, NVIDIA_SUB_VEN, KFA2_RTX_2080_SUPER_EX_OC_SUB_DEV, 0x23);
|
||||
REGISTER_I2C_PCI_DETECTOR("KFA2 GeForce RTX 2080 Ti EX OC", DetectGalaxGPUControllers, NVIDIA_VEN, NVIDIA_RTX2080TI_DEV, NVIDIA_SUB_VEN, KFA2_RTX_2080TI_EX_OC_SUB_DEV, 0x23);
|
||||
REGISTER_I2C_PCI_DETECTOR("GALAX GeForce RTX 3070 1-Click OC", DetectGalaxGPUControllers, NVIDIA_VEN, NVIDIA_RTX3070_DEV, NVIDIA_SUB_VEN, GALAX_RTX_3070_1_CLICK_OC_SUB_DEV, 0x23);
|
||||
REGISTER_I2C_PCI_DETECTOR("GALAX GeForce RTX 3080 SG", DetectGalaxGPUControllers, NVIDIA_VEN, NVIDIA_RTX3080_DEV, NVIDIA_SUB_VEN, GALAX_RTX_3080_SG_SUB_DEV, 0x23);
|
||||
REGISTER_I2C_PCI_DETECTOR("GALAX GeForce RTX 5070 Ti EX Gamer 1-Click OC", DetectGalaxGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, NVIDIA_SUB_VEN, GALAX_RTX_5070TI_EX_OC_SUB_DEV, 0x51);
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| GameSirController.cpp |
|
||||
| |
|
||||
| GameSir RGB Device |
|
||||
| |
|
||||
| Added by OpenRGB Community 08 Aug 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "GameSirController.h"
|
||||
#include <cstring>
|
||||
#include "StringUtils.h"
|
||||
|
||||
GameSirController::GameSirController(hid_device* dev_handle, const char* path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
}
|
||||
|
||||
GameSirController::~GameSirController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string GameSirController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string GameSirController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
memset(serial_string, 0x00, sizeof(serial_string));
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void GameSirController::SetColor(unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
unsigned char buf[64];
|
||||
memset(buf, 0x00, sizeof(buf));
|
||||
|
||||
buf[0] = 0x05;
|
||||
buf[1] = 0x08;
|
||||
buf[2] = 0x0A;
|
||||
buf[3] = 0x01;
|
||||
buf[4] = 0x03;
|
||||
buf[5] = red;
|
||||
buf[6] = green;
|
||||
buf[7] = blue;
|
||||
buf[8] = 0x00;
|
||||
|
||||
unsigned int checksum = 0;
|
||||
for(int i = 0; i < 9; i++)
|
||||
{
|
||||
checksum += buf[i];
|
||||
}
|
||||
|
||||
buf[9] = checksum & 0xFF;
|
||||
|
||||
hid_write(dev, buf, sizeof(buf));
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| GameSirController.h |
|
||||
| |
|
||||
| GameSir RGB Device |
|
||||
| |
|
||||
| Added by OpenRGB Community 08 Aug 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
|
||||
class GameSirController
|
||||
{
|
||||
public:
|
||||
GameSirController(hid_device* dev_handle, const char* path);
|
||||
~GameSirController();
|
||||
|
||||
std::string GetLocation();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| GameSirControllerDetect.cpp |
|
||||
| |
|
||||
| GameSir RGB Device |
|
||||
| |
|
||||
| Added by OpenRGB Community 08 Aug 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_GameSir.h"
|
||||
|
||||
#define GAMESIR_VID 0x3537
|
||||
#define GAMESIR_NOVA_LITE_2_PID 0x100F
|
||||
|
||||
DetectedControllers DetectGameSirControllers(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
|
||||
hid_device* dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
GameSirController* controller = new GameSirController(dev, info->path);
|
||||
RGBController_GameSir* rgb_controller = new RGBController_GameSir(controller);
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return detected_controllers;
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("GameSir Nova 2 Lite", DetectGameSirControllers, GAMESIR_VID, GAMESIR_NOVA_LITE_2_PID, 2, 0xFF7A, 0x0001);
|
||||
@@ -0,0 +1,75 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_GameSir.cpp |
|
||||
| |
|
||||
| GameSir RGB Device |
|
||||
| |
|
||||
| Added by OpenRGB Community 08 Aug 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_GameSir.h"
|
||||
|
||||
RGBController_GameSir::RGBController_GameSir(GameSirController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = "GameSir Nova 2 Lite";
|
||||
vendor = "GameSir";
|
||||
type = DEVICE_TYPE_GAMEPAD;
|
||||
description = "GameSir RGB Device";
|
||||
location = controller->GetLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = 0xFFFF;
|
||||
Static.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Static.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Static);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_GameSir::~RGBController_GameSir()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_GameSir::SetupZones()
|
||||
{
|
||||
zone new_zone;
|
||||
new_zone.name = "Controller";
|
||||
new_zone.type = ZONE_TYPE_SINGLE;
|
||||
new_zone.leds_min = 1;
|
||||
new_zone.leds_max = 1;
|
||||
new_zone.leds_count = 1;
|
||||
zones.push_back(new_zone);
|
||||
|
||||
led new_led;
|
||||
new_led.name = "Main LED";
|
||||
leds.push_back(new_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_GameSir::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetColor(RGBGetRValue(colors[0]), RGBGetGValue(colors[0]), RGBGetBValue(colors[0]));
|
||||
}
|
||||
|
||||
void RGBController_GameSir::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_GameSir::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_GameSir::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_GameSir.h |
|
||||
| |
|
||||
| GameSir RGB Device |
|
||||
| |
|
||||
| Added by OpenRGB Community 08 Aug 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "GameSirController.h"
|
||||
|
||||
class RGBController_GameSir : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_GameSir(GameSirController* controller_ptr);
|
||||
~RGBController_GameSir();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
GameSirController* controller;
|
||||
};
|
||||
+4
-2
@@ -44,8 +44,9 @@ bool TestForGigabyteRGBFusion2BlackwellGPUController(i2c_smbus_interface* bus, u
|
||||
//GeForce RTX 5070 Ti Gaming OC 16G 0x01 0x01 0x01 0x00
|
||||
//GeForce RTX 5070 Gaming OC 12G 0x01 0x01 0x01 0x00
|
||||
//GeForce RTX 5080 AORUS MASTER 16G 0x01 0x01 0x01 0x10
|
||||
//Radeon RX 9070 XT GAMING OC 16G 0x01 0x02 0x01 0x00
|
||||
|
||||
if(res < 0 || data_readpkt[0] != 0x01 || data_readpkt[1] != 0x01 || data_readpkt[2] != 0x01)
|
||||
if(res < 0 || data_readpkt[0] != 0x01 || (data_readpkt[1] != 0x01 && data_readpkt[1] != 0x02) || data_readpkt[2] != 0x01)
|
||||
{
|
||||
// Assemble C-string with respons for debugging
|
||||
std::string text = "";
|
||||
@@ -57,7 +58,7 @@ bool TestForGigabyteRGBFusion2BlackwellGPUController(i2c_smbus_interface* bus, u
|
||||
text.append(str);
|
||||
}
|
||||
|
||||
LOG_DEBUG("[%s] at address 0x%02X invalid. Expected 0x01 0x01 0x01 [0x*] but received:%s", GIGABYTEGPU_CONTROLLER_NAME3, address, text.c_str());
|
||||
LOG_DEBUG("[%s] at address 0x%02X invalid. Expected 0x01 0x01/0x02 0x01 [0x*] but received:%s", GIGABYTEGPU_CONTROLLER_NAME3, address, text.c_str());
|
||||
pass = false;
|
||||
}
|
||||
|
||||
@@ -144,3 +145,4 @@ REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS Radeon RX 9070 XT Elite",
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 9070 XT GAMING OC", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX9070XT_GAMING_OC_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 9070 XT GAMING OC ICE", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX9070XT_GAMING_OC_ICE_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 9070 XT GAMING", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX9070XT_GAMING_16G_SUB_DEV, 0x75);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 9070 GAMING OC", DetectGigabyteRGBFusion2BlackwellGamingLayoutGPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX9070_GAMING_OC_16G_SUB_DEV, 0x75);
|
||||
|
||||
@@ -108,6 +108,7 @@ REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 2080 SUPER Waterforce WB",
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 2080 SUPER Waterforce WB", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX2080S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX2080S_WATERFORCE_WB_SUB_DEV_P,0x51);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 2080 SUPER Waterforce", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX2080S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX2080S_WATERFORCE_SUB_DEV_H, 0x08);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 2080 SUPER Waterforce", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX2080S_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX2080S_WATERFORCE_SUB_DEV_P, 0x08);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 2080 Ti 11G", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX2080TI_A_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX2080TI_11G_SUB_DEV_H, 0x50);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 2080 Ti XTREME", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX2080TI_A_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX2080TI_EXTREME_SUB_DEV_H, 0x50);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 2080 Ti XTREME", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX2080TI_A_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX2080TI_EXTREME_SUB_DEV_P, 0x50);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 3060 ELITE", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX3060_GA104_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX3060_ELITE_12GB_SUB_DEV, 0x70);
|
||||
@@ -160,6 +161,7 @@ REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4090 AERO OC",
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4090 GAMING OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4090_GAMING_OC_24G_SUB_DEV, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 4090 MASTER", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX4090_MASTER_24G_SUB_DEV, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 5090 D MASTER", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX5090D_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX5090D_MASTER_32G_SUB_DEV, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5080 GAMING OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX5080_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5080_GAMING_OC_16G_SUB_DEV, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 5090 GAMING OC", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX5090D_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX5090_GAMING_OC_32G_SUB_DEV, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 5090 MASTER", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX5090_MASTER_32G_SUB_DEV, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS GeForce RTX 5090 MASTER ICE", DetectGigabyteRGBFusion2GPUControllers, NVIDIA_VEN, NVIDIA_RTX5090_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RTX5090_MASTER_ICE_32G_SUB_DEV, 0x71);
|
||||
@@ -181,6 +183,7 @@ REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 7900 XT GAMING OC",
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 7900 XTX GAMING OC", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI31_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX7900XTX_GAMING_OC_24G_SUB_DEV, 0x62);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS Radeon RX 7900 XTX ELITE 24G", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI31_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RX7900XTX_ELITE_24G_SUB_DEV, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS RX 6750 XT ELITE 12G", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI22_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RX_6750_XT_ELITE_12G_SUB_DEV, 0x70);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS RX 6900 XT MASTER rev 2.0", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV2, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RX6900XT_MASTER_SUB_DEV, 0x70);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS RX 6900 XT EXTREME WATERFORCE WB", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI21_DEV2, GIGABYTE_SUB_VEN, GIGABYTE_RX6900XT_XTREME_WATERFORCE_WB_SUB_DEV, 0x70);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte AORUS Radeon RX 9070 XT Elite", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, GIGABYTE_SUB_VEN, GIGABYTE_AORUS_RX9070XT_ELITE_16G_SUB_DEV, 0x73);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte Radeon RX 9070 XT GAMING OC", DetectGigabyteRGBFusion2GPUControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RX9070XT_GAMING_OC_16G_SUB_DEV, 0x73);
|
||||
|
||||
+1
@@ -56,6 +56,7 @@ json rgb_fusion_2_smbus_motherboards[] =
|
||||
"X470 AORUS ULTRA GAMING",
|
||||
"X470 AORUS ULTRA GAMING-CF",
|
||||
"B360M AORUS Gaming 3-CF",
|
||||
"B360 AORUS GAMING 3 WIFI-CF",
|
||||
"Z370 AORUS Gaming 5-CF",
|
||||
"Z370 AORUS Ultra Gaming-CF"
|
||||
};
|
||||
|
||||
@@ -596,8 +596,8 @@ static const gb_fusion2_zone common_team_up_logo_11_zone =
|
||||
static const gb_fusion2_zone common_wifi_ant_9_zone =
|
||||
{
|
||||
LED9,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
2,
|
||||
"WIFI Antenna"
|
||||
};
|
||||
|
||||
@@ -3930,6 +3930,23 @@ static const gb_fusion2_device b550_vision_dp_device =
|
||||
"B550 VISION D-P",
|
||||
};
|
||||
|
||||
static const gb_fusion2_device b550_ud_ac_device =
|
||||
{
|
||||
&it5702_24_device,
|
||||
0x0140005F,
|
||||
0,
|
||||
"B550 UD AC",
|
||||
};
|
||||
|
||||
static const gb_fusion2_device b550_ud_ac_y1_device =
|
||||
{
|
||||
&it5702_24_device,
|
||||
0x0140005F,
|
||||
0,
|
||||
"B550 UD AC-Y1",
|
||||
};
|
||||
|
||||
|
||||
static const gb_fusion2_device b550m_aor_elite_device =
|
||||
{
|
||||
&it5702_24_device,
|
||||
@@ -4542,6 +4559,14 @@ static const gb_fusion2_device z490_aor_ultra_g2_device =
|
||||
"Z490 AORUS ULTRA G2",
|
||||
};
|
||||
|
||||
static const gb_fusion2_device z490_vision_d_device =
|
||||
{
|
||||
&it5702_30_device,
|
||||
0x0180005F,
|
||||
0,
|
||||
"Z490 VISION D",
|
||||
};
|
||||
|
||||
static const gb_fusion2_device b760m_aor_pro_device =
|
||||
{
|
||||
&it5702_30_device,
|
||||
@@ -4894,48 +4919,13 @@ static const gb_fusion2_device b760m_aor_elite_x_ax_device =
|
||||
| |
|
||||
| Zone "D_LED1" : Linear |
|
||||
| Zone "D_LED2" : Linear |
|
||||
| Zone "IO Cover" : Single |
|
||||
| Zone "LED_C1" : Single |
|
||||
| Zone "Chipset Accent" : Single |
|
||||
| Zone "PCI-E Accent" : Single |
|
||||
| Zone "LED_C2" : Single |
|
||||
\*-------------------------------------------------------------*/
|
||||
static gb_fusion2_layout it5702_36_device =
|
||||
{
|
||||
&common_d_led1_zone,
|
||||
&common_d_led2_zone,
|
||||
&common_io_cov_btm_1_zone,
|
||||
&common_io_cov_btm_mid_2_zone,
|
||||
&common_chip_io_cov_tm_3_zone,
|
||||
&common_io_cov_top_4_zone,
|
||||
&common_led_c2_5_zone,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
};
|
||||
|
||||
static const gb_fusion2_device z490_vision_d_device =
|
||||
{
|
||||
&it5702_36_device,
|
||||
0x0180005F,
|
||||
0,
|
||||
"Z490 VISION D",
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Layout 37 048D:5702 |
|
||||
| |
|
||||
| Zone "D_LED1" : Linear |
|
||||
| Zone "D_LED2" : Linear |
|
||||
| Zone "IO Cover (Top)" : Single |
|
||||
| Zone "LED_C1" : Single |
|
||||
| Zone "LED_CPU" : Single |
|
||||
| Zone "IO Cover (Bottom)" : Single |
|
||||
| Zone "LED_C2" : Single |
|
||||
\*-------------------------------------------------------------*/
|
||||
static gb_fusion2_layout it5702_37_device =
|
||||
static gb_fusion2_layout it5702_36_device =
|
||||
{
|
||||
&common_d_led1_zone,
|
||||
&common_d_led2_zone,
|
||||
@@ -4953,7 +4943,7 @@ static gb_fusion2_layout it5702_37_device =
|
||||
|
||||
static const gb_fusion2_device b650_aor_pro_ax_device =
|
||||
{
|
||||
&it5702_37_device,
|
||||
&it5702_36_device,
|
||||
0x09A001DF,
|
||||
0,
|
||||
"B650 AORUS PRO AX",
|
||||
@@ -4961,7 +4951,7 @@ static const gb_fusion2_device b650_aor_pro_ax_device =
|
||||
|
||||
static const gb_fusion2_device b650e_aor_mstr_device =
|
||||
{
|
||||
&it5702_37_device,
|
||||
&it5702_36_device,
|
||||
0x09A001DF,
|
||||
0,
|
||||
"B650E AORUS MASTER",
|
||||
@@ -4969,14 +4959,14 @@ static const gb_fusion2_device b650e_aor_mstr_device =
|
||||
|
||||
static const gb_fusion2_device x670e_aor_mstr_device =
|
||||
{
|
||||
&it5702_37_device,
|
||||
&it5702_36_device,
|
||||
0x024001DF,
|
||||
0,
|
||||
"X670E AORUS MASTER",
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Layout 38 048D:5702 |
|
||||
| Layout 37 048D:5702 |
|
||||
| |
|
||||
| Zone "D_LED1" : Linear |
|
||||
| Zone "D_LED2" : Linear |
|
||||
@@ -4986,7 +4976,7 @@ static const gb_fusion2_device x670e_aor_mstr_device =
|
||||
| Zone "Board Accent (Right Side, Top Middle)" : Single |
|
||||
| Zone "LED_C2" : Single |
|
||||
\*-------------------------------------------------------------*/
|
||||
static gb_fusion2_layout it5702_38_device =
|
||||
static gb_fusion2_layout it5702_37_device =
|
||||
{
|
||||
&common_d_led1_zone,
|
||||
&common_d_led2_zone,
|
||||
@@ -5004,7 +4994,7 @@ static gb_fusion2_layout it5702_38_device =
|
||||
|
||||
static const gb_fusion2_device b660_aor_mstr_device =
|
||||
{
|
||||
&it5702_38_device,
|
||||
&it5702_37_device,
|
||||
0x094001DF,
|
||||
0,
|
||||
"B660 AORUS MASTER",
|
||||
@@ -5012,7 +5002,7 @@ static const gb_fusion2_device b660_aor_mstr_device =
|
||||
|
||||
static const gb_fusion2_device b660_aor_mstr_ddr4_device =
|
||||
{
|
||||
&it5702_38_device,
|
||||
&it5702_37_device,
|
||||
0x094001DF,
|
||||
0,
|
||||
"B660 AORUS MASTER DDR4",
|
||||
@@ -5020,7 +5010,7 @@ static const gb_fusion2_device b660_aor_mstr_ddr4_device =
|
||||
|
||||
static const gb_fusion2_device b760_aor_mstr_ddr4_device =
|
||||
{
|
||||
&it5702_38_device,
|
||||
&it5702_37_device,
|
||||
0x094001DF,
|
||||
0,
|
||||
"B760 AORUS MASTER DDR4",
|
||||
@@ -5028,7 +5018,7 @@ static const gb_fusion2_device b760_aor_mstr_ddr4_device =
|
||||
|
||||
static const gb_fusion2_device z690_aor_elite_device =
|
||||
{
|
||||
&it5702_38_device,
|
||||
&it5702_37_device,
|
||||
0x016001DF,
|
||||
0,
|
||||
"Z690 AORUS ELITE",
|
||||
@@ -5036,7 +5026,7 @@ static const gb_fusion2_device z690_aor_elite_device =
|
||||
|
||||
static const gb_fusion2_device z690_aor_elite_ax_2_device =
|
||||
{
|
||||
&it5702_38_device,
|
||||
&it5702_37_device,
|
||||
0x016001DF,
|
||||
0,
|
||||
"Z690 AORUS ELITE AX",
|
||||
@@ -5044,7 +5034,7 @@ static const gb_fusion2_device z690_aor_elite_ax_2_device =
|
||||
|
||||
static const gb_fusion2_device z690_aor_elite_ax_ddr4_device =
|
||||
{
|
||||
&it5702_38_device,
|
||||
&it5702_37_device,
|
||||
0x016001DF,
|
||||
0,
|
||||
"Z690 AORUS ELITE AX DDR4",
|
||||
@@ -5052,7 +5042,7 @@ static const gb_fusion2_device z690_aor_elite_ax_ddr4_device =
|
||||
|
||||
static const gb_fusion2_device z690_aor_elite_ax_ddr4_v2_device =
|
||||
{
|
||||
&it5702_38_device,
|
||||
&it5702_37_device,
|
||||
0x016001DF,
|
||||
0,
|
||||
"Z690 AORUS ELITE AX DDR4 V2",
|
||||
@@ -5060,7 +5050,7 @@ static const gb_fusion2_device z690_aor_elite_ax_ddr4_v2_device =
|
||||
|
||||
static const gb_fusion2_device z690_aor_elite_ddr4_device =
|
||||
{
|
||||
&it5702_38_device,
|
||||
&it5702_37_device,
|
||||
0x016001DF,
|
||||
0,
|
||||
"Z690 AORUS ELITE DDR4",
|
||||
@@ -5077,7 +5067,7 @@ static const gb_fusion2_device z690_aor_elite_ddr4_device =
|
||||
| Zone "PCI-E Accent" : Single |
|
||||
| Zone "LED_C2" : Single |
|
||||
\*-------------------------------------------------------------*/
|
||||
static gb_fusion2_layout it5702_39_device =
|
||||
static gb_fusion2_layout it5702_38_device =
|
||||
{
|
||||
&common_d_led1_zone,
|
||||
&common_d_led2_zone,
|
||||
@@ -5095,7 +5085,7 @@ static gb_fusion2_layout it5702_39_device =
|
||||
|
||||
static const gb_fusion2_device b550_aor_elite_device =
|
||||
{
|
||||
&it5702_39_device,
|
||||
&it5702_38_device,
|
||||
0x0170005F,
|
||||
0,
|
||||
"B550 AORUS ELITE",
|
||||
@@ -5103,7 +5093,7 @@ static const gb_fusion2_device b550_aor_elite_device =
|
||||
|
||||
static const gb_fusion2_device b550_aor_elite_ax_device =
|
||||
{
|
||||
&it5702_39_device,
|
||||
&it5702_38_device,
|
||||
0x0170005F,
|
||||
0,
|
||||
"B550 AORUS ELITE AX",
|
||||
@@ -5111,7 +5101,7 @@ static const gb_fusion2_device b550_aor_elite_ax_device =
|
||||
|
||||
static const gb_fusion2_device b550_aor_elite_ax_v2_device =
|
||||
{
|
||||
&it5702_39_device,
|
||||
&it5702_38_device,
|
||||
0x0170005F,
|
||||
0,
|
||||
"B550 AORUS ELITE AX V2",
|
||||
@@ -5119,7 +5109,7 @@ static const gb_fusion2_device b550_aor_elite_ax_v2_device =
|
||||
|
||||
static const gb_fusion2_device b550_aor_elite_ax_v3_device =
|
||||
{
|
||||
&it5702_39_device,
|
||||
&it5702_38_device,
|
||||
0x0170005F,
|
||||
0,
|
||||
"B550 AORUS ELITE AX V3",
|
||||
@@ -5127,7 +5117,7 @@ static const gb_fusion2_device b550_aor_elite_ax_v3_device =
|
||||
|
||||
static const gb_fusion2_device b550_aor_elite_v2_device =
|
||||
{
|
||||
&it5702_39_device,
|
||||
&it5702_38_device,
|
||||
0x0170005F,
|
||||
0,
|
||||
"B550 AORUS ELITE V2",
|
||||
@@ -5135,7 +5125,7 @@ static const gb_fusion2_device b550_aor_elite_v2_device =
|
||||
|
||||
static const gb_fusion2_device b550_aor_pro_device =
|
||||
{
|
||||
&it5702_39_device,
|
||||
&it5702_38_device,
|
||||
0x0170005F,
|
||||
0,
|
||||
"B550 AORUS PRO",
|
||||
@@ -5143,7 +5133,7 @@ static const gb_fusion2_device b550_aor_pro_device =
|
||||
|
||||
static const gb_fusion2_device b550_aor_pro_ac_device =
|
||||
{
|
||||
&it5702_39_device,
|
||||
&it5702_38_device,
|
||||
0x0170005F,
|
||||
0,
|
||||
"B550 AORUS PRO AC",
|
||||
@@ -5151,7 +5141,7 @@ static const gb_fusion2_device b550_aor_pro_ac_device =
|
||||
|
||||
static const gb_fusion2_device b550_aor_pro_ax_device =
|
||||
{
|
||||
&it5702_39_device,
|
||||
&it5702_38_device,
|
||||
0x0170005F,
|
||||
0,
|
||||
"B550 AORUS PRO AX",
|
||||
@@ -5159,7 +5149,7 @@ static const gb_fusion2_device b550_aor_pro_ax_device =
|
||||
|
||||
static const gb_fusion2_device b550_aor_pro_v2_device =
|
||||
{
|
||||
&it5702_39_device,
|
||||
&it5702_38_device,
|
||||
0x0170005F,
|
||||
0,
|
||||
"B550 AORUS PRO V2",
|
||||
@@ -5167,7 +5157,7 @@ static const gb_fusion2_device b550_aor_pro_v2_device =
|
||||
|
||||
static const gb_fusion2_device x570s_aor_pro_ax_device =
|
||||
{
|
||||
&it5702_39_device,
|
||||
&it5702_38_device,
|
||||
0x0150015F,
|
||||
0,
|
||||
"X570S AORUS PRO AX",
|
||||
@@ -5178,7 +5168,7 @@ static const gb_fusion2_device x570s_aor_pro_ax_device =
|
||||
| |
|
||||
| Zone "IO Cover" : Single |
|
||||
\*-------------------------------------------------------------*/
|
||||
static gb_fusion2_layout it5702_40_device =
|
||||
static gb_fusion2_layout it5702_39_device =
|
||||
{
|
||||
&common_io_cov_1_zone,
|
||||
nullptr,
|
||||
@@ -5196,7 +5186,7 @@ static gb_fusion2_layout it5702_40_device =
|
||||
|
||||
static const gb_fusion2_device z790_aor_mstr_x_2_device =
|
||||
{
|
||||
&it5702_40_device,
|
||||
&it5702_39_device,
|
||||
0x123001DF,
|
||||
1,
|
||||
"Z790 AORUS MASTER X",
|
||||
@@ -5204,7 +5194,7 @@ static const gb_fusion2_device z790_aor_mstr_x_2_device =
|
||||
|
||||
static const gb_fusion2_device z790_aor_mstr_2_device =
|
||||
{
|
||||
&it5702_40_device,
|
||||
&it5702_39_device,
|
||||
0x015001DF,
|
||||
1,
|
||||
"Z790 AORUS MASTER",
|
||||
@@ -5212,7 +5202,7 @@ static const gb_fusion2_device z790_aor_mstr_2_device =
|
||||
|
||||
static const gb_fusion2_device x670_aor_xtrm_2_device =
|
||||
{
|
||||
&it5702_40_device,
|
||||
&it5702_39_device,
|
||||
0x023001DF,
|
||||
1,
|
||||
"X670E AORUS XTREME",
|
||||
@@ -5223,7 +5213,7 @@ static const gb_fusion2_device x670_aor_xtrm_2_device =
|
||||
| |
|
||||
| Zone "Chipset Accent" : Single |
|
||||
\*-------------------------------------------------------------*/
|
||||
static gb_fusion2_layout it5702_41_device =
|
||||
static gb_fusion2_layout it5702_40_device =
|
||||
{
|
||||
&common_chip_acc_3_zone,
|
||||
nullptr,
|
||||
@@ -5241,7 +5231,7 @@ static gb_fusion2_layout it5702_41_device =
|
||||
|
||||
static const gb_fusion2_device z790_aor_xtrm_2_device =
|
||||
{
|
||||
&it5702_41_device,
|
||||
&it5702_40_device,
|
||||
0x026001DF,
|
||||
1,
|
||||
"Z790 AORUS XTREME",
|
||||
@@ -5249,7 +5239,7 @@ static const gb_fusion2_device z790_aor_xtrm_2_device =
|
||||
|
||||
static const gb_fusion2_device z790_aor_xtrm_x_2_device =
|
||||
{
|
||||
&it5702_41_device,
|
||||
&it5702_40_device,
|
||||
0x124001DF,
|
||||
1,
|
||||
"Z790 AORUS XTREME X",
|
||||
@@ -5261,7 +5251,7 @@ static const gb_fusion2_device z790_aor_xtrm_x_2_device =
|
||||
| Zone "IO Cover" : Single |
|
||||
| Zone "LED_CPU" : Single |
|
||||
\*-------------------------------------------------------------*/
|
||||
static gb_fusion2_layout it5702_42_device =
|
||||
static gb_fusion2_layout it5702_41_device =
|
||||
{
|
||||
&common_chip_acc_3_zone,
|
||||
&common_led_cpu_8_zone,
|
||||
@@ -5279,7 +5269,7 @@ static gb_fusion2_layout it5702_42_device =
|
||||
|
||||
static const gb_fusion2_device z690_aor_xtrm_waterforce_2_device =
|
||||
{
|
||||
&it5702_42_device,
|
||||
&it5702_41_device,
|
||||
0x029001DF,
|
||||
1,
|
||||
"Z690 AORUS XTREME WATERFORCE",
|
||||
@@ -5292,7 +5282,7 @@ static const gb_fusion2_device z690_aor_xtrm_waterforce_2_device =
|
||||
| Zone "Chipset Accent" : Single |
|
||||
| Zone "LED_CPU" : Single |
|
||||
\*-------------------------------------------------------------*/
|
||||
static gb_fusion2_layout it5702_43_device =
|
||||
static gb_fusion2_layout it5702_42_device =
|
||||
{
|
||||
&common_chip_acc_3_zone,
|
||||
&common_chip_acc_3_zone,
|
||||
@@ -5310,7 +5300,7 @@ static gb_fusion2_layout it5702_43_device =
|
||||
|
||||
static const gb_fusion2_device z490_aor_xtrm_2_device =
|
||||
{
|
||||
&it5702_43_device,
|
||||
&it5702_42_device,
|
||||
0x029001DF,
|
||||
1,
|
||||
"Z490 AORUS XTREME",
|
||||
@@ -5318,7 +5308,7 @@ static const gb_fusion2_device z490_aor_xtrm_2_device =
|
||||
|
||||
static const gb_fusion2_device z490_aor_xtrm_waterforce_2_device =
|
||||
{
|
||||
&it5702_43_device,
|
||||
&it5702_42_device,
|
||||
0x029001DF,
|
||||
1,
|
||||
"Z490 AORUS XTREME WATERFORCE",
|
||||
@@ -5326,7 +5316,7 @@ static const gb_fusion2_device z490_aor_xtrm_waterforce_2_device =
|
||||
|
||||
static const gb_fusion2_device z590_aor_xtrm_waterforce_2_device =
|
||||
{
|
||||
&it5702_43_device,
|
||||
&it5702_42_device,
|
||||
0x029001DF,
|
||||
1,
|
||||
"Z590 AORUS XTREME WATERFORCE",
|
||||
@@ -5340,7 +5330,7 @@ static const gb_fusion2_device z590_aor_xtrm_waterforce_2_device =
|
||||
| Zone "RAM Cover" : Single |
|
||||
| Zone "LED_CPU" : Single |
|
||||
\*-------------------------------------------------------------*/
|
||||
static gb_fusion2_layout it5702_44_device =
|
||||
static gb_fusion2_layout it5702_43_device =
|
||||
{
|
||||
&common_chip_acc_3_zone,
|
||||
&common_chip_acc_3_zone,
|
||||
@@ -5358,7 +5348,7 @@ static gb_fusion2_layout it5702_44_device =
|
||||
|
||||
static const gb_fusion2_device z690_aor_xtrm_2_device =
|
||||
{
|
||||
&it5702_44_device,
|
||||
&it5702_43_device,
|
||||
0x028001DF,
|
||||
1,
|
||||
"Z690 AORUS XTREME",
|
||||
@@ -5375,7 +5365,7 @@ static const gb_fusion2_device z690_aor_xtrm_2_device =
|
||||
| Zone "IO Cover (Bottom)" : Single |
|
||||
| Zone "LED_C2" : Single |
|
||||
\*-------------------------------------------------------------*/
|
||||
static gb_fusion2_layout it5702_45_device =
|
||||
static gb_fusion2_layout it5702_44_device =
|
||||
{
|
||||
&common_d_led1_zone,
|
||||
&common_d_led2_zone,
|
||||
@@ -5393,7 +5383,7 @@ static gb_fusion2_layout it5702_45_device =
|
||||
|
||||
static const gb_fusion2_device z690_aor_mstr_device =
|
||||
{
|
||||
&it5702_45_device,
|
||||
&it5702_44_device,
|
||||
0x017001DF,
|
||||
0,
|
||||
"Z690 AORUS MASTER",
|
||||
@@ -5409,7 +5399,7 @@ static const gb_fusion2_device z690_aor_mstr_device =
|
||||
| Zone "Board Accent (Right Side)" : Single |
|
||||
| Zone "LED_C2" : Single |
|
||||
\*-------------------------------------------------------------*/
|
||||
static gb_fusion2_layout it5702_46_device =
|
||||
static gb_fusion2_layout it5702_45_device =
|
||||
{
|
||||
&common_d_led1_zone,
|
||||
&common_d_led2_zone,
|
||||
@@ -5427,7 +5417,7 @@ static gb_fusion2_layout it5702_46_device =
|
||||
|
||||
static const gb_fusion2_device x570s_aor_elite_device =
|
||||
{
|
||||
&it5702_46_device,
|
||||
&it5702_45_device,
|
||||
0x0120015F,
|
||||
0,
|
||||
"X570S AORUS ELITE",
|
||||
@@ -5435,7 +5425,7 @@ static const gb_fusion2_device x570s_aor_elite_device =
|
||||
|
||||
static const gb_fusion2_device x570s_aor_elite_ax_device =
|
||||
{
|
||||
&it5702_46_device,
|
||||
&it5702_45_device,
|
||||
0x0120015F,
|
||||
0,
|
||||
"X570S AORUS ELITE AX",
|
||||
@@ -5443,7 +5433,7 @@ static const gb_fusion2_device x570s_aor_elite_ax_device =
|
||||
|
||||
static const gb_fusion2_device x570s_gmg_x_device =
|
||||
{
|
||||
&it5702_46_device,
|
||||
&it5702_45_device,
|
||||
0x0120015F,
|
||||
0,
|
||||
"X570S GAMING X",
|
||||
@@ -5458,7 +5448,7 @@ static const gb_fusion2_device x570s_gmg_x_device =
|
||||
| Zone "Aorus Logo" : Single |
|
||||
| Zone "LED_C2" : Single |
|
||||
\*-------------------------------------------------------------*/
|
||||
static gb_fusion2_layout it5702_47_device =
|
||||
static gb_fusion2_layout it5702_46_device =
|
||||
{
|
||||
&common_d_led1_zone,
|
||||
&common_d_led2_zone,
|
||||
@@ -5475,7 +5465,7 @@ static gb_fusion2_layout it5702_47_device =
|
||||
|
||||
static const gb_fusion2_device a520m_aor_elite_device =
|
||||
{
|
||||
&it5702_47_device,
|
||||
&it5702_46_device,
|
||||
0x0050005F,
|
||||
0,
|
||||
"A520M AORUS ELITE",
|
||||
@@ -6987,7 +6977,6 @@ static const gb_fusion2_device z890_aor_mstr_ai_top_5711_device =
|
||||
| Zone "ARGB_V2_1" : Linear |
|
||||
| Zone "ARGB_V2_2" : Linear |
|
||||
| Zone "ARGB_V2_3" : Linear |
|
||||
| Zone "ARGB_V2_4" : Linear |
|
||||
| Zone "LED_C" : Single |
|
||||
| Zone "WIFI Antenna" : Single |
|
||||
| Zone "IO Cover" : Single |
|
||||
@@ -6998,7 +6987,6 @@ static gb_fusion2_layout it5711_14_device =
|
||||
&common_argb_v2_1_zone,
|
||||
&common_argb_v2_2_zone,
|
||||
&common_argb_v2_3_zone,
|
||||
&common_argb_v2_4_zone,
|
||||
&common_led_c_5_zone,
|
||||
&common_wifi_ant_9_zone,
|
||||
&common_io_cov_10_zone,
|
||||
@@ -7007,6 +6995,7 @@ static gb_fusion2_layout it5711_14_device =
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
};
|
||||
|
||||
static const gb_fusion2_device x870e_aor_xtrm_ai_top_5711_device =
|
||||
@@ -7393,6 +7382,8 @@ const gb_fusion2_device* gb_fusion2_device_list_data[] =
|
||||
&b550_gmg_x_v2_device,
|
||||
&b550_vision_d_device,
|
||||
&b550_vision_dp_device,
|
||||
&b550_ud_ac_device,
|
||||
&b550_ud_ac_y1_device,
|
||||
&b550i_aor_pro_ax_device,
|
||||
&b550m_aor_elite_device,
|
||||
&b550m_aor_elite_ax_device,
|
||||
|
||||
@@ -575,7 +575,7 @@ void RGBController_RGBFusion2USB::SetupZones()
|
||||
continue;
|
||||
}
|
||||
|
||||
bool fixed_zone = (zone_at_idx->leds_min == zone_at_idx->leds_max);
|
||||
bool fixed_zone = (zone_at_idx->leds_min == 1 && zone_at_idx->leds_max == 1);
|
||||
|
||||
const Gen2StripInfo* gen2_info = nullptr;
|
||||
|
||||
|
||||
@@ -182,4 +182,5 @@ REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 3090 Gaming OC",
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4060 Gaming OC", DetectGigabyteRGBFusionGPUControllers, NVIDIA_VEN, NVIDIA_RTX4060_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4060_GAMING_OC_8G_SUB_DEV, 0x55);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4060 Ti Gaming OC", DetectGigabyteRGBFusionGPUControllers, NVIDIA_VEN, NVIDIA_RTX4060TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4060TI_GAMING_OC_8G_SUB_DEV, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4060 Ti Gaming OC", DetectGigabyteRGBFusionGPUControllers, NVIDIA_VEN, NVIDIA_RTX4060TI_16G_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4060TI_GAMING_OC_16G_SUB_DEV, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4060 Ti AERO OC", DetectGigabyteRGBFusionGPUControllers, NVIDIA_VEN, NVIDIA_RTX4060TI_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4060TI_AERO_OC_16G_SUB_DEV, 0x71);
|
||||
REGISTER_I2C_PCI_DETECTOR("Gigabyte GeForce RTX 4070 Ti SUPER EAGLE OC", DetectGigabyteRGBFusionGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TIS_DEV, GIGABYTE_SUB_VEN, GIGABYTE_RTX4070TIS_EAGLE_OC_16G_SUB_DEV, 0x71);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user