diff --git a/Cargo.lock b/Cargo.lock index 1c89b48e..45f268dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,6 +40,7 @@ dependencies = [ "rog_types", "serde_json", "supergfxctl", + "zbus", ] [[package]] @@ -57,7 +58,7 @@ dependencies = [ "rog_types", "supergfxctl", "tinybmp", - "yansi-term", + "zbus", ] [[package]] @@ -221,7 +222,6 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "supergfxctl", "sysfs-class", "toml", "udev", @@ -1070,6 +1070,8 @@ dependencies = [ name = "supergfxctl" version = "1.1.0" dependencies = [ + "env_logger", + "gumdrop", "log", "logind-zbus", "serde", @@ -1314,15 +1316,6 @@ dependencies = [ "bitflags 0.9.1", ] -[[package]] -name = "yansi-term" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1" -dependencies = [ - "winapi", -] - [[package]] name = "zbus" version = "1.9.1" diff --git a/Makefile b/Makefile index 0125072d..190d4f8a 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,8 @@ BIN_C := asusctl BIN_D := asusd BIN_U := asusd-user BIN_N := asus-notify +BIN_SD := supergfxd +BIN_SC := supergfxctl LEDCFG := asusd-ledmodes.toml X11CFG := 90-nvidia-screen-G05.conf PMRULES := 90-asusd-nvidia-pm.rules @@ -45,14 +47,15 @@ install: $(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/$(PMRULES)" "$(DESTDIR)$(libdir)/udev/rules.d/$(PMRULES)" + $(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/$(X11CFG)" "$(DESTDIR)$(datarootdir)/X11/xorg.conf.d/$(X11CFG)" + $(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" $(INSTALL_DATA) "./data/icons/asus_notif_green.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_green.png" $(INSTALL_DATA) "./data/icons/asus_notif_red.png" "$(DESTDIR)$(datarootdir)/icons/hicolor/512x512/apps/asus_notif_red.png" @@ -63,10 +66,18 @@ install: $(INSTALL_DATA) "./data/icons/scalable/gpu-nvidia.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-nvidia.svg" $(INSTALL_DATA) "./data/icons/scalable/gpu-vfio.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/gpu-vfio.svg" $(INSTALL_DATA) "./data/icons/scalable/notification-reboot.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/notification-reboot.svg" + $(INSTALL_DATA) "./data/_asusctl" "$(DESTDIR)$(zshcpl)/_asusctl" $(INSTALL_DATA) "./data/completions/asusctl.fish" "$(DESTDIR)$(datarootdir)/fish/vendor_completions.d/asusctl.fish" cd data && find "./anime" -type f -exec install -Dm 755 "{}" "$(DESTDIR)$(datarootdir)/asusd/{}" \; + $(INSTALL_PROGRAM) "./target/release/$(BIN_SD)" "$(DESTDIR)$(bindir)/$(BIN_SD)" + $(INSTALL_PROGRAM) "./target/release/$(BIN_SC)" "$(DESTDIR)$(bindir)/$(BIN_SC)" + $(INSTALL_DATA) "./supergfx/data/$(BIN_SD).service" "$(DESTDIR)$(libdir)/systemd/system/$(BIN_SD).service" + $(INSTALL_DATA) "./supergfx/data/org.supergfxctl.Daemon.conf" "$(DESTDIR)$(datarootdir)/dbus-1/system.d/org.supergfxctl.Daemon.conf" + $(INSTALL_DATA) "./supergfx/data/$(X11CFG)" "$(DESTDIR)$(datarootdir)/X11/xorg.conf.d/$(X11CFG)" + $(INSTALL_DATA) "./supergfx/data/$(PMRULES)" "$(DESTDIR)$(libdir)/udev/rules.d/$(PMRULES)" + uninstall: rm -f "$(DESTDIR)$(bindir)/$(BIN_C)" rm -f "$(DESTDIR)$(bindir)/$(BIN_D)" @@ -90,6 +101,10 @@ uninstall: rm -f "$(DESTDIR)$(zshcpl)/_asusctl" rm -f "$(DESTDIR)$(datarootdir)/fish/vendor_completions.d/asusctl.fish" rm -rf "$(DESTDIR)$(datarootdir)/asusd" + rm -f "$(DESTDIR)$(bindir)/$(BIN_SC)" + rm -f "$(DESTDIR)$(bindir)/$(BIN_SD)" + rm -f "$(DESTDIR)$(libdir)/systemd/system/$(BIN_SD).service" + rm -f "$(DESTDIR)$(datarootdir)/dbus-1/system.d/org.supergfxctl.Daemon.conf" update: cargo update diff --git a/asus-notify/Cargo.toml b/asus-notify/Cargo.toml index 7f5bc0f6..a4d6d103 100644 --- a/asus-notify/Cargo.toml +++ b/asus-notify/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +zbus = "^1.9" # serialisation serde_json = "^1.0" rog_dbus = { path = "../rog-dbus" } diff --git a/asus-notify/src/main.rs b/asus-notify/src/main.rs index e36c75f8..bb3593bd 100644 --- a/asus-notify/src/main.rs +++ b/asus-notify/src/main.rs @@ -2,11 +2,14 @@ use notify_rust::{Hint, Notification, NotificationHandle}; use rog_aura::AuraEffect; use rog_dbus::{DbusProxies, Signals}; use rog_profiles::Profile; -use supergfxctl::gfx_vendors::{GfxRequiredUserAction, GfxVendors}; use std::error::Error; -use std::process; +use std::sync::mpsc::channel; use std::thread::sleep; use std::time::Duration; +use std::{process, thread}; +use supergfxctl::gfx_vendors::{GfxRequiredUserAction, GfxVendors}; +use supergfxctl::zbus_proxy::GfxProxy; +use zbus::Connection; const NOTIF_HEADER: &str = "ROG Control"; @@ -42,6 +45,9 @@ fn main() -> Result<(), Box> { let recv = proxies.setup_recv(conn); let mut err_count = 0; + + gfx_thread()?; + loop { sleep(Duration::from_millis(100)); if let Err(err) = recv.next_signal() { @@ -67,23 +73,57 @@ fn main() -> Result<(), Box> { if let Ok(data) = signals.charge.try_recv() { notify!(do_charge_notif, last_notification, &data); } - if let Ok(data) = signals.gfx_vendor.try_recv() { + } +} + +fn gfx_thread() -> Result<(), Box> { + let mut last_notification: Option = None; + + let conn = Connection::new_system()?; + let proxy = GfxProxy::new(&conn)?; + + let (tx1, rx1) = channel(); + proxy.connect_notify_gfx(tx1)?; + + let (tx2, rx2) = channel(); + proxy.connect_notify_action(tx2)?; + + thread::spawn(move || loop { + if proxy + .next_signal() + .map_err(|e| println!("Error: {}", e)) + .is_err() + { + break; + } + + if let Ok(data) = rx1.try_recv() { notify!(do_gfx_notif, last_notification, &data); } - if let Ok(data) = signals.gfx_action.try_recv() { + + if let Ok(data) = rx2.try_recv() { match data { GfxRequiredUserAction::Logout | GfxRequiredUserAction::Reboot => { - do_gfx_action_notif(&data)?; + do_gfx_action_notif(&data) + .map_err(|e| { + println!("Error: {}", e); + }) + .ok(); } GfxRequiredUserAction::Integrated => { base_notification!( "You must be in integrated mode first to switch to the requested mode" - )?; + ) + .map_err(|e| { + println!("Error: {}", e); + }) + .ok(); } GfxRequiredUserAction::None => {} } } - } + }); + Ok(()) } fn do_thermal_notif(profile: &Profile) -> Result> { diff --git a/asusctl/Cargo.toml b/asusctl/Cargo.toml index 1e1cce13..3c182768 100644 --- a/asusctl/Cargo.toml +++ b/asusctl/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +zbus = "^1.9.1" rog_anime = { path = "../rog-anime" } rog_aura = { path = "../rog-aura" } rog_dbus = { path = "../rog-dbus" } @@ -14,7 +15,6 @@ rog_profiles = { path = "../rog-profiles" } rog_types = { path = "../rog-types" } daemon = { path = "../daemon" } gumdrop = "^0.8" -yansi-term = "^0.1" supergfxctl = { path = "../supergfx" } [dev-dependencies] diff --git a/asusctl/src/main.rs b/asusctl/src/main.rs index bdfc6ca8..448f04fd 100644 --- a/asusctl/src/main.rs +++ b/asusctl/src/main.rs @@ -9,16 +9,17 @@ use profiles_cli::ProfileCommand; use rog_anime::{AnimeDataBuffer, AnimeImage, Vec2, ANIME_DATA_LEN}; use rog_aura::{self, AuraEffect}; use rog_dbus::RogDbusClient; -use rog_types::{ - supported::{ - AnimeSupportedFunctions, LedSupportedFunctions, PlatformProfileFunctions, - RogBiosSupportedFunctions, - }, +use rog_types::supported::{ + AnimeSupportedFunctions, LedSupportedFunctions, PlatformProfileFunctions, + RogBiosSupportedFunctions, }; -use supergfxctl::gfx_vendors::{GfxPower, GfxRequiredUserAction, GfxVendors}; -use std::{env::args, path::Path}; -use yansi_term::Colour::Green; -use yansi_term::Colour::Red; +use std::{env::args, path::Path, sync::mpsc::channel}; +use supergfxctl::{ + gfx_vendors::{GfxRequiredUserAction, GfxVendors}, + special::{get_asus_gsync_gfx_mode, has_asus_gsync_gfx_mode}, + zbus_proxy::GfxProxy, +}; +use zbus::Connection; #[derive(Default, Options)] struct CliStart { @@ -152,7 +153,7 @@ fn main() -> Result<(), Box> { match parsed.command { Some(CliCommand::LedMode(mode)) => handle_led_mode(&dbus, &supported.keyboard_led, &mode)?, Some(CliCommand::Profile(cmd)) => handle_profile(&dbus, &supported.platform_profile, &cmd)?, - Some(CliCommand::Graphics(cmd)) => do_gfx(&dbus, &supported.rog_bios_ctrl, cmd)?, + Some(CliCommand::Graphics(cmd)) => do_gfx(cmd)?, Some(CliCommand::Anime(cmd)) => handle_anime(&dbus, &supported.anime_ctrl, &cmd)?, Some(CliCommand::Bios(cmd)) => handle_bios_option(&dbus, &supported.rog_bios_ctrl, &cmd)?, None => { @@ -190,62 +191,67 @@ fn main() -> Result<(), Box> { Ok(()) } -fn do_gfx( - dbus: &RogDbusClient, - supported: &RogBiosSupportedFunctions, - command: GraphicsCommand, -) -> Result<(), Box> { +fn do_gfx(command: GraphicsCommand) -> Result<(), Box> { if command.mode.is_none() && !command.get && !command.pow && !command.force || command.help { println!("{}", command.self_usage()); } + let conn = Connection::new_system()?; + let proxy = GfxProxy::new(&conn)?; + + let (tx, rx) = channel(); + proxy.connect_notify_action(tx)?; + if let Some(mode) = command.mode { - if supported.dedicated_gfx_toggle && dbus.proxies().rog_bios().get_dedicated_gfx()? == 1 { + if has_asus_gsync_gfx_mode() && get_asus_gsync_gfx_mode()? == 1 { println!("You can not change modes until you turn dedicated/G-Sync off and reboot"); std::process::exit(-1); } println!("If anything fails check `journalctl -b -u asusd`\n"); - dbus.proxies().gfx().gfx_write_mode(&mode).map_err(|err|{ + proxy.gfx_write_mode(&mode).map_err(|err|{ println!("Graphics mode change error. You may be in an invalid state."); println!("Check mode with `asusctl graphics -g` and switch to opposite\nmode to correct it, e.g: if integrated, switch to hybrid, or if nvidia, switch to integrated.\n"); err })?; - let res = dbus.gfx_wait_changed()?; - match res { - GfxRequiredUserAction::Integrated => { - println!( - "You must change to Integrated before you can change to {}", - <&str>::from(mode) - ); - } - GfxRequiredUserAction::Logout | GfxRequiredUserAction::Reboot => { - println!( - "Graphics mode changed to {}. User action required is: {}", - <&str>::from(mode), - <&str>::from(&res) - ); - } - GfxRequiredUserAction::None => { - println!("Graphics mode changed to {}", <&str>::from(mode)); + + loop { + proxy.next_signal()?; + + if let Ok(res) = rx.try_recv() { + match res { + GfxRequiredUserAction::Integrated => { + println!( + "You must change to Integrated before you can change to {}", + <&str>::from(mode) + ); + } + GfxRequiredUserAction::Logout | GfxRequiredUserAction::Reboot => { + println!( + "Graphics mode changed to {}. User action required is: {}", + <&str>::from(mode), + <&str>::from(&res) + ); + } + GfxRequiredUserAction::None => { + println!("Graphics mode changed to {}", <&str>::from(mode)); + } + } } + std::process::exit(0) } - std::process::exit(0) } + if command.get { - let res = dbus.proxies().gfx().gfx_get_mode()?; + let res = proxy.gfx_get_mode()?; println!("Current graphics mode: {}", <&str>::from(res)); } if command.pow { - let res = dbus.proxies().gfx().gfx_get_pwr()?; - match res { - GfxPower::Active => { - println!("Current power status: {}", Red.paint(<&str>::from(&res))) - } - _ => println!("Current power status: {}", Green.paint(<&str>::from(&res))), - } + let res = proxy.gfx_get_pwr()?; + println!("Current power status: {}", <&str>::from(&res)); } + Ok(()) } diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index e6addacd..60e167f8 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -23,7 +23,6 @@ rog_aura = { path = "../rog-aura" } rog_types = { path = "../rog-types" } rog_profiles = { path = "../rog-profiles" } rog_dbus = { path = "../rog-dbus" } -supergfxctl = { path = "../supergfx" } rusb = "^0.8" udev = "^0.6" diff --git a/daemon/src/config.rs b/daemon/src/config.rs index 604c95b8..5f5b0a6c 100644 --- a/daemon/src/config.rs +++ b/daemon/src/config.rs @@ -3,7 +3,6 @@ use serde_derive::{Deserialize, Serialize}; use std::fs::{File, OpenOptions}; use std::io::{Read, Write}; -use crate::config_old::*; use crate::VERSION; pub static CONFIG_PATH: &str = "/etc/asusd/asusd.conf"; @@ -36,9 +35,6 @@ impl Config { config = Self::new(); } else if let Ok(data) = serde_json::from_str(&buf) { config = data; - } else if let Ok(data) = serde_json::from_str::(&buf) { - config = data.into_current(); - info!("Updated config version to: {}", VERSION); } else { warn!("Could not deserialise {}", CONFIG_PATH); panic!("Please remove {} then restart asusd", CONFIG_PATH); diff --git a/daemon/src/config_old.rs b/daemon/src/config_old.rs deleted file mode 100644 index 0271380b..00000000 --- a/daemon/src/config_old.rs +++ /dev/null @@ -1,53 +0,0 @@ -use serde_derive::{Deserialize, Serialize}; -use supergfxctl::gfx_vendors::GfxVendors; -use std::collections::BTreeMap; - -use crate::config::Config; - -#[derive(Deserialize, Serialize)] -pub struct ConfigV352 { - pub gfx_mode: GfxVendors, - pub gfx_last_mode: GfxVendors, - pub gfx_managed: bool, - pub gfx_vfio_enable: bool, - pub gfx_save_compute_vfio: bool, - pub active_profile: String, - pub toggle_profiles: Vec, - #[serde(skip)] - pub curr_fan_mode: u8, - pub bat_charge_limit: u8, - pub power_profiles: BTreeMap, -} - -impl ConfigV352 { - pub(crate) fn into_current(self) -> Config { - Config { - bat_charge_limit: self.bat_charge_limit, - } - } -} - -#[derive(Deserialize, Serialize)] -pub struct ConfigV372 { - pub gfx_mode: GfxVendors, - /// Only for informational purposes. - #[serde(skip)] - pub gfx_tmp_mode: Option, - pub gfx_managed: bool, - pub gfx_vfio_enable: bool, - pub active_profile: String, - pub toggle_profiles: Vec, - #[serde(skip)] - pub curr_fan_mode: u8, - pub bat_charge_limit: u8, - pub power_profiles: BTreeMap, -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct ProfileV317 { - pub min_percentage: u8, - pub max_percentage: u8, - pub turbo: bool, - pub fan_preset: u8, - pub fan_curve: Option<()>, -} diff --git a/daemon/src/ctrl_profiles/controller.rs b/daemon/src/ctrl_profiles/controller.rs index 81f06945..c49d130c 100644 --- a/daemon/src/ctrl_profiles/controller.rs +++ b/daemon/src/ctrl_profiles/controller.rs @@ -40,19 +40,23 @@ impl GetSupported for CtrlPlatformProfile { fn get_supported() -> Self::A { if !Profile::is_platform_profile_supported() { - warn!(r#" + warn!( + r#" platform_profile kernel interface not found, your laptop does not support this, or the iterface is missing. To enable profile support you require a kernel with the following patch applied: https://lkml.org/lkml/2021/8/18/1022 -"#); +"# + ); } if !FanCurves::is_fan_curves_supported() { - info!(r#" + info!( + r#" fan curves kernel interface not found, your laptop does not support this, or the iterface is missing. To enable fan-curve support you require a kernel with the following patch applied: https://lkml.org/lkml/2021/8/20/232 Please note that as of 24/08/2021 this is not final. -"#); +"# + ); } PlatformProfileFunctions { platform_profile: Profile::is_platform_profile_supported(), diff --git a/daemon/src/daemon.rs b/daemon/src/daemon.rs index 808df1a0..3b4be38f 100644 --- a/daemon/src/daemon.rs +++ b/daemon/src/daemon.rs @@ -1,5 +1,6 @@ use daemon::ctrl_anime::config::AnimeConfig; use daemon::ctrl_anime::zbus::CtrlAnimeZbus; +use daemon::ctrl_anime::*; use daemon::ctrl_aura::config::AuraConfig; use daemon::ctrl_aura::controller::{ CtrlKbdLed, CtrlKbdLedReloader, CtrlKbdLedTask, CtrlKbdLedZbus, @@ -10,15 +11,11 @@ use daemon::ctrl_profiles::controller::CtrlPlatformTask; use daemon::{ config::Config, ctrl_supported::SupportedFunctions, laptops::print_board_info, GetSupported, }; -use daemon::{ctrl_anime::*}; use daemon::{ ctrl_profiles::{controller::CtrlPlatformProfile, zbus::ProfileZbus}, laptops::LaptopLedData, }; -use supergfxctl::config::GfxConfig; -use supergfxctl::controller::CtrlGraphics; -use supergfxctl::gfx_vendors::GfxVendors; use ::zbus::{fdo, Connection, ObjectServer}; use daemon::{CtrlTask, Reloadable, ZbusAdd}; use log::LevelFilter; @@ -34,7 +31,6 @@ use daemon::ctrl_rog_bios::CtrlRogBios; use zvariant::ObjectPath; static PROFILE_CONFIG_PATH: &str = "/etc/asusd/profile.conf"; -static GFX_CONFIG_PATH: &str = "/etc/asusd/supergfx.conf"; pub fn main() -> Result<(), Box> { let mut logger = env_logger::Builder::new(); @@ -86,10 +82,6 @@ fn start_daemon() -> Result<(), Box> { let config = Config::load(); let config = Arc::new(Mutex::new(config)); - let gfx_config = GfxConfig::load(GFX_CONFIG_PATH.into()); - let enable_gfx_switching = gfx_config.gfx_managed; - let gfx_config = Arc::new(Mutex::new(gfx_config)); - supported.add_to_server(&mut object_server); match CtrlRogBios::new(config.clone()) { @@ -105,7 +97,7 @@ fn start_daemon() -> Result<(), Box> { } } - match CtrlCharge::new(config.clone()) { + match CtrlCharge::new(config) { Ok(mut ctrl) => { // Do a reload of any settings ctrl.reload() @@ -173,48 +165,6 @@ fn start_daemon() -> Result<(), Box> { } } - // Graphics switching requires some checks on boot specifically for g-sync capable laptops - if enable_gfx_switching { - match CtrlGraphics::new(gfx_config.clone()) { - Ok(mut ctrl) => { - // Need to check if a laptop has the dedicated gfx switch - if CtrlRogBios::has_dedicated_gfx_toggle() { - if let Ok(ded) = CtrlRogBios::get_gfx_mode() { - if let Ok(config) = gfx_config.lock() { - if ded == 1 { - warn!("Dedicated GFX toggle is on but driver mode is not nvidia \nSetting to nvidia driver mode"); - let devices = ctrl.devices(); - let bus = ctrl.bus(); - CtrlGraphics::do_mode_setup_tasks( - GfxVendors::Nvidia, - false, - &devices, - &bus, - )?; - } else if ded == 0 { - info!("Dedicated GFX toggle is off"); - let devices = ctrl.devices(); - let bus = ctrl.bus(); - CtrlGraphics::do_mode_setup_tasks( - config.gfx_mode, - false, - &devices, - &bus, - )?; - } - } - } - } - ctrl.reload() - .unwrap_or_else(|err| error!("Gfx controller: {}", err)); - ctrl.add_to_server(&mut object_server); - } - Err(err) => { - error!("Gfx control: {}", err); - } - } - } - // TODO: implement messaging between threads to check fails // Run tasks diff --git a/daemon/src/error.rs b/daemon/src/error.rs index 27384ef0..bcfb9111 100644 --- a/daemon/src/error.rs +++ b/daemon/src/error.rs @@ -1,6 +1,4 @@ use rog_profiles::error::ProfileError; -use rog_types::error::GraphicsError; -use supergfxctl::error::GfxError; use std::convert::From; use std::fmt; @@ -19,7 +17,6 @@ pub enum RogError { MissingFunction(String), MissingLedBrightNode(String, std::io::Error), ReloadFail(String), - GfxSwitching(GfxError), Profiles(ProfileError), Initramfs(String), Modprobe(String), @@ -44,7 +41,6 @@ impl fmt::Display for RogError { 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::ReloadFail(deets) => write!(f, "Task error: {}", deets), - RogError::GfxSwitching(deets) => write!(f, "Graphics switching error: {}", deets), RogError::Profiles(deets) => write!(f, "Profile error: {}", deets), RogError::Initramfs(detail) => write!(f, "Initiramfs error: {}", detail), RogError::Modprobe(detail) => write!(f, "Modprobe error: {}", detail), @@ -56,15 +52,6 @@ impl fmt::Display for RogError { impl std::error::Error for RogError {} -impl From for RogError { - fn from(err: GraphicsError) -> Self { - match err { - GraphicsError::ParseVendor => RogError::GfxSwitching(GfxError::ParseVendor), - GraphicsError::ParsePower => RogError::GfxSwitching(GfxError::ParsePower), - } - } -} - impl From for RogError { fn from(err: ProfileError) -> Self { RogError::Profiles(err) diff --git a/daemon/src/lib.rs b/daemon/src/lib.rs index 82984d50..766f9cd7 100644 --- a/daemon/src/lib.rs +++ b/daemon/src/lib.rs @@ -1,7 +1,6 @@ #![deny(unused_must_use)] /// Configuration loading, saving pub mod config; -pub(crate) mod config_old; /// Control of AniMe matrix display pub mod ctrl_anime; /// Keyboard LED brightness control, RGB, and LED display modes diff --git a/data/anime/asus/festive/Love u mom.gif b/data/anime/asus/festive/Love u mom.gif new file mode 100755 index 00000000..8fd6d363 Binary files /dev/null and b/data/anime/asus/festive/Love u mom.gif differ diff --git a/data/anime/asus/festive/Mother's day.gif b/data/anime/asus/festive/Mother's day.gif new file mode 100755 index 00000000..e95d0243 Binary files /dev/null and b/data/anime/asus/festive/Mother's day.gif differ diff --git a/data/anime/asus/music/Diamond.gif b/data/anime/asus/music/Diamond.gif new file mode 100755 index 00000000..cc2da200 Binary files /dev/null and b/data/anime/asus/music/Diamond.gif differ diff --git a/data/anime/asus/trend/Hero.gif b/data/anime/asus/trend/Hero.gif new file mode 100755 index 00000000..61ecfdb4 Binary files /dev/null and b/data/anime/asus/trend/Hero.gif differ diff --git a/rog-dbus/src/lib.rs b/rog-dbus/src/lib.rs index 7babbb09..458f4501 100644 --- a/rog-dbus/src/lib.rs +++ b/rog-dbus/src/lib.rs @@ -1,10 +1,10 @@ pub static DBUS_NAME: &str = "org.asuslinux.Daemon"; +pub static DBUS_NAME_GFX: &str = "org.supergfxctl.Daemon"; pub static DBUS_PATH: &str = "/org/asuslinux/Daemon"; pub static DBUS_IFACE: &str = "org.asuslinux.Daemon"; pub mod zbus_anime; pub mod zbus_charge; -pub mod zbus_gfx; pub mod zbus_led; pub mod zbus_profile; pub mod zbus_rogbios; @@ -13,7 +13,6 @@ pub mod zbus_supported; use rog_anime::AnimePowerStates; use rog_aura::{AuraEffect, LedPowerStates}; use rog_profiles::Profile; -use supergfxctl::gfx_vendors::{GfxRequiredUserAction, GfxVendors}; use std::sync::mpsc::{channel, Receiver}; use zbus::{Connection, Result, SignalReceiver}; @@ -21,7 +20,6 @@ pub static VERSION: &str = env!("CARGO_PKG_VERSION"); pub struct DbusProxies<'a> { anime: zbus_anime::AnimeProxy<'a>, charge: zbus_charge::ChargeProxy<'a>, - gfx: zbus_gfx::GfxProxy<'a>, led: zbus_led::LedProxy<'a>, profile: zbus_profile::ProfileProxy<'a>, rog_bios: zbus_rogbios::RogBiosProxy<'a>, @@ -38,7 +36,6 @@ impl<'a> DbusProxies<'a> { anime: zbus_anime::AnimeProxy::new(&conn)?, led: zbus_led::LedProxy::new(&conn)?, charge: zbus_charge::ChargeProxy::new(&conn)?, - gfx: zbus_gfx::GfxProxy::new(&conn)?, profile: zbus_profile::ProfileProxy::new(&conn)?, rog_bios: zbus_rogbios::RogBiosProxy::new(&conn)?, supported: zbus_supported::SupportProxy::new(&conn)?, @@ -52,7 +49,6 @@ impl<'a> DbusProxies<'a> { recv.receive_for(self.anime.proxy()); recv.receive_for(self.led.proxy()); recv.receive_for(self.charge.proxy()); - recv.receive_for(self.gfx.proxy()); recv.receive_for(self.profile.proxy()); recv.receive_for(self.rog_bios.proxy()); recv.receive_for(self.supported.proxy()); @@ -67,10 +63,6 @@ impl<'a> DbusProxies<'a> { &self.charge } - pub fn gfx(&self) -> &zbus_gfx::GfxProxy<'a> { - &self.gfx - } - pub fn led(&self) -> &zbus_led::LedProxy<'a> { &self.led } @@ -90,8 +82,6 @@ impl<'a> DbusProxies<'a> { // Signals separated out pub struct Signals { - pub gfx_vendor: Receiver, - pub gfx_action: Receiver, pub profile: Receiver, pub led_mode: Receiver, pub led_power_state: Receiver, @@ -105,16 +95,6 @@ impl Signals { #[inline] pub fn new(proxies: &DbusProxies) -> Result { Ok(Signals { - gfx_vendor: { - let (tx, rx) = channel(); - proxies.gfx.connect_notify_gfx(tx)?; - rx - }, - gfx_action: { - let (tx, rx) = channel(); - proxies.gfx.connect_notify_action(tx)?; - rx - }, profile: { let (tx, rx) = channel(); proxies.profile.connect_notify_profile(tx)?; @@ -182,26 +162,9 @@ impl<'a> RogDbusClient<'a> { recv.receive_for(self.proxies.anime.proxy()); recv.receive_for(self.proxies.led.proxy()); recv.receive_for(self.proxies.charge.proxy()); - recv.receive_for(self.proxies.gfx.proxy()); recv.receive_for(self.proxies.profile.proxy()); recv.receive_for(self.proxies.rog_bios.proxy()); recv.receive_for(self.proxies.supported.proxy()); recv } - - /* - * GFX - */ - pub fn gfx_wait_changed(&self) -> Result { - loop { - if let Ok(res) = self.proxies.gfx.proxy().next_signal() { - if res.is_none() { - if let Ok(stuff) = self.signals.gfx_action.try_recv() { - return Ok(stuff); - } - // return Ok("Failed for unknown reason".to_owned()); - } - } - } - } } diff --git a/rog-types/src/error.rs b/rog-types/src/error.rs deleted file mode 100644 index 432772f0..00000000 --- a/rog-types/src/error.rs +++ /dev/null @@ -1,20 +0,0 @@ -use std::error::Error; -use std::fmt; - -#[derive(Debug)] -pub enum GraphicsError { - ParseVendor, - ParsePower, -} - -impl fmt::Display for GraphicsError { - // This trait requires `fmt` with this exact signature. - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - GraphicsError::ParseVendor => write!(f, "Could not parse vendor name"), - GraphicsError::ParsePower => write!(f, "Could not parse dGPU power status"), - } - } -} - -impl Error for GraphicsError {} diff --git a/rog-types/src/lib.rs b/rog-types/src/lib.rs index 478c9e5b..eddc8a53 100644 --- a/rog-types/src/lib.rs +++ b/rog-types/src/lib.rs @@ -8,6 +8,4 @@ pub static DBUS_IFACE: &str = "org.asuslinux.Daemon"; pub mod supported; -pub mod error; - pub static VERSION: &str = env!("CARGO_PKG_VERSION"); diff --git a/supergfx/Cargo.toml b/supergfx/Cargo.toml index c67e654f..1bcfc747 100644 --- a/supergfx/Cargo.toml +++ b/supergfx/Cargo.toml @@ -12,6 +12,26 @@ keywords = ["graphics", "nvidia", "switching"] edition = "2018" exclude = ["data"] +[features] +daemon = ["env_logger"] +cli = ["gumdrop"] +default = ["daemon", "cli"] + +[lib] +name = "supergfxctl" +path = "src/lib.rs" + +[[bin]] +name = "supergfxd" +path = "src/daemon.rs" +required-features = ["daemon"] + +[[bin]] +name = "supergfxctl" +path = "src/cli.rs" +required-features = ["cli"] +default-features = ["cli"] + [dependencies] serde = "^1.0" serde_derive = "^1.0" @@ -23,4 +43,7 @@ zvariant = "^2.8" zvariant_derive = "^2.8" logind-zbus = "^0.7.1" -sysfs-class = "^0.1.2" \ No newline at end of file +sysfs-class = "^0.1.2" + +env_logger = { version = "^0.8", optional = true } +gumdrop = { version = "^0.8", optional = true } \ No newline at end of file diff --git a/supergfx/Makefile b/supergfx/Makefile new file mode 100644 index 00000000..fb4f47ae --- /dev/null +++ b/supergfx/Makefile @@ -0,0 +1,74 @@ +VERSION := $(shell grep -Pm1 'version = "(\d.\d.\d)"' daemon/Cargo.toml | cut -d'"' -f2) + +INSTALL = install +INSTALL_PROGRAM = ${INSTALL} -D -m 0755 +INSTALL_DATA = ${INSTALL} -D -m 0644 + +prefix = /usr +exec_prefix = $(prefix) +bindir = $(exec_prefix)/bin +datarootdir = $(prefix)/share +libdir = $(exec_prefix)/lib + +BIN_SD := supergfxd +BIN_SC := supergfxctl +X11CFG := 90-nvidia-screen-G05.conf +PMRULES := 90-asusd-nvidia-pm.rules + +SRC := Cargo.toml Cargo.lock Makefile $(shell find -type f -wholename '**/src/*.rs') + +DEBUG ?= 0 +ifeq ($(DEBUG),0) + ARGS += --release + TARGET = release +endif + +VENDORED ?= 0 +ifeq ($(VENDORED),1) + ARGS += --frozen +endif + +all: build + +clean: + cargo clean + +distclean: + rm -rf .cargo vendor vendor.tar.xz + +install: + $(INSTALL_PROGRAM) "./target/release/$(BIN_SD)" "$(DESTDIR)$(bindir)/$(BIN_SD)" + $(INSTALL_PROGRAM) "./target/release/$(BIN_SC)" "$(DESTDIR)$(bindir)/$(BIN_SC)" + $(INSTALL_DATA) "./data/$(BIN_SD).service" "$(DESTDIR)$(libdir)/systemd/system/$(BIN_SD).service" + $(INSTALL_DATA) "./data/org.supergfxctl.Daemon.conf" "$(DESTDIR)$(datarootdir)/dbus-1/system.d/org.supergfxctl.Daemon.conf" + $(INSTALL_DATA) "./data/$(X11CFG)" "$(DESTDIR)$(datarootdir)/X11/xorg.conf.d/$(X11CFG)" + $(INSTALL_DATA) "./data/$(PMRULES)" "$(DESTDIR)$(libdir)/udev/rules.d/$(PMRULES)" + +uninstall: + rm -f "$(DESTDIR)$(bindir)/$(BIN_SC)" + rm -f "$(DESTDIR)$(bindir)/$(BIN_SD)" + rm -f "$(DESTDIR)$(libdir)/systemd/system/$(BIN_SD).service" + rm -f "$(DESTDIR)$(datarootdir)/dbus-1/system.d/org.supergfxctl.Daemon.conf" + rm -f "$(DESTDIR)$(datarootdir)/X11/xorg.conf.d/$(X11CFG)" + rm -f "$(DESTDIR)$(libdir)/udev/rules.d/$(PMRULES)" + +update: + cargo update + +vendor: + mkdir -p .cargo + cargo vendor | head -n -1 > .cargo/config + echo 'directory = "vendor"' >> .cargo/config + mv .cargo/config ./cargo-config + rm -rf .cargo + tar pcfJ vendor_asusctl_$(VERSION).tar.xz vendor + rm -rf vendor + +build: +ifeq ($(VENDORED),1) + @echo "version = $(VERSION)" + tar pxf vendor_asusctl_$(VERSION).tar.xz +endif + cargo build $(ARGS) + +.PHONY: all clean distclean install uninstall update build diff --git a/data/90-asusd-nvidia-pm.rules b/supergfx/data/90-asusd-nvidia-pm.rules similarity index 100% rename from data/90-asusd-nvidia-pm.rules rename to supergfx/data/90-asusd-nvidia-pm.rules diff --git a/data/90-nvidia-screen-G05.conf b/supergfx/data/90-nvidia-screen-G05.conf similarity index 100% rename from data/90-nvidia-screen-G05.conf rename to supergfx/data/90-nvidia-screen-G05.conf diff --git a/supergfx/data/org.supergfxctl.Daemon.conf b/supergfx/data/org.supergfxctl.Daemon.conf new file mode 100644 index 00000000..77fa6276 --- /dev/null +++ b/supergfx/data/org.supergfxctl.Daemon.conf @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/supergfx/data/supergfxd.service b/supergfx/data/supergfxd.service new file mode 100644 index 00000000..cbe73694 --- /dev/null +++ b/supergfx/data/supergfxd.service @@ -0,0 +1,16 @@ +[Unit] +Description=SUPERGFX +StartLimitInterval=200 +StartLimitBurst=2 +Before=display-manager.service + +[Service] +Environment=IS_SUPERGFX_SERVICE=1 +ExecStart=/usr/bin/supergfxd +Restart=on-failure +Restart=always +RestartSec=1 +Type=dbus +BusName=org.supergfxctl.Daemon +SELinuxContext=system_u:system_r:unconfined_t:s0 +#SELinuxContext=system_u:object_r:modules_object_t:s0 \ No newline at end of file diff --git a/supergfx/src/cli.rs b/supergfx/src/cli.rs new file mode 100644 index 00000000..f2926cae --- /dev/null +++ b/supergfx/src/cli.rs @@ -0,0 +1,105 @@ +use std::{env::args, sync::mpsc::channel}; +use supergfxctl::{ + gfx_vendors::{GfxRequiredUserAction, GfxVendors}, + special::{get_asus_gsync_gfx_mode, has_asus_gsync_gfx_mode}, + zbus_proxy::GfxProxy, +}; + +use gumdrop::Options; +use zbus::Connection; + +#[derive(Default, Options)] +struct CliStart { + #[options(help = "print help message")] + help: bool, + #[options( + meta = "", + help = "Set graphics mode: " + )] + mode: Option, + #[options(help = "Get the current mode")] + get: bool, + #[options(help = "Get the current power status")] + pow: bool, + #[options(help = "Do not ask for confirmation")] + force: bool, +} + +fn main() -> Result<(), Box> { + let args: Vec = args().skip(1).collect(); + + match CliStart::parse_args_default(&args) { + Ok(command) => { + do_gfx(command)?; + } + Err(err) => { + eprintln!("source {}", err); + std::process::exit(2); + } + } + + Ok(()) +} + +fn do_gfx(command: CliStart) -> Result<(), Box> { + if command.mode.is_none() && !command.get && !command.pow && !command.force || command.help { + println!("{}", command.self_usage()); + } + + let conn = Connection::new_system()?; + let proxy = GfxProxy::new(&conn)?; + + let (tx, rx) = channel(); + proxy.connect_notify_action(tx)?; + + if let Some(mode) = command.mode { + if has_asus_gsync_gfx_mode() && get_asus_gsync_gfx_mode()? == 1 { + println!("You can not change modes until you turn dedicated/G-Sync off and reboot"); + std::process::exit(-1); + } + + println!("If anything fails check `journalctl -b -u supergfxd`\n"); + + proxy.gfx_write_mode(&mode).map_err(|err|{ + println!("Graphics mode change error. You may be in an invalid state."); + println!("Check mode with `-g` and switch to opposite\nmode to correct it, e.g: if integrated, switch to hybrid, or if nvidia, switch to integrated.\n"); + err + })?; + + loop { + proxy.next_signal()?; + + if let Ok(res) = rx.try_recv() { + match res { + GfxRequiredUserAction::Integrated => { + println!( + "You must change to Integrated before you can change to {}", + <&str>::from(mode) + ); + } + GfxRequiredUserAction::Logout | GfxRequiredUserAction::Reboot => { + println!( + "Graphics mode changed to {}. User action required is: {}", + <&str>::from(mode), + <&str>::from(&res) + ); + } + GfxRequiredUserAction::None => { + println!("Graphics mode changed to {}", <&str>::from(mode)); + } + } + } + std::process::exit(0) + } + } + if command.get { + let res = proxy.gfx_get_mode()?; + println!("Current graphics mode: {}", <&str>::from(res)); + } + if command.pow { + let res = proxy.gfx_get_pwr()?; + println!("Current power status: {}", <&str>::from(&res)); + } + + Ok(()) +} diff --git a/supergfx/src/daemon.rs b/supergfx/src/daemon.rs new file mode 100644 index 00000000..f898f046 --- /dev/null +++ b/supergfx/src/daemon.rs @@ -0,0 +1,105 @@ +use std::{ + env, + error::Error, + sync::{Arc, Mutex}, +}; + +use log::{error, info, warn, LevelFilter}; +use std::io::Write; +use supergfxctl::{ + config::GfxConfig, + controller::CtrlGraphics, + error::GfxError, + gfx_vendors::GfxVendors, + special::{get_asus_gsync_gfx_mode, has_asus_gsync_gfx_mode}, + DBUS_DEST_NAME, GFX_CONFIG_PATH, +}; +use zbus::{fdo, Connection, ObjectServer}; + +pub fn main() -> Result<(), Box> { + let mut logger = env_logger::Builder::new(); + logger + .target(env_logger::Target::Stdout) + .format(|buf, record| writeln!(buf, "{}: {}", record.level(), record.args())) + .filter(None, LevelFilter::Info) + .init(); + + let is_service = match env::var_os("IS_SUPERGFX_SERVICE") { + Some(val) => val == "1", + None => false, + }; + + if !is_service { + println!("supergfxd schould be only run from the right systemd service"); + println!( + "do not run in your terminal, if you need an logs please use journalctl -b -u supergfxd" + ); + println!("supergfxd will now exit"); + return Ok(()); + } + + start_daemon() +} + +fn start_daemon() -> Result<(), Box> { + // Start zbus server + let connection = Connection::new_system()?; + fdo::DBusProxy::new(&connection)?.request_name( + DBUS_DEST_NAME, + fdo::RequestNameFlags::ReplaceExisting.into(), + )?; + + let mut object_server = ObjectServer::new(&connection); + + let config = GfxConfig::load(GFX_CONFIG_PATH.into()); + let enable_gfx_switching = config.gfx_managed; + let config = Arc::new(Mutex::new(config)); + + // Graphics switching requires some checks on boot specifically for g-sync capable laptops + if enable_gfx_switching { + match CtrlGraphics::new(config.clone()) { + Ok(mut ctrl) => { + // Need to check if a laptop has the dedicated gfx switch + if has_asus_gsync_gfx_mode() { + do_asus_laptop_checks(&ctrl, config)?; + } + + ctrl.reload() + .unwrap_or_else(|err| error!("Gfx controller: {}", err)); + ctrl.add_to_server(&mut object_server); + } + Err(err) => { + error!("Gfx control: {}", err); + } + } + } + + // Loop to check errors and iterate zbus server + loop { + if let Err(err) = object_server.try_handle_next() { + error!("{}", err); + } + } +} + +fn do_asus_laptop_checks( + ctrl: &CtrlGraphics, + config: Arc>, +) -> Result<(), GfxError> { + if let Ok(ded) = get_asus_gsync_gfx_mode() { + if let Ok(config) = config.lock() { + if ded == 1 { + warn!("Dedicated GFX toggle is on but driver mode is not nvidia \nSetting to nvidia driver mode"); + let devices = ctrl.devices(); + let bus = ctrl.bus(); + CtrlGraphics::do_mode_setup_tasks(GfxVendors::Nvidia, false, &devices, &bus)?; + } else if ded == 0 { + info!("Dedicated GFX toggle is off"); + let devices = ctrl.devices(); + let bus = ctrl.bus(); + CtrlGraphics::do_mode_setup_tasks(config.gfx_mode, false, &devices, &bus)?; + } + } + } + Ok(()) +} diff --git a/supergfx/src/error.rs b/supergfx/src/error.rs index b5e94612..d47c7d1a 100644 --- a/supergfx/src/error.rs +++ b/supergfx/src/error.rs @@ -69,4 +69,4 @@ impl From for GfxError { fn from(err: std::io::Error) -> Self { GfxError::Io(err) } -} \ No newline at end of file +} diff --git a/supergfx/src/lib.rs b/supergfx/src/lib.rs index 484aece7..4fbc1af3 100644 --- a/supergfx/src/lib.rs +++ b/supergfx/src/lib.rs @@ -1,12 +1,17 @@ -pub mod error; pub mod config; -pub mod gfx_vendors; pub mod controller; -pub mod system; +pub mod error; +pub mod gfx_vendors; /// Special-case functions for check/read/write of key functions on unique laptops /// such as the G-Sync mode available on some ASUS ROG laptops -pub(crate) mod special; -pub mod zbus; +pub mod special; +pub mod system; +pub mod zbus_iface; +pub mod zbus_proxy; + +pub const GFX_CONFIG_PATH: &str = "/etc/supergfxd.conf"; +pub const DBUS_DEST_NAME: &str = "org.supergfxctl.Daemon"; +pub const DBUS_IFACE_PATH: &str = "/org/supergfxctl/Gfx"; const NVIDIA_DRIVERS: [&str; 4] = ["nvidia_drm", "nvidia_modeset", "nvidia_uvm", "nvidia"]; diff --git a/supergfx/src/special.rs b/supergfx/src/special.rs index fdccc37e..ee1ef4d5 100644 --- a/supergfx/src/special.rs +++ b/supergfx/src/special.rs @@ -5,11 +5,11 @@ use crate::error::GfxError; static ASUS_SWITCH_GRAPHIC_MODE: &str = "/sys/firmware/efi/efivars/AsusSwitchGraphicMode-607005d5-3f75-4b2e-98f0-85ba66797a3e"; -pub(crate) fn has_asus_gsync_gfx_mode() -> bool { +pub fn has_asus_gsync_gfx_mode() -> bool { Path::new(ASUS_SWITCH_GRAPHIC_MODE).exists() } -pub(crate) fn get_asus_gsync_gfx_mode() -> Result { +pub fn get_asus_gsync_gfx_mode() -> Result { let path = ASUS_SWITCH_GRAPHIC_MODE; let mut file = OpenOptions::new() .read(true) @@ -22,4 +22,4 @@ pub(crate) fn get_asus_gsync_gfx_mode() -> Result { let idx = data.len() - 1; Ok(data[idx] as i8) -} \ No newline at end of file +} diff --git a/supergfx/src/zbus.rs b/supergfx/src/zbus_iface.rs similarity index 87% rename from supergfx/src/zbus.rs rename to supergfx/src/zbus_iface.rs index b625912b..c6fd371c 100644 --- a/supergfx/src/zbus.rs +++ b/supergfx/src/zbus_iface.rs @@ -1,12 +1,15 @@ +use ::zbus::dbus_interface; use log::{error, info, warn}; use zvariant::ObjectPath; -use ::zbus::dbus_interface; -use crate::gfx_vendors::{GfxPower, GfxRequiredUserAction, GfxVendors}; +use crate::{ + gfx_vendors::{GfxPower, GfxRequiredUserAction, GfxVendors}, + DBUS_IFACE_PATH, +}; use super::controller::CtrlGraphics; -#[dbus_interface(name = "org.asuslinux.Daemon")] +#[dbus_interface(name = "org.supergfxctl.Daemon")] impl CtrlGraphics { fn vendor(&self) -> zbus::fdo::Result { self.get_gfx_mode().map_err(|err| { @@ -28,10 +31,13 @@ impl CtrlGraphics { error!("GFX: {}", err); zbus::fdo::Error::Failed(format!("GFX fail: {}", err)) })?; - self.notify_gfx(&vendor) - .unwrap_or_else(|err| warn!("GFX: {}", err)); + self.notify_action(&msg) .unwrap_or_else(|err| warn!("GFX: {}", err)); + + self.notify_gfx(&vendor) + .unwrap_or_else(|err| warn!("GFX: {}", err)); + Ok(msg) } @@ -45,7 +51,7 @@ impl CtrlGraphics { impl CtrlGraphics { pub fn add_to_server(self, server: &mut zbus::ObjectServer) { server - .at(&ObjectPath::from_str_unchecked("/org/asuslinux/Gfx"), self) + .at(&ObjectPath::from_str_unchecked(DBUS_IFACE_PATH), self) .map_err(|err| { warn!("GFX: CtrlGraphics: add_to_server {}", err); err diff --git a/rog-dbus/src/zbus_gfx.rs b/supergfx/src/zbus_proxy.rs similarity index 70% rename from rog-dbus/src/zbus_gfx.rs rename to supergfx/src/zbus_proxy.rs index a84f1e6f..2f7a1725 100644 --- a/rog-dbus/src/zbus_gfx.rs +++ b/supergfx/src/zbus_proxy.rs @@ -1,7 +1,7 @@ //! # DBus interface proxy for: `org.asuslinux.Gfx` //! //! This code was generated by `zbus-xmlgen` `1.0.0` from DBus introspection data. -//! Source: `Interface '/org/asuslinux/Gfx' from service 'org.asuslinux.Daemon' on system bus`. +//! Source: `Interface '/org/supergfxctl/Gfx' from service 'org.asuslinux.Daemon' on system bus`. //! //! You may prefer to adapt it, instead of using it verbatim. //! @@ -19,15 +19,16 @@ //! //! …consequently `zbus-xmlgen` did not generate code for the above interfaces. -use std::sync::mpsc::Sender; +use std::sync::mpsc::{Receiver, Sender}; -use supergfxctl::gfx_vendors::{GfxPower, GfxRequiredUserAction, GfxVendors}; -use zbus::{dbus_proxy, Connection, Result}; +use zbus::{dbus_proxy, Connection, Message, Result}; -#[dbus_proxy( - interface = "org.asuslinux.Daemon", - default_path = "/org/asuslinux/Gfx" -)] +use crate::{ + gfx_vendors::{GfxPower, GfxRequiredUserAction, GfxVendors}, + DBUS_IFACE_PATH, +}; + +#[dbus_proxy(interface = "org.supergfxctl.Daemon")] trait Daemon { /// Power method fn power(&self) -> zbus::Result; @@ -47,12 +48,25 @@ trait Daemon { fn notify_gfx(&self, vendor: GfxVendors) -> zbus::Result<()>; } -pub struct GfxProxy<'a>(DaemonProxy<'a>); +pub struct GfxProxy<'a>(pub DaemonProxy<'a>); impl<'a> GfxProxy<'a> { #[inline] pub fn new(conn: &Connection) -> Result { - Ok(GfxProxy(DaemonProxy::new(conn)?)) + let proxy = DaemonProxy::new_for(conn, "org.supergfxctl.Daemon", DBUS_IFACE_PATH)?; + Ok(GfxProxy(proxy)) + } + + #[inline] + pub fn new_for(conn: &Connection, destination: &'a str, path: &'a str) -> Result { + let proxy = DaemonProxy::new_for(conn, destination, path)?; + Ok(GfxProxy(proxy)) + } + + #[inline] + pub fn new_for_owned(conn: Connection, destination: String, path: String) -> Result { + let proxy = DaemonProxy::new_for_owned(conn, destination, path)?; + Ok(GfxProxy(proxy)) } #[inline] @@ -95,4 +109,9 @@ impl<'a> GfxProxy<'a> { Ok(()) }) } + + #[inline] + pub fn next_signal(&self) -> Result> { + self.0.next_signal() + } }