Compare commits
70
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b86be6b75d | ||
|
|
c11090a4cf | ||
|
|
a69390e5a8 | ||
|
|
a900d5c402 | ||
|
|
f870dcdc3a | ||
|
|
9a105ccdaf | ||
|
|
1faa2b1d31 | ||
|
|
91923f3a82 | ||
|
|
fcb594cb0e | ||
|
|
32f0f1a9a2 | ||
|
|
4d379b97c6 | ||
|
|
a3e5296bf2 | ||
|
|
072d27d9dd | ||
|
|
201f2d7aba | ||
|
|
28cd45b8c0 | ||
|
|
7a9aab5a37 | ||
|
|
24ea50df71 | ||
|
|
75df39252b | ||
|
|
385f123816 | ||
|
|
e1fc54de85 | ||
|
|
e22e88d97d | ||
|
|
0ba254e38f | ||
|
|
9d35d28a6a | ||
|
|
b4b4f3b891 | ||
|
|
e1086712ad | ||
|
|
fd7ccad1e6 | ||
|
|
8bc1a0cb8f | ||
|
|
5112224240 | ||
|
|
5e2cc42290 | ||
|
|
b1436a8435 | ||
|
|
a8d4e25642 | ||
|
|
2b3638ba57 | ||
|
|
78369c2a92 | ||
|
|
03ce513254 | ||
|
|
18503cccc6 | ||
|
|
e1d46d3bb3 | ||
|
|
0466996970 | ||
|
|
56bd7580ba | ||
|
|
ca47047bf8 | ||
|
|
cc00690dd4 | ||
|
|
973311aa48 | ||
|
|
747afdf553 | ||
|
|
8f11f8fd97 | ||
|
|
2b11f6fe07 | ||
|
|
94981f107b | ||
|
|
0144a6a150 | ||
|
|
6ec8b80e65 | ||
|
|
ddae1ed20a | ||
|
|
70f79e97b4 | ||
|
|
d05fe1bdf1 | ||
|
|
e9e99a029d | ||
|
|
98dd494f75 | ||
|
|
7b7f0aa0fe | ||
|
|
70876193cf | ||
|
|
f47a22fb2f | ||
|
|
f24b56b64f | ||
|
|
4e70949aec | ||
|
|
5133887632 | ||
|
|
45950047cb | ||
|
|
a56a08411f | ||
|
|
52f0049025 | ||
|
|
f6f317d487 | ||
|
|
ad364871c6 | ||
|
|
58582202cf | ||
|
|
57cde755c1 | ||
|
|
b0c7dba441 | ||
|
|
d763f7ecc7 | ||
|
|
4ec4df8741 | ||
|
|
5d055d30a3 | ||
|
|
fc73fe0b4c |
+19
-55
@@ -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 or #
|
||||
# tag builds, otherwise run them if the source is part #
|
||||
# of a merge request #
|
||||
# automatically run all jobs on the default branch, #
|
||||
# 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_COMMIT_TAG || $CI_PIPELINE_SOURCE == "merge_request_event")'
|
||||
- if: '$CI_PROJECT_PATH == "CalcProgrammer1/OpenRGB" && ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $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:trixie-amd64
|
||||
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:bookworm-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:trixie-${TGT_ARCH}
|
||||
image: registry.gitlab.com/openrgbdevelopers/openrgb-linux-ci-deb-builder:bookworm-${TGT_ARCH}
|
||||
tags:
|
||||
- linux
|
||||
- ${TGT_ARCH}
|
||||
@@ -87,6 +87,8 @@ 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:
|
||||
@@ -288,13 +290,13 @@ before_script:
|
||||
<<: *debian_script_steps
|
||||
|
||||
#-----------------------------------------------------------#
|
||||
# Linux (.rpm) Fedora 44 amd64 Build Target #
|
||||
# Linux (.rpm, F43) 64-bit Build Target #
|
||||
#-----------------------------------------------------------#
|
||||
"Linux amd64 .rpm (Fedora 44)":
|
||||
image: fedora:44
|
||||
"Linux 64 F43 rpm":
|
||||
image: fedora:43
|
||||
stage: build
|
||||
script:
|
||||
- dnf install rpmdevtools dnf-plugins-core libcurl-devel qt6-qtbase-devel git wget -y
|
||||
- dnf install rpmdevtools dnf-plugins-core libcurl-devel qt5-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
|
||||
@@ -310,7 +312,7 @@ before_script:
|
||||
- cd ${CI_PROJECT_DIR}
|
||||
|
||||
artifacts:
|
||||
name: "${CI_PROJECT_NAME}_Linux_amd64_rpm_${CI_COMMIT_SHORT_SHA}"
|
||||
name: "${CI_PROJECT_NAME}_Linux_64_rpm_${CI_COMMIT_SHORT_SHA}"
|
||||
paths:
|
||||
- openrgb*.rpm
|
||||
expire_in: 30 days
|
||||
@@ -318,44 +320,6 @@ 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 #
|
||||
#-----------------------------------------------------------#
|
||||
@@ -423,10 +387,10 @@ before_script:
|
||||
- !reference [.upstream_rules, rules]
|
||||
|
||||
#-----------------------------------------------------------#
|
||||
# Fedora amd64 44 test #
|
||||
# Fedora 64 v43 test #
|
||||
#-----------------------------------------------------------#
|
||||
"Fedora 64 44":
|
||||
image: fedora:44
|
||||
"Fedora 64 v43":
|
||||
image: fedora:43
|
||||
stage: test
|
||||
script:
|
||||
- dnf install unzip wget -y
|
||||
@@ -437,9 +401,9 @@ before_script:
|
||||
- openrgb --version
|
||||
- dnf5 -y remove openrgb
|
||||
dependencies:
|
||||
- "Linux amd64 .rpm (Fedora 44)"
|
||||
- "Linux 64 F43 rpm"
|
||||
needs:
|
||||
- "Linux amd64 .rpm (Fedora 44)"
|
||||
- "Linux 64 F43 rpm"
|
||||
rules:
|
||||
- !reference [.upstream_rules, rules]
|
||||
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| AutoStart-Flatpak.cpp |
|
||||
| |
|
||||
| Autostart implementation for Linux via Flatpak Portal |
|
||||
| |
|
||||
| Adam Honse <[email protected]> 04 Sep 2026 |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "AutoStart-Flatpak.h"
|
||||
#include <gio/gio.h>
|
||||
|
||||
AutoStart::AutoStart(std::string name)
|
||||
{
|
||||
InitAutoStart(name);
|
||||
}
|
||||
|
||||
void AutoStart::InitAutoStart(std::string name)
|
||||
{
|
||||
app_name = name;
|
||||
}
|
||||
|
||||
bool AutoStart::CallBackgroundPortal(bool enable, const AutoStartInfo& autostart_info)
|
||||
{
|
||||
GError* error = nullptr;
|
||||
GDBusConnection* connection = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, &error);
|
||||
|
||||
if(!connection)
|
||||
{
|
||||
if(error)
|
||||
{
|
||||
g_error_free(error);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| FreeDesktop Background Portal parameters |
|
||||
\*-----------------------------------------------------*/
|
||||
const char* bus_name = "org.freedesktop.portal.Desktop";
|
||||
const char* object_path = "/org/freedesktop/portal/desktop";
|
||||
const char* interface_name = "org.freedesktop.portal.Background";
|
||||
const char* method_name = "RequestBackground";
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Build the options dictionary (vardict) required by |
|
||||
| the Portal |
|
||||
\*-----------------------------------------------------*/
|
||||
GVariantBuilder options_builder;
|
||||
g_variant_builder_init(&options_builder, G_VARIANT_TYPE_VARDICT);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Reason shown to the user in the system settings / |
|
||||
| permission prompt |
|
||||
\*-----------------------------------------------------*/
|
||||
std::string reason_str = "Allow " + app_name + " to launch automatically at startup.";
|
||||
g_variant_builder_add(&options_builder, "{sv}", "reason", g_variant_new_string(reason_str.c_str()));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Toggle the autostart feature state |
|
||||
\*-----------------------------------------------------*/
|
||||
g_variant_builder_add(&options_builder, "{sv}", "autostart", g_variant_new_boolean(enable));
|
||||
|
||||
if(enable)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Pass command-line arguments to the background |
|
||||
| request |
|
||||
\*-------------------------------------------------*/
|
||||
GVariantBuilder arg_builder;
|
||||
g_variant_builder_init(&arg_builder, G_VARIANT_TYPE("as"));
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Add the primary executable path inside the |
|
||||
| Flatpak sandbox |
|
||||
\*-------------------------------------------------*/
|
||||
g_variant_builder_add(&arg_builder, "s", GetExePath().c_str());
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Append any additional arguments provided by |
|
||||
| OpenRGB's autostart config |
|
||||
\*-------------------------------------------------*/
|
||||
if(!autostart_info.args.empty())
|
||||
{
|
||||
g_variant_builder_add(&arg_builder, "s", autostart_info.args.c_str());
|
||||
}
|
||||
|
||||
GVariant* commandline_args = g_variant_builder_end(&arg_builder);
|
||||
g_variant_builder_add(&options_builder, "{sv}", "commandline", commandline_args);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| An empty string window handle is used since this is a |
|
||||
| background configuration request |
|
||||
\*-----------------------------------------------------*/
|
||||
const char* parent_window = "";
|
||||
GVariant* options = g_variant_builder_end(&options_builder);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Bundle parameters: (s a{sv}) -> Parent window handle, |
|
||||
| Options dictionary |
|
||||
\*-----------------------------------------------------*/
|
||||
GVariant* parameters = g_variant_new("(s@a{sv})", parent_window, options);
|
||||
GVariant* reply;
|
||||
|
||||
reply = g_dbus_connection_call_sync(connection, bus_name, object_path, interface_name, method_name, parameters, G_VARIANT_TYPE("(o)"), G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error);
|
||||
|
||||
g_object_unref(connection);
|
||||
|
||||
if(error)
|
||||
{
|
||||
g_error_free(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(reply)
|
||||
{
|
||||
g_variant_unref(reply);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AutoStart::EnableAutoStart(AutoStartInfo autostart_info)
|
||||
{
|
||||
return CallBackgroundPortal(true, autostart_info);
|
||||
}
|
||||
|
||||
bool AutoStart::DisableAutoStart()
|
||||
{
|
||||
return CallBackgroundPortal(false);
|
||||
}
|
||||
|
||||
bool AutoStart::IsAutoStartEnabled()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| The FreeDesktop Background Portal does not provide a |
|
||||
| stateless status getter. Sandbox permissions are |
|
||||
| securely managed and persisted internally by the |
|
||||
| host's portal service. To implement a true state |
|
||||
| track here, OpenRGB will need to manage a local |
|
||||
| boolean flag inside its own configuration files (e.g. |
|
||||
| OpenRGB.json). |
|
||||
\*-----------------------------------------------------*/
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string AutoStart::GetExePath()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Flatpak applications always run from this specific |
|
||||
| exported path hierarchy |
|
||||
\*-----------------------------------------------------*/
|
||||
return "/app/bin/openrgb";
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| AutoStart-Flatpak.h |
|
||||
| |
|
||||
| Autostart implementation for Linux via Flatpak Portal |
|
||||
| |
|
||||
| Adam Honse <[email protected]> 04 Sep 2026 |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "AutoStart.h"
|
||||
|
||||
class AutoStart : public AutoStartInterface
|
||||
{
|
||||
public:
|
||||
AutoStart(std::string name);
|
||||
|
||||
bool DisableAutoStart();
|
||||
bool EnableAutoStart(AutoStartInfo autostart_info);
|
||||
bool IsAutoStartEnabled();
|
||||
std::string GetExePath();
|
||||
|
||||
private:
|
||||
void InitAutoStart(std::string name);
|
||||
bool CallBackgroundPortal(bool enable, const AutoStartInfo& autostart_info = {});
|
||||
|
||||
std::string app_name;
|
||||
};
|
||||
@@ -119,21 +119,6 @@ bool AutoStart::IsAutoStartEnabled()
|
||||
|
||||
std::string AutoStart::GetExePath()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| When running from an AppImage, the AppImage runtime |
|
||||
| sets the APPIMAGE environment variable to the path of |
|
||||
| the AppImage file itself. /proc/self/exe would |
|
||||
| instead point at the extracted binary inside the |
|
||||
| temporary squashfs mount, which disappears once the |
|
||||
| AppImage is closed, so prefer APPIMAGE when it is set |
|
||||
\*-----------------------------------------------------*/
|
||||
const char* appimage_path = getenv("APPIMAGE");
|
||||
|
||||
if(appimage_path != NULL)
|
||||
{
|
||||
return(std::string(appimage_path));
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Create the OpenRGB executable path |
|
||||
\*-----------------------------------------------------*/
|
||||
@@ -149,64 +134,6 @@ 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)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
@@ -227,17 +154,11 @@ std::string AutoStart::GenerateDesktopFile(AutoStartInfo autostart_info)
|
||||
/*-----------------------------------------------------*\
|
||||
| Add the executable path and arguments |
|
||||
\*-----------------------------------------------------*/
|
||||
fileContents << "Exec=" << DesktopExecEscape(autostart_info.path);
|
||||
fileContents << "Exec=" << autostart_info.path;
|
||||
|
||||
if (autostart_info.args != "")
|
||||
{
|
||||
std::istringstream arg_parser(autostart_info.args);
|
||||
std::string arg;
|
||||
|
||||
while(arg_parser >> arg)
|
||||
{
|
||||
fileContents << " " << DesktopExecEscape(arg);
|
||||
}
|
||||
fileContents << " " << autostart_info.args;
|
||||
}
|
||||
|
||||
fileContents << std::endl;
|
||||
|
||||
@@ -137,43 +137,6 @@ 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)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
@@ -190,8 +153,7 @@ 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>" << XmlEscape(autostart_info.path) << "</string>"
|
||||
<< std::endl;
|
||||
fileContents << " <string>" << autostart_info.path << "</string>" << std::endl;
|
||||
|
||||
if(autostart_info.args != "")
|
||||
{
|
||||
@@ -200,8 +162,7 @@ std::string AutoStart::GenerateLaunchAgentFile(AutoStartInfo autostart_info)
|
||||
|
||||
while(arg_parser >> arg)
|
||||
{
|
||||
fileContents << " <string>" << XmlEscape(arg) << "</string>"
|
||||
<< std::endl;
|
||||
fileContents << " <string>" << arg << "</string>" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <shlobj.h>
|
||||
#include "AutoStart-Windows.h"
|
||||
#include "LogManager.h"
|
||||
#include "StringUtils.h"
|
||||
#include "filesystem.h"
|
||||
#include "windows.h"
|
||||
|
||||
@@ -72,11 +71,11 @@ bool AutoStart::EnableAutoStart(AutoStartInfo autostart_info)
|
||||
HRESULT result;
|
||||
IShellLinkW* shellLink = NULL;
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
result = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL, IID_IShellLinkW, (void**)&shellLink);
|
||||
|
||||
@@ -151,16 +150,11 @@ std::string AutoStart::GetExePath()
|
||||
/*-----------------------------------------------------*\
|
||||
| Create the OpenRGB executable path |
|
||||
\*-----------------------------------------------------*/
|
||||
wchar_t exepath[MAX_PATH] = L"";
|
||||
char exepath[MAX_PATH] = "";
|
||||
|
||||
DWORD count = GetModuleFileNameW(NULL, exepath, MAX_PATH);
|
||||
DWORD count = GetModuleFileNameA(NULL, exepath, MAX_PATH);
|
||||
|
||||
if(count == 0)
|
||||
{
|
||||
return(std::string());
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(std::wstring(exepath, count)));
|
||||
return(std::string(exepath, (count > 0) ? count : 0));
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
@@ -170,39 +164,43 @@ std::string AutoStart::GetExePath()
|
||||
|
||||
void AutoStart::InitAutoStart(std::string name)
|
||||
{
|
||||
wchar_t startMenuPath[MAX_PATH];
|
||||
char startMenuPath[MAX_PATH];
|
||||
|
||||
autostart_name = name;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get startup applications path |
|
||||
\*-----------------------------------------------------*/
|
||||
HRESULT result = SHGetFolderPathW(NULL, CSIDL_PROGRAMS, NULL, 0, startMenuPath);
|
||||
HRESULT result = SHGetFolderPathA(NULL, CSIDL_PROGRAMS, NULL, 0, startMenuPath);
|
||||
|
||||
if(SUCCEEDED(result))
|
||||
{
|
||||
std::string autostart_dir = StringUtils::wstring_to_string(startMenuPath);
|
||||
autostart_dir += "\\Startup\\";
|
||||
autostart_file = std::string(startMenuPath);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| 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";
|
||||
}
|
||||
autostart_file += "\\Startup\\" + 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,4 +24,5 @@ public:
|
||||
|
||||
private:
|
||||
void InitAutoStart(std::string name);
|
||||
std::wstring utf8_decode(const std::string& str);
|
||||
};
|
||||
|
||||
@@ -40,15 +40,9 @@ protected:
|
||||
#include "AutoStart-Windows.h"
|
||||
#endif
|
||||
|
||||
#ifdef FLATPAK_BUILD
|
||||
#include "AutoStart-Flatpak.h"
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#ifndef FLATPAK_BUILD
|
||||
#include "AutoStart-Linux.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "AutoStart-MacOS.h"
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| A4TechDetector.cpp |
|
||||
| |
|
||||
| Detector for A4Tech Devices |
|
||||
| |
|
||||
| Chris M (Dr_No) 30 Jun 2022 |
|
||||
| Mohammed Julfikar Ali Mahbub (o-julfikar) 01 Apr 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "BloodyB820RController.h"
|
||||
#include "BloodyMouseController.h"
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_BloodyB820R.h"
|
||||
#include "RGBController_BloodyMouse.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| A4 Tech USB vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define A4_TECH_VID 0x09DA
|
||||
|
||||
DetectedControllers DetectA4TechMouseControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
BloodyMouseController* controller = new BloodyMouseController(dev, info->path, info->product_id, name);
|
||||
RGBController_BloodyMouse* rgb_controller = new RGBController_BloodyMouse(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectBloodyB820R(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
BloodyB820RController* controller = new BloodyB820RController(dev, info->path, name);
|
||||
RGBController_BloodyB820R* rgb_controller = new RGBController_BloodyB820R(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W60 Pro", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_W60_PRO_PID, 2, 0xFF33, 0x0529);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W70 Max", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_W70_MAX_PID, 2, 0xFF33, 0x0518);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W90 Max", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_W90_MAX_PID, 2, 0xFF33, 0x053D);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W90 Pro", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_W90_PRO_PID, 2, 0xFF33, 0x054D);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody MP 50RS", DetectA4TechMouseControllers, A4_TECH_VID, BLOODY_MP_50RS_PID, 2, 0xFFF2, 0x6009);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody B820R", DetectBloodyB820R, A4_TECH_VID, BLOODY_B820R_PID, 2, 0xFF52, 0x0210);
|
||||
@@ -1,40 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| BloodyB820RControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Bloody B820R Devices |
|
||||
| |
|
||||
| Mohammed Julfikar Ali Mahbub (o-julfikar) 01 Apr 2024 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "BloodyB820RController.h"
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_BloodyB820R.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| A4 Tech USB vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define A4_TECH_VID 0x09DA
|
||||
|
||||
DetectedControllers DetectBloodyB820R(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
BloodyB820RController* controller = new BloodyB820RController(dev, info->path, name);
|
||||
RGBController_BloodyB820R* rgb_controller = new RGBController_BloodyB820R(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody B820R", DetectBloodyB820R, A4_TECH_VID, BLOODY_B820R_PID, 2, 0xFF52, 0x0210);
|
||||
@@ -1,44 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| BloodyMouseControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Bloody Mouse Devices |
|
||||
| |
|
||||
| Chris M (Dr_No) 30 Jun 2022 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "BloodyMouseController.h"
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_BloodyMouse.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| A4 Tech USB vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define A4_TECH_VID 0x09DA
|
||||
|
||||
DetectedControllers DetectBloodyMouseControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
BloodyMouseController* controller = new BloodyMouseController(dev, info->path, info->product_id, name);
|
||||
RGBController_BloodyMouse* rgb_controller = new RGBController_BloodyMouse(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W60 Pro", DetectBloodyMouseControllers, A4_TECH_VID, BLOODY_W60_PRO_PID, 2, 0xFF33, 0x0529);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W70 Max", DetectBloodyMouseControllers, A4_TECH_VID, BLOODY_W70_MAX_PID, 2, 0xFF33, 0x0518);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W90 Max", DetectBloodyMouseControllers, A4_TECH_VID, BLOODY_W90_MAX_PID, 2, 0xFF33, 0x053D);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody W90 Pro", DetectBloodyMouseControllers, A4_TECH_VID, BLOODY_W90_PRO_PID, 2, 0xFF33, 0x054D);
|
||||
REGISTER_HID_DETECTOR_IPU("Bloody MP 50RS", DetectBloodyMouseControllers, A4_TECH_VID, BLOODY_MP_50RS_PID, 2, 0xFFF2, 0x6009);
|
||||
@@ -269,7 +269,7 @@ void RGBController_PolychromeUSB::SetupZones()
|
||||
new_led.name = zones[channel_idx].name;
|
||||
new_led.name.append(", LED ");
|
||||
new_led.name.append(std::to_string(led_ch_idx + 1));
|
||||
new_led.value = (unsigned int)channel_idx;
|
||||
new_led.value = channel_idx;
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
@@ -334,14 +334,9 @@ void RGBController_PolychromeUSB::DeviceUpdateLEDs()
|
||||
}
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
if(zones[zone_idx].leds_count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned char set_mode = zones_info[zone_idx].mode;
|
||||
|
||||
if(set_mode>modes.size())
|
||||
if (set_mode>modes.size())
|
||||
{
|
||||
set_mode = active_mode;
|
||||
}
|
||||
@@ -352,11 +347,6 @@ void RGBController_PolychromeUSB::DeviceUpdateLEDs()
|
||||
|
||||
void RGBController_PolychromeUSB::DeviceUpdateZoneLEDs(int zone)
|
||||
{
|
||||
if(zones[zone].leds_count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char set_mode=zones_info[zone].mode;
|
||||
|
||||
if(set_mode > modes.size())
|
||||
@@ -364,7 +354,7 @@ void RGBController_PolychromeUSB::DeviceUpdateZoneLEDs(int zone)
|
||||
set_mode = active_mode;
|
||||
}
|
||||
|
||||
controller->WriteZone((unsigned char)zone, set_mode, zones_info[zone].speed, zones[zone].colors[0], false);
|
||||
controller->WriteZone(zone, set_mode, zones_info[zone].speed, zones[zone].colors[0], false);
|
||||
}
|
||||
|
||||
void RGBController_PolychromeUSB::DeviceUpdateSingleLED(int led)
|
||||
@@ -372,17 +362,12 @@ void RGBController_PolychromeUSB::DeviceUpdateSingleLED(int led)
|
||||
unsigned int channel = leds[led].value;
|
||||
unsigned char set_mode = zones_info[channel].mode;
|
||||
|
||||
if(zones[channel].leds_count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(set_mode > modes.size())
|
||||
{
|
||||
set_mode = active_mode;
|
||||
}
|
||||
|
||||
controller->WriteZone((unsigned char)channel, set_mode, zones_info[channel].speed, zones[channel].colors[0], false);
|
||||
controller->WriteZone(channel, set_mode, zones_info[channel].speed, zones[channel].colors[0], false);
|
||||
}
|
||||
|
||||
unsigned char RGBController_PolychromeUSB::GetDeviceMode(unsigned char zone)
|
||||
|
||||
-199
@@ -1,199 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ASRockGPUSMBusController.cpp |
|
||||
| |
|
||||
| Driver for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| Based on SignalRGB ASRock GPU.js plugin |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "ASRockGPUSMBusController.h"
|
||||
#include "LogManager.h"
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <thread>
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
ASRockGPUSMBusController::ASRockGPUSMBusController(i2c_smbus_interface* bus, asrock_gpu_dev_id dev, std::string name)
|
||||
{
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
this->device_name = name;
|
||||
this->num_channels = 0;
|
||||
|
||||
memset(enabled_channels, 0, sizeof(enabled_channels));
|
||||
memset(led_counts, 0, sizeof(led_counts));
|
||||
}
|
||||
|
||||
ASRockGPUSMBusController::~ASRockGPUSMBusController()
|
||||
{
|
||||
}
|
||||
|
||||
std::string ASRockGPUSMBusController::GetDeviceLocation()
|
||||
{
|
||||
std::string return_string(bus->info.device_name);
|
||||
char addr[5];
|
||||
snprintf(addr, 5, "0x%02X", dev);
|
||||
return_string.append(", address ");
|
||||
return_string.append(addr);
|
||||
return("I2C: " + return_string);
|
||||
}
|
||||
|
||||
std::string ASRockGPUSMBusController::GetDeviceName()
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
bool ASRockGPUSMBusController::WriteBlock(uint8_t command, uint8_t subcommand, const uint8_t* data, uint8_t len)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| SignalRGB packet format |
|
||||
| [command, 0, subcommand, data...] |
|
||||
| Uses pure I2C rather than SMBus |
|
||||
\*-----------------------------------------------------*/
|
||||
uint8_t packet[12];
|
||||
memset(packet, 0, sizeof(packet));
|
||||
|
||||
packet[0] = command;
|
||||
packet[1] = 0x00;
|
||||
packet[2] = subcommand;
|
||||
|
||||
if(data != nullptr && len > 0)
|
||||
{
|
||||
uint8_t copy_len = (len > 9) ? 9 : len;
|
||||
memcpy(&packet[3], data, copy_len);
|
||||
}
|
||||
|
||||
int size = 12;
|
||||
int result = bus->i2c_write_block(dev, size, packet);
|
||||
|
||||
if(result < 0)
|
||||
{
|
||||
LOG_DEBUG("[ASRock GPU] Write block failed: %d", result);
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool ASRockGPUSMBusController::ReadBlock(uint8_t* response, uint8_t len)
|
||||
{
|
||||
memset(response, 0, len);
|
||||
int size = len;
|
||||
int result = bus->i2c_read_block(dev, &size, response);
|
||||
|
||||
if(result < 0)
|
||||
{
|
||||
LOG_DEBUG("[ASRock GPU] Read block failed: %d", result);
|
||||
return(false);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool ASRockGPUSMBusController::DetectChannels()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Get enabled channels |
|
||||
| Command 0x14, subcommand 0x01 |
|
||||
\*-----------------------------------------------------*/
|
||||
if(!WriteBlock(0x14, 0x01, nullptr, 0))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to request enabled channels");
|
||||
return(false);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(20ms);
|
||||
|
||||
uint8_t response[I2C_SMBUS_BLOCK_MAX];
|
||||
if(!ReadBlock(response, sizeof(response)))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to read enabled channels");
|
||||
return(false);
|
||||
}
|
||||
|
||||
LOG_TRACE("[ASRock GPU] Enabled channels response: %02X %02X %02X %02X %02X %02X", response[0], response[1], response[2], response[3], response[4], response[5]);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Response format |
|
||||
| Bytes 4-5 contain the channel bitmap |
|
||||
\*-----------------------------------------------------*/
|
||||
uint16_t channel_bits = response[4] | (response[5] << 8);
|
||||
LOG_TRACE("[ASRock GPU] Channel bits: 0x%04X", channel_bits);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get LED counts |
|
||||
| Command 0x14, subcommand 0x02 |
|
||||
\*-----------------------------------------------------*/
|
||||
if(!WriteBlock(0x14, 0x02, nullptr, 0))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to request LED counts");
|
||||
return(false);
|
||||
}
|
||||
|
||||
std::this_thread::sleep_for(20ms);
|
||||
|
||||
if(!ReadBlock(response, sizeof(response)))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to read LED counts");
|
||||
return(false);
|
||||
}
|
||||
|
||||
num_channels = 0;
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
if(channel_bits & (1 << i))
|
||||
{
|
||||
enabled_channels[num_channels] = i;
|
||||
led_counts[num_channels] = response[4 + i];
|
||||
|
||||
const char* name = "Unknown";
|
||||
if(i == ASROCK_GPU_CHANNEL_ARGB_HEADER)
|
||||
{
|
||||
name = "ARGB Header";
|
||||
}
|
||||
else if(i == ASROCK_GPU_CHANNEL_TOP_SIDE)
|
||||
{
|
||||
name = "Top Side";
|
||||
}
|
||||
else if(i == ASROCK_GPU_CHANNEL_FAN)
|
||||
{
|
||||
name = "Fan";
|
||||
}
|
||||
|
||||
LOG_DEBUG("[ASRock GPU] Channel %d (%s) active with %d LEDs", i, name, response[4 + i]);
|
||||
num_channels++;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("[ASRock GPU] Found %d active channels", num_channels);
|
||||
return(num_channels > 0);
|
||||
}
|
||||
|
||||
void ASRockGPUSMBusController::SetChannelColor(uint8_t channel_idx, uint8_t red, uint8_t green, uint8_t blue)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| SignalRGB color packet |
|
||||
| Command 0x10, subcommand is the channel index |
|
||||
\*-----------------------------------------------------*/
|
||||
uint8_t data[8] =
|
||||
{
|
||||
0x01, // Mode: direct/static
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
0x80, // Effect speed
|
||||
0xFF, // Brightness
|
||||
0x00, // Effect direction
|
||||
0x1A // Unknown constant
|
||||
};
|
||||
|
||||
if(!WriteBlock(0x10, channel_idx, data, sizeof(data)))
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] Failed to set color for channel %d", channel_idx);
|
||||
}
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ASRockGPUSMBusController.h |
|
||||
| |
|
||||
| Driver for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| Based on SignalRGB ASRock GPU.js plugin |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "i2c_smbus.h"
|
||||
|
||||
typedef uint8_t asrock_gpu_dev_id;
|
||||
|
||||
#define ASROCK_GPU_CONTROLLER_NAME "ASRock GPU SMBus Controller"
|
||||
#define ASROCK_GPU_SMBUS_ADDRESS 0x36
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| ASRock GPU Channel Names (from SignalRGB) |
|
||||
\*-----------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
ASROCK_GPU_CHANNEL_ARGB_HEADER = 3,
|
||||
ASROCK_GPU_CHANNEL_TOP_SIDE = 6,
|
||||
ASROCK_GPU_CHANNEL_FAN = 7,
|
||||
};
|
||||
|
||||
class ASRockGPUSMBusController
|
||||
{
|
||||
public:
|
||||
ASRockGPUSMBusController(i2c_smbus_interface* bus, asrock_gpu_dev_id dev, std::string name);
|
||||
~ASRockGPUSMBusController();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetDeviceName();
|
||||
|
||||
void SetChannelColor(uint8_t channel_idx, uint8_t red, uint8_t green, uint8_t blue);
|
||||
bool DetectChannels();
|
||||
|
||||
uint8_t enabled_channels[16];
|
||||
uint8_t led_counts[16];
|
||||
uint8_t num_channels;
|
||||
|
||||
private:
|
||||
i2c_smbus_interface* bus;
|
||||
asrock_gpu_dev_id dev;
|
||||
std::string device_name;
|
||||
|
||||
bool WriteBlock(uint8_t command, uint8_t subcommand, const uint8_t* data, uint8_t len);
|
||||
bool ReadBlock(uint8_t* response, uint8_t len);
|
||||
};
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ASRockGPUSMBusControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "DetectionManager.h"
|
||||
#include "ASRockGPUSMBusController.h"
|
||||
#include "LogManager.h"
|
||||
#include "RGBController_ASRockGPUSMBus.h"
|
||||
#include "i2c_amd_gpu.h"
|
||||
#include "i2c_smbus.h"
|
||||
#include "pci_ids.h"
|
||||
|
||||
DetectedControllers DetectASRockGPUSMBusControllers(i2c_smbus_interface* bus, uint8_t address, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
|
||||
if(bus->info.pci_vendor == AMD_GPU_VEN && !is_amd_gpu_i2c_bus(bus))
|
||||
{
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
LOG_DEBUG("[ASRock GPU] Checking GPU I2C bus for RGB controller at 0x%02X", address);
|
||||
|
||||
ASRockGPUSMBusController* controller = new ASRockGPUSMBusController(bus, address, name);
|
||||
|
||||
if(controller->DetectChannels())
|
||||
{
|
||||
detected_controllers.push_back(new RGBController_ASRockGPUSMBus(controller));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_WARNING("[ASRock GPU] No active channels found, device not registered");
|
||||
delete controller;
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_I2C_PCI_DETECTOR("ASRock Radeon RX 9070 XT Steel Legend", DetectASRockGPUSMBusControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, ASROCK_SUB_VEN, 0x5403, ASROCK_GPU_SMBUS_ADDRESS);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASRock Radeon RX 9070 XT Steel Legend Dark", DetectASRockGPUSMBusControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, ASROCK_SUB_VEN, 0x5414, ASROCK_GPU_SMBUS_ADDRESS);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASRock Radeon RX 9070 XT Taichi 16GB OC", DetectASRockGPUSMBusControllers, AMD_GPU_VEN, AMD_NAVI48_DEV, ASROCK_SUB_VEN, 0x5401, ASROCK_GPU_SMBUS_ADDRESS);
|
||||
REGISTER_I2C_PCI_DETECTOR("ASRock Radeon RX 9060 XT Steel Legend", DetectASRockGPUSMBusControllers, AMD_GPU_VEN, AMD_NAVI44_DEV, ASROCK_SUB_VEN, 0x5407, ASROCK_GPU_SMBUS_ADDRESS);
|
||||
-140
@@ -1,140 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_ASRockGPUSMBus.cpp |
|
||||
| |
|
||||
| RGBController for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| Based on SignalRGB ASRock GPU.js plugin |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_ASRockGPUSMBus.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name ASRock GPU SMBus
|
||||
@category GPU
|
||||
@type I2C
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectASRockGPUSMBusControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_ASRockGPUSMBus::RGBController_ASRockGPUSMBus(ASRockGPUSMBusController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
vendor = "ASRock";
|
||||
type = DEVICE_TYPE_GPU;
|
||||
description = "ASRock GPU RGB Controller";
|
||||
location = controller->GetDeviceLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_ASRockGPUSMBus::~RGBController_ASRockGPUSMBus()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::SetupZones()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up zones - one zone per channel |
|
||||
\*-----------------------------------------------------*/
|
||||
for(unsigned int i = 0; i < controller->num_channels; i++)
|
||||
{
|
||||
uint8_t channel_idx = controller->enabled_channels[i];
|
||||
|
||||
zone new_zone;
|
||||
new_zone.type = ZONE_TYPE_SINGLE;
|
||||
new_zone.leds_min = 1;
|
||||
new_zone.leds_max = 1;
|
||||
new_zone.leds_count = 1;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Channel names from SignalRGB |
|
||||
\*-----------------------------------------------------*/
|
||||
if(channel_idx == ASROCK_GPU_CHANNEL_ARGB_HEADER)
|
||||
{
|
||||
new_zone.name = "ARGB Header";
|
||||
}
|
||||
else if(channel_idx == ASROCK_GPU_CHANNEL_TOP_SIDE)
|
||||
{
|
||||
new_zone.name = "Top Side";
|
||||
}
|
||||
else if(channel_idx == ASROCK_GPU_CHANNEL_FAN)
|
||||
{
|
||||
new_zone.name = "Fan";
|
||||
}
|
||||
else
|
||||
{
|
||||
new_zone.name = "Channel " + std::to_string(channel_idx);
|
||||
}
|
||||
|
||||
zones.push_back(new_zone);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up LED for this zone |
|
||||
\*-----------------------------------------------------*/
|
||||
led new_led;
|
||||
new_led.name = new_zone.name;
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::ResizeZone(int /*zone*/, int /*new_size*/)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| This device does not support resizing zones |
|
||||
\*-----------------------------------------------------*/
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::DeviceUpdateLEDs()
|
||||
{
|
||||
for(unsigned int i = 0; i < controller->num_channels; i++)
|
||||
{
|
||||
uint8_t channel_idx = controller->enabled_channels[i];
|
||||
RGBColor color = colors[i];
|
||||
|
||||
controller->SetChannelColor(channel_idx,
|
||||
RGBGetRValue(color),
|
||||
RGBGetGValue(color),
|
||||
RGBGetBValue(color));
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::UpdateZoneLEDs(int zone)
|
||||
{
|
||||
uint8_t channel_idx = controller->enabled_channels[zone];
|
||||
RGBColor color = colors[zone];
|
||||
|
||||
controller->SetChannelColor(channel_idx,
|
||||
RGBGetRValue(color),
|
||||
RGBGetGValue(color),
|
||||
RGBGetBValue(color));
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::UpdateSingleLED(int led)
|
||||
{
|
||||
UpdateZoneLEDs(led);
|
||||
}
|
||||
|
||||
void RGBController_ASRockGPUSMBus::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_ASRockGPUSMBus.h |
|
||||
| |
|
||||
| RGBController for ASRock GPU RGB controllers |
|
||||
| |
|
||||
| Based on SignalRGB ASRock GPU.js plugin |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "ASRockGPUSMBusController.h"
|
||||
|
||||
class RGBController_ASRockGPUSMBus : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_ASRockGPUSMBus(ASRockGPUSMBusController* controller_ptr);
|
||||
~RGBController_ASRockGPUSMBus();
|
||||
|
||||
void SetupZones();
|
||||
void ResizeZone(int zone, int new_size);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void UpdateZoneLEDs(int zone);
|
||||
void UpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
ASRockGPUSMBusController* controller;
|
||||
};
|
||||
+3
@@ -238,6 +238,7 @@ void RGBController_ASRockPolychromeV2SMBus::SetupZones()
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int led_count = 0;
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up LEDs |
|
||||
\*---------------------------------------------------------*/
|
||||
@@ -267,6 +268,8 @@ void RGBController_ASRockPolychromeV2SMBus::SetupZones()
|
||||
\*---------------------------------------------------------*/
|
||||
leds.push_back(*new_led);
|
||||
|
||||
led_count++;
|
||||
|
||||
if(zone_idx == POLYCHROME_V2_ZONE_ADDRESSABLE)
|
||||
{
|
||||
break;
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| Detector for Acer Nitro HID Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <vector>
|
||||
#include "DetectionManager.h"
|
||||
#include "AcerNitroHidKeyboardController.h"
|
||||
#include "RGBController_AcerNitroHidKeyboard.h"
|
||||
#include "RGBController_AcerNitroHidLed.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| HID vendor and product IDs for ENEK EC in Acer Nitro |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#define ACER_ENEC_VID 0x0CF2
|
||||
#define ACER_ENEC_PID 0x5130
|
||||
#define ACER_ENEC_USAGE_PAGE 0xFF5A
|
||||
#define ACER_ENEC_USAGE 0x01
|
||||
|
||||
DetectedControllers DetectAcerHIDControllers(hid_device_info* info, const std::string&)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
if(dev)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Controller is shared between keyboard and onboard |
|
||||
| led |
|
||||
\*-------------------------------------------------*/
|
||||
std::shared_ptr<AcerNitroHidKeyboardController> controller = std::make_shared<AcerNitroHidKeyboardController>(dev, info->path);
|
||||
RGBController_AcerNitroHidKeyboard* rgb_kb_controller = new RGBController_AcerNitroHidKeyboard(controller);
|
||||
RGBController_AcerNitroHidLed* rgb_led_controller = new RGBController_AcerNitroHidLed(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_kb_controller);
|
||||
detected_controllers.push_back(rgb_led_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_PU("AcerNitroHidKeyboardController", DetectAcerHIDControllers, ACER_ENEC_VID, ACER_ENEC_PID, ACER_ENEC_USAGE_PAGE, ACER_ENEC_USAGE);
|
||||
@@ -1,80 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| Driver for Acer Nitro Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "AcerNitroHidKeyboardController.h"
|
||||
|
||||
AcerNitroHidKeyboardController::AcerNitroHidKeyboardController(hid_device *dev_handle, const char *path)
|
||||
{
|
||||
this->location = path;
|
||||
this->dev = dev_handle;
|
||||
|
||||
device_name = "Acer Nitro HID Keyboard";
|
||||
}
|
||||
|
||||
AcerNitroHidKeyboardController::~AcerNitroHidKeyboardController()
|
||||
{
|
||||
if(dev)
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
}
|
||||
|
||||
std::string AcerNitroHidKeyboardController::GetLocation() const
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string AcerNitroHidKeyboardController::GetDeviceName() const
|
||||
{
|
||||
return(device_name);
|
||||
}
|
||||
|
||||
void AcerNitroHidKeyboardController::SetLEDs(const std::vector<RGBColor>& colors, unsigned char brightness, unsigned char device_id)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(device_mutex);
|
||||
|
||||
for(unsigned int led_idx = 0; (led_idx < colors.size()) && (led_idx < ACER_HID_NUM_ZONES); led_idx++)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Convert colors to RGB format |
|
||||
\*-------------------------------------------------*/
|
||||
unsigned char r = RGBGetRValue(colors[led_idx]);
|
||||
unsigned char g = RGBGetGValue(colors[led_idx]);
|
||||
unsigned char b = RGBGetBValue(colors[led_idx]);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-------------------------------------------------*/
|
||||
unsigned char zone_select = (unsigned char)(1<<led_idx);
|
||||
unsigned char packet[ACER_HID_PACKET_SIZE] = {0xA4, device_id, ACER_HID_MODE_STATIC, brightness, 0, 1, r, g, b, zone_select, 0};
|
||||
hid_send_feature_report(dev, packet, ACER_HID_PACKET_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
void AcerNitroHidKeyboardController::SetAllLEDs(const RGBColor &color, unsigned char brightness, unsigned char speed, unsigned char direction, unsigned char mode, unsigned char device_id)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(device_mutex);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Convert color to RGB format |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char r = RGBGetRValue(color);
|
||||
unsigned char g = RGBGetGValue(color);
|
||||
unsigned char b = RGBGetBValue(color);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
| Zone select = All zones |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned char zone_select = 0x0F;
|
||||
unsigned char packet[ACER_HID_PACKET_SIZE] = {0xA4, device_id, mode, brightness, speed, direction, r, g, b, zone_select, 0};
|
||||
hid_send_feature_report(dev, packet, ACER_HID_PACKET_SIZE);
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| Driver for Acer Nitro Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum
|
||||
{
|
||||
ACER_HID_MODE_DIRECT = 1,
|
||||
ACER_HID_MODE_STATIC = 2,
|
||||
ACER_HID_MODE_BREATHING = 4,
|
||||
ACER_HID_MODE_NEON = 5,
|
||||
ACER_HID_MODE_OPMODE = 6,
|
||||
ACER_HID_MODE_WAVE = 7,
|
||||
ACER_HID_MODE_SHIFTING = 8,
|
||||
ACER_HID_MODE_ZOOM = 9,
|
||||
ACER_HID_MODE_METEOR = 10,
|
||||
ACER_HID_MODE_TWINKLING = 11,
|
||||
};
|
||||
|
||||
#define ACER_HID_NAME_BUFFER_SIZE 255
|
||||
#define ACER_HID_NUM_ZONES 4
|
||||
#define ACER_HID_PACKET_SIZE 11
|
||||
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "RGBControllerInterface.h"
|
||||
|
||||
class AcerNitroHidKeyboardController
|
||||
{
|
||||
public:
|
||||
AcerNitroHidKeyboardController(hid_device *dev_handle, const char *path);
|
||||
~AcerNitroHidKeyboardController();
|
||||
|
||||
std::string GetDeviceName() const;
|
||||
std::string GetSerial() const;
|
||||
std::string GetLocation() const;
|
||||
|
||||
void SetLEDs(const std::vector<RGBColor> &colors, unsigned char brightness, unsigned char device_id);
|
||||
void SetAllLEDs(const RGBColor &color, unsigned char brightness, unsigned char speed, unsigned char direction, unsigned char mode, unsigned char device_id);
|
||||
|
||||
private:
|
||||
hid_device *dev;
|
||||
std::string device_name;
|
||||
std::string location;
|
||||
std::mutex device_mutex;
|
||||
};
|
||||
@@ -1,231 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| RGBController for Acer Nitro HID Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_AcerNitroHidKeyboard.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Acer Nitro HID Keyboard
|
||||
@category Laptop
|
||||
@type HID
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectAcerHIDControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_AcerNitroHidKeyboard::RGBController_AcerNitroHidKeyboard(std::shared_ptr<AcerNitroHidKeyboardController> controller)
|
||||
{
|
||||
this->controller = controller;
|
||||
device_id = 0x21;
|
||||
|
||||
name = "Acer Nitro HID Keyboard";
|
||||
vendor = "Acer";
|
||||
type = DEVICE_TYPE_LAPTOP;
|
||||
description = "Acer Nitro HID Keyboard Device";
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = ACER_HID_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS ;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
Direct.brightness_min = 0;
|
||||
Direct.brightness_max = 100;
|
||||
Direct.brightness = 100;
|
||||
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = ACER_HID_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.brightness_min = 0;
|
||||
Static.brightness_max = 100;
|
||||
Static.brightness = 100;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(1);
|
||||
Static.speed = 0;
|
||||
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = ACER_HID_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = 100;
|
||||
Breathing.brightness = 100;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.speed_min = 1;
|
||||
Breathing.speed_max = 9;
|
||||
Breathing.speed = 4;
|
||||
Breathing.colors.resize(1);
|
||||
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Neon;
|
||||
Neon.name = "Neon";
|
||||
Neon.value = ACER_HID_MODE_NEON;
|
||||
Neon.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Neon.color_mode = MODE_COLORS_NONE;
|
||||
Neon.brightness_min = 0;
|
||||
Neon.brightness_max = 100;
|
||||
Neon.brightness = 100;
|
||||
Neon.speed_min = 1;
|
||||
Neon.speed_max = 9;
|
||||
Neon.speed = 4;
|
||||
|
||||
modes.push_back(Neon);
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = ACER_HID_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR;
|
||||
Wave.color_mode = MODE_COLORS_NONE;
|
||||
Wave.brightness_min = 0;
|
||||
Wave.brightness_max = 100;
|
||||
Wave.brightness = 100;
|
||||
Wave.speed_min = 1;
|
||||
Wave.speed_max = 9;
|
||||
Wave.speed = 4;
|
||||
Wave.direction = 0;
|
||||
|
||||
modes.push_back(Wave);
|
||||
|
||||
mode Shifting;
|
||||
Shifting.name = "Shifting";
|
||||
Shifting.value = ACER_HID_MODE_SHIFTING;
|
||||
Shifting.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Shifting.color_mode = MODE_COLORS_NONE;
|
||||
Shifting.brightness_min = 0;
|
||||
Shifting.brightness_max = 100;
|
||||
Shifting.brightness = 100;
|
||||
Shifting.speed_min = 1;
|
||||
Shifting.speed_max = 9;
|
||||
Shifting.speed = 4;
|
||||
|
||||
modes.push_back(Shifting);
|
||||
|
||||
mode Zoom;
|
||||
Zoom.name = "Zoom";
|
||||
Zoom.value = ACER_HID_MODE_ZOOM;
|
||||
Zoom.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Zoom.color_mode = MODE_COLORS_NONE;
|
||||
Zoom.brightness_min = 0;
|
||||
Zoom.brightness_max = 100;
|
||||
Zoom.brightness = 100;
|
||||
Zoom.speed_min = 1;
|
||||
Zoom.speed_max = 9;
|
||||
Zoom.speed = 4;
|
||||
|
||||
modes.push_back(Zoom);
|
||||
|
||||
mode Meteor;
|
||||
Meteor.name = "Meteor";
|
||||
Meteor.value = ACER_HID_MODE_METEOR;
|
||||
Meteor.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Meteor.color_mode = MODE_COLORS_NONE;
|
||||
Meteor.brightness_min = 0;
|
||||
Meteor.brightness_max = 100;
|
||||
Meteor.brightness = 100;
|
||||
Meteor.speed_min = 1;
|
||||
Meteor.speed_max = 9;
|
||||
Meteor.speed = 4;
|
||||
|
||||
modes.push_back(Meteor);
|
||||
|
||||
mode Twinkling;
|
||||
Twinkling.name = "Twinkling";
|
||||
Twinkling.value = ACER_HID_MODE_TWINKLING;
|
||||
Twinkling.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Twinkling.color_mode = MODE_COLORS_NONE;
|
||||
Twinkling.brightness_min = 0;
|
||||
Twinkling.brightness_max = 100;
|
||||
Twinkling.brightness = 100;
|
||||
Twinkling.colors_min = 1;
|
||||
Twinkling.colors_max = 1;
|
||||
Twinkling.speed_min = 1;
|
||||
Twinkling.speed_max = 9;
|
||||
Twinkling.speed = 4;
|
||||
|
||||
modes.push_back(Twinkling);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_AcerNitroHidKeyboard::~RGBController_AcerNitroHidKeyboard()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::SetupZones()
|
||||
{
|
||||
zone* new_zone = new zone;
|
||||
|
||||
new_zone->name = "Keyboard Backlight Zone";
|
||||
new_zone->type = ZONE_TYPE_LINEAR;
|
||||
new_zone->leds_min = 4;
|
||||
new_zone->leds_max = 4;
|
||||
new_zone->leds_count = 4;
|
||||
|
||||
zones.push_back(*new_zone);
|
||||
|
||||
for(std::size_t zone_idx = 0; zone_idx < ACER_HID_NUM_ZONES; zone_idx++)
|
||||
{
|
||||
led* new_led = new led();
|
||||
new_led->name = "Keyboard Backlight Zone ";
|
||||
new_led->name.append(std::to_string(zone_idx + 1));
|
||||
new_led->value = (unsigned int)leds.size();
|
||||
|
||||
leds.push_back(*new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::DeviceUpdateLEDs()
|
||||
{
|
||||
mode& current_mode = modes[active_mode];
|
||||
if(current_mode.value == ACER_HID_MODE_DIRECT)
|
||||
{
|
||||
controller->SetLEDs(colors, current_mode.brightness, device_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
RGBColor color = current_mode.colors.size()==0? (RGBColor)0 : current_mode.colors[0];
|
||||
unsigned char direction = 1;
|
||||
if((modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR) && modes[active_mode].direction)
|
||||
{
|
||||
direction = 2;
|
||||
}
|
||||
controller->SetAllLEDs(color, current_mode.brightness, current_mode.speed, direction, current_mode.value, device_id);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::DeviceUpdateZoneLEDs(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::DeviceUpdateSingleLED(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidKeyboard::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidKeyboard.cpp |
|
||||
| |
|
||||
| RGBController for Acer Nitro HID Keyboard |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "AcerNitroHidKeyboardController.h"
|
||||
|
||||
class RGBController_AcerNitroHidKeyboard : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_AcerNitroHidKeyboard(std::shared_ptr<AcerNitroHidKeyboardController> controller);
|
||||
~RGBController_AcerNitroHidKeyboard();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
std::shared_ptr<AcerNitroHidKeyboardController> controller;
|
||||
unsigned int device_id;
|
||||
};
|
||||
@@ -1,152 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidLed.cpp |
|
||||
| |
|
||||
| RGBController for Acer Nitro HID LED |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBController_AcerNitroHidLed.h"
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Acer Nitro HID Led
|
||||
@category Laptop
|
||||
@type HID
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :white_check_mark:
|
||||
@detectors DetectAcerHIDControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_AcerNitroHidLed::RGBController_AcerNitroHidLed(std::shared_ptr<AcerNitroHidKeyboardController> controller)
|
||||
{
|
||||
this->controller = controller;
|
||||
device_id = 0x65;
|
||||
|
||||
name = "Acer Nitro HID LED Device";
|
||||
vendor = "Acer";
|
||||
type = DEVICE_TYPE_LIGHT;
|
||||
description = "Acer Nitro HID LED Device";
|
||||
location = controller->GetLocation();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = ACER_HID_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS ;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
Direct.brightness_min = 0;
|
||||
Direct.brightness_max = 100;
|
||||
Direct.brightness = 100;
|
||||
|
||||
modes.push_back(Direct);
|
||||
|
||||
mode Static;
|
||||
Static.name = "Static";
|
||||
Static.value = ACER_HID_MODE_STATIC;
|
||||
Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Static.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Static.brightness_min = 0;
|
||||
Static.brightness_max = 100;
|
||||
Static.brightness = 100;
|
||||
Static.colors_min = 1;
|
||||
Static.colors_max = 1;
|
||||
Static.colors.resize(1);
|
||||
Static.speed = 0;
|
||||
|
||||
modes.push_back(Static);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = ACER_HID_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Breathing.brightness_min = 0;
|
||||
Breathing.brightness_max = 100;
|
||||
Breathing.brightness = 100;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.speed_min = 1;
|
||||
Breathing.speed_max = 5;
|
||||
Breathing.speed = 4;
|
||||
Breathing.colors.resize(1);
|
||||
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Neon;
|
||||
Neon.name = "Neon";
|
||||
Neon.value = ACER_HID_MODE_NEON;
|
||||
Neon.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Neon.color_mode = MODE_COLORS_NONE;
|
||||
Neon.brightness_min = 0;
|
||||
Neon.brightness_max = 100;
|
||||
Neon.brightness = 100;
|
||||
Neon.speed_min = 1;
|
||||
Neon.speed_max = 5;
|
||||
Neon.speed = 4;
|
||||
|
||||
modes.push_back(Neon);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
|
||||
RGBController_AcerNitroHidLed::~RGBController_AcerNitroHidLed()
|
||||
{
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::SetupZones()
|
||||
{
|
||||
zone* new_zone = new zone;
|
||||
|
||||
new_zone->name = "LED";
|
||||
new_zone->type = ZONE_TYPE_LINEAR;
|
||||
new_zone->leds_min = 1;
|
||||
new_zone->leds_max = 1;
|
||||
new_zone->leds_count = 1;
|
||||
zones.push_back(*new_zone);
|
||||
|
||||
led* new_led = new led();
|
||||
new_led->name = "LED";
|
||||
new_led->value = (unsigned int)leds.size();
|
||||
leds.push_back(*new_led);
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::DeviceUpdateLEDs()
|
||||
{
|
||||
mode& current_mode = modes[active_mode];
|
||||
if(current_mode.value == ACER_HID_MODE_DIRECT)
|
||||
{
|
||||
controller->SetLEDs(colors, current_mode.brightness, device_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
RGBColor color = current_mode.colors.size()==0? (RGBColor)0 : current_mode.colors[0];
|
||||
unsigned char direction = 1;
|
||||
if((modes[active_mode].flags & MODE_FLAG_HAS_DIRECTION_LR) && modes[active_mode].direction)
|
||||
{
|
||||
direction = 2;
|
||||
}
|
||||
controller->SetAllLEDs(color, current_mode.brightness, current_mode.speed, direction, current_mode.value, device_id);
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::DeviceUpdateZoneLEDs(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::DeviceUpdateSingleLED(int)
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
|
||||
void RGBController_AcerNitroHidLed::DeviceUpdateMode()
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_AcerNitroHidLed.cpp |
|
||||
| |
|
||||
| RGBController for Acer Nitro HID LED |
|
||||
| |
|
||||
| Marek Pokropiński Jul 27 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "AcerNitroHidKeyboardController.h"
|
||||
#include "RGBController_AcerNitroHidKeyboard.h"
|
||||
|
||||
class RGBController_AcerNitroHidLed : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_AcerNitroHidLed(std::shared_ptr<AcerNitroHidKeyboardController> controller);
|
||||
~RGBController_AcerNitroHidLed();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
std::shared_ptr<AcerNitroHidKeyboardController> controller;
|
||||
unsigned int device_id;
|
||||
};
|
||||
@@ -32,7 +32,6 @@ static const std::map<alienware_platform_id, uint8_t> zone_quirks_table =
|
||||
{ 0x0C01, 4 }, // Dell G5 SE 5505
|
||||
{ 0x0A01, 16 }, // Dell G7 15 7500
|
||||
{ 0x0E03, 4 }, // Dell G15 5511
|
||||
{ 0x0E07, 4 }, // Dell G15 5520
|
||||
{ 0x0E0A, 4 } // Dell G15 5530
|
||||
|
||||
};
|
||||
@@ -50,21 +49,9 @@ static const std::map<alienware_platform_id, std::vector<const char*>> zone_name
|
||||
"Light Bar 7", "Light Bar 8", "Light Bar 9",
|
||||
"Light Bar 10", "Light Bar 11", "Light Bar 12" } },
|
||||
{ 0x0E03, { "Left", "Middle", "Right", "Numpad" } },
|
||||
{ 0x0E07, { "Left", "Middle", "Right", "Numpad" } },
|
||||
{ 0x0E0A, { "Left", "Middle", "Right", "Numpad" } }
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Mapping the platform ID to the actual hardware zone IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
static const std::map<alienware_platform_id, std::vector<uint8_t>> zone_ids_table =
|
||||
{
|
||||
{ 0x0C01, { 0x00, 0x01, 0x02, 0x03 } }, // Dell G5 SE 5505
|
||||
{ 0x0E03, { 0x00, 0x01, 0x02, 0x03 } }, // Dell G15 5511
|
||||
{ 0x0E07, { 0x10, 0x11, 0x12, 0x13 } }, // Dell G15 5520
|
||||
{ 0x0E0A, { 0x10, 0x11, 0x12, 0x13 } } // Dell G15 5530
|
||||
};
|
||||
|
||||
static void SendHIDReport(hid_device *dev, const unsigned char* usb_buf, size_t usb_buf_size)
|
||||
{
|
||||
using namespace std::chrono_literals;
|
||||
@@ -151,21 +138,6 @@ AlienwareController::AlienwareController(hid_device* dev_handle, const hid_devic
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Initialize hardware zone IDs |
|
||||
\*-----------------------------------------------------*/
|
||||
if(zone_ids_table.count(platform_id))
|
||||
{
|
||||
zone_ids = zone_ids_table.at(platform_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(size_t i = 0; i < number_of_zones; i++)
|
||||
{
|
||||
zone_ids.push_back(static_cast<uint8_t>(i));
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set defaults for all zones |
|
||||
| It doesn't seem possible to read the controller's |
|
||||
@@ -183,7 +155,6 @@ AlienwareController::AlienwareController(hid_device* dev_handle, const hid_devic
|
||||
zones[zone_idx].period = 2000;
|
||||
zones[zone_idx].tempo = ALIENWARE_TEMPO_MAX;
|
||||
zones[zone_idx].dim = 0;
|
||||
zones[zone_idx].direction = 0;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
@@ -295,53 +266,42 @@ bool AlienwareController::Dim(std::vector<uint8_t> zones, double percent)
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Split the zone list into packet-sized chunks so it |
|
||||
| never overflows usb_buf |
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
for(size_t offset = 0; offset < zones.size(); offset += ALIENWARE_MAX_ZONES_PER_PACKET)
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
usb_buf[0x06+i] = zones[i];
|
||||
}
|
||||
|
||||
return(result);
|
||||
/*-----------------------------------------------------*\
|
||||
| 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));
|
||||
}
|
||||
|
||||
bool AlienwareController::UserAnimation(uint16_t subcommand, uint16_t animation, uint16_t duration)
|
||||
@@ -410,53 +370,42 @@ bool AlienwareController::SelectZones(const std::vector<uint8_t>& zones)
|
||||
return(false);
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Split the zone list into packet-sized chunks so it |
|
||||
| never overflows usb_buf |
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
for(size_t offset = 0; offset < zones.size(); offset += ALIENWARE_MAX_ZONES_PER_PACKET)
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
usb_buf[0x06+i] = zones[i];
|
||||
}
|
||||
|
||||
return(result);
|
||||
/*-----------------------------------------------------*\
|
||||
| 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));
|
||||
}
|
||||
|
||||
bool AlienwareController::ModeAction(uint8_t mode, uint16_t duration, uint16_t tempo, RGBColor color)
|
||||
@@ -560,55 +509,44 @@ bool AlienwareController::SetColorDirect(RGBColor color, std::vector<uint8_t> zo
|
||||
return(true);
|
||||
}
|
||||
|
||||
bool result = true;
|
||||
unsigned char usb_buf[HIDAPI_ALIENWARE_REPORT_SIZE];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Split the zone list into packet-sized chunks so it |
|
||||
| never overflows usb_buf |
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
for(size_t offset = 0; offset < zones.size(); offset += ALIENWARE_MAX_ZONES_PER_PACKET)
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
usb_buf[0x08 + i] = zones[i];
|
||||
}
|
||||
|
||||
return(result);
|
||||
/*-----------------------------------------------------*\
|
||||
| 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));
|
||||
}
|
||||
|
||||
bool AlienwareController::Reset()
|
||||
@@ -702,15 +640,6 @@ void AlienwareController::SetDim(uint8_t zone, uint8_t dim)
|
||||
}
|
||||
}
|
||||
|
||||
void AlienwareController::SetDirection(uint8_t zone, uint8_t direction)
|
||||
{
|
||||
if(zone < zones.size())
|
||||
{
|
||||
zones[zone].direction = direction;
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AlienwareController::UpdateDim()
|
||||
{
|
||||
if(!dirty_dim)
|
||||
@@ -726,8 +655,7 @@ void AlienwareController::UpdateDim()
|
||||
|
||||
for(size_t i = 0; i < zones.size(); i++)
|
||||
{
|
||||
uint8_t hw_zone = (i < zone_ids.size()) ? zone_ids[i] : static_cast<uint8_t>(i);
|
||||
dim_zone_map[zones[i].dim].emplace_back(hw_zone);
|
||||
dim_zone_map[zones[i].dim].emplace_back((uint8_t)i);
|
||||
}
|
||||
|
||||
for(std::pair<const uint8_t, std::vector<uint8_t>> &pair : dim_zone_map)
|
||||
@@ -754,8 +682,7 @@ bool AlienwareController::UpdateDirect()
|
||||
|
||||
for(size_t i = 0; i < zones.size(); i++)
|
||||
{
|
||||
uint8_t hw_zone = (i < zone_ids.size()) ? zone_ids[i] : static_cast<uint8_t>(i);
|
||||
color_zone_map[zones[i].color[0]].emplace_back(hw_zone);
|
||||
color_zone_map[zones[i].color[0]].emplace_back((uint8_t)i);
|
||||
}
|
||||
|
||||
for(std::pair<const RGBColor, std::vector<uint8_t>> &pair : color_zone_map)
|
||||
@@ -799,9 +726,8 @@ void AlienwareController::UpdateMode()
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
alienware_zone zone = zones[zone_idx];
|
||||
uint8_t hw_zone = (zone_idx < zone_ids.size()) ? zone_ids[zone_idx] : static_cast<uint8_t>(zone_idx);
|
||||
|
||||
result = SelectZones({hw_zone});
|
||||
result = SelectZones({static_cast<uint8_t>(zone_idx)});
|
||||
|
||||
if(!result)
|
||||
{
|
||||
@@ -824,18 +750,18 @@ void AlienwareController::UpdateMode()
|
||||
|
||||
case ALIENWARE_MODE_MORPH:
|
||||
{
|
||||
uint8_t modes[2] = { zone.mode, zone.mode };
|
||||
uint8_t zones[2] = { zone.mode, zone.mode };
|
||||
uint16_t periods[2] = { zone.period, zone.period };
|
||||
uint16_t tempos[2] = { zone.tempo, zone.tempo };
|
||||
RGBColor colors[2] = { zone.color[0], zone.color[1] };
|
||||
|
||||
result = MultiModeAction(modes, periods, tempos, colors, 2);
|
||||
result = MultiModeAction(zones, periods, tempos, colors, 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case ALIENWARE_MODE_SPECTRUM:
|
||||
{
|
||||
uint8_t modes[7] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
|
||||
uint8_t zones[7] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
|
||||
ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
|
||||
ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
|
||||
ALIENWARE_MODE_MORPH };
|
||||
@@ -848,13 +774,13 @@ void AlienwareController::UpdateMode()
|
||||
zone.tempo, zone.tempo,
|
||||
zone.tempo };
|
||||
|
||||
result = MultiModeAction(modes, periods, tempos, rainbow_colors[0], 7);
|
||||
result = MultiModeAction(zones, periods, tempos, rainbow_colors[0], 7);
|
||||
}
|
||||
break;
|
||||
|
||||
case ALIENWARE_MODE_RAINBOW:
|
||||
{
|
||||
uint8_t modes[7] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
|
||||
uint8_t zones[7] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
|
||||
ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
|
||||
ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
|
||||
ALIENWARE_MODE_MORPH };
|
||||
@@ -867,19 +793,18 @@ void AlienwareController::UpdateMode()
|
||||
zone.tempo, zone.tempo,
|
||||
zone.tempo };
|
||||
|
||||
unsigned int color_idx = (zone.direction == MODE_DIRECTION_LEFT) ? (4 - 1 - (zone_idx % 4)) : (zone_idx % 4);
|
||||
result = MultiModeAction(modes, periods, tempos, rainbow_colors[color_idx], 7);
|
||||
result = MultiModeAction(zones, periods, tempos, rainbow_colors[zone_idx], 7);
|
||||
}
|
||||
break;
|
||||
|
||||
case ALIENWARE_MODE_BREATHING:
|
||||
{
|
||||
uint8_t modes[2] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH };
|
||||
uint8_t zones[2] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH };
|
||||
uint16_t periods[2] = { zone.period, zone.period };
|
||||
uint16_t tempos[2] = { zone.tempo, zone.tempo };
|
||||
RGBColor colors[2] = { zone.color[0], 0x0 };
|
||||
|
||||
result = MultiModeAction(modes, periods, tempos, colors, 2);
|
||||
result = MultiModeAction(zones, periods, tempos, colors, 2);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -906,117 +831,6 @@ void AlienwareController::UpdateMode()
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
void AlienwareController::SaveController()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Save current mode configuration to EEPROM slot 0x0061 |
|
||||
\*-----------------------------------------------------*/
|
||||
UserAnimation(ALIENWARE_COMMAND_USER_ANIM_REMOVE, ALIENWARE_ANIM_DEFAULT, 0);
|
||||
bool result = UserAnimation(ALIENWARE_COMMAND_USER_ANIM_NEW, ALIENWARE_ANIM_DEFAULT, 0);
|
||||
|
||||
if(!result)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
alienware_zone zone = zones[zone_idx];
|
||||
uint8_t hw_zone = (zone_idx < zone_ids.size()) ? zone_ids[zone_idx] : static_cast<uint8_t>(zone_idx);
|
||||
|
||||
result = SelectZones({hw_zone});
|
||||
|
||||
if(!result)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (zone.mode)
|
||||
{
|
||||
case ALIENWARE_MODE_COLOR:
|
||||
result = ModeAction(zone.mode, 2000, ALIENWARE_TEMPO_MAX, zone.color[0]);
|
||||
break;
|
||||
|
||||
case ALIENWARE_MODE_PULSE:
|
||||
result = ModeAction(zone.mode, zone.period, zone.tempo, zone.color[0]);
|
||||
break;
|
||||
|
||||
case ALIENWARE_MODE_MORPH:
|
||||
{
|
||||
uint8_t modes[2] = { zone.mode, zone.mode };
|
||||
uint16_t periods[2] = { zone.period, zone.period };
|
||||
uint16_t tempos[2] = { zone.tempo, zone.tempo };
|
||||
RGBColor colors[2] = { zone.color[0], zone.color[1] };
|
||||
|
||||
result = MultiModeAction(modes, periods, tempos, colors, 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case ALIENWARE_MODE_SPECTRUM:
|
||||
{
|
||||
uint8_t modes[7] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
|
||||
ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
|
||||
ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
|
||||
ALIENWARE_MODE_MORPH };
|
||||
uint16_t periods[7] = { zone.period, zone.period,
|
||||
zone.period, zone.period,
|
||||
zone.period, zone.period,
|
||||
zone.period };
|
||||
uint16_t tempos[7] = { zone.tempo, zone.tempo,
|
||||
zone.tempo, zone.tempo,
|
||||
zone.tempo, zone.tempo,
|
||||
zone.tempo };
|
||||
|
||||
result = MultiModeAction(modes, periods, tempos, rainbow_colors[0], 7);
|
||||
}
|
||||
break;
|
||||
|
||||
case ALIENWARE_MODE_RAINBOW:
|
||||
{
|
||||
uint8_t modes[7] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
|
||||
ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
|
||||
ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH,
|
||||
ALIENWARE_MODE_MORPH };
|
||||
uint16_t periods[7] = { zone.period, zone.period,
|
||||
zone.period, zone.period,
|
||||
zone.period, zone.period,
|
||||
zone.period };
|
||||
uint16_t tempos[7] = { zone.tempo, zone.tempo,
|
||||
zone.tempo, zone.tempo,
|
||||
zone.tempo, zone.tempo,
|
||||
zone.tempo };
|
||||
|
||||
unsigned int color_idx = (zone.direction == MODE_DIRECTION_LEFT) ? (4 - 1 - (zone_idx % 4)) : (zone_idx % 4);
|
||||
result = MultiModeAction(modes, periods, tempos, rainbow_colors[color_idx], 7);
|
||||
}
|
||||
break;
|
||||
|
||||
case ALIENWARE_MODE_BREATHING:
|
||||
{
|
||||
uint8_t modes[2] = { ALIENWARE_MODE_MORPH, ALIENWARE_MODE_MORPH };
|
||||
uint16_t periods[2] = { zone.period, zone.period };
|
||||
uint16_t tempos[2] = { zone.tempo, zone.tempo };
|
||||
RGBColor colors[2] = { zone.color[0], 0x0 };
|
||||
|
||||
result = MultiModeAction(modes, periods, tempos, colors, 2);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
result = false;
|
||||
}
|
||||
|
||||
if(!result)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
UserAnimation(ALIENWARE_COMMAND_USER_ANIM_FINISH_SAVE, ALIENWARE_ANIM_DEFAULT, 0);
|
||||
UserAnimation(ALIENWARE_COMMAND_USER_ANIM_DEFAULT, ALIENWARE_ANIM_DEFAULT, 0);
|
||||
UserAnimation(ALIENWARE_COMMAND_USER_ANIM_STARTUP, ALIENWARE_ANIM_DEFAULT, 0);
|
||||
}
|
||||
|
||||
void AlienwareController::UpdateController()
|
||||
{
|
||||
UpdateMode();
|
||||
|
||||
@@ -22,14 +22,6 @@
|
||||
#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 */
|
||||
@@ -123,13 +115,11 @@ public:
|
||||
void SetPeriod(uint8_t zone, uint16_t period);
|
||||
void SetTempo(uint8_t zone, uint16_t tempo);
|
||||
void SetDim(uint8_t zone, uint8_t dim);
|
||||
void SetDirection(uint8_t zone, uint8_t direction);
|
||||
AlienwareReport GetStatus(uint8_t subcommand);
|
||||
|
||||
void UpdateDim();
|
||||
void UpdateMode();
|
||||
void UpdateController();
|
||||
void SaveController();
|
||||
|
||||
protected:
|
||||
hid_device* dev;
|
||||
@@ -142,7 +132,6 @@ private:
|
||||
uint16_t period;
|
||||
uint16_t tempo;
|
||||
uint8_t dim;
|
||||
uint8_t direction;
|
||||
} alienware_zone;
|
||||
|
||||
typedef struct
|
||||
@@ -156,7 +145,6 @@ private:
|
||||
std::string serial_number;
|
||||
std::string version;
|
||||
std::vector<const char*> zone_names;
|
||||
std::vector<uint8_t> zone_ids;
|
||||
bool dirty;
|
||||
bool dirty_dim;
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ RGBController_Alienware::RGBController_Alienware(AlienwareController* controller
|
||||
mode Color;
|
||||
Color.name = "Static";
|
||||
Color.value = ALIENWARE_MODE_COLOR;
|
||||
Color.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE;
|
||||
Color.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Color.color_mode = MODE_COLORS_PER_LED;
|
||||
Color.colors_min = 1;
|
||||
Color.colors_max = 1;
|
||||
@@ -51,13 +51,13 @@ RGBController_Alienware::RGBController_Alienware(AlienwareController* controller
|
||||
mode Pulse;
|
||||
Pulse.name = "Flashing";
|
||||
Pulse.value = ALIENWARE_MODE_PULSE;
|
||||
Pulse.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE;
|
||||
Pulse.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Pulse.color_mode = MODE_COLORS_PER_LED;
|
||||
Pulse.colors_min = 1;
|
||||
Pulse.colors_max = 1;
|
||||
Pulse.speed_min = ALIENWARE_TEMPO_MAX;
|
||||
Pulse.speed_max = 50;
|
||||
Pulse.speed = 150;
|
||||
Pulse.speed_min = ALIENWARE_TEMPO_MIN;
|
||||
Pulse.speed_max = ALIENWARE_TEMPO_MAX;
|
||||
Pulse.speed = ALIENWARE_TEMPO_MIN;
|
||||
Pulse.brightness_min = 100;
|
||||
Pulse.brightness_max = 0;
|
||||
Pulse.brightness = 0;
|
||||
@@ -66,16 +66,14 @@ RGBController_Alienware::RGBController_Alienware(AlienwareController* controller
|
||||
mode Morph;
|
||||
Morph.name = "Morph";
|
||||
Morph.value = ALIENWARE_MODE_MORPH;
|
||||
Morph.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE;
|
||||
Morph.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Morph.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
Morph.colors_min = 2;
|
||||
Morph.colors_max = 2 * controller->GetZoneCount();
|
||||
Morph.colors.resize(2);
|
||||
Morph.colors[0] = 0x0000FF;
|
||||
Morph.colors[1] = 0xFF0000;
|
||||
Morph.speed_min = ALIENWARE_TEMPO_MAX;
|
||||
Morph.speed_max = 20;
|
||||
Morph.speed = 100;
|
||||
Morph.colors_min = 2 * controller->GetZoneCount();
|
||||
Morph.colors_max = Morph.colors_min;
|
||||
Morph.colors.resize(Morph.colors_max);
|
||||
Morph.speed_min = ALIENWARE_TEMPO_MIN;
|
||||
Morph.speed_max = ALIENWARE_TEMPO_MAX;
|
||||
Morph.speed = ALIENWARE_TEMPO_MIN;
|
||||
Morph.brightness_min = 100;
|
||||
Morph.brightness_max = 0;
|
||||
Morph.brightness = 0;
|
||||
@@ -84,11 +82,11 @@ RGBController_Alienware::RGBController_Alienware(AlienwareController* controller
|
||||
mode Spectrum;
|
||||
Spectrum.name = "Spectrum Cycle";
|
||||
Spectrum.value = ALIENWARE_MODE_SPECTRUM;
|
||||
Spectrum.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE;
|
||||
Spectrum.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Spectrum.color_mode = MODE_COLORS_NONE;
|
||||
Spectrum.speed_min = ALIENWARE_TEMPO_MAX;
|
||||
Spectrum.speed_max = ALIENWARE_TEMPO_SPECTRUM;
|
||||
Spectrum.speed = 40;
|
||||
Spectrum.speed_min = ALIENWARE_TEMPO_SPECTRUM;
|
||||
Spectrum.speed_max = ALIENWARE_TEMPO_MAX;
|
||||
Spectrum.speed = ALIENWARE_TEMPO_SPECTRUM;
|
||||
Spectrum.brightness_min = 100;
|
||||
Spectrum.brightness_max = 0;
|
||||
Spectrum.brightness = 0;
|
||||
@@ -97,12 +95,11 @@ RGBController_Alienware::RGBController_Alienware(AlienwareController* controller
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow Wave";
|
||||
Rainbow.value = ALIENWARE_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_MANUAL_SAVE;
|
||||
Rainbow.flags = MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
Rainbow.speed_min = ALIENWARE_TEMPO_MAX;
|
||||
Rainbow.speed_max = ALIENWARE_TEMPO_SPECTRUM;
|
||||
Rainbow.speed = 40;
|
||||
Rainbow.direction = MODE_DIRECTION_RIGHT;
|
||||
Rainbow.speed_min = ALIENWARE_TEMPO_SPECTRUM;
|
||||
Rainbow.speed_max = ALIENWARE_TEMPO_MAX;
|
||||
Rainbow.speed = ALIENWARE_TEMPO_SPECTRUM;
|
||||
Rainbow.brightness_min = 100;
|
||||
Rainbow.brightness_max = 0;
|
||||
Rainbow.brightness = 0;
|
||||
@@ -111,13 +108,13 @@ RGBController_Alienware::RGBController_Alienware(AlienwareController* controller
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = ALIENWARE_MODE_BREATHING;
|
||||
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED | MODE_FLAG_MANUAL_SAVE;
|
||||
Breathing.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_SPEED;
|
||||
Breathing.color_mode = MODE_COLORS_PER_LED;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.speed_min = ALIENWARE_TEMPO_MAX;
|
||||
Breathing.speed_max = 50;
|
||||
Breathing.speed = 150;
|
||||
Breathing.speed_min = ALIENWARE_TEMPO_MIN;
|
||||
Breathing.speed_max = ALIENWARE_TEMPO_MAX;
|
||||
Breathing.speed = ALIENWARE_TEMPO_MIN;
|
||||
Breathing.brightness_min = 100;
|
||||
Breathing.brightness_max = 0;
|
||||
Breathing.brightness = 0;
|
||||
@@ -227,7 +224,6 @@ void RGBController_Alienware::DeviceUpdateMode()
|
||||
uint16_t period = 0x07d0;
|
||||
|
||||
controller->SetMode(zone_idx, current_mode.value);
|
||||
controller->SetDirection(zone_idx, current_mode.direction);
|
||||
|
||||
switch(current_mode_idx)
|
||||
{
|
||||
@@ -239,7 +235,6 @@ void RGBController_Alienware::DeviceUpdateMode()
|
||||
break;
|
||||
|
||||
case ALIENWARE_MODE_PULSE:
|
||||
period = std::max<uint16_t>(500, (uint16_t)(current_mode.speed * 10));
|
||||
controller->SetPeriod(zone_idx, period);
|
||||
controller->SetColor( zone_idx, colors[current_zone.start_idx]);
|
||||
controller->SetTempo( zone_idx, current_mode.speed);
|
||||
@@ -247,22 +242,10 @@ void RGBController_Alienware::DeviceUpdateMode()
|
||||
break;
|
||||
|
||||
case ALIENWARE_MODE_MORPH:
|
||||
{
|
||||
RGBColor c1 = (current_mode.colors.size() >= 1) ? current_mode.colors[0] : 0x0000FF;
|
||||
RGBColor c2 = (current_mode.colors.size() >= 2) ? current_mode.colors[1] : 0xFF0000;
|
||||
|
||||
if(current_mode.colors.size() >= (std::size_t)((zone_idx + 1) * 2))
|
||||
{
|
||||
c1 = current_mode.colors[zone_idx * 2];
|
||||
c2 = current_mode.colors[(zone_idx * 2) + 1];
|
||||
}
|
||||
|
||||
period = std::max<uint16_t>(400, (uint16_t)(current_mode.speed * 10));
|
||||
controller->SetPeriod(zone_idx, period);
|
||||
controller->SetColor( zone_idx, c1, c2);
|
||||
controller->SetTempo( zone_idx, current_mode.speed);
|
||||
controller->SetDim( zone_idx, modes[current_mode_idx].brightness);
|
||||
}
|
||||
controller->SetPeriod(zone_idx, period);
|
||||
controller->SetColor( zone_idx, current_mode.colors[zone_idx * 2], current_mode.colors[(zone_idx * 2) + 1]);
|
||||
controller->SetTempo( zone_idx, current_mode.speed);
|
||||
controller->SetDim( zone_idx, modes[current_mode_idx].brightness);
|
||||
break;
|
||||
|
||||
case ALIENWARE_MODE_SPECTRUM:
|
||||
@@ -273,7 +256,6 @@ void RGBController_Alienware::DeviceUpdateMode()
|
||||
break;
|
||||
|
||||
case ALIENWARE_MODE_BREATHING:
|
||||
period = std::max<uint16_t>(500, (uint16_t)(current_mode.speed * 10));
|
||||
controller->SetPeriod(zone_idx, period);
|
||||
controller->SetColor( zone_idx, colors[current_zone.start_idx], 0x0);
|
||||
controller->SetTempo( zone_idx, current_mode.speed);
|
||||
@@ -300,9 +282,3 @@ void RGBController_Alienware::DeviceUpdateMode()
|
||||
current_mode = new_current_mode;
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_Alienware::DeviceSaveMode()
|
||||
{
|
||||
controller->SaveController();
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ public:
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
AlienwareController* controller;
|
||||
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| AlienwareAW410KControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Alienware AW410K Keyboard |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "AlienwareAW410KController.h"
|
||||
#include "RGBController_AlienwareAW410K.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Alienware vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ALIENWARE_VID 0x04F2
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ALIENWARE_AW410K_PID 0x1968
|
||||
|
||||
DetectedControllers DetectAlienwareAW410KControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
AlienwareAW410KController* controller = new AlienwareAW410KController(dev, info->path, name);
|
||||
RGBController_AlienwareAW410K* rgb_controller = new RGBController_AlienwareAW410K(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Alienware AW410K", DetectAlienwareAW410KControllers, ALIENWARE_VID, ALIENWARE_AW410K_PID, 0x02, 0xFF00, 0x01);
|
||||
+26
-4
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| AlienwareAW510KControllerDetect.cpp |
|
||||
| AlienwareKeyboardControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Alienware AW510K Keyboard |
|
||||
| Detector for Alienware Keyboard |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -9,18 +9,21 @@
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "AlienwareAW410KController.h"
|
||||
#include "AlienwareAW510KController.h"
|
||||
#include "RGBController_AlienwareAW410K.h"
|
||||
#include "RGBController_AlienwareAW510K.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Alienware vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ALIENWARE_VID 0x04F2
|
||||
#define ALIENWARE_VID 0x04F2
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ALIENWARE_AW510K_PID 0x1830
|
||||
#define ALIENWARE_AW510K_PID 0x1830
|
||||
#define ALIENWARE_AW410K_PID 0x1968
|
||||
|
||||
DetectedControllers DetectAlienwareAW510KControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
@@ -40,4 +43,23 @@ DetectedControllers DetectAlienwareAW510KControllers(hid_device_info* info, cons
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectAlienwareAW410KControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
AlienwareAW410KController* controller = new AlienwareAW410KController(dev, info->path, name);
|
||||
RGBController_AlienwareAW410K* rgb_controller = new RGBController_AlienwareAW410K(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_IPU("Alienware AW510K", DetectAlienwareAW510KControllers, ALIENWARE_VID, ALIENWARE_AW510K_PID, 0x02, 0xFF00, 0x01);
|
||||
REGISTER_HID_DETECTOR_IPU("Alienware AW410K", DetectAlienwareAW410KControllers, ALIENWARE_VID, ALIENWARE_AW410K_PID, 0x02, 0xFF00, 0x01);
|
||||
+5
-5
@@ -40,11 +40,11 @@ std::vector<unsigned char> AlienwareAW3423DWFController::GetReportResponse()
|
||||
|
||||
void AlienwareAW3423DWFController::PerformLogin()
|
||||
{
|
||||
unsigned char init_packet[192] = {0x00};
|
||||
init_packet[0] = 0x40;
|
||||
init_packet[1] = 0xE1;
|
||||
init_packet[2] = 0x01;
|
||||
SendControlPacket(init_packet, 192);
|
||||
unsigned char init_packet[64] =
|
||||
{
|
||||
0x40, 0xE1, 0x01
|
||||
};
|
||||
SendControlPacket(init_packet, 4);
|
||||
|
||||
std::vector<unsigned char> response = GetReportResponse();
|
||||
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| 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,8 +10,10 @@
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "AlienwareAW3423DWFController.h"
|
||||
#include "AlienwareMonitorController.h"
|
||||
#include "DetectionManager.h"
|
||||
#include "RGBController_AlienwareAW3423DWF.h"
|
||||
#include "RGBController_AlienwareMonitor.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
@@ -22,10 +24,29 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| 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;
|
||||
@@ -44,4 +65,5 @@ 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);
|
||||
@@ -21,13 +21,13 @@
|
||||
DetectedControllers DetectArcticControllers()
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
std::vector<std::string> ports;
|
||||
std::vector<std::string *> ports;
|
||||
|
||||
ports = find_usb_serial_port(CH341_VID, CH341_PID);
|
||||
|
||||
for(unsigned int device = 0; device < ports.size(); device++)
|
||||
{
|
||||
ArcticController *controller = new ArcticController(ports[device]);
|
||||
ArcticController *controller = new ArcticController(*ports[device]);
|
||||
|
||||
if(controller->IsPresent())
|
||||
{
|
||||
@@ -38,10 +38,16 @@ DetectedControllers DetectArcticControllers()
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
|
||||
delete ports[device];
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("Arctic RGB controller", DetectArcticControllers);
|
||||
REGISTER_CUSTOM_UDEV_RULE(arctic, "Arctic RGB controller", "SUBSYSTEMS==\"serial|hidraw\", ATTRS{idVendor}==\"1a86\", ATTRS{idProduct}==\"7523\", TAG+=\"uaccess\", TAG+=\"Arctic_RGB_controller\"");
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Entries for dynamic UDEV rules |
|
||||
| |
|
||||
| DUMMY_DEVICE_DETECTOR("Arctic RGB controller", DetectArcticControllers, 0x1A86, 0x7523 ) |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
+26
-2
@@ -4,15 +4,18 @@
|
||||
| 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 <hidapi.h>
|
||||
#include "AsusAuraCoreController.h"
|
||||
#include "DetectionManager.h"
|
||||
#include "AsusAuraCoreController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_AsusAuraCore.h"
|
||||
#include "RGBController_AsusAuraCoreLaptop.h"
|
||||
#include <hidapi.h>
|
||||
|
||||
#define AURA_CORE_VID 0x0B05
|
||||
|
||||
@@ -41,6 +44,27 @@ 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
@@ -1,38 +0,0 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| 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,25 +940,6 @@ 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 |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
@@ -973,7 +954,6 @@ 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 ]));
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#define AURA_ROG_GLADIUS_II_WIRELESS_1_PID 0x189E
|
||||
#define AURA_ROG_GLADIUS_II_WIRELESS_2_PID 0x18A0
|
||||
#define AURA_ROG_GLADIUS_III_PID 0x197B
|
||||
#define AURA_ROG_GLADIUS_III_CORE_PID 0x1C8D
|
||||
#define AURA_ROG_GLADIUS_III_WIRELESS_USB_PID 0x197D
|
||||
#define AURA_ROG_GLADIUS_III_WIRELESS_2_4_PID 0x197F
|
||||
#define AURA_ROG_GLADIUS_III_WIRELESS_BT_PID 0x1981
|
||||
@@ -218,20 +217,6 @@ static std::map<int,mouse_type> aura_mouse_devices =
|
||||
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_WAVE, AURA_MOUSE_MODE_REACTIVE, AURA_MOUSE_MODE_COMET, AURA_MOUSE_MODE_BATTERY }
|
||||
}
|
||||
},
|
||||
{
|
||||
AURA_ROG_GLADIUS_III_CORE_PID, // ROG Gladius III Core
|
||||
{
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
false,
|
||||
1,
|
||||
false,
|
||||
{ AURA_MOUSE_ZONE_LOGO, AURA_MOUSE_ZONE_SCROLL },
|
||||
{ AURA_MOUSE_MODE_STATIC, AURA_MOUSE_MODE_BREATHING, AURA_MOUSE_MODE_SPECTRUM, AURA_MOUSE_MODE_NONE, AURA_MOUSE_MODE_REACTIVE }
|
||||
}
|
||||
},
|
||||
{
|
||||
AURA_ROG_GLADIUS_III_WIRELESS_USB_PID, // ROG Gladius III Wireless USB
|
||||
{
|
||||
|
||||
+1
-1
@@ -428,6 +428,7 @@ 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:
|
||||
@@ -484,7 +485,6 @@ 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:
|
||||
|
||||
+1
-1
@@ -221,7 +221,7 @@ void RGBController_AuraUSB::SetupZones()
|
||||
|
||||
new_led.name.append(std::to_string(led_idx));
|
||||
|
||||
new_led.value = (unsigned int)channel_idx;
|
||||
new_led.value = channel_idx;
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
@@ -417,7 +417,7 @@ REGISTER_HID_DETECTOR ("ASUS Aura Addressable", DetectAs
|
||||
REGISTER_HID_DETECTOR ("ASUS Aura Addressable", DetectAsusAuraUSBAddressable, AURA_USB_VID, AURA_ADDRESSABLE_4_PID);
|
||||
REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_1_PID);
|
||||
REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_2_PID);
|
||||
REGISTER_HID_DETECTOR_PU("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_3_PID, 0xFF72, 0x00A1);
|
||||
REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_3_PID);
|
||||
REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_4_PID);
|
||||
REGISTER_HID_DETECTOR ("ASUS Aura Motherboard", DetectAsusAuraUSBMotherboards, AURA_USB_VID, AURA_MOTHERBOARD_5_PID);
|
||||
|
||||
@@ -464,7 +464,6 @@ REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Origin COD",
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Wireless", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_WIRELESS_1_PID, 1, 0xFF13);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius II Wireless", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_II_WIRELESS_2_PID, 2, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_PID, 0, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III Core", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_CORE_PID, 0, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III Wireless USB", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_WIRELESS_USB_PID, 0, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III Wireless 2.4Ghz", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_WIRELESS_2_4_PID, 0, 0xFF01);
|
||||
REGISTER_HID_DETECTOR_IP("ASUS ROG Gladius III Wireless Bluetooth", DetectAsusAuraUSBMice, AURA_USB_VID, AURA_ROG_GLADIUS_III_WIRELESS_BT_PID, 0, 0xFF01);
|
||||
|
||||
@@ -22,12 +22,8 @@
|
||||
| Product ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define ASUS_ROG_STRIX_XG27AQDMG_PID 0x1BA3
|
||||
#define ASUS_ROG_STRIX_XG27ACDNG_PID 0x1BC9
|
||||
#define ASUS_ROG_STRIX_XG27UCG_PID 0x1BB4
|
||||
#define ASUS_ROG_SWIFT_XG27UCG_PID 0x1BB4
|
||||
#define ASUS_ROG_SWIFT_PG32UCDM_PID 0x1B2B
|
||||
#define ASUS_ROG_SWIFT_PG32UCDMR_PID 0x1C9B
|
||||
#define ASUS_ROG_SWIFT_PG32UCDP_PID 0x1BCA
|
||||
#define ASUS_ROG_AURA_MONITOR_LIGHT_BAR_PID 0x1AC8
|
||||
|
||||
DetectedControllers DetectAsusMonitorControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
@@ -48,13 +44,5 @@ 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 XG27ACDNG", DetectAsusMonitorControllers, ASUS_VID, ASUS_ROG_STRIX_XG27ACDNG_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);
|
||||
REGISTER_HID_DETECTOR_IPU("Asus ROG SWIFT PG32UCDP", DetectAsusMonitorControllers, ASUS_VID, ASUS_ROG_SWIFT_PG32UCDP_PID, 1, 0xFF72, 0x00A1);
|
||||
/*---------------------------------------------------------*\
|
||||
| ALB01 exposes the Aura HID collection on interface 2. |
|
||||
\*---------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IPU("Asus ROG Aura Monitor Light Bar", DetectAsusMonitorControllers, ASUS_VID, ASUS_ROG_AURA_MONITOR_LIGHT_BAR_PID, 2, 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);
|
||||
|
||||
@@ -36,5 +36,3 @@ 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\"");
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
DetectedControllers DetectBlinkyTapeControllers()
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
std::vector<std::string> device_locations = find_usb_serial_port(BLINKINLABS_VID, BLINKYTAPE_PID);
|
||||
std::vector<std::string *> device_locations = find_usb_serial_port(BLINKINLABS_VID, BLINKYTAPE_PID);
|
||||
|
||||
for(unsigned int device_idx = 0; device_idx < device_locations.size(); device_idx++)
|
||||
{
|
||||
BlinkyTapeController* controller = new BlinkyTapeController();
|
||||
controller->Initialize(device_locations[device_idx]);
|
||||
controller->Initialize(*device_locations[device_idx]);
|
||||
|
||||
RGBController_BlinkyTape* rgb_controller = new RGBController_BlinkyTape(controller);
|
||||
|
||||
@@ -40,4 +40,8 @@ DetectedControllers DetectBlinkyTapeControllers()
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("BlinkyTape", DetectBlinkyTapeControllers);
|
||||
REGISTER_CUSTOM_UDEV_RULE(blinky_tape, "BlinkyTape", "SUBSYSTEMS==\"serial|hidraw\", ATTRS{idVendor}==\"1d50\", ATTRS{idProduct}==\"605e\", TAG+=\"uaccess\", TAG+=\"BlinkyTape\"");
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Entries for dynamic UDEV rules |
|
||||
| |
|
||||
| DUMMY_DEVICE_DETECTOR("BlinkyTape", DetectBlinkyTapeControllers, 0x1D50, 0x605E ) |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardController.cpp |
|
||||
| |
|
||||
| Driver for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| Driver for Clevo laptop per-key RGB keyboard (ITE 8291) |
|
||||
| Protocol based on tuxedo-drivers ite_8291 module |
|
||||
| |
|
||||
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
|
||||
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include "ClevoKeyboardController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
ClevoKeyboardController::ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info, clevo_keyboard_type kb_type)
|
||||
ClevoKeyboardController::ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info)
|
||||
{
|
||||
dev = dev_handle;
|
||||
type = kb_type;
|
||||
location = info.path;
|
||||
version = info.release_number;
|
||||
}
|
||||
@@ -29,31 +26,6 @@ ClevoKeyboardController::~ClevoKeyboardController()
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
clevo_keyboard_type ClevoKeyboardController::GetType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
int ClevoKeyboardController::GetNumRows()
|
||||
{
|
||||
return(type == CLEVO_KB_ITE829X) ? CLEVO_829X_NUM_ROWS : CLEVO_8291_NUM_ROWS;
|
||||
}
|
||||
|
||||
int ClevoKeyboardController::GetNumCols()
|
||||
{
|
||||
return(type == CLEVO_KB_ITE829X) ? CLEVO_829X_NUM_COLS : CLEVO_8291_NUM_COLS;
|
||||
}
|
||||
|
||||
int ClevoKeyboardController::GetNumLEDs()
|
||||
{
|
||||
return GetNumRows() * GetNumCols();
|
||||
}
|
||||
|
||||
unsigned char ClevoKeyboardController::GetBrightnessMax()
|
||||
{
|
||||
return(type == CLEVO_KB_ITE829X) ? CLEVO_829X_BRIGHTNESS_MAX : CLEVO_8291_BRIGHTNESS_MAX;
|
||||
}
|
||||
|
||||
std::string ClevoKeyboardController::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
@@ -79,355 +51,147 @@ std::string ClevoKeyboardController::GetFirmwareVersion()
|
||||
return(version_string);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291: 8-byte feature report, no report ID |
|
||||
\*---------------------------------------------------------*/
|
||||
void ClevoKeyboardController::WriteControl8291(unsigned char* data)
|
||||
void ClevoKeyboardController::WriteControl(unsigned char* data)
|
||||
{
|
||||
hid_send_feature_report(dev, data, CLEVO_8291_REPORT_SIZE);
|
||||
hid_send_feature_report(dev, data, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::WriteRowData(unsigned char* data)
|
||||
{
|
||||
hid_write(dev, data, CLEVO_8291_ROW_DATA_SIZE);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x: 6-byte feature report with report ID 0xCC |
|
||||
\*---------------------------------------------------------*/
|
||||
void ClevoKeyboardController::SendCommand829x(unsigned char cmd, unsigned char d0, unsigned char d1, unsigned char d2, unsigned char d3)
|
||||
{
|
||||
unsigned char buf[CLEVO_829X_REPORT_SIZE];
|
||||
|
||||
buf[0] = CLEVO_829X_REPORT_ID;
|
||||
buf[1] = cmd;
|
||||
buf[2] = d0;
|
||||
buf[3] = d1;
|
||||
buf[4] = d2;
|
||||
buf[5] = d3;
|
||||
|
||||
hid_send_feature_report(dev, buf, CLEVO_829X_REPORT_SIZE);
|
||||
hid_write(dev, data, CLEVO_KEYBOARD_ROW_DATA_SIZE);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::TurnOff()
|
||||
{
|
||||
if(type == CLEVO_KB_ITE829X)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_BRIGHTNESS);
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| Turn off: 08 01 00 00 00 00 00 00 |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char buf[CLEVO_KEYBOARD_REPORT_SIZE];
|
||||
|
||||
unsigned char buf[CLEVO_8291_REPORT_SIZE];
|
||||
memset(buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
buf[0] = CLEVO_8291_CMD_MODE;
|
||||
buf[1] = CLEVO_8291_POWER_OFF;
|
||||
WriteControl8291(buf);
|
||||
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
buf[0] = 0x08;
|
||||
buf[1] = 0x01;
|
||||
|
||||
WriteControl(buf);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SetMode(unsigned char mode, unsigned char brightness, unsigned char speed, unsigned char behaviour)
|
||||
{
|
||||
if(type == CLEVO_KB_ITE829X)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_BRIGHTNESS, brightness, speed);
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| Set params: 08 [power] [mode] [speed] [brightness] 08 |
|
||||
| [behaviour] 00 |
|
||||
| power: 01=off, 02=on |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char buf[CLEVO_KEYBOARD_REPORT_SIZE];
|
||||
|
||||
unsigned char buf[CLEVO_8291_REPORT_SIZE];
|
||||
memset(buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
buf[0] = CLEVO_8291_CMD_MODE;
|
||||
buf[1] = CLEVO_8291_POWER_ON;
|
||||
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
buf[0] = 0x08;
|
||||
buf[1] = 0x02; // Power on
|
||||
buf[2] = mode;
|
||||
buf[3] = speed;
|
||||
buf[4] = brightness;
|
||||
buf[5] = CLEVO_8291_MODE_FLAG;
|
||||
buf[5] = 0x08;
|
||||
buf[6] = behaviour;
|
||||
WriteControl8291(buf);
|
||||
|
||||
WriteControl(buf);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SetModeColor(unsigned char color_idx, RGBColor color)
|
||||
void ClevoKeyboardController::SetModeColor(unsigned char color_idx, unsigned char red, unsigned char green, unsigned char blue)
|
||||
{
|
||||
if(type == CLEVO_KB_ITE829X)
|
||||
{
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------*\
|
||||
| Set color define: 14 00 [index] R G B 00 00 |
|
||||
| index: 1-7 for built-in effects |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char buf[CLEVO_KEYBOARD_REPORT_SIZE];
|
||||
|
||||
unsigned char buf[CLEVO_8291_REPORT_SIZE];
|
||||
memset(buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
buf[0] = CLEVO_8291_CMD_COLOR;
|
||||
memset(buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
buf[0] = 0x14;
|
||||
buf[1] = 0x00;
|
||||
buf[2] = color_idx;
|
||||
buf[3] = RGBGetRValue(color);
|
||||
buf[4] = RGBGetGValue(color);
|
||||
buf[5] = RGBGetBValue(color);
|
||||
WriteControl8291(buf);
|
||||
buf[3] = red;
|
||||
buf[4] = green;
|
||||
buf[5] = blue;
|
||||
|
||||
WriteControl(buf);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SetBrightnessSpeed829x(unsigned char brightness, unsigned char speed)
|
||||
void ClevoKeyboardController::SendColors(unsigned char* color_data, unsigned char brightness)
|
||||
{
|
||||
if(brightness > CLEVO_829X_BRIGHTNESS_MAX)
|
||||
{
|
||||
brightness = CLEVO_829X_BRIGHTNESS_MAX;
|
||||
}
|
||||
|
||||
if(brightness != current_brightness_829x || speed != current_speed_829x)
|
||||
{
|
||||
current_brightness_829x = brightness;
|
||||
current_speed_829x = speed;
|
||||
SendCommand829x(CLEVO_829X_CMD_BRIGHTNESS, brightness, speed);
|
||||
}
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SendColorSlot829x(unsigned char cmd, unsigned char slot, RGBColor color)
|
||||
{
|
||||
SendCommand829x(cmd, slot, RGBGetRValue(color), RGBGetGValue(color), RGBGetBValue(color));
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x: Save/Clear BIOS keyboard state |
|
||||
\*---------------------------------------------------------*/
|
||||
void ClevoKeyboardController::SaveToBios829x()
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_SAVE_BIOS, 0x01);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::ClearBiosSave829x()
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_SAVE_BIOS, 0x00);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::StopAnimation829x()
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_ANIM, CLEVO_829X_CMD_STOP_ANIM);
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SetEffect829x(unsigned char mode_value, const std::vector<RGBColor>& colors, unsigned int direction, unsigned int color_mode)
|
||||
{
|
||||
bool mode_changed = (mode_value != current_mode_829x);
|
||||
current_mode_829x = mode_value;
|
||||
bool use_custom_color = (color_mode != MODE_COLORS_RANDOM) && !colors.empty();
|
||||
/*---------------------------------------------------------*\
|
||||
| Per-key RGB mode (mode 0x33) |
|
||||
| 1. Set params with mode 0x33 and brightness |
|
||||
| 2. For each row 0-5: |
|
||||
| - Announce row: 16 00 [row] 00 00 00 00 00 |
|
||||
| - Send 65 bytes row data via output report |
|
||||
| |
|
||||
| Row data format (65 bytes): |
|
||||
| [0x00 padding][0x00 padding] |
|
||||
| [B0..B20][G0..G20][R0..R20] |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char ctrl_buf[CLEVO_KEYBOARD_REPORT_SIZE];
|
||||
unsigned char row_buf[CLEVO_KEYBOARD_ROW_DATA_SIZE];
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Animation modes: send [CC, 00, mode_id] on mode change |
|
||||
| Clamp brightness |
|
||||
\*---------------------------------------------------------*/
|
||||
struct anim_entry { unsigned char mode; unsigned char anim_id; };
|
||||
static const anim_entry anim_modes[] =
|
||||
if(brightness > CLEVO_KEYBOARD_BRIGHTNESS_MAX)
|
||||
{
|
||||
{ CLEVO_829X_MODE_WAVE, 0x04 },
|
||||
{ CLEVO_829X_MODE_RANDOM, 0x09 },
|
||||
{ CLEVO_829X_MODE_SCAN, 0x0A },
|
||||
{ CLEVO_829X_MODE_SNAKE, 0x0B },
|
||||
{ CLEVO_829X_MODE_RAINBOW_CYCLE, 0x02 },
|
||||
{ CLEVO_829X_MODE_RAINBOW_GRAD, 0x04 },
|
||||
};
|
||||
|
||||
const anim_entry* anim_it = std::find_if(std::begin(anim_modes), std::end(anim_modes),
|
||||
[mode_value](const anim_entry& e) { return e.mode == mode_value; });
|
||||
|
||||
if(anim_it != std::end(anim_modes) && mode_changed)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_ANIM, anim_it->anim_id);
|
||||
brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Direction-based effects (Wave/Snake) |
|
||||
| Slot = base + direction_index |
|
||||
| Custom color: base = 0xA1, Preset: base = 0x71 |
|
||||
| Set params for per-key mode |
|
||||
\*---------------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| Map OpenRGB direction enum to firmware slot index |
|
||||
\*---------------------------------------------------------*/
|
||||
static const unsigned char dir_to_wave_idx[] =
|
||||
{
|
||||
6, /* MODE_DIRECTION_LEFT */
|
||||
7, /* MODE_DIRECTION_RIGHT */
|
||||
4, /* MODE_DIRECTION_UP */
|
||||
5, /* MODE_DIRECTION_DOWN */
|
||||
6, /* MODE_DIRECTION_HORIZONTAL */
|
||||
4, /* MODE_DIRECTION_VERTICAL */
|
||||
0, /* MODE_DIRECTION_UP_LEFT */
|
||||
1, /* MODE_DIRECTION_UP_RIGHT */
|
||||
2, /* MODE_DIRECTION_DOWN_LEFT */
|
||||
3, /* MODE_DIRECTION_DOWN_RIGHT */
|
||||
};
|
||||
|
||||
static const unsigned char dir_to_snake_idx[] =
|
||||
{
|
||||
0, /* MODE_DIRECTION_LEFT */
|
||||
0, /* MODE_DIRECTION_RIGHT */
|
||||
0, /* MODE_DIRECTION_UP */
|
||||
0, /* MODE_DIRECTION_DOWN */
|
||||
0, /* MODE_DIRECTION_HORIZONTAL */
|
||||
0, /* MODE_DIRECTION_VERTICAL */
|
||||
0, /* MODE_DIRECTION_UP_LEFT */
|
||||
1, /* MODE_DIRECTION_UP_RIGHT */
|
||||
2, /* MODE_DIRECTION_DOWN_LEFT */
|
||||
3, /* MODE_DIRECTION_DOWN_RIGHT */
|
||||
};
|
||||
|
||||
if((mode_value == CLEVO_829X_MODE_WAVE || mode_value == CLEVO_829X_MODE_RAINBOW_GRAD) && direction < sizeof(dir_to_wave_idx))
|
||||
{
|
||||
unsigned char base = use_custom_color ? CLEVO_829X_COLOR_SLOT_BASE : CLEVO_829X_PRESET_SLOT_BASE;
|
||||
unsigned char idx = dir_to_wave_idx[direction];
|
||||
unsigned char slot = base + idx;
|
||||
|
||||
if(use_custom_color)
|
||||
{
|
||||
SendColorSlot829x(CLEVO_829X_CMD_WAVE_COLOR, slot, colors[0]);
|
||||
}
|
||||
|
||||
if(!use_custom_color)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_WAVE_COLOR, slot);
|
||||
}
|
||||
}
|
||||
|
||||
if(mode_value == CLEVO_829X_MODE_SNAKE && direction < sizeof(dir_to_snake_idx))
|
||||
{
|
||||
unsigned char base = use_custom_color ? CLEVO_829X_COLOR_SLOT_BASE : CLEVO_829X_PRESET_SLOT_BASE;
|
||||
unsigned char idx = dir_to_snake_idx[direction];
|
||||
unsigned char slot = base + idx;
|
||||
|
||||
if(use_custom_color)
|
||||
{
|
||||
SendColorSlot829x(CLEVO_829X_CMD_SNAKE_COLOR, slot, colors[0]);
|
||||
}
|
||||
|
||||
if(!use_custom_color)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_SNAKE_COLOR, slot);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Breathing/Flashing: random or custom color |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == CLEVO_829X_MODE_BREATH && use_custom_color)
|
||||
{
|
||||
SendColorSlot829x(0x0A, CLEVO_829X_COLOR_CUSTOM, colors[0]);
|
||||
}
|
||||
|
||||
if(mode_value == CLEVO_829X_MODE_BREATH && !use_custom_color)
|
||||
{
|
||||
SendCommand829x(0x0A);
|
||||
}
|
||||
|
||||
if(mode_value == CLEVO_829X_MODE_BLINK && use_custom_color)
|
||||
{
|
||||
SendColorSlot829x(0x0B, CLEVO_829X_COLOR_CUSTOM, colors[0]);
|
||||
}
|
||||
|
||||
if(mode_value == CLEVO_829X_MODE_BLINK && !use_custom_color)
|
||||
{
|
||||
SendCommand829x(0x0B);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Random: custom color only (multicolor is the default) |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == CLEVO_829X_MODE_RANDOM && use_custom_color)
|
||||
{
|
||||
SendColorSlot829x(CLEVO_829X_CMD_RANDOM_COLOR, CLEVO_829X_COLOR_SLOT_BASE, colors[0]);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Scan: 2 custom color bands |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == CLEVO_829X_MODE_SCAN)
|
||||
{
|
||||
for(size_t i = 0; i < colors.size() && i < 2; i++)
|
||||
{
|
||||
SendColorSlot829x(CLEVO_829X_CMD_SCAN_COLOR, CLEVO_829X_COLOR_SLOT_BASE + (unsigned char)i, colors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Fn Highlight: per-key color on function keys |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == CLEVO_829X_MODE_FN_COLOR && !colors.empty())
|
||||
{
|
||||
static const unsigned char fn_keys[] =
|
||||
{
|
||||
0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x08, 0x09,
|
||||
0x0A, 0x0B, 0x0C, 0x21, 0x23, 0x31, 0x32, 0x33,
|
||||
0x53, 0x73, 0xA2
|
||||
};
|
||||
|
||||
SendCommand829x(CLEVO_829X_CMD_ANIM, CLEVO_829X_CMD_CLEAR);
|
||||
|
||||
for(unsigned char key : fn_keys)
|
||||
{
|
||||
SendCommand829x(CLEVO_829X_CMD_SET_LED, key,
|
||||
RGBGetRValue(colors[0]),
|
||||
RGBGetGValue(colors[0]),
|
||||
RGBGetBValue(colors[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClevoKeyboardController::SendColors(const unsigned char* color_data, unsigned char brightness, unsigned char speed)
|
||||
{
|
||||
int num_rows = GetNumRows();
|
||||
int num_cols = GetNumCols();
|
||||
|
||||
if(type == CLEVO_KB_ITE829X)
|
||||
{
|
||||
if(brightness > CLEVO_829X_BRIGHTNESS_MAX)
|
||||
{
|
||||
brightness = CLEVO_829X_BRIGHTNESS_MAX;
|
||||
}
|
||||
|
||||
SendCommand829x(CLEVO_829X_CMD_BRIGHTNESS, brightness, speed);
|
||||
|
||||
for(int row = 0; row < num_rows; row++)
|
||||
{
|
||||
for(int col = 0; col < num_cols; col++)
|
||||
{
|
||||
int idx = (row * num_cols + col) * 3;
|
||||
|
||||
SendCommand829x(CLEVO_829X_CMD_SET_LED,
|
||||
CLEVO_829X_LED_ID(row, col),
|
||||
color_data[idx + 0],
|
||||
color_data[idx + 1],
|
||||
color_data[idx + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291: row-based color transfer |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char ctrl_buf[CLEVO_8291_REPORT_SIZE];
|
||||
unsigned char row_buf[CLEVO_8291_ROW_DATA_SIZE];
|
||||
|
||||
if(brightness > CLEVO_8291_BRIGHTNESS_MAX)
|
||||
{
|
||||
brightness = CLEVO_8291_BRIGHTNESS_MAX;
|
||||
}
|
||||
|
||||
memset(ctrl_buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
ctrl_buf[0] = CLEVO_8291_CMD_MODE;
|
||||
ctrl_buf[1] = CLEVO_8291_POWER_ON;
|
||||
ctrl_buf[2] = CLEVO_KEYBOARD_MODE_DIRECT;
|
||||
memset(ctrl_buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
ctrl_buf[0] = 0x08;
|
||||
ctrl_buf[1] = 0x02; // Power on
|
||||
ctrl_buf[2] = CLEVO_KEYBOARD_MODE_DIRECT; // Per-key mode
|
||||
ctrl_buf[3] = 0x00; // Speed (unused)
|
||||
ctrl_buf[4] = brightness;
|
||||
WriteControl8291(ctrl_buf);
|
||||
ctrl_buf[5] = 0x00;
|
||||
ctrl_buf[6] = 0x00;
|
||||
|
||||
for(int row = 0; row < num_rows; row++)
|
||||
WriteControl(ctrl_buf);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Send each row |
|
||||
\*---------------------------------------------------------*/
|
||||
for(int row = 0; row < CLEVO_KEYBOARD_NUM_ROWS; row++)
|
||||
{
|
||||
memset(ctrl_buf, 0x00, CLEVO_8291_REPORT_SIZE);
|
||||
ctrl_buf[0] = CLEVO_8291_CMD_ROW;
|
||||
/*-----------------------------------------------------*\
|
||||
| Announce row data |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(ctrl_buf, 0x00, CLEVO_KEYBOARD_REPORT_SIZE);
|
||||
ctrl_buf[0] = 0x16;
|
||||
ctrl_buf[1] = 0x00;
|
||||
ctrl_buf[2] = row;
|
||||
WriteControl8291(ctrl_buf);
|
||||
|
||||
memset(row_buf, 0x00, CLEVO_8291_ROW_DATA_SIZE);
|
||||
WriteControl(ctrl_buf);
|
||||
|
||||
for(int col = 0; col < num_cols; col++)
|
||||
/*-----------------------------------------------------*\
|
||||
| Build row data buffer |
|
||||
| Format: [pad][pad][B0..B20][G0..G20][R0..R20] |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(row_buf, 0x00, CLEVO_KEYBOARD_ROW_DATA_SIZE);
|
||||
|
||||
for(int col = 0; col < CLEVO_KEYBOARD_NUM_COLS; col++)
|
||||
{
|
||||
int idx = (row * num_cols + col) * 3;
|
||||
int led_idx = (row * CLEVO_KEYBOARD_NUM_COLS) + col;
|
||||
int color_offset = led_idx * 3;
|
||||
|
||||
row_buf[2 + col] = color_data[idx + 2];
|
||||
row_buf[2 + num_cols + col] = color_data[idx + 1];
|
||||
row_buf[2 + num_cols * 2 + col] = color_data[idx + 0];
|
||||
unsigned char red = color_data[color_offset + 0];
|
||||
unsigned char green = color_data[color_offset + 1];
|
||||
unsigned char blue = color_data[color_offset + 2];
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Row data layout (after 2-byte padding): |
|
||||
| Bytes 2-22: Blue values for columns 0-20 |
|
||||
| Bytes 23-43: Green values for columns 0-20 |
|
||||
| Bytes 44-64: Red values for columns 0-20 |
|
||||
\*-------------------------------------------------*/
|
||||
row_buf[2 + col] = blue;
|
||||
row_buf[2 + CLEVO_KEYBOARD_NUM_COLS + col] = green;
|
||||
row_buf[2 + CLEVO_KEYBOARD_NUM_COLS*2 + col] = red;
|
||||
}
|
||||
|
||||
WriteRowData(row_buf);
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardController.h |
|
||||
| |
|
||||
| Driver for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| Driver for Clevo laptop per-key RGB keyboard (ITE 8291) |
|
||||
| |
|
||||
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
|
||||
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -14,75 +12,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "RGBController.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Device type enumeration |
|
||||
\*---------------------------------------------------------*/
|
||||
enum clevo_keyboard_type
|
||||
{
|
||||
CLEVO_KB_ITE8291,
|
||||
CLEVO_KB_ITE829X,
|
||||
};
|
||||
/*-----------------------------------------------------*\
|
||||
| ITE 8291 keyboard defines |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CLEVO_KEYBOARD_REPORT_SIZE 8
|
||||
#define CLEVO_KEYBOARD_ROW_DATA_SIZE 65
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291 keyboard defines (PID 0x600B) |
|
||||
| 8 bytes, no report ID, row-based color data |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CLEVO_8291_REPORT_SIZE 8
|
||||
#define CLEVO_8291_ROW_DATA_SIZE 65
|
||||
#define CLEVO_8291_NUM_ROWS 6
|
||||
#define CLEVO_8291_NUM_COLS 21
|
||||
#define CLEVO_8291_NUM_LEDS (CLEVO_8291_NUM_ROWS * CLEVO_8291_NUM_COLS)
|
||||
#define CLEVO_8291_BRIGHTNESS_MAX 0x32
|
||||
#define CLEVO_8291_CMD_MODE 0x08
|
||||
#define CLEVO_8291_CMD_COLOR 0x14
|
||||
#define CLEVO_8291_CMD_ROW 0x16
|
||||
#define CLEVO_8291_POWER_OFF 0x01
|
||||
#define CLEVO_8291_POWER_ON 0x02
|
||||
#define CLEVO_8291_MODE_FLAG 0x08
|
||||
#define CLEVO_KEYBOARD_NUM_ROWS 6
|
||||
#define CLEVO_KEYBOARD_NUM_COLS 21
|
||||
#define CLEVO_KEYBOARD_NUM_LEDS (CLEVO_KEYBOARD_NUM_ROWS * CLEVO_KEYBOARD_NUM_COLS)
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x keyboard defines (PID 0x8910) |
|
||||
| 6 bytes with report ID 0xCC, per-key color commands |
|
||||
| Protocol: [0xCC, cmd, d0, d1, d2, d3] |
|
||||
| LED ID: ((row & 0x07) << 5) | (col & 0x1F) |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CLEVO_829X_REPORT_ID 0xCC
|
||||
#define CLEVO_829X_REPORT_SIZE 6
|
||||
#define CLEVO_829X_NUM_ROWS 6
|
||||
#define CLEVO_829X_NUM_COLS 20
|
||||
#define CLEVO_829X_NUM_LEDS (CLEVO_829X_NUM_ROWS * CLEVO_829X_NUM_COLS)
|
||||
#define CLEVO_829X_BRIGHTNESS_MAX 0x0A
|
||||
#define CLEVO_829X_LED_ID(row, col) (unsigned char)((((row) & 0x07) << 5) | ((col) & 0x1F))
|
||||
|
||||
#define CLEVO_829X_CMD_SET_LED 0x01
|
||||
#define CLEVO_829X_CMD_BRIGHTNESS 0x09
|
||||
#define CLEVO_829X_CMD_ANIM 0x00
|
||||
#define CLEVO_829X_CMD_CLEAR 0x0C
|
||||
#define CLEVO_829X_CMD_WAVE_COLOR 0x15
|
||||
#define CLEVO_829X_CMD_SNAKE_COLOR 0x16
|
||||
#define CLEVO_829X_CMD_SCAN_COLOR 0x17
|
||||
#define CLEVO_829X_CMD_RANDOM_COLOR 0x18
|
||||
#define CLEVO_829X_COLOR_CUSTOM 0xAA
|
||||
#define CLEVO_829X_COLOR_SLOT_BASE 0xA1
|
||||
#define CLEVO_829X_PRESET_SLOT_BASE 0x71
|
||||
#define CLEVO_829X_CMD_SAVE_BIOS 0x20
|
||||
#define CLEVO_829X_CMD_STOP_ANIM 0x03
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Shared defines |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CLEVO_KEYBOARD_BRIGHTNESS_MIN 0x00
|
||||
#define CLEVO_KEYBOARD_SPEED_MIN 0x00
|
||||
#define CLEVO_KEYBOARD_SPEED_MAX 0x0A
|
||||
#define CLEVO_KEYBOARD_SPEED_DEFAULT 0x00
|
||||
#define CLEVO_KEYBOARD_BRIGHTNESS_MAX 0x32
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291 modes |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CLEVO_KEYBOARD_SPEED_MIN 0x01
|
||||
#define CLEVO_KEYBOARD_SPEED_MAX 0x0A
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| ITE 8291 modes |
|
||||
\*-----------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CLEVO_KEYBOARD_MODE_DIRECT = 0x33,
|
||||
@@ -97,36 +47,9 @@ enum
|
||||
CLEVO_KEYBOARD_MODE_SPARK = 0x11,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x firmware modes |
|
||||
| Two command styles: |
|
||||
| cmd=0x00, d0=mode_id (animation select) |
|
||||
| cmd=mode_id, d0=0x00 (standalone effects) |
|
||||
\*---------------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CLEVO_829X_MODE_DIRECT = 0xFD,
|
||||
CLEVO_829X_MODE_WAVE = 0xA0,
|
||||
CLEVO_829X_MODE_WAVE_COLOR = 0xB0,
|
||||
CLEVO_829X_MODE_BREATH = 0xA1,
|
||||
CLEVO_829X_MODE_BREATH_COLOR = 0xB1,
|
||||
CLEVO_829X_MODE_BLINK = 0xA2,
|
||||
CLEVO_829X_MODE_BLINK_COLOR = 0xB2,
|
||||
CLEVO_829X_MODE_RANDOM = 0xA3,
|
||||
CLEVO_829X_MODE_RANDOM_COLOR = 0xA9,
|
||||
CLEVO_829X_MODE_SCAN = 0xA4,
|
||||
/* Ripple (0x07) requires Insyde BIOS EC config, not supported */
|
||||
CLEVO_829X_MODE_SNAKE = 0xA6,
|
||||
CLEVO_829X_MODE_SNAKE_COLOR = 0xB6,
|
||||
CLEVO_829X_MODE_RAINBOW_CYCLE = 0xA7,
|
||||
CLEVO_829X_MODE_RAINBOW_GRAD = 0xA8,
|
||||
CLEVO_829X_MODE_FN_COLOR = 0xAF,
|
||||
CLEVO_829X_MODE_OFF = 0xFF,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Wave/reactive behaviour |
|
||||
\*---------------------------------------------------------*/
|
||||
/*-----------------------------------------------------*\
|
||||
| Wave/reactive behaviour |
|
||||
\*-----------------------------------------------------*/
|
||||
enum
|
||||
{
|
||||
CLEVO_KEYBOARD_DIRECTION_LEFT = 0x01,
|
||||
@@ -144,40 +67,23 @@ enum
|
||||
class ClevoKeyboardController
|
||||
{
|
||||
public:
|
||||
ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info, clevo_keyboard_type kb_type);
|
||||
ClevoKeyboardController(hid_device* dev_handle, const hid_device_info& info);
|
||||
~ClevoKeyboardController();
|
||||
|
||||
clevo_keyboard_type GetType();
|
||||
int GetNumRows();
|
||||
int GetNumCols();
|
||||
int GetNumLEDs();
|
||||
unsigned char GetBrightnessMax();
|
||||
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetSerialString();
|
||||
std::string GetFirmwareVersion();
|
||||
|
||||
void TurnOff();
|
||||
void SetMode(unsigned char mode, unsigned char brightness, unsigned char speed, unsigned char behaviour);
|
||||
void SetModeColor(unsigned char color_idx, RGBColor color);
|
||||
void SendColors(const unsigned char* color_data, unsigned char brightness, unsigned char speed);
|
||||
void SetEffect829x(unsigned char mode_value, const std::vector<RGBColor>& colors, unsigned int direction = 0, unsigned int color_mode = 0);
|
||||
void SetBrightnessSpeed829x(unsigned char brightness, unsigned char speed);
|
||||
void SaveToBios829x();
|
||||
void ClearBiosSave829x();
|
||||
void StopAnimation829x();
|
||||
void SetModeColor(unsigned char color_idx, unsigned char red, unsigned char green, unsigned char blue);
|
||||
void SendColors(unsigned char* color_data, unsigned char brightness);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
clevo_keyboard_type type;
|
||||
std::string location;
|
||||
unsigned short version;
|
||||
unsigned char current_mode_829x = 0xFF;
|
||||
unsigned char current_brightness_829x = 0xFF;
|
||||
unsigned char current_speed_829x = 0xFF;
|
||||
hid_device* dev;
|
||||
std::string location;
|
||||
unsigned short version;
|
||||
|
||||
void WriteControl8291(unsigned char* data);
|
||||
void WriteControl(unsigned char* data);
|
||||
void WriteRowData(unsigned char* data);
|
||||
void SendCommand829x(unsigned char cmd, unsigned char d0 = 0, unsigned char d1 = 0, unsigned char d2 = 0, unsigned char d3 = 0);
|
||||
void SendColorSlot829x(unsigned char cmd, unsigned char slot, RGBColor color);
|
||||
};
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| Detector for Clevo per-key RGB keyboard (ITE 8291) |
|
||||
| |
|
||||
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
|
||||
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -24,12 +22,11 @@
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Clevo Keyboard product IDs |
|
||||
| ITE 8291 and ITE 829x per-key RGB keyboard controllers |
|
||||
| These are ITE 8291 per-key RGB keyboard controllers |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CLEVO_KEYBOARD_PID_8291 0x600B
|
||||
#define CLEVO_KEYBOARD_PID_829X 0x8910
|
||||
#define CLEVO_KEYBOARD_PID_600B 0x600B
|
||||
|
||||
static DetectedControllers DetectClevoKeyboard(hid_device_info* info, clevo_keyboard_type kb_type)
|
||||
DetectedControllers DetectClevoKeyboardControllers(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
@@ -38,7 +35,7 @@ static DetectedControllers DetectClevoKeyboard(hid_device_info* info, clevo_keyb
|
||||
|
||||
if(dev)
|
||||
{
|
||||
ClevoKeyboardController* controller = new ClevoKeyboardController(dev, *info, kb_type);
|
||||
ClevoKeyboardController* controller = new ClevoKeyboardController(dev, *info);
|
||||
RGBController_ClevoKeyboard* rgb_controller = new RGBController_ClevoKeyboard(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
@@ -47,15 +44,4 @@ static DetectedControllers DetectClevoKeyboard(hid_device_info* info, clevo_keyb
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
DetectedControllers DetectClevoKeyboard8291(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
return(DetectClevoKeyboard(info, CLEVO_KB_ITE8291));
|
||||
}
|
||||
|
||||
DetectedControllers DetectClevoKeyboard829x(hid_device_info* info, const std::string& /*name*/)
|
||||
{
|
||||
return(DetectClevoKeyboard(info, CLEVO_KB_ITE829X));
|
||||
}
|
||||
|
||||
REGISTER_HID_DETECTOR_PU("Clevo Keyboard (ITE 8291)", DetectClevoKeyboard8291, ITE_VID, CLEVO_KEYBOARD_PID_8291, 0xFF03, 0x01);
|
||||
REGISTER_HID_DETECTOR_PU("Clevo Keyboard (ITE 829x)", DetectClevoKeyboard829x, ITE_VID, CLEVO_KEYBOARD_PID_829X, 0xFF89, 0xCC);
|
||||
REGISTER_HID_DETECTOR_PU("CLEVO Keyboard", DetectClevoKeyboardControllers, 0x048D, 0x600B, 0xFF03, 0x01);
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardDevices.cpp |
|
||||
| |
|
||||
| Device list for Clevo per-key RGB keyboards |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| Device list for Clevo per-key RGB keyboards (ITE 8291) |
|
||||
| |
|
||||
| Kyle Cascade (kyle@cascade.family) 21 Jan 2026 |
|
||||
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -18,79 +16,71 @@
|
||||
| |
|
||||
| Based on KEYBOARD_SIZE_TKL with numpad added and |
|
||||
| navigation cluster adjusted to match Clevo's layout. |
|
||||
| |
|
||||
| Hardware LED indices (value field): |
|
||||
| - Row 5 (F-keys): 105-124 |
|
||||
| - Row 4 (numbers): 84-102 |
|
||||
| - Row 3 (QWERTY): 63-81 |
|
||||
| - Row 2 (home): 42-59 |
|
||||
| - Row 1 (Z row): 22-39 |
|
||||
| - Row 0 (modifiers): 0-18 |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| LED values, in physical (row, then column) order. |
|
||||
| |
|
||||
| This must match the order KeyboardLayoutManager assigns |
|
||||
| default_values against: the structural keymap sorted by |
|
||||
| (row, col) across main+fn_row+extras combined, NOT the |
|
||||
| fn_row-then-main-then-extras order the zone tables below |
|
||||
| are declared in. Getting this wrong silently misassigns |
|
||||
| almost every key from Print Screen onward, not just a few.|
|
||||
| LED values in TKL order (fn_row + main + extras) |
|
||||
| |
|
||||
| Values follow the key order in KeyboardLayoutManager.cpp. |
|
||||
| For ANSI-only keys (not present on this ISO keyboard), |
|
||||
| use 0 as a placeholder - they won't be displayed. |
|
||||
| Numpad values are added via edit_keys. |
|
||||
\*---------------------------------------------------------*/
|
||||
static const std::vector<unsigned int> clevo_tkl_values =
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Row 0: fn_row + Print Screen/Scroll Lock/Pause |
|
||||
\*-----------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| Function row (keyboard_zone_fn_row) |
|
||||
\*---------------------------------------------------------*/
|
||||
105, // Escape
|
||||
106, 107, 108, 109, // F1-F4
|
||||
110, 111, 112, 113, // F5-F8
|
||||
114, 115, 116, 117, // F9-F12
|
||||
118, // Print Screen
|
||||
0, // Scroll Lock (removed via edit_keys)
|
||||
0, // Pause (removed via edit_keys)
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Row 1: numbers row + Insert/Home/Page Up |
|
||||
\*-----------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| Main block - Row 1 (keyboard_zone_main) |
|
||||
\*---------------------------------------------------------*/
|
||||
84, // Back tick
|
||||
85, 86, 87, 88, 89, 90, 91, 92, 93, 94, // 1-0
|
||||
95, 96, // Minus, Equals
|
||||
98, // Backspace
|
||||
119, // Insert
|
||||
121, // Home
|
||||
122, // Page Up
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Row 2: Tab/QWERTY row + Delete/End/PageDown |
|
||||
\*-----------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| Main block - Row 2 |
|
||||
\*---------------------------------------------------------*/
|
||||
63, // Tab
|
||||
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, // Q-P
|
||||
75, 76, // [ ]
|
||||
0, // ANSI backslash (not on ISO)
|
||||
120, // Delete
|
||||
124, // End
|
||||
123, // Page Down
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Row 3: Caps Lock/home row/Enter |
|
||||
\*-----------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| Main block - Row 3 |
|
||||
\*---------------------------------------------------------*/
|
||||
42, // Caps Lock
|
||||
44, 45, 46, 47, 48, 49, 50, 51, 52, // A-L
|
||||
53, 54, // ; '
|
||||
55, // ISO # (POUND)
|
||||
56, // Enter
|
||||
77, // Enter (ANSI/ISO share same LED)
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Row 4: Left Shift/ISO backslash/Z row + Up |
|
||||
\*-----------------------------------------------------*/
|
||||
21, // Left Shift
|
||||
77, // ISO backslash
|
||||
/*---------------------------------------------------------*\
|
||||
| Main block - Row 4 |
|
||||
\*---------------------------------------------------------*/
|
||||
22, // Left Shift
|
||||
23, // ISO backslash
|
||||
24, 25, 26, 27, 28, 29, 30, 31, 32, // Z-. (9 keys)
|
||||
33, // /
|
||||
35, // Right Shift
|
||||
14, // Up
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Row 5: bottom modifier row + Left/Down/Right |
|
||||
\*-----------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| Main block - Row 5 |
|
||||
\*---------------------------------------------------------*/
|
||||
0, // Left Ctrl
|
||||
3, // Left Win
|
||||
4, // Left Alt
|
||||
@@ -99,53 +89,29 @@ static const std::vector<unsigned int> clevo_tkl_values =
|
||||
0, // Right Fn (removed via edit_keys)
|
||||
0, // Menu (removed via edit_keys)
|
||||
12, // Right Ctrl
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Extras - Navigation cluster (keyboard_zone_extras) |
|
||||
\*---------------------------------------------------------*/
|
||||
118, // Print Screen
|
||||
0, // Scroll Lock (removed via edit_keys)
|
||||
0, // Pause (removed via edit_keys)
|
||||
119, // Insert
|
||||
121, // Home
|
||||
123, // Page Up
|
||||
120, // Delete
|
||||
122, // End
|
||||
124, // Page Down
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Extras - Arrow keys |
|
||||
\*---------------------------------------------------------*/
|
||||
14, // Up
|
||||
13, // Left
|
||||
18, // Down
|
||||
15, // Right
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x LED value mapping |
|
||||
| LED ID = ((row & 7) << 5) | col |
|
||||
| Row 5 (F-keys) = 0xA0+, Row 4 (numbers) = 0x80+ |
|
||||
| Row 3 (QWERTY) = 0x60+, Row 2 (home) = 0x40+ |
|
||||
| Row 1 (Z row) = 0x20+, Row 0 (mods) = 0x00+ |
|
||||
\*---------------------------------------------------------*/
|
||||
static const std::vector<unsigned int> clevo_829x_full_values =
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Values in FULL layout visual order (same as CM keyboard) |
|
||||
| LED ID = ((row & 7) << 5) | col |
|
||||
| Row counts: 16, 21, 21, 17, 18, 13 |
|
||||
\*---------------------------------------------------------*/
|
||||
/* ESC F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 PRSC SCLK PSBK */
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0, 0,
|
||||
/* BKTK 1 2 3 4 5 6 7 8 9 0 - = BSPC INS HOME PGUP NMLK NMDV NMTM NMMI */
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2D, 0x2E, 0x0E, 0x10, 0x12, 0x30, 0x31, 0x32, 0x33,
|
||||
/* TAB Q W E R T Y U I O P [ ] ANSI\ DEL END PGDN NM7 NM8 NM9 NMPL */
|
||||
0x40, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x0F, 0x11, 0x13, 0x50, 0x51, 0x52, 0x53,
|
||||
/* CPLK A S D F G H J K L ; ' # ENTR NM4 NM5 NM6 */
|
||||
0x60, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0, 0x6E, 0x70, 0x71, 0x72,
|
||||
/* LSFT ISO\ Z X C V B N M , . / RSFT ARWU NM1 NM2 NM3 NMER */
|
||||
0x80, 0, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8F, 0x90, 0x91, 0x92, 0x93,
|
||||
/* LCTL LFNC LWIN LALT SPACE RALT RMNU RCTL ARWL ARDN ARWR NM0 NMPD */
|
||||
0xA0, 0xA2, 0xA3, 0xA4, 0xA5, 0xAA, 0xAB, 0xAC, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2,
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values clevo_829x_keyboard_layout
|
||||
{
|
||||
KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
clevo_829x_full_values,
|
||||
{
|
||||
/* No regional overlays needed */
|
||||
}
|
||||
},
|
||||
{
|
||||
/* No edit keys needed - all keys defined in full layout */
|
||||
}
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values clevo_keyboard_layout
|
||||
{
|
||||
KEYBOARD_SIZE_TKL,
|
||||
@@ -156,9 +122,10 @@ keyboard_keymap_overlay_values clevo_keyboard_layout
|
||||
}
|
||||
},
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
\*---------------------------------------------------------*/
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Key, Alternate Name, OpCode, |
|
||||
\*-------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Remove keys not present on Clevo keyboard |
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| ClevoKeyboardDevices.h |
|
||||
| |
|
||||
| Device list for Clevo per-key RGB keyboards |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| Device list for Clevo per-key RGB keyboards (ITE 8291) |
|
||||
| |
|
||||
| Kyle Cascade (kyle@cascade.family) 21 Jan 2026 |
|
||||
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -16,8 +14,7 @@
|
||||
#include <string>
|
||||
#include "KeyboardLayoutManager.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Clevo keyboard layout definitions |
|
||||
\*---------------------------------------------------------*/
|
||||
/*-----------------------------------------------------*\
|
||||
| Clevo keyboard layout definitions |
|
||||
\*-----------------------------------------------------*/
|
||||
extern keyboard_keymap_overlay_values clevo_keyboard_layout;
|
||||
extern keyboard_keymap_overlay_values clevo_829x_keyboard_layout;
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_ClevoKeyboard.cpp |
|
||||
| |
|
||||
| RGBController for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| RGBController for Clevo per-key RGB keyboard (ITE 8291) |
|
||||
| |
|
||||
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
|
||||
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <vector>
|
||||
#include "RGBController_ClevoKeyboard.h"
|
||||
#include "KeyboardLayoutManager.h"
|
||||
|
||||
@@ -43,306 +40,152 @@ RGBController_ClevoKeyboard::RGBController_ClevoKeyboard(ClevoKeyboardController
|
||||
Direct.value = CLEVO_KEYBOARD_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Direct.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Direct.brightness_max = controller->GetBrightnessMax();
|
||||
Direct.brightness = controller->GetBrightnessMax();
|
||||
Direct.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Direct.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 8291 built-in effects (not available on ITE 829x) |
|
||||
\*---------------------------------------------------------*/
|
||||
if(controller->GetType() == CLEVO_KB_ITE8291)
|
||||
{
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = CLEVO_KEYBOARD_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Rainbow.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Rainbow.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Rainbow.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Rainbow.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Rainbow.brightness_max = controller->GetBrightnessMax();
|
||||
Rainbow.brightness = controller->GetBrightnessMax();
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Rainbow);
|
||||
mode Rainbow;
|
||||
Rainbow.name = "Rainbow";
|
||||
Rainbow.value = CLEVO_KEYBOARD_MODE_RAINBOW;
|
||||
Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Rainbow.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Rainbow.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Rainbow.speed = 0x05;
|
||||
Rainbow.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Rainbow.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Rainbow.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Rainbow.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(Rainbow);
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = CLEVO_KEYBOARD_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Wave.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Wave.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Wave.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Wave.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Wave.brightness_max = controller->GetBrightnessMax();
|
||||
Wave.brightness = controller->GetBrightnessMax();
|
||||
Wave.direction = MODE_DIRECTION_LEFT;
|
||||
Wave.colors_min = 1;
|
||||
Wave.colors_max = 1;
|
||||
Wave.colors.resize(1);
|
||||
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Wave);
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = CLEVO_KEYBOARD_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Wave.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Wave.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Wave.speed = 0x05;
|
||||
Wave.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Wave.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Wave.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Wave.direction = MODE_DIRECTION_LEFT;
|
||||
Wave.colors_min = 1;
|
||||
Wave.colors_max = 1;
|
||||
Wave.colors.resize(1);
|
||||
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Wave);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CLEVO_KEYBOARD_MODE_BREATH;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Breathing.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Breathing.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Breathing.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Breathing.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = controller->GetBrightnessMax();
|
||||
Breathing.brightness = controller->GetBrightnessMax();
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Breathing);
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CLEVO_KEYBOARD_MODE_BREATH;
|
||||
Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Breathing.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Breathing.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Breathing.speed = 0x05;
|
||||
Breathing.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Breathing.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1);
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Reactive;
|
||||
Reactive.name = "Reactive";
|
||||
Reactive.value = CLEVO_KEYBOARD_MODE_REACTIVE;
|
||||
Reactive.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Reactive.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Reactive.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Reactive.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Reactive.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Reactive.brightness_max = controller->GetBrightnessMax();
|
||||
Reactive.brightness = controller->GetBrightnessMax();
|
||||
Reactive.colors_min = 1;
|
||||
Reactive.colors_max = 1;
|
||||
Reactive.colors.resize(1);
|
||||
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Reactive);
|
||||
mode Reactive;
|
||||
Reactive.name = "Reactive";
|
||||
Reactive.value = CLEVO_KEYBOARD_MODE_REACTIVE;
|
||||
Reactive.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Reactive.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Reactive.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Reactive.speed = 0x05;
|
||||
Reactive.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Reactive.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Reactive.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Reactive.colors_min = 1;
|
||||
Reactive.colors_max = 1;
|
||||
Reactive.colors.resize(1);
|
||||
Reactive.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Reactive);
|
||||
|
||||
mode Ripple;
|
||||
Ripple.name = "Ripple";
|
||||
Ripple.value = CLEVO_KEYBOARD_MODE_RIPPLE;
|
||||
Ripple.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Ripple.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Ripple.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Ripple.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Ripple.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Ripple.brightness_max = controller->GetBrightnessMax();
|
||||
Ripple.brightness = controller->GetBrightnessMax();
|
||||
Ripple.colors_min = 1;
|
||||
Ripple.colors_max = 1;
|
||||
Ripple.colors.resize(1);
|
||||
Ripple.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Ripple);
|
||||
mode Ripple;
|
||||
Ripple.name = "Ripple";
|
||||
Ripple.value = CLEVO_KEYBOARD_MODE_RIPPLE;
|
||||
Ripple.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Ripple.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Ripple.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Ripple.speed = 0x05;
|
||||
Ripple.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Ripple.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Ripple.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Ripple.colors_min = 1;
|
||||
Ripple.colors_max = 1;
|
||||
Ripple.colors.resize(1);
|
||||
Ripple.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Ripple);
|
||||
|
||||
mode Marquee;
|
||||
Marquee.name = "Marquee";
|
||||
Marquee.value = CLEVO_KEYBOARD_MODE_MARQUEE;
|
||||
Marquee.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Marquee.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Marquee.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Marquee.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Marquee.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Marquee.brightness_max = controller->GetBrightnessMax();
|
||||
Marquee.brightness = controller->GetBrightnessMax();
|
||||
Marquee.colors_min = 1;
|
||||
Marquee.colors_max = 1;
|
||||
Marquee.colors.resize(1);
|
||||
Marquee.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Marquee);
|
||||
mode Marquee;
|
||||
Marquee.name = "Marquee";
|
||||
Marquee.value = CLEVO_KEYBOARD_MODE_MARQUEE;
|
||||
Marquee.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Marquee.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Marquee.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Marquee.speed = 0x05;
|
||||
Marquee.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Marquee.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Marquee.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Marquee.colors_min = 1;
|
||||
Marquee.colors_max = 1;
|
||||
Marquee.colors.resize(1);
|
||||
Marquee.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Marquee);
|
||||
|
||||
mode Raindrop;
|
||||
Raindrop.name = "Raindrop";
|
||||
Raindrop.value = CLEVO_KEYBOARD_MODE_RAINDROP;
|
||||
Raindrop.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Raindrop.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Raindrop.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Raindrop.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Raindrop.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Raindrop.brightness_max = controller->GetBrightnessMax();
|
||||
Raindrop.brightness = controller->GetBrightnessMax();
|
||||
Raindrop.colors_min = 1;
|
||||
Raindrop.colors_max = 1;
|
||||
Raindrop.colors.resize(1);
|
||||
Raindrop.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Raindrop);
|
||||
mode Raindrop;
|
||||
Raindrop.name = "Raindrop";
|
||||
Raindrop.value = CLEVO_KEYBOARD_MODE_RAINDROP;
|
||||
Raindrop.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Raindrop.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Raindrop.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Raindrop.speed = 0x05;
|
||||
Raindrop.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Raindrop.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Raindrop.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Raindrop.colors_min = 1;
|
||||
Raindrop.colors_max = 1;
|
||||
Raindrop.colors.resize(1);
|
||||
Raindrop.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Raindrop);
|
||||
|
||||
mode Aurora;
|
||||
Aurora.name = "Aurora";
|
||||
Aurora.value = CLEVO_KEYBOARD_MODE_AURORA;
|
||||
Aurora.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Aurora.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Aurora.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Aurora.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Aurora.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Aurora.brightness_max = controller->GetBrightnessMax();
|
||||
Aurora.brightness = controller->GetBrightnessMax();
|
||||
Aurora.colors_min = 1;
|
||||
Aurora.colors_max = 1;
|
||||
Aurora.colors.resize(1);
|
||||
Aurora.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Aurora);
|
||||
mode Aurora;
|
||||
Aurora.name = "Aurora";
|
||||
Aurora.value = CLEVO_KEYBOARD_MODE_AURORA;
|
||||
Aurora.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Aurora.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Aurora.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Aurora.speed = 0x05;
|
||||
Aurora.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Aurora.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Aurora.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Aurora.colors_min = 1;
|
||||
Aurora.colors_max = 1;
|
||||
Aurora.colors.resize(1);
|
||||
Aurora.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Aurora);
|
||||
|
||||
mode Spark;
|
||||
Spark.name = "Spark";
|
||||
Spark.value = CLEVO_KEYBOARD_MODE_SPARK;
|
||||
Spark.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Spark.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Spark.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Spark.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Spark.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Spark.brightness_max = controller->GetBrightnessMax();
|
||||
Spark.brightness = controller->GetBrightnessMax();
|
||||
Spark.colors_min = 1;
|
||||
Spark.colors_max = 1;
|
||||
Spark.colors.resize(1);
|
||||
Spark.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Spark);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| ITE 829x firmware effects |
|
||||
\*---------------------------------------------------------*/
|
||||
if(controller->GetType() == CLEVO_KB_ITE829X)
|
||||
{
|
||||
unsigned char bmax = controller->GetBrightnessMax();
|
||||
|
||||
mode Wave;
|
||||
Wave.name = "Wave";
|
||||
Wave.value = CLEVO_829X_MODE_WAVE;
|
||||
Wave.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_DIRECTION_DIAG;
|
||||
Wave.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Wave.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Wave.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Wave.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Wave.brightness_max = bmax;
|
||||
Wave.brightness = bmax;
|
||||
Wave.direction = MODE_DIRECTION_LEFT;
|
||||
Wave.colors_min = 1;
|
||||
Wave.colors_max = 1;
|
||||
Wave.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Wave.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Wave);
|
||||
|
||||
mode Breathing;
|
||||
Breathing.name = "Breathing";
|
||||
Breathing.value = CLEVO_829X_MODE_BREATH;
|
||||
Breathing.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Breathing.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Breathing.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Breathing.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Breathing.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Breathing.brightness_max = bmax;
|
||||
Breathing.brightness = bmax;
|
||||
Breathing.colors_min = 1;
|
||||
Breathing.colors_max = 1;
|
||||
Breathing.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Flashing;
|
||||
Flashing.name = "Flashing";
|
||||
Flashing.value = CLEVO_829X_MODE_BLINK;
|
||||
Flashing.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Flashing.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Flashing.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Flashing.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Flashing.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Flashing.brightness_max = bmax;
|
||||
Flashing.brightness = bmax;
|
||||
Flashing.colors_min = 1;
|
||||
Flashing.colors_max = 1;
|
||||
Flashing.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Flashing.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Flashing);
|
||||
|
||||
mode Random;
|
||||
Random.name = "Random";
|
||||
Random.value = CLEVO_829X_MODE_RANDOM;
|
||||
Random.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR;
|
||||
Random.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Random.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Random.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Random.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Random.brightness_max = bmax;
|
||||
Random.brightness = bmax;
|
||||
Random.colors_min = 1;
|
||||
Random.colors_max = 1;
|
||||
Random.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Random.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Random);
|
||||
|
||||
mode Scan;
|
||||
Scan.name = "Scan";
|
||||
Scan.value = CLEVO_829X_MODE_SCAN;
|
||||
Scan.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Scan.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Scan.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Scan.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Scan.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Scan.brightness_max = bmax;
|
||||
Scan.brightness = bmax;
|
||||
Scan.colors_min = 2;
|
||||
Scan.colors_max = 2;
|
||||
Scan.colors.resize(2);
|
||||
Scan.colors[0] = ToRGBColor(255, 0, 0);
|
||||
Scan.colors[1] = ToRGBColor(0, 0, 255);
|
||||
Scan.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Scan);
|
||||
|
||||
mode Snake;
|
||||
Snake.name = "Snake";
|
||||
Snake.value = CLEVO_829X_MODE_SNAKE;
|
||||
Snake.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_DIRECTION_DIAG;
|
||||
Snake.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Snake.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Snake.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
Snake.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Snake.brightness_max = bmax;
|
||||
Snake.brightness = bmax;
|
||||
Snake.direction = MODE_DIRECTION_UP_LEFT;
|
||||
Snake.colors_min = 1;
|
||||
Snake.colors_max = 1;
|
||||
Snake.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
Snake.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Snake);
|
||||
|
||||
mode RainbowCycle;
|
||||
RainbowCycle.name = "Spectrum Cycle";
|
||||
RainbowCycle.value = CLEVO_829X_MODE_RAINBOW_CYCLE;
|
||||
RainbowCycle.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
RainbowCycle.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
RainbowCycle.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
RainbowCycle.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
RainbowCycle.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
RainbowCycle.brightness_max = bmax;
|
||||
RainbowCycle.brightness = bmax;
|
||||
RainbowCycle.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(RainbowCycle);
|
||||
|
||||
mode RainbowGrad;
|
||||
RainbowGrad.name = "Rainbow Wave";
|
||||
RainbowGrad.value = CLEVO_829X_MODE_RAINBOW_GRAD;
|
||||
RainbowGrad.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_DIRECTION_DIAG;
|
||||
RainbowGrad.speed_min = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
RainbowGrad.speed_max = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
RainbowGrad.speed = CLEVO_KEYBOARD_SPEED_DEFAULT;
|
||||
RainbowGrad.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
RainbowGrad.brightness_max = bmax;
|
||||
RainbowGrad.brightness = bmax;
|
||||
RainbowGrad.direction = MODE_DIRECTION_LEFT;
|
||||
RainbowGrad.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(RainbowGrad);
|
||||
|
||||
mode FnColor;
|
||||
FnColor.name = "Fn Highlight";
|
||||
FnColor.value = CLEVO_829X_MODE_FN_COLOR;
|
||||
FnColor.flags = MODE_FLAG_MANUAL_SAVE | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
FnColor.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
FnColor.brightness_max = bmax;
|
||||
FnColor.brightness = bmax;
|
||||
FnColor.colors_min = 1;
|
||||
FnColor.colors_max = 1;
|
||||
FnColor.colors.resize(1, ToRGBColor(255, 0, 0));
|
||||
FnColor.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(FnColor);
|
||||
}
|
||||
mode Spark;
|
||||
Spark.name = "Spark";
|
||||
Spark.value = CLEVO_KEYBOARD_MODE_SPARK;
|
||||
Spark.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR;
|
||||
Spark.speed_min = CLEVO_KEYBOARD_SPEED_MAX;
|
||||
Spark.speed_max = CLEVO_KEYBOARD_SPEED_MIN;
|
||||
Spark.speed = 0x05;
|
||||
Spark.brightness_min = CLEVO_KEYBOARD_BRIGHTNESS_MIN;
|
||||
Spark.brightness_max = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Spark.brightness = CLEVO_KEYBOARD_BRIGHTNESS_MAX;
|
||||
Spark.colors_min = 1;
|
||||
Spark.colors_max = 1;
|
||||
Spark.colors.resize(1);
|
||||
Spark.color_mode = MODE_COLORS_MODE_SPECIFIC;
|
||||
modes.push_back(Spark);
|
||||
|
||||
mode Off;
|
||||
Off.name = "Off";
|
||||
@@ -364,22 +207,16 @@ RGBController_ClevoKeyboard::~RGBController_ClevoKeyboard()
|
||||
void RGBController_ClevoKeyboard::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Select layout based on device type |
|
||||
| Create keyboard layout using KeyboardLayoutManager |
|
||||
\*---------------------------------------------------------*/
|
||||
bool is_829x = (controller->GetType() == CLEVO_KB_ITE829X);
|
||||
|
||||
keyboard_keymap_overlay_values& layout = is_829x
|
||||
? clevo_829x_keyboard_layout
|
||||
: clevo_keyboard_layout;
|
||||
|
||||
KeyboardLayoutManager new_kb(KEYBOARD_LAYOUT_ISO_QWERTY,
|
||||
layout.base_size,
|
||||
layout.key_values);
|
||||
clevo_keyboard_layout.base_size,
|
||||
clevo_keyboard_layout.key_values);
|
||||
|
||||
new_kb.ChangeKeys(layout);
|
||||
new_kb.ChangeKeys(clevo_keyboard_layout);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create keyboard zone from KLM |
|
||||
| Create a matrix zone for the keyboard |
|
||||
\*---------------------------------------------------------*/
|
||||
zone keyboard_zone;
|
||||
|
||||
@@ -396,6 +233,9 @@ void RGBController_ClevoKeyboard::SetupZones()
|
||||
|
||||
zones.push_back(keyboard_zone);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create LEDs from the KeyboardLayoutManager data |
|
||||
\*---------------------------------------------------------*/
|
||||
for(unsigned int led_idx = 0; led_idx < keyboard_zone.leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
@@ -409,48 +249,36 @@ void RGBController_ClevoKeyboard::SetupZones()
|
||||
SetupColors();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Build buffer map from LED values to color pointers |
|
||||
| 829x LED IDs have gaps (stride 32), need larger map |
|
||||
| Create buffer map to translate OpenRGB LED order to |
|
||||
| hardware LED order. The hardware expects 126 color values |
|
||||
| indexed by LED position (0-125). |
|
||||
\*---------------------------------------------------------*/
|
||||
null_color = 0x00000000;
|
||||
|
||||
size_t map_size = is_829x
|
||||
? CLEVO_829X_LED_ID(CLEVO_829X_NUM_ROWS - 1, CLEVO_829X_NUM_COLS - 1) + 1
|
||||
: (size_t)controller->GetNumLEDs();
|
||||
|
||||
buffer_map.resize(map_size, &null_color);
|
||||
buffer_map.resize(CLEVO_KEYBOARD_NUM_LEDS, &null_color);
|
||||
|
||||
for(size_t led_idx = 0; led_idx < leds.size(); led_idx++)
|
||||
{
|
||||
if(leds[led_idx].value < buffer_map.size())
|
||||
{
|
||||
buffer_map[leds[led_idx].value] = &colors[led_idx];
|
||||
}
|
||||
buffer_map[leds[led_idx].value] = &colors[led_idx];
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_ClevoKeyboard::DeviceUpdateLEDs()
|
||||
{
|
||||
int num_rows = controller->GetNumRows();
|
||||
int num_cols = controller->GetNumCols();
|
||||
bool is_829x = (controller->GetType() == CLEVO_KB_ITE829X);
|
||||
/*---------------------------------------------------------*\
|
||||
| Build color data array using buffer map and send to device|
|
||||
| The buffer_map translates from hardware LED index to the |
|
||||
| corresponding color pointer for that LED. |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char color_data[CLEVO_KEYBOARD_NUM_LEDS * 3];
|
||||
|
||||
std::vector<unsigned char> color_data(num_rows * num_cols * 3);
|
||||
|
||||
for(int row = 0; row < num_rows; row++)
|
||||
for(int i = 0; i < CLEVO_KEYBOARD_NUM_LEDS; i++)
|
||||
{
|
||||
for(int col = 0; col < num_cols; col++)
|
||||
{
|
||||
int seq = row * num_cols + col;
|
||||
int led_id = is_829x ? CLEVO_829X_LED_ID(row, col) : seq;
|
||||
|
||||
color_data[seq * 3 + 0] = RGBGetRValue(*buffer_map[led_id]);
|
||||
color_data[seq * 3 + 1] = RGBGetGValue(*buffer_map[led_id]);
|
||||
color_data[seq * 3 + 2] = RGBGetBValue(*buffer_map[led_id]);
|
||||
}
|
||||
color_data[i * 3 + 0] = RGBGetRValue(*buffer_map[i]);
|
||||
color_data[i * 3 + 1] = RGBGetGValue(*buffer_map[i]);
|
||||
color_data[i * 3 + 2] = RGBGetBValue(*buffer_map[i]);
|
||||
}
|
||||
|
||||
controller->SendColors(color_data.data(), modes[active_mode].brightness, modes[active_mode].speed);
|
||||
controller->SendColors(color_data, modes[active_mode].brightness);
|
||||
}
|
||||
|
||||
void RGBController_ClevoKeyboard::DeviceUpdateZoneLEDs(int /*zone*/)
|
||||
@@ -476,16 +304,6 @@ void RGBController_ClevoKeyboard::DeviceUpdateMode()
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Handle ITE 829x firmware effects |
|
||||
\*---------------------------------------------------------*/
|
||||
if(controller->GetType() == CLEVO_KB_ITE829X && mode_value != CLEVO_KEYBOARD_MODE_DIRECT)
|
||||
{
|
||||
controller->SetEffect829x(mode_value, modes[active_mode].colors, modes[active_mode].direction, modes[active_mode].color_mode);
|
||||
controller->SetBrightnessSpeed829x(modes[active_mode].brightness, modes[active_mode].speed);
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Handle Direct (per-key) mode |
|
||||
\*---------------------------------------------------------*/
|
||||
@@ -500,26 +318,41 @@ void RGBController_ClevoKeyboard::DeviceUpdateMode()
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned char brightness = modes[active_mode].brightness;
|
||||
unsigned char speed = modes[active_mode].speed;
|
||||
unsigned char behaviour = (mode_value == CLEVO_KEYBOARD_MODE_WAVE)
|
||||
? modes[active_mode].direction + 1
|
||||
: 0x00;
|
||||
unsigned char behaviour = 0x00;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set direction for wave mode |
|
||||
\*---------------------------------------------------------*/
|
||||
if(mode_value == CLEVO_KEYBOARD_MODE_WAVE)
|
||||
{
|
||||
switch(modes[active_mode].direction)
|
||||
{
|
||||
case MODE_DIRECTION_LEFT:
|
||||
behaviour = CLEVO_KEYBOARD_DIRECTION_LEFT;
|
||||
break;
|
||||
case MODE_DIRECTION_RIGHT:
|
||||
behaviour = CLEVO_KEYBOARD_DIRECTION_RIGHT;
|
||||
break;
|
||||
case MODE_DIRECTION_UP:
|
||||
behaviour = CLEVO_KEYBOARD_DIRECTION_UP;
|
||||
break;
|
||||
case MODE_DIRECTION_DOWN:
|
||||
behaviour = CLEVO_KEYBOARD_DIRECTION_DOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set mode color if applicable |
|
||||
\*---------------------------------------------------------*/
|
||||
if(modes[active_mode].colors.size() > 0)
|
||||
{
|
||||
controller->SetModeColor(1, modes[active_mode].colors[0]);
|
||||
unsigned char red = RGBGetRValue(modes[active_mode].colors[0]);
|
||||
unsigned char green = RGBGetGValue(modes[active_mode].colors[0]);
|
||||
unsigned char blue = RGBGetBValue(modes[active_mode].colors[0]);
|
||||
|
||||
controller->SetModeColor(1, red, green, blue);
|
||||
}
|
||||
|
||||
controller->SetMode(mode_value, brightness, speed, behaviour);
|
||||
}
|
||||
|
||||
void RGBController_ClevoKeyboard::DeviceSaveMode()
|
||||
{
|
||||
if(controller->GetType() == CLEVO_KB_ITE829X)
|
||||
{
|
||||
DeviceUpdateMode();
|
||||
controller->SaveToBios829x();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_ClevoKeyboard.h |
|
||||
| |
|
||||
| RGBController for Clevo per-key RGB keyboard |
|
||||
| Supports ITE 8291 (PID 0x600B) and ITE 829x (0x8910) |
|
||||
| RGBController for Clevo per-key RGB keyboard (ITE 8291) |
|
||||
| |
|
||||
| Kyle Cascade (kyle@cascade.family) 16 Jan 2026 |
|
||||
| Valentin Lobstein (balgogan@protonmail.com) 27 Mar 2026 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
@@ -20,7 +18,7 @@
|
||||
class RGBController_ClevoKeyboard : public RGBController
|
||||
{
|
||||
public:
|
||||
explicit RGBController_ClevoKeyboard(ClevoKeyboardController* controller_ptr);
|
||||
RGBController_ClevoKeyboard(ClevoKeyboardController* controller_ptr);
|
||||
~RGBController_ClevoKeyboard();
|
||||
|
||||
void SetupZones();
|
||||
@@ -30,7 +28,6 @@ public:
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
void DeviceSaveMode();
|
||||
|
||||
private:
|
||||
ClevoKeyboardController* controller;
|
||||
|
||||
@@ -45,8 +45,7 @@ void ColorfulGPUController::SetDirect(RGBColor color)
|
||||
uint8_t g = RGBGetGValue(color);
|
||||
uint8_t b = RGBGetBValue(color);
|
||||
|
||||
if(this->bus->info.pci_subsystem_device == COLORFUL_IGAME_RTX_4070_VULCAN_OCV
|
||||
|| this->bus->info.pci_subsystem_device == COLORFUL_IGAME_RTX_4090_NEPTUNE_OCV)
|
||||
if(this->bus->info.pci_subsystem_device == COLORFUL_IGAME_RTX_4070_VULCAN_OCV)
|
||||
{
|
||||
uint8_t data_pkt[COLORFUL_PACKET_LENGTH_V2] = { 0xAA, 0xEF, 0x01, 0x04, 0x88, 0x26 };
|
||||
for(int i=6; i < COLORFUL_PACKET_LENGTH_V2 -2; i = i + 3)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*---------------------------------------------------------*\
|
||||
/*---------------------------------------------------------*\
|
||||
| ColorfulGPUControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Colorful GPU |
|
||||
@@ -51,9 +51,8 @@ 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, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Ultra W OC LHR-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060_ULTRAW_OC_12G_2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3070_ADVANCED_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 3060 Ti Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_3060TI_ADVANCED_OC, 0x61);
|
||||
@@ -72,17 +71,11 @@ REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 Ti SUPER Advanced OC-V", Detec
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 Ti SUPER Ultra W", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070TIS_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070TI_SUPER_ULTRA_W, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 SUPER Ultra W OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070_SUPER_ULTRA_W_OC, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 Vulcan OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070_VULCAN_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070_ULTRAW_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4070 SUPER Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4070S_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4070S_ULTRAW_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4080 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4080_ULTRAW_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4080 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4080_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4080_ULTRAW_OCV2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4090 Neptune OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4090_NEPTUNE_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4090 Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4090_ADVANCED_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 4090 Advanced OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX4090_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_4090_ADVANCED_OCV2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5060 Ultra W OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5060_ULTRAW_OC, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5060 Ultra W OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5060_ULTRAW_OC_2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5060 Ti Ultra W DUO OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060TI_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5060TI_ULTRAW_DUO_OC, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5060 Ti Ultra W DUO OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060TI_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5060TI_ULTRAW_DUO_OC_2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5060 Ti Ultra W DUO OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5060TI_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5060TI_ULTRAW_DUO_OC, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5070 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5070_ULTRAW_OCV, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5070 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5070_ULTRAW_OCV2, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5070 Ti Ultra W OC", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070TI_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5070TI_ULTRAW_OC, 0x61);
|
||||
REGISTER_I2C_PCI_DETECTOR("iGame GeForce RTX 5070 Ultra W OC-V", DetectColorfulGPUControllers, NVIDIA_VEN, NVIDIA_RTX5070_DEV, COLORFUL_SUB_VEN, COLORFUL_IGAME_RTX_5070_ULTRAW_OCV2, 0x61);
|
||||
@@ -13,6 +13,11 @@
|
||||
#include "CMSmallARGBController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
cm_small_argb_headers cm_small_argb_header_data[1] =
|
||||
{
|
||||
{ "CM Small ARGB", 0x01, true, 12 }
|
||||
};
|
||||
|
||||
CMSmallARGBController::CMSmallARGBController(hid_device* dev_handle, char *_path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
@@ -87,24 +92,6 @@ std::string CMSmallARGBController::GetSerial()
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
std::string CMSmallARGBController::GetVersion()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| This device uses the serial value to determine the |
|
||||
| version. It does not report a proper unique serial. |
|
||||
\*-----------------------------------------------------*/
|
||||
std::string serial_string = GetSerial();
|
||||
|
||||
if(serial_string == CM_SMALL_ARGB_FW0012)
|
||||
{
|
||||
return("0012");
|
||||
}
|
||||
else
|
||||
{
|
||||
return("Unsupported");
|
||||
}
|
||||
}
|
||||
|
||||
std::string CMSmallARGBController::GetLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
@@ -135,11 +122,6 @@ unsigned char CMSmallARGBController::GetLedSpeed()
|
||||
return(current_speed);
|
||||
}
|
||||
|
||||
unsigned char CMSmallARGBController::GetBrightness()
|
||||
{
|
||||
return(current_brightness);
|
||||
}
|
||||
|
||||
bool CMSmallARGBController::GetRandomColours()
|
||||
{
|
||||
return(bool_random);
|
||||
@@ -235,9 +217,9 @@ void CMSmallARGBController::SendUpdate()
|
||||
|
||||
hid_write(dev, buffer, buffer_size);
|
||||
|
||||
buffer[CM_SMALL_ARGB_COMMAND_BYTE] = 0x0B;
|
||||
buffer[CM_SMALL_ARGB_FUNCTION_BYTE] = 0x02;
|
||||
buffer[CM_SMALL_ARGB_ZONE_BYTE] = 0x01;
|
||||
buffer[CM_SMALL_ARGB_COMMAND_BYTE] = 0x0b;
|
||||
buffer[CM_SMALL_ARGB_FUNCTION_BYTE] = (false) ? 0x01 : 0x02; //This controls custom mode TODO
|
||||
buffer[CM_SMALL_ARGB_ZONE_BYTE] = cm_small_argb_header_data[0].header;
|
||||
buffer[CM_SMALL_ARGB_MODE_BYTE] = current_mode;
|
||||
buffer[CM_SMALL_ARGB_SPEED_BYTE] = current_speed;
|
||||
buffer[CM_SMALL_ARGB_COLOUR_INDEX_BYTE] = (bool_random) ? 0x00 : 0x10; //This looks to still be the colour index and controls random colours
|
||||
|
||||
@@ -39,6 +39,16 @@ enum
|
||||
CM_SMALL_ARGB_BLUE_BYTE = 11,
|
||||
};
|
||||
|
||||
struct cm_small_argb_headers
|
||||
{
|
||||
const char* name;
|
||||
unsigned char header;
|
||||
bool digital;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
extern cm_small_argb_headers cm_small_argb_header_data[1];
|
||||
|
||||
enum
|
||||
{
|
||||
CM_SMALL_ARGB_MODE_SPECTRUM = 0x01, //Spectrum Mode
|
||||
@@ -61,8 +71,6 @@ enum
|
||||
CM_SMALL_ARGB_SPEED_FASTEST = 0x04, // Fastest speed
|
||||
};
|
||||
|
||||
#define CM_SMALL_ARGB_FW0012 std::string("A202104052336")
|
||||
|
||||
class CMSmallARGBController
|
||||
{
|
||||
public:
|
||||
@@ -72,14 +80,12 @@ public:
|
||||
std::string GetDeviceName();
|
||||
std::string GetSerial();
|
||||
std::string GetLocation();
|
||||
std::string GetVersion();
|
||||
|
||||
unsigned char GetMode();
|
||||
unsigned char GetLedRed();
|
||||
unsigned char GetLedGreen();
|
||||
unsigned char GetLedBlue();
|
||||
unsigned char GetLedSpeed();
|
||||
unsigned char GetBrightness();
|
||||
bool GetRandomColours();
|
||||
|
||||
void SetLedCount(int zone, int led_count);
|
||||
|
||||
+51
-121
@@ -27,68 +27,22 @@
|
||||
RGBController_CMSmallARGBController::RGBController_CMSmallARGBController(CMSmallARGBController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
unsigned char speed = controller->GetLedSpeed();
|
||||
|
||||
name = controller->GetDeviceName();
|
||||
name = cm_small_argb_header_data[0].name;
|
||||
vendor = "Cooler Master";
|
||||
type = DEVICE_TYPE_LEDSTRIP;
|
||||
description = "Cooler Master Small ARGB Controller Device";
|
||||
version = controller->GetVersion();
|
||||
description = controller->GetDeviceName();
|
||||
version = "2.0 for FW0012";
|
||||
serial = controller->GetSerial();
|
||||
location = controller->GetLocation();
|
||||
|
||||
SetupModes();
|
||||
SetupZones();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Initialize the active mode to the device's current |
|
||||
| mode |
|
||||
\*-----------------------------------------------------*/
|
||||
int device_mode = controller->GetMode();
|
||||
|
||||
for(std::size_t mode_idx = 0; mode_idx < modes.size(); mode_idx++)
|
||||
{
|
||||
if(modes[mode_idx].value == device_mode)
|
||||
{
|
||||
active_mode = (int)mode_idx;
|
||||
|
||||
if((modes[mode_idx].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR) && (modes[mode_idx].colors.size() > 0))
|
||||
{
|
||||
modes[mode_idx].colors[0] = ToRGBColor(controller->GetLedRed(), controller->GetLedGreen(), controller->GetLedBlue());
|
||||
}
|
||||
|
||||
if(modes[mode_idx].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
modes[mode_idx].speed = controller->GetLedSpeed();
|
||||
}
|
||||
|
||||
if(modes[mode_idx].flags & MODE_FLAG_HAS_BRIGHTNESS)
|
||||
{
|
||||
modes[mode_idx].brightness = controller->GetBrightness();
|
||||
}
|
||||
|
||||
if(modes[mode_idx].flags & MODE_FLAG_HAS_RANDOM_COLOR)
|
||||
{
|
||||
modes[mode_idx].color_mode = controller->GetRandomColours() ? MODE_COLORS_RANDOM : MODE_COLORS_MODE_SPECIFIC;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMSmallARGBController::SetupModes()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| The Small ARGB only supports Direct mode from FW0012 |
|
||||
| onwards, older firmware does not accept direct mode |
|
||||
| packets |
|
||||
\*-----------------------------------------------------*/
|
||||
//if(serial >= CM_SMALL_ARGB_FW0012)
|
||||
if(serial >= CM_SMALL_ARGB_FW0012)
|
||||
{
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = CM_SMALL_ARGB_MODE_DIRECT;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_REQUIRES_ENTIRE_DEVICE;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS;
|
||||
Direct.brightness_min = 0;
|
||||
Direct.brightness_max = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
Direct.brightness = CM_SMALL_ARGB_BRIGHTNESS_MAX;
|
||||
@@ -115,7 +69,7 @@ void RGBController_CMSmallARGBController::SetupModes()
|
||||
Reload.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
|
||||
Reload.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
|
||||
Reload.color_mode = MODE_COLORS_RANDOM;
|
||||
Reload.speed = CM_SMALL_ARGB_SPEED_NORMAL;
|
||||
Reload.speed = speed;
|
||||
modes.push_back(Reload);
|
||||
|
||||
mode Recoil;
|
||||
@@ -131,7 +85,7 @@ void RGBController_CMSmallARGBController::SetupModes()
|
||||
Recoil.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
|
||||
Recoil.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
|
||||
Recoil.color_mode = MODE_COLORS_RANDOM;
|
||||
Recoil.speed = CM_SMALL_ARGB_SPEED_NORMAL;
|
||||
Recoil.speed = speed;
|
||||
modes.push_back(Recoil);
|
||||
|
||||
mode Breathing;
|
||||
@@ -147,7 +101,7 @@ void RGBController_CMSmallARGBController::SetupModes()
|
||||
Breathing.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
|
||||
Breathing.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
|
||||
Breathing.color_mode = MODE_COLORS_RANDOM;
|
||||
Breathing.speed = CM_SMALL_ARGB_SPEED_NORMAL;
|
||||
Breathing.speed = speed;
|
||||
modes.push_back(Breathing);
|
||||
|
||||
mode Refill;
|
||||
@@ -163,7 +117,7 @@ void RGBController_CMSmallARGBController::SetupModes()
|
||||
Refill.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
|
||||
Refill.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
|
||||
Refill.color_mode = MODE_COLORS_RANDOM;
|
||||
Refill.speed = CM_SMALL_ARGB_SPEED_NORMAL;
|
||||
Refill.speed = speed;
|
||||
modes.push_back(Refill);
|
||||
|
||||
mode Demo;
|
||||
@@ -176,7 +130,7 @@ void RGBController_CMSmallARGBController::SetupModes()
|
||||
Demo.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
|
||||
Demo.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
|
||||
Demo.color_mode = MODE_COLORS_NONE;
|
||||
Demo.speed = CM_SMALL_ARGB_SPEED_NORMAL;
|
||||
Demo.speed = speed;
|
||||
modes.push_back(Demo);
|
||||
|
||||
mode Spectrum;
|
||||
@@ -189,19 +143,39 @@ void RGBController_CMSmallARGBController::SetupModes()
|
||||
Spectrum.speed_min = CM_SMALL_ARGB_SPEED_SLOWEST;
|
||||
Spectrum.speed_max = CM_SMALL_ARGB_SPEED_FASTEST;
|
||||
Spectrum.color_mode = MODE_COLORS_NONE;
|
||||
Spectrum.speed = CM_SMALL_ARGB_SPEED_NORMAL;
|
||||
Spectrum.speed = speed;
|
||||
modes.push_back(Spectrum);
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Define Passthrough mode as requiring the entire |
|
||||
| device, it hands control over to the motherboard |
|
||||
\*-----------------------------------------------------*/
|
||||
mode PassThru;
|
||||
PassThru.name = "Pass Thru";
|
||||
PassThru.value = CM_SMALL_ARGB_MODE_PASSTHRU;
|
||||
PassThru.flags = MODE_FLAG_REQUIRES_ENTIRE_DEVICE;
|
||||
PassThru.color_mode = MODE_COLORS_NONE;
|
||||
modes.push_back(PassThru);
|
||||
|
||||
SetupZones();
|
||||
|
||||
int temp_mode = controller->GetMode();
|
||||
|
||||
for(int mode_idx = 0; mode_idx < (int)modes.size() ; mode_idx++)
|
||||
{
|
||||
if(temp_mode == modes[mode_idx].value)
|
||||
{
|
||||
active_mode = mode_idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (modes[active_mode].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR)
|
||||
{
|
||||
modes[active_mode].colors[0] = ToRGBColor(controller->GetLedRed(), controller->GetLedGreen(), controller->GetLedBlue());
|
||||
}
|
||||
|
||||
modes[active_mode].color_mode = (controller->GetRandomColours()) ? MODE_COLORS_RANDOM : MODE_COLORS_MODE_SPECIFIC;
|
||||
|
||||
if (modes[active_mode].flags & MODE_FLAG_HAS_SPEED)
|
||||
{
|
||||
modes[active_mode].speed = controller->GetLedSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
RGBController_CMSmallARGBController::~RGBController_CMSmallARGBController()
|
||||
@@ -274,9 +248,7 @@ void RGBController_CMSmallARGBController::SetupZones()
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = zones[zone_idx].name;
|
||||
new_led.name.append(", LED ");
|
||||
new_led.name.append(std::to_string(lp_idx + 1));
|
||||
new_led.value = (unsigned int)zone_idx;
|
||||
new_led.name.append(", LED " + std::to_string(lp_idx));
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
@@ -289,7 +261,7 @@ void RGBController_CMSmallARGBController::DeviceConfigureZone(int zone_idx)
|
||||
{
|
||||
if((size_t)zone_idx < zones.size())
|
||||
{
|
||||
controller->SetLedCount(1, zones[zone_idx].leds_count);
|
||||
controller->SetLedCount(cm_small_argb_header_data[zone_idx].header, zones[zone_idx].leds_count);
|
||||
|
||||
SetupZones();
|
||||
}
|
||||
@@ -305,79 +277,37 @@ void RGBController_CMSmallARGBController::DeviceUpdateLEDs()
|
||||
|
||||
void RGBController_CMSmallARGBController::DeviceUpdateZoneLEDs(int zone)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Only send direct packets while Direct mode is active. |
|
||||
| Direct mode is only offered on FW0012 and newer, so |
|
||||
| older firmware will never send direct packets here |
|
||||
\*-----------------------------------------------------*/
|
||||
if(modes[active_mode].value != CM_SMALL_ARGB_MODE_DIRECT)
|
||||
if(serial >= CM_SMALL_ARGB_FW0012)
|
||||
{
|
||||
return;
|
||||
controller->SetLedsDirect( zones[zone].colors, zones[zone].leds_count );
|
||||
}
|
||||
|
||||
controller->SetLedsDirect(zones[zone].colors, zones[zone].leds_count);
|
||||
}
|
||||
|
||||
void RGBController_CMSmallARGBController::DeviceUpdateSingleLED(int led)
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Map the LED back to its zone and update that zone |
|
||||
\*-----------------------------------------------------*/
|
||||
unsigned int zone_idx = leds[led].value;
|
||||
|
||||
UpdateZoneLEDs(zone_idx);
|
||||
DeviceUpdateZoneLEDs(led);
|
||||
}
|
||||
|
||||
void RGBController_CMSmallARGBController::SetCustomMode()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Direct mode is only supported on FW0012 and newer |
|
||||
\*-----------------------------------------------------*/
|
||||
/*-------------------------------------------------*\
|
||||
| The small ARGB may not support "Direct" mode |
|
||||
| in which case this will select "Pass Thru" |
|
||||
\*-------------------------------------------------*/
|
||||
if(serial >= CM_SMALL_ARGB_FW0012)
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Search the mode list for Direct mode |
|
||||
\*-------------------------------------------------*/
|
||||
for(std::size_t mode_idx = 0; mode_idx < modes.size(); mode_idx++)
|
||||
{
|
||||
if(modes[mode_idx].name == "Direct")
|
||||
{
|
||||
SetActiveMode((int)mode_idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
active_mode = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*-------------------------------------------------*\
|
||||
| Direct mode is unsupported by the firmware, |
|
||||
| fall back to Pass Thru |
|
||||
\*-------------------------------------------------*/
|
||||
for(std::size_t mode_idx = 0; mode_idx < modes.size(); mode_idx++)
|
||||
{
|
||||
if(modes[mode_idx].value == CM_SMALL_ARGB_MODE_PASSTHRU)
|
||||
{
|
||||
SetActiveMode((int)mode_idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
active_mode = 7;
|
||||
}
|
||||
}
|
||||
|
||||
void RGBController_CMSmallARGBController::DeviceUpdateMode()
|
||||
{
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up mode parameters |
|
||||
\*-----------------------------------------------------*/
|
||||
bool random_colours = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
|
||||
RGBColor colour = 0;
|
||||
unsigned int speed = modes[active_mode].speed;
|
||||
unsigned int brightness = modes[active_mode].brightness;
|
||||
bool random_colours = (modes[active_mode].color_mode == MODE_COLORS_RANDOM);
|
||||
RGBColor colour = (modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) ? modes[active_mode].colors[0] : 0;
|
||||
|
||||
if(modes[active_mode].colors.size() > 0)
|
||||
{
|
||||
colour = modes[active_mode].colors[0];
|
||||
}
|
||||
|
||||
controller->SetMode(modes[active_mode].value, speed, brightness, colour, random_colours);
|
||||
controller->SetMode( modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, colour, random_colours);
|
||||
}
|
||||
|
||||
+4
-3
@@ -18,6 +18,7 @@
|
||||
#define CM_SMALL_ARGB_MIN_LEDS 4
|
||||
#define CM_SMALL_ARGB_MAX_LEDS 48
|
||||
#define CM_SMALL_ARGB_BRIGHTNESS_MAX 0xFF
|
||||
#define CM_SMALL_ARGB_FW0012 "A202104052336"
|
||||
|
||||
class RGBController_CMSmallARGBController : public RGBController
|
||||
{
|
||||
@@ -25,9 +26,7 @@ public:
|
||||
RGBController_CMSmallARGBController(CMSmallARGBController* controller_ptr);
|
||||
~RGBController_CMSmallARGBController();
|
||||
|
||||
void SetupModes();
|
||||
void SetupZones();
|
||||
|
||||
void DeviceConfigureZone(int zone_idx);
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
@@ -36,7 +35,9 @@ public:
|
||||
|
||||
void SetCustomMode();
|
||||
void DeviceUpdateMode();
|
||||
|
||||
private:
|
||||
void Init_Controller();
|
||||
int GetDeviceMode();
|
||||
|
||||
CMSmallARGBController* controller;
|
||||
};
|
||||
|
||||
@@ -327,18 +327,9 @@ DetectedControllers DetectCoolerMasterSmallARGB(hid_device_info* info, const std
|
||||
if(dev)
|
||||
{
|
||||
CMSmallARGBController* controller = new CMSmallARGBController(dev, info->path);
|
||||
RGBController_CMSmallARGBController* rgb_controller = new RGBController_CMSmallARGBController(controller);
|
||||
|
||||
if(controller->GetVersion() != "Unsupported")
|
||||
{
|
||||
RGBController_CMSmallARGBController* rgb_controller = new RGBController_CMSmallARGBController(controller);
|
||||
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("[CMSmallARGBController] Unsupported firmware version");
|
||||
delete controller;
|
||||
}
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
|
||||
@@ -340,6 +340,7 @@ void CorsairCommanderCoreController::SetDirectColor
|
||||
lastzones = zones;
|
||||
int packet_offset = 0;
|
||||
int led_idx = 0;
|
||||
int channel_idx = 0;
|
||||
int packet_len = CORSAIR_COMMANDER_CORE_RGB_DATA_LENGTH;
|
||||
|
||||
if(pid == CORSAIR_COMMANDER_CORE_XT_PID)
|
||||
@@ -368,6 +369,8 @@ void CorsairCommanderCoreController::SetDirectColor
|
||||
{
|
||||
packet_offset += 3 * (34 - zones[zone_idx].leds_count);
|
||||
}
|
||||
|
||||
channel_idx++;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
|
||||
@@ -26,7 +26,6 @@ CorsairDRAMController::CorsairDRAMController(i2c_smbus_interface *bus, corsair_d
|
||||
this->bus = bus;
|
||||
this->dev = dev;
|
||||
device_index = 0;
|
||||
direct_mode = true;
|
||||
pid = 0;
|
||||
vid = 0;
|
||||
protocol_version = 0;
|
||||
@@ -133,77 +132,13 @@ void CorsairDRAMController::SetColorsPerLED(RGBColor* colors)
|
||||
| bytes, use a second block write to the second |
|
||||
| block write address for the remaining data |
|
||||
\*-------------------------------------------------*/
|
||||
s32 ret = bus->i2c_smbus_write_block_data(dev, CORSAIR_DRAM_REG_COLOR_BUFFER_BLOCK_1, 32, direct_packet);
|
||||
bus->i2c_smbus_write_block_data(dev, CORSAIR_DRAM_REG_COLOR_BUFFER_BLOCK_1, 32, direct_packet);
|
||||
|
||||
if((ret >= 0) && (direct_packet_size > 32))
|
||||
if(direct_packet_size > 32)
|
||||
{
|
||||
bus->i2c_smbus_write_block_data(dev, CORSAIR_DRAM_REG_COLOR_BUFFER_BLOCK_2, direct_packet_size - 32, direct_packet + 32);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Corsair DRAM supports an alternate means of |
|
||||
| writing block data without using SMBus block |
|
||||
| operations. If block operations are not |
|
||||
| available, fall back to this scheme. |
|
||||
| |
|
||||
| Blocks are split up into word data writes. |
|
||||
| Some data bytes are packed into the lower nibble |
|
||||
| of the register address byte. |
|
||||
\*-------------------------------------------------*/
|
||||
if(ret < 0)
|
||||
{
|
||||
unsigned int block_index = 0;
|
||||
|
||||
while(block_index < direct_packet_size)
|
||||
{
|
||||
unsigned char reg_value_0 = 0xA0;
|
||||
unsigned char reg_value_1 = 0x00;
|
||||
unsigned short word_value_0 = 0;
|
||||
unsigned short word_value_1 = 0;
|
||||
|
||||
if(block_index == 0)
|
||||
{
|
||||
reg_value_0 = 0x90;
|
||||
}
|
||||
|
||||
word_value_0 = (direct_packet[block_index]);
|
||||
block_index++;
|
||||
|
||||
if(block_index < direct_packet_size)
|
||||
{
|
||||
word_value_0 |= (direct_packet[block_index] << 8);
|
||||
block_index++;
|
||||
}
|
||||
|
||||
if(block_index < direct_packet_size)
|
||||
{
|
||||
reg_value_1 = 0xA0;
|
||||
reg_value_0 |= (direct_packet[block_index] & 0x0F);
|
||||
reg_value_1 |= (direct_packet[block_index] & 0xF0) >> 4;
|
||||
block_index++;
|
||||
}
|
||||
|
||||
if(block_index < direct_packet_size)
|
||||
{
|
||||
word_value_1 = (direct_packet[block_index]);
|
||||
block_index++;
|
||||
}
|
||||
|
||||
if(block_index < direct_packet_size)
|
||||
{
|
||||
word_value_1 |= (direct_packet[block_index] << 8);
|
||||
block_index++;
|
||||
}
|
||||
|
||||
bus->i2c_smbus_write_word_data(dev, reg_value_0, word_value_0);
|
||||
|
||||
if(reg_value_1 > 0)
|
||||
{
|
||||
bus->i2c_smbus_write_word_data(dev, reg_value_1, word_value_1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Remember to delete the data buffer |
|
||||
\*-------------------------------------------------*/
|
||||
|
||||
@@ -24,15 +24,18 @@ using namespace std::chrono_literals;
|
||||
|
||||
bool TestForCorsairDRAMController(i2c_smbus_interface *bus, unsigned char address)
|
||||
{
|
||||
LOG_DEBUG("[%s] Trying address %02X", CORSAIR_DRAM_NAME, address);
|
||||
int res = bus->i2c_smbus_write_quick(address, I2C_SMBUS_WRITE);
|
||||
|
||||
int res = bus->i2c_smbus_read_byte_data(address, 0x43);
|
||||
LOG_DEBUG("[%s] Trying address %02X", CORSAIR_DRAM_NAME, address);
|
||||
|
||||
if(res < 0)
|
||||
{
|
||||
LOG_DEBUG("[%s] Failed: res was %04X", CORSAIR_DRAM_NAME, res);
|
||||
return false;
|
||||
}
|
||||
|
||||
res = bus->i2c_smbus_read_byte_data(address, 0x43);
|
||||
|
||||
if(!(res == 0x1A || res == 0x1B || res == 0x1C))
|
||||
{
|
||||
LOG_DEBUG("[%s] Failed: expected 0x1A, 0x1B, or 0x1C, got %04X", CORSAIR_DRAM_NAME, res);
|
||||
|
||||
@@ -44,4 +44,8 @@ DetectedControllers DetectCorsairHydro2Controllers()
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("Corsair H100i v2", DetectCorsairHydro2Controllers);
|
||||
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\"");
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| Entries for dynamic UDEV rules |
|
||||
| |
|
||||
| DUMMY_DEVICE_DETECTOR("Corsair H100i v2", DetectCorsairHydro2Controllers, 0x1B1C, 0x0C09 ) |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -77,6 +77,10 @@ DetectedControllers DetectCorsairHydroControllers()
|
||||
}
|
||||
|
||||
REGISTER_DETECTOR("Corsair Hydro Series", DetectCorsairHydroControllers);
|
||||
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\"");
|
||||
/*---------------------------------------------------------------------------------------------------------*\
|
||||
| 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 ) |
|
||||
\*---------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
@@ -98,16 +98,7 @@ void RGBController_CorsairICueLink::SetupZones()
|
||||
lcd_zone.leds_min = controller->GetEndpoints()[lcd_idx]->led_channels;
|
||||
lcd_zone.leds_max = lcd_zone.leds_min;
|
||||
lcd_zone.leds_count = lcd_zone.leds_min;
|
||||
|
||||
zones.push_back(lcd_zone);
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < lcd_zone.leds_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
new_led.name = "LED " + std::to_string(led_idx + 1);
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ void CorsairLightingNodeController::SendFirmwareRequest()
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet |
|
||||
\*-----------------------------------------------------*/
|
||||
actual = WriteAndRead(usb_buf, CORSAIR_LIGHTING_NODE_READ_TIMEOUT);
|
||||
actual = WriteAndRead(usb_buf);
|
||||
|
||||
if(actual > 0)
|
||||
{
|
||||
|
||||
@@ -365,7 +365,7 @@ void RGBController_CorsairLightingNode::SetupZones()
|
||||
new_led.name = zones[zone_idx].name + ", LED " + std::to_string(led_ch_idx + 1);
|
||||
|
||||
leds.push_back(new_led);
|
||||
leds_channel.push_back((unsigned int)zone_idx);
|
||||
leds_channel.push_back(zone_idx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,7 +413,7 @@ void RGBController_CorsairLightingNode::DeviceUpdateMode()
|
||||
{
|
||||
for(std::size_t zone_idx = 0; zone_idx < zones.size(); zone_idx++)
|
||||
{
|
||||
DeviceUpdateZoneMode((int)zone_idx);
|
||||
DeviceUpdateZoneMode(zone_idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 || logical_layout == CORSAIR_TYPE_K70_LUX_RGB)
|
||||
else if (logical_layout == CORSAIR_TYPE_K70_MK2)
|
||||
{
|
||||
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 || logical_layout == CORSAIR_TYPE_K70_LUX_RGB)
|
||||
if(logical_layout == CORSAIR_TYPE_K70_MK2)
|
||||
{
|
||||
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]);
|
||||
@@ -526,26 +526,27 @@ void CorsairPeripheralController::ReadFirmwareInfo()
|
||||
char offset = 0;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Some Corsair keyboards (e.g. K70 RGB MK.2) do not |
|
||||
| answer the firmware-info query on the control |
|
||||
| interface until several seconds after the host first |
|
||||
| talks to them following a cold boot. A single read |
|
||||
| attempt returns all zeros, the device type comes back |
|
||||
| as 0x00, and the device is discarded as UNKNOWN. |
|
||||
| Retry the query until a valid device type byte is |
|
||||
| returned or the attempt cap is reached. Each failed |
|
||||
| attempt is paced by the 1s hid_read_timeout below, so |
|
||||
| the cap also bounds the detection stall for a device |
|
||||
| that opens but never answers. Observed need |
|
||||
| on a K70 RGB MK.2 cold boot is 2 attempts; the cap |
|
||||
| leaves generous headroom. |
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
int attempt = 0;
|
||||
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
|
||||
do
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Read Firmware Info packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_READ;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet and try reading it using an HID read |
|
||||
| If that fails, repeat the send and read the reply as |
|
||||
| a feature report. |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
actual = hid_read_timeout(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH, 1000);
|
||||
|
||||
if(actual == 0)
|
||||
{
|
||||
offset = 0;
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-------------------------------------------------*/
|
||||
@@ -558,48 +559,10 @@ void CorsairPeripheralController::ReadFirmwareInfo()
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_READ;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Send packet and try reading it using an HID read |
|
||||
| If that fails, repeat the send and read the reply |
|
||||
| as a feature report. |
|
||||
\*-------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
actual = hid_read_timeout(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH, 1000);
|
||||
|
||||
if(actual == 0)
|
||||
{
|
||||
/*---------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*---------------------------------------------*/
|
||||
memset(usb_buf, 0x00, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
|
||||
/*---------------------------------------------*\
|
||||
| Set up Read Firmware Info packet |
|
||||
\*---------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = CORSAIR_COMMAND_READ;
|
||||
usb_buf[0x02] = CORSAIR_PROPERTY_FIRMWARE_INFO;
|
||||
|
||||
hid_send_feature_report(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
actual = hid_get_feature_report(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
attempt++;
|
||||
|
||||
LOG_DEBUG("[%s] Firmware info attempt %d/%d: device type %02X", CORSAIR_PERIPHERAL_CONTROLLER_NAME, attempt, CORSAIR_FW_INFO_MAX_ATTEMPTS, usb_buf[0x14 + offset]);
|
||||
|
||||
/*-------------------------------------------------*\
|
||||
| Stop as soon as a valid device type is returned |
|
||||
| 0xC0 keyboard / 0xC1 mouse / 0xC2 pad or stand |
|
||||
\*-------------------------------------------------*/
|
||||
if(usb_buf[0x14 + offset] == 0xC0
|
||||
|| usb_buf[0x14 + offset] == 0xC1
|
||||
|| usb_buf[0x14 + offset] == 0xC2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
} while(attempt < CORSAIR_FW_INFO_MAX_ATTEMPTS);
|
||||
hid_send_feature_report(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
actual = hid_get_feature_report(dev, usb_buf, CORSAIR_PERIPHERAL_PACKET_LENGTH);
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Get device type |
|
||||
@@ -607,7 +570,7 @@ void CorsairPeripheralController::ReadFirmwareInfo()
|
||||
| 0xC1 Device is a mouse |
|
||||
| 0xC2 Device is a mousepad or headset stand |
|
||||
\*-----------------------------------------------------*/
|
||||
LOG_DEBUG("[%s] Device type %02X after %d attempt(s)", CORSAIR_PERIPHERAL_CONTROLLER_NAME, usb_buf[0x14 + offset], attempt);
|
||||
LOG_DEBUG("[%s] Device type %02X", CORSAIR_PERIPHERAL_CONTROLLER_NAME, usb_buf[0x14 + offset]);
|
||||
|
||||
switch(usb_buf[0x14 + offset])
|
||||
{
|
||||
@@ -632,15 +595,10 @@ 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;
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "RGBController.h"
|
||||
|
||||
#define CORSAIR_PERIPHERAL_PACKET_LENGTH 65
|
||||
#define CORSAIR_FW_INFO_MAX_ATTEMPTS 10
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -67,8 +66,7 @@ enum
|
||||
CORSAIR_TYPE_K95 = 2,
|
||||
CORSAIR_TYPE_K55 = 3,
|
||||
CORSAIR_TYPE_K70_MK2 = 4,
|
||||
CORSAIR_TYPE_K68 = 5,
|
||||
CORSAIR_TYPE_K70_LUX_RGB = 6
|
||||
CORSAIR_TYPE_K68 = 5
|
||||
};
|
||||
|
||||
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
|
||||
@@ -81,7 +81,6 @@
|
||||
#define CORSAIR_SCIMITAR_PRO_RGB_PID 0x1B3E
|
||||
#define CORSAIR_SCIMITAR_ELITE_RGB_PID 0x1B8B
|
||||
#define CORSAIR_SABRE_RGB_PID 0x1B2F
|
||||
#define CORSAIR_SABRE_RGB_OPTICAL_PID 0x1B32
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Mousepad product IDs |
|
||||
@@ -193,7 +192,6 @@ 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);
|
||||
@@ -216,7 +214,6 @@ REGISTER_HID_DETECTOR_IP("Corsair Scimitar RGB", DetectCorsairPeriphe
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Scimitar PRO RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_SCIMITAR_PRO_RGB_PID, 1, 0xFFC2);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Scimitar Elite RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_SCIMITAR_ELITE_RGB_PID, 1, 0xFFC2);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Sabre RGB", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_SABRE_RGB_PID, 1, 0xFFC2);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair Sabre RGB Optical", DetectCorsairPeripheralControllers, CORSAIR_VID, CORSAIR_SABRE_RGB_OPTICAL_PID, 1, 0xFFC2);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Mousemats |
|
||||
|
||||
@@ -23,15 +23,6 @@ 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 },
|
||||
@@ -77,24 +68,6 @@ 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 |
|
||||
\*---------------------------------------------------------*/
|
||||
@@ -186,7 +159,7 @@ static const char* led_names[] =
|
||||
KEY_EN_LEFT_CONTROL, //5
|
||||
KEY_EN_F12, //6
|
||||
KEY_EN_EQUALS, //7
|
||||
KEY_EN_WINDOWS_LOCK, //8
|
||||
"Key: Lock", //8
|
||||
KEY_EN_NUMPAD_7, //9
|
||||
KEY_EN_F1, //12
|
||||
KEY_EN_1, //13
|
||||
@@ -285,7 +258,7 @@ static const char* led_names[] =
|
||||
KEY_EN_LEFT_BRACKET, //134
|
||||
KEY_EN_QUOTE, //135
|
||||
KEY_EN_FORWARD_SLASH, //136
|
||||
KEY_EN_BRIGHTNESS, //137
|
||||
"Key: Brightness", //137
|
||||
KEY_EN_RIGHT_ARROW, //139
|
||||
KEY_EN_NUMPAD_ENTER, //140
|
||||
KEY_EN_NUMPAD_PERIOD, //141
|
||||
@@ -293,131 +266,6 @@ static const char* led_names[] =
|
||||
KEY_EN_ISO_BACK_SLASH,
|
||||
};
|
||||
|
||||
static const char* led_names_k70_lux_rgb[] =
|
||||
{
|
||||
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
|
||||
"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
|
||||
@@ -428,7 +276,7 @@ static const char* led_names_k70_mk2[] =
|
||||
KEY_EN_LEFT_CONTROL, //5
|
||||
KEY_EN_F12, //6
|
||||
KEY_EN_EQUALS, //7
|
||||
KEY_EN_WINDOWS_LOCK, //8
|
||||
"Key: Lock", //8
|
||||
KEY_EN_NUMPAD_7, //9
|
||||
KEY_EN_F1, //12
|
||||
KEY_EN_1, //13
|
||||
@@ -532,7 +380,7 @@ static const char* led_names_k70_mk2[] =
|
||||
KEY_EN_LEFT_BRACKET, //134
|
||||
KEY_EN_QUOTE, //135
|
||||
KEY_EN_FORWARD_SLASH, //136
|
||||
KEY_EN_BRIGHTNESS, //137
|
||||
"Key: Brightness", //137
|
||||
KEY_EN_RIGHT_ARROW, //139
|
||||
KEY_EN_NUMPAD_ENTER, //140
|
||||
KEY_EN_NUMPAD_PERIOD, //141
|
||||
@@ -553,7 +401,7 @@ static const char* led_names_k95_plat[] =
|
||||
KEY_EN_LEFT_CONTROL, //5
|
||||
KEY_EN_F12, //6
|
||||
KEY_EN_EQUALS, //7
|
||||
KEY_EN_WINDOWS_LOCK, //8
|
||||
"Key: Lock", //8
|
||||
KEY_EN_NUMPAD_7, //9
|
||||
KEY_EN_F1, //12
|
||||
KEY_EN_1, //13
|
||||
@@ -652,7 +500,7 @@ static const char* led_names_k95_plat[] =
|
||||
KEY_EN_LEFT_BRACKET, //134
|
||||
KEY_EN_QUOTE, //135
|
||||
KEY_EN_FORWARD_SLASH, //136
|
||||
KEY_EN_BRIGHTNESS, //137
|
||||
"Key: Brightness", //137
|
||||
KEY_EN_RIGHT_ARROW, //139
|
||||
KEY_EN_NUMPAD_ENTER, //140
|
||||
KEY_EN_NUMPAD_PERIOD, //141
|
||||
@@ -696,7 +544,7 @@ static const char* led_names_k95[] =
|
||||
KEY_EN_LEFT_CONTROL, //5
|
||||
KEY_EN_F12, //6
|
||||
KEY_EN_EQUALS, //7
|
||||
KEY_EN_WINDOWS_LOCK, //8
|
||||
"Key: Lock", //8
|
||||
KEY_EN_NUMPAD_7, //9
|
||||
KEY_EN_F1, //12
|
||||
KEY_EN_1, //13
|
||||
@@ -795,7 +643,7 @@ static const char* led_names_k95[] =
|
||||
KEY_EN_LEFT_BRACKET, //134
|
||||
KEY_EN_QUOTE, //135
|
||||
KEY_EN_FORWARD_SLASH, //136
|
||||
KEY_EN_BRIGHTNESS, //137
|
||||
"Key: Brightness", //137
|
||||
KEY_EN_RIGHT_ARROW, //139
|
||||
KEY_EN_NUMPAD_ENTER, //140
|
||||
KEY_EN_NUMPAD_PERIOD, //141
|
||||
@@ -1164,19 +1012,6 @@ 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];
|
||||
@@ -1266,10 +1101,6 @@ 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,9 +9,6 @@
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "CorsairPeripheralV2Controller.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
@@ -22,42 +19,21 @@ 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 |
|
||||
\*---------------------------------------------------------*/
|
||||
/*---------------------------------------------------------*\
|
||||
| Establish the packet size before talking to the device. |
|
||||
\*---------------------------------------------------------*/
|
||||
uint16_t report_size = GetOutputReportSize();
|
||||
|
||||
if(report_size >= CORSAIR_V2_WRITE_SIZE && report_size <= CORSAIR_V2_PACKET_SIZE)
|
||||
{
|
||||
pkt_sze = report_size;
|
||||
}
|
||||
|
||||
LOG_DEBUG("[%s] Packet length set to %d", device_name.c_str(), pkt_sze);
|
||||
|
||||
unsigned int pid = GetAddressRetry(0x12);
|
||||
unsigned int pid = GetAddress(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 = GetAddressRetry(0x12);
|
||||
break;
|
||||
|
||||
case CORSAIR_K57_RGB_WIRED_PID:
|
||||
write_cmd = 0x80;
|
||||
light_ctrl = CORSAIR_V2_LIGHT_CTRL1;
|
||||
skip_reads = true;
|
||||
pid = GetAddress(0x12);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -76,12 +52,14 @@ CorsairPeripheralV2Controller::CorsairPeripheralV2Controller(hid_device* dev_han
|
||||
| the device being set up. |
|
||||
\*---------------------------------------------------------*/
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
memset(buffer, 0, pkt_sze);
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_GET;
|
||||
buffer[3] = 0x11;
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
uint16_t result = hid_read_timeout(dev, buffer, CORSAIR_V2_PACKET_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
result++;
|
||||
pkt_sze = std::max(result, (uint16_t)CORSAIR_V2_WRITE_SIZE);
|
||||
LOG_DEBUG("[%s] Packet length set to %d", device_name.c_str(), pkt_sze);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| NB: If the device is not found in the device list |
|
||||
@@ -104,127 +82,23 @@ 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Check lighting control endpoints |
|
||||
| If lighting control endpoint 2 is unavailable |
|
||||
| then use endpoint 1. |
|
||||
\*---------------------------------------------------------*/
|
||||
uint16_t CorsairPeripheralV2Controller::GetOutputReportSize()
|
||||
{
|
||||
unsigned char descriptor[HID_API_MAX_REPORT_DESCRIPTOR_SIZE];
|
||||
int length = hid_get_report_descriptor(dev, descriptor, sizeof(descriptor));
|
||||
|
||||
if(length <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int report_size = 0;
|
||||
unsigned int report_count = 0;
|
||||
int index = 0;
|
||||
|
||||
while(index < length)
|
||||
{
|
||||
unsigned char item = descriptor[index];
|
||||
unsigned char tag = item & 0xFC;
|
||||
unsigned char item_size = item & 0x03;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| A size field of 3 means four data bytes follow. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(item_size == 3)
|
||||
{
|
||||
item_size = 4;
|
||||
}
|
||||
|
||||
if(index + 1 + item_size > length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned int value = 0;
|
||||
|
||||
for(unsigned char byte = 0; byte < item_size; byte++)
|
||||
{
|
||||
value |= (unsigned int)descriptor[index + 1 + byte] << (8 * byte);
|
||||
}
|
||||
|
||||
switch(tag)
|
||||
{
|
||||
case 0x74: /* Report Size */
|
||||
report_size = value;
|
||||
break;
|
||||
|
||||
case 0x94: /* Report Count */
|
||||
report_count = value;
|
||||
break;
|
||||
|
||||
case 0x90: /* Output */
|
||||
if(report_size > 0 && report_count > 0)
|
||||
{
|
||||
return (uint16_t)(((report_size * report_count) / 8) + 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
index += 1 + item_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2Controller::DetectLightingEndpoint()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| A device that cannot be read from cannot be probed; those |
|
||||
| carry the endpoint they need already set. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(skip_reads)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Lighting control 1 is the plain lighting resource and |
|
||||
| takes colour block data. A device that answers |
|
||||
| invalid or unsupported for it wants the alternate |
|
||||
| lighting resource, which takes RGB triplets. |
|
||||
| Check lighting control endpoints |
|
||||
| If lighting control endpoint 2 is unavailable |
|
||||
| then use endpoint 1. |
|
||||
\*---------------------------------------------------------*/
|
||||
light_ctrl = CORSAIR_V2_LIGHT_CTRL1;
|
||||
unsigned char result = StartTransaction(0);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| A handle left open by an earlier session answers failed; |
|
||||
| close it and open it again. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(result == CORSAIR_V2_ERR_FAILED)
|
||||
result = StartTransaction(0);
|
||||
if(result > 0)
|
||||
{
|
||||
StopTransaction(0);
|
||||
result = StartTransaction(0);
|
||||
}
|
||||
|
||||
if(result == CORSAIR_V2_ERR_INVALID || result == CORSAIR_V2_ERR_NOT_SUPPORTED)
|
||||
{
|
||||
light_ctrl = CORSAIR_V2_LIGHT_CTRL2;
|
||||
light_ctrl = CORSAIR_V2_LIGHT_CTRL1;
|
||||
StartTransaction(0);
|
||||
}
|
||||
|
||||
StopTransaction(0);
|
||||
LOG_DEBUG("[%s] Lighting Endpoint set to %02X", device_name.c_str(), light_ctrl);
|
||||
}
|
||||
@@ -236,19 +110,9 @@ 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);
|
||||
@@ -294,9 +158,9 @@ std::string CorsairPeripheralV2Controller::GetSerialString()
|
||||
|
||||
void CorsairPeripheralV2Controller::SetRenderMode(corsair_v2_device_mode mode)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
|
||||
memset(buffer, 0, pkt_sze);
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set Mode |
|
||||
@@ -306,19 +170,15 @@ void CorsairPeripheralV2Controller::SetRenderMode(corsair_v2_device_mode mode)
|
||||
buffer[3] = CORSAIR_V2_VALUE_MODE;
|
||||
buffer[5] = mode;
|
||||
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2Controller::LightingControl(uint8_t opt1)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
|
||||
memset(buffer, 0, pkt_sze);
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| The Corsair command is the same for each initialisation |
|
||||
@@ -330,12 +190,8 @@ void CorsairPeripheralV2Controller::LightingControl(uint8_t opt1)
|
||||
buffer[3] = opt1;
|
||||
buffer[5] = 0x00;
|
||||
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
|
||||
unsigned int CorsairPeripheralV2Controller::GetKeyboardLayout()
|
||||
@@ -343,48 +199,20 @@ 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_PACKET_SIZE];
|
||||
uint8_t read[CORSAIR_V2_PACKET_SIZE];
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
uint8_t read[CORSAIR_V2_WRITE_SIZE];
|
||||
|
||||
memset(buffer, 0, pkt_sze);
|
||||
memset(read, 0, pkt_sze);
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
memset(read, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_GET;
|
||||
buffer[3] = address;
|
||||
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
hid_read_timeout(dev, read, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_read_timeout(dev, read, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
|
||||
unsigned int temp = (unsigned int)(read[6] << 24 | read[5] << 16 | read[4] << 8 | read[3]);
|
||||
LOG_DEBUG("[%s] GetAddress %02X - %02X %02X - %02X %02X %02X %02X %02X %02X %02X %02X", device_name.c_str(),
|
||||
@@ -402,59 +230,41 @@ unsigned int CorsairPeripheralV2Controller::GetAddress(uint8_t address)
|
||||
|
||||
unsigned char CorsairPeripheralV2Controller::StartTransaction(uint8_t opt1)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
|
||||
memset(buffer, 0, pkt_sze);
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_START_TX;
|
||||
buffer[3] = opt1;
|
||||
buffer[4] = light_ctrl;
|
||||
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
|
||||
return buffer[2];
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2Controller::StopTransaction(uint8_t opt1)
|
||||
{
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
uint8_t buffer[CORSAIR_V2_WRITE_SIZE];
|
||||
|
||||
memset(buffer, 0, pkt_sze);
|
||||
memset(buffer, 0, CORSAIR_V2_WRITE_SIZE);
|
||||
|
||||
buffer[1] = write_cmd;
|
||||
buffer[2] = CORSAIR_V2_CMD_STOP_TX;
|
||||
buffer[3] = 0x01;
|
||||
buffer[4] = opt1;
|
||||
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
hid_write(dev, buffer, CORSAIR_V2_WRITE_SIZE);
|
||||
hid_read_timeout(dev, buffer, CORSAIR_V2_WRITE_SIZE, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
|
||||
void CorsairPeripheralV2Controller::ClearPacketBuffer()
|
||||
{
|
||||
if(skip_reads)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t result = 0;
|
||||
uint8_t buffer[CORSAIR_V2_PACKET_SIZE];
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Draining expects to find nothing, so the last read here |
|
||||
| always waits out the timeout. Keep it short: this runs |
|
||||
| before every LED update. |
|
||||
\*---------------------------------------------------------*/
|
||||
do
|
||||
{
|
||||
result = hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
|
||||
@@ -464,8 +274,6 @@ void CorsairPeripheralV2Controller::ClearPacketBuffer()
|
||||
|
||||
void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(device_mutex);
|
||||
|
||||
const uint8_t offset1 = 8;
|
||||
const uint8_t offset2 = 4;
|
||||
uint16_t remaining = data_size;
|
||||
@@ -496,11 +304,7 @@ void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
|
||||
memcpy(&buffer[offset1], &data[0], copy_bytes);
|
||||
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
|
||||
|
||||
remaining -= copy_bytes;
|
||||
buffer[2] = CORSAIR_V2_CMD_BLK_WN;
|
||||
@@ -521,11 +325,7 @@ void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
|
||||
memcpy(&buffer[offset2], &data[index], copy_bytes);
|
||||
|
||||
hid_write(dev, buffer, pkt_sze);
|
||||
|
||||
if(!skip_reads)
|
||||
{
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT);
|
||||
}
|
||||
hid_read_timeout(dev, buffer, pkt_sze, CORSAIR_V2_TIMEOUT_SHORT);
|
||||
|
||||
remaining -= copy_bytes;
|
||||
}
|
||||
@@ -536,8 +336,6 @@ void CorsairPeripheralV2Controller::SetLEDs(uint8_t *data, uint16_t data_size)
|
||||
void CorsairPeripheralV2Controller::UpdateHWMode(uint16_t mode, corsair_v2_color /*color_mode*/, uint8_t /*speed*/,
|
||||
uint8_t /*direction*/, uint8_t /*brightness*/, std::vector<RGBColor> /*colors*/)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(device_mutex);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| If we are switching to `Direct` mode |
|
||||
| set device in software mode |
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <hidapi.h>
|
||||
#include "LogManager.h"
|
||||
@@ -22,33 +21,13 @@
|
||||
#define NA 0xFFFFFFFF
|
||||
#define HID_MAX_STR 255
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| A jumbo packet device answers a 1KB command in well over |
|
||||
| 50ms. Missing the reply leaves it queued and the next |
|
||||
| write to the device then fails outright, so this has to |
|
||||
| be generous. A reply that does arrive is returned as |
|
||||
| soon as it lands, so this only costs time on failure. |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CORSAIR_V2_TIMEOUT 500
|
||||
#define CORSAIR_V2_TIMEOUT 50
|
||||
#define CORSAIR_V2_TIMEOUT_SHORT 3
|
||||
#define CORSAIR_V2_VALUE_MODE 3
|
||||
#define CORSAIR_V2_WRITE_WIRED_ID 8
|
||||
#define CORSAIR_V2_WRITE_WIRELESS_ID 9
|
||||
#define CORSAIR_V2_WRITE_SIZE 65
|
||||
/*---------------------------------------------------------*\
|
||||
| Largest packet the protocol uses: 1024 payload bytes |
|
||||
| plus the leading report ID. pkt_sze is measured |
|
||||
| against this, and every stack buffer handed to hidapi |
|
||||
| with pkt_sze is this size, so the two must agree. |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CORSAIR_V2_PACKET_SIZE 1025
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Error codes the device returns in byte 2 of a reply. |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CORSAIR_V2_ERR_INVALID 0x01
|
||||
#define CORSAIR_V2_ERR_FAILED 0x03
|
||||
#define CORSAIR_V2_ERR_NOT_SUPPORTED 0x06
|
||||
#define CORSAIR_V2_PACKET_SIZE 1024
|
||||
|
||||
#define CORSAIR_V2_LIGHT_CTRL1 1
|
||||
#define CORSAIR_V2_LIGHT_CTRL2 34 /* 0x22 */
|
||||
@@ -58,19 +37,6 @@
|
||||
#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 */
|
||||
@@ -118,7 +84,6 @@ public:
|
||||
std::string GetName();
|
||||
std::string GetSerialString();
|
||||
const corsair_v2_device* GetDeviceData();
|
||||
bool IsDeviceSupported();
|
||||
unsigned int GetKeyboardLayout();
|
||||
|
||||
void SetRenderMode(corsair_v2_device_mode mode);
|
||||
@@ -134,49 +99,16 @@ protected:
|
||||
std::string device_name;
|
||||
uint8_t light_ctrl = CORSAIR_V2_LIGHT_CTRL2;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Works out which lighting control endpoint the device |
|
||||
| accepts. Must be called only once the device has been |
|
||||
| put into software render mode: endpoint 2 rejects the |
|
||||
| transaction while the device is still driving its own |
|
||||
| lighting, which would pick endpoint 1 for a device that |
|
||||
| does not support it. |
|
||||
\*---------------------------------------------------------*/
|
||||
void DetectLightingEndpoint();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Size of one output report, plus the leading report ID. |
|
||||
| Read from the HID report descriptor before anything is |
|
||||
| sent: these devices come in a 64 byte and a 1024 byte |
|
||||
| flavour, and sending a short packet to a 1024 byte |
|
||||
| endpoint wedges it until the device is reset, so the |
|
||||
| size has to be known before the first write rather than |
|
||||
| inferred from a reply. Returns 0 if it cannot be read. |
|
||||
\*---------------------------------------------------------*/
|
||||
uint16_t GetOutputReportSize();
|
||||
|
||||
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);
|
||||
|
||||
hid_device* dev;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Serialises device transactions. |
|
||||
| The RGB controllers run a keepalive thread that writes |
|
||||
| LEDs independently of the caller, and a Corsair block |
|
||||
| write spans several packets. Letting two of those |
|
||||
| interleave on one HID handle corrupts the transaction |
|
||||
| and leaves the device unresponsive until it is reset. |
|
||||
\*---------------------------------------------------------*/
|
||||
std::mutex device_mutex;
|
||||
|
||||
uint8_t write_cmd = CORSAIR_V2_WRITE_WIRED_ID;
|
||||
uint16_t pkt_sze = CORSAIR_V2_WRITE_SIZE;
|
||||
bool skip_reads = false;
|
||||
std::string firmware_version;
|
||||
std::string location;
|
||||
};
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
\*---------------------------------------------------------*/
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "LogManager.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Corsair Peripheral specific includes |
|
||||
@@ -38,20 +37,6 @@ 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);
|
||||
@@ -70,14 +55,6 @@ 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);
|
||||
@@ -90,9 +67,7 @@ DetectedControllers DetectCorsairV2SoftwareControllers(hid_device_info* info, co
|
||||
| Keyboards |
|
||||
\*---------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K55 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K55_RGB_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K57 RGB (Wired)", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K57_RGB_WIRED_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO SE", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_SE_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO Low Profile", DetectCorsairV2SoftwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_LP_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO TKL Black", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_TKL_B_PID, 1, 0xFF42);
|
||||
REGISTER_HID_DETECTOR_IP("Corsair K60 RGB PRO TKL White", DetectCorsairV2HardwareControllers, CORSAIR_VID, CORSAIR_K60_RGB_PRO_TKL_W_PID, 1, 0xFF42);
|
||||
@@ -115,8 +90,6 @@ 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);
|
||||
@@ -124,8 +97,6 @@ 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);
|
||||
|
||||
@@ -48,31 +48,6 @@ std::vector<unsigned int> corsair_full_size_values =
|
||||
/*-------------------------------------------------------------------------*\
|
||||
| KEYMAPS |
|
||||
\*-------------------------------------------------------------------------*/
|
||||
keyboard_keymap_overlay_values corsair_K57_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_FULL,
|
||||
{
|
||||
corsair_full_size_values,
|
||||
{
|
||||
/* Add more regional layout fixes here */
|
||||
}
|
||||
},
|
||||
{
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Name, Alternate Name, OpCode |
|
||||
\*-------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 0, 17, 0, "Power/Wireless Indicator", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_ROW, }, // Insert Profile into new row
|
||||
{ 0, 0, 18, 1, "Lock/Macro Indicator", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Light key
|
||||
{ 0, 1, 0, 131, "Key: G1", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert G1 key
|
||||
{ 0, 2, 0, 132, "Key: G2", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert G2 key
|
||||
{ 0, 3, 0, 133, "Key: G3", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert G3 key
|
||||
{ 0, 4, 0, 134, "Key: G4", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert G4 key
|
||||
{ 0, 5, 0, 135, "Key: G5", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert G5 key
|
||||
{ 0, 6, 0, 136, "Key: G6", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert G6 key
|
||||
}
|
||||
};
|
||||
|
||||
keyboard_keymap_overlay_values corsair_K60_layout
|
||||
{
|
||||
KEYBOARD_SIZE::KEYBOARD_SIZE_FULL,
|
||||
@@ -141,14 +116,12 @@ keyboard_keymap_overlay_values corsair_k70_pro_layout
|
||||
{ 0, 0, 0, 128, "Profile", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_ROW, }, // Insert Profile into new row
|
||||
{ 0, 0, 1, 113, "Light", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Light key
|
||||
{ 0, 0, 2, 114, "Lock", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Lock Key
|
||||
{ 0, 0, 10, 138, "Logo", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Logo
|
||||
{ 0, 0, 10, 191, "Logo", KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Logo
|
||||
{ 0, 0, 18, 102, KEY_EN_MEDIA_MUTE, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Mute Key
|
||||
{ 0, 1, 17, 123, KEY_EN_MEDIA_STOP, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Stop Key
|
||||
{ 0, 1, 18, 126, KEY_EN_MEDIA_PREVIOUS, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Previous Track Key
|
||||
{ 0, 1, 19, 124, KEY_EN_MEDIA_PLAY_PAUSE, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Play Pause Key
|
||||
{ 0, 1, 20, 125, KEY_EN_MEDIA_NEXT, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert Next Tack Key
|
||||
{ 0, 6, 5, 140, KEY_EN_SPACE, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert spacebar L
|
||||
{ 0, 6, 7, 141, KEY_EN_SPACE, KEY_EN_UNUSED, KEYBOARD_OPCODE_INSERT_SHIFT_RIGHT, }, // Insert spacebar R
|
||||
}
|
||||
};
|
||||
|
||||
@@ -194,10 +167,10 @@ keyboard_keymap_overlay_values corsair_K70_CORE_TKL_layout
|
||||
| Edit Keys |
|
||||
| Zone, Row, Column, Value, Name, Alternate Name, OpCode, |
|
||||
\*-------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
{ 0, 0, 14, 70, KEY_EN_MEDIA_MUTE, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Swap PRSC with Mute
|
||||
{ 0, 0, 14, 70, KEY_EN_MEDIA_MUTE, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Swap PRSC with Mute
|
||||
{ 0, 0, 15, 71, KEY_EN_UNUSED, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Remove SCLK
|
||||
{ 0, 0, 16, 72, KEY_EN_MEDIA_VOLUME_UP, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Swap PSBK with Volume Potion Up
|
||||
|
||||
{ 0, 0, 16, 72, KEY_EN_MEDIA_VOLUME_UP, KEY_EN_UNUSED, KEYBOARD_OPCODE_SWAP_ONLY, }, // Swap PSBK with Volume Potion Up
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -638,71 +611,6 @@ 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 |
|
||||
| |
|
||||
@@ -864,44 +772,12 @@ static const corsair_v2_device k55_rgb_pro_device =
|
||||
nullptr
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Corsair K57 RGB (Wired) 1B1C:1B6E |
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 7 Rows, 22 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone k57_rgb_wired_zone =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
ZONE_TYPE_MATRIX,
|
||||
7,
|
||||
22
|
||||
};
|
||||
|
||||
static const corsair_v2_device k57_rgb_wired_device =
|
||||
{
|
||||
CORSAIR_K57_RGB_WIRED_PID,
|
||||
DEVICE_TYPE_KEYBOARD,
|
||||
7,
|
||||
22,
|
||||
{
|
||||
&k57_rgb_wired_zone,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
},
|
||||
&corsair_K57_layout
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Corsair K60 RGB Pro 1B1C:1BA0 |
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 7 Rows, 22 Columns |
|
||||
| 6 Rows, 21 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone k60_rgb_pro_zone =
|
||||
{
|
||||
@@ -928,34 +804,12 @@ static const corsair_v2_device k60_rgb_pro_device =
|
||||
&corsair_K60_layout
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Corsair K60 RGB Pro SE 1B1C:1B8D |
|
||||
| |
|
||||
| Initial implementation reuses K60 RGB Pro zone/layout |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_device k60_rgb_pro_se_device =
|
||||
{
|
||||
CORSAIR_K60_RGB_PRO_SE_PID,
|
||||
DEVICE_TYPE_KEYBOARD,
|
||||
6,
|
||||
21,
|
||||
{
|
||||
&k60_rgb_pro_zone,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
},
|
||||
&corsair_K60_layout
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
| Corsair K60 RGB Pro Low Profile 1B1C:1BAD |
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 7 Rows, 22 Columns |
|
||||
| 6 Rows, 21 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone k60_rgb_pro_lp_zone =
|
||||
{
|
||||
@@ -988,7 +842,7 @@ static const corsair_v2_device k60_rgb_pro_lp_device =
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 7 Rows, 22 Columns |
|
||||
| 6 Rows, 21 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone k60_rgb_pro_tkl_zone =
|
||||
{
|
||||
@@ -1038,7 +892,7 @@ static const corsair_v2_device k60_rgb_pro_tkl_device_w =
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 7 Rows, 22 Columns |
|
||||
| 6 Rows, 21 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone k70_core_rgb_zone =
|
||||
{
|
||||
@@ -1167,14 +1021,14 @@ static const corsair_v2_device k70_rgb_tkl_cs_device =
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 7 Rows, 22 Columns |
|
||||
| 6 Rows, 21 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_zone k70_rgb_pro_zone =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
ZONE_TYPE_MATRIX,
|
||||
7,
|
||||
22
|
||||
21
|
||||
};
|
||||
|
||||
static const corsair_v2_device k70_rgb_pro_device =
|
||||
@@ -1182,7 +1036,7 @@ static const corsair_v2_device k70_rgb_pro_device =
|
||||
CORSAIR_K70_RGB_PRO_PID,
|
||||
DEVICE_TYPE_KEYBOARD,
|
||||
7,
|
||||
22,
|
||||
21,
|
||||
{
|
||||
&k70_rgb_pro_zone,
|
||||
nullptr,
|
||||
@@ -1199,14 +1053,14 @@ static const corsair_v2_device k70_rgb_pro_device =
|
||||
| |
|
||||
| Zone "Keyboard" |
|
||||
| Matrix |
|
||||
| 7 Rows, 22 Columns |
|
||||
| 6 Rows, 21 Columns |
|
||||
\*-------------------------------------------------------------*/
|
||||
static const corsair_v2_device k70_rgb_pro_v2_device =
|
||||
{
|
||||
CORSAIR_K70_RGB_PRO_V2_PID,
|
||||
DEVICE_TYPE_KEYBOARD,
|
||||
7,
|
||||
22,
|
||||
21,
|
||||
{
|
||||
&k70_rgb_pro_zone,
|
||||
nullptr,
|
||||
@@ -1215,8 +1069,7 @@ static const corsair_v2_device k70_rgb_pro_v2_device =
|
||||
nullptr,
|
||||
nullptr
|
||||
},
|
||||
&corsair_k70_pro_layout,
|
||||
193
|
||||
&corsair_k70_pro_layout
|
||||
};
|
||||
|
||||
/*-------------------------------------------------------------*\
|
||||
@@ -1531,44 +1384,6 @@ 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 |
|
||||
| |
|
||||
@@ -1646,9 +1461,7 @@ const corsair_v2_device* corsair_v2_device_list_data[] =
|
||||
| KEYBOARDS |
|
||||
\*-----------------------------------------------------------------*/
|
||||
&k55_rgb_pro_device,
|
||||
&k57_rgb_wired_device,
|
||||
&k60_rgb_pro_device,
|
||||
&k60_rgb_pro_se_device,
|
||||
&k60_rgb_pro_lp_device,
|
||||
&k60_rgb_pro_tkl_device_b,
|
||||
&k60_rgb_pro_tkl_device_w,
|
||||
@@ -1670,7 +1483,6 @@ 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,
|
||||
@@ -1678,7 +1490,6 @@ const corsair_v2_device* corsair_v2_device_list_data[] =
|
||||
&m65_rgb_ultra_wired_device,
|
||||
&m65_ultra_rgb_device,
|
||||
&m75_device,
|
||||
&m75_wireless_device,
|
||||
|
||||
/*-----------------------------------------------------------------*\
|
||||
| MOUSEMATS |
|
||||
|
||||
@@ -63,25 +63,13 @@ typedef struct
|
||||
uint8_t cols;
|
||||
const corsair_v2_zone* zones[CORSAIR_ZONES_MAX];
|
||||
keyboard_keymap_overlay_values* layout_new;
|
||||
/*-------------------------------------------------------*\
|
||||
| Number of LED slots the device expects in a direct |
|
||||
| lighting write. The keymap only covers the keys that |
|
||||
| exist, but the device wants its full slot count and |
|
||||
| ignores a short write, so the buffer map is padded up |
|
||||
| to this. Left 0 where the count is not known, which |
|
||||
| keeps the keymap derived size. |
|
||||
\*-------------------------------------------------------*/
|
||||
uint16_t hw_led_count;
|
||||
} corsair_v2_device;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Corsair V2 Protocol Keyboards |
|
||||
\*-----------------------------------------------------*/
|
||||
#define CORSAIR_K55_RGB_PRO_PID 0x1BA4
|
||||
#define CORSAIR_K57_RGB_WIRED_PID 0x1B6E
|
||||
#define CORSAIR_K57_RGB_WIRELESS_PID 0x1B62
|
||||
#define CORSAIR_K60_RGB_PRO_PID 0x1BA0
|
||||
#define CORSAIR_K60_RGB_PRO_SE_PID 0x1B8D
|
||||
#define CORSAIR_K60_RGB_PRO_LP_PID 0x1BAD
|
||||
#define CORSAIR_K60_RGB_PRO_TKL_B_PID 0x1BC7
|
||||
#define CORSAIR_K60_RGB_PRO_TKL_W_PID 0x1BED
|
||||
@@ -103,8 +91,6 @@ 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
|
||||
@@ -112,8 +98,6 @@ 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
|
||||
|
||||
@@ -16,12 +16,6 @@ CorsairPeripheralV2HWController::CorsairPeripheralV2HWController(hid_device* dev
|
||||
{
|
||||
SetRenderMode(CORSAIR_V2_MODE_SW);
|
||||
LightingControl(0x5F);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Only now that the device is in software render mode can |
|
||||
| its lighting control endpoint be probed reliably. |
|
||||
\*---------------------------------------------------------*/
|
||||
DetectLightingEndpoint();
|
||||
}
|
||||
|
||||
CorsairPeripheralV2HWController::~CorsairPeripheralV2HWController()
|
||||
|
||||
@@ -16,12 +16,6 @@ CorsairPeripheralV2SWController::CorsairPeripheralV2SWController(hid_device* dev
|
||||
{
|
||||
SetRenderMode(CORSAIR_V2_MODE_SW);
|
||||
LightingControl(0x5F);
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Only now that the device is in software render mode can |
|
||||
| its lighting control endpoint be probed reliably. |
|
||||
\*---------------------------------------------------------*/
|
||||
DetectLightingEndpoint();
|
||||
}
|
||||
|
||||
CorsairPeripheralV2SWController::~CorsairPeripheralV2SWController()
|
||||
|
||||
@@ -66,32 +66,21 @@ RGBController_CorsairV2HW::RGBController_CorsairV2HW(CorsairPeripheralV2Controll
|
||||
| to not revert back into rainbow mode. Start a thread |
|
||||
| to continuously send a keepalive packet every 50 sec |
|
||||
\*-----------------------------------------------------*/
|
||||
/*-----------------------------------------------------*\
|
||||
| Start the keepalive clock before the thread runs. |
|
||||
| A default constructed time_point sits at the clock |
|
||||
| epoch, which is always older than the update |
|
||||
| period, so the thread would otherwise fire a write |
|
||||
| on its first pass - during detection, racing |
|
||||
| whatever the caller is doing. |
|
||||
\*-----------------------------------------------------*/
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
|
||||
keepalive_thread_run = true;
|
||||
keepalive_thread = new std::thread(&RGBController_CorsairV2HW::KeepaliveThread, this);
|
||||
}
|
||||
|
||||
RGBController_CorsairV2HW::~RGBController_CorsairV2HW()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Close keepalive thread first, so that it cannot issue |
|
||||
| a write while the device is being shut down. |
|
||||
| Close keepalive thread |
|
||||
\*-----------------------------------------------------*/
|
||||
keepalive_thread_run = false;
|
||||
keepalive_thread->join();
|
||||
delete keepalive_thread;
|
||||
|
||||
Shutdown();
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
@@ -209,15 +198,6 @@ void RGBController_CorsairV2HW::SetupZones()
|
||||
|
||||
SetupColors();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Pad out to the slot count the device expects. A write |
|
||||
| that is short of it is ignored by the hardware. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(corsair->hw_led_count > max_led_value)
|
||||
{
|
||||
max_led_value = corsair->hw_led_count;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create a buffer map of pointers which contains the |
|
||||
| layout order of colors the device expects. |
|
||||
|
||||
@@ -53,32 +53,21 @@ RGBController_CorsairV2SW::RGBController_CorsairV2SW(CorsairPeripheralV2Controll
|
||||
| to not revert back into rainbow mode. Start a thread |
|
||||
| to continuously send a keepalive packet every 50 sec |
|
||||
\*-----------------------------------------------------*/
|
||||
/*-----------------------------------------------------*\
|
||||
| Start the keepalive clock before the thread runs. |
|
||||
| A default constructed time_point sits at the clock |
|
||||
| epoch, which is always older than the update |
|
||||
| period, so the thread would otherwise fire a write |
|
||||
| on its first pass - during detection, racing |
|
||||
| whatever the caller is doing. |
|
||||
\*-----------------------------------------------------*/
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
|
||||
keepalive_thread_run = true;
|
||||
keepalive_thread = new std::thread(&RGBController_CorsairV2SW::KeepaliveThread, this);
|
||||
}
|
||||
|
||||
RGBController_CorsairV2SW::~RGBController_CorsairV2SW()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Close keepalive thread first, so that it cannot issue |
|
||||
| a write while the device is being shut down. |
|
||||
| Close keepalive thread |
|
||||
\*-----------------------------------------------------*/
|
||||
keepalive_thread_run = false;
|
||||
keepalive_thread->join();
|
||||
delete keepalive_thread;
|
||||
|
||||
Shutdown();
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
@@ -196,15 +185,6 @@ void RGBController_CorsairV2SW::SetupZones()
|
||||
|
||||
SetupColors();
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Pad out to the slot count the device expects. A write |
|
||||
| that is short of it is ignored by the hardware. |
|
||||
\*---------------------------------------------------------*/
|
||||
if(corsair->hw_led_count > max_led_value)
|
||||
{
|
||||
max_led_value = corsair->hw_led_count;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Create a buffer map of pointers which contains the |
|
||||
| layout order of colors the device expects. |
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairWirelessController.cpp |
|
||||
| |
|
||||
| Driver for Corsair wireless keyboard |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 08 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <cstring>
|
||||
#include "CorsairWirelessController.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
CorsairWirelessController::CorsairWirelessController(hid_device* dev_handle, const char* path)
|
||||
{
|
||||
dev = dev_handle;
|
||||
location = path;
|
||||
|
||||
type = DEVICE_TYPE_KEYBOARD;
|
||||
|
||||
EnterDirectMode();
|
||||
}
|
||||
|
||||
CorsairWirelessController::~CorsairWirelessController()
|
||||
{
|
||||
hid_close(dev);
|
||||
}
|
||||
|
||||
device_type CorsairWirelessController::GetDeviceType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
std::string CorsairWirelessController::GetDeviceLocation()
|
||||
{
|
||||
return("HID: " + location);
|
||||
}
|
||||
|
||||
std::string CorsairWirelessController::GetFirmwareString()
|
||||
{
|
||||
return firmware_version;
|
||||
}
|
||||
|
||||
std::string CorsairWirelessController::GetName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
std::string CorsairWirelessController::GetSerialString()
|
||||
{
|
||||
wchar_t serial_string[128];
|
||||
int ret = hid_get_serial_number_string(dev, serial_string, 128);
|
||||
|
||||
if(ret != 0)
|
||||
{
|
||||
return("");
|
||||
}
|
||||
|
||||
return(StringUtils::wstring_to_string(serial_string));
|
||||
}
|
||||
|
||||
void CorsairWirelessController::SetLEDs(std::vector<RGBColor>colors)
|
||||
{
|
||||
unsigned char buf[3 * 137];
|
||||
|
||||
for(int color = 0; color < 137; color++)
|
||||
{
|
||||
buf[0 + color] = RGBGetRValue(colors[color]);
|
||||
buf[137 + color] = RGBGetGValue(colors[color]);
|
||||
buf[274+color] = RGBGetBValue(colors[color]);
|
||||
}
|
||||
|
||||
StartDirectMode();
|
||||
|
||||
SendDirectFrame(true, &buf[0]);
|
||||
SendDirectFrame(false, &buf[57]);
|
||||
SendDirectFrame(false, &buf[118]);
|
||||
SendDirectFrame(false, &buf[179]);
|
||||
SendDirectFrame(false, &buf[240]);
|
||||
SendDirectFrame(false, &buf[301]);
|
||||
SendDirectFrame(false, &buf[362]);
|
||||
}
|
||||
|
||||
void CorsairWirelessController::SetName(std::string device_name)
|
||||
{
|
||||
name = device_name;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------*\
|
||||
| Private packet sending functions. |
|
||||
\*-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
void CorsairWirelessController::EnterDirectMode()
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Submit Mouse Colors packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x80;
|
||||
usb_buf[0x02] = 0x01;
|
||||
usb_buf[0x03] = 0x03;
|
||||
usb_buf[0x04] = 0x00;
|
||||
usb_buf[0x05] = 0x02;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet using feature reports, as headset stand |
|
||||
| seems to not update completely using HID writes |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
|
||||
}
|
||||
|
||||
void CorsairWirelessController::StartDirectMode()
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Submit Mouse Colors packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x80;
|
||||
usb_buf[0x02] = 0x0D;
|
||||
usb_buf[0x03] = 0x00;
|
||||
usb_buf[0x04] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet using feature reports, as headset stand |
|
||||
| seems to not update completely using HID writes |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
|
||||
}
|
||||
|
||||
void CorsairWirelessController::ExitDirectMode()
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Submit Mouse Colors packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x80;
|
||||
usb_buf[0x02] = 0x01;
|
||||
usb_buf[0x03] = 0x03;
|
||||
usb_buf[0x04] = 0x00;
|
||||
usb_buf[0x05] = 0x01;
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet using feature reports, as headset stand |
|
||||
| seems to not update completely using HID writes |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
|
||||
}
|
||||
|
||||
void CorsairWirelessController::SendDirectFrame(bool first_frame, unsigned char* data)
|
||||
{
|
||||
unsigned char usb_buf[65];
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Zero out buffer |
|
||||
\*-----------------------------------------------------*/
|
||||
memset(usb_buf, 0x00, sizeof(usb_buf));
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Set up Submit Mouse Colors packet |
|
||||
\*-----------------------------------------------------*/
|
||||
usb_buf[0x00] = 0x00;
|
||||
usb_buf[0x01] = 0x80;
|
||||
usb_buf[0x02] = first_frame ? 0x06 : 0x07;
|
||||
usb_buf[0x03] = 0x00;
|
||||
|
||||
if(first_frame)
|
||||
{
|
||||
usb_buf[0x04] = 0x9B;
|
||||
usb_buf[0x05] = 0x01;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Copy in colors in <RED> <GREEN> <BLUE> order |
|
||||
\*-----------------------------------------------------*/
|
||||
if(first_frame)
|
||||
{
|
||||
memcpy(&usb_buf[0x08], data, 57);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&usb_buf[0x04], data, 61);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Send packet using feature reports, as headset stand |
|
||||
| seems to not update completely using HID writes |
|
||||
\*-----------------------------------------------------*/
|
||||
hid_write(dev, usb_buf, 65);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairWirelessController.h |
|
||||
| |
|
||||
| Driver for Corsair wireless keyboard |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 08 May 2021 |
|
||||
| |
|
||||
| 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"
|
||||
|
||||
class CorsairWirelessController
|
||||
{
|
||||
public:
|
||||
CorsairWirelessController(hid_device* dev_handle, const char* path);
|
||||
~CorsairWirelessController();
|
||||
|
||||
device_type GetDeviceType();
|
||||
std::string GetDeviceLocation();
|
||||
std::string GetFirmwareString();
|
||||
std::string GetName();
|
||||
std::string GetSerialString();
|
||||
|
||||
void SetLEDs(std::vector<RGBColor> colors);
|
||||
void SetName(std::string device_name);
|
||||
|
||||
private:
|
||||
hid_device* dev;
|
||||
|
||||
std::string firmware_version;
|
||||
std::string location;
|
||||
std::string name;
|
||||
device_type type;
|
||||
|
||||
void EnterDirectMode();
|
||||
void ExitDirectMode();
|
||||
void StartDirectMode();
|
||||
void SendDirectFrame(bool first_frame, unsigned char* data);
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CorsairWirelessControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Corsair wireless keyboard |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 08 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include <hidapi.h>
|
||||
#include "DetectionManager.h"
|
||||
#include "CorsairWirelessController.h"
|
||||
#include "RGBController.h"
|
||||
#include "RGBController_CorsairWireless.h"
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Corsair vendor ID |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CORSAIR_VID 0x1B1C
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keyboard product IDs |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CORSAIR_K57_RGB_WIRED_PID 0x1B6E
|
||||
#define CORSAIR_K57_RGB_WIRELESS_PID 0x1B62
|
||||
|
||||
DetectedControllers DetectCorsairWirelessControllers(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
|
||||
dev = hid_open_path(info->path);
|
||||
|
||||
if(dev)
|
||||
{
|
||||
CorsairWirelessController* controller = new CorsairWirelessController(dev, info->path);
|
||||
controller->SetName(name);
|
||||
|
||||
if(controller->GetDeviceType() != DEVICE_TYPE_UNKNOWN)
|
||||
{
|
||||
RGBController_CorsairWireless* rgb_controller = new RGBController_CorsairWireless(controller);
|
||||
detected_controllers.push_back(rgb_controller);
|
||||
}
|
||||
else
|
||||
{
|
||||
delete controller;
|
||||
}
|
||||
}
|
||||
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Keyboards |
|
||||
\*---------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_IPU("Corsair K57 RGB (Wired)", DetectCorsairWirelessControllers, CORSAIR_VID, CORSAIR_K57_RGB_WIRED_PID, 1, 0xFF42, 1);
|
||||
//REGISTER_HID_DETECTOR_IPU("Corsair K57 RGB (Wireless)", DetectCorsairWirelessControllers, CORSAIR_VID, CORSAIR_K57_RGB_WIRELESS_PID, 1, 0xFF42, 1);
|
||||
@@ -0,0 +1,319 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CorsairWireless.cpp |
|
||||
| |
|
||||
| RGBController for Corsair wireless keyboard |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 08 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#include "RGBControllerKeyNames.h"
|
||||
#include "RGBController_CorsairWireless.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
//0xFFFFFFFF indicates an unused entry in matrix
|
||||
#define NA 0xFFFFFFFF
|
||||
|
||||
static unsigned int matrix_map[7][24] =
|
||||
{ { NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 0, 1, NA, NA, NA },
|
||||
{ 131, 41, NA, 58, 59, 60, 61, NA, 62, 63, 64, 65, NA, 66, 67, 68, 69, 70, 71, 72, NA, NA, NA, NA },
|
||||
{ 132, 53, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, NA, 45, 46, 42, NA, 73, 74, 75, 83, 84, 85, 86 },
|
||||
{ 133, 43, NA, 20, 26, 8, 21, NA, 23, 28, 24, 12, 18, 19, 47, 48, 49, 76, 77, 78, 95, 96, 97, 87 },
|
||||
{ 134, 57, NA, 4, 22, 7, 9, NA, 10, 11, 13, 14, 15, 51, 52, NA, 40, NA, NA, NA, 92, 93, 94, NA },
|
||||
{ 135, 106, NA, 29, 27, 6, 25, NA, 5, NA, 17, 16, 54, 55, 56, 110, NA, NA, 82, NA, 89, 90, 91, 88 },
|
||||
{ 136, 105, 108, 107, NA, NA, NA, NA, 44, NA, NA, NA, NA, 111, 122, 101, 109, 80, 81, 79, 98, NA, 99, NA } };
|
||||
|
||||
static const char* zone_names[] =
|
||||
{
|
||||
ZONE_EN_KEYBOARD,
|
||||
};
|
||||
|
||||
static const unsigned int zone_sizes[] =
|
||||
{
|
||||
137
|
||||
};
|
||||
|
||||
static const zone_type zone_types[] =
|
||||
{
|
||||
ZONE_TYPE_MATRIX,
|
||||
};
|
||||
|
||||
static const char* led_names[] =
|
||||
{
|
||||
"Power/Wireless Indicator",
|
||||
"Lock/Macro Indicator",
|
||||
"N/A",
|
||||
"N/A",
|
||||
KEY_EN_A,
|
||||
KEY_EN_B,
|
||||
KEY_EN_C,
|
||||
KEY_EN_D,
|
||||
KEY_EN_E,
|
||||
KEY_EN_F,
|
||||
KEY_EN_G,
|
||||
KEY_EN_H,
|
||||
KEY_EN_I,
|
||||
KEY_EN_J,
|
||||
KEY_EN_K,
|
||||
KEY_EN_L,
|
||||
KEY_EN_M,
|
||||
KEY_EN_N,
|
||||
KEY_EN_O,
|
||||
KEY_EN_P,
|
||||
KEY_EN_Q,
|
||||
KEY_EN_R,
|
||||
KEY_EN_S,
|
||||
KEY_EN_T,
|
||||
KEY_EN_U,
|
||||
KEY_EN_V,
|
||||
KEY_EN_W,
|
||||
KEY_EN_X,
|
||||
KEY_EN_Y,
|
||||
KEY_EN_Z,
|
||||
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_ANSI_ENTER,
|
||||
KEY_EN_ESCAPE,
|
||||
KEY_EN_BACKSPACE,
|
||||
KEY_EN_TAB,
|
||||
KEY_EN_SPACE,
|
||||
KEY_EN_MINUS,
|
||||
KEY_EN_EQUALS,
|
||||
KEY_EN_LEFT_BRACKET,
|
||||
KEY_EN_RIGHT_BRACKET,
|
||||
KEY_EN_ANSI_BACK_SLASH,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_SEMICOLON,
|
||||
KEY_EN_QUOTE,
|
||||
KEY_EN_BACK_TICK,
|
||||
KEY_EN_COMMA,
|
||||
KEY_EN_PERIOD,
|
||||
KEY_EN_FORWARD_SLASH,
|
||||
KEY_EN_CAPS_LOCK,
|
||||
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_INSERT,
|
||||
KEY_EN_HOME,
|
||||
KEY_EN_PAGE_UP,
|
||||
KEY_EN_DELETE,
|
||||
KEY_EN_END,
|
||||
KEY_EN_PAGE_DOWN,
|
||||
KEY_EN_RIGHT_ARROW,
|
||||
KEY_EN_LEFT_ARROW,
|
||||
KEY_EN_DOWN_ARROW,
|
||||
KEY_EN_UP_ARROW,
|
||||
KEY_EN_NUMPAD_LOCK,
|
||||
KEY_EN_NUMPAD_DIVIDE,
|
||||
KEY_EN_NUMPAD_TIMES,
|
||||
KEY_EN_NUMPAD_MINUS,
|
||||
KEY_EN_NUMPAD_PLUS,
|
||||
KEY_EN_NUMPAD_ENTER,
|
||||
KEY_EN_NUMPAD_1,
|
||||
KEY_EN_NUMPAD_2,
|
||||
KEY_EN_NUMPAD_3,
|
||||
KEY_EN_NUMPAD_4,
|
||||
KEY_EN_NUMPAD_5,
|
||||
KEY_EN_NUMPAD_6,
|
||||
KEY_EN_NUMPAD_7,
|
||||
KEY_EN_NUMPAD_8,
|
||||
KEY_EN_NUMPAD_9,
|
||||
KEY_EN_NUMPAD_0,
|
||||
KEY_EN_NUMPAD_PERIOD,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_MENU,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_LEFT_CONTROL,
|
||||
KEY_EN_LEFT_SHIFT,
|
||||
KEY_EN_LEFT_ALT,
|
||||
KEY_EN_LEFT_WINDOWS,
|
||||
KEY_EN_RIGHT_CONTROL,
|
||||
KEY_EN_RIGHT_SHIFT,
|
||||
KEY_EN_RIGHT_ALT,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_RIGHT_FUNCTION,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
KEY_EN_UNUSED,
|
||||
"Key: G1",
|
||||
"Key: G2",
|
||||
"Key: G3",
|
||||
"Key: G4",
|
||||
"Key: G5",
|
||||
"Key: G6",
|
||||
};
|
||||
|
||||
/**------------------------------------------------------------------*\
|
||||
@name Corsair Wireless Peripheral
|
||||
@category Keyboard
|
||||
@type USB
|
||||
@save :x:
|
||||
@direct :white_check_mark:
|
||||
@effects :x:
|
||||
@detectors DetectCorsairWirelessControllers
|
||||
@comment
|
||||
\*-------------------------------------------------------------------*/
|
||||
|
||||
RGBController_CorsairWireless::RGBController_CorsairWireless(CorsairWirelessController* controller_ptr)
|
||||
{
|
||||
controller = controller_ptr;
|
||||
|
||||
name = controller->GetName();
|
||||
vendor = "Corsair";
|
||||
description = "Corsair RGB Peripheral Device";
|
||||
type = controller->GetDeviceType();
|
||||
version = controller->GetFirmwareString();
|
||||
location = controller->GetDeviceLocation();
|
||||
serial = controller->GetSerialString();
|
||||
|
||||
mode Direct;
|
||||
Direct.name = "Direct";
|
||||
Direct.value = 0;
|
||||
Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR;
|
||||
Direct.color_mode = MODE_COLORS_PER_LED;
|
||||
modes.push_back(Direct);
|
||||
|
||||
SetupZones();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| The Corsair Lighting Node Pro requires a packet within|
|
||||
| 20 seconds of sending the lighting change in order |
|
||||
| to not revert back into rainbow mode. Start a thread |
|
||||
| to continuously send a keepalive packet every 5s |
|
||||
\*-----------------------------------------------------*/
|
||||
keepalive_thread_run = true;
|
||||
keepalive_thread = new std::thread(&RGBController_CorsairWireless::KeepaliveThread, this);
|
||||
}
|
||||
|
||||
RGBController_CorsairWireless::~RGBController_CorsairWireless()
|
||||
{
|
||||
Shutdown();
|
||||
|
||||
/*-----------------------------------------------------*\
|
||||
| Close keepalive thread |
|
||||
\*-----------------------------------------------------*/
|
||||
keepalive_thread_run = false;
|
||||
keepalive_thread->join();
|
||||
delete keepalive_thread;
|
||||
|
||||
delete controller;
|
||||
}
|
||||
|
||||
void RGBController_CorsairWireless::SetupZones()
|
||||
{
|
||||
/*---------------------------------------------------------*\
|
||||
| Determine number of zones |
|
||||
| For now, keyboard has 2 zones and mousemat has 1 |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int num_zones = 1;
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Set up zones |
|
||||
\*---------------------------------------------------------*/
|
||||
unsigned int total_led_count = 0;
|
||||
for(unsigned int zone_idx = 0; zone_idx < num_zones; zone_idx++)
|
||||
{
|
||||
zone new_zone;
|
||||
|
||||
new_zone.name = zone_names[zone_idx];
|
||||
new_zone.type = zone_types[zone_idx];
|
||||
new_zone.leds_min = zone_sizes[zone_idx];
|
||||
new_zone.leds_max = zone_sizes[zone_idx];
|
||||
new_zone.leds_count = zone_sizes[zone_idx];
|
||||
|
||||
if(zone_types[zone_idx] == ZONE_TYPE_MATRIX)
|
||||
{
|
||||
new_zone.matrix_map.Set(7, 24, (unsigned int *)&matrix_map);
|
||||
}
|
||||
|
||||
zones.push_back(new_zone);
|
||||
total_led_count += new_zone.leds_count;
|
||||
}
|
||||
|
||||
for(unsigned int led_idx = 0; led_idx < total_led_count; led_idx++)
|
||||
{
|
||||
led new_led;
|
||||
|
||||
new_led.name = led_names[led_idx];
|
||||
|
||||
leds.push_back(new_led);
|
||||
}
|
||||
|
||||
SetupColors();
|
||||
}
|
||||
|
||||
void RGBController_CorsairWireless::DeviceUpdateLEDs()
|
||||
{
|
||||
last_update_time = std::chrono::steady_clock::now();
|
||||
|
||||
controller->SetLEDs(colors);
|
||||
}
|
||||
|
||||
void RGBController_CorsairWireless::DeviceUpdateZoneLEDs(int /*zone*/)
|
||||
{
|
||||
controller->SetLEDs(colors);
|
||||
}
|
||||
|
||||
void RGBController_CorsairWireless::DeviceUpdateSingleLED(int /*led*/)
|
||||
{
|
||||
controller->SetLEDs(colors);
|
||||
}
|
||||
|
||||
void RGBController_CorsairWireless::DeviceUpdateMode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RGBController_CorsairWireless::KeepaliveThread()
|
||||
{
|
||||
while(keepalive_thread_run.load())
|
||||
{
|
||||
if(active_mode == 0)
|
||||
{
|
||||
if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(5000))
|
||||
{
|
||||
DeviceUpdateLEDs();
|
||||
}
|
||||
}
|
||||
std::this_thread::sleep_for(1000ms);
|
||||
}
|
||||
}
|
||||
+41
-37
@@ -1,37 +1,41 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_HyperXEve1800.h |
|
||||
| |
|
||||
| RGBController for HyperX Eve 1800 keyboard |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include "RGBController.h"
|
||||
#include "HyperXEve1800Controller.h"
|
||||
|
||||
class RGBController_HyperXEve1800 : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_HyperXEve1800(HyperXEve1800Controller* controller_ptr);
|
||||
~RGBController_HyperXEve1800();
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
void KeepaliveThread();
|
||||
|
||||
private:
|
||||
HyperXEve1800Controller* controller;
|
||||
std::thread* keepalive_thread;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
|
||||
};
|
||||
/*---------------------------------------------------------*\
|
||||
| RGBController_CorsairWireless.h |
|
||||
| |
|
||||
| RGBController for Corsair wireless keyboard |
|
||||
| |
|
||||
| Adam Honse (CalcProgrammer1) 08 May 2021 |
|
||||
| |
|
||||
| This file is part of the OpenRGB project |
|
||||
| SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
\*---------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RGBController.h"
|
||||
#include "CorsairWirelessController.h"
|
||||
|
||||
class RGBController_CorsairWireless : public RGBController
|
||||
{
|
||||
public:
|
||||
RGBController_CorsairWireless(CorsairWirelessController* controller_ptr);
|
||||
~RGBController_CorsairWireless();
|
||||
|
||||
int physical_layout;
|
||||
int logical_layout;
|
||||
|
||||
void SetupZones();
|
||||
|
||||
void DeviceUpdateLEDs();
|
||||
void DeviceUpdateZoneLEDs(int zone);
|
||||
void DeviceUpdateSingleLED(int led);
|
||||
|
||||
void DeviceUpdateMode();
|
||||
|
||||
void KeepaliveThread();
|
||||
|
||||
private:
|
||||
CorsairWirelessController* controller;
|
||||
std::thread* keepalive_thread;
|
||||
std::atomic<bool> keepalive_thread_run;
|
||||
std::chrono::time_point<std::chrono::steady_clock> last_update_time;
|
||||
};
|
||||
+10
-10
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------*\
|
||||
| CreativeSoundBlasterXG6ControllerDetect.cpp |
|
||||
| CreativeControllerDetect.cpp |
|
||||
| |
|
||||
| Detector for Creative Sound Blaster XG6 devices |
|
||||
| Detector for Creative 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
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Creative Sound Blaster XG6 product ID |
|
||||
| SoundCards |
|
||||
\*---------------------------------------------------------*/
|
||||
#define CREATIVE_SOUNDBLASTERX_G6_PID 0x3256
|
||||
#define CREATIVE_SOUNDBLASTERX_G6_PID 0x3256
|
||||
|
||||
DetectedControllers DetectCreativeSoundBlasterXG6Device(hid_device_info* info, const std::string& name)
|
||||
DetectedControllers DetectCreativeDevice(hid_device_info* info, const std::string& name)
|
||||
{
|
||||
DetectedControllers detected_controllers;
|
||||
hid_device* dev;
|
||||
@@ -40,7 +40,7 @@ DetectedControllers DetectCreativeSoundBlasterXG6Device(hid_device_info* info, c
|
||||
return(detected_controllers);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------*\
|
||||
| Sound Cards |
|
||||
\*---------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_I("Creative SoundBlasterX G6", DetectCreativeSoundBlasterXG6Device, CREATIVE_VID, CREATIVE_SOUNDBLASTERX_G6_PID, 4);
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------*\
|
||||
| Sound Cards |
|
||||
\*-------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
REGISTER_HID_DETECTOR_I("Creative SoundBlasterX G6", DetectCreativeDevice, CREATIVE_VID, CREATIVE_SOUNDBLASTERX_G6_PID, 4);
|
||||
+3
@@ -16,10 +16,13 @@ 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);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user