Compare commits
159
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 |
+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]
|
||||
|
||||
|
||||
@@ -149,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)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
@@ -169,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);
|
||||
};
|
||||
|
||||
@@ -11,16 +11,16 @@
|
||||
|
||||
#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
|
||||
// \*-------------------------------------------------------------------*/
|
||||
/**------------------------------------------------------------------*\
|
||||
@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)
|
||||
{
|
||||
@@ -72,7 +72,7 @@ RGBController_AcerNitroHidKeyboard::RGBController_AcerNitroHidKeyboard(std::shar
|
||||
Breathing.speed_min = 1;
|
||||
Breathing.speed_max = 9;
|
||||
Breathing.speed = 4;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.colors.resize(1);
|
||||
|
||||
modes.push_back(Breathing);
|
||||
|
||||
@@ -86,7 +86,7 @@ RGBController_AcerNitroHidKeyboard::RGBController_AcerNitroHidKeyboard(std::shar
|
||||
Neon.brightness = 100;
|
||||
Neon.speed_min = 1;
|
||||
Neon.speed_max = 9;
|
||||
Neon.speed = 4;
|
||||
Neon.speed = 4;
|
||||
|
||||
modes.push_back(Neon);
|
||||
|
||||
@@ -104,7 +104,7 @@ RGBController_AcerNitroHidKeyboard::RGBController_AcerNitroHidKeyboard(std::shar
|
||||
Wave.direction = 0;
|
||||
|
||||
modes.push_back(Wave);
|
||||
|
||||
|
||||
mode Shifting;
|
||||
Shifting.name = "Shifting";
|
||||
Shifting.value = ACER_HID_MODE_SHIFTING;
|
||||
@@ -199,15 +199,15 @@ void RGBController_AcerNitroHidKeyboard::SetupZones()
|
||||
void RGBController_AcerNitroHidKeyboard::DeviceUpdateLEDs()
|
||||
{
|
||||
mode& current_mode = modes[active_mode];
|
||||
if(current_mode.value == ACER_HID_MODE_DIRECT)
|
||||
if(current_mode.value == ACER_HID_MODE_DIRECT)
|
||||
{
|
||||
controller->SetLEDs(colors, current_mode.brightness, device_id);
|
||||
}
|
||||
else
|
||||
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)
|
||||
if((modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR) && modes[active_mode].direction)
|
||||
{
|
||||
direction = 2;
|
||||
}
|
||||
|
||||
@@ -11,16 +11,16 @@
|
||||
|
||||
#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
|
||||
// \*-------------------------------------------------------------------*/
|
||||
/**------------------------------------------------------------------*\
|
||||
@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)
|
||||
{
|
||||
@@ -108,27 +108,27 @@ void RGBController_AcerNitroHidLed::SetupZones()
|
||||
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)
|
||||
if(current_mode.value == ACER_HID_MODE_DIRECT)
|
||||
{
|
||||
controller->SetLEDs(colors, current_mode.brightness, device_id);
|
||||
}
|
||||
else
|
||||
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)
|
||||
if((modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR) && modes[active_mode].direction)
|
||||
{
|
||||
direction = 2;
|
||||
}
|
||||
|
||||
@@ -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,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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -427,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;
|
||||
};
|
||||
@@ -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;
|
||||
};
|
||||
+1
@@ -145,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"
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -12,6 +12,18 @@
|
||||
#include "GigabyteSuperIORGBController.h"
|
||||
#include "super_io.h"
|
||||
|
||||
void GigabyteSuperIOEnter(int sioaddr)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| ITE8620 Ambient LED Extended Function Mode sequence |
|
||||
\*-----------------------------------------------------*/
|
||||
superio_enter(sioaddr);
|
||||
superio_inb(sioaddr, GIGABYTE_SUPERIO_EXTENDED_FUNCTION_ENTRY_1);
|
||||
superio_inb(sioaddr, GIGABYTE_SUPERIO_EXTENDED_FUNCTION_ENTRY_2);
|
||||
superio_inb(sioaddr, GIGABYTE_SUPERIO_EXTENDED_FUNCTION_ENTRY_3);
|
||||
superio_inb(sioaddr, GIGABYTE_SUPERIO_EXTENDED_FUNCTION_ENTRY_4);
|
||||
}
|
||||
|
||||
GigabyteSuperIORGBController::GigabyteSuperIORGBController(int sioaddr, std::string dev_name)
|
||||
{
|
||||
gig_sioaddr = sioaddr;
|
||||
@@ -40,10 +52,7 @@ void GigabyteSuperIORGBController::ChipEntry()
|
||||
/*--------------------------------*\
|
||||
| Chip Entry Command |
|
||||
\*_-------------------------------*/
|
||||
superio_enter(gig_sioaddr);
|
||||
superio_outb(gig_sioaddr, GIGABYTE_SUPERIO_CHIPENTRY_REGISTER_1, GIGABYTE_SUPERIO_CHIPENTRY_VALUE_1);
|
||||
superio_outb(gig_sioaddr, GIGABYTE_SUPERIO_CHIPENTRY_REGISTER_2, GIGABYTE_SUPERIO_CHIPENTRY_VALUE_2);
|
||||
superio_outb(gig_sioaddr, GIGABYTE_SUPERIO_CHIPENTRY_REGISTER_2, GIGABYTE_SUPERIO_CHIPENTRY_VALUE_2);
|
||||
GigabyteSuperIOEnter(gig_sioaddr);
|
||||
|
||||
/*--------------------------------*\
|
||||
| Chip Select Command |
|
||||
|
||||
@@ -15,6 +15,14 @@
|
||||
|
||||
enum
|
||||
{
|
||||
/*-----------------------------------*\
|
||||
| Extended Function Mode Entry Values |
|
||||
\*_----------------------------------*/
|
||||
GIGABYTE_SUPERIO_EXTENDED_FUNCTION_ENTRY_1 = 0x87,
|
||||
GIGABYTE_SUPERIO_EXTENDED_FUNCTION_ENTRY_2 = 0x01,
|
||||
GIGABYTE_SUPERIO_EXTENDED_FUNCTION_ENTRY_3 = 0x55,
|
||||
GIGABYTE_SUPERIO_EXTENDED_FUNCTION_ENTRY_4 = 0x55,
|
||||
|
||||
/*--------------------------------*\
|
||||
| Chip Entry Registers and Values |
|
||||
\*_-------------------------------*/
|
||||
@@ -129,6 +137,8 @@ enum
|
||||
|
||||
};
|
||||
|
||||
void GigabyteSuperIOEnter(int sioaddr);
|
||||
|
||||
class GigabyteSuperIORGBController
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -24,7 +24,8 @@ typedef struct
|
||||
|
||||
static gig_device compatible_devices[] =
|
||||
{
|
||||
{"X570 UD"}
|
||||
{"X570 UD"},
|
||||
{"Z390 DESIGNARE-CF"}
|
||||
};
|
||||
|
||||
DetectedControllers DetectGigabyteSuperIORGBControllers()
|
||||
@@ -41,12 +42,13 @@ DetectedControllers DetectGigabyteSuperIORGBControllers()
|
||||
{
|
||||
int sioaddr = sio_addrs[sioaddr_idx];
|
||||
|
||||
superio_enter(sioaddr);
|
||||
GigabyteSuperIOEnter(sioaddr);
|
||||
|
||||
int val = (superio_inb(sioaddr, SIO_REG_DEVID) << 8) | superio_inb(sioaddr, SIO_REG_DEVID + 1);
|
||||
|
||||
switch(val & SIO_ID_MASK)
|
||||
{
|
||||
case SIO_ITE8620_ID:
|
||||
case SIO_ITE8688_ID:
|
||||
for(unsigned int i = 0; i < NUM_COMPATIBLE_DEVICES; i++)
|
||||
{
|
||||
|
||||
@@ -270,6 +270,33 @@ void GoveeController::SendRazerEnable()
|
||||
port.udp_write((char *)command_str.c_str(), (int)command_str.length() + 1);
|
||||
}
|
||||
|
||||
void GoveeController::SetBrightness(unsigned int brightness)
|
||||
{
|
||||
json command;
|
||||
|
||||
command["msg"]["cmd"] = "brightness";
|
||||
command["msg"]["data"]["value"] = std::min(brightness, 100u);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Convert the JSON object to a string and write it |
|
||||
\*-----------------------------------------------------*/
|
||||
std::string command_str = command.dump();
|
||||
|
||||
port.udp_write((char *)command_str.c_str(), (int)command_str.length() + 1);
|
||||
}
|
||||
|
||||
void GoveeController::SetPower(bool enabled)
|
||||
{
|
||||
json command;
|
||||
|
||||
command["msg"]["cmd"] = "turn";
|
||||
command["msg"]["data"]["value"] = enabled ? 1 : 0;
|
||||
|
||||
std::string command_str = command.dump();
|
||||
|
||||
port.udp_write((char *)command_str.c_str(), (int)command_str.length() + 1);
|
||||
}
|
||||
|
||||
void GoveeController::SendScan()
|
||||
{
|
||||
json command;
|
||||
|
||||
@@ -35,7 +35,9 @@ public:
|
||||
|
||||
void SendScan();
|
||||
|
||||
void SetBrightness(unsigned int brightness);
|
||||
void SetColor(unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SetPower(bool enabled);
|
||||
|
||||
private:
|
||||
std::string firmware_version;
|
||||
|
||||
@@ -20,22 +20,33 @@ struct GoveeHardwareInfo
|
||||
{
|
||||
unsigned int led_count;
|
||||
unsigned int matrix_row_len; // 0 = linear
|
||||
bool supports_razer;
|
||||
};
|
||||
|
||||
const unsigned int GOVEE_FALLBACK_LED_COUNT = 20;
|
||||
const unsigned int GOVEE_FALLBACK_LED_COUNT = 1;
|
||||
|
||||
static std::map<std::string, GoveeHardwareInfo> govee_hardware_info
|
||||
{
|
||||
{ "H6022", { 132, 12 } }, // Govee Smart Table Lamp 2
|
||||
{ "H612F", { 12, 0 } }, // Govee Strip Light S (3m)
|
||||
{ "H619A", { 20, 0 } }, // Govee RGBIC Led Strip Lights
|
||||
{ "H70B1", { 20, 0 } }, // Govee LED Curtain Lights
|
||||
{ "H607C", { 174, 0 } }, // Govee Floor Lamp 2
|
||||
{ "H6022", { 132, 12, true } }, // Govee Smart Table Lamp 2
|
||||
{ "H612F", { 12, 0, true } }, // Govee Strip Light S (3m)
|
||||
{ "H619A", { 20, 0, true } }, // Govee RGBIC Led Strip Lights
|
||||
{ "H70B1", { 20, 0, true } }, // Govee LED Curtain Lights
|
||||
{ "H607C", { 174, 0, true } }, // Govee Floor Lamp 2
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GOVEE_MODE_STATIC = 0,
|
||||
GOVEE_MODE_DIRECT = 1,
|
||||
};
|
||||
|
||||
RGBController_Govee::RGBController_Govee(GoveeController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
controller = controller_ptr;
|
||||
last_static_color = 0;
|
||||
last_static_brightness = 0;
|
||||
razer_supported = false;
|
||||
static_initialized = false;
|
||||
|
||||
name = "Govee " + controller->GetSku();
|
||||
vendor = "Govee";
|
||||
@@ -45,25 +56,32 @@ RGBController_Govee::RGBController_Govee(GoveeController* controller_ptr)
|
||||
version = controller->GetVersion();
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = 1;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.name = "Static";
|
||||
Static.value = GOVEE_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.brightness_min = 0;
|
||||
Static.brightness_max = 100;
|
||||
Static.brightness = 100;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = GOVEE_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Direct.brightness_min = 0;
|
||||
Direct.brightness_max = 100;
|
||||
Direct.brightness = 100;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
|
||||
keepalive_thread_run = 1;
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
keepalive_thread = new std::thread(&RGBController_Govee::KeepaliveThread, this);
|
||||
}
|
||||
|
||||
@@ -80,20 +98,19 @@ RGBController_Govee::~RGBController_Govee()
|
||||
|
||||
void RGBController_Govee::SetupZones()
|
||||
{
|
||||
GoveeHardwareInfo hw = { GOVEE_FALLBACK_LED_COUNT, 0 };
|
||||
bool resizable = true;
|
||||
GoveeHardwareInfo hw = { GOVEE_FALLBACK_LED_COUNT, 0, false };
|
||||
|
||||
std::map<std::string, GoveeHardwareInfo>::iterator it = govee_hardware_info.find(controller->GetSku());
|
||||
if(it != govee_hardware_info.end())
|
||||
{
|
||||
hw = it->second;
|
||||
resizable = false;
|
||||
razer_supported = hw.supports_razer;
|
||||
}
|
||||
|
||||
zone strip;
|
||||
strip.leds_count = hw.led_count;
|
||||
strip.leds_min = resizable ? 0 : hw.led_count;
|
||||
strip.leds_max = resizable ? 255 : hw.led_count;
|
||||
strip.leds_min = hw.led_count;
|
||||
strip.leds_max = hw.led_count;
|
||||
|
||||
if(hw.matrix_row_len == 0)
|
||||
{
|
||||
@@ -171,14 +188,40 @@ void RGBController_Govee::DeviceConfigureZone(int zone_idx)
|
||||
|
||||
void RGBController_Govee::DeviceUpdateLEDs()
|
||||
{
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_PER_LED)
|
||||
if(colors.empty())
|
||||
{
|
||||
if(!colors.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
const std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
|
||||
last_update_time = now;
|
||||
|
||||
const unsigned int brightness = modes[active_mode].brightness;
|
||||
|
||||
if(razer_supported)
|
||||
{
|
||||
controller->SendRazerData(&colors[0], (unsigned int)colors.size());
|
||||
controller->SetBrightness(brightness);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!static_initialized)
|
||||
{
|
||||
controller->SendRazerData(&colors[0], (unsigned int)colors.size());
|
||||
controller->SetPower(true);
|
||||
}
|
||||
|
||||
controller->SetColor
|
||||
(
|
||||
RGBGetRValue(colors[0]),
|
||||
RGBGetGValue(colors[0]),
|
||||
RGBGetBValue(colors[0])
|
||||
);
|
||||
|
||||
controller->SetBrightness(brightness);
|
||||
|
||||
last_static_color = colors[0];
|
||||
last_static_brightness = brightness;
|
||||
static_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,28 +237,59 @@ void RGBController_Govee::DeviceUpdateSingleLED(int /*led*/)
|
||||
|
||||
void RGBController_Govee::DeviceUpdateMode()
|
||||
{
|
||||
if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC)
|
||||
if(modes[active_mode].value == GOVEE_MODE_STATIC)
|
||||
{
|
||||
unsigned char red = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
unsigned char grn = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
unsigned char blu = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
controller->SetColor(red, grn, blu);
|
||||
UpdateStatic(false);
|
||||
}
|
||||
else
|
||||
else if(modes[active_mode].value == GOVEE_MODE_DIRECT)
|
||||
{
|
||||
controller->SendRazerEnable();
|
||||
if(razer_supported)
|
||||
{
|
||||
controller->SendRazerEnable();
|
||||
}
|
||||
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_Govee::UpdateStatic(bool force)
|
||||
{
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
|
||||
const RGBColor color = modes[active_mode].colors[0];
|
||||
const unsigned int brightness = modes[active_mode].brightness;
|
||||
|
||||
if(force || !static_initialized || (color != last_static_color))
|
||||
{
|
||||
controller->SetPower(true);
|
||||
controller->SetColor(RGBGetRValue(color), RGBGetGValue(color), RGBGetBValue(color));
|
||||
last_static_color = color;
|
||||
}
|
||||
|
||||
if(force || !static_initialized || (brightness != last_static_brightness))
|
||||
{
|
||||
controller->SetBrightness(brightness);
|
||||
last_static_brightness = brightness;
|
||||
}
|
||||
|
||||
static_initialized = true;
|
||||
}
|
||||
|
||||
void RGBController_Govee::KeepaliveThread()
|
||||
{
|
||||
while(keepalive_thread_run.load())
|
||||
{
|
||||
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::seconds(30))
|
||||
const std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
|
||||
|
||||
if((now - last_update_time) > std::chrono::seconds(30))
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
if(modes[active_mode].value == GOVEE_MODE_STATIC)
|
||||
{
|
||||
UpdateStatic(true);
|
||||
}
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(10s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,8 +32,14 @@ public:
|
||||
void KeepaliveThread();
|
||||
|
||||
private:
|
||||
void UpdateStatic(bool force);
|
||||
|
||||
GoveeController* controller;
|
||||
std::thread* keepalive_thread;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
|
||||
RGBColor last_static_color;
|
||||
unsigned int last_static_brightness;
|
||||
bool razer_supported;
|
||||
bool static_initialized;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,344 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HIDLampArrayController.cpp |
|
||||
| |
|
||||
| Driver for HID LampArray Devices |
|
||||
| |
|
||||
| Adam Honse ([email protected]) 26 Mar 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include "hid_util.h"
|
||||
#include "HIDLampArrayController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
HIDLampArrayController::HIDLampArrayController(hid_device *dev_handle, const char *path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Parse report IDs from descriptor |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned int curr_collection_usage = 0;
|
||||
unsigned char data_len = 0;
|
||||
unsigned char key = 0;
|
||||
unsigned char key_cmd = 0;
|
||||
unsigned char key_size = 0;
|
||||
unsigned int pos = 0;
|
||||
unsigned char report_descriptor[HID_API_MAX_REPORT_DESCRIPTOR_SIZE];
|
||||
unsigned char report_id = 0;
|
||||
unsigned int size = hid_get_report_descriptor(dev, report_descriptor, sizeof(report_descriptor));
|
||||
unsigned int usage = 0;
|
||||
unsigned char usage_page = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Create a list of usages and their report IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
std::unordered_map<unsigned int, unsigned int> usage_to_report_id;
|
||||
|
||||
while(pos < size)
|
||||
{
|
||||
get_hid_item_size(report_descriptor, size, pos, &data_len, &key_size);
|
||||
|
||||
key = report_descriptor[pos];
|
||||
key_cmd = key & 0xFC;
|
||||
|
||||
switch(key)
|
||||
{
|
||||
case 0xA1:
|
||||
curr_collection_usage = usage;
|
||||
if(usage_page == 0x59 && report_id)
|
||||
{
|
||||
usage_to_report_id[curr_collection_usage] = report_id;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xC0:
|
||||
curr_collection_usage = 0;
|
||||
report_id = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(key_cmd)
|
||||
{
|
||||
case 0x4:
|
||||
usage_page = get_hid_report_bytes(report_descriptor, size, data_len, pos);
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
usage = get_hid_report_bytes(report_descriptor, size, data_len, pos);
|
||||
if(data_len == 4)
|
||||
{
|
||||
int local_usage_page = usage >> 16;
|
||||
usage &= 0x0000FFFF;
|
||||
if (local_usage_page == 0x59 && report_id)
|
||||
{
|
||||
usage_to_report_id[usage] = report_id;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x84:
|
||||
report_id = get_hid_report_bytes(report_descriptor, size, data_len, pos);
|
||||
if (usage_page == 0x59 && curr_collection_usage)
|
||||
{
|
||||
usage_to_report_id[curr_collection_usage] = report_id;
|
||||
}
|
||||
break;
|
||||
}
|
||||
pos += data_len + key_size;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get the report IDs for each report |
|
||||
\*-----------------------------------------------------*/
|
||||
for(const std::pair<const unsigned int, unsigned int>& pair : usage_to_report_id)
|
||||
{
|
||||
switch(pair.first)
|
||||
{
|
||||
case 0x02:
|
||||
ids.LampArrayAttributesReportID = pair.second;
|
||||
break;
|
||||
|
||||
case 0x20:
|
||||
ids.LampAttributesRequestReportID = pair.second;
|
||||
break;
|
||||
|
||||
case 0x22:
|
||||
ids.LampAttributesResponseReportID = pair.second;
|
||||
break;
|
||||
|
||||
case 0x50:
|
||||
ids.LampMultiUpdateReportID = pair.second;
|
||||
break;
|
||||
|
||||
case 0x60:
|
||||
ids.LampRangeUpdateReportID = pair.second;
|
||||
break;
|
||||
|
||||
case 0x70:
|
||||
ids.LampArrayControlReportID = pair.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| If reports are missing, return |
|
||||
\*-----------------------------------------------------*/
|
||||
bool report_missing = (ids.LampArrayAttributesReportID == 0)
|
||||
|| (ids.LampAttributesRequestReportID == 0)
|
||||
|| (ids.LampAttributesResponseReportID == 0)
|
||||
|| (ids.LampMultiUpdateReportID == 0)
|
||||
|| (ids.LampRangeUpdateReportID == 0)
|
||||
|| (ids.LampArrayControlReportID == 0);
|
||||
|
||||
if(report_missing)
|
||||
{
|
||||
LampArray.LampCount = 0;
|
||||
LampArray.LampArrayKind = HID_LAMPARRAY_KIND_UNDEFINED;
|
||||
return;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get LampArrayAttributesReport |
|
||||
\*-----------------------------------------------------*/
|
||||
GetLampArrayAttributesReport();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set LampAttributesRequestReport for LampId 0 |
|
||||
\*-----------------------------------------------------*/
|
||||
SetLampAttributesRequestReport(0);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get LampAttributesResponseReport for each LampId |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int LampId = 0; LampId < LampArray.LampCount; LampId++)
|
||||
{
|
||||
GetLampAttributesResponseReport();
|
||||
}
|
||||
}
|
||||
|
||||
HIDLampArrayController::~HIDLampArrayController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string HIDLampArrayController::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string HIDLampArrayController::GetDeviceName()
|
||||
{
|
||||
wchar_t name_string[128];
|
||||
int ret = hid_get_product_string(dev, name_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(name_string));
|
||||
}
|
||||
|
||||
std::string HIDLampArrayController::GetDeviceSerial()
|
||||
{
|
||||
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 HIDLampArrayController::GetDeviceVendor()
|
||||
{
|
||||
wchar_t vendor_string[128];
|
||||
int ret = hid_get_manufacturer_string(dev, vendor_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(vendor_string));
|
||||
}
|
||||
|
||||
unsigned int HIDLampArrayController::GetLampArrayKind()
|
||||
{
|
||||
return(LampArray.LampArrayKind);
|
||||
}
|
||||
|
||||
unsigned int HIDLampArrayController::GetLampCount()
|
||||
{
|
||||
return(LampArray.LampCount);
|
||||
}
|
||||
|
||||
std::vector<LampAttributes> HIDLampArrayController::GetLamps()
|
||||
{
|
||||
return(Lamps);
|
||||
}
|
||||
|
||||
void HIDLampArrayController::GetLampArrayAttributesReport()
|
||||
{
|
||||
unsigned char usb_buf[sizeof(LampArrayAttributes) + 1];
|
||||
|
||||
memset(usb_buf, 0, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| First byte is the report ID |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0] = ids.LampArrayAttributesReportID;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get the report |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_get_feature_report(dev, usb_buf, sizeof(usb_buf));
|
||||
|
||||
memcpy(&LampArray, &usb_buf[1], sizeof(LampArray));
|
||||
}
|
||||
|
||||
void HIDLampArrayController::GetLampAttributesResponseReport()
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
LampAttributes attributes;
|
||||
|
||||
memset(usb_buf, 0, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| First byte is the report ID |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0] = ids.LampAttributesResponseReportID;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get the report |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_get_feature_report(dev, usb_buf, sizeof(usb_buf));
|
||||
|
||||
memcpy(&attributes, &usb_buf[1], sizeof(attributes));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Store the attributes |
|
||||
\*-----------------------------------------------------*/
|
||||
Lamps.push_back(attributes);
|
||||
}
|
||||
|
||||
void HIDLampArrayController::SetLampArrayControlReport(unsigned char AutonomousMode)
|
||||
{
|
||||
unsigned char usb_buf[sizeof(LampArrayControl) + 1];
|
||||
|
||||
memset(usb_buf, 0, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| First byte is the report ID |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0] = ids.LampArrayControlReportID;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in control data |
|
||||
\*-----------------------------------------------------*/
|
||||
((LampArrayControl *)&usb_buf[1])->AutonomousMode = AutonomousMode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send the report |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, usb_buf, sizeof(usb_buf));
|
||||
}
|
||||
|
||||
void HIDLampArrayController::SetLampAttributesRequestReport(unsigned short LampId)
|
||||
{
|
||||
unsigned char usb_buf[sizeof(LampAttributesRequest) + 1];
|
||||
|
||||
memset(usb_buf, 0, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| First byte is the report ID |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0] = ids.LampAttributesRequestReportID;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in request data |
|
||||
\*-----------------------------------------------------*/
|
||||
((LampAttributesRequest *)&usb_buf[1])->LampId = LampId;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send the report |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, usb_buf, sizeof(usb_buf));
|
||||
}
|
||||
|
||||
void HIDLampArrayController::SetLampMultiUpdateReport(unsigned char LampCount, unsigned char LampUpdateFlags, unsigned short * LampIds, LampArrayColor * UpdateColors)
|
||||
{
|
||||
unsigned char usb_buf[sizeof(LampMultiUpdate) + 1];
|
||||
|
||||
memset(usb_buf, 0, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| First byte is the report ID |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0] = ids.LampMultiUpdateReportID;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Fill in multi update data |
|
||||
\*-----------------------------------------------------*/
|
||||
((LampMultiUpdate *)&usb_buf[1])->LampCount = LampCount;
|
||||
((LampMultiUpdate *)&usb_buf[1])->LampUpdateFlags = LampUpdateFlags;
|
||||
|
||||
for(unsigned char LampId = 0; LampId < LampCount; LampId++)
|
||||
{
|
||||
((LampMultiUpdate *)&usb_buf[1])->LampIds[LampId] = LampIds[LampId];
|
||||
((LampMultiUpdate *)&usb_buf[1])->UpdateColors[LampId] = UpdateColors[LampId];
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send the report |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_send_feature_report(dev, usb_buf, sizeof(usb_buf));
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HIDLampArrayController.h |
|
||||
| |
|
||||
| Driver for HID LampArray Devices |
|
||||
| |
|
||||
| Adam Honse ([email protected]) 26 Mar 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
|
||||
#include "RGBController.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Struct packing macro for GCC and MSVC |
|
||||
\*---------------------------------------------------------*/
|
||||
#ifdef __GNUC__
|
||||
#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
|
||||
#endif
|
||||
|
||||
PACK(struct LampArrayAttributes
|
||||
{
|
||||
unsigned short LampCount;
|
||||
unsigned int BoundingBoxWidthInMicrometers;
|
||||
unsigned int BoundingBoxHeightInMicrometers;
|
||||
unsigned int BoundingBoxDepthInMicrometers;
|
||||
unsigned int LampArrayKind;
|
||||
unsigned int MinUpdateIntervalInMilliseconds;
|
||||
});
|
||||
|
||||
PACK(struct LampArrayColor
|
||||
{
|
||||
unsigned char RedChannel;
|
||||
unsigned char GreenChannel;
|
||||
unsigned char BlueChannel;
|
||||
unsigned char IntensityChannel;
|
||||
});
|
||||
|
||||
PACK(struct LampArrayControl
|
||||
{
|
||||
unsigned char AutonomousMode;
|
||||
});
|
||||
|
||||
PACK(struct LampAttributes
|
||||
{
|
||||
unsigned short LampId;
|
||||
unsigned int PositionXInMicrometers;
|
||||
unsigned int PositionYInMicrometers;
|
||||
unsigned int PositionZInMicrometers;
|
||||
unsigned int UpdateLatencyInMilliseconds;
|
||||
unsigned int LampPurposes;
|
||||
unsigned char RedLevelCount;
|
||||
unsigned char GreenLevelCount;
|
||||
unsigned char BlueLevelCount;
|
||||
unsigned char IntensityLevelCount;
|
||||
unsigned char IsProgrammable;
|
||||
unsigned char LampKey;
|
||||
});
|
||||
|
||||
PACK(struct LampAttributesRequest
|
||||
{
|
||||
unsigned short LampId;
|
||||
});
|
||||
|
||||
#define LAMP_MULTI_UPDATE_LAMP_COUNT 8
|
||||
#define LAMP_UPDATE_FLAG_UPDATE_COMPLETE 1
|
||||
PACK(struct LampMultiUpdate
|
||||
{
|
||||
unsigned char LampCount;
|
||||
unsigned char LampUpdateFlags;
|
||||
unsigned short LampIds[LAMP_MULTI_UPDATE_LAMP_COUNT];
|
||||
LampArrayColor UpdateColors[LAMP_MULTI_UPDATE_LAMP_COUNT];
|
||||
});
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char LampArrayAttributesReportID;
|
||||
unsigned char LampAttributesRequestReportID;
|
||||
unsigned char LampAttributesResponseReportID;
|
||||
unsigned char LampMultiUpdateReportID;
|
||||
unsigned char LampRangeUpdateReportID;
|
||||
unsigned char LampArrayControlReportID;
|
||||
} HIDLampArrayReportIDs;
|
||||
|
||||
enum
|
||||
{
|
||||
HID_LAMPARRAY_KIND_UNDEFINED = 0x00, /* Undefined */
|
||||
HID_LAMPARRAY_KIND_KEYBOARD = 0x01, /* LampArrayKindKeyboard */
|
||||
HID_LAMPARRAY_KIND_MOUSE = 0x02, /* LampArrayKindMouse */
|
||||
HID_LAMPARRAY_KIND_GAME_CONTROLLER = 0x03, /* LampArrayKindGameController */
|
||||
HID_LAMPARRAY_KIND_PERIPHERAL = 0x04, /* LampArrayKindPeripheral */
|
||||
HID_LAMPARRAY_KIND_SCENE = 0x05, /* LampArrayKindScene */
|
||||
HID_LAMPARRAY_KIND_NOTIFICATION = 0x06, /* LampArrayKindNotification */
|
||||
HID_LAMPARRAY_KIND_CHASSIS = 0x07, /* LampArrayKindChassis */
|
||||
HID_LAMPARRAY_KIND_WEARABLE = 0x08, /* LampArrayKindWearable */
|
||||
HID_LAMPARRAY_KIND_FURNITURE = 0x09, /* LampArrayKindFurniture */
|
||||
HID_LAMPARRAY_KIND_ART = 0x0A, /* LampArrayKindArt */
|
||||
};
|
||||
|
||||
class HIDLampArrayController
|
||||
{
|
||||
public:
|
||||
HIDLampArrayController(hid_device *dev_handle, const char *path);
|
||||
~HIDLampArrayController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
std::string GetDeviceSerial();
|
||||
std::string GetDeviceVendor();
|
||||
|
||||
unsigned int GetLampArrayKind();
|
||||
unsigned int GetLampCount();
|
||||
std::vector<LampAttributes> GetLamps();
|
||||
|
||||
void SetLampArrayControlReport(unsigned char AutonomousMode);
|
||||
void SetLampMultiUpdateReport(unsigned char LampCount, unsigned char LampUpdateFlags, unsigned short * LampIds, LampArrayColor * UpdateColors);
|
||||
|
||||
private:
|
||||
hid_device * dev;
|
||||
HIDLampArrayReportIDs ids;
|
||||
std::string location;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Vector to store lamp attributes for each lamp |
|
||||
\*-----------------------------------------------------*/
|
||||
std::vector<LampAttributes> Lamps;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Parameters from LampArrayAttributesReport |
|
||||
\*-----------------------------------------------------*/
|
||||
LampArrayAttributes LampArray;
|
||||
|
||||
void GetLampArrayAttributesReport();
|
||||
void GetLampAttributesResponseReport();
|
||||
void SetLampAttributesRequestReport(unsigned short LampId);
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| HIDLampArrayControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for HID LampArray Devices |
|
||||
| |
|
||||
| Adam Honse ([email protected]) 26 Mar 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "DetectionManager.h"
|
||||
#include "HIDLampArrayController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_HIDLampArray.h"
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
|
||||
DetectedControllers DetectHIDLampArrayControllers(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
HIDLampArrayController* controller = new HIDLampArrayController(dev, info->path);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Only create the RGBController if there are lamps |
|
||||
| detected in the controller. Otherwise, delete |
|
||||
| the controller. |
|
||||
\*-------------------------------------------------*/
|
||||
if(controller->GetLampCount() > 0)
|
||||
{
|
||||
RGBController_HIDLampArray* rgb_controller = new RGBController_HIDLampArray(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_PU_ONLY("HID LampArray Device", DetectHIDLampArrayControllers, 0x59, 0x01);
|
||||
@@ -0,0 +1,429 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_HIDLampArray.cpp |
|
||||
| |
|
||||
| RGBController for HID LampArray Devices |
|
||||
| |
|
||||
| Adam Honse ([email protected]) 26 Mar 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include <set>
|
||||
#include "RGBController_HIDLampArray.h"
|
||||
#include "RGBControllerKeyNames.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name HID LampArray Controllers
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@detectors DetectHIDLampArrayControllers
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_HIDLampArray::RGBController_HIDLampArray(HIDLampArrayController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
description = "HID LampArray Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetDeviceSerial();
|
||||
vendor = controller->GetDeviceVendor();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Determine device type from LampArray kind |
|
||||
\*-----------------------------------------------------*/
|
||||
switch(controller->GetLampArrayKind())
|
||||
{
|
||||
case HID_LAMPARRAY_KIND_UNDEFINED:
|
||||
default:
|
||||
type = DEVICE_TYPE_UNKNOWN;
|
||||
break;
|
||||
|
||||
case HID_LAMPARRAY_KIND_KEYBOARD:
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
break;
|
||||
|
||||
case HID_LAMPARRAY_KIND_MOUSE:
|
||||
type = DEVICE_TYPE_MOUSE;
|
||||
break;
|
||||
|
||||
case HID_LAMPARRAY_KIND_GAME_CONTROLLER:
|
||||
type = DEVICE_TYPE_GAMEPAD;
|
||||
break;
|
||||
|
||||
case HID_LAMPARRAY_KIND_PERIPHERAL:
|
||||
case HID_LAMPARRAY_KIND_SCENE:
|
||||
case HID_LAMPARRAY_KIND_NOTIFICATION:
|
||||
case HID_LAMPARRAY_KIND_CHASSIS:
|
||||
case HID_LAMPARRAY_KIND_WEARABLE:
|
||||
case HID_LAMPARRAY_KIND_FURNITURE:
|
||||
case HID_LAMPARRAY_KIND_ART:
|
||||
type = DEVICE_TYPE_ACCESSORY;
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
mode Autonomous;
|
||||
Autonomous.name = "Autonomous";
|
||||
Autonomous.value = 1;
|
||||
Autonomous.flags = 0;
|
||||
Autonomous.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Autonomous);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_HIDLampArray::~RGBController_HIDLampArray()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HID Usage Tables 1.6 -> 10 Keyboard/Keypad Page (0x07) |
|
||||
\*---------------------------------------------------------*/
|
||||
#define HID_KEYBOARD_USAGE_IDS_COUNT 0xE9
|
||||
|
||||
static const char *HIDUsageIDsToKeyNames[HID_KEYBOARD_USAGE_IDS_COUNT] =
|
||||
{
|
||||
KEY_EN_UNUSED, // Reserved
|
||||
KEY_EN_UNUSED, // Keyboard ErrorRollOver
|
||||
KEY_EN_UNUSED, // Keyboard POSTFail
|
||||
KEY_EN_UNUSED, // Keyboard ErrorUndefined
|
||||
KEY_EN_A, // Keyboard a and A
|
||||
KEY_EN_B, // Keyboard b and B
|
||||
KEY_EN_C, // Keyboard c and C
|
||||
KEY_EN_D, // Keyboard d and D
|
||||
KEY_EN_E, // Keyboard e and E
|
||||
KEY_EN_F, // Keyboard f and F
|
||||
KEY_EN_G, // Keyboard g and G
|
||||
KEY_EN_H, // Keyboard h and H
|
||||
KEY_EN_I, // Keyboard i and I
|
||||
KEY_EN_J, // Keyboard j and J
|
||||
KEY_EN_K, // Keyboard k and K
|
||||
KEY_EN_L, // Keyboard l and L
|
||||
KEY_EN_M, // Keyboard m and M
|
||||
KEY_EN_N, // Keyboard n and N
|
||||
KEY_EN_O, // Keyboard o and O
|
||||
KEY_EN_P, // Keyboard p and P
|
||||
KEY_EN_Q, // Keyboard q and Q
|
||||
KEY_EN_R, // Keyboard r and R
|
||||
KEY_EN_S, // Keyboard s and S
|
||||
KEY_EN_T, // Keyboard t and T
|
||||
KEY_EN_U, // Keyboard u and U
|
||||
KEY_EN_V, // Keyboard v and V
|
||||
KEY_EN_W, // Keyboard w and W
|
||||
KEY_EN_X, // Keyboard x and X
|
||||
KEY_EN_Y, // Keyboard y and Y
|
||||
KEY_EN_Z, // Keyboard z and Z
|
||||
KEY_EN_1, // Keyboard 1 and !
|
||||
KEY_EN_2, // Keyboard 2 and @
|
||||
KEY_EN_3, // Keyboard 3 and #
|
||||
KEY_EN_4, // Keyboard 4 and $
|
||||
KEY_EN_5, // Keyboard 5 and %
|
||||
KEY_EN_6, // Keyboard 6 and ∧
|
||||
KEY_EN_7, // Keyboard 7 and &
|
||||
KEY_EN_8, // Keyboard 8 and *
|
||||
KEY_EN_9, // Keyboard 9 and (
|
||||
KEY_EN_0, // Keyboard 0 and )
|
||||
KEY_EN_ANSI_ENTER, // Keyboard Return (ENTER)
|
||||
KEY_EN_ESCAPE, // Keyboard ESCAPE
|
||||
KEY_EN_BACKSPACE, // Keyboard DELETE (Backspace)
|
||||
KEY_EN_TAB, // Keyboard Tab
|
||||
KEY_EN_SPACE, // Keyboard Spacebar
|
||||
KEY_EN_MINUS, // Keyboard - and (underscore)
|
||||
KEY_EN_EQUALS, // Keyboard = and +
|
||||
KEY_EN_LEFT_BRACKET, // Keyboard [ and {
|
||||
KEY_EN_RIGHT_BRACKET, // Keyboard ] and }
|
||||
KEY_EN_BACK_SLASH, // Keyboard \ and |
|
||||
KEY_EN_POUND, // Keyboard Non-US # and ˜
|
||||
KEY_EN_SEMICOLON, // Keyboard ; and :
|
||||
KEY_EN_QUOTE, // Keyboard ‘ and “
|
||||
KEY_EN_BACK_TICK, // Keyboard Grave Accent and Tilde
|
||||
KEY_EN_COMMA, // Keyboard , and <
|
||||
KEY_EN_PERIOD, // Keyboard . and >
|
||||
KEY_EN_FORWARD_SLASH, // Keyboard / and ?
|
||||
KEY_EN_CAPS_LOCK, // Keyboard Caps Lock
|
||||
KEY_EN_F1, // Keyboard F1
|
||||
KEY_EN_F2, // Keyboard F2
|
||||
KEY_EN_F3, // Keyboard F3
|
||||
KEY_EN_F4, // Keyboard F4
|
||||
KEY_EN_F5, // Keyboard F5
|
||||
KEY_EN_F6, // Keyboard F6
|
||||
KEY_EN_F7, // Keyboard F7
|
||||
KEY_EN_F8, // Keyboard F8
|
||||
KEY_EN_F9, // Keyboard F9
|
||||
KEY_EN_F10, // Keyboard F10
|
||||
KEY_EN_F11, // Keyboard F11
|
||||
KEY_EN_F12, // Keyboard F12
|
||||
KEY_EN_PRINT_SCREEN, // Keyboard PrintScreen
|
||||
KEY_EN_SCROLL_LOCK, // Keyboard Scroll Lock
|
||||
KEY_EN_PAUSE_BREAK, // Keyboard Pause
|
||||
KEY_EN_INSERT, // Keyboard Insert
|
||||
KEY_EN_HOME, // Keyboard Home
|
||||
KEY_EN_PAGE_UP, // Keyboard PageUp
|
||||
KEY_EN_DELETE, // Keyboard Delete Forward
|
||||
KEY_EN_END, // Keyboard End
|
||||
KEY_EN_PAGE_DOWN, // Keyboard PageDown
|
||||
KEY_EN_RIGHT_ARROW, // Keyboard RightArrow
|
||||
KEY_EN_LEFT_ARROW, // Keyboard LeftArrow
|
||||
KEY_EN_DOWN_ARROW, // Keyboard DownArrow
|
||||
KEY_EN_UP_ARROW, // Keyboard UpArrow
|
||||
KEY_EN_NUMPAD_LOCK, // Keypad Num Lock and Clear
|
||||
KEY_EN_NUMPAD_DIVIDE, // Keypad /
|
||||
KEY_EN_NUMPAD_TIMES, // Keypad *
|
||||
KEY_EN_NUMPAD_MINUS, // Keypad -
|
||||
KEY_EN_NUMPAD_PLUS, // Keypad +
|
||||
KEY_EN_NUMPAD_ENTER, // Keypad ENTER
|
||||
KEY_EN_NUMPAD_1, // Keypad 1 and End
|
||||
KEY_EN_NUMPAD_2, // Keypad 2 and Down Arrow
|
||||
KEY_EN_NUMPAD_3, // Keypad 3 and PageDn
|
||||
KEY_EN_NUMPAD_4, // Keypad 4 and Left Arrow
|
||||
KEY_EN_NUMPAD_5, // Keypad 5
|
||||
KEY_EN_NUMPAD_6, // Keypad 6 and Right Arrow
|
||||
KEY_EN_NUMPAD_7, // Keypad 7 and Home
|
||||
KEY_EN_NUMPAD_8, // Keypad 8 and Up Arrow
|
||||
KEY_EN_NUMPAD_9, // Keypad 9 and PageUp
|
||||
KEY_EN_NUMPAD_0, // Keypad 0 and Insert
|
||||
KEY_EN_NUMPAD_PERIOD, // Keypad . and Delete
|
||||
KEY_EN_BACK_SLASH, // Keyboard Non-US \ and |
|
||||
KEY_EN_UNUSED, // Keyboard Application
|
||||
KEY_EN_POWER, // Keyboard Power
|
||||
KEY_EN_NUMPAD_EQUAL, // Keypad =
|
||||
KEY_EN_F13, // Keyboard F13
|
||||
KEY_EN_F14, // Keyboard F14
|
||||
KEY_EN_F15, // Keyboard F15
|
||||
KEY_EN_F16, // Keyboard F16
|
||||
KEY_EN_F17, // Keyboard F17
|
||||
KEY_EN_F18, // Keyboard F18
|
||||
KEY_EN_F19, // Keyboard F19
|
||||
KEY_EN_F20, // Keyboard F20
|
||||
KEY_EN_F21, // Keyboard F21
|
||||
KEY_EN_F22, // Keyboard F22
|
||||
KEY_EN_F23, // Keyboard F23
|
||||
KEY_EN_F24, // Keyboard F24
|
||||
KEY_EN_UNUSED, // Keyboard Execute
|
||||
KEY_EN_UNUSED, // Keyboard Help
|
||||
KEY_EN_MENU, // Keyboard Menu
|
||||
KEY_EN_UNUSED, // Keyboard Select
|
||||
KEY_EN_UNUSED, // Keyboard Stop
|
||||
KEY_EN_UNUSED, // Keyboard Again
|
||||
KEY_EN_UNUSED, // Keyboard Undo
|
||||
KEY_EN_UNUSED, // Keyboard Cut
|
||||
KEY_EN_UNUSED, // Keyboard Copy
|
||||
KEY_EN_UNUSED, // Keyboard Paste
|
||||
KEY_EN_UNUSED, // Keyboard Find
|
||||
KEY_EN_MEDIA_MUTE, // Keyboard Mute
|
||||
KEY_EN_MEDIA_VOLUME_UP, // Keyboard Volume Up
|
||||
KEY_EN_MEDIA_VOLUME_DOWN, // Keyboard Volume Down
|
||||
KEY_EN_UNUSED, // Keyboard Locking Caps Lock
|
||||
KEY_EN_UNUSED, // Keyboard Locking Num Lock
|
||||
KEY_EN_UNUSED, // Keyboard Locking Scroll Lock
|
||||
KEY_EN_NUMPAD_PERIOD, // Keypad Comma
|
||||
KEY_EN_NUMPAD_EQUAL, // Keypad Equal Sign
|
||||
KEY_JP_RO, // Keyboard International1
|
||||
KEY_JP_KANA, // Keyboard International2
|
||||
KEY_JP_YEN, // Keyboard International3
|
||||
KEY_JP_HENKAN, // Keyboard International4
|
||||
KEY_JP_MUHENKAN, // Keyboard International5
|
||||
KEY_EN_COMMA, // Keyboard International6
|
||||
KEY_JP_ZENKAKU, // Keyboard International7
|
||||
KEY_EN_UNUSED, // Keyboard International8
|
||||
KEY_EN_UNUSED, // Keyboard International9
|
||||
KEY_KR_HAN, // Keyboard LANG1
|
||||
KEY_KR_HANJA, // Keyboard LANG2
|
||||
KEY_JP_KATAKANA, // Keyboard LANG3
|
||||
KEY_JP_HIRAGANA, // Keyboard LANG4
|
||||
KEY_JP_ZENKAKU, // Keyboard LANG5
|
||||
KEY_EN_UNUSED, // Keyboard LANG6
|
||||
KEY_EN_UNUSED, // Keyboard LANG7
|
||||
KEY_EN_UNUSED, // Keyboard LANG8
|
||||
KEY_EN_UNUSED, // Keyboard LANG9
|
||||
KEY_EN_UNUSED, // Keyboard Alternate Erase
|
||||
KEY_EN_UNUSED, // Keyboard SysReq/Attention
|
||||
KEY_EN_UNUSED, // Keyboard Cancel
|
||||
KEY_EN_UNUSED, // Keyboard Clear
|
||||
KEY_EN_UNUSED, // Keyboard Prior
|
||||
KEY_EN_UNUSED, // Keyboard Return
|
||||
KEY_EN_UNUSED, // Keyboard Separator
|
||||
KEY_EN_UNUSED, // Keyboard Out
|
||||
KEY_EN_UNUSED, // Keyboard Oper
|
||||
KEY_EN_UNUSED, // Keyboard Clear/Again
|
||||
KEY_EN_UNUSED, // Keyboard CrSel/Props
|
||||
KEY_EN_UNUSED, // Keyboard ExSel
|
||||
KEY_EN_UNUSED, // AF Reserved
|
||||
KEY_EN_UNUSED, // Keypad 00
|
||||
KEY_EN_UNUSED, // Keypad 000
|
||||
KEY_EN_UNUSED, // Thousands Separator
|
||||
KEY_EN_UNUSED, // Decimal Separator
|
||||
KEY_EN_UNUSED, // Currency Unit
|
||||
KEY_EN_UNUSED, // Currency Sub-unit
|
||||
KEY_EN_UNUSED, // Keypad (
|
||||
KEY_EN_UNUSED, // Keypad )
|
||||
KEY_EN_UNUSED, // Keypad {
|
||||
KEY_EN_UNUSED, // Keypad }
|
||||
KEY_EN_UNUSED, // Keypad Tab
|
||||
KEY_EN_UNUSED, // Keypad Backspace
|
||||
KEY_EN_UNUSED, // Keypad A
|
||||
KEY_EN_UNUSED, // Keypad B
|
||||
KEY_EN_UNUSED, // Keypad C
|
||||
KEY_EN_UNUSED, // Keypad D
|
||||
KEY_EN_UNUSED, // Keypad E
|
||||
KEY_EN_UNUSED, // Keypad F
|
||||
KEY_EN_UNUSED, // Keypad XOR
|
||||
KEY_EN_UNUSED, // Keypad ∧
|
||||
KEY_EN_UNUSED, // Keypad %
|
||||
KEY_EN_UNUSED, // Keypad <
|
||||
KEY_EN_UNUSED, // Keypad >
|
||||
KEY_EN_UNUSED, // Keypad &
|
||||
KEY_EN_UNUSED, // Keypad &&
|
||||
KEY_EN_UNUSED, // Keypad |
|
||||
KEY_EN_UNUSED, // Keypad ||
|
||||
KEY_EN_UNUSED, // Keypad :
|
||||
KEY_EN_UNUSED, // Keypad #
|
||||
KEY_EN_UNUSED, // Keypad Space
|
||||
KEY_EN_UNUSED, // Keypad @
|
||||
KEY_EN_UNUSED, // Keypad !
|
||||
KEY_EN_UNUSED, // Keypad Memory Store
|
||||
KEY_EN_UNUSED, // Keypad Memory Recall
|
||||
KEY_EN_UNUSED, // Keypad Memory Clear
|
||||
KEY_EN_UNUSED, // Keypad Memory Add
|
||||
KEY_EN_UNUSED, // Keypad Memory Subtract
|
||||
KEY_EN_UNUSED, // Keypad Memory Multiply
|
||||
KEY_EN_UNUSED, // Keypad Memory Divide
|
||||
KEY_EN_UNUSED, // Keypad +/-
|
||||
KEY_EN_UNUSED, // Keypad Clear
|
||||
KEY_EN_UNUSED, // Keypad Clear Entry
|
||||
KEY_EN_UNUSED, // Keypad Binary
|
||||
KEY_EN_UNUSED, // Keypad Octal
|
||||
KEY_EN_UNUSED, // Keypad Decimal
|
||||
KEY_EN_UNUSED, // Keypad Hexadecimal
|
||||
KEY_EN_UNUSED, // DF Reserved
|
||||
KEY_EN_LEFT_CONTROL, // Keyboard LeftControl
|
||||
KEY_EN_LEFT_SHIFT, // Keyboard LeftShift
|
||||
KEY_EN_LEFT_ALT, // Keyboard LeftAlt
|
||||
KEY_EN_LEFT_WINDOWS, // Keyboard Left GUI
|
||||
KEY_EN_RIGHT_CONTROL, // Keyboard RightControl
|
||||
KEY_EN_RIGHT_SHIFT, // Keyboard RightShift
|
||||
KEY_EN_RIGHT_ALT, // Keyboard RightAlt
|
||||
KEY_EN_RIGHT_WINDOWS, // Keyboard Right GUI
|
||||
};
|
||||
|
||||
void RGBController_HIDLampArray::SetupZones()
|
||||
{
|
||||
zone new_zone;
|
||||
new_zone.name = RGBController::DeviceTypeToString(type);
|
||||
new_zone.type = ZONE_TYPE_MATRIX;
|
||||
new_zone.leds_count = controller->GetLampCount();
|
||||
new_zone.leds_min = new_zone.leds_count;
|
||||
new_zone.leds_max = new_zone.leds_count;
|
||||
|
||||
std::set<unsigned int> columns;
|
||||
std::set<unsigned int> rows;
|
||||
|
||||
for(std::size_t lamp_idx = 0; lamp_idx < controller->GetLamps().size(); lamp_idx++)
|
||||
{
|
||||
rows.insert(controller->GetLamps()[lamp_idx].PositionYInMicrometers);
|
||||
columns.insert(controller->GetLamps()[lamp_idx].PositionXInMicrometers);
|
||||
}
|
||||
|
||||
new_zone.matrix_map.height = rows.size();
|
||||
new_zone.matrix_map.width = columns.size();
|
||||
new_zone.matrix_map.map.resize(rows.size() * columns.size());
|
||||
|
||||
memset(new_zone.matrix_map.map.data(), 0xFF, (new_zone.matrix_map.map.size() * sizeof(unsigned int)));
|
||||
|
||||
for(std::size_t lamp_idx = 0; lamp_idx < controller->GetLamps().size(); lamp_idx++)
|
||||
{
|
||||
//FIXME this assumes that matrix_size is big enough which is only guaranteed when no key possition is doubled
|
||||
size_t idx = std::distance(columns.begin(), columns.find(controller->GetLamps()[lamp_idx].PositionXInMicrometers));
|
||||
size_t idy = std::distance(rows.begin(), rows.find(controller->GetLamps()[lamp_idx].PositionYInMicrometers));
|
||||
|
||||
new_zone.matrix_map.map[idx + idy * new_zone.matrix_map.width] = lamp_idx;
|
||||
}
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
for(std::size_t lamp_idx = 0; lamp_idx < controller->GetLamps().size(); lamp_idx++)
|
||||
{
|
||||
led new_led;
|
||||
|
||||
if(controller->GetLamps()[lamp_idx].LampKey < HID_KEYBOARD_USAGE_IDS_COUNT)
|
||||
{
|
||||
new_led.name = HIDUsageIDsToKeyNames[controller->GetLamps()[lamp_idx].LampKey];
|
||||
}
|
||||
else
|
||||
{
|
||||
new_led.name = KEY_EN_UNUSED;
|
||||
}
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_HIDLampArray::DeviceUpdateLEDs()
|
||||
{
|
||||
unsigned int leds_to_go = leds.size();
|
||||
|
||||
while(leds_to_go > 0)
|
||||
{
|
||||
unsigned int leds_this_frame = LAMP_MULTI_UPDATE_LAMP_COUNT;
|
||||
unsigned short LampIds[LAMP_MULTI_UPDATE_LAMP_COUNT];
|
||||
LampArrayColor UpdateColors[LAMP_MULTI_UPDATE_LAMP_COUNT];
|
||||
unsigned char LampUpdateFlags = 0;
|
||||
|
||||
if(leds_to_go < leds_this_frame)
|
||||
{
|
||||
leds_this_frame = leds_to_go;
|
||||
}
|
||||
|
||||
for(unsigned int led_frame_idx = 0; led_frame_idx < leds_this_frame; led_frame_idx++)
|
||||
{
|
||||
unsigned short led_idx = (leds.size() - leds_to_go) + led_frame_idx;
|
||||
LampIds[led_frame_idx] = led_idx;
|
||||
UpdateColors[led_frame_idx].RedChannel = RGBGetRValue(colors[led_idx]);
|
||||
UpdateColors[led_frame_idx].GreenChannel = RGBGetGValue(colors[led_idx]);
|
||||
UpdateColors[led_frame_idx].BlueChannel = RGBGetBValue(colors[led_idx]);
|
||||
UpdateColors[led_frame_idx].IntensityChannel = 255;
|
||||
}
|
||||
|
||||
leds_to_go -= leds_this_frame;
|
||||
|
||||
if(leds_to_go <= 0)
|
||||
{
|
||||
LampUpdateFlags = LAMP_UPDATE_FLAG_UPDATE_COMPLETE;
|
||||
}
|
||||
|
||||
controller->SetLampMultiUpdateReport(leds_this_frame, LampUpdateFlags, LampIds, UpdateColors);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_HIDLampArray::DeviceUpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_HIDLampArray::DeviceUpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_HIDLampArray::DeviceUpdateMode()
|
||||
{
|
||||
if(modes[active_mode].value == 0)
|
||||
{
|
||||
controller->SetLampArrayControlReport(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetLampArrayControlReport(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_HIDLampArray.h |
|
||||
| |
|
||||
| RGBController for HID LampArray Devices |
|
||||
| |
|
||||
| Adam Honse ([email protected]) 26 Mar 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-only |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "HIDLampArrayController.h"
|
||||
|
||||
class RGBController_HIDLampArray : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_HIDLampArray(HIDLampArrayController* controller_ptr);
|
||||
~RGBController_HIDLampArray();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
HIDLampArrayController* controller;
|
||||
};
|
||||
@@ -0,0 +1,107 @@
|
||||
/*******************************************************
|
||||
Utility functions taken from:
|
||||
|
||||
HIDAPI - Multi-Platform library for
|
||||
communication with HID devices.
|
||||
|
||||
Alan Ott
|
||||
Signal 11 Software
|
||||
|
||||
libusb/hidapi Team
|
||||
|
||||
Copyright 2022, All Rights Reserved.
|
||||
|
||||
At the discretion of the user of this library,
|
||||
this software may be licensed under the terms of the
|
||||
GNU General Public License v3, a BSD-Style license, or the
|
||||
original HIDAPI license as outlined in the LICENSE.txt,
|
||||
LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
|
||||
files located at the root of the source distribution.
|
||||
These files may also be found in the public source
|
||||
code repository located at:
|
||||
https://github.com/libusb/hidapi .
|
||||
********************************************************/
|
||||
|
||||
/*
|
||||
* Gets the size of the HID item at the given position
|
||||
* Returns 1 if successful, 0 if an invalid key
|
||||
* Sets data_len and key_size when successful
|
||||
*/
|
||||
static int get_hid_item_size(const unsigned char *report_descriptor, unsigned size, unsigned pos, unsigned char *data_len, unsigned char *key_size)
|
||||
{
|
||||
int key = report_descriptor[pos];
|
||||
int size_code;
|
||||
|
||||
/*
|
||||
* This is a Long Item. The next byte contains the
|
||||
* length of the data section (value) for this key.
|
||||
* See the HID specification, version 1.11, section
|
||||
* 6.2.2.3, titled "Long Items."
|
||||
*/
|
||||
if ((key & 0xf0) == 0xf0) {
|
||||
if (pos + 1 < size)
|
||||
{
|
||||
*data_len = report_descriptor[pos + 1];
|
||||
*key_size = 3;
|
||||
return 1;
|
||||
}
|
||||
*data_len = 0; /* malformed report */
|
||||
*key_size = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a Short Item. The bottom two bits of the
|
||||
* key contain the size code for the data section
|
||||
* (value) for this key. Refer to the HID
|
||||
* specification, version 1.11, section 6.2.2.2,
|
||||
* titled "Short Items."
|
||||
*/
|
||||
size_code = key & 0x3;
|
||||
switch (size_code) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
*data_len = size_code;
|
||||
*key_size = 1;
|
||||
return 1;
|
||||
case 3:
|
||||
*data_len = 4;
|
||||
*key_size = 1;
|
||||
return 1;
|
||||
default:
|
||||
/* Can't ever happen since size_code is & 0x3 */
|
||||
*data_len = 0;
|
||||
*key_size = 0;
|
||||
break;
|
||||
};
|
||||
|
||||
/* malformed report */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get bytes from a HID Report Descriptor.
|
||||
* Only call with a num_bytes of 0, 1, 2, or 4.
|
||||
*/
|
||||
static unsigned get_hid_report_bytes(unsigned char *rpt, size_t len, size_t num_bytes, size_t cur)
|
||||
{
|
||||
/* Return if there aren't enough bytes. */
|
||||
if (cur + num_bytes >= len)
|
||||
return 0;
|
||||
|
||||
if (num_bytes == 0)
|
||||
return 0;
|
||||
else if (num_bytes == 1)
|
||||
return rpt[cur + 1];
|
||||
else if (num_bytes == 2)
|
||||
return (rpt[cur + 2] * 256 + rpt[cur + 1]);
|
||||
else if (num_bytes == 4)
|
||||
return (
|
||||
rpt[cur + 4] * 0x01000000 +
|
||||
rpt[cur + 3] * 0x00010000 +
|
||||
rpt[cur + 2] * 0x00000100 +
|
||||
rpt[cur + 1] * 0x00000001
|
||||
);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
+2
-6
@@ -75,9 +75,5 @@ DetectedControllers DetectHYTEMousematControllers()
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("HYTE Mousemat", DetectHYTEMousematControllers);
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Entries for dynamic UDEV rules |
|
||||
| |
|
||||
| DUMMY_DEVICE_DETECTOR("HYTE Mousemat", DetectHYTEMousematControllers, 0x3402, 0x0B00 ) |
|
||||
| DUMMY_DEVICE_DETECTOR("HYTE Mousemat", DetectHYTEMousematControllers, 0x3402, 0x0B01 ) |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_CUSTOM_UDEV_RULE(hyte_mousemat_1, "HYTE Mousemat", "SUBSYSTEMS==\"usb|hidraw\", ATTRS{idVendor}==\"3402\", ATTRS{idProduct}==\"0b00\", TAG+=\"uaccess\", TAG+=\"HYTE_Mousemat\"");
|
||||
REGISTER_CUSTOM_UDEV_RULE(hyte_mousemat_2, "HYTE Mousemat", "SUBSYSTEMS==\"usb|hidraw\", ATTRS{idVendor}==\"3402\", ATTRS{idProduct}==\"0b01\", TAG+=\"uaccess\", TAG+=\"HYTE_Mousemat\"");
|
||||
|
||||
-6
@@ -60,9 +60,3 @@ DetectedControllers DetectHYTEMousematControllers()
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("HYTE Mousemat", DetectHYTEMousematControllers);
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Entries for dynamic UDEV rules |
|
||||
| |
|
||||
| DUMMY_DEVICE_DETECTOR("HYTE Mousemat", DetectHYTEMousematControllers, 0x3402, 0x0B00 ) |
|
||||
| DUMMY_DEVICE_DETECTOR("HYTE Mousemat", DetectHYTEMousematControllers, 0x3402, 0x0B01 ) |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -56,9 +56,5 @@ DetectedControllers DetectHYTENexusControllers()
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("HYTE Nexus", DetectHYTENexusControllers);
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Entries for dynamic UDEV rules |
|
||||
| |
|
||||
| DUMMY_DEVICE_DETECTOR("HYTE THICC Q60", DetectHYTENexusControllers, 0x3402, 0x0400 ) |
|
||||
| DUMMY_DEVICE_DETECTOR("HYTE Nexus Portal NP50", DetectHYTENexusControllers, 0x3402, 0x0901 ) |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_CUSTOM_UDEV_RULE(hyte_q60, "HYTE THICC Q60", "SUBSYSTEMS==\"usb|hidraw\", ATTRS{idVendor}==\"3402\", ATTRS{idProduct}==\"0400\", TAG+=\"uaccess\", TAG+=\"HYTE_THICC_Q60\"");
|
||||
REGISTER_CUSTOM_UDEV_RULE(hyte_nexus_portal, "HYTE Nexus Portal NP50", "SUBSYSTEMS==\"usb|hidraw\", ATTRS{idVendor}==\"3402\", ATTRS{idProduct}==\"0901\", TAG+=\"uaccess\", TAG+=\"HYTE_Nexus_Portal_NP50\"");
|
||||
|
||||
@@ -45,6 +45,7 @@ bool TestDDR5Models(char code)
|
||||
TestResult TestForFurySignature(i2c_smbus_interface *bus, unsigned int slot_addr, bool (*modelChecker)(char))
|
||||
{
|
||||
bool passed = true;
|
||||
bool signature_ok = true;
|
||||
char test_str[] = "FURY";
|
||||
int res;
|
||||
|
||||
@@ -92,6 +93,24 @@ TestResult TestForFurySignature(i2c_smbus_interface *bus, unsigned int slot_addr
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| Some Kingston Fury DDR5 modules return garbage for the signature |
|
||||
| and model registers (e.g. res=0708 at register 01) while every |
|
||||
| other register and the apply command work normally. This happens |
|
||||
| per slot on some boards (seen on ASUS B650 with DIMMs swapped: |
|
||||
| the bad readings stay on the slot, not on the module). The SPD |
|
||||
| already told us this slot holds a Kingston DDR5 module and the |
|
||||
| RGB controller ACKed the transaction, so accept it with a warning.|
|
||||
| See https://gitlab.com/CalcProgrammer1/OpenRGB/-/issues/4981 |
|
||||
\*-----------------------------------------------------------------*/
|
||||
if(!passed)
|
||||
{
|
||||
LOG_WARNING("[%s] 0x%02X: unreadable FURY signature, accepting anyway (SPD says Kingston DDR5, controller ACKs). See issue #4981",
|
||||
FURY_CONTROLLER_NAME, slot_addr);
|
||||
passed = true;
|
||||
signature_ok = false;
|
||||
}
|
||||
|
||||
if(passed)
|
||||
{
|
||||
// Get the model code
|
||||
@@ -103,8 +122,16 @@ TestResult TestForFurySignature(i2c_smbus_interface *bus, unsigned int slot_addr
|
||||
|
||||
if(!modelChecker(model_code))
|
||||
{
|
||||
LOG_INFO("[%s] Unknown model code 0x%02X", FURY_CONTROLLER_NAME, model_code);
|
||||
passed = false;
|
||||
if(signature_ok)
|
||||
{
|
||||
LOG_INFO("[%s] Unknown model code 0x%02X", FURY_CONTROLLER_NAME, model_code);
|
||||
passed = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING("[%s] 0x%02X: model code 0x%02X unreadable too, assuming Fury Beast DDR5",
|
||||
FURY_CONTROLLER_NAME, slot_addr, model_code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,18 +50,60 @@ RGBController_LEDStrip::~RGBController_LEDStrip()
|
||||
|
||||
void RGBController_LEDStrip::SetupZones()
|
||||
{
|
||||
zone led_zone;
|
||||
led_zone.name = "LED Strip";
|
||||
led_zone.type = ZONE_TYPE_LINEAR;
|
||||
led_zone.leds_min = controller->num_leds;
|
||||
led_zone.leds_max = controller->num_leds;
|
||||
led_zone.leds_count = controller->num_leds;
|
||||
zones.push_back(led_zone);
|
||||
/*-----------------------------------------------------*\
|
||||
| Only set LED count on the first run |
|
||||
\------------------------------------------------------*/
|
||||
bool first_run = false;
|
||||
|
||||
for(int led_idx = 0; led_idx < controller->num_leds; led_idx++)
|
||||
if(zones.size() == 0)
|
||||
{
|
||||
first_run = true;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Clear any existing color/LED configuration |
|
||||
\------------------------------------------------------*/
|
||||
leds.clear();
|
||||
colors.clear();
|
||||
zones.resize(1);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set zones and leds |
|
||||
\------------------------------------------------------*/
|
||||
zones[0].leds_min = controller->num_leds;
|
||||
zones[0].leds_max = controller->num_leds;
|
||||
|
||||
if(first_run)
|
||||
{
|
||||
zones[0].flags = ZONE_FLAG_MANUALLY_CONFIGURABLE_NAME
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_TYPE
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_MATRIX_MAP
|
||||
| ZONE_FLAG_MANUALLY_CONFIGURABLE_SEGMENTS;
|
||||
}
|
||||
|
||||
if(!(zones[0].flags & ZONE_FLAG_MANUALLY_CONFIGURED_NAME))
|
||||
{
|
||||
zones[0].name = "LED Strip";
|
||||
}
|
||||
|
||||
zones[0].leds_count = controller->num_leds;
|
||||
|
||||
if(!(zones[0].flags & ZONE_FLAG_MANUALLY_CONFIGURED_TYPE))
|
||||
{
|
||||
zones[0].type = ZONE_TYPE_LINEAR;
|
||||
}
|
||||
|
||||
if(!(zones[0].flags & ZONE_FLAG_MANUALLY_CONFIGURED_MATRIX_MAP))
|
||||
{
|
||||
zones[0].matrix_map.width = 0;
|
||||
zones[0].matrix_map.height = 0;
|
||||
zones[0].matrix_map.map.resize(0);
|
||||
}
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < zones[0].leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = "LED ";
|
||||
new_led.name = zones[0].name + ", LED ";
|
||||
new_led.name.append(std::to_string(led_idx));
|
||||
|
||||
leds.push_back(new_led);
|
||||
@@ -70,6 +112,14 @@ void RGBController_LEDStrip::SetupZones()
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LEDStrip::DeviceConfigureZone(int zone_idx)
|
||||
{
|
||||
if((size_t)zone_idx < zones.size())
|
||||
{
|
||||
SetupZones();
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_LEDStrip::DeviceUpdateLEDs()
|
||||
{
|
||||
controller->SetLEDs(colors);
|
||||
|
||||
@@ -23,6 +23,8 @@ public:
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceConfigureZone(int zone_idx);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LenovoK500Controller.cpp |
|
||||
| |
|
||||
| Driver for Lenovo Legion K500 keyboard |
|
||||
| |
|
||||
| MX1D 10 Aug 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include "LenovoK500Controller.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char byte_idx;
|
||||
unsigned char bit_idx;
|
||||
} k500_key;
|
||||
|
||||
static const k500_key k500_matrix[104] =
|
||||
{
|
||||
{0, 0}, // ESC
|
||||
{0, 1}, // F1
|
||||
{0, 2}, // F2
|
||||
{0, 3}, // F3
|
||||
{0, 4}, // F4
|
||||
{0, 5}, // F5
|
||||
{0, 6}, // F6
|
||||
{0, 7}, // F7
|
||||
{1, 0}, // F8
|
||||
{1, 1}, // F9
|
||||
{1, 2}, // F10
|
||||
{1, 3}, // F11
|
||||
{1, 4}, // F12
|
||||
{1, 5}, // PrtSc
|
||||
{1, 6}, // ScrollLock
|
||||
{1, 7}, // Pause
|
||||
{2, 0}, // Grave
|
||||
{2, 1}, // 1
|
||||
{2, 2}, // 2
|
||||
{2, 3}, // 3
|
||||
{2, 4}, // 4
|
||||
{2, 5}, // 5
|
||||
{2, 6}, // 6
|
||||
{2, 7}, // 7
|
||||
{3, 0}, // 8
|
||||
{3, 1}, // 9
|
||||
{3, 2}, // 0
|
||||
{3, 3}, // Minus
|
||||
{3, 4}, // Equal
|
||||
{3, 5}, // Backspace
|
||||
{3, 6}, // Insert
|
||||
{3, 7}, // Home
|
||||
{7, 6}, // PgUp
|
||||
{12, 0}, // NumLock
|
||||
{12, 5}, // NumSlash
|
||||
{13, 1}, // NumAsterisk
|
||||
{14, 0}, // NumMinus
|
||||
{4, 0}, // Tab
|
||||
{4, 1}, // Q
|
||||
{4, 2}, // W
|
||||
{4, 3}, // E
|
||||
{4, 4}, // R
|
||||
{4, 5}, // T
|
||||
{4, 6}, // Y
|
||||
{4, 7}, // U
|
||||
{5, 0}, // I
|
||||
{5, 1}, // O
|
||||
{5, 2}, // P
|
||||
{5, 3}, // LBracket
|
||||
{5, 4}, // RBracket
|
||||
{5, 5}, // Backslash
|
||||
{5, 6}, // Delete
|
||||
{5, 7}, // End
|
||||
{7, 7}, // PgDn
|
||||
{12, 1}, // Num7
|
||||
{12, 6}, // Num8
|
||||
{13, 2}, // Num9
|
||||
{14, 1}, // NumPlus
|
||||
{6, 0}, // CapsLock
|
||||
{6, 1}, // A
|
||||
{6, 2}, // S
|
||||
{6, 3}, // D
|
||||
{6, 4}, // F
|
||||
{6, 5}, // G
|
||||
{6, 6}, // H
|
||||
{6, 7}, // J
|
||||
{7, 0}, // K
|
||||
{7, 1}, // L
|
||||
{7, 2}, // Semicolon
|
||||
{7, 3}, // Quote
|
||||
{7, 4}, // Enter
|
||||
{12, 2}, // Num4
|
||||
{12, 7}, // Num5
|
||||
{13, 3}, // Num6
|
||||
{8, 0}, // LShift
|
||||
{8, 1}, // Z
|
||||
{8, 2}, // X
|
||||
{8, 3}, // C
|
||||
{8, 4}, // V
|
||||
{8, 5}, // B
|
||||
{8, 6}, // N
|
||||
{8, 7}, // M
|
||||
{9, 0}, // Comma
|
||||
{9, 1}, // Period
|
||||
{9, 2}, // Slash
|
||||
{9, 3}, // RShift
|
||||
{9, 6}, // Up
|
||||
{12, 3}, // Num1
|
||||
{13, 0}, // Num2
|
||||
{13, 4}, // Num3
|
||||
{14, 3}, // NumEnter
|
||||
{10, 0}, // LCtrl
|
||||
{10, 1}, // LWin
|
||||
{10, 2}, // LAlt
|
||||
{10, 5}, // Space
|
||||
{11, 0}, // RAlt
|
||||
{11, 1}, // RWin
|
||||
{11, 2}, // Menu
|
||||
{11, 3}, // RCtrl
|
||||
{11, 6}, // Left
|
||||
{11, 7}, // Down
|
||||
{9, 7}, // Right
|
||||
{12, 4}, // Num0
|
||||
{13, 5}, // NumDecimal
|
||||
};
|
||||
|
||||
static const unsigned char default_palette[] =
|
||||
{
|
||||
0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
|
||||
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||
0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0x00
|
||||
};
|
||||
|
||||
LenovoK500Controller::LenovoK500Controller(hid_device* dev_handle, const hid_device_info& info, std::string dev_name)
|
||||
{
|
||||
device = dev_handle;
|
||||
location = info.path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LenovoK500Controller::~LenovoK500Controller()
|
||||
{
|
||||
hid_close(device);
|
||||
}
|
||||
|
||||
std::string LenovoK500Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string LenovoK500Controller::GetDeviceName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
void LenovoK500Controller::SetMode(unsigned char mode_value, std::vector<RGBColor> colors, unsigned int brightness, unsigned int speed)
|
||||
{
|
||||
LOG_DEBUG("[%s] Setting mode %02X, brightness %d, speed %d", name.c_str(), mode_value, brightness, speed);
|
||||
|
||||
unsigned char feature_buf[9];
|
||||
memset(feature_buf, 0x00, sizeof(feature_buf));
|
||||
feature_buf[0] = 0x00; // Report ID
|
||||
feature_buf[1] = 0x14;
|
||||
feature_buf[2] = 0x00;
|
||||
feature_buf[3] = 0x5A;
|
||||
hid_send_feature_report(device, feature_buf, sizeof(feature_buf));
|
||||
|
||||
unsigned char usb_buf[K500_DATA_SIZE + 1];
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
usb_buf[0x00] = 0x00; // HID Report ID (0 = no report ID)
|
||||
usb_buf[0x01] = 0x01; // Magic byte
|
||||
usb_buf[0x02] = mode_value;
|
||||
usb_buf[0x03] = static_cast<unsigned char>(brightness);
|
||||
usb_buf[0x04] = static_cast<unsigned char>(speed);
|
||||
|
||||
memcpy(&usb_buf[0x11], default_palette, sizeof(default_palette));
|
||||
|
||||
if(mode_value == K500_MODE_CUSTOMIZE)
|
||||
{
|
||||
memset(&usb_buf[0x31], 0x00, 16);
|
||||
unsigned int custom_color = 0;
|
||||
|
||||
for(size_t i = 0; i < colors.size() && i < 104; i++)
|
||||
{
|
||||
if(colors[i] != 0)
|
||||
{
|
||||
custom_color = colors[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < colors.size() && i < 104; i++)
|
||||
{
|
||||
if(colors[i] != 0)
|
||||
{
|
||||
unsigned char byte_idx = k500_matrix[i].byte_idx;
|
||||
unsigned char bit_idx = k500_matrix[i].bit_idx;
|
||||
usb_buf[0x31 + byte_idx] |= (1 << bit_idx);
|
||||
}
|
||||
}
|
||||
|
||||
usb_buf[0x11] = static_cast<unsigned char>(RGBGetRValue(custom_color));
|
||||
usb_buf[0x12] = static_cast<unsigned char>(RGBGetGValue(custom_color));
|
||||
usb_buf[0x13] = static_cast<unsigned char>(RGBGetBValue(custom_color));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(colors.size() > 0)
|
||||
{
|
||||
usb_buf[0x11] = static_cast<unsigned char>(RGBGetRValue(colors[0]));
|
||||
usb_buf[0x12] = static_cast<unsigned char>(RGBGetGValue(colors[0]));
|
||||
usb_buf[0x13] = static_cast<unsigned char>(RGBGetBValue(colors[0]));
|
||||
}
|
||||
|
||||
if(colors.size() > 1)
|
||||
{
|
||||
usb_buf[0x15] = static_cast<unsigned char>(RGBGetRValue(colors[1]));
|
||||
usb_buf[0x16] = static_cast<unsigned char>(RGBGetGValue(colors[1]));
|
||||
usb_buf[0x17] = static_cast<unsigned char>(RGBGetBValue(colors[1]));
|
||||
}
|
||||
|
||||
if(colors.size() > 2)
|
||||
{
|
||||
usb_buf[0x19] = static_cast<unsigned char>(RGBGetRValue(colors[2]));
|
||||
usb_buf[0x1A] = static_cast<unsigned char>(RGBGetGValue(colors[2]));
|
||||
usb_buf[0x1B] = static_cast<unsigned char>(RGBGetBValue(colors[2]));
|
||||
}
|
||||
}
|
||||
|
||||
hid_write(device, usb_buf, sizeof(usb_buf));
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LenovoK500Controller.h |
|
||||
| |
|
||||
| Driver for Lenovo Legion K500 keyboard |
|
||||
| |
|
||||
| MX1D 10 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>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define K500_DATA_SIZE 64
|
||||
|
||||
#define K500_BRIGHTNESS_DEFAULT 2
|
||||
#define K500_BRIGHTNESS_MIN 0
|
||||
#define K500_BRIGHTNESS_MAX 2
|
||||
|
||||
#define K500_SPEED_DEFAULT 3
|
||||
#define K500_SPEED_MIN 0
|
||||
#define K500_SPEED_MAX 3
|
||||
|
||||
enum
|
||||
{
|
||||
K500_MODE_STATIC = 0x01,
|
||||
K500_MODE_SPIRAL = 0x02,
|
||||
K500_MODE_LASER = 0x03,
|
||||
K500_MODE_DRIFTING = 0x04,
|
||||
K500_MODE_FADING_TRACE = 0x05,
|
||||
K500_MODE_CUSTOMIZE = 0x06,
|
||||
K500_MODE_BREATHING = 0x07,
|
||||
K500_MODE_BREATHING_RAINBOW = 0x08,
|
||||
K500_MODE_STARLIGHT = 0x09,
|
||||
K500_MODE_STARLIGHT_DUAL = 0x0A,
|
||||
K500_MODE_SURFING = 0x0B,
|
||||
};
|
||||
|
||||
class LenovoK500Controller
|
||||
{
|
||||
public:
|
||||
LenovoK500Controller(hid_device* dev_handle, const hid_device_info& info, std::string dev_name);
|
||||
~LenovoK500Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
|
||||
void SetMode(unsigned char mode_value, std::vector<RGBColor> colors, unsigned int brightness, unsigned int speed);
|
||||
|
||||
private:
|
||||
hid_device* device;
|
||||
std::string location;
|
||||
std::string name;
|
||||
};
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LenovoK500ControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Lenovo Legion K500 keyboard |
|
||||
| |
|
||||
| MX1D 10 Aug 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_LenovoK500.h"
|
||||
#include "LenovoK500Controller.h"
|
||||
|
||||
#define LENOVO_VID 0x17EF
|
||||
#define LEGION_K500_PID 0x60D5
|
||||
|
||||
DetectedControllers DetectLenovoLegionK500Controllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
LenovoK500Controller* controller = new LenovoK500Controller(dev, *info, name);
|
||||
RGBController_LenovoK500* rgb_controller = new RGBController_LenovoK500(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_I("Lenovo Legion K500", DetectLenovoLegionK500Controllers, LENOVO_VID, LEGION_K500_PID, 3);
|
||||
+415
@@ -0,0 +1,415 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LenovoK500.cpp |
|
||||
| |
|
||||
| Driver for Lenovo Legion K500 keyboard |
|
||||
| |
|
||||
| MX1D 10 Aug 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_LenovoK500.h"
|
||||
#include "RGBControllerKeyNames.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Lenovo Legion K500
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :robot:
|
||||
@direct :x:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectLenovoLegionK500Controllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
#define NA 0xFFFFFFFF
|
||||
|
||||
static unsigned int matrix_map[6][23] =
|
||||
{
|
||||
{ 0 , NA, 1 , 2 , 3 , 4 , NA, 5 , 6 , 7 , 8 , NA, 9 , 10 , 11 , 12 , NA, 13 , 14 , 15 , NA, NA, NA, },
|
||||
{ 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , NA, 30 , 31 , 32 , NA, 33 , 34 , 35 , 36 , },
|
||||
{ 37 , NA, 38 , 39 , 40 , 41 , 42 , 43 , 44 , 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 53 , NA, 54 , 55 , 56 , 57 , },
|
||||
{ 58 , NA, 59 , 60 , 61 , 62 , 63 , 64 , 65 , 66 , 67 , 68 , 69 , 70 , NA, NA, NA, NA, NA, 71 , 72 , 73 , NA, },
|
||||
{ 74 , NA, 75 , 76 , 77 , 78 , 79 , 80 , 81 , 82 , 83 , 84 , 85 , NA, NA, NA, 86 , NA, NA, 87 , 88 , 89 , 90 , },
|
||||
{ 91 , 92 , 93 , NA, NA, NA, 94 , NA, NA, NA, NA, 95 , 96 , 97 , 98 , 99 , 100, 101, NA, 102, NA, 103, NA, },
|
||||
};
|
||||
|
||||
static const char* led_names[] =
|
||||
{
|
||||
KEY_EN_ESCAPE,
|
||||
KEY_EN_F1,
|
||||
KEY_EN_F2,
|
||||
KEY_EN_F3,
|
||||
KEY_EN_F4,
|
||||
KEY_EN_F5,
|
||||
KEY_EN_F6,
|
||||
KEY_EN_F7,
|
||||
KEY_EN_F8,
|
||||
KEY_EN_F9,
|
||||
KEY_EN_F10,
|
||||
KEY_EN_F11,
|
||||
KEY_EN_F12,
|
||||
KEY_EN_PRINT_SCREEN,
|
||||
KEY_EN_SCROLL_LOCK,
|
||||
KEY_EN_PAUSE_BREAK,
|
||||
KEY_EN_BACK_TICK,
|
||||
KEY_EN_1,
|
||||
KEY_EN_2,
|
||||
KEY_EN_3,
|
||||
KEY_EN_4,
|
||||
KEY_EN_5,
|
||||
KEY_EN_6,
|
||||
KEY_EN_7,
|
||||
KEY_EN_8,
|
||||
KEY_EN_9,
|
||||
KEY_EN_0,
|
||||
KEY_EN_MINUS,
|
||||
KEY_EN_EQUALS,
|
||||
KEY_EN_BACKSPACE,
|
||||
KEY_EN_INSERT,
|
||||
KEY_EN_HOME,
|
||||
KEY_EN_PAGE_UP,
|
||||
KEY_EN_NUMPAD_LOCK,
|
||||
KEY_EN_NUMPAD_DIVIDE,
|
||||
KEY_EN_NUMPAD_TIMES,
|
||||
KEY_EN_NUMPAD_MINUS,
|
||||
KEY_EN_TAB,
|
||||
KEY_EN_Q,
|
||||
KEY_EN_W,
|
||||
KEY_EN_E,
|
||||
KEY_EN_R,
|
||||
KEY_EN_T,
|
||||
KEY_EN_Y,
|
||||
KEY_EN_U,
|
||||
KEY_EN_I,
|
||||
KEY_EN_O,
|
||||
KEY_EN_P,
|
||||
KEY_EN_LEFT_BRACKET,
|
||||
KEY_EN_RIGHT_BRACKET,
|
||||
KEY_EN_BACK_SLASH,
|
||||
KEY_EN_DELETE,
|
||||
KEY_EN_END,
|
||||
KEY_EN_PAGE_DOWN,
|
||||
KEY_EN_NUMPAD_7,
|
||||
KEY_EN_NUMPAD_8,
|
||||
KEY_EN_NUMPAD_9,
|
||||
KEY_EN_NUMPAD_PLUS,
|
||||
KEY_EN_CAPS_LOCK,
|
||||
KEY_EN_A,
|
||||
KEY_EN_S,
|
||||
KEY_EN_D,
|
||||
KEY_EN_F,
|
||||
KEY_EN_G,
|
||||
KEY_EN_H,
|
||||
KEY_EN_J,
|
||||
KEY_EN_K,
|
||||
KEY_EN_L,
|
||||
KEY_EN_SEMICOLON,
|
||||
KEY_EN_QUOTE,
|
||||
KEY_EN_ANSI_ENTER,
|
||||
KEY_EN_NUMPAD_4,
|
||||
KEY_EN_NUMPAD_5,
|
||||
KEY_EN_NUMPAD_6,
|
||||
KEY_EN_LEFT_SHIFT,
|
||||
KEY_EN_Z,
|
||||
KEY_EN_X,
|
||||
KEY_EN_C,
|
||||
KEY_EN_V,
|
||||
KEY_EN_B,
|
||||
KEY_EN_N,
|
||||
KEY_EN_M,
|
||||
KEY_EN_COMMA,
|
||||
KEY_EN_PERIOD,
|
||||
KEY_EN_FORWARD_SLASH,
|
||||
KEY_EN_RIGHT_SHIFT,
|
||||
KEY_EN_UP_ARROW,
|
||||
KEY_EN_NUMPAD_1,
|
||||
KEY_EN_NUMPAD_2,
|
||||
KEY_EN_NUMPAD_3,
|
||||
KEY_EN_NUMPAD_ENTER,
|
||||
KEY_EN_LEFT_CONTROL,
|
||||
KEY_EN_LEFT_WINDOWS,
|
||||
KEY_EN_LEFT_ALT,
|
||||
KEY_EN_SPACE,
|
||||
KEY_EN_RIGHT_ALT,
|
||||
KEY_EN_RIGHT_WINDOWS,
|
||||
KEY_EN_MENU,
|
||||
KEY_EN_RIGHT_CONTROL,
|
||||
KEY_EN_LEFT_ARROW,
|
||||
KEY_EN_DOWN_ARROW,
|
||||
KEY_EN_RIGHT_ARROW,
|
||||
KEY_EN_NUMPAD_0,
|
||||
KEY_EN_NUMPAD_PERIOD,
|
||||
};
|
||||
|
||||
RGBController_LenovoK500::RGBController_LenovoK500(LenovoK500Controller* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = "Lenovo Legion K500";
|
||||
vendor = "Lenovo";
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
description = "Lenovo Legion K500 Device";
|
||||
location = controller->GetDeviceLocation();
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = K500_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.brightness_min = K500_BRIGHTNESS_MIN;
|
||||
Static.brightness_max = K500_BRIGHTNESS_MAX;
|
||||
Static.brightness = K500_BRIGHTNESS_DEFAULT;
|
||||
Static.speed_min = K500_SPEED_MIN;
|
||||
Static.speed_max = K500_SPEED_MAX;
|
||||
Static.speed = K500_SPEED_DEFAULT;
|
||||
Static.colors.resize(1);
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Spiral;
|
||||
Spiral.name = "Spiral";
|
||||
Spiral.value = K500_MODE_SPIRAL;
|
||||
Spiral.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Spiral.color_mode = MODE_COLORS_NONE;
|
||||
Spiral.brightness_min = K500_BRIGHTNESS_MIN;
|
||||
Spiral.brightness_max = K500_BRIGHTNESS_MAX;
|
||||
Spiral.brightness = K500_BRIGHTNESS_DEFAULT;
|
||||
Spiral.speed_min = K500_SPEED_MIN;
|
||||
Spiral.speed_max = K500_SPEED_MAX;
|
||||
Spiral.speed = K500_SPEED_DEFAULT;
|
||||
modes.push_back(Spiral);
|
||||
|
||||
mode Laser;
|
||||
Laser.name = "Laser";
|
||||
Laser.value = K500_MODE_LASER;
|
||||
Laser.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Laser.color_mode = MODE_COLORS_NONE;
|
||||
Laser.brightness_min = K500_BRIGHTNESS_MIN;
|
||||
Laser.brightness_max = K500_BRIGHTNESS_MAX;
|
||||
Laser.brightness = K500_BRIGHTNESS_DEFAULT;
|
||||
Laser.speed_min = K500_SPEED_MIN;
|
||||
Laser.speed_max = K500_SPEED_MAX;
|
||||
Laser.speed = K500_SPEED_DEFAULT;
|
||||
modes.push_back(Laser);
|
||||
|
||||
mode Drifting;
|
||||
Drifting.name = "Drifting";
|
||||
Drifting.value = K500_MODE_DRIFTING;
|
||||
Drifting.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Drifting.color_mode = MODE_COLORS_NONE;
|
||||
Drifting.brightness_min = K500_BRIGHTNESS_MIN;
|
||||
Drifting.brightness_max = K500_BRIGHTNESS_MAX;
|
||||
Drifting.brightness = K500_BRIGHTNESS_DEFAULT;
|
||||
Drifting.speed_min = K500_SPEED_MIN;
|
||||
Drifting.speed_max = K500_SPEED_MAX;
|
||||
Drifting.speed = K500_SPEED_DEFAULT;
|
||||
modes.push_back(Drifting);
|
||||
|
||||
mode FadingTrace;
|
||||
FadingTrace.name = "Fading Trace";
|
||||
FadingTrace.value = K500_MODE_FADING_TRACE;
|
||||
FadingTrace.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
FadingTrace.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
FadingTrace.colors_min = 1;
|
||||
FadingTrace.colors_max = 1;
|
||||
FadingTrace.brightness_min = K500_BRIGHTNESS_MIN;
|
||||
FadingTrace.brightness_max = K500_BRIGHTNESS_MAX;
|
||||
FadingTrace.brightness = K500_BRIGHTNESS_DEFAULT;
|
||||
FadingTrace.speed_min = K500_SPEED_MIN;
|
||||
FadingTrace.speed_max = K500_SPEED_MAX;
|
||||
FadingTrace.speed = K500_SPEED_DEFAULT;
|
||||
FadingTrace.colors.resize(1);
|
||||
modes.push_back(FadingTrace);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = K500_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.brightness_min = K500_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = K500_BRIGHTNESS_MAX;
|
||||
Breathing.brightness = K500_BRIGHTNESS_DEFAULT;
|
||||
Breathing.speed_min = K500_SPEED_MIN;
|
||||
Breathing.speed_max = K500_SPEED_MAX;
|
||||
Breathing.speed = K500_SPEED_DEFAULT;
|
||||
Breathing.colors.resize(1);
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Customize;
|
||||
Customize.name = "Custom";
|
||||
Customize.value = K500_MODE_CUSTOMIZE;
|
||||
Customize.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Customize.color_mode = MODE_COLORS_PER_LED;
|
||||
Customize.brightness_min = K500_BRIGHTNESS_MIN;
|
||||
Customize.brightness_max = K500_BRIGHTNESS_MAX;
|
||||
Customize.brightness = K500_BRIGHTNESS_DEFAULT;
|
||||
Customize.speed_min = K500_SPEED_MIN;
|
||||
Customize.speed_max = K500_SPEED_MAX;
|
||||
Customize.speed = K500_SPEED_DEFAULT;
|
||||
Customize.colors.resize(104);
|
||||
modes.push_back(Customize);
|
||||
|
||||
mode BreathingRainbow;
|
||||
BreathingRainbow.name = "Breathing (Rainbow)";
|
||||
BreathingRainbow.value = K500_MODE_BREATHING_RAINBOW;
|
||||
BreathingRainbow.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
BreathingRainbow.color_mode = MODE_COLORS_NONE;
|
||||
BreathingRainbow.brightness_min = K500_BRIGHTNESS_MIN;
|
||||
BreathingRainbow.brightness_max = K500_BRIGHTNESS_MAX;
|
||||
BreathingRainbow.brightness = K500_BRIGHTNESS_DEFAULT;
|
||||
BreathingRainbow.speed_min = K500_SPEED_MIN;
|
||||
BreathingRainbow.speed_max = K500_SPEED_MAX;
|
||||
BreathingRainbow.speed = K500_SPEED_DEFAULT;
|
||||
modes.push_back(BreathingRainbow);
|
||||
|
||||
mode Starlight;
|
||||
Starlight.name = "Starlight";
|
||||
Starlight.value = K500_MODE_STARLIGHT;
|
||||
Starlight.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Starlight.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Starlight.colors_min = 1;
|
||||
Starlight.colors_max = 1;
|
||||
Starlight.brightness_min = K500_BRIGHTNESS_MIN;
|
||||
Starlight.brightness_max = K500_BRIGHTNESS_MAX;
|
||||
Starlight.brightness = K500_BRIGHTNESS_DEFAULT;
|
||||
Starlight.speed_min = K500_SPEED_MIN;
|
||||
Starlight.speed_max = K500_SPEED_MAX;
|
||||
Starlight.speed = K500_SPEED_DEFAULT;
|
||||
Starlight.colors.resize(1);
|
||||
modes.push_back(Starlight);
|
||||
|
||||
mode StarlightDual;
|
||||
StarlightDual.name = "Starlight (Dual Colors)";
|
||||
StarlightDual.value = K500_MODE_STARLIGHT_DUAL;
|
||||
StarlightDual.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
StarlightDual.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
StarlightDual.colors_min = 2;
|
||||
StarlightDual.colors_max = 2;
|
||||
StarlightDual.brightness_min = K500_BRIGHTNESS_MIN;
|
||||
StarlightDual.brightness_max = K500_BRIGHTNESS_MAX;
|
||||
StarlightDual.brightness = K500_BRIGHTNESS_DEFAULT;
|
||||
StarlightDual.speed_min = K500_SPEED_MIN;
|
||||
StarlightDual.speed_max = K500_SPEED_MAX;
|
||||
StarlightDual.speed = K500_SPEED_DEFAULT;
|
||||
StarlightDual.colors.resize(2);
|
||||
modes.push_back(StarlightDual);
|
||||
|
||||
mode Surfing;
|
||||
Surfing.name = "Surfing";
|
||||
Surfing.value = K500_MODE_SURFING;
|
||||
Surfing.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_AUTOMATIC_SAVE;
|
||||
Surfing.color_mode = MODE_COLORS_NONE;
|
||||
Surfing.brightness_min = K500_BRIGHTNESS_MIN;
|
||||
Surfing.brightness_max = K500_BRIGHTNESS_MAX;
|
||||
Surfing.brightness = K500_BRIGHTNESS_DEFAULT;
|
||||
Surfing.speed_min = K500_SPEED_MIN;
|
||||
Surfing.speed_max = K500_SPEED_MAX;
|
||||
Surfing.speed = K500_SPEED_DEFAULT;
|
||||
modes.push_back(Surfing);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_LenovoK500::~RGBController_LenovoK500()
|
||||
{
|
||||
Shutdown();
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_LenovoK500::SetupZones()
|
||||
{
|
||||
zone new_zone;
|
||||
new_zone.name = "Keyboard";
|
||||
new_zone.type = ZONE_TYPE_MATRIX;
|
||||
new_zone.leds_min = 104;
|
||||
new_zone.leds_max = 104;
|
||||
new_zone.leds_count = 104;
|
||||
new_zone.matrix_map.Set(6, 23, (unsigned int*)&matrix_map);
|
||||
zones.push_back(new_zone);
|
||||
|
||||
for(int i = 0; i < 104; i++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = led_names[i];
|
||||
new_led.value = i;
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_LenovoK500::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/* This device does not support resizing zones */
|
||||
}
|
||||
|
||||
void RGBController_LenovoK500::DeviceUpdateLEDs()
|
||||
{
|
||||
if (modes[active_mode].value == K500_MODE_CUSTOMIZE)
|
||||
{
|
||||
unsigned int custom_color = 0;
|
||||
for(size_t i = 0; i < colors.size() && i < 104; i++)
|
||||
{
|
||||
if(colors[i] != 0 && (last_colors.size() <= i || colors[i] != last_colors[i]))
|
||||
{
|
||||
custom_color = colors[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(custom_color == 0)
|
||||
{
|
||||
for(size_t i = 0; i < colors.size() && i < 104; i++)
|
||||
{
|
||||
if(colors[i] != 0)
|
||||
{
|
||||
custom_color = colors[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < colors.size() && i < 104; i++)
|
||||
{
|
||||
if(colors[i] != 0)
|
||||
{
|
||||
colors[i] = custom_color;
|
||||
}
|
||||
}
|
||||
|
||||
last_colors = colors;
|
||||
|
||||
controller->SetMode(modes[active_mode].value, colors, modes[active_mode].brightness, modes[active_mode].speed);
|
||||
}
|
||||
else if (active_mode == 0)
|
||||
{
|
||||
std::vector<RGBColor> mode_colors = { colors[0] };
|
||||
controller->SetMode(K500_MODE_STATIC, mode_colors, modes[active_mode].brightness, modes[active_mode].speed);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_LenovoK500::UpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LenovoK500::UpdateSingleLED(int /*led*/)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_LenovoK500::DeviceUpdateMode()
|
||||
{
|
||||
if (modes[active_mode].value == K500_MODE_CUSTOMIZE)
|
||||
{
|
||||
controller->SetMode(modes[active_mode].value, colors, modes[active_mode].brightness, modes[active_mode].speed);
|
||||
}
|
||||
else
|
||||
{
|
||||
controller->SetMode(modes[active_mode].value, modes[active_mode].colors, modes[active_mode].brightness, modes[active_mode].speed);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_LenovoK500.h |
|
||||
| |
|
||||
| Driver for Lenovo Legion K500 keyboard |
|
||||
| |
|
||||
| MX1D 10 Aug 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
#include "RGBController.h"
|
||||
#include "LenovoK500Controller.h"
|
||||
|
||||
class RGBController_LenovoK500 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_LenovoK500(LenovoK500Controller* controller_ptr);
|
||||
~RGBController_LenovoK500();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
LenovoK500Controller* controller;
|
||||
std::vector<RGBColor> last_colors;
|
||||
};
|
||||
@@ -324,12 +324,6 @@ DetectedControllers DetectLianLiUniversalScreen()
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Entries for dynamic UDEV rules for libusb devices |
|
||||
| |
|
||||
| DUMMY_DEVICE_DETECTOR("Lian Li Uni Hub", DetectLianLiUniHub, 0x0CF2, 0x7750 ) |
|
||||
| DUMMY_DEVICE_DETECTOR("Lian Li Universal Screen", DetectLianLiUniversalScreen, 0x0416, 0x8050 ) |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_DETECTOR("Lian Li Uni Hub", DetectLianLiUniHub);
|
||||
REGISTER_DETECTOR("Lian Li Universal Screen", DetectLianLiUniversalScreen);
|
||||
|
||||
@@ -342,3 +336,6 @@ REGISTER_HID_DETECTOR_IPU("Lian Li Uni Hub - SL Infinity", DetectLianLiUniH
|
||||
REGISTER_HID_DETECTOR_IPU("Lian Li Strimer L Connect", DetectLianLiStrimerControllers, ENE_USB_VID, STRIMER_L_CONNECT_PID, 1, 0xFF72, 0xA1);
|
||||
REGISTER_HID_DETECTOR_I("Lian Li GA II Trinity", DetectLianLiGAIITrinity, NUVOTON_USB_VID, GAII_USB_PID, 0x02);
|
||||
REGISTER_HID_DETECTOR_I("Lian Li GA II Trinity Performance", DetectLianLiGAIITrinity, NUVOTON_USB_VID, GAII_Perf_USB_PID, 0x02);
|
||||
|
||||
REGISTER_CUSTOM_UDEV_RULE(lianli_uni_hub, "Lian Li Uni Hub", "SUBSYSTEMS==\"usb|hidraw\", ATTRS{idVendor}==\"0cf2\", ATTRS{idProduct}==\"7750\", TAG+=\"uaccess\", TAG+=\"Lian_Li_Uni_Hub\"");
|
||||
REGISTER_CUSTOM_UDEV_RULE(lianli_universal_screen, "Lian Li Universal Screen", "SUBSYSTEMS==\"usb|hidraw\", ATTRS{idVendor}==\"0416\", ATTRS{idProduct}==\"8050\", TAG+=\"uaccess\", TAG+=\"Lian_Li_Universal_Screen\"");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,154 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG560Controller.cpp |
|
||||
| |
|
||||
| Driver for Logitech G560 |
|
||||
| |
|
||||
| Cheerpipe 28 Oct 2020 |
|
||||
| based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "LogitechG560Controller.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
LogitechG560Controller::LogitechG560Controller(hid_device* dev_handle, const char* path, std::string dev_name)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
name = dev_name;
|
||||
}
|
||||
|
||||
LogitechG560Controller::~LogitechG560Controller()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
std::string LogitechG560Controller::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string LogitechG560Controller::GetDeviceName()
|
||||
{
|
||||
return(name);
|
||||
}
|
||||
|
||||
void LogitechG560Controller::SetDirectMode(uint8_t zone)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G560_LED_PACKET_SIZE];
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
usb_buf[0x03] = 0xCA;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G560_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG560Controller::SetOffMode(uint8_t zone)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G560_LED_PACKET_SIZE];
|
||||
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
usb_buf[0x03] = 0x3F;
|
||||
usb_buf[0x04] = zone;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G560_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG560Controller::SendSpeakerMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
)
|
||||
{
|
||||
unsigned char usb_buf[LOGI_G560_LED_PACKET_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Lighting Control |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x11;
|
||||
usb_buf[0x01] = 0xFF;
|
||||
usb_buf[0x02] = 0x04;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| This packet sets speaker into direct mode. This mode |
|
||||
| is used by Lightsync Ambilight and Music Visualizer |
|
||||
| realtime effect. |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x03] = 0x3A;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up mode and speed |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x04] = zone;
|
||||
usb_buf[0x05] = mode;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| And set up the colors |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x06] = red;
|
||||
usb_buf[0x07] = green;
|
||||
usb_buf[0x08] = blue;
|
||||
|
||||
if(mode == LOGITECH_G560_MODE_DIRECT) //G560 only has Direct Mode.
|
||||
{
|
||||
usb_buf[0x09] = 0x02;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
fail_retry_write(dev, usb_buf, LOGI_G560_LED_PACKET_SIZE);
|
||||
}
|
||||
|
||||
void LogitechG560Controller::fail_retry_write(hid_device *device, const unsigned char *data, size_t length)
|
||||
{
|
||||
unsigned char usb_buf_out[LOGI_G560_LED_PACKET_SIZE];
|
||||
unsigned int write_max_retry = LOGI_G560_LED_COMMAND_SEND_RETRIES;
|
||||
do
|
||||
{
|
||||
std::this_thread::sleep_for(1ms);
|
||||
int ret = hid_write(device, data, length);
|
||||
|
||||
/*-------------------------------------------------------------------------------------*\
|
||||
| HID write fails if a change led color and set volume command are sent at |
|
||||
| the same time because RGB controller and volume control shares the same interface. |
|
||||
\*-------------------------------------------------------------------------------------*/
|
||||
if(ret == 20)
|
||||
{
|
||||
std::this_thread::sleep_for(1ms);
|
||||
hid_read_timeout(dev, usb_buf_out, LOGI_G560_LED_PACKET_SIZE, 20);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
write_max_retry--;
|
||||
std::this_thread::sleep_for(10ms);
|
||||
}
|
||||
|
||||
}while (write_max_retry > 0);
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| LogitechG560Controller.h |
|
||||
| |
|
||||
| Driver for Logitech G560 |
|
||||
| |
|
||||
| Cheerpipe 28 Oct 2020 |
|
||||
| based on TheRogueZeta 31 Aug 2020 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
#define LOGI_G560_LED_PACKET_SIZE 20
|
||||
#define LOGI_G560_LED_COMMAND_SEND_RETRIES 3
|
||||
|
||||
enum
|
||||
{
|
||||
LOGITECH_G560_MODE_OFF = 0x00,
|
||||
LOGITECH_G560_MODE_DIRECT = 0x01,
|
||||
LOGITECH_G560_MODE_CYCLE = 0x02,
|
||||
LOGITECH_G560_MODE_BREATHING = 0x03,
|
||||
};
|
||||
|
||||
class LogitechG560Controller
|
||||
{
|
||||
public:
|
||||
LogitechG560Controller(hid_device* dev_handle, const char* path, std::string dev_name);
|
||||
~LogitechG560Controller();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
|
||||
void SetDirectMode(uint8_t zone);
|
||||
void SetOffMode(uint8_t zone);
|
||||
|
||||
void SendSpeakerMode
|
||||
(
|
||||
unsigned char zone,
|
||||
unsigned char mode,
|
||||
unsigned char red,
|
||||
unsigned char green,
|
||||
unsigned char blue
|
||||
);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
std::string name;
|
||||
|
||||
void fail_retry_write(hid_device *device, const unsigned char *data, size_t length);
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user