mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ae0f896cf | |||
| fb0374512d | |||
| 14f031ad34 | |||
| bee5508099 | |||
| c741204200 | |||
| 858c9841a7 | |||
| fdc7d88a70 | |||
| da3017bb89 | |||
| 641e762e80 | |||
| 25ecfda095 | |||
| 31af8f9511 | |||
| 8db783d9b4 | |||
| 45a354880a | |||
| ca1c67e803 | |||
| c819fa458a | |||
| 869ab90299 | |||
| c40029f5e7 | |||
| e864dfb0e7 | |||
| 476b394add | |||
| 4ea5480e66 | |||
| cfc46a2b70 | |||
| 235763a615 | |||
| 6e19c16e70 | |||
| 6ea550b6ff | |||
| dd30c8092b | |||
| 2bd751f841 | |||
| 7a6aafded7 | |||
| 940b93a75f | |||
| 5c70fec29a | |||
| 8ac505e0dd | |||
| 3bdb03b1d8 | |||
| 4ac4909881 | |||
| ec5e6d2e7c | |||
| 5600c51ba0 | |||
| cb5856c4dc | |||
| aad6f6350b | |||
| 1ec45a6449 | |||
| bb612283fe | |||
| bcba11d4ec | |||
| 7eab94bc7f | |||
| e73bbedb41 | |||
| a83ccbd33d | |||
| b5b7799018 | |||
| 24ecb92621 |
Executable
+12
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo '+cargo +nightly fmt --all -- --check'
|
||||||
|
cargo +nightly fmt --all -- --check
|
||||||
|
echo '+cargo clippy --all -- -D warnings'
|
||||||
|
cargo clippy --all -- -D warnings
|
||||||
|
echo '+cargo test --all'
|
||||||
|
cargo test --all
|
||||||
|
echo '+cargo cranky'
|
||||||
|
cargo cranky
|
||||||
Executable
+10
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo '+cargo +nightly fmt --all -- --check'
|
||||||
|
cargo +nightly fmt --all -- --check
|
||||||
|
echo '+cargo clippy --all -- -D warnings'
|
||||||
|
cargo clippy --all -- -D warnings
|
||||||
|
echo '+cargo cranky'
|
||||||
|
cargo cranky
|
||||||
+29
-8
@@ -1,15 +1,15 @@
|
|||||||
image: rust:latest
|
image: rust:latest
|
||||||
|
|
||||||
cache:
|
.rust_cache: &rust_cache
|
||||||
key: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
cache:
|
||||||
paths:
|
# key: $CI_COMMIT_REF_SLUG
|
||||||
|
paths:
|
||||||
# Don't include `incremental` to save space
|
# Don't include `incremental` to save space
|
||||||
# Debug
|
# Debug
|
||||||
- target/debug/build/
|
- target/debug/build/
|
||||||
- target/debug/deps/
|
- target/debug/deps/
|
||||||
- target/debug/.fingerprint/
|
- target/debug/.fingerprint/
|
||||||
- target/debug/.cargo-lock
|
- target/debug/.cargo-lock
|
||||||
- target/debug/df_storyteller
|
|
||||||
# Release
|
# Release
|
||||||
- target/release/build/
|
- target/release/build/
|
||||||
- target/release/deps/
|
- target/release/deps/
|
||||||
@@ -20,14 +20,16 @@ before_script:
|
|||||||
- apt-get update -qq && apt-get install -y -qq libudev-dev libgtk-3-dev grep llvm clang libclang-dev
|
- apt-get update -qq && apt-get install -y -qq libudev-dev libgtk-3-dev grep llvm clang libclang-dev
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- format
|
- format
|
||||||
- check
|
- check
|
||||||
- test
|
- test
|
||||||
- release
|
- release
|
||||||
|
- deploy
|
||||||
|
|
||||||
format:
|
format:
|
||||||
except:
|
except:
|
||||||
- tags
|
- tags
|
||||||
|
<<: *rust_cache
|
||||||
script:
|
script:
|
||||||
- echo "nightly" > rust-toolchain
|
- echo "nightly" > rust-toolchain
|
||||||
- rustup component add rustfmt
|
- rustup component add rustfmt
|
||||||
@@ -36,6 +38,7 @@ format:
|
|||||||
check:
|
check:
|
||||||
except:
|
except:
|
||||||
- tags
|
- tags
|
||||||
|
<<: *rust_cache
|
||||||
script:
|
script:
|
||||||
- rustup component add clippy
|
- rustup component add clippy
|
||||||
- cargo check
|
- cargo check
|
||||||
@@ -46,12 +49,15 @@ check:
|
|||||||
test:
|
test:
|
||||||
except:
|
except:
|
||||||
- tags
|
- tags
|
||||||
|
<<: *rust_cache
|
||||||
script:
|
script:
|
||||||
|
- mkdir -p .git/hooks > /dev/null
|
||||||
- cargo test
|
- cargo test
|
||||||
|
|
||||||
release:
|
release:
|
||||||
only:
|
only:
|
||||||
- tags
|
- tags
|
||||||
|
<<: *rust_cache
|
||||||
script:
|
script:
|
||||||
- make && make vendor
|
- make && make vendor
|
||||||
artifacts:
|
artifacts:
|
||||||
@@ -59,5 +65,20 @@ release:
|
|||||||
- vendor_asusctl_*.tar.xz
|
- vendor_asusctl_*.tar.xz
|
||||||
- cargo-config
|
- cargo-config
|
||||||
|
|
||||||
|
pages:
|
||||||
|
stage: deploy
|
||||||
|
only:
|
||||||
|
- tags
|
||||||
|
<<: *rust_cache
|
||||||
|
script:
|
||||||
|
- cargo doc --document-private-items --no-deps --workspace
|
||||||
|
- rm -rf public
|
||||||
|
- mkdir public
|
||||||
|
- cp -R target/doc/* public
|
||||||
|
- cp misc/index.html public
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- public
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
GIT_SUBMODULE_STRATEGY: normal
|
GIT_SUBMODULE_STRATEGY: normal
|
||||||
|
|||||||
+31
-2
@@ -5,8 +5,35 @@ 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).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
## [v4.6.2]
|
||||||
|
- Fix rog-control-center not reopening if `startup_in_background` is set
|
||||||
|
|
||||||
|
## [v4.6.1]
|
||||||
|
### Added
|
||||||
|
- Support for G733Z LED modes
|
||||||
|
- Support for GU604V LED modes
|
||||||
|
- Support for GX650P LED modes
|
||||||
|
- Support for GV604I LED modes
|
||||||
|
- Support for FX516P LED modes (this laptop still has further issues, will require a patched kernel when patch is ready)
|
||||||
|
- Add device code for the Z13 ACRNM keyboard (requires kernel patch, in progress)
|
||||||
|
- Support for GV301VIC LED modes
|
||||||
|
- Add device code for the plain Z13 keyboard (requires kernel patch, in progress)
|
||||||
|
- Support for GV301V LED modes
|
||||||
|
### Changed
|
||||||
|
- Adjustments to Anime system events thread
|
||||||
|
- Add "sleep" animetion config options to anime config
|
||||||
|
- rog-control-center dark/light mode persistency
|
||||||
|
- Adjustments to keyboard detection
|
||||||
|
- Better support of using supergfxctl when available (tray icon and menu)
|
||||||
|
- Check supergfx version before enabling use in tray (require 5.1.0+)
|
||||||
|
- Update allowed Aura modes on asusd restart if changed
|
||||||
|
- Set tray icon for dgpu to "On" if in Vfio mode to prevent confusion
|
||||||
|
- Add support for Logout/Reboot in notification for KDE
|
||||||
|
|
||||||
|
## [v4.6.0]
|
||||||
### Added
|
### Added
|
||||||
- Support for GL703GE keyboard layout
|
- Support for GL703GE keyboard layout
|
||||||
|
- Support for G533Z modes and keyboard layout
|
||||||
### Changed
|
### Changed
|
||||||
- Better handling of `/etc/asusd` not existing
|
- Better handling of `/etc/asusd` not existing
|
||||||
- Better handling of non-existant config files
|
- Better handling of non-existant config files
|
||||||
@@ -20,6 +47,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- ROGCC: Add CLI opt for viewing all layout files + filenames to help find a layout matching your laptop
|
- ROGCC: Add CLI opt for viewing all layout files + filenames to help find a layout matching your laptop
|
||||||
+ Both of these options would hopefully be temporary and replaced with a "wizard" GUI helper
|
+ Both of these options would hopefully be temporary and replaced with a "wizard" GUI helper
|
||||||
- Fix profile controller not detecting if platform_profile is changed
|
- Fix profile controller not detecting if platform_profile is changed
|
||||||
|
- Fix remove the leftover initial config writes on `new()` for some controllers to prevent resetting settings on startup
|
||||||
|
+ refactor the loading of systemd curve defaults and config file
|
||||||
### BREAKING
|
### BREAKING
|
||||||
- Rename aura dbus method from `per_key_raw` to `direct_addressing_raw` and add doc comment
|
- Rename aura dbus method from `per_key_raw` to `direct_addressing_raw` and add doc comment
|
||||||
- Changes to aura.conf:
|
- Changes to aura.conf:
|
||||||
@@ -39,7 +68,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
## [v4.5.7]
|
## [v4.5.7]
|
||||||
### Changed
|
### Changed
|
||||||
- ROGCC: Don't notify user if changing to same mux mode
|
- ROGCC: Don't notify user if changing to same mux mode
|
||||||
-
|
-
|
||||||
|
|
||||||
## [v4.5.7]
|
## [v4.5.7]
|
||||||
### Changed
|
### Changed
|
||||||
@@ -604,4 +633,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
- Fix small deadlock with awaits
|
- Fix small deadlock with awaits
|
||||||
|
|
||||||
## [1.0.0]
|
## [1.0.0]
|
||||||
Generated
+880
-968
File diff suppressed because it is too large
Load Diff
+8
-1
@@ -2,7 +2,7 @@
|
|||||||
members = ["asusctl", "config-traits", "daemon", "daemon-user", "rog-platform", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center"]
|
members = ["asusctl", "config-traits", "daemon", "daemon-user", "rog-platform", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "4.6.0-rc1"
|
version = "4.6.2"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
async-trait = "^0.1"
|
async-trait = "^0.1"
|
||||||
@@ -35,6 +35,8 @@ pix = "^0.13"
|
|||||||
tinybmp = "^0.4.0"
|
tinybmp = "^0.4.0"
|
||||||
gif = "^0.12.0"
|
gif = "^0.12.0"
|
||||||
|
|
||||||
|
versions = "4.1"
|
||||||
|
|
||||||
notify-rust = { git = "https://github.com/flukejones/notify-rust.git", default-features = false, features = ["z"] }
|
notify-rust = { git = "https://github.com/flukejones/notify-rust.git", default-features = false, features = ["z"] }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
@@ -52,3 +54,8 @@ opt-level = 1
|
|||||||
[profile.bench]
|
[profile.bench]
|
||||||
debug = false
|
debug = false
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
||||||
|
[workspace.dependencies.cargo-husky]
|
||||||
|
version = "1"
|
||||||
|
default-features = false
|
||||||
|
features = ["user-hooks"]
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
# https://github.com/ericseppanen/cargo-cranky
|
# https://github.com/ericseppanen/cargo-cranky
|
||||||
# cargo install cargo-cranky && cargo cranky
|
# cargo install cargo-cranky && cargo cranky
|
||||||
|
|
||||||
warn = [
|
error = [
|
||||||
"clippy::all",
|
"clippy::all",
|
||||||
"clippy::await_holding_lock",
|
"clippy::await_holding_lock",
|
||||||
"clippy::bool_to_int_with_if",
|
"clippy::bool_to_int_with_if",
|
||||||
|
|||||||
@@ -38,16 +38,18 @@ clean:
|
|||||||
distclean:
|
distclean:
|
||||||
rm -rf .cargo vendor vendor.tar.xz
|
rm -rf .cargo vendor vendor.tar.xz
|
||||||
|
|
||||||
install:
|
install-program:
|
||||||
$(INSTALL_PROGRAM) "./target/release/$(BIN_ROG)" "$(DESTDIR)$(bindir)/$(BIN_ROG)"
|
$(INSTALL_PROGRAM) "./target/release/$(BIN_ROG)" "$(DESTDIR)$(bindir)/$(BIN_ROG)"
|
||||||
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).desktop" "$(DESTDIR)$(datarootdir)/applications/$(BIN_ROG).desktop"
|
|
||||||
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/$(BIN_ROG).png"
|
|
||||||
cd rog-aura/data/layouts && find . -type f -name "*.ron" -exec $(INSTALL_DATA) "{}" "$(DESTDIR)$(datarootdir)/rog-gui/layouts/{}" \;
|
|
||||||
|
|
||||||
$(INSTALL_PROGRAM) "./target/release/$(BIN_C)" "$(DESTDIR)$(bindir)/$(BIN_C)"
|
$(INSTALL_PROGRAM) "./target/release/$(BIN_C)" "$(DESTDIR)$(bindir)/$(BIN_C)"
|
||||||
$(INSTALL_PROGRAM) "./target/release/$(BIN_D)" "$(DESTDIR)$(bindir)/$(BIN_D)"
|
$(INSTALL_PROGRAM) "./target/release/$(BIN_D)" "$(DESTDIR)$(bindir)/$(BIN_D)"
|
||||||
$(INSTALL_PROGRAM) "./target/release/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)"
|
$(INSTALL_PROGRAM) "./target/release/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)"
|
||||||
|
|
||||||
|
install-data:
|
||||||
|
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).desktop" "$(DESTDIR)$(datarootdir)/applications/$(BIN_ROG).desktop"
|
||||||
|
$(INSTALL_DATA) "./rog-control-center/data/$(BIN_ROG).png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/$(BIN_ROG).png"
|
||||||
|
cd rog-aura/data/layouts && find . -type f -name "*.ron" -exec $(INSTALL_DATA) "{}" "$(DESTDIR)$(datarootdir)/rog-gui/layouts/{}" \;
|
||||||
|
|
||||||
$(INSTALL_DATA) "./data/$(BIN_D).rules" "$(DESTDIR)$(libdir)/udev/rules.d/99-$(BIN_D).rules"
|
$(INSTALL_DATA) "./data/$(BIN_D).rules" "$(DESTDIR)$(libdir)/udev/rules.d/99-$(BIN_D).rules"
|
||||||
$(INSTALL_DATA) "./rog-aura/data/$(LEDCFG)" "$(DESTDIR)$(datarootdir)/asusd/$(LEDCFG)"
|
$(INSTALL_DATA) "./rog-aura/data/$(LEDCFG)" "$(DESTDIR)$(datarootdir)/asusd/$(LEDCFG)"
|
||||||
$(INSTALL_DATA) "./data/$(BIN_D).conf" "$(DESTDIR)$(datarootdir)/dbus-1/system.d/$(BIN_D).conf"
|
$(INSTALL_DATA) "./data/$(BIN_D).conf" "$(DESTDIR)$(datarootdir)/dbus-1/system.d/$(BIN_D).conf"
|
||||||
@@ -71,6 +73,8 @@ install:
|
|||||||
|
|
||||||
cd rog-anime/data && find "./anime" -type f -exec $(INSTALL_DATA) "{}" "$(DESTDIR)$(datarootdir)/asusd/{}" \;
|
cd rog-anime/data && find "./anime" -type f -exec $(INSTALL_DATA) "{}" "$(DESTDIR)$(datarootdir)/asusd/{}" \;
|
||||||
|
|
||||||
|
install: install-program install-data
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f "$(DESTDIR)$(bindir)/$(BIN_ROG)"
|
rm -f "$(DESTDIR)$(bindir)/$(BIN_ROG)"
|
||||||
rm -r "$(DESTDIR)$(datarootdir)/applications/$(BIN_ROG).desktop"
|
rm -r "$(DESTDIR)$(datarootdir)/applications/$(BIN_ROG).desktop"
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ Requirements are rust >= 1.57 installed from rustup.io if the distro provided ve
|
|||||||
|
|
||||||
**popos (unsuported):**
|
**popos (unsuported):**
|
||||||
|
|
||||||
sudo apt install cmake libclang-dev libudev-dev libgtk-3-dev ibclang-dev libglib2.0-dev libatkmm-1.6-dev libpangomm-1.4-dev librust-gdk-pixbuf-dev
|
sudo apt install cmake libclang-dev libudev-dev libgtk-3-dev libclang-dev libglib2.0-dev libatkmm-1.6-dev libpangomm-1.4-dev librust-gdk-pixbuf-dev
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||||
source "$HOME/.cargo/env"
|
source "$HOME/.cargo/env"
|
||||||
make
|
make
|
||||||
@@ -91,7 +91,7 @@ Requirements are rust >= 1.57 installed from rustup.io if the distro provided ve
|
|||||||
|
|
||||||
**fedora:**
|
**fedora:**
|
||||||
|
|
||||||
dnf install cmake clang-devel systemd-devel glib2-devel cairo-devel atkmm-devel pangomm-devel gdk-pixbuf-devel gtk3-devel libappindicator-gtk3
|
dnf install cmake clang-devel systemd-devel glib2-devel cairo-devel atkmm-devel pangomm-devel gdk-pixbuf2-devel gtk3-devel libappindicator-gtk3
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ Requirements are rust >= 1.57 installed from rustup.io if the distro provided ve
|
|||||||
Works with KDE Plasma (without GTK packages)
|
Works with KDE Plasma (without GTK packages)
|
||||||
|
|
||||||
zypper in -t pattern devel_basis
|
zypper in -t pattern devel_basis
|
||||||
zypper in rustup cmake clang-devel systemd-devel glib2-devel cairo-devel atkmm-devel pangomm-devel gdk-pixbuf-devel gtk3-devel
|
zypper in rustup make cmake systemd-devel clang-devel llvm-devel gdk-pixbuf-devel cairo-devel pango-devel freetype-devel gtk3-devel libexpat-devel libayatana-indicator3-7
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
|
|
||||||
@@ -126,6 +126,10 @@ You may also need to activate the service for debian install. If running Pop!_OS
|
|||||||
|
|
||||||
Run `sudo make uninstall` in the source repo, and remove `/etc/asusd/`.
|
Run `sudo make uninstall` in the source repo, and remove `/etc/asusd/`.
|
||||||
|
|
||||||
|
# Contributing
|
||||||
|
|
||||||
|
See `CONTRIBUTING.md`. Additionally, also do `cargo clean` and `cargo test` on first checkout to ensure the commit hooks are used (via `cargo-husky`).
|
||||||
|
|
||||||
# OTHER
|
# OTHER
|
||||||
|
|
||||||
## Supporting more laptops
|
## Supporting more laptops
|
||||||
|
|||||||
@@ -22,3 +22,5 @@ gif.workspace = true
|
|||||||
tinybmp.workspace = true
|
tinybmp.workspace = true
|
||||||
glam.workspace = true
|
glam.workspace = true
|
||||||
rog_dbus = { path = "../rog-dbus" }
|
rog_dbus = { path = "../rog-dbus" }
|
||||||
|
|
||||||
|
cargo-husky.workspace = true
|
||||||
+41
-43
@@ -10,7 +10,7 @@ use gumdrop::{Opt, Options};
|
|||||||
use profiles_cli::{FanCurveCommand, ProfileCommand};
|
use profiles_cli::{FanCurveCommand, ProfileCommand};
|
||||||
use rog_anime::usb::get_anime_type;
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, Vec2};
|
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, Vec2};
|
||||||
use rog_aura::usb::{AuraDev1866, AuraDev19b6, AuraDevTuf, AuraDevice, AuraPowerDev};
|
use rog_aura::usb::{AuraDevRog1, AuraDevRog2, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||||
use rog_aura::{self, AuraEffect};
|
use rog_aura::{self, AuraEffect};
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::RogDbusClientBlocking;
|
||||||
use rog_platform::platform::GpuMode;
|
use rog_platform::platform::GpuMode;
|
||||||
@@ -36,15 +36,14 @@ fn main() {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("source {}", err);
|
panic!("source {}", err);
|
||||||
std::process::exit(2);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let (dbus, _) = RogDbusClientBlocking::new()
|
let (dbus, _) = RogDbusClientBlocking::new()
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
print_error_help(&e, None);
|
print_error_help(&e, None);
|
||||||
std::process::exit(3);
|
panic!("Could not start dbus client");
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -54,7 +53,7 @@ fn main() {
|
|||||||
.supported_functions()
|
.supported_functions()
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
print_error_help(&e, None);
|
print_error_help(&e, None);
|
||||||
std::process::exit(4);
|
panic!("Could not start dbus proxy");
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -158,7 +157,7 @@ fn do_parsed(
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if supported.keyboard_led.dev_id != AuraDevice::X19B6
|
if supported.keyboard_led.dev_id != AuraDevice::X19b6
|
||||||
&& command.trim().starts_with("led-pow-2")
|
&& command.trim().starts_with("led-pow-2")
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -260,7 +259,7 @@ fn handle_anime(
|
|||||||
if let Some(lst) = image.self_command_list() {
|
if let Some(lst) = image.self_command_list() {
|
||||||
println!("\n{}", lst);
|
println!("\n{}", lst);
|
||||||
}
|
}
|
||||||
std::process::exit(1);
|
return Ok(());
|
||||||
}
|
}
|
||||||
verify_brightness(image.bright);
|
verify_brightness(image.bright);
|
||||||
|
|
||||||
@@ -283,7 +282,7 @@ fn handle_anime(
|
|||||||
if let Some(lst) = image.self_command_list() {
|
if let Some(lst) = image.self_command_list() {
|
||||||
println!("\n{}", lst);
|
println!("\n{}", lst);
|
||||||
}
|
}
|
||||||
std::process::exit(1);
|
return Ok(());
|
||||||
}
|
}
|
||||||
verify_brightness(image.bright);
|
verify_brightness(image.bright);
|
||||||
|
|
||||||
@@ -304,7 +303,7 @@ fn handle_anime(
|
|||||||
if let Some(lst) = gif.self_command_list() {
|
if let Some(lst) = gif.self_command_list() {
|
||||||
println!("\n{}", lst);
|
println!("\n{}", lst);
|
||||||
}
|
}
|
||||||
std::process::exit(1);
|
return Ok(());
|
||||||
}
|
}
|
||||||
verify_brightness(gif.bright);
|
verify_brightness(gif.bright);
|
||||||
|
|
||||||
@@ -338,7 +337,7 @@ fn handle_anime(
|
|||||||
if let Some(lst) = gif.self_command_list() {
|
if let Some(lst) = gif.self_command_list() {
|
||||||
println!("\n{}", lst);
|
println!("\n{}", lst);
|
||||||
}
|
}
|
||||||
std::process::exit(1);
|
return Ok(());
|
||||||
}
|
}
|
||||||
verify_brightness(gif.bright);
|
verify_brightness(gif.bright);
|
||||||
|
|
||||||
@@ -374,7 +373,6 @@ fn verify_brightness(brightness: f32) {
|
|||||||
"Image and global brightness must be between 0.0 and 1.0 (inclusive), was {}",
|
"Image and global brightness must be between 0.0 and 1.0 (inclusive), was {}",
|
||||||
brightness
|
brightness
|
||||||
);
|
);
|
||||||
std::process::exit(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,7 +389,7 @@ fn handle_led_mode(
|
|||||||
println!("Commands available");
|
println!("Commands available");
|
||||||
|
|
||||||
if let Some(cmdlist) = LedModeCommand::command_list() {
|
if let Some(cmdlist) = LedModeCommand::command_list() {
|
||||||
let commands: Vec<String> = cmdlist.lines().map(|s| s.to_string()).collect();
|
let commands: Vec<String> = cmdlist.lines().map(|s| s.to_owned()).collect();
|
||||||
for command in commands.iter().filter(|command| {
|
for command in commands.iter().filter(|command| {
|
||||||
for mode in &supported.basic_modes {
|
for mode in &supported.basic_modes {
|
||||||
if command
|
if command
|
||||||
@@ -474,10 +472,10 @@ fn handle_led_power_1_do_1866(
|
|||||||
dbus: &RogDbusClientBlocking<'_>,
|
dbus: &RogDbusClientBlocking<'_>,
|
||||||
power: &LedPowerCommand1,
|
power: &LedPowerCommand1,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut enabled: Vec<AuraDev1866> = Vec::new();
|
let mut enabled: Vec<AuraDevRog1> = Vec::new();
|
||||||
let mut disabled: Vec<AuraDev1866> = Vec::new();
|
let mut disabled: Vec<AuraDevRog1> = Vec::new();
|
||||||
|
|
||||||
let mut check = |e: Option<bool>, a: AuraDev1866| {
|
let mut check = |e: Option<bool>, a: AuraDevRog1| {
|
||||||
if let Some(arg) = e {
|
if let Some(arg) = e {
|
||||||
if arg {
|
if arg {
|
||||||
enabled.push(a);
|
enabled.push(a);
|
||||||
@@ -487,11 +485,11 @@ fn handle_led_power_1_do_1866(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
check(power.awake, AuraDev1866::Awake);
|
check(power.awake, AuraDevRog1::Awake);
|
||||||
check(power.boot, AuraDev1866::Boot);
|
check(power.boot, AuraDevRog1::Boot);
|
||||||
check(power.sleep, AuraDev1866::Sleep);
|
check(power.sleep, AuraDevRog1::Sleep);
|
||||||
check(power.keyboard, AuraDev1866::Keyboard);
|
check(power.keyboard, AuraDevRog1::Keyboard);
|
||||||
check(power.lightbar, AuraDev1866::Lightbar);
|
check(power.lightbar, AuraDevRog1::Lightbar);
|
||||||
|
|
||||||
let data = AuraPowerDev {
|
let data = AuraPowerDev {
|
||||||
x1866: enabled,
|
x1866: enabled,
|
||||||
@@ -578,13 +576,13 @@ fn handle_led_power2(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if supported.dev_id != AuraDevice::X19B6 {
|
if supported.dev_id != AuraDevice::X19b6 {
|
||||||
println!("This option applies only to keyboards with product ID 0x19b6");
|
println!("This option applies only to keyboards with product ID 0x19b6");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut enabled: Vec<AuraDev19b6> = Vec::new();
|
let mut enabled: Vec<AuraDevRog2> = Vec::new();
|
||||||
let mut disabled: Vec<AuraDev19b6> = Vec::new();
|
let mut disabled: Vec<AuraDevRog2> = Vec::new();
|
||||||
let mut check = |e: Option<bool>, a: AuraDev19b6| {
|
let mut check = |e: Option<bool>, a: AuraDevRog2| {
|
||||||
if let Some(arg) = e {
|
if let Some(arg) = e {
|
||||||
if arg {
|
if arg {
|
||||||
enabled.push(a);
|
enabled.push(a);
|
||||||
@@ -596,28 +594,28 @@ fn handle_led_power2(
|
|||||||
|
|
||||||
match pow {
|
match pow {
|
||||||
aura_cli::SetAuraEnabled::Boot(arg) => {
|
aura_cli::SetAuraEnabled::Boot(arg) => {
|
||||||
check(arg.keyboard, AuraDev19b6::BootKeyb);
|
check(arg.keyboard, AuraDevRog2::BootKeyb);
|
||||||
check(arg.logo, AuraDev19b6::BootLogo);
|
check(arg.logo, AuraDevRog2::BootLogo);
|
||||||
check(arg.lightbar, AuraDev19b6::BootBar);
|
check(arg.lightbar, AuraDevRog2::BootBar);
|
||||||
check(arg.lid, AuraDev19b6::AwakeLid);
|
check(arg.lid, AuraDevRog2::AwakeLid);
|
||||||
}
|
}
|
||||||
aura_cli::SetAuraEnabled::Sleep(arg) => {
|
aura_cli::SetAuraEnabled::Sleep(arg) => {
|
||||||
check(arg.keyboard, AuraDev19b6::SleepKeyb);
|
check(arg.keyboard, AuraDevRog2::SleepKeyb);
|
||||||
check(arg.logo, AuraDev19b6::SleepLogo);
|
check(arg.logo, AuraDevRog2::SleepLogo);
|
||||||
check(arg.lightbar, AuraDev19b6::SleepBar);
|
check(arg.lightbar, AuraDevRog2::SleepBar);
|
||||||
check(arg.lid, AuraDev19b6::SleepLid);
|
check(arg.lid, AuraDevRog2::SleepLid);
|
||||||
}
|
}
|
||||||
aura_cli::SetAuraEnabled::Awake(arg) => {
|
aura_cli::SetAuraEnabled::Awake(arg) => {
|
||||||
check(arg.keyboard, AuraDev19b6::AwakeKeyb);
|
check(arg.keyboard, AuraDevRog2::AwakeKeyb);
|
||||||
check(arg.logo, AuraDev19b6::AwakeLogo);
|
check(arg.logo, AuraDevRog2::AwakeLogo);
|
||||||
check(arg.lightbar, AuraDev19b6::AwakeBar);
|
check(arg.lightbar, AuraDevRog2::AwakeBar);
|
||||||
check(arg.lid, AuraDev19b6::AwakeLid);
|
check(arg.lid, AuraDevRog2::AwakeLid);
|
||||||
}
|
}
|
||||||
aura_cli::SetAuraEnabled::Shutdown(arg) => {
|
aura_cli::SetAuraEnabled::Shutdown(arg) => {
|
||||||
check(arg.keyboard, AuraDev19b6::ShutdownKeyb);
|
check(arg.keyboard, AuraDevRog2::ShutdownKeyb);
|
||||||
check(arg.logo, AuraDev19b6::ShutdownLogo);
|
check(arg.logo, AuraDevRog2::ShutdownLogo);
|
||||||
check(arg.lightbar, AuraDev19b6::ShutdownBar);
|
check(arg.lightbar, AuraDevRog2::ShutdownBar);
|
||||||
check(arg.lid, AuraDev19b6::ShutdownBar);
|
check(arg.lid, AuraDevRog2::ShutdownBar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,7 +660,7 @@ fn handle_profile(
|
|||||||
if let Some(lst) = cmd.self_command_list() {
|
if let Some(lst) = cmd.self_command_list() {
|
||||||
println!("\n{}", lst);
|
println!("\n{}", lst);
|
||||||
}
|
}
|
||||||
std::process::exit(1);
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.next {
|
if cmd.next {
|
||||||
@@ -706,14 +704,14 @@ fn handle_fan_curve(
|
|||||||
if let Some(lst) = cmd.self_command_list() {
|
if let Some(lst) = cmd.self_command_list() {
|
||||||
println!("\n{}", lst);
|
println!("\n{}", lst);
|
||||||
}
|
}
|
||||||
std::process::exit(1);
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd.enabled.is_some() || cmd.fan.is_some() || cmd.data.is_some())
|
if (cmd.enabled.is_some() || cmd.fan.is_some() || cmd.data.is_some())
|
||||||
&& cmd.mod_profile.is_none()
|
&& cmd.mod_profile.is_none()
|
||||||
{
|
{
|
||||||
println!("--enabled, --fan, and --data options require --mod-profile");
|
println!("--enabled, --fan, and --data options require --mod-profile");
|
||||||
std::process::exit(666);
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.get_enabled {
|
if cmd.get_enabled {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "config-traits"
|
name = "config-traits"
|
||||||
version = "0.1.0"
|
license = "MPL-2.0"
|
||||||
|
authors = ["Luke D Jones <luke@ljones.dev>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
version.workspace = true
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
@@ -12,4 +12,7 @@ serde_json.workspace = true
|
|||||||
toml.workspace = true
|
toml.workspace = true
|
||||||
ron.workspace = true
|
ron.workspace = true
|
||||||
|
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
cargo-husky.workspace = true
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# config-traits
|
||||||
|
|
||||||
|
`config_traits` is a crate that broke out from the requirement to manage various
|
||||||
|
different config files, including parsing from different formats and updating
|
||||||
|
them from previous versions where fields or names are changed in some way.
|
||||||
|
|
||||||
|
The end canonical file format is `.ron` as this supports rust types well, and includes
|
||||||
|
the ability to add commenting, and is less verbose than `json`. Currently the crate will
|
||||||
|
also try to parse from `json` and `toml` if the `ron` parsing fails, then update to `ron`
|
||||||
|
format.
|
||||||
+38
-27
@@ -1,4 +1,14 @@
|
|||||||
use std::fs::{create_dir, File, OpenOptions};
|
//! `config_traits` is a crate that broke out from the requirement to manage
|
||||||
|
//! various different config files, including parsing from different formats and
|
||||||
|
//! updating them from previous versions where fields or names are changed in
|
||||||
|
//! some way.
|
||||||
|
//!
|
||||||
|
//! The end canonical file format is `.ron` as this supports rust types well,
|
||||||
|
//! and includes the ability to add commenting, and is less verbose than `json`.
|
||||||
|
//! Currently the crate will also try to parse from `json` and `toml` if the
|
||||||
|
//! `ron` parsing fails, then update to `ron` format.
|
||||||
|
|
||||||
|
use std::fs::{self, create_dir, File, OpenOptions};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
@@ -49,7 +59,7 @@ where
|
|||||||
"Could not rename. Please remove {} then restart service: Error {}",
|
"Could not rename. Please remove {} then restart service: Error {}",
|
||||||
self.file_name(),
|
self.file_name(),
|
||||||
err
|
err
|
||||||
)
|
);
|
||||||
});
|
});
|
||||||
do_rename = false;
|
do_rename = false;
|
||||||
}
|
}
|
||||||
@@ -68,7 +78,7 @@ where
|
|||||||
"Could not rename. Please remove {} then restart service: Error {}",
|
"Could not rename. Please remove {} then restart service: Error {}",
|
||||||
self.file_name(),
|
self.file_name(),
|
||||||
err
|
err
|
||||||
)
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
config
|
config
|
||||||
@@ -88,18 +98,10 @@ where
|
|||||||
|
|
||||||
/// Open and parse the config file to self from ron format
|
/// Open and parse the config file to self from ron format
|
||||||
fn read(&mut self) {
|
fn read(&mut self) {
|
||||||
let mut file = match OpenOptions::new().read(true).open(self.file_path()) {
|
if let Ok(data) = fs::read_to_string(self.file_path()) {
|
||||||
Ok(data) => data,
|
if data.is_empty() {
|
||||||
Err(err) => {
|
|
||||||
error!("Error reading {:?}: {}", self.file_path(), err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let mut buf = String::new();
|
|
||||||
if let Ok(l) = file.read_to_string(&mut buf) {
|
|
||||||
if l == 0 {
|
|
||||||
warn!("File is empty {:?}", self.file_path());
|
warn!("File is empty {:?}", self.file_path());
|
||||||
} else if let Ok(data) = ron::from_str(&buf) {
|
} else if let Ok(data) = ron::from_str(&data) {
|
||||||
*self = data;
|
*self = data;
|
||||||
} else {
|
} else {
|
||||||
warn!("Could not deserialise {:?}", self.file_path());
|
warn!("Could not deserialise {:?}", self.file_path());
|
||||||
@@ -137,13 +139,14 @@ where
|
|||||||
self.file_name(),
|
self.file_name(),
|
||||||
self.file_name()
|
self.file_name()
|
||||||
);
|
);
|
||||||
let cfg_old = self.file_path().to_string_lossy().to_string() + "-old";
|
let mut cfg_old = self.file_path().to_string_lossy().to_string();
|
||||||
|
cfg_old.push_str("-old");
|
||||||
std::fs::rename(self.file_path(), cfg_old).unwrap_or_else(|err| {
|
std::fs::rename(self.file_path(), cfg_old).unwrap_or_else(|err| {
|
||||||
error!(
|
error!(
|
||||||
"Could not rename. Please remove {} then restart service: Error {}",
|
"Could not rename. Please remove {} then restart service: Error {}",
|
||||||
self.file_name(),
|
self.file_name(),
|
||||||
err
|
err
|
||||||
)
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,13 +163,13 @@ macro_rules! std_config_load {
|
|||||||
/// use serde::{Deserialize, Serialize};
|
/// use serde::{Deserialize, Serialize};
|
||||||
/// use config_traits::{StdConfig, StdConfigLoad2};
|
/// use config_traits::{StdConfig, StdConfigLoad2};
|
||||||
///
|
///
|
||||||
/// #[derive(Deserialize, Serialize)]
|
/// #[derive(Deserialize, Serialize, Debug)]
|
||||||
/// struct FanCurveConfigOld {}
|
/// struct FanCurveConfigOld {}
|
||||||
///
|
///
|
||||||
/// #[derive(Deserialize, Serialize)]
|
/// #[derive(Deserialize, Serialize, Debug)]
|
||||||
/// struct FanCurveConfigOlder {}
|
/// struct FanCurveConfigOlder {}
|
||||||
///
|
///
|
||||||
/// #[derive(Deserialize, Serialize)]
|
/// #[derive(Deserialize, Serialize, Debug)]
|
||||||
/// struct FanCurveConfig {}
|
/// struct FanCurveConfig {}
|
||||||
///
|
///
|
||||||
/// impl From<FanCurveConfigOld> for FanCurveConfig {
|
/// impl From<FanCurveConfigOld> for FanCurveConfig {
|
||||||
@@ -192,7 +195,7 @@ macro_rules! std_config_load {
|
|||||||
/// new one created
|
/// new one created
|
||||||
pub trait $trait_name<$($generic),*>
|
pub trait $trait_name<$($generic),*>
|
||||||
where
|
where
|
||||||
Self: $crate::StdConfig + DeserializeOwned + Serialize,
|
Self: $crate::StdConfig +std::fmt::Debug + DeserializeOwned + Serialize,
|
||||||
$($generic: DeserializeOwned + Into<Self>),*
|
$($generic: DeserializeOwned + Into<Self>),*
|
||||||
{
|
{
|
||||||
fn load(mut self) -> Self {
|
fn load(mut self) -> Self {
|
||||||
@@ -202,14 +205,22 @@ macro_rules! std_config_load {
|
|||||||
if read_len != 0 {
|
if read_len != 0 {
|
||||||
if let Ok(data) = ron::from_str(&buf) {
|
if let Ok(data) = ron::from_str(&buf) {
|
||||||
self = data;
|
self = data;
|
||||||
|
log::info!("Parsed RON for {:?}", std::any::type_name::<Self>());
|
||||||
} else if let Ok(data) = serde_json::from_str(&buf) {
|
} else if let Ok(data) = serde_json::from_str(&buf) {
|
||||||
self = data;
|
self = data;
|
||||||
|
log::info!("Parsed JSON for {:?}", std::any::type_name::<Self>());
|
||||||
} else if let Ok(data) = toml::from_str(&buf) {
|
} else if let Ok(data) = toml::from_str(&buf) {
|
||||||
self = data;
|
self = data;
|
||||||
} $(else if let Ok(data) = serde_json::from_str::<$generic>(&buf) {
|
log::info!("Parsed TOML for {:?}", std::any::type_name::<Self>());
|
||||||
|
} $(else if let Ok(data) = ron::from_str::<$generic>(&buf) {
|
||||||
self = data.into();
|
self = data.into();
|
||||||
|
log::info!("New version failed, trying previous: Parsed RON for {:?}", std::any::type_name::<$generic>());
|
||||||
|
} else if let Ok(data) = serde_json::from_str::<$generic>(&buf) {
|
||||||
|
self = data.into();
|
||||||
|
log::info!("New version failed, trying previous: Parsed JSON for {:?}", std::any::type_name::<$generic>());
|
||||||
} else if let Ok(data) = toml::from_str::<$generic>(&buf) {
|
} else if let Ok(data) = toml::from_str::<$generic>(&buf) {
|
||||||
self = data.into();
|
self = data.into();
|
||||||
|
log::info!("Newvious version failed, trying previous: Parsed TOML for {:?}", std::any::type_name::<$generic>());
|
||||||
})* else {
|
})* else {
|
||||||
self.rename_file_old();
|
self.rename_file_old();
|
||||||
self = Self::new();
|
self = Self::new();
|
||||||
@@ -237,10 +248,10 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_macro_from_1() {
|
fn check_macro_from_1() {
|
||||||
#[derive(serde::Deserialize, serde::Serialize)]
|
#[derive(serde::Deserialize, serde::Serialize, Debug)]
|
||||||
struct Test {}
|
struct Test {}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, serde::Serialize)]
|
#[derive(serde::Deserialize, serde::Serialize, Debug)]
|
||||||
struct Old1 {}
|
struct Old1 {}
|
||||||
|
|
||||||
impl crate::StdConfig for Test {
|
impl crate::StdConfig for Test {
|
||||||
@@ -268,16 +279,16 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_macro_from_3() {
|
fn check_macro_from_3() {
|
||||||
#[derive(serde::Deserialize, serde::Serialize)]
|
#[derive(serde::Deserialize, serde::Serialize, Debug)]
|
||||||
struct Test {}
|
struct Test {}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, serde::Serialize)]
|
#[derive(serde::Deserialize, serde::Serialize, Debug)]
|
||||||
struct Old1 {}
|
struct Old1 {}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, serde::Serialize)]
|
#[derive(serde::Deserialize, serde::Serialize, Debug)]
|
||||||
struct Old2 {}
|
struct Old2 {}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, serde::Serialize)]
|
#[derive(serde::Deserialize, serde::Serialize, Debug)]
|
||||||
struct Old3 {}
|
struct Old3 {}
|
||||||
|
|
||||||
impl crate::StdConfig for Test {
|
impl crate::StdConfig for Test {
|
||||||
|
|||||||
@@ -33,4 +33,7 @@ zbus.workspace = true
|
|||||||
|
|
||||||
# cli and logging
|
# cli and logging
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
env_logger.workspace = true
|
env_logger.workspace = true
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
cargo-husky.workspace = true
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
use std::fs::OpenOptions;
|
use std::io::Write;
|
||||||
use std::io::{Read, Write};
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
@@ -78,17 +77,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
// if supported.keyboard_led.per_key_led_mode {
|
// if supported.keyboard_led.per_key_led_mode {
|
||||||
if let Some(cfg) = config.active_aura {
|
if let Some(cfg) = config.active_aura {
|
||||||
let mut aura_config = ConfigAura::new().set_name(cfg).load();
|
let mut aura_config = ConfigAura::new().set_name(cfg).load();
|
||||||
|
// let baord_name = std::fs::read_to_string(BOARD_NAME)?;
|
||||||
// Find and load a matching layout for laptop
|
|
||||||
let mut file = OpenOptions::new()
|
|
||||||
.read(true)
|
|
||||||
.open(PathBuf::from(BOARD_NAME))
|
|
||||||
.map_err(|e| {
|
|
||||||
println!("{BOARD_NAME}, {e}");
|
|
||||||
e
|
|
||||||
})?;
|
|
||||||
let mut board_name = String::new();
|
|
||||||
file.read_to_string(&mut board_name)?;
|
|
||||||
|
|
||||||
let led_support = LaptopLedData::get_data();
|
let led_support = LaptopLedData::get_data();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! # DBus interface proxy for: `org.asuslinux.Daemon`
|
//! # `DBus` interface proxy for: `org.asuslinux.Daemon`
|
||||||
//!
|
//!
|
||||||
//! This code was generated by `zbus-xmlgen` `1.0.0` from DBus introspection
|
//! This code was generated by `zbus-xmlgen` `1.0.0` from `DBus` introspection
|
||||||
//! data. Source: `Interface '/org/asuslinux/Anime' from service
|
//! data. Source: `Interface '/org/asuslinux/Anime' from service
|
||||||
//! 'org.asuslinux.Daemon' on session bus`.
|
//! 'org.asuslinux.Daemon' on session bus`.
|
||||||
//!
|
//!
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
//! [Writing a client proxy](https://dbus.pages.freedesktop.org/zbus/client.html)
|
//! [Writing a client proxy](https://dbus.pages.freedesktop.org/zbus/client.html)
|
||||||
//! section of the zbus documentation.
|
//! section of the zbus documentation.
|
||||||
//!
|
//!
|
||||||
//! This DBus object implements
|
//! This `DBus` object implements
|
||||||
//! [standard DBus interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
|
//! [standard `DBus` interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
|
||||||
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
|
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
|
||||||
//!
|
//!
|
||||||
//! * [`zbus::fdo::PeerProxy`]
|
//! * [`zbus::fdo::PeerProxy`]
|
||||||
|
|||||||
+4
-1
@@ -44,4 +44,7 @@ sysfs-class.workspace = true # used for backlight control and baord ID
|
|||||||
|
|
||||||
concat-idents.workspace = true
|
concat-idents.workspace = true
|
||||||
|
|
||||||
systemd-zbus = "*"
|
systemd-zbus = "*"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
cargo-husky.workspace = true
|
||||||
@@ -3,7 +3,7 @@ use serde_derive::{Deserialize, Serialize};
|
|||||||
|
|
||||||
const CONFIG_FILE: &str = "asusd.ron";
|
const CONFIG_FILE: &str = "asusd.ron";
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Default)]
|
#[derive(Deserialize, Serialize, Default, Debug)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// Save charge limit for restoring on boot
|
/// Save charge limit for restoring on boot
|
||||||
pub bat_charge_limit: u8,
|
pub bat_charge_limit: u8,
|
||||||
@@ -29,7 +29,7 @@ impl StdConfig for Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn file_name(&self) -> String {
|
fn file_name(&self) -> String {
|
||||||
CONFIG_FILE.to_string()
|
CONFIG_FILE.to_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,12 @@ impl From<AnimeConfigV341> for AnimeConfig {
|
|||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
},
|
},
|
||||||
shutdown: if let Some(ani) = c.shutdown {
|
shutdown: if let Some(ani) = c.shutdown.clone() {
|
||||||
|
vec![ani]
|
||||||
|
} else {
|
||||||
|
vec![]
|
||||||
|
},
|
||||||
|
sleep: if let Some(ani) = c.shutdown.clone() {
|
||||||
vec![ani]
|
vec![ani]
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
@@ -60,6 +65,32 @@ impl From<AnimeConfigV352> for AnimeConfig {
|
|||||||
system: c.system,
|
system: c.system,
|
||||||
boot: c.boot,
|
boot: c.boot,
|
||||||
wake: c.wake,
|
wake: c.wake,
|
||||||
|
sleep: c.shutdown.clone(),
|
||||||
|
shutdown: c.shutdown,
|
||||||
|
brightness: 1.0,
|
||||||
|
awake_enabled: true,
|
||||||
|
boot_anim_enabled: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct AnimeConfigV460 {
|
||||||
|
pub system: Vec<ActionLoader>,
|
||||||
|
pub boot: Vec<ActionLoader>,
|
||||||
|
pub wake: Vec<ActionLoader>,
|
||||||
|
pub sleep: Vec<ActionLoader>,
|
||||||
|
pub shutdown: Vec<ActionLoader>,
|
||||||
|
pub brightness: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<AnimeConfigV460> for AnimeConfig {
|
||||||
|
fn from(c: AnimeConfigV460) -> AnimeConfig {
|
||||||
|
AnimeConfig {
|
||||||
|
system: c.system,
|
||||||
|
boot: c.boot,
|
||||||
|
wake: c.wake,
|
||||||
|
sleep: c.sleep,
|
||||||
shutdown: c.shutdown,
|
shutdown: c.shutdown,
|
||||||
brightness: 1.0,
|
brightness: 1.0,
|
||||||
awake_enabled: true,
|
awake_enabled: true,
|
||||||
@@ -73,6 +104,7 @@ pub struct AnimeConfigCached {
|
|||||||
pub system: Vec<ActionData>,
|
pub system: Vec<ActionData>,
|
||||||
pub boot: Vec<ActionData>,
|
pub boot: Vec<ActionData>,
|
||||||
pub wake: Vec<ActionData>,
|
pub wake: Vec<ActionData>,
|
||||||
|
pub sleep: Vec<ActionData>,
|
||||||
pub shutdown: Vec<ActionData>,
|
pub shutdown: Vec<ActionData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +132,12 @@ impl AnimeConfigCached {
|
|||||||
}
|
}
|
||||||
self.wake = wake;
|
self.wake = wake;
|
||||||
|
|
||||||
|
let mut sleep = Vec::with_capacity(config.sleep.len());
|
||||||
|
for ani in &config.sleep {
|
||||||
|
sleep.push(ActionData::from_anime_action(anime_type, ani)?);
|
||||||
|
}
|
||||||
|
self.sleep = sleep;
|
||||||
|
|
||||||
let mut shutdown = Vec::with_capacity(config.shutdown.len());
|
let mut shutdown = Vec::with_capacity(config.shutdown.len());
|
||||||
for ani in &config.shutdown {
|
for ani in &config.shutdown {
|
||||||
shutdown.push(ActionData::from_anime_action(anime_type, ani)?);
|
shutdown.push(ActionData::from_anime_action(anime_type, ani)?);
|
||||||
@@ -110,11 +148,12 @@ impl AnimeConfigCached {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Config for base system actions for the anime display
|
/// Config for base system actions for the anime display
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub struct AnimeConfig {
|
pub struct AnimeConfig {
|
||||||
pub system: Vec<ActionLoader>,
|
pub system: Vec<ActionLoader>,
|
||||||
pub boot: Vec<ActionLoader>,
|
pub boot: Vec<ActionLoader>,
|
||||||
pub wake: Vec<ActionLoader>,
|
pub wake: Vec<ActionLoader>,
|
||||||
|
pub sleep: Vec<ActionLoader>,
|
||||||
pub shutdown: Vec<ActionLoader>,
|
pub shutdown: Vec<ActionLoader>,
|
||||||
pub brightness: f32,
|
pub brightness: f32,
|
||||||
pub awake_enabled: bool,
|
pub awake_enabled: bool,
|
||||||
@@ -127,6 +166,7 @@ impl Default for AnimeConfig {
|
|||||||
system: Vec::new(),
|
system: Vec::new(),
|
||||||
boot: Vec::new(),
|
boot: Vec::new(),
|
||||||
wake: Vec::new(),
|
wake: Vec::new(),
|
||||||
|
sleep: Vec::new(),
|
||||||
shutdown: Vec::new(),
|
shutdown: Vec::new(),
|
||||||
brightness: 1.0,
|
brightness: 1.0,
|
||||||
awake_enabled: true,
|
awake_enabled: true,
|
||||||
@@ -145,7 +185,7 @@ impl StdConfig for AnimeConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn file_name(&self) -> String {
|
fn file_name(&self) -> String {
|
||||||
CONFIG_FILE.to_string()
|
CONFIG_FILE.to_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +204,7 @@ impl AnimeConfig {
|
|||||||
|
|
||||||
fn create_default() -> Self {
|
fn create_default() -> Self {
|
||||||
// create a default config here
|
// create a default config here
|
||||||
let config = AnimeConfig {
|
AnimeConfig {
|
||||||
system: vec![],
|
system: vec![],
|
||||||
boot: vec![ActionLoader::ImageAnimation {
|
boot: vec![ActionLoader::ImageAnimation {
|
||||||
file: "/usr/share/asusd/anime/custom/sonic-run.gif".into(),
|
file: "/usr/share/asusd/anime/custom/sonic-run.gif".into(),
|
||||||
@@ -190,6 +230,14 @@ impl AnimeConfig {
|
|||||||
Duration::from_secs(2),
|
Duration::from_secs(2),
|
||||||
)),
|
)),
|
||||||
}],
|
}],
|
||||||
|
sleep: vec![ActionLoader::ImageAnimation {
|
||||||
|
file: "/usr/share/asusd/anime/custom/sonic-wait.gif".into(),
|
||||||
|
scale: 0.9,
|
||||||
|
angle: 0.0,
|
||||||
|
translation: Vec2::new(3.0, 2.0),
|
||||||
|
brightness: 1.0,
|
||||||
|
time: AnimTime::Infinite,
|
||||||
|
}],
|
||||||
shutdown: vec![ActionLoader::ImageAnimation {
|
shutdown: vec![ActionLoader::ImageAnimation {
|
||||||
file: "/usr/share/asusd/anime/custom/sonic-wait.gif".into(),
|
file: "/usr/share/asusd/anime/custom/sonic-wait.gif".into(),
|
||||||
scale: 0.9,
|
scale: 0.9,
|
||||||
@@ -201,8 +249,6 @@ impl AnimeConfig {
|
|||||||
brightness: 1.0,
|
brightness: 1.0,
|
||||||
awake_enabled: true,
|
awake_enabled: true,
|
||||||
boot_anim_enabled: true,
|
boot_anim_enabled: true,
|
||||||
};
|
}
|
||||||
config.write();
|
|
||||||
config
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,9 +113,8 @@ impl CtrlAnime {
|
|||||||
|
|
||||||
info!("AniMe no previous system thread running (now)");
|
info!("AniMe no previous system thread running (now)");
|
||||||
thread_exit.store(false, Ordering::SeqCst);
|
thread_exit.store(false, Ordering::SeqCst);
|
||||||
|
thread_running.store(true, Ordering::SeqCst);
|
||||||
'main: loop {
|
'main: loop {
|
||||||
thread_running.store(true, Ordering::SeqCst);
|
|
||||||
for action in &actions {
|
for action in &actions {
|
||||||
if thread_exit.load(Ordering::SeqCst) {
|
if thread_exit.load(Ordering::SeqCst) {
|
||||||
break 'main;
|
break 'main;
|
||||||
@@ -124,7 +123,7 @@ impl CtrlAnime {
|
|||||||
ActionData::Animation(frames) => {
|
ActionData::Animation(frames) => {
|
||||||
rog_anime::run_animation(frames, &|frame| {
|
rog_anime::run_animation(frames, &|frame| {
|
||||||
if thread_exit.load(Ordering::Acquire) {
|
if thread_exit.load(Ordering::Acquire) {
|
||||||
info!("rog-anime: frame-loop was asked to exit");
|
info!("rog-anime: animation sub-loop was asked to exit");
|
||||||
return Ok(true); // Do safe exit
|
return Ok(true); // Do safe exit
|
||||||
}
|
}
|
||||||
inner
|
inner
|
||||||
@@ -148,6 +147,10 @@ impl CtrlAnime {
|
|||||||
Ok,
|
Ok,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
if thread_exit.load(Ordering::Acquire) {
|
||||||
|
info!("rog-anime: sub-loop exited and main loop exiting now");
|
||||||
|
break 'main;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ActionData::Image(image) => {
|
ActionData::Image(image) => {
|
||||||
once = false;
|
once = false;
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use config_traits::StdConfig;
|
use config_traits::StdConfig;
|
||||||
use log::{info, warn};
|
use log::warn;
|
||||||
use rog_anime::usb::{pkt_for_apply, pkt_for_set_boot, pkt_for_set_on};
|
use rog_anime::usb::{pkt_for_apply, pkt_for_set_boot, pkt_for_set_on};
|
||||||
use rog_anime::{AnimeDataBuffer, AnimePowerStates};
|
use rog_anime::{AnimeDataBuffer, AnimePowerStates};
|
||||||
use zbus::export::futures_util::lock::{Mutex, MutexGuard};
|
use zbus::export::futures_util::lock::Mutex;
|
||||||
use zbus::{dbus_interface, Connection, SignalContext};
|
use zbus::{dbus_interface, Connection, SignalContext};
|
||||||
|
|
||||||
use super::CtrlAnime;
|
use super::CtrlAnime;
|
||||||
@@ -149,50 +149,41 @@ impl crate::CtrlTask for CtrlAnimeZbus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
|
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
|
||||||
let run_action =
|
|
||||||
|start: bool, lock: MutexGuard<'_, CtrlAnime>, inner: Arc<Mutex<CtrlAnime>>| {
|
|
||||||
if start {
|
|
||||||
info!("CtrlAnimeTask running sleep animation");
|
|
||||||
CtrlAnime::run_thread(inner, lock.cache.shutdown.clone(), true);
|
|
||||||
} else {
|
|
||||||
info!("CtrlAnimeTask running wake animation");
|
|
||||||
CtrlAnime::run_thread(inner, lock.cache.wake.clone(), true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let inner1 = self.0.clone();
|
let inner1 = self.0.clone();
|
||||||
let inner2 = self.0.clone();
|
let inner2 = self.0.clone();
|
||||||
let inner3 = self.0.clone();
|
let inner3 = self.0.clone();
|
||||||
let inner4 = self.0.clone();
|
let inner4 = self.0.clone();
|
||||||
self.create_sys_event_tasks(
|
self.create_sys_event_tasks(
|
||||||
// Loop is required to try an attempt to get the mutex *without* blocking
|
|
||||||
// other threads - it is possible to end up with deadlocks otherwise.
|
|
||||||
move || {
|
move || {
|
||||||
|
// on_sleep
|
||||||
let inner1 = inner1.clone();
|
let inner1 = inner1.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner1.lock().await;
|
let lock = inner1.lock().await;
|
||||||
run_action(true, lock, inner1.clone());
|
CtrlAnime::run_thread(inner1.clone(), lock.cache.sleep.clone(), true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || {
|
move || {
|
||||||
|
// on_wake
|
||||||
let inner2 = inner2.clone();
|
let inner2 = inner2.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner2.lock().await;
|
let lock = inner2.lock().await;
|
||||||
run_action(true, lock, inner2.clone());
|
CtrlAnime::run_thread(inner2.clone(), lock.cache.wake.clone(), true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || {
|
move || {
|
||||||
|
// on_shutdown
|
||||||
let inner3 = inner3.clone();
|
let inner3 = inner3.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner3.lock().await;
|
let lock = inner3.lock().await;
|
||||||
run_action(true, lock, inner3.clone());
|
CtrlAnime::run_thread(inner3.clone(), lock.cache.shutdown.clone(), true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || {
|
move || {
|
||||||
|
// on_boot
|
||||||
let inner4 = inner4.clone();
|
let inner4 = inner4.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner4.lock().await;
|
let lock = inner4.lock().await;
|
||||||
run_action(true, lock, inner4.clone());
|
CtrlAnime::run_thread(inner4.clone(), lock.cache.boot.clone(), true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
use std::collections::{BTreeMap, HashSet};
|
use std::collections::{BTreeMap, HashSet};
|
||||||
|
|
||||||
use config_traits::{StdConfig, StdConfigLoad};
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
use rog_aura::aura_detection::{LaptopLedData, ASUS_KEYBOARD_DEVICES};
|
use rog_aura::aura_detection::LaptopLedData;
|
||||||
use rog_aura::usb::{AuraDev1866, AuraDev19b6, AuraDevTuf, AuraDevice, AuraPowerDev};
|
use rog_aura::usb::{AuraDevRog1, AuraDevRog2, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT};
|
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Direction, LedBrightness, Speed, GRADIENT};
|
||||||
use rog_platform::hid_raw::HidRaw;
|
|
||||||
use rog_platform::keyboard_led::KeyboardLed;
|
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
const CONFIG_FILE: &str = "aura.ron";
|
const CONFIG_FILE: &str = "aura.ron";
|
||||||
@@ -16,8 +14,8 @@ const CONFIG_FILE: &str = "aura.ron";
|
|||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub enum AuraPowerConfig {
|
pub enum AuraPowerConfig {
|
||||||
AuraDevTuf(HashSet<AuraDevTuf>),
|
AuraDevTuf(HashSet<AuraDevTuf>),
|
||||||
AuraDev1866(HashSet<AuraDev1866>),
|
AuraDevRog1(HashSet<AuraDevRog1>),
|
||||||
AuraDev19b6(HashSet<AuraDev19b6>),
|
AuraDevRog2(HashSet<AuraDevRog2>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AuraPowerConfig {
|
impl AuraPowerConfig {
|
||||||
@@ -25,13 +23,13 @@ impl AuraPowerConfig {
|
|||||||
pub fn to_bytes(control: &Self) -> [u8; 3] {
|
pub fn to_bytes(control: &Self) -> [u8; 3] {
|
||||||
match control {
|
match control {
|
||||||
AuraPowerConfig::AuraDevTuf(_) => [0, 0, 0],
|
AuraPowerConfig::AuraDevTuf(_) => [0, 0, 0],
|
||||||
AuraPowerConfig::AuraDev1866(c) => {
|
AuraPowerConfig::AuraDevRog1(c) => {
|
||||||
let c: Vec<AuraDev1866> = c.iter().copied().collect();
|
let c: Vec<AuraDevRog1> = c.iter().copied().collect();
|
||||||
AuraDev1866::to_bytes(&c)
|
AuraDevRog1::to_bytes(&c)
|
||||||
}
|
}
|
||||||
AuraPowerConfig::AuraDev19b6(c) => {
|
AuraPowerConfig::AuraDevRog2(c) => {
|
||||||
let c: Vec<AuraDev19b6> = c.iter().copied().collect();
|
let c: Vec<AuraDevRog2> = c.iter().copied().collect();
|
||||||
AuraDev19b6::to_bytes(&c)
|
AuraDevRog2::to_bytes(&c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,13 +45,13 @@ impl AuraPowerConfig {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Self::AuraDev1866(c) = control {
|
if let Self::AuraDevRog1(c) = control {
|
||||||
return Some([
|
return Some([
|
||||||
true,
|
true,
|
||||||
c.contains(&AuraDev1866::Boot),
|
c.contains(&AuraDevRog1::Boot),
|
||||||
c.contains(&AuraDev1866::Awake),
|
c.contains(&AuraDevRog1::Awake),
|
||||||
c.contains(&AuraDev1866::Sleep),
|
c.contains(&AuraDevRog1::Sleep),
|
||||||
c.contains(&AuraDev1866::Keyboard),
|
c.contains(&AuraDevRog1::Keyboard),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,8 +68,8 @@ impl AuraPowerConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_0x1866(&mut self, power: AuraDev1866, on: bool) {
|
pub fn set_0x1866(&mut self, power: AuraDevRog1, on: bool) {
|
||||||
if let Self::AuraDev1866(p) = self {
|
if let Self::AuraDevRog1(p) = self {
|
||||||
if on {
|
if on {
|
||||||
p.insert(power);
|
p.insert(power);
|
||||||
} else {
|
} else {
|
||||||
@@ -80,8 +78,8 @@ impl AuraPowerConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_0x19b6(&mut self, power: AuraDev19b6, on: bool) {
|
pub fn set_0x19b6(&mut self, power: AuraDevRog2, on: bool) {
|
||||||
if let Self::AuraDev19b6(p) = self {
|
if let Self::AuraDevRog2(p) = self {
|
||||||
if on {
|
if on {
|
||||||
p.insert(power);
|
p.insert(power);
|
||||||
} else {
|
} else {
|
||||||
@@ -99,12 +97,12 @@ impl From<&AuraPowerConfig> for AuraPowerDev {
|
|||||||
x1866: vec![],
|
x1866: vec![],
|
||||||
x19b6: vec![],
|
x19b6: vec![],
|
||||||
},
|
},
|
||||||
AuraPowerConfig::AuraDev1866(d) => AuraPowerDev {
|
AuraPowerConfig::AuraDevRog1(d) => AuraPowerDev {
|
||||||
tuf: vec![],
|
tuf: vec![],
|
||||||
x1866: d.iter().copied().collect(),
|
x1866: d.iter().copied().collect(),
|
||||||
x19b6: vec![],
|
x19b6: vec![],
|
||||||
},
|
},
|
||||||
AuraPowerConfig::AuraDev19b6(d) => AuraPowerDev {
|
AuraPowerConfig::AuraDevRog2(d) => AuraPowerDev {
|
||||||
tuf: vec![],
|
tuf: vec![],
|
||||||
x1866: vec![],
|
x1866: vec![],
|
||||||
x19b6: d.iter().copied().collect(),
|
x19b6: d.iter().copied().collect(),
|
||||||
@@ -113,7 +111,7 @@ impl From<&AuraPowerConfig> for AuraPowerDev {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||||
// #[serde(default)]
|
// #[serde(default)]
|
||||||
pub struct AuraConfig {
|
pub struct AuraConfig {
|
||||||
pub brightness: LedBrightness,
|
pub brightness: LedBrightness,
|
||||||
@@ -124,38 +122,40 @@ pub struct AuraConfig {
|
|||||||
pub enabled: AuraPowerConfig,
|
pub enabled: AuraPowerConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AuraConfig {
|
impl StdConfig for AuraConfig {
|
||||||
fn default() -> Self {
|
fn new() -> Self {
|
||||||
let mut prod_id = AuraDevice::Unknown;
|
// Self::create_default(AuraDevice::X19b6, &LaptopLedData::get_data())
|
||||||
for prod in &ASUS_KEYBOARD_DEVICES {
|
panic!("AuraConfig::new() should not be used, use AuraConfig::create_default() instead");
|
||||||
if HidRaw::new(prod).is_ok() {
|
}
|
||||||
prod_id = AuraDevice::from(*prod);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if prod_id == AuraDevice::Unknown {
|
fn config_dir() -> std::path::PathBuf {
|
||||||
if let Ok(p) = KeyboardLed::new() {
|
std::path::PathBuf::from(crate::CONFIG_PATH_BASE)
|
||||||
if p.has_kbd_rgb_mode() {
|
}
|
||||||
prod_id = AuraDevice::Tuf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let enabled = if prod_id == AuraDevice::X19B6 {
|
fn file_name(&self) -> String {
|
||||||
AuraPowerConfig::AuraDev19b6(HashSet::from([
|
CONFIG_FILE.to_owned()
|
||||||
AuraDev19b6::BootLogo,
|
}
|
||||||
AuraDev19b6::BootKeyb,
|
}
|
||||||
AuraDev19b6::SleepLogo,
|
|
||||||
AuraDev19b6::SleepKeyb,
|
impl StdConfigLoad for AuraConfig {}
|
||||||
AuraDev19b6::AwakeLogo,
|
|
||||||
AuraDev19b6::AwakeKeyb,
|
impl AuraConfig {
|
||||||
AuraDev19b6::ShutdownLogo,
|
pub fn create_default(prod_id: AuraDevice, support_data: &LaptopLedData) -> Self {
|
||||||
AuraDev19b6::ShutdownKeyb,
|
// create a default config here
|
||||||
AuraDev19b6::BootBar,
|
let enabled = if prod_id == AuraDevice::X19b6 {
|
||||||
AuraDev19b6::AwakeBar,
|
AuraPowerConfig::AuraDevRog2(HashSet::from([
|
||||||
AuraDev19b6::SleepBar,
|
AuraDevRog2::BootLogo,
|
||||||
AuraDev19b6::ShutdownBar,
|
AuraDevRog2::BootKeyb,
|
||||||
|
AuraDevRog2::SleepLogo,
|
||||||
|
AuraDevRog2::SleepKeyb,
|
||||||
|
AuraDevRog2::AwakeLogo,
|
||||||
|
AuraDevRog2::AwakeKeyb,
|
||||||
|
AuraDevRog2::ShutdownLogo,
|
||||||
|
AuraDevRog2::ShutdownKeyb,
|
||||||
|
AuraDevRog2::BootBar,
|
||||||
|
AuraDevRog2::AwakeBar,
|
||||||
|
AuraDevRog2::SleepBar,
|
||||||
|
AuraDevRog2::ShutdownBar,
|
||||||
]))
|
]))
|
||||||
} else if prod_id == AuraDevice::Tuf {
|
} else if prod_id == AuraDevice::Tuf {
|
||||||
AuraPowerConfig::AuraDevTuf(HashSet::from([
|
AuraPowerConfig::AuraDevTuf(HashSet::from([
|
||||||
@@ -165,46 +165,22 @@ impl Default for AuraConfig {
|
|||||||
AuraDevTuf::Keyboard,
|
AuraDevTuf::Keyboard,
|
||||||
]))
|
]))
|
||||||
} else {
|
} else {
|
||||||
AuraPowerConfig::AuraDev1866(HashSet::from([
|
AuraPowerConfig::AuraDevRog1(HashSet::from([
|
||||||
AuraDev1866::Awake,
|
AuraDevRog1::Awake,
|
||||||
AuraDev1866::Boot,
|
AuraDevRog1::Boot,
|
||||||
AuraDev1866::Sleep,
|
AuraDevRog1::Sleep,
|
||||||
AuraDev1866::Keyboard,
|
AuraDevRog1::Keyboard,
|
||||||
AuraDev1866::Lightbar,
|
AuraDevRog1::Lightbar,
|
||||||
]))
|
]))
|
||||||
};
|
};
|
||||||
|
let mut config = AuraConfig {
|
||||||
AuraConfig {
|
|
||||||
brightness: LedBrightness::Med,
|
brightness: LedBrightness::Med,
|
||||||
current_mode: AuraModeNum::Static,
|
current_mode: AuraModeNum::Static,
|
||||||
builtins: BTreeMap::new(),
|
builtins: BTreeMap::new(),
|
||||||
multizone: None,
|
multizone: None,
|
||||||
multizone_on: false,
|
multizone_on: false,
|
||||||
enabled,
|
enabled,
|
||||||
}
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StdConfig for AuraConfig {
|
|
||||||
fn new() -> Self {
|
|
||||||
Self::create_default(&LaptopLedData::get_data())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn config_dir() -> std::path::PathBuf {
|
|
||||||
std::path::PathBuf::from(crate::CONFIG_PATH_BASE)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn file_name(&self) -> String {
|
|
||||||
CONFIG_FILE.to_string()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StdConfigLoad for AuraConfig {}
|
|
||||||
|
|
||||||
impl AuraConfig {
|
|
||||||
fn create_default(support_data: &LaptopLedData) -> Self {
|
|
||||||
// create a default config here
|
|
||||||
let mut config = AuraConfig::default();
|
|
||||||
|
|
||||||
for n in &support_data.basic_modes {
|
for n in &support_data.basic_modes {
|
||||||
config
|
config
|
||||||
@@ -232,7 +208,6 @@ impl AuraConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config.write();
|
|
||||||
config
|
config
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,13 +252,15 @@ impl AuraConfig {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use rog_aura::aura_detection::LaptopLedData;
|
||||||
|
use rog_aura::usb::AuraDevice;
|
||||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour};
|
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour};
|
||||||
|
|
||||||
use super::AuraConfig;
|
use super::AuraConfig;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_multizone_4key_config() {
|
fn set_multizone_4key_config() {
|
||||||
let mut config = AuraConfig::default();
|
let mut config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||||
|
|
||||||
let effect = AuraEffect {
|
let effect = AuraEffect {
|
||||||
colour1: Colour(0xff, 0x00, 0xff),
|
colour1: Colour(0xff, 0x00, 0xff),
|
||||||
@@ -329,7 +306,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_multizone_multimode_config() {
|
fn set_multizone_multimode_config() {
|
||||||
let mut config = AuraConfig::default();
|
let mut config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||||
|
|
||||||
let effect = AuraEffect {
|
let effect = AuraEffect {
|
||||||
zone: AuraZone::Key1,
|
zone: AuraZone::Key1,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use config_traits::StdConfig;
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
use rog_aura::advanced::{LedUsbPackets, UsbPackets};
|
use rog_aura::advanced::{LedUsbPackets, UsbPackets};
|
||||||
use rog_aura::aura_detection::{LaptopLedData, ASUS_KEYBOARD_DEVICES};
|
use rog_aura::aura_detection::{LaptopLedData, ASUS_KEYBOARD_DEVICES};
|
||||||
@@ -25,9 +25,9 @@ impl GetSupported for CtrlKbdLed {
|
|||||||
let advanced_type = laptop.advanced_type;
|
let advanced_type = laptop.advanced_type;
|
||||||
|
|
||||||
let mut prod_id = AuraDevice::Unknown;
|
let mut prod_id = AuraDevice::Unknown;
|
||||||
for prod in &ASUS_KEYBOARD_DEVICES {
|
for prod in ASUS_KEYBOARD_DEVICES {
|
||||||
if HidRaw::new(prod).is_ok() {
|
if HidRaw::new(prod.into()).is_ok() {
|
||||||
prod_id = AuraDevice::from(*prod);
|
prod_id = prod;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ pub enum LEDNode {
|
|||||||
|
|
||||||
pub struct CtrlKbdLed {
|
pub struct CtrlKbdLed {
|
||||||
// TODO: config stores the keyboard type as an AuraPower, use or update this
|
// TODO: config stores the keyboard type as an AuraPower, use or update this
|
||||||
pub led_prod: Option<String>,
|
pub led_prod: AuraDevice,
|
||||||
pub led_node: LEDNode,
|
pub led_node: LEDNode,
|
||||||
pub kd_brightness: KeyboardLed,
|
pub kd_brightness: KeyboardLed,
|
||||||
pub supported_modes: LaptopLedData,
|
pub supported_modes: LaptopLedData,
|
||||||
@@ -68,34 +68,43 @@ pub struct CtrlKbdLed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CtrlKbdLed {
|
impl CtrlKbdLed {
|
||||||
pub fn new(supported_modes: LaptopLedData, config: AuraConfig) -> Result<Self, RogError> {
|
pub fn new(supported_modes: LaptopLedData) -> Result<Self, RogError> {
|
||||||
let mut led_prod = None;
|
let mut led_prod = AuraDevice::Unknown;
|
||||||
let mut led_node = None;
|
let mut usb_node = None;
|
||||||
for prod in &ASUS_KEYBOARD_DEVICES {
|
for prod in ASUS_KEYBOARD_DEVICES {
|
||||||
match HidRaw::new(prod) {
|
match HidRaw::new(prod.into()) {
|
||||||
Ok(node) => {
|
Ok(node) => {
|
||||||
led_prod = Some((*prod).to_owned());
|
led_prod = prod;
|
||||||
led_node = Some(node);
|
usb_node = Some(node);
|
||||||
info!("Looked for keyboard controller 0x{prod}: Found");
|
info!(
|
||||||
|
"Looked for keyboard controller 0x{}: Found",
|
||||||
|
<&str>::from(prod)
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Err(err) => info!("Looked for keyboard controller 0x{prod}: {err}"),
|
Err(err) => info!(
|
||||||
|
"Looked for keyboard controller 0x{}: {err}",
|
||||||
|
<&str>::from(prod)
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let rgb_led = KeyboardLed::new()?;
|
let rgb_led = KeyboardLed::new()?;
|
||||||
|
|
||||||
if led_node.is_none() && !rgb_led.has_kbd_rgb_mode() {
|
if usb_node.is_none() && !rgb_led.has_kbd_rgb_mode() {
|
||||||
let dmi = sysfs_class::DmiId::default();
|
let dmi = sysfs_class::DmiId::default();
|
||||||
if let Ok(prod_family) = dmi.product_family() {
|
if let Ok(prod_family) = dmi.product_family() {
|
||||||
if prod_family.contains("TUF") {
|
if prod_family.contains("TUF") {
|
||||||
warn!("A kernel patch is in progress for TUF RGB support");
|
warn!(
|
||||||
|
"kbd_rgb_mode was not found in the /sys/. You require a minimum 6.1 \
|
||||||
|
kernel and a supported TUF laptop"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Err(RogError::NoAuraKeyboard);
|
return Err(RogError::NoAuraKeyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
let led_node = if let Some(rog) = led_node {
|
let led_node = if let Some(rog) = usb_node {
|
||||||
info!("Found ROG USB keyboard");
|
info!("Found ROG USB keyboard");
|
||||||
LEDNode::Rog(rog)
|
LEDNode::Rog(rog)
|
||||||
} else if rgb_led.has_kbd_rgb_mode() {
|
} else if rgb_led.has_kbd_rgb_mode() {
|
||||||
@@ -105,14 +114,44 @@ impl CtrlKbdLed {
|
|||||||
LEDNode::None
|
LEDNode::None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut config_init = AuraConfig::create_default(led_prod, &supported_modes);
|
||||||
|
let mut config_loaded = config_init.clone().load();
|
||||||
|
|
||||||
|
for mode in &mut config_init.builtins {
|
||||||
|
// update init values from loaded values if they exist
|
||||||
|
if let Some(loaded) = config_loaded.builtins.get(mode.0) {
|
||||||
|
*mode.1 = loaded.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config_loaded.builtins = config_init.builtins;
|
||||||
|
|
||||||
|
if let (Some(mut multizone_init), Some(multizone_loaded)) =
|
||||||
|
(config_init.multizone, config_loaded.multizone.as_mut())
|
||||||
|
{
|
||||||
|
for mode in multizone_init.iter_mut() {
|
||||||
|
// update init values from loaded values if they exist
|
||||||
|
if let Some(loaded) = multizone_loaded.get(mode.0) {
|
||||||
|
let mut new_set = Vec::new();
|
||||||
|
// only reuse a zone mode if the mode is supported
|
||||||
|
for mode in loaded {
|
||||||
|
if supported_modes.basic_modes.contains(&mode.mode) {
|
||||||
|
new_set.push(mode.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*mode.1 = new_set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*multizone_loaded = multizone_init;
|
||||||
|
}
|
||||||
|
|
||||||
let ctrl = CtrlKbdLed {
|
let ctrl = CtrlKbdLed {
|
||||||
led_prod,
|
led_prod,
|
||||||
led_node,
|
led_node, // on TUF this is the same as rgb_led / kd_brightness
|
||||||
kd_brightness: rgb_led, // If was none then we already returned above
|
kd_brightness: rgb_led, // If was none then we already returned above
|
||||||
supported_modes,
|
supported_modes,
|
||||||
flip_effect_write: false,
|
flip_effect_write: false,
|
||||||
per_key_mode_active: false,
|
per_key_mode_active: false,
|
||||||
config,
|
config: config_loaded,
|
||||||
};
|
};
|
||||||
Ok(ctrl)
|
Ok(ctrl)
|
||||||
}
|
}
|
||||||
@@ -356,6 +395,7 @@ impl CtrlKbdLed {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use rog_aura::aura_detection::LaptopLedData;
|
use rog_aura::aura_detection::LaptopLedData;
|
||||||
|
use rog_aura::usb::AuraDevice;
|
||||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour};
|
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour};
|
||||||
use rog_platform::keyboard_led::KeyboardLed;
|
use rog_platform::keyboard_led::KeyboardLed;
|
||||||
|
|
||||||
@@ -367,7 +407,7 @@ mod tests {
|
|||||||
// #[ignore = "Must be manually run due to detection stage"]
|
// #[ignore = "Must be manually run due to detection stage"]
|
||||||
fn check_set_mode_errors() {
|
fn check_set_mode_errors() {
|
||||||
// Checking to ensure set_mode errors when unsupported modes are tried
|
// Checking to ensure set_mode errors when unsupported modes are tried
|
||||||
let config = AuraConfig::default();
|
let config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||||
let supported_modes = LaptopLedData {
|
let supported_modes = LaptopLedData {
|
||||||
board_name: String::new(),
|
board_name: String::new(),
|
||||||
layout_name: "ga401".to_owned(),
|
layout_name: "ga401".to_owned(),
|
||||||
@@ -376,7 +416,7 @@ mod tests {
|
|||||||
advanced_type: rog_aura::AdvancedAuraType::None,
|
advanced_type: rog_aura::AdvancedAuraType::None,
|
||||||
};
|
};
|
||||||
let mut controller = CtrlKbdLed {
|
let mut controller = CtrlKbdLed {
|
||||||
led_prod: None,
|
led_prod: AuraDevice::X19b6,
|
||||||
led_node: LEDNode::None,
|
led_node: LEDNode::None,
|
||||||
kd_brightness: KeyboardLed::default(),
|
kd_brightness: KeyboardLed::default(),
|
||||||
supported_modes,
|
supported_modes,
|
||||||
@@ -430,7 +470,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn create_multizone_if_no_config() {
|
fn create_multizone_if_no_config() {
|
||||||
// Checking to ensure set_mode errors when unsupported modes are tried
|
// Checking to ensure set_mode errors when unsupported modes are tried
|
||||||
let config = AuraConfig::default();
|
let config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||||
let supported_modes = LaptopLedData {
|
let supported_modes = LaptopLedData {
|
||||||
board_name: String::new(),
|
board_name: String::new(),
|
||||||
layout_name: "ga401".to_owned(),
|
layout_name: "ga401".to_owned(),
|
||||||
@@ -439,7 +479,7 @@ mod tests {
|
|||||||
advanced_type: rog_aura::AdvancedAuraType::None,
|
advanced_type: rog_aura::AdvancedAuraType::None,
|
||||||
};
|
};
|
||||||
let mut controller = CtrlKbdLed {
|
let mut controller = CtrlKbdLed {
|
||||||
led_prod: None,
|
led_prod: AuraDevice::X19b6,
|
||||||
led_node: LEDNode::None,
|
led_node: LEDNode::None,
|
||||||
kd_brightness: KeyboardLed::default(),
|
kd_brightness: KeyboardLed::default(),
|
||||||
supported_modes,
|
supported_modes,
|
||||||
@@ -468,7 +508,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn next_mode_create_multizone_if_no_config() {
|
fn next_mode_create_multizone_if_no_config() {
|
||||||
// Checking to ensure set_mode errors when unsupported modes are tried
|
// Checking to ensure set_mode errors when unsupported modes are tried
|
||||||
let config = AuraConfig::default();
|
let config = AuraConfig::create_default(AuraDevice::X19b6, &LaptopLedData::default());
|
||||||
let supported_modes = LaptopLedData {
|
let supported_modes = LaptopLedData {
|
||||||
board_name: String::new(),
|
board_name: String::new(),
|
||||||
layout_name: "ga401".to_owned(),
|
layout_name: "ga401".to_owned(),
|
||||||
@@ -477,7 +517,7 @@ mod tests {
|
|||||||
advanced_type: rog_aura::AdvancedAuraType::None,
|
advanced_type: rog_aura::AdvancedAuraType::None,
|
||||||
};
|
};
|
||||||
let mut controller = CtrlKbdLed {
|
let mut controller = CtrlKbdLed {
|
||||||
led_prod: None,
|
led_prod: AuraDevice::X19b6,
|
||||||
led_node: LEDNode::None,
|
led_node: LEDNode::None,
|
||||||
kd_brightness: KeyboardLed::default(),
|
kd_brightness: KeyboardLed::default(),
|
||||||
supported_modes,
|
supported_modes,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod controller;
|
pub mod controller;
|
||||||
/// Implements CtrlTask, Reloadable, ZbusRun
|
/// Implements `CtrlTask`, `Reloadable`, `ZbusRun`
|
||||||
pub mod trait_impls;
|
pub mod trait_impls;
|
||||||
|
|||||||
@@ -92,15 +92,8 @@ impl CtrlPlatform {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_boot_sound() -> Result<i8, RogError> {
|
pub fn get_boot_sound() -> Result<i8, RogError> {
|
||||||
let path = ASUS_POST_LOGO_SOUND;
|
let data = std::fs::read(ASUS_POST_LOGO_SOUND)
|
||||||
let mut file = OpenOptions::new()
|
.map_err(|err| RogError::Read(ASUS_POST_LOGO_SOUND.into(), err))?;
|
||||||
.read(true)
|
|
||||||
.open(path)
|
|
||||||
.map_err(|err| RogError::Path(path.into(), err))?;
|
|
||||||
|
|
||||||
let mut data = Vec::new();
|
|
||||||
file.read_to_end(&mut data)
|
|
||||||
.map_err(|err| RogError::Read(path.into(), err))?;
|
|
||||||
|
|
||||||
let idx = data.len() - 1;
|
let idx = data.len() - 1;
|
||||||
Ok(data[idx] as i8)
|
Ok(data[idx] as i8)
|
||||||
@@ -115,6 +108,7 @@ impl CtrlPlatform {
|
|||||||
.map_err(|err| RogError::Path(path.into(), err))?;
|
.map_err(|err| RogError::Path(path.into(), err))?;
|
||||||
|
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
|
#[allow(clippy::verbose_file_reads)]
|
||||||
file.read_to_end(&mut data)
|
file.read_to_end(&mut data)
|
||||||
.map_err(|err| RogError::Read(path.into(), err))?;
|
.map_err(|err| RogError::Read(path.into(), err))?;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::path::PathBuf;
|
|||||||
|
|
||||||
use config_traits::{StdConfig, StdConfigLoad};
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
use rog_profiles::fan_curve_set::FanCurveSet;
|
use rog_profiles::fan_curve_set::FanCurveSet;
|
||||||
use rog_profiles::{FanCurveProfiles, Profile};
|
use rog_profiles::Profile;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::CONFIG_PATH_BASE;
|
use crate::CONFIG_PATH_BASE;
|
||||||
@@ -28,7 +28,7 @@ impl StdConfig for ProfileConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn file_name(&self) -> String {
|
fn file_name(&self) -> String {
|
||||||
CONFIG_FILE.to_string()
|
CONFIG_FILE.to_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,40 +36,16 @@ impl StdConfigLoad for ProfileConfig {}
|
|||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, Default)]
|
#[derive(Deserialize, Serialize, Debug, Default)]
|
||||||
pub struct FanCurveConfig {
|
pub struct FanCurveConfig {
|
||||||
balanced: FanCurveSet,
|
pub balanced: FanCurveSet,
|
||||||
performance: FanCurveSet,
|
pub performance: FanCurveSet,
|
||||||
quiet: FanCurveSet,
|
pub quiet: FanCurveSet,
|
||||||
#[serde(skip)]
|
|
||||||
device: FanCurveProfiles,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FanCurveConfig {
|
|
||||||
pub fn update_device_config(&mut self) {
|
|
||||||
self.balanced = self.device.balanced.clone();
|
|
||||||
self.performance = self.device.performance.clone();
|
|
||||||
self.quiet = self.device.quiet.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn update_config(&mut self) {
|
|
||||||
self.balanced = self.device.balanced.clone();
|
|
||||||
self.performance = self.device.performance.clone();
|
|
||||||
self.quiet = self.device.quiet.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn device(&self) -> &FanCurveProfiles {
|
|
||||||
&self.device
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn device_mut(&mut self) -> &mut FanCurveProfiles {
|
|
||||||
&mut self.device
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdConfig for FanCurveConfig {
|
impl StdConfig for FanCurveConfig {
|
||||||
|
/// Create a new config. The defaults are zeroed so the device must be read
|
||||||
|
/// to get the actual device defaults.
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
let mut tmp = Self::default();
|
Self::default()
|
||||||
tmp.update_device_config();
|
|
||||||
tmp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn config_dir() -> std::path::PathBuf {
|
fn config_dir() -> std::path::PathBuf {
|
||||||
@@ -77,7 +53,7 @@ impl StdConfig for FanCurveConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn file_name(&self) -> String {
|
fn file_name(&self) -> String {
|
||||||
CONFIG_FAN_FILE.to_string()
|
CONFIG_FAN_FILE.to_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use config_traits::StdConfig;
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
use rog_platform::platform::AsusPlatform;
|
use rog_platform::platform::AsusPlatform;
|
||||||
use rog_platform::supported::PlatformProfileFunctions;
|
use rog_platform::supported::PlatformProfileFunctions;
|
||||||
@@ -9,9 +9,39 @@ use super::config::{FanCurveConfig, ProfileConfig};
|
|||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
use crate::GetSupported;
|
use crate::GetSupported;
|
||||||
|
|
||||||
|
// TODO: macro wrapper for warn/info/error log macros to add module name
|
||||||
|
const MOD_NAME: &str = "CtrlPlatformProfile";
|
||||||
|
|
||||||
|
pub struct FanCurves {
|
||||||
|
config_file: FanCurveConfig,
|
||||||
|
profiles: FanCurveProfiles,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FanCurves {
|
||||||
|
pub fn update_profiles_from_config(&mut self) {
|
||||||
|
self.profiles.balanced = self.config_file.balanced.clone();
|
||||||
|
self.profiles.performance = self.config_file.performance.clone();
|
||||||
|
self.profiles.quiet = self.config_file.quiet.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_config_from_profiles(&mut self) {
|
||||||
|
self.config_file.balanced = self.profiles.balanced.clone();
|
||||||
|
self.config_file.performance = self.profiles.performance.clone();
|
||||||
|
self.config_file.quiet = self.profiles.quiet.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn profiles(&self) -> &FanCurveProfiles {
|
||||||
|
&self.profiles
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn profiles_mut(&mut self) -> &mut FanCurveProfiles {
|
||||||
|
&mut self.profiles
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct CtrlPlatformProfile {
|
pub struct CtrlPlatformProfile {
|
||||||
pub profile_config: ProfileConfig,
|
pub profile_config: ProfileConfig,
|
||||||
pub fan_config: Option<FanCurveConfig>,
|
pub fan_curves: Option<FanCurves>,
|
||||||
pub platform: AsusPlatform,
|
pub platform: AsusPlatform,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,30 +80,50 @@ impl CtrlPlatformProfile {
|
|||||||
pub fn new(config: ProfileConfig) -> Result<Self, RogError> {
|
pub fn new(config: ProfileConfig) -> Result<Self, RogError> {
|
||||||
let platform = AsusPlatform::new()?;
|
let platform = AsusPlatform::new()?;
|
||||||
if platform.has_platform_profile() || platform.has_throttle_thermal_policy() {
|
if platform.has_platform_profile() || platform.has_throttle_thermal_policy() {
|
||||||
info!("Device has profile control available");
|
info!("{MOD_NAME}: Device has profile control available");
|
||||||
|
|
||||||
let mut controller = CtrlPlatformProfile {
|
let mut controller = CtrlPlatformProfile {
|
||||||
profile_config: config,
|
profile_config: config,
|
||||||
fan_config: None,
|
fan_curves: None,
|
||||||
platform,
|
platform,
|
||||||
};
|
};
|
||||||
if FanCurveProfiles::get_device().is_ok() {
|
if FanCurveProfiles::get_device().is_ok() {
|
||||||
info!("Device has fan curves available");
|
info!("{MOD_NAME}: Device has fan curves available");
|
||||||
if controller.fan_config.is_none() {
|
let fan_config = FanCurveConfig::new();
|
||||||
controller.fan_config = Some(Default::default());
|
// Only do defaults if the config doesn't already exist
|
||||||
|
if !fan_config.file_path().exists() {
|
||||||
|
info!("{MOD_NAME}: Fetching default fan curves");
|
||||||
|
controller.fan_curves = Some(FanCurves {
|
||||||
|
config_file: fan_config,
|
||||||
|
profiles: FanCurveProfiles::default(),
|
||||||
|
});
|
||||||
for _ in [Profile::Balanced, Profile::Performance, Profile::Quiet] {
|
for _ in [Profile::Balanced, Profile::Performance, Profile::Quiet] {
|
||||||
|
// For each profile we need to switch to it before we
|
||||||
|
// can read the existing values from hardware. The ACPI method used
|
||||||
|
// for this is what limits us.
|
||||||
controller.set_next_profile()?;
|
controller.set_next_profile()?;
|
||||||
|
// Make sure to set the baseline to default
|
||||||
controller.set_active_curve_to_defaults()?;
|
controller.set_active_curve_to_defaults()?;
|
||||||
|
|
||||||
let active = Profile::get_active_profile().unwrap_or(Profile::Balanced);
|
let active = Profile::get_active_profile().unwrap_or(Profile::Balanced);
|
||||||
if let Some(curves) = controller.fan_config.as_ref() {
|
|
||||||
|
if let Some(curves) = controller.fan_curves.as_ref() {
|
||||||
info!(
|
info!(
|
||||||
"{active:?}: {}",
|
"{MOD_NAME}: {active:?}: {}",
|
||||||
String::from(curves.device().get_fan_curves_for(active))
|
String::from(curves.profiles().get_fan_curves_for(active))
|
||||||
);
|
);
|
||||||
curves.write();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let Some(curves) = controller.fan_curves.as_ref() {
|
||||||
|
curves.config_file.write();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info!("{MOD_NAME}: Fan curves previously stored, loading...");
|
||||||
|
let mut fan_curves = FanCurves {
|
||||||
|
config_file: fan_config.load(),
|
||||||
|
profiles: FanCurveProfiles::default(),
|
||||||
|
};
|
||||||
|
fan_curves.update_profiles_from_config();
|
||||||
|
controller.fan_curves = Some(fan_curves);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,9 +135,9 @@ impl CtrlPlatformProfile {
|
|||||||
|
|
||||||
pub fn save_config(&mut self) {
|
pub fn save_config(&mut self) {
|
||||||
self.profile_config.write();
|
self.profile_config.write();
|
||||||
if let Some(fans) = self.fan_config.as_mut() {
|
if let Some(fans) = self.fan_curves.as_mut() {
|
||||||
fans.update_config();
|
fans.update_config_from_profiles();
|
||||||
fans.write();
|
fans.config_file.write(); // config write
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,9 +165,9 @@ impl CtrlPlatformProfile {
|
|||||||
|
|
||||||
/// Set the curve for the active profile active
|
/// Set the curve for the active profile active
|
||||||
pub(super) fn write_profile_curve_to_platform(&mut self) -> Result<(), RogError> {
|
pub(super) fn write_profile_curve_to_platform(&mut self) -> Result<(), RogError> {
|
||||||
if let Some(curves) = &mut self.fan_config {
|
if let Some(curves) = &mut self.fan_curves {
|
||||||
if let Ok(mut device) = FanCurveProfiles::get_device() {
|
if let Ok(mut device) = FanCurveProfiles::get_device() {
|
||||||
curves.device_mut().write_profile_curve_to_platform(
|
curves.profiles_mut().write_profile_curve_to_platform(
|
||||||
self.profile_config.active_profile,
|
self.profile_config.active_profile,
|
||||||
&mut device,
|
&mut device,
|
||||||
)?;
|
)?;
|
||||||
@@ -127,13 +177,13 @@ impl CtrlPlatformProfile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn set_active_curve_to_defaults(&mut self) -> Result<(), RogError> {
|
pub(super) fn set_active_curve_to_defaults(&mut self) -> Result<(), RogError> {
|
||||||
if let Some(curves) = self.fan_config.as_mut() {
|
if let Some(curves) = self.fan_curves.as_mut() {
|
||||||
if let Ok(mut device) = FanCurveProfiles::get_device() {
|
if let Ok(mut device) = FanCurveProfiles::get_device() {
|
||||||
curves.device_mut().set_active_curve_to_defaults(
|
curves.profiles_mut().set_active_curve_to_defaults(
|
||||||
self.profile_config.active_profile,
|
self.profile_config.active_profile,
|
||||||
&mut device,
|
&mut device,
|
||||||
)?;
|
)?;
|
||||||
curves.update_config();
|
curves.update_config_from_profiles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ use super::controller::CtrlPlatformProfile;
|
|||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
use crate::CtrlTask;
|
use crate::CtrlTask;
|
||||||
|
|
||||||
|
const MOD_NAME: &str = "ProfileZbus";
|
||||||
|
|
||||||
const ZBUS_PATH: &str = "/org/asuslinux/Profile";
|
const ZBUS_PATH: &str = "/org/asuslinux/Profile";
|
||||||
const UNSUPPORTED_MSG: &str =
|
const UNSUPPORTED_MSG: &str =
|
||||||
"Fan curves are not supported on this laptop or you require a patched kernel";
|
"Fan curves are not supported on this laptop or you require a patched kernel";
|
||||||
@@ -39,7 +41,7 @@ impl ProfileZbus {
|
|||||||
async fn next_profile(&mut self, #[zbus(signal_context)] ctxt: SignalContext<'_>) {
|
async fn next_profile(&mut self, #[zbus(signal_context)] ctxt: SignalContext<'_>) {
|
||||||
let mut ctrl = self.0.lock().await;
|
let mut ctrl = self.0.lock().await;
|
||||||
ctrl.set_next_profile()
|
ctrl.set_next_profile()
|
||||||
.unwrap_or_else(|err| warn!("{}", err));
|
.unwrap_or_else(|err| warn!("{MOD_NAME}: {}", err));
|
||||||
ctrl.save_config();
|
ctrl.save_config();
|
||||||
|
|
||||||
Self::notify_profile(&ctxt, ctrl.profile_config.active_profile)
|
Self::notify_profile(&ctxt, ctrl.profile_config.active_profile)
|
||||||
@@ -64,11 +66,11 @@ impl ProfileZbus {
|
|||||||
// Read first just incase the user has modified the config before calling this
|
// Read first just incase the user has modified the config before calling this
|
||||||
ctrl.profile_config.read();
|
ctrl.profile_config.read();
|
||||||
Profile::set_profile(profile)
|
Profile::set_profile(profile)
|
||||||
.map_err(|e| warn!("set_profile, {}", e))
|
.map_err(|e| warn!("{MOD_NAME}: set_profile, {}", e))
|
||||||
.ok();
|
.ok();
|
||||||
ctrl.profile_config.active_profile = profile;
|
ctrl.profile_config.active_profile = profile;
|
||||||
ctrl.write_profile_curve_to_platform()
|
ctrl.write_profile_curve_to_platform()
|
||||||
.map_err(|e| warn!("write_profile_curve_to_platform, {}", e))
|
.map_err(|e| warn!("{MOD_NAME}: write_profile_curve_to_platform, {}", e))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
ctrl.save_config();
|
ctrl.save_config();
|
||||||
@@ -82,8 +84,8 @@ impl ProfileZbus {
|
|||||||
async fn enabled_fan_profiles(&mut self) -> zbus::fdo::Result<Vec<Profile>> {
|
async fn enabled_fan_profiles(&mut self) -> zbus::fdo::Result<Vec<Profile>> {
|
||||||
let mut ctrl = self.0.lock().await;
|
let mut ctrl = self.0.lock().await;
|
||||||
ctrl.profile_config.read();
|
ctrl.profile_config.read();
|
||||||
if let Some(curves) = &mut ctrl.fan_config {
|
if let Some(curves) = &mut ctrl.fan_curves {
|
||||||
return Ok(curves.device().get_enabled_curve_profiles());
|
return Ok(curves.profiles().get_enabled_curve_profiles());
|
||||||
}
|
}
|
||||||
Err(Error::Failed(UNSUPPORTED_MSG.to_owned()))
|
Err(Error::Failed(UNSUPPORTED_MSG.to_owned()))
|
||||||
}
|
}
|
||||||
@@ -97,14 +99,13 @@ impl ProfileZbus {
|
|||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
let mut ctrl = self.0.lock().await;
|
let mut ctrl = self.0.lock().await;
|
||||||
ctrl.profile_config.read();
|
ctrl.profile_config.read();
|
||||||
if let Some(curves) = &mut ctrl.fan_config {
|
if let Some(curves) = &mut ctrl.fan_curves {
|
||||||
curves
|
curves
|
||||||
.device_mut()
|
.profiles_mut()
|
||||||
.set_profile_curve_enabled(profile, enabled);
|
.set_profile_curve_enabled(profile, enabled);
|
||||||
curves.update_config();
|
|
||||||
|
|
||||||
ctrl.write_profile_curve_to_platform()
|
ctrl.write_profile_curve_to_platform()
|
||||||
.map_err(|e| warn!("write_profile_curve_to_platform, {}", e))
|
.map_err(|e| warn!("{MOD_NAME}: write_profile_curve_to_platform, {}", e))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
ctrl.save_config();
|
ctrl.save_config();
|
||||||
@@ -118,8 +119,8 @@ impl ProfileZbus {
|
|||||||
async fn fan_curve_data(&mut self, profile: Profile) -> zbus::fdo::Result<FanCurveSet> {
|
async fn fan_curve_data(&mut self, profile: Profile) -> zbus::fdo::Result<FanCurveSet> {
|
||||||
let mut ctrl = self.0.lock().await;
|
let mut ctrl = self.0.lock().await;
|
||||||
ctrl.profile_config.read();
|
ctrl.profile_config.read();
|
||||||
if let Some(curves) = &mut ctrl.fan_config {
|
if let Some(curves) = &mut ctrl.fan_curves {
|
||||||
let curve = curves.device().get_fan_curves_for(profile);
|
let curve = curves.profiles().get_fan_curves_for(profile);
|
||||||
return Ok(curve.clone());
|
return Ok(curve.clone());
|
||||||
}
|
}
|
||||||
Err(Error::Failed(UNSUPPORTED_MSG.to_owned()))
|
Err(Error::Failed(UNSUPPORTED_MSG.to_owned()))
|
||||||
@@ -130,17 +131,16 @@ impl ProfileZbus {
|
|||||||
async fn set_fan_curve(&self, profile: Profile, curve: CurveData) -> zbus::fdo::Result<()> {
|
async fn set_fan_curve(&self, profile: Profile, curve: CurveData) -> zbus::fdo::Result<()> {
|
||||||
let mut ctrl = self.0.lock().await;
|
let mut ctrl = self.0.lock().await;
|
||||||
ctrl.profile_config.read();
|
ctrl.profile_config.read();
|
||||||
if let Some(curves) = &mut ctrl.fan_config {
|
if let Some(curves) = &mut ctrl.fan_curves {
|
||||||
curves
|
curves
|
||||||
.device_mut()
|
.profiles_mut()
|
||||||
.save_fan_curve(curve, profile)
|
.save_fan_curve(curve, profile)
|
||||||
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
||||||
curves.update_config();
|
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::Failed(UNSUPPORTED_MSG.to_owned()));
|
return Err(Error::Failed(UNSUPPORTED_MSG.to_owned()));
|
||||||
}
|
}
|
||||||
ctrl.write_profile_curve_to_platform()
|
ctrl.write_profile_curve_to_platform()
|
||||||
.map_err(|e| warn!("Profile::set_profile, {}", e))
|
.map_err(|e| warn!("{MOD_NAME}: Profile::set_profile, {}", e))
|
||||||
.ok();
|
.ok();
|
||||||
ctrl.save_config();
|
ctrl.save_config();
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ impl ProfileZbus {
|
|||||||
let mut ctrl = self.0.lock().await;
|
let mut ctrl = self.0.lock().await;
|
||||||
ctrl.profile_config.read();
|
ctrl.profile_config.read();
|
||||||
ctrl.set_active_curve_to_defaults()
|
ctrl.set_active_curve_to_defaults()
|
||||||
.map_err(|e| warn!("Profile::set_active_curve_to_defaults, {}", e))
|
.map_err(|e| warn!("{MOD_NAME}: Profile::set_active_curve_to_defaults, {}", e))
|
||||||
.ok();
|
.ok();
|
||||||
ctrl.save_config();
|
ctrl.save_config();
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -173,14 +173,14 @@ impl ProfileZbus {
|
|||||||
let active = Profile::get_active_profile().unwrap_or(Profile::Balanced);
|
let active = Profile::get_active_profile().unwrap_or(Profile::Balanced);
|
||||||
|
|
||||||
Profile::set_profile(profile)
|
Profile::set_profile(profile)
|
||||||
.map_err(|e| warn!("set_profile, {}", e))
|
.map_err(|e| warn!("{MOD_NAME}: set_profile, {}", e))
|
||||||
.ok();
|
.ok();
|
||||||
ctrl.set_active_curve_to_defaults()
|
ctrl.set_active_curve_to_defaults()
|
||||||
.map_err(|e| warn!("Profile::set_active_curve_to_defaults, {}", e))
|
.map_err(|e| warn!("{MOD_NAME}: Profile::set_active_curve_to_defaults, {}", e))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
Profile::set_profile(active)
|
Profile::set_profile(active)
|
||||||
.map_err(|e| warn!("set_profile, {}", e))
|
.map_err(|e| warn!("{MOD_NAME}: set_profile, {}", e))
|
||||||
.ok();
|
.ok();
|
||||||
ctrl.save_config();
|
ctrl.save_config();
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -222,12 +222,12 @@ impl CtrlTask for ProfileZbus {
|
|||||||
let mut lock = ctrl.lock().await;
|
let mut lock = ctrl.lock().await;
|
||||||
if let Ok(profile) =
|
if let Ok(profile) =
|
||||||
lock.platform.get_throttle_thermal_policy().map_err(|e| {
|
lock.platform.get_throttle_thermal_policy().map_err(|e| {
|
||||||
error!("get_throttle_thermal_policy error: {e}");
|
error!("{MOD_NAME}: get_throttle_thermal_policy error: {e}");
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
let new_profile = Profile::from_throttle_thermal_policy(profile);
|
let new_profile = Profile::from_throttle_thermal_policy(profile);
|
||||||
if new_profile != lock.profile_config.active_profile {
|
if new_profile != lock.profile_config.active_profile {
|
||||||
info!("platform_profile changed to {new_profile}");
|
info!("{MOD_NAME}: platform_profile changed to {new_profile}");
|
||||||
lock.profile_config.active_profile = new_profile;
|
lock.profile_config.active_profile = new_profile;
|
||||||
lock.write_profile_curve_to_platform().unwrap();
|
lock.write_profile_curve_to_platform().unwrap();
|
||||||
lock.save_config();
|
lock.save_config();
|
||||||
@@ -262,7 +262,7 @@ impl CtrlTask for ProfileZbus {
|
|||||||
error!("Profile::from_str(&profile) error: {e}");
|
error!("Profile::from_str(&profile) error: {e}");
|
||||||
}) {
|
}) {
|
||||||
if new_profile != lock.profile_config.active_profile {
|
if new_profile != lock.profile_config.active_profile {
|
||||||
info!("platform_profile changed to {new_profile}");
|
info!("{MOD_NAME}: platform_profile changed to {new_profile}");
|
||||||
lock.profile_config.active_profile = new_profile;
|
lock.profile_config.active_profile = new_profile;
|
||||||
lock.write_profile_curve_to_platform().unwrap();
|
lock.write_profile_curve_to_platform().unwrap();
|
||||||
lock.save_config();
|
lock.save_config();
|
||||||
@@ -295,15 +295,14 @@ impl crate::Reloadable for ProfileZbus {
|
|||||||
async fn reload(&mut self) -> Result<(), RogError> {
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
let mut ctrl = self.0.lock().await;
|
let mut ctrl = self.0.lock().await;
|
||||||
let active = ctrl.profile_config.active_profile;
|
let active = ctrl.profile_config.active_profile;
|
||||||
if let Some(curves) = &mut ctrl.fan_config {
|
if let Some(curves) = &mut ctrl.fan_curves {
|
||||||
if let Ok(mut device) = FanCurveProfiles::get_device() {
|
if let Ok(mut device) = FanCurveProfiles::get_device() {
|
||||||
// There is a possibility that the curve was default zeroed, so this call
|
// There is a possibility that the curve was default zeroed, so this call
|
||||||
// initialises the data from system read and we need to save it
|
// initialises the data from system read and we need to save it
|
||||||
// after
|
// after
|
||||||
curves
|
curves
|
||||||
.device_mut()
|
.profiles_mut()
|
||||||
.write_profile_curve_to_platform(active, &mut device)?;
|
.write_profile_curve_to_platform(active, &mut device)?;
|
||||||
curves.update_config();
|
|
||||||
ctrl.profile_config.write();
|
ctrl.profile_config.write();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ use daemon::config::Config;
|
|||||||
use daemon::ctrl_anime::config::AnimeConfig;
|
use daemon::ctrl_anime::config::AnimeConfig;
|
||||||
use daemon::ctrl_anime::trait_impls::CtrlAnimeZbus;
|
use daemon::ctrl_anime::trait_impls::CtrlAnimeZbus;
|
||||||
use daemon::ctrl_anime::CtrlAnime;
|
use daemon::ctrl_anime::CtrlAnime;
|
||||||
use daemon::ctrl_aura::config::AuraConfig;
|
|
||||||
use daemon::ctrl_aura::controller::CtrlKbdLed;
|
use daemon::ctrl_aura::controller::CtrlKbdLed;
|
||||||
use daemon::ctrl_aura::trait_impls::CtrlKbdLedZbus;
|
use daemon::ctrl_aura::trait_impls::CtrlKbdLedZbus;
|
||||||
use daemon::ctrl_platform::CtrlPlatform;
|
use daemon::ctrl_platform::CtrlPlatform;
|
||||||
@@ -124,8 +123,9 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let laptop = LaptopLedData::get_data();
|
let laptop = LaptopLedData::get_data();
|
||||||
let aura_config = AuraConfig::new().load();
|
// CtrlKbdLed deviates from the config pattern above due to requiring a keyboard
|
||||||
match CtrlKbdLed::new(laptop, aura_config) {
|
// detection first
|
||||||
|
match CtrlKbdLed::new(laptop) {
|
||||||
Ok(ctrl) => {
|
Ok(ctrl) => {
|
||||||
let zbus = CtrlKbdLedZbus(Arc::new(Mutex::new(ctrl)));
|
let zbus = CtrlKbdLedZbus(Arc::new(Mutex::new(ctrl)));
|
||||||
let sig_ctx = CtrlKbdLedZbus::signal_context(&connection)?;
|
let sig_ctx = CtrlKbdLedZbus::signal_context(&connection)?;
|
||||||
|
|||||||
@@ -32,4 +32,7 @@ zbus = { workspace = true, optional = true }
|
|||||||
|
|
||||||
sysfs-class = { workspace = true, optional = true }
|
sysfs-class = { workspace = true, optional = true }
|
||||||
|
|
||||||
uhid-virt = "^0.0.5"
|
uhid-virt = "^0.0.6"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
cargo-husky.workspace = true
|
||||||
@@ -212,7 +212,7 @@ pub fn run_animation(frames: &AnimeGif, callback: &dyn Fn(AnimeDataBuffer) -> Re
|
|||||||
|
|
||||||
// TODO: Log this error
|
// TODO: Log this error
|
||||||
if matches!(callback(output), Ok(true)) {
|
if matches!(callback(output), Ok(true)) {
|
||||||
info!("rog-anime: frame-loop callback asked to exit early");
|
info!("rog-anime: animation frame-loop callback asked to exit early");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,9 @@ impl AnimeImage {
|
|||||||
///
|
///
|
||||||
/// In relation to the display itself you should think of it as a full
|
/// In relation to the display itself you should think of it as a full
|
||||||
/// square grid, so `first_x` is the x position on that grid where the
|
/// square grid, so `first_x` is the x position on that grid where the
|
||||||
/// LED is actually positioned in relation to the Y. ```text
|
/// LED is actually positioned in relation to the Y.
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
/// +------------+
|
/// +------------+
|
||||||
/// | |
|
/// | |
|
||||||
/// | |
|
/// | |
|
||||||
|
|||||||
+4
-1
@@ -27,4 +27,7 @@ log.workspace = true
|
|||||||
# Device control
|
# Device control
|
||||||
sysfs-class.workspace = true # used for backlight control and baord ID
|
sysfs-class.workspace = true # used for backlight control and baord ID
|
||||||
|
|
||||||
ron = { version = "*", optional = true }
|
ron = { version = "*", optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
cargo-husky.workspace = true
|
||||||
@@ -34,6 +34,20 @@
|
|||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: None,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
board_name: "FX506LH",
|
||||||
|
layout_name: "fa506i",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
board_name: "FX516P",
|
||||||
|
layout_name: "fa506i",
|
||||||
|
basic_modes: [Static, Breathe, Strobe],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
board_name: "G512",
|
board_name: "G512",
|
||||||
layout_name: "g512",
|
layout_name: "g512",
|
||||||
@@ -181,6 +195,13 @@
|
|||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: PerKey,
|
advanced_type: PerKey,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
board_name: "G533Z",
|
||||||
|
layout_name: "g533q-per-key",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: PerKey,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
board_name: "G712LI",
|
board_name: "G712LI",
|
||||||
layout_name: "gl503",
|
layout_name: "gl503",
|
||||||
@@ -286,6 +307,20 @@
|
|||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: PerKey,
|
advanced_type: PerKey,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
board_name: "G733Z",
|
||||||
|
layout_name: "g513i-per-key",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: PerKey,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
board_name: "GA401Q",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
board_name: "GA402R",
|
board_name: "GA402R",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
@@ -391,6 +426,13 @@
|
|||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: Zoned([SingleZone]),
|
advanced_type: Zoned([SingleZone]),
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
board_name: "GU604V",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: Zoned([SingleZone]),
|
||||||
|
),
|
||||||
(
|
(
|
||||||
board_name: "GV301Q",
|
board_name: "GV301Q",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
@@ -398,6 +440,20 @@
|
|||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: None,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
board_name: "GV301V",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
board_name: "GV301VIC",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
board_name: "GV601R",
|
board_name: "GV601R",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
@@ -405,6 +461,13 @@
|
|||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: None,
|
advanced_type: None,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
board_name: "GV604V",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
board_name: "GX502",
|
board_name: "GX502",
|
||||||
layout_name: "gx502",
|
layout_name: "gx502",
|
||||||
@@ -433,6 +496,13 @@
|
|||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
advanced_type: PerKey,
|
advanced_type: PerKey,
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
board_name: "GX650P",
|
||||||
|
layout_name: "gx531-per-key",
|
||||||
|
basic_modes: [Static, Breathe, Strobe, Rainbow, Star, Rain, Highlight, Laser, Ripple, Pulse, Comet, Flash],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: PerKey,
|
||||||
|
),
|
||||||
(
|
(
|
||||||
board_name: "GX701",
|
board_name: "GX701",
|
||||||
layout_name: "gx531-per-key",
|
layout_name: "gx531-per-key",
|
||||||
@@ -448,7 +518,14 @@
|
|||||||
advanced_type: None,
|
advanced_type: None,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
board_name: "ga401qQ",
|
board_name: "GZ301V",
|
||||||
|
layout_name: "ga401q",
|
||||||
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
|
basic_zones: [],
|
||||||
|
advanced_type: None,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
board_name: "GZ301VIC",
|
||||||
layout_name: "ga401q",
|
layout_name: "ga401q",
|
||||||
basic_modes: [Static, Breathe, Pulse],
|
basic_modes: [Static, Breathe, Pulse],
|
||||||
basic_zones: [],
|
basic_zones: [],
|
||||||
|
|||||||
@@ -303,6 +303,7 @@ impl LedUsbPackets {
|
|||||||
fn rgb_for_led_code(&mut self, led_code: LedCode) -> Option<&mut [u8]> {
|
fn rgb_for_led_code(&mut self, led_code: LedCode) -> Option<&mut [u8]> {
|
||||||
let zoned = self.zoned;
|
let zoned = self.zoned;
|
||||||
// Tuples are indexes in to array
|
// Tuples are indexes in to array
|
||||||
|
#[allow(clippy::match_same_arms)]
|
||||||
let (row, col) = match led_code {
|
let (row, col) = match led_code {
|
||||||
LedCode::VolDown => (0, 15),
|
LedCode::VolDown => (0, 15),
|
||||||
LedCode::VolUp => (0, 18),
|
LedCode::VolUp => (0, 18),
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ impl From<LedCode> for &str {
|
|||||||
|
|
||||||
impl From<&LedCode> for &str {
|
impl From<&LedCode> for &str {
|
||||||
fn from(k: &LedCode) -> Self {
|
fn from(k: &LedCode) -> Self {
|
||||||
|
#[allow(clippy::match_same_arms)]
|
||||||
match k {
|
match k {
|
||||||
LedCode::VolUp => "Volume Up",
|
LedCode::VolUp => "Volume Up",
|
||||||
LedCode::VolDown => "Volume Down",
|
LedCode::VolDown => "Volume Down",
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
use std::fs::OpenOptions;
|
|
||||||
use std::io::Read;
|
|
||||||
|
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::usb::AuraDevice;
|
||||||
use crate::{AdvancedAuraType, AuraModeNum, AuraZone};
|
use crate::{AdvancedAuraType, AuraModeNum, AuraZone};
|
||||||
|
|
||||||
pub const ASUS_LED_MODE_CONF: &str = "/usr/share/asusd/aura_support.ron";
|
pub const ASUS_LED_MODE_CONF: &str = "/usr/share/asusd/aura_support.ron";
|
||||||
pub const ASUS_LED_MODE_USER_CONF: &str = "/etc/asusd/asusd_user_ledmodes.ron";
|
pub const ASUS_LED_MODE_USER_CONF: &str = "/etc/asusd/asusd_user_ledmodes.ron";
|
||||||
pub const ASUS_KEYBOARD_DEVICES: [&str; 4] = ["1866", "1869", "1854", "19b6"];
|
pub const ASUS_KEYBOARD_DEVICES: [AuraDevice; 7] = [
|
||||||
|
AuraDevice::Tuf,
|
||||||
|
AuraDevice::X1854,
|
||||||
|
AuraDevice::X1869,
|
||||||
|
AuraDevice::X1866,
|
||||||
|
AuraDevice::X18c6,
|
||||||
|
AuraDevice::X19b6,
|
||||||
|
AuraDevice::X1a30,
|
||||||
|
];
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub struct LedSupportFile(Vec<LaptopLedData>);
|
pub struct LedSupportFile(Vec<LaptopLedData>);
|
||||||
@@ -76,39 +82,33 @@ impl LedSupportFile {
|
|||||||
let mut loaded = false;
|
let mut loaded = false;
|
||||||
let mut data = LedSupportFile::default();
|
let mut data = LedSupportFile::default();
|
||||||
// Load user configs first so they are first to be checked
|
// Load user configs first so they are first to be checked
|
||||||
if let Ok(mut file) = OpenOptions::new().read(true).open(ASUS_LED_MODE_USER_CONF) {
|
if let Ok(file) = std::fs::read_to_string(ASUS_LED_MODE_USER_CONF) {
|
||||||
let mut buf = String::new();
|
if file.is_empty() {
|
||||||
if let Ok(l) = file.read_to_string(&mut buf) {
|
warn!("{} is empty", ASUS_LED_MODE_USER_CONF);
|
||||||
if l == 0 {
|
} else {
|
||||||
warn!("{} is empty", ASUS_LED_MODE_USER_CONF);
|
if let Ok(mut tmp) = ron::from_str::<LedSupportFile>(&file) {
|
||||||
} else {
|
data.0.append(&mut tmp.0);
|
||||||
if let Ok(mut tmp) = ron::from_str::<LedSupportFile>(&buf) {
|
|
||||||
data.0.append(&mut tmp.0);
|
|
||||||
}
|
|
||||||
info!(
|
|
||||||
"Loaded user-defined LED support data from {}",
|
|
||||||
ASUS_LED_MODE_USER_CONF
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
info!(
|
||||||
|
"Loaded user-defined LED support data from {}",
|
||||||
|
ASUS_LED_MODE_USER_CONF
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Load and append the default LED support data
|
// Load and append the default LED support data
|
||||||
if let Ok(mut file) = OpenOptions::new().read(true).open(ASUS_LED_MODE_CONF) {
|
if let Ok(file) = std::fs::read_to_string(ASUS_LED_MODE_CONF) {
|
||||||
let mut buf = String::new();
|
if file.is_empty() {
|
||||||
if let Ok(l) = file.read_to_string(&mut buf) {
|
warn!("{} is empty", ASUS_LED_MODE_CONF);
|
||||||
if l == 0 {
|
} else {
|
||||||
warn!("{} is empty", ASUS_LED_MODE_CONF);
|
let mut tmp: LedSupportFile = ron::from_str(&file)
|
||||||
} else {
|
.map_err(|e| error!("{e}"))
|
||||||
let mut tmp: LedSupportFile = ron::from_str(&buf)
|
.unwrap_or_else(|_| panic!("Could not deserialise {}", ASUS_LED_MODE_CONF));
|
||||||
.map_err(|e| error!("{e}"))
|
data.0.append(&mut tmp.0);
|
||||||
.unwrap_or_else(|_| panic!("Could not deserialise {}", ASUS_LED_MODE_CONF));
|
loaded = true;
|
||||||
data.0.append(&mut tmp.0);
|
info!(
|
||||||
loaded = true;
|
"Loaded default LED support data from {}",
|
||||||
info!(
|
ASUS_LED_MODE_CONF
|
||||||
"Loaded default LED support data from {}",
|
);
|
||||||
ASUS_LED_MODE_CONF
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data.0.sort_by(|a, b| a.board_name.cmp(&b.board_name));
|
data.0.sort_by(|a, b| a.board_name.cmp(&b.board_name));
|
||||||
@@ -125,7 +125,7 @@ impl LedSupportFile {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::io::{Read, Write};
|
use std::io::Write;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use ron::ser::PrettyConfig;
|
use ron::ser::PrettyConfig;
|
||||||
@@ -155,9 +155,7 @@ mod tests {
|
|||||||
let mut data = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
let mut data = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
data.push("data/aura_support.ron");
|
data.push("data/aura_support.ron");
|
||||||
|
|
||||||
let mut file = OpenOptions::new().read(true).open(&data).unwrap();
|
let buf = std::fs::read_to_string(&data).unwrap();
|
||||||
let mut buf = String::new();
|
|
||||||
file.read_to_string(&mut buf).unwrap();
|
|
||||||
|
|
||||||
let tmp = ron::from_str::<LedSupportFile>(&buf).unwrap();
|
let tmp = ron::from_str::<LedSupportFile>(&buf).unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -284,7 +284,8 @@ impl FromStr for AuraZone {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Default factory modes structure. This easily converts to an USB HID packet
|
/// Default factory modes structure. This easily converts to an USB HID packet
|
||||||
/// with: ```rust
|
/// with:
|
||||||
|
/// ```rust
|
||||||
/// // let bytes: [u8; LED_MSG_LEN] = mode.into();
|
/// // let bytes: [u8; LED_MSG_LEN] = mode.into();
|
||||||
/// ```
|
/// ```
|
||||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||||
@@ -350,6 +351,7 @@ pub struct AuraParameters {
|
|||||||
pub direction: bool,
|
pub direction: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::fn_params_excessive_bools)]
|
||||||
impl AuraParameters {
|
impl AuraParameters {
|
||||||
pub const fn new(
|
pub const fn new(
|
||||||
zone: bool,
|
zone: bool,
|
||||||
|
|||||||
@@ -28,6 +28,6 @@ impl EffectState for InputBased {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn set_led(&mut self, address: LedCode) {
|
fn set_led(&mut self, address: LedCode) {
|
||||||
self.led = address
|
self.led = address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-27
@@ -2,8 +2,6 @@
|
|||||||
//! editable config.
|
//! editable config.
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fs::{self, OpenOptions};
|
|
||||||
use std::io::Read;
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::slice::Iter;
|
use std::slice::Iter;
|
||||||
|
|
||||||
@@ -88,8 +86,8 @@ impl KeyShape {
|
|||||||
/// The first `Key` will determine the row height.
|
/// The first `Key` will determine the row height.
|
||||||
///
|
///
|
||||||
/// Every row is considered to start a x=0, with the first row being y=0,
|
/// Every row is considered to start a x=0, with the first row being y=0,
|
||||||
/// and following rows starting after the previous row_y+pad_top and
|
/// and following rows starting after the previous `row_y + pad_top` and
|
||||||
/// row_x+pad_left
|
/// `row_x + pad_left`
|
||||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
pub struct KeyRow {
|
pub struct KeyRow {
|
||||||
pad_left: f32,
|
pad_left: f32,
|
||||||
@@ -138,7 +136,7 @@ impl KeyRow {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if h < height {
|
if h < height {
|
||||||
h = height
|
h = height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h
|
h
|
||||||
@@ -192,15 +190,9 @@ pub struct KeyLayout {
|
|||||||
|
|
||||||
impl KeyLayout {
|
impl KeyLayout {
|
||||||
pub fn from_file(path: &Path) -> Result<Self, Error> {
|
pub fn from_file(path: &Path) -> Result<Self, Error> {
|
||||||
let mut file = OpenOptions::new()
|
let buf: String = std::fs::read_to_string(path)
|
||||||
.read(true)
|
|
||||||
.open(path)
|
|
||||||
.map_err(|e| Error::IoPath(path.to_string_lossy().to_string(), e))?;
|
.map_err(|e| Error::IoPath(path.to_string_lossy().to_string(), e))?;
|
||||||
let mut buf = String::new();
|
if buf.is_empty() {
|
||||||
let read_len = file
|
|
||||||
.read_to_string(&mut buf)
|
|
||||||
.map_err(|e| Error::IoPath(path.to_string_lossy().to_string(), e))?;
|
|
||||||
if read_len == 0 {
|
|
||||||
Err(Error::IoPath(
|
Err(Error::IoPath(
|
||||||
path.to_string_lossy().to_string(),
|
path.to_string_lossy().to_string(),
|
||||||
std::io::ErrorKind::InvalidData.into(),
|
std::io::ErrorKind::InvalidData.into(),
|
||||||
@@ -233,7 +225,7 @@ impl KeyLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rows(&self) -> Iter<KeyRow> {
|
pub fn rows(&self) -> Iter<'_, KeyRow> {
|
||||||
self.key_rows.iter()
|
self.key_rows.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,7 +271,7 @@ impl KeyLayout {
|
|||||||
for r in &self.key_rows {
|
for r in &self.key_rows {
|
||||||
let tmp = r.width();
|
let tmp = r.width();
|
||||||
if width < tmp {
|
if width < tmp {
|
||||||
width = tmp
|
width = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
width
|
width
|
||||||
@@ -288,7 +280,13 @@ impl KeyLayout {
|
|||||||
/// Find a layout matching the name in `LaptopLedData` in the provided dir
|
/// Find a layout matching the name in `LaptopLedData` in the provided dir
|
||||||
pub fn find_layout(led_data: LaptopLedData, mut data_path: PathBuf) -> Result<Self, Error> {
|
pub fn find_layout(led_data: LaptopLedData, mut data_path: PathBuf) -> Result<Self, Error> {
|
||||||
// TODO: locales
|
// TODO: locales
|
||||||
let layout_file = format!("{}_US.ron", led_data.layout_name);
|
let layout_name = if led_data.layout_name.is_empty() {
|
||||||
|
"ga401q".to_owned() // Need some sort of default here due to ROGCC
|
||||||
|
// expecting it
|
||||||
|
} else {
|
||||||
|
led_data.layout_name
|
||||||
|
};
|
||||||
|
let layout_file = format!("{layout_name}_US.ron");
|
||||||
data_path.push("layouts");
|
data_path.push("layouts");
|
||||||
data_path.push(layout_file);
|
data_path.push(layout_file);
|
||||||
let path = data_path.as_path();
|
let path = data_path.as_path();
|
||||||
@@ -305,7 +303,7 @@ impl KeyLayout {
|
|||||||
data_path.push("layouts");
|
data_path.push("layouts");
|
||||||
let path = data_path.as_path();
|
let path = data_path.as_path();
|
||||||
let mut files = Vec::new();
|
let mut files = Vec::new();
|
||||||
fs::read_dir(path)
|
std::fs::read_dir(path)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
println!("{:?}, {e}", path);
|
println!("{:?}, {e}", path);
|
||||||
e
|
e
|
||||||
@@ -471,7 +469,6 @@ mod tests {
|
|||||||
data_path.push("data");
|
data_path.push("data");
|
||||||
data_path.push("layouts");
|
data_path.push("layouts");
|
||||||
let path = data_path.as_path();
|
let path = data_path.as_path();
|
||||||
let mut buf = String::new();
|
|
||||||
for p in fs::read_dir(path)
|
for p in fs::read_dir(path)
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
println!("{:?}, {e}", path);
|
println!("{:?}, {e}", path);
|
||||||
@@ -479,9 +476,7 @@ mod tests {
|
|||||||
})
|
})
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
let path = p.unwrap().path();
|
let mut buf = std::fs::read_to_string(p.unwrap().path()).unwrap();
|
||||||
let mut file = OpenOptions::new().read(true).open(&path).unwrap();
|
|
||||||
file.read_to_string(&mut buf).unwrap();
|
|
||||||
|
|
||||||
let data: KeyLayout = ron::from_str(&buf).unwrap();
|
let data: KeyLayout = ron::from_str(&buf).unwrap();
|
||||||
|
|
||||||
@@ -501,9 +496,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !unused.is_empty() {
|
assert!(
|
||||||
panic!("The layout {path:?} had unused shapes {unused:?}",);
|
unused.is_empty(),
|
||||||
}
|
"The layout {path:?} had unused shapes {unused:?}",
|
||||||
|
);
|
||||||
buf.clear();
|
buf.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,9 +523,7 @@ mod tests {
|
|||||||
data_path.push("data");
|
data_path.push("data");
|
||||||
data_path.push("aura_support.ron");
|
data_path.push("aura_support.ron");
|
||||||
|
|
||||||
let mut buf = String::new();
|
let mut buf = std::fs::read_to_string(&data_path).unwrap();
|
||||||
let mut file = OpenOptions::new().read(true).open(&data_path).unwrap();
|
|
||||||
file.read_to_string(&mut buf).unwrap();
|
|
||||||
let data: LedSupportFile = ron::from_str(&buf).unwrap();
|
let data: LedSupportFile = ron::from_str(&buf).unwrap();
|
||||||
|
|
||||||
data_path.pop();
|
data_path.pop();
|
||||||
@@ -553,6 +547,7 @@ mod tests {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
#[allow(clippy::verbose_file_reads)]
|
||||||
if let Err(e) = file.read_to_string(&mut buf) {
|
if let Err(e) = file.read_to_string(&mut buf) {
|
||||||
panic!(
|
panic!(
|
||||||
"Error checking {data_path:?} for {} : {e:?}",
|
"Error checking {data_path:?} for {} : {e:?}",
|
||||||
|
|||||||
+131
-110
@@ -23,25 +23,44 @@ pub const fn aura_brightness_bytes(brightness: u8) -> [u8; 17] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Serialize, Deserialize, Default)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Serialize, Deserialize, Default)]
|
||||||
pub enum AuraDevice {
|
pub enum AuraDevice {
|
||||||
Tuf,
|
Tuf,
|
||||||
X1854,
|
X1854,
|
||||||
X1869,
|
X1869,
|
||||||
X1866,
|
X1866,
|
||||||
|
X18c6,
|
||||||
#[default]
|
#[default]
|
||||||
X19B6,
|
X19b6,
|
||||||
|
X1a30,
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<AuraDevice> for &str {
|
||||||
|
fn from(a: AuraDevice) -> Self {
|
||||||
|
match a {
|
||||||
|
AuraDevice::Tuf => "tuf",
|
||||||
|
AuraDevice::X1854 => "1854",
|
||||||
|
AuraDevice::X1869 => "1869",
|
||||||
|
AuraDevice::X1866 => "1866",
|
||||||
|
AuraDevice::X18c6 => "18c6",
|
||||||
|
AuraDevice::X19b6 => "19b6",
|
||||||
|
AuraDevice::X1a30 => "1a30",
|
||||||
|
AuraDevice::Unknown => "unknown",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<&str> for AuraDevice {
|
impl From<&str> for AuraDevice {
|
||||||
fn from(s: &str) -> Self {
|
fn from(s: &str) -> Self {
|
||||||
match s.to_lowercase().as_str() {
|
match s.to_lowercase().as_str() {
|
||||||
"tuf" => AuraDevice::Tuf,
|
"tuf" => AuraDevice::Tuf,
|
||||||
"1866" | "0x1866" => AuraDevice::X1866,
|
"1866" | "0x1866" => AuraDevice::X1866,
|
||||||
|
"18c6" | "0x18c6" => AuraDevice::X18c6,
|
||||||
"1869" | "0x1869" => AuraDevice::X1869,
|
"1869" | "0x1869" => AuraDevice::X1869,
|
||||||
"1854" | "0x1854" => AuraDevice::X1854,
|
"1854" | "0x1854" => AuraDevice::X1854,
|
||||||
"19b6" | "0x19b6" => AuraDevice::X19B6,
|
"19b6" | "0x19b6" => AuraDevice::X19b6,
|
||||||
|
"1a30" | "0x1a30" => AuraDevice::X1a30,
|
||||||
_ => AuraDevice::Unknown,
|
_ => AuraDevice::Unknown,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,7 +73,9 @@ impl Debug for AuraDevice {
|
|||||||
Self::X1854 => write!(f, "0x1854"),
|
Self::X1854 => write!(f, "0x1854"),
|
||||||
Self::X1869 => write!(f, "0x1869"),
|
Self::X1869 => write!(f, "0x1869"),
|
||||||
Self::X1866 => write!(f, "0x1866"),
|
Self::X1866 => write!(f, "0x1866"),
|
||||||
Self::X19B6 => write!(f, "0x19B6"),
|
Self::X18c6 => write!(f, "0x18c6"),
|
||||||
|
Self::X19b6 => write!(f, "0x19B6"),
|
||||||
|
Self::X1a30 => write!(f, "0x1A30"),
|
||||||
Self::Unknown => write!(f, "Unknown"),
|
Self::Unknown => write!(f, "Unknown"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,8 +86,8 @@ impl Debug for AuraDevice {
|
|||||||
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
|
||||||
pub struct AuraPowerDev {
|
pub struct AuraPowerDev {
|
||||||
pub tuf: Vec<AuraDevTuf>,
|
pub tuf: Vec<AuraDevTuf>,
|
||||||
pub x1866: Vec<AuraDev1866>,
|
pub x1866: Vec<AuraDevRog1>,
|
||||||
pub x19b6: Vec<AuraDev19b6>,
|
pub x19b6: Vec<AuraDevRog2>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||||
@@ -85,7 +106,7 @@ impl AuraDevTuf {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Bits for older 0x1866 keyboard model
|
/// # Bits for older 0x1866, 0x1869, 0x1854 keyboard models
|
||||||
///
|
///
|
||||||
/// Keybord and Lightbar require Awake, Boot and Sleep apply to both
|
/// Keybord and Lightbar require Awake, Boot and Sleep apply to both
|
||||||
/// Keybord and Lightbar regardless of if either are enabled (or Awake is
|
/// Keybord and Lightbar regardless of if either are enabled (or Awake is
|
||||||
@@ -102,7 +123,7 @@ impl AuraDevTuf {
|
|||||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum AuraDev1866 {
|
pub enum AuraDevRog1 {
|
||||||
Awake = 0x000002,
|
Awake = 0x000002,
|
||||||
Keyboard = 0x080000,
|
Keyboard = 0x080000,
|
||||||
Lightbar = 0x040500,
|
Lightbar = 0x040500,
|
||||||
@@ -110,13 +131,13 @@ pub enum AuraDev1866 {
|
|||||||
Sleep = 0x300804,
|
Sleep = 0x300804,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<AuraDev1866> for u32 {
|
impl From<AuraDevRog1> for u32 {
|
||||||
fn from(a: AuraDev1866) -> Self {
|
fn from(a: AuraDevRog1) -> Self {
|
||||||
a as u32
|
a as u32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AuraDev1866 {
|
impl AuraDevRog1 {
|
||||||
pub fn to_bytes(control: &[Self]) -> [u8; 3] {
|
pub fn to_bytes(control: &[Self]) -> [u8; 3] {
|
||||||
let mut a: u32 = 0;
|
let mut a: u32 = 0;
|
||||||
for n in control {
|
for n in control {
|
||||||
@@ -134,23 +155,23 @@ impl AuraDev1866 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitOr<AuraDev1866> for AuraDev1866 {
|
impl BitOr<AuraDevRog1> for AuraDevRog1 {
|
||||||
type Output = u32;
|
type Output = u32;
|
||||||
|
|
||||||
fn bitor(self, rhs: AuraDev1866) -> Self::Output {
|
fn bitor(self, rhs: AuraDevRog1) -> Self::Output {
|
||||||
self as u32 | rhs as u32
|
self as u32 | rhs as u32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitAnd<AuraDev1866> for AuraDev1866 {
|
impl BitAnd<AuraDevRog1> for AuraDevRog1 {
|
||||||
type Output = u32;
|
type Output = u32;
|
||||||
|
|
||||||
fn bitand(self, rhs: AuraDev1866) -> Self::Output {
|
fn bitand(self, rhs: AuraDevRog1) -> Self::Output {
|
||||||
self as u32 & rhs as u32
|
self as u32 & rhs as u32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Bits for 0x19b6 keyboard model
|
/// # Bits for newer 0x18c6, 0x19B6, 0x1a30, keyboard models
|
||||||
///
|
///
|
||||||
/// byte 4 in the USB packet is for keyboard + logo power states
|
/// byte 4 in the USB packet is for keyboard + logo power states
|
||||||
/// default is on, `ff`
|
/// default is on, `ff`
|
||||||
@@ -179,7 +200,7 @@ impl BitAnd<AuraDev1866> for AuraDev1866 {
|
|||||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum AuraDev19b6 {
|
pub enum AuraDevRog2 {
|
||||||
BootLogo = 1,
|
BootLogo = 1,
|
||||||
BootKeyb = 1 << 1,
|
BootKeyb = 1 << 1,
|
||||||
AwakeLogo = 1 << 2,
|
AwakeLogo = 1 << 2,
|
||||||
@@ -198,13 +219,13 @@ pub enum AuraDev19b6 {
|
|||||||
ShutdownLid = 1 << (15 + 4),
|
ShutdownLid = 1 << (15 + 4),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<AuraDev19b6> for u32 {
|
impl From<AuraDevRog2> for u32 {
|
||||||
fn from(a: AuraDev19b6) -> Self {
|
fn from(a: AuraDevRog2) -> Self {
|
||||||
a as u32
|
a as u32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AuraDev19b6 {
|
impl AuraDevRog2 {
|
||||||
pub fn to_bytes(control: &[Self]) -> [u8; 3] {
|
pub fn to_bytes(control: &[Self]) -> [u8; 3] {
|
||||||
let mut a: u32 = 0;
|
let mut a: u32 = 0;
|
||||||
for n in control {
|
for n in control {
|
||||||
@@ -222,58 +243,58 @@ impl AuraDev19b6 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitOr<AuraDev19b6> for AuraDev19b6 {
|
impl BitOr<AuraDevRog2> for AuraDevRog2 {
|
||||||
type Output = u16;
|
type Output = u16;
|
||||||
|
|
||||||
fn bitor(self, rhs: AuraDev19b6) -> Self::Output {
|
fn bitor(self, rhs: AuraDevRog2) -> Self::Output {
|
||||||
self as u16 | rhs as u16
|
self as u16 | rhs as u16
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BitAnd<AuraDev19b6> for AuraDev19b6 {
|
impl BitAnd<AuraDevRog2> for AuraDevRog2 {
|
||||||
type Output = u16;
|
type Output = u16;
|
||||||
|
|
||||||
fn bitand(self, rhs: AuraDev19b6) -> Self::Output {
|
fn bitand(self, rhs: AuraDevRog2) -> Self::Output {
|
||||||
self as u16 & rhs as u16
|
self as u16 & rhs as u16
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::AuraDev1866;
|
use super::AuraDevRog1;
|
||||||
use crate::usb::AuraDev19b6;
|
use crate::usb::AuraDevRog2;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_0x1866_control_bytes() {
|
fn check_0x1866_control_bytes() {
|
||||||
let bytes = [AuraDev1866::Keyboard, AuraDev1866::Awake];
|
let bytes = [AuraDevRog1::Keyboard, AuraDevRog1::Awake];
|
||||||
let bytes = AuraDev1866::to_bytes(&bytes);
|
let bytes = AuraDevRog1::to_bytes(&bytes);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes, [0x08, 0x00, 0x02]);
|
assert_eq!(bytes, [0x08, 0x00, 0x02]);
|
||||||
|
|
||||||
let bytes = [AuraDev1866::Lightbar, AuraDev1866::Awake];
|
let bytes = [AuraDevRog1::Lightbar, AuraDevRog1::Awake];
|
||||||
let bytes = AuraDev1866::to_bytes(&bytes);
|
let bytes = AuraDevRog1::to_bytes(&bytes);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes, [0x04, 0x05, 0x02]);
|
assert_eq!(bytes, [0x04, 0x05, 0x02]);
|
||||||
|
|
||||||
let bytes = [AuraDev1866::Sleep];
|
let bytes = [AuraDevRog1::Sleep];
|
||||||
let bytes = AuraDev1866::to_bytes(&bytes);
|
let bytes = AuraDevRog1::to_bytes(&bytes);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes, [0x30, 0x08, 0x04]);
|
assert_eq!(bytes, [0x30, 0x08, 0x04]);
|
||||||
|
|
||||||
let bytes = [AuraDev1866::Boot];
|
let bytes = [AuraDevRog1::Boot];
|
||||||
let bytes = AuraDev1866::to_bytes(&bytes);
|
let bytes = AuraDevRog1::to_bytes(&bytes);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes, [0xc3, 0x12, 0x09]);
|
assert_eq!(bytes, [0xc3, 0x12, 0x09]);
|
||||||
|
|
||||||
let bytes = [
|
let bytes = [
|
||||||
AuraDev1866::Keyboard,
|
AuraDevRog1::Keyboard,
|
||||||
AuraDev1866::Lightbar,
|
AuraDevRog1::Lightbar,
|
||||||
AuraDev1866::Awake,
|
AuraDevRog1::Awake,
|
||||||
AuraDev1866::Sleep,
|
AuraDevRog1::Sleep,
|
||||||
AuraDev1866::Boot,
|
AuraDevRog1::Boot,
|
||||||
];
|
];
|
||||||
|
|
||||||
let bytes = AuraDev1866::to_bytes(&bytes);
|
let bytes = AuraDevRog1::to_bytes(&bytes);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes, [0xff, 0x1f, 0x000f]);
|
assert_eq!(bytes, [0xff, 0x1f, 0x000f]);
|
||||||
}
|
}
|
||||||
@@ -282,143 +303,143 @@ mod tests {
|
|||||||
fn check_0x19b6_control_bytes() {
|
fn check_0x19b6_control_bytes() {
|
||||||
// All on
|
// All on
|
||||||
let byte1 = [
|
let byte1 = [
|
||||||
AuraDev19b6::BootLogo,
|
AuraDevRog2::BootLogo,
|
||||||
AuraDev19b6::BootKeyb,
|
AuraDevRog2::BootKeyb,
|
||||||
AuraDev19b6::SleepLogo,
|
AuraDevRog2::SleepLogo,
|
||||||
AuraDev19b6::SleepKeyb,
|
AuraDevRog2::SleepKeyb,
|
||||||
AuraDev19b6::AwakeLogo,
|
AuraDevRog2::AwakeLogo,
|
||||||
AuraDev19b6::AwakeKeyb,
|
AuraDevRog2::AwakeKeyb,
|
||||||
AuraDev19b6::ShutdownLogo,
|
AuraDevRog2::ShutdownLogo,
|
||||||
AuraDev19b6::ShutdownKeyb,
|
AuraDevRog2::ShutdownKeyb,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte1);
|
let bytes = AuraDevRog2::to_bytes(&byte1);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[0], 0xff);
|
assert_eq!(bytes[0], 0xff);
|
||||||
|
|
||||||
//
|
//
|
||||||
let byte1 = [
|
let byte1 = [
|
||||||
// AuraControl::BootLogo,
|
// AuraControl::BootLogo,
|
||||||
AuraDev19b6::BootKeyb,
|
AuraDevRog2::BootKeyb,
|
||||||
AuraDev19b6::SleepLogo,
|
AuraDevRog2::SleepLogo,
|
||||||
AuraDev19b6::SleepKeyb,
|
AuraDevRog2::SleepKeyb,
|
||||||
AuraDev19b6::AwakeLogo,
|
AuraDevRog2::AwakeLogo,
|
||||||
AuraDev19b6::AwakeKeyb,
|
AuraDevRog2::AwakeKeyb,
|
||||||
AuraDev19b6::ShutdownLogo,
|
AuraDevRog2::ShutdownLogo,
|
||||||
AuraDev19b6::ShutdownKeyb,
|
AuraDevRog2::ShutdownKeyb,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte1);
|
let bytes = AuraDevRog2::to_bytes(&byte1);
|
||||||
println!("{:08b}", bytes[0]);
|
println!("{:08b}", bytes[0]);
|
||||||
assert_eq!(bytes[0], 0xfe);
|
assert_eq!(bytes[0], 0xfe);
|
||||||
|
|
||||||
let byte1 = [
|
let byte1 = [
|
||||||
AuraDev19b6::BootLogo,
|
AuraDevRog2::BootLogo,
|
||||||
// AuraControl::BootKeyb,
|
// AuraControl::BootKeyb,
|
||||||
AuraDev19b6::SleepLogo,
|
AuraDevRog2::SleepLogo,
|
||||||
AuraDev19b6::SleepKeyb,
|
AuraDevRog2::SleepKeyb,
|
||||||
AuraDev19b6::AwakeLogo,
|
AuraDevRog2::AwakeLogo,
|
||||||
AuraDev19b6::AwakeKeyb,
|
AuraDevRog2::AwakeKeyb,
|
||||||
AuraDev19b6::ShutdownLogo,
|
AuraDevRog2::ShutdownLogo,
|
||||||
AuraDev19b6::ShutdownKeyb,
|
AuraDevRog2::ShutdownKeyb,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte1);
|
let bytes = AuraDevRog2::to_bytes(&byte1);
|
||||||
println!("{:08b}", bytes[0]);
|
println!("{:08b}", bytes[0]);
|
||||||
assert_eq!(bytes[0], 0xfd);
|
assert_eq!(bytes[0], 0xfd);
|
||||||
|
|
||||||
let byte1 = [
|
let byte1 = [
|
||||||
AuraDev19b6::BootLogo,
|
AuraDevRog2::BootLogo,
|
||||||
AuraDev19b6::BootKeyb,
|
AuraDevRog2::BootKeyb,
|
||||||
// AuraControl::SleepLogo,
|
// AuraControl::SleepLogo,
|
||||||
AuraDev19b6::SleepKeyb,
|
AuraDevRog2::SleepKeyb,
|
||||||
AuraDev19b6::AwakeLogo,
|
AuraDevRog2::AwakeLogo,
|
||||||
AuraDev19b6::AwakeKeyb,
|
AuraDevRog2::AwakeKeyb,
|
||||||
AuraDev19b6::ShutdownLogo,
|
AuraDevRog2::ShutdownLogo,
|
||||||
AuraDev19b6::ShutdownKeyb,
|
AuraDevRog2::ShutdownKeyb,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte1);
|
let bytes = AuraDevRog2::to_bytes(&byte1);
|
||||||
println!("{:08b}", bytes[0]);
|
println!("{:08b}", bytes[0]);
|
||||||
assert_eq!(bytes[0], 0xef);
|
assert_eq!(bytes[0], 0xef);
|
||||||
|
|
||||||
let byte1 = [
|
let byte1 = [
|
||||||
AuraDev19b6::BootLogo,
|
AuraDevRog2::BootLogo,
|
||||||
AuraDev19b6::BootKeyb,
|
AuraDevRog2::BootKeyb,
|
||||||
AuraDev19b6::SleepLogo,
|
AuraDevRog2::SleepLogo,
|
||||||
// AuraControl::SleepKeyb,
|
// AuraControl::SleepKeyb,
|
||||||
AuraDev19b6::AwakeLogo,
|
AuraDevRog2::AwakeLogo,
|
||||||
AuraDev19b6::AwakeKeyb,
|
AuraDevRog2::AwakeKeyb,
|
||||||
AuraDev19b6::ShutdownLogo,
|
AuraDevRog2::ShutdownLogo,
|
||||||
AuraDev19b6::ShutdownKeyb,
|
AuraDevRog2::ShutdownKeyb,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte1);
|
let bytes = AuraDevRog2::to_bytes(&byte1);
|
||||||
println!("{:08b}", bytes[0]);
|
println!("{:08b}", bytes[0]);
|
||||||
assert_eq!(bytes[0], 0xdf);
|
assert_eq!(bytes[0], 0xdf);
|
||||||
|
|
||||||
let byte2 = [
|
let byte2 = [
|
||||||
AuraDev19b6::BootBar,
|
AuraDevRog2::BootBar,
|
||||||
AuraDev19b6::AwakeBar,
|
AuraDevRog2::AwakeBar,
|
||||||
AuraDev19b6::SleepBar,
|
AuraDevRog2::SleepBar,
|
||||||
AuraDev19b6::ShutdownBar,
|
AuraDevRog2::ShutdownBar,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte2);
|
let bytes = AuraDevRog2::to_bytes(&byte2);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[1], 0x1e);
|
assert_eq!(bytes[1], 0x1e);
|
||||||
|
|
||||||
let byte2 = [
|
let byte2 = [
|
||||||
AuraDev19b6::BootBar,
|
AuraDevRog2::BootBar,
|
||||||
AuraDev19b6::AwakeBar,
|
AuraDevRog2::AwakeBar,
|
||||||
// AuraControl::SleepBar,
|
// AuraControl::SleepBar,
|
||||||
AuraDev19b6::ShutdownBar,
|
AuraDevRog2::ShutdownBar,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte2);
|
let bytes = AuraDevRog2::to_bytes(&byte2);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[1], 0x16);
|
assert_eq!(bytes[1], 0x16);
|
||||||
|
|
||||||
let byte3 = [
|
let byte3 = [
|
||||||
AuraDev19b6::AwakeLid,
|
AuraDevRog2::AwakeLid,
|
||||||
AuraDev19b6::BootLid,
|
AuraDevRog2::BootLid,
|
||||||
AuraDev19b6::SleepLid,
|
AuraDevRog2::SleepLid,
|
||||||
AuraDev19b6::ShutdownLid,
|
AuraDevRog2::ShutdownLid,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte3);
|
let bytes = AuraDevRog2::to_bytes(&byte3);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[2], 0x0f);
|
assert_eq!(bytes[2], 0x0f);
|
||||||
|
|
||||||
let byte3 = [
|
let byte3 = [
|
||||||
// AuraDev19b6::AwakeLid,
|
// AuraDev19b6::AwakeLid,
|
||||||
AuraDev19b6::BootLid,
|
AuraDevRog2::BootLid,
|
||||||
AuraDev19b6::SleepLid,
|
AuraDevRog2::SleepLid,
|
||||||
AuraDev19b6::ShutdownLid,
|
AuraDevRog2::ShutdownLid,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte3);
|
let bytes = AuraDevRog2::to_bytes(&byte3);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[2], 0x0d);
|
assert_eq!(bytes[2], 0x0d);
|
||||||
|
|
||||||
let byte3 = [
|
let byte3 = [
|
||||||
AuraDev19b6::AwakeLid,
|
AuraDevRog2::AwakeLid,
|
||||||
AuraDev19b6::BootLid,
|
AuraDevRog2::BootLid,
|
||||||
// AuraControl::SleepLid,
|
// AuraControl::SleepLid,
|
||||||
AuraDev19b6::ShutdownLid,
|
AuraDevRog2::ShutdownLid,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte3);
|
let bytes = AuraDevRog2::to_bytes(&byte3);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[2], 0x0b);
|
assert_eq!(bytes[2], 0x0b);
|
||||||
|
|
||||||
let byte3 = [
|
let byte3 = [
|
||||||
AuraDev19b6::AwakeLid,
|
AuraDevRog2::AwakeLid,
|
||||||
AuraDev19b6::BootLid,
|
AuraDevRog2::BootLid,
|
||||||
AuraDev19b6::SleepLid,
|
AuraDevRog2::SleepLid,
|
||||||
// AuraDev19b6::ShutdownLid,
|
// AuraDev19b6::ShutdownLid,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte3);
|
let bytes = AuraDevRog2::to_bytes(&byte3);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[2], 0x07);
|
assert_eq!(bytes[2], 0x07);
|
||||||
|
|
||||||
let byte3 = [
|
let byte3 = [
|
||||||
AuraDev19b6::AwakeLid,
|
AuraDevRog2::AwakeLid,
|
||||||
// AuraDev19b6::BootLid,
|
// AuraDev19b6::BootLid,
|
||||||
AuraDev19b6::SleepLid,
|
AuraDevRog2::SleepLid,
|
||||||
// AuraDev19b6::ShutdownLid,
|
// AuraDev19b6::ShutdownLid,
|
||||||
];
|
];
|
||||||
let bytes = AuraDev19b6::to_bytes(&byte3);
|
let bytes = AuraDevRog2::to_bytes(&byte3);
|
||||||
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
|
||||||
assert_eq!(bytes[2], 0x06);
|
assert_eq!(bytes[2], 0x06);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,13 @@ edition = "2021"
|
|||||||
mocking = []
|
mocking = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
egui = { git = "https://github.com/flukejones/egui", branch = "wayland_dark_theme" }
|
egui = { git = "https://github.com/emilk/egui", rev = "b8e798777de519de3a1878798097ab2ab0bd4def"}
|
||||||
eframe = { git = "https://github.com/flukejones/egui", branch = "wayland_dark_theme" }
|
eframe = { git = "https://github.com/emilk/egui", rev = "b8e798777de519de3a1878798097ab2ab0bd4def"}
|
||||||
|
# egui = { path = "../../egui/crates/egui" }
|
||||||
|
# eframe = { path = "../../egui/crates/eframe" }
|
||||||
|
|
||||||
libappindicator = "0.7" # Tray icon
|
libappindicator = "0.8" # Tray icon
|
||||||
gtk = "0.15.5"
|
gtk = "0.16"
|
||||||
|
|
||||||
daemon = { path = "../daemon" }
|
daemon = { path = "../daemon" }
|
||||||
rog_anime = { path = "../rog-anime" }
|
rog_anime = { path = "../rog-anime" }
|
||||||
@@ -39,5 +41,14 @@ notify-rust.workspace = true
|
|||||||
|
|
||||||
png_pong.workspace = true
|
png_pong.workspace = true
|
||||||
|
|
||||||
|
versions.workspace = true
|
||||||
|
|
||||||
nix = "^0.26.1"
|
nix = "^0.26.1"
|
||||||
tempfile = "3.3.0"
|
tempfile = "3.3.0"
|
||||||
|
|
||||||
|
# [patch.crates-io]
|
||||||
|
# egui = { git = "https://github.com/flukejones/egui" }
|
||||||
|
# eframe = { git = "https://github.com/flukejones/egui" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
cargo-husky.workspace = true
|
||||||
@@ -17,6 +17,7 @@ pub struct Config {
|
|||||||
pub ac_command: String,
|
pub ac_command: String,
|
||||||
pub bat_command: String,
|
pub bat_command: String,
|
||||||
pub enable_notifications: bool,
|
pub enable_notifications: bool,
|
||||||
|
pub dark_mode: bool,
|
||||||
// This field must be last
|
// This field must be last
|
||||||
pub enabled_notifications: EnabledNotifications,
|
pub enabled_notifications: EnabledNotifications,
|
||||||
}
|
}
|
||||||
@@ -27,6 +28,7 @@ impl Default for Config {
|
|||||||
run_in_background: true,
|
run_in_background: true,
|
||||||
startup_in_background: false,
|
startup_in_background: false,
|
||||||
enable_notifications: true,
|
enable_notifications: true,
|
||||||
|
dark_mode: true,
|
||||||
enabled_notifications: EnabledNotifications::default(),
|
enabled_notifications: EnabledNotifications::default(),
|
||||||
ac_command: String::new(),
|
ac_command: String::new(),
|
||||||
bat_command: String::new(),
|
bat_command: String::new(),
|
||||||
@@ -60,6 +62,8 @@ impl Config {
|
|||||||
|
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
|
// Lint to allow, because we want the above file behaviour
|
||||||
|
#[allow(clippy::verbose_file_reads)]
|
||||||
if let Ok(read_len) = file.read_to_string(&mut buf) {
|
if let Ok(read_len) = file.read_to_string(&mut buf) {
|
||||||
if read_len == 0 {
|
if read_len == 0 {
|
||||||
warn!("Zero len read of Config file");
|
warn!("Zero len read of Config file");
|
||||||
@@ -70,6 +74,9 @@ impl Config {
|
|||||||
} else if let Ok(data) = toml::from_str::<Config>(&buf) {
|
} else if let Ok(data) = toml::from_str::<Config>(&buf) {
|
||||||
info!("Loaded config file {path:?}");
|
info!("Loaded config file {path:?}");
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
|
} else if let Ok(data) = toml::from_str::<Config460>(&buf) {
|
||||||
|
info!("Loaded old v4.6.0 config file {path:?}");
|
||||||
|
return Ok(data.into());
|
||||||
} else if let Ok(data) = toml::from_str::<Config455>(&buf) {
|
} else if let Ok(data) = toml::from_str::<Config455>(&buf) {
|
||||||
info!("Loaded old v4.5.5 config file {path:?}");
|
info!("Loaded old v4.5.5 config file {path:?}");
|
||||||
return Ok(data.into());
|
return Ok(data.into());
|
||||||
@@ -122,8 +129,33 @@ impl From<Config455> for Config {
|
|||||||
startup_in_background: c.startup_in_background,
|
startup_in_background: c.startup_in_background,
|
||||||
enable_notifications: c.enable_notifications,
|
enable_notifications: c.enable_notifications,
|
||||||
enabled_notifications: c.enabled_notifications,
|
enabled_notifications: c.enabled_notifications,
|
||||||
|
dark_mode: true,
|
||||||
ac_command: String::new(),
|
ac_command: String::new(),
|
||||||
bat_command: String::new(),
|
bat_command: String::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
|
pub struct Config460 {
|
||||||
|
pub run_in_background: bool,
|
||||||
|
pub startup_in_background: bool,
|
||||||
|
pub ac_command: String,
|
||||||
|
pub bat_command: String,
|
||||||
|
pub enable_notifications: bool,
|
||||||
|
pub enabled_notifications: EnabledNotifications,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Config460> for Config {
|
||||||
|
fn from(c: Config460) -> Self {
|
||||||
|
Self {
|
||||||
|
run_in_background: c.run_in_background,
|
||||||
|
startup_in_background: c.startup_in_background,
|
||||||
|
ac_command: c.ac_command,
|
||||||
|
bat_command: c.bat_command,
|
||||||
|
dark_mode: true,
|
||||||
|
enable_notifications: c.enable_notifications,
|
||||||
|
enabled_notifications: c.enabled_notifications,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ pub enum Error {
|
|||||||
XdgVars,
|
XdgVars,
|
||||||
Zbus(zbus::Error),
|
Zbus(zbus::Error),
|
||||||
Notification(notify_rust::error::Error),
|
Notification(notify_rust::error::Error),
|
||||||
|
Eframe(eframe::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
@@ -24,6 +25,7 @@ impl fmt::Display for Error {
|
|||||||
Error::XdgVars => write!(f, "XDG environment vars appear unset"),
|
Error::XdgVars => write!(f, "XDG environment vars appear unset"),
|
||||||
Error::Zbus(err) => write!(f, "Error: {}", err),
|
Error::Zbus(err) => write!(f, "Error: {}", err),
|
||||||
Error::Notification(err) => write!(f, "Notification Error: {}", err),
|
Error::Notification(err) => write!(f, "Notification Error: {}", err),
|
||||||
|
Error::Eframe(err) => write!(f, "Eframe Error: {}", err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -53,3 +55,9 @@ impl From<notify_rust::error::Error> for Error {
|
|||||||
Error::Notification(err)
|
Error::Notification(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<eframe::Error> for Error {
|
||||||
|
fn from(err: eframe::Error) -> Self {
|
||||||
|
Error::Eframe(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ pub fn on_tmp_dir_exists() -> Result<TempDir, std::io::Error> {
|
|||||||
// First entry is the actual state
|
// First entry is the actual state
|
||||||
if buf[0] == SHOWING_GUI {
|
if buf[0] == SHOWING_GUI {
|
||||||
ipc_file.write_all(&[SHOWING_GUI])?; // Store state again as we drained the fifo
|
ipc_file.write_all(&[SHOWING_GUI])?; // Store state again as we drained the fifo
|
||||||
|
// Early exit is not an error and we don't want to pass back a dir
|
||||||
|
#[allow(clippy::exit)]
|
||||||
exit(0);
|
exit(0);
|
||||||
} else if buf[0] == SHOW_GUI {
|
} else if buf[0] == SHOW_GUI {
|
||||||
remove_dir_all(&path)?;
|
remove_dir_all(&path)?;
|
||||||
@@ -89,7 +91,7 @@ pub fn on_tmp_dir_exists() -> Result<TempDir, std::io::Error> {
|
|||||||
.rand_bytes(0)
|
.rand_bytes(0)
|
||||||
.tempdir();
|
.tempdir();
|
||||||
}
|
}
|
||||||
exit(-1);
|
panic!("Invalid exit or app state");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ipc_file() -> Result<File, crate::error::Error> {
|
pub fn get_ipc_file() -> Result<File, crate::error::Error> {
|
||||||
@@ -103,6 +105,6 @@ pub fn get_ipc_file() -> Result<File, crate::error::Error> {
|
|||||||
Ok(OpenOptions::new()
|
Ok(OpenOptions::new()
|
||||||
.read(true)
|
.read(true)
|
||||||
.write(true)
|
.write(true)
|
||||||
.truncate(true)
|
// .truncate(true)
|
||||||
.open(&fifo_path)?)
|
.open(&fifo_path)?)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
use std::env::args;
|
use std::env::args;
|
||||||
use std::fs::OpenOptions;
|
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use eframe::{IconData, NativeOptions};
|
use eframe::IconData;
|
||||||
use gumdrop::Options;
|
use gumdrop::Options;
|
||||||
use log::{error, info, warn};
|
use log::{debug, error, info, warn, LevelFilter};
|
||||||
use rog_aura::aura_detection::{LaptopLedData, LedSupportFile};
|
use rog_aura::aura_detection::{LaptopLedData, LedSupportFile};
|
||||||
use rog_aura::layouts::KeyLayout;
|
use rog_aura::layouts::KeyLayout;
|
||||||
use rog_control_center::cli_options::CliStart;
|
use rog_control_center::cli_options::CliStart;
|
||||||
@@ -46,6 +48,7 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
let mut logger = env_logger::Builder::new();
|
let mut logger = env_logger::Builder::new();
|
||||||
logger
|
logger
|
||||||
|
.filter_level(LevelFilter::Warn)
|
||||||
.parse_default_env()
|
.parse_default_env()
|
||||||
.target(env_logger::Target::Stdout)
|
.target(env_logger::Target::Stdout)
|
||||||
.format(|buf, record| writeln!(buf, "{}: {}", record.level(), record.args()))
|
.format(|buf, record| writeln!(buf, "{}: {}", record.level(), record.args()))
|
||||||
@@ -73,7 +76,9 @@ fn main() -> Result<()> {
|
|||||||
"ROG Control Center",
|
"ROG Control Center",
|
||||||
native_options.clone(),
|
native_options.clone(),
|
||||||
Box::new(move |_| Box::new(AppErrorShow::new(e.to_string()))),
|
Box::new(move |_| Box::new(AppErrorShow::new(e.to_string()))),
|
||||||
);
|
)
|
||||||
|
.map_err(|e| error!("{e}"))
|
||||||
|
.ok();
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -84,14 +89,16 @@ fn main() -> Result<()> {
|
|||||||
"ROG Control Center",
|
"ROG Control Center",
|
||||||
native_options.clone(),
|
native_options.clone(),
|
||||||
Box::new(move |_| Box::new(AppErrorShow::new(e.to_string()))),
|
Box::new(move |_| Box::new(AppErrorShow::new(e.to_string()))),
|
||||||
);
|
)
|
||||||
|
.map_err(|e| error!("{e}"))
|
||||||
|
.ok();
|
||||||
SupportedFunctions::default()
|
SupportedFunctions::default()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Startup
|
// Startup
|
||||||
let mut config = Config::load()?;
|
let mut config = Config::load()?;
|
||||||
let mut start_closed = config.startup_in_background;
|
let running_in_bg = Arc::new(AtomicBool::new(config.startup_in_background));
|
||||||
|
|
||||||
if config.startup_in_background {
|
if config.startup_in_background {
|
||||||
config.run_in_background = true;
|
config.run_in_background = true;
|
||||||
@@ -101,15 +108,10 @@ fn main() -> Result<()> {
|
|||||||
let enabled_notifications = EnabledNotifications::tokio_mutex(&config);
|
let enabled_notifications = EnabledNotifications::tokio_mutex(&config);
|
||||||
|
|
||||||
// Find and load a matching layout for laptop
|
// Find and load a matching layout for laptop
|
||||||
let mut file = OpenOptions::new()
|
let mut board_name = std::fs::read_to_string(BOARD_NAME).map_err(|e| {
|
||||||
.read(true)
|
println!("DOH! {BOARD_NAME}, {e}");
|
||||||
.open(PathBuf::from(BOARD_NAME))
|
e
|
||||||
.map_err(|e| {
|
})?;
|
||||||
println!("DOH! {BOARD_NAME}, {e}");
|
|
||||||
e
|
|
||||||
})?;
|
|
||||||
let mut board_name = String::new();
|
|
||||||
file.read_to_string(&mut board_name)?;
|
|
||||||
|
|
||||||
let mut led_support = LaptopLedData::get_data();
|
let mut led_support = LaptopLedData::get_data();
|
||||||
|
|
||||||
@@ -122,7 +124,7 @@ fn main() -> Result<()> {
|
|||||||
path.push("rog-aura");
|
path.push("rog-aura");
|
||||||
path.push("data");
|
path.push("data");
|
||||||
}
|
}
|
||||||
layouts = KeyLayout::layout_files(path.to_owned()).unwrap();
|
layouts = KeyLayout::layout_files(path.clone()).unwrap();
|
||||||
|
|
||||||
if let Some(name) = &cli_parsed.board_name {
|
if let Some(name) = &cli_parsed.board_name {
|
||||||
if let Some(modes) = LedSupportFile::load_from_config() {
|
if let Some(modes) = LedSupportFile::load_from_config() {
|
||||||
@@ -130,7 +132,7 @@ fn main() -> Result<()> {
|
|||||||
led_support = data;
|
led_support = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
board_name = name.to_owned();
|
board_name = name.clone();
|
||||||
for layout in &layouts {
|
for layout in &layouts {
|
||||||
if layout
|
if layout
|
||||||
.file_name()
|
.file_name()
|
||||||
@@ -138,11 +140,11 @@ fn main() -> Result<()> {
|
|||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.contains(&led_support.layout_name.to_lowercase())
|
.contains(&led_support.layout_name.to_lowercase())
|
||||||
{
|
{
|
||||||
layout_name = Some(layout.to_owned());
|
layout_name = Some(layout.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
board_name = "GQ401QM".to_string()
|
board_name = "GQ401QM".to_owned();
|
||||||
};
|
};
|
||||||
|
|
||||||
if cli_parsed.layout_viewing {
|
if cli_parsed.layout_viewing {
|
||||||
@@ -182,33 +184,55 @@ fn main() -> Result<()> {
|
|||||||
layout_name,
|
layout_name,
|
||||||
layout,
|
layout,
|
||||||
layouts,
|
layouts,
|
||||||
enabled_notifications,
|
&enabled_notifications,
|
||||||
&config,
|
&config,
|
||||||
&supported,
|
&supported,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
init_tray(supported, states.clone());
|
init_tray(supported, states.clone());
|
||||||
|
|
||||||
|
let mut bg_check_spawned = false;
|
||||||
loop {
|
loop {
|
||||||
if !start_closed {
|
if !running_in_bg.load(Ordering::Relaxed) {
|
||||||
start_app(states.clone(), native_options.clone())?;
|
// blocks until window is closed
|
||||||
|
let states = states.clone();
|
||||||
|
let mut ipc_file = get_ipc_file()?;
|
||||||
|
ipc_file.write_all(&[SHOWING_GUI])?;
|
||||||
|
eframe::run_native(
|
||||||
|
"ROG Control Center",
|
||||||
|
native_options.clone(),
|
||||||
|
Box::new(move |cc| {
|
||||||
|
Box::new(RogApp::new(Config::load().unwrap(), states, cc).unwrap())
|
||||||
|
}),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
running_in_bg.store(true, Ordering::SeqCst);
|
||||||
|
bg_check_spawned = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = Config::load()?;
|
|
||||||
if !config.run_in_background || cli_parsed.board_name.is_some() || cli_parsed.layout_viewing
|
if !config.run_in_background || cli_parsed.board_name.is_some() || cli_parsed.layout_viewing
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.run_in_background {
|
if config.run_in_background && running_in_bg.load(Ordering::Acquire) && !bg_check_spawned {
|
||||||
let mut buf = [0u8; 4];
|
let running_in_bg = running_in_bg.clone();
|
||||||
// blocks until it is read, typically the read will happen after a second
|
thread::spawn(move || {
|
||||||
// process writes to the IPC (so there is data to actually read)
|
let mut buf = [0u8; 4];
|
||||||
if get_ipc_file()?.read(&mut buf).is_ok() && buf[0] == SHOW_GUI {
|
// blocks until it is read, typically the read will happen after a second
|
||||||
start_closed = false;
|
// process writes to the IPC (so there is data to actually read)
|
||||||
continue;
|
loop {
|
||||||
}
|
if get_ipc_file().unwrap().read(&mut buf).is_ok() && buf[0] == SHOW_GUI {
|
||||||
|
running_in_bg.store(false, Ordering::Release);
|
||||||
|
debug!("Wait thread got from tray {buf:#?}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
bg_check_spawned = true;
|
||||||
}
|
}
|
||||||
|
// Prevent hogging CPU
|
||||||
|
thread::sleep(Duration::from_millis(500));
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop {
|
// loop {
|
||||||
@@ -222,7 +246,7 @@ fn setup_page_state_and_notifs(
|
|||||||
layout_testing: Option<PathBuf>,
|
layout_testing: Option<PathBuf>,
|
||||||
keyboard_layout: KeyLayout,
|
keyboard_layout: KeyLayout,
|
||||||
keyboard_layouts: Vec<PathBuf>,
|
keyboard_layouts: Vec<PathBuf>,
|
||||||
enabled_notifications: Arc<Mutex<EnabledNotifications>>,
|
enabled_notifications: &Arc<Mutex<EnabledNotifications>>,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
supported: &SupportedFunctions,
|
supported: &SupportedFunctions,
|
||||||
) -> Result<Arc<Mutex<SystemState>>> {
|
) -> Result<Arc<Mutex<SystemState>>> {
|
||||||
@@ -234,40 +258,23 @@ fn setup_page_state_and_notifs(
|
|||||||
supported,
|
supported,
|
||||||
)?));
|
)?));
|
||||||
|
|
||||||
start_notifications(config, page_states.clone(), enabled_notifications)?;
|
start_notifications(config, &page_states, enabled_notifications)?;
|
||||||
|
|
||||||
Ok(page_states)
|
Ok(page_states)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_app(states: Arc<Mutex<SystemState>>, native_options: NativeOptions) -> Result<()> {
|
|
||||||
let mut ipc_file = get_ipc_file()?;
|
|
||||||
ipc_file.write_all(&[SHOWING_GUI])?;
|
|
||||||
eframe::run_native(
|
|
||||||
"ROG Control Center",
|
|
||||||
native_options,
|
|
||||||
Box::new(move |cc| Box::new(RogApp::new(Config::load().unwrap(), states, cc).unwrap())),
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Bah.. the icon dosn't work on wayland anyway, but we'll leave it in for now.
|
/// Bah.. the icon dosn't work on wayland anyway, but we'll leave it in for now.
|
||||||
fn load_icon() -> IconData {
|
fn load_icon() -> IconData {
|
||||||
let path = PathBuf::from(APP_ICON_PATH);
|
let path = PathBuf::from(APP_ICON_PATH);
|
||||||
let mut buf = Vec::new();
|
|
||||||
let mut rgba = Vec::new();
|
let mut rgba = Vec::new();
|
||||||
let mut height = 512;
|
let mut height = 512;
|
||||||
let mut width = 512;
|
let mut width = 512;
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
if let Ok(mut file) = OpenOptions::new()
|
if let Ok(data) = std::fs::read(path)
|
||||||
.read(true)
|
.map_err(|e| error!("Error reading app icon: {e:?}"))
|
||||||
.open(path)
|
|
||||||
.map_err(|e| error!("Error opening app icon: {e:?}"))
|
.map_err(|e| error!("Error opening app icon: {e:?}"))
|
||||||
{
|
{
|
||||||
file.read_to_end(&mut buf)
|
let data = std::io::Cursor::new(data);
|
||||||
.map_err(|e| error!("Error reading app icon: {e:?}"))
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
let data = std::io::Cursor::new(buf);
|
|
||||||
let decoder = png_pong::Decoder::new(data).unwrap().into_steps();
|
let decoder = png_pong::Decoder::new(data).unwrap().into_steps();
|
||||||
let png_pong::Step { raster, delay: _ } = decoder.last().unwrap().unwrap();
|
let png_pong::Step { raster, delay: _ } = decoder.last().unwrap().unwrap();
|
||||||
|
|
||||||
@@ -295,7 +302,7 @@ fn do_cli_help(parsed: &CliStart) -> bool {
|
|||||||
println!();
|
println!();
|
||||||
if let Some(cmdlist) = CliStart::command_list() {
|
if let Some(cmdlist) = CliStart::command_list() {
|
||||||
let commands: Vec<String> = cmdlist.lines().map(|s| s.to_owned()).collect();
|
let commands: Vec<String> = cmdlist.lines().map(|s| s.to_owned()).collect();
|
||||||
for command in commands.iter() {
|
for command in &commands {
|
||||||
println!("{}", command);
|
println!("{}", command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+99
-137
@@ -2,7 +2,6 @@
|
|||||||
//! commands over an MPSC channel.
|
//! commands over an MPSC channel.
|
||||||
|
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
|
||||||
use std::sync::mpsc::{channel, Receiver};
|
use std::sync::mpsc::{channel, Receiver};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@@ -14,8 +13,10 @@ use log::{debug, error, info, trace, warn};
|
|||||||
use rog_dbus::zbus_platform::RogBiosProxyBlocking;
|
use rog_dbus::zbus_platform::RogBiosProxyBlocking;
|
||||||
use rog_platform::platform::GpuMode;
|
use rog_platform::platform::GpuMode;
|
||||||
use rog_platform::supported::SupportedFunctions;
|
use rog_platform::supported::SupportedFunctions;
|
||||||
|
use supergfxctl::actions::UserActionRequired as GfxUserActionRequired;
|
||||||
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
||||||
use supergfxctl::zbus_proxy::DaemonProxyBlocking as GfxProxyBlocking;
|
use supergfxctl::zbus_proxy::DaemonProxyBlocking as GfxProxyBlocking;
|
||||||
|
use versions::Versioning;
|
||||||
|
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use crate::system_state::SystemState;
|
use crate::system_state::SystemState;
|
||||||
@@ -79,6 +80,8 @@ pub struct ROGTray {
|
|||||||
menu: gtk::Menu,
|
menu: gtk::Menu,
|
||||||
icon: &'static str,
|
icon: &'static str,
|
||||||
bios_proxy: RogBiosProxyBlocking<'static>,
|
bios_proxy: RogBiosProxyBlocking<'static>,
|
||||||
|
gfx_proxy_is_active: bool,
|
||||||
|
gfx_action: Arc<Mutex<GfxUserActionRequired>>,
|
||||||
gfx_proxy: GfxProxyBlocking<'static>,
|
gfx_proxy: GfxProxyBlocking<'static>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,6 +91,12 @@ impl ROGTray {
|
|||||||
error!("ROGTray: {e}");
|
error!("ROGTray: {e}");
|
||||||
e
|
e
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let gfx_proxy = GfxProxyBlocking::new(&conn).map_err(|e| {
|
||||||
|
error!("ROGTray: {e}");
|
||||||
|
e
|
||||||
|
})?;
|
||||||
|
|
||||||
let rog_tray = Self {
|
let rog_tray = Self {
|
||||||
tray: AppIndicator::new(TRAY_LABEL, TRAY_APP_ICON),
|
tray: AppIndicator::new(TRAY_LABEL, TRAY_APP_ICON),
|
||||||
menu: gtk::Menu::new(),
|
menu: gtk::Menu::new(),
|
||||||
@@ -96,10 +105,9 @@ impl ROGTray {
|
|||||||
error!("ROGTray: {e}");
|
error!("ROGTray: {e}");
|
||||||
e
|
e
|
||||||
})?,
|
})?,
|
||||||
gfx_proxy: GfxProxyBlocking::new(&conn).map_err(|e| {
|
gfx_proxy_is_active: gfx_proxy.mode().is_ok(),
|
||||||
error!("ROGTray: {e}");
|
gfx_action: Arc::new(Mutex::new(GfxUserActionRequired::Nothing)),
|
||||||
e
|
gfx_proxy,
|
||||||
})?,
|
|
||||||
};
|
};
|
||||||
Ok(rog_tray)
|
Ok(rog_tray)
|
||||||
}
|
}
|
||||||
@@ -208,6 +216,7 @@ impl ROGTray {
|
|||||||
if let Ok(mut ipc) = get_ipc_file().map_err(|e| {
|
if let Ok(mut ipc) = get_ipc_file().map_err(|e| {
|
||||||
error!("ROGTray: get_ipc_file: {}", e);
|
error!("ROGTray: get_ipc_file: {}", e);
|
||||||
}) {
|
}) {
|
||||||
|
debug!("Tray told app to show self");
|
||||||
ipc.write_all(&[SHOW_GUI]).ok();
|
ipc.write_all(&[SHOW_GUI]).ok();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -238,132 +247,64 @@ impl ROGTray {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn menu_add_gpu(&mut self, supported: &SupportedFunctions, current_mode: GfxMode) {
|
fn menu_add_supergfx(&mut self, supported_gfx: &[GfxMode], current_mode: GfxMode) {
|
||||||
let set_mux_off = Arc::new(AtomicBool::new(false));
|
if !self.gfx_proxy_is_active {
|
||||||
|
trace!("menu_add_supergfx: gfx_proxy_is_active is false");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let gfx_dbus = self.gfx_proxy.clone();
|
let gfx_dbus = self.gfx_proxy.clone();
|
||||||
let set_mux_off1 = set_mux_off.clone();
|
let gfx_action = self.gfx_action.clone();
|
||||||
let mut gpu_menu = RadioGroup::new("Integrated", move |_| {
|
let mut gpu_menu = RadioGroup::new("Integrated", move |_| {
|
||||||
let mode = gfx_dbus
|
if current_mode != GfxMode::Integrated {
|
||||||
.mode()
|
if let Ok(res) = gfx_dbus.set_mode(&GfxMode::Integrated).map_err(|e| {
|
||||||
.map_err(|e| {
|
error!("ROGTray: srt_mode: {e}");
|
||||||
error!("ROGTray: mode: {e}");
|
|
||||||
e
|
e
|
||||||
})
|
}) {
|
||||||
.unwrap_or(GfxMode::None);
|
if let Ok(mut lock) = gfx_action.lock() {
|
||||||
if mode != GfxMode::Integrated {
|
*lock = res;
|
||||||
gfx_dbus
|
}
|
||||||
.set_mode(&GfxMode::Integrated)
|
}
|
||||||
.map_err(|e| {
|
|
||||||
error!("ROGTray: srt_mode: {e}");
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
set_mux_off1.store(true, Ordering::Relaxed);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let gfx_dbus = self.gfx_proxy.clone();
|
let mut func = |menu_mode: GfxMode| {
|
||||||
let set_mux_off1 = set_mux_off.clone();
|
|
||||||
gpu_menu.add("Hybrid", move |_| {
|
|
||||||
let mode = gfx_dbus
|
|
||||||
.mode()
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("ROGTray: mode: {e}");
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.unwrap_or(GfxMode::None);
|
|
||||||
if mode != GfxMode::Hybrid {
|
|
||||||
gfx_dbus
|
|
||||||
.set_mode(&GfxMode::Hybrid)
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("ROGTray: set_mode: {e}");
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
set_mux_off1.store(true, Ordering::Relaxed);
|
|
||||||
});
|
|
||||||
if supported.rog_bios_ctrl.egpu_enable {
|
|
||||||
let set_mux_off1 = set_mux_off.clone();
|
|
||||||
let gfx_dbus = self.gfx_proxy.clone();
|
let gfx_dbus = self.gfx_proxy.clone();
|
||||||
gpu_menu.add("eGPU", move |_| {
|
let gfx_action = self.gfx_action.clone();
|
||||||
let mode = gfx_dbus
|
gpu_menu.add(&format!("{menu_mode}"), move |_| {
|
||||||
.mode()
|
if current_mode != menu_mode {
|
||||||
.map_err(|e| {
|
if let Ok(res) = gfx_dbus.set_mode(&menu_mode).map_err(|e| {
|
||||||
error!("ROGTray: mode: {e}");
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.unwrap_or(GfxMode::None);
|
|
||||||
if mode != GfxMode::Egpu {
|
|
||||||
gfx_dbus
|
|
||||||
.set_mode(&GfxMode::Egpu)
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("ROGTray: set_mode: {e}");
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
set_mux_off1.store(true, Ordering::Relaxed);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut reboot_required = false;
|
|
||||||
if supported.rog_bios_ctrl.gpu_mux {
|
|
||||||
let gfx_dbus = self.bios_proxy.clone();
|
|
||||||
gpu_menu.add("Ultimate (Reboot required)", move |_| {
|
|
||||||
let mode = gfx_dbus
|
|
||||||
.gpu_mux_mode()
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("ROGTray: mode: {e}");
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.unwrap_or(GpuMode::Error);
|
|
||||||
if mode != GpuMode::Discrete {
|
|
||||||
gfx_dbus
|
|
||||||
.set_gpu_mux_mode(GpuMode::Discrete)
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("ROGTray: set_mode: {e}");
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if set_mux_off.load(Ordering::Relaxed) {
|
|
||||||
warn!("Selected non-dgpu mode, must set MUX to optimus");
|
|
||||||
self.bios_proxy
|
|
||||||
.set_gpu_mux_mode(GpuMode::Optimus)
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("ROGTray: set_mode: {e}");
|
error!("ROGTray: set_mode: {e}");
|
||||||
e
|
e
|
||||||
})
|
}) {
|
||||||
.ok();
|
if let Ok(mut lock) = gfx_action.lock() {
|
||||||
}
|
*lock = res;
|
||||||
|
}
|
||||||
if let Ok(mode) = self.bios_proxy.gpu_mux_mode() {
|
}
|
||||||
let mode = match mode {
|
}
|
||||||
GpuMode::Discrete => GfxMode::AsusMuxDiscreet,
|
});
|
||||||
_ => GfxMode::Hybrid,
|
|
||||||
};
|
|
||||||
reboot_required = mode != current_mode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let active = match current_mode {
|
|
||||||
GfxMode::AsusMuxDiscreet => "Discreet".to_owned(),
|
|
||||||
_ => current_mode.to_string(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let reboot_required = if reboot_required {
|
for item in supported_gfx {
|
||||||
"(Reboot required)"
|
if *item == GfxMode::Integrated {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
func(*item);
|
||||||
|
}
|
||||||
|
|
||||||
|
let action_required = if let Ok(lock) = self.gfx_action.lock() {
|
||||||
|
if matches!(*lock, GfxUserActionRequired::Nothing) {
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
<&str>::from(*lock)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
};
|
};
|
||||||
|
|
||||||
self.add_radio_sub_menu(
|
self.add_radio_sub_menu(
|
||||||
&format!("GPU Mode: {active} {reboot_required}"),
|
&format!("GPU Mode: {current_mode} {action_required}"),
|
||||||
active.as_str(),
|
¤t_mode.to_string(),
|
||||||
&gpu_menu,
|
&gpu_menu,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -376,7 +317,7 @@ impl ROGTray {
|
|||||||
let mut reboot_required = false;
|
let mut reboot_required = false;
|
||||||
if let Ok(mode) = gfx_dbus.gpu_mux_mode() {
|
if let Ok(mode) = gfx_dbus.gpu_mux_mode() {
|
||||||
let mode = match mode {
|
let mode = match mode {
|
||||||
GpuMode::Discrete => GfxMode::AsusMuxDiscreet,
|
GpuMode::Discrete => GfxMode::AsusMuxDgpu,
|
||||||
_ => GfxMode::Hybrid,
|
_ => GfxMode::Hybrid,
|
||||||
};
|
};
|
||||||
reboot_required = mode != current_mode;
|
reboot_required = mode != current_mode;
|
||||||
@@ -406,7 +347,7 @@ impl ROGTray {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let active = match current_mode {
|
let active = match current_mode {
|
||||||
GfxMode::AsusMuxDiscreet => "Ultimate".to_owned(),
|
GfxMode::AsusMuxDgpu => "Ultimate".to_owned(),
|
||||||
GfxMode::Hybrid => "Optimus".to_owned(),
|
GfxMode::Hybrid => "Optimus".to_owned(),
|
||||||
_ => current_mode.to_string(),
|
_ => current_mode.to_string(),
|
||||||
};
|
};
|
||||||
@@ -441,7 +382,7 @@ impl ROGTray {
|
|||||||
fn rebuild_and_update(
|
fn rebuild_and_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
supported: &SupportedFunctions,
|
supported: &SupportedFunctions,
|
||||||
has_supergfx: bool,
|
supported_gfx: &[GfxMode],
|
||||||
current_gfx_mode: GfxMode,
|
current_gfx_mode: GfxMode,
|
||||||
charge_limit: u8,
|
charge_limit: u8,
|
||||||
panel_od: bool,
|
panel_od: bool,
|
||||||
@@ -450,8 +391,9 @@ impl ROGTray {
|
|||||||
self.menu_add_base();
|
self.menu_add_base();
|
||||||
self.menu_add_charge_limit(supported, charge_limit);
|
self.menu_add_charge_limit(supported, charge_limit);
|
||||||
self.menu_add_panel_od(supported, panel_od);
|
self.menu_add_panel_od(supported, panel_od);
|
||||||
if has_supergfx {
|
if self.gfx_proxy_is_active {
|
||||||
self.menu_add_gpu(supported, current_gfx_mode);
|
// Add a supergfxctl specific menu
|
||||||
|
self.menu_add_supergfx(supported_gfx, current_gfx_mode);
|
||||||
} else if supported.rog_bios_ctrl.gpu_mux {
|
} else if supported.rog_bios_ctrl.gpu_mux {
|
||||||
self.menu_add_mux(current_gfx_mode);
|
self.menu_add_mux(current_gfx_mode);
|
||||||
}
|
}
|
||||||
@@ -466,20 +408,12 @@ pub fn init_tray(
|
|||||||
let (send, recv) = channel();
|
let (send, recv) = channel();
|
||||||
let _send = Arc::new(Mutex::new(send));
|
let _send = Arc::new(Mutex::new(send));
|
||||||
|
|
||||||
let has_supergfx = if let Ok(lock) = states.try_lock() {
|
|
||||||
lock.gfx_state.has_supergfx
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
|
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
if gtk::init()
|
let gtk_init = gtk::init().map_err(|e| {
|
||||||
.map_err(|e| {
|
error!("ROGTray: gtk init {e}");
|
||||||
error!("ROGTray: gtk init {e}");
|
e
|
||||||
e
|
});
|
||||||
})
|
if gtk_init.is_err() {
|
||||||
.is_err()
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
} // Make this the main thread for gtk
|
} // Make this the main thread for gtk
|
||||||
debug!("init_tray gtk");
|
debug!("init_tray gtk");
|
||||||
@@ -497,7 +431,29 @@ pub fn init_tray(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
tray.rebuild_and_update(&supported, has_supergfx, GfxMode::Hybrid, 100, false);
|
|
||||||
|
let supported_gfx = if tray.gfx_proxy_is_active {
|
||||||
|
if let Ok(version) = tray.gfx_proxy.version() {
|
||||||
|
if let Some(version) = Versioning::new(&version) {
|
||||||
|
let curr_gfx = Versioning::new("5.0.3-RC4").unwrap();
|
||||||
|
warn!("supergfxd version = {version}");
|
||||||
|
if version < curr_gfx {
|
||||||
|
// Don't allow mode changing if too old a version
|
||||||
|
warn!("supergfxd found but is too old to use");
|
||||||
|
tray.gfx_proxy_is_active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if tray.gfx_proxy_is_active {
|
||||||
|
tray.gfx_proxy.supported().unwrap()
|
||||||
|
} else {
|
||||||
|
Default::default()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
tray.rebuild_and_update(&supported, &supported_gfx, GfxMode::Hybrid, 100, false);
|
||||||
tray.set_icon(TRAY_APP_ICON);
|
tray.set_icon(TRAY_APP_ICON);
|
||||||
info!("Started ROGTray");
|
info!("Started ROGTray");
|
||||||
|
|
||||||
@@ -509,13 +465,13 @@ pub fn init_tray(
|
|||||||
lock.gfx_state.mode
|
lock.gfx_state.mode
|
||||||
} else {
|
} else {
|
||||||
match lock.bios.dedicated_gfx {
|
match lock.bios.dedicated_gfx {
|
||||||
GpuMode::Discrete => GfxMode::AsusMuxDiscreet,
|
GpuMode::Discrete => GfxMode::AsusMuxDgpu,
|
||||||
_ => GfxMode::Hybrid,
|
_ => GfxMode::Hybrid,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
tray.rebuild_and_update(
|
tray.rebuild_and_update(
|
||||||
&supported,
|
&supported,
|
||||||
has_supergfx,
|
&supported_gfx,
|
||||||
current_gpu_mode,
|
current_gpu_mode,
|
||||||
lock.power_state.charge_limit,
|
lock.power_state.charge_limit,
|
||||||
lock.bios.panel_overdrive,
|
lock.bios.panel_overdrive,
|
||||||
@@ -525,13 +481,19 @@ pub fn init_tray(
|
|||||||
|
|
||||||
match lock.gfx_state.power_status {
|
match lock.gfx_state.power_status {
|
||||||
GfxPower::Suspended => tray.set_icon("asus_notif_blue"),
|
GfxPower::Suspended => tray.set_icon("asus_notif_blue"),
|
||||||
GfxPower::Off => tray.set_icon("asus_notif_green"),
|
GfxPower::Off => {
|
||||||
|
if lock.gfx_state.mode == GfxMode::Vfio {
|
||||||
|
tray.set_icon("asus_notif_red")
|
||||||
|
} else {
|
||||||
|
tray.set_icon("asus_notif_green")
|
||||||
|
}
|
||||||
|
}
|
||||||
GfxPower::AsusDisabled => tray.set_icon("asus_notif_white"),
|
GfxPower::AsusDisabled => tray.set_icon("asus_notif_white"),
|
||||||
GfxPower::AsusMuxDiscreet | GfxPower::Active => {
|
GfxPower::AsusMuxDiscreet | GfxPower::Active => {
|
||||||
tray.set_icon("asus_notif_red");
|
tray.set_icon("asus_notif_red");
|
||||||
}
|
}
|
||||||
GfxPower::Unknown => {
|
GfxPower::Unknown => {
|
||||||
if has_supergfx {
|
if tray.gfx_proxy_is_active {
|
||||||
tray.set_icon("gpu-integrated");
|
tray.set_icon("gpu-integrated");
|
||||||
} else {
|
} else {
|
||||||
tray.set_icon("asus_notif_red");
|
tray.set_icon("asus_notif_red");
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ use rog_dbus::zbus_profile::ProfileProxy;
|
|||||||
use rog_platform::platform::GpuMode;
|
use rog_platform::platform::GpuMode;
|
||||||
use rog_profiles::Profile;
|
use rog_profiles::Profile;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use supergfxctl::pci_device::GfxPower;
|
use supergfxctl::actions::UserActionRequired as GfxUserAction;
|
||||||
|
use supergfxctl::pci_device::{GfxMode, GfxPower};
|
||||||
use supergfxctl::zbus_proxy::DaemonProxy as SuperProxy;
|
use supergfxctl::zbus_proxy::DaemonProxy as SuperProxy;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use zbus::export::futures_util::{future, StreamExt};
|
use zbus::export::futures_util::{future, StreamExt};
|
||||||
@@ -139,8 +140,8 @@ type SharedHandle = Arc<Mutex<Option<NotificationHandle>>>;
|
|||||||
|
|
||||||
pub fn start_notifications(
|
pub fn start_notifications(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
page_states: Arc<Mutex<SystemState>>,
|
page_states: &Arc<Mutex<SystemState>>,
|
||||||
enabled_notifications: Arc<Mutex<EnabledNotifications>>,
|
enabled_notifications: &Arc<Mutex<EnabledNotifications>>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let last_notification: SharedHandle = Arc::new(Mutex::new(None));
|
let last_notification: SharedHandle = Arc::new(Mutex::new(None));
|
||||||
|
|
||||||
@@ -406,6 +407,7 @@ pub fn start_notifications(
|
|||||||
do_notification
|
do_notification
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let page_states1 = page_states.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let conn = zbus::Connection::system()
|
let conn = zbus::Connection::system()
|
||||||
.await
|
.await
|
||||||
@@ -426,15 +428,25 @@ pub fn start_notifications(
|
|||||||
while let Some(e) = p.next().await {
|
while let Some(e) = p.next().await {
|
||||||
if let Ok(out) = e.args() {
|
if let Ok(out) = e.args() {
|
||||||
let action = out.action();
|
let action = out.action();
|
||||||
do_gfx_action_notif(
|
let mode = if let Ok(lock) = page_states1.lock() {
|
||||||
"Gfx mode change requires",
|
convert_gfx_mode(lock.gfx_state.mode)
|
||||||
&format!("{action:?}",),
|
} else {
|
||||||
)
|
GpuMode::Error
|
||||||
|
};
|
||||||
|
match action {
|
||||||
|
supergfxctl::actions::UserActionRequired::Reboot => {
|
||||||
|
do_mux_notification(
|
||||||
|
"Graphics mode change requires reboot",
|
||||||
|
&mode,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
_ => do_gfx_action_notif(<&str>::from(action), *action, mode),
|
||||||
|
}
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
error!("zbus signal: do_gfx_action_notif: {e}");
|
error!("zbus signal: do_gfx_action_notif: {e}");
|
||||||
e
|
e
|
||||||
})
|
})
|
||||||
.unwrap();
|
.ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -445,6 +457,18 @@ pub fn start_notifications(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn convert_gfx_mode(gfx: GfxMode) -> GpuMode {
|
||||||
|
match gfx {
|
||||||
|
GfxMode::Hybrid => GpuMode::Optimus,
|
||||||
|
GfxMode::Integrated => GpuMode::Integrated,
|
||||||
|
GfxMode::NvidiaNoModeset => GpuMode::Discrete,
|
||||||
|
GfxMode::Vfio => GpuMode::Vfio,
|
||||||
|
GfxMode::AsusEgpu => GpuMode::Egpu,
|
||||||
|
GfxMode::AsusMuxDgpu => GpuMode::Ultimate,
|
||||||
|
GfxMode::None => GpuMode::Error,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn base_notification<T>(message: &str, data: &T) -> Notification
|
fn base_notification<T>(message: &str, data: &T) -> Notification
|
||||||
where
|
where
|
||||||
T: Display,
|
T: Display,
|
||||||
@@ -516,47 +540,91 @@ fn do_gpu_status_notif(message: &str, data: &GfxPower) -> Result<NotificationHan
|
|||||||
Ok(Notification::show(¬if)?)
|
Ok(Notification::show(¬if)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_gfx_action_notif<T>(message: &str, data: &T) -> Result<()>
|
fn do_gfx_action_notif(message: &str, action: GfxUserAction, mode: GpuMode) -> Result<()> {
|
||||||
where
|
if matches!(action, GfxUserAction::Reboot) {
|
||||||
T: Display,
|
do_mux_notification("Graphics mode change requires reboot", &mode).ok();
|
||||||
{
|
return Ok(());
|
||||||
let mut notif = base_notification(message, data);
|
}
|
||||||
notif.action("gnome-session-quit", "Logout");
|
|
||||||
notif.urgency(Urgency::Critical);
|
let mut notif = Notification::new();
|
||||||
notif.timeout(3000);
|
notif
|
||||||
notif.icon("dialog-warning");
|
.summary(NOTIF_HEADER)
|
||||||
notif.hint(Hint::Transient(true));
|
.body(&format!("Changing to {mode}. {message}"))
|
||||||
let handle = notif.show()?;
|
.timeout(2000)
|
||||||
handle.wait_for_action(|id| {
|
//.hint(Hint::Resident(true))
|
||||||
if id == "gnome-session-quit" {
|
.hint(Hint::Category("device".into()))
|
||||||
let mut cmd = Command::new("gnome-session-quit");
|
.urgency(Urgency::Critical)
|
||||||
cmd.spawn().ok();
|
.timeout(3000)
|
||||||
} else if id == "__closed" {
|
.icon("dialog-warning")
|
||||||
// TODO: cancel the switching
|
.hint(Hint::Transient(true));
|
||||||
|
|
||||||
|
if matches!(action, GfxUserAction::Logout) {
|
||||||
|
notif.action("gfx-mode-session-action", "Logout");
|
||||||
|
let handle = notif.show()?;
|
||||||
|
if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") {
|
||||||
|
if desktop.to_lowercase() == "gnome" {
|
||||||
|
handle.wait_for_action(|id| {
|
||||||
|
if id == "gfx-mode-session-action" {
|
||||||
|
let mut cmd = Command::new("gnome-session-quit");
|
||||||
|
cmd.spawn().ok();
|
||||||
|
} else if id == "__closed" {
|
||||||
|
// TODO: cancel the switching
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if desktop.to_lowercase() == "kde" {
|
||||||
|
handle.wait_for_action(|id| {
|
||||||
|
if id == "gfx-mode-session-action" {
|
||||||
|
let mut cmd = Command::new("qdbus");
|
||||||
|
cmd.args(["org.kde.ksmserver", "/KSMServer", "logout", "1", "0", "0"]);
|
||||||
|
cmd.spawn().ok();
|
||||||
|
} else if id == "__closed" {
|
||||||
|
// TODO: cancel the switching
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// todo: handle alternatives
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
} else {
|
||||||
|
notif.show()?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Actual `GpuMode` unused as data is never correct until switched by reboot
|
/// Actual `GpuMode` unused as data is never correct until switched by reboot
|
||||||
fn do_mux_notification(message: &str, m: &GpuMode) -> Result<()> {
|
fn do_mux_notification(message: &str, m: &GpuMode) -> Result<()> {
|
||||||
let mut notif = base_notification(message, &m.to_string());
|
let mut notif = base_notification(message, &m.to_string());
|
||||||
notif.action("gnome-session-quit", "Reboot");
|
notif
|
||||||
notif.urgency(Urgency::Critical);
|
.action("gfx-mode-session-action", "Reboot")
|
||||||
notif.icon("system-reboot-symbolic");
|
.urgency(Urgency::Critical)
|
||||||
notif.hint(Hint::Transient(true));
|
.icon("system-reboot-symbolic")
|
||||||
|
.hint(Hint::Transient(true));
|
||||||
let handle = notif.show()?;
|
let handle = notif.show()?;
|
||||||
|
|
||||||
std::thread::spawn(|| {
|
std::thread::spawn(|| {
|
||||||
handle.wait_for_action(|id| {
|
if let Ok(desktop) = std::env::var("XDG_CURRENT_DESKTOP") {
|
||||||
if id == "gnome-session-quit" {
|
if desktop.to_lowercase() == "gnome" {
|
||||||
let mut cmd = Command::new("gnome-session-quit");
|
handle.wait_for_action(|id| {
|
||||||
cmd.arg("--reboot");
|
if id == "gfx-mode-session-action" {
|
||||||
cmd.spawn().ok();
|
let mut cmd = Command::new("gnome-session-quit");
|
||||||
} else if id == "__closed" {
|
cmd.arg("--reboot");
|
||||||
// TODO: cancel the switching
|
cmd.spawn().ok();
|
||||||
|
} else if id == "__closed" {
|
||||||
|
// TODO: cancel the switching
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if desktop.to_lowercase() == "kde" {
|
||||||
|
handle.wait_for_action(|id| {
|
||||||
|
if id == "gfx-mode-session-action" {
|
||||||
|
let mut cmd = Command::new("qdbus");
|
||||||
|
cmd.args(["org.kde.ksmserver", "/KSMServer", "logout", "1", "1", "0"]);
|
||||||
|
cmd.spawn().ok();
|
||||||
|
} else if id == "__closed" {
|
||||||
|
// TODO: cancel the switching
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use egui::{RichText, Ui};
|
use egui::{RichText, Ui};
|
||||||
use rog_aura::usb::{AuraDev1866, AuraDev19b6, AuraDevTuf, AuraDevice, AuraPowerDev};
|
use rog_aura::usb::{AuraDevRog1, AuraDevRog2, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||||
use rog_aura::AuraZone;
|
use rog_aura::AuraZone;
|
||||||
use rog_platform::supported::SupportedFunctions;
|
use rog_platform::supported::SupportedFunctions;
|
||||||
|
|
||||||
@@ -12,7 +12,9 @@ pub fn aura_power_group(supported: &SupportedFunctions, states: &mut SystemState
|
|||||||
AuraDevice::X1854 | AuraDevice::X1869 | AuraDevice::X1866 => {
|
AuraDevice::X1854 | AuraDevice::X1869 | AuraDevice::X1866 => {
|
||||||
aura_power1(supported, states, ui);
|
aura_power1(supported, states, ui);
|
||||||
}
|
}
|
||||||
AuraDevice::X19B6 => aura_power2(supported, states, ui),
|
AuraDevice::X19b6 | AuraDevice::X18c6 | AuraDevice::X1a30 => {
|
||||||
|
aura_power2(supported, states, ui)
|
||||||
|
}
|
||||||
AuraDevice::Tuf => aura_power1(supported, states, ui),
|
AuraDevice::Tuf => aura_power1(supported, states, ui),
|
||||||
AuraDevice::Unknown => {}
|
AuraDevice::Unknown => {}
|
||||||
}
|
}
|
||||||
@@ -20,10 +22,10 @@ pub fn aura_power_group(supported: &SupportedFunctions, states: &mut SystemState
|
|||||||
|
|
||||||
fn aura_power1(supported: &SupportedFunctions, states: &mut SystemState, ui: &mut Ui) {
|
fn aura_power1(supported: &SupportedFunctions, states: &mut SystemState, ui: &mut Ui) {
|
||||||
let enabled_states = &mut states.aura.enabled;
|
let enabled_states = &mut states.aura.enabled;
|
||||||
let mut boot = enabled_states.x1866.contains(&AuraDev1866::Boot);
|
let mut boot = enabled_states.x1866.contains(&AuraDevRog1::Boot);
|
||||||
let mut sleep = enabled_states.x1866.contains(&AuraDev1866::Sleep);
|
let mut sleep = enabled_states.x1866.contains(&AuraDevRog1::Sleep);
|
||||||
let mut keyboard = enabled_states.x1866.contains(&AuraDev1866::Keyboard);
|
let mut keyboard = enabled_states.x1866.contains(&AuraDevRog1::Keyboard);
|
||||||
let mut lightbar = enabled_states.x1866.contains(&AuraDev1866::Lightbar);
|
let mut lightbar = enabled_states.x1866.contains(&AuraDevRog1::Lightbar);
|
||||||
if supported.keyboard_led.dev_id == AuraDevice::Tuf {
|
if supported.keyboard_led.dev_id == AuraDevice::Tuf {
|
||||||
boot = enabled_states.tuf.contains(&AuraDevTuf::Boot);
|
boot = enabled_states.tuf.contains(&AuraDevTuf::Boot);
|
||||||
sleep = enabled_states.tuf.contains(&AuraDevTuf::Sleep);
|
sleep = enabled_states.tuf.contains(&AuraDevTuf::Sleep);
|
||||||
@@ -148,7 +150,7 @@ fn aura_power1(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
|||||||
let mut enabled = Vec::new();
|
let mut enabled = Vec::new();
|
||||||
let mut disabled = Vec::new();
|
let mut disabled = Vec::new();
|
||||||
|
|
||||||
let mut modify_x1866 = |b: bool, a: AuraDev1866| {
|
let mut modify_x1866 = |b: bool, a: AuraDevRog1| {
|
||||||
if b {
|
if b {
|
||||||
enabled.push(a);
|
enabled.push(a);
|
||||||
if !enabled_states.x1866.contains(&a) {
|
if !enabled_states.x1866.contains(&a) {
|
||||||
@@ -169,14 +171,14 @@ fn aura_power1(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
modify_x1866(boot, AuraDev1866::Boot);
|
modify_x1866(boot, AuraDevRog1::Boot);
|
||||||
modify_x1866(sleep, AuraDev1866::Sleep);
|
modify_x1866(sleep, AuraDevRog1::Sleep);
|
||||||
modify_x1866(keyboard, AuraDev1866::Keyboard);
|
modify_x1866(keyboard, AuraDevRog1::Keyboard);
|
||||||
if !supported.keyboard_led.basic_zones.is_empty() {
|
if !supported.keyboard_led.basic_zones.is_empty() {
|
||||||
modify_x1866(lightbar, AuraDev1866::Lightbar);
|
modify_x1866(lightbar, AuraDevRog1::Lightbar);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut send = |enable: bool, data: Vec<AuraDev1866>| {
|
let mut send = |enable: bool, data: Vec<AuraDevRog1>| {
|
||||||
let options = AuraPowerDev {
|
let options = AuraPowerDev {
|
||||||
tuf: vec![],
|
tuf: vec![],
|
||||||
x1866: data,
|
x1866: data,
|
||||||
@@ -211,17 +213,17 @@ fn aura_power2(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
|||||||
.basic_zones
|
.basic_zones
|
||||||
.contains(&AuraZone::BarRight);
|
.contains(&AuraZone::BarRight);
|
||||||
|
|
||||||
let boot_bar = &mut enabled_states.x19b6.contains(&AuraDev19b6::AwakeBar);
|
let boot_bar = &mut enabled_states.x19b6.contains(&AuraDevRog2::AwakeBar);
|
||||||
let boot_logo = &mut enabled_states.x19b6.contains(&AuraDev19b6::BootLogo);
|
let boot_logo = &mut enabled_states.x19b6.contains(&AuraDevRog2::BootLogo);
|
||||||
let boot_keyb = &mut enabled_states.x19b6.contains(&AuraDev19b6::BootKeyb);
|
let boot_keyb = &mut enabled_states.x19b6.contains(&AuraDevRog2::BootKeyb);
|
||||||
|
|
||||||
let awake_bar = &mut enabled_states.x19b6.contains(&AuraDev19b6::BootBar);
|
let awake_bar = &mut enabled_states.x19b6.contains(&AuraDevRog2::BootBar);
|
||||||
let awake_logo = &mut enabled_states.x19b6.contains(&AuraDev19b6::AwakeLogo);
|
let awake_logo = &mut enabled_states.x19b6.contains(&AuraDevRog2::AwakeLogo);
|
||||||
let awake_keyb = &mut enabled_states.x19b6.contains(&AuraDev19b6::AwakeKeyb);
|
let awake_keyb = &mut enabled_states.x19b6.contains(&AuraDevRog2::AwakeKeyb);
|
||||||
|
|
||||||
let sleep_bar = &mut enabled_states.x19b6.contains(&AuraDev19b6::SleepBar);
|
let sleep_bar = &mut enabled_states.x19b6.contains(&AuraDevRog2::SleepBar);
|
||||||
let sleep_logo = &mut enabled_states.x19b6.contains(&AuraDev19b6::SleepLogo);
|
let sleep_logo = &mut enabled_states.x19b6.contains(&AuraDevRog2::SleepLogo);
|
||||||
let sleep_keyb = &mut enabled_states.x19b6.contains(&AuraDev19b6::SleepKeyb);
|
let sleep_keyb = &mut enabled_states.x19b6.contains(&AuraDevRog2::SleepKeyb);
|
||||||
|
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
|
|
||||||
@@ -265,7 +267,7 @@ fn aura_power2(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
|||||||
let mut enabled = Vec::new();
|
let mut enabled = Vec::new();
|
||||||
let mut disabled = Vec::new();
|
let mut disabled = Vec::new();
|
||||||
|
|
||||||
let mut modify = |b: bool, a: AuraDev19b6| {
|
let mut modify = |b: bool, a: AuraDevRog2| {
|
||||||
if b {
|
if b {
|
||||||
enabled.push(a);
|
enabled.push(a);
|
||||||
if !enabled_states.x19b6.contains(&a) {
|
if !enabled_states.x19b6.contains(&a) {
|
||||||
@@ -286,25 +288,25 @@ fn aura_power2(supported: &SupportedFunctions, states: &mut SystemState, ui: &mu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
modify(*boot_keyb, AuraDev19b6::BootKeyb);
|
modify(*boot_keyb, AuraDevRog2::BootKeyb);
|
||||||
modify(*sleep_keyb, AuraDev19b6::SleepKeyb);
|
modify(*sleep_keyb, AuraDevRog2::SleepKeyb);
|
||||||
modify(*awake_keyb, AuraDev19b6::AwakeKeyb);
|
modify(*awake_keyb, AuraDevRog2::AwakeKeyb);
|
||||||
if supported.keyboard_led.basic_zones.contains(&AuraZone::Logo) {
|
if supported.keyboard_led.basic_zones.contains(&AuraZone::Logo) {
|
||||||
modify(*boot_logo, AuraDev19b6::BootLogo);
|
modify(*boot_logo, AuraDevRog2::BootLogo);
|
||||||
modify(*sleep_logo, AuraDev19b6::SleepLogo);
|
modify(*sleep_logo, AuraDevRog2::SleepLogo);
|
||||||
modify(*awake_logo, AuraDev19b6::AwakeLogo);
|
modify(*awake_logo, AuraDevRog2::AwakeLogo);
|
||||||
}
|
}
|
||||||
if supported
|
if supported
|
||||||
.keyboard_led
|
.keyboard_led
|
||||||
.basic_zones
|
.basic_zones
|
||||||
.contains(&AuraZone::BarLeft)
|
.contains(&AuraZone::BarLeft)
|
||||||
{
|
{
|
||||||
modify(*boot_bar, AuraDev19b6::AwakeBar);
|
modify(*boot_bar, AuraDevRog2::AwakeBar);
|
||||||
modify(*sleep_bar, AuraDev19b6::SleepBar);
|
modify(*sleep_bar, AuraDevRog2::SleepBar);
|
||||||
modify(*awake_bar, AuraDev19b6::BootBar);
|
modify(*awake_bar, AuraDevRog2::BootBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut send = |enable: bool, data: Vec<AuraDev19b6>| {
|
let mut send = |enable: bool, data: Vec<AuraDevRog2>| {
|
||||||
let options = AuraPowerDev {
|
let options = AuraPowerDev {
|
||||||
tuf: vec![],
|
tuf: vec![],
|
||||||
x1866: vec![],
|
x1866: vec![],
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ pub fn keyboard(
|
|||||||
AdvancedAuraType::None => (false, keyboard_layout.max_width(), false),
|
AdvancedAuraType::None => (false, keyboard_layout.max_width(), false),
|
||||||
AdvancedAuraType::Zoned(zones) => {
|
AdvancedAuraType::Zoned(zones) => {
|
||||||
let width = if let Some(row) = keyboard_layout.rows_ref().get(2) {
|
let width = if let Some(row) = keyboard_layout.rows_ref().get(2) {
|
||||||
row.width() as f32
|
row.width()
|
||||||
} else {
|
} else {
|
||||||
0.0
|
0.0
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ impl RogApp {
|
|||||||
// The top panel is often a good place for a menu bar:
|
// The top panel is often a good place for a menu bar:
|
||||||
egui::menu::bar(ui, |ui| {
|
egui::menu::bar(ui, |ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
egui::global_dark_light_mode_buttons(ui);
|
self.dark_light_mode_buttons(ui);
|
||||||
egui::warn_if_debug_build(ui);
|
egui::warn_if_debug_build(ui);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -45,4 +45,34 @@ impl RogApp {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dark_light_mode_buttons(&mut self, ui: &mut egui::Ui) {
|
||||||
|
let load_from_cfg = self.config.dark_mode != ui.ctx().style().visuals.dark_mode;
|
||||||
|
|
||||||
|
if ui
|
||||||
|
.add(egui::SelectableLabel::new(
|
||||||
|
!self.config.dark_mode,
|
||||||
|
"☀ Light",
|
||||||
|
))
|
||||||
|
.clicked()
|
||||||
|
|| (load_from_cfg && !self.config.dark_mode)
|
||||||
|
{
|
||||||
|
ui.ctx().set_visuals(egui::Visuals::light());
|
||||||
|
}
|
||||||
|
if ui
|
||||||
|
.add(egui::SelectableLabel::new(self.config.dark_mode, "🌙 Dark"))
|
||||||
|
.clicked()
|
||||||
|
|| (load_from_cfg && self.config.dark_mode)
|
||||||
|
{
|
||||||
|
ui.ctx().set_visuals(egui::Visuals::dark());
|
||||||
|
}
|
||||||
|
|
||||||
|
let applied_dark_mode = ui.ctx().style().visuals.dark_mode;
|
||||||
|
|
||||||
|
if self.config.dark_mode != applied_dark_mode {
|
||||||
|
self.config.dark_mode = applied_dark_mode;
|
||||||
|
let tmp = self.config.enabled_notifications.clone();
|
||||||
|
self.config.save(&tmp).ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,3 +15,6 @@ rog_aura = { path = "../rog-aura" }
|
|||||||
rog_profiles = { path = "../rog-profiles" }
|
rog_profiles = { path = "../rog-profiles" }
|
||||||
rog_platform = { path = "../rog-platform" }
|
rog_platform = { path = "../rog-platform" }
|
||||||
zbus.workspace = true
|
zbus.workspace = true
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
cargo-husky.workspace = true
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
//! # DBus interface proxy for: `org.asuslinux.Daemon`
|
//! # `DBus` interface proxy for: `org.asuslinux.Daemon`
|
||||||
//!
|
//!
|
||||||
//! This code was generated by `zbus-xmlgen` `1.0.0` from DBus introspection
|
//! This code was generated by `zbus-xmlgen` `1.0.0` from `DBus` introspection
|
||||||
//! data. Source: `Interface '/org/asuslinux/Aura' from service
|
//! data. Source: `Interface '/org/asuslinux/Aura' from service
|
||||||
//! 'org.asuslinux.Daemon' on system bus`.
|
//! 'org.asuslinux.Daemon' on system bus`.
|
||||||
//!
|
//!
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
//! [Writing a client proxy](https://zeenix.pages.freedesktop.org/zbus/client.html)
|
//! [Writing a client proxy](https://zeenix.pages.freedesktop.org/zbus/client.html)
|
||||||
//! section of the zbus documentation.
|
//! section of the zbus documentation.
|
||||||
//!
|
//!
|
||||||
//! This DBus object implements
|
//! This `DBus` object implements
|
||||||
//! [standard DBus interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
|
//! [standard `DBus` interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
|
||||||
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
|
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
|
||||||
//!
|
//!
|
||||||
//! * [`zbus::fdo::PeerProxy`]
|
//! * [`zbus::fdo::PeerProxy`]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! # DBus interface proxy for: `org.asuslinux.Daemon`
|
//! # `DBus` interface proxy for: `org.asuslinux.Daemon`
|
||||||
//!
|
//!
|
||||||
//! This code was generated by `zbus-xmlgen` `1.0.0` from DBus introspection
|
//! This code was generated by `zbus-xmlgen` `1.0.0` from `DBus` introspection
|
||||||
//! data. Source: `Interface '/org/asuslinux/Platform' from service
|
//! data. Source: `Interface '/org/asuslinux/Platform' from service
|
||||||
//! 'org.asuslinux.Daemon' on system bus`.
|
//! 'org.asuslinux.Daemon' on system bus`.
|
||||||
//!
|
//!
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
//! [Writing a client proxy](https://zeenix.pages.freedesktop.org/zbus/client.html)
|
//! [Writing a client proxy](https://zeenix.pages.freedesktop.org/zbus/client.html)
|
||||||
//! section of the zbus documentation.
|
//! section of the zbus documentation.
|
||||||
//!
|
//!
|
||||||
//! This DBus object implements
|
//! This `DBus` object implements
|
||||||
//! [standard DBus interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
|
//! [standard `DBus` interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
|
||||||
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
|
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
|
||||||
//!
|
//!
|
||||||
//! * [`zbus::fdo::PropertiesProxy`]
|
//! * [`zbus::fdo::PropertiesProxy`]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! # DBus interface proxy for: `org.asuslinux.Daemon`
|
//! # `DBus` interface proxy for: `org.asuslinux.Daemon`
|
||||||
//!
|
//!
|
||||||
//! This code was generated by `zbus-xmlgen` `1.0.0` from DBus introspection
|
//! This code was generated by `zbus-xmlgen` `1.0.0` from `DBus` introspection
|
||||||
//! data. Source: `Interface '/org/asuslinux/Charge' from service
|
//! data. Source: `Interface '/org/asuslinux/Charge' from service
|
||||||
//! 'org.asuslinux.Daemon' on system bus`.
|
//! 'org.asuslinux.Daemon' on system bus`.
|
||||||
//!
|
//!
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
//! [Writing a client proxy](https://zeenix.pages.freedesktop.org/zbus/client.html)
|
//! [Writing a client proxy](https://zeenix.pages.freedesktop.org/zbus/client.html)
|
||||||
//! section of the zbus documentation.
|
//! section of the zbus documentation.
|
||||||
//!
|
//!
|
||||||
//! This DBus object implements
|
//! This `DBus` object implements
|
||||||
//! [standard DBus interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
|
//! [standard `DBus` interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
|
||||||
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
|
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
|
||||||
//!
|
//!
|
||||||
//! * [`zbus::fdo::PropertiesProxy`]
|
//! * [`zbus::fdo::PropertiesProxy`]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! # DBus interface proxy for: `org.asuslinux.Daemon`
|
//! # `DBus` interface proxy for: `org.asuslinux.Daemon`
|
||||||
//!
|
//!
|
||||||
//! This code was generated by `zbus-xmlgen` `1.0.0` from DBus introspection
|
//! This code was generated by `zbus-xmlgen` `1.0.0` from `DBus` introspection
|
||||||
//! data. Source: `Interface '/org/asuslinux/Profile' from service
|
//! data. Source: `Interface '/org/asuslinux/Profile' from service
|
||||||
//! 'org.asuslinux.Daemon' on system bus`.
|
//! 'org.asuslinux.Daemon' on system bus`.
|
||||||
//!
|
//!
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
//! [Writing a client proxy](https://zeenix.pages.freedesktop.org/zbus/client.html)
|
//! [Writing a client proxy](https://zeenix.pages.freedesktop.org/zbus/client.html)
|
||||||
//! section of the zbus documentation.
|
//! section of the zbus documentation.
|
||||||
//!
|
//!
|
||||||
//! This DBus object implements
|
//! This `DBus object implements
|
||||||
//! [standard DBus interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
|
//! [standard DBus` interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
|
||||||
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
|
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
|
||||||
//!
|
//!
|
||||||
//! * [`zbus::fdo::IntrospectableProxy`]
|
//! * [`zbus::fdo::IntrospectableProxy`]
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//! # DBus interface proxy for: `org.asuslinux.Daemon`
|
//! # `DBus` interface proxy for: `org.asuslinux.Daemon`
|
||||||
//!
|
//!
|
||||||
//! This code was generated by `zbus-xmlgen` `1.0.0` from DBus introspection
|
//! This code was generated by `zbus-xmlgen` `1.0.0` from `DBus` introspection
|
||||||
//! data. Source: `Interface '/org/asuslinux/Supported' from service
|
//! data. Source: `Interface '/org/asuslinux/Supported' from service
|
||||||
//! 'org.asuslinux.Daemon' on system bus`.
|
//! 'org.asuslinux.Daemon' on system bus`.
|
||||||
//!
|
//!
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
//! [Writing a client proxy](https://zeenix.pages.freedesktop.org/zbus/client.html)
|
//! [Writing a client proxy](https://zeenix.pages.freedesktop.org/zbus/client.html)
|
||||||
//! section of the zbus documentation.
|
//! section of the zbus documentation.
|
||||||
//!
|
//!
|
||||||
//! This DBus object implements
|
//! This `DBus` object implements
|
||||||
//! [standard DBus interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
|
//! [standard `DBus` interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
|
||||||
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
|
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
|
||||||
//!
|
//!
|
||||||
//! * [`zbus::fdo::PeerProxy`]
|
//! * [`zbus::fdo::PeerProxy`]
|
||||||
|
|||||||
@@ -16,3 +16,6 @@ udev.workspace = true
|
|||||||
inotify.workspace = true
|
inotify.workspace = true
|
||||||
|
|
||||||
rusb.workspace = true
|
rusb.workspace = true
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
cargo-husky.workspace = true
|
||||||
+1
-39
@@ -51,7 +51,7 @@ pub fn write_attr_bool(device: &mut Device, attr: &str, value: bool) -> Result<(
|
|||||||
pub fn read_attr_u8(device: &Device, attr_name: &str) -> Result<u8> {
|
pub fn read_attr_u8(device: &Device, attr_name: &str) -> Result<u8> {
|
||||||
if let Some(value) = device.attribute_value(attr_name) {
|
if let Some(value) = device.attribute_value(attr_name) {
|
||||||
let tmp = value.to_string_lossy();
|
let tmp = value.to_string_lossy();
|
||||||
return tmp.parse::<u8>().map_err(|_| PlatformError::ParseNum);
|
return tmp.parse::<u8>().map_err(|_e| PlatformError::ParseNum);
|
||||||
}
|
}
|
||||||
Err(PlatformError::AttrNotFound(attr_name.to_owned()))
|
Err(PlatformError::AttrNotFound(attr_name.to_owned()))
|
||||||
}
|
}
|
||||||
@@ -114,41 +114,3 @@ mod tests {
|
|||||||
assert_eq!(tmp, &[1, 2, 3, 4, 5]);
|
assert_eq!(tmp, &[1, 2, 3, 4, 5]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn find_led_node(id_product: &str) -> Result<Device, PlatformError> {
|
|
||||||
// let mut enumerator = udev::Enumerator::new().map_err(|err| {
|
|
||||||
// warn!("{}", err);
|
|
||||||
// PlatformError::Udev("enumerator failed".into(), err)
|
|
||||||
// })?;
|
|
||||||
// enumerator.match_subsystem("hidraw").map_err(|err| {
|
|
||||||
// warn!("{}", err);
|
|
||||||
// PlatformError::Udev("match_subsystem failed".into(), err)
|
|
||||||
// })?;
|
|
||||||
|
|
||||||
// for device in enumerator.scan_devices().map_err(|err| {
|
|
||||||
// warn!("{}", err);
|
|
||||||
// PlatformError::Udev("scan_devices failed".into(), err)
|
|
||||||
// })? {
|
|
||||||
// if let Some(parent) = device
|
|
||||||
// .parent_with_subsystem_devtype("usb", "usb_device")
|
|
||||||
// .map_err(|err| {
|
|
||||||
// warn!("{}", err);
|
|
||||||
// PlatformError::Udev("parent_with_subsystem_devtype
|
|
||||||
// failed".into(), err) })?
|
|
||||||
// {
|
|
||||||
// if parent
|
|
||||||
// .attribute_value("idProduct")
|
|
||||||
// .ok_or_else(|| PlatformError::NotFound("LED
|
|
||||||
// idProduct".into()))? == id_product
|
|
||||||
// {
|
|
||||||
// if let Some(dev_node) = device.devnode() {
|
|
||||||
// info!("Using device at: {:?} for LED control", dev_node);
|
|
||||||
// return Ok(device);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Err(PlatformError::MissingFunction(
|
|
||||||
// "ASUS LED device node not found".into(),
|
|
||||||
// ))
|
|
||||||
// }
|
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ pub enum GpuMode {
|
|||||||
Optimus,
|
Optimus,
|
||||||
Integrated,
|
Integrated,
|
||||||
Egpu,
|
Egpu,
|
||||||
|
Vfio,
|
||||||
|
Ultimate,
|
||||||
#[default]
|
#[default]
|
||||||
Error,
|
Error,
|
||||||
NotSupported,
|
NotSupported,
|
||||||
@@ -135,6 +137,8 @@ impl Display for GpuMode {
|
|||||||
GpuMode::Optimus => write!(f, "Optimus"),
|
GpuMode::Optimus => write!(f, "Optimus"),
|
||||||
GpuMode::Integrated => write!(f, "Integrated"),
|
GpuMode::Integrated => write!(f, "Integrated"),
|
||||||
GpuMode::Egpu => write!(f, "eGPU"),
|
GpuMode::Egpu => write!(f, "eGPU"),
|
||||||
|
GpuMode::Vfio => write!(f, "VFIO"),
|
||||||
|
GpuMode::Ultimate => write!(f, "Ultimate"),
|
||||||
GpuMode::Error => write!(f, "Error"),
|
GpuMode::Error => write!(f, "Error"),
|
||||||
GpuMode::NotSupported => write!(f, "Not Supported"),
|
GpuMode::NotSupported => write!(f, "Not Supported"),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,3 +15,6 @@ serde.workspace = true
|
|||||||
serde_derive.workspace = true
|
serde_derive.workspace = true
|
||||||
|
|
||||||
zbus = { workspace = true, optional = true }
|
zbus = { workspace = true, optional = true }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
cargo-husky.workspace = true
|
||||||
@@ -19,7 +19,7 @@ pub enum ProfileError {
|
|||||||
|
|
||||||
impl fmt::Display for ProfileError {
|
impl fmt::Display for ProfileError {
|
||||||
// This trait requires `fmt` with this exact signature.
|
// This trait requires `fmt` with this exact signature.
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
ProfileError::Path(path, error) => write!(f, "Path {}: {}", path, error),
|
ProfileError::Path(path, error) => write!(f, "Path {}: {}", path, error),
|
||||||
ProfileError::Read(path, error) => write!(f, "Read {}: {}", path, error),
|
ProfileError::Read(path, error) => write!(f, "Read {}: {}", path, error),
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::error::ProfileError;
|
|||||||
use crate::FanCurvePU;
|
use crate::FanCurvePU;
|
||||||
|
|
||||||
pub(crate) fn pwm_str(fan: char, index: usize) -> String {
|
pub(crate) fn pwm_str(fan: char, index: usize) -> String {
|
||||||
let mut buf = "pwm1_auto_point1_pwm".to_string();
|
let mut buf = "pwm1_auto_point1_pwm".to_owned();
|
||||||
unsafe {
|
unsafe {
|
||||||
let tmp = buf.as_bytes_mut();
|
let tmp = buf.as_bytes_mut();
|
||||||
tmp[3] = fan as u8;
|
tmp[3] = fan as u8;
|
||||||
@@ -17,7 +17,7 @@ pub(crate) fn pwm_str(fan: char, index: usize) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn temp_str(fan: char, index: usize) -> String {
|
pub(crate) fn temp_str(fan: char, index: usize) -> String {
|
||||||
let mut buf = "pwm1_auto_point1_temp".to_string();
|
let mut buf = "pwm1_auto_point1_temp".to_owned();
|
||||||
unsafe {
|
unsafe {
|
||||||
let tmp = buf.as_bytes_mut();
|
let tmp = buf.as_bytes_mut();
|
||||||
tmp[3] = fan as u8;
|
tmp[3] = fan as u8;
|
||||||
@@ -146,10 +146,10 @@ impl CurveData {
|
|||||||
for attr in device.attributes() {
|
for attr in device.attributes() {
|
||||||
let tmp = attr.name().to_string_lossy();
|
let tmp = attr.name().to_string_lossy();
|
||||||
if tmp.starts_with("pwm1") && tmp.ends_with("_temp") {
|
if tmp.starts_with("pwm1") && tmp.ends_with("_temp") {
|
||||||
Self::set_val_from_attr(tmp.as_ref(), device, &mut self.temp)
|
Self::set_val_from_attr(tmp.as_ref(), device, &mut self.temp);
|
||||||
}
|
}
|
||||||
if tmp.starts_with("pwm1") && tmp.ends_with("_pwm") {
|
if tmp.starts_with("pwm1") && tmp.ends_with("_pwm") {
|
||||||
Self::set_val_from_attr(tmp.as_ref(), device, &mut self.pwm)
|
Self::set_val_from_attr(tmp.as_ref(), device, &mut self.pwm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-10
@@ -2,8 +2,8 @@ pub mod error;
|
|||||||
pub mod fan_curve_set;
|
pub mod fan_curve_set;
|
||||||
|
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::fs::OpenOptions;
|
use std::fs::{self, OpenOptions};
|
||||||
use std::io::{Read, Write};
|
use std::io::Write;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use error::ProfileError;
|
use error::ProfileError;
|
||||||
@@ -49,18 +49,12 @@ impl Profile {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_active_profile() -> Result<Profile, ProfileError> {
|
pub fn get_active_profile() -> Result<Profile, ProfileError> {
|
||||||
let mut file = OpenOptions::new().read(true).open(PLATFORM_PROFILE)?;
|
let buf = fs::read_to_string(PLATFORM_PROFILE)?;
|
||||||
|
|
||||||
let mut buf = String::new();
|
|
||||||
file.read_to_string(&mut buf)?;
|
|
||||||
Ok(buf.as_str().into())
|
Ok(buf.as_str().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_profile_names() -> Result<Vec<Profile>, ProfileError> {
|
pub fn get_profile_names() -> Result<Vec<Profile>, ProfileError> {
|
||||||
let mut file = OpenOptions::new().read(true).open(PLATFORM_PROFILES)?;
|
let buf = fs::read_to_string(PLATFORM_PROFILES)?;
|
||||||
|
|
||||||
let mut buf = String::new();
|
|
||||||
file.read_to_string(&mut buf)?;
|
|
||||||
Ok(buf.rsplit(' ').map(|p| p.into()).collect())
|
Ok(buf.rsplit(' ').map(|p| p.into()).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user