diff --git a/Cargo.lock b/Cargo.lock index 59f1b5a6..9667b281 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -75,20 +75,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" -[[package]] -name = "asus-notify" -version = "4.5.0-rc4" -dependencies = [ - "notify-rust", - "rog_aura", - "rog_dbus", - "rog_platform", - "rog_profiles", - "serde_json", - "smol", - "zbus 3.4.0", -] - [[package]] name = "asusctl" version = "4.5.0-rc4" diff --git a/Cargo.toml b/Cargo.toml index d3a8981b..34050bca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["asusctl", "asus-notify", "daemon", "daemon-user", "rog-platform", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center"] +members = ["asusctl", "daemon", "daemon-user", "rog-platform", "rog-dbus", "rog-anime", "rog-aura", "rog-profiles", "rog-control-center"] [workspace.package] version = "4.5.0-rc4" diff --git a/Makefile b/Makefile index e97a242c..aec1bcf1 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,6 @@ BIN_ROG := rog-control-center BIN_C := asusctl BIN_D := asusd BIN_U := asusd-user -BIN_N := asus-notify LEDCFG := asusd-ledmodes.toml SRC := Cargo.toml Cargo.lock Makefile $(shell find -type f -wholename '**/src/*.rs') @@ -48,14 +47,12 @@ install: $(INSTALL_PROGRAM) "./target/release/$(BIN_C)" "$(DESTDIR)$(bindir)/$(BIN_C)" $(INSTALL_PROGRAM) "./target/release/$(BIN_D)" "$(DESTDIR)$(bindir)/$(BIN_D)" $(INSTALL_PROGRAM) "./target/release/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)" - $(INSTALL_PROGRAM) "./target/release/$(BIN_N)" "$(DESTDIR)$(bindir)/$(BIN_N)" $(INSTALL_DATA) "./data/$(BIN_D).rules" "$(DESTDIR)$(libdir)/udev/rules.d/99-$(BIN_D).rules" $(INSTALL_DATA) "./data/$(LEDCFG)" "$(DESTDIR)/etc/asusd/$(LEDCFG)" $(INSTALL_DATA) "./data/$(BIN_D).conf" "$(DESTDIR)$(datarootdir)/dbus-1/system.d/$(BIN_D).conf" $(INSTALL_DATA) "./data/$(BIN_D).service" "$(DESTDIR)$(libdir)/systemd/system/$(BIN_D).service" - $(INSTALL_DATA) "./data/$(BIN_N).service" "$(DESTDIR)$(libdir)/systemd/user/$(BIN_N).service" $(INSTALL_DATA) "./data/$(BIN_U).service" "$(DESTDIR)$(libdir)/systemd/user/$(BIN_U).service" $(INSTALL_DATA) "./data/icons/asus_notif_yellow.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_yellow.png" @@ -78,12 +75,10 @@ uninstall: rm -f "$(DESTDIR)$(bindir)/$(BIN_C)" rm -f "$(DESTDIR)$(bindir)/$(BIN_D)" - rm -f "$(DESTDIR)$(bindir)/$(BIN_N)" rm -f "$(DESTDIR)$(libdir)/udev/rules.d/99-$(BIN_D).rules" rm -f "$(DESTDIR)/etc/asusd/$(LEDCFG)" rm -f "$(DESTDIR)$(datarootdir)/dbus-1/system.d/$(BIN_D).conf" rm -f "$(DESTDIR)$(libdir)/systemd/system/$(BIN_D).service" - rm -r "$(DESTDIR)$(libdir)/systemd/user/$(BIN_N).service" rm -r "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_yellow.png" rm -r "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_green.png" rm -r "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_red.png" @@ -117,7 +112,6 @@ endif strip -s ./target/release/$(BIN_C) strip -s ./target/release/$(BIN_D) strip -s ./target/release/$(BIN_U) - strip -s ./target/release/$(BIN_N) strip -s ./target/release/$(BIN_ROG) .PHONY: all clean distclean install uninstall update build diff --git a/asus-notify/Cargo.toml b/asus-notify/Cargo.toml deleted file mode 100644 index 4c0b8768..00000000 --- a/asus-notify/Cargo.toml +++ /dev/null @@ -1,16 +0,0 @@ -[package] -name = "asus-notify" -version.workspace = true -authors = ["Luke D Jones "] -edition = "2021" - -[dependencies] -zbus.workspace = true -# serialisation -serde_json.workspace = true -rog_dbus = { path = "../rog-dbus" } -rog_aura = { path = "../rog-aura" } -rog_platform = { path = "../rog-platform" } -rog_profiles = { path = "../rog-profiles" } -smol.workspace = true -notify-rust.workspace = true \ No newline at end of file diff --git a/asus-notify/src/main.rs b/asus-notify/src/main.rs deleted file mode 100644 index 490b0b95..00000000 --- a/asus-notify/src/main.rs +++ /dev/null @@ -1,166 +0,0 @@ -use notify_rust::{Hint, Notification, NotificationHandle}; -use rog_aura::AuraEffect; -use rog_dbus::{ - zbus_led::LedProxy, zbus_platform::RogBiosProxy, zbus_power::PowerProxy, - zbus_profile::ProfileProxy, -}; -use rog_profiles::Profile; -use smol::{future, Executor}; -use std::{ - error::Error, - sync::{Arc, Mutex}, -}; -use zbus::export::futures_util::StreamExt; - -const NOTIF_HEADER: &str = "ROG Control"; - -macro_rules! notify { - ($notifier:ident, $last_notif:ident, $data:expr) => { - if let Some(notif) = $last_notif.take() { - notif.close(); - } - if let Ok(x) = $notifier($data) { - $last_notif.replace(x); - } - }; -} - -macro_rules! base_notification { - ($body:expr) => { - Notification::new() - .summary(NOTIF_HEADER) - .body($body) - .timeout(2000) - .show() - }; -} - -type SharedHandle = Arc>>; - -fn main() -> Result<(), Box> { - println!("asus-notify version {}", env!("CARGO_PKG_VERSION")); - println!(" rog-dbus version {}", rog_dbus::VERSION); - - let last_notification: SharedHandle = Arc::new(Mutex::new(None)); - - let executor = Executor::new(); - // BIOS notif - let x = last_notification.clone(); - executor - .spawn(async move { - let conn = zbus::Connection::system().await.unwrap(); - let proxy = RogBiosProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_notify_post_boot_sound().await { - p.for_each(|e| { - if let Ok(out) = e.args() { - if let Ok(ref mut lock) = x.try_lock() { - notify!(do_post_sound_notif, lock, out.on()); - } - } - future::ready(()) - }) - .await; - }; - }) - .detach(); - - // Charge notif - let x = last_notification.clone(); - executor - .spawn(async move { - let conn = zbus::Connection::system().await.unwrap(); - let proxy = PowerProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_notify_charge_control_end_threshold().await { - p.for_each(|e| { - if let Ok(out) = e.args() { - if let Ok(ref mut lock) = x.try_lock() { - notify!(do_charge_notif, lock, &out.limit); - } - } - future::ready(()) - }) - .await; - }; - }) - .detach(); - - // Profile notif - let x = last_notification.clone(); - executor - .spawn(async move { - let conn = zbus::Connection::system().await.unwrap(); - let proxy = ProfileProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_notify_profile().await { - p.for_each(|e| { - if let Ok(out) = e.args() { - if let Ok(ref mut lock) = x.try_lock() { - notify!(do_thermal_notif, lock, &out.profile); - } - } - future::ready(()) - }) - .await; - }; - }) - .detach(); - - // LED notif - executor - .spawn(async move { - let conn = zbus::Connection::system().await.unwrap(); - let proxy = LedProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_notify_led().await { - p.for_each(|e| { - if let Ok(out) = e.args() { - if let Ok(ref mut lock) = last_notification.try_lock() { - notify!(do_led_notif, lock, &out.data); - } - } - future::ready(()) - }) - .await; - }; - }) - .detach(); - - loop { - smol::block_on(executor.tick()); - } -} - -fn do_thermal_notif(profile: &Profile) -> Result> { - let icon = match profile { - Profile::Balanced => "asus_notif_yellow", - Profile::Performance => "asus_notif_red", - Profile::Quiet => "asus_notif_green", - }; - let profile: &str = (*profile).into(); - let x = Notification::new() - .summary("ASUS ROG") - .body(&format!( - "Thermal profile changed to {}", - profile.to_uppercase(), - )) - .hint(Hint::Resident(true)) - .timeout(2000) - .hint(Hint::Category("device".into())) - //.hint(Hint::Transient(true)) - .icon(icon) - .show()?; - Ok(x) -} - -fn do_led_notif(ledmode: &AuraEffect) -> Result { - base_notification!(&format!( - "Keyboard LED mode changed to {}", - ledmode.mode_name() - )) -} - -fn do_charge_notif(limit: &u8) -> Result { - base_notification!(&format!("Battery charge limit changed to {}", limit)) -} - -fn do_post_sound_notif(on: &bool) -> Result { - base_notification!(&format!("BIOS Post sound {}", on)) -} diff --git a/data/asus-notify.service b/data/asus-notify.service deleted file mode 100644 index 076c8c4a..00000000 --- a/data/asus-notify.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description=ASUS Notifications -StartLimitInterval=200 -StartLimitBurst=2 - -[Service] -ExecStartPre=/usr/bin/sleep 2 -ExecStart=/usr/bin/asus-notify -Restart=on-failure -RestartSec=1 -Type=simple - -[Install] -WantedBy=default.target \ No newline at end of file diff --git a/rog-control-center/src/notify.rs b/rog-control-center/src/notify.rs index fa116838..871ecd19 100644 --- a/rog-control-center/src/notify.rs +++ b/rog-control-center/src/notify.rs @@ -6,7 +6,6 @@ use rog_dbus::{ use rog_profiles::Profile; use smol::{future, Executor}; use std::{ - error::Error, fmt::Display, sync::{ atomic::{AtomicBool, Ordering}, @@ -30,6 +29,43 @@ macro_rules! notify { }; } +macro_rules! recv_notif { + ($executor:ident, + $proxy:ident, + $signal:ident, + $was_notified:ident, + $last_notif:ident, + $notif_enabled:ident, + [$($out_arg:ident)+], + $msg:literal, + $notifier:ident) => { + let last_notif = $last_notif.clone(); + let notifs_enabled1 = $notif_enabled.clone(); + let notified = $was_notified.clone(); + // TODO: make a macro or generic function or something... + $executor + .spawn(async move { + let conn = zbus::Connection::system().await.unwrap(); + let proxy = $proxy::new(&conn).await.unwrap(); + if let Ok(p) = proxy.$signal().await { + p.for_each(|e| { + if let Ok(out) = e.args() { + if notifs_enabled1.load(Ordering::SeqCst) { + if let Ok(ref mut lock) = last_notif.try_lock() { + notify!($notifier($msg, &out$(.$out_arg)+()), lock); + } + } + notified.store(true, Ordering::SeqCst); + } + future::ready(()) + }) + .await; + }; + }) + .detach(); + }; +} + type SharedHandle = Arc>>; pub fn start_notifications( @@ -45,24 +81,127 @@ pub fn start_notifications( let executor = Executor::new(); // BIOS notif - let last_notif = last_notification.clone(); - let notifs_enabled1 = notifs_enabled.clone(); - let bios_notified1 = bios_notified.clone(); - // TODO: make a macro or generic function or something... + recv_notif!( + executor, + RogBiosProxy, + receive_notify_post_boot_sound, + bios_notified, + last_notification, + notifs_enabled, + [on], + "BIOS Post sound", + do_notification + ); + + recv_notif!( + executor, + RogBiosProxy, + receive_notify_panel_od, + bios_notified, + last_notification, + notifs_enabled, + [overdrive], + "BIOS Panel Overdrive", + do_notification + ); + + recv_notif!( + executor, + RogBiosProxy, + receive_notify_dgpu_disable, + bios_notified, + last_notification, + notifs_enabled, + [disable], + "BIOS dGPU disabled", + do_notification + ); + + recv_notif!( + executor, + RogBiosProxy, + receive_notify_egpu_enable, + bios_notified, + last_notification, + notifs_enabled, + [enable], + "BIOS eGPU enabled", + do_notification + ); + + recv_notif!( + executor, + RogBiosProxy, + receive_notify_gpu_mux_mode, + bios_notified, + last_notification, + notifs_enabled, + [mode], + "BIOS GPU MUX mode (reboot required)", + do_notification + ); + + // Charge notif + recv_notif!( + executor, + PowerProxy, + receive_notify_charge_control_end_threshold, + charge_notified, + last_notification, + notifs_enabled, + [limit], + "Battery charge limit changed to", + do_notification + ); + + // Profile notif + recv_notif!( + executor, + ProfileProxy, + receive_notify_profile, + profiles_notified, + last_notification, + notifs_enabled, + [profile], + "Profile changed to", + do_thermal_notif + ); + // notify!(do_thermal_notif(&out.profile), lock); + + // LED notif + recv_notif!( + executor, + LedProxy, + receive_notify_led, + aura_notified, + last_notification, + notifs_enabled, + [data mode_name], + "Keyboard LED mode changed to", + do_notification + ); + executor .spawn(async move { let conn = zbus::Connection::system().await.unwrap(); - let proxy = RogBiosProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_notify_post_boot_sound().await { - p.for_each(|e| { - if let Ok(out) = e.args() { - if notifs_enabled1.load(Ordering::SeqCst) { - if let Ok(ref mut lock) = last_notif.try_lock() { - notify!(do_notification("BIOS Post sound", &out.on()), lock); - } - } - bios_notified1.store(true, Ordering::SeqCst); - } + let proxy = LedProxy::new(&conn).await.unwrap(); + if let Ok(p) = proxy.receive_all_signals().await { + p.for_each(|_| { + aura_notified.store(true, Ordering::SeqCst); + future::ready(()) + }) + .await; + }; + }) + .detach(); + + executor + .spawn(async move { + let conn = zbus::Connection::system().await.unwrap(); + let proxy = AnimeProxy::new(&conn).await.unwrap(); + if let Ok(p) = proxy.receive_power_states().await { + p.for_each(|_| { + anime_notified.store(true, Ordering::SeqCst); future::ready(()) }) .await; @@ -106,197 +245,28 @@ pub fn start_notifications( }) .detach(); - let bios_notified1 = bios_notified.clone(); - executor - .spawn(async move { - let conn = zbus::Connection::system().await.unwrap(); - let proxy = RogBiosProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_notify_panel_od().await { - p.for_each(|_| { - bios_notified1.store(true, Ordering::SeqCst); - future::ready(()) - }) - .await; - }; - }) - .detach(); - - let bios_notified1 = bios_notified.clone(); - executor - .spawn(async move { - let conn = zbus::Connection::system().await.unwrap(); - let proxy = RogBiosProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_notify_dgpu_disable().await { - p.for_each(|_| { - bios_notified1.store(true, Ordering::SeqCst); - future::ready(()) - }) - .await; - }; - }) - .detach(); - - let bios_notified1 = bios_notified.clone(); - executor - .spawn(async move { - let conn = zbus::Connection::system().await.unwrap(); - let proxy = RogBiosProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_notify_egpu_enable().await { - p.for_each(|_| { - bios_notified1.store(true, Ordering::SeqCst); - future::ready(()) - }) - .await; - }; - }) - .detach(); - - let bios_notified1 = bios_notified; - executor - .spawn(async move { - let conn = zbus::Connection::system().await.unwrap(); - let proxy = RogBiosProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_notify_gpu_mux_mode().await { - p.for_each(|_| { - bios_notified1.store(true, Ordering::SeqCst); - future::ready(()) - }) - .await; - }; - }) - .detach(); - - // Charge notif - let last_notif = last_notification.clone(); - let notifs_enabled1 = notifs_enabled.clone(); - executor - .spawn(async move { - let conn = zbus::Connection::system().await.unwrap(); - let proxy = PowerProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_notify_charge_control_end_threshold().await { - p.for_each(|e| { - if let Ok(out) = e.args() { - if notifs_enabled1.load(Ordering::SeqCst) { - if let Ok(ref mut lock) = last_notif.try_lock() { - notify!( - do_notification("Battery charge limit changed to", &out.limit), - lock - ); - } - } - charge_notified.store(true, Ordering::SeqCst); - } - future::ready(()) - }) - .await; - }; - }) - .detach(); - - // Profile notif - let last_notif = last_notification.clone(); - let notifs_enabled1 = notifs_enabled.clone(); - executor - .spawn(async move { - let conn = zbus::Connection::system().await.unwrap(); - let proxy = ProfileProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_notify_profile().await { - p.for_each(|e| { - if let Ok(out) = e.args() { - if notifs_enabled1.load(Ordering::SeqCst) { - if let Ok(ref mut lock) = last_notif.try_lock() { - notify!(do_thermal_notif(&out.profile), lock); - } - } - profiles_notified.store(true, Ordering::SeqCst); - } - future::ready(()) - }) - .await; - }; - }) - .detach(); - - // LED notif - let last_notif = last_notification; - let aura_notif = aura_notified.clone(); - let notifs_enabled1 = notifs_enabled; - executor - .spawn(async move { - let conn = zbus::Connection::system().await.unwrap(); - let proxy = LedProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_notify_led().await { - p.for_each(|e| { - if let Ok(out) = e.args() { - if notifs_enabled1.load(Ordering::SeqCst) { - if let Ok(ref mut lock) = last_notif.try_lock() { - notify!( - do_notification( - "Keyboard LED mode changed to", - &out.data.mode_name() - ), - lock - ); - } - } - aura_notif.store(true, Ordering::SeqCst); - } - future::ready(()) - }) - .await; - }; - }) - .detach(); - - let aura_notif = aura_notified.clone(); - executor - .spawn(async move { - let conn = zbus::Connection::system().await.unwrap(); - let proxy = LedProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_notify_led().await { - p.for_each(|_| { - aura_notif.store(true, Ordering::SeqCst); - future::ready(()) - }) - .await; - }; - }) - .detach(); - - executor - .spawn(async move { - let conn = zbus::Connection::system().await.unwrap(); - let proxy = LedProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_all_signals().await { - p.for_each(|_| { - aura_notified.store(true, Ordering::SeqCst); - future::ready(()) - }) - .await; - }; - }) - .detach(); - - executor - .spawn(async move { - let conn = zbus::Connection::system().await.unwrap(); - let proxy = AnimeProxy::new(&conn).await.unwrap(); - if let Ok(p) = proxy.receive_power_states().await { - p.for_each(|_| { - anime_notified.store(true, Ordering::SeqCst); - future::ready(()) - }) - .await; - }; - }) - .detach(); - spawn(move || loop { smol::block_on(executor.tick()); }); Ok(()) } +fn base_notification(message: &str, data: &T) -> Notification +where + T: Display, +{ + let mut notif = Notification::new(); + + notif + .summary(NOTIF_HEADER) + .body(&format!("{message} {data}")) + .timeout(2000) + .hint(Hint::Resident(true)) + .hint(Hint::Category("device".into())); + + notif +} + fn do_notification( message: &str, data: &T, @@ -304,31 +274,19 @@ fn do_notification( where T: Display, { - Notification::new() - .summary(NOTIF_HEADER) - .body(&format!("{message} {data}")) - .timeout(2000) - .show() + base_notification(message, data).show() } -fn do_thermal_notif(profile: &Profile) -> Result> { +fn do_thermal_notif( + message: &str, + profile: &Profile, +) -> Result { let icon = match profile { Profile::Balanced => "asus_notif_yellow", Profile::Performance => "asus_notif_red", Profile::Quiet => "asus_notif_green", }; let profile: &str = (*profile).into(); - let x = Notification::new() - .summary("ASUS ROG") - .body(&format!( - "Thermal profile changed to {}", - profile.to_uppercase(), - )) - .hint(Hint::Resident(true)) - .timeout(2000) - .hint(Hint::Category("device".into())) - //.hint(Hint::Transient(true)) - .icon(icon) - .show()?; - Ok(x) + let mut notif = base_notification(message, &profile.to_uppercase()); + notif.icon(icon).show() } diff --git a/rog-platform/src/platform.rs b/rog-platform/src/platform.rs index ef2fe085..96aa44bf 100644 --- a/rog-platform/src/platform.rs +++ b/rog-platform/src/platform.rs @@ -1,4 +1,4 @@ -use std::{path::PathBuf, str::FromStr}; +use std::{fmt::Display, path::PathBuf, str::FromStr}; use log::{info, warn}; use serde::{Deserialize, Serialize}; @@ -121,3 +121,16 @@ impl GpuMode { Self::Optimus } } + +impl Display for GpuMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + GpuMode::Discrete => write!(f, "Discrete"), + GpuMode::Optimus => write!(f, "Optimus"), + GpuMode::Integrated => write!(f, "Integrated"), + GpuMode::Egpu => write!(f, "eGPU"), + GpuMode::Error => write!(f, "Error"), + GpuMode::NotSupported => write!(f, "Not Supported"), + } + } +} diff --git a/rog-profiles/src/lib.rs b/rog-profiles/src/lib.rs index 23df403c..ee0bd026 100644 --- a/rog-profiles/src/lib.rs +++ b/rog-profiles/src/lib.rs @@ -2,6 +2,7 @@ pub mod error; pub mod fan_curve_set; use std::{ + fmt::Display, fs::OpenOptions, io::{Read, Write}, path::Path, @@ -113,6 +114,12 @@ impl std::str::FromStr for Profile { } } +impl Display for Profile { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + #[cfg_attr(feature = "dbus", derive(Type))] #[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone, Copy)] pub enum FanCurvePU {