mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-01-22 09:23:19 +01:00
Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9aa332de3b | ||
|
|
5efd7fc6a7 | ||
|
|
0aafe24a02 | ||
|
|
dda6d343d9 | ||
|
|
6f39307080 | ||
|
|
ef63789faa | ||
|
|
c422e77ba6 | ||
|
|
3c234dd3c4 | ||
|
|
c420dd820a | ||
|
|
a3e6fec163 | ||
|
|
9b4e76be87 | ||
|
|
7b2125cbdf | ||
|
|
694a644cc6 | ||
|
|
922aa0c352 | ||
|
|
c06f78990f | ||
|
|
5c8bb6e6ea | ||
|
|
993131d0a9 | ||
|
|
0a69c23288 | ||
|
|
f6e4cc0626 | ||
|
|
1f696508e7 | ||
|
|
fa043adc99 | ||
|
|
b9c2d929b3 | ||
|
|
eda1e920df | ||
|
|
0de2c9e424 | ||
|
|
e88e7be8ae | ||
|
|
e470d3acc0 | ||
|
|
f5b3f0bc38 | ||
|
|
19497c94e0 | ||
|
|
670eee23e8 | ||
|
|
26309776e9 | ||
|
|
a7d5057976 | ||
|
|
8eb9b1d4eb | ||
|
|
71ee9e43ba | ||
|
|
f1b0e1288a | ||
|
|
35c7fd10b3 | ||
|
|
4c50dc259c | ||
|
|
0fd0aeff88 | ||
|
|
fd37f41ef1 | ||
|
|
1307997122 | ||
|
|
85187d2d8d | ||
|
|
e29a568195 | ||
|
|
6c375a9951 | ||
|
|
4641e19c43 | ||
|
|
91f0c2ea14 | ||
|
|
b4a8cb9de2 | ||
|
|
67bbcdb964 | ||
|
|
8acfe0a9e8 | ||
|
|
5f6e6ec382 | ||
|
|
cf92526d87 | ||
|
|
b652fd15a2 | ||
|
|
9e65921c0a |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -14,7 +14,8 @@ vendor_*
|
|||||||
node-modules
|
node-modules
|
||||||
bindings/ts/*.d.ts
|
bindings/ts/*.d.ts
|
||||||
bindings/ts/*.js.map
|
bindings/ts/*.js.map
|
||||||
desktop-extensions/gnome/dist
|
desktop-extensions/gnome*/dist
|
||||||
desktop-extensions/gnome/node_modules
|
desktop-extensions/gnome*/@types/gir-generated
|
||||||
desktop-extensions/gnome/schemas/gschemas.compiled
|
desktop-extensions/gnome*/node_modules
|
||||||
desktop-extensions/gnome/*.zip
|
desktop-extensions/gnome*/schemas/gschemas.compiled
|
||||||
|
desktop-extensions/gnome*/*.zip
|
||||||
|
|||||||
45
CHANGELOG.md
45
CHANGELOG.md
@@ -5,6 +5,51 @@ 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]
|
||||||
|
|
||||||
|
## [v5.0.1]
|
||||||
|
### Changed
|
||||||
|
- Fix setting next fan profile
|
||||||
|
- Fix the assud.service
|
||||||
|
- Fix dbus signature of some power setting types for some keyboards
|
||||||
|
|
||||||
|
## [v5.0.0]
|
||||||
|
### Added
|
||||||
|
- Gnome 45 plugin
|
||||||
|
- Support for G513RW LED modes
|
||||||
|
- Support Rog Ally LED modes (basic)
|
||||||
|
- Add on_lid_closed and on_external_power_changed events for running certain tasks
|
||||||
|
- Anime dbus: add:
|
||||||
|
- SetOffWhenUnplugged, also add asusctl CLI option
|
||||||
|
- SetOffWhenSuspended, also add asusctl CLI option
|
||||||
|
- SetOffWhenLidClosed, also add asusctl CLI option
|
||||||
|
- Anime: add brightness_on_battery config option
|
||||||
|
- Platform: add `post_animation_sound`, kernel 6.7+ requires patch
|
||||||
|
- Add changing of CPU energy perfromance preference in relation to throttle_thermal_policy. This means that the CPU correctly behaves according to throttle_thermal_policy (and platform profile use is *removed*)
|
||||||
|
- Add setting of throttle_thermal_policy on power plug/unplug
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- asusd: remove set_image_brightness for anime
|
||||||
|
- asusd: refactor how certain things like display enable/builtins are toggled
|
||||||
|
- Refactor sleep/shutdown tasks
|
||||||
|
- rog-control-center: ensure brightness slider works correctly
|
||||||
|
- Update `smithay-client-toolkit` for fix to issue #407
|
||||||
|
- Remove the "sleep" animations from Anime to stop preventing the display-off
|
||||||
|
- Anime:
|
||||||
|
- Ensure display is off when lid is closed and option is set
|
||||||
|
- Ensure display is off when on battery and option is set
|
||||||
|
- Ensure builtin animations run instead of custom animations if option is set
|
||||||
|
|
||||||
|
### Breaking
|
||||||
|
- DBUS stuff. Again. All of it.
|
||||||
|
|
||||||
|
## [v4.7.2]
|
||||||
|
### Added
|
||||||
|
- Support for G733PZ LED modes
|
||||||
|
- Support for G713RC LED modes
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Fix loading of fan curves from stored settings
|
||||||
|
|
||||||
## [v4.7.1]
|
## [v4.7.1]
|
||||||
### Changed
|
### Changed
|
||||||
- Fixes to asusctl CLI tool to show fan curves
|
- Fixes to asusctl CLI tool to show fan curves
|
||||||
|
|||||||
1071
Cargo.lock
generated
1071
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
12
Cargo.toml
12
Cargo.toml
@@ -1,14 +1,14 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = ["asusctl", "asusd", "asusd-user", "config-traits", "rog-platform", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center", "simulators"]
|
members = ["asusctl", "asusd", "asusd-user", "config-traits", "cpuctl", "dmi-id", "rog-platform", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center", "simulators"]
|
||||||
default-members = ["asusctl", "asusd", "asusd-user", "rog-control-center"]
|
default-members = ["asusctl", "asusd", "asusd-user", "cpuctl", "rog-control-center"]
|
||||||
workspace.resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "4.7.1"
|
version = "5.0.1"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
async-trait = "^0.1"
|
async-trait = "^0.1"
|
||||||
tokio = { version = "^1.23.0", features = ["macros", "rt-multi-thread", "time", "sync"]}
|
tokio = { version = "^1.23.0", features = ["macros", "sync", "rt-multi-thread"]}
|
||||||
concat-idents = "^1.1"
|
concat-idents = "^1.1"
|
||||||
dirs = "^4.0"
|
dirs = "^4.0"
|
||||||
smol = "^1.3"
|
smol = "^1.3"
|
||||||
@@ -30,7 +30,6 @@ glam = { version = "^0.22", features = ["serde"] }
|
|||||||
gumdrop = "^0.8"
|
gumdrop = "^0.8"
|
||||||
udev = "^0.7"
|
udev = "^0.7"
|
||||||
rusb = "^0.9"
|
rusb = "^0.9"
|
||||||
sysfs-class = "^0.1.3"
|
|
||||||
inotify = "^0.10.0"
|
inotify = "^0.10.0"
|
||||||
|
|
||||||
png_pong = "^0.8"
|
png_pong = "^0.8"
|
||||||
@@ -49,6 +48,7 @@ lto = "fat"
|
|||||||
debug = false
|
debug = false
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
panic = "abort"
|
panic = "abort"
|
||||||
|
#codegen-units = 1
|
||||||
|
|
||||||
[profile.dev]
|
[profile.dev]
|
||||||
debug = true
|
debug = true
|
||||||
|
|||||||
9
Makefile
9
Makefile
@@ -112,6 +112,8 @@ vendor:
|
|||||||
echo 'directory = "vendor"' >> .cargo/config
|
echo 'directory = "vendor"' >> .cargo/config
|
||||||
mv .cargo/config ./cargo-config
|
mv .cargo/config ./cargo-config
|
||||||
rm -rf .cargo
|
rm -rf .cargo
|
||||||
|
rm -rf vendor
|
||||||
|
cargo vendor-filterer --platform x86_64-unknown-linux-gnu vendor
|
||||||
tar pcfJ vendor_asusctl_$(VERSION).tar.xz vendor
|
tar pcfJ vendor_asusctl_$(VERSION).tar.xz vendor
|
||||||
rm -rf vendor
|
rm -rf vendor
|
||||||
|
|
||||||
@@ -122,18 +124,17 @@ bindings:
|
|||||||
typeshare ./rog-platform/src/ --lang=typescript --output-file=bindings/ts/platform.ts
|
typeshare ./rog-platform/src/ --lang=typescript --output-file=bindings/ts/platform.ts
|
||||||
|
|
||||||
introspect:
|
introspect:
|
||||||
|
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Platform -x > bindings/dbus-xml/org-asuslinux-platform-4.xml
|
||||||
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Aura -x > bindings/dbus-xml/org-asuslinux-aura-4.xml
|
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Aura -x > bindings/dbus-xml/org-asuslinux-aura-4.xml
|
||||||
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Anime -x > bindings/dbus-xml/org-asuslinux-anime-4.xml
|
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Anime -x > bindings/dbus-xml/org-asuslinux-anime-4.xml
|
||||||
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Platform -x > bindings/dbus-xml/org-asuslinux-platform-4.xml
|
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/FanCurves -x > bindings/dbus-xml/org-asuslinux-fan-curves-4.xml
|
||||||
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Power -x > bindings/dbus-xml/org-asuslinux-power-4.xml
|
|
||||||
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Profile -x > bindings/dbus-xml/org-asuslinux-profile-4.xml
|
|
||||||
gdbus introspect --system -d org.asuslinux.Daemon -o /org/asuslinux/Supported -x > bindings/dbus-xml/org-asuslinux-supported-4.xml
|
|
||||||
xmlstarlet ed -L -O -d '//interface[@name="org.freedesktop.DBus.Introspectable"]' bindings/dbus-xml/org-asuslinux-*
|
xmlstarlet ed -L -O -d '//interface[@name="org.freedesktop.DBus.Introspectable"]' bindings/dbus-xml/org-asuslinux-*
|
||||||
xmlstarlet ed -L -O -d '//interface[@name="org.freedesktop.DBus.Properties"]' bindings/dbus-xml/org-asuslinux-*
|
xmlstarlet ed -L -O -d '//interface[@name="org.freedesktop.DBus.Properties"]' bindings/dbus-xml/org-asuslinux-*
|
||||||
xmlstarlet ed -L -O -d '//interface[@name="org.freedesktop.DBus.Peer"]' bindings/dbus-xml/org-asuslinux-*
|
xmlstarlet ed -L -O -d '//interface[@name="org.freedesktop.DBus.Peer"]' bindings/dbus-xml/org-asuslinux-*
|
||||||
|
|
||||||
build:
|
build:
|
||||||
ifeq ($(VENDORED),1)
|
ifeq ($(VENDORED),1)
|
||||||
|
cargo vendor
|
||||||
@echo "version = $(VERSION)"
|
@echo "version = $(VERSION)"
|
||||||
tar pxf vendor_asusctl_$(VERSION).tar.xz
|
tar pxf vendor_asusctl_$(VERSION).tar.xz
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ rog_dbus = { path = "../rog-dbus" }
|
|||||||
rog_profiles = { path = "../rog-profiles" }
|
rog_profiles = { path = "../rog-profiles" }
|
||||||
rog_platform = { path = "../rog-platform" }
|
rog_platform = { path = "../rog-platform" }
|
||||||
asusd = { path = "../asusd" }
|
asusd = { path = "../asusd" }
|
||||||
|
dmi_id = { path = "../dmi-id" }
|
||||||
|
|
||||||
gumdrop.workspace = true
|
gumdrop.workspace = true
|
||||||
toml.workspace = true
|
toml.workspace = true
|
||||||
sysfs-class.workspace = true
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
gif.workspace = true
|
gif.workspace = true
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use rog_dbus::RogDbusClientBlocking;
|
|||||||
fn main() -> Result<(), Box<dyn Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
||||||
|
|
||||||
let args: Vec<String> = env::args().into_iter().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
if args.len() != 3 {
|
if args.len() != 3 {
|
||||||
println!("Usage: <filepath> <brightness>");
|
println!("Usage: <filepath> <brightness>");
|
||||||
println!("e.g, asusctl/examples/doom_large.png 0.8");
|
println!("e.g, asusctl/examples/doom_large.png 0.8");
|
||||||
|
|||||||
@@ -15,13 +15,13 @@ fn main() {
|
|||||||
|
|
||||||
for step in (2..50).rev() {
|
for step in (2..50).rev() {
|
||||||
let mut matrix = AnimeDiagonal::new(AnimeType::GA401, None);
|
let mut matrix = AnimeDiagonal::new(AnimeType::GA401, None);
|
||||||
for c in (0..60).into_iter().step_by(step) {
|
for c in (0..60).step_by(step) {
|
||||||
for i in matrix.get_mut().iter_mut() {
|
for i in matrix.get_mut().iter_mut() {
|
||||||
i[c] = 50;
|
i[c] = 50;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for c in (0..35).into_iter().step_by(step) {
|
for c in (0..35).step_by(step) {
|
||||||
for i in &mut matrix.get_mut()[c] {
|
for i in &mut matrix.get_mut()[c] {
|
||||||
*i = 50;
|
*i = 50;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use rog_dbus::RogDbusClientBlocking;
|
|||||||
fn main() {
|
fn main() {
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
||||||
|
|
||||||
let args: Vec<String> = env::args().into_iter().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
if args.len() != 3 {
|
if args.len() != 3 {
|
||||||
println!("Please supply filepath and brightness");
|
println!("Please supply filepath and brightness");
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use rog_dbus::RogDbusClientBlocking;
|
|||||||
fn main() -> Result<(), Box<dyn Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
||||||
|
|
||||||
let args: Vec<String> = env::args().into_iter().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
if args.len() != 7 {
|
if args.len() != 7 {
|
||||||
println!("Usage: <filepath> <scale> <angle> <x pos> <y pos> <brightness>");
|
println!("Usage: <filepath> <scale> <angle> <x pos> <y pos> <brightness>");
|
||||||
println!("e.g, asusctl/examples/doom_large.png 0.9 0.4 0.0 0.0 0.8");
|
println!("e.g, asusctl/examples/doom_large.png 0.9 0.4 0.0 0.0 0.8");
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use rog_dbus::RogDbusClientBlocking;
|
|||||||
fn main() -> Result<(), Box<dyn Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
||||||
|
|
||||||
let args: Vec<String> = env::args().into_iter().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
if args.len() != 7 {
|
if args.len() != 7 {
|
||||||
println!("Usage: <filepath> <scale> <angle> <x pos> <y pos> <brightness>");
|
println!("Usage: <filepath> <scale> <angle> <x pos> <y pos> <brightness>");
|
||||||
println!("e.g, asusctl/examples/doom_large.png 0.9 0.4 0.0 0.0 0.8");
|
println!("e.g, asusctl/examples/doom_large.png 0.9 0.4 0.0 0.0 0.8");
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
seq.next_state(&layout);
|
seq.next_state(&layout);
|
||||||
let packets = seq.create_packets();
|
let packets = seq.create_packets();
|
||||||
|
|
||||||
client.proxies().led().direct_addressing_raw(packets)?;
|
client.proxies().aura().direct_addressing_raw(packets)?;
|
||||||
std::thread::sleep(std::time::Duration::from_millis(33));
|
std::thread::sleep(std::time::Duration::from_millis(33));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,28 @@ pub struct AnimeCommand {
|
|||||||
help = "set global base brightness value <Off, Low, Med, High>"
|
help = "set global base brightness value <Off, Low, Med, High>"
|
||||||
)]
|
)]
|
||||||
pub brightness: Option<Brightness>,
|
pub brightness: Option<Brightness>,
|
||||||
#[options(meta = "", help = "set global (image) brightness value")]
|
|
||||||
pub image_brightness: Option<f32>,
|
|
||||||
#[options(help = "clear the display")]
|
#[options(help = "clear the display")]
|
||||||
pub clear: bool,
|
pub clear: bool,
|
||||||
|
#[options(
|
||||||
|
no_short,
|
||||||
|
meta = "",
|
||||||
|
help = "turn the anime off when external power is unplugged"
|
||||||
|
)]
|
||||||
|
pub off_when_unplugged: Option<bool>,
|
||||||
|
#[options(
|
||||||
|
no_short,
|
||||||
|
meta = "",
|
||||||
|
help = "turn the anime off when the laptop suspends"
|
||||||
|
)]
|
||||||
|
pub off_when_suspended: Option<bool>,
|
||||||
|
#[options(
|
||||||
|
no_short,
|
||||||
|
meta = "",
|
||||||
|
help = "turn the anime off when the lid is closed"
|
||||||
|
)]
|
||||||
|
pub off_when_lid_closed: Option<bool>,
|
||||||
|
#[options(no_short, meta = "", help = "Off with his head!!!")]
|
||||||
|
pub off_with_his_head: Option<bool>,
|
||||||
#[options(command)]
|
#[options(command)]
|
||||||
pub command: Option<AnimeActions>,
|
pub command: Option<AnimeActions>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,14 +59,14 @@ pub struct AuraPowerStates {
|
|||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
pub struct LedBrightness {
|
pub struct LedBrightness {
|
||||||
level: Option<u32>,
|
level: Option<u8>,
|
||||||
}
|
}
|
||||||
impl LedBrightness {
|
impl LedBrightness {
|
||||||
pub fn new(level: Option<u32>) -> Self {
|
pub fn new(level: Option<u8>) -> Self {
|
||||||
LedBrightness { level }
|
LedBrightness { level }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn level(&self) -> Option<u32> {
|
pub fn level(&self) -> Option<u8> {
|
||||||
self.level
|
self.level
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
use gumdrop::Options;
|
use gumdrop::Options;
|
||||||
|
use rog_platform::platform::PlatformPolicy;
|
||||||
|
|
||||||
use crate::anime_cli::AnimeCommand;
|
use crate::anime_cli::AnimeCommand;
|
||||||
use crate::aura_cli::{LedBrightness, LedPowerCommand1, LedPowerCommand2, SetAuraBuiltin};
|
use crate::aura_cli::{LedBrightness, LedPowerCommand1, LedPowerCommand2, SetAuraBuiltin};
|
||||||
use crate::profiles_cli::{FanCurveCommand, ProfileCommand};
|
use crate::fan_curve_cli::FanCurveCommand;
|
||||||
|
|
||||||
#[derive(Default, Options)]
|
#[derive(Default, Options)]
|
||||||
pub struct CliStart {
|
pub struct CliStart {
|
||||||
@@ -44,6 +45,24 @@ pub enum CliCommand {
|
|||||||
Bios(BiosCommand),
|
Bios(BiosCommand),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Options)]
|
||||||
|
pub struct ProfileCommand {
|
||||||
|
#[options(help = "print help message")]
|
||||||
|
pub help: bool,
|
||||||
|
|
||||||
|
#[options(help = "toggle to next profile in list")]
|
||||||
|
pub next: bool,
|
||||||
|
|
||||||
|
#[options(help = "list available profiles")]
|
||||||
|
pub list: bool,
|
||||||
|
|
||||||
|
#[options(help = "get profile")]
|
||||||
|
pub profile_get: bool,
|
||||||
|
|
||||||
|
#[options(meta = "", help = "set the active profile")]
|
||||||
|
pub profile_set: Option<PlatformPolicy>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
pub struct LedModeCommand {
|
pub struct LedModeCommand {
|
||||||
#[options(help = "print help message")]
|
#[options(help = "print help message")]
|
||||||
|
|||||||
@@ -1,24 +1,7 @@
|
|||||||
use gumdrop::Options;
|
use gumdrop::Options;
|
||||||
|
use rog_platform::platform::PlatformPolicy;
|
||||||
use rog_profiles::fan_curve_set::CurveData;
|
use rog_profiles::fan_curve_set::CurveData;
|
||||||
use rog_profiles::{FanCurvePU, Profile};
|
use rog_profiles::FanCurvePU;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Options)]
|
|
||||||
pub struct ProfileCommand {
|
|
||||||
#[options(help = "print help message")]
|
|
||||||
pub help: bool,
|
|
||||||
|
|
||||||
#[options(help = "toggle to next profile in list")]
|
|
||||||
pub next: bool,
|
|
||||||
|
|
||||||
#[options(help = "list available profiles")]
|
|
||||||
pub list: bool,
|
|
||||||
|
|
||||||
#[options(help = "get profile")]
|
|
||||||
pub profile_get: bool,
|
|
||||||
|
|
||||||
#[options(meta = "", help = "set the active profile")]
|
|
||||||
pub profile_set: Option<Profile>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Options)]
|
#[derive(Debug, Clone, Options)]
|
||||||
pub struct FanCurveCommand {
|
pub struct FanCurveCommand {
|
||||||
@@ -35,7 +18,7 @@ pub struct FanCurveCommand {
|
|||||||
meta = "",
|
meta = "",
|
||||||
help = "profile to modify fan-curve for. Shows data if no options provided"
|
help = "profile to modify fan-curve for. Shows data if no options provided"
|
||||||
)]
|
)]
|
||||||
pub mod_profile: Option<Profile>,
|
pub mod_profile: Option<PlatformPolicy>,
|
||||||
|
|
||||||
#[options(
|
#[options(
|
||||||
meta = "",
|
meta = "",
|
||||||
@@ -5,17 +5,20 @@ use std::process::Command;
|
|||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
|
|
||||||
use anime_cli::{AnimeActions, AnimeCommand};
|
use anime_cli::{AnimeActions, AnimeCommand};
|
||||||
|
use asusd::ctrl_aura::trait_impls::AURA_ZBUS_NAME;
|
||||||
|
use asusd::ctrl_fancurves::FAN_CURVE_ZBUS_NAME;
|
||||||
use aura_cli::{LedPowerCommand1, LedPowerCommand2};
|
use aura_cli::{LedPowerCommand1, LedPowerCommand2};
|
||||||
|
use dmi_id::DMIID;
|
||||||
|
use fan_curve_cli::FanCurveCommand;
|
||||||
use gumdrop::{Opt, Options};
|
use gumdrop::{Opt, Options};
|
||||||
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, AnimeType, Vec2};
|
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, AnimeType, Vec2};
|
||||||
use rog_aura::power::KbAuraPowerState;
|
use rog_aura::power::KbAuraPowerState;
|
||||||
use rog_aura::usb::{AuraDevRog1, AuraDevTuf, AuraDevice, AuraPowerDev};
|
use rog_aura::usb::{AuraDevRog1, AuraDevTuf, 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::error::PlatformError;
|
||||||
use rog_platform::supported::*;
|
use rog_platform::platform::{GpuMode, PlatformPolicy, Properties};
|
||||||
use rog_profiles::error::ProfileError;
|
use rog_profiles::error::ProfileError;
|
||||||
|
|
||||||
use crate::aura_cli::{AuraPowerStates, LedBrightness};
|
use crate::aura_cli::{AuraPowerStates, LedBrightness};
|
||||||
@@ -24,7 +27,7 @@ use crate::cli_opts::*;
|
|||||||
mod anime_cli;
|
mod anime_cli;
|
||||||
mod aura_cli;
|
mod aura_cli;
|
||||||
mod cli_opts;
|
mod cli_opts;
|
||||||
mod profiles_cli;
|
mod fan_curve_cli;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<String> = args().skip(1).collect();
|
let args: Vec<String> = args().skip(1).collect();
|
||||||
@@ -43,43 +46,42 @@ fn main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Ok((dbus, _)) = RogDbusClientBlocking::new().map_err(|e| {
|
if let Ok((dbus, _)) = RogDbusClientBlocking::new().map_err(|e| {
|
||||||
print_error_help(&e, None);
|
check_service("asusd");
|
||||||
|
println!("\nError: {e}\n");
|
||||||
|
print_info();
|
||||||
}) {
|
}) {
|
||||||
if let Ok(supported) = dbus
|
let supported_properties = dbus.proxies().platform().supported_properties().unwrap();
|
||||||
.proxies()
|
let supported_interfaces = dbus.proxies().platform().supported_interfaces().unwrap();
|
||||||
.supported()
|
|
||||||
.supported_functions()
|
|
||||||
.map_err(|e| {
|
|
||||||
print_error_help(&e, None);
|
|
||||||
})
|
|
||||||
{
|
|
||||||
if parsed.version {
|
|
||||||
println!("asusctl v{}", env!("CARGO_PKG_VERSION"));
|
|
||||||
println!();
|
|
||||||
print_info();
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Err(err) = do_parsed(&parsed, &supported, &dbus) {
|
if parsed.version {
|
||||||
print_error_help(&*err, Some(&supported));
|
println!("asusctl v{}", env!("CARGO_PKG_VERSION"));
|
||||||
}
|
println!();
|
||||||
|
print_info();
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Err(err) = do_parsed(&parsed, &supported_interfaces, &supported_properties, &dbus) {
|
||||||
|
print_error_help(&*err, &supported_interfaces, &supported_properties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_error_help(err: &dyn std::error::Error, supported: Option<&SupportedFunctions>) {
|
fn print_error_help(
|
||||||
|
err: &dyn std::error::Error,
|
||||||
|
supported_interfaces: &[String],
|
||||||
|
supported_properties: &[Properties],
|
||||||
|
) {
|
||||||
check_service("asusd");
|
check_service("asusd");
|
||||||
println!("\nError: {}\n", err);
|
println!("\nError: {}\n", err);
|
||||||
print_info();
|
print_info();
|
||||||
if let Some(supported) = supported {
|
println!();
|
||||||
println!();
|
println!("Supported interfaces:\n\n{:#?}\n", supported_interfaces);
|
||||||
println!("Supported laptop functions:\n\n{}", supported);
|
println!("Supported properties:\n\n{:#?}\n", supported_properties);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_info() {
|
fn print_info() {
|
||||||
let dmi = sysfs_class::DmiId::default();
|
let dmi = DMIID::new().unwrap_or_default();
|
||||||
let board_name = dmi.board_name().expect("Could not get board_name");
|
let board_name = dmi.board_name;
|
||||||
let prod_family = dmi.product_family().expect("Could not get product_family");
|
let prod_family = dmi.product_family;
|
||||||
println!("asusctl version: {}", env!("CARGO_PKG_VERSION"));
|
println!("asusctl version: {}", env!("CARGO_PKG_VERSION"));
|
||||||
println!(" Product family: {}", prod_family.trim());
|
println!(" Product family: {}", prod_family.trim());
|
||||||
println!(" Board name: {}", board_name.trim());
|
println!(" Board name: {}", board_name.trim());
|
||||||
@@ -104,20 +106,21 @@ fn check_service(name: &str) -> bool {
|
|||||||
|
|
||||||
fn do_parsed(
|
fn do_parsed(
|
||||||
parsed: &CliStart,
|
parsed: &CliStart,
|
||||||
supported: &SupportedFunctions,
|
supported_interfaces: &[String],
|
||||||
|
supported_properties: &[Properties],
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
dbus: &RogDbusClientBlocking<'_>,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
match &parsed.command {
|
match &parsed.command {
|
||||||
Some(CliCommand::LedMode(mode)) => handle_led_mode(dbus, &supported.keyboard_led, mode)?,
|
Some(CliCommand::LedMode(mode)) => handle_led_mode(dbus, supported_interfaces, mode)?,
|
||||||
Some(CliCommand::LedPow1(pow)) => handle_led_power1(dbus, &supported.keyboard_led, pow)?,
|
Some(CliCommand::LedPow1(pow)) => handle_led_power1(dbus, supported_interfaces, pow)?,
|
||||||
Some(CliCommand::LedPow2(pow)) => handle_led_power2(dbus, &supported.keyboard_led, pow)?,
|
Some(CliCommand::LedPow2(pow)) => handle_led_power2(dbus, supported_interfaces, pow)?,
|
||||||
Some(CliCommand::Profile(cmd)) => handle_profile(dbus, &supported.platform_profile, cmd)?,
|
Some(CliCommand::Profile(cmd)) => handle_throttle_profile(dbus, supported_properties, cmd)?,
|
||||||
Some(CliCommand::FanCurve(cmd)) => {
|
Some(CliCommand::FanCurve(cmd)) => {
|
||||||
handle_fan_curve(dbus, &supported.platform_profile, cmd)?;
|
handle_fan_curve(dbus, supported_interfaces, cmd)?;
|
||||||
}
|
}
|
||||||
Some(CliCommand::Graphics(_)) => do_gfx(),
|
Some(CliCommand::Graphics(_)) => do_gfx(),
|
||||||
Some(CliCommand::Anime(cmd)) => handle_anime(dbus, &supported.anime_ctrl, cmd)?,
|
Some(CliCommand::Anime(cmd)) => handle_anime(dbus, cmd)?,
|
||||||
Some(CliCommand::Bios(cmd)) => handle_bios_option(dbus, &supported.rog_bios_ctrl, cmd)?,
|
Some(CliCommand::Bios(cmd)) => handle_platform_properties(dbus, supported_properties, cmd)?,
|
||||||
None => {
|
None => {
|
||||||
if (!parsed.show_supported
|
if (!parsed.show_supported
|
||||||
&& parsed.kbd_bright.is_none()
|
&& parsed.kbd_bright.is_none()
|
||||||
@@ -131,19 +134,14 @@ fn do_parsed(
|
|||||||
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().filter(|command| {
|
for command in commands.iter().filter(|command| {
|
||||||
if !matches!(
|
let dev_type = dbus.proxies().aura().device_type().unwrap();
|
||||||
supported.keyboard_led.dev_id,
|
if !dev_type.is_old_style()
|
||||||
AuraDevice::X1854
|
&& !dev_type.is_tuf_style()
|
||||||
| AuraDevice::X1869
|
&& command.trim().starts_with("led-pow-1")
|
||||||
| AuraDevice::X1866
|
|
||||||
| AuraDevice::Tuf
|
|
||||||
) && command.trim().starts_with("led-pow-1")
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if supported.keyboard_led.dev_id != AuraDevice::X19b6
|
if !dev_type.is_new_style() && command.trim().starts_with("led-pow-2") {
|
||||||
&& command.trim().starts_with("led-pow-2")
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
@@ -162,31 +160,34 @@ fn do_parsed(
|
|||||||
if let Some(brightness) = &parsed.kbd_bright {
|
if let Some(brightness) = &parsed.kbd_bright {
|
||||||
match brightness.level() {
|
match brightness.level() {
|
||||||
None => {
|
None => {
|
||||||
let level = dbus.proxies().led().led_brightness()?;
|
let level = dbus.proxies().aura().brightness()?;
|
||||||
println!("Current keyboard led brightness: {}", level);
|
println!("Current keyboard led brightness: {level:?}");
|
||||||
}
|
}
|
||||||
Some(level) => dbus
|
Some(level) => dbus
|
||||||
.proxies()
|
.proxies()
|
||||||
.led()
|
.aura()
|
||||||
.set_brightness(<rog_aura::LedBrightness>::from(level))?,
|
.set_brightness(rog_aura::LedBrightness::from(level))?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if parsed.next_kbd_bright {
|
if parsed.next_kbd_bright {
|
||||||
dbus.proxies().led().next_led_brightness()?;
|
let brightness = dbus.proxies().aura().brightness()?;
|
||||||
|
dbus.proxies().aura().set_brightness(brightness.next())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if parsed.prev_kbd_bright {
|
if parsed.prev_kbd_bright {
|
||||||
dbus.proxies().led().prev_led_brightness()?;
|
let brightness = dbus.proxies().aura().brightness()?;
|
||||||
|
dbus.proxies().aura().set_brightness(brightness.prev())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if parsed.show_supported {
|
// TODO:
|
||||||
println!("Supported laptop functions:\n\n{}", supported);
|
// if parsed.show_supported {
|
||||||
}
|
// println!("Supported laptop functions:\n\n{}", supported);
|
||||||
|
// }
|
||||||
|
|
||||||
if let Some(chg_limit) = parsed.chg_limit {
|
if let Some(chg_limit) = parsed.chg_limit {
|
||||||
dbus.proxies()
|
dbus.proxies()
|
||||||
.charge()
|
.platform()
|
||||||
.set_charge_control_end_threshold(chg_limit)?;
|
.set_charge_control_end_threshold(chg_limit)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,14 +204,16 @@ fn do_gfx() {
|
|||||||
|
|
||||||
fn handle_anime(
|
fn handle_anime(
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
dbus: &RogDbusClientBlocking<'_>,
|
||||||
_supported: &AnimeSupportedFunctions,
|
|
||||||
cmd: &AnimeCommand,
|
cmd: &AnimeCommand,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if (cmd.command.is_none()
|
if (cmd.command.is_none()
|
||||||
&& cmd.enable_display.is_none()
|
&& cmd.enable_display.is_none()
|
||||||
&& cmd.enable_powersave_anim.is_none()
|
&& cmd.enable_powersave_anim.is_none()
|
||||||
&& cmd.brightness.is_none()
|
&& cmd.brightness.is_none()
|
||||||
&& cmd.image_brightness.is_none()
|
&& cmd.off_when_lid_closed.is_none()
|
||||||
|
&& cmd.off_when_suspended.is_none()
|
||||||
|
&& cmd.off_when_unplugged.is_none()
|
||||||
|
&& cmd.off_with_his_head.is_none()
|
||||||
&& !cmd.clear)
|
&& !cmd.clear)
|
||||||
|| cmd.help
|
|| cmd.help
|
||||||
{
|
{
|
||||||
@@ -228,9 +231,17 @@ fn handle_anime(
|
|||||||
if let Some(bright) = cmd.brightness {
|
if let Some(bright) = cmd.brightness {
|
||||||
dbus.proxies().anime().set_brightness(bright)?;
|
dbus.proxies().anime().set_brightness(bright)?;
|
||||||
}
|
}
|
||||||
if let Some(bright) = cmd.image_brightness {
|
if let Some(enable) = cmd.off_when_lid_closed {
|
||||||
verify_brightness(bright);
|
dbus.proxies().anime().set_off_when_lid_closed(enable)?;
|
||||||
dbus.proxies().anime().set_image_brightness(bright)?;
|
}
|
||||||
|
if let Some(enable) = cmd.off_when_suspended {
|
||||||
|
dbus.proxies().anime().set_off_when_suspended(enable)?;
|
||||||
|
}
|
||||||
|
if let Some(enable) = cmd.off_when_unplugged {
|
||||||
|
dbus.proxies().anime().set_off_when_unplugged(enable)?;
|
||||||
|
}
|
||||||
|
if cmd.off_with_his_head.is_some() {
|
||||||
|
println!("Did Alice _really_ make it back from Wonderland?");
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut anime_type = get_anime_type()?;
|
let mut anime_type = get_anime_type()?;
|
||||||
@@ -367,12 +378,14 @@ fn handle_anime(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
dbus.proxies().anime().set_builtin_animations(
|
dbus.proxies()
|
||||||
builtins.boot,
|
.anime()
|
||||||
builtins.awake,
|
.set_builtin_animations(rog_anime::Animations {
|
||||||
builtins.sleep,
|
boot: builtins.boot,
|
||||||
builtins.shutdown,
|
awake: builtins.awake,
|
||||||
)?;
|
sleep: builtins.sleep,
|
||||||
|
shutdown: builtins.shutdown,
|
||||||
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -390,9 +403,14 @@ fn verify_brightness(brightness: f32) {
|
|||||||
|
|
||||||
fn handle_led_mode(
|
fn handle_led_mode(
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
dbus: &RogDbusClientBlocking<'_>,
|
||||||
supported: &LedSupportedFunctions,
|
supported: &[String],
|
||||||
mode: &LedModeCommand,
|
mode: &LedModeCommand,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
if !supported.contains(&AURA_ZBUS_NAME.to_string()) {
|
||||||
|
println!("This laptop does not support power options");
|
||||||
|
return Err(PlatformError::NotSupported.into());
|
||||||
|
}
|
||||||
|
|
||||||
if mode.command.is_none() && !mode.prev_mode && !mode.next_mode {
|
if mode.command.is_none() && !mode.prev_mode && !mode.next_mode {
|
||||||
if !mode.help {
|
if !mode.help {
|
||||||
println!("Missing arg or command\n");
|
println!("Missing arg or command\n");
|
||||||
@@ -403,7 +421,8 @@ fn handle_led_mode(
|
|||||||
if let Some(cmdlist) = LedModeCommand::command_list() {
|
if let Some(cmdlist) = LedModeCommand::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().filter(|command| {
|
for command in commands.iter().filter(|command| {
|
||||||
for mode in &supported.basic_modes {
|
let modes = dbus.proxies().aura().supported_modes().unwrap();
|
||||||
|
for mode in &modes {
|
||||||
if command
|
if command
|
||||||
.trim()
|
.trim()
|
||||||
.starts_with(&<&str>::from(mode).to_lowercase())
|
.starts_with(&<&str>::from(mode).to_lowercase())
|
||||||
@@ -411,9 +430,10 @@ fn handle_led_mode(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !supported.basic_zones.is_empty() && command.trim().starts_with("multi") {
|
// TODO
|
||||||
return true;
|
// if !supported.basic_zones.is_empty() && command.trim().starts_with("multi") {
|
||||||
}
|
// return true;
|
||||||
|
// }
|
||||||
false
|
false
|
||||||
}) {
|
}) {
|
||||||
println!("{}", command);
|
println!("{}", command);
|
||||||
@@ -429,17 +449,31 @@ fn handle_led_mode(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if mode.next_mode {
|
if mode.next_mode {
|
||||||
dbus.proxies().led().next_led_mode()?;
|
let mode = dbus.proxies().aura().led_mode()?;
|
||||||
|
let modes = dbus.proxies().aura().supported_modes()?;
|
||||||
|
let mut pos = modes.iter().position(|m| *m == mode).unwrap() + 1;
|
||||||
|
if pos >= modes.len() {
|
||||||
|
pos = 0;
|
||||||
|
}
|
||||||
|
dbus.proxies().aura().set_led_mode(modes[pos])?;
|
||||||
} else if mode.prev_mode {
|
} else if mode.prev_mode {
|
||||||
dbus.proxies().led().prev_led_mode()?;
|
let mode = dbus.proxies().aura().led_mode()?;
|
||||||
|
let modes = dbus.proxies().aura().supported_modes()?;
|
||||||
|
let mut pos = modes.iter().position(|m| *m == mode).unwrap();
|
||||||
|
if pos == 0 {
|
||||||
|
pos = modes.len() - 1;
|
||||||
|
} else {
|
||||||
|
pos -= 1;
|
||||||
|
}
|
||||||
|
dbus.proxies().aura().set_led_mode(modes[pos])?;
|
||||||
} else if let Some(mode) = mode.command.as_ref() {
|
} else if let Some(mode) = mode.command.as_ref() {
|
||||||
if mode.help_requested() {
|
if mode.help_requested() {
|
||||||
println!("{}", mode.self_usage());
|
println!("{}", mode.self_usage());
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
dbus.proxies()
|
dbus.proxies()
|
||||||
.led()
|
.aura()
|
||||||
.set_led_mode(&<AuraEffect>::from(mode))?;
|
.set_led_mode_data(<AuraEffect>::from(mode))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -447,9 +481,18 @@ fn handle_led_mode(
|
|||||||
|
|
||||||
fn handle_led_power1(
|
fn handle_led_power1(
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
dbus: &RogDbusClientBlocking<'_>,
|
||||||
supported: &LedSupportedFunctions,
|
supported: &[String],
|
||||||
power: &LedPowerCommand1,
|
power: &LedPowerCommand1,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
if !supported.contains(&AURA_ZBUS_NAME.to_string()) {
|
||||||
|
println!("This laptop does not support power options");
|
||||||
|
return Err(PlatformError::NotSupported.into());
|
||||||
|
}
|
||||||
|
let dev_type = dbus.proxies().aura().device_type()?;
|
||||||
|
if !dev_type.is_old_style() && !dev_type.is_tuf_style() {
|
||||||
|
println!("This option applies only to keyboards 2021+");
|
||||||
|
}
|
||||||
|
|
||||||
if power.awake.is_none()
|
if power.awake.is_none()
|
||||||
&& power.sleep.is_none()
|
&& power.sleep.is_none()
|
||||||
&& power.boot.is_none()
|
&& power.boot.is_none()
|
||||||
@@ -463,15 +506,12 @@ fn handle_led_power1(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches!(
|
if dev_type.is_old_style() {
|
||||||
supported.dev_id,
|
|
||||||
AuraDevice::X1854 | AuraDevice::X1869 | AuraDevice::X1866
|
|
||||||
) {
|
|
||||||
handle_led_power_1_do_1866(dbus, power)?;
|
handle_led_power_1_do_1866(dbus, power)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if matches!(supported.dev_id, AuraDevice::Tuf) {
|
if dev_type.is_tuf_style() {
|
||||||
handle_led_power_1_do_tuf(dbus, power)?;
|
handle_led_power_1_do_tuf(dbus, power)?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
@@ -507,13 +547,13 @@ fn handle_led_power_1_do_1866(
|
|||||||
old_rog: enabled,
|
old_rog: enabled,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
dbus.proxies().led().set_led_power(data, true)?;
|
dbus.proxies().aura().set_led_power((data, true))?;
|
||||||
|
|
||||||
let data = AuraPowerDev {
|
let data = AuraPowerDev {
|
||||||
old_rog: disabled,
|
old_rog: disabled,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
dbus.proxies().led().set_led_power(data, false)?;
|
dbus.proxies().aura().set_led_power((data, false))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -544,22 +584,31 @@ fn handle_led_power_1_do_tuf(
|
|||||||
tuf: enabled,
|
tuf: enabled,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
dbus.proxies().led().set_led_power(data, true)?;
|
dbus.proxies().aura().set_led_power((data, true))?;
|
||||||
|
|
||||||
let data = AuraPowerDev {
|
let data = AuraPowerDev {
|
||||||
tuf: disabled,
|
tuf: disabled,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
dbus.proxies().led().set_led_power(data, false)?;
|
dbus.proxies().aura().set_led_power((data, false))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_led_power2(
|
fn handle_led_power2(
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
dbus: &RogDbusClientBlocking<'_>,
|
||||||
supported: &LedSupportedFunctions,
|
supported: &[String],
|
||||||
power: &LedPowerCommand2,
|
power: &LedPowerCommand2,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
if !supported.contains(&AURA_ZBUS_NAME.to_string()) {
|
||||||
|
println!("This laptop does not support power options");
|
||||||
|
return Err(PlatformError::NotSupported.into());
|
||||||
|
}
|
||||||
|
let dev_type = dbus.proxies().aura().device_type()?;
|
||||||
|
if !dev_type.is_new_style() {
|
||||||
|
println!("This option applies only to keyboards 2021+");
|
||||||
|
}
|
||||||
|
|
||||||
if power.command().is_none() {
|
if power.command().is_none() {
|
||||||
if !power.help {
|
if !power.help {
|
||||||
println!("Missing arg or command\n");
|
println!("Missing arg or command\n");
|
||||||
@@ -584,10 +633,6 @@ fn handle_led_power2(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if supported.dev_id != AuraDevice::X19b6 {
|
|
||||||
println!("This option applies only to keyboards with product ID 0x19b6");
|
|
||||||
}
|
|
||||||
|
|
||||||
let set = |power: &mut KbAuraPowerState, set_to: &AuraPowerStates| {
|
let set = |power: &mut KbAuraPowerState, set_to: &AuraPowerStates| {
|
||||||
power.boot = set_to.boot;
|
power.boot = set_to.boot;
|
||||||
power.awake = set_to.awake;
|
power.awake = set_to.awake;
|
||||||
@@ -595,7 +640,7 @@ fn handle_led_power2(
|
|||||||
power.shutdown = set_to.shutdown;
|
power.shutdown = set_to.shutdown;
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut enabled = dbus.proxies().led().led_power()?;
|
let mut enabled = dbus.proxies().aura().led_power()?;
|
||||||
if let Some(cmd) = &power.command {
|
if let Some(cmd) = &power.command {
|
||||||
match cmd {
|
match cmd {
|
||||||
aura_cli::SetAuraZoneEnabled::Keyboard(k) => set(&mut enabled.rog.keyboard, k),
|
aura_cli::SetAuraZoneEnabled::Keyboard(k) => set(&mut enabled.rog.keyboard, k),
|
||||||
@@ -606,18 +651,18 @@ fn handle_led_power2(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbus.proxies().led().set_led_power(enabled, true)?;
|
dbus.proxies().aura().set_led_power((enabled, true))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_profile(
|
fn handle_throttle_profile(
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
dbus: &RogDbusClientBlocking<'_>,
|
||||||
supported: &PlatformProfileFunctions,
|
supported: &[Properties],
|
||||||
cmd: &ProfileCommand,
|
cmd: &ProfileCommand,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if !supported.platform_profile {
|
if !supported.contains(&Properties::DgpuDisable) {
|
||||||
println!("Profiles not supported by either this kernel or by the laptop.");
|
println!("Profiles not supported by either this kernel or by the laptop.");
|
||||||
return Err(ProfileError::NotSupported.into());
|
return Err(ProfileError::NotSupported.into());
|
||||||
}
|
}
|
||||||
@@ -633,23 +678,27 @@ fn handle_profile(
|
|||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
let current = dbus.proxies().platform().throttle_thermal_policy()?;
|
||||||
|
|
||||||
if cmd.next {
|
if cmd.next {
|
||||||
dbus.proxies().profile().next_profile()?;
|
dbus.proxies()
|
||||||
|
.platform()
|
||||||
|
.set_throttle_thermal_policy(current.next())?;
|
||||||
} else if let Some(profile) = cmd.profile_set {
|
} else if let Some(profile) = cmd.profile_set {
|
||||||
dbus.proxies().profile().set_active_profile(profile)?;
|
dbus.proxies()
|
||||||
|
.platform()
|
||||||
|
.set_throttle_thermal_policy(profile)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.list {
|
if cmd.list {
|
||||||
let res = dbus.proxies().profile().profiles()?;
|
let res = PlatformPolicy::list();
|
||||||
for p in &res {
|
for p in &res {
|
||||||
println!("{:?}", p);
|
println!("{:?}", p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.profile_get {
|
if cmd.profile_get {
|
||||||
let res = dbus.proxies().profile().active_profile()?;
|
println!("Active profile is {current:?}");
|
||||||
println!("Active profile is {:?}", res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -657,12 +706,11 @@ fn handle_profile(
|
|||||||
|
|
||||||
fn handle_fan_curve(
|
fn handle_fan_curve(
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
dbus: &RogDbusClientBlocking<'_>,
|
||||||
supported: &PlatformProfileFunctions,
|
supported: &[String],
|
||||||
cmd: &FanCurveCommand,
|
cmd: &FanCurveCommand,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
if supported.fans.is_empty() {
|
if !supported.contains(&FAN_CURVE_ZBUS_NAME.to_string()) {
|
||||||
println!("Fan-curves not supported by either this kernel or by the laptop.");
|
println!("Fan-curves not supported by either this kernel or by the laptop.");
|
||||||
println!("This requires kernel 5.17 or the fan curve patch listed in the readme.");
|
|
||||||
return Err(ProfileError::NotSupported.into());
|
return Err(ProfileError::NotSupported.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -689,34 +737,34 @@ fn handle_fan_curve(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if cmd.get_enabled {
|
if cmd.get_enabled {
|
||||||
let profile = dbus.proxies().profile().active_profile()?;
|
let profile = dbus.proxies().platform().throttle_thermal_policy()?;
|
||||||
let curves = dbus.proxies().profile().fan_curve_data(profile)?;
|
let curves = dbus.proxies().fan_curves().fan_curve_data(profile)?;
|
||||||
for curve in curves.iter() {
|
for curve in curves.iter() {
|
||||||
println!("{}", String::from(curve));
|
println!("{}", String::from(curve));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmd.default {
|
if cmd.default {
|
||||||
dbus.proxies().profile().set_active_curve_to_defaults()?;
|
dbus.proxies().fan_curves().set_active_curve_to_defaults()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(profile) = cmd.mod_profile {
|
if let Some(profile) = cmd.mod_profile {
|
||||||
if cmd.enable_fan_curves.is_none() && cmd.data.is_none() {
|
if cmd.enable_fan_curves.is_none() && cmd.data.is_none() {
|
||||||
let data = dbus.proxies().profile().fan_curve_data(profile)?;
|
let data = dbus.proxies().fan_curves().fan_curve_data(profile)?;
|
||||||
let data = toml::to_string(&data)?;
|
let data = toml::to_string(&data)?;
|
||||||
println!("\nFan curves for {:?}\n\n{}", profile, data);
|
println!("\nFan curves for {:?}\n\n{}", profile, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(enabled) = cmd.enable_fan_curves {
|
if let Some(enabled) = cmd.enable_fan_curves {
|
||||||
dbus.proxies()
|
dbus.proxies()
|
||||||
.profile()
|
.fan_curves()
|
||||||
.set_fan_curves_enabled(profile, enabled)?;
|
.set_fan_curves_enabled(profile, enabled)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(enabled) = cmd.enable_fan_curve {
|
if let Some(enabled) = cmd.enable_fan_curve {
|
||||||
if let Some(fan) = cmd.fan {
|
if let Some(fan) = cmd.fan {
|
||||||
dbus.proxies()
|
dbus.proxies()
|
||||||
.profile()
|
.fan_curves()
|
||||||
.set_profile_fan_curve_enabled(profile, fan, enabled)?;
|
.set_profile_fan_curve_enabled(profile, fan, enabled)?;
|
||||||
} else {
|
} else {
|
||||||
println!(
|
println!(
|
||||||
@@ -729,16 +777,16 @@ fn handle_fan_curve(
|
|||||||
if let Some(mut curve) = cmd.data.clone() {
|
if let Some(mut curve) = cmd.data.clone() {
|
||||||
let fan = cmd.fan.unwrap_or_default();
|
let fan = cmd.fan.unwrap_or_default();
|
||||||
curve.set_fan(fan);
|
curve.set_fan(fan);
|
||||||
dbus.proxies().profile().set_fan_curve(profile, curve)?;
|
dbus.proxies().fan_curves().set_fan_curve(profile, curve)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_bios_option(
|
fn handle_platform_properties(
|
||||||
dbus: &RogDbusClientBlocking<'_>,
|
dbus: &RogDbusClientBlocking<'_>,
|
||||||
supported: &RogBiosSupportedFunctions,
|
supported: &[Properties],
|
||||||
cmd: &BiosCommand,
|
cmd: &BiosCommand,
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
{
|
{
|
||||||
@@ -755,26 +803,26 @@ fn handle_bios_option(
|
|||||||
let usage: Vec<String> = BiosCommand::usage().lines().map(|s| s.to_owned()).collect();
|
let usage: Vec<String> = BiosCommand::usage().lines().map(|s| s.to_owned()).collect();
|
||||||
|
|
||||||
for line in usage.iter().filter(|line| {
|
for line in usage.iter().filter(|line| {
|
||||||
line.contains("sound") && supported.post_sound
|
line.contains("sound") && supported.contains(&Properties::PostAnimationSound)
|
||||||
|| line.contains("GPU") && supported.gpu_mux
|
|| line.contains("GPU") && supported.contains(&Properties::GpuMuxMode)
|
||||||
|| line.contains("panel") && supported.panel_overdrive
|
|| line.contains("panel") && supported.contains(&Properties::PanelOd)
|
||||||
}) {
|
}) {
|
||||||
println!("{}", line);
|
println!("{}", line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(opt) = cmd.post_sound_set {
|
if let Some(opt) = cmd.post_sound_set {
|
||||||
dbus.proxies().rog_bios().set_post_boot_sound(opt)?;
|
dbus.proxies().platform().set_post_animation_sound(opt)?;
|
||||||
}
|
}
|
||||||
if cmd.post_sound_get {
|
if cmd.post_sound_get {
|
||||||
let res = dbus.proxies().rog_bios().post_boot_sound()? == 1;
|
let res = dbus.proxies().platform().post_animation_sound()?;
|
||||||
println!("Bios POST sound on: {}", res);
|
println!("Bios POST sound on: {}", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(opt) = cmd.gpu_mux_mode_set {
|
if let Some(opt) = cmd.gpu_mux_mode_set {
|
||||||
println!("Rebuilding initrd to include drivers");
|
println!("Rebuilding initrd to include drivers");
|
||||||
dbus.proxies()
|
dbus.proxies()
|
||||||
.rog_bios()
|
.platform()
|
||||||
.set_gpu_mux_mode(GpuMode::from_mux(opt))?;
|
.set_gpu_mux_mode(GpuMode::from_mux(opt))?;
|
||||||
println!(
|
println!(
|
||||||
"The mode change is not active until you reboot, on boot the bios will make the \
|
"The mode change is not active until you reboot, on boot the bios will make the \
|
||||||
@@ -782,15 +830,15 @@ fn handle_bios_option(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if cmd.gpu_mux_mode_get {
|
if cmd.gpu_mux_mode_get {
|
||||||
let res = dbus.proxies().rog_bios().gpu_mux_mode()?;
|
let res = dbus.proxies().platform().gpu_mux_mode()?;
|
||||||
println!("Bios GPU MUX: {:?}", res);
|
println!("Bios GPU MUX: {:?}", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(opt) = cmd.panel_overdrive_set {
|
if let Some(opt) = cmd.panel_overdrive_set {
|
||||||
dbus.proxies().rog_bios().set_panel_od(opt)?;
|
dbus.proxies().platform().set_panel_od(opt)?;
|
||||||
}
|
}
|
||||||
if cmd.panel_overdrive_get {
|
if cmd.panel_overdrive_get {
|
||||||
let res = dbus.proxies().rog_bios().panel_od()?;
|
let res = dbus.proxies().platform().panel_od()?;
|
||||||
println!("Panel overdrive on: {}", res);
|
println!("Panel overdrive on: {}", res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,11 @@ use std::sync::{Arc, Mutex};
|
|||||||
|
|
||||||
use asusd_user::config::*;
|
use asusd_user::config::*;
|
||||||
use asusd_user::ctrl_anime::{CtrlAnime, CtrlAnimeInner};
|
use asusd_user::ctrl_anime::{CtrlAnime, CtrlAnimeInner};
|
||||||
use asusd_user::DBUS_NAME;
|
|
||||||
use config_traits::{StdConfig, StdConfigLoad};
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
use rog_anime::usb::get_anime_type;
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_aura::aura_detection::LaptopLedData;
|
use rog_aura::aura_detection::LaptopLedData;
|
||||||
use rog_aura::layouts::KeyLayout;
|
use rog_aura::layouts::KeyLayout;
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::{RogDbusClientBlocking, DBUS_NAME};
|
||||||
use smol::Executor;
|
use smol::Executor;
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
|
|
||||||
@@ -34,15 +33,18 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
println!("rog-platform v{}", rog_platform::VERSION);
|
println!("rog-platform v{}", rog_platform::VERSION);
|
||||||
|
|
||||||
let (client, _) = RogDbusClientBlocking::new()?;
|
let (client, _) = RogDbusClientBlocking::new()?;
|
||||||
let supported = client.proxies().supported().supported_functions()?;
|
let supported = client
|
||||||
|
.proxies()
|
||||||
|
.platform()
|
||||||
|
.supported_interfaces()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.contains(&"Anime".to_string());
|
||||||
let config = ConfigBase::new().load();
|
let config = ConfigBase::new().load();
|
||||||
|
|
||||||
let executor = Executor::new();
|
let executor = Executor::new();
|
||||||
|
|
||||||
let early_return = Arc::new(AtomicBool::new(false));
|
let early_return = Arc::new(AtomicBool::new(false));
|
||||||
// Set up the anime data and run loop/thread
|
// Set up the anime data and run loop/thread
|
||||||
if supported.anime_ctrl.0 {
|
if supported {
|
||||||
if let Some(cfg) = config.active_anime {
|
if let Some(cfg) = config.active_anime {
|
||||||
let anime_type = get_anime_type()?;
|
let anime_type = get_anime_type()?;
|
||||||
let anime_config = ConfigAnime::new().set_name(cfg).load();
|
let anime_config = ConfigAnime::new().set_name(cfg).load();
|
||||||
@@ -100,7 +102,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
client
|
client
|
||||||
.proxies()
|
.proxies()
|
||||||
.led()
|
.aura()
|
||||||
.direct_addressing_raw(packets)
|
.direct_addressing_raw(packets)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
std::thread::sleep(std::time::Duration::from_millis(33));
|
std::thread::sleep(std::time::Duration::from_millis(33));
|
||||||
|
|||||||
@@ -6,6 +6,4 @@ pub mod ctrl_anime;
|
|||||||
|
|
||||||
pub mod zbus_anime;
|
pub mod zbus_anime;
|
||||||
|
|
||||||
pub static DBUS_NAME: &str = "org.asuslinux.Daemon";
|
|
||||||
|
|
||||||
pub static VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ rog_anime = { path = "../rog-anime", features = ["dbus"] }
|
|||||||
rog_aura = { path = "../rog-aura", features = ["dbus"] }
|
rog_aura = { path = "../rog-aura", features = ["dbus"] }
|
||||||
rog_platform = { path = "../rog-platform" }
|
rog_platform = { path = "../rog-platform" }
|
||||||
rog_profiles = { path = "../rog-profiles" }
|
rog_profiles = { path = "../rog-profiles" }
|
||||||
rog_dbus = { path = "../rog-dbus" }
|
dmi_id = { path = "../dmi-id" }
|
||||||
|
futures-lite = "*"
|
||||||
|
|
||||||
async-trait.workspace = true
|
async-trait.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
@@ -35,9 +36,6 @@ logind-zbus.workspace = true
|
|||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
serde_derive.workspace = true
|
serde_derive.workspace = true
|
||||||
|
|
||||||
# Device control
|
|
||||||
sysfs-class.workspace = true # used for backlight control and baord ID
|
|
||||||
|
|
||||||
concat-idents.workspace = true
|
concat-idents.workspace = true
|
||||||
|
|
||||||
systemd-zbus = "*"
|
systemd-zbus = "*"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use config_traits::{StdConfig, StdConfigLoad2};
|
use config_traits::{StdConfig, StdConfigLoad2};
|
||||||
|
use rog_platform::platform::PlatformPolicy;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
const CONFIG_FILE: &str = "asusd.ron";
|
const CONFIG_FILE: &str = "asusd.ron";
|
||||||
@@ -6,23 +7,37 @@ const CONFIG_FILE: &str = "asusd.ron";
|
|||||||
#[derive(Deserialize, Serialize, Default, Debug)]
|
#[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 charge_control_end_threshold: u8,
|
||||||
pub panel_od: bool,
|
pub panel_od: bool,
|
||||||
pub mini_led_mode: bool,
|
pub mini_led_mode: bool,
|
||||||
pub disable_nvidia_powerd_on_battery: bool,
|
pub disable_nvidia_powerd_on_battery: bool,
|
||||||
pub ac_command: String,
|
pub ac_command: String,
|
||||||
pub bat_command: String,
|
pub bat_command: String,
|
||||||
|
/// Restored on boot as well as when power is plugged
|
||||||
|
#[serde(skip)]
|
||||||
|
pub platform_policy_to_restore: PlatformPolicy,
|
||||||
|
pub platform_policy_on_battery: PlatformPolicy,
|
||||||
|
pub platform_policy_on_ac: PlatformPolicy,
|
||||||
|
//
|
||||||
|
pub ppt_pl1_spl: Option<u8>,
|
||||||
|
pub ppt_pl2_sppt: Option<u8>,
|
||||||
|
pub ppt_fppt: Option<u8>,
|
||||||
|
pub ppt_apu_sppt: Option<u8>,
|
||||||
|
pub ppt_platform_sppt: Option<u8>,
|
||||||
|
pub nv_dynamic_boost: Option<u8>,
|
||||||
|
pub nv_temp_target: Option<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdConfig for Config {
|
impl StdConfig for Config {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Config {
|
Config {
|
||||||
bat_charge_limit: 100,
|
charge_control_end_threshold: 100,
|
||||||
panel_od: false,
|
|
||||||
mini_led_mode: false,
|
|
||||||
disable_nvidia_powerd_on_battery: true,
|
disable_nvidia_powerd_on_battery: true,
|
||||||
|
platform_policy_on_battery: PlatformPolicy::Quiet,
|
||||||
|
platform_policy_on_ac: PlatformPolicy::Performance,
|
||||||
ac_command: String::new(),
|
ac_command: String::new(),
|
||||||
bat_command: String::new(),
|
bat_command: String::new(),
|
||||||
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +50,31 @@ impl StdConfig for Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdConfigLoad2<Config458, Config462> for Config {}
|
impl StdConfigLoad2<Config462, Config472> for Config {}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Default, Debug)]
|
||||||
|
pub struct Config472 {
|
||||||
|
/// Save charge limit for restoring on boot
|
||||||
|
pub bat_charge_limit: u8,
|
||||||
|
pub panel_od: bool,
|
||||||
|
pub mini_led_mode: bool,
|
||||||
|
pub disable_nvidia_powerd_on_battery: bool,
|
||||||
|
pub ac_command: String,
|
||||||
|
pub bat_command: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Config472> for Config {
|
||||||
|
fn from(c: Config472) -> Self {
|
||||||
|
Self {
|
||||||
|
charge_control_end_threshold: c.bat_charge_limit,
|
||||||
|
panel_od: c.panel_od,
|
||||||
|
disable_nvidia_powerd_on_battery: true,
|
||||||
|
ac_command: c.ac_command,
|
||||||
|
bat_command: c.bat_command,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct Config462 {
|
pub struct Config462 {
|
||||||
@@ -50,34 +89,12 @@ pub struct Config462 {
|
|||||||
impl From<Config462> for Config {
|
impl From<Config462> for Config {
|
||||||
fn from(c: Config462) -> Self {
|
fn from(c: Config462) -> Self {
|
||||||
Self {
|
Self {
|
||||||
bat_charge_limit: c.bat_charge_limit,
|
charge_control_end_threshold: c.bat_charge_limit,
|
||||||
panel_od: c.panel_od,
|
panel_od: c.panel_od,
|
||||||
mini_led_mode: false,
|
|
||||||
disable_nvidia_powerd_on_battery: true,
|
disable_nvidia_powerd_on_battery: true,
|
||||||
ac_command: String::new(),
|
ac_command: String::new(),
|
||||||
bat_command: String::new(),
|
bat_command: String::new(),
|
||||||
}
|
..Default::default()
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
|
||||||
pub struct Config458 {
|
|
||||||
/// Save charge limit for restoring on boot
|
|
||||||
pub bat_charge_limit: u8,
|
|
||||||
pub panel_od: bool,
|
|
||||||
pub ac_command: String,
|
|
||||||
pub bat_command: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Config458> for Config {
|
|
||||||
fn from(c: Config458) -> Self {
|
|
||||||
Self {
|
|
||||||
bat_charge_limit: c.bat_charge_limit,
|
|
||||||
panel_od: c.panel_od,
|
|
||||||
mini_led_mode: false,
|
|
||||||
disable_nvidia_powerd_on_battery: true,
|
|
||||||
ac_command: c.ac_command,
|
|
||||||
bat_command: c.bat_command,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ use std::time::Duration;
|
|||||||
use config_traits::{StdConfig, StdConfigLoad2};
|
use config_traits::{StdConfig, StdConfigLoad2};
|
||||||
use rog_anime::error::AnimeError;
|
use rog_anime::error::AnimeError;
|
||||||
use rog_anime::usb::Brightness;
|
use rog_anime::usb::Brightness;
|
||||||
use rog_anime::{ActionData, ActionLoader, AnimTime, Animations, AnimeType, Fade, Vec2};
|
use rog_anime::{
|
||||||
|
ActionData, ActionLoader, AnimTime, Animations, AnimeType, DeviceState, Fade, Vec2,
|
||||||
|
};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
const CONFIG_FILE: &str = "anime.ron";
|
const CONFIG_FILE: &str = "anime.ron";
|
||||||
@@ -24,7 +26,6 @@ impl From<AnimeConfigV460> for AnimeConfig {
|
|||||||
system: c.system,
|
system: c.system,
|
||||||
boot: c.boot,
|
boot: c.boot,
|
||||||
wake: c.wake,
|
wake: c.wake,
|
||||||
sleep: c.sleep,
|
|
||||||
shutdown: c.shutdown,
|
shutdown: c.shutdown,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
@@ -32,25 +33,32 @@ impl From<AnimeConfigV460> for AnimeConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub struct AnimeConfigV5 {
|
pub struct AnimeConfigV472 {
|
||||||
|
pub model_override: Option<AnimeType>,
|
||||||
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 sleep: Vec<ActionLoader>,
|
||||||
pub shutdown: Vec<ActionLoader>,
|
pub shutdown: Vec<ActionLoader>,
|
||||||
pub brightness: f32,
|
pub brightness: f32,
|
||||||
pub awake_enabled: bool,
|
pub display_enabled: bool,
|
||||||
pub boot_anim_enabled: bool,
|
pub display_brightness: Brightness,
|
||||||
|
pub builtin_anims_enabled: bool,
|
||||||
|
pub builtin_anims: Animations,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<AnimeConfigV5> for AnimeConfig {
|
impl From<AnimeConfigV472> for AnimeConfig {
|
||||||
fn from(c: AnimeConfigV5) -> AnimeConfig {
|
fn from(c: AnimeConfigV472) -> AnimeConfig {
|
||||||
AnimeConfig {
|
AnimeConfig {
|
||||||
system: c.system,
|
system: c.system,
|
||||||
boot: c.boot,
|
boot: c.boot,
|
||||||
wake: c.wake,
|
wake: c.wake,
|
||||||
sleep: c.sleep,
|
|
||||||
shutdown: c.shutdown,
|
shutdown: c.shutdown,
|
||||||
|
model_override: c.model_override,
|
||||||
|
display_enabled: c.display_enabled,
|
||||||
|
display_brightness: c.display_brightness,
|
||||||
|
builtin_anims_enabled: c.builtin_anims_enabled,
|
||||||
|
builtin_anims: c.builtin_anims,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,7 +69,6 @@ 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>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,12 +96,6 @@ 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)?);
|
||||||
@@ -111,12 +112,15 @@ 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 display_enabled: bool,
|
pub display_enabled: bool,
|
||||||
pub display_brightness: Brightness,
|
pub display_brightness: Brightness,
|
||||||
pub builtin_anims_enabled: bool,
|
pub builtin_anims_enabled: bool,
|
||||||
|
pub off_when_unplugged: bool,
|
||||||
|
pub off_when_suspended: bool,
|
||||||
|
pub off_when_lid_closed: bool,
|
||||||
|
pub brightness_on_battery: Brightness,
|
||||||
pub builtin_anims: Animations,
|
pub builtin_anims: Animations,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,12 +131,15 @@ 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,
|
||||||
display_enabled: true,
|
display_enabled: true,
|
||||||
display_brightness: Brightness::Med,
|
display_brightness: Brightness::Med,
|
||||||
builtin_anims_enabled: true,
|
builtin_anims_enabled: true,
|
||||||
|
off_when_unplugged: true,
|
||||||
|
off_when_suspended: true,
|
||||||
|
off_when_lid_closed: true,
|
||||||
|
brightness_on_battery: Brightness::Low,
|
||||||
builtin_anims: Animations::default(),
|
builtin_anims: Animations::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,7 +159,22 @@ impl StdConfig for AnimeConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StdConfigLoad2<AnimeConfigV460, AnimeConfigV5> for AnimeConfig {}
|
impl StdConfigLoad2<AnimeConfigV460, AnimeConfigV472> for AnimeConfig {}
|
||||||
|
|
||||||
|
impl From<&AnimeConfig> for DeviceState {
|
||||||
|
fn from(config: &AnimeConfig) -> Self {
|
||||||
|
DeviceState {
|
||||||
|
display_enabled: config.display_enabled,
|
||||||
|
display_brightness: config.display_brightness,
|
||||||
|
builtin_anims_enabled: config.builtin_anims_enabled,
|
||||||
|
builtin_anims: config.builtin_anims,
|
||||||
|
off_when_unplugged: config.off_when_unplugged,
|
||||||
|
off_when_suspended: config.off_when_suspended,
|
||||||
|
off_when_lid_closed: config.off_when_lid_closed,
|
||||||
|
brightness_on_battery: config.brightness_on_battery,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AnimeConfig {
|
impl AnimeConfig {
|
||||||
// fn clamp_config_brightness(mut config: &mut AnimeConfig) {
|
// fn clamp_config_brightness(mut config: &mut AnimeConfig) {
|
||||||
@@ -193,14 +215,6 @@ 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,
|
||||||
@@ -209,7 +223,6 @@ impl AnimeConfig {
|
|||||||
brightness: 1.0,
|
brightness: 1.0,
|
||||||
time: AnimTime::Infinite,
|
time: AnimTime::Infinite,
|
||||||
}],
|
}],
|
||||||
brightness: 1.0,
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,27 +10,16 @@ use std::thread::sleep;
|
|||||||
use ::zbus::export::futures_util::lock::Mutex;
|
use ::zbus::export::futures_util::lock::Mutex;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use rog_anime::error::AnimeError;
|
use rog_anime::error::AnimeError;
|
||||||
use rog_anime::usb::{get_anime_type, pkt_flush, pkt_set_enable_powersave_anim, pkts_for_init};
|
use rog_anime::usb::{
|
||||||
|
get_anime_type, pkt_flush, pkt_set_brightness, pkt_set_enable_display,
|
||||||
|
pkt_set_enable_powersave_anim, pkts_for_init, Brightness,
|
||||||
|
};
|
||||||
use rog_anime::{ActionData, AnimeDataBuffer, AnimePacketType, AnimeType};
|
use rog_anime::{ActionData, AnimeDataBuffer, AnimePacketType, AnimeType};
|
||||||
use rog_platform::hid_raw::HidRaw;
|
use rog_platform::hid_raw::HidRaw;
|
||||||
use rog_platform::supported::AnimeSupportedFunctions;
|
|
||||||
use rog_platform::usb_raw::USBRaw;
|
use rog_platform::usb_raw::USBRaw;
|
||||||
|
|
||||||
use self::config::{AnimeConfig, AnimeConfigCached};
|
use self::config::{AnimeConfig, AnimeConfigCached};
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
use crate::GetSupported;
|
|
||||||
|
|
||||||
impl GetSupported for CtrlAnime {
|
|
||||||
type A = AnimeSupportedFunctions;
|
|
||||||
|
|
||||||
fn get_supported() -> Self::A {
|
|
||||||
if USBRaw::new(0x193b).is_ok() {
|
|
||||||
AnimeSupportedFunctions(true)
|
|
||||||
} else {
|
|
||||||
AnimeSupportedFunctions(HidRaw::new("193b").is_ok())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Node {
|
enum Node {
|
||||||
Usb(USBRaw),
|
Usb(USBRaw),
|
||||||
@@ -50,6 +39,13 @@ impl Node {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_builtins_enabled(&self, enabled: bool, bright: Brightness) -> Result<(), RogError> {
|
||||||
|
self.write_bytes(&pkt_set_enable_powersave_anim(enabled))?;
|
||||||
|
self.write_bytes(&pkt_set_enable_display(enabled))?;
|
||||||
|
self.write_bytes(&pkt_set_brightness(bright))?;
|
||||||
|
self.write_bytes(&pkt_set_enable_powersave_anim(enabled))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CtrlAnime {
|
pub struct CtrlAnime {
|
||||||
@@ -234,6 +230,14 @@ impl CtrlAnime {
|
|||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&pkt_set_enable_powersave_anim(
|
||||||
|
lock.config.builtin_anims_enabled,
|
||||||
|
))
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("rog_anime::run_animation:callback {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
}
|
}
|
||||||
// Loop ended, set the atmonics
|
// Loop ended, set the atmonics
|
||||||
thread_running.store(false, Ordering::SeqCst);
|
thread_running.store(false, Ordering::SeqCst);
|
||||||
@@ -247,7 +251,7 @@ impl CtrlAnime {
|
|||||||
/// global brightness set in config.
|
/// global brightness set in config.
|
||||||
fn write_data_buffer(&self, mut buffer: AnimeDataBuffer) -> Result<(), RogError> {
|
fn write_data_buffer(&self, mut buffer: AnimeDataBuffer) -> Result<(), RogError> {
|
||||||
for led in buffer.data_mut().iter_mut() {
|
for led in buffer.data_mut().iter_mut() {
|
||||||
let mut bright = *led as f32 * self.config.brightness;
|
let mut bright = *led as f32;
|
||||||
if bright > 254.0 {
|
if bright > 254.0 {
|
||||||
bright = 254.0;
|
bright = 254.0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,18 +4,32 @@ use std::sync::Arc;
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use config_traits::StdConfig;
|
use config_traits::StdConfig;
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
use logind_zbus::manager::ManagerProxy;
|
||||||
use rog_anime::usb::{
|
use rog_anime::usb::{
|
||||||
pkt_set_brightness, pkt_set_builtin_animations, pkt_set_enable_display,
|
pkt_set_brightness, pkt_set_builtin_animations, pkt_set_enable_display,
|
||||||
pkt_set_enable_powersave_anim, AnimAwake, AnimBooting, AnimShutdown, AnimSleeping, Brightness,
|
pkt_set_enable_powersave_anim, Brightness,
|
||||||
};
|
};
|
||||||
use rog_anime::{AnimeDataBuffer, DeviceState};
|
use rog_anime::{Animations, AnimeDataBuffer, DeviceState};
|
||||||
use zbus::export::futures_util::lock::Mutex;
|
use zbus::export::futures_util::lock::Mutex;
|
||||||
use zbus::{dbus_interface, Connection, SignalContext};
|
use zbus::{dbus_interface, CacheProperties, Connection, SignalContext};
|
||||||
|
|
||||||
use super::CtrlAnime;
|
use super::CtrlAnime;
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
|
|
||||||
pub(super) const ZBUS_PATH: &str = "/org/asuslinux/Anime";
|
pub const ANIME_ZBUS_NAME: &str = "Anime";
|
||||||
|
pub const ANIME_ZBUS_PATH: &str = "/org/asuslinux/Anime";
|
||||||
|
|
||||||
|
async fn get_logind_manager<'a>() -> ManagerProxy<'a> {
|
||||||
|
let connection = Connection::system()
|
||||||
|
.await
|
||||||
|
.expect("Controller could not create dbus connection");
|
||||||
|
|
||||||
|
ManagerProxy::builder(&connection)
|
||||||
|
.cache_properties(CacheProperties::No)
|
||||||
|
.build()
|
||||||
|
.await
|
||||||
|
.expect("Controller could not create ManagerProxy")
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CtrlAnimeZbus(pub Arc<Mutex<CtrlAnime>>);
|
pub struct CtrlAnimeZbus(pub Arc<Mutex<CtrlAnime>>);
|
||||||
@@ -24,7 +38,7 @@ pub struct CtrlAnimeZbus(pub Arc<Mutex<CtrlAnime>>);
|
|||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl crate::ZbusRun for CtrlAnimeZbus {
|
impl crate::ZbusRun for CtrlAnimeZbus {
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
Self::add_to_server_helper(self, ZBUS_PATH, server).await;
|
Self::add_to_server_helper(self, ANIME_ZBUS_PATH, server).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,156 +53,192 @@ impl CtrlAnimeZbus {
|
|||||||
let lock = self.0.lock().await;
|
let lock = self.0.lock().await;
|
||||||
lock.thread_exit.store(true, Ordering::SeqCst);
|
lock.thread_exit.store(true, Ordering::SeqCst);
|
||||||
lock.write_data_buffer(input).map_err(|err| {
|
lock.write_data_buffer(input).map_err(|err| {
|
||||||
warn!("rog_anime::run_animation:callback {}", err);
|
warn!("ctrl_anime::run_animation:callback {}", err);
|
||||||
err
|
err
|
||||||
})?;
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the global AniMe brightness
|
/// Set base brightness level
|
||||||
async fn set_image_brightness(&self, bright: f32) {
|
#[dbus_interface(property)]
|
||||||
let mut lock = self.0.lock().await;
|
async fn brightness(&self) -> Brightness {
|
||||||
let mut bright = bright;
|
let lock = self.0.lock().await;
|
||||||
if bright < 0.0 {
|
lock.config.display_brightness
|
||||||
bright = 0.0;
|
|
||||||
} else if bright > 1.0 {
|
|
||||||
bright = 1.0;
|
|
||||||
}
|
|
||||||
lock.config.brightness = bright;
|
|
||||||
lock.config.write();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set base brightness level
|
/// Set base brightness level
|
||||||
// TODO: enum for brightness
|
#[dbus_interface(property)]
|
||||||
async fn set_brightness(
|
async fn set_brightness(&self, brightness: Brightness) {
|
||||||
&self,
|
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
||||||
brightness: Brightness,
|
|
||||||
) {
|
|
||||||
let mut lock = self.0.lock().await;
|
let mut lock = self.0.lock().await;
|
||||||
lock.node
|
lock.node
|
||||||
.write_bytes(&pkt_set_brightness(brightness))
|
.write_bytes(&pkt_set_brightness(brightness))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("rog_anime::run_animation:callback {}", err);
|
warn!("ctrl_anime::set_brightness {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&pkt_set_enable_display(brightness != Brightness::Off))
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("ctrl_anime::set_brightness {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
lock.config.display_enabled = brightness != Brightness::Off;
|
||||||
lock.config.display_brightness = brightness;
|
lock.config.display_brightness = brightness;
|
||||||
lock.config.write();
|
lock.config.write();
|
||||||
|
}
|
||||||
|
|
||||||
Self::notify_device_state(
|
#[dbus_interface(property)]
|
||||||
&ctxt,
|
async fn builtins_enabled(&self) -> bool {
|
||||||
DeviceState {
|
let lock = self.0.lock().await;
|
||||||
display_enabled: lock.config.display_enabled,
|
lock.config.builtin_anims_enabled
|
||||||
display_brightness: lock.config.display_brightness,
|
|
||||||
builtin_anims_enabled: lock.config.builtin_anims_enabled,
|
|
||||||
builtin_anims: lock.config.builtin_anims,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enable the builtin animations or not. This is quivalent to "Powersave
|
/// Enable the builtin animations or not. This is quivalent to "Powersave
|
||||||
/// animations" in Armory crate
|
/// animations" in Armory crate
|
||||||
async fn set_builtins_enabled(
|
#[dbus_interface(property)]
|
||||||
&self,
|
async fn set_builtins_enabled(&self, enabled: bool) {
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
||||||
enabled: bool,
|
|
||||||
) {
|
|
||||||
let mut lock = self.0.lock().await;
|
let mut lock = self.0.lock().await;
|
||||||
lock.node
|
lock.node
|
||||||
.write_bytes(&pkt_set_enable_powersave_anim(enabled))
|
.set_builtins_enabled(enabled, lock.config.display_brightness)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("rog_anime::run_animation:callback {}", err);
|
warn!("ctrl_anime::set_builtins_enabled {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
if !enabled {
|
||||||
|
let data = vec![255u8; lock.anime_type.data_length()];
|
||||||
|
if let Ok(tmp) = AnimeDataBuffer::from_vec(lock.anime_type, data).map_err(|err| {
|
||||||
|
warn!("ctrl_anime::set_builtins_enabled {}", err);
|
||||||
|
}) {
|
||||||
|
lock.node
|
||||||
|
.write_bytes(tmp.data())
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("ctrl_anime::set_builtins_enabled {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lock.config.builtin_anims_enabled = enabled;
|
lock.config.builtin_anims_enabled = enabled;
|
||||||
lock.config.write();
|
lock.config.write();
|
||||||
if enabled {
|
if enabled {
|
||||||
lock.thread_exit.store(true, Ordering::Release);
|
lock.thread_exit.store(true, Ordering::Release);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Self::notify_device_state(
|
#[dbus_interface(property)]
|
||||||
&ctxt,
|
async fn builtin_animations(&self) -> Animations {
|
||||||
DeviceState {
|
let lock = self.0.lock().await;
|
||||||
display_enabled: lock.config.display_enabled,
|
lock.config.builtin_anims
|
||||||
display_brightness: lock.config.display_brightness,
|
|
||||||
builtin_anims_enabled: lock.config.builtin_anims_enabled,
|
|
||||||
builtin_anims: lock.config.builtin_anims,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set which builtin animation is used for each stage
|
/// Set which builtin animation is used for each stage
|
||||||
async fn set_builtin_animations(
|
#[dbus_interface(property)]
|
||||||
&self,
|
async fn set_builtin_animations(&self, settings: Animations) {
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
||||||
boot: AnimBooting,
|
|
||||||
awake: AnimAwake,
|
|
||||||
sleep: AnimSleeping,
|
|
||||||
shutdown: AnimShutdown,
|
|
||||||
) {
|
|
||||||
let mut lock = self.0.lock().await;
|
let mut lock = self.0.lock().await;
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&pkt_set_builtin_animations(
|
||||||
|
settings.boot,
|
||||||
|
settings.awake,
|
||||||
|
settings.sleep,
|
||||||
|
settings.shutdown,
|
||||||
|
))
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("ctrl_anime::run_animation:callback {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
lock.node
|
lock.node
|
||||||
.write_bytes(&pkt_set_enable_powersave_anim(true))
|
.write_bytes(&pkt_set_enable_powersave_anim(true))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("rog_anime::run_animation:callback {}", err);
|
warn!("ctrl_anime::run_animation:callback {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
lock.node
|
lock.config.display_enabled = true;
|
||||||
.write_bytes(&pkt_set_builtin_animations(boot, awake, sleep, shutdown))
|
lock.config.builtin_anims = settings;
|
||||||
.map_err(|err| {
|
|
||||||
warn!("rog_anime::run_animation:callback {}", err);
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
lock.config.builtin_anims.boot = boot;
|
|
||||||
lock.config.builtin_anims.sleep = sleep;
|
|
||||||
lock.config.builtin_anims.awake = awake;
|
|
||||||
lock.config.builtin_anims.shutdown = shutdown;
|
|
||||||
lock.config.write();
|
lock.config.write();
|
||||||
|
}
|
||||||
|
|
||||||
Self::notify_device_state(
|
#[dbus_interface(property)]
|
||||||
&ctxt,
|
async fn enable_display(&self) -> bool {
|
||||||
DeviceState {
|
let lock = self.0.lock().await;
|
||||||
display_enabled: lock.config.display_enabled,
|
lock.config.display_enabled
|
||||||
display_brightness: lock.config.display_brightness,
|
|
||||||
builtin_anims_enabled: lock.config.builtin_anims_enabled,
|
|
||||||
builtin_anims: lock.config.builtin_anims,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set whether the AniMe is enabled at all
|
/// Set whether the AniMe is enabled at all
|
||||||
async fn set_enable_display(
|
#[dbus_interface(property)]
|
||||||
&self,
|
async fn set_enable_display(&self, enabled: bool) {
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
||||||
enabled: bool,
|
|
||||||
) {
|
|
||||||
let mut lock = self.0.lock().await;
|
let mut lock = self.0.lock().await;
|
||||||
lock.node
|
lock.node
|
||||||
.write_bytes(&pkt_set_enable_display(enabled))
|
.write_bytes(&pkt_set_enable_display(enabled))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("rog_anime::run_animation:callback {}", err);
|
warn!("ctrl_anime::run_animation:callback {}", err);
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
lock.config.display_enabled = enabled;
|
lock.config.display_enabled = enabled;
|
||||||
lock.config.write();
|
lock.config.write();
|
||||||
|
}
|
||||||
|
|
||||||
Self::notify_device_state(
|
#[dbus_interface(property)]
|
||||||
&ctxt,
|
async fn off_when_unplugged(&self) -> bool {
|
||||||
DeviceState {
|
let lock = self.0.lock().await;
|
||||||
display_enabled: lock.config.display_enabled,
|
lock.config.off_when_unplugged
|
||||||
display_brightness: lock.config.display_brightness,
|
}
|
||||||
builtin_anims_enabled: lock.config.builtin_anims_enabled,
|
|
||||||
builtin_anims: lock.config.builtin_anims,
|
/// Set if to turn the AniMe Matrix off when external power is unplugged
|
||||||
},
|
#[dbus_interface(property)]
|
||||||
)
|
async fn set_off_when_unplugged(&self, enabled: bool) {
|
||||||
.await
|
let mut lock = self.0.lock().await;
|
||||||
.ok();
|
let manager = get_logind_manager().await;
|
||||||
|
let pow = manager.on_external_power().await.unwrap_or_default();
|
||||||
|
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&pkt_set_enable_display(!pow && !enabled))
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("create_sys_event_tasks::off_when_lid_closed {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
lock.config.off_when_unplugged = enabled;
|
||||||
|
lock.config.write();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn off_when_suspended(&self) -> bool {
|
||||||
|
let lock = self.0.lock().await;
|
||||||
|
lock.config.off_when_suspended
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set if to turn the AniMe Matrix off when the laptop is suspended
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_off_when_suspended(&self, enabled: bool) {
|
||||||
|
let mut lock = self.0.lock().await;
|
||||||
|
lock.config.off_when_suspended = enabled;
|
||||||
|
lock.config.write();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn off_when_lid_closed(&self) -> bool {
|
||||||
|
let lock = self.0.lock().await;
|
||||||
|
lock.config.off_when_lid_closed
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set if to turn the AniMe Matrix off when the lid is closed
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_off_when_lid_closed(&self, enabled: bool) {
|
||||||
|
let mut lock = self.0.lock().await;
|
||||||
|
let manager = get_logind_manager().await;
|
||||||
|
let lid = manager.lid_closed().await.unwrap_or_default();
|
||||||
|
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&pkt_set_enable_display(lid && !enabled))
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("create_sys_event_tasks::off_when_lid_closed {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
lock.config.off_when_lid_closed = enabled;
|
||||||
|
lock.config.write();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The main loop is the base system set action if the user isn't running
|
/// The main loop is the base system set action if the user isn't running
|
||||||
@@ -205,24 +255,14 @@ impl CtrlAnimeZbus {
|
|||||||
// #[dbus_interface(property)]
|
// #[dbus_interface(property)]
|
||||||
async fn device_state(&self) -> DeviceState {
|
async fn device_state(&self) -> DeviceState {
|
||||||
let lock = self.0.lock().await;
|
let lock = self.0.lock().await;
|
||||||
DeviceState {
|
DeviceState::from(&lock.config)
|
||||||
display_enabled: lock.config.display_enabled,
|
|
||||||
display_brightness: lock.config.display_brightness,
|
|
||||||
builtin_anims_enabled: lock.config.builtin_anims_enabled,
|
|
||||||
builtin_anims: lock.config.builtin_anims,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Notify listeners of the status of AniMe LED power and factory
|
|
||||||
/// system-status animations
|
|
||||||
#[dbus_interface(signal)]
|
|
||||||
async fn notify_device_state(ctxt: &SignalContext<'_>, data: DeviceState) -> zbus::Result<()>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl crate::CtrlTask for CtrlAnimeZbus {
|
impl crate::CtrlTask for CtrlAnimeZbus {
|
||||||
fn zbus_path() -> &'static str {
|
fn zbus_path() -> &'static str {
|
||||||
ZBUS_PATH
|
ANIME_ZBUS_PATH
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
|
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
|
||||||
@@ -231,36 +271,80 @@ impl crate::CtrlTask for CtrlAnimeZbus {
|
|||||||
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(
|
||||||
move || {
|
move |sleeping| {
|
||||||
// on_sleep
|
// on_sleep
|
||||||
let inner1 = inner1.clone();
|
let inner = inner1.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner1.lock().await;
|
let lock = inner.lock().await;
|
||||||
CtrlAnime::run_thread(inner1.clone(), lock.cache.sleep.clone(), true).await;
|
if lock.config.display_enabled {
|
||||||
|
lock.thread_exit.store(true, Ordering::Release); // ensure clean slate
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&pkt_set_enable_display(
|
||||||
|
!(sleeping && lock.config.off_when_suspended),
|
||||||
|
))
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("create_sys_event_tasks::off_when_suspended {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
if !sleeping && !lock.config.builtin_anims_enabled {
|
||||||
|
CtrlAnime::run_thread(inner.clone(), lock.cache.wake.clone(), true)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || {
|
move |shutting_down| {
|
||||||
// on_wake
|
|
||||||
let inner2 = inner2.clone();
|
|
||||||
async move {
|
|
||||||
let lock = inner2.lock().await;
|
|
||||||
CtrlAnime::run_thread(inner2.clone(), lock.cache.wake.clone(), true).await;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
move || {
|
|
||||||
// on_shutdown
|
// on_shutdown
|
||||||
let inner3 = inner3.clone();
|
let inner = inner2.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner3.lock().await;
|
let lock = inner.lock().await;
|
||||||
CtrlAnime::run_thread(inner3.clone(), lock.cache.shutdown.clone(), true).await;
|
if lock.config.display_enabled && !lock.config.builtin_anims_enabled {
|
||||||
|
if shutting_down {
|
||||||
|
CtrlAnime::run_thread(inner.clone(), lock.cache.shutdown.clone(), true)
|
||||||
|
.await;
|
||||||
|
} else {
|
||||||
|
CtrlAnime::run_thread(inner.clone(), lock.cache.boot.clone(), true)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || {
|
move |lid_closed| {
|
||||||
// on_boot
|
let inner = inner3.clone();
|
||||||
let inner4 = inner4.clone();
|
// on lid change
|
||||||
async move {
|
async move {
|
||||||
let lock = inner4.lock().await;
|
let lock = inner.lock().await;
|
||||||
CtrlAnime::run_thread(inner4.clone(), lock.cache.boot.clone(), true).await;
|
if lock.config.off_when_lid_closed {
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&pkt_set_enable_display(lid_closed))
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("create_sys_event_tasks::off_when_lid_closed {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
move |power_plugged| {
|
||||||
|
let inner = inner4.clone();
|
||||||
|
// on power change
|
||||||
|
async move {
|
||||||
|
let lock = inner.lock().await;
|
||||||
|
if lock.config.off_when_unplugged {
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&pkt_set_enable_display(power_plugged))
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("create_sys_event_tasks::off_when_unplugged {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
} else {
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&pkt_set_brightness(lock.config.brightness_on_battery))
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("create_sys_event_tasks::off_when_unplugged {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -275,25 +359,48 @@ impl crate::Reloadable for CtrlAnimeZbus {
|
|||||||
async fn reload(&mut self) -> Result<(), RogError> {
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
if let Some(lock) = self.0.try_lock() {
|
if let Some(lock) = self.0.try_lock() {
|
||||||
let anim = &lock.config.builtin_anims;
|
let anim = &lock.config.builtin_anims;
|
||||||
lock.node
|
// Set builtins
|
||||||
.write_bytes(&pkt_set_enable_display(lock.config.display_enabled))?;
|
if lock.config.builtin_anims_enabled {
|
||||||
lock.node.write_bytes(&pkt_set_enable_powersave_anim(
|
lock.node.write_bytes(&pkt_set_builtin_animations(
|
||||||
|
anim.boot,
|
||||||
|
anim.awake,
|
||||||
|
anim.sleep,
|
||||||
|
anim.shutdown,
|
||||||
|
))?;
|
||||||
|
}
|
||||||
|
// Builtins enabled or na?
|
||||||
|
lock.node.set_builtins_enabled(
|
||||||
lock.config.builtin_anims_enabled,
|
lock.config.builtin_anims_enabled,
|
||||||
))?;
|
lock.config.display_brightness,
|
||||||
lock.node.write_bytes(&pkt_set_builtin_animations(
|
)?;
|
||||||
anim.boot,
|
|
||||||
anim.awake,
|
|
||||||
anim.sleep,
|
|
||||||
anim.shutdown,
|
|
||||||
))?;
|
|
||||||
|
|
||||||
if lock.config.builtin_anims_enabled && !lock.cache.boot.is_empty() {
|
let manager = get_logind_manager().await;
|
||||||
|
let lid_closed = manager.lid_closed().await.unwrap_or_default();
|
||||||
|
let power_plugged = manager.on_external_power().await.unwrap_or_default();
|
||||||
|
|
||||||
|
let turn_off = (lid_closed && lock.config.off_when_lid_closed)
|
||||||
|
|| (!power_plugged && lock.config.off_when_unplugged);
|
||||||
|
lock.node
|
||||||
|
.write_bytes(&pkt_set_enable_display(!turn_off))
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("create_sys_event_tasks::reload {}", err);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
if turn_off || !lock.config.display_enabled {
|
||||||
|
lock.node.write_bytes(&pkt_set_enable_display(false))?;
|
||||||
|
// early return so we don't run animation thread
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if !lock.config.builtin_anims_enabled && !lock.cache.boot.is_empty() {
|
||||||
lock.node
|
lock.node
|
||||||
.write_bytes(&pkt_set_enable_powersave_anim(false))
|
.write_bytes(&pkt_set_enable_powersave_anim(false))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
|
let action = lock.cache.boot.clone();
|
||||||
|
CtrlAnime::run_thread(self.0.clone(), action, true).await;
|
||||||
}
|
}
|
||||||
let action = lock.cache.boot.clone();
|
|
||||||
CtrlAnime::run_thread(self.0.clone(), action, true).await;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,9 +143,9 @@ impl StdConfigLoad for AuraConfig {}
|
|||||||
impl AuraConfig {
|
impl AuraConfig {
|
||||||
pub fn from_default_support(prod_id: AuraDevice, support_data: &LaptopLedData) -> Self {
|
pub fn from_default_support(prod_id: AuraDevice, support_data: &LaptopLedData) -> Self {
|
||||||
// create a default config here
|
// create a default config here
|
||||||
let enabled = if prod_id == AuraDevice::X19b6 {
|
let enabled = if prod_id.is_new_style() {
|
||||||
AuraPowerConfig::AuraDevRog2(AuraPower::new_all_on())
|
AuraPowerConfig::AuraDevRog2(AuraPower::new_all_on())
|
||||||
} else if prod_id == AuraDevice::Tuf {
|
} else if prod_id.is_tuf_style() {
|
||||||
AuraPowerConfig::AuraDevTuf(HashSet::from([
|
AuraPowerConfig::AuraDevTuf(HashSet::from([
|
||||||
AuraDevTuf::Awake,
|
AuraDevTuf::Awake,
|
||||||
AuraDevTuf::Boot,
|
AuraDevTuf::Boot,
|
||||||
|
|||||||
@@ -1,53 +1,19 @@
|
|||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use config_traits::{StdConfig, StdConfigLoad};
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
|
use dmi_id::DMIID;
|
||||||
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};
|
||||||
use rog_aura::usb::{AuraDevice, LED_APPLY, LED_SET};
|
use rog_aura::usb::{AuraDevice, LED_APPLY, LED_SET};
|
||||||
use rog_aura::{AuraEffect, AuraZone, Direction, LedBrightness, Speed, GRADIENT, LED_MSG_LEN};
|
use rog_aura::{AuraEffect, Direction, LedBrightness, Speed, GRADIENT, LED_MSG_LEN};
|
||||||
use rog_platform::hid_raw::HidRaw;
|
use rog_platform::hid_raw::HidRaw;
|
||||||
use rog_platform::keyboard_led::KeyboardLed;
|
use rog_platform::keyboard_led::KeyboardLed;
|
||||||
use rog_platform::supported::LedSupportedFunctions;
|
|
||||||
|
|
||||||
use super::config::{AuraConfig, AuraPowerConfig};
|
use super::config::{AuraConfig, AuraPowerConfig};
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
use crate::GetSupported;
|
|
||||||
|
|
||||||
impl GetSupported for CtrlKbdLed {
|
#[derive(Debug)]
|
||||||
type A = LedSupportedFunctions;
|
|
||||||
|
|
||||||
fn get_supported() -> Self::A {
|
|
||||||
// let mode = <&str>::from(&<AuraModes>::from(*mode));
|
|
||||||
let laptop = LaptopLedData::get_data();
|
|
||||||
|
|
||||||
let mut prod_id = AuraDevice::Unknown;
|
|
||||||
for prod in ASUS_KEYBOARD_DEVICES {
|
|
||||||
if HidRaw::new(prod.into()).is_ok() {
|
|
||||||
prod_id = prod;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let rgb = KeyboardLed::new();
|
|
||||||
if let Ok(p) = rgb.as_ref() {
|
|
||||||
if p.has_kbd_rgb_mode() {
|
|
||||||
prod_id = AuraDevice::Tuf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LedSupportedFunctions {
|
|
||||||
dev_id: prod_id,
|
|
||||||
brightness: rgb.is_ok(),
|
|
||||||
basic_modes: laptop.basic_modes,
|
|
||||||
basic_zones: laptop.basic_zones,
|
|
||||||
advanced_type: laptop.advanced_type.into(),
|
|
||||||
power_zones: laptop.power_zones,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
|
||||||
pub enum LEDNode {
|
pub enum LEDNode {
|
||||||
KbdLed(KeyboardLed),
|
KbdLed(KeyboardLed),
|
||||||
Rog(HidRaw),
|
Rog(HidRaw),
|
||||||
@@ -58,9 +24,8 @@ 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: AuraDevice,
|
pub led_prod: AuraDevice,
|
||||||
pub led_node: LEDNode,
|
pub led_node: LEDNode,
|
||||||
pub kd_brightness: KeyboardLed,
|
pub sysfs_node: KeyboardLed,
|
||||||
pub supported_modes: LaptopLedData,
|
pub supported_modes: LaptopLedData,
|
||||||
pub flip_effect_write: bool,
|
|
||||||
pub per_key_mode_active: bool,
|
pub per_key_mode_active: bool,
|
||||||
pub config: AuraConfig,
|
pub config: AuraConfig,
|
||||||
}
|
}
|
||||||
@@ -90,14 +55,12 @@ impl CtrlKbdLed {
|
|||||||
let rgb_led = KeyboardLed::new()?;
|
let rgb_led = KeyboardLed::new()?;
|
||||||
|
|
||||||
if usb_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 = DMIID::new().unwrap_or_default();
|
||||||
if let Ok(prod_family) = dmi.product_family() {
|
if dmi.dmi_family.contains("TUF") {
|
||||||
if prod_family.contains("TUF") {
|
warn!(
|
||||||
warn!(
|
"kbd_rgb_mode was not found in the /sys/. You require a minimum 6.1 kernel \
|
||||||
"kbd_rgb_mode was not found in the /sys/. You require a minimum 6.1 \
|
and a supported TUF laptop"
|
||||||
kernel and a supported TUF laptop"
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Err(RogError::NoAuraKeyboard);
|
return Err(RogError::NoAuraKeyboard);
|
||||||
}
|
}
|
||||||
@@ -146,50 +109,15 @@ impl CtrlKbdLed {
|
|||||||
|
|
||||||
let ctrl = CtrlKbdLed {
|
let ctrl = CtrlKbdLed {
|
||||||
led_prod,
|
led_prod,
|
||||||
led_node, // on TUF this is the same as rgb_led / kd_brightness
|
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
|
sysfs_node: rgb_led, // If was none then we already returned above
|
||||||
supported_modes,
|
supported_modes,
|
||||||
flip_effect_write: false,
|
|
||||||
per_key_mode_active: false,
|
per_key_mode_active: false,
|
||||||
config: config_loaded,
|
config: config_loaded,
|
||||||
};
|
};
|
||||||
Ok(ctrl)
|
Ok(ctrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get_brightness(&self) -> Result<u8, RogError> {
|
|
||||||
self.kd_brightness
|
|
||||||
.get_brightness()
|
|
||||||
.map_err(RogError::Platform)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn set_brightness(&self, brightness: LedBrightness) -> Result<(), RogError> {
|
|
||||||
self.kd_brightness
|
|
||||||
.set_brightness(brightness as u8)
|
|
||||||
.map_err(RogError::Platform)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn next_brightness(&mut self) -> Result<(), RogError> {
|
|
||||||
let mut bright = (self.config.brightness as u32) + 1;
|
|
||||||
if bright > 3 {
|
|
||||||
bright = 0;
|
|
||||||
}
|
|
||||||
self.config.brightness = <LedBrightness>::from(bright);
|
|
||||||
self.config.write();
|
|
||||||
self.set_brightness(self.config.brightness)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prev_brightness(&mut self) -> Result<(), RogError> {
|
|
||||||
let mut bright = self.config.brightness as u32;
|
|
||||||
if bright == 0 {
|
|
||||||
bright = 3;
|
|
||||||
} else {
|
|
||||||
bright -= 1;
|
|
||||||
}
|
|
||||||
self.config.brightness = <LedBrightness>::from(bright);
|
|
||||||
self.config.write();
|
|
||||||
self.set_brightness(self.config.brightness)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set combination state for boot animation/sleep animation/all leds/keys
|
/// Set combination state for boot animation/sleep animation/all leds/keys
|
||||||
/// leds/side leds LED active
|
/// leds/side leds LED active
|
||||||
pub(super) fn set_power_states(&mut self) -> Result<(), RogError> {
|
pub(super) fn set_power_states(&mut self) -> Result<(), RogError> {
|
||||||
@@ -210,29 +138,6 @@ impl CtrlKbdLed {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set an Aura effect if the effect mode or zone is supported.
|
|
||||||
///
|
|
||||||
/// On success the aura config file is read to refresh cached values, then
|
|
||||||
/// the effect is stored and config written to disk.
|
|
||||||
pub(crate) fn set_effect(&mut self, effect: AuraEffect) -> Result<(), RogError> {
|
|
||||||
if !self.supported_modes.basic_modes.contains(&effect.mode)
|
|
||||||
|| effect.zone != AuraZone::None
|
|
||||||
&& !self.supported_modes.basic_zones.contains(&effect.zone)
|
|
||||||
{
|
|
||||||
return Err(RogError::AuraEffectNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.write_mode(&effect)?;
|
|
||||||
self.config.read(); // refresh config if successful
|
|
||||||
self.config.set_builtin(effect);
|
|
||||||
if self.config.brightness == LedBrightness::Off {
|
|
||||||
self.config.brightness = LedBrightness::Med;
|
|
||||||
}
|
|
||||||
self.config.write();
|
|
||||||
self.set_brightness(self.config.brightness)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Write an effect block. This is for per-key, but can be repurposed to
|
/// Write an effect block. This is for per-key, but can be repurposed to
|
||||||
/// write the raw factory mode packets - when doing this it is expected that
|
/// write the raw factory mode packets - when doing this it is expected that
|
||||||
/// only the first `Vec` (`effect[0]`) is valid.
|
/// only the first `Vec` (`effect[0]`) is valid.
|
||||||
@@ -272,47 +177,11 @@ impl CtrlKbdLed {
|
|||||||
tuf.set_kbd_rgb_mode(&[0, 0, r, g, b, 0])?;
|
tuf.set_kbd_rgb_mode(&[0, 0, r, g, b, 0])?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.flip_effect_write = !self.flip_effect_write;
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn toggle_mode(&mut self, reverse: bool) -> Result<(), RogError> {
|
pub fn write_mode(&mut self, mode: &AuraEffect) -> Result<(), RogError> {
|
||||||
let current = self.config.current_mode;
|
|
||||||
if let Some(idx) = self
|
|
||||||
.supported_modes
|
|
||||||
.basic_modes
|
|
||||||
.iter()
|
|
||||||
.position(|v| *v == current)
|
|
||||||
{
|
|
||||||
let mut idx = idx;
|
|
||||||
// goes past end of array
|
|
||||||
if reverse {
|
|
||||||
if idx == 0 {
|
|
||||||
idx = self.supported_modes.basic_modes.len() - 1;
|
|
||||||
} else {
|
|
||||||
idx -= 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
idx += 1;
|
|
||||||
if idx == self.supported_modes.basic_modes.len() {
|
|
||||||
idx = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let next = self.supported_modes.basic_modes[idx];
|
|
||||||
|
|
||||||
self.config.read();
|
|
||||||
// if self.config.builtins.contains_key(&next) {
|
|
||||||
self.config.current_mode = next;
|
|
||||||
self.write_current_config_mode()?;
|
|
||||||
// }
|
|
||||||
self.config.write();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_mode(&mut self, mode: &AuraEffect) -> Result<(), RogError> {
|
|
||||||
if let LEDNode::KbdLed(platform) = &self.led_node {
|
if let LEDNode::KbdLed(platform) = &self.led_node {
|
||||||
let buf = [
|
let buf = [
|
||||||
1,
|
1,
|
||||||
@@ -405,82 +274,13 @@ impl CtrlKbdLed {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use rog_aura::aura_detection::{LaptopLedData, PowerZones};
|
use rog_aura::aura_detection::{LaptopLedData, PowerZones};
|
||||||
use rog_aura::usb::AuraDevice;
|
use rog_aura::usb::AuraDevice;
|
||||||
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, Colour};
|
use rog_aura::{AuraModeNum, AuraZone};
|
||||||
use rog_platform::keyboard_led::KeyboardLed;
|
use rog_platform::keyboard_led::KeyboardLed;
|
||||||
|
|
||||||
use super::CtrlKbdLed;
|
use super::CtrlKbdLed;
|
||||||
use crate::ctrl_aura::config::AuraConfig;
|
use crate::ctrl_aura::config::AuraConfig;
|
||||||
use crate::ctrl_aura::controller::LEDNode;
|
use crate::ctrl_aura::controller::LEDNode;
|
||||||
|
|
||||||
#[test]
|
|
||||||
// #[ignore = "Must be manually run due to detection stage"]
|
|
||||||
fn check_set_mode_errors() {
|
|
||||||
// Checking to ensure set_mode errors when unsupported modes are tried
|
|
||||||
let config = AuraConfig::from_default_support(AuraDevice::X19b6, &LaptopLedData::default());
|
|
||||||
let supported_modes = LaptopLedData {
|
|
||||||
board_name: String::new(),
|
|
||||||
layout_name: "ga401".to_owned(),
|
|
||||||
basic_modes: vec![AuraModeNum::Static],
|
|
||||||
basic_zones: vec![],
|
|
||||||
advanced_type: rog_aura::AdvancedAuraType::None,
|
|
||||||
power_zones: vec![PowerZones::Keyboard, PowerZones::RearGlow],
|
|
||||||
};
|
|
||||||
let mut controller = CtrlKbdLed {
|
|
||||||
led_prod: AuraDevice::X19b6,
|
|
||||||
led_node: LEDNode::None,
|
|
||||||
kd_brightness: KeyboardLed::default(),
|
|
||||||
supported_modes,
|
|
||||||
flip_effect_write: false,
|
|
||||||
per_key_mode_active: false,
|
|
||||||
config,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut effect = AuraEffect {
|
|
||||||
colour1: Colour {
|
|
||||||
r: 0xff,
|
|
||||||
g: 0x00,
|
|
||||||
b: 0xff,
|
|
||||||
},
|
|
||||||
zone: AuraZone::None,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
// This error comes from write_bytes because we don't have a keyboard node
|
|
||||||
// stored
|
|
||||||
assert_eq!(
|
|
||||||
controller
|
|
||||||
.set_effect(effect.clone())
|
|
||||||
.unwrap_err()
|
|
||||||
.to_string(),
|
|
||||||
"No supported Aura keyboard"
|
|
||||||
);
|
|
||||||
|
|
||||||
effect.mode = AuraModeNum::Laser;
|
|
||||||
assert_eq!(
|
|
||||||
controller
|
|
||||||
.set_effect(effect.clone())
|
|
||||||
.unwrap_err()
|
|
||||||
.to_string(),
|
|
||||||
"Aura effect not supported"
|
|
||||||
);
|
|
||||||
|
|
||||||
effect.mode = AuraModeNum::Static;
|
|
||||||
effect.zone = AuraZone::Key2;
|
|
||||||
assert_eq!(
|
|
||||||
controller
|
|
||||||
.set_effect(effect.clone())
|
|
||||||
.unwrap_err()
|
|
||||||
.to_string(),
|
|
||||||
"Aura effect not supported"
|
|
||||||
);
|
|
||||||
|
|
||||||
controller.supported_modes.basic_zones.push(AuraZone::Key2);
|
|
||||||
assert_eq!(
|
|
||||||
controller.set_effect(effect).unwrap_err().to_string(),
|
|
||||||
"No supported Aura keyboard"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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
|
||||||
@@ -496,9 +296,8 @@ mod tests {
|
|||||||
let mut controller = CtrlKbdLed {
|
let mut controller = CtrlKbdLed {
|
||||||
led_prod: AuraDevice::X19b6,
|
led_prod: AuraDevice::X19b6,
|
||||||
led_node: LEDNode::None,
|
led_node: LEDNode::None,
|
||||||
kd_brightness: KeyboardLed::default(),
|
sysfs_node: KeyboardLed::default(),
|
||||||
supported_modes,
|
supported_modes,
|
||||||
flip_effect_write: false,
|
|
||||||
per_key_mode_active: false,
|
per_key_mode_active: false,
|
||||||
config,
|
config,
|
||||||
};
|
};
|
||||||
@@ -535,9 +334,8 @@ mod tests {
|
|||||||
let mut controller = CtrlKbdLed {
|
let mut controller = CtrlKbdLed {
|
||||||
led_prod: AuraDevice::X19b6,
|
led_prod: AuraDevice::X19b6,
|
||||||
led_node: LEDNode::None,
|
led_node: LEDNode::None,
|
||||||
kd_brightness: KeyboardLed::default(),
|
sysfs_node: KeyboardLed::default(),
|
||||||
supported_modes,
|
supported_modes,
|
||||||
flip_effect_write: false,
|
|
||||||
per_key_mode_active: false,
|
per_key_mode_active: false,
|
||||||
config,
|
config,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,34 +6,36 @@ use config_traits::StdConfig;
|
|||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use rog_aura::advanced::UsbPackets;
|
use rog_aura::advanced::UsbPackets;
|
||||||
use rog_aura::usb::{AuraDevice, AuraPowerDev};
|
use rog_aura::usb::{AuraDevice, AuraPowerDev};
|
||||||
use rog_aura::{AuraEffect, AuraModeNum, LedBrightness};
|
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, LedBrightness};
|
||||||
use zbus::export::futures_util::lock::{Mutex, MutexGuard};
|
use zbus::export::futures_util::lock::{Mutex, MutexGuard};
|
||||||
use zbus::export::futures_util::StreamExt;
|
use zbus::export::futures_util::StreamExt;
|
||||||
|
use zbus::fdo::Error as ZbErr;
|
||||||
use zbus::{dbus_interface, Connection, SignalContext};
|
use zbus::{dbus_interface, Connection, SignalContext};
|
||||||
|
|
||||||
use super::controller::CtrlKbdLed;
|
use super::controller::CtrlKbdLed;
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
use crate::CtrlTask;
|
use crate::CtrlTask;
|
||||||
|
|
||||||
pub(super) const ZBUS_PATH: &str = "/org/asuslinux/Aura";
|
pub const AURA_ZBUS_NAME: &str = "Aura";
|
||||||
|
pub const AURA_ZBUS_PATH: &str = "/org/asuslinux/Aura";
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CtrlKbdLedZbus(pub Arc<Mutex<CtrlKbdLed>>);
|
pub struct CtrlAuraZbus(pub Arc<Mutex<CtrlKbdLed>>);
|
||||||
|
|
||||||
impl CtrlKbdLedZbus {
|
impl CtrlAuraZbus {
|
||||||
fn update_config(lock: &mut CtrlKbdLed) -> Result<(), RogError> {
|
fn update_config(lock: &mut CtrlKbdLed) -> Result<(), RogError> {
|
||||||
let bright = lock.kd_brightness.get_brightness()?;
|
let bright = lock.sysfs_node.get_brightness()?;
|
||||||
lock.config.read();
|
lock.config.read();
|
||||||
lock.config.brightness = (bright as u32).into();
|
lock.config.brightness = bright.into();
|
||||||
lock.config.write();
|
lock.config.write();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl crate::ZbusRun for CtrlKbdLedZbus {
|
impl crate::ZbusRun for CtrlAuraZbus {
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
Self::add_to_server_helper(self, ZBUS_PATH, server).await;
|
Self::add_to_server_helper(self, AURA_ZBUS_PATH, server).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,25 +43,130 @@ impl crate::ZbusRun for CtrlKbdLedZbus {
|
|||||||
///
|
///
|
||||||
/// LED commands are split between Brightness, Modes, Per-Key
|
/// LED commands are split between Brightness, Modes, Per-Key
|
||||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||||
impl CtrlKbdLedZbus {
|
impl CtrlAuraZbus {
|
||||||
/// Set the keyboard brightness level (0-3)
|
/// Return the device type for this Aura keyboard
|
||||||
async fn set_brightness(&mut self, brightness: LedBrightness) {
|
#[dbus_interface(property)]
|
||||||
|
async fn device_type(&self) -> AuraDevice {
|
||||||
let ctrl = self.0.lock().await;
|
let ctrl = self.0.lock().await;
|
||||||
ctrl.set_brightness(brightness)
|
ctrl.led_prod
|
||||||
.map_err(|err| warn!("{}", err))
|
}
|
||||||
.ok();
|
|
||||||
|
/// Return the current LED brightness
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn brightness(&self) -> Result<LedBrightness, ZbErr> {
|
||||||
|
let ctrl = self.0.lock().await;
|
||||||
|
Ok(ctrl.sysfs_node.get_brightness().map(|n| n.into())?)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the keyboard brightness level (0-3)
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_brightness(&mut self, brightness: LedBrightness) -> Result<(), ZbErr> {
|
||||||
|
let ctrl = self.0.lock().await;
|
||||||
|
Ok(ctrl.sysfs_node.set_brightness(brightness.into())?)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Total levels of brightness available
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn supported_brightness(&self) -> Vec<LedBrightness> {
|
||||||
|
vec![
|
||||||
|
LedBrightness::Off,
|
||||||
|
LedBrightness::Low,
|
||||||
|
LedBrightness::Med,
|
||||||
|
LedBrightness::High,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The total available modes
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn supported_modes(&self) -> Result<Vec<AuraModeNum>, ZbErr> {
|
||||||
|
let ctrl = self.0.lock().await;
|
||||||
|
Ok(ctrl.config.builtins.keys().cloned().collect())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The current mode data
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn led_mode(&self) -> Result<AuraModeNum, ZbErr> {
|
||||||
|
let ctrl = self.0.lock().await;
|
||||||
|
Ok(ctrl.config.current_mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set an Aura effect if the effect mode or zone is supported.
|
||||||
|
///
|
||||||
|
/// On success the aura config file is read to refresh cached values, then
|
||||||
|
/// the effect is stored and config written to disk.
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_led_mode(&mut self, num: AuraModeNum) -> Result<(), ZbErr> {
|
||||||
|
let mut ctrl = self.0.lock().await;
|
||||||
|
ctrl.config.current_mode = num;
|
||||||
|
ctrl.write_current_config_mode()?;
|
||||||
|
if ctrl.config.brightness == LedBrightness::Off {
|
||||||
|
ctrl.config.brightness = LedBrightness::Med;
|
||||||
|
}
|
||||||
|
ctrl.sysfs_node
|
||||||
|
.set_brightness(ctrl.config.brightness.into())?;
|
||||||
|
ctrl.config.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The current mode data
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn led_mode_data(&self) -> Result<AuraEffect, ZbErr> {
|
||||||
|
let ctrl = self.0.lock().await;
|
||||||
|
let mode = ctrl.config.current_mode;
|
||||||
|
match ctrl.config.builtins.get(&mode) {
|
||||||
|
Some(effect) => Ok(effect.clone()),
|
||||||
|
None => Err(ZbErr::Failed("Could not get the current effect".into())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set an Aura effect if the effect mode or zone is supported.
|
||||||
|
///
|
||||||
|
/// On success the aura config file is read to refresh cached values, then
|
||||||
|
/// the effect is stored and config written to disk.
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_led_mode_data(&mut self, effect: AuraEffect) -> Result<(), ZbErr> {
|
||||||
|
let mut ctrl = self.0.lock().await;
|
||||||
|
if !ctrl.supported_modes.basic_modes.contains(&effect.mode)
|
||||||
|
|| effect.zone != AuraZone::None
|
||||||
|
&& !ctrl.supported_modes.basic_zones.contains(&effect.zone)
|
||||||
|
{
|
||||||
|
return Err(ZbErr::NotSupported(format!(
|
||||||
|
"The Aura effect is not supported: {effect:?}"
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
ctrl.write_mode(&effect)?;
|
||||||
|
if ctrl.config.brightness == LedBrightness::Off {
|
||||||
|
ctrl.config.brightness = LedBrightness::Med;
|
||||||
|
}
|
||||||
|
ctrl.sysfs_node
|
||||||
|
.set_brightness(ctrl.config.brightness.into())?;
|
||||||
|
ctrl.config.set_builtin(effect);
|
||||||
|
ctrl.config.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the data set for every mode available
|
||||||
|
async fn all_mode_data(&self) -> BTreeMap<AuraModeNum, AuraEffect> {
|
||||||
|
let ctrl = self.0.lock().await;
|
||||||
|
ctrl.config.builtins.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
// As property doesn't work for AuraPowerDev (complexity of serialization?)
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn led_power(&self) -> AuraPowerDev {
|
||||||
|
let ctrl = self.0.lock().await;
|
||||||
|
AuraPowerDev::from(&ctrl.config.enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a variety of states, input is array of enum.
|
/// Set a variety of states, input is array of enum.
|
||||||
/// `enabled` sets if the sent array should be disabled or enabled
|
/// `enabled` sets if the sent array should be disabled or enabled
|
||||||
///
|
///
|
||||||
/// For Modern ROG devices the "enabled" flag is ignored.
|
/// For Modern ROG devices the "enabled" flag is ignored.
|
||||||
async fn set_led_power(
|
#[dbus_interface(property)]
|
||||||
&mut self,
|
async fn set_led_power(&mut self, options: (AuraPowerDev, bool)) -> Result<(), ZbErr> {
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
let enabled = options.1;
|
||||||
options: AuraPowerDev,
|
let options = options.0;
|
||||||
enabled: bool,
|
|
||||||
) -> zbus::fdo::Result<()> {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
let mut ctrl = self.0.lock().await;
|
||||||
for p in options.tuf {
|
for p in options.tuf {
|
||||||
ctrl.config.enabled.set_tuf(p, enabled);
|
ctrl.config.enabled.set_tuf(p, enabled);
|
||||||
@@ -68,158 +175,27 @@ impl CtrlKbdLedZbus {
|
|||||||
ctrl.config.enabled.set_0x1866(p, enabled);
|
ctrl.config.enabled.set_0x1866(p, enabled);
|
||||||
}
|
}
|
||||||
ctrl.config.enabled.set_0x19b6(options.rog);
|
ctrl.config.enabled.set_0x19b6(options.rog);
|
||||||
|
|
||||||
ctrl.config.write();
|
ctrl.config.write();
|
||||||
|
Ok(ctrl.set_power_states().map_err(|e| {
|
||||||
ctrl.set_power_states().map_err(|e| {
|
|
||||||
warn!("{}", e);
|
warn!("{}", e);
|
||||||
e
|
e
|
||||||
})?;
|
})?)
|
||||||
|
|
||||||
Self::notify_power_states(&ctxt, &AuraPowerDev::from(&ctrl.config.enabled))
|
|
||||||
.await
|
|
||||||
.unwrap_or_else(|err| warn!("{}", err));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn set_led_mode(
|
|
||||||
&mut self,
|
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
||||||
effect: AuraEffect,
|
|
||||||
) -> zbus::fdo::Result<()> {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
|
|
||||||
ctrl.set_effect(effect).map_err(|e| {
|
|
||||||
warn!("{}", e);
|
|
||||||
e
|
|
||||||
})?;
|
|
||||||
|
|
||||||
ctrl.set_brightness(ctrl.config.brightness).map_err(|e| {
|
|
||||||
warn!("{}", e);
|
|
||||||
e
|
|
||||||
})?;
|
|
||||||
|
|
||||||
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
|
||||||
Self::notify_led(&ctxt, mode.clone())
|
|
||||||
.await
|
|
||||||
.unwrap_or_else(|err| warn!("{}", err));
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn next_led_mode(
|
|
||||||
&self,
|
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
||||||
) -> zbus::fdo::Result<()> {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
|
|
||||||
ctrl.toggle_mode(false).map_err(|e| {
|
|
||||||
warn!("{}", e);
|
|
||||||
e
|
|
||||||
})?;
|
|
||||||
|
|
||||||
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
|
||||||
Self::notify_led(&ctxt, mode.clone())
|
|
||||||
.await
|
|
||||||
.unwrap_or_else(|err| warn!("{}", err));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn prev_led_mode(
|
|
||||||
&self,
|
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
||||||
) -> zbus::fdo::Result<()> {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
|
|
||||||
ctrl.toggle_mode(true).map_err(|e| {
|
|
||||||
warn!("{}", e);
|
|
||||||
e
|
|
||||||
})?;
|
|
||||||
|
|
||||||
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
|
||||||
Self::notify_led(&ctxt, mode.clone())
|
|
||||||
.await
|
|
||||||
.unwrap_or_else(|err| warn!("{}", err));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn next_led_brightness(&self) -> zbus::fdo::Result<()> {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
ctrl.next_brightness().map_err(|e| {
|
|
||||||
warn!("{}", e);
|
|
||||||
e
|
|
||||||
})?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn prev_led_brightness(&self) -> zbus::fdo::Result<()> {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
ctrl.prev_brightness().map_err(|e| {
|
|
||||||
warn!("{}", e);
|
|
||||||
e
|
|
||||||
})?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the device type for this Aura keyboard
|
|
||||||
async fn device_type(&self) -> AuraDevice {
|
|
||||||
let ctrl = self.0.lock().await;
|
|
||||||
ctrl.led_prod
|
|
||||||
}
|
|
||||||
|
|
||||||
// As property doesn't work for AuraPowerDev (complexity of serialization?)
|
|
||||||
// #[dbus_interface(property)]
|
|
||||||
async fn led_power(&self) -> AuraPowerDev {
|
|
||||||
let ctrl = self.0.lock().await;
|
|
||||||
AuraPowerDev::from(&ctrl.config.enabled)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the current mode data
|
|
||||||
async fn led_mode(&self) -> AuraModeNum {
|
|
||||||
let ctrl = self.0.lock().await;
|
|
||||||
ctrl.config.current_mode
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return a list of available modes
|
|
||||||
async fn led_modes(&self) -> BTreeMap<AuraModeNum, AuraEffect> {
|
|
||||||
let ctrl = self.0.lock().await;
|
|
||||||
ctrl.config.builtins.clone()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// On machine that have some form of either per-key keyboard or per-zone
|
/// On machine that have some form of either per-key keyboard or per-zone
|
||||||
/// this can be used to write custom effects over dbus. The input is a
|
/// this can be used to write custom effects over dbus. The input is a
|
||||||
/// nested `Vec<Vec<8>>` where `Vec<u8>` is a raw USB packet
|
/// nested `Vec<Vec<8>>` where `Vec<u8>` is a raw USB packet
|
||||||
async fn direct_addressing_raw(&self, data: UsbPackets) -> zbus::fdo::Result<()> {
|
async fn direct_addressing_raw(&self, data: UsbPackets) -> Result<(), ZbErr> {
|
||||||
let mut ctrl = self.0.lock().await;
|
let mut ctrl = self.0.lock().await;
|
||||||
ctrl.write_effect_block(&data)?;
|
ctrl.write_effect_block(&data)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the current LED brightness
|
|
||||||
#[dbus_interface(property)]
|
|
||||||
async fn led_brightness(&self) -> i8 {
|
|
||||||
let ctrl = self.0.lock().await;
|
|
||||||
ctrl.get_brightness().map(|n| n as i8).unwrap_or(-1)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[dbus_interface(signal)]
|
|
||||||
async fn notify_led(signal_ctxt: &SignalContext<'_>, data: AuraEffect) -> zbus::Result<()>;
|
|
||||||
|
|
||||||
#[dbus_interface(signal)]
|
|
||||||
async fn notify_power_states(
|
|
||||||
signal_ctxt: &SignalContext<'_>,
|
|
||||||
data: &AuraPowerDev,
|
|
||||||
) -> zbus::Result<()>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl CtrlTask for CtrlKbdLedZbus {
|
impl CtrlTask for CtrlAuraZbus {
|
||||||
fn zbus_path() -> &'static str {
|
fn zbus_path() -> &'static str {
|
||||||
ZBUS_PATH
|
AURA_ZBUS_PATH
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
|
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
|
||||||
@@ -227,7 +203,8 @@ impl CtrlTask for CtrlKbdLedZbus {
|
|||||||
// If waking up
|
// If waking up
|
||||||
if !start {
|
if !start {
|
||||||
info!("CtrlKbdLedTask reloading brightness and modes");
|
info!("CtrlKbdLedTask reloading brightness and modes");
|
||||||
lock.set_brightness(lock.config.brightness)
|
lock.sysfs_node
|
||||||
|
.set_brightness(lock.config.brightness.into())
|
||||||
.map_err(|e| error!("CtrlKbdLedTask: {e}"))
|
.map_err(|e| error!("CtrlKbdLedTask: {e}"))
|
||||||
.ok();
|
.ok();
|
||||||
lock.write_current_config_mode()
|
lock.write_current_config_mode()
|
||||||
@@ -241,46 +218,36 @@ impl CtrlTask for CtrlKbdLedZbus {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let inner1 = self.0.clone();
|
let inner1 = self.0.clone();
|
||||||
let inner2 = self.0.clone();
|
|
||||||
let inner3 = self.0.clone();
|
let inner3 = self.0.clone();
|
||||||
let inner4 = self.0.clone();
|
|
||||||
self.create_sys_event_tasks(
|
self.create_sys_event_tasks(
|
||||||
// Loop so that we do aquire the lock but also don't block other
|
move |sleeping| {
|
||||||
// threads (prevents potential deadlocks)
|
|
||||||
move || {
|
|
||||||
let inner1 = inner1.clone();
|
let inner1 = inner1.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner1.lock().await;
|
let lock = inner1.lock().await;
|
||||||
load_save(true, lock);
|
load_save(sleeping, lock);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || {
|
move |_shutting_down| {
|
||||||
let inner2 = inner2.clone();
|
|
||||||
async move {
|
|
||||||
let lock = inner2.lock().await;
|
|
||||||
load_save(false, lock);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
move || {
|
|
||||||
let inner3 = inner3.clone();
|
let inner3 = inner3.clone();
|
||||||
async move {
|
async move {
|
||||||
let lock = inner3.lock().await;
|
let lock = inner3.lock().await;
|
||||||
load_save(false, lock);
|
load_save(false, lock);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || {
|
move |_lid_closed| {
|
||||||
let inner4 = inner4.clone();
|
// on lid change
|
||||||
async move {
|
async move {}
|
||||||
let lock = inner4.lock().await;
|
},
|
||||||
load_save(false, lock);
|
move |_power_plugged| {
|
||||||
}
|
// power change
|
||||||
|
async move {}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let ctrl2 = self.0.clone();
|
let ctrl2 = self.0.clone();
|
||||||
let ctrl = self.0.lock().await;
|
let ctrl = self.0.lock().await;
|
||||||
let watch = ctrl.kd_brightness.monitor_brightness()?;
|
let watch = ctrl.sysfs_node.monitor_brightness()?;
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut buffer = [0; 32];
|
let mut buffer = [0; 32];
|
||||||
watch
|
watch
|
||||||
@@ -299,7 +266,7 @@ impl CtrlTask for CtrlKbdLedZbus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl crate::Reloadable for CtrlKbdLedZbus {
|
impl crate::Reloadable for CtrlAuraZbus {
|
||||||
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;
|
||||||
debug!("CtrlKbdLedZbus: reloading keyboard mode");
|
debug!("CtrlKbdLedZbus: reloading keyboard mode");
|
||||||
|
|||||||
295
asusd/src/ctrl_fancurves.rs
Normal file
295
asusd/src/ctrl_fancurves.rs
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
use std::path::PathBuf;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use config_traits::{StdConfig, StdConfigLoad};
|
||||||
|
use futures_lite::StreamExt;
|
||||||
|
use log::{debug, error, info, warn};
|
||||||
|
use rog_platform::platform::{PlatformPolicy, RogPlatform};
|
||||||
|
use rog_profiles::error::ProfileError;
|
||||||
|
use rog_profiles::fan_curve_set::CurveData;
|
||||||
|
use rog_profiles::{find_fan_curve_node, FanCurvePU, FanCurveProfiles};
|
||||||
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
use zbus::{dbus_interface, Connection, SignalContext};
|
||||||
|
|
||||||
|
use crate::error::RogError;
|
||||||
|
use crate::{CtrlTask, CONFIG_PATH_BASE};
|
||||||
|
|
||||||
|
const MOD_NAME: &str = "FanCurveZbus";
|
||||||
|
pub const FAN_CURVE_ZBUS_NAME: &str = "FanCurves";
|
||||||
|
pub const FAN_CURVE_ZBUS_PATH: &str = "/org/asuslinux/FanCurves";
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Debug, Default)]
|
||||||
|
pub struct FanCurveConfig {
|
||||||
|
pub balanced: Vec<CurveData>,
|
||||||
|
pub performance: Vec<CurveData>,
|
||||||
|
pub quiet: Vec<CurveData>,
|
||||||
|
#[serde(skip)]
|
||||||
|
pub current: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn file_name(&self) -> String {
|
||||||
|
"fan_curves.ron".to_owned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn config_dir() -> std::path::PathBuf {
|
||||||
|
PathBuf::from(CONFIG_PATH_BASE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl StdConfigLoad for FanCurveConfig {}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct CtrlFanCurveZbus {
|
||||||
|
config: Arc<Mutex<FanCurveConfig>>,
|
||||||
|
fan_curves: Arc<Mutex<FanCurveProfiles>>,
|
||||||
|
platform: RogPlatform,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-zbus-derive impl
|
||||||
|
impl CtrlFanCurveZbus {
|
||||||
|
pub fn new() -> Result<Self, RogError> {
|
||||||
|
let platform = RogPlatform::new()?;
|
||||||
|
if platform.has_throttle_thermal_policy() {
|
||||||
|
info!("{MOD_NAME}: Device has profile control available");
|
||||||
|
find_fan_curve_node()?;
|
||||||
|
info!("{MOD_NAME}: Device has fan curves available");
|
||||||
|
let mut config = FanCurveConfig::new();
|
||||||
|
let mut fan_curves = FanCurveProfiles::default();
|
||||||
|
|
||||||
|
// Only do defaults if the config doesn't already exist
|
||||||
|
if !config.file_path().exists() {
|
||||||
|
info!("{MOD_NAME}: Fetching default fan curves");
|
||||||
|
|
||||||
|
for this in [
|
||||||
|
PlatformPolicy::Balanced,
|
||||||
|
PlatformPolicy::Performance,
|
||||||
|
PlatformPolicy::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.
|
||||||
|
let next = PlatformPolicy::get_next_profile(this);
|
||||||
|
platform.set_throttle_thermal_policy(next.into())?;
|
||||||
|
|
||||||
|
let active = platform
|
||||||
|
.get_throttle_thermal_policy()
|
||||||
|
.map_or(PlatformPolicy::Balanced, |t| t.into());
|
||||||
|
|
||||||
|
info!("{MOD_NAME}: {active:?}:");
|
||||||
|
for curve in fan_curves.get_fan_curves_for(active) {
|
||||||
|
info!("{}", String::from(curve));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config.write();
|
||||||
|
} else {
|
||||||
|
info!("{MOD_NAME}: Fan curves previously stored, loading...");
|
||||||
|
config = config.load();
|
||||||
|
fan_curves.balanced = config.balanced.clone();
|
||||||
|
fan_curves.performance = config.performance.clone();
|
||||||
|
fan_curves.quiet = config.quiet.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(Self {
|
||||||
|
config: Arc::new(Mutex::new(config)),
|
||||||
|
fan_curves: Arc::new(Mutex::new(fan_curves)),
|
||||||
|
platform,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Err(ProfileError::NotSupported.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn update_profiles_from_config(&self) {
|
||||||
|
let mut fan_curves = self.fan_curves.lock().await;
|
||||||
|
let config = self.config.lock().await;
|
||||||
|
fan_curves.balanced = config.balanced.clone();
|
||||||
|
fan_curves.performance = config.performance.clone();
|
||||||
|
fan_curves.quiet = config.quiet.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn update_config_from_profiles(&self) {
|
||||||
|
let fan_curves = self.fan_curves.lock().await;
|
||||||
|
let mut config = self.config.lock().await;
|
||||||
|
config.balanced = fan_curves.balanced.clone();
|
||||||
|
config.performance = fan_curves.performance.clone();
|
||||||
|
config.quiet = fan_curves.quiet.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||||
|
impl CtrlFanCurveZbus {
|
||||||
|
/// Set all fan curves for a profile to enabled status. Will also activate a
|
||||||
|
/// fan curve if in the same profile mode
|
||||||
|
async fn set_fan_curves_enabled(
|
||||||
|
&mut self,
|
||||||
|
profile: PlatformPolicy,
|
||||||
|
enabled: bool,
|
||||||
|
) -> zbus::fdo::Result<()> {
|
||||||
|
let mut fan_curves = self.fan_curves.lock().await;
|
||||||
|
fan_curves.set_profile_curves_enabled(profile, enabled);
|
||||||
|
fan_curves.write_profile_curve_to_platform(profile, &mut find_fan_curve_node()?)?;
|
||||||
|
|
||||||
|
self.update_config_from_profiles().await;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set a single fan curve for a profile to enabled status. Will also
|
||||||
|
/// activate a fan curve if in the same profile mode
|
||||||
|
async fn set_profile_fan_curve_enabled(
|
||||||
|
&mut self,
|
||||||
|
profile: PlatformPolicy,
|
||||||
|
fan: FanCurvePU,
|
||||||
|
enabled: bool,
|
||||||
|
) -> zbus::fdo::Result<()> {
|
||||||
|
let mut fan_curves = self.fan_curves.lock().await;
|
||||||
|
fan_curves.set_profile_fan_curve_enabled(profile, fan, enabled);
|
||||||
|
fan_curves.write_profile_curve_to_platform(profile, &mut find_fan_curve_node()?)?;
|
||||||
|
|
||||||
|
self.update_config_from_profiles().await;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the fan-curve data for the currently active PlatformPolicy
|
||||||
|
async fn fan_curve_data(
|
||||||
|
&mut self,
|
||||||
|
profile: PlatformPolicy,
|
||||||
|
) -> zbus::fdo::Result<Vec<CurveData>> {
|
||||||
|
let fan_curves = self.fan_curves.lock().await;
|
||||||
|
let curve = fan_curves.get_fan_curves_for(profile);
|
||||||
|
Ok(curve.to_vec())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the fan curve for the specified profile.
|
||||||
|
/// Will also activate the fan curve if the user is in the same mode.
|
||||||
|
async fn set_fan_curve(
|
||||||
|
&mut self,
|
||||||
|
profile: PlatformPolicy,
|
||||||
|
curve: CurveData,
|
||||||
|
) -> zbus::fdo::Result<()> {
|
||||||
|
let mut fan_curves = self.fan_curves.lock().await;
|
||||||
|
fan_curves.save_fan_curve(curve, profile)?;
|
||||||
|
fan_curves.write_profile_curve_to_platform(profile, &mut find_fan_curve_node()?)?;
|
||||||
|
|
||||||
|
self.update_config_from_profiles().await;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reset the stored (self) and device curve to the defaults of the
|
||||||
|
/// platform.
|
||||||
|
///
|
||||||
|
/// Each platform_profile has a different default and the defualt can be
|
||||||
|
/// read only for the currently active profile.
|
||||||
|
async fn set_active_curve_to_defaults(&mut self) -> zbus::fdo::Result<()> {
|
||||||
|
let mut fan_curves = self.fan_curves.lock().await;
|
||||||
|
let active = self.platform.get_throttle_thermal_policy()?;
|
||||||
|
fan_curves.set_active_curve_to_defaults(active.into(), &mut find_fan_curve_node()?)?;
|
||||||
|
|
||||||
|
self.update_config_from_profiles().await;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reset the stored (self) and device curve to the defaults of the
|
||||||
|
/// platform.
|
||||||
|
///
|
||||||
|
/// Each platform_profile has a different default and the defualt can be
|
||||||
|
/// read only for the currently active profile.
|
||||||
|
async fn reset_profile_curves(&self, profile: PlatformPolicy) -> zbus::fdo::Result<()> {
|
||||||
|
let mut fan_curves = self.fan_curves.lock().await;
|
||||||
|
|
||||||
|
let active = self
|
||||||
|
.platform
|
||||||
|
.get_throttle_thermal_policy()
|
||||||
|
.unwrap_or(PlatformPolicy::Balanced.into());
|
||||||
|
|
||||||
|
self.platform.set_throttle_thermal_policy(profile.into())?;
|
||||||
|
fan_curves.set_active_curve_to_defaults(active.into(), &mut find_fan_curve_node()?)?;
|
||||||
|
self.platform.set_throttle_thermal_policy(active)?;
|
||||||
|
|
||||||
|
self.update_config_from_profiles().await;
|
||||||
|
self.config.lock().await.write();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl crate::ZbusRun for CtrlFanCurveZbus {
|
||||||
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
|
Self::add_to_server_helper(self, FAN_CURVE_ZBUS_PATH, server).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl CtrlTask for CtrlFanCurveZbus {
|
||||||
|
fn zbus_path() -> &'static str {
|
||||||
|
FAN_CURVE_ZBUS_PATH
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn create_tasks(&self, _signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
|
||||||
|
let watch_throttle_thermal_policy = self.platform.monitor_throttle_thermal_policy()?;
|
||||||
|
let platform = self.platform.clone();
|
||||||
|
let config = self.config.clone();
|
||||||
|
let fan_curves = self.fan_curves.clone();
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let mut buffer = [0; 32];
|
||||||
|
if let Ok(mut stream) = watch_throttle_thermal_policy.into_event_stream(&mut buffer) {
|
||||||
|
while (stream.next().await).is_some() {
|
||||||
|
debug!("watch_throttle_thermal_policy changed");
|
||||||
|
if let Ok(profile) = platform.get_throttle_thermal_policy().map_err(|e| {
|
||||||
|
error!("{MOD_NAME}: get_throttle_thermal_policy error: {e}");
|
||||||
|
}) {
|
||||||
|
if profile != config.lock().await.current {
|
||||||
|
fan_curves
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.write_profile_curve_to_platform(
|
||||||
|
profile.into(),
|
||||||
|
&mut find_fan_curve_node().unwrap(),
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
warn!("{MOD_NAME}: write_profile_curve_to_platform, {}", e)
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
config.lock().await.current = profile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbg!("STREAM ENDED");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
impl crate::Reloadable for CtrlFanCurveZbus {
|
||||||
|
/// Fetch the active profile and use that to set all related components up
|
||||||
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
|
// let active = self.platform.get_throttle_thermal_policy()?.into();
|
||||||
|
// if let Ok(mut device) = find_fan_curve_node() {
|
||||||
|
// // 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
|
||||||
|
// // after
|
||||||
|
// self.fan_curves
|
||||||
|
// .lock()
|
||||||
|
// .await
|
||||||
|
// .write_profile_curve_to_platform(active, &mut device)?;
|
||||||
|
// }
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,86 +1,137 @@
|
|||||||
use std::fs::OpenOptions;
|
|
||||||
use std::io::{Read, Write};
|
|
||||||
use std::path::Path;
|
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::sync::Arc;
|
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::{debug, error, info, warn};
|
||||||
use rog_platform::platform::{AsusPlatform, GpuMode};
|
use rog_platform::cpu::CPUControl;
|
||||||
use rog_platform::supported::RogBiosSupportedFunctions;
|
use rog_platform::platform::{GpuMode, PlatformPolicy, Properties, RogPlatform};
|
||||||
|
use rog_platform::power::AsusPower;
|
||||||
use zbus::export::futures_util::lock::Mutex;
|
use zbus::export::futures_util::lock::Mutex;
|
||||||
use zbus::{dbus_interface, Connection, SignalContext};
|
use zbus::fdo::Error as FdoErr;
|
||||||
|
use zbus::{dbus_interface, Connection, ObjectServer, SignalContext};
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
|
use crate::ctrl_anime::trait_impls::{CtrlAnimeZbus, ANIME_ZBUS_NAME, ANIME_ZBUS_PATH};
|
||||||
|
use crate::ctrl_aura::trait_impls::{CtrlAuraZbus, AURA_ZBUS_NAME, AURA_ZBUS_PATH};
|
||||||
|
use crate::ctrl_fancurves::{CtrlFanCurveZbus, FAN_CURVE_ZBUS_NAME, FAN_CURVE_ZBUS_PATH};
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
use crate::{task_watch_item, CtrlTask, GetSupported};
|
use crate::{task_watch_item, task_watch_item_notify, CtrlTask};
|
||||||
|
|
||||||
const ZBUS_PATH: &str = "/org/asuslinux/Platform";
|
const ZBUS_PATH: &str = "/org/asuslinux/Platform";
|
||||||
const ASUS_POST_LOGO_SOUND: &str =
|
|
||||||
"/sys/firmware/efi/efivars/AsusPostLogoSound-607005d5-3f75-4b2e-98f0-85ba66797a3e";
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
macro_rules! platform_get_value {
|
||||||
pub struct CtrlPlatform {
|
($self:ident, $property:tt, $prop_name:literal) => {
|
||||||
platform: AsusPlatform,
|
concat_idents::concat_idents!(has = has_, $property {
|
||||||
config: Arc<Mutex<Config>>,
|
if $self.platform.has() {
|
||||||
|
concat_idents::concat_idents!(get = get_, $property {
|
||||||
|
$self.platform
|
||||||
|
.get()
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("RogPlatform: {}: {}", $prop_name, err);
|
||||||
|
FdoErr::Failed(format!("RogPlatform: {}: {}", $prop_name, err))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
error!("RogPlatform: {} not supported", $prop_name);
|
||||||
|
return Err(FdoErr::NotSupported(format!("RogPlatform: {} not supported", $prop_name)));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetSupported for CtrlPlatform {
|
macro_rules! platform_get_value_if_some {
|
||||||
type A = RogBiosSupportedFunctions;
|
($self:ident, $property:tt, $prop_name:literal, $default:expr) => {
|
||||||
|
concat_idents::concat_idents!(has = has_, $property {
|
||||||
|
if $self.platform.has() {
|
||||||
|
let lock = $self.config.lock().await;
|
||||||
|
Ok(lock.ppt_pl1_spl.unwrap_or($default))
|
||||||
|
} else {
|
||||||
|
error!("RogPlatform: {} not supported", $prop_name);
|
||||||
|
return Err(FdoErr::NotSupported(format!("RogPlatform: {} not supported", $prop_name)));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn get_supported() -> Self::A {
|
macro_rules! platform_set_bool {
|
||||||
let mut panel_overdrive = false;
|
($self:ident, $property:tt, $prop_name:literal, $new_value:expr) => {
|
||||||
let mut mini_led_mode = false;
|
concat_idents::concat_idents!(has = has_, $property {
|
||||||
let mut dgpu_disable = false;
|
if $self.platform.has() {
|
||||||
let mut egpu_enable = false;
|
concat_idents::concat_idents!(set = set_, $property {
|
||||||
let mut gpu_mux = false;
|
$self.platform.set($new_value).map_err(|err| {
|
||||||
|
error!("RogPlatform: {} {err}", $prop_name);
|
||||||
|
FdoErr::NotSupported(format!("RogPlatform: {} {err}", $prop_name))
|
||||||
|
})?;
|
||||||
|
});
|
||||||
|
let mut lock = $self.config.lock().await;
|
||||||
|
lock.$property = $new_value;
|
||||||
|
lock.write();
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
error!("RogPlatform: {} not supported", $prop_name);
|
||||||
|
Err(FdoErr::NotSupported(format!("RogPlatform: {} not supported", $prop_name)))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Ok(platform) = AsusPlatform::new() {
|
/// Intended only for setting platform object values where the value isn't
|
||||||
panel_overdrive = platform.has_panel_od();
|
/// retained across boots
|
||||||
mini_led_mode = platform.has_mini_led_mode();
|
macro_rules! platform_set_with_min_max {
|
||||||
dgpu_disable = platform.has_dgpu_disable();
|
($self:ident, $property:tt, $prop_name:literal, $new_value:expr, $min_value:expr, $max_value:expr) => {
|
||||||
egpu_enable = platform.has_egpu_enable();
|
if !($min_value..=$max_value).contains(&$new_value) {
|
||||||
gpu_mux = platform.has_gpu_mux_mode();
|
Err(FdoErr::Failed(
|
||||||
}
|
format!("RogPlatform: {} value not in range {}=..={}", $prop_name, $min_value, $max_value)
|
||||||
|
))
|
||||||
RogBiosSupportedFunctions {
|
} else {
|
||||||
post_sound: Path::new(ASUS_POST_LOGO_SOUND).exists(),
|
concat_idents::concat_idents!(has = has_, $property {
|
||||||
gpu_mux,
|
if $self.platform.has() {
|
||||||
panel_overdrive,
|
concat_idents::concat_idents!(set = set_, $property {
|
||||||
mini_led_mode,
|
$self.platform.set($new_value).map_err(|err| {
|
||||||
dgpu_disable,
|
error!("RogPlatform: {} {err}", $prop_name);
|
||||||
egpu_enable,
|
FdoErr::NotSupported(format!("RogPlatform: {} {err}", $prop_name))
|
||||||
|
})?;
|
||||||
|
});
|
||||||
|
let mut lock = $self.config.lock().await;
|
||||||
|
lock.$property = Some($new_value);
|
||||||
|
lock.write();
|
||||||
|
} else {
|
||||||
|
error!("RogPlatform: {} not supported", $prop_name);
|
||||||
|
return Err(FdoErr::NotSupported(format!("RogPlatform: {} not supported", $prop_name)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct CtrlPlatform {
|
||||||
|
power: AsusPower,
|
||||||
|
platform: RogPlatform,
|
||||||
|
cpu_control: Option<CPUControl>,
|
||||||
|
config: Arc<Mutex<Config>>,
|
||||||
|
}
|
||||||
|
|
||||||
impl CtrlPlatform {
|
impl CtrlPlatform {
|
||||||
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
|
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
|
||||||
let platform = AsusPlatform::new()?;
|
let platform = RogPlatform::new()?;
|
||||||
|
let power = AsusPower::new()?;
|
||||||
|
|
||||||
if !platform.has_gpu_mux_mode() {
|
if !platform.has_gpu_mux_mode() {
|
||||||
info!("G-Sync Switchable Graphics or GPU MUX not detected");
|
info!("G-Sync Switchable Graphics or GPU MUX not detected");
|
||||||
info!("Standard graphics switching will still work.");
|
info!("Standard graphics switching will still work.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if Path::new(ASUS_POST_LOGO_SOUND).exists() {
|
Ok(CtrlPlatform {
|
||||||
CtrlPlatform::set_path_mutable(ASUS_POST_LOGO_SOUND)?;
|
power,
|
||||||
} else {
|
platform,
|
||||||
info!("Switch for POST boot sound not detected");
|
config,
|
||||||
}
|
cpu_control: CPUControl::new()
|
||||||
|
.map_err(|e| error!("Couldn't get CPU control sysfs: {e}"))
|
||||||
Ok(CtrlPlatform { platform, config })
|
.ok(),
|
||||||
}
|
})
|
||||||
|
|
||||||
fn set_path_mutable(path: &str) -> Result<(), RogError> {
|
|
||||||
let output = Command::new("/usr/bin/chattr")
|
|
||||||
.arg("-i")
|
|
||||||
.arg(path)
|
|
||||||
.output()
|
|
||||||
.map_err(|err| RogError::Path(path.into(), err))?;
|
|
||||||
info!("Set {} writeable: status: {}", path, output.status);
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_gfx_mode(&self, mode: GpuMode) -> Result<(), RogError> {
|
fn set_gfx_mode(&self, mode: GpuMode) -> Result<(), RogError> {
|
||||||
@@ -94,232 +145,362 @@ impl CtrlPlatform {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_boot_sound() -> Result<i8, RogError> {
|
async fn run_ac_or_bat_cmd(&self, power_plugged: bool) {
|
||||||
let data = std::fs::read(ASUS_POST_LOGO_SOUND)
|
let prog: Vec<String> = if power_plugged {
|
||||||
.map_err(|err| RogError::Read(ASUS_POST_LOGO_SOUND.into(), err))?;
|
// AC ONLINE
|
||||||
|
self.config
|
||||||
let idx = data.len() - 1;
|
.lock()
|
||||||
Ok(data[idx] as i8)
|
.await
|
||||||
}
|
.ac_command
|
||||||
|
.split_whitespace()
|
||||||
pub(super) fn set_boot_sound(on: bool) -> Result<(), RogError> {
|
.map(|s| s.to_string())
|
||||||
let path = ASUS_POST_LOGO_SOUND;
|
.collect()
|
||||||
let mut file = OpenOptions::new()
|
|
||||||
.read(true)
|
|
||||||
.write(true)
|
|
||||||
.open(path)
|
|
||||||
.map_err(|err| RogError::Path(path.into(), err))?;
|
|
||||||
|
|
||||||
let mut data = Vec::new();
|
|
||||||
#[allow(clippy::verbose_file_reads)]
|
|
||||||
file.read_to_end(&mut data)
|
|
||||||
.map_err(|err| RogError::Read(path.into(), err))?;
|
|
||||||
|
|
||||||
let idx = data.len() - 1;
|
|
||||||
if on {
|
|
||||||
data[idx] = 1;
|
|
||||||
info!("Set boot POST sound on");
|
|
||||||
} else {
|
} else {
|
||||||
data[idx] = 0;
|
// BATTERY
|
||||||
info!("Set boot POST sound off");
|
self.config
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.bat_command
|
||||||
|
.split_whitespace()
|
||||||
|
.map(|s| s.to_string())
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
if prog.len() > 1 {
|
||||||
|
let mut cmd = Command::new(&prog[0]);
|
||||||
|
for arg in prog.iter().skip(1) {
|
||||||
|
cmd.arg(arg);
|
||||||
|
}
|
||||||
|
if let Err(e) = cmd.spawn() {
|
||||||
|
if power_plugged {
|
||||||
|
error!("AC power command error: {e}");
|
||||||
|
} else {
|
||||||
|
error!("Battery power command error: {e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
file.write_all(&data)
|
|
||||||
.map_err(|err| RogError::Path(path.into(), err))?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_panel_overdrive(&self, enable: bool) -> Result<(), RogError> {
|
async fn update_policy_ac_or_bat(&self, power_plugged: bool) {
|
||||||
self.platform.set_panel_od(enable).map_err(|err| {
|
let profile = if power_plugged {
|
||||||
warn!("CtrlRogBios: set_panel_overdrive {}", err);
|
self.config.lock().await.platform_policy_on_ac
|
||||||
err
|
} else {
|
||||||
})?;
|
self.config.lock().await.platform_policy_on_battery
|
||||||
Ok(())
|
};
|
||||||
|
self.platform
|
||||||
|
.set_throttle_thermal_policy(profile.into())
|
||||||
|
.ok();
|
||||||
|
if let Some(cpu) = self.cpu_control.as_ref() {
|
||||||
|
cpu.set_epp(profile.into()).ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
||||||
impl CtrlPlatform {
|
impl CtrlPlatform {
|
||||||
async fn set_gpu_mux_mode(
|
/// Returns a list of property names that this system supports
|
||||||
&mut self,
|
async fn supported_properties(&self) -> Vec<Properties> {
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
let mut supported = Vec::new();
|
||||||
mode: GpuMode,
|
|
||||||
) {
|
macro_rules! platform_name {
|
||||||
self.set_gfx_mode(mode)
|
($property:tt, $prop_name:ty) => {
|
||||||
.map_err(|err| {
|
concat_idents::concat_idents!(has = has_, $property {
|
||||||
warn!("CtrlRogBios: set_gpu_mux_mode {}", err);
|
if self.platform.has() {
|
||||||
err
|
supported.push($prop_name.to_owned());
|
||||||
})
|
}
|
||||||
.ok();
|
})
|
||||||
Self::notify_gpu_mux_mode(&ctxt, mode).await.ok();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! power_name {
|
||||||
|
($property:tt, $prop_name:ty) => {
|
||||||
|
concat_idents::concat_idents!(has = has_, $property {
|
||||||
|
if self.power.has() {
|
||||||
|
supported.push($prop_name.to_owned());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: automate this
|
||||||
|
power_name!(
|
||||||
|
charge_control_end_threshold,
|
||||||
|
Properties::ChargeControlEndThreshold
|
||||||
|
);
|
||||||
|
|
||||||
|
platform_name!(dgpu_disable, Properties::DgpuDisable);
|
||||||
|
platform_name!(gpu_mux_mode, Properties::GpuMuxMode);
|
||||||
|
platform_name!(post_animation_sound, Properties::PostAnimationSound);
|
||||||
|
platform_name!(panel_od, Properties::PanelOd);
|
||||||
|
platform_name!(mini_led_mode, Properties::MiniLedMode);
|
||||||
|
platform_name!(egpu_enable, Properties::EgpuEnable);
|
||||||
|
platform_name!(throttle_thermal_policy, Properties::PlatformPolicy);
|
||||||
|
|
||||||
|
platform_name!(ppt_pl1_spl, Properties::PptPl1Spl);
|
||||||
|
platform_name!(ppt_pl2_sppt, Properties::PptPl2Sppt);
|
||||||
|
platform_name!(ppt_fppt, Properties::PptFppt);
|
||||||
|
platform_name!(ppt_apu_sppt, Properties::PptApuSppt);
|
||||||
|
platform_name!(ppt_platform_sppt, Properties::PptPlatformSppt);
|
||||||
|
platform_name!(nv_dynamic_boost, Properties::NvDynamicBoost);
|
||||||
|
platform_name!(nv_temp_target, Properties::NvTempTarget);
|
||||||
|
|
||||||
|
supported
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gpu_mux_mode(&self) -> GpuMode {
|
async fn supported_interfaces(
|
||||||
match self.platform.get_gpu_mux_mode() {
|
&self,
|
||||||
Ok(m) => GpuMode::from_mux(m as u8),
|
#[zbus(object_server)] server: &ObjectServer,
|
||||||
Err(e) => {
|
) -> Vec<String> {
|
||||||
warn!("CtrlRogBios: get_gfx_mode {}", e);
|
let mut interfaces = Vec::default();
|
||||||
GpuMode::Error
|
if server
|
||||||
}
|
.interface::<_, CtrlAnimeZbus>(ANIME_ZBUS_PATH)
|
||||||
|
.await
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
interfaces.push(ANIME_ZBUS_NAME.to_owned());
|
||||||
|
}
|
||||||
|
if server
|
||||||
|
.interface::<_, CtrlAuraZbus>(AURA_ZBUS_PATH)
|
||||||
|
.await
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
interfaces.push(AURA_ZBUS_NAME.to_owned());
|
||||||
|
}
|
||||||
|
if server
|
||||||
|
.interface::<_, CtrlFanCurveZbus>(FAN_CURVE_ZBUS_PATH)
|
||||||
|
.await
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
interfaces.push(FAN_CURVE_ZBUS_NAME.to_owned());
|
||||||
|
}
|
||||||
|
interfaces
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
fn charge_control_end_threshold(&self) -> Result<u8, FdoErr> {
|
||||||
|
let limit = self.power.get_charge_control_end_threshold()?;
|
||||||
|
Ok(limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_charge_control_end_threshold(&mut self, limit: u8) -> Result<(), FdoErr> {
|
||||||
|
if !(20..=100).contains(&limit) {
|
||||||
|
return Err(RogError::ChargeLimit(limit))?;
|
||||||
|
}
|
||||||
|
self.power.set_charge_control_end_threshold(limit)?;
|
||||||
|
self.config.lock().await.charge_control_end_threshold = limit;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
fn gpu_mux_mode(&self) -> Result<u8, FdoErr> {
|
||||||
|
self.platform.get_gpu_mux_mode().map_err(|err| {
|
||||||
|
warn!("RogPlatform: set_gpu_mux_mode {err}");
|
||||||
|
FdoErr::NotSupported("RogPlatform: set_gpu_mux_mode not supported".to_owned())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_gpu_mux_mode(&mut self, mode: u8) -> Result<(), FdoErr> {
|
||||||
|
if self.platform.has_gpu_mux_mode() {
|
||||||
|
self.set_gfx_mode(mode.into()).map_err(|err| {
|
||||||
|
warn!("RogPlatform: set_gpu_mux_mode {}", err);
|
||||||
|
FdoErr::Failed(format!("RogPlatform: set_gpu_mux_mode: {err}"))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(FdoErr::NotSupported(
|
||||||
|
"RogPlatform: set_gpu_mux_mode not supported".to_owned(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(signal)]
|
/// Toggle to next platform_profile. Names provided by `Profiles`.
|
||||||
async fn notify_gpu_mux_mode(
|
/// If fan-curves are supported will also activate a fan curve for profile.
|
||||||
signal_ctxt: &SignalContext<'_>,
|
async fn next_throttle_thermal_policy(
|
||||||
mode: GpuMode,
|
|
||||||
) -> zbus::Result<()> {
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn set_post_boot_sound(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
||||||
on: bool,
|
) -> Result<(), FdoErr> {
|
||||||
) {
|
let policy: PlatformPolicy =
|
||||||
Self::set_boot_sound(on)
|
platform_get_value!(self, throttle_thermal_policy, "throttle_thermal_policy")
|
||||||
.map_err(|err| {
|
.map(|n| n.into())?;
|
||||||
warn!("CtrlRogBios: set_post_boot_sound {}", err);
|
let policy = PlatformPolicy::next(&policy);
|
||||||
err
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
Self::notify_post_boot_sound(&ctxt, on)
|
|
||||||
.await
|
|
||||||
.map_err(|err| {
|
|
||||||
warn!("CtrlRogBios: set_post_boot_sound {}", err);
|
|
||||||
err
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn post_boot_sound(&self) -> i8 {
|
if self.platform.has_throttle_thermal_policy() {
|
||||||
Self::get_boot_sound()
|
if let Some(cpu) = self.cpu_control.as_ref() {
|
||||||
.map_err(|err| {
|
info!("PlatformPolicy setting EPP");
|
||||||
warn!("CtrlRogBios: get_boot_sound {}", err);
|
cpu.set_epp(policy.into())?
|
||||||
err
|
|
||||||
})
|
|
||||||
.unwrap_or(-1)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[dbus_interface(signal)]
|
|
||||||
async fn notify_post_boot_sound(ctxt: &SignalContext<'_>, on: bool) -> zbus::Result<()> {}
|
|
||||||
|
|
||||||
async fn set_panel_od(&mut self, overdrive: bool) {
|
|
||||||
match self.platform.set_panel_od(overdrive) {
|
|
||||||
Ok(_) => {
|
|
||||||
if let Some(mut lock) = self.config.try_lock() {
|
|
||||||
lock.panel_od = overdrive;
|
|
||||||
lock.write();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(err) => warn!("CtrlRogBios: set_panel_overdrive {}", err),
|
self.platform
|
||||||
};
|
.set_throttle_thermal_policy(policy.into())
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("RogPlatform: throttle_thermal_policy {}", err);
|
||||||
|
FdoErr::Failed(format!("RogPlatform: throttle_thermal_policy: {err}"))
|
||||||
|
})?;
|
||||||
|
self.config.lock().await.platform_policy_to_restore = policy;
|
||||||
|
Ok(self.throttle_thermal_policy_changed(&ctxt).await?)
|
||||||
|
} else {
|
||||||
|
Err(FdoErr::NotSupported(
|
||||||
|
"RogPlatform: throttle_thermal_policy not supported".to_owned(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
fn throttle_thermal_policy(&self) -> Result<PlatformPolicy, FdoErr> {
|
||||||
|
platform_get_value!(self, throttle_thermal_policy, "throttle_thermal_policy")
|
||||||
|
.map(|n| n.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_throttle_thermal_policy(&mut self, policy: PlatformPolicy) -> Result<(), FdoErr> {
|
||||||
|
// TODO: watch for external changes
|
||||||
|
if self.platform.has_throttle_thermal_policy() {
|
||||||
|
if let Some(cpu) = self.cpu_control.as_ref() {
|
||||||
|
info!("PlatformPolicy setting EPP");
|
||||||
|
cpu.set_epp(policy.into())?
|
||||||
|
}
|
||||||
|
self.config.lock().await.platform_policy_to_restore = policy;
|
||||||
|
self.platform
|
||||||
|
.set_throttle_thermal_policy(policy.into())
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("RogPlatform: throttle_thermal_policy {}", err);
|
||||||
|
FdoErr::Failed(format!("RogPlatform: throttle_thermal_policy: {err}"))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(FdoErr::NotSupported(
|
||||||
|
"RogPlatform: throttle_thermal_policy not supported".to_owned(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
fn post_animation_sound(&self) -> Result<bool, FdoErr> {
|
||||||
|
platform_get_value!(self, post_animation_sound, "post_animation_sound")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_post_animation_sound(&mut self, on: bool) -> Result<(), FdoErr> {
|
||||||
|
if self.platform.has_post_animation_sound() {
|
||||||
|
self.platform.set_post_animation_sound(on).map_err(|err| {
|
||||||
|
warn!("RogPlatform: set_post_animation_sound {}", err);
|
||||||
|
FdoErr::Failed(format!("RogPlatform: set_post_animation_sound: {err}"))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(FdoErr::NotSupported(
|
||||||
|
"RogPlatform: set_post_animation_sound not supported".to_owned(),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the `panel_od` value from platform. Updates the stored value in
|
/// Get the `panel_od` value from platform. Updates the stored value in
|
||||||
/// internal config also.
|
/// internal config also.
|
||||||
fn panel_od(&self) -> bool {
|
#[dbus_interface(property)]
|
||||||
self.platform
|
fn panel_od(&self) -> Result<bool, FdoErr> {
|
||||||
.get_panel_od()
|
platform_get_value!(self, panel_od, "panel_od")
|
||||||
.map_err(|err| {
|
|
||||||
warn!("CtrlRogBios: get_panel_od {}", err);
|
|
||||||
err
|
|
||||||
})
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(signal)]
|
#[dbus_interface(property)]
|
||||||
async fn notify_panel_od(signal_ctxt: &SignalContext<'_>, overdrive: bool) -> zbus::Result<()> {
|
async fn set_panel_od(&mut self, overdrive: bool) -> Result<(), FdoErr> {
|
||||||
}
|
platform_set_bool!(self, panel_od, "panel_od", overdrive)
|
||||||
|
|
||||||
async fn set_mini_led_mode(&mut self, on: bool) {
|
|
||||||
match self.platform.set_mini_led_mode(on) {
|
|
||||||
Ok(_) => {
|
|
||||||
if let Some(mut lock) = self.config.try_lock() {
|
|
||||||
lock.mini_led_mode = on;
|
|
||||||
lock.write();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => warn!("CtrlRogBios: set_mini_led_mode {}", err),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the `panel_od` value from platform. Updates the stored value in
|
/// Get the `panel_od` value from platform. Updates the stored value in
|
||||||
/// internal config also.
|
/// internal config also.
|
||||||
fn mini_led_mode(&self) -> bool {
|
#[dbus_interface(property)]
|
||||||
self.platform
|
fn mini_led_mode(&self) -> Result<bool, FdoErr> {
|
||||||
.get_mini_led_mode()
|
platform_get_value!(self, mini_led_mode, "mini_led_mode")
|
||||||
.map_err(|err| {
|
|
||||||
warn!("CtrlRogBios: get_mini_led_mode {}", err);
|
|
||||||
err
|
|
||||||
})
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(signal)]
|
#[dbus_interface(property)]
|
||||||
async fn notify_mini_led_mode(signal_ctxt: &SignalContext<'_>, on: bool) -> zbus::Result<()> {}
|
async fn set_mini_led_mode(&mut self, on: bool) -> Result<(), FdoErr> {
|
||||||
|
platform_set_bool!(self, mini_led_mode, "mini_led_mode", on)
|
||||||
async fn set_dgpu_disable(
|
|
||||||
&mut self,
|
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
||||||
disable: bool,
|
|
||||||
) {
|
|
||||||
match self.platform.set_dgpu_disable(disable) {
|
|
||||||
Ok(_) => {
|
|
||||||
Self::notify_dgpu_disable(&ctxt, disable).await.ok();
|
|
||||||
}
|
|
||||||
Err(err) => warn!("CtrlRogBios: set_dgpu_disable {}", err),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dgpu_disable(&self) -> bool {
|
#[dbus_interface(property)]
|
||||||
self.platform
|
fn dgpu_disable(&self) -> Result<bool, FdoErr> {
|
||||||
.get_dgpu_disable()
|
platform_get_value!(self, dgpu_disable, "dgpu_disable")
|
||||||
.map_err(|err| {
|
|
||||||
warn!("CtrlRogBios: get_dgpu_disable {}", err);
|
|
||||||
err
|
|
||||||
})
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(signal)]
|
#[dbus_interface(property)]
|
||||||
async fn notify_dgpu_disable(
|
fn egpu_enable(&self) -> Result<bool, FdoErr> {
|
||||||
signal_ctxt: &SignalContext<'_>,
|
platform_get_value!(self, egpu_enable, "egpu_enable")
|
||||||
disable: bool,
|
|
||||||
) -> zbus::Result<()> {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_egpu_enable(
|
/// ************************************************************************
|
||||||
&mut self,
|
#[dbus_interface(property)]
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
async fn ppt_pl1_spl(&self) -> Result<u8, FdoErr> {
|
||||||
enable: bool,
|
platform_get_value_if_some!(self, ppt_pl1_spl, "ppt_pl1_spl", 5)
|
||||||
) {
|
|
||||||
match self.platform.set_egpu_enable(enable) {
|
|
||||||
Ok(_) => {
|
|
||||||
Self::notify_egpu_enable(&ctxt, enable).await.ok();
|
|
||||||
}
|
|
||||||
Err(err) => warn!("CtrlRogBios: set_egpu_enable {}", err),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn egpu_enable(&self) -> bool {
|
#[dbus_interface(property)]
|
||||||
self.platform
|
async fn set_ppt_pl1_spl(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||||
.get_egpu_enable()
|
platform_set_with_min_max!(self, ppt_pl1_spl, "ppt_pl1_spl", value, 5, 250)
|
||||||
.map_err(|err| {
|
|
||||||
warn!("CtrlRogBios: get_egpu_enable {}", err);
|
|
||||||
err
|
|
||||||
})
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[dbus_interface(signal)]
|
#[dbus_interface(property)]
|
||||||
async fn notify_egpu_enable(signal_ctxt: &SignalContext<'_>, enable: bool) -> zbus::Result<()> {
|
async fn ppt_pl2_sppt(&self) -> Result<u8, FdoErr> {
|
||||||
|
platform_get_value_if_some!(self, ppt_pl2_sppt, "ppt_pl2_sppt", 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_ppt_pl2_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||||
|
platform_set_with_min_max!(self, ppt_pl2_sppt, "ppt_pl2_sppt", value, 5, 250)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn ppt_fppt(&self) -> Result<u8, FdoErr> {
|
||||||
|
platform_get_value_if_some!(self, ppt_fppt, "ppt_fppt", 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_ppt_fppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||||
|
platform_set_with_min_max!(self, ppt_fppt, "ppt_fppt", value, 5, 250)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn ppt_apu_sppt(&self) -> Result<u8, FdoErr> {
|
||||||
|
platform_get_value_if_some!(self, ppt_apu_sppt, "ppt_apu_sppt", 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_ppt_apu_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||||
|
platform_set_with_min_max!(self, ppt_apu_sppt, "ppt_apu_sppt", value, 5, 130)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn ppt_platform_sppt(&self) -> Result<u8, FdoErr> {
|
||||||
|
platform_get_value_if_some!(self, ppt_platform_sppt, "ppt_platform_sppt", 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_ppt_platform_sppt(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||||
|
platform_set_with_min_max!(self, ppt_platform_sppt, "ppt_platform_sppt", value, 5, 130)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn nv_dynamic_boost(&self) -> Result<u8, FdoErr> {
|
||||||
|
platform_get_value_if_some!(self, nv_dynamic_boost, "nv_dynamic_boost", 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_nv_dynamic_boost(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||||
|
platform_set_with_min_max!(self, nv_dynamic_boost, "nv_dynamic_boost", value, 5, 25)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn nv_temp_target(&self) -> Result<u8, FdoErr> {
|
||||||
|
platform_get_value_if_some!(self, nv_temp_target, "nv_temp_target", 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[dbus_interface(property)]
|
||||||
|
async fn set_nv_temp_target(&mut self, value: u8) -> Result<(), FdoErr> {
|
||||||
|
platform_set_with_min_max!(self, nv_temp_target, "nv_temp_target", value, 5, 87)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl crate::ZbusRun for CtrlPlatform {
|
impl crate::ZbusRun for CtrlPlatform {
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
async fn add_to_server(self, server: &mut Connection) {
|
||||||
Self::add_to_server_helper(self, "/org/asuslinux/Platform", server).await;
|
Self::add_to_server_helper(self, ZBUS_PATH, server).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,13 +508,28 @@ impl crate::ZbusRun for CtrlPlatform {
|
|||||||
impl crate::Reloadable for CtrlPlatform {
|
impl crate::Reloadable for CtrlPlatform {
|
||||||
async fn reload(&mut self) -> Result<(), RogError> {
|
async fn reload(&mut self) -> Result<(), RogError> {
|
||||||
if self.platform.has_panel_od() {
|
if self.platform.has_panel_od() {
|
||||||
let p = if let Some(lock) = self.config.try_lock() {
|
self.platform
|
||||||
lock.panel_od
|
.set_panel_od(self.config.lock().await.panel_od)?;
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
self.set_panel_overdrive(p)?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.platform.has_mini_led_mode() {
|
||||||
|
self.platform
|
||||||
|
.set_mini_led_mode(self.config.lock().await.mini_led_mode)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.power.has_charge_control_end_threshold() {
|
||||||
|
self.power.set_charge_control_end_threshold(
|
||||||
|
self.config.lock().await.charge_control_end_threshold,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(power_plugged) = self.power.get_online() {
|
||||||
|
if self.platform.has_throttle_thermal_policy() {
|
||||||
|
self.update_policy_ac_or_bat(power_plugged > 0).await;
|
||||||
|
}
|
||||||
|
self.run_ac_or_bat_cmd(power_plugged > 0).await;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -341,13 +537,32 @@ impl crate::Reloadable for CtrlPlatform {
|
|||||||
impl CtrlPlatform {
|
impl CtrlPlatform {
|
||||||
task_watch_item!(panel_od platform);
|
task_watch_item!(panel_od platform);
|
||||||
|
|
||||||
task_watch_item!(dgpu_disable platform);
|
|
||||||
|
|
||||||
task_watch_item!(egpu_enable platform);
|
|
||||||
|
|
||||||
task_watch_item!(mini_led_mode platform);
|
task_watch_item!(mini_led_mode platform);
|
||||||
|
|
||||||
|
task_watch_item!(charge_control_end_threshold power);
|
||||||
|
|
||||||
|
task_watch_item_notify!(post_animation_sound platform);
|
||||||
|
|
||||||
|
task_watch_item_notify!(dgpu_disable platform);
|
||||||
|
|
||||||
|
task_watch_item_notify!(egpu_enable platform);
|
||||||
|
|
||||||
// NOTE: see note further below
|
// NOTE: see note further below
|
||||||
// task_watch_item!(gpu_mux_mode platform);
|
task_watch_item_notify!(gpu_mux_mode platform);
|
||||||
|
|
||||||
|
task_watch_item_notify!(ppt_pl1_spl platform);
|
||||||
|
|
||||||
|
task_watch_item_notify!(ppt_pl2_sppt platform);
|
||||||
|
|
||||||
|
task_watch_item_notify!(ppt_fppt platform);
|
||||||
|
|
||||||
|
task_watch_item_notify!(ppt_apu_sppt platform);
|
||||||
|
|
||||||
|
task_watch_item_notify!(ppt_platform_sppt platform);
|
||||||
|
|
||||||
|
task_watch_item_notify!(nv_dynamic_boost platform);
|
||||||
|
|
||||||
|
task_watch_item_notify!(nv_temp_target platform);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
@@ -359,16 +574,54 @@ impl CtrlTask for CtrlPlatform {
|
|||||||
async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
|
async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
|
||||||
let platform1 = self.clone();
|
let platform1 = self.clone();
|
||||||
let platform2 = self.clone();
|
let platform2 = self.clone();
|
||||||
|
let platform3 = self.clone();
|
||||||
self.create_sys_event_tasks(
|
self.create_sys_event_tasks(
|
||||||
move || async { {} },
|
move |sleeping| {
|
||||||
move || {
|
|
||||||
let platform1 = platform1.clone();
|
let platform1 = platform1.clone();
|
||||||
async move {
|
async move {
|
||||||
info!("CtrlRogBios reloading panel_od");
|
info!("RogPlatform reloading panel_od");
|
||||||
let lock = platform1.config.lock().await;
|
if !sleeping && platform1.platform.has_panel_od() {
|
||||||
if platform1.platform.has_panel_od() {
|
|
||||||
platform1
|
platform1
|
||||||
.set_panel_overdrive(lock.panel_od)
|
.platform
|
||||||
|
.set_panel_od(platform1.config.lock().await.panel_od)
|
||||||
|
.map_err(|err| {
|
||||||
|
warn!("CtrlCharge: panel_od {}", err);
|
||||||
|
err
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
if sleeping && platform1.power.has_charge_control_end_threshold() {
|
||||||
|
platform1.config.lock().await.charge_control_end_threshold = platform1
|
||||||
|
.power
|
||||||
|
.get_charge_control_end_threshold()
|
||||||
|
.unwrap_or(100);
|
||||||
|
} else if !sleeping && platform1.power.has_charge_control_end_threshold() {
|
||||||
|
platform1
|
||||||
|
.power
|
||||||
|
.set_charge_control_end_threshold(
|
||||||
|
platform1.config.lock().await.charge_control_end_threshold,
|
||||||
|
)
|
||||||
|
.ok();
|
||||||
|
}
|
||||||
|
if let Ok(power_plugged) = platform1.power.get_online() {
|
||||||
|
if !sleeping && platform1.platform.has_throttle_thermal_policy() {
|
||||||
|
platform1.update_policy_ac_or_bat(power_plugged > 0).await;
|
||||||
|
}
|
||||||
|
if !sleeping {
|
||||||
|
platform1.run_ac_or_bat_cmd(power_plugged > 0).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
move |shutting_down| {
|
||||||
|
let platform2 = platform2.clone();
|
||||||
|
async move {
|
||||||
|
info!("RogPlatform reloading panel_od");
|
||||||
|
let lock = platform2.config.lock().await;
|
||||||
|
if !shutting_down && platform2.platform.has_panel_od() {
|
||||||
|
platform2
|
||||||
|
.platform
|
||||||
|
.set_panel_od(lock.panel_od)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("CtrlCharge: panel_od {}", err);
|
warn!("CtrlCharge: panel_od {}", err);
|
||||||
err
|
err
|
||||||
@@ -377,33 +630,73 @@ impl CtrlTask for CtrlPlatform {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
move || async { {} },
|
move |_lid_closed| {
|
||||||
move || {
|
// on lid change
|
||||||
let platform2 = platform2.clone();
|
async move {}
|
||||||
|
},
|
||||||
|
move |power_plugged| {
|
||||||
|
let platform3 = platform3.clone();
|
||||||
|
// power change
|
||||||
async move {
|
async move {
|
||||||
info!("CtrlRogBios reloading panel_od");
|
if platform3.platform.has_throttle_thermal_policy() {
|
||||||
let lock = platform2.config.lock().await;
|
platform3.update_policy_ac_or_bat(power_plugged).await;
|
||||||
if platform2.platform.has_panel_od() {
|
|
||||||
platform2
|
|
||||||
.set_panel_overdrive(lock.panel_od)
|
|
||||||
.map_err(|err| {
|
|
||||||
warn!("CtrlCharge: panel_od {}", err);
|
|
||||||
err
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
|
platform3.run_ac_or_bat_cmd(power_plugged).await;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
// This spawns a new task for every item.
|
||||||
|
// TODO: find a better way to manage this
|
||||||
self.watch_panel_od(signal_ctxt.clone()).await?;
|
self.watch_panel_od(signal_ctxt.clone()).await?;
|
||||||
|
self.watch_mini_led_mode(signal_ctxt.clone()).await?;
|
||||||
|
self.watch_charge_control_end_threshold(signal_ctxt.clone())
|
||||||
|
.await?;
|
||||||
|
|
||||||
self.watch_dgpu_disable(signal_ctxt.clone()).await?;
|
self.watch_dgpu_disable(signal_ctxt.clone()).await?;
|
||||||
self.watch_egpu_enable(signal_ctxt.clone()).await?;
|
self.watch_egpu_enable(signal_ctxt.clone()).await?;
|
||||||
self.watch_mini_led_mode(signal_ctxt.clone()).await?;
|
|
||||||
// NOTE: Can't have this as a watch because on a write to it, it reverts back to
|
// NOTE: Can't have this as a watch because on a write to it, it reverts back to
|
||||||
// booted-with value as it does not actually change until reboot.
|
// booted-with value as it does not actually change until reboot.
|
||||||
// self.watch_gpu_mux_mode(signal_ctxt.clone()).await?;
|
self.watch_gpu_mux_mode(signal_ctxt.clone()).await?;
|
||||||
|
self.watch_post_animation_sound(signal_ctxt.clone()).await?;
|
||||||
|
|
||||||
|
self.watch_ppt_pl1_spl(signal_ctxt.clone()).await?;
|
||||||
|
self.watch_ppt_pl2_sppt(signal_ctxt.clone()).await?;
|
||||||
|
self.watch_ppt_fppt(signal_ctxt.clone()).await?;
|
||||||
|
self.watch_ppt_apu_sppt(signal_ctxt.clone()).await?;
|
||||||
|
self.watch_ppt_platform_sppt(signal_ctxt.clone()).await?;
|
||||||
|
self.watch_nv_dynamic_boost(signal_ctxt.clone()).await?;
|
||||||
|
self.watch_nv_temp_target(signal_ctxt.clone()).await?;
|
||||||
|
|
||||||
|
let watch_throttle_thermal_policy = self.platform.monitor_throttle_thermal_policy()?;
|
||||||
|
let ctrl = self.clone();
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
use futures_lite::StreamExt;
|
||||||
|
let mut buffer = [0; 32];
|
||||||
|
if let Ok(mut stream) = watch_throttle_thermal_policy.into_event_stream(&mut buffer) {
|
||||||
|
while (stream.next().await).is_some() {
|
||||||
|
// this blocks
|
||||||
|
debug!("Platform: watch_throttle_thermal_policy changed");
|
||||||
|
if let Ok(profile) = ctrl
|
||||||
|
.platform
|
||||||
|
.get_throttle_thermal_policy()
|
||||||
|
.map(PlatformPolicy::from)
|
||||||
|
.map_err(|e| {
|
||||||
|
error!("Platform: get_throttle_thermal_policy error: {e}");
|
||||||
|
})
|
||||||
|
{
|
||||||
|
if let Some(cpu) = ctrl.cpu_control.as_ref() {
|
||||||
|
info!("PlatformPolicy setting EPP");
|
||||||
|
cpu.set_epp(profile.into()).ok();
|
||||||
|
}
|
||||||
|
ctrl.config.lock().await.platform_policy_to_restore = profile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,287 +0,0 @@
|
|||||||
use std::process::Command;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use config_traits::StdConfig;
|
|
||||||
use log::{error, info, warn};
|
|
||||||
use rog_platform::power::AsusPower;
|
|
||||||
use rog_platform::supported::ChargeSupportedFunctions;
|
|
||||||
use systemd_zbus::{ManagerProxy as SystemdProxy, Mode, UnitFileState};
|
|
||||||
use tokio::time::sleep;
|
|
||||||
use zbus::export::futures_util::lock::Mutex;
|
|
||||||
use zbus::{dbus_interface, Connection, SignalContext};
|
|
||||||
|
|
||||||
use crate::config::Config;
|
|
||||||
use crate::error::RogError;
|
|
||||||
use crate::{CtrlTask, GetSupported};
|
|
||||||
|
|
||||||
const ZBUS_PATH: &str = "/org/asuslinux/Power";
|
|
||||||
const NVIDIA_POWERD: &str = "nvidia-powerd.service";
|
|
||||||
|
|
||||||
impl GetSupported for CtrlPower {
|
|
||||||
type A = ChargeSupportedFunctions;
|
|
||||||
|
|
||||||
fn get_supported() -> Self::A {
|
|
||||||
ChargeSupportedFunctions {
|
|
||||||
charge_level_set: if let Ok(power) = AsusPower::new() {
|
|
||||||
power.has_charge_control_end_threshold()
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct CtrlPower {
|
|
||||||
power: AsusPower,
|
|
||||||
config: Arc<Mutex<Config>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
|
||||||
impl CtrlPower {
|
|
||||||
async fn set_charge_control_end_threshold(
|
|
||||||
&mut self,
|
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
||||||
limit: u8,
|
|
||||||
) -> zbus::fdo::Result<()> {
|
|
||||||
if !(20..=100).contains(&limit) {
|
|
||||||
return Err(RogError::ChargeLimit(limit))?;
|
|
||||||
}
|
|
||||||
self.set(limit)
|
|
||||||
.map_err(|err| {
|
|
||||||
warn!("CtrlCharge: set_limit {}", err);
|
|
||||||
err
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
Self::notify_charge_control_end_threshold(&ctxt, limit)
|
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn charge_control_end_threshold(&self) -> u8 {
|
|
||||||
loop {
|
|
||||||
if let Some(mut config) = self.config.try_lock() {
|
|
||||||
let limit = self
|
|
||||||
.power
|
|
||||||
.get_charge_control_end_threshold()
|
|
||||||
.map_err(|err| {
|
|
||||||
warn!("CtrlCharge: get_charge_control_end_threshold {}", err);
|
|
||||||
err
|
|
||||||
})
|
|
||||||
.unwrap_or(100);
|
|
||||||
|
|
||||||
config.read();
|
|
||||||
config.bat_charge_limit = limit;
|
|
||||||
config.write();
|
|
||||||
|
|
||||||
return config.bat_charge_limit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mains_online(&self) -> bool {
|
|
||||||
if self.power.has_online() {
|
|
||||||
if let Ok(v) = self.power.get_online() {
|
|
||||||
return v == 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
#[dbus_interface(signal)]
|
|
||||||
async fn notify_charge_control_end_threshold(
|
|
||||||
ctxt: &SignalContext<'_>,
|
|
||||||
limit: u8,
|
|
||||||
) -> zbus::Result<()>;
|
|
||||||
|
|
||||||
#[dbus_interface(signal)]
|
|
||||||
async fn notify_mains_online(ctxt: &SignalContext<'_>, on: bool) -> zbus::Result<()>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl crate::ZbusRun for CtrlPower {
|
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
|
||||||
Self::add_to_server_helper(self, ZBUS_PATH, server).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl crate::Reloadable for CtrlPower {
|
|
||||||
async fn reload(&mut self) -> Result<(), RogError> {
|
|
||||||
if let Some(mut config) = self.config.try_lock() {
|
|
||||||
config.read();
|
|
||||||
self.set(config.bat_charge_limit)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CtrlPower {
|
|
||||||
// task_watch_item!(charge_control_end_threshold power);
|
|
||||||
|
|
||||||
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
|
|
||||||
Ok(CtrlPower {
|
|
||||||
power: AsusPower::new()?,
|
|
||||||
config,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn set(&self, limit: u8) -> Result<(), RogError> {
|
|
||||||
if !(20..=100).contains(&limit) {
|
|
||||||
return Err(RogError::ChargeLimit(limit));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.power.set_charge_control_end_threshold(limit)?;
|
|
||||||
|
|
||||||
info!("Battery charge limit: {}", limit);
|
|
||||||
|
|
||||||
if let Some(mut config) = self.config.try_lock() {
|
|
||||||
config.read();
|
|
||||||
config.bat_charge_limit = limit;
|
|
||||||
config.write();
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl CtrlTask for CtrlPower {
|
|
||||||
fn zbus_path() -> &'static str {
|
|
||||||
ZBUS_PATH
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
|
|
||||||
let conn = zbus::Connection::system().await?;
|
|
||||||
let sysd1 = SystemdProxy::new(&conn).await?;
|
|
||||||
let sysd2 = sysd1.clone();
|
|
||||||
let sysd3 = sysd1.clone();
|
|
||||||
|
|
||||||
let power1 = self.clone();
|
|
||||||
let power2 = self.clone();
|
|
||||||
self.create_sys_event_tasks(
|
|
||||||
move || async {},
|
|
||||||
move || {
|
|
||||||
let power = power1.clone();
|
|
||||||
let sysd = sysd1.clone();
|
|
||||||
async move {
|
|
||||||
info!("CtrlCharge reloading charge limit");
|
|
||||||
let lock = power.config.lock().await;
|
|
||||||
power
|
|
||||||
.set(lock.bat_charge_limit)
|
|
||||||
.map_err(|err| {
|
|
||||||
warn!("CtrlCharge: set_limit {}", err);
|
|
||||||
err
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
if lock.disable_nvidia_powerd_on_battery {
|
|
||||||
if let Ok(value) = power.power.get_online() {
|
|
||||||
do_nvidia_powerd_action(&sysd, value == 1).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
move || async {},
|
|
||||||
move || {
|
|
||||||
let power = power2.clone();
|
|
||||||
let sysd = sysd2.clone();
|
|
||||||
async move {
|
|
||||||
info!("CtrlCharge reloading charge limit");
|
|
||||||
let lock = power.config.lock().await;
|
|
||||||
power
|
|
||||||
.set(lock.bat_charge_limit)
|
|
||||||
.map_err(|err| {
|
|
||||||
warn!("CtrlCharge: set_limit {}", err);
|
|
||||||
err
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
if lock.disable_nvidia_powerd_on_battery {
|
|
||||||
if let Ok(value) = power.power.get_online() {
|
|
||||||
do_nvidia_powerd_action(&sysd, value == 1).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let config = self.config.clone();
|
|
||||||
// self.watch_charge_control_end_threshold(signal_ctxt.clone())
|
|
||||||
// .await?;
|
|
||||||
|
|
||||||
let ctrl = self.clone();
|
|
||||||
tokio::spawn(async move {
|
|
||||||
let mut online = 10;
|
|
||||||
loop {
|
|
||||||
if let Ok(value) = ctrl.power.get_online() {
|
|
||||||
if online != value {
|
|
||||||
online = value;
|
|
||||||
let mut config = config.lock().await;
|
|
||||||
config.read();
|
|
||||||
|
|
||||||
if config.disable_nvidia_powerd_on_battery {
|
|
||||||
do_nvidia_powerd_action(&sysd3, value == 1).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
Self::notify_mains_online(&signal_ctxt, value == 1)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let mut prog: Vec<&str> = Vec::new();
|
|
||||||
if value == 1 {
|
|
||||||
// AC ONLINE
|
|
||||||
prog = config.ac_command.split_whitespace().collect();
|
|
||||||
} else if value == 0 {
|
|
||||||
// BATTERY
|
|
||||||
prog = config.bat_command.split_whitespace().collect();
|
|
||||||
}
|
|
||||||
|
|
||||||
if prog.len() > 1 {
|
|
||||||
let mut cmd = Command::new(prog[0]);
|
|
||||||
for arg in prog.iter().skip(1) {
|
|
||||||
cmd.arg(*arg);
|
|
||||||
}
|
|
||||||
if let Err(e) = cmd.spawn() {
|
|
||||||
if value == 1 {
|
|
||||||
error!("AC power command error: {e}");
|
|
||||||
} else {
|
|
||||||
error!("Battery power command error: {e}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// The inotify doesn't pick up events when the kernel changes internal value
|
|
||||||
// so we need to watch it with a thread and sleep unfortunately
|
|
||||||
sleep(Duration::from_secs(1)).await;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn do_nvidia_powerd_action(proxy: &SystemdProxy<'_>, ac_on: bool) {
|
|
||||||
if let Ok(res) = proxy.get_unit_file_state(NVIDIA_POWERD).await {
|
|
||||||
if res == UnitFileState::Enabled {
|
|
||||||
if ac_on {
|
|
||||||
proxy
|
|
||||||
.start_unit(NVIDIA_POWERD, Mode::Replace)
|
|
||||||
.await
|
|
||||||
.map_err(|e| error!("Error stopping {NVIDIA_POWERD}, {e:?}"))
|
|
||||||
.ok();
|
|
||||||
} else {
|
|
||||||
proxy
|
|
||||||
.stop_unit(NVIDIA_POWERD, Mode::Replace)
|
|
||||||
.await
|
|
||||||
.map_err(|e| error!("Error stopping {NVIDIA_POWERD}, {e:?}"))
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use config_traits::{StdConfig, StdConfigLoad};
|
|
||||||
use rog_profiles::fan_curve_set::CurveData;
|
|
||||||
use rog_profiles::Profile;
|
|
||||||
use serde_derive::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use crate::CONFIG_PATH_BASE;
|
|
||||||
|
|
||||||
const CONFIG_FILE: &str = "profile.ron";
|
|
||||||
const CONFIG_FAN_FILE: &str = "fan_curves.ron";
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
|
||||||
pub struct ProfileConfig {
|
|
||||||
/// For restore on boot
|
|
||||||
pub active_profile: Profile,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StdConfig for ProfileConfig {
|
|
||||||
fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
active_profile: Profile::Balanced,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn config_dir() -> std::path::PathBuf {
|
|
||||||
PathBuf::from(CONFIG_PATH_BASE)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn file_name(&self) -> String {
|
|
||||||
CONFIG_FILE.to_owned()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StdConfigLoad for ProfileConfig {}
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug, Default)]
|
|
||||||
pub struct FanCurveConfig {
|
|
||||||
pub balanced: Vec<CurveData>,
|
|
||||||
pub performance: Vec<CurveData>,
|
|
||||||
pub quiet: Vec<CurveData>,
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
Self::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn file_name(&self) -> String {
|
|
||||||
CONFIG_FAN_FILE.to_owned()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn config_dir() -> std::path::PathBuf {
|
|
||||||
PathBuf::from(CONFIG_PATH_BASE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl StdConfigLoad for FanCurveConfig {}
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
use config_traits::{StdConfig, StdConfigLoad};
|
|
||||||
use log::{info, warn};
|
|
||||||
use rog_platform::platform::AsusPlatform;
|
|
||||||
use rog_platform::supported::PlatformProfileFunctions;
|
|
||||||
use rog_profiles::error::ProfileError;
|
|
||||||
use rog_profiles::{FanCurveProfiles, Profile};
|
|
||||||
|
|
||||||
use super::config::{FanCurveConfig, ProfileConfig};
|
|
||||||
use crate::error::RogError;
|
|
||||||
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 profile_config: ProfileConfig,
|
|
||||||
pub fan_curves: Option<FanCurves>,
|
|
||||||
pub platform: AsusPlatform,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GetSupported for CtrlPlatformProfile {
|
|
||||||
type A = PlatformProfileFunctions;
|
|
||||||
|
|
||||||
fn get_supported() -> Self::A {
|
|
||||||
if !Profile::is_platform_profile_supported() {
|
|
||||||
warn!(
|
|
||||||
"platform_profile kernel interface not found, your laptop does not support this, \
|
|
||||||
or the interface is missing."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let res = FanCurveProfiles::supported_fans();
|
|
||||||
|
|
||||||
if res.is_err() {
|
|
||||||
info!(
|
|
||||||
"fan curves kernel interface not found, your laptop does not support this, or the \
|
|
||||||
interface is missing."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
PlatformProfileFunctions {
|
|
||||||
platform_profile: Profile::is_platform_profile_supported(),
|
|
||||||
fans: res.unwrap_or_default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CtrlPlatformProfile {
|
|
||||||
pub fn new(config: ProfileConfig) -> Result<Self, RogError> {
|
|
||||||
let platform = AsusPlatform::new()?;
|
|
||||||
if platform.has_platform_profile() || platform.has_throttle_thermal_policy() {
|
|
||||||
info!("{MOD_NAME}: Device has profile control available");
|
|
||||||
|
|
||||||
let mut controller = CtrlPlatformProfile {
|
|
||||||
profile_config: config,
|
|
||||||
fan_curves: None,
|
|
||||||
platform,
|
|
||||||
};
|
|
||||||
if FanCurveProfiles::get_device().is_ok() {
|
|
||||||
info!("{MOD_NAME}: Device has fan curves available");
|
|
||||||
let fan_config = FanCurveConfig::new();
|
|
||||||
// Only do defaults if the config doesn't already exist
|
|
||||||
if !fan_config.file_path().exists()
|
|
||||||
|| fan_config.balanced.is_empty()
|
|
||||||
|| fan_config.performance.is_empty()
|
|
||||||
|| fan_config.quiet.is_empty()
|
|
||||||
{
|
|
||||||
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 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.
|
|
||||||
let next =
|
|
||||||
Profile::get_next_profile(controller.profile_config.active_profile);
|
|
||||||
Profile::set_profile(next)
|
|
||||||
.map_err(|e| warn!("{MOD_NAME}: set_profile, {}", e))
|
|
||||||
.ok();
|
|
||||||
controller.profile_config.active_profile = next;
|
|
||||||
|
|
||||||
// Make sure to set the baseline to default
|
|
||||||
controller.set_active_curve_to_defaults()?;
|
|
||||||
let active = Profile::get_active_profile().unwrap_or(Profile::Balanced);
|
|
||||||
|
|
||||||
if let Some(curves) = controller.fan_curves.as_ref() {
|
|
||||||
info!("{MOD_NAME}: {active:?}:");
|
|
||||||
for curve in curves.profiles().get_fan_curves_for(active) {
|
|
||||||
info!("{}", String::from(curve));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(ProfileError::NotSupported.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn save_config(&mut self) {
|
|
||||||
self.profile_config.write();
|
|
||||||
if let Some(fans) = self.fan_curves.as_mut() {
|
|
||||||
fans.update_config_from_profiles();
|
|
||||||
fans.config_file.write(); // config write
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the curve for the active profile active
|
|
||||||
pub(super) fn write_profile_curve_to_platform(&mut self) -> Result<(), RogError> {
|
|
||||||
if let Some(curves) = &mut self.fan_curves {
|
|
||||||
if let Ok(mut device) = FanCurveProfiles::get_device() {
|
|
||||||
curves.profiles_mut().write_profile_curve_to_platform(
|
|
||||||
self.profile_config.active_profile,
|
|
||||||
&mut device,
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn set_active_curve_to_defaults(&mut self) -> Result<(), RogError> {
|
|
||||||
if let Some(curves) = self.fan_curves.as_mut() {
|
|
||||||
if let Ok(mut device) = FanCurveProfiles::get_device() {
|
|
||||||
curves.profiles_mut().set_active_curve_to_defaults(
|
|
||||||
self.profile_config.active_profile,
|
|
||||||
&mut device,
|
|
||||||
)?;
|
|
||||||
curves.update_config_from_profiles();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
pub mod config;
|
|
||||||
pub mod controller;
|
|
||||||
/// Implements `CtrlTask`, Reloadable, `ZbusRun`
|
|
||||||
pub mod trait_impls;
|
|
||||||
@@ -1,332 +0,0 @@
|
|||||||
use std::str::FromStr;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use config_traits::StdConfig;
|
|
||||||
use log::{error, info, warn};
|
|
||||||
use rog_profiles::fan_curve_set::CurveData;
|
|
||||||
use rog_profiles::{FanCurvePU, FanCurveProfiles, Profile};
|
|
||||||
use zbus::export::futures_util::lock::Mutex;
|
|
||||||
use zbus::export::futures_util::StreamExt;
|
|
||||||
use zbus::fdo::Error;
|
|
||||||
use zbus::{dbus_interface, Connection, SignalContext};
|
|
||||||
|
|
||||||
use super::controller::CtrlPlatformProfile;
|
|
||||||
use crate::error::RogError;
|
|
||||||
use crate::CtrlTask;
|
|
||||||
|
|
||||||
const MOD_NAME: &str = "ProfileZbus";
|
|
||||||
|
|
||||||
const ZBUS_PATH: &str = "/org/asuslinux/Profile";
|
|
||||||
const UNSUPPORTED_MSG: &str =
|
|
||||||
"Fan curves are not supported on this laptop or you require a patched kernel";
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct ProfileZbus(pub Arc<Mutex<CtrlPlatformProfile>>);
|
|
||||||
|
|
||||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
|
||||||
impl ProfileZbus {
|
|
||||||
/// Fetch profile names
|
|
||||||
fn profiles(&mut self) -> zbus::fdo::Result<Vec<Profile>> {
|
|
||||||
if let Ok(profiles) = Profile::get_profile_names() {
|
|
||||||
return Ok(profiles);
|
|
||||||
}
|
|
||||||
Err(Error::Failed(
|
|
||||||
"Failed to get all profile details".to_owned(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Toggle to next platform_profile. Names provided by `Profiles`.
|
|
||||||
/// If fan-curves are supported will also activate a fan curve for profile.
|
|
||||||
async fn next_profile(&mut self, #[zbus(signal_context)] ctxt: SignalContext<'_>) {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
let next = Profile::get_next_profile(ctrl.profile_config.active_profile);
|
|
||||||
Profile::set_profile(next)
|
|
||||||
.map_err(|e| warn!("{MOD_NAME}: set_profile, {}", e))
|
|
||||||
.ok();
|
|
||||||
ctrl.profile_config.active_profile = next;
|
|
||||||
ctrl.save_config();
|
|
||||||
|
|
||||||
Self::notify_profile(&ctxt, ctrl.profile_config.active_profile)
|
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Fetch the active profile name
|
|
||||||
async fn active_profile(&mut self) -> zbus::fdo::Result<Profile> {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
ctrl.profile_config.read();
|
|
||||||
Ok(ctrl.profile_config.active_profile)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set this platform_profile name as active
|
|
||||||
async fn set_active_profile(
|
|
||||||
&self,
|
|
||||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
||||||
profile: Profile,
|
|
||||||
) {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
// Read first just incase the user has modified the config before calling this
|
|
||||||
ctrl.profile_config.read();
|
|
||||||
Profile::set_profile(profile)
|
|
||||||
.map_err(|e| warn!("{MOD_NAME}: set_profile, {}", e))
|
|
||||||
.ok();
|
|
||||||
ctrl.profile_config.active_profile = profile;
|
|
||||||
ctrl.write_profile_curve_to_platform()
|
|
||||||
.map_err(|e| warn!("{MOD_NAME}: write_profile_curve_to_platform, {}", e))
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
ctrl.save_config();
|
|
||||||
|
|
||||||
Self::notify_profile(&ctxt, ctrl.profile_config.active_profile)
|
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set all fan curves for a profile to enabled status. Will also activate a
|
|
||||||
/// fan curve if in the same profile mode
|
|
||||||
async fn set_fan_curves_enabled(
|
|
||||||
&mut self,
|
|
||||||
profile: Profile,
|
|
||||||
enabled: bool,
|
|
||||||
) -> zbus::fdo::Result<()> {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
ctrl.profile_config.read();
|
|
||||||
if let Some(curves) = &mut ctrl.fan_curves {
|
|
||||||
curves
|
|
||||||
.profiles_mut()
|
|
||||||
.set_profile_curves_enabled(profile, enabled);
|
|
||||||
|
|
||||||
ctrl.write_profile_curve_to_platform()
|
|
||||||
.map_err(|e| warn!("{MOD_NAME}: write_profile_curve_to_platform, {}", e))
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
ctrl.save_config();
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(Error::Failed(UNSUPPORTED_MSG.to_owned()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set a single fan curve for a profile to enabled status. Will also
|
|
||||||
/// activate a fan curve if in the same profile mode
|
|
||||||
async fn set_profile_fan_curve_enabled(
|
|
||||||
&mut self,
|
|
||||||
profile: Profile,
|
|
||||||
fan: FanCurvePU,
|
|
||||||
enabled: bool,
|
|
||||||
) -> zbus::fdo::Result<()> {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
ctrl.profile_config.read();
|
|
||||||
if let Some(curves) = &mut ctrl.fan_curves {
|
|
||||||
curves
|
|
||||||
.profiles_mut()
|
|
||||||
.set_profile_fan_curve_enabled(profile, fan, enabled);
|
|
||||||
|
|
||||||
ctrl.write_profile_curve_to_platform()
|
|
||||||
.map_err(|e| warn!("{MOD_NAME}: write_profile_curve_to_platform, {}", e))
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
ctrl.save_config();
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(Error::Failed(UNSUPPORTED_MSG.to_owned()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the fan-curve data for the currently active Profile
|
|
||||||
async fn fan_curve_data(&mut self, profile: Profile) -> zbus::fdo::Result<Vec<CurveData>> {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
ctrl.profile_config.read();
|
|
||||||
if let Some(curves) = &mut ctrl.fan_curves {
|
|
||||||
let curve = curves.profiles().get_fan_curves_for(profile);
|
|
||||||
return Ok(curve.to_vec());
|
|
||||||
}
|
|
||||||
Err(Error::Failed(UNSUPPORTED_MSG.to_owned()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the fan curve for the specified profile.
|
|
||||||
/// Will also activate the fan curve if the user is in the same mode.
|
|
||||||
async fn set_fan_curve(&self, profile: Profile, curve: CurveData) -> zbus::fdo::Result<()> {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
ctrl.profile_config.read();
|
|
||||||
if let Some(curves) = &mut ctrl.fan_curves {
|
|
||||||
curves
|
|
||||||
.profiles_mut()
|
|
||||||
.save_fan_curve(curve, profile)
|
|
||||||
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
|
||||||
} else {
|
|
||||||
return Err(Error::Failed(UNSUPPORTED_MSG.to_owned()));
|
|
||||||
}
|
|
||||||
ctrl.write_profile_curve_to_platform()
|
|
||||||
.map_err(|e| warn!("{MOD_NAME}: Profile::set_profile, {}", e))
|
|
||||||
.ok();
|
|
||||||
ctrl.save_config();
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reset the stored (self) and device curve to the defaults of the
|
|
||||||
/// platform.
|
|
||||||
///
|
|
||||||
/// Each platform_profile has a different default and the defualt can be
|
|
||||||
/// read only for the currently active profile.
|
|
||||||
async fn set_active_curve_to_defaults(&self) -> zbus::fdo::Result<()> {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
ctrl.profile_config.read();
|
|
||||||
ctrl.set_active_curve_to_defaults()
|
|
||||||
.map_err(|e| warn!("{MOD_NAME}: Profile::set_active_curve_to_defaults, {}", e))
|
|
||||||
.ok();
|
|
||||||
ctrl.save_config();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reset the stored (self) and device curve to the defaults of the
|
|
||||||
/// platform.
|
|
||||||
///
|
|
||||||
/// Each platform_profile has a different default and the defualt can be
|
|
||||||
/// read only for the currently active profile.
|
|
||||||
async fn reset_profile_curves(&self, profile: Profile) -> zbus::fdo::Result<()> {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
ctrl.profile_config.read();
|
|
||||||
let active = Profile::get_active_profile().unwrap_or(Profile::Balanced);
|
|
||||||
|
|
||||||
Profile::set_profile(profile)
|
|
||||||
.map_err(|e| warn!("{MOD_NAME}: set_profile, {}", e))
|
|
||||||
.ok();
|
|
||||||
ctrl.set_active_curve_to_defaults()
|
|
||||||
.map_err(|e| warn!("{MOD_NAME}: Profile::set_active_curve_to_defaults, {}", e))
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
Profile::set_profile(active)
|
|
||||||
.map_err(|e| warn!("{MOD_NAME}: set_profile, {}", e))
|
|
||||||
.ok();
|
|
||||||
ctrl.save_config();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[dbus_interface(signal)]
|
|
||||||
async fn notify_profile(signal_ctxt: &SignalContext<'_>, profile: Profile) -> zbus::Result<()> {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl crate::ZbusRun for ProfileZbus {
|
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
|
||||||
Self::add_to_server_helper(self, ZBUS_PATH, server).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl CtrlTask for ProfileZbus {
|
|
||||||
fn zbus_path() -> &'static str {
|
|
||||||
ZBUS_PATH
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn create_tasks(&self, signal_ctxt: SignalContext<'static>) -> Result<(), RogError> {
|
|
||||||
let ctrl = self.0.clone();
|
|
||||||
let sig_ctx = signal_ctxt.clone();
|
|
||||||
let watch = self
|
|
||||||
.0
|
|
||||||
.lock()
|
|
||||||
.await
|
|
||||||
.platform
|
|
||||||
.monitor_throttle_thermal_policy()?;
|
|
||||||
|
|
||||||
tokio::spawn(async move {
|
|
||||||
let mut buffer = [0; 32];
|
|
||||||
if let Ok(stream) = watch.into_event_stream(&mut buffer) {
|
|
||||||
stream
|
|
||||||
.for_each(|_| async {
|
|
||||||
let mut lock = ctrl.lock().await;
|
|
||||||
if let Ok(profile) =
|
|
||||||
lock.platform.get_throttle_thermal_policy().map_err(|e| {
|
|
||||||
error!("{MOD_NAME}: get_throttle_thermal_policy error: {e}");
|
|
||||||
})
|
|
||||||
{
|
|
||||||
let new_profile = Profile::from_throttle_thermal_policy(profile);
|
|
||||||
if new_profile != lock.profile_config.active_profile {
|
|
||||||
info!("{MOD_NAME}: platform_profile changed to {new_profile}");
|
|
||||||
lock.profile_config.active_profile = new_profile;
|
|
||||||
lock.write_profile_curve_to_platform().unwrap();
|
|
||||||
lock.save_config();
|
|
||||||
Profile::set_profile(lock.profile_config.active_profile)
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("Profile::set_profile() error: {e}");
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
Self::notify_profile(&sig_ctx, lock.profile_config.active_profile)
|
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let ctrl = self.0.clone();
|
|
||||||
let watch = self.0.lock().await.platform.monitor_platform_profile()?;
|
|
||||||
|
|
||||||
tokio::spawn(async move {
|
|
||||||
let mut buffer = [0; 32];
|
|
||||||
if let Ok(stream) = watch.into_event_stream(&mut buffer) {
|
|
||||||
stream
|
|
||||||
.for_each(|_| async {
|
|
||||||
let mut lock = ctrl.lock().await;
|
|
||||||
if let Ok(profile) = lock.platform.get_platform_profile().map_err(|e| {
|
|
||||||
error!("get_platform_profile error: {e}");
|
|
||||||
}) {
|
|
||||||
if let Ok(new_profile) = Profile::from_str(&profile).map_err(|e| {
|
|
||||||
error!("Profile::from_str(&profile) error: {e}");
|
|
||||||
}) {
|
|
||||||
if new_profile != lock.profile_config.active_profile {
|
|
||||||
info!("{MOD_NAME}: platform_profile changed to {new_profile}");
|
|
||||||
lock.profile_config.active_profile = new_profile;
|
|
||||||
lock.write_profile_curve_to_platform().unwrap();
|
|
||||||
lock.save_config();
|
|
||||||
Profile::set_profile(lock.profile_config.active_profile)
|
|
||||||
.map_err(|e| {
|
|
||||||
error!("Profile::set_profile() error: {e}");
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
Self::notify_profile(
|
|
||||||
&signal_ctxt,
|
|
||||||
lock.profile_config.active_profile,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl crate::Reloadable for ProfileZbus {
|
|
||||||
/// Fetch the active profile and use that to set all related components up
|
|
||||||
async fn reload(&mut self) -> Result<(), RogError> {
|
|
||||||
let mut ctrl = self.0.lock().await;
|
|
||||||
let active = ctrl.profile_config.active_profile;
|
|
||||||
if let Some(curves) = &mut ctrl.fan_curves {
|
|
||||||
if let Ok(mut device) = FanCurveProfiles::get_device() {
|
|
||||||
// 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
|
|
||||||
// after
|
|
||||||
curves
|
|
||||||
.profiles_mut()
|
|
||||||
.write_profile_curve_to_platform(active, &mut device)?;
|
|
||||||
ctrl.profile_config.write();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
use async_trait::async_trait;
|
|
||||||
use serde_derive::{Deserialize, Serialize};
|
|
||||||
use zbus::zvariant::Type;
|
|
||||||
use zbus::{dbus_interface, Connection};
|
|
||||||
|
|
||||||
use crate::ctrl_anime::CtrlAnime;
|
|
||||||
use crate::ctrl_aura::controller::CtrlKbdLed;
|
|
||||||
use crate::ctrl_platform::CtrlPlatform;
|
|
||||||
use crate::ctrl_power::CtrlPower;
|
|
||||||
use crate::ctrl_profiles::controller::CtrlPlatformProfile;
|
|
||||||
use crate::GetSupported;
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Type)]
|
|
||||||
pub struct SupportedFunctions(rog_platform::supported::SupportedFunctions);
|
|
||||||
|
|
||||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
|
||||||
impl SupportedFunctions {
|
|
||||||
pub fn supported_functions(
|
|
||||||
&self,
|
|
||||||
) -> zbus::fdo::Result<&rog_platform::supported::SupportedFunctions> {
|
|
||||||
Ok(&self.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[dbus_interface(out_args("answer", "question"))]
|
|
||||||
fn meaning_of_life(&self) -> zbus::fdo::Result<(i32, String)> {
|
|
||||||
Ok((42, String::from("Meaning of life")))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl crate::ZbusRun for SupportedFunctions {
|
|
||||||
async fn add_to_server(self, server: &mut Connection) {
|
|
||||||
Self::add_to_server_helper(self, "/org/asuslinux/Supported", server).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GetSupported for SupportedFunctions {
|
|
||||||
type A = SupportedFunctions;
|
|
||||||
|
|
||||||
fn get_supported() -> Self::A {
|
|
||||||
Self(rog_platform::supported::SupportedFunctions {
|
|
||||||
anime_ctrl: CtrlAnime::get_supported(),
|
|
||||||
keyboard_led: CtrlKbdLed::get_supported(),
|
|
||||||
charge_ctrl: CtrlPower::get_supported(),
|
|
||||||
platform_profile: CtrlPlatformProfile::get_supported(),
|
|
||||||
rog_bios_ctrl: CtrlPlatform::get_supported(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,19 +11,13 @@ use asusd::ctrl_anime::config::AnimeConfig;
|
|||||||
use asusd::ctrl_anime::trait_impls::CtrlAnimeZbus;
|
use asusd::ctrl_anime::trait_impls::CtrlAnimeZbus;
|
||||||
use asusd::ctrl_anime::CtrlAnime;
|
use asusd::ctrl_anime::CtrlAnime;
|
||||||
use asusd::ctrl_aura::controller::CtrlKbdLed;
|
use asusd::ctrl_aura::controller::CtrlKbdLed;
|
||||||
use asusd::ctrl_aura::trait_impls::CtrlKbdLedZbus;
|
use asusd::ctrl_aura::trait_impls::CtrlAuraZbus;
|
||||||
|
use asusd::ctrl_fancurves::CtrlFanCurveZbus;
|
||||||
use asusd::ctrl_platform::CtrlPlatform;
|
use asusd::ctrl_platform::CtrlPlatform;
|
||||||
use asusd::ctrl_power::CtrlPower;
|
use asusd::{print_board_info, CtrlTask, Reloadable, ZbusRun, DBUS_NAME};
|
||||||
use asusd::ctrl_profiles::config::ProfileConfig;
|
use config_traits::{StdConfig, StdConfigLoad2};
|
||||||
use asusd::ctrl_profiles::controller::CtrlPlatformProfile;
|
|
||||||
use asusd::ctrl_profiles::trait_impls::ProfileZbus;
|
|
||||||
use asusd::ctrl_supported::SupportedFunctions;
|
|
||||||
use asusd::{print_board_info, CtrlTask, GetSupported, Reloadable, ZbusRun};
|
|
||||||
use config_traits::{StdConfig, StdConfigLoad, StdConfigLoad2};
|
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use rog_aura::aura_detection::LaptopLedData;
|
use rog_aura::aura_detection::LaptopLedData;
|
||||||
use rog_dbus::DBUS_NAME;
|
|
||||||
use rog_profiles::Profile;
|
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use zbus::SignalContext;
|
use zbus::SignalContext;
|
||||||
|
|
||||||
@@ -53,7 +47,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
info!(" daemon v{}", asusd::VERSION);
|
info!(" daemon v{}", asusd::VERSION);
|
||||||
info!(" rog-anime v{}", rog_anime::VERSION);
|
info!(" rog-anime v{}", rog_anime::VERSION);
|
||||||
info!(" rog-aura v{}", rog_aura::VERSION);
|
info!(" rog-aura v{}", rog_aura::VERSION);
|
||||||
info!(" rog-dbus v{}", rog_dbus::VERSION);
|
|
||||||
info!(" rog-profiles v{}", rog_profiles::VERSION);
|
info!(" rog-profiles v{}", rog_profiles::VERSION);
|
||||||
info!("rog-platform v{}", rog_platform::VERSION);
|
info!("rog-platform v{}", rog_platform::VERSION);
|
||||||
|
|
||||||
@@ -63,9 +56,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
/// The actual main loop for the daemon
|
/// The actual main loop for the daemon
|
||||||
async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
||||||
let supported = SupportedFunctions::get_supported();
|
// let supported = SupportedFunctions::get_supported();
|
||||||
print_board_info();
|
print_board_info();
|
||||||
println!("{:?}", supported.supported_functions());
|
// println!("{:?}", supported.supported_functions());
|
||||||
|
|
||||||
// Start zbus server
|
// Start zbus server
|
||||||
let mut connection = Connection::system().await?;
|
let mut connection = Connection::system().await?;
|
||||||
@@ -73,7 +66,7 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
let config = Config::new().load();
|
let config = Config::new().load();
|
||||||
let config = Arc::new(Mutex::new(config));
|
let config = Arc::new(Mutex::new(config));
|
||||||
|
|
||||||
supported.add_to_server(&mut connection).await;
|
// supported.add_to_server(&mut connection).await;
|
||||||
|
|
||||||
match CtrlPlatform::new(config.clone()) {
|
match CtrlPlatform::new(config.clone()) {
|
||||||
Ok(ctrl) => {
|
Ok(ctrl) => {
|
||||||
@@ -85,32 +78,16 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match CtrlPower::new(config.clone()) {
|
match CtrlFanCurveZbus::new() {
|
||||||
Ok(ctrl) => {
|
Ok(ctrl) => {
|
||||||
let sig_ctx = CtrlPower::signal_context(&connection)?;
|
let sig_ctx = CtrlFanCurveZbus::signal_context(&connection)?;
|
||||||
start_tasks(ctrl, &mut connection, sig_ctx).await?;
|
start_tasks(ctrl, &mut connection, sig_ctx).await?;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("CtrlPower: {}", err);
|
error!("FanCurves: {}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if Profile::is_platform_profile_supported() {
|
|
||||||
let profile_config = ProfileConfig::new().load();
|
|
||||||
match CtrlPlatformProfile::new(profile_config) {
|
|
||||||
Ok(ctrl) => {
|
|
||||||
let zbus = ProfileZbus(Arc::new(Mutex::new(ctrl)));
|
|
||||||
let sig_ctx = ProfileZbus::signal_context(&connection)?;
|
|
||||||
start_tasks(zbus, &mut connection, sig_ctx).await?;
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
error!("Profile control: {}", err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
warn!("platform_profile support not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
match CtrlAnime::new(AnimeConfig::new().load()) {
|
match CtrlAnime::new(AnimeConfig::new().load()) {
|
||||||
Ok(ctrl) => {
|
Ok(ctrl) => {
|
||||||
let zbus = CtrlAnimeZbus(Arc::new(Mutex::new(ctrl)));
|
let zbus = CtrlAnimeZbus(Arc::new(Mutex::new(ctrl)));
|
||||||
@@ -127,8 +104,8 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
// detection first
|
// detection first
|
||||||
match CtrlKbdLed::new(laptop) {
|
match CtrlKbdLed::new(laptop) {
|
||||||
Ok(ctrl) => {
|
Ok(ctrl) => {
|
||||||
let zbus = CtrlKbdLedZbus(Arc::new(Mutex::new(ctrl)));
|
let zbus = CtrlAuraZbus(Arc::new(Mutex::new(ctrl)));
|
||||||
let sig_ctx = CtrlKbdLedZbus::signal_context(&connection)?;
|
let sig_ctx = CtrlAuraZbus::signal_context(&connection)?;
|
||||||
start_tasks(zbus, &mut connection, sig_ctx).await?;
|
start_tasks(zbus, &mut connection, sig_ctx).await?;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
|
|||||||
151
asusd/src/lib.rs
151
asusd/src/lib.rs
@@ -5,30 +5,31 @@ pub mod config;
|
|||||||
pub mod ctrl_anime;
|
pub mod ctrl_anime;
|
||||||
/// Keyboard LED brightness control, RGB, and LED display modes
|
/// Keyboard LED brightness control, RGB, and LED display modes
|
||||||
pub mod ctrl_aura;
|
pub mod ctrl_aura;
|
||||||
|
/// Control platform profiles + fan-curves if available
|
||||||
|
pub mod ctrl_fancurves;
|
||||||
/// Control ASUS bios function such as boot sound, Optimus/Dedicated gfx mode
|
/// Control ASUS bios function such as boot sound, Optimus/Dedicated gfx mode
|
||||||
pub mod ctrl_platform;
|
pub mod ctrl_platform;
|
||||||
/// Control of battery charge level
|
|
||||||
pub mod ctrl_power;
|
|
||||||
/// Control platform profiles + fan-curves if available
|
|
||||||
pub mod ctrl_profiles;
|
|
||||||
|
|
||||||
/// Fetch all supported functions for the laptop
|
|
||||||
pub mod ctrl_supported;
|
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use dmi_id::DMIID;
|
||||||
|
use futures_lite::stream::StreamExt;
|
||||||
use log::{debug, info, warn};
|
use log::{debug, info, warn};
|
||||||
use logind_zbus::manager::ManagerProxy;
|
use logind_zbus::manager::ManagerProxy;
|
||||||
use zbus::export::futures_util::StreamExt;
|
use tokio::time::sleep;
|
||||||
use zbus::zvariant::ObjectPath;
|
use zbus::zvariant::ObjectPath;
|
||||||
use zbus::{Connection, SignalContext};
|
use zbus::{CacheProperties, Connection, SignalContext};
|
||||||
|
|
||||||
use crate::error::RogError;
|
use crate::error::RogError;
|
||||||
|
|
||||||
const CONFIG_PATH_BASE: &str = "/etc/asusd/";
|
const CONFIG_PATH_BASE: &str = "/etc/asusd/";
|
||||||
|
pub static DBUS_NAME: &str = "org.asuslinux.Daemon";
|
||||||
|
pub static DBUS_PATH: &str = "/org/asuslinux/Daemon";
|
||||||
|
pub static DBUS_IFACE: &str = "org.asuslinux.Daemon";
|
||||||
|
|
||||||
/// This macro adds a function which spawns an `inotify` task on the passed in
|
/// This macro adds a function which spawns an `inotify` task on the passed in
|
||||||
/// `Executor`.
|
/// `Executor`.
|
||||||
@@ -46,7 +47,7 @@ const CONFIG_PATH_BASE: &str = "/etc/asusd/";
|
|||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```ignore
|
/// ```ignore
|
||||||
/// impl CtrlRogBios {
|
/// impl RogPlatform {
|
||||||
/// task_watch_item!(panel_od platform);
|
/// task_watch_item!(panel_od platform);
|
||||||
/// task_watch_item!(gpu_mux_mode platform);
|
/// task_watch_item!(gpu_mux_mode platform);
|
||||||
/// }
|
/// }
|
||||||
@@ -69,9 +70,45 @@ macro_rules! task_watch_item {
|
|||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut buffer = [0; 32];
|
let mut buffer = [0; 32];
|
||||||
watch.into_event_stream(&mut buffer).unwrap().for_each(|_| async {
|
watch.into_event_stream(&mut buffer).unwrap().for_each(|_| async {
|
||||||
let value = ctrl.$name();
|
if let Ok(value) = ctrl.$name() { // get new value from zbus method
|
||||||
concat_idents::concat_idents!(notif_fn = notify_, $name {
|
concat_idents::concat_idents!(notif_fn = $name, _changed {
|
||||||
Self::notif_fn(&signal_ctxt, value).await.ok();
|
ctrl.notif_fn(&signal_ctxt).await.ok();
|
||||||
|
});
|
||||||
|
let mut lock = ctrl.config.lock().await;
|
||||||
|
lock.$name = value;
|
||||||
|
lock.write();
|
||||||
|
}
|
||||||
|
}).await;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Err(e) => info!("inotify watch failed: {}. You can ignore this if your device does not support the feature", e),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! task_watch_item_notify {
|
||||||
|
($name:ident $self_inner:ident) => {
|
||||||
|
concat_idents::concat_idents!(fn_name = watch_, $name {
|
||||||
|
async fn fn_name(
|
||||||
|
&self,
|
||||||
|
signal_ctxt: SignalContext<'static>,
|
||||||
|
) -> Result<(), RogError> {
|
||||||
|
use zbus::export::futures_util::StreamExt;
|
||||||
|
|
||||||
|
let ctrl = self.clone();
|
||||||
|
concat_idents::concat_idents!(watch_fn = monitor_, $name {
|
||||||
|
match self.$self_inner.watch_fn() {
|
||||||
|
Ok(watch) => {
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let mut buffer = [0; 32];
|
||||||
|
watch.into_event_stream(&mut buffer).unwrap().for_each(|_| async {
|
||||||
|
concat_idents::concat_idents!(notif_fn = $name, _changed {
|
||||||
|
ctrl.notif_fn(&signal_ctxt).await.ok();
|
||||||
});
|
});
|
||||||
}).await;
|
}).await;
|
||||||
});
|
});
|
||||||
@@ -88,12 +125,9 @@ macro_rules! task_watch_item {
|
|||||||
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|
||||||
pub fn print_board_info() {
|
pub fn print_board_info() {
|
||||||
let dmi = sysfs_class::DmiId::default();
|
let dmi = DMIID::new().unwrap_or_default();
|
||||||
let board_name = dmi.board_name().expect("Could not get board_name");
|
info!("Product family: {}", dmi.product_family);
|
||||||
let prod_family = dmi.product_family().expect("Could not get product_family");
|
info!("Board name: {}", dmi.board_name);
|
||||||
|
|
||||||
info!("Product family: {}", prod_family.trim());
|
|
||||||
info!("Board name: {}", board_name.trim());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
@@ -163,15 +197,15 @@ pub trait CtrlTask {
|
|||||||
F4: Send + 'static,
|
F4: Send + 'static,
|
||||||
>(
|
>(
|
||||||
&self,
|
&self,
|
||||||
mut on_sleep: F1,
|
mut on_prepare_for_sleep: F1,
|
||||||
mut on_wake: F2,
|
mut on_prepare_for_shutdown: F2,
|
||||||
mut on_shutdown: F3,
|
mut on_lid_change: F3,
|
||||||
mut on_boot: F4,
|
mut on_external_power_change: F4,
|
||||||
) where
|
) where
|
||||||
F1: FnMut() -> Fut1,
|
F1: FnMut(bool) -> Fut1,
|
||||||
F2: FnMut() -> Fut2,
|
F2: FnMut(bool) -> Fut2,
|
||||||
F3: FnMut() -> Fut3,
|
F3: FnMut(bool) -> Fut3,
|
||||||
F4: FnMut() -> Fut4,
|
F4: FnMut(bool) -> Fut4,
|
||||||
Fut1: Future<Output = ()> + Send,
|
Fut1: Future<Output = ()> + Send,
|
||||||
Fut2: Future<Output = ()> + Send,
|
Fut2: Future<Output = ()> + Send,
|
||||||
Fut3: Future<Output = ()> + Send,
|
Fut3: Future<Output = ()> + Send,
|
||||||
@@ -181,45 +215,66 @@ pub trait CtrlTask {
|
|||||||
.await
|
.await
|
||||||
.expect("Controller could not create dbus connection");
|
.expect("Controller could not create dbus connection");
|
||||||
|
|
||||||
let manager = ManagerProxy::new(&connection)
|
let manager = ManagerProxy::builder(&connection)
|
||||||
|
.cache_properties(CacheProperties::No)
|
||||||
|
.build()
|
||||||
.await
|
.await
|
||||||
.expect("Controller could not create ManagerProxy");
|
.expect("Controller could not create ManagerProxy");
|
||||||
|
|
||||||
|
let manager1 = manager.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
if let Ok(mut notif) = manager.receive_prepare_for_sleep().await {
|
if let Ok(mut notif) = manager1.receive_prepare_for_shutdown().await {
|
||||||
while let Some(event) = notif.next().await {
|
while let Some(event) = notif.next().await {
|
||||||
|
// blocks thread :|
|
||||||
if let Ok(args) = event.args() {
|
if let Ok(args) = event.args() {
|
||||||
if args.start {
|
debug!("Doing on_prepare_for_shutdown({})", args.start);
|
||||||
debug!("Doing on_sleep()");
|
on_prepare_for_shutdown(args.start).await;
|
||||||
on_sleep().await;
|
|
||||||
} else if !args.start() {
|
|
||||||
debug!("Doing on_wake()");
|
|
||||||
on_wake().await;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let manager = ManagerProxy::new(&connection)
|
let manager2 = manager.clone();
|
||||||
.await
|
|
||||||
.expect("Controller could not create ManagerProxy");
|
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
if let Ok(mut notif) = manager.receive_prepare_for_shutdown().await {
|
if let Ok(mut notif) = manager2.receive_prepare_for_sleep().await {
|
||||||
while let Some(event) = notif.next().await {
|
while let Some(event) = notif.next().await {
|
||||||
|
// blocks thread :|
|
||||||
if let Ok(args) = event.args() {
|
if let Ok(args) = event.args() {
|
||||||
if args.start {
|
debug!("Doing on_prepare_for_sleep({})", args.start);
|
||||||
debug!("Doing on_shutdown()");
|
on_prepare_for_sleep(args.start).await;
|
||||||
on_shutdown().await;
|
|
||||||
} else if !args.start() {
|
|
||||||
debug!("Doing on_boot()");
|
|
||||||
on_boot().await;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let manager3 = manager.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let mut last_power = manager3.on_external_power().await.unwrap_or_default();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if let Ok(next) = manager3.on_external_power().await {
|
||||||
|
if next != last_power {
|
||||||
|
last_power = next;
|
||||||
|
on_external_power_change(next).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sleep(Duration::from_secs(2)).await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let mut last_lid = manager.lid_closed().await.unwrap_or_default();
|
||||||
|
// need to loop on these as they don't emit signals
|
||||||
|
loop {
|
||||||
|
if let Ok(next) = manager.lid_closed().await {
|
||||||
|
if next != last_lid {
|
||||||
|
last_lid = next;
|
||||||
|
on_lid_change(next).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sleep(Duration::from_secs(2)).await;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,39 +8,6 @@
|
|||||||
<method name="Write">
|
<method name="Write">
|
||||||
<arg name="input" type="(ays)" direction="in"/>
|
<arg name="input" type="(ays)" direction="in"/>
|
||||||
</method>
|
</method>
|
||||||
<!--
|
|
||||||
Set the global AniMe brightness
|
|
||||||
-->
|
|
||||||
<method name="SetImageBrightness">
|
|
||||||
<arg name="bright" type="d" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Set base brightness level
|
|
||||||
-->
|
|
||||||
<method name="SetBrightness">
|
|
||||||
<arg name="brightness" type="s" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Enable the builtin animations or not
|
|
||||||
-->
|
|
||||||
<method name="SetBuiltinsEnabled">
|
|
||||||
<arg name="enabled" type="b" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Set which builtin animation is used for each stage
|
|
||||||
-->
|
|
||||||
<method name="SetBuiltinAnimations">
|
|
||||||
<arg name="boot" type="s" direction="in"/>
|
|
||||||
<arg name="awake" type="s" direction="in"/>
|
|
||||||
<arg name="sleep" type="s" direction="in"/>
|
|
||||||
<arg name="shutdown" type="s" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Set whether the AniMe is enabled at all
|
|
||||||
-->
|
|
||||||
<method name="SetEnableDisplay">
|
|
||||||
<arg name="enabled" type="b" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
<!--
|
||||||
The main loop is the base system set action if the user isn't running
|
The main loop is the base system set action if the user isn't running
|
||||||
the user daemon
|
the user daemon
|
||||||
@@ -52,14 +19,39 @@
|
|||||||
Get the device state as stored by asusd
|
Get the device state as stored by asusd
|
||||||
-->
|
-->
|
||||||
<method name="DeviceState">
|
<method name="DeviceState">
|
||||||
<arg type="bsb(ssss)" direction="out"/>
|
<arg type="(bub(ssss)bbbu)" direction="out"/>
|
||||||
</method>
|
</method>
|
||||||
<!--
|
<!--
|
||||||
Notify listeners of the status of AniMe LED power and factory
|
Set base brightness level
|
||||||
system-status animations
|
|
||||||
-->
|
-->
|
||||||
<signal name="NotifyDeviceState">
|
<!--
|
||||||
<arg name="data" type="(bsb(ssss))"/>
|
Set base brightness level
|
||||||
</signal>
|
-->
|
||||||
|
<property name="Brightness" type="u" access="readwrite"/>
|
||||||
|
<!--
|
||||||
|
Set which builtin animation is used for each stage
|
||||||
|
-->
|
||||||
|
<property name="BuiltinAnimations" type="(ssss)" access="readwrite"/>
|
||||||
|
<!--
|
||||||
|
Enable the builtin animations or not. This is quivalent to "Powersave
|
||||||
|
animations" in Armory crate
|
||||||
|
-->
|
||||||
|
<property name="BuiltinsEnabled" type="b" access="readwrite"/>
|
||||||
|
<!--
|
||||||
|
Set whether the AniMe is enabled at all
|
||||||
|
-->
|
||||||
|
<property name="EnableDisplay" type="b" access="readwrite"/>
|
||||||
|
<!--
|
||||||
|
Set if to turn the AniMe Matrix off when the lid is closed
|
||||||
|
-->
|
||||||
|
<property name="OffWhenLidClosed" type="b" access="readwrite"/>
|
||||||
|
<!--
|
||||||
|
Set if to turn the AniMe Matrix off when the laptop is suspended
|
||||||
|
-->
|
||||||
|
<property name="OffWhenSuspended" type="b" access="readwrite"/>
|
||||||
|
<!--
|
||||||
|
Set if to turn the AniMe Matrix off when external power is unplugged
|
||||||
|
-->
|
||||||
|
<property name="OffWhenUnplugged" type="b" access="readwrite"/>
|
||||||
</interface>
|
</interface>
|
||||||
</node>
|
</node>
|
||||||
|
|||||||
@@ -2,52 +2,10 @@
|
|||||||
<node>
|
<node>
|
||||||
<interface name="org.asuslinux.Daemon">
|
<interface name="org.asuslinux.Daemon">
|
||||||
<!--
|
<!--
|
||||||
Set the keyboard brightness level (0-3)
|
Get the data set for every mode available
|
||||||
-->
|
-->
|
||||||
<method name="SetBrightness">
|
<method name="AllModeData">
|
||||||
<arg name="brightness" type="s" direction="in"/>
|
<arg type="a{u(us(yyy)(yyy)ss)}" direction="out"/>
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Set a variety of states, input is array of enum.
|
|
||||||
`enabled` sets if the sent array should be disabled or enabled
|
|
||||||
|
|
||||||
For Modern ROG devices the "enabled" flag is ignored.
|
|
||||||
-->
|
|
||||||
<method name="SetLedPower">
|
|
||||||
<arg name="options" type="(asas((sbbbb)(sbbbb)(sbbbb)(sbbbb)(sbbbb)))" direction="in"/>
|
|
||||||
<arg name="enabled" type="b" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<method name="SetLedMode">
|
|
||||||
<arg name="effect" type="(ss(yyy)(yyy)ss)" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<method name="NextLedMode">
|
|
||||||
</method>
|
|
||||||
<method name="PrevLedMode">
|
|
||||||
</method>
|
|
||||||
<method name="NextLedBrightness">
|
|
||||||
</method>
|
|
||||||
<method name="PrevLedBrightness">
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Return the device type for this Aura keyboard
|
|
||||||
-->
|
|
||||||
<method name="DeviceType">
|
|
||||||
<arg type="s" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<method name="LedPower">
|
|
||||||
<arg type="asas((sbbbb)(sbbbb)(sbbbb)(sbbbb)(sbbbb))" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Return the current mode data
|
|
||||||
-->
|
|
||||||
<method name="LedMode">
|
|
||||||
<arg type="s" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Return a list of available modes
|
|
||||||
-->
|
|
||||||
<method name="LedModes">
|
|
||||||
<arg type="a{s(ss(yyy)(yyy)ss)}" direction="out"/>
|
|
||||||
</method>
|
</method>
|
||||||
<!--
|
<!--
|
||||||
On machine that have some form of either per-key keyboard or per-zone
|
On machine that have some form of either per-key keyboard or per-zone
|
||||||
@@ -57,15 +15,51 @@
|
|||||||
<method name="DirectAddressingRaw">
|
<method name="DirectAddressingRaw">
|
||||||
<arg name="data" type="aay" direction="in"/>
|
<arg name="data" type="aay" direction="in"/>
|
||||||
</method>
|
</method>
|
||||||
<signal name="NotifyLed">
|
|
||||||
<arg name="data" type="(ss(yyy)(yyy)ss)"/>
|
|
||||||
</signal>
|
|
||||||
<signal name="NotifyPowerStates">
|
|
||||||
<arg name="data" type="(asas((sbbbb)(sbbbb)(sbbbb)(sbbbb)(sbbbb)))"/>
|
|
||||||
</signal>
|
|
||||||
<!--
|
<!--
|
||||||
Return the current LED brightness
|
Return the current LED brightness
|
||||||
-->
|
-->
|
||||||
<property name="LedBrightness" type="n" access="read"/>
|
<!--
|
||||||
|
Set the keyboard brightness level (0-3)
|
||||||
|
-->
|
||||||
|
<property name="Brightness" type="u" access="readwrite"/>
|
||||||
|
<!--
|
||||||
|
Return the device type for this Aura keyboard
|
||||||
|
-->
|
||||||
|
<property name="DeviceType" type="s" access="read"/>
|
||||||
|
<!--
|
||||||
|
The current mode data
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
Set an Aura effect if the effect mode or zone is supported.
|
||||||
|
|
||||||
|
On success the aura config file is read to refresh cached values, then
|
||||||
|
the effect is stored and config written to disk.
|
||||||
|
-->
|
||||||
|
<property name="LedMode" type="u" access="readwrite"/>
|
||||||
|
<!--
|
||||||
|
The current mode data
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
Set an Aura effect if the effect mode or zone is supported.
|
||||||
|
|
||||||
|
On success the aura config file is read to refresh cached values, then
|
||||||
|
the effect is stored and config written to disk.
|
||||||
|
-->
|
||||||
|
<property name="LedModeData" type="(us(yyy)(yyy)ss)" access="readwrite"/>
|
||||||
|
<!--
|
||||||
|
Set a variety of states, input is array of enum.
|
||||||
|
`enabled` sets if the sent array should be disabled or enabled
|
||||||
|
|
||||||
|
For Modern ROG devices the "enabled" flag is ignored.
|
||||||
|
-->
|
||||||
|
<property name="LedPower" type="(asas((sbbbb)(sbbbb)(sbbbb)(sbbbb)(sbbbb)))" access="readwrite"/>
|
||||||
|
<!--
|
||||||
|
Total levels of brightness available
|
||||||
|
-->
|
||||||
|
<property name="SupportedBrightness" type="au" access="read"/>
|
||||||
|
<!--
|
||||||
|
The total available modes
|
||||||
|
-->
|
||||||
|
<property name="SupportedModes" type="au" access="read"/>
|
||||||
</interface>
|
</interface>
|
||||||
</node>
|
</node>
|
||||||
|
|||||||
@@ -2,49 +2,28 @@
|
|||||||
<node>
|
<node>
|
||||||
<interface name="org.asuslinux.Daemon">
|
<interface name="org.asuslinux.Daemon">
|
||||||
<!--
|
<!--
|
||||||
Fetch profile names
|
Set all fan curves for a profile to enabled status. Will also activate a
|
||||||
|
fan curve if in the same profile mode
|
||||||
-->
|
-->
|
||||||
<method name="Profiles">
|
<method name="SetFanCurvesEnabled">
|
||||||
<arg type="as" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Toggle to next platform_profile. Names provided by `Profiles`.
|
|
||||||
If fan-curves are supported will also activate a fan curve for profile.
|
|
||||||
-->
|
|
||||||
<method name="NextProfile">
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Fetch the active profile name
|
|
||||||
-->
|
|
||||||
<method name="ActiveProfile">
|
|
||||||
<arg type="s" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Set this platform_profile name as active
|
|
||||||
-->
|
|
||||||
<method name="SetActiveProfile">
|
|
||||||
<arg name="profile" type="s" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Get a list of profiles that have fan-curves enabled.
|
|
||||||
-->
|
|
||||||
<method name="EnabledFanProfiles">
|
|
||||||
<arg type="as" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
|
||||||
Set a profile fan curve enabled status. Will also activate a fan curve
|
|
||||||
if in the same profile mode
|
|
||||||
-->
|
|
||||||
<method name="SetFanCurveEnabled">
|
|
||||||
<arg name="profile" type="s" direction="in"/>
|
<arg name="profile" type="s" direction="in"/>
|
||||||
<arg name="enabled" type="b" direction="in"/>
|
<arg name="enabled" type="b" direction="in"/>
|
||||||
</method>
|
</method>
|
||||||
<!--
|
<!--
|
||||||
Get the fan-curve data for the currently active Profile
|
Set a single fan curve for a profile to enabled status. Will also
|
||||||
|
activate a fan curve if in the same profile mode
|
||||||
|
-->
|
||||||
|
<method name="SetProfileFanCurveEnabled">
|
||||||
|
<arg name="profile" type="s" direction="in"/>
|
||||||
|
<arg name="fan" type="s" direction="in"/>
|
||||||
|
<arg name="enabled" type="b" direction="in"/>
|
||||||
|
</method>
|
||||||
|
<!--
|
||||||
|
Get the fan-curve data for the currently active PlatformPolicy
|
||||||
-->
|
-->
|
||||||
<method name="FanCurveData">
|
<method name="FanCurveData">
|
||||||
<arg name="profile" type="s" direction="in"/>
|
<arg name="profile" type="s" direction="in"/>
|
||||||
<arg type="(b(s(yyyyyyyy)(yyyyyyyy))(s(yyyyyyyy)(yyyyyyyy)))" direction="out"/>
|
<arg type="a(s(yyyyyyyy)(yyyyyyyy)b)" direction="out"/>
|
||||||
</method>
|
</method>
|
||||||
<!--
|
<!--
|
||||||
Set the fan curve for the specified profile.
|
Set the fan curve for the specified profile.
|
||||||
@@ -52,7 +31,7 @@
|
|||||||
-->
|
-->
|
||||||
<method name="SetFanCurve">
|
<method name="SetFanCurve">
|
||||||
<arg name="profile" type="s" direction="in"/>
|
<arg name="profile" type="s" direction="in"/>
|
||||||
<arg name="curve" type="(s(yyyyyyyy)(yyyyyyyy))" direction="in"/>
|
<arg name="curve" type="(s(yyyyyyyy)(yyyyyyyy)b)" direction="in"/>
|
||||||
</method>
|
</method>
|
||||||
<!--
|
<!--
|
||||||
Reset the stored (self) and device curve to the defaults of the
|
Reset the stored (self) and device curve to the defaults of the
|
||||||
@@ -73,8 +52,5 @@
|
|||||||
<method name="ResetProfileCurves">
|
<method name="ResetProfileCurves">
|
||||||
<arg name="profile" type="s" direction="in"/>
|
<arg name="profile" type="s" direction="in"/>
|
||||||
</method>
|
</method>
|
||||||
<signal name="NotifyProfile">
|
|
||||||
<arg name="profile" type="s"/>
|
|
||||||
</signal>
|
|
||||||
</interface>
|
</interface>
|
||||||
</node>
|
</node>
|
||||||
@@ -1,67 +1,46 @@
|
|||||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
||||||
<node>
|
<node>
|
||||||
<interface name="org.asuslinux.Daemon">
|
<interface name="org.asuslinux.Daemon">
|
||||||
<method name="SetGpuMuxMode">
|
<!--
|
||||||
<arg name="mode" type="u" direction="in"/>
|
Returns a list of property names that this system supports
|
||||||
|
-->
|
||||||
|
<method name="SupportedProperties">
|
||||||
|
<arg type="as" direction="out"/>
|
||||||
</method>
|
</method>
|
||||||
<method name="GpuMuxMode">
|
<method name="SupportedInterfaces">
|
||||||
<arg type="u" direction="out"/>
|
<arg type="as" direction="out"/>
|
||||||
</method>
|
</method>
|
||||||
<signal name="NotifyGpuMuxMode">
|
<!--
|
||||||
<arg name="mode" type="u"/>
|
Toggle to next platform_profile. Names provided by `Profiles`.
|
||||||
</signal>
|
If fan-curves are supported will also activate a fan curve for profile.
|
||||||
<method name="SetPostBootSound">
|
-->
|
||||||
<arg name="on" type="b" direction="in"/>
|
<method name="NextThrottleThermalPolicy">
|
||||||
</method>
|
|
||||||
<method name="PostBootSound">
|
|
||||||
<arg type="n" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<signal name="NotifyPostBootSound">
|
|
||||||
<arg name="on" type="b"/>
|
|
||||||
</signal>
|
|
||||||
<method name="SetPanelOd">
|
|
||||||
<arg name="overdrive" type="b" direction="in"/>
|
|
||||||
</method>
|
</method>
|
||||||
|
<property name="ChargeControlEndThreshold" type="y" access="readwrite"/>
|
||||||
|
<property name="DgpuDisable" type="b" access="read"/>
|
||||||
|
<property name="EgpuEnable" type="b" access="read"/>
|
||||||
|
<property name="GpuMuxMode" type="y" access="readwrite"/>
|
||||||
<!--
|
<!--
|
||||||
Get the `panel_od` value from platform. Updates the stored value in
|
Get the `panel_od` value from platform. Updates the stored value in
|
||||||
internal config also.
|
internal config also.
|
||||||
-->
|
-->
|
||||||
<method name="PanelOd">
|
<property name="MiniLedMode" type="b" access="readwrite"/>
|
||||||
<arg type="b" direction="out"/>
|
<property name="NvDynamicBoost" type="y" access="readwrite"/>
|
||||||
</method>
|
<property name="NvTempTarget" type="y" access="readwrite"/>
|
||||||
<signal name="NotifyPanelOd">
|
|
||||||
<arg name="overdrive" type="b"/>
|
|
||||||
</signal>
|
|
||||||
<method name="SetMiniLedMode">
|
|
||||||
<arg name="on" type="b" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<!--
|
<!--
|
||||||
Get the `panel_od` value from platform. Updates the stored value in
|
Get the `panel_od` value from platform. Updates the stored value in
|
||||||
internal config also.
|
internal config also.
|
||||||
-->
|
-->
|
||||||
<method name="MiniLedMode">
|
<property name="PanelOd" type="b" access="readwrite"/>
|
||||||
<arg type="b" direction="out"/>
|
<property name="PostAnimationSound" type="b" access="readwrite"/>
|
||||||
</method>
|
<property name="PptApuSppt" type="y" access="readwrite"/>
|
||||||
<signal name="NotifyMiniLedMode">
|
<property name="PptFppt" type="y" access="readwrite"/>
|
||||||
<arg name="on" type="b"/>
|
<!--
|
||||||
</signal>
|
************************************************************************
|
||||||
<method name="SetDgpuDisable">
|
-->
|
||||||
<arg name="disable" type="b" direction="in"/>
|
<property name="PptPl1Spl" type="y" access="readwrite"/>
|
||||||
</method>
|
<property name="PptPl2Sppt" type="y" access="readwrite"/>
|
||||||
<method name="DgpuDisable">
|
<property name="PptPlatformSppt" type="y" access="readwrite"/>
|
||||||
<arg type="b" direction="out"/>
|
<property name="ThrottleThermalPolicy" type="s" access="readwrite"/>
|
||||||
</method>
|
|
||||||
<signal name="NotifyDgpuDisable">
|
|
||||||
<arg name="disable" type="b"/>
|
|
||||||
</signal>
|
|
||||||
<method name="SetEgpuEnable">
|
|
||||||
<arg name="enable" type="b" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<method name="EgpuEnable">
|
|
||||||
<arg type="b" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<signal name="NotifyEgpuEnable">
|
|
||||||
<arg name="enable" type="b"/>
|
|
||||||
</signal>
|
|
||||||
</interface>
|
</interface>
|
||||||
</node>
|
</node>
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
|
||||||
<node>
|
|
||||||
<interface name="org.asuslinux.Daemon">
|
|
||||||
<method name="SetChargeControlEndThreshold">
|
|
||||||
<arg name="limit" type="y" direction="in"/>
|
|
||||||
</method>
|
|
||||||
<method name="ChargeControlEndThreshold">
|
|
||||||
<arg type="y" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<method name="MainsOnline">
|
|
||||||
<arg type="b" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<signal name="NotifyChargeControlEndThreshold">
|
|
||||||
<arg name="limit" type="y"/>
|
|
||||||
</signal>
|
|
||||||
<signal name="NotifyMainsOnline">
|
|
||||||
<arg name="on" type="b"/>
|
|
||||||
</signal>
|
|
||||||
</interface>
|
|
||||||
</node>
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
|
|
||||||
<node>
|
|
||||||
<interface name="org.asuslinux.Daemon">
|
|
||||||
<method name="SupportedFunctions">
|
|
||||||
<arg type="b(b)(bb)(sbasassas)(bbbbbb)" direction="out"/>
|
|
||||||
</method>
|
|
||||||
<method name="MeaningOfLife">
|
|
||||||
<arg name="answer" type="i" direction="out"/>
|
|
||||||
<arg name="question" type="s" direction="out"/>
|
|
||||||
</method>
|
|
||||||
</interface>
|
|
||||||
</node>
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Generated by typeshare 1.6.0
|
Generated by typeshare 1.7.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export enum AnimBooting {
|
export enum AnimBooting {
|
||||||
@@ -42,6 +42,10 @@ export interface DeviceState {
|
|||||||
display_brightness: Brightness;
|
display_brightness: Brightness;
|
||||||
builtin_anims_enabled: boolean;
|
builtin_anims_enabled: boolean;
|
||||||
builtin_anims: Animations;
|
builtin_anims: Animations;
|
||||||
|
off_when_unplugged: boolean;
|
||||||
|
off_when_suspended: boolean;
|
||||||
|
off_when_lid_closed: boolean;
|
||||||
|
brightness_on_battery: Brightness;
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum AnimeType {
|
export enum AnimeType {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Generated by typeshare 1.6.0
|
Generated by typeshare 1.7.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Represents the per-key raw USB packets */
|
/** Represents the per-key raw USB packets */
|
||||||
@@ -227,6 +227,7 @@ export enum AuraDevice {
|
|||||||
X18c6 = "X18c6",
|
X18c6 = "X18c6",
|
||||||
X19b6 = "X19b6",
|
X19b6 = "X19b6",
|
||||||
X1a30 = "X1a30",
|
X1a30 = "X1a30",
|
||||||
|
X1abe = "X1abe",
|
||||||
Unknown = "Unknown",
|
Unknown = "Unknown",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,50 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
Generated by typeshare 1.6.0
|
Generated by typeshare 1.7.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export type AnimeSupportedFunctions = boolean;
|
|
||||||
|
|
||||||
export interface ChargeSupportedFunctions {
|
|
||||||
charge_level_set: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PlatformProfileFunctions {
|
|
||||||
platform_profile: boolean;
|
|
||||||
fan_curves: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum AdvancedAura {
|
|
||||||
None = "None",
|
|
||||||
Zoned = "Zoned",
|
|
||||||
PerKey = "PerKey",
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface LedSupportedFunctions {
|
|
||||||
dev_id: AuraDevice;
|
|
||||||
brightness: boolean;
|
|
||||||
basic_modes: AuraModeNum[];
|
|
||||||
basic_zones: AuraZone[];
|
|
||||||
advanced_type: AdvancedAura;
|
|
||||||
power_zones: PowerZones[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RogBiosSupportedFunctions {
|
|
||||||
post_sound: boolean;
|
|
||||||
gpu_mux: boolean;
|
|
||||||
panel_overdrive: boolean;
|
|
||||||
dgpu_disable: boolean;
|
|
||||||
egpu_enable: boolean;
|
|
||||||
mini_led_mode: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SupportedFunctions {
|
|
||||||
anime_ctrl: AnimeSupportedFunctions;
|
|
||||||
charge_ctrl: ChargeSupportedFunctions;
|
|
||||||
platform_profile: PlatformProfileFunctions;
|
|
||||||
keyboard_led: LedSupportedFunctions;
|
|
||||||
rog_bios_ctrl: RogBiosSupportedFunctions;
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum GpuMode {
|
export enum GpuMode {
|
||||||
Discrete = "Discrete",
|
Discrete = "Discrete",
|
||||||
Optimus = "Optimus",
|
Optimus = "Optimus",
|
||||||
@@ -56,3 +13,28 @@ export enum GpuMode {
|
|||||||
NotSupported = "NotSupported",
|
NotSupported = "NotSupported",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum PlatformPolicy {
|
||||||
|
Balanced = "Balanced",
|
||||||
|
Performance = "Performance",
|
||||||
|
Quiet = "Quiet",
|
||||||
|
}
|
||||||
|
|
||||||
|
/** CamelCase names of the properties. Intended for use with DBUS */
|
||||||
|
export enum Properties {
|
||||||
|
ChargeControlEndThreshold = "ChargeControlEndThreshold",
|
||||||
|
DgpuDisable = "DgpuDisable",
|
||||||
|
GpuMuxMode = "GpuMuxMode",
|
||||||
|
PostAnimationSound = "PostAnimationSound",
|
||||||
|
PanelOd = "PanelOd",
|
||||||
|
MiniLedMode = "MiniLedMode",
|
||||||
|
EgpuEnable = "EgpuEnable",
|
||||||
|
PlatformPolicy = "PlatformPolicy",
|
||||||
|
PptPl1Spl = "PptPl1Spl",
|
||||||
|
PptPl2Sppt = "PptPl2Sppt",
|
||||||
|
PptFppt = "PptFppt",
|
||||||
|
PptApuSppt = "PptApuSppt",
|
||||||
|
PptPlatformSppt = "PptPlatformSppt",
|
||||||
|
NvDynamicBoost = "NvDynamicBoost",
|
||||||
|
NvTempTarget = "NvTempTarget",
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,35 +1,24 @@
|
|||||||
/*
|
/*
|
||||||
Generated by typeshare 1.6.0
|
Generated by typeshare 1.7.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export enum FanCurvePU {
|
export enum FanCurvePU {
|
||||||
CPU = "CPU",
|
CPU = "CPU",
|
||||||
GPU = "GPU",
|
GPU = "GPU",
|
||||||
|
MID = "MID",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CurveData {
|
export interface CurveData {
|
||||||
fan: FanCurvePU;
|
fan: FanCurvePU;
|
||||||
pwm: [number, number, number, number, number, number, number, number];
|
pwm: [number, number, number, number, number, number, number, number];
|
||||||
temp: [number, number, number, number, number, number, number, number];
|
temp: [number, number, number, number, number, number, number, number];
|
||||||
}
|
|
||||||
|
|
||||||
/** A `FanCurveSet` contains both CPU and GPU fan curve data */
|
|
||||||
export interface FanCurveSet {
|
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
cpu: CurveData;
|
|
||||||
gpu: CurveData;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Main purpose of `FanCurves` is to enable restoring state on system boot */
|
/** Main purpose of `FanCurves` is to enable restoring state on system boot */
|
||||||
export interface FanCurveProfiles {
|
export interface FanCurveProfiles {
|
||||||
balanced: FanCurveSet;
|
balanced: CurveData[];
|
||||||
performance: FanCurveSet;
|
performance: CurveData[];
|
||||||
quiet: FanCurveSet;
|
quiet: CurveData[];
|
||||||
}
|
|
||||||
|
|
||||||
export enum Profile {
|
|
||||||
Balanced = "Balanced",
|
|
||||||
Performance = "Performance",
|
|
||||||
Quiet = "Quiet",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
7
cpuctl/Cargo.toml
Normal file
7
cpuctl/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "cpuctl"
|
||||||
|
license = "MPL-2.0"
|
||||||
|
edition = "2021"
|
||||||
|
version.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
14
cpuctl/src/lib.rs
Normal file
14
cpuctl/src/lib.rs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
pub fn add(left: usize, right: usize) -> usize {
|
||||||
|
left + right
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = add(2, 2);
|
||||||
|
assert_eq!(result, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,3 @@
|
|||||||
#ACTION=="add|change", SUBSYSTEM=="input", ENV{ID_VENDOR_ID}=="0b05", ENV{ID_MODEL_ID}=="1[89][a-zA-Z0-9][a-zA-Z0-9]|193b", ENV{ID_TYPE}=="hid", TAG+="systemd", ENV{SYSTEMD_WANTS}="asusd.service"
|
|
||||||
#ACTION=="add|remove", SUBSYSTEM=="input", ENV{ID_VENDOR_ID}=="0b05", ENV{ID_MODEL_ID}=="1[89][a-zA-Z0-9][a-zA-Z0-9]|193b", RUN+="systemctl restart asusd.service"
|
|
||||||
|
|
||||||
ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}"
|
ENV{DMI_VENDOR}="$attr{[dmi/id]sys_vendor}"
|
||||||
ENV{DMI_VENDOR}!="ASUSTeK COMPUTER INC.", GOTO="asusd_end"
|
ENV{DMI_VENDOR}!="ASUSTeK COMPUTER INC.", GOTO="asusd_end"
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=ASUS Notebook Control
|
Description=ASUS Notebook Control
|
||||||
StartLimitInterval=200
|
StartLimitInterval=500
|
||||||
StartLimitBurst=2
|
StartLimitBurst=5
|
||||||
Before=multi-user.target
|
After=nvidia-powerd.service systemd-udevd.service
|
||||||
After=power-profiles-daemon.service
|
|
||||||
After=nvidia-powerd.service
|
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Environment=IS_SERVICE=1
|
Environment=IS_SERVICE=1
|
||||||
Environment=RUST_LOG="info"
|
Environment=RUST_LOG="info"
|
||||||
ExecStartPre=/bin/sleep 2
|
# ExecStartPre=/bin/sleep 2 # was required only for slow devices
|
||||||
ExecStart=/usr/bin/asusd
|
ExecStart=/usr/bin/asusd
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartSec=1
|
RestartSec=1
|
||||||
|
|||||||
25
desktop-extensions/gnome-45/.eslintrc.cjs
Normal file
25
desktop-extensions/gnome-45/.eslintrc.cjs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/* eslint-env node */
|
||||||
|
module.exports = {
|
||||||
|
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
||||||
|
parser: "@typescript-eslint/parser",
|
||||||
|
plugins: ["@typescript-eslint"],
|
||||||
|
root: true,
|
||||||
|
|
||||||
|
rules: {
|
||||||
|
// enable additional rules
|
||||||
|
indent: ["error", 4],
|
||||||
|
"linebreak-style": ["error", "unix"],
|
||||||
|
quotes: ["error", "double"],
|
||||||
|
semi: ["error", "always"],
|
||||||
|
|
||||||
|
// override configuration set by extending "eslint:recommended"
|
||||||
|
"no-empty": "warn",
|
||||||
|
"no-cond-assign": ["error", "always"],
|
||||||
|
|
||||||
|
// disable rules from base configurations
|
||||||
|
"for-direction": "off",
|
||||||
|
|
||||||
|
"@typescript-eslint/no-explicit-any": "warn",
|
||||||
|
"@typescript-eslint/ban-ts-comment": "off",
|
||||||
|
},
|
||||||
|
};
|
||||||
13
desktop-extensions/gnome-45/.prettierignore
Normal file
13
desktop-extensions/gnome-45/.prettierignore
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Generated files
|
||||||
|
/@types/gir-generated/*
|
||||||
|
|
||||||
|
# Build outputes
|
||||||
|
/dist/
|
||||||
|
/build/
|
||||||
|
|
||||||
|
# Node configuration and modules
|
||||||
|
/package.json
|
||||||
|
/node_modules/
|
||||||
|
|
||||||
|
# Files I prefer not to be formatted
|
||||||
|
*.md
|
||||||
9
desktop-extensions/gnome-45/.prettierrc.json
Normal file
9
desktop-extensions/gnome-45/.prettierrc.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 100,
|
||||||
|
"useTabs": false,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": false,
|
||||||
|
"trailingComma": "all",
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"arrowParens": "always"
|
||||||
|
}
|
||||||
67
desktop-extensions/gnome-45/esbuild.js
Normal file
67
desktop-extensions/gnome-45/esbuild.js
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import { build } from "esbuild";
|
||||||
|
import { exec } from "child_process";
|
||||||
|
import { copyFileSync, cpSync } from "fs";
|
||||||
|
import { resolve, dirname } from "path";
|
||||||
|
import { fileURLToPath } from "url";
|
||||||
|
import AdmZip from "adm-zip";
|
||||||
|
import metadata from "./src/metadata.json" assert { type: "json" };
|
||||||
|
|
||||||
|
build({
|
||||||
|
entryPoints: ["src/extension.ts"],
|
||||||
|
outdir: "dist",
|
||||||
|
bundle: true,
|
||||||
|
// Do not remove the functions `enable()`, `disable()` and `init()`
|
||||||
|
treeShaking: false,
|
||||||
|
// firefox60 // Since GJS 1.53.90
|
||||||
|
// firefox68 // Since GJS 1.63.90
|
||||||
|
// firefox78 // Since GJS 1.65.90
|
||||||
|
// firefox91 // Since GJS 1.71.1
|
||||||
|
// firefox102 // Since GJS 1.73.2
|
||||||
|
target: "firefox102",
|
||||||
|
//platform: "neutral",
|
||||||
|
platform: "node",
|
||||||
|
// mainFields: ['main'],
|
||||||
|
// conditions: ['require', 'default'],
|
||||||
|
format: "esm",
|
||||||
|
external: ["gi://*", "resource://*", "system", "gettext", "cairo"],
|
||||||
|
}).then(() => {
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
|
const metaSrc = resolve(__dirname, "src/metadata.json");
|
||||||
|
const metaDist = resolve(__dirname, "dist/metadata.json");
|
||||||
|
const schemaSrc = resolve(__dirname, "schemas");
|
||||||
|
const schemaDist = resolve(__dirname, "dist/schemas");
|
||||||
|
const dbusXmlSrc = resolve(__dirname, "../../bindings/dbus-xml");
|
||||||
|
const dbusXmlDist = resolve(__dirname, "dist/resources/dbus");
|
||||||
|
const zipFilename = `${metadata.uuid}.zip`;
|
||||||
|
const zipDist = resolve(__dirname, zipFilename);
|
||||||
|
|
||||||
|
exec("glib-compile-schemas schemas/", (error, stdout, stderr) => {
|
||||||
|
console.log("stdout: " + stdout);
|
||||||
|
console.log("stderr: " + stderr);
|
||||||
|
});
|
||||||
|
|
||||||
|
copyFileSync(metaSrc, metaDist);
|
||||||
|
|
||||||
|
cpSync(schemaSrc, schemaDist, { recursive: true }, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cpSync(dbusXmlSrc, dbusXmlDist, { recursive: true }, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const zip = new AdmZip();
|
||||||
|
zip.addLocalFolder(resolve(__dirname, "dist"));
|
||||||
|
zip.writeZip(zipDist);
|
||||||
|
|
||||||
|
console.log(`Build complete. Zip file: ${zipFilename}\n`);
|
||||||
|
console.log(`Install with: gnome-extensions install ${zipFilename}`);
|
||||||
|
console.log(`Update with: gnome-extensions install ${zipFilename} --force`);
|
||||||
|
console.log(`Enable with: gnome-extensions enable ${metadata.uuid} --user`);
|
||||||
|
});
|
||||||
51
desktop-extensions/gnome-45/generate.sh
Executable file
51
desktop-extensions/gnome-45/generate.sh
Executable file
@@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
## Script to initialise dev-environment (types)
|
||||||
|
gv="44"
|
||||||
|
wd=${PWD}
|
||||||
|
|
||||||
|
# cleanup
|
||||||
|
rm -rf @types
|
||||||
|
|
||||||
|
# generate GJS from gir (this does not include the extensions)
|
||||||
|
echo "Generating GJS types from gir.."
|
||||||
|
npx ts-for-gir generate Shell-12 St-12 Gtk-4.0 \
|
||||||
|
-g /usr/share/gir-1.0 \
|
||||||
|
-g /usr/share/gnome-shell \
|
||||||
|
-g /usr/share/gnome-shell/gir-1.0 \
|
||||||
|
-g /usr/lib64/mutter-12 \
|
||||||
|
-t esm -o @types/Gjs
|
||||||
|
|
||||||
|
# get latest js (44) in this case and create the types for it
|
||||||
|
echo "Generating GJS Extension (Gex) types from extension source.."
|
||||||
|
mkdir -p ./_tmp/
|
||||||
|
cd ./_tmp
|
||||||
|
wget -q -O gnome-shell-js-${gv}.tar.gz https://gitlab.gnome.org/GNOME/gnome-shell/-/archive/gnome-${gv}/gnome-shell-gnome-${gv}.tar.gz?path=js
|
||||||
|
tar xf gnome-shell-js-${gv}.tar.gz
|
||||||
|
cd gnome-shell-gnome-${gv}-js
|
||||||
|
cat >tsconfig.json <<EOL
|
||||||
|
{
|
||||||
|
"include": ["js/ui/*"],
|
||||||
|
"exclude": [
|
||||||
|
"js/ui/shellDBus.js",
|
||||||
|
"node_modules",
|
||||||
|
"**/node_modules/*"
|
||||||
|
],
|
||||||
|
"compilerOptions": {
|
||||||
|
"allowJs": true,
|
||||||
|
"declaration": true,
|
||||||
|
"emitDeclarationOnly": true,
|
||||||
|
"outDir": "gex-types",
|
||||||
|
"declarationMap": true,
|
||||||
|
"lib": ["es2019"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOL
|
||||||
|
npx tsc
|
||||||
|
cd ${wd}
|
||||||
|
mv ./_tmp/gnome-shell-gnome-${gv}-js/gex-types @types/Gex
|
||||||
|
# rm -rf ./_tmp/
|
||||||
|
|
||||||
|
echo "done."
|
||||||
|
|
||||||
|
exit 0
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,21 +1,36 @@
|
|||||||
{
|
{
|
||||||
"name": "asusctl-gnome",
|
"name": "asusctl-gnome",
|
||||||
"version": "4.7.0",
|
"version": "5.0.0-RC1",
|
||||||
"description": "asusctl-gnome a gnome extension exposing some of the base features of asusd in a helpful and easy to use way",
|
"description": "asusctl-gnome a gnome extension exposing some of the base features of asusd in a helpful and easy to use way",
|
||||||
|
"type": "module",
|
||||||
"main": "dist/extension.js",
|
"main": "dist/extension.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clear": "rm -rf dist",
|
"clear": "rm -rf dist",
|
||||||
|
"compile": "tsc --build tsconfig.json",
|
||||||
"build:app": "node esbuild.js",
|
"build:app": "node esbuild.js",
|
||||||
"build": "yarn run clear && yarn run build:app",
|
"build": "yarn run clear && yarn run build:app",
|
||||||
"validate": "tsc --noEmit"
|
"validate": "tsc --noEmit",
|
||||||
|
"generate:gir-types": "ts-for-gir generate",
|
||||||
|
"check:types": "tsc --build tsconfig.types.json",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"format": "prettier . -w"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@girs/gnome-shell": "^45.0.0-beta2",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
"@typescript-eslint/eslint-plugin": "^5.60.1",
|
||||||
"@typescript-eslint/parser": "^5.60.1",
|
"@typescript-eslint/parser": "^5.60.1",
|
||||||
"adm-zip": "^0.5.10",
|
"adm-zip": "^0.5.10",
|
||||||
"esbuild": "^0.17.19",
|
"esbuild": "^0.19.5",
|
||||||
"eslint": "^8.44.0",
|
"eslint": "^8.51.0",
|
||||||
"typescript": "^5.1.6"
|
"eslint-config-prettier": "^9.0.0",
|
||||||
|
"eslint-plugin-promise": "^6.1.1",
|
||||||
|
"prettier": "^3.0.3",
|
||||||
|
"typescript": "^5.2.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@girs/gjs": "^3.2.5",
|
||||||
|
"@girs/gobject-2.0": "^2.78.0-3.2.5",
|
||||||
|
"@girs/st-13": "^13.0.0-3.2.5"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@@ -10,6 +10,9 @@
|
|||||||
<key type="b" name="anime-power">
|
<key type="b" name="anime-power">
|
||||||
<default>false</default>
|
<default>false</default>
|
||||||
</key>
|
</key>
|
||||||
|
<key type="b" name="anime-builtins">
|
||||||
|
<default>false</default>
|
||||||
|
</key>
|
||||||
<key name="charge-level" type="u">
|
<key name="charge-level" type="u">
|
||||||
<range min="20" max="100"/>
|
<range min="20" max="100"/>
|
||||||
<default>100</default>
|
<default>100</default>
|
||||||
127
desktop-extensions/gnome-45/src/extension.ts
Normal file
127
desktop-extensions/gnome-45/src/extension.ts
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
|
||||||
|
import * as platform from "./bindings/platform";
|
||||||
|
import { AsusQuickToggle } from "./modules/rog_quick_toggle";
|
||||||
|
import { AsusMenuToggle } from "./modules/rog_menu_toggle";
|
||||||
|
import { AsusIndicator } from "./modules/rog_indicator";
|
||||||
|
import { AsusSlider } from "./modules/rog_slider_100pc";
|
||||||
|
import { FeatureMenuToggle } from "./modules/quick_menus/laptop_features";
|
||||||
|
import { DbusBase } from "./modules/dbus_proxy";
|
||||||
|
import { main } from "@girs/gnome-shell/ui";
|
||||||
|
|
||||||
|
export const uuid = "asusctl-gnome@asus-linux.org";
|
||||||
|
export default class AsusExtension extends Extension {
|
||||||
|
// public dbus_aura: AuraDbus = new AuraDbus;
|
||||||
|
// public dbus_anime: AnimeDbus = new AnimeDbus;
|
||||||
|
public dbus_platform: DbusBase | undefined;
|
||||||
|
public dbus_anime: DbusBase | undefined;
|
||||||
|
|
||||||
|
private individual = false;
|
||||||
|
public supported_properties!: platform.Properties;
|
||||||
|
public supported_interfaces: string[] = [];
|
||||||
|
private feature_menu = null;
|
||||||
|
private panel_od = null;
|
||||||
|
private mini_led = null;
|
||||||
|
private anime_display = null;
|
||||||
|
private anime_builtins = null;
|
||||||
|
private charge_thres = null;
|
||||||
|
// private _feature: typeof FeatureMenuToggle;
|
||||||
|
|
||||||
|
async enable() {
|
||||||
|
log(this.path);
|
||||||
|
|
||||||
|
if (this.dbus_platform == undefined) {
|
||||||
|
this.dbus_platform = new DbusBase("org-asuslinux-platform-4.xml", "/org/asuslinux/Platform");
|
||||||
|
await this.dbus_platform.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.dbus_anime == undefined) {
|
||||||
|
this.dbus_anime = new DbusBase("org-asuslinux-anime-4.xml", "/org/asuslinux/Anime");
|
||||||
|
await this.dbus_anime.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.supported_interfaces = this.dbus_platform?.proxy.SupportedInterfacesSync()[0];
|
||||||
|
this.supported_properties = this.dbus_platform?.proxy.SupportedPropertiesSync()[0];
|
||||||
|
log(this.supported_interfaces);
|
||||||
|
log(this.supported_properties);
|
||||||
|
|
||||||
|
// new AsusIndicator("selection-mode-symbolic", "mini-led-enabled");
|
||||||
|
// new AsusIndicator("selection-mode-symbolic", "panel-od-enabled");
|
||||||
|
|
||||||
|
if (!this.individual) {
|
||||||
|
if (this.feature_menu == null)
|
||||||
|
this.feature_menu = new FeatureMenuToggle(this.dbus_platform, this.dbus_anime);
|
||||||
|
} else {
|
||||||
|
if (this.supported_properties.includes("PanelOd") && this.dbus_platform.proxy.PanelOd != null)
|
||||||
|
if (this.panel_od == null) {
|
||||||
|
this.panel_od = new AsusQuickToggle(
|
||||||
|
this.dbus_platform,
|
||||||
|
"PanelOd",
|
||||||
|
"panel-od-enabled",
|
||||||
|
"Panel Overdrive",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.supported_properties.includes("MiniLed") && this.dbus_platform.proxy.MiniLed != null)
|
||||||
|
if (this.mini_led == null) {
|
||||||
|
this.mini_led = new AsusQuickToggle(
|
||||||
|
this.dbus_platform,
|
||||||
|
"MiniLed",
|
||||||
|
"mini-led-enabled",
|
||||||
|
"Mini-LED",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.supported_interfaces.includes("Anime") &&
|
||||||
|
this.dbus_anime.proxy.EnableDisplay != null
|
||||||
|
)
|
||||||
|
if (this.anime_display == null) {
|
||||||
|
this.anime_display = new AsusQuickToggle(
|
||||||
|
this.dbus_anime,
|
||||||
|
"EnableDisplay",
|
||||||
|
"anime-power",
|
||||||
|
"AniMe Display",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.supported_interfaces.includes("Anime") &&
|
||||||
|
this.dbus_anime.proxy.BuiltinsEnabled != null
|
||||||
|
)
|
||||||
|
if (this.anime_builtins == null) {
|
||||||
|
this.anime_builtins = new AsusQuickToggle(
|
||||||
|
this.dbus_anime,
|
||||||
|
"BuiltinsEnabled",
|
||||||
|
"anime-builtins",
|
||||||
|
"Use builtins",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.supported_properties.includes("ChargeControlEndThreshold") &&
|
||||||
|
this.dbus_platform.proxy.ChargeControlEndThreshold != null
|
||||||
|
)
|
||||||
|
if (this.charge_thres == null) {
|
||||||
|
this.charge_thres = new AsusSlider(
|
||||||
|
this.dbus_platform,
|
||||||
|
"ChargeControlEndThreshold",
|
||||||
|
"charge-level",
|
||||||
|
"Charge Level",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
disable() {
|
||||||
|
this.dbus_platform?.stop();
|
||||||
|
this.dbus_anime?.stop();
|
||||||
|
|
||||||
|
this.feature_menu?.destroy();
|
||||||
|
feature_menu?.destroy();
|
||||||
|
panel_od?.destroy();
|
||||||
|
mini_led?.destroy();
|
||||||
|
anime_display?.destroy();
|
||||||
|
anime_builtins?.destroy();
|
||||||
|
charge_thres?.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,5 @@
|
|||||||
"uuid-dev": "asusctl-gnome-dev@asus-linux.org",
|
"uuid-dev": "asusctl-gnome-dev@asus-linux.org",
|
||||||
"settings-schema": "org.gnome.shell.extensions.asusctl-gnome",
|
"settings-schema": "org.gnome.shell.extensions.asusctl-gnome",
|
||||||
"version": "4.3.2",
|
"version": "4.3.2",
|
||||||
"shell-version": [
|
"shell-version": ["45"]
|
||||||
"43", "44", "45"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
98
desktop-extensions/gnome-45/src/modules/dbus/animatrix.ts
Normal file
98
desktop-extensions/gnome-45/src/modules/dbus/animatrix.ts
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
import { DbusBase } from "../dbus_proxy";
|
||||||
|
import {
|
||||||
|
DeviceState,
|
||||||
|
AnimBooting,
|
||||||
|
Brightness,
|
||||||
|
AnimAwake,
|
||||||
|
AnimSleeping,
|
||||||
|
AnimShutdown,
|
||||||
|
} from "../../bindings/anime";
|
||||||
|
|
||||||
|
export class AnimeDbus extends DbusBase {
|
||||||
|
deviceState: DeviceState = {
|
||||||
|
display_enabled: false,
|
||||||
|
display_brightness: Brightness.Med,
|
||||||
|
builtin_anims_enabled: false,
|
||||||
|
builtin_anims: {
|
||||||
|
boot: AnimBooting.GlitchConstruction,
|
||||||
|
awake: AnimAwake.BinaryBannerScroll,
|
||||||
|
sleep: AnimSleeping.BannerSwipe,
|
||||||
|
shutdown: AnimShutdown.GlitchOut,
|
||||||
|
},
|
||||||
|
off_when_unplugged: false,
|
||||||
|
off_when_suspended: false,
|
||||||
|
off_when_lid_closed: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: interface or something to enforce requirement of "sync()" method
|
||||||
|
public notifyAnimeStateSubscribers: any[] = [];
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super("org-asuslinux-anime-4", "/org/asuslinux/Anime");
|
||||||
|
}
|
||||||
|
|
||||||
|
_parseData(data: any) {
|
||||||
|
if (data.length > 0) {
|
||||||
|
this.deviceState.display_enabled = data[0];
|
||||||
|
this.deviceState.display_brightness = Brightness[data[1] as Brightness];
|
||||||
|
this.deviceState.builtin_anims_enabled = data[2];
|
||||||
|
this.deviceState.builtin_anims.boot = AnimBooting[data[3][0] as AnimBooting];
|
||||||
|
this.deviceState.builtin_anims.awake = AnimAwake[data[3][1] as AnimAwake];
|
||||||
|
this.deviceState.builtin_anims.sleep = AnimSleeping[data[3][2] as AnimSleeping];
|
||||||
|
this.deviceState.builtin_anims.shutdown = AnimShutdown[data[3][3] as AnimShutdown];
|
||||||
|
this.deviceState.off_when_unplugged = data[4];
|
||||||
|
this.deviceState.off_when_suspended = data[5];
|
||||||
|
this.deviceState.off_when_lid_closed = data[6];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDeviceState() {
|
||||||
|
if (this.isRunning()) {
|
||||||
|
try {
|
||||||
|
// janky shit going on with DeviceStateSync
|
||||||
|
this._parseData(this.dbus_proxy.DeviceStateSync());
|
||||||
|
//@ts-ignore
|
||||||
|
log("Anime Matrix: display_enabled: " + this.deviceState.display_enabled);
|
||||||
|
//@ts-ignore
|
||||||
|
log("Anime Matrix: display_brightness: " + this.deviceState.display_brightness);
|
||||||
|
//@ts-ignore
|
||||||
|
log("Anime Matrix: builtin_anims_enabled: " + this.deviceState.builtin_anims_enabled);
|
||||||
|
//@ts-ignore
|
||||||
|
log("Anime Matrix: builtin_anims: " + this.deviceState.builtin_anims);
|
||||||
|
//@ts-ignore
|
||||||
|
log("Anime Matrix: off_when_unplugged: " + this.deviceState.off_when_unplugged);
|
||||||
|
//@ts-ignore
|
||||||
|
log("Anime Matrix: off_when_suspended: " + this.deviceState.off_when_suspended);
|
||||||
|
//@ts-ignore
|
||||||
|
log("Anime Matrix: off_when_lid_closed: " + this.deviceState.off_when_lid_closed);
|
||||||
|
} catch (e) {
|
||||||
|
//@ts-ignore
|
||||||
|
log("Failed to fetch DeviceState!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this.deviceState;
|
||||||
|
}
|
||||||
|
|
||||||
|
async start() {
|
||||||
|
await super.start();
|
||||||
|
this.getDeviceState();
|
||||||
|
|
||||||
|
this.dbus_proxy.connectSignal(
|
||||||
|
"NotifyDeviceState",
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
(proxy: any = null, name: string, data: string) => {
|
||||||
|
if (proxy) {
|
||||||
|
// idiot xml parsing mneans the get is not nested while this is
|
||||||
|
this._parseData(data[0]);
|
||||||
|
this.notifyAnimeStateSubscribers.forEach((sub) => {
|
||||||
|
sub.sync();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async stop() {
|
||||||
|
await super.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
300
desktop-extensions/gnome-45/src/modules/dbus/aura.ts
Normal file
300
desktop-extensions/gnome-45/src/modules/dbus/aura.ts
Normal file
@@ -0,0 +1,300 @@
|
|||||||
|
import {
|
||||||
|
AuraDevRog1,
|
||||||
|
AuraDevTuf,
|
||||||
|
AuraDevice,
|
||||||
|
AuraEffect,
|
||||||
|
AuraModeNum,
|
||||||
|
AuraPower,
|
||||||
|
AuraPowerDev,
|
||||||
|
AuraZone,
|
||||||
|
Direction,
|
||||||
|
PowerZones,
|
||||||
|
Speed,
|
||||||
|
} from "../../bindings/aura";
|
||||||
|
import { DbusBase } from "./base";
|
||||||
|
|
||||||
|
export class AuraDbus extends DbusBase {
|
||||||
|
public device: AuraDevice = AuraDevice.Unknown;
|
||||||
|
public current_aura_mode: AuraModeNum = AuraModeNum.Static;
|
||||||
|
public aura_modes: Map<AuraModeNum, AuraEffect> = new Map();
|
||||||
|
public leds_powered: AuraPowerDev = {
|
||||||
|
tuf: [],
|
||||||
|
old_rog: [],
|
||||||
|
rog: {
|
||||||
|
keyboard: {
|
||||||
|
zone: PowerZones.Keyboard,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
},
|
||||||
|
logo: {
|
||||||
|
zone: PowerZones.Logo,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
},
|
||||||
|
lightbar: {
|
||||||
|
zone: PowerZones.Lightbar,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
},
|
||||||
|
lid: {
|
||||||
|
zone: PowerZones.Lid,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
},
|
||||||
|
rear_glow: {
|
||||||
|
zone: PowerZones.RearGlow,
|
||||||
|
boot: false,
|
||||||
|
awake: false,
|
||||||
|
sleep: false,
|
||||||
|
shutdown: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
// TODO: interface or something to enforce requirement of "sync()" method
|
||||||
|
public notifyAuraModeSubscribers: any[] = [];
|
||||||
|
public notifyAuraPowerSubscribers: any[] = [];
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super("org-asuslinux-aura-4", "/org/asuslinux/Aura");
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDevice() {
|
||||||
|
if (this.isRunning()) {
|
||||||
|
try {
|
||||||
|
this.device = AuraDevice[this.dbus_proxy.DeviceTypeSync() as AuraDevice];
|
||||||
|
//@ts-ignore
|
||||||
|
log("LED device: " + this.device);
|
||||||
|
} catch (e) {
|
||||||
|
//@ts-ignore
|
||||||
|
log("Failed to fetch supported functionalities", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_parsePowerStates(data: any[]) {
|
||||||
|
const power: AuraPowerDev = this.leds_powered;
|
||||||
|
|
||||||
|
power.tuf = data[0].map((value: string) => {
|
||||||
|
return AuraDevTuf[value as AuraDevTuf];
|
||||||
|
});
|
||||||
|
power.old_rog = data[1].map((value: string) => {
|
||||||
|
return AuraDevRog1[value as AuraDevRog1];
|
||||||
|
});
|
||||||
|
power.rog = {
|
||||||
|
keyboard: {
|
||||||
|
zone: PowerZones[data[2][0][0] as PowerZones],
|
||||||
|
boot: data[2][0][1],
|
||||||
|
awake: data[2][0][2],
|
||||||
|
sleep: data[2][0][3],
|
||||||
|
shutdown: data[2][0][4],
|
||||||
|
},
|
||||||
|
logo: {
|
||||||
|
zone: PowerZones[data[2][1][0] as PowerZones],
|
||||||
|
boot: data[2][1][1],
|
||||||
|
awake: data[2][1][2],
|
||||||
|
sleep: data[2][1][3],
|
||||||
|
shutdown: data[2][1][4],
|
||||||
|
},
|
||||||
|
lightbar: {
|
||||||
|
zone: PowerZones[data[2][2][0] as PowerZones],
|
||||||
|
boot: data[2][2][1],
|
||||||
|
awake: data[2][2][2],
|
||||||
|
sleep: data[2][2][3],
|
||||||
|
shutdown: data[2][2][4],
|
||||||
|
},
|
||||||
|
lid: {
|
||||||
|
zone: PowerZones[data[2][3][0] as PowerZones],
|
||||||
|
boot: data[2][3][1],
|
||||||
|
awake: data[2][3][2],
|
||||||
|
sleep: data[2][3][3],
|
||||||
|
shutdown: data[2][3][4],
|
||||||
|
},
|
||||||
|
rear_glow: {
|
||||||
|
zone: PowerZones[data[2][4][0] as PowerZones],
|
||||||
|
boot: data[2][4][1],
|
||||||
|
awake: data[2][4][2],
|
||||||
|
sleep: data[2][4][3],
|
||||||
|
shutdown: data[2][4][4],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return power;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getLedPower() {
|
||||||
|
if (this.isRunning()) {
|
||||||
|
try {
|
||||||
|
const data = this.dbus_proxy.LedPowerSync();
|
||||||
|
this.leds_powered = this._parsePowerStates(data);
|
||||||
|
//@ts-ignore
|
||||||
|
log("LED power tuf: " + this.leds_powered.tuf);
|
||||||
|
//@ts-ignore
|
||||||
|
log("LED power x1866: " + this.leds_powered.old_rog);
|
||||||
|
//@ts-ignore
|
||||||
|
log("LED power x19b6: " + this.leds_powered.rog);
|
||||||
|
} catch (e) {
|
||||||
|
//@ts-ignore
|
||||||
|
log("Failed to fetch supported functionalities", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getLedMode() {
|
||||||
|
if (this.isRunning()) {
|
||||||
|
try {
|
||||||
|
this.current_aura_mode = AuraModeNum[this.dbus_proxy.LedModeSync() as AuraModeNum];
|
||||||
|
//@ts-ignore
|
||||||
|
log("Current LED mode:", this.current_aura_mode);
|
||||||
|
} catch (e) {
|
||||||
|
//@ts-ignore
|
||||||
|
log("Failed to fetch supported functionalities", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public setLedMode(mode: AuraEffect) {
|
||||||
|
if (this.isRunning()) {
|
||||||
|
try {
|
||||||
|
this.dbus_proxy.SetLedModeSync([
|
||||||
|
mode.mode,
|
||||||
|
mode.zone,
|
||||||
|
[mode.colour1.r, mode.colour1.g, mode.colour1.b],
|
||||||
|
[mode.colour2.r, mode.colour2.g, mode.colour2.b],
|
||||||
|
mode.speed,
|
||||||
|
mode.direction,
|
||||||
|
]);
|
||||||
|
} catch (e) {
|
||||||
|
//@ts-ignore
|
||||||
|
log("Failed to fetch supported functionalities", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_parseAuraEffect(data: any[]) {
|
||||||
|
const aura: AuraEffect = {
|
||||||
|
mode: AuraModeNum[data[0] as AuraModeNum],
|
||||||
|
zone: AuraZone[data[1] as AuraZone],
|
||||||
|
colour1: {
|
||||||
|
r: parseInt(data[2][0]),
|
||||||
|
g: parseInt(data[2][1]),
|
||||||
|
b: parseInt(data[2][2]),
|
||||||
|
},
|
||||||
|
colour2: {
|
||||||
|
r: parseInt(data[3][0]),
|
||||||
|
g: parseInt(data[3][1]),
|
||||||
|
b: parseInt(data[3][2]),
|
||||||
|
},
|
||||||
|
speed: Speed[data[4] as Speed],
|
||||||
|
direction: Direction[data[5] as Direction],
|
||||||
|
};
|
||||||
|
return aura;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a list of the available modes, and the current settings for each
|
||||||
|
public getLedModes() {
|
||||||
|
// {'Breathe': ('Breathe', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right'),
|
||||||
|
// 'Comet': ('Comet', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right'),
|
||||||
|
// 'Static': ('Static', 'None', (78, 0, 0), (0, 0, 0), 'Med', 'Right'),
|
||||||
|
// 'Strobe': ('Strobe', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right')}
|
||||||
|
if (this.isRunning()) {
|
||||||
|
try {
|
||||||
|
const _data = this.dbus_proxy.LedModesSync();
|
||||||
|
for (const key in _data[0]) {
|
||||||
|
const data = _data[0][key];
|
||||||
|
const aura: AuraEffect = this._parseAuraEffect(data);
|
||||||
|
this.aura_modes.set(AuraModeNum[key as AuraModeNum], aura);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [key, value] of this.aura_modes) {
|
||||||
|
//@ts-ignore
|
||||||
|
log(key, value.zone, value.colour1.r, value.speed, value.direction);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
//@ts-ignore
|
||||||
|
log("Failed to fetch supported functionalities", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async start() {
|
||||||
|
try {
|
||||||
|
await super.start();
|
||||||
|
this.getDevice();
|
||||||
|
this.getLedPower();
|
||||||
|
this.getLedMode();
|
||||||
|
this.getLedModes();
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
log("Current LED mode data:", this.aura_modes.get(this.current_aura_mode)?.speed);
|
||||||
|
|
||||||
|
this.dbus_proxy.connectSignal("NotifyLed", (proxy: any = null, name: string, data: any) => {
|
||||||
|
if (proxy) {
|
||||||
|
const aura: AuraEffect = this._parseAuraEffect(data[0]);
|
||||||
|
this.current_aura_mode = aura.mode;
|
||||||
|
this.aura_modes.set(aura.mode, aura);
|
||||||
|
//@ts-ignore
|
||||||
|
log(
|
||||||
|
"LED data has changed to ",
|
||||||
|
aura.mode,
|
||||||
|
aura.zone,
|
||||||
|
aura.colour1.r,
|
||||||
|
aura.speed,
|
||||||
|
aura.direction,
|
||||||
|
);
|
||||||
|
this.notifyAuraModeSubscribers.forEach((sub) => {
|
||||||
|
sub.sync();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.dbus_proxy.connectSignal(
|
||||||
|
"NotifyPowerStates",
|
||||||
|
(proxy: any = null, name: string, data: any) => {
|
||||||
|
if (proxy) {
|
||||||
|
const power: AuraPowerDev = this._parsePowerStates(data[0]);
|
||||||
|
this.leds_powered = power;
|
||||||
|
switch (this.device) {
|
||||||
|
case AuraDevice.Tuf:
|
||||||
|
//@ts-ignore
|
||||||
|
log("LED power has changed to ", this.leds_powered.tuf);
|
||||||
|
break;
|
||||||
|
case AuraDevice.X1854:
|
||||||
|
case AuraDevice.X1869:
|
||||||
|
case AuraDevice.X18c6:
|
||||||
|
//@ts-ignore
|
||||||
|
log("LED power has changed to ", this.leds_powered.old_rog);
|
||||||
|
break;
|
||||||
|
case AuraDevice.X19b6:
|
||||||
|
case AuraDevice.X1a30:
|
||||||
|
//@ts-ignore
|
||||||
|
log("LED power has changed to ", this.leds_powered.rog);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//@ts-ignore
|
||||||
|
log("LED power has changed to ", this.leds_powered.rog);
|
||||||
|
this.notifyAuraPowerSubscribers.forEach((sub) => {
|
||||||
|
sub.sync();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
//@ts-ignore
|
||||||
|
log("Supported DBus initialization failed!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async stop() {
|
||||||
|
await super.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
64
desktop-extensions/gnome-45/src/modules/dbus_proxy.ts
Normal file
64
desktop-extensions/gnome-45/src/modules/dbus_proxy.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
|
||||||
|
import { Gio } from "@girs/gio-2.0";
|
||||||
|
import { GLib } from "@girs/glib-2.0";
|
||||||
|
import { imports } from "@girs/gjs";
|
||||||
|
|
||||||
|
// Reads the contents of a file contained in the global resources archive. The data
|
||||||
|
// is returned as a string.
|
||||||
|
export function getStringResource(path: string | null) {
|
||||||
|
const data = Gio.resources_lookup_data(path, 0);
|
||||||
|
return new TextDecoder().decode(data.get_data()?.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DbusBase {
|
||||||
|
proxy!: Gio.DBusProxy;
|
||||||
|
connected = false;
|
||||||
|
ifaceXml = "";
|
||||||
|
dbus_path = "";
|
||||||
|
|
||||||
|
constructor(file_name: string, dbus_path: string) {
|
||||||
|
let extensionObject = Extension.lookupByUUID("asusctl-gnome@asus-linux.org");
|
||||||
|
const path = extensionObject?.path + "/resources/dbus/" + file_name;
|
||||||
|
const [ok, data] = GLib.file_get_contents(path);
|
||||||
|
if (!ok) {
|
||||||
|
throw new Error("could not read interface file");
|
||||||
|
}
|
||||||
|
this.ifaceXml = imports.byteArray.toString(data);
|
||||||
|
this.dbus_path = dbus_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
async start() {
|
||||||
|
//@ts-ignore
|
||||||
|
log(`Starting ${this.dbus_path} dbus module`);
|
||||||
|
try {
|
||||||
|
log(this.ifaceXml);
|
||||||
|
this.proxy = Gio.DBusProxy.makeProxyWrapper(this.ifaceXml)(
|
||||||
|
Gio.DBus.system,
|
||||||
|
"org.asuslinux.Daemon",
|
||||||
|
this.dbus_path,
|
||||||
|
);
|
||||||
|
|
||||||
|
this.connected = true;
|
||||||
|
//@ts-ignore
|
||||||
|
log(`${this.dbus_path} client started successfully.`);
|
||||||
|
} catch (e) {
|
||||||
|
//@ts-ignore
|
||||||
|
logError(`${this.xml_resource} dbus init failed!`, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async stop() {
|
||||||
|
//@ts-ignore
|
||||||
|
log(`Stopping ${this.xml_resource} dbus module`);
|
||||||
|
|
||||||
|
if (this.connected && this.proxy != undefined) {
|
||||||
|
this.proxy.run_dispose();
|
||||||
|
this.proxy = undefined;
|
||||||
|
this.connected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isRunning(): boolean {
|
||||||
|
return this.connected;
|
||||||
|
}
|
||||||
|
}
|
||||||
14
desktop-extensions/gnome-45/src/modules/helpers.ts
Normal file
14
desktop-extensions/gnome-45/src/modules/helpers.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import * as Main from "resource:///org/gnome/shell/ui/main.js";
|
||||||
|
import { QuickToggle } from "resource:///org/gnome/shell/ui/quickSettings.js";
|
||||||
|
|
||||||
|
export function addQuickSettingsItems(items: [typeof QuickToggle], width = 1) {
|
||||||
|
const QuickSettingsMenu = Main.panel.statusArea.quickSettings;
|
||||||
|
items.forEach((item) => QuickSettingsMenu.menu.addItem(item, width));
|
||||||
|
// Ensure the tile(s) are above the background apps menu
|
||||||
|
for (const item of items) {
|
||||||
|
QuickSettingsMenu.menu._grid.set_child_below_sibling(
|
||||||
|
item,
|
||||||
|
QuickSettingsMenu._backgroundApps.quickSettingsItems[0],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
85
desktop-extensions/gnome-45/src/modules/quick_menus/aura.ts
Normal file
85
desktop-extensions/gnome-45/src/modules/quick_menus/aura.ts
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import { addQuickSettingsItems } from "../helpers";
|
||||||
|
import { AuraDbus } from "../dbus/aura";
|
||||||
|
import { AuraEffect, AuraModeNum } from "../../bindings/aura";
|
||||||
|
import GObject from "gi://GObject";
|
||||||
|
|
||||||
|
import * as PopupMenu from "resource:///org/gnome/shell/ui/popupMenu.js";
|
||||||
|
import * as QuickSettings from "resource:///org/gnome/shell/ui/quickSettings.js";
|
||||||
|
|
||||||
|
export const AuraMenuToggle = GObject.registerClass(
|
||||||
|
class AuraMenuToggle extends QuickSettings.QuickMenuToggle {
|
||||||
|
private _dbus_aura: AuraDbus;
|
||||||
|
private _last_mode: AuraModeNum = AuraModeNum.Static;
|
||||||
|
|
||||||
|
constructor(dbus_aura: AuraDbus) {
|
||||||
|
super({
|
||||||
|
title: "Aura Modes",
|
||||||
|
iconName: "selection-mode-symbolic",
|
||||||
|
toggleMode: true,
|
||||||
|
});
|
||||||
|
this._dbus_aura = dbus_aura;
|
||||||
|
|
||||||
|
this.connectObject(this);
|
||||||
|
|
||||||
|
this.menu.setHeader("selection-mode-symbolic", this._dbus_aura.current_aura_mode);
|
||||||
|
|
||||||
|
this._itemsSection = new PopupMenu.PopupMenuSection();
|
||||||
|
|
||||||
|
this._dbus_aura.aura_modes.forEach((mode, key) => {
|
||||||
|
this._itemsSection.addAction(
|
||||||
|
key,
|
||||||
|
() => {
|
||||||
|
this._dbus_aura.setLedMode(mode);
|
||||||
|
this.sync();
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.menu.addMenuItem(this._itemsSection);
|
||||||
|
|
||||||
|
// Add an entry-point for more settings
|
||||||
|
// this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
|
// const settingsItem = this.menu.addAction("More Settings",
|
||||||
|
// () => ExtensionUtils.openPrefs());
|
||||||
|
// // Ensure the settings are unavailable when the screen is locked
|
||||||
|
// settingsItem.visible = Main.sessionMode.allowSettings;
|
||||||
|
// this.menu._settingsActions[Me.uuid] = settingsItem;
|
||||||
|
|
||||||
|
this.connectObject(
|
||||||
|
"clicked",
|
||||||
|
() => {
|
||||||
|
let mode: AuraEffect | undefined;
|
||||||
|
if (this._dbus_aura.current_aura_mode == AuraModeNum.Static) {
|
||||||
|
mode = this._dbus_aura.aura_modes.get(this._last_mode);
|
||||||
|
} else {
|
||||||
|
mode = this._dbus_aura.aura_modes.get(AuraModeNum.Static);
|
||||||
|
}
|
||||||
|
if (mode != undefined) {
|
||||||
|
this._dbus_aura.setLedMode(mode);
|
||||||
|
this.sync();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
|
||||||
|
this._dbus_aura.notifyAuraModeSubscribers.push(this);
|
||||||
|
this.sync();
|
||||||
|
|
||||||
|
addQuickSettingsItems([this]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sync() {
|
||||||
|
const checked = this._dbus_aura.current_aura_mode != AuraModeNum.Static;
|
||||||
|
this.title = this._dbus_aura.current_aura_mode;
|
||||||
|
if (
|
||||||
|
this._last_mode != this._dbus_aura.current_aura_mode &&
|
||||||
|
this._dbus_aura.current_aura_mode != AuraModeNum.Static
|
||||||
|
) {
|
||||||
|
this._last_mode = this._dbus_aura.current_aura_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.checked !== checked) this.set({ checked });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
@@ -0,0 +1,216 @@
|
|||||||
|
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
|
||||||
|
import { quickSettings, popupMenu } from "@girs/gnome-shell/ui";
|
||||||
|
import { GObject } from "@girs/gobject-2.0";
|
||||||
|
|
||||||
|
import { DbusBase } from "../../modules/dbus_proxy";
|
||||||
|
|
||||||
|
import { addQuickSettingsItems } from "../helpers";
|
||||||
|
|
||||||
|
import * as AsusExtension from "../../extension";
|
||||||
|
import * as platform from "../../bindings/platform";
|
||||||
|
import { uuid } from "../../extension";
|
||||||
|
import { AsusMenuToggle } from "../rog_menu_toggle";
|
||||||
|
|
||||||
|
export const FeatureMenuToggle = GObject.registerClass(
|
||||||
|
class FeatureMenuToggle extends quickSettings.QuickMenuToggle {
|
||||||
|
private dbus_platform: DbusBase;
|
||||||
|
private dbus_anime: DbusBase;
|
||||||
|
private last_selection = "mini-led";
|
||||||
|
private supported_properties!: platform.Properties;
|
||||||
|
private supported_interfaces: string[] = [];
|
||||||
|
|
||||||
|
private miniLed?: typeof AsusMenuToggle;
|
||||||
|
private panelOd?: typeof AsusMenuToggle;
|
||||||
|
private animeDisplayPower?: typeof AsusMenuToggle;
|
||||||
|
private animePowersaveAnim?: typeof AsusMenuToggle;
|
||||||
|
_itemsSection: popupMenu.PopupMenuSection;
|
||||||
|
|
||||||
|
constructor(dbus_platform: DbusBase, dbus_anime: DbusBase) {
|
||||||
|
super({
|
||||||
|
label: "Laptop",
|
||||||
|
toggle_mode: true,
|
||||||
|
icon_name: "selection-mode-symbolic",
|
||||||
|
});
|
||||||
|
this.label = "Laptop";
|
||||||
|
this.title = "Laptop";
|
||||||
|
this.dbus_platform = dbus_platform;
|
||||||
|
this.dbus_anime = dbus_anime;
|
||||||
|
|
||||||
|
this.menu.setHeader("selection-mode-symbolic", "Laptop features");
|
||||||
|
|
||||||
|
this.last_selection = Extension.lookupByUUID(AsusExtension.uuid)
|
||||||
|
?.getSettings()
|
||||||
|
.get_string("primary-quickmenu-toggle")!;
|
||||||
|
|
||||||
|
this.supported_interfaces = this.dbus_platform?.proxy.SupportedInterfacesSync()[0];
|
||||||
|
this.supported_properties = this.dbus_platform?.proxy.SupportedPropertiesSync()[0];
|
||||||
|
|
||||||
|
// TODO: temporary block
|
||||||
|
if (this.last_selection == "mini-led" && !this.supported_properties.includes("MiniLed")) {
|
||||||
|
this.last_selection = "panel-od";
|
||||||
|
} else if (
|
||||||
|
this.last_selection == "panel-od" &&
|
||||||
|
!this.supported_properties.includes("PanelOd")
|
||||||
|
) {
|
||||||
|
this.last_selection = "anime-power";
|
||||||
|
} else if (
|
||||||
|
this.last_selection == "anime-power" &&
|
||||||
|
!this.supported_interfaces.includes("Anime")
|
||||||
|
) {
|
||||||
|
this.last_selection = "mini-led";
|
||||||
|
} else if (this.last_selection.length == 0) {
|
||||||
|
this.last_selection = "panel-od";
|
||||||
|
}
|
||||||
|
|
||||||
|
// AsusExtension.extension._settings.connect('changed::primary-quickmenu-toggle', this.sync);
|
||||||
|
Extension.lookupByUUID(uuid)
|
||||||
|
?.getSettings()
|
||||||
|
.set_string("primary-quickmenu-toggle", this.last_selection);
|
||||||
|
|
||||||
|
this._itemsSection = new popupMenu.PopupMenuSection();
|
||||||
|
if (this.supported_properties.includes("MiniLed")) {
|
||||||
|
if (this.miniLed == null) {
|
||||||
|
this.miniLed = new AsusMenuToggle(
|
||||||
|
this.dbus_platform,
|
||||||
|
"MiniLed",
|
||||||
|
"mini-led-enabled",
|
||||||
|
"Mini-LED Enabled",
|
||||||
|
);
|
||||||
|
this._itemsSection.addMenuItem(this.miniLed, 0);
|
||||||
|
this.miniLed.toggle_callback = () => {
|
||||||
|
this.last_selection = "mini-led";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.supported_properties.includes("PanelOd")) {
|
||||||
|
if (this.panelOd == null) {
|
||||||
|
this.panelOd = new AsusMenuToggle(
|
||||||
|
this.dbus_platform,
|
||||||
|
"PanelOd",
|
||||||
|
"panel-od-enabled",
|
||||||
|
"Panel Overdrive Enabled",
|
||||||
|
);
|
||||||
|
this._itemsSection.addMenuItem(this.panelOd, 1);
|
||||||
|
this.panelOd.toggle_callback = () => {
|
||||||
|
this.last_selection = "panel-od";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.supported_interfaces.includes("Anime")) {
|
||||||
|
if (this.animeDisplayPower == null) {
|
||||||
|
this.animeDisplayPower = new AsusMenuToggle(
|
||||||
|
this.dbus_anime,
|
||||||
|
"EnableDisplay",
|
||||||
|
"anime-power",
|
||||||
|
"AniMe Display Enabled",
|
||||||
|
);
|
||||||
|
this._itemsSection.addMenuItem(this.animeDisplayPower, 2);
|
||||||
|
this.animeDisplayPower.toggle_callback = () => {
|
||||||
|
this.last_selection = "anime-power";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.animePowersaveAnim == null) {
|
||||||
|
this.animePowersaveAnim = new AsusMenuToggle(
|
||||||
|
this.dbus_anime,
|
||||||
|
"BuiltinsEnabled",
|
||||||
|
"anime-builtins",
|
||||||
|
"AniMe Built-in Animations",
|
||||||
|
);
|
||||||
|
this._itemsSection.addMenuItem(this.animePowersaveAnim, 3);
|
||||||
|
this.animePowersaveAnim.toggle_callback = () => {
|
||||||
|
this.last_selection = "anime-builtins";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.connectObject(
|
||||||
|
"clicked",
|
||||||
|
() => {
|
||||||
|
this._toggle();
|
||||||
|
},
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
|
||||||
|
this.menu.addMenuItem(this._itemsSection, 0);
|
||||||
|
|
||||||
|
this.dbus_platform?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
|
||||||
|
//const properties = changed.deepUnpack();
|
||||||
|
this.sync();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.dbus_anime?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
|
||||||
|
//const properties = changed.deepUnpack();
|
||||||
|
this.sync();
|
||||||
|
});
|
||||||
|
|
||||||
|
// // Add an entry-point for more extension._settings
|
||||||
|
// this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
||||||
|
// const settingsItem = this.menu.addAction("More Settings",
|
||||||
|
// () => ExtensionUtils.openPrefs());
|
||||||
|
// // Ensure the extension._settings are unavailable when the screen is locked
|
||||||
|
// settingsItem.visible = Main.sessionMode.allowSettings;
|
||||||
|
// this.menu._settingsActions[Me.uuid] = settingsItem;
|
||||||
|
|
||||||
|
this.sync();
|
||||||
|
addQuickSettingsItems([this]);
|
||||||
|
}
|
||||||
|
|
||||||
|
_toggle() {
|
||||||
|
if (this.last_selection == "mini-led" && this.miniLed != null) {
|
||||||
|
if (this.checked !== this.dbus_platform.proxy.MiniLed)
|
||||||
|
this.dbus_platform.proxy.MiniLed = this.checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.last_selection == "panel-od" && this.panelOd != null) {
|
||||||
|
if (this.checked !== this.dbus_platform.proxy.PanelOd) {
|
||||||
|
this.dbus_platform.proxy.PanelOd = this.checked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.last_selection == "anime-power" && this.animeDisplayPower != null) {
|
||||||
|
if (this.checked !== this.dbus_anime.proxy.EnableDisplay)
|
||||||
|
this.dbus_anime.proxy.EnableDisplay = this.checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.last_selection == "anime-builtins" && this.animePowersaveAnim != null) {
|
||||||
|
if (this.checked !== this.dbus_anime.proxy.BuiltinsEnabled)
|
||||||
|
this.dbus_anime.proxy.BuiltinsEnabled = this.checked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sync() {
|
||||||
|
let checked = false;
|
||||||
|
if (this.last_selection == "mini-led" && this.miniLed != null) {
|
||||||
|
this.title = this.miniLed.title;
|
||||||
|
checked = this.dbus_platform.proxy.MiniLed;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.last_selection == "panel-od" && this.panelOd != null) {
|
||||||
|
this.title = this.panelOd.title;
|
||||||
|
checked = this.dbus_platform.proxy.PanelOd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.last_selection == "anime-power" && this.animeDisplayPower != null) {
|
||||||
|
this.title = this.animeDisplayPower.title;
|
||||||
|
checked = this.dbus_anime.proxy.EnableDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.last_selection == "anime-builtins" && this.animePowersaveAnim != null) {
|
||||||
|
this.title = this.animePowersaveAnim.title;
|
||||||
|
checked = this.dbus_anime.proxy.BuiltinsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (this.animePowersaveAnim != null) {
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (this.checked !== checked) this.set({ checked });
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
// this.panelOd?.destroy();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
26
desktop-extensions/gnome-45/src/modules/rog_indicator.ts
Normal file
26
desktop-extensions/gnome-45/src/modules/rog_indicator.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
|
||||||
|
import { quickSettings, main } from "@girs/gnome-shell/ui";
|
||||||
|
import { Gio } from "@girs/gio-2.0";
|
||||||
|
import { GObject } from "@girs/gobject-2.0";
|
||||||
|
import { uuid } from "../extension";
|
||||||
|
//import { DbusBase } from '../dbus_proxy';
|
||||||
|
|
||||||
|
export const AsusIndicator = GObject.registerClass(
|
||||||
|
class AsusIndicator extends quickSettings.SystemIndicator {
|
||||||
|
private _indicator: any;
|
||||||
|
private _settings: Gio.Settings | undefined;
|
||||||
|
|
||||||
|
constructor(icon_name: string, setting_name: string) {
|
||||||
|
super();
|
||||||
|
// Create an icon for the indicator
|
||||||
|
this._indicator = this._addIndicator();
|
||||||
|
this._indicator.icon_name = icon_name;
|
||||||
|
|
||||||
|
// Showing an indicator when the feature is enabled
|
||||||
|
this._settings = Extension.lookupByUUID(uuid)?.getSettings();
|
||||||
|
this._settings?.bind(setting_name, this._indicator, "visible", Gio.SettingsBindFlags.DEFAULT);
|
||||||
|
|
||||||
|
main.panel.statusArea.quickSettings.addExternalIndicator(this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
50
desktop-extensions/gnome-45/src/modules/rog_menu_toggle.ts
Normal file
50
desktop-extensions/gnome-45/src/modules/rog_menu_toggle.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { popupMenu } from "@girs/gnome-shell/ui";
|
||||||
|
import { GObject } from "@girs/gobject-2.0";
|
||||||
|
import { DbusBase } from "./dbus_proxy";
|
||||||
|
|
||||||
|
export const AsusMenuToggle = GObject.registerClass(
|
||||||
|
class AsusMenuToggle extends popupMenu.PopupSwitchMenuItem {
|
||||||
|
public title: string = "";
|
||||||
|
dbus!: DbusBase;
|
||||||
|
prop_name: string = "";
|
||||||
|
public toggle_callback = () => {};
|
||||||
|
|
||||||
|
constructor(dbus: DbusBase, prop_name: string, setting: string, title: string) {
|
||||||
|
super(title, true);
|
||||||
|
this.prop_name = prop_name;
|
||||||
|
this.dbus = dbus;
|
||||||
|
this.title = title;
|
||||||
|
|
||||||
|
this.dbus?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
|
||||||
|
const properties = changed.deepUnpack();
|
||||||
|
// .find() fails on some shit for some reason
|
||||||
|
for (const v of Object.entries(properties)) {
|
||||||
|
if (v[0] == this.prop_name) {
|
||||||
|
this.sync();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.connectObject("toggled", () => this._toggleMode(), this);
|
||||||
|
|
||||||
|
this.connect("destroy", () => {
|
||||||
|
this.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
_toggleMode() {
|
||||||
|
// hacky shit, index to get base object property and set it
|
||||||
|
const state = this.dbus.proxy[this.prop_name];
|
||||||
|
if (this.state !== state) this.dbus.proxy[this.prop_name] = this.state;
|
||||||
|
this.toggle_callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
sync() {
|
||||||
|
const state = this.dbus.proxy[this.prop_name];
|
||||||
|
if (this.state !== state) this.setToggleState(state);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
64
desktop-extensions/gnome-45/src/modules/rog_quick_toggle.ts
Normal file
64
desktop-extensions/gnome-45/src/modules/rog_quick_toggle.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
|
||||||
|
import { addQuickSettingsItems } from "./helpers";
|
||||||
|
import { quickSettings } from "@girs/gnome-shell/ui";
|
||||||
|
import { Gio } from "@girs/gio-2.0";
|
||||||
|
import { GObject } from "@girs/gobject-2.0";
|
||||||
|
import { uuid } from "../extension";
|
||||||
|
import { DbusBase } from "./dbus_proxy";
|
||||||
|
|
||||||
|
export const AsusQuickToggle = GObject.registerClass(
|
||||||
|
class AsusQuickToggle extends quickSettings.QuickToggle {
|
||||||
|
dbus!: DbusBase;
|
||||||
|
prop_name: string = "";
|
||||||
|
public toggle_callback = () => {};
|
||||||
|
|
||||||
|
constructor(dbus: DbusBase, prop_name: string, setting: string, title: string) {
|
||||||
|
super({
|
||||||
|
label: title,
|
||||||
|
icon_name: "selection-mode-symbolic",
|
||||||
|
toggle_mode: true,
|
||||||
|
});
|
||||||
|
this.prop_name = prop_name;
|
||||||
|
this.label = title;
|
||||||
|
this.dbus = dbus;
|
||||||
|
|
||||||
|
this.dbus?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
|
||||||
|
const properties = changed.deepUnpack();
|
||||||
|
// .find() fails on some shit for some reason
|
||||||
|
for (const v of Object.entries(properties)) {
|
||||||
|
if (v[0] == this.prop_name) {
|
||||||
|
const checked = v[1].unpack();
|
||||||
|
if (this.checked !== checked) this.checked = checked;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.connectObject("clicked", () => this._toggleMode(), this);
|
||||||
|
|
||||||
|
this.connect("destroy", () => {
|
||||||
|
this.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
Extension.lookupByUUID(uuid)
|
||||||
|
?.getSettings()
|
||||||
|
.bind(setting, this, "checked", Gio.SettingsBindFlags.DEFAULT);
|
||||||
|
|
||||||
|
this.sync();
|
||||||
|
|
||||||
|
addQuickSettingsItems([this]);
|
||||||
|
}
|
||||||
|
|
||||||
|
_toggleMode() {
|
||||||
|
// hacky shit, index to get base object property and set it
|
||||||
|
const checked = this.dbus.proxy[this.prop_name];
|
||||||
|
if (this.checked !== checked) this.dbus.proxy[this.prop_name] = this.checked;
|
||||||
|
this.toggle_callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
sync() {
|
||||||
|
const checked = this.dbus.proxy[this.prop_name];
|
||||||
|
if (this.checked !== checked) this.set({ checked });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
75
desktop-extensions/gnome-45/src/modules/rog_slider_100pc.ts
Normal file
75
desktop-extensions/gnome-45/src/modules/rog_slider_100pc.ts
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import { Extension, gettext as _ } from "@girs/gnome-shell/extensions/extension";
|
||||||
|
import { addQuickSettingsItems } from "./helpers";
|
||||||
|
import { quickSettings } from "@girs/gnome-shell/ui";
|
||||||
|
import { Gio } from "@girs/gio-2.0";
|
||||||
|
import { GObject } from "@girs/gobject-2.0";
|
||||||
|
import { uuid } from "../extension";
|
||||||
|
import { DbusBase } from "./dbus_proxy";
|
||||||
|
|
||||||
|
export const AsusSlider = GObject.registerClass(
|
||||||
|
class AsusSlider extends quickSettings.QuickSlider {
|
||||||
|
private dbus: DbusBase;
|
||||||
|
private settings: any = undefined;
|
||||||
|
private setting = "";
|
||||||
|
private prop_name = "";
|
||||||
|
|
||||||
|
constructor(dbus: DbusBase, prop_name: string, setting: string, title: string) {
|
||||||
|
super({
|
||||||
|
label: title,
|
||||||
|
icon_name: "selection-mode-symbolic",
|
||||||
|
});
|
||||||
|
this.label = title;
|
||||||
|
this.dbus = dbus;
|
||||||
|
this.setting = setting;
|
||||||
|
this.prop_name = prop_name;
|
||||||
|
this.settings = Extension.lookupByUUID(uuid)?.getSettings();
|
||||||
|
|
||||||
|
this._sliderChangedId = this.slider.connect("drag-end", this._onSliderChanged.bind(this));
|
||||||
|
|
||||||
|
// Binding the slider to a GSettings key
|
||||||
|
|
||||||
|
this.settings.connect(`changed::${this.setting}`, this._onSettingsChanged.bind(this));
|
||||||
|
|
||||||
|
// Set an accessible name for the slider
|
||||||
|
this.slider.accessible_name = title;
|
||||||
|
|
||||||
|
this.dbus?.proxy.connect("g-properties-changed", (_proxy, changed, invalidated) => {
|
||||||
|
const properties = changed.deepUnpack();
|
||||||
|
// .find() fails on some shit for some reason
|
||||||
|
for (const v of Object.entries(properties)) {
|
||||||
|
if (v[0] == this.prop_name) {
|
||||||
|
const checked = v[1].unpack();
|
||||||
|
this._sync();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this._sync();
|
||||||
|
this._onSettingsChanged();
|
||||||
|
|
||||||
|
addQuickSettingsItems([this], 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onSettingsChanged() {
|
||||||
|
// Prevent the slider from emitting a change signal while being updated
|
||||||
|
this.slider.block_signal_handler(this._sliderChangedId);
|
||||||
|
this.slider.value = this.settings.get_uint(this.setting) / 100.0;
|
||||||
|
this.slider.unblock_signal_handler(this._sliderChangedId);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onSliderChanged() {
|
||||||
|
// Assuming our GSettings holds values between 0..100, adjust for the
|
||||||
|
// slider taking values between 0..1
|
||||||
|
const percent = Math.floor(this.slider.value * 100);
|
||||||
|
const stored = Math.floor(this.settings.get_uint(this.setting) / 100.0);
|
||||||
|
if (this.slider.value !== stored) this.dbus.proxy[this.prop_name] = percent;
|
||||||
|
this.settings.set_uint(this.setting, percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
_sync() {
|
||||||
|
const value = this.dbus.proxy[this.prop_name];
|
||||||
|
if (this.slider.value !== value / 100) this.settings.set_uint(this.setting, value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
19
desktop-extensions/gnome-45/tsconfig.json
Normal file
19
desktop-extensions/gnome-45/tsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
// "extends": "@tsconfig/strictest/tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["ESNext"],
|
||||||
|
"types": [],
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"declaration": true,
|
||||||
|
"removeComments": true,
|
||||||
|
"strict": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"paths": {},
|
||||||
|
"skipLibCheck": true
|
||||||
|
},
|
||||||
|
"files": ["./src/extension.ts"],
|
||||||
|
"include": ["src/*.ts"],
|
||||||
|
"exclude": [".ts-for-girrc.js", ".eslintrc.cjs"]
|
||||||
|
}
|
||||||
1584
desktop-extensions/gnome-45/yarn.lock
Normal file
1584
desktop-extensions/gnome-45/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,25 +0,0 @@
|
|||||||
/* eslint-env node */
|
|
||||||
module.exports = {
|
|
||||||
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
|
||||||
parser: "@typescript-eslint/parser",
|
|
||||||
plugins: ["@typescript-eslint"],
|
|
||||||
root: true,
|
|
||||||
|
|
||||||
"rules": {
|
|
||||||
// enable additional rules
|
|
||||||
"indent": ["error", 4],
|
|
||||||
"linebreak-style": ["error", "unix"],
|
|
||||||
"quotes": ["error", "double"],
|
|
||||||
"semi": ["error", "always"],
|
|
||||||
|
|
||||||
// override configuration set by extending "eslint:recommended"
|
|
||||||
"no-empty": "warn",
|
|
||||||
"no-cond-assign": ["error", "always"],
|
|
||||||
|
|
||||||
// disable rules from base configurations
|
|
||||||
"for-direction": "off",
|
|
||||||
|
|
||||||
"@typescript-eslint/no-explicit-any": "warn",
|
|
||||||
"@typescript-eslint/ban-ts-comment": "off"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
const { build } = require("esbuild");
|
|
||||||
const fs = require("fs");
|
|
||||||
const path = require("path");
|
|
||||||
var exec = require('child_process').exec;
|
|
||||||
const AdmZip = require("adm-zip");
|
|
||||||
const metadata = require("./src/metadata.json");
|
|
||||||
|
|
||||||
build({
|
|
||||||
entryPoints: ['src/extension.ts'],
|
|
||||||
outdir: 'dist',
|
|
||||||
bundle: true,
|
|
||||||
// Do not remove the functions `enable()`, `disable()` and `init()`
|
|
||||||
treeShaking: false,
|
|
||||||
// firefox60 // Since GJS 1.53.90
|
|
||||||
// firefox68 // Since GJS 1.63.90
|
|
||||||
// firefox78 // Since GJS 1.65.90
|
|
||||||
// firefox91 // Since GJS 1.71.1
|
|
||||||
// firefox102 // Since GJS 1.73.2
|
|
||||||
target: "firefox78",
|
|
||||||
platform: "node",
|
|
||||||
// platform: "neutral",
|
|
||||||
// mainFields: ['main'],
|
|
||||||
// conditions: ['require', 'default'],
|
|
||||||
// format: 'cjs',
|
|
||||||
external: ['gi://*', 'system', 'gettext', 'cairo'],
|
|
||||||
}).then(() => {
|
|
||||||
const metaSrc = path.resolve(__dirname, "src/metadata.json");
|
|
||||||
const metaDist = path.resolve(__dirname, "dist/metadata.json");
|
|
||||||
const schemaSrc = path.resolve(__dirname, "schemas");
|
|
||||||
const schemaDist = path.resolve(__dirname, "dist/schemas");
|
|
||||||
const dbusXmlSrc = path.resolve(__dirname, "../../bindings/dbus-xml");
|
|
||||||
const dbusXmlDist = path.resolve(__dirname, "dist/resources/dbus");
|
|
||||||
const zipFilename = `${metadata.uuid}.zip`;
|
|
||||||
const zipDist = path.resolve(__dirname, zipFilename);
|
|
||||||
|
|
||||||
exec('glib-compile-schemas schemas/',
|
|
||||||
(error, stdout, stderr) => {
|
|
||||||
console.log('stdout: ' + stdout);
|
|
||||||
console.log('stderr: ' + stderr);
|
|
||||||
});
|
|
||||||
|
|
||||||
fs.copyFileSync(metaSrc, metaDist);
|
|
||||||
|
|
||||||
fs.cpSync(schemaSrc, schemaDist, { recursive: true }, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
fs.cpSync(dbusXmlSrc, dbusXmlDist, { recursive: true }, (err) => {
|
|
||||||
if (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const zip = new AdmZip();
|
|
||||||
zip.addLocalFolder(path.resolve(__dirname, "dist"));
|
|
||||||
zip.writeZip(zipDist);
|
|
||||||
|
|
||||||
console.log(`Build complete. Zip file: ${zipFilename}\n`);
|
|
||||||
console.log(`Install with: gnome-extensions install ${zipFilename}`)
|
|
||||||
console.log(`Update with: gnome-extensions install ${zipFilename} --force`)
|
|
||||||
console.log(`Enable with: gnome-extensions enable ${metadata.uuid} --user`)
|
|
||||||
});
|
|
||||||
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
import { AnimeDbus } from "./modules/dbus/animatrix";
|
|
||||||
import { Power } from "./modules/dbus/power";
|
|
||||||
import { Supported } from "./modules/dbus/supported";
|
|
||||||
import { Platform } from "./modules/dbus/platform";
|
|
||||||
|
|
||||||
import { QuickPanelOd } from "./modules/quick_toggles/panel_od";
|
|
||||||
import { IndicateMiniLed } from "./modules/indicators/mini_led";
|
|
||||||
import { QuickMiniLed } from "./modules/quick_toggles/mini_led";
|
|
||||||
import { SliderChargeLevel } from "./modules/sliders/charge";
|
|
||||||
import { QuickAnimePower } from "./modules/quick_toggles/anime_power";
|
|
||||||
import { FeatureMenuToggle } from "./modules/quick_menus/laptop_features";
|
|
||||||
import { AuraDbus } from "./modules/dbus/aura";
|
|
||||||
import { AuraMenuToggle } from "./modules/quick_menus/aura";
|
|
||||||
|
|
||||||
class Extension {
|
|
||||||
private _indicateMiniLed: typeof IndicateMiniLed;
|
|
||||||
private _quickMiniLed: typeof QuickMiniLed;
|
|
||||||
private _quickPanelOd: typeof QuickPanelOd;
|
|
||||||
private _quickAnimePower: typeof QuickAnimePower;
|
|
||||||
private _featureMenuToggle: typeof FeatureMenuToggle;
|
|
||||||
private _auraModeMenuToggle: typeof AuraMenuToggle;
|
|
||||||
private _sliderCharge: typeof SliderChargeLevel;
|
|
||||||
|
|
||||||
public dbus_supported: Supported = new Supported;
|
|
||||||
public dbus_power: Power = new Power;
|
|
||||||
public dbus_aura: AuraDbus = new AuraDbus;
|
|
||||||
public dbus_anime: AnimeDbus = new AnimeDbus;
|
|
||||||
public dbus_platform: Platform = new Platform;
|
|
||||||
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this._indicateMiniLed = null;
|
|
||||||
this._quickMiniLed = null;
|
|
||||||
this._quickPanelOd = null;
|
|
||||||
this._quickAnimePower = null;
|
|
||||||
this._sliderCharge = null;
|
|
||||||
|
|
||||||
this.dbus_supported.start();
|
|
||||||
this.dbus_aura.start();
|
|
||||||
this.dbus_platform.start();
|
|
||||||
this.dbus_power.start();
|
|
||||||
this.dbus_anime.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
enable() {
|
|
||||||
if (this._featureMenuToggle == null) {
|
|
||||||
this._featureMenuToggle = new FeatureMenuToggle(this.dbus_supported, this.dbus_platform, this.dbus_anime);
|
|
||||||
}
|
|
||||||
if (this._auraModeMenuToggle == null) {
|
|
||||||
this._auraModeMenuToggle = new AuraMenuToggle(this.dbus_aura);
|
|
||||||
}
|
|
||||||
if (this.dbus_supported.supported.rog_bios_ctrl.mini_led_mode) {
|
|
||||||
// if (this._quickMiniLed == null) {
|
|
||||||
// this._quickMiniLed = new QuickMiniLed(this.dbus_platform);
|
|
||||||
// this.dbus_platform.notifyMiniLedSubscribers.push(this._quickMiniLed);
|
|
||||||
// }
|
|
||||||
if (this._indicateMiniLed == null) {
|
|
||||||
this._indicateMiniLed = new IndicateMiniLed(this.dbus_platform);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if (this.dbus_supported.supported.rog_bios_ctrl.panel_overdrive) {
|
|
||||||
// if (this._quickPanelOd == null) {
|
|
||||||
// this._quickPanelOd = new QuickPanelOd(this.dbus_platform);
|
|
||||||
// this.dbus_platform.notifyPanelOdSubscribers.push(this._quickPanelOd);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (this.dbus_supported.supported.anime_ctrl) {
|
|
||||||
// if (this._quickAnimePower == null) {
|
|
||||||
// this._quickAnimePower = new QuickAnimePower(this._dbus_anime);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
if (this.dbus_supported.supported.charge_ctrl.charge_level_set) {
|
|
||||||
if (this._sliderCharge == null) {
|
|
||||||
this._sliderCharge = new SliderChargeLevel(this.dbus_power);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
disable() {
|
|
||||||
if (this._indicateMiniLed != null) {
|
|
||||||
this._indicateMiniLed.destroy();
|
|
||||||
this._indicateMiniLed = null;
|
|
||||||
}
|
|
||||||
if (this._quickMiniLed != null) {
|
|
||||||
this._quickMiniLed.destroy();
|
|
||||||
this._quickMiniLed = null;
|
|
||||||
}
|
|
||||||
if (this._quickPanelOd != null) {
|
|
||||||
this._quickPanelOd.destroy();
|
|
||||||
this._quickPanelOd = null;
|
|
||||||
}
|
|
||||||
if (this._quickAnimePower != null) {
|
|
||||||
this._quickAnimePower.destroy();
|
|
||||||
this._quickAnimePower = null;
|
|
||||||
}
|
|
||||||
if (this._sliderCharge != null) {
|
|
||||||
this._sliderCharge.destroy();
|
|
||||||
this._sliderCharge = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.dbus_power.stop();
|
|
||||||
this.dbus_platform.stop();
|
|
||||||
this.dbus_anime.stop();
|
|
||||||
this.dbus_aura.stop();
|
|
||||||
this.dbus_supported.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
function init() {
|
|
||||||
return new Extension();
|
|
||||||
}
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
import { DbusBase } from "./base";
|
|
||||||
import { DeviceState, AnimBooting, Brightness, AnimAwake, AnimSleeping, AnimShutdown } from "../../bindings/anime";
|
|
||||||
|
|
||||||
export class AnimeDbus extends DbusBase {
|
|
||||||
deviceState: DeviceState = {
|
|
||||||
display_enabled: false,
|
|
||||||
display_brightness: Brightness.Med,
|
|
||||||
builtin_anims_enabled: false,
|
|
||||||
builtin_anims: {
|
|
||||||
boot: AnimBooting.GlitchConstruction,
|
|
||||||
awake: AnimAwake.BinaryBannerScroll,
|
|
||||||
sleep: AnimSleeping.BannerSwipe,
|
|
||||||
shutdown: AnimShutdown.GlitchOut
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: interface or something to enforce requirement of "sync()" method
|
|
||||||
public notifyAnimeStateSubscribers: any[] = [];
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super("org-asuslinux-anime-4", "/org/asuslinux/Anime");
|
|
||||||
}
|
|
||||||
|
|
||||||
public setEnableDisplay(state: boolean | null) {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
// if null, toggle the current state
|
|
||||||
state = (state == null ? !this.deviceState.display_enabled : state);
|
|
||||||
|
|
||||||
if (this.deviceState.display_enabled !== state) {
|
|
||||||
this.deviceState.display_enabled = state;
|
|
||||||
}
|
|
||||||
return this.dbus_proxy.SetEnableDisplaySync(state);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("AniMe DBus set power failed!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public setPowersaveAnim(state: boolean | null) {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
// if null, toggle the current state
|
|
||||||
state = (state == null ? !this.deviceState.builtin_anims_enabled : state);
|
|
||||||
|
|
||||||
if (this.deviceState.builtin_anims_enabled !== state) {
|
|
||||||
this.deviceState.builtin_anims_enabled = state;
|
|
||||||
}
|
|
||||||
return this.dbus_proxy.SetEnableBuiltinsSync(state);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("AniMe DBus set builtins failed!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public setBrightness(brightness: Brightness) {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
if (this.deviceState.display_brightness !== brightness) {
|
|
||||||
this.deviceState.display_brightness = brightness;
|
|
||||||
}
|
|
||||||
return this.dbus_proxy.SetBrightnessSync(brightness);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("AniMe DBus set brightness failed!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_parseData(data: any) {
|
|
||||||
if (data.length > 0) {
|
|
||||||
this.deviceState.display_enabled = data[0];
|
|
||||||
this.deviceState.display_brightness = Brightness[data[1] as Brightness];
|
|
||||||
this.deviceState.builtin_anims_enabled = data[2];
|
|
||||||
this.deviceState.builtin_anims.boot = AnimBooting[data[3][0] as AnimBooting];
|
|
||||||
this.deviceState.builtin_anims.awake = AnimAwake[data[3][1] as AnimAwake];
|
|
||||||
this.deviceState.builtin_anims.sleep = AnimSleeping[data[3][2] as AnimSleeping];
|
|
||||||
this.deviceState.builtin_anims.shutdown = AnimShutdown[data[3][2] as AnimShutdown];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public getDeviceState() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
// janky shit going on with DeviceStateSync
|
|
||||||
this._parseData(this.dbus_proxy.DeviceStateSync());
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch DeviceState!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.deviceState;
|
|
||||||
}
|
|
||||||
|
|
||||||
async start() {
|
|
||||||
await super.start();
|
|
||||||
this.getDeviceState();
|
|
||||||
|
|
||||||
this.dbus_proxy.connectSignal(
|
|
||||||
"NotifyDeviceState",
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
(proxy: any = null, name: string, data: string) => {
|
|
||||||
if (proxy) {
|
|
||||||
// idiot xml parsing mneans the get is not nested while this is
|
|
||||||
this._parseData(data[0]);
|
|
||||||
this.notifyAnimeStateSubscribers.forEach(sub => {
|
|
||||||
sub.sync();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async stop() {
|
|
||||||
await super.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,284 +0,0 @@
|
|||||||
import { AuraDevRog1, AuraDevTuf, AuraDevice, AuraEffect, AuraModeNum, AuraPower, AuraPowerDev, AuraZone, Direction, PowerZones, Speed } from "../../bindings/aura";
|
|
||||||
import { DbusBase } from "./base";
|
|
||||||
|
|
||||||
export class AuraDbus extends DbusBase {
|
|
||||||
public device: AuraDevice = AuraDevice.Unknown;
|
|
||||||
public current_aura_mode: AuraModeNum = AuraModeNum.Static;
|
|
||||||
public aura_modes: Map<AuraModeNum, AuraEffect> = new Map;
|
|
||||||
public leds_powered: AuraPowerDev = {
|
|
||||||
tuf: [],
|
|
||||||
old_rog: [],
|
|
||||||
rog: {
|
|
||||||
keyboard: {
|
|
||||||
zone: PowerZones.Keyboard,
|
|
||||||
boot: false,
|
|
||||||
awake: false,
|
|
||||||
sleep: false,
|
|
||||||
shutdown: false
|
|
||||||
},
|
|
||||||
logo: {
|
|
||||||
zone: PowerZones.Logo,
|
|
||||||
boot: false,
|
|
||||||
awake: false,
|
|
||||||
sleep: false,
|
|
||||||
shutdown: false
|
|
||||||
},
|
|
||||||
lightbar: {
|
|
||||||
zone: PowerZones.Lightbar,
|
|
||||||
boot: false,
|
|
||||||
awake: false,
|
|
||||||
sleep: false,
|
|
||||||
shutdown: false
|
|
||||||
},
|
|
||||||
lid: {
|
|
||||||
zone: PowerZones.Lid,
|
|
||||||
boot: false,
|
|
||||||
awake: false,
|
|
||||||
sleep: false,
|
|
||||||
shutdown: false
|
|
||||||
},
|
|
||||||
rear_glow: {
|
|
||||||
zone: PowerZones.RearGlow,
|
|
||||||
boot: false,
|
|
||||||
awake: false,
|
|
||||||
sleep: false,
|
|
||||||
shutdown: false
|
|
||||||
},
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// TODO: interface or something to enforce requirement of "sync()" method
|
|
||||||
public notifyAuraModeSubscribers: any[] = [];
|
|
||||||
public notifyAuraPowerSubscribers: any[] = [];
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super("org-asuslinux-aura-4", "/org/asuslinux/Aura");
|
|
||||||
}
|
|
||||||
|
|
||||||
public getDevice() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
this.device = AuraDevice[this.dbus_proxy.DeviceTypeSync() as AuraDevice];
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED device: " + this.device);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch supported functionalities", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_parsePowerStates(data: any[]) {
|
|
||||||
const power: AuraPowerDev = this.leds_powered;
|
|
||||||
|
|
||||||
power.tuf = data[0].map((value: string) => {
|
|
||||||
return AuraDevTuf[value as AuraDevTuf];
|
|
||||||
});
|
|
||||||
power.old_rog = data[1].map((value: string) => {
|
|
||||||
return AuraDevRog1[value as AuraDevRog1];
|
|
||||||
});
|
|
||||||
power.rog = {
|
|
||||||
keyboard: {
|
|
||||||
zone: PowerZones[data[2][0][0] as PowerZones],
|
|
||||||
boot: data[2][0][1],
|
|
||||||
awake: data[2][0][2],
|
|
||||||
sleep: data[2][0][3],
|
|
||||||
shutdown: data[2][0][4]
|
|
||||||
},
|
|
||||||
logo: {
|
|
||||||
zone: PowerZones[data[2][1][0] as PowerZones],
|
|
||||||
boot: data[2][1][1],
|
|
||||||
awake: data[2][1][2],
|
|
||||||
sleep: data[2][1][3],
|
|
||||||
shutdown: data[2][1][4]
|
|
||||||
},
|
|
||||||
lightbar: {
|
|
||||||
zone: PowerZones[data[2][2][0] as PowerZones],
|
|
||||||
boot: data[2][2][1],
|
|
||||||
awake: data[2][2][2],
|
|
||||||
sleep: data[2][2][3],
|
|
||||||
shutdown: data[2][2][4]
|
|
||||||
},
|
|
||||||
lid: {
|
|
||||||
zone: PowerZones[data[2][3][0] as PowerZones],
|
|
||||||
boot: data[2][3][1],
|
|
||||||
awake: data[2][3][2],
|
|
||||||
sleep: data[2][3][3],
|
|
||||||
shutdown: data[2][3][4]
|
|
||||||
},
|
|
||||||
rear_glow: {
|
|
||||||
zone: PowerZones[data[2][4][0] as PowerZones],
|
|
||||||
boot: data[2][4][1],
|
|
||||||
awake: data[2][4][2],
|
|
||||||
sleep: data[2][4][3],
|
|
||||||
shutdown: data[2][4][4]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return power;
|
|
||||||
}
|
|
||||||
|
|
||||||
public getLedPower() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
const data = this.dbus_proxy.LedPowerSync();
|
|
||||||
this.leds_powered = this._parsePowerStates(data);
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED power tuf: " + this.leds_powered.tuf);
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED power x1866: " + this.leds_powered.old_rog);
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED power x19b6: " + this.leds_powered.rog);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch supported functionalities", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public getLedMode() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
this.current_aura_mode = AuraModeNum[this.dbus_proxy.LedModeSync() as AuraModeNum];
|
|
||||||
//@ts-ignore
|
|
||||||
log("Current LED mode:", this.current_aura_mode);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch supported functionalities", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public setLedMode(mode: AuraEffect) {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
this.dbus_proxy.SetLedModeSync([
|
|
||||||
mode.mode,
|
|
||||||
mode.zone,
|
|
||||||
[mode.colour1.r, mode.colour1.g, mode.colour1.b],
|
|
||||||
[mode.colour2.r, mode.colour2.g, mode.colour2.b],
|
|
||||||
mode.speed,
|
|
||||||
mode.direction]);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch supported functionalities", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_parseAuraEffect(data: any[]) {
|
|
||||||
const aura: AuraEffect = {
|
|
||||||
mode: AuraModeNum[data[0] as AuraModeNum],
|
|
||||||
zone: AuraZone[data[1] as AuraZone],
|
|
||||||
colour1: {
|
|
||||||
r: parseInt(data[2][0]),
|
|
||||||
g: parseInt(data[2][1]),
|
|
||||||
b: parseInt(data[2][2]),
|
|
||||||
},
|
|
||||||
colour2: {
|
|
||||||
r: parseInt(data[3][0]),
|
|
||||||
g: parseInt(data[3][1]),
|
|
||||||
b: parseInt(data[3][2]),
|
|
||||||
},
|
|
||||||
speed: Speed[data[4] as Speed],
|
|
||||||
direction: Direction[data[5] as Direction],
|
|
||||||
};
|
|
||||||
return aura;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return a list of the available modes, and the current settings for each
|
|
||||||
public getLedModes() {
|
|
||||||
// {'Breathe': ('Breathe', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right'),
|
|
||||||
// 'Comet': ('Comet', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right'),
|
|
||||||
// 'Static': ('Static', 'None', (78, 0, 0), (0, 0, 0), 'Med', 'Right'),
|
|
||||||
// 'Strobe': ('Strobe', 'None', (166, 0, 0), (0, 0, 0), 'Med', 'Right')}
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
const _data = this.dbus_proxy.LedModesSync();
|
|
||||||
for (const key in _data[0]) {
|
|
||||||
const data = _data[0][key];
|
|
||||||
const aura: AuraEffect = this._parseAuraEffect(data);
|
|
||||||
this.aura_modes.set(AuraModeNum[key as AuraModeNum], aura);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const [key, value] of this.aura_modes) {
|
|
||||||
//@ts-ignore
|
|
||||||
log(key, value.zone, value.colour1.r, value.speed, value.direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch supported functionalities", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async start() {
|
|
||||||
try {
|
|
||||||
await super.start();
|
|
||||||
this.getDevice();
|
|
||||||
this.getLedPower();
|
|
||||||
this.getLedMode();
|
|
||||||
this.getLedModes();
|
|
||||||
|
|
||||||
//@ts-ignore
|
|
||||||
log("Current LED mode data:", this.aura_modes.get(this.current_aura_mode)?.speed);
|
|
||||||
|
|
||||||
this.dbus_proxy.connectSignal(
|
|
||||||
"NotifyLed",
|
|
||||||
(proxy: any = null, name: string, data: any) => {
|
|
||||||
if (proxy) {
|
|
||||||
const aura: AuraEffect = this._parseAuraEffect(data[0]);
|
|
||||||
this.current_aura_mode = aura.mode;
|
|
||||||
this.aura_modes.set(aura.mode, aura);
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED data has changed to ", aura.mode, aura.zone, aura.colour1.r, aura.speed, aura.direction);
|
|
||||||
this.notifyAuraModeSubscribers.forEach(sub => {
|
|
||||||
sub.sync();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.dbus_proxy.connectSignal(
|
|
||||||
"NotifyPowerStates",
|
|
||||||
(proxy: any = null, name: string, data: any) => {
|
|
||||||
if (proxy) {
|
|
||||||
const power: AuraPowerDev = this._parsePowerStates(data[0]);
|
|
||||||
this.leds_powered = power;
|
|
||||||
switch (this.device) {
|
|
||||||
case AuraDevice.Tuf:
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED power has changed to ", this.leds_powered.tuf);
|
|
||||||
break;
|
|
||||||
case AuraDevice.X1854:
|
|
||||||
case AuraDevice.X1869:
|
|
||||||
case AuraDevice.X18c6:
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED power has changed to ", this.leds_powered.old_rog);
|
|
||||||
break;
|
|
||||||
case AuraDevice.X19b6:
|
|
||||||
case AuraDevice.X1a30:
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED power has changed to ", this.leds_powered.rog);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
//@ts-ignore
|
|
||||||
log("LED power has changed to ", this.leds_powered.rog);
|
|
||||||
this.notifyAuraPowerSubscribers.forEach(sub => {
|
|
||||||
sub.sync();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Supported DBus initialization failed!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async stop() {
|
|
||||||
await super.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
declare const imports: any;
|
|
||||||
|
|
||||||
import * as Resources from "../resources";
|
|
||||||
|
|
||||||
const { Gio } = imports.gi;
|
|
||||||
|
|
||||||
export class DbusBase {
|
|
||||||
dbus_proxy: any = null; // type: Gio.DbusProxy
|
|
||||||
connected = false;
|
|
||||||
xml_resource = "";
|
|
||||||
dbus_path = "";
|
|
||||||
|
|
||||||
constructor(resource: string, dbus_path: string) {
|
|
||||||
this.xml_resource = resource;
|
|
||||||
this.dbus_path = dbus_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
async start() {
|
|
||||||
//@ts-ignore
|
|
||||||
log(`Starting ${this.dbus_path} dbus module`);
|
|
||||||
try {
|
|
||||||
const xml = Resources.File.DBus(this.xml_resource);
|
|
||||||
this.dbus_proxy = new Gio.DBusProxy.makeProxyWrapper(xml)(
|
|
||||||
Gio.DBus.system,
|
|
||||||
"org.asuslinux.Daemon",
|
|
||||||
this.dbus_path,
|
|
||||||
);
|
|
||||||
|
|
||||||
this.connected = true;
|
|
||||||
//@ts-ignore
|
|
||||||
log(`${this.dbus_path} client started successfully.`);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
logError(`${this.xml_resource} dbus init failed!`, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async stop() {
|
|
||||||
//@ts-ignore
|
|
||||||
log(`Stopping ${this.xml_resource} dbus module`);
|
|
||||||
|
|
||||||
if (this.connected) {
|
|
||||||
this.dbus_proxy.destroy();
|
|
||||||
this.connected = false;
|
|
||||||
this.dbus_proxy = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isRunning(): boolean {
|
|
||||||
return this.connected;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,202 +0,0 @@
|
|||||||
import * as bios from "../../bindings/platform";
|
|
||||||
import { DbusBase } from "./base";
|
|
||||||
|
|
||||||
// TODO: add callbacks for notifications
|
|
||||||
export class Platform extends DbusBase {
|
|
||||||
bios: bios.RogBiosSupportedFunctions = {
|
|
||||||
post_sound: false,
|
|
||||||
gpu_mux: false,
|
|
||||||
panel_overdrive: false,
|
|
||||||
dgpu_disable: false,
|
|
||||||
egpu_enable: false,
|
|
||||||
mini_led_mode: false
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: interface or something to enforce requirement of "sync()" method
|
|
||||||
public notifyPanelOdSubscribers: any[] = [];
|
|
||||||
public notifyPostBootSoundSubscribers: any[] = [];
|
|
||||||
public notifyMiniLedSubscribers: any[] = [];
|
|
||||||
public notifyGpuMuxSubscribers: any[] = [];
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super("org-asuslinux-platform-4", "/org/asuslinux/Platform");
|
|
||||||
}
|
|
||||||
|
|
||||||
public getPostBootSound() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
this.bios.post_sound = this.dbus_proxy.PostBootSoundSync() == "true" ? true : false;
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to get POST Boot Sound state!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.bios.post_sound;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setPostBootSound(state: boolean) {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
if (state !== this.bios.post_sound) {
|
|
||||||
this.bios.post_sound = state;
|
|
||||||
}
|
|
||||||
return this.dbus_proxy.SetPostBootSoundSync(state);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Platform DBus set Post Boot Sound failed!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public getGpuMuxMode() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
this.bios.gpu_mux = this.dbus_proxy.GpuMuxModeSync() == "true" ? true : false;
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to get MUX state!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.bios.gpu_mux;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setGpuMuxMode(state: boolean) {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
if (!state !== this.bios.gpu_mux) {
|
|
||||||
this.bios.gpu_mux = !state;
|
|
||||||
}
|
|
||||||
return this.dbus_proxy.SetGpuMuxModeSync(!state);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Switching the MUX failed!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public getPanelOd() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
this.bios.panel_overdrive = this.dbus_proxy.PanelOdSync() == "true" ? true : false;
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to get Overdrive state!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.bios.panel_overdrive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setPanelOd(state: boolean) {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
if (state !== this.bios.panel_overdrive) {
|
|
||||||
this.bios.panel_overdrive = state;
|
|
||||||
}
|
|
||||||
return this.dbus_proxy.SetPanelOdSync(state);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Overdrive DBus set overdrive state failed!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public getMiniLedMode() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
this.bios.mini_led_mode = this.dbus_proxy.MiniLedModeSync() == "true" ? true : false;
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to get Overdrive state!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.bios.mini_led_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setMiniLedMode(state: boolean) {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
if (state !== this.bios.mini_led_mode) {
|
|
||||||
this.bios.mini_led_mode = state;
|
|
||||||
}
|
|
||||||
return this.dbus_proxy.SetMiniLedModeSync(state);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("setMiniLedMode failed!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async start() {
|
|
||||||
try {
|
|
||||||
await super.start();
|
|
||||||
|
|
||||||
this.getPostBootSound();
|
|
||||||
this.dbus_proxy.connectSignal(
|
|
||||||
"NotifyPostBootSound",
|
|
||||||
(proxy: any = null, _name: string, data: boolean) => {
|
|
||||||
if (proxy) {
|
|
||||||
//@ts-ignore
|
|
||||||
log(`PostBootSound changed to ${data}`);
|
|
||||||
this.notifyPostBootSoundSubscribers.forEach(sub => {
|
|
||||||
sub.sync();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.getPanelOd();
|
|
||||||
this.dbus_proxy.connectSignal(
|
|
||||||
"NotifyPanelOd",
|
|
||||||
(proxy: any = null, _name: string, data: boolean) => {
|
|
||||||
if (proxy) {
|
|
||||||
//@ts-ignore
|
|
||||||
log(`NotifyPanelOd has changed to ${data}.`);
|
|
||||||
this.notifyPanelOdSubscribers.forEach(sub => {
|
|
||||||
sub.sync();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.getMiniLedMode();
|
|
||||||
this.dbus_proxy.connectSignal(
|
|
||||||
"NotifyMiniLedMode",
|
|
||||||
(proxy: any = null, _name: string, data: boolean) => {
|
|
||||||
if (proxy) {
|
|
||||||
//@ts-ignore
|
|
||||||
log(`MiniLedMode has changed to ${data}.`);
|
|
||||||
this.notifyMiniLedSubscribers.forEach(sub => {
|
|
||||||
sub.sync();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.getGpuMuxMode();
|
|
||||||
this.dbus_proxy.connectSignal(
|
|
||||||
"NotifyGpuMuxMode",
|
|
||||||
(proxy: any = null, _name: string, data: boolean) => {
|
|
||||||
if (proxy) {
|
|
||||||
//@ts-ignore
|
|
||||||
log(`MUX has changed to ${data}.`);
|
|
||||||
this.notifyGpuMuxSubscribers.forEach(sub => {
|
|
||||||
sub.sync();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Platform DBus init failed!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async stop() {
|
|
||||||
await super.stop();
|
|
||||||
this.bios.post_sound = false;
|
|
||||||
this.bios.panel_overdrive = false;
|
|
||||||
this.bios.mini_led_mode = false;
|
|
||||||
this.bios.gpu_mux = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
import { DbusBase } from "./base";
|
|
||||||
|
|
||||||
// function getMethods(obj: { [x: string]: { toString: () => string; }; }) {
|
|
||||||
// var result = [];
|
|
||||||
// for (var id in obj) {
|
|
||||||
// try {
|
|
||||||
// if (typeof(obj[id]) == "function") {
|
|
||||||
// result.push(id + ": " + obj[id].toString());
|
|
||||||
// }
|
|
||||||
// } catch (err) {
|
|
||||||
// result.push(id + ": inaccessible");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
|
|
||||||
export class Power extends DbusBase {
|
|
||||||
chargeLimit = 100;
|
|
||||||
mainsOnline = false;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super("org-asuslinux-power-4", "/org/asuslinux/Power");
|
|
||||||
}
|
|
||||||
|
|
||||||
public getChargingLimit() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
this.chargeLimit = this.dbus_proxy.ChargeControlEndThresholdSync();
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch Charging Limit!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.chargeLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setChargingLimit(limit: number) {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
if (limit > 0 && this.chargeLimit !== limit) {
|
|
||||||
// update state
|
|
||||||
this.chargeLimit = limit;
|
|
||||||
}
|
|
||||||
return this.dbus_proxy.SetChargeControlEndThresholdSync(limit);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Profile DBus set power profile failed!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public getMainsOnline() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
this.mainsOnline = this.dbus_proxy.MainsOnlineSync();
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch MainsLonline!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.mainsOnline;
|
|
||||||
}
|
|
||||||
|
|
||||||
async start() {
|
|
||||||
try {
|
|
||||||
await super.start();
|
|
||||||
this.getChargingLimit();
|
|
||||||
|
|
||||||
this.dbus_proxy.connectSignal(
|
|
||||||
"NotifyChargeControlEndThreshold",
|
|
||||||
(proxy: any = null, name: string, data: string) => {
|
|
||||||
if (proxy) {
|
|
||||||
//@ts-ignore
|
|
||||||
log(`Charging Limit has changed to ${data}% (${name}).`);
|
|
||||||
this.chargeLimit = parseInt(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.dbus_proxy.connectSignal(
|
|
||||||
"NotifyMainsOnline",
|
|
||||||
(proxy: any = null, name: string, data: string) => {
|
|
||||||
if (proxy) {
|
|
||||||
//@ts-ignore
|
|
||||||
log(`NotifyMainsOnline has changed to ${data}% (${name}).`);
|
|
||||||
this.mainsOnline = parseInt(data) == 1 ? true : false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Charging Limit DBus initialization failed!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async stop() {
|
|
||||||
await super.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
import { SupportedFunctions, AdvancedAura } from "../../bindings/platform";
|
|
||||||
import { AuraDevice, AuraModeNum, AuraZone, PowerZones } from "../../bindings/aura";
|
|
||||||
import { DbusBase } from "./base";
|
|
||||||
|
|
||||||
export class Supported extends DbusBase {
|
|
||||||
// False,
|
|
||||||
// (True,),
|
|
||||||
// (True, True),
|
|
||||||
// ('X19b6',
|
|
||||||
// True,
|
|
||||||
// ['Static',
|
|
||||||
// 'Breathe',
|
|
||||||
// 'Strobe',
|
|
||||||
// 'Rainbow',
|
|
||||||
// 'Star',
|
|
||||||
// 'Rain',
|
|
||||||
// 'Highlight',
|
|
||||||
// 'Laser',
|
|
||||||
// 'Ripple',
|
|
||||||
// 'Pulse',
|
|
||||||
// 'Comet',
|
|
||||||
// 'Flash'],
|
|
||||||
// [],
|
|
||||||
// 'PerKey',
|
|
||||||
// ['Keyboard', 'Lightbar', 'Logo', 'RearGlow']),
|
|
||||||
// (False, True, True, True, False, True)
|
|
||||||
|
|
||||||
supported: SupportedFunctions = {
|
|
||||||
anime_ctrl: false,
|
|
||||||
charge_ctrl: {
|
|
||||||
charge_level_set: false
|
|
||||||
},
|
|
||||||
platform_profile: {
|
|
||||||
platform_profile: false,
|
|
||||||
fan_curves: false
|
|
||||||
},
|
|
||||||
keyboard_led: {
|
|
||||||
dev_id: AuraDevice.Unknown,
|
|
||||||
brightness: false,
|
|
||||||
basic_modes: [],
|
|
||||||
basic_zones: [],
|
|
||||||
advanced_type: AdvancedAura.None
|
|
||||||
},
|
|
||||||
rog_bios_ctrl: {
|
|
||||||
post_sound: false,
|
|
||||||
gpu_mux: false,
|
|
||||||
panel_overdrive: false,
|
|
||||||
dgpu_disable: false,
|
|
||||||
egpu_enable: false,
|
|
||||||
mini_led_mode: false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super("org-asuslinux-supported-4", "/org/asuslinux/Supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
public getSupported() {
|
|
||||||
if (this.isRunning()) {
|
|
||||||
try {
|
|
||||||
const _data = this.dbus_proxy.SupportedFunctionsSync();
|
|
||||||
this.supported.anime_ctrl = _data[0];
|
|
||||||
this.supported.charge_ctrl.charge_level_set = _data[1];
|
|
||||||
this.supported.platform_profile.platform_profile = _data[2][0];
|
|
||||||
this.supported.platform_profile.fan_curves = _data[2][1];
|
|
||||||
this.supported.keyboard_led.dev_id = AuraDevice[_data[3][0] as AuraDevice];
|
|
||||||
this.supported.keyboard_led.brightness = _data[3][1];
|
|
||||||
|
|
||||||
this.supported.keyboard_led.basic_modes = _data[3][2].map(function (value: string) {
|
|
||||||
return AuraModeNum[value as AuraModeNum];
|
|
||||||
});
|
|
||||||
this.supported.keyboard_led.basic_zones = _data[3][3].map(function (value: string) {
|
|
||||||
return AuraZone[value as AuraZone];
|
|
||||||
});
|
|
||||||
this.supported.keyboard_led.advanced_type = AdvancedAura[_data[3][4] as AdvancedAura];
|
|
||||||
this.supported.keyboard_led.power_zones = _data[3][5].map(function (value: string) {
|
|
||||||
return PowerZones[value as PowerZones];
|
|
||||||
});
|
|
||||||
|
|
||||||
this.supported.rog_bios_ctrl.post_sound = _data[4][0];
|
|
||||||
this.supported.rog_bios_ctrl.gpu_mux = _data[4][1];
|
|
||||||
this.supported.rog_bios_ctrl.panel_overdrive = _data[4][2];
|
|
||||||
this.supported.rog_bios_ctrl.dgpu_disable = _data[4][3];
|
|
||||||
this.supported.rog_bios_ctrl.egpu_enable = _data[4][4];
|
|
||||||
this.supported.rog_bios_ctrl.mini_led_mode = _data[4][5];
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Failed to fetch supported functionalities", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async start() {
|
|
||||||
try {
|
|
||||||
await super.start();
|
|
||||||
this.getSupported();
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log("Supported DBus initialization failed!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async stop() {
|
|
||||||
await super.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
declare const imports: any;
|
|
||||||
|
|
||||||
const { QuickToggle } = imports.ui.quickSettings;
|
|
||||||
const QuickSettingsMenu = imports.ui.main.panel.statusArea.quickSettings;
|
|
||||||
|
|
||||||
export function addQuickSettingsItems(items: [typeof QuickToggle], width = 1) {
|
|
||||||
// Add the items with the built-in function
|
|
||||||
QuickSettingsMenu._addItems(items, width);
|
|
||||||
|
|
||||||
// Ensure the tile(s) are above the background apps menu
|
|
||||||
for (const item of items) {
|
|
||||||
QuickSettingsMenu.menu._grid.set_child_below_sibling(item,
|
|
||||||
QuickSettingsMenu._backgroundApps.quickSettingsItems[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
declare const imports: any;
|
|
||||||
// REF: https://gjs.guide/extensions/development/creating.html
|
|
||||||
|
|
||||||
const { GObject, Gio } = imports.gi;
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
|
||||||
|
|
||||||
const { SystemIndicator } = imports.ui.quickSettings;
|
|
||||||
const QuickSettingsMenu = imports.ui.main.panel.statusArea.quickSettings;
|
|
||||||
|
|
||||||
export const IndicateMiniLed = GObject.registerClass(
|
|
||||||
class IndicateMiniLed extends SystemIndicator {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
// Create the icon for the indicator
|
|
||||||
this._indicator = this._addIndicator();
|
|
||||||
this._indicator.icon_name = "selection-mode-symbolic";
|
|
||||||
|
|
||||||
// Showing the indicator when the feature is enabled
|
|
||||||
this._settings = ExtensionUtils.getSettings();
|
|
||||||
this._settings.bind("mini-led-enabled",
|
|
||||||
this._indicator, "visible",
|
|
||||||
Gio.SettingsBindFlags.DEFAULT);
|
|
||||||
|
|
||||||
// Add the indicator to the panel and the toggle to the menu
|
|
||||||
QuickSettingsMenu._indicators.add_child(this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
declare const imports: any;
|
|
||||||
|
|
||||||
import { AnimeDbus } from "../dbus/animatrix";
|
|
||||||
|
|
||||||
const { GObject } = imports.gi;
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
|
||||||
|
|
||||||
export const MenuToggleAnimePower = GObject.registerClass(
|
|
||||||
class MenuToggleAnimePower extends PopupMenu.PopupSwitchMenuItem {
|
|
||||||
private _dbus_anime: AnimeDbus;
|
|
||||||
public toggle_callback = () => {};
|
|
||||||
|
|
||||||
constructor(dbus_anime: AnimeDbus) {
|
|
||||||
super(
|
|
||||||
"AniMatrix Display Power", dbus_anime.deviceState.display_enabled
|
|
||||||
);
|
|
||||||
this._dbus_anime = dbus_anime;
|
|
||||||
this.label = "AniMatrix Display Power";
|
|
||||||
this._settings = ExtensionUtils.getSettings();
|
|
||||||
|
|
||||||
this.connectObject(
|
|
||||||
"destroy", () => this._settings.run_dispose(),
|
|
||||||
"toggled", () => this._toggleMode(),
|
|
||||||
this);
|
|
||||||
|
|
||||||
this.connect("destroy", () => {
|
|
||||||
this.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleMode() {
|
|
||||||
this._dbus_anime.getDeviceState();
|
|
||||||
if (this.state !== this._dbus_anime.deviceState.display_enabled)
|
|
||||||
this._dbus_anime.setEnableDisplay(this.state);
|
|
||||||
this.toggle_callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
sync() {
|
|
||||||
this._dbus_anime.getDeviceState();
|
|
||||||
const checked = this._dbus_anime.deviceState.display_enabled;
|
|
||||||
this.setToggleState(checked);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export const MenuToggleAnimeBuiltins = GObject.registerClass(
|
|
||||||
class MenuToggleAnimeBuiltins extends PopupMenu.PopupSwitchMenuItem {
|
|
||||||
private _dbus_anime: AnimeDbus;
|
|
||||||
public toggle_callback = () => {};
|
|
||||||
|
|
||||||
constructor(dbus_anime: AnimeDbus) {
|
|
||||||
super(
|
|
||||||
"AniMatrix Powersave Animation", dbus_anime.deviceState.builtin_anims_enabled
|
|
||||||
);
|
|
||||||
this._dbus_anime = dbus_anime;
|
|
||||||
this.label = "AniMatrix Powersave Animation";
|
|
||||||
this._settings = ExtensionUtils.getSettings();
|
|
||||||
|
|
||||||
this.connectObject(
|
|
||||||
"destroy", () => this._settings.run_dispose(),
|
|
||||||
"toggled", () => this._toggleMode(),
|
|
||||||
this);
|
|
||||||
|
|
||||||
this.connect("destroy", () => {
|
|
||||||
this.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleMode() {
|
|
||||||
this._dbus_anime.getDeviceState();
|
|
||||||
if (this.state !== this._dbus_anime.deviceState.builtin_anims_enabled)
|
|
||||||
this._dbus_anime.setPowersaveAnim(this.state);
|
|
||||||
this.toggle_callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
sync() {
|
|
||||||
this._dbus_anime.getDeviceState();
|
|
||||||
const checked = this._dbus_anime.deviceState.display_enabled;
|
|
||||||
this.setToggleState(checked);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
declare const imports: any;
|
|
||||||
|
|
||||||
import { Platform } from "../dbus/platform";
|
|
||||||
|
|
||||||
const { GObject, Gio } = imports.gi;
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
|
||||||
|
|
||||||
export const MenuToggleMiniLed = GObject.registerClass(
|
|
||||||
class MenuToggleMiniLed extends PopupMenu.PopupSwitchMenuItem {
|
|
||||||
private _dbus_platform: Platform;
|
|
||||||
public toggle_callback = () => {};
|
|
||||||
|
|
||||||
constructor(dbus_platform: Platform) {
|
|
||||||
super("MiniLED", dbus_platform.bios.mini_led_mode);
|
|
||||||
|
|
||||||
this._dbus_platform = dbus_platform;
|
|
||||||
this.label = "MiniLED";
|
|
||||||
this._settings = ExtensionUtils.getSettings();
|
|
||||||
|
|
||||||
this.connectObject(
|
|
||||||
"destroy", () => this._settings.run_dispose(),
|
|
||||||
"toggled", () => this._toggleMode(),
|
|
||||||
this);
|
|
||||||
|
|
||||||
this.connect("destroy", () => {
|
|
||||||
this.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleMode() {
|
|
||||||
this._dbus_platform.getMiniLedMode();
|
|
||||||
const state = this._dbus_platform.bios.mini_led_mode;
|
|
||||||
if (this.state !== state)
|
|
||||||
this._dbus_platform.setMiniLedMode(this.state);
|
|
||||||
this.toggle_callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
sync() {
|
|
||||||
this._dbus_platform.getMiniLedMode();
|
|
||||||
const toggled = this._dbus_platform.bios.mini_led_mode;
|
|
||||||
this.setToggleState(toggled);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
declare const imports: any;
|
|
||||||
|
|
||||||
import { Platform } from "../dbus/platform";
|
|
||||||
|
|
||||||
const { GObject, Gio } = imports.gi;
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
|
||||||
|
|
||||||
export const MenuTogglePanelOd = GObject.registerClass(
|
|
||||||
class MenuTogglePanelOd extends PopupMenu.PopupSwitchMenuItem {
|
|
||||||
private _dbus_platform: Platform;
|
|
||||||
public toggle_callback = () => {};
|
|
||||||
|
|
||||||
constructor(dbus_platform: Platform) {
|
|
||||||
super("Panel Overdrive", dbus_platform.bios.panel_overdrive);
|
|
||||||
|
|
||||||
this._dbus_platform = dbus_platform;
|
|
||||||
this.label = "Panel Overdrive";
|
|
||||||
this._settings = ExtensionUtils.getSettings();
|
|
||||||
|
|
||||||
this.connectObject(
|
|
||||||
"destroy", () => this._settings.run_dispose(),
|
|
||||||
"toggled", () => this._toggleMode(),
|
|
||||||
this);
|
|
||||||
|
|
||||||
this.connect("destroy", () => {
|
|
||||||
this.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
this.sync();
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleMode() {
|
|
||||||
this._dbus_platform.getPanelOd();
|
|
||||||
const state = this._dbus_platform.bios.panel_overdrive;
|
|
||||||
if (this.state !== state)
|
|
||||||
this._dbus_platform.setPanelOd(this.state);
|
|
||||||
this.toggle_callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
sync() {
|
|
||||||
this._dbus_platform.getPanelOd();
|
|
||||||
const toggled = this._dbus_platform.bios.panel_overdrive;
|
|
||||||
this.setToggleState(toggled);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
declare const imports: any;
|
|
||||||
// REF: https://gjs.guide/extensions/development/creating.html
|
|
||||||
|
|
||||||
import { addQuickSettingsItems } from "../helpers";
|
|
||||||
import { AuraDbus } from "../dbus/aura";
|
|
||||||
import { AuraEffect, AuraModeNum } from "../../bindings/aura";
|
|
||||||
|
|
||||||
const { GObject } = imports.gi;
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
|
||||||
// const Me = ExtensionUtils.getCurrentExtension();
|
|
||||||
// const Main = imports.ui.main;
|
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
|
||||||
const QuickSettings = imports.ui.quickSettings;
|
|
||||||
|
|
||||||
export const AuraMenuToggle = GObject.registerClass(
|
|
||||||
class AuraMenuToggle extends QuickSettings.QuickMenuToggle {
|
|
||||||
private _dbus_aura: AuraDbus;
|
|
||||||
private _last_mode: AuraModeNum = AuraModeNum.Static;
|
|
||||||
|
|
||||||
constructor(dbus_aura: AuraDbus) {
|
|
||||||
super({
|
|
||||||
title: "Aura Modes",
|
|
||||||
iconName: "selection-mode-symbolic",
|
|
||||||
toggleMode: true,
|
|
||||||
});
|
|
||||||
this._dbus_aura = dbus_aura;
|
|
||||||
|
|
||||||
this.connectObject(
|
|
||||||
"destroy", () => this._settings.run_dispose(),
|
|
||||||
this);
|
|
||||||
|
|
||||||
this.menu.setHeader("selection-mode-symbolic", this._dbus_aura.current_aura_mode);
|
|
||||||
|
|
||||||
this._settings = ExtensionUtils.getSettings();
|
|
||||||
|
|
||||||
this._itemsSection = new PopupMenu.PopupMenuSection();
|
|
||||||
|
|
||||||
this._dbus_aura.aura_modes.forEach((mode, key) => {
|
|
||||||
this._itemsSection.addAction(key, () => {
|
|
||||||
this._dbus_aura.setLedMode(mode);
|
|
||||||
this.sync();
|
|
||||||
}, "");
|
|
||||||
});
|
|
||||||
|
|
||||||
this.menu.addMenuItem(this._itemsSection);
|
|
||||||
|
|
||||||
// Add an entry-point for more settings
|
|
||||||
// this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
|
||||||
// const settingsItem = this.menu.addAction("More Settings",
|
|
||||||
// () => ExtensionUtils.openPrefs());
|
|
||||||
// // Ensure the settings are unavailable when the screen is locked
|
|
||||||
// settingsItem.visible = Main.sessionMode.allowSettings;
|
|
||||||
// this.menu._settingsActions[Me.uuid] = settingsItem;
|
|
||||||
|
|
||||||
this.connectObject(
|
|
||||||
"clicked", () => {
|
|
||||||
let mode: AuraEffect | undefined;
|
|
||||||
if (this._dbus_aura.current_aura_mode == AuraModeNum.Static) {
|
|
||||||
mode = this._dbus_aura.aura_modes.get(this._last_mode);
|
|
||||||
} else {
|
|
||||||
mode = this._dbus_aura.aura_modes.get(AuraModeNum.Static);
|
|
||||||
}
|
|
||||||
if (mode != undefined) {
|
|
||||||
this._dbus_aura.setLedMode(mode);
|
|
||||||
this.sync();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
this);
|
|
||||||
|
|
||||||
this._dbus_aura.notifyAuraModeSubscribers.push(this);
|
|
||||||
this.sync();
|
|
||||||
|
|
||||||
addQuickSettingsItems([this]);
|
|
||||||
}
|
|
||||||
|
|
||||||
sync() {
|
|
||||||
const checked = this._dbus_aura.current_aura_mode != AuraModeNum.Static;
|
|
||||||
this.title = this._dbus_aura.current_aura_mode;
|
|
||||||
if (this._last_mode != this._dbus_aura.current_aura_mode && this._dbus_aura.current_aura_mode != AuraModeNum.Static) {
|
|
||||||
this._last_mode = this._dbus_aura.current_aura_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.checked !== checked)
|
|
||||||
this.set({ checked });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,179 +0,0 @@
|
|||||||
declare const imports: any;
|
|
||||||
// REF: https://gjs.guide/extensions/development/creating.html
|
|
||||||
|
|
||||||
import { AnimeDbus } from "../dbus/animatrix";
|
|
||||||
import { Supported } from "../dbus/supported";
|
|
||||||
import { Platform } from "../dbus/platform";
|
|
||||||
|
|
||||||
import { addQuickSettingsItems } from "../helpers";
|
|
||||||
import { MenuToggleAnimeBuiltins, MenuToggleAnimePower } from "../menu_toggles/anime";
|
|
||||||
import { MenuTogglePanelOd } from "../menu_toggles/panel_od";
|
|
||||||
import { MenuToggleMiniLed } from "../menu_toggles/mini_led";
|
|
||||||
|
|
||||||
|
|
||||||
const { GObject } = imports.gi;
|
|
||||||
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
|
||||||
// const Me = ExtensionUtils.getCurrentExtension();
|
|
||||||
// const Main = imports.ui.main;
|
|
||||||
const PopupMenu = imports.ui.popupMenu;
|
|
||||||
const QuickSettings = imports.ui.quickSettings;
|
|
||||||
|
|
||||||
export const FeatureMenuToggle = GObject.registerClass(
|
|
||||||
class FeatureMenuToggle extends QuickSettings.QuickMenuToggle {
|
|
||||||
private _dbus_supported: Supported;
|
|
||||||
private _dbus_platform: Platform;
|
|
||||||
private _dbus_anime: AnimeDbus;
|
|
||||||
|
|
||||||
public miniLed: typeof MenuToggleMiniLed;
|
|
||||||
public panelOd: typeof MenuTogglePanelOd;
|
|
||||||
public animeDisplayPower: typeof MenuToggleAnimePower;
|
|
||||||
public animePowersaveAnim: typeof MenuToggleAnimeBuiltins;
|
|
||||||
private primary = "mini-led";
|
|
||||||
|
|
||||||
constructor(dbus_supported: Supported, dbus_platform: Platform, dbus_anime: AnimeDbus) {
|
|
||||||
super({
|
|
||||||
title: "Laptop",
|
|
||||||
iconName: "selection-mode-symbolic",
|
|
||||||
toggleMode: true,
|
|
||||||
});
|
|
||||||
this._dbus_supported = dbus_supported;
|
|
||||||
this._dbus_platform = dbus_platform;
|
|
||||||
this._dbus_anime = dbus_anime;
|
|
||||||
|
|
||||||
this.menu.setHeader("selection-mode-symbolic", "Laptop features");
|
|
||||||
|
|
||||||
this._settings = ExtensionUtils.getSettings();
|
|
||||||
this.primary = this._settings.get_string("primary-quickmenu-toggle");
|
|
||||||
|
|
||||||
// TODO: temporary block
|
|
||||||
if (this.primary == "mini-led" && !this._dbus_supported.supported.rog_bios_ctrl.mini_led_mode) {
|
|
||||||
this.primary = "panel-od";
|
|
||||||
} else if (this.primary == "panel-od" && !this._dbus_supported.supported.rog_bios_ctrl.panel_overdrive) {
|
|
||||||
this.primary = "anime-power";
|
|
||||||
} else if (this.primary == "anime-power" && !this._dbus_supported.supported.anime_ctrl) {
|
|
||||||
this.primary = "mini-led";
|
|
||||||
} else if (this.primary.length == 0) {
|
|
||||||
this.primary = "panel-od";
|
|
||||||
}
|
|
||||||
|
|
||||||
this.connectObject(
|
|
||||||
"destroy", () => this._settings.run_dispose(),
|
|
||||||
this);
|
|
||||||
this._settings.connect('changed::primary-quickmenu-toggle',
|
|
||||||
this.sync);
|
|
||||||
this._settings.set_string("primary-quickmenu-toggle", this.primary);
|
|
||||||
|
|
||||||
this._itemsSection = new PopupMenu.PopupMenuSection();
|
|
||||||
if (this._dbus_supported.supported.rog_bios_ctrl.mini_led_mode) {
|
|
||||||
if (this.miniLed == null) {
|
|
||||||
this.miniLed = new MenuToggleMiniLed(this._dbus_platform);
|
|
||||||
this._dbus_platform.notifyMiniLedSubscribers.push(this.miniLed);
|
|
||||||
this._itemsSection.addMenuItem(this.miniLed);
|
|
||||||
this._dbus_platform.notifyMiniLedSubscribers.push(this);
|
|
||||||
this.miniLed.toggle_callback = () => {
|
|
||||||
this.primary = "mini-led";
|
|
||||||
this.sync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._dbus_supported.supported.rog_bios_ctrl.panel_overdrive) {
|
|
||||||
if (this.panelOd == null) {
|
|
||||||
this.panelOd = new MenuTogglePanelOd(this._dbus_platform);
|
|
||||||
this._dbus_platform.notifyPanelOdSubscribers.push(this.panelOd);
|
|
||||||
this._itemsSection.addMenuItem(this.panelOd);
|
|
||||||
this._dbus_platform.notifyPanelOdSubscribers.push(this);
|
|
||||||
this.panelOd.toggle_callback = () => {
|
|
||||||
this.primary = "panel-od";
|
|
||||||
this.sync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._dbus_supported.supported.anime_ctrl) {
|
|
||||||
if (this.animeDisplayPower == null) {
|
|
||||||
this.animeDisplayPower = new MenuToggleAnimePower(this._dbus_anime);
|
|
||||||
this._dbus_anime.notifyAnimeStateSubscribers.push(this.animeDisplayPower);
|
|
||||||
this._itemsSection.addMenuItem(this.animeDisplayPower);
|
|
||||||
this._dbus_anime.notifyAnimeStateSubscribers.push(this);
|
|
||||||
this.animeDisplayPower.toggle_callback = () => {
|
|
||||||
this.primary = "anime-power";
|
|
||||||
this.sync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.animePowersaveAnim == null) {
|
|
||||||
this.animePowersaveAnim = new MenuToggleAnimeBuiltins(this._dbus_anime);
|
|
||||||
this._dbus_anime.notifyAnimeStateSubscribers.push(this.animePowersaveAnim);
|
|
||||||
this._itemsSection.addMenuItem(this.animePowersaveAnim);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.connectObject(
|
|
||||||
"clicked", () => {
|
|
||||||
this._toggle();
|
|
||||||
},
|
|
||||||
this);
|
|
||||||
|
|
||||||
this.menu.addMenuItem(this._itemsSection);
|
|
||||||
|
|
||||||
// // Add an entry-point for more settings
|
|
||||||
// this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
|
||||||
// const settingsItem = this.menu.addAction("More Settings",
|
|
||||||
// () => ExtensionUtils.openPrefs());
|
|
||||||
// // Ensure the settings are unavailable when the screen is locked
|
|
||||||
// settingsItem.visible = Main.sessionMode.allowSettings;
|
|
||||||
// this.menu._settingsActions[Me.uuid] = settingsItem;
|
|
||||||
|
|
||||||
this.sync();
|
|
||||||
addQuickSettingsItems([this]);
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggle() {
|
|
||||||
if (this.primary == "mini-led" && this.miniLed != null) {
|
|
||||||
this._dbus_platform.getMiniLedMode();
|
|
||||||
const checked = this._dbus_platform.bios.mini_led_mode;
|
|
||||||
if (this.checked !== checked)
|
|
||||||
this._dbus_platform.setMiniLedMode(this.checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.primary == "panel-od" && this.panelOd != null) {
|
|
||||||
this._dbus_platform.getPanelOd();
|
|
||||||
const checked = this._dbus_platform.bios.panel_overdrive;
|
|
||||||
if (this.checked !== checked)
|
|
||||||
this._dbus_platform.setPanelOd(this.checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.primary == "anime-power" && this.animeDisplayPower != null) {
|
|
||||||
this._dbus_anime.getDeviceState();
|
|
||||||
const checked = this._dbus_anime.deviceState.display_enabled;
|
|
||||||
if (this.checked !== checked)
|
|
||||||
this._dbus_anime.setEnableDisplay(this.checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sync() {
|
|
||||||
let checked = false;
|
|
||||||
if (this.primary == "mini-led" && this.miniLed != null) {
|
|
||||||
this.title = this.miniLed.label;
|
|
||||||
checked = this._dbus_platform.bios.mini_led_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.primary == "panel-od" && this.panelOd != null) {
|
|
||||||
this.title = this.panelOd.label;
|
|
||||||
checked = this._dbus_platform.bios.panel_overdrive;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.primary == "anime-power" && this.animeDisplayPower != null) {
|
|
||||||
this.title = this.animeDisplayPower.label;
|
|
||||||
checked = this._dbus_anime.deviceState.display_enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (this.animePowersaveAnim != null) {
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (this.checked !== checked)
|
|
||||||
this.set({ checked });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
declare const imports: any;
|
|
||||||
|
|
||||||
import { AnimeDbus } from "../dbus/animatrix";
|
|
||||||
import { addQuickSettingsItems } from "../helpers";
|
|
||||||
|
|
||||||
const { GObject, Gio } = imports.gi;
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
|
||||||
|
|
||||||
const { QuickToggle } = imports.ui.quickSettings;
|
|
||||||
|
|
||||||
export const QuickAnimePower = GObject.registerClass(
|
|
||||||
class QuickAnimePower extends QuickToggle {
|
|
||||||
private _dbus_anime: AnimeDbus;
|
|
||||||
|
|
||||||
constructor(dbus_anime: AnimeDbus) {
|
|
||||||
super({
|
|
||||||
title: "AniMatrix Power",
|
|
||||||
iconName: "selection-mode-symbolic",
|
|
||||||
toggleMode: true,
|
|
||||||
});
|
|
||||||
this._dbus_anime = dbus_anime;
|
|
||||||
this.label = "AniMatrix Power";
|
|
||||||
this._settings = ExtensionUtils.getSettings();
|
|
||||||
|
|
||||||
this.connectObject(
|
|
||||||
"destroy", () => this._settings.run_dispose(),
|
|
||||||
"clicked", () => this._toggleMode(),
|
|
||||||
this);
|
|
||||||
|
|
||||||
this.connect("destroy", () => {
|
|
||||||
this.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
this._settings.bind("anime-power",
|
|
||||||
this, "checked",
|
|
||||||
Gio.SettingsBindFlags.DEFAULT);
|
|
||||||
|
|
||||||
this.sync();
|
|
||||||
|
|
||||||
addQuickSettingsItems([this]);
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleMode() {
|
|
||||||
this._dbus_anime.getDeviceState();
|
|
||||||
const checked = this._dbus_anime.deviceState.display_enabled;
|
|
||||||
if (this.checked !== checked)
|
|
||||||
this._dbus_anime.setEnableDisplay(this.checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
sync() {
|
|
||||||
this._dbus_anime.getDeviceState();
|
|
||||||
const checked = this._dbus_anime.deviceState.display_enabled;
|
|
||||||
if (this.checked !== checked)
|
|
||||||
this.set({ checked });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
declare const imports: any;
|
|
||||||
|
|
||||||
import { Platform } from "../dbus/platform";
|
|
||||||
import { addQuickSettingsItems } from "../helpers";
|
|
||||||
|
|
||||||
const { GObject, Gio } = imports.gi;
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
|
||||||
|
|
||||||
const { QuickToggle } = imports.ui.quickSettings;
|
|
||||||
|
|
||||||
export const QuickMiniLed = GObject.registerClass(
|
|
||||||
class QuickMiniLed extends QuickToggle {
|
|
||||||
private _dbus_platform: Platform;
|
|
||||||
|
|
||||||
constructor(dbus_platform: Platform) {
|
|
||||||
super({
|
|
||||||
title: "MiniLED",
|
|
||||||
iconName: "selection-mode-symbolic",
|
|
||||||
toggleMode: true,
|
|
||||||
});
|
|
||||||
this._dbus_platform = dbus_platform;
|
|
||||||
this.label = "MiniLED";
|
|
||||||
this._settings = ExtensionUtils.getSettings();
|
|
||||||
|
|
||||||
this.connectObject(
|
|
||||||
"destroy", () => this._settings.run_dispose(),
|
|
||||||
"clicked", () => this._toggleMode(),
|
|
||||||
this);
|
|
||||||
|
|
||||||
this.connect("destroy", () => {
|
|
||||||
this.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
this._settings.bind("mini-led-enabled",
|
|
||||||
this, "checked",
|
|
||||||
Gio.SettingsBindFlags.DEFAULT);
|
|
||||||
|
|
||||||
this.sync();
|
|
||||||
|
|
||||||
addQuickSettingsItems([this]);
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleMode() {
|
|
||||||
const checked = this._dbus_platform.getMiniLedMode();
|
|
||||||
if (this.checked !== checked)
|
|
||||||
this._dbus_platform.setMiniLedMode(this.checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
sync() {
|
|
||||||
const checked = this._dbus_platform.getMiniLedMode();
|
|
||||||
if (this.checked !== checked)
|
|
||||||
this.set({ checked });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
declare const imports: any;
|
|
||||||
|
|
||||||
import { Platform } from "../dbus/platform";
|
|
||||||
import { addQuickSettingsItems } from "../helpers";
|
|
||||||
|
|
||||||
const { GObject, Gio } = imports.gi;
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
|
||||||
|
|
||||||
const { QuickToggle } = imports.ui.quickSettings;
|
|
||||||
|
|
||||||
export const QuickPanelOd = GObject.registerClass(
|
|
||||||
class QuickPanelOd extends QuickToggle {
|
|
||||||
private _dbus_platform: Platform;
|
|
||||||
|
|
||||||
constructor(dbus_platform: Platform) {
|
|
||||||
super({
|
|
||||||
title: "Panel Overdrive",
|
|
||||||
iconName: "selection-mode-symbolic",
|
|
||||||
toggleMode: true,
|
|
||||||
});
|
|
||||||
this._dbus_platform = dbus_platform;
|
|
||||||
this.label = "Panel Overdrive";
|
|
||||||
this._settings = ExtensionUtils.getSettings();
|
|
||||||
|
|
||||||
this.connectObject(
|
|
||||||
"destroy", () => this._settings.run_dispose(),
|
|
||||||
"clicked", () => this._toggleMode(),
|
|
||||||
this);
|
|
||||||
|
|
||||||
this.connect("destroy", () => {
|
|
||||||
this.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
this._settings.bind("panel-od-enabled",
|
|
||||||
this, "checked",
|
|
||||||
Gio.SettingsBindFlags.DEFAULT);
|
|
||||||
|
|
||||||
this.sync();
|
|
||||||
|
|
||||||
addQuickSettingsItems([this]);
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleMode() {
|
|
||||||
const checked = this._dbus_platform.getPanelOd();
|
|
||||||
if (this.checked !== checked)
|
|
||||||
this._dbus_platform.setPanelOd(this.checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
sync() {
|
|
||||||
const checked = this._dbus_platform.getPanelOd();
|
|
||||||
if (this.checked !== checked)
|
|
||||||
this.set({ checked });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
declare const imports: any;
|
|
||||||
const Me = imports.misc.extensionUtils.getCurrentExtension();
|
|
||||||
|
|
||||||
const GLib = imports.gi.GLib;
|
|
||||||
|
|
||||||
export class File {
|
|
||||||
public static DBus(name: string) {
|
|
||||||
const file = `${Me.path}/resources/dbus/${name}.xml`;
|
|
||||||
try {
|
|
||||||
const [_ok, bytes] = GLib.file_get_contents(file);
|
|
||||||
if (!_ok)
|
|
||||||
//@ts-ignore
|
|
||||||
log(`Couldn't read contents of "${file}"`);
|
|
||||||
return _ok ? imports.byteArray.toString(bytes) : null;
|
|
||||||
} catch (e) {
|
|
||||||
//@ts-ignore
|
|
||||||
log(`Failed to load "${file}"`, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
import { Power } from "../dbus/power";
|
|
||||||
import { addQuickSettingsItems } from "../helpers";
|
|
||||||
|
|
||||||
declare const imports: any;
|
|
||||||
|
|
||||||
const { GObject } = imports.gi;
|
|
||||||
const ExtensionUtils = imports.misc.extensionUtils;
|
|
||||||
const QuickSettings = imports.ui.quickSettings;
|
|
||||||
|
|
||||||
export const SliderChargeLevel = GObject.registerClass(
|
|
||||||
class SliderChargeLevel extends QuickSettings.QuickSlider {
|
|
||||||
private _dbus_power: Power;
|
|
||||||
|
|
||||||
constructor(dbus_power: Power) {
|
|
||||||
super({
|
|
||||||
iconName: "selection-mode-symbolic",
|
|
||||||
});
|
|
||||||
this._dbus_power = dbus_power;
|
|
||||||
|
|
||||||
this._sliderChangedId = this.slider.connect("drag-end",
|
|
||||||
this._onSliderChanged.bind(this));
|
|
||||||
|
|
||||||
// Binding the slider to a GSettings key
|
|
||||||
this._settings = ExtensionUtils.getSettings();
|
|
||||||
|
|
||||||
this._settings.connect("changed::charge-level",
|
|
||||||
this._onSettingsChanged.bind(this));
|
|
||||||
|
|
||||||
// Set an accessible name for the slider
|
|
||||||
this.slider.accessible_name = "Charge level";
|
|
||||||
|
|
||||||
this._sync();
|
|
||||||
this._onSettingsChanged();
|
|
||||||
|
|
||||||
addQuickSettingsItems([this], 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onSettingsChanged() {
|
|
||||||
// Prevent the slider from emitting a change signal while being updated
|
|
||||||
this.slider.block_signal_handler(this._sliderChangedId);
|
|
||||||
this.slider.value = this._settings.get_uint("charge-level") / 100.0;
|
|
||||||
this.slider.unblock_signal_handler(this._sliderChangedId);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onSliderChanged() {
|
|
||||||
// Assuming our GSettings holds values between 0..100, adjust for the
|
|
||||||
// slider taking values between 0..1
|
|
||||||
const percent = Math.floor(this.slider.value * 100);
|
|
||||||
const stored = Math.floor(this._settings.get_uint("charge-level") / 100.0);
|
|
||||||
if (this.slider.value !== stored)
|
|
||||||
this._dbus_power.setChargingLimit(percent);
|
|
||||||
this._settings.set_uint("charge-level", percent);
|
|
||||||
}
|
|
||||||
|
|
||||||
_sync() {
|
|
||||||
const value = this._dbus_power.getChargingLimit();
|
|
||||||
if (this.slider.value !== value / 100)
|
|
||||||
this._settings.set_uint("charge-level", value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"lib": [
|
|
||||||
"es2019"
|
|
||||||
],
|
|
||||||
"types": [],
|
|
||||||
"target": "es2019",
|
|
||||||
"module": "CommonJS",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"declaration": true,
|
|
||||||
"removeComments": true,
|
|
||||||
"strict": true,
|
|
||||||
"allowJs": true
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"./src/extension.ts",
|
|
||||||
],
|
|
||||||
"include": [
|
|
||||||
"src/*.ts",
|
|
||||||
"src/**/*.ts"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
8
dmi-id/Cargo.toml
Normal file
8
dmi-id/Cargo.toml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "dmi_id"
|
||||||
|
edition = "2021"
|
||||||
|
version.workspace = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
log.workspace = true
|
||||||
|
udev.workspace = true
|
||||||
113
dmi-id/src/lib.rs
Normal file
113
dmi-id/src/lib.rs
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
use log::{info, warn};
|
||||||
|
|
||||||
|
#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Clone)]
|
||||||
|
pub struct DMIID {
|
||||||
|
pub id_model: String,
|
||||||
|
pub dmi_family: String,
|
||||||
|
pub dmi_vendor: String,
|
||||||
|
pub board_name: String,
|
||||||
|
pub board_vendor: String,
|
||||||
|
pub bios_date: String,
|
||||||
|
pub bios_release: String,
|
||||||
|
pub bios_vendor: String,
|
||||||
|
pub bios_version: String,
|
||||||
|
pub product_family: String,
|
||||||
|
pub product_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DMIID {
|
||||||
|
pub fn new() -> Result<Self, String> {
|
||||||
|
let mut enumerator = udev::Enumerator::new().map_err(|err| {
|
||||||
|
warn!("{}", err);
|
||||||
|
format!("dmi enumerator failed: {err}")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
enumerator.match_subsystem("dmi").map_err(|err| {
|
||||||
|
warn!("{}", err);
|
||||||
|
format!("dmi match_subsystem failed: {err}")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let mut result = enumerator.scan_devices().map_err(|err| {
|
||||||
|
warn!("{}", err);
|
||||||
|
format!("dmi scan_devices failed: {err}")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
if let Some(device) = (result).next() {
|
||||||
|
info!("Found dmi ID info at {:?}", device.sysname());
|
||||||
|
|
||||||
|
return Ok(Self {
|
||||||
|
id_model: device
|
||||||
|
.property_value("ID_MODEL")
|
||||||
|
.map(|s| s.to_string_lossy().to_string())
|
||||||
|
.unwrap_or("Unknown".to_string()),
|
||||||
|
dmi_family: device
|
||||||
|
.property_value("DMI_FAMILY")
|
||||||
|
.map(|s| s.to_string_lossy().to_string())
|
||||||
|
.unwrap_or("Unknown".to_string()),
|
||||||
|
dmi_vendor: device
|
||||||
|
.property_value("DMI_VENDOR")
|
||||||
|
.map(|s| s.to_string_lossy().to_string())
|
||||||
|
.unwrap_or("Unknown".to_string()),
|
||||||
|
board_name: device
|
||||||
|
.attribute_value("board_name")
|
||||||
|
.map(|s| s.to_string_lossy().to_string())
|
||||||
|
.unwrap_or("Unknown".to_string()),
|
||||||
|
board_vendor: device
|
||||||
|
.attribute_value("board_vendor")
|
||||||
|
.map(|s| s.to_string_lossy().to_string())
|
||||||
|
.unwrap_or("Unknown".to_string()),
|
||||||
|
bios_date: device
|
||||||
|
.attribute_value("bios_date")
|
||||||
|
.map(|s| s.to_string_lossy().to_string())
|
||||||
|
.unwrap_or("Unknown".to_string()),
|
||||||
|
bios_release: device
|
||||||
|
.attribute_value("bios_release")
|
||||||
|
.map(|s| s.to_string_lossy().to_string())
|
||||||
|
.unwrap_or("Unknown".to_string()),
|
||||||
|
bios_vendor: device
|
||||||
|
.attribute_value("bios_vendor")
|
||||||
|
.map(|s| s.to_string_lossy().to_string())
|
||||||
|
.unwrap_or("Unknown".to_string()),
|
||||||
|
bios_version: device
|
||||||
|
.attribute_value("bios_version")
|
||||||
|
.map(|s| s.to_string_lossy().to_string())
|
||||||
|
.unwrap_or("Unknown".to_string()),
|
||||||
|
product_family: device
|
||||||
|
.attribute_value("product_family")
|
||||||
|
.map(|s| s.to_string_lossy().to_string())
|
||||||
|
.unwrap_or("Unknown".to_string()),
|
||||||
|
product_name: device
|
||||||
|
.attribute_value("product_name")
|
||||||
|
.map(|s| s.to_string_lossy().to_string())
|
||||||
|
.unwrap_or("Unknown".to_string()),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Err("dmi not found".into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore = "Does not run in docker images"]
|
||||||
|
fn dmi_sysfs_properties_not_unknown() {
|
||||||
|
let dmi = DMIID::new().unwrap();
|
||||||
|
|
||||||
|
assert_ne!(dmi.id_model, "Unknown".to_string());
|
||||||
|
dbg!(dmi.id_model);
|
||||||
|
assert_ne!(dmi.dmi_family, "Unknown".to_string());
|
||||||
|
dbg!(dmi.dmi_family);
|
||||||
|
assert_ne!(dmi.dmi_vendor, "Unknown".to_string());
|
||||||
|
dbg!(dmi.dmi_vendor);
|
||||||
|
assert_ne!(dmi.board_name, "Unknown".to_string());
|
||||||
|
dbg!(dmi.board_name);
|
||||||
|
assert_ne!(dmi.board_vendor, "Unknown".to_string());
|
||||||
|
dbg!(dmi.board_vendor);
|
||||||
|
assert_ne!(dmi.product_family, "Unknown".to_string());
|
||||||
|
dbg!(dmi.product_family);
|
||||||
|
assert_ne!(dmi.product_name, "Unknown".to_string());
|
||||||
|
dbg!(dmi.product_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user