Initial Commit
This commit is contained in:
13 files changed
+1267
No files matched your search
+133
@@ -0,0 +1,133 @@
|
|||||||
|
pkg/
|
||||||
|
*.tar
|
||||||
|
|
||||||
|
### VisualStudioCode template
|
||||||
|
.vscode/*
|
||||||
|
#!.vscode/settings.json
|
||||||
|
#!.vscode/tasks.json
|
||||||
|
#!.vscode/launch.json
|
||||||
|
#!.vscode/extensions.json
|
||||||
|
#!.vscode/*.code-snippets
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Built Visual Studio Code Extensions
|
||||||
|
*.vsix
|
||||||
|
|
||||||
|
### Rust template
|
||||||
|
# Generated by Cargo
|
||||||
|
# will have compiled files and executables
|
||||||
|
debug/
|
||||||
|
target/
|
||||||
|
|
||||||
|
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||||
|
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||||
|
Cargo.lock
|
||||||
|
|
||||||
|
# These are backup files generated by rustfmt
|
||||||
|
**/*.rs.bk
|
||||||
|
|
||||||
|
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||||
|
*.pdb
|
||||||
|
|
||||||
|
# RustRover
|
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||||
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||||
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
|
.idea/
|
||||||
|
### JetBrains template
|
||||||
|
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||||
|
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||||
|
|
||||||
|
# User-specific stuff
|
||||||
|
.idea/**/workspace.xml
|
||||||
|
.idea/**/tasks.xml
|
||||||
|
.idea/**/usage.statistics.xml
|
||||||
|
.idea/**/dictionaries
|
||||||
|
.idea/**/shelf
|
||||||
|
|
||||||
|
# AWS User-specific
|
||||||
|
.idea/**/aws.xml
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
.idea/**/contentModel.xml
|
||||||
|
|
||||||
|
# Sensitive or high-churn files
|
||||||
|
.idea/**/dataSources/
|
||||||
|
.idea/**/dataSources.ids
|
||||||
|
.idea/**/dataSources.local.xml
|
||||||
|
.idea/**/sqlDataSources.xml
|
||||||
|
.idea/**/dynamic.xml
|
||||||
|
.idea/**/uiDesigner.xml
|
||||||
|
.idea/**/dbnavigator.xml
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.idea/**/gradle.xml
|
||||||
|
.idea/**/libraries
|
||||||
|
|
||||||
|
# Gradle and Maven with auto-import
|
||||||
|
# When using Gradle or Maven with auto-import, you should exclude module files,
|
||||||
|
# since they will be recreated, and may cause churn. Uncomment if using
|
||||||
|
# auto-import.
|
||||||
|
# .idea/artifacts
|
||||||
|
# .idea/compiler.xml
|
||||||
|
# .idea/jarRepositories.xml
|
||||||
|
# .idea/modules.xml
|
||||||
|
# .idea/*.iml
|
||||||
|
# .idea/modules
|
||||||
|
# *.iml
|
||||||
|
# *.ipr
|
||||||
|
|
||||||
|
# CMake
|
||||||
|
cmake-build-*/
|
||||||
|
|
||||||
|
# Mongo Explorer plugin
|
||||||
|
.idea/**/mongoSettings.xml
|
||||||
|
|
||||||
|
# File-based project format
|
||||||
|
*.iws
|
||||||
|
|
||||||
|
# IntelliJ
|
||||||
|
out/
|
||||||
|
|
||||||
|
# mpeltonen/sbt-idea plugin
|
||||||
|
.idea_modules/
|
||||||
|
|
||||||
|
# JIRA plugin
|
||||||
|
atlassian-ide-plugin.xml
|
||||||
|
|
||||||
|
# Cursive Clojure plugin
|
||||||
|
.idea/replstate.xml
|
||||||
|
|
||||||
|
# SonarLint plugin
|
||||||
|
.idea/sonarlint/
|
||||||
|
|
||||||
|
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||||
|
com_crashlytics_export_strings.xml
|
||||||
|
crashlytics.properties
|
||||||
|
crashlytics-build.properties
|
||||||
|
fabric.properties
|
||||||
|
|
||||||
|
# Editor-based Rest Client
|
||||||
|
.idea/httpRequests
|
||||||
|
|
||||||
|
# Android studio 3.1+ serialized cache file
|
||||||
|
.idea/caches/build_file_checksums.ser
|
||||||
|
|
||||||
|
### Linux template
|
||||||
|
*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed
|
||||||
|
.nfs*
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "gk1000_controller"
|
||||||
|
version = "1.0.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
hidapi = "2.6.5"
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||||
|
distribute this software, either in source code form or as a compiled
|
||||||
|
binary, for any purpose, commercial or non-commercial, and by any
|
||||||
|
means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors
|
||||||
|
of this software dedicate any and all copyright interest in the
|
||||||
|
software to the public domain. We make this dedication for the benefit
|
||||||
|
of the public at large and to the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of
|
||||||
|
relinquishment in perpetuity of all present and future rights to this
|
||||||
|
software under copyright law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||||
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
For more information, please refer to <http://unlicense.org>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
extern crate hidapi;
|
||||||
|
mod constants;
|
||||||
|
pub mod error;
|
||||||
|
pub mod wrapper;
|
||||||
|
|
||||||
|
pub use error::HidWrapperError;
|
||||||
|
pub use wrapper::HidWrapper;
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
pub const VENDOR_ID: u16 = 0x0c45;
|
||||||
|
pub const PRODUCT_ID: u16 = 0x8006;
|
||||||
|
pub const MAX_SEND_REPORT_LEN: usize = 65;
|
||||||
|
pub const GET_REPORT_REPORT: [u8; MAX_SEND_REPORT_LEN] = [0u8; MAX_SEND_REPORT_LEN];
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
use hidapi::HidError;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum HidWrapperError {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
HidApiError(HidError),
|
||||||
|
NoHidDeviceError,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for HidWrapperError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
HidWrapperError::HidApiError(err) => {
|
||||||
|
write!(f, "Hid Api Error: {err}")
|
||||||
|
}
|
||||||
|
HidWrapperError::NoHidDeviceError => {
|
||||||
|
write!(f, "No Hid Device Found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for HidWrapperError {}
|
||||||
|
|
||||||
|
impl From<HidError> for HidWrapperError {
|
||||||
|
fn from(error: HidError) -> Self {
|
||||||
|
match error {
|
||||||
|
HidError::HidApiError { ref message } => {
|
||||||
|
if message == "No HID devices with requested VID/PID found in the system." {
|
||||||
|
HidWrapperError::NoHidDeviceError
|
||||||
|
} else {
|
||||||
|
HidWrapperError::HidApiError(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => HidWrapperError::HidApiError(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
use crate::hid_wrapper::constants::{
|
||||||
|
GET_REPORT_REPORT, MAX_SEND_REPORT_LEN, PRODUCT_ID, VENDOR_ID,
|
||||||
|
};
|
||||||
|
use crate::hid_wrapper::error::HidWrapperError;
|
||||||
|
use hidapi::{HidApi, HidDevice};
|
||||||
|
|
||||||
|
pub struct HidWrapper {
|
||||||
|
hid_api: HidApi,
|
||||||
|
hid_device: Option<HidDevice>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for HidWrapper {
|
||||||
|
/// Makes a new instance of HidWrapper (No shit Sherlock)
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
/// If ```HidWrapperError::HidApiError``` is returned from new()
|
||||||
|
fn default() -> Self {
|
||||||
|
match Self::new() {
|
||||||
|
Ok(hid_wrapper) => hid_wrapper,
|
||||||
|
Err(err) => panic!("hid wrapper Default() failed to create new HidWrapper: {err}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HidWrapper {
|
||||||
|
/// Makes a new instance of HidWrapper (No shit Sherlock)
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// ```HidWrapperError::HidApiError```
|
||||||
|
pub fn new() -> Result<HidWrapper, HidWrapperError> {
|
||||||
|
Ok(HidWrapper {
|
||||||
|
hid_api: match HidApi::new() {
|
||||||
|
Ok(hidapi) => hidapi,
|
||||||
|
Err(err) => return Err(HidWrapperError::from(err)),
|
||||||
|
},
|
||||||
|
hid_device: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_device_connected(&mut self) -> Result<bool, HidWrapperError> {
|
||||||
|
match self.hid_api.reset_devices() {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(err) => return Err(HidWrapperError::from(err)),
|
||||||
|
};
|
||||||
|
match self.hid_api.add_devices(VENDOR_ID, PRODUCT_ID) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(err) => return Err(HidWrapperError::from(err)),
|
||||||
|
};
|
||||||
|
Ok(self.hid_api.device_list().count() >= 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Opens a device
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// ```HidWrapperError::HidApiError```
|
||||||
|
/// ```HidWrapperError::NoHidDeviceError```
|
||||||
|
pub fn open_device(&mut self) -> Result<(), HidWrapperError> {
|
||||||
|
self.hid_device = match self.hid_api.open(VENDOR_ID, PRODUCT_ID) {
|
||||||
|
Ok(hid_device) => Some(hid_device),
|
||||||
|
Err(err) => return Err(HidWrapperError::from(err)),
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Drops the device
|
||||||
|
///
|
||||||
|
pub fn close_device(&mut self) {
|
||||||
|
self.hid_device = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sends a set report (65 bytes len)
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// ```HidWrapperError::HidApiError```
|
||||||
|
/// ```HidWrapperError::NoHidDeviceError```
|
||||||
|
pub fn send_report(&mut self, data: &[u8]) -> Result<(), HidWrapperError> {
|
||||||
|
match &self.hid_device {
|
||||||
|
Some(hid_device) => {
|
||||||
|
let mut out = [0; MAX_SEND_REPORT_LEN];
|
||||||
|
out[1..1 + data.len()].copy_from_slice(data);
|
||||||
|
match hid_device.send_feature_report(&out) {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(err) => Err(HidWrapperError::from(err)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => Err(HidWrapperError::NoHidDeviceError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sends a get report (64 bytes len)
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// ```HidWrapperError::HidApiError```
|
||||||
|
/// ```HidWrapperError::NoHidDeviceError```
|
||||||
|
pub fn get_report(&mut self) -> Result<usize, HidWrapperError> {
|
||||||
|
match &self.hid_device {
|
||||||
|
Some(hid_device) => {
|
||||||
|
let mut request = GET_REPORT_REPORT;
|
||||||
|
request[1] = 64;
|
||||||
|
match hid_device.get_feature_report(&mut request) {
|
||||||
|
Ok(usize) => Ok(usize),
|
||||||
|
Err(err) => Err(HidWrapperError::from(err)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => Err(HidWrapperError::NoHidDeviceError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
mod hid_wrapper;
|
||||||
|
mod rgb_controller;
|
||||||
|
|
||||||
|
pub use hid_wrapper::HidWrapperError;
|
||||||
|
pub use rgb_controller::controller::RGBController;
|
||||||
|
pub use rgb_controller::effects::Effects;
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
pub mod controller;
|
||||||
|
pub mod effect_info;
|
||||||
|
pub mod effects;
|
||||||
@@ -0,0 +1,695 @@
|
|||||||
|
use crate::Effects;
|
||||||
|
use crate::HidWrapperError;
|
||||||
|
use crate::hid_wrapper::HidWrapper;
|
||||||
|
|
||||||
|
pub struct RGBController {
|
||||||
|
hid_wrapper: HidWrapper,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for RGBController {
|
||||||
|
/// Makes a new instance of HidWrapper (No shit Sherlock)
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
/// if ```HidWrapperError::HidApiError``` is returned from new()
|
||||||
|
fn default() -> Self {
|
||||||
|
match Self::new() {
|
||||||
|
Ok(hid_wrapper) => hid_wrapper,
|
||||||
|
Err(err) => panic!("RGBController Default() failed to create new RGBController: {err}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RGBController {
|
||||||
|
/// Makes a new instance of HidWrapper (No shit Sherlock)
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// ```HidWrapperError::HidApiError```
|
||||||
|
pub fn new() -> Result<RGBController, HidWrapperError> {
|
||||||
|
Ok(RGBController {
|
||||||
|
hid_wrapper: HidWrapper::new()?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_device_connected(&mut self) -> Result<bool, HidWrapperError> {
|
||||||
|
self.hid_wrapper.is_device_connected()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Starts the RGB conversation
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// ```HidWrapperError::HidApiError```
|
||||||
|
/// ```HidWrapperError::NoHidDeviceError```
|
||||||
|
fn prepare_device(&mut self) -> Result<(), HidWrapperError> {
|
||||||
|
self.hid_wrapper.send_report(&[0x04, 0xab])?;
|
||||||
|
self.hid_wrapper.get_report()?;
|
||||||
|
|
||||||
|
self.hid_wrapper.send_report(&[
|
||||||
|
0x26, 0x36, 0xf2, 0x27, 0xb7, 0x2a, 0x56, 0x77, 0x98, 0x59, 0x9c, 0x6d, 0x9f, 0xc6,
|
||||||
|
0xb, 0x44, 0xec, 0xa8, 0x47, 0x21, 0xe2, 0x65, 0x76, 0xa3, 0x70, 0xbe, 0xa2, 0xbb,
|
||||||
|
0x95, 0x47, 0x5e, 0xbe, 0x23, 0x1b, 0xad, 0xb8, 0xc3, 0xcd, 0x1f, 0x4, 0x39, 0xa2,
|
||||||
|
0x3d, 0x19, 0xe9, 0xfd, 0x27, 0xa7, 0x9a, 0x1a, 0x7c, 0xe3, 0x7b, 0xff, 0x7a, 0x1e,
|
||||||
|
0x63, 0xb0, 0x67, 0x9d, 0x5d, 0xa3, 0x2f, 0xa5,
|
||||||
|
])?;
|
||||||
|
|
||||||
|
self.hid_wrapper.send_report(&[0x04, 0x02])?;
|
||||||
|
self.hid_wrapper.get_report()?;
|
||||||
|
|
||||||
|
self.hid_wrapper
|
||||||
|
.send_report(&[0x04, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12])?;
|
||||||
|
self.hid_wrapper.get_report()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Some middle bytes IDK what to name ts
|
||||||
|
/// Is a required part of the RGB conversation
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// ```HidWrapperError::HidApiError```
|
||||||
|
/// ```HidWrapperError::NoHidDeviceError```
|
||||||
|
fn mid(&mut self) -> Result<(), HidWrapperError> {
|
||||||
|
//TODO: Rename func and possibly change packets depending on mode
|
||||||
|
self.hid_wrapper.send_report(&[
|
||||||
|
0x1, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0x2, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0x3, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0x4, 0x5a, 0xff, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
])?;
|
||||||
|
|
||||||
|
self.hid_wrapper.send_report(&[
|
||||||
|
0x5, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0x6, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0x7, 0x5a, 0xff, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0x8, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
])?;
|
||||||
|
|
||||||
|
self.hid_wrapper.send_report(&[
|
||||||
|
0x9, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0xa, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0xb, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0xc, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
])?;
|
||||||
|
|
||||||
|
self.hid_wrapper.send_report(&[
|
||||||
|
0xd, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0xe, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0xf, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0x10, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
])?;
|
||||||
|
|
||||||
|
self.hid_wrapper.send_report(&[
|
||||||
|
0x11, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0x12, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0x13, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x1, 0x10, 0xc, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
0x80, 0xff, 0xff, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0xaa, 0x55,
|
||||||
|
])?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets colors for each key (only if StaticPerKey effect is set) base on a 2d array
|
||||||
|
/// Is a required part of the RGB conversation
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// ```HidWrapperError::HidApiError```
|
||||||
|
/// ```HidWrapperError::NoHidDeviceError```
|
||||||
|
fn custom_keys(&mut self, keymap: &[[u8; 3]; 144]) -> Result<(), HidWrapperError> {
|
||||||
|
for i in 0..9 {
|
||||||
|
//Magic num 9 == len of keymap / 16
|
||||||
|
self.hid_wrapper.send_report(&[
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16][0],
|
||||||
|
keymap[i * 16][1],
|
||||||
|
keymap[i * 16][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 1][0],
|
||||||
|
keymap[i * 16 + 1][1],
|
||||||
|
keymap[i * 16 + 1][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 2][0],
|
||||||
|
keymap[i * 16 + 2][1],
|
||||||
|
keymap[i * 16 + 2][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 3][0],
|
||||||
|
keymap[i * 16 + 3][1],
|
||||||
|
keymap[i * 16 + 3][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 4][0],
|
||||||
|
keymap[i * 16 + 4][1],
|
||||||
|
keymap[i * 16 + 4][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 5][0],
|
||||||
|
keymap[i * 16 + 5][1],
|
||||||
|
keymap[i * 16 + 5][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 6][0],
|
||||||
|
keymap[i * 16 + 6][1],
|
||||||
|
keymap[i * 16 + 6][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 7][0],
|
||||||
|
keymap[i * 16 + 7][1],
|
||||||
|
keymap[i * 16 + 7][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 8][0],
|
||||||
|
keymap[i * 16 + 8][1],
|
||||||
|
keymap[i * 16 + 8][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 9][0],
|
||||||
|
keymap[i * 16 + 9][1],
|
||||||
|
keymap[i * 16 + 9][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 10][0],
|
||||||
|
keymap[i * 16 + 10][1],
|
||||||
|
keymap[i * 16 + 10][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 11][0],
|
||||||
|
keymap[i * 16 + 11][1],
|
||||||
|
keymap[i * 16 + 11][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 12][0],
|
||||||
|
keymap[i * 16 + 12][1],
|
||||||
|
keymap[i * 16 + 12][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 13][0],
|
||||||
|
keymap[i * 16 + 13][1],
|
||||||
|
keymap[i * 16 + 13][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 14][0],
|
||||||
|
keymap[i * 16 + 14][1],
|
||||||
|
keymap[i * 16 + 14][2],
|
||||||
|
0x80,
|
||||||
|
keymap[i * 16 + 15][0],
|
||||||
|
keymap[i * 16 + 15][1],
|
||||||
|
keymap[i * 16 + 15][2],
|
||||||
|
])?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Applies an effect to the device
|
||||||
|
/// Is a required part of the RGB conversation
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// ```HidWrapperError::HidApiError```
|
||||||
|
/// ```HidWrapperError::NoHidDeviceError```
|
||||||
|
fn apply_to_device(&mut self) -> Result<(), HidWrapperError> {
|
||||||
|
self.hid_wrapper.send_report(&[0x04, 0x02])?;
|
||||||
|
self.hid_wrapper.get_report()?;
|
||||||
|
|
||||||
|
self.hid_wrapper.send_report(&[0x04, 0xf0])?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets an effect
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// ```HidWrapperError::HidApiError```
|
||||||
|
/// ```HidWrapperError::NoHidDeviceError```
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub fn set_effect(
|
||||||
|
&mut self,
|
||||||
|
effect: Effects,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
full_color: bool,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
direction: u8,
|
||||||
|
keymap: Option<[[u8; 3]; 144]>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.hid_wrapper.open_device()?;
|
||||||
|
|
||||||
|
self.prepare_device()?;
|
||||||
|
|
||||||
|
self.mid()?;
|
||||||
|
|
||||||
|
self.hid_wrapper.send_report(&[])?;
|
||||||
|
self.hid_wrapper.send_report(&[])?;
|
||||||
|
self.hid_wrapper.send_report(&[])?;
|
||||||
|
|
||||||
|
match keymap {
|
||||||
|
Some(map) => self.custom_keys(&map)?,
|
||||||
|
None => self.custom_keys(&[[0, 255, 0]; 144])?,
|
||||||
|
}
|
||||||
|
|
||||||
|
self.hid_wrapper.send_report(&[
|
||||||
|
effect.to_u8(),
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
u8::from(full_color),
|
||||||
|
brightness.clamp(0, 16),
|
||||||
|
speed.clamp(1, 16),
|
||||||
|
direction.clamp(0, 3),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0xaa,
|
||||||
|
0x55,
|
||||||
|
])?;
|
||||||
|
|
||||||
|
self.apply_to_device()?;
|
||||||
|
|
||||||
|
self.hid_wrapper.close_device();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
pub fn set_static_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::Static,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_single_off_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::SingleOff,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_single_on_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::SingleOn,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_glittering_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::Glittering,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_rain_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::Rain,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_colorful_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::Colorful,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_breath_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::Breath,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_spectrum_effect(
|
||||||
|
&mut self,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::Spectrum,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_centrifugal_wave_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::CentrifugalWave,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub fn set_vertical_wave_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
direction: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::VerticalWave,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
direction.clamp(2, 3),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub fn set_horizontal_wave_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
direction: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::HorizontalWave,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
direction.clamp(0, 1),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_rotating_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::Rotating,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_explosion_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::Explosion,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_launch_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::Launch,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_ripples_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::Ripples,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_snake_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::Snake,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_pulse_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::Pulse,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_tilt_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::Tilt,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_shuttle_effect(
|
||||||
|
&mut self,
|
||||||
|
red: u8,
|
||||||
|
green: u8,
|
||||||
|
blue: u8,
|
||||||
|
brightness: u8,
|
||||||
|
speed: u8,
|
||||||
|
full_color: Option<bool>,
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::Shuttle,
|
||||||
|
red,
|
||||||
|
green,
|
||||||
|
blue,
|
||||||
|
full_color.unwrap_or(false),
|
||||||
|
brightness,
|
||||||
|
speed,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_static_per_key_effect(
|
||||||
|
&mut self,
|
||||||
|
brightness: u8,
|
||||||
|
keymap: [[u8; 3]; 144],
|
||||||
|
) -> Result<(), HidWrapperError> {
|
||||||
|
self.set_effect(
|
||||||
|
Effects::StaticPerKey,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
false,
|
||||||
|
brightness,
|
||||||
|
1,
|
||||||
|
0,
|
||||||
|
Some(keymap),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
use crate::Effects;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub struct EffectInfo<'a> {
|
||||||
|
name: &'a str,
|
||||||
|
effect: Effects,
|
||||||
|
can_set_color: bool,
|
||||||
|
can_set_speed: bool,
|
||||||
|
can_set_direction: DirectionPolicy,
|
||||||
|
can_set_full_color: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub enum DirectionPolicy {
|
||||||
|
None,
|
||||||
|
Horizontal01,
|
||||||
|
Vertical23,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub const EFFECTS: [EffectInfo; 20] = [
|
||||||
|
EffectInfo {
|
||||||
|
name: "Static",
|
||||||
|
effect: Effects::Static,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: false,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "SingleOn",
|
||||||
|
effect: Effects::SingleOn,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "SingleOff",
|
||||||
|
effect: Effects::SingleOff,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "Glittering",
|
||||||
|
effect: Effects::Glittering,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "Rain",
|
||||||
|
effect: Effects::Rain,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "Colorful",
|
||||||
|
effect: Effects::Colorful,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "Breath",
|
||||||
|
effect: Effects::Breath,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "Spectrum",
|
||||||
|
effect: Effects::Spectrum,
|
||||||
|
can_set_color: false,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: false,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "CentrifugalWave",
|
||||||
|
effect: Effects::CentrifugalWave,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "VerticalWave",
|
||||||
|
effect: Effects::VerticalWave,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::Vertical23,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "HorizontalWave",
|
||||||
|
effect: Effects::HorizontalWave,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::Horizontal01,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "Rotating",
|
||||||
|
effect: Effects::Rotating,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "Explosion",
|
||||||
|
effect: Effects::Explosion,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "Launch",
|
||||||
|
effect: Effects::Launch,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "Ripples",
|
||||||
|
effect: Effects::Ripples,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "Snake",
|
||||||
|
effect: Effects::Snake,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "Pulse",
|
||||||
|
effect: Effects::Pulse,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "Tilt",
|
||||||
|
effect: Effects::Tilt,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "Shuttle",
|
||||||
|
effect: Effects::Shuttle,
|
||||||
|
can_set_color: true,
|
||||||
|
can_set_speed: true,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: true,
|
||||||
|
},
|
||||||
|
EffectInfo {
|
||||||
|
name: "StaticPerKey",
|
||||||
|
effect: Effects::StaticPerKey,
|
||||||
|
can_set_color: false,
|
||||||
|
can_set_speed: false,
|
||||||
|
can_set_direction: DirectionPolicy::None,
|
||||||
|
can_set_full_color: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
use Effects::{
|
||||||
|
Breath, CentrifugalWave, Colorful, Explosion, Glittering, HorizontalWave, Launch, Pulse, Rain,
|
||||||
|
Ripples, Rotating, Shuttle, SingleOff, SingleOn, Snake, Spectrum, Static, StaticPerKey, Tilt,
|
||||||
|
VerticalWave,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Effects of the keyboard
|
||||||
|
pub enum Effects {
|
||||||
|
Static,
|
||||||
|
SingleOn,
|
||||||
|
SingleOff,
|
||||||
|
Glittering,
|
||||||
|
Rain,
|
||||||
|
Colorful,
|
||||||
|
Breath,
|
||||||
|
Spectrum,
|
||||||
|
CentrifugalWave,
|
||||||
|
VerticalWave,
|
||||||
|
HorizontalWave,
|
||||||
|
Rotating,
|
||||||
|
Explosion,
|
||||||
|
Launch,
|
||||||
|
Ripples,
|
||||||
|
Snake,
|
||||||
|
Pulse,
|
||||||
|
Tilt,
|
||||||
|
Shuttle,
|
||||||
|
StaticPerKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Effects {
|
||||||
|
/// Returns an u8 of the effect used for communication with the device
|
||||||
|
pub fn to_u8(&self) -> u8 {
|
||||||
|
match self {
|
||||||
|
Static => 1,
|
||||||
|
SingleOn => 2,
|
||||||
|
SingleOff => 3,
|
||||||
|
Glittering => 4,
|
||||||
|
Rain => 5,
|
||||||
|
Colorful => 6,
|
||||||
|
Breath => 7,
|
||||||
|
Spectrum => 8,
|
||||||
|
CentrifugalWave => 9,
|
||||||
|
VerticalWave => 10,
|
||||||
|
HorizontalWave => 11,
|
||||||
|
Rotating => 12,
|
||||||
|
Explosion => 13,
|
||||||
|
Launch => 14,
|
||||||
|
Ripples => 15,
|
||||||
|
Snake => 16,
|
||||||
|
Pulse => 17,
|
||||||
|
Tilt => 18,
|
||||||
|
Shuttle => 19,
|
||||||
|
StaticPerKey => 20,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user