CLI args for bios. Cleanup and improve

- dbus method for 'supported modes'
- add dedicated gfx safety
- bring ctrl-gfx back in to main control for better integration
- safely upgrade config files
This commit is contained in:
Luke
2021-01-23 20:40:02 +13:00
parent 703bba9ffd
commit 82900f4645
28 changed files with 993 additions and 215 deletions

View File

@@ -6,6 +6,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
# [2.2.0] - 2021-01-26
### Added
- Dbus command to fetch all supported functions of the laptop. That is, all the
functions that asusd supports for the currently running laptop.
- Bios setting toggles for:
+ Dedicated gfx toggle (support depends on the laptop)
+ Bios boot POST sound toggle
### Changed
- added config option for dedicated gfx mode on laptops with it to enable
switching directly to dedicated using `asusctl graphics -m nvidia`
# [2.1.2] - 2021-01-10 # [2.1.2] - 2021-01-10
### Changed ### Changed
- Adjust gfx controller to assume that the graphics driver is loaded if the - Adjust gfx controller to assume that the graphics driver is loaded if the

144
Cargo.lock generated
View File

@@ -29,9 +29,8 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]] [[package]]
name = "asus-nb" name = "asus-nb"
version = "2.1.2" version = "2.2.0"
dependencies = [ dependencies = [
"ctrl-gfx",
"dbus", "dbus",
"gumdrop", "gumdrop",
"rog_fan_curve", "rog_fan_curve",
@@ -46,10 +45,9 @@ dependencies = [
[[package]] [[package]]
name = "asus-nb-ctrl" name = "asus-nb-ctrl"
version = "2.1.2" version = "2.2.0"
dependencies = [ dependencies = [
"asus-nb", "asus-nb",
"ctrl-gfx",
"env_logger", "env_logger",
"gumdrop", "gumdrop",
"intel-pstate", "intel-pstate",
@@ -230,16 +228,6 @@ dependencies = [
"lazy_static", "lazy_static",
] ]
[[package]]
name = "ctrl-gfx"
version = "2.1.4"
dependencies = [
"log",
"sysfs-class",
"zbus",
"zvariant",
]
[[package]] [[package]]
name = "dbus" name = "dbus"
version = "0.8.4" version = "0.8.4"
@@ -252,13 +240,13 @@ dependencies = [
[[package]] [[package]]
name = "derivative" name = "derivative"
version = "2.1.3" version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaed5874effa6cde088c644ddcdcb4ffd1511391c5be4fdd7a5ccd02c7e4a183" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.8", "quote 1.0.8",
"syn 1.0.58", "syn 1.0.60",
] ]
[[package]] [[package]]
@@ -290,7 +278,7 @@ checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.8", "quote 1.0.8",
"syn 1.0.58", "syn 1.0.60",
] ]
[[package]] [[package]]
@@ -316,7 +304,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.8", "quote 1.0.8",
"rustversion", "rustversion",
"syn 1.0.58", "syn 1.0.60",
"synstructure", "synstructure",
] ]
@@ -331,21 +319,21 @@ dependencies = [
[[package]] [[package]]
name = "filetime" name = "filetime"
version = "0.2.13" version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c122a393ea57648015bf06fbd3d372378992e86b9ff5a7a497b076a28c79efe" checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"libc", "libc",
"redox_syscall", "redox_syscall 0.2.4",
"winapi", "winapi",
] ]
[[package]] [[package]]
name = "futures" name = "futures"
version = "0.3.9" version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c70be434c505aee38639abccb918163b63158a4b4bb791b45b7023044bdc3c9c" checksum = "da9052a1a50244d8d5aa9bf55cbc2fb6f357c86cc52e46c62ed390a7180cf150"
dependencies = [ dependencies = [
"futures-channel", "futures-channel",
"futures-core", "futures-core",
@@ -358,9 +346,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.9" version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f01c61843314e95f96cc9245702248733a3a3d744e43e2e755e3c7af8348a0a9" checksum = "f2d31b7ec7efab6eefc7c57233bb10b847986139d88cc2f5a02a1ae6871a1846"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-sink", "futures-sink",
@@ -368,15 +356,15 @@ dependencies = [
[[package]] [[package]]
name = "futures-core" name = "futures-core"
version = "0.3.9" version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db8d3b0917ff63a2a96173133c02818fac4a746b0a57569d3baca9ec0e945e08" checksum = "79e5145dde8da7d1b3892dad07a9c98fc04bc39892b1ecc9692cf53e2b780a65"
[[package]] [[package]]
name = "futures-executor" name = "futures-executor"
version = "0.3.9" version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ee9ca2f7eb4475772cf39dd1cd06208dce2670ad38f4d9c7262b3e15f127068" checksum = "e9e59fdc009a4b3096bf94f740a0f2424c082521f20a9b08c5c07c48d90fd9b9"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"futures-task", "futures-task",
@@ -385,9 +373,9 @@ dependencies = [
[[package]] [[package]]
name = "futures-io" name = "futures-io"
version = "0.3.9" version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e37c1a51b037b80922864b8eed90692c5cd8abd4c71ce49b77146caa47f3253b" checksum = "28be053525281ad8259d47e4de5de657b25e7bac113458555bb4b70bc6870500"
[[package]] [[package]]
name = "futures-lite" name = "futures-lite"
@@ -406,36 +394,36 @@ dependencies = [
[[package]] [[package]]
name = "futures-macro" name = "futures-macro"
version = "0.3.9" version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f8719ca0e1f3c5e34f3efe4570ef2c0610ca6da85ae7990d472e9cbfba13664" checksum = "c287d25add322d9f9abdcdc5927ca398917996600182178774032e9f8258fedd"
dependencies = [ dependencies = [
"proc-macro-hack", "proc-macro-hack",
"proc-macro2", "proc-macro2",
"quote 1.0.8", "quote 1.0.8",
"syn 1.0.58", "syn 1.0.60",
] ]
[[package]] [[package]]
name = "futures-sink" name = "futures-sink"
version = "0.3.9" version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6adabac1290109cfa089f79192fb6244ad2c3f1cc2281f3e1dd987592b71feb" checksum = "caf5c69029bda2e743fddd0582d1083951d65cc9539aebf8812f36c3491342d6"
[[package]] [[package]]
name = "futures-task" name = "futures-task"
version = "0.3.9" version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a92a0843a2ff66823a8f7c77bffe9a09be2b64e533562c412d63075643ec0038" checksum = "13de07eb8ea81ae445aca7b69f5f7bf15d7bf4912d8ca37d6645c77ae8a58d86"
dependencies = [ dependencies = [
"once_cell", "once_cell",
] ]
[[package]] [[package]]
name = "futures-util" name = "futures-util"
version = "0.3.9" version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "036a2107cdeb57f6d7322f1b6c363dad67cd63ca3b7d1b925bdf75bd5d96cda9" checksum = "632a8cd0f2a4b3fdea1657f08bde063848c3bd00f9bbf6e256b8be78802e624b"
dependencies = [ dependencies = [
"futures-channel", "futures-channel",
"futures-core", "futures-core",
@@ -479,14 +467,14 @@ checksum = "915ef07c710d84733522461de2a734d4d62a3fd39a4d4f404c2f385ef8618d05"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.8", "quote 1.0.8",
"syn 1.0.58", "syn 1.0.60",
] ]
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.1.17" version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@@ -590,9 +578,9 @@ dependencies = [
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.11" version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2"
dependencies = [ dependencies = [
"cfg-if 0.1.10", "cfg-if 0.1.10",
] ]
@@ -739,9 +727,9 @@ checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
[[package]] [[package]]
name = "pin-project-lite" name = "pin-project-lite"
version = "0.2.1" version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e36743d754ccdf9954c2e352ce2d4b106e024c814f6499c2dadff80da9a442d8" checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827"
[[package]] [[package]]
name = "pin-utils" name = "pin-utils"
@@ -786,7 +774,7 @@ dependencies = [
"proc-macro-error-attr", "proc-macro-error-attr",
"proc-macro2", "proc-macro2",
"quote 1.0.8", "quote 1.0.8",
"syn 1.0.58", "syn 1.0.60",
"version_check", "version_check",
] ]
@@ -809,9 +797,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]] [[package]]
name = "proc-macro-nested" name = "proc-macro-nested"
version = "0.1.6" version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a" checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
@@ -849,6 +837,15 @@ version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_syscall"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05ec8ca9416c5ea37062b502703cd7fcb207736bc294f6e0cf367ac6fc234570"
dependencies = [
"bitflags 1.2.1",
]
[[package]] [[package]]
name = "redox_users" name = "redox_users"
version = "0.3.5" version = "0.3.5"
@@ -856,7 +853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
dependencies = [ dependencies = [
"getrandom", "getrandom",
"redox_syscall", "redox_syscall 0.1.57",
"rust-argon2", "rust-argon2",
] ]
@@ -935,22 +932,22 @@ checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.118" version = "1.0.123"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06c64263859d87aa2eb554587e2d23183398d617427327cf2b3d0ed8c69e4800" checksum = "92d5161132722baa40d802cc70b15262b98258453e85e5d1d365c757c73869ae"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.118" version = "1.0.123"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c84d3526699cd55261af4b941e4e725444df67aa4f9e6a3564f18030d12672df" checksum = "9391c295d64fc0abb2c556bad848f33cb8296276b1ad2677d1ae1ace4f258f31"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.8", "quote 1.0.8",
"syn 1.0.58", "syn 1.0.60",
] ]
[[package]] [[package]]
@@ -972,7 +969,7 @@ checksum = "2dc6b7951b17b051f3210b063f12cc17320e2fe30ae05b0fe2a3abb068551c76"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.8", "quote 1.0.8",
"syn 1.0.58", "syn 1.0.60",
] ]
[[package]] [[package]]
@@ -989,7 +986,7 @@ checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.8", "quote 1.0.8",
"syn 1.0.58", "syn 1.0.60",
] ]
[[package]] [[package]]
@@ -1021,9 +1018,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.58" version = "1.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5" checksum = "c700597eca8a5a762beb35753ef6b94df201c81cca676604f547495a0d7f0081"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.8", "quote 1.0.8",
@@ -1047,7 +1044,7 @@ checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote 1.0.8", "quote 1.0.8",
"syn 1.0.58", "syn 1.0.60",
"unicode-xid 0.2.1", "unicode-xid 0.2.1",
] ]
@@ -1062,13 +1059,12 @@ dependencies = [
[[package]] [[package]]
name = "tar" name = "tar"
version = "0.4.30" version = "0.4.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "489997b7557e9a43e192c527face4feacc78bfbe6eed67fd55c4c9e381cba290" checksum = "0313546c01d59e29be4f09687bcb4fb6690cec931cc3607b6aec7a0e417f4cc6"
dependencies = [ dependencies = [
"filetime", "filetime",
"libc", "libc",
"redox_syscall",
"xattr", "xattr",
] ]
@@ -1083,11 +1079,11 @@ dependencies = [
[[package]] [[package]]
name = "thread_local" name = "thread_local"
version = "1.1.0" version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447" checksum = "d8208a331e1cb318dd5bd76951d2b8fc48ca38a69f5f4e4af1b6a9f8c6236915"
dependencies = [ dependencies = [
"lazy_static", "once_cell",
] ]
[[package]] [[package]]
@@ -1313,14 +1309,14 @@ dependencies = [
"proc-macro-crate", "proc-macro-crate",
"proc-macro2", "proc-macro2",
"quote 1.0.8", "quote 1.0.8",
"syn 1.0.58", "syn 1.0.60",
] ]
[[package]] [[package]]
name = "zvariant" name = "zvariant"
version = "2.4.0" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bfdc513511335faee7b18d6e8b6086de555d6e8b0a598415571bb0f0b446519" checksum = "2fc67d552ac18ccd9e440f062f5b32c46776f96073122a8da2fe0c533833a213"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"enumflags2", "enumflags2",
@@ -1330,12 +1326,12 @@ dependencies = [
[[package]] [[package]]
name = "zvariant_derive" name = "zvariant_derive"
version = "2.4.0" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6651d08772eefc17d36ef4da3a521b2e5f87c10ef730125b83eb500512073c92" checksum = "eaee686340b5bff077d52423d8cc4f0f7cb323fe3f31ef676b8a3a2810bc53c5"
dependencies = [ dependencies = [
"proc-macro-crate", "proc-macro-crate",
"proc-macro2", "proc-macro2",
"quote 1.0.8", "quote 1.0.8",
"syn 1.0.58", "syn 1.0.60",
] ]

View File

@@ -1,5 +1,5 @@
[workspace] [workspace]
members = ["asus-notify", "asus-nb-ctrl", "asus-nb", "ctrl-gfx"] members = ["asus-notify", "asus-nb-ctrl", "asus-nb"]
[profile.release] [profile.release]
lto = true lto = true

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "asus-nb-ctrl" name = "asus-nb-ctrl"
version = "2.1.2" version = "2.2.0"
license = "MPL-2.0" license = "MPL-2.0"
readme = "README.md" readme = "README.md"
authors = ["Luke <luke@ljones.dev>"] authors = ["Luke <luke@ljones.dev>"]
@@ -22,7 +22,6 @@ name = "asusd"
path = "src/daemon.rs" path = "src/daemon.rs"
[dependencies] [dependencies]
ctrl-gfx = { path = "../ctrl-gfx" }
asus-nb = { path = "../asus-nb" } asus-nb = { path = "../asus-nb" }
rusb = "^0.6.0" rusb = "^0.6.0"
udev = "^0.4.0" udev = "^0.4.0"
@@ -47,4 +46,4 @@ rog_fan_curve = { version = "0.1.5", features = ["serde"] }
# cpu power management # cpu power management
intel-pstate = "^0.2.1" intel-pstate = "^0.2.1"
yansi-term = "^0.1" yansi-term = "^0.1"

View File

@@ -1,16 +1,51 @@
use asus_nb::aura_modes::AuraModes; use asus_nb::aura_modes::AuraModes;
use log::{error, warn}; use log::{error, info, warn};
use rog_fan_curve::Curve; use rog_fan_curve::Curve;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fs::{File, OpenOptions}; use std::fs::{File, OpenOptions};
use std::io::{Read, Write}; use std::io::{Read, Write};
use crate::VERSION;
pub static CONFIG_PATH: &str = "/etc/asusd/asusd.conf"; pub static CONFIG_PATH: &str = "/etc/asusd/asusd.conf";
/// for parsing old v2.1.2 config
#[derive(Deserialize)]
struct ConfigV212 {
gfx_managed: bool,
active_profile: String,
toggle_profiles: Vec<String>,
// TODO: remove power_profile
power_profile: u8,
bat_charge_limit: u8,
kbd_led_brightness: u8,
kbd_backlight_mode: u8,
kbd_backlight_modes: Vec<AuraModes>,
power_profiles: BTreeMap<String, Profile>,
}
impl ConfigV212 {
fn into_current(self) -> Config {
Config {
gfx_managed: self.gfx_managed,
gfx_nv_mode_is_dedicated: true,
active_profile: self.active_profile,
toggle_profiles: self.toggle_profiles,
power_profile: self.power_profile,
bat_charge_limit: self.bat_charge_limit,
kbd_led_brightness: self.kbd_led_brightness,
kbd_backlight_mode: self.kbd_backlight_mode,
kbd_backlight_modes: self.kbd_backlight_modes,
power_profiles: self.power_profiles,
}
}
}
#[derive(Default, Deserialize, Serialize)] #[derive(Default, Deserialize, Serialize)]
pub struct Config { pub struct Config {
pub gfx_managed: bool, pub gfx_managed: bool,
pub gfx_nv_mode_is_dedicated: bool,
pub active_profile: String, pub active_profile: String,
pub toggle_profiles: Vec<String>, pub toggle_profiles: Vec<String>,
// TODO: remove power_profile // TODO: remove power_profile
@@ -24,7 +59,7 @@ pub struct Config {
impl Config { impl Config {
/// `load` will attempt to read the config, and panic if the dir is missing /// `load` will attempt to read the config, and panic if the dir is missing
pub fn load(mut self, supported_led_modes: &[u8]) -> Self { pub fn load(supported_led_modes: &[u8]) -> Self {
let mut file = OpenOptions::new() let mut file = OpenOptions::new()
.read(true) .read(true)
.write(true) .write(true)
@@ -35,23 +70,30 @@ impl Config {
CONFIG_PATH CONFIG_PATH
)); // okay to cause panic here )); // okay to cause panic here
let mut buf = String::new(); let mut buf = String::new();
if let Ok(l) = file.read_to_string(&mut buf) { if let Ok(read_len) = file.read_to_string(&mut buf) {
if l == 0 { if read_len == 0 {
self = Config::create_default(&mut file, &supported_led_modes); return Config::create_default(&mut file, &supported_led_modes);
} else { } else {
self = serde_json::from_str(&buf).unwrap_or_else(|_| { if let Ok(data) = serde_json::from_str(&buf) {
warn!("Could not deserialise {}", CONFIG_PATH); return data;
panic!("Please remove {} then restart asusd", CONFIG_PATH); } else if let Ok(data) = serde_json::from_str::<ConfigV212>(&buf) {
}); let config = data.into_current();
config.write();
info!("Updated config version to: {}", VERSION);
return config;
}
warn!("Could not deserialise {}", CONFIG_PATH);
panic!("Please remove {} then restart asusd", CONFIG_PATH);
} }
} }
self Config::create_default(&mut file, &supported_led_modes)
} }
fn create_default(file: &mut File, supported_led_modes: &[u8]) -> Self { fn create_default(file: &mut File, supported_led_modes: &[u8]) -> Self {
// create a default config here // create a default config here
let mut config = Config::default(); let mut config = Config::default();
config.gfx_managed = true; config.gfx_managed = true;
config.gfx_nv_mode_is_dedicated = true;
config.bat_charge_limit = 100; config.bat_charge_limit = 100;
config.kbd_backlight_mode = 0; config.kbd_backlight_mode = 0;

View File

@@ -21,6 +21,20 @@ use std::error::Error;
use std::time::Duration; use std::time::Duration;
use zbus::dbus_interface; use zbus::dbus_interface;
use crate::GetSupported;
use serde_derive::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct AnimeSupportedFunctions(bool);
impl GetSupported for CtrlAnimeDisplay {
type A = AnimeSupportedFunctions;
fn get_supported() -> Self::A {
AnimeSupportedFunctions(CtrlAnimeDisplay::get_device(0x0b05, 0x193b).is_ok())
}
}
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug)] #[derive(Debug)]
pub enum AnimatrixCommand { pub enum AnimatrixCommand {

View File

@@ -1,6 +1,7 @@
use crate::{config::Config, error::RogError}; use crate::{config::Config, error::RogError, GetSupported};
//use crate::dbus::DbusEvents; //use crate::dbus::DbusEvents;
use log::{info, warn}; use log::{info, warn};
use serde_derive::{Deserialize, Serialize};
use std::convert::TryInto; use std::convert::TryInto;
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::io::Write; use std::io::Write;
@@ -11,8 +12,22 @@ use zbus::dbus_interface;
static BAT_CHARGE_PATH: &str = "/sys/class/power_supply/BAT0/charge_control_end_threshold"; static BAT_CHARGE_PATH: &str = "/sys/class/power_supply/BAT0/charge_control_end_threshold";
#[derive(Serialize, Deserialize)]
pub struct ChargeSupportedFunctions {
pub charge_level_set: bool,
}
impl GetSupported for CtrlCharge {
type A = ChargeSupportedFunctions;
fn get_supported() -> Self::A {
ChargeSupportedFunctions {
charge_level_set: CtrlCharge::get_battery_path().is_ok(),
}
}
}
pub struct CtrlCharge { pub struct CtrlCharge {
path: &'static str,
config: Arc<Mutex<Config>>, config: Arc<Mutex<Config>>,
} }
@@ -43,7 +58,7 @@ impl CtrlCharge {
} }
#[dbus_interface(signal)] #[dbus_interface(signal)]
pub fn notify_charge(&self, limit: u8) -> zbus::Result<()>; pub fn notify_charge(&self, limit: u8) -> zbus::Result<()> {}
} }
impl crate::ZbusAdd for CtrlCharge { impl crate::ZbusAdd for CtrlCharge {
@@ -62,7 +77,6 @@ impl crate::Reloadable for CtrlCharge {
fn reload(&mut self) -> Result<(), RogError> { fn reload(&mut self) -> Result<(), RogError> {
if let Ok(mut config) = self.config.try_lock() { if let Ok(mut config) = self.config.try_lock() {
config.read(); config.read();
info!("Reloaded battery charge limit");
self.set(config.bat_charge_limit, &mut config)?; self.set(config.bat_charge_limit, &mut config)?;
} }
Ok(()) Ok(())
@@ -71,9 +85,8 @@ impl crate::Reloadable for CtrlCharge {
impl CtrlCharge { impl CtrlCharge {
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> { pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
let path = CtrlCharge::get_battery_path()?; CtrlCharge::get_battery_path()?;
info!("Device has battery charge threshold control"); Ok(CtrlCharge { config })
Ok(CtrlCharge { path, config })
} }
fn get_battery_path() -> Result<&'static str, RogError> { fn get_battery_path() -> Result<&'static str, RogError> {
@@ -97,10 +110,10 @@ impl CtrlCharge {
let mut file = OpenOptions::new() let mut file = OpenOptions::new()
.write(true) .write(true)
.open(self.path) .open(BAT_CHARGE_PATH)
.map_err(|err| RogError::Path(self.path.into(), err))?; .map_err(|err| RogError::Path(BAT_CHARGE_PATH.into(), err))?;
file.write_all(limit.to_string().as_bytes()) file.write_all(limit.to_string().as_bytes())
.map_err(|err| RogError::Write(self.path.into(), err))?; .map_err(|err| RogError::Write(BAT_CHARGE_PATH.into(), err))?;
info!("Battery charge limit: {}", limit); info!("Battery charge limit: {}", limit);
config.read(); config.read();

View File

@@ -1,6 +1,10 @@
use crate::config::{Config, Profile}; use crate::{
config::{Config, Profile},
GetSupported,
};
use asus_nb::profile::ProfileEvent; use asus_nb::profile::ProfileEvent;
use log::{info, warn}; use log::{info, warn};
use serde_derive::{Deserialize, Serialize};
use std::convert::TryInto; use std::convert::TryInto;
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::io::{Read, Write}; use std::io::{Read, Write};
@@ -19,6 +23,25 @@ pub struct CtrlFanAndCPU {
config: Arc<Mutex<Config>>, config: Arc<Mutex<Config>>,
} }
#[derive(Serialize, Deserialize)]
pub struct FanCpuSupportedFunctions {
pub stock_fan_modes: bool,
pub min_max_freq: bool,
pub fan_curve_set: bool,
}
impl GetSupported for CtrlFanAndCPU {
type A = FanCpuSupportedFunctions;
fn get_supported() -> Self::A {
FanCpuSupportedFunctions {
stock_fan_modes: CtrlFanAndCPU::get_fan_path().is_ok(),
min_max_freq: intel_pstate::PState::new().is_ok(),
fan_curve_set: rog_fan_curve::Board::from_board_name().is_some(),
}
}
}
pub struct DbusFanAndCpu { pub struct DbusFanAndCpu {
inner: Arc<Mutex<CtrlFanAndCPU>>, inner: Arc<Mutex<CtrlFanAndCPU>>,
} }
@@ -101,7 +124,7 @@ impl DbusFanAndCpu {
} }
#[dbus_interface(signal)] #[dbus_interface(signal)]
fn notify_profile(&self, profile: &str) -> zbus::Result<()>; fn notify_profile(&self, profile: &str) -> zbus::Result<()> {}
} }
impl crate::ZbusAdd for DbusFanAndCpu { impl crate::ZbusAdd for DbusFanAndCpu {

View File

@@ -1,16 +1,19 @@
use ctrl_gfx::error::GfxError;
use ctrl_gfx::*;
use ctrl_rog_bios::CtrlRogBios;
use log::{error, info, warn}; use log::{error, info, warn};
use std::error::Error;
use std::io::Write; use std::io::Write;
use std::iter::FromIterator; use std::iter::FromIterator;
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
use std::str::FromStr; use std::str::FromStr;
use std::{error::Error, sync::Arc, sync::Mutex};
use sysfs_class::{PciDevice, SysClass}; use sysfs_class::{PciDevice, SysClass};
use system::{GraphicsDevice, Module, PciBus};
use vendors::{GfxCtrlAction, GfxVendors};
use zbus::dbus_interface; use zbus::dbus_interface;
use crate::vendors::*;
use crate::*; use crate::*;
use crate::{error::GfxError, system::*};
pub struct CtrlGraphics { pub struct CtrlGraphics {
bus: PciBus, bus: PciBus,
@@ -20,6 +23,7 @@ pub struct CtrlGraphics {
#[allow(dead_code)] #[allow(dead_code)]
other: Vec<GraphicsDevice>, other: Vec<GraphicsDevice>,
initfs_cmd: Option<Command>, initfs_cmd: Option<Command>,
config: Arc<Mutex<Config>>,
} }
trait Dbus { trait Dbus {
@@ -30,10 +34,8 @@ trait Dbus {
fn notify_action(&self, action: &str) -> zbus::Result<()>; fn notify_action(&self, action: &str) -> zbus::Result<()>;
} }
#[cfg(feature = "use-zbus")]
use std::convert::TryInto; use std::convert::TryInto;
#[cfg(feature = "use-zbus")]
#[dbus_interface(name = "org.asuslinux.Daemon")] #[dbus_interface(name = "org.asuslinux.Daemon")]
impl Dbus for CtrlGraphics { impl Dbus for CtrlGraphics {
fn vendor(&self) -> String { fn vendor(&self) -> String {
@@ -58,14 +60,14 @@ impl Dbus for CtrlGraphics {
} }
#[dbus_interface(signal)] #[dbus_interface(signal)]
fn notify_gfx(&self, vendor: &str) -> zbus::Result<()>; fn notify_gfx(&self, vendor: &str) -> zbus::Result<()> {}
#[dbus_interface(signal)] #[dbus_interface(signal)]
fn notify_action(&self, action: &str) -> zbus::Result<()>; fn notify_action(&self, action: &str) -> zbus::Result<()> {}
} }
impl CtrlGraphics { impl CtrlGraphics {
pub fn new() -> std::io::Result<CtrlGraphics> { pub fn new(config: Arc<Mutex<Config>>) -> std::io::Result<CtrlGraphics> {
let bus = PciBus::new()?; let bus = PciBus::new()?;
info!("Rescanning PCI bus"); info!("Rescanning PCI bus");
@@ -138,13 +140,16 @@ impl CtrlGraphics {
nvidia, nvidia,
other, other,
initfs_cmd, initfs_cmd,
config,
}) })
} }
#[cfg(feature = "use-zbus")]
pub fn add_to_server(self, server: &mut zbus::ObjectServer) { pub fn add_to_server(self, server: &mut zbus::ObjectServer) {
server server
.at(&"/org/asuslinux/Gfx".try_into().unwrap(), self) .at(
&"/org/asuslinux/Gfx".try_into().expect("Some fail here"),
self,
)
.map_err(|err| { .map_err(|err| {
warn!("CtrlGraphics: add_to_server {}", err); warn!("CtrlGraphics: add_to_server {}", err);
err err
@@ -158,10 +163,6 @@ impl CtrlGraphics {
Ok(()) Ok(())
} }
// fn can_switch(&self) -> bool {
// !self.nvidia.is_empty() && (!self.intel.is_empty() || !self.amd.is_empty())
// }
fn get_prime_discrete() -> Result<String, GfxError> { fn get_prime_discrete() -> Result<String, GfxError> {
let s = std::fs::read_to_string(PRIME_DISCRETE_PATH) let s = std::fs::read_to_string(PRIME_DISCRETE_PATH)
.map_err(|err| GfxError::Read(PRIME_DISCRETE_PATH.into(), err))? .map_err(|err| GfxError::Read(PRIME_DISCRETE_PATH.into(), err))?
@@ -220,10 +221,7 @@ impl CtrlGraphics {
Ok(x) Ok(x)
} }
/// Write out config files if required, enable/disable relevant services, and update the ramdisk pub fn set_gfx_config(vendor: GfxVendors) -> Result<(), GfxError> {
pub fn set(&mut self, vendor: GfxVendors) -> Result<String, GfxError> {
//self.switchable_or_fail()?;
let mode = if vendor == GfxVendors::Hybrid { let mode = if vendor == GfxVendors::Hybrid {
"on-demand\n" "on-demand\n"
} else if vendor == GfxVendors::Nvidia { } else if vendor == GfxVendors::Nvidia {
@@ -236,10 +234,6 @@ impl CtrlGraphics {
info!("Setting {} to {}", PRIME_DISCRETE_PATH, mode); info!("Setting {} to {}", PRIME_DISCRETE_PATH, mode);
Self::set_prime_discrete(mode)?; Self::set_prime_discrete(mode)?;
// Switching from hybrid to/from nvidia shouldn't require a ramdisk update
// or a reboot.
let no_reboot = Self::is_switching_prime_modes(&vendor)?;
{ {
info!("Writing {}", MODPROBE_PATH); info!("Writing {}", MODPROBE_PATH);
@@ -307,6 +301,32 @@ impl CtrlGraphics {
status status
); );
} }
Ok(())
}
/// Write out config files if required, enable/disable relevant services, and update the ramdisk
pub fn set(&mut self, vendor: GfxVendors) -> Result<String, GfxError> {
if CtrlRogBios::has_dedicated_gfx_toggle() {
if let Ok(config) = self.config.clone().try_lock() {
// Switch to dedicated if config says to do so
if config.gfx_nv_mode_is_dedicated && vendor == GfxVendors::Nvidia {
CtrlRogBios::set_gfx_mode(true)
.unwrap_or_else(|err| warn!("Gfx controller: {}", err));
} else if let Ok(ded) = CtrlRogBios::get_gfx_mode() {
// otherwise if switching to non-Nvidia mode turn off dedicated mode
if ded == 1 && vendor != GfxVendors::Nvidia {
CtrlRogBios::set_gfx_mode(false)
.unwrap_or_else(|err| warn!("Gfx controller: {}", err));
}
}
}
}
// Switching from hybrid to/from nvidia shouldn't require a ramdisk update
// or a reboot.
let no_reboot = Self::is_switching_prime_modes(&vendor)?;
Self::set_gfx_config(vendor)?;
let mut required_action = GfxCtrlAction::None; let mut required_action = GfxCtrlAction::None;
if !no_reboot { if !no_reboot {
@@ -329,12 +349,6 @@ impl CtrlGraphics {
Ok(required_action.into()) Ok(required_action.into())
} }
// pub fn get_power(&self) -> Option<bool> {
// if self.can_switch() {
// return Some(self.nvidia.iter().any(GraphicsDevice::exists));
// }
// None
// }
pub fn get_runtime_status() -> Result<String, GfxError> { pub fn get_runtime_status() -> Result<String, GfxError> {
const PATH: &str = "/sys/bus/pci/devices/0000:01:00.0/power/runtime_status"; const PATH: &str = "/sys/bus/pci/devices/0000:01:00.0/power/runtime_status";
let buf = std::fs::read_to_string(PATH).map_err(|err| GfxError::Read(PATH.into(), err))?; let buf = std::fs::read_to_string(PATH).map_err(|err| GfxError::Read(PATH.into(), err))?;
@@ -342,8 +356,6 @@ impl CtrlGraphics {
} }
fn set_power(&self, power: bool) -> Result<(), GfxError> { fn set_power(&self, power: bool) -> Result<(), GfxError> {
// self.switchable_or_fail()?;
if power { if power {
info!("Enabling graphics power"); info!("Enabling graphics power");
self.bus self.bus

View File

@@ -2,7 +2,7 @@ pub mod vendors;
pub mod error; pub mod error;
pub mod ctrl_gfx; pub mod gfx;
pub mod system; pub mod system;

View File

@@ -6,9 +6,10 @@ pub enum GfxVendors {
Hybrid, Hybrid,
} }
use crate::error::GfxError;
use std::str::FromStr; use std::str::FromStr;
use super::error::GfxError;
impl FromStr for GfxVendors { impl FromStr for GfxVendors {
type Err = GfxError; type Err = GfxError;

View File

@@ -4,8 +4,17 @@ static LED_SET: [u8; 17] = [0x5d, 0xb5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
static KBD_BRIGHT_PATH: &str = "/sys/class/leds/asus::kbd_backlight/brightness"; static KBD_BRIGHT_PATH: &str = "/sys/class/leds/asus::kbd_backlight/brightness";
use crate::{config::Config, error::RogError, laptops::HELP_ADDRESS}; use crate::{
use asus_nb::{aura_brightness_bytes, aura_modes::AuraModes, fancy::KeyColourArray, LED_MSG_LEN}; config::Config,
error::RogError,
laptops::{match_laptop, HELP_ADDRESS},
};
use asus_nb::{
aura_brightness_bytes,
aura_modes::{AuraModes, PER_KEY},
fancy::KeyColourArray,
LED_MSG_LEN,
};
use log::{info, warn}; use log::{info, warn};
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::io::{Read, Write}; use std::io::{Read, Write};
@@ -14,6 +23,44 @@ use std::sync::Mutex;
use std::{convert::TryInto, path::Path}; use std::{convert::TryInto, path::Path};
use zbus::dbus_interface; use zbus::dbus_interface;
use crate::GetSupported;
use serde_derive::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct LedSupportedFunctions {
pub brightness_set: bool,
pub stock_led_modes: Option<Vec<u8>>,
pub per_key_led_mode: bool,
}
impl GetSupported for CtrlKbdBacklight {
type A = LedSupportedFunctions;
fn get_supported() -> Self::A {
// let mode = <&str>::from(&<AuraModes>::from(*mode));
let mut stock_led_modes = None;
let mut per_key_led_mode = false;
if let Some(laptop) = match_laptop() {
let modes = laptop.supported_modes().to_vec();
if modes.contains(&PER_KEY) {
per_key_led_mode = true;
let modes = modes
.iter()
.filter(|x| **x != PER_KEY)
.map(|x| *x)
.collect();
stock_led_modes = Some(modes);
}
}
LedSupportedFunctions {
brightness_set: CtrlKbdBacklight::get_kbd_bright_path().is_ok(),
stock_led_modes,
per_key_led_mode,
}
}
}
pub struct CtrlKbdBacklight { pub struct CtrlKbdBacklight {
led_node: Option<String>, led_node: Option<String>,
#[allow(dead_code)] #[allow(dead_code)]

View File

@@ -0,0 +1,261 @@
use crate::{
config::Config,
ctrl_gfx::{gfx::CtrlGraphics, vendors::GfxVendors},
error::RogError,
GetSupported,
};
//use crate::dbus::DbusEvents;
use log::{info, warn};
use serde_derive::{Deserialize, Serialize};
use std::convert::TryInto;
use std::fs::OpenOptions;
use std::io::{Read, Write};
use std::path::Path;
use std::sync::Arc;
use std::sync::Mutex;
use zbus::dbus_interface;
static ASUS_SWITCH_GRAPHIC_MODE: &str =
"/sys/firmware/efi/efivars/AsusSwitchGraphicMode-607005d5-3f75-4b2e-98f0-85ba66797a3e";
static ASUS_POST_LOGO_SOUND: &str =
"/sys/firmware/efi/efivars/AsusPostLogoSound-607005d5-3f75-4b2e-98f0-85ba66797a3e";
pub struct CtrlRogBios {
config: Arc<Mutex<Config>>,
}
#[derive(Serialize, Deserialize)]
pub struct RogBiosSupportedFunctions {
pub post_sound_toggle: bool,
pub dedicated_gfx_toggle: bool,
}
impl GetSupported for CtrlRogBios {
type A = RogBiosSupportedFunctions;
fn get_supported() -> Self::A {
RogBiosSupportedFunctions {
post_sound_toggle: CtrlRogBios::check_path_exists(ASUS_POST_LOGO_SOUND).is_ok(),
dedicated_gfx_toggle: CtrlRogBios::check_path_exists(ASUS_SWITCH_GRAPHIC_MODE).is_ok(),
}
}
}
#[dbus_interface(name = "org.asuslinux.Daemon")]
impl CtrlRogBios {
pub fn set_dedicated_graphic_mode(&mut self, dedicated: bool) {
Self::set_gfx_mode(dedicated)
.map_err(|err| {
warn!("CtrlRogBios: set_asus_switch_graphic_mode {}", err);
err
})
.ok();
self.notify_dedicated_graphic_mode(dedicated)
.map_err(|err| {
warn!("CtrlRogBios: notify_asus_switch_graphic_mode {}", err);
err
})
.ok();
}
pub fn dedicated_graphic_mode(&self) -> i8 {
Self::get_gfx_mode()
.map_err(|err| {
warn!("CtrlRogBios: get_gfx_mode {}", err);
err
})
.unwrap_or(-1)
}
#[dbus_interface(signal)]
pub fn notify_dedicated_graphic_mode(&self, dedicated: bool) -> zbus::Result<()> {}
// // // // // // // // // //
pub fn set_post_boot_sound(&mut self, on: bool) {
Self::set_boot_sound(on)
.map_err(|err| {
warn!("CtrlRogBios: set_post_boot_sound {}", err);
err
})
.ok();
self.notify_post_boot_sound(on)
.map_err(|err| {
warn!("CtrlRogBios: notify_post_boot_sound {}", err);
err
})
.ok();
}
pub fn post_boot_sound(&self) -> i8 {
Self::get_boot_sound()
.map_err(|err| {
warn!("CtrlRogBios: get_boot_sound {}", err);
err
})
.unwrap_or(-1)
}
#[dbus_interface(signal)]
pub fn notify_post_boot_sound(&self, dedicated: bool) -> zbus::Result<()> {}
}
impl crate::ZbusAdd for CtrlRogBios {
fn add_to_server(self, server: &mut zbus::ObjectServer) {
server
.at(&"/org/asuslinux/RogBios".try_into().unwrap(), self)
.map_err(|err| {
warn!("CtrlRogBios: add_to_server {}", err);
err
})
.ok();
}
}
impl crate::Reloadable for CtrlRogBios {
fn reload(&mut self) -> Result<(), RogError> {
Ok(())
}
}
impl CtrlRogBios {
pub fn new(config: Arc<Mutex<Config>>) -> Result<Self, RogError> {
match CtrlRogBios::check_path_exists(ASUS_SWITCH_GRAPHIC_MODE) {
Ok(_) => {
CtrlRogBios::set_path_mutable(ASUS_SWITCH_GRAPHIC_MODE)?;
}
Err(err) => {
info!("ROG Switchable Graphics (bios) not detected: {}", err);
}
}
match CtrlRogBios::check_path_exists(ASUS_POST_LOGO_SOUND) {
Ok(_) => {
CtrlRogBios::set_path_mutable(ASUS_POST_LOGO_SOUND)?;
}
Err(err) => {
info!("ROG boot sound toggle (bios) not detected: {}", err);
}
}
Ok(CtrlRogBios { config })
}
fn set_path_mutable(path: &str) -> Result<(), RogError> {
use std::process::Command;
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 check_path_exists(path: &str) -> Result<(), RogError> {
if Path::new(path).exists() {
Ok(())
} else {
Err(RogError::MissingFunction(path.into()))
}
}
pub fn has_dedicated_gfx_toggle() -> bool {
if CtrlRogBios::check_path_exists(ASUS_SWITCH_GRAPHIC_MODE).is_ok() {
return true;
}
false
}
pub fn get_gfx_mode() -> Result<i8, RogError> {
let path = ASUS_SWITCH_GRAPHIC_MODE;
let mut file = OpenOptions::new()
.read(true)
.open(path)
.map_err(|err| RogError::Path(path.into(), err))?;
let mut data = Vec::new();
file.read_to_end(&mut data)
.map_err(|err| RogError::Read(path.into(), err))?;
let idx = data.len() - 1;
Ok(data[idx] as i8)
}
pub(super) fn set_gfx_mode(dedicated: bool) -> Result<(), RogError> {
let path = ASUS_SWITCH_GRAPHIC_MODE;
let mut file = OpenOptions::new()
.read(true)
.write(true)
.open(path)
.map_err(|err| RogError::Path(path.into(), err))?;
let mut data = Vec::new();
file.read_to_end(&mut data).unwrap();
let idx = data.len() - 1;
if dedicated {
data[idx] = 1;
info!("Set system-level graphics mode: Dedicated Nvidia");
} else {
data[idx] = 0;
info!("Set system-level graphics mode: Optimus");
}
file.write_all(&data)
.map_err(|err| RogError::Path(path.into(), err))?;
if let Ok(ded) = CtrlRogBios::get_gfx_mode() {
if let Ok(vendor) = CtrlGraphics::get_vendor() {
if ded == 1 && vendor != "nvidia" {
warn!("Dedicated GFX toggle is on but driver mode is not nvidia \nSetting to nvidia driver mode");
CtrlGraphics::set_gfx_config(GfxVendors::Nvidia)
.unwrap_or_else(|err| warn!("Gfx controller: {}", err));
}
}
}
Ok(())
}
pub fn get_boot_sound() -> Result<i8, RogError> {
let path = ASUS_POST_LOGO_SOUND;
let mut file = OpenOptions::new()
.read(true)
.open(path)
.map_err(|err| RogError::Path(path.into(), err))?;
let mut data = Vec::new();
file.read_to_end(&mut data)
.map_err(|err| RogError::Read(path.into(), err))?;
let idx = data.len() - 1;
Ok(data[idx] as i8)
}
pub(super) fn set_boot_sound(on: bool) -> Result<(), RogError> {
let path = ASUS_POST_LOGO_SOUND;
let mut file = OpenOptions::new()
.read(true)
.write(true)
.open(path)
.map_err(|err| RogError::Path(path.into(), err))?;
let mut data = Vec::new();
file.read_to_end(&mut data)
.map_err(|err| RogError::Read(path.into(), err))?;
let idx = data.len() - 1;
if on {
data[idx] = 1;
info!("Set boot POST sound on");
} else {
data[idx] = 0;
info!("Set boot POST sound off");
}
file.write_all(&data)
.map_err(|err| RogError::Path(path.into(), err))?;
Ok(())
}
}

View File

@@ -1,10 +1,14 @@
use ctrl_gfx::ctrl_gfx::CtrlGraphics;
use daemon::config::Config;
use daemon::ctrl_anime::CtrlAnimeDisplay;
use daemon::ctrl_charge::CtrlCharge; use daemon::ctrl_charge::CtrlCharge;
use daemon::ctrl_fan_cpu::{CtrlFanAndCPU, DbusFanAndCpu}; use daemon::ctrl_fan_cpu::{CtrlFanAndCPU, DbusFanAndCpu};
use daemon::ctrl_leds::{CtrlKbdBacklight, DbusKbdBacklight}; use daemon::ctrl_leds::{CtrlKbdBacklight, DbusKbdBacklight};
use daemon::laptops::match_laptop; use daemon::laptops::match_laptop;
use daemon::{
config::Config, laptops::print_board_info, supported::SupportedFunctions, GetSupported,
};
use daemon::{
ctrl_anime::CtrlAnimeDisplay,
ctrl_gfx::{gfx::CtrlGraphics, vendors::GfxVendors},
};
use asus_nb::DBUS_NAME; use asus_nb::DBUS_NAME;
use daemon::{CtrlTask, Reloadable, ZbusAdd}; use daemon::{CtrlTask, Reloadable, ZbusAdd};
@@ -15,6 +19,7 @@ use std::io::Write;
use std::sync::Arc; use std::sync::Arc;
use std::sync::Mutex; use std::sync::Mutex;
use daemon::ctrl_rog_bios::CtrlRogBios;
use std::convert::Into; use std::convert::Into;
use std::convert::TryInto; use std::convert::TryInto;
use zbus::fdo; use zbus::fdo;
@@ -40,14 +45,16 @@ pub fn main() -> Result<(), Box<dyn std::error::Error>> {
// - to maintain constant times of 1ms, per-key colours should use // - to maintain constant times of 1ms, per-key colours should use
// the effect endpoint so that the complete colour block is written // the effect endpoint so that the complete colour block is written
// as fast as 1ms per row of the matrix inside it. (10ms total time) // as fast as 1ms per row of the matrix inside it. (10ms total time)
//
// DBUS processing takes 6ms if not tokiod
fn start_daemon() -> Result<(), Box<dyn Error>> { fn start_daemon() -> Result<(), Box<dyn Error>> {
let supported = SupportedFunctions::get_supported();
print_board_info();
println!("{}", serde_json::to_string_pretty(&supported).unwrap());
let laptop = match_laptop(); let laptop = match_laptop();
let config = if let Some(laptop) = laptop.as_ref() { let config = if let Some(laptop) = laptop.as_ref() {
Config::default().load(laptop.supported_modes()) Config::load(laptop.supported_modes())
} else { } else {
Config::default().load(&[]) Config::load(&[])
}; };
let connection = Connection::new_system()?; let connection = Connection::new_system()?;
@@ -55,9 +62,24 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
.request_name(DBUS_NAME, fdo::RequestNameFlags::ReplaceExisting.into())?; .request_name(DBUS_NAME, fdo::RequestNameFlags::ReplaceExisting.into())?;
let mut object_server = zbus::ObjectServer::new(&connection); let mut object_server = zbus::ObjectServer::new(&connection);
supported.add_to_server(&mut object_server);
let enable_gfx_switching = config.gfx_managed; let enable_gfx_switching = config.gfx_managed;
let config = Arc::new(Mutex::new(config)); let config = Arc::new(Mutex::new(config));
match CtrlRogBios::new(config.clone()) {
Ok(mut ctrl) => {
// Do a reload of any settings
ctrl.reload()
.unwrap_or_else(|err| warn!("Battery charge limit: {}", err));
// Then register to dbus server
ctrl.add_to_server(&mut object_server);
}
Err(err) => {
error!("rog_bios_control: {}", err);
}
}
match CtrlCharge::new(config.clone()) { match CtrlCharge::new(config.clone()) {
Ok(mut ctrl) => { Ok(mut ctrl) => {
// Do a reload of any settings // Do a reload of any settings
@@ -81,10 +103,25 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
} }
if enable_gfx_switching { if enable_gfx_switching {
match CtrlGraphics::new() { match CtrlGraphics::new(config.clone()) {
Ok(mut ctrl) => { Ok(mut ctrl) => {
ctrl.reload() // Need to check if a laptop has the dedicated gfx switch
.unwrap_or_else(|err| warn!("Gfx controller: {}", err)); if CtrlRogBios::has_dedicated_gfx_toggle() {
if let Ok(ded) = CtrlRogBios::get_gfx_mode() {
if let Ok(vendor) = CtrlGraphics::get_vendor() {
if ded == 1 && vendor != "nvidia" {
error!("Dedicated GFX toggle is on but driver mode is not nvidia \nSetting to nvidia driver mode");
error!("You must reboot to enable Nvidia driver");
ctrl.set(GfxVendors::Nvidia)?;
} else if ded == 0 {
info!("Dedicated GFX toggle is off");
}
}
}
} else {
ctrl.reload()
.unwrap_or_else(|err| warn!("Gfx controller: {}", err));
}
ctrl.add_to_server(&mut object_server); ctrl.add_to_server(&mut object_server);
} }
Err(err) => { Err(err) => {

View File

@@ -20,6 +20,7 @@ pub enum RogError {
DoTask(String), DoTask(String),
MissingFunction(String), MissingFunction(String),
MissingLedBrightNode(String, std::io::Error), MissingLedBrightNode(String, std::io::Error),
ReloadFail(String),
} }
impl fmt::Display for RogError { impl fmt::Display for RogError {
@@ -41,6 +42,7 @@ impl fmt::Display for RogError {
RogError::DoTask(deets) => write!(f, "Task error: {}", deets), RogError::DoTask(deets) => write!(f, "Task error: {}", deets),
RogError::MissingFunction(deets) => write!(f, "Missing functionality: {}", deets), RogError::MissingFunction(deets) => write!(f, "Missing functionality: {}", deets),
RogError::MissingLedBrightNode(path, error) => write!(f, "Led node at {} is missing, please check you have the required patch or dkms module installed: {}", path, error), RogError::MissingLedBrightNode(path, error) => write!(f, "Led node at {} is missing, please check you have the required patch or dkms module installed: {}", path, error),
RogError::ReloadFail(deets) => write!(f, "Task error: {}", deets),
} }
} }
} }

View File

@@ -27,13 +27,12 @@ impl LaptopBase {
} }
pub fn match_laptop() -> Option<LaptopBase> { pub fn match_laptop() -> Option<LaptopBase> {
for device in rusb::devices().unwrap().iter() { for device in rusb::devices().expect("Failed here").iter() {
let device_desc = device.device_descriptor().unwrap(); let device_desc = device.device_descriptor().expect("Failed there");
if device_desc.vendor_id() == 0x0b05 { if device_desc.vendor_id() == 0x0b05 {
match device_desc.product_id() { match device_desc.product_id() {
0x1866 => { 0x1866 => {
let laptop = select_1866_device("1866".to_owned()); let laptop = select_1866_device("1866".to_owned());
print_modes(&laptop.supported_modes);
return Some(laptop); return Some(laptop);
} }
0x1869 => return Some(select_1866_device("1869".to_owned())), 0x1869 => return Some(select_1866_device("1869".to_owned())),
@@ -61,10 +60,6 @@ fn select_1866_device(prod: String) -> LaptopBase {
let dmi = sysfs_class::DmiId::default(); let dmi = sysfs_class::DmiId::default();
let board_name = dmi.board_name().expect("Could not get board_name"); let board_name = dmi.board_name().expect("Could not get board_name");
let prod_family = dmi.product_family().expect("Could not get product_family"); let prod_family = dmi.product_family().expect("Could not get product_family");
let prod_name = dmi.product_name().expect("Could not get product_name");
info!("Product name: {}", prod_name.trim());
info!("Board name: {}", board_name.trim());
let mut laptop = LaptopBase { let mut laptop = LaptopBase {
usb_product: prod, usb_product: prod,
@@ -81,7 +76,18 @@ fn select_1866_device(prod: String) -> LaptopBase {
laptop laptop
} }
fn print_modes(supported_modes: &[u8]) { pub fn print_board_info() {
let dmi = sysfs_class::DmiId::default();
let board_name = dmi.board_name().expect("Could not get board_name");
let prod_name = dmi.product_name().expect("Could not get product_name");
let prod_family = dmi.product_family().expect("Could not get product_family");
info!("Product name: {}", prod_name.trim());
info!("Product family: {}", prod_family.trim());
info!("Board name: {}", board_name.trim());
}
pub fn print_modes(supported_modes: &[u8]) {
if !supported_modes.is_empty() { if !supported_modes.is_empty() {
info!("Supported Keyboard LED modes are:"); info!("Supported Keyboard LED modes are:");
for mode in supported_modes { for mode in supported_modes {

View File

@@ -8,11 +8,17 @@ pub mod ctrl_charge;
/// ///
pub mod ctrl_fan_cpu; pub mod ctrl_fan_cpu;
/// ///
pub mod ctrl_leds; pub mod ctrl_gfx;
/// ///
pub mod ctrl_leds;
/// Control ASUS bios function such as boot sound, Optimus/Dedicated gfx mode
pub mod ctrl_rog_bios;
/// Laptop matching to determine capabilities /// Laptop matching to determine capabilities
pub mod laptops; pub mod laptops;
/// Fetch all supported functions for the laptop
pub mod supported;
mod error; mod error;
use crate::error::RogError; use crate::error::RogError;
@@ -38,3 +44,9 @@ pub trait CtrlTaskComplex {
fn do_task(&mut self, config: &mut Config, event: Self::A); fn do_task(&mut self, config: &mut Config, event: Self::A);
} }
pub trait GetSupported {
type A;
fn get_supported() -> Self::A;
}

View File

@@ -4,8 +4,7 @@ use asus_nb::{
core_dbus::AuraDbusClient, core_dbus::AuraDbusClient,
profile::{ProfileCommand, ProfileEvent}, profile::{ProfileCommand, ProfileEvent},
}; };
use ctrl_gfx::vendors::GfxVendors; use daemon::{ctrl_fan_cpu::FanLevel, ctrl_gfx::vendors::GfxVendors};
use daemon::ctrl_fan_cpu::FanLevel;
use gumdrop::{Opt, Options}; use gumdrop::{Opt, Options};
use log::LevelFilter; use log::LevelFilter;
use std::{env::args, io::Write, process::Command}; use std::{env::args, io::Write, process::Command};
@@ -18,11 +17,13 @@ struct CLIStart {
help: bool, help: bool,
#[options(help = "show program version number")] #[options(help = "show program version number")]
version: bool, version: bool,
#[options(meta = "VAL", help = "<off, low, med, high>")] #[options(help = "show supported functions of this laptop")]
show_supported: bool,
#[options(meta = "", help = "<off, low, med, high>")]
kbd_bright: Option<LedBrightness>, kbd_bright: Option<LedBrightness>,
#[options(meta = "PWR", help = "<silent, normal, boost>")] #[options(meta = "", help = "<silent, normal, boost>")]
pwr_profile: Option<FanLevel>, pwr_profile: Option<FanLevel>,
#[options(meta = "CHRG", help = "<20-100>")] #[options(meta = "", help = "<20-100>")]
chg_limit: Option<u8>, chg_limit: Option<u8>,
#[options(command)] #[options(command)]
command: Option<CliCommand>, command: Option<CliCommand>,
@@ -38,6 +39,8 @@ enum CliCommand {
Graphics(GraphicsCommand), Graphics(GraphicsCommand),
#[options(name = "anime", help = "Manage AniMe Matrix")] #[options(name = "anime", help = "Manage AniMe Matrix")]
AniMe(AniMeCommand), AniMe(AniMeCommand),
#[options(help = "Change bios settings")]
Bios(BiosCommand),
} }
#[derive(Options)] #[derive(Options)]
@@ -56,7 +59,10 @@ struct LedModeCommand {
struct GraphicsCommand { struct GraphicsCommand {
#[options(help = "print help message")] #[options(help = "print help message")]
help: bool, help: bool,
#[options(help = "Set graphics mode: <nvidia, hybrid, compute, integrated>")] #[options(
meta = "",
help = "Set graphics mode: <nvidia, hybrid, compute, integrated>"
)]
mode: Option<GfxVendors>, mode: Option<GfxVendors>,
#[options(help = "Get the current mode")] #[options(help = "Get the current mode")]
get: bool, get: bool,
@@ -70,14 +76,31 @@ struct GraphicsCommand {
struct AniMeCommand { struct AniMeCommand {
#[options(help = "print help message")] #[options(help = "print help message")]
help: bool, help: bool,
#[options(help = "turn on/off the panel (accept/reject write requests)")] #[options(
meta = "",
help = "turn on/off the panel (accept/reject write requests)"
)]
turn: Option<AniMeStatusValue>, turn: Option<AniMeStatusValue>,
#[options(help = "turn on/off the panel at boot (with Asus effect)")] #[options(meta = "", help = "turn on/off the panel at boot (with Asus effect)")]
boot: Option<AniMeStatusValue>, boot: Option<AniMeStatusValue>,
#[options(command)] #[options(command)]
command: Option<AniMeActions>, command: Option<AniMeActions>,
} }
#[derive(Options, Debug)]
struct BiosCommand {
#[options(help = "print help message")]
help: bool,
#[options(meta = "", no_long, help = "toggle bios POST sound")]
post_sound_set: Option<bool>,
#[options(no_long, help = "read bios POST sound")]
post_sound_get: bool,
#[options(meta = "", no_long, help = "toggle GPU to/from dedicated mode")]
dedicated_gfx_set: Option<bool>,
#[options(no_long, help = "get GPU mode")]
dedicated_gfx_get: bool,
}
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut logger = env_logger::Builder::new(); let mut logger = env_logger::Builder::new();
logger logger
@@ -117,78 +140,157 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Version: {}", daemon::VERSION); println!("Version: {}", daemon::VERSION);
} }
let writer = AuraDbusClient::new()?; let dbus_client = AuraDbusClient::new()?;
let anime_writer = AniMeDbusWriter::new()?; let anime_dbus_client = AniMeDbusWriter::new()?;
match parsed.command { match parsed.command {
Some(CliCommand::LedMode(mode)) => { Some(CliCommand::LedMode(mode)) => {
if (mode.command.is_none() && !mode.prev_mode && !mode.next_mode) || mode.help {
println!("Missing arg or command\n\n{}", mode.self_usage());
if let Some(lst) = mode.self_command_list() {
println!("\n{}", lst);
}
}
if mode.next_mode && mode.prev_mode { if mode.next_mode && mode.prev_mode {
println!("Please specify either next or previous") println!("Please specify either next or previous")
} }
if mode.next_mode { if mode.next_mode {
writer.next_keyboard_led_mode()?; dbus_client.next_keyboard_led_mode()?;
} else if mode.prev_mode { } else if mode.prev_mode {
writer.prev_keyboard_led_mode()?; dbus_client.prev_keyboard_led_mode()?;
} else if let Some(command) = mode.command { } else if let Some(command) = mode.command {
writer.write_builtin_mode(&command.into())? dbus_client.write_builtin_mode(&command.into())?
} }
} }
Some(CliCommand::Profile(command)) => { Some(CliCommand::Profile(cmd)) => {
if command.next { if (!cmd.next
writer.next_fan_profile()?; && !cmd.create
&& cmd.curve.is_none()
&& cmd.max_percentage.is_none()
&& cmd.min_percentage.is_none()
&& cmd.preset.is_none()
&& cmd.profile.is_none()
&& cmd.turbo.is_none())
|| cmd.help
{
println!("Missing arg or command\n\n{}", cmd.self_usage());
if let Some(lst) = cmd.self_command_list() {
println!("\n{}", lst);
}
}
if cmd.next {
dbus_client.next_fan_profile()?;
} else { } else {
writer.write_profile_command(&ProfileEvent::Cli(command))? dbus_client.write_profile_command(&ProfileEvent::Cli(cmd))?
} }
} }
Some(CliCommand::Graphics(command)) => do_gfx(command, &writer)?, Some(CliCommand::Graphics(cmd)) => do_gfx(cmd, &dbus_client)?,
Some(CliCommand::AniMe(anime)) => { Some(CliCommand::AniMe(cmd)) => {
if let Some(anime_turn) = anime.turn { if (cmd.command.is_none() && cmd.boot.is_none() && cmd.turn.is_none()) || cmd.help {
anime_writer.turn_on_off(anime_turn.into())? println!("Missing arg or command\n\n{}", cmd.self_usage());
if let Some(lst) = cmd.self_command_list() {
println!("\n{}", lst);
}
} }
if let Some(anime_boot) = anime.boot { if let Some(anime_turn) = cmd.turn {
anime_writer.turn_boot_on_off(anime_boot.into())? anime_dbus_client.turn_on_off(anime_turn.into())?
} }
if let Some(action) = anime.command { if let Some(anime_boot) = cmd.boot {
anime_dbus_client.turn_boot_on_off(anime_boot.into())?
}
if let Some(action) = cmd.command {
match action { match action {
AniMeActions::Leds(anime_leds) => { AniMeActions::Leds(anime_leds) => {
let led_brightness = anime_leds.led_brightness(); let led_brightness = anime_leds.led_brightness();
anime_writer.set_leds_brightness(led_brightness)?; anime_dbus_client.set_leds_brightness(led_brightness)?;
} }
} }
} }
} }
None => (), Some(CliCommand::Bios(cmd)) => {
if (cmd.dedicated_gfx_set.is_none()
&& !cmd.dedicated_gfx_get
&& cmd.post_sound_set.is_none()
&& !cmd.post_sound_get)
|| cmd.help
{
println!("Missing arg or command\n\n{}", cmd.self_usage());
if let Some(lst) = cmd.self_command_list() {
println!("\n{}", lst);
}
}
if let Some(opt) = cmd.post_sound_set {
dbus_client.set_bios_post_sound(opt)?;
}
if cmd.post_sound_get {
let res = if dbus_client.get_bios_post_sound()? == 1 {
true
} else {
false
};
println!("Bios POST sound on: {}", res);
}
if let Some(opt) = cmd.dedicated_gfx_set {
dbus_client.set_bios_dedicated_gfx(opt)?;
}
if cmd.dedicated_gfx_get {
let res = if dbus_client.get_bios_dedicated_gfx()? == 1 {
true
} else {
false
};
println!("Bios dedicated GPU on: {}", res);
}
}
None => {
if (!parsed.show_supported
&& parsed.kbd_bright.is_none()
&& parsed.pwr_profile.is_none()
&& parsed.chg_limit.is_none())
|| parsed.help
{
println!("{}", CLIStart::usage());
println!();
println!("{}", CLIStart::command_list().unwrap());
}
}
} }
if let Some(brightness) = parsed.kbd_bright { if let Some(brightness) = parsed.kbd_bright {
match brightness.level() { match brightness.level() {
None => { None => {
let level = writer.get_led_brightness()?; let level = dbus_client.get_led_brightness()?;
println!("Current keyboard led brightness: {}", level.to_string()); println!("Current keyboard led brightness: {}", level.to_string());
} }
Some(level) => writer.write_brightness(level)?, Some(level) => dbus_client.write_brightness(level)?,
} }
} }
if parsed.show_supported {
let dat = dbus_client.get_supported_functions()?;
println!("Supported laptop functions:\n{}", dat.to_string());
}
if let Some(fan_level) = parsed.pwr_profile { if let Some(fan_level) = parsed.pwr_profile {
writer.write_fan_mode(fan_level.into())?; dbus_client.write_fan_mode(fan_level.into())?;
} }
if let Some(chg_limit) = parsed.chg_limit { if let Some(chg_limit) = parsed.chg_limit {
writer.write_charge_limit(chg_limit)?; dbus_client.write_charge_limit(chg_limit)?;
} }
Ok(()) Ok(())
} }
fn do_gfx( fn do_gfx(
command: GraphicsCommand, command: GraphicsCommand,
writer: &AuraDbusClient, dbus_client: &AuraDbusClient,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
if let Some(mode) = command.mode { if let Some(mode) = command.mode {
println!("Updating settings, please wait..."); println!("Updating settings, please wait...");
println!("If this takes longer than 30s, ctrl+c then check `journalctl -b -u asusd`"); println!("If this takes longer than 30s, ctrl+c then check `journalctl -b -u asusd`");
writer.write_gfx_mode(mode)?; dbus_client.write_gfx_mode(<&str>::from(&mode).into())?;
let res = writer.wait_gfx_changed()?; let res = dbus_client.wait_gfx_changed()?;
match res.as_str() { match res.as_str() {
"reboot" => { "reboot" => {
println!( println!(
@@ -222,11 +324,11 @@ fn do_gfx(
std::process::exit(-1) std::process::exit(-1)
} }
if command.get { if command.get {
let res = writer.get_gfx_mode()?; let res = dbus_client.get_gfx_mode()?;
println!("Current graphics mode: {}", res); println!("Current graphics mode: {}", res);
} }
if command.pow { if command.pow {
let res = writer.get_gfx_pwr()?; let res = dbus_client.get_gfx_pwr()?;
if res.contains("active") { if res.contains("active") {
println!("Current power status: {}", Red.paint(&format!("{}", res))); println!("Current power status: {}", Red.paint(&format!("{}", res)));
} else { } else {

View File

@@ -0,0 +1,56 @@
use std::convert::TryInto;
use log::warn;
use serde_derive::{Deserialize, Serialize};
use zbus::dbus_interface;
use crate::{
ctrl_anime::{AnimeSupportedFunctions, CtrlAnimeDisplay},
ctrl_charge::{ChargeSupportedFunctions, CtrlCharge},
ctrl_fan_cpu::{CtrlFanAndCPU, FanCpuSupportedFunctions},
ctrl_leds::{CtrlKbdBacklight, LedSupportedFunctions},
ctrl_rog_bios::{CtrlRogBios, RogBiosSupportedFunctions},
GetSupported,
};
#[derive(Serialize, Deserialize)]
pub struct SupportedFunctions {
anime_ctrl: AnimeSupportedFunctions,
charge_ctrl: ChargeSupportedFunctions,
fan_cpu_ctrl: FanCpuSupportedFunctions,
keyboard_led: LedSupportedFunctions,
rog_bios_ctrl: RogBiosSupportedFunctions,
}
#[dbus_interface(name = "org.asuslinux.Daemon")]
impl SupportedFunctions {
fn supported_functions(&self) -> String {
serde_json::to_string_pretty(self).unwrap()
}
}
impl crate::ZbusAdd for SupportedFunctions {
fn add_to_server(self, server: &mut zbus::ObjectServer) {
server
.at(&"/org/asuslinux/Supported".try_into().unwrap(), self)
.map_err(|err| {
warn!("SupportedFunctions: add_to_server {}", err);
err
})
.ok();
}
}
impl GetSupported for SupportedFunctions {
type A = SupportedFunctions;
fn get_supported() -> Self::A {
SupportedFunctions {
keyboard_led: CtrlKbdBacklight::get_supported(),
anime_ctrl: CtrlAnimeDisplay::get_supported(),
charge_ctrl: CtrlCharge::get_supported(),
fan_cpu_ctrl: CtrlFanAndCPU::get_supported(),
rog_bios_ctrl: CtrlRogBios::get_supported(),
}
}
}

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "asus-nb" name = "asus-nb"
version = "2.1.2" version = "2.2.0"
license = "MPL-2.0" license = "MPL-2.0"
readme = "README.md" readme = "README.md"
authors = ["Luke <luke@ljones.dev>"] authors = ["Luke <luke@ljones.dev>"]
@@ -19,7 +19,6 @@ yansi-term = "^0.1"
rog_fan_curve = { version = "0.1", features = ["serde"] } rog_fan_curve = { version = "0.1", features = ["serde"] }
zbus = "^1.8.0" zbus = "^1.8.0"
zvariant = "^2.4.0" zvariant = "^2.4.0"
ctrl-gfx = { path = "../ctrl-gfx" }
[dev-dependencies] [dev-dependencies]
tinybmp = "^0.2.3" tinybmp = "^0.2.3"

View File

@@ -2,7 +2,6 @@ use super::*;
use crate::cli_options::LedBrightness; use crate::cli_options::LedBrightness;
use crate::fancy::KeyColourArray; use crate::fancy::KeyColourArray;
use crate::profile::ProfileEvent; use crate::profile::ProfileEvent;
use ctrl_gfx::vendors::GfxVendors;
use dbus::{blocking::Connection, Message}; use dbus::{blocking::Connection, Message};
use std::error::Error; use std::error::Error;
use std::sync::{ use std::sync::{
@@ -24,6 +23,8 @@ use crate::dbus_ledmode::{
use crate::dbus_profile::{ use crate::dbus_profile::{
OrgAsuslinuxDaemon as OrgAsuslinuxDaemonProfile, OrgAsuslinuxDaemonNotifyProfile, OrgAsuslinuxDaemon as OrgAsuslinuxDaemonProfile, OrgAsuslinuxDaemonNotifyProfile,
}; };
use crate::dbus_rogbios::OrgAsuslinuxDaemon as OrgAsuslinuxDaemonRogBios;
use crate::dbus_supported::OrgAsuslinuxDaemon as OrgAsuslinuxDaemonSupported;
// Signals separated out // Signals separated out
pub struct CtrlSignals { pub struct CtrlSignals {
@@ -278,13 +279,13 @@ impl AuraDbusClient {
} }
#[inline] #[inline]
pub fn write_gfx_mode(&self, vendor: GfxVendors) -> Result<(), Box<dyn std::error::Error>> { pub fn write_gfx_mode(&self, vendor: String) -> Result<(), Box<dyn std::error::Error>> {
let proxy = self.connection.with_proxy( let proxy = self.connection.with_proxy(
"org.asuslinux.Daemon", "org.asuslinux.Daemon",
"/org/asuslinux/Gfx", "/org/asuslinux/Gfx",
Duration::from_secs(30), Duration::from_secs(30),
); );
proxy.set_vendor(<&str>::from(&vendor))?; proxy.set_vendor(&vendor)?;
Ok(()) Ok(())
} }
@@ -358,4 +359,60 @@ impl AuraDbusClient {
self.write_keyboard_leds(&AuraModes::LedBrightness(level))?; self.write_keyboard_leds(&AuraModes::LedBrightness(level))?;
Ok(()) Ok(())
} }
//
#[inline]
pub fn get_bios_dedicated_gfx(&self) -> Result<i16, Box<dyn std::error::Error>> {
let proxy = self.connection.with_proxy(
"org.asuslinux.Daemon",
"/org/asuslinux/RogBios",
Duration::from_secs(2),
);
let x = proxy.dedicated_graphic_mode()?;
Ok(x)
}
#[inline]
pub fn set_bios_dedicated_gfx(&self, on: bool) -> Result<(), Box<dyn std::error::Error>> {
let proxy = self.connection.with_proxy(
"org.asuslinux.Daemon",
"/org/asuslinux/RogBios",
Duration::from_secs(2),
);
proxy.set_dedicated_graphic_mode(<bool>::from(on))?;
Ok(())
}
#[inline]
pub fn get_bios_post_sound(&self) -> Result<i16, Box<dyn std::error::Error>> {
let proxy = self.connection.with_proxy(
"org.asuslinux.Daemon",
"/org/asuslinux/RogBios",
Duration::from_secs(2),
);
let x = proxy.post_boot_sound()?;
Ok(x)
}
#[inline]
pub fn set_bios_post_sound(&self, on: bool) -> Result<(), Box<dyn std::error::Error>> {
let proxy = self.connection.with_proxy(
"org.asuslinux.Daemon",
"/org/asuslinux/RogBios",
Duration::from_secs(2),
);
proxy.set_post_boot_sound(<bool>::from(on))?;
Ok(())
}
#[inline]
pub fn get_supported_functions(&self) -> Result<String, Box<dyn std::error::Error>> {
let proxy = self.connection.with_proxy(
"org.asuslinux.Daemon",
"/org/asuslinux/Supported",
Duration::from_secs(2),
);
let x = proxy.supported_functions()?;
Ok(x)
}
} }

View File

@@ -0,0 +1,86 @@
// This code was autogenerated with `dbus-codegen-rust -s -d org.asuslinux.Daemon -f org.asuslinux.Daemon -c blocking -p /org/asuslinux/RogBios -m None -o asus-nb/src/dbus_rogbios.rs`, see https://github.com/diwic/dbus-rs
use dbus;
#[allow(unused_imports)]
use dbus::arg;
use dbus::blocking;
pub trait OrgAsuslinuxDaemon {
fn set_dedicated_graphic_mode(&self, dedicated: bool) -> Result<(), dbus::Error>;
fn dedicated_graphic_mode(&self) -> Result<i16, dbus::Error>;
fn set_post_boot_sound(&self, on: bool) -> Result<(), dbus::Error>;
fn post_boot_sound(&self) -> Result<i16, dbus::Error>;
}
impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target = T>> OrgAsuslinuxDaemon
for blocking::Proxy<'a, C>
{
fn set_dedicated_graphic_mode(&self, dedicated: bool) -> Result<(), dbus::Error> {
self.method_call(
"org.asuslinux.Daemon",
"SetDedicatedGraphicMode",
(dedicated,),
)
}
fn dedicated_graphic_mode(&self) -> Result<i16, dbus::Error> {
self.method_call("org.asuslinux.Daemon", "DedicatedGraphicMode", ())
.and_then(|r: (i16,)| Ok(r.0))
}
fn set_post_boot_sound(&self, on: bool) -> Result<(), dbus::Error> {
self.method_call("org.asuslinux.Daemon", "SetPostBootSound", (on,))
}
fn post_boot_sound(&self) -> Result<i16, dbus::Error> {
self.method_call("org.asuslinux.Daemon", "PostBootSound", ())
.and_then(|r: (i16,)| Ok(r.0))
}
}
#[derive(Debug)]
pub struct OrgAsuslinuxDaemonNotifyDedicatedGraphicMode {
pub dedicated: bool,
}
impl arg::AppendAll for OrgAsuslinuxDaemonNotifyDedicatedGraphicMode {
fn append(&self, i: &mut arg::IterAppend) {
arg::RefArg::append(&self.dedicated, i);
}
}
impl arg::ReadAll for OrgAsuslinuxDaemonNotifyDedicatedGraphicMode {
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
Ok(OrgAsuslinuxDaemonNotifyDedicatedGraphicMode {
dedicated: i.read()?,
})
}
}
impl dbus::message::SignalArgs for OrgAsuslinuxDaemonNotifyDedicatedGraphicMode {
const NAME: &'static str = "NotifyDedicatedGraphicMode";
const INTERFACE: &'static str = "org.asuslinux.Daemon";
}
#[derive(Debug)]
pub struct OrgAsuslinuxDaemonNotifyPostBootSound {
pub dedicated: bool,
}
impl arg::AppendAll for OrgAsuslinuxDaemonNotifyPostBootSound {
fn append(&self, i: &mut arg::IterAppend) {
arg::RefArg::append(&self.dedicated, i);
}
}
impl arg::ReadAll for OrgAsuslinuxDaemonNotifyPostBootSound {
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
Ok(OrgAsuslinuxDaemonNotifyPostBootSound {
dedicated: i.read()?,
})
}
}
impl dbus::message::SignalArgs for OrgAsuslinuxDaemonNotifyPostBootSound {
const NAME: &'static str = "NotifyPostBootSound";
const INTERFACE: &'static str = "org.asuslinux.Daemon";
}

View File

@@ -0,0 +1,18 @@
// This code was autogenerated with `dbus-codegen-rust -s -d org.asuslinux.Daemon -f org.asuslinux.Daemon -c blocking -p /org/asuslinux/Supported -m None -o asus-nb/src/dbus_supported.rs`, see https://github.com/diwic/dbus-rs
use dbus;
#[allow(unused_imports)]
use dbus::arg;
use dbus::blocking;
pub trait OrgAsuslinuxDaemon {
fn supported_functions(&self) -> Result<String, dbus::Error>;
}
impl<'a, T: blocking::BlockingSender, C: ::std::ops::Deref<Target = T>> OrgAsuslinuxDaemon
for blocking::Proxy<'a, C>
{
fn supported_functions(&self) -> Result<String, dbus::Error> {
self.method_call("org.asuslinux.Daemon", "SupportedFunctions", ())
.and_then(|r: (String,)| Ok(r.0))
}
}

View File

@@ -23,13 +23,15 @@ pub mod anime_dbus;
/// Helper functions for the AniMe display /// Helper functions for the AniMe display
pub mod anime_matrix; pub mod anime_matrix;
pub mod error;
pub mod dbus_anime; pub mod dbus_anime;
pub mod dbus_charge; pub mod dbus_charge;
pub mod dbus_gfx; pub mod dbus_gfx;
pub mod dbus_ledmode; pub mod dbus_ledmode;
pub mod dbus_profile; pub mod dbus_profile;
pub mod dbus_rogbios;
pub mod error; pub mod dbus_supported;
// static LED_INIT1: [u8; 2] = [0x5d, 0xb9]; // static LED_INIT1: [u8; 2] = [0x5d, 0xb9];
// static LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d // static LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d

View File

@@ -75,7 +75,7 @@ fn parse_fan_curve(data: &str) -> Result<Curve, String> {
#[derive(Debug, Clone, Options, Serialize, Deserialize)] #[derive(Debug, Clone, Options, Serialize, Deserialize)]
pub struct ProfileCommand { pub struct ProfileCommand {
#[options(help = "print help message")] #[options(help = "print help message")]
help: bool, pub help: bool,
#[options(help = "toggle to next profile in list")] #[options(help = "toggle to next profile in list")]
pub next: bool, pub next: bool,
#[options(help = "create the profile if it doesn't exist")] #[options(help = "create the profile if it doesn't exist")]

View File

@@ -1,19 +0,0 @@
[package]
name = "ctrl-gfx"
version = "2.1.4"
license = "MPL-2.0"
readme = "README.md"
authors = ["Luke <luke@ljones.dev>"]
description = "Fine control of laptop GPU"
edition = "2018"
[dependencies]
sysfs-class = "^0.1.2"
log = "^0.4"
zbus = { version = "1.8.0", optional = true }
zvariant = { version = "2.4.0", optional = true }
[features]
default = ["use-zbus"]
use-zbus = ["zbus", "zvariant"]