Add extra models to ledmodes
- Configurable anime example - Gfx power states as enum Closes #72
@@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
### Changed
|
||||
- Display PNG images on AniMe with scale, position, angle, and brightness
|
||||
- AniMe display parts split out to individual crate in preparation for publishing
|
||||
on crates.io
|
||||
|
||||
# [3.3.0] - 2021-04-3
|
||||
### Changed
|
||||
- Add ledmodes for G733QS
|
||||
|
||||
101
Cargo.lock
generated
@@ -1,5 +1,11 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.15"
|
||||
@@ -34,10 +40,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "asusctl"
|
||||
version = "3.1.5"
|
||||
version = "3.3.1"
|
||||
dependencies = [
|
||||
"daemon",
|
||||
"glam",
|
||||
"gumdrop",
|
||||
"rog_anime",
|
||||
"rog_dbus",
|
||||
"rog_types",
|
||||
"serde_json",
|
||||
@@ -197,12 +205,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "daemon"
|
||||
version = "3.3.0"
|
||||
version = "3.3.1"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"intel-pstate",
|
||||
"log",
|
||||
"logind-zbus",
|
||||
"rog_anime",
|
||||
"rog_dbus",
|
||||
"rog_fan_curve",
|
||||
"rog_types",
|
||||
@@ -431,6 +440,15 @@ dependencies = [
|
||||
"wasi 0.10.2+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glam"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70155b56080764b8b758e91e4c63d06da0262c0c939f2cd991cd1382087147df"
|
||||
dependencies = [
|
||||
"spirv-std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gumdrop"
|
||||
version = "0.8.0"
|
||||
@@ -509,6 +527,12 @@ version = "0.2.90"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba4aede83fc3617411dc6993bc8c70919750c1c257c6ca6a502aed6e0e2394ae"
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7d73b3f436185384286bd8098d17ec07c9a7d2388a6599f824d8502b529702a"
|
||||
|
||||
[[package]]
|
||||
name = "libudev-sys"
|
||||
version = "0.1.4"
|
||||
@@ -581,6 +605,16 @@ version = "2.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nb-connect"
|
||||
version = "1.0.3"
|
||||
@@ -657,6 +691,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"libm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -700,6 +735,12 @@ version = "1.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3"
|
||||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2fe43bf372b08cc9ccee5144715db59c79ab00168bbe4cf0d274dc0d5f64d7f"
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.0.0"
|
||||
@@ -718,12 +759,28 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pix"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bea9d5c668f13b4a1b97d848780e00cfabf76eb83538129c264c0c6d6a968047"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c"
|
||||
|
||||
[[package]]
|
||||
name = "png_pong"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75851150081bd473079e03e2fa00e25557bcb19706e502b095ca71ce392b70ff"
|
||||
dependencies = [
|
||||
"miniz_oxide",
|
||||
"pix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
version = "2.0.2"
|
||||
@@ -887,9 +944,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
|
||||
|
||||
[[package]]
|
||||
name = "rog_dbus"
|
||||
version = "3.1.0"
|
||||
name = "rog_anime"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"glam",
|
||||
"owo-colors",
|
||||
"pix",
|
||||
"png_pong",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"zvariant",
|
||||
"zvariant_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rog_dbus"
|
||||
version = "3.2.0"
|
||||
dependencies = [
|
||||
"rog_anime",
|
||||
"rog_fan_curve",
|
||||
"rog_types",
|
||||
"serde_json",
|
||||
@@ -1044,6 +1116,27 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spirv-std"
|
||||
version = "0.4.0-alpha.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6de6f1b80004dfc3e9e02fdf8eb32c663f3b85e3942f39d02b6540ed0d2460dd"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"spirv-std-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spirv-std-macros"
|
||||
version = "0.4.0-alpha.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4972082b5236fd57a46cc47fbc315ad78b5ad07b33e51077c688a2fe28d6f2d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote 1.0.9",
|
||||
"syn 1.0.64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strum"
|
||||
version = "0.8.0"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
[workspace]
|
||||
members = ["asusctl", "asus-notify", "daemon", "rog-types", "rog-dbus"]
|
||||
members = ["asusctl", "asus-notify", "daemon", "rog-types", "rog-dbus", "rog-anime"]
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
|
||||
@@ -14,6 +14,6 @@ rog_types = { path = "../rog-types" }
|
||||
daemon = { path = "../daemon" }
|
||||
|
||||
[dependencies.notify-rust]
|
||||
version = "^4.0"
|
||||
version = "^4.3"
|
||||
default-features = false
|
||||
features = ["z"]
|
||||
@@ -9,9 +9,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
println!(" daemon version {}", daemon::VERSION);
|
||||
println!(" rog-dbus version {}", rog_dbus::VERSION);
|
||||
|
||||
// let mut cfg = Config::read_new()?;
|
||||
// let mut last_profile = String::new();
|
||||
|
||||
let (proxies, conn) = DbusProxies::new()?;
|
||||
let signals = Signals::new(&proxies)?;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "asusctl"
|
||||
version = "3.1.5"
|
||||
version = "3.3.1"
|
||||
authors = ["Luke D Jones <luke@ljones.dev>"]
|
||||
edition = "2018"
|
||||
|
||||
@@ -9,13 +9,14 @@ edition = "2018"
|
||||
[dependencies]
|
||||
# serialisation
|
||||
serde_json = "^1.0"
|
||||
rog_anime = { path = "../rog-anime" }
|
||||
rog_dbus = { path = "../rog-dbus" }
|
||||
rog_types = { path = "../rog-types" }
|
||||
daemon = { path = "../daemon" }
|
||||
gumdrop = "^0.8"
|
||||
yansi-term = "^0.1"
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
tinybmp = "^0.2.3"
|
||||
glam = "*"
|
||||
rog_dbus = { path = "../rog-dbus" }
|
||||
26
asusctl/examples/animatrix-grid.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
use rog_anime::{AniMeDataBuffer, AniMeGrid};
|
||||
use rog_dbus::AuraDbusClient;
|
||||
|
||||
// In usable data:
|
||||
// Top row start at 1, ends at 32
|
||||
|
||||
fn main() {
|
||||
let (client, _) = AuraDbusClient::new().unwrap();
|
||||
let mut matrix = AniMeGrid::new();
|
||||
{
|
||||
let tmp = matrix.get_mut();
|
||||
for row in tmp.iter_mut() {
|
||||
row[row.len() - 33] = 0xff;
|
||||
|
||||
row[row.len() - 22] = 0xff;
|
||||
|
||||
row[row.len() - 11] = 0xff;
|
||||
|
||||
row[row.len() - 1] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
let matrix = <AniMeDataBuffer>::from(matrix);
|
||||
|
||||
client.proxies().anime().write(matrix).unwrap();
|
||||
}
|
||||
129
asusctl/examples/animatrix-outline.rs
Normal file
@@ -0,0 +1,129 @@
|
||||
use rog_anime::AniMeDataBuffer;
|
||||
use rog_dbus::AuraDbusClient;
|
||||
|
||||
// In usable data:
|
||||
// Top row start at 1, ends at 32
|
||||
|
||||
fn main() {
|
||||
let (client, _) = AuraDbusClient::new().unwrap();
|
||||
let mut matrix = AniMeDataBuffer::new();
|
||||
matrix.get_mut()[1] = 100; // start = 1
|
||||
for n in matrix.get_mut()[2..32].iter_mut() {
|
||||
*n = 250;
|
||||
}
|
||||
matrix.get_mut()[32] = 100; // end
|
||||
matrix.get_mut()[34] = 100; // start x = 0
|
||||
matrix.get_mut()[66] = 100; // end
|
||||
matrix.get_mut()[69] = 100; // start x = 1
|
||||
matrix.get_mut()[101] = 100; // end
|
||||
matrix.get_mut()[102] = 100; // start
|
||||
matrix.get_mut()[134] = 100; // end
|
||||
matrix.get_mut()[137] = 100; // start
|
||||
matrix.get_mut()[169] = 100; // end
|
||||
matrix.get_mut()[170] = 100; // start
|
||||
matrix.get_mut()[202] = 100; // end
|
||||
matrix.get_mut()[204] = 100; // start
|
||||
matrix.get_mut()[236] = 100; // end
|
||||
matrix.get_mut()[237] = 100; // start
|
||||
matrix.get_mut()[268] = 100; // end
|
||||
matrix.get_mut()[270] = 100; // start
|
||||
matrix.get_mut()[301] = 100; // end
|
||||
matrix.get_mut()[302] = 100; // start
|
||||
matrix.get_mut()[332] = 100; // end
|
||||
matrix.get_mut()[334] = 100; // start
|
||||
matrix.get_mut()[364] = 100; // end
|
||||
matrix.get_mut()[365] = 100; // start
|
||||
matrix.get_mut()[394] = 100; // end
|
||||
matrix.get_mut()[396] = 100; // start
|
||||
matrix.get_mut()[425] = 100; // end
|
||||
matrix.get_mut()[426] = 100; // start
|
||||
matrix.get_mut()[454] = 100; // end
|
||||
matrix.get_mut()[456] = 100; // start
|
||||
matrix.get_mut()[484] = 100; // end
|
||||
matrix.get_mut()[485] = 100; // start
|
||||
matrix.get_mut()[512] = 100; // end
|
||||
matrix.get_mut()[514] = 100; // start
|
||||
matrix.get_mut()[541] = 100; // end
|
||||
matrix.get_mut()[542] = 100; // start
|
||||
matrix.get_mut()[568] = 100; // end
|
||||
matrix.get_mut()[570] = 100; // start
|
||||
matrix.get_mut()[596] = 100; // end
|
||||
matrix.get_mut()[597] = 100; // start
|
||||
matrix.get_mut()[622] = 100; // end
|
||||
matrix.get_mut()[624] = 100; // start
|
||||
matrix.get_mut()[649] = 100; // end
|
||||
matrix.get_mut()[650] = 100; // start
|
||||
matrix.get_mut()[674] = 100; // end
|
||||
matrix.get_mut()[676] = 100; // start
|
||||
matrix.get_mut()[700] = 100; // end
|
||||
matrix.get_mut()[701] = 100; // start
|
||||
matrix.get_mut()[724] = 100; // end
|
||||
matrix.get_mut()[726] = 100; // start
|
||||
matrix.get_mut()[749] = 100; // end
|
||||
matrix.get_mut()[750] = 100; // start
|
||||
matrix.get_mut()[772] = 100; // end
|
||||
matrix.get_mut()[774] = 100; // start
|
||||
matrix.get_mut()[796] = 100; // end
|
||||
matrix.get_mut()[797] = 100; // start
|
||||
matrix.get_mut()[818] = 100; // end
|
||||
matrix.get_mut()[820] = 100; // start
|
||||
matrix.get_mut()[841] = 100; // end
|
||||
matrix.get_mut()[842] = 100; // start
|
||||
matrix.get_mut()[862] = 100; // end
|
||||
matrix.get_mut()[864] = 100; // start
|
||||
matrix.get_mut()[884] = 100; // end
|
||||
matrix.get_mut()[885] = 100; // start
|
||||
matrix.get_mut()[904] = 100; // end
|
||||
matrix.get_mut()[906] = 100; // start
|
||||
matrix.get_mut()[925] = 100; // end
|
||||
matrix.get_mut()[926] = 100; // start
|
||||
matrix.get_mut()[944] = 100; // end
|
||||
matrix.get_mut()[946] = 100; // start
|
||||
matrix.get_mut()[964] = 100; // end
|
||||
matrix.get_mut()[965] = 100; // start
|
||||
matrix.get_mut()[982] = 100; // end
|
||||
matrix.get_mut()[984] = 100; // start
|
||||
matrix.get_mut()[1001] = 100; // end
|
||||
matrix.get_mut()[1002] = 100; // start
|
||||
matrix.get_mut()[1018] = 100; // end
|
||||
matrix.get_mut()[1020] = 100; // start
|
||||
matrix.get_mut()[1036] = 100; // end
|
||||
matrix.get_mut()[1037] = 100; // start
|
||||
matrix.get_mut()[1052] = 100; // end
|
||||
matrix.get_mut()[1054] = 100; // start
|
||||
matrix.get_mut()[1069] = 100; // end
|
||||
matrix.get_mut()[1070] = 100; // start
|
||||
matrix.get_mut()[1084] = 100; // end
|
||||
matrix.get_mut()[1086] = 100; // start
|
||||
matrix.get_mut()[1100] = 100; // end
|
||||
matrix.get_mut()[1101] = 100; // start
|
||||
matrix.get_mut()[1114] = 100; // end
|
||||
matrix.get_mut()[1116] = 100; // start
|
||||
matrix.get_mut()[1129] = 100; // end
|
||||
matrix.get_mut()[1130] = 100; // start
|
||||
matrix.get_mut()[1142] = 100; // end
|
||||
matrix.get_mut()[1144] = 100; // start
|
||||
matrix.get_mut()[1156] = 100; // end
|
||||
matrix.get_mut()[1157] = 100; // start
|
||||
matrix.get_mut()[1168] = 100; // end
|
||||
matrix.get_mut()[1170] = 100; // start
|
||||
matrix.get_mut()[1181] = 100; // end
|
||||
matrix.get_mut()[1182] = 100; // start
|
||||
matrix.get_mut()[1192] = 100; // end
|
||||
matrix.get_mut()[1194] = 100; // start
|
||||
matrix.get_mut()[1204] = 100; // end
|
||||
matrix.get_mut()[1205] = 100; // start
|
||||
matrix.get_mut()[1214] = 100; // end
|
||||
matrix.get_mut()[1216] = 100; // start
|
||||
matrix.get_mut()[1225] = 100; // end
|
||||
matrix.get_mut()[1226] = 100; // start
|
||||
matrix.get_mut()[1234] = 100; // end
|
||||
matrix.get_mut()[1236] = 100; // start
|
||||
for n in matrix.get_mut()[1237..1244].iter_mut() {
|
||||
*n = 250;
|
||||
}
|
||||
matrix.get_mut()[1244] = 100; // end
|
||||
println!("{:?}", &matrix);
|
||||
|
||||
client.proxies().anime().write(matrix).unwrap();
|
||||
}
|
||||
42
asusctl/examples/animatrix-png.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
use std::{env, error::Error, path::Path, process::exit};
|
||||
|
||||
use rog_anime::{
|
||||
AniMeDataBuffer, {AnimeImage, Vec2},
|
||||
};
|
||||
use rog_dbus::AuraDbusClient;
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let (client, _) = AuraDbusClient::new().unwrap();
|
||||
|
||||
let args: Vec<String> = env::args().into_iter().collect();
|
||||
if args.len() != 8 {
|
||||
println!(
|
||||
"Usage: <filepath> <x scale> <y scale> <angle> <x pos> <y pos> <fineness> <brightness>"
|
||||
);
|
||||
println!("e.g, asusctl/examples/doom_large.png 0.9 0.9 0.4 0.0 0.0, 0.8");
|
||||
println!("All args except path and fineness are floats");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
let matrix = AnimeImage::from_png(
|
||||
Path::new(&args[1]),
|
||||
Vec2::new(
|
||||
args[2].parse::<f32>().unwrap(),
|
||||
args[3].parse::<f32>().unwrap(),
|
||||
),
|
||||
args[4].parse::<f32>().unwrap(),
|
||||
Vec2::new(
|
||||
args[5].parse::<f32>().unwrap(),
|
||||
args[6].parse::<f32>().unwrap(),
|
||||
),
|
||||
args[7].parse::<f32>().unwrap(),
|
||||
)?;
|
||||
|
||||
client
|
||||
.proxies()
|
||||
.anime()
|
||||
.write(<AniMeDataBuffer>::from(&matrix))
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
49
asusctl/examples/animatrix-spinning.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
use std::{
|
||||
env, error::Error, f32::consts::PI, path::Path, process::exit, thread::sleep, time::Duration,
|
||||
};
|
||||
|
||||
use rog_anime::{
|
||||
AniMeDataBuffer, {AnimeImage, Vec2},
|
||||
};
|
||||
use rog_dbus::AuraDbusClient;
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let (client, _) = AuraDbusClient::new().unwrap();
|
||||
|
||||
let args: Vec<String> = env::args().into_iter().collect();
|
||||
if args.len() != 8 {
|
||||
println!("Usage: <filepath> <x scale> <y scale> <angle> <x pos> <y pos> <brightness>");
|
||||
println!("e.g, asusctl/examples/doom_large.bmp 0.9 0.9 0.4 0.0 0.0, 0.8");
|
||||
println!("All args except path and fineness are floats");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
let mut matrix = AnimeImage::from_png(
|
||||
Path::new(&args[1]),
|
||||
Vec2::new(
|
||||
args[2].parse::<f32>().unwrap(),
|
||||
args[3].parse::<f32>().unwrap(),
|
||||
),
|
||||
args[4].parse::<f32>().unwrap(),
|
||||
Vec2::new(
|
||||
args[5].parse::<f32>().unwrap(),
|
||||
args[6].parse::<f32>().unwrap(),
|
||||
),
|
||||
args[7].parse::<f32>().unwrap(),
|
||||
)?;
|
||||
|
||||
loop {
|
||||
matrix.angle += 0.05;
|
||||
if matrix.angle > PI * 2.0 {
|
||||
matrix.angle = 0.0
|
||||
}
|
||||
matrix.update();
|
||||
|
||||
client
|
||||
.proxies()
|
||||
.anime()
|
||||
.write(<AniMeDataBuffer>::from(&matrix))
|
||||
.unwrap();
|
||||
sleep(Duration::from_micros(500));
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
use rog_dbus::AuraDbusClient;
|
||||
use rog_types::anime_matrix::{AniMeImageBuffer, HEIGHT, WIDTH};
|
||||
use tinybmp::{Bmp, Pixel};
|
||||
|
||||
fn main() {
|
||||
let (client, _) = AuraDbusClient::new().unwrap();
|
||||
|
||||
let bmp = Bmp::from_slice(include_bytes!("rust.bmp")).expect("Failed to parse BMP image");
|
||||
let pixels: Vec<Pixel> = bmp.into_iter().collect();
|
||||
//assert_eq!(pixels.len(), 56 * 56);
|
||||
|
||||
// Try an outline, top and right
|
||||
let mut matrix = AniMeImageBuffer::new();
|
||||
|
||||
// Aligned left
|
||||
for (i, px) in pixels.iter().enumerate() {
|
||||
if (px.x as usize / 2) < WIDTH && (px.y as usize) < HEIGHT && px.x % 2 == 0 {
|
||||
let c = px.color as u32;
|
||||
matrix.get_mut()[px.y as usize][px.x as usize / 2] = c as u8;
|
||||
}
|
||||
}
|
||||
|
||||
// Throw an alignment border up
|
||||
{
|
||||
let tmp = matrix.get_mut();
|
||||
for x in tmp[0].iter_mut() {
|
||||
*x = 0xff;
|
||||
}
|
||||
for (i, row) in tmp.iter_mut().enumerate() {
|
||||
if i % 2 == 0 {
|
||||
let l = row.len();
|
||||
row[l - 1] = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
matrix.debug_print();
|
||||
|
||||
//let mut matrix: AniMePacketType = AniMePacketType::from(matrix);
|
||||
// println!("{:?}", matrix[0].to_vec());
|
||||
// println!("{:?}", matrix[1].to_vec());
|
||||
|
||||
client.proxies().anime().write_image(matrix).unwrap();
|
||||
}
|
||||
BIN
asusctl/examples/doom.png
Normal file
|
After Width: | Height: | Size: 140 KiB |
BIN
asusctl/examples/ferris.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
BIN
asusctl/examples/nudoom.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
@@ -10,7 +10,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
loop {
|
||||
let count = 49;
|
||||
for _ in 0..count {
|
||||
*key_colours.key(Key::ROG).unwrap().0 += 5;
|
||||
*key_colours.key(Key::Rog).unwrap().0 += 5;
|
||||
*key_colours.key(Key::L).unwrap().0 += 5;
|
||||
*key_colours.key(Key::I).unwrap().0 += 5;
|
||||
*key_colours.key(Key::N).unwrap().0 += 5;
|
||||
@@ -19,7 +19,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
dbus.proxies().led().set_per_key(&key_colours)?;
|
||||
}
|
||||
for _ in 0..count {
|
||||
*key_colours.key(Key::ROG).unwrap().0 -= 5;
|
||||
*key_colours.key(Key::Rog).unwrap().0 -= 5;
|
||||
*key_colours.key(Key::L).unwrap().0 -= 5;
|
||||
*key_colours.key(Key::I).unwrap().0 -= 5;
|
||||
*key_colours.key(Key::N).unwrap().0 -= 5;
|
||||
|
||||
|
Before Width: | Height: | Size: 7.6 KiB |
BIN
asusctl/examples/rust.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
94
asusctl/src/anime_cli.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
use gumdrop::Options;
|
||||
use rog_types::error::AuraError;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum AniMeStatusValue {
|
||||
On,
|
||||
Off,
|
||||
}
|
||||
impl FromStr for AniMeStatusValue {
|
||||
type Err = AuraError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let s = s.to_lowercase();
|
||||
match s.as_str() {
|
||||
"on" => Ok(AniMeStatusValue::On),
|
||||
"off" => Ok(AniMeStatusValue::Off),
|
||||
_ => {
|
||||
print!("Invalid argument, must be one of: on, off");
|
||||
Err(AuraError::ParseAnime)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<AniMeStatusValue> for bool {
|
||||
fn from(value: AniMeStatusValue) -> Self {
|
||||
match value {
|
||||
AniMeStatusValue::On => true,
|
||||
AniMeStatusValue::Off => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
pub struct AniMeLeds {
|
||||
#[options(help = "print help message")]
|
||||
help: bool,
|
||||
#[options(
|
||||
no_long,
|
||||
required,
|
||||
short = "b",
|
||||
meta = "",
|
||||
help = "set all leds brightness value"
|
||||
)]
|
||||
led_brightness: u8,
|
||||
}
|
||||
impl AniMeLeds {
|
||||
pub fn led_brightness(&self) -> u8 {
|
||||
self.led_brightness
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
pub struct AniMeCommand {
|
||||
#[options(help = "print help message")]
|
||||
pub help: bool,
|
||||
#[options(
|
||||
meta = "",
|
||||
help = "turn on/off the panel (accept/reject write requests)"
|
||||
)]
|
||||
pub turn: Option<AniMeStatusValue>,
|
||||
#[options(meta = "", help = "turn on/off the panel at boot (with Asus effect)")]
|
||||
pub boot: Option<AniMeStatusValue>,
|
||||
#[options(command)]
|
||||
pub command: Option<AniMeActions>,
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
pub enum AniMeActions {
|
||||
#[options(help = "change all leds brightness")]
|
||||
Leds(AniMeLeds),
|
||||
#[options(help = "display an 8bit greyscale png")]
|
||||
Image(AniMeImage),
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
pub struct AniMeImage {
|
||||
#[options(help = "print help message")]
|
||||
pub help: bool,
|
||||
#[options(meta = "", help = "full path to the png to display")]
|
||||
pub path: String,
|
||||
#[options(meta = "", default = "0.0", help = "x scale 0.0-1.0")]
|
||||
pub x_scale: f32,
|
||||
#[options(meta = "", default = "0.0", help = "y scale 0.0-1.0")]
|
||||
pub y_scale: f32,
|
||||
#[options(meta = "", default = "0.0", help = "x position (float)")]
|
||||
pub x_pos: f32,
|
||||
#[options(meta = "", default = "0.0", help = "y position (float)")]
|
||||
pub y_pos: f32,
|
||||
#[options(meta = "", default = "0.0", help = "the angle in radians")]
|
||||
pub angle: f32,
|
||||
#[options(meta = "", default = "1.0", help = "brightness 0.0-1.0")]
|
||||
pub bright: f32,
|
||||
}
|
||||
@@ -1,25 +1,29 @@
|
||||
mod anime_cli;
|
||||
mod aura_cli;
|
||||
|
||||
use crate::aura_cli::{LedBrightness, SetAuraBuiltin};
|
||||
use anime_cli::{AniMeActions, AniMeCommand};
|
||||
use daemon::{
|
||||
ctrl_fan_cpu::FanCpuSupportedFunctions, ctrl_leds::LedSupportedFunctions,
|
||||
ctrl_rog_bios::RogBiosSupportedFunctions, ctrl_supported::SupportedFunctions,
|
||||
};
|
||||
use gumdrop::{Opt, Options};
|
||||
use rog_anime::{
|
||||
AniMeDataBuffer, ANIME_DATA_LEN,
|
||||
AnimeImage, Vec2,
|
||||
};
|
||||
use rog_dbus::AuraDbusClient;
|
||||
use rog_types::{
|
||||
anime_matrix::{AniMeDataBuffer, FULL_PANE_LEN},
|
||||
aura_modes::{self, AuraEffect, AuraModeNum},
|
||||
cli_options::{AniMeActions, AniMeStatusValue},
|
||||
gfx_vendors::GfxVendors,
|
||||
profile::{FanLevel, ProfileCommand, ProfileEvent},
|
||||
};
|
||||
use std::env::args;
|
||||
use std::{env::args, path::Path};
|
||||
use yansi_term::Colour::Green;
|
||||
use yansi_term::Colour::Red;
|
||||
|
||||
#[derive(Default, Options)]
|
||||
struct CLIStart {
|
||||
struct CliStart {
|
||||
#[options(help_flag, help = "print help message")]
|
||||
help: bool,
|
||||
#[options(help = "show program version number")]
|
||||
@@ -82,21 +86,6 @@ struct GraphicsCommand {
|
||||
force: bool,
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
struct AniMeCommand {
|
||||
#[options(help = "print help message")]
|
||||
help: bool,
|
||||
#[options(
|
||||
meta = "",
|
||||
help = "turn on/off the panel (accept/reject write requests)"
|
||||
)]
|
||||
turn: Option<AniMeStatusValue>,
|
||||
#[options(meta = "", help = "turn on/off the panel at boot (with Asus effect)")]
|
||||
boot: Option<AniMeStatusValue>,
|
||||
#[options(command)]
|
||||
command: Option<AniMeActions>,
|
||||
}
|
||||
|
||||
#[derive(Options, Debug)]
|
||||
struct BiosCommand {
|
||||
#[options(help = "print help message")]
|
||||
@@ -118,14 +107,14 @@ struct BiosCommand {
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args: Vec<String> = args().skip(1).collect();
|
||||
|
||||
let parsed: CLIStart;
|
||||
let parsed: CliStart;
|
||||
let missing_argument_k = gumdrop::Error::missing_argument(Opt::Short('k'));
|
||||
match CLIStart::parse_args_default(&args) {
|
||||
match CliStart::parse_args_default(&args) {
|
||||
Ok(p) => {
|
||||
parsed = p;
|
||||
}
|
||||
Err(err) if err.to_string() == missing_argument_k.to_string() => {
|
||||
parsed = CLIStart {
|
||||
parsed = CliStart {
|
||||
kbd_bright: Some(LedBrightness::new(None)),
|
||||
..Default::default()
|
||||
};
|
||||
@@ -175,9 +164,32 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
if let Some(action) = cmd.command {
|
||||
match action {
|
||||
AniMeActions::Leds(anime_leds) => {
|
||||
let mut data = AniMeDataBuffer::new();
|
||||
data.set([anime_leds.led_brightness(); FULL_PANE_LEN]);
|
||||
dbus.proxies().anime().write_direct(data)?;
|
||||
let data = AniMeDataBuffer::from_vec(
|
||||
[anime_leds.led_brightness(); ANIME_DATA_LEN].to_vec(),
|
||||
);
|
||||
dbus.proxies().anime().write(data)?;
|
||||
}
|
||||
AniMeActions::Image(image) => {
|
||||
if image.help_requested() {
|
||||
println!("Missing arg or command\n\n{}", image.self_usage());
|
||||
if let Some(lst) = image.self_command_list() {
|
||||
println!("\n{}", lst);
|
||||
}
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let matrix = AnimeImage::from_png(
|
||||
Path::new(&image.path),
|
||||
Vec2::new(image.x_scale, image.y_scale),
|
||||
image.angle,
|
||||
Vec2::new(image.x_pos, image.y_pos),
|
||||
image.bright,
|
||||
)?;
|
||||
|
||||
dbus.proxies()
|
||||
.anime()
|
||||
.write(<AniMeDataBuffer>::from(&matrix))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,9 +202,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
&& parsed.chg_limit.is_none())
|
||||
|| parsed.help
|
||||
{
|
||||
println!("{}", CLIStart::usage());
|
||||
println!("{}", CliStart::usage());
|
||||
println!();
|
||||
println!("{}", CLIStart::command_list().unwrap());
|
||||
println!("{}", CliStart::command_list().unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,7 +236,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_supported_help(supported: &SupportedFunctions, parsed: &CLIStart) {
|
||||
fn print_supported_help(supported: &SupportedFunctions, parsed: &CliStart) {
|
||||
// As help option don't work with `parse_args_default`
|
||||
// we will call `parse_args_default_or_exit` instead
|
||||
let usage: Vec<String> = parsed.self_usage().lines().map(|s| s.to_string()).collect();
|
||||
@@ -311,10 +323,11 @@ fn do_gfx(
|
||||
}
|
||||
if command.pow {
|
||||
let res = dbus.proxies().gfx().gfx_get_pwr()?;
|
||||
if res.contains("active") {
|
||||
println!("Current power status: {}", Red.paint(&res));
|
||||
} else {
|
||||
println!("Current power status: {}", Green.paint(&res));
|
||||
match res {
|
||||
rog_types::gfx_vendors::GfxPower::Active => {
|
||||
println!("Current power status: {}", Red.paint(<&str>::from(&res)))
|
||||
}
|
||||
_ => println!("Current power status: {}", Green.paint(<&str>::from(&res))),
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "daemon"
|
||||
version = "3.3.0"
|
||||
version = "3.3.1"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
authors = ["Luke <luke@ljones.dev>"]
|
||||
@@ -18,6 +18,7 @@ name = "asusd"
|
||||
path = "src/daemon.rs"
|
||||
|
||||
[dependencies]
|
||||
rog_anime = { path = "../rog-anime" }
|
||||
rog_types = { path = "../rog-types" }
|
||||
rog_dbus = { path = "../rog-dbus" }
|
||||
rusb = "^0.7"
|
||||
|
||||
@@ -14,12 +14,7 @@ const APPLY: u8 = 0xc4;
|
||||
const ON_OFF: u8 = 0x04;
|
||||
|
||||
use log::{error, info, warn};
|
||||
use rog_types::{
|
||||
anime_matrix::{
|
||||
AniMeDataBuffer, AniMeImageBuffer, AniMePacketType, ANIME_PANE1_PREFIX, ANIME_PANE2_PREFIX,
|
||||
},
|
||||
error::AuraError,
|
||||
};
|
||||
use rog_anime::{AniMeDataBuffer, AniMePacketType};
|
||||
use rusb::{Device, DeviceHandle};
|
||||
use std::error::Error;
|
||||
use std::time::Duration;
|
||||
@@ -45,11 +40,8 @@ pub struct CtrlAnimeDisplay {
|
||||
|
||||
//AnimatrixWrite
|
||||
pub trait Dbus {
|
||||
/// Write an image 34x56 pixels. Each pixel is 0-255 greyscale.
|
||||
fn write_image(&self, input: AniMeImageBuffer);
|
||||
|
||||
/// Write a direct stream of data
|
||||
fn write_direct(&self, input: AniMeDataBuffer);
|
||||
fn write(&self, input: AniMeDataBuffer);
|
||||
|
||||
fn set_on_off(&self, status: bool);
|
||||
|
||||
@@ -70,16 +62,9 @@ impl crate::ZbusAdd for CtrlAnimeDisplay {
|
||||
|
||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||
impl Dbus for CtrlAnimeDisplay {
|
||||
/// Writes a 34x56 image
|
||||
fn write_image(&self, input: AniMeImageBuffer) {
|
||||
self.write_image_buffer(input)
|
||||
.map_or_else(|err| warn!("{}", err), |()| info!("Writing image to Anime"));
|
||||
}
|
||||
|
||||
/// Writes a data stream of length
|
||||
fn write_direct(&self, input: AniMeDataBuffer) {
|
||||
self.write_data_buffer(input)
|
||||
.map_or_else(|err| warn!("{}", err), |()| info!("Writing data to Anime"));
|
||||
fn write(&self, input: AniMeDataBuffer) {
|
||||
self.write_data_buffer(input);
|
||||
}
|
||||
|
||||
fn set_on_off(&self, status: bool) {
|
||||
@@ -98,16 +83,8 @@ impl Dbus for CtrlAnimeDisplay {
|
||||
}
|
||||
|
||||
fn set_boot_on_off(&self, status: bool) {
|
||||
let status_str = if status { "on" } else { "off" };
|
||||
|
||||
self.do_set_boot(status).map_or_else(
|
||||
|err| warn!("{}", err),
|
||||
|()| info!("Turning {} the AniMe at boot/shutdown", status_str),
|
||||
);
|
||||
self.do_apply().map_or_else(
|
||||
|err| warn!("{}", err),
|
||||
|()| info!("Turning {} the AniMe at boot/shutdown", status_str),
|
||||
);
|
||||
self.do_set_boot(status);
|
||||
self.do_apply();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +109,7 @@ impl CtrlAnimeDisplay {
|
||||
|
||||
info!("Device has an AniMe Matrix display");
|
||||
let ctrl = CtrlAnimeDisplay { handle: device };
|
||||
ctrl.do_initialization()?;
|
||||
ctrl.do_initialization();
|
||||
|
||||
Ok(ctrl)
|
||||
}
|
||||
@@ -167,48 +144,16 @@ impl CtrlAnimeDisplay {
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn write_data_buffer(&self, buffer: AniMeDataBuffer) -> Result<(), AuraError> {
|
||||
let mut image = AniMePacketType::from(buffer);
|
||||
image[0][..7].copy_from_slice(&ANIME_PANE1_PREFIX);
|
||||
image[1][..7].copy_from_slice(&ANIME_PANE2_PREFIX);
|
||||
|
||||
for row in image.iter() {
|
||||
fn write_data_buffer(&self, buffer: AniMeDataBuffer) {
|
||||
let data = AniMePacketType::from(buffer);
|
||||
for row in data.iter() {
|
||||
self.write_bytes(row);
|
||||
}
|
||||
self.do_flush()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write an Animatrix image
|
||||
///
|
||||
/// The expected USB input here is *two* Vectors, 640 bytes in length. The two vectors
|
||||
/// are each one half of the full image write.
|
||||
///
|
||||
/// After each write a flush is written, it is assumed that this tells the device to
|
||||
/// go ahead and display the written bytes
|
||||
///
|
||||
/// # Note:
|
||||
/// The vectors are expected to contain the full sequence of bytes as follows
|
||||
///
|
||||
/// - Write pane 1: 0x5e 0xc0 0x02 0x01 0x00 0x73 0x02 .. <led brightness>
|
||||
/// - Write pane 2: 0x5e 0xc0 0x02 0x74 0x02 0x73 0x02 .. <led brightness>
|
||||
///
|
||||
/// Where led brightness is 0..255, low to high
|
||||
#[inline]
|
||||
fn write_image_buffer(&self, buffer: AniMeImageBuffer) -> Result<(), AuraError> {
|
||||
let mut image = AniMePacketType::from(buffer);
|
||||
image[0][..7].copy_from_slice(&ANIME_PANE1_PREFIX);
|
||||
image[1][..7].copy_from_slice(&ANIME_PANE2_PREFIX);
|
||||
|
||||
for row in image.iter() {
|
||||
self.write_bytes(row);
|
||||
}
|
||||
self.do_flush()?;
|
||||
Ok(())
|
||||
self.do_flush();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn do_initialization(&self) -> Result<(), AuraError> {
|
||||
fn do_initialization(&self) {
|
||||
let mut init = [0; PACKET_SIZE];
|
||||
init[0] = DEV_PAGE; // This is the USB page we're using throughout
|
||||
for (idx, byte) in INIT_STR.as_bytes().iter().enumerate() {
|
||||
@@ -224,22 +169,20 @@ impl CtrlAnimeDisplay {
|
||||
init[1] = INIT;
|
||||
|
||||
self.write_bytes(&init);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn do_flush(&self) -> Result<(), AuraError> {
|
||||
fn do_flush(&self) {
|
||||
let mut flush = [0; PACKET_SIZE];
|
||||
flush[0] = DEV_PAGE;
|
||||
flush[1] = WRITE;
|
||||
flush[2] = 0x03;
|
||||
|
||||
self.write_bytes(&flush);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn do_set_boot(&self, status: bool) -> Result<(), AuraError> {
|
||||
fn do_set_boot(&self, status: bool) {
|
||||
let mut flush = [0; PACKET_SIZE];
|
||||
flush[0] = DEV_PAGE;
|
||||
flush[1] = SET;
|
||||
@@ -247,11 +190,10 @@ impl CtrlAnimeDisplay {
|
||||
flush[3] = if status { 0x00 } else { 0x80 };
|
||||
|
||||
self.write_bytes(&flush);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn do_apply(&self) -> Result<(), AuraError> {
|
||||
fn do_apply(&self) {
|
||||
let mut flush = [0; PACKET_SIZE];
|
||||
flush[0] = DEV_PAGE;
|
||||
flush[1] = APPLY;
|
||||
@@ -259,6 +201,5 @@ impl CtrlAnimeDisplay {
|
||||
flush[3] = 0x80;
|
||||
|
||||
self.write_bytes(&flush);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ static FAN_TYPE_1_PATH: &str = "/sys/devices/platform/asus-nb-wmi/throttle_therm
|
||||
static FAN_TYPE_2_PATH: &str = "/sys/devices/platform/asus-nb-wmi/fan_boost_mode";
|
||||
static AMD_BOOST_PATH: &str = "/sys/devices/system/cpu/cpufreq/boost";
|
||||
|
||||
pub struct CtrlFanAndCPU {
|
||||
pub struct CtrlFanAndCpu {
|
||||
pub path: &'static str,
|
||||
config: Arc<Mutex<Config>>,
|
||||
}
|
||||
@@ -26,12 +26,12 @@ pub struct FanCpuSupportedFunctions {
|
||||
pub fan_curve_set: bool,
|
||||
}
|
||||
|
||||
impl GetSupported for CtrlFanAndCPU {
|
||||
impl GetSupported for CtrlFanAndCpu {
|
||||
type A = FanCpuSupportedFunctions;
|
||||
|
||||
fn get_supported() -> Self::A {
|
||||
FanCpuSupportedFunctions {
|
||||
stock_fan_modes: CtrlFanAndCPU::get_fan_path().is_ok(),
|
||||
stock_fan_modes: CtrlFanAndCpu::get_fan_path().is_ok(),
|
||||
min_max_freq: intel_pstate::PState::new().is_ok(),
|
||||
fan_curve_set: rog_fan_curve::Board::from_board_name().is_some(),
|
||||
}
|
||||
@@ -39,11 +39,11 @@ impl GetSupported for CtrlFanAndCPU {
|
||||
}
|
||||
|
||||
pub struct DbusFanAndCpu {
|
||||
inner: Arc<Mutex<CtrlFanAndCPU>>,
|
||||
inner: Arc<Mutex<CtrlFanAndCpu>>,
|
||||
}
|
||||
|
||||
impl DbusFanAndCpu {
|
||||
pub fn new(inner: Arc<Mutex<CtrlFanAndCPU>>) -> Self {
|
||||
pub fn new(inner: Arc<Mutex<CtrlFanAndCpu>>) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
}
|
||||
@@ -189,7 +189,7 @@ impl crate::ZbusAdd for DbusFanAndCpu {
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Reloadable for CtrlFanAndCPU {
|
||||
impl crate::Reloadable for CtrlFanAndCpu {
|
||||
fn reload(&mut self) -> Result<(), RogError> {
|
||||
if let Ok(mut config) = self.config.clone().try_lock() {
|
||||
let profile = config.active_profile.clone();
|
||||
@@ -203,11 +203,11 @@ impl crate::Reloadable for CtrlFanAndCPU {
|
||||
}
|
||||
}
|
||||
|
||||
impl CtrlFanAndCPU {
|
||||
impl CtrlFanAndCpu {
|
||||
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
|
||||
let path = CtrlFanAndCPU::get_fan_path()?;
|
||||
let path = CtrlFanAndCpu::get_fan_path()?;
|
||||
info!("Device has thermal throttle control");
|
||||
Ok(CtrlFanAndCPU { path, config })
|
||||
Ok(CtrlFanAndCpu { path, config })
|
||||
}
|
||||
|
||||
fn get_fan_path() -> Result<&'static str, RogError> {
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::error::RogError;
|
||||
#[derive(Debug)]
|
||||
pub enum GfxError {
|
||||
ParseVendor,
|
||||
ParsePower,
|
||||
Bus(String, std::io::Error),
|
||||
DisplayManagerAction(String, ExitStatus),
|
||||
DisplayManagerTimeout(String),
|
||||
@@ -22,6 +23,7 @@ impl fmt::Display for GfxError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
GfxError::ParseVendor => write!(f, "Could not parse vendor name"),
|
||||
GfxError::ParsePower => write!(f, "Could not parse dGPU power status"),
|
||||
GfxError::Bus(func, error) => write!(f, "Bus error: {}: {}", func, error),
|
||||
GfxError::DisplayManagerAction(action, status) => {
|
||||
write!(f, "Display-manager action {} failed: {}", action, status)
|
||||
|
||||
@@ -6,11 +6,11 @@ use logind_zbus::{
|
||||
types::{SessionClass, SessionInfo, SessionState, SessionType},
|
||||
ManagerProxy, SessionProxy,
|
||||
};
|
||||
use rog_types::gfx_vendors::{GfxRequiredUserAction, GfxVendors};
|
||||
use std::sync::mpsc;
|
||||
use rog_types::gfx_vendors::{GfxPower, GfxRequiredUserAction, GfxVendors};
|
||||
use std::{io::Write, ops::Add, path::Path, time::Instant};
|
||||
use std::{iter::FromIterator, thread::JoinHandle};
|
||||
use std::{process::Command, thread::sleep, time::Duration};
|
||||
use std::{str::FromStr, sync::mpsc};
|
||||
use std::{sync::Arc, sync::Mutex};
|
||||
use sysfs_class::{PciDevice, SysClass};
|
||||
use system::{GraphicsDevice, PciBus};
|
||||
@@ -33,7 +33,7 @@ pub struct CtrlGraphics {
|
||||
|
||||
trait Dbus {
|
||||
fn vendor(&self) -> zbus::fdo::Result<GfxVendors>;
|
||||
fn power(&self) -> String;
|
||||
fn power(&self) -> zbus::fdo::Result<GfxPower>;
|
||||
fn set_vendor(&mut self, vendor: GfxVendors) -> zbus::fdo::Result<GfxRequiredUserAction>;
|
||||
fn notify_gfx(&self, vendor: &GfxVendors) -> zbus::Result<()>;
|
||||
fn notify_action(&self, action: &GfxRequiredUserAction) -> zbus::Result<()>;
|
||||
@@ -48,8 +48,11 @@ impl Dbus for CtrlGraphics {
|
||||
})
|
||||
}
|
||||
|
||||
fn power(&self) -> String {
|
||||
Self::get_runtime_status().unwrap_or_else(|err| format!("Get power status failed: {}", err))
|
||||
fn power(&self) -> zbus::fdo::Result<GfxPower> {
|
||||
Self::get_runtime_status().map_err(|err| {
|
||||
error!("GFX: {}", err);
|
||||
zbus::fdo::Error::Failed(format!("GFX fail: {}", err))
|
||||
})
|
||||
}
|
||||
|
||||
fn set_vendor(&mut self, vendor: GfxVendors) -> zbus::fdo::Result<GfxRequiredUserAction> {
|
||||
@@ -178,10 +181,19 @@ impl CtrlGraphics {
|
||||
Ok(GfxVendors::Hybrid)
|
||||
}
|
||||
|
||||
fn get_runtime_status() -> Result<String, RogError> {
|
||||
const PATH: &str = "/sys/bus/pci/devices/0000:01:00.0/power/runtime_status";
|
||||
let buf = std::fs::read_to_string(PATH).map_err(|err| RogError::Read(PATH.into(), err))?;
|
||||
Ok(buf)
|
||||
fn get_runtime_status() -> Result<GfxPower, RogError> {
|
||||
let path = Path::new("/sys/bus/pci/devices/0000:01:00.0/power/runtime_status");
|
||||
if path.exists() {
|
||||
let buf = std::fs::read_to_string(path).map_err(|err| {
|
||||
RogError::Read(
|
||||
"/sys/bus/pci/devices/0000:01:00.0/power/runtime_status".to_string(),
|
||||
err,
|
||||
)
|
||||
})?;
|
||||
Ok(GfxPower::from_str(&buf)?)
|
||||
} else {
|
||||
Ok(GfxPower::Off)
|
||||
}
|
||||
}
|
||||
|
||||
/// Some systems have a fallback service to load nouveau if nvidia fails
|
||||
|
||||
@@ -248,7 +248,7 @@ impl crate::CtrlTask for CtrlKbdBacklight {
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
Err(RogError::ParseLED)
|
||||
Err(RogError::ParseLed)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use zbus::dbus_interface;
|
||||
use crate::{
|
||||
ctrl_anime::{AnimeSupportedFunctions, CtrlAnimeDisplay},
|
||||
ctrl_charge::{ChargeSupportedFunctions, CtrlCharge},
|
||||
ctrl_fan_cpu::{CtrlFanAndCPU, FanCpuSupportedFunctions},
|
||||
ctrl_fan_cpu::{CtrlFanAndCpu, FanCpuSupportedFunctions},
|
||||
ctrl_leds::{CtrlKbdBacklight, LedSupportedFunctions},
|
||||
ctrl_rog_bios::{CtrlRogBios, RogBiosSupportedFunctions},
|
||||
GetSupported,
|
||||
@@ -47,7 +47,7 @@ impl GetSupported for SupportedFunctions {
|
||||
keyboard_led: CtrlKbdBacklight::get_supported(),
|
||||
anime_ctrl: CtrlAnimeDisplay::get_supported(),
|
||||
charge_ctrl: CtrlCharge::get_supported(),
|
||||
fan_cpu_ctrl: CtrlFanAndCPU::get_supported(),
|
||||
fan_cpu_ctrl: CtrlFanAndCpu::get_supported(),
|
||||
rog_bios_ctrl: CtrlRogBios::get_supported(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use daemon::{
|
||||
use daemon::{config_aura::AuraConfig, ctrl_charge::CtrlCharge};
|
||||
use daemon::{ctrl_anime::CtrlAnimeDisplay, ctrl_gfx::gfx::CtrlGraphics};
|
||||
use daemon::{
|
||||
ctrl_fan_cpu::{CtrlFanAndCPU, DbusFanAndCpu},
|
||||
ctrl_fan_cpu::{CtrlFanAndCpu, DbusFanAndCpu},
|
||||
laptops::LaptopLedData,
|
||||
};
|
||||
|
||||
@@ -134,7 +134,7 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||
// Collect tasks for task thread
|
||||
let mut tasks: Vec<Arc<Mutex<dyn CtrlTask + Send>>> = Vec::new();
|
||||
|
||||
if let Ok(mut ctrl) = CtrlFanAndCPU::new(config).map_err(|err| {
|
||||
if let Ok(mut ctrl) = CtrlFanAndCpu::new(config).map_err(|err| {
|
||||
error!("Profile control: {}", err);
|
||||
}) {
|
||||
ctrl.reload()
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::ctrl_gfx::error::GfxError;
|
||||
pub enum RogError {
|
||||
ParseFanLevel,
|
||||
ParseVendor,
|
||||
ParseLED,
|
||||
ParseLed,
|
||||
MissingProfile(String),
|
||||
Udev(String, std::io::Error),
|
||||
Path(String, std::io::Error),
|
||||
@@ -38,7 +38,7 @@ impl fmt::Display for RogError {
|
||||
match self {
|
||||
RogError::ParseFanLevel => write!(f, "Parse profile error"),
|
||||
RogError::ParseVendor => write!(f, "Parse gfx vendor error"),
|
||||
RogError::ParseLED => write!(f, "Parse LED error"),
|
||||
RogError::ParseLed => write!(f, "Parse LED error"),
|
||||
RogError::MissingProfile(profile) => write!(f, "Profile does not exist {}", profile),
|
||||
RogError::Udev(deets, error) => write!(f, "udev {}: {}", deets, error),
|
||||
RogError::Path(path, error) => write!(f, "Path {}: {}", path, error),
|
||||
@@ -80,6 +80,7 @@ impl From<GraphicsError> for RogError {
|
||||
fn from(err: GraphicsError) -> Self {
|
||||
match err {
|
||||
GraphicsError::ParseVendor => RogError::GfxSwitching(GfxError::ParseVendor),
|
||||
GraphicsError::ParsePower => RogError::GfxSwitching(GfxError::ParsePower),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
25
rog-anime/Cargo.toml
Normal file
@@ -0,0 +1,25 @@
|
||||
[package]
|
||||
name = "rog_anime"
|
||||
version = "1.0.0"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
authors = ["Luke <luke@ljones.dev>"]
|
||||
repository = "https://gitlab.com/asus-linux/asus-nb-ctrl"
|
||||
homepage = "https://gitlab.com/asus-linux/asus-nb-ctrl"
|
||||
description = "Types useful for translating images and other data for display on the ASUS AniMe Matrix display"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
png_pong = "^0.8.0"
|
||||
glam = "*"
|
||||
pix = "0.13"
|
||||
owo-colors = "2.0.0"
|
||||
|
||||
serde = "^1.0"
|
||||
serde_derive = "^1.0"
|
||||
zvariant = "^2.5"
|
||||
zvariant_derive = "^2.5"
|
||||
|
||||
[features]
|
||||
default = ["zbus"]
|
||||
zbus = []
|
||||
373
rog-anime/LICENSE
Normal file
@@ -0,0 +1,373 @@
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
||||
56
rog-anime/README.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# rog-anime
|
||||
|
||||
## Features
|
||||
|
||||
`zbus` is enabled by default.
|
||||
|
||||
## Example
|
||||
|
||||
```rust
|
||||
use std::{env, error::Error, path::Path, process::exit};
|
||||
|
||||
use rog_dbus::AuraDbusClient;
|
||||
use rog_anime::{
|
||||
anime_data::AniMeDataBuffer,
|
||||
anime_image::{AnimeImage, Vec2},
|
||||
};
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
let (client, _) = AuraDbusClient::new().unwrap();
|
||||
|
||||
let args: Vec<String> = env::args().into_iter().collect();
|
||||
if args.len() != 8 {
|
||||
println!(
|
||||
"Usage: <filepath> <x scale> <y scale> <angle> <x pos> <y pos> <fineness> <brightness>"
|
||||
);
|
||||
println!("e.g, asusctl/examples/doom_large.png 0.9 0.9 0.4 0.0 0.0, 0.8");
|
||||
println!("All args except path and fineness are floats");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
let image = AnimeImage::from_png(
|
||||
Path::new(&args[1]),
|
||||
Vec2::new(
|
||||
args[2].parse::<f32>().unwrap(),
|
||||
args[3].parse::<f32>().unwrap(),
|
||||
),
|
||||
args[4].parse::<f32>().unwrap(),
|
||||
Vec2::new(
|
||||
args[5].parse::<f32>().unwrap(),
|
||||
args[6].parse::<f32>().unwrap(),
|
||||
),
|
||||
args[7].parse::<f32>().unwrap(),
|
||||
)?;
|
||||
|
||||
/// This data can also be written direct to the USB device by transforming with
|
||||
let data = AniMePacketType::from(image);
|
||||
let data = <AniMeDataBuffer>::from(&image);
|
||||
client
|
||||
.proxies()
|
||||
.anime()
|
||||
.write(data)
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
62
rog-anime/src/anime_data.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
#[cfg(feature = "zbus")]
|
||||
use zvariant_derive::Type;
|
||||
|
||||
/// The first 7 bytes of a USB packet are accounted for by `USB_PREFIX1` and `USB_PREFIX2`
|
||||
const BLOCK_START: usize = 7;
|
||||
/// *Not* inclusive, the byte before this is the final for each "pane"
|
||||
const BLOCK_END: usize = 634;
|
||||
/// Individual usable data length of each USB packet
|
||||
const PANE_LEN: usize = BLOCK_END - BLOCK_START;
|
||||
/// The length of usable data
|
||||
pub const ANIME_DATA_LEN: usize = PANE_LEN * 2;
|
||||
|
||||
const USB_PREFIX1: [u8; 7] = [0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02];
|
||||
const USB_PREFIX2: [u8; 7] = [0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02];
|
||||
|
||||
/// The minimal serializable data that can be transferred over wire types.
|
||||
/// Other data structures in `rog_anime` will convert to this.
|
||||
#[cfg_attr(feature = "zbus", derive(Type))]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct AniMeDataBuffer(Vec<u8>);
|
||||
|
||||
impl Default for AniMeDataBuffer {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl AniMeDataBuffer {
|
||||
pub fn new() -> Self {
|
||||
AniMeDataBuffer(vec![0u8; ANIME_DATA_LEN])
|
||||
}
|
||||
|
||||
pub fn get(&self) -> &[u8] {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self) -> &mut [u8] {
|
||||
&mut self.0
|
||||
}
|
||||
|
||||
pub fn from_vec(input: Vec<u8>) -> Self {
|
||||
Self(input)
|
||||
}
|
||||
}
|
||||
|
||||
/// The two packets to be written to USB
|
||||
pub type AniMePacketType = [[u8; 640]; 2];
|
||||
|
||||
impl From<AniMeDataBuffer> for AniMePacketType {
|
||||
#[inline]
|
||||
fn from(anime: AniMeDataBuffer) -> Self {
|
||||
assert!(anime.0.len() == ANIME_DATA_LEN);
|
||||
let mut buffers = [[0; 640]; 2];
|
||||
for (idx, chunk) in anime.0.as_slice().chunks(PANE_LEN).enumerate() {
|
||||
buffers[idx][BLOCK_START..BLOCK_END].copy_from_slice(chunk);
|
||||
}
|
||||
buffers[0][..7].copy_from_slice(&USB_PREFIX1);
|
||||
buffers[1][..7].copy_from_slice(&USB_PREFIX2);
|
||||
buffers
|
||||
}
|
||||
}
|
||||
165
rog-anime/src/anime_grid.rs
Normal file
@@ -0,0 +1,165 @@
|
||||
use crate::anime_data::{AniMeDataBuffer, ANIME_DATA_LEN};
|
||||
use crate::anime_image::LED_IMAGE_POSITIONS;
|
||||
use owo_colors::{OwoColorize, Rgb};
|
||||
|
||||
const WIDTH: usize = 33;
|
||||
const HEIGHT: usize = 55;
|
||||
|
||||
/// Helper structure for writing images.
|
||||
///
|
||||
/// See the examples for ways to write an image to `AniMeMatrix` format.
|
||||
/// Width = 33
|
||||
/// height = 55
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AniMeGrid([[u8; WIDTH]; HEIGHT]);
|
||||
|
||||
impl Default for AniMeGrid {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl AniMeGrid {
|
||||
pub fn new() -> Self {
|
||||
AniMeGrid([[0u8; WIDTH]; HEIGHT])
|
||||
}
|
||||
|
||||
pub fn set(&mut self, x: usize, y: usize, b: u8) {
|
||||
self.0[y][x] = b;
|
||||
}
|
||||
|
||||
pub fn get(&self) -> &[[u8; WIDTH]; HEIGHT] {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self) -> &mut [[u8; WIDTH]; HEIGHT] {
|
||||
&mut self.0
|
||||
}
|
||||
|
||||
pub fn fill_with(&mut self, fill: u8) {
|
||||
for row in self.0.iter_mut() {
|
||||
for x in row.iter_mut() {
|
||||
*x = fill;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debug_print(&self) {
|
||||
// this is the index from right. It is used to progressively shorten rows
|
||||
let mut prog_row_len = WIDTH - 2;
|
||||
|
||||
for (count, row) in self.0.iter().enumerate() {
|
||||
// Switch to next block (looks like )
|
||||
if count % 2 != 0 {
|
||||
// Row after 6 is only 1 less, then rows after 7 follow pattern
|
||||
if count == 7 {
|
||||
prog_row_len -= 1;
|
||||
} else {
|
||||
prog_row_len -= 2;
|
||||
}
|
||||
} else {
|
||||
prog_row_len += 1; // if count 6, 0
|
||||
}
|
||||
|
||||
let index = row.len() - prog_row_len;
|
||||
|
||||
if count % 2 == 0 {
|
||||
print!(" ");
|
||||
}
|
||||
for (i, n) in row.iter().enumerate() {
|
||||
if i >= index {
|
||||
print!(" {}", "XXX".color(Rgb(0, *n, 0)));
|
||||
} else {
|
||||
print!(" ");
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AniMeGrid> for AniMeDataBuffer {
|
||||
/// Do conversion from the nested Vec in AniMeMatrix to the two required
|
||||
/// packets suitable for sending over USB
|
||||
#[inline]
|
||||
fn from(anime: AniMeGrid) -> Self {
|
||||
let mut buf = vec![0u8; ANIME_DATA_LEN];
|
||||
|
||||
for (idx, pos) in LED_IMAGE_POSITIONS.iter().enumerate() {
|
||||
if let Some(pos) = pos {
|
||||
let x = pos.x().ceil() as usize;
|
||||
let y = pos.y().ceil() as usize;
|
||||
buf[idx + 1] = anime.0[y][x];
|
||||
}
|
||||
}
|
||||
AniMeDataBuffer::from_vec(buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::anime_grid::*;
|
||||
|
||||
#[test]
|
||||
fn check_data_alignment() {
|
||||
let mut matrix = AniMeGrid::new();
|
||||
{
|
||||
let tmp = matrix.get_mut();
|
||||
for row in tmp.iter_mut() {
|
||||
let idx = row.len() - 1;
|
||||
row[idx] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
let matrix = <AniMeDataBuffer>::from(matrix);
|
||||
|
||||
let data_cmp = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
assert_eq!(matrix.get(), &data_cmp);
|
||||
}
|
||||
}
|
||||
1626
rog-anime/src/anime_image.rs
Normal file
37
rog-anime/src/error.rs
Normal file
@@ -0,0 +1,37 @@
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use png_pong::decode::Error as PngError;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AnimeError {
|
||||
NoFrames,
|
||||
Io(std::io::Error),
|
||||
Png(PngError),
|
||||
Format
|
||||
}
|
||||
|
||||
impl fmt::Display for AnimeError {
|
||||
// This trait requires `fmt` with this exact signature.
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
AnimeError::NoFrames => write!(f, "No frames in PNG"),
|
||||
AnimeError::Io(e) => write!(f, "Could not open: {}", e),
|
||||
AnimeError::Png(e) => write!(f, "PNG error: {}", e),
|
||||
AnimeError::Format => write!(f, "PNG file is not 8bit greyscale"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for AnimeError {}
|
||||
|
||||
impl From<std::io::Error> for AnimeError {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
AnimeError::Io(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PngError> for AnimeError {
|
||||
fn from(err: PngError) -> Self {
|
||||
AnimeError::Png(err)
|
||||
}
|
||||
}
|
||||
15
rog-anime/src/lib.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
/// The main data conversion for transfering in shortform over dbus or other,
|
||||
/// or writing directly to the USB device
|
||||
mod anime_data;
|
||||
pub use anime_data::*;
|
||||
|
||||
/// Useful for specialised effects that required a grid of data
|
||||
mod anime_grid;
|
||||
pub use anime_grid::*;
|
||||
|
||||
/// Transform a PNG image for displaying on AniMe matrix display
|
||||
mod anime_image;
|
||||
pub use anime_image::*;
|
||||
|
||||
/// Base errors that are possible
|
||||
pub mod error;
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rog_dbus"
|
||||
version = "3.1.0"
|
||||
version = "3.2.0"
|
||||
license = "MPL-2.0"
|
||||
readme = "README.md"
|
||||
authors = ["Luke <luke@ljones.dev>"]
|
||||
@@ -11,6 +11,7 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
serde_json = "^1.0"
|
||||
rog_anime = { path = "../rog-anime" }
|
||||
rog_types = { path = "../rog-types" }
|
||||
rog_fan_curve = { version = "^0.1", features = ["serde"] }
|
||||
zbus = "^1.8"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
//!
|
||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||
|
||||
use rog_types::anime_matrix::{AniMeDataBuffer, AniMeImageBuffer};
|
||||
use rog_anime::AniMeDataBuffer;
|
||||
use zbus::{dbus_proxy, Connection, Result};
|
||||
|
||||
#[dbus_proxy(
|
||||
@@ -34,10 +34,7 @@ trait Daemon {
|
||||
fn set_on_off(&self, status: bool) -> zbus::Result<()>;
|
||||
|
||||
/// WriteDirect method
|
||||
fn write_direct(&self, input: &[u8]) -> zbus::Result<()>;
|
||||
|
||||
/// WriteImage method
|
||||
fn write_image(&self, input: &[Vec<u8>]) -> zbus::Result<()>;
|
||||
fn write(&self, input: &[u8]) -> zbus::Result<()>;
|
||||
}
|
||||
|
||||
pub struct AnimeProxy<'a>(DaemonProxy<'a>);
|
||||
@@ -63,12 +60,7 @@ impl<'a> AnimeProxy<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn write_direct(&self, input: AniMeDataBuffer) -> Result<()> {
|
||||
self.0.write_direct(input.get())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn write_image(&self, input: AniMeImageBuffer) -> Result<()> {
|
||||
self.0.write_image(input.get())
|
||||
pub fn write(&self, input: AniMeDataBuffer) -> Result<()> {
|
||||
self.0.write(input.get())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use rog_types::gfx_vendors::{GfxRequiredUserAction, GfxVendors};
|
||||
use rog_types::gfx_vendors::{GfxPower, GfxRequiredUserAction, GfxVendors};
|
||||
use zbus::{dbus_proxy, Connection, Result};
|
||||
|
||||
#[dbus_proxy(
|
||||
@@ -30,7 +30,7 @@ use zbus::{dbus_proxy, Connection, Result};
|
||||
)]
|
||||
trait Daemon {
|
||||
/// Power method
|
||||
fn power(&self) -> zbus::Result<String>;
|
||||
fn power(&self) -> zbus::Result<GfxPower>;
|
||||
|
||||
/// SetVendor method
|
||||
fn set_vendor(&self, vendor: &GfxVendors) -> zbus::Result<GfxRequiredUserAction>;
|
||||
@@ -60,7 +60,7 @@ impl<'a> GfxProxy<'a> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn gfx_get_pwr(&self) -> Result<String> {
|
||||
pub fn gfx_get_pwr(&self) -> Result<GfxPower> {
|
||||
self.0.power()
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
gumdrop = "^0.8"
|
||||
rog_fan_curve = { version = "^0.1", features = ["serde"] }
|
||||
serde = "^1.0"
|
||||
serde_derive = "^1.0"
|
||||
rog_fan_curve = { version = "^0.1", features = ["serde"] }
|
||||
zvariant = "^2.5"
|
||||
zvariant_derive = "^2.5"
|
||||
@@ -1,291 +0,0 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use zvariant_derive::Type;
|
||||
|
||||
pub const WIDTH: usize = 34; // Width is definitely 34 items
|
||||
pub const HEIGHT: usize = 56;
|
||||
pub type AniMePacketType = [[u8; 640]; 2];
|
||||
const BLOCK_START: usize = 7;
|
||||
/// *Not* inclusive, the byte before this is the final for each "pane"
|
||||
const BLOCK_END: usize = 634;
|
||||
pub const PANE_LEN: usize = BLOCK_END - BLOCK_START;
|
||||
/// The length of usable data
|
||||
pub const FULL_PANE_LEN: usize = PANE_LEN * 2;
|
||||
|
||||
pub const ANIME_PANE1_PREFIX: [u8; 7] = [0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02];
|
||||
pub const ANIME_PANE2_PREFIX: [u8; 7] = [0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02];
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Type)]
|
||||
pub struct AniMeDataBuffer(Vec<u8>);
|
||||
|
||||
impl Default for AniMeDataBuffer {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl AniMeDataBuffer {
|
||||
pub fn new() -> Self {
|
||||
AniMeDataBuffer(vec![0u8; FULL_PANE_LEN])
|
||||
}
|
||||
|
||||
pub fn get(&self) -> &[u8] {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn set(&mut self, input: [u8; FULL_PANE_LEN]) {
|
||||
self.0 = input.to_vec();
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AniMeDataBuffer> for AniMePacketType {
|
||||
#[inline]
|
||||
fn from(anime: AniMeDataBuffer) -> Self {
|
||||
assert!(anime.0.len() == FULL_PANE_LEN);
|
||||
let mut buffers = [[0; 640]; 2];
|
||||
for (idx, chunk) in anime.0.as_slice().chunks(PANE_LEN).enumerate() {
|
||||
buffers[idx][BLOCK_START..BLOCK_END].copy_from_slice(chunk);
|
||||
}
|
||||
buffers
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper structure for writing images.
|
||||
///
|
||||
/// See the examples for ways to write an image to `AniMeMatrix` format.
|
||||
#[derive(Debug, Deserialize, Serialize, Type)]
|
||||
pub struct AniMeImageBuffer(Vec<Vec<u8>>);
|
||||
|
||||
impl Default for AniMeImageBuffer {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl AniMeImageBuffer {
|
||||
pub fn new() -> Self {
|
||||
AniMeImageBuffer(vec![vec![0u8; WIDTH]; HEIGHT])
|
||||
}
|
||||
|
||||
pub fn get(&self) -> &Vec<Vec<u8>> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
pub fn get_mut(&mut self) -> &mut Vec<Vec<u8>> {
|
||||
&mut self.0
|
||||
}
|
||||
|
||||
pub fn fill_with(&mut self, fill: u8) {
|
||||
for row in self.0.iter_mut() {
|
||||
for x in row.iter_mut() {
|
||||
*x = fill;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debug_print(&self) {
|
||||
// this is the index from right. It is used to progressively shorten rows
|
||||
let mut prog_row_len = WIDTH - 2;
|
||||
|
||||
for (count, row) in self.0.iter().enumerate() {
|
||||
// Write the top block of LEDs (first 7 rows)
|
||||
if count < 6 {
|
||||
if count % 2 != 0 {
|
||||
print!(" ");
|
||||
} else {
|
||||
print!("");
|
||||
}
|
||||
let tmp = if count == 0 || count == 1 || count == 3 || count == 5 {
|
||||
row[1..].iter()
|
||||
} else {
|
||||
row.iter()
|
||||
};
|
||||
for _ in tmp {
|
||||
print!(" XY");
|
||||
}
|
||||
|
||||
println!();
|
||||
} else {
|
||||
// Switch to next block (looks like )
|
||||
if count % 2 != 0 {
|
||||
// Row after 6 is only 1 less, then rows after 7 follow pattern
|
||||
if count == 7 {
|
||||
prog_row_len -= 1;
|
||||
} else {
|
||||
prog_row_len -= 2;
|
||||
}
|
||||
} else {
|
||||
prog_row_len += 1; // if count 6, 0
|
||||
}
|
||||
|
||||
let index = row.len() - prog_row_len;
|
||||
|
||||
if count % 2 == 0 {
|
||||
print!(" ");
|
||||
}
|
||||
for (i, _) in row.iter().enumerate() {
|
||||
if i >= index {
|
||||
print!(" XY");
|
||||
} else {
|
||||
print!(" ");
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AniMeImageBuffer> for AniMePacketType {
|
||||
/// Do conversion from the nested Vec in AniMeMatrix to the two required
|
||||
/// packets suitable for sending over USB
|
||||
#[inline]
|
||||
fn from(anime: AniMeImageBuffer) -> Self {
|
||||
let mut buffers = [[0; 640]; 2];
|
||||
|
||||
let mut write_index = BLOCK_START;
|
||||
let mut write_block = &mut buffers[0];
|
||||
let mut block1_done = false;
|
||||
|
||||
// this is the index from right. It is used to progressively shorten rows
|
||||
let mut prog_row_len = WIDTH - 2;
|
||||
|
||||
for (count, row) in anime.0.iter().enumerate() {
|
||||
// Write the top block of LEDs (first 7 rows)
|
||||
if count < 6 {
|
||||
for (i, x) in row.iter().enumerate() {
|
||||
// Rows 0, 1, 3, 5 are short and misaligned
|
||||
if count == 0 || count == 1 || count == 3 || count == 5 {
|
||||
if i > 0 {
|
||||
write_block[write_index - 1] = *x;
|
||||
}
|
||||
} else {
|
||||
write_block[write_index] = *x;
|
||||
}
|
||||
write_index += 1;
|
||||
}
|
||||
} else {
|
||||
// Switch to next block (looks like )
|
||||
if count % 2 != 0 {
|
||||
// Row after 6 is only 1 less, then rows after 7 follow pattern
|
||||
if count == 7 {
|
||||
prog_row_len -= 1;
|
||||
} else {
|
||||
prog_row_len -= 2;
|
||||
}
|
||||
} else {
|
||||
prog_row_len += 1; // if count 6, 0
|
||||
}
|
||||
|
||||
let index = row.len() - prog_row_len;
|
||||
for n in row.iter().skip(index) {
|
||||
// Require a special case to catch the correct end-of-packet which is
|
||||
// 6 bytes from the end
|
||||
if write_index == BLOCK_END && !block1_done {
|
||||
block1_done = true;
|
||||
write_block = &mut buffers[1];
|
||||
write_index = BLOCK_START;
|
||||
}
|
||||
|
||||
write_block[write_index] = *n;
|
||||
write_index += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
buffers
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::anime_matrix::*;
|
||||
|
||||
use super::AniMeDataBuffer;
|
||||
|
||||
#[test]
|
||||
fn check_from_data_buffer() {
|
||||
let mut data = AniMeDataBuffer::new();
|
||||
data.set([42u8; FULL_PANE_LEN]);
|
||||
|
||||
let out: AniMePacketType = data.into();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_data_alignment() {
|
||||
let mut matrix = AniMeImageBuffer::new();
|
||||
{
|
||||
let tmp = matrix.get_mut();
|
||||
for row in tmp.iter_mut() {
|
||||
let idx = row.len() - 1;
|
||||
row[idx] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
let matrix: AniMePacketType = AniMePacketType::from(matrix);
|
||||
|
||||
// The bytes at the right of the initial AniMeMatrix should always end up aligned in the
|
||||
// same place after conversion to data packets
|
||||
|
||||
// Check against manually worked out right align
|
||||
assert_eq!(
|
||||
matrix[0].to_vec(),
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
]
|
||||
.to_vec()
|
||||
);
|
||||
assert_eq!(
|
||||
matrix[1].to_vec(),
|
||||
[
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0,
|
||||
0, 0, 0, 0
|
||||
]
|
||||
.to_vec()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,7 @@ impl KeyColourArray {
|
||||
Key::VolDown => (0, 15),
|
||||
Key::VolUp => (0, 18),
|
||||
Key::MicMute => (0, 21),
|
||||
Key::ROG => (0, 24),
|
||||
Key::Rog => (0, 24),
|
||||
//
|
||||
Key::Esc => (1, 24),
|
||||
Key::F1 => (1, 30),
|
||||
@@ -186,7 +186,7 @@ pub enum Key {
|
||||
VolUp,
|
||||
VolDown,
|
||||
MicMute,
|
||||
ROG,
|
||||
Rog,
|
||||
Esc,
|
||||
F1,
|
||||
F2,
|
||||
@@ -287,6 +287,7 @@ pub trait KeyLayout {
|
||||
fn get_rows(&self) -> &Vec<[Key; 17]>;
|
||||
}
|
||||
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub struct GX502Layout(Vec<[Key; 17]>);
|
||||
|
||||
impl KeyLayout for GX502Layout {
|
||||
@@ -304,7 +305,7 @@ impl Default for GX502Layout {
|
||||
Key::VolDown,
|
||||
Key::VolUp,
|
||||
Key::MicMute,
|
||||
Key::ROG,
|
||||
Key::Rog,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
use crate::error::AuraError;
|
||||
use gumdrop::Options;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum AniMeStatusValue {
|
||||
On,
|
||||
Off,
|
||||
}
|
||||
impl FromStr for AniMeStatusValue {
|
||||
type Err = AuraError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let s = s.to_lowercase();
|
||||
match s.as_str() {
|
||||
"on" => Ok(AniMeStatusValue::On),
|
||||
"off" => Ok(AniMeStatusValue::Off),
|
||||
_ => {
|
||||
print!("Invalid argument, must be one of: on, off");
|
||||
Err(AuraError::ParseAnime)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl From<AniMeStatusValue> for bool {
|
||||
fn from(value: AniMeStatusValue) -> Self {
|
||||
match value {
|
||||
AniMeStatusValue::On => true,
|
||||
AniMeStatusValue::Off => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
pub struct AniMeLeds {
|
||||
#[options(help = "print help message")]
|
||||
help: bool,
|
||||
#[options(
|
||||
no_long,
|
||||
required,
|
||||
short = "b",
|
||||
meta = "",
|
||||
help = "set all leds brightness value"
|
||||
)]
|
||||
led_brightness: u8,
|
||||
}
|
||||
impl AniMeLeds {
|
||||
pub fn led_brightness(&self) -> u8 {
|
||||
self.led_brightness
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Options)]
|
||||
pub enum AniMeActions {
|
||||
#[options(help = "change all leds brightness")]
|
||||
Leds(AniMeLeds),
|
||||
}
|
||||
@@ -28,6 +28,7 @@ impl Error for AuraError {}
|
||||
#[derive(Debug)]
|
||||
pub enum GraphicsError {
|
||||
ParseVendor,
|
||||
ParsePower,
|
||||
}
|
||||
|
||||
impl fmt::Display for GraphicsError {
|
||||
@@ -35,8 +36,33 @@ impl fmt::Display for GraphicsError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
GraphicsError::ParseVendor => write!(f, "Could not parse vendor name"),
|
||||
GraphicsError::ParsePower => write!(f, "Could not parse dGPU power status"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for GraphicsError {}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AnimeError {
|
||||
InvalidBitmap,
|
||||
Io(std::io::Error),
|
||||
}
|
||||
|
||||
impl fmt::Display for AnimeError {
|
||||
// This trait requires `fmt` with this exact signature.
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
AnimeError::InvalidBitmap => write!(f, "Bitmap is invalid"),
|
||||
AnimeError::Io(e) => write!(f, "Could not open: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for AnimeError {}
|
||||
|
||||
impl From<std::io::Error> for AnimeError {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
AnimeError::Io(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,38 @@ use serde_derive::{Deserialize, Serialize};
|
||||
use std::str::FromStr;
|
||||
use zvariant_derive::Type;
|
||||
|
||||
#[derive(Debug, Type, PartialEq, Copy, Clone, Deserialize, Serialize)]
|
||||
pub enum GfxPower {
|
||||
Active,
|
||||
Suspended,
|
||||
Off,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
impl FromStr for GfxPower {
|
||||
type Err = GraphicsError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, GraphicsError> {
|
||||
match s.to_lowercase().trim() {
|
||||
"active" => Ok(GfxPower::Active),
|
||||
"suspended" => Ok(GfxPower::Suspended),
|
||||
"off" => Ok(GfxPower::Off),
|
||||
_ => Ok(GfxPower::Unknown),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&GfxPower> for &str {
|
||||
fn from(gfx: &GfxPower) -> &'static str {
|
||||
match gfx {
|
||||
GfxPower::Active => "active",
|
||||
GfxPower::Suspended => "suspended",
|
||||
GfxPower::Off => "off",
|
||||
GfxPower::Unknown => "unknown",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Type, PartialEq, Copy, Clone, Deserialize, Serialize)]
|
||||
pub enum GfxVendors {
|
||||
Nvidia,
|
||||
|
||||
@@ -11,15 +11,9 @@ pub mod aura_modes;
|
||||
|
||||
pub mod profile;
|
||||
|
||||
/// Contains mostly only what is required for parsing CLI options
|
||||
pub mod cli_options;
|
||||
|
||||
/// Enables you to create fancy RGB effects
|
||||
pub mod aura_perkey;
|
||||
|
||||
/// Helper functions for the AniMe display
|
||||
pub mod anime_matrix;
|
||||
|
||||
pub mod gfx_vendors;
|
||||
|
||||
pub mod error;
|
||||
|
||||
@@ -13,7 +13,7 @@ pub struct Profile {
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub type CPUSettings = Profile;
|
||||
pub type CpuSettings = Profile;
|
||||
|
||||
impl Default for Profile {
|
||||
fn default() -> Self {
|
||||
|
||||