mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Major update to supergfx and others
This commit is contained in:
15
Cargo.lock
generated
15
Cargo.lock
generated
@@ -40,6 +40,7 @@ dependencies = [
|
|||||||
"rog_types",
|
"rog_types",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"supergfxctl",
|
"supergfxctl",
|
||||||
|
"zbus",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -57,7 +58,7 @@ dependencies = [
|
|||||||
"rog_types",
|
"rog_types",
|
||||||
"supergfxctl",
|
"supergfxctl",
|
||||||
"tinybmp",
|
"tinybmp",
|
||||||
"yansi-term",
|
"zbus",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -221,7 +222,6 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"supergfxctl",
|
|
||||||
"sysfs-class",
|
"sysfs-class",
|
||||||
"toml",
|
"toml",
|
||||||
"udev",
|
"udev",
|
||||||
@@ -1070,6 +1070,8 @@ dependencies = [
|
|||||||
name = "supergfxctl"
|
name = "supergfxctl"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"env_logger",
|
||||||
|
"gumdrop",
|
||||||
"log",
|
"log",
|
||||||
"logind-zbus",
|
"logind-zbus",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -1314,15 +1316,6 @@ dependencies = [
|
|||||||
"bitflags 0.9.1",
|
"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]]
|
[[package]]
|
||||||
name = "zbus"
|
name = "zbus"
|
||||||
version = "1.9.1"
|
version = "1.9.1"
|
||||||
|
|||||||
19
Makefile
19
Makefile
@@ -15,6 +15,8 @@ BIN_C := asusctl
|
|||||||
BIN_D := asusd
|
BIN_D := asusd
|
||||||
BIN_U := asusd-user
|
BIN_U := asusd-user
|
||||||
BIN_N := asus-notify
|
BIN_N := asus-notify
|
||||||
|
BIN_SD := supergfxd
|
||||||
|
BIN_SC := supergfxctl
|
||||||
LEDCFG := asusd-ledmodes.toml
|
LEDCFG := asusd-ledmodes.toml
|
||||||
X11CFG := 90-nvidia-screen-G05.conf
|
X11CFG := 90-nvidia-screen-G05.conf
|
||||||
PMRULES := 90-asusd-nvidia-pm.rules
|
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_D)" "$(DESTDIR)$(bindir)/$(BIN_D)"
|
||||||
$(INSTALL_PROGRAM) "./target/release/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)"
|
$(INSTALL_PROGRAM) "./target/release/$(BIN_U)" "$(DESTDIR)$(bindir)/$(BIN_U)"
|
||||||
$(INSTALL_PROGRAM) "./target/release/$(BIN_N)" "$(DESTDIR)$(bindir)/$(BIN_N)"
|
$(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/$(BIN_D).rules" "$(DESTDIR)$(libdir)/udev/rules.d/99-$(BIN_D).rules"
|
||||||
$(INSTALL_DATA) "./data/$(LEDCFG)" "$(DESTDIR)/etc/asusd/$(LEDCFG)"
|
$(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).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_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_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/$(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_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_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"
|
$(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-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/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/icons/scalable/notification-reboot.svg" "$(DESTDIR)$(datarootdir)/icons/hicolor/scalable/status/notification-reboot.svg"
|
||||||
|
|
||||||
$(INSTALL_DATA) "./data/_asusctl" "$(DESTDIR)$(zshcpl)/_asusctl"
|
$(INSTALL_DATA) "./data/_asusctl" "$(DESTDIR)$(zshcpl)/_asusctl"
|
||||||
$(INSTALL_DATA) "./data/completions/asusctl.fish" "$(DESTDIR)$(datarootdir)/fish/vendor_completions.d/asusctl.fish"
|
$(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/{}" \;
|
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:
|
uninstall:
|
||||||
rm -f "$(DESTDIR)$(bindir)/$(BIN_C)"
|
rm -f "$(DESTDIR)$(bindir)/$(BIN_C)"
|
||||||
rm -f "$(DESTDIR)$(bindir)/$(BIN_D)"
|
rm -f "$(DESTDIR)$(bindir)/$(BIN_D)"
|
||||||
@@ -90,6 +101,10 @@ uninstall:
|
|||||||
rm -f "$(DESTDIR)$(zshcpl)/_asusctl"
|
rm -f "$(DESTDIR)$(zshcpl)/_asusctl"
|
||||||
rm -f "$(DESTDIR)$(datarootdir)/fish/vendor_completions.d/asusctl.fish"
|
rm -f "$(DESTDIR)$(datarootdir)/fish/vendor_completions.d/asusctl.fish"
|
||||||
rm -rf "$(DESTDIR)$(datarootdir)/asusd"
|
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:
|
update:
|
||||||
cargo update
|
cargo update
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ edition = "2018"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
zbus = "^1.9"
|
||||||
# serialisation
|
# serialisation
|
||||||
serde_json = "^1.0"
|
serde_json = "^1.0"
|
||||||
rog_dbus = { path = "../rog-dbus" }
|
rog_dbus = { path = "../rog-dbus" }
|
||||||
|
|||||||
@@ -2,11 +2,14 @@ use notify_rust::{Hint, Notification, NotificationHandle};
|
|||||||
use rog_aura::AuraEffect;
|
use rog_aura::AuraEffect;
|
||||||
use rog_dbus::{DbusProxies, Signals};
|
use rog_dbus::{DbusProxies, Signals};
|
||||||
use rog_profiles::Profile;
|
use rog_profiles::Profile;
|
||||||
use supergfxctl::gfx_vendors::{GfxRequiredUserAction, GfxVendors};
|
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::process;
|
use std::sync::mpsc::channel;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
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";
|
const NOTIF_HEADER: &str = "ROG Control";
|
||||||
|
|
||||||
@@ -42,6 +45,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
|
|
||||||
let recv = proxies.setup_recv(conn);
|
let recv = proxies.setup_recv(conn);
|
||||||
let mut err_count = 0;
|
let mut err_count = 0;
|
||||||
|
|
||||||
|
gfx_thread()?;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
sleep(Duration::from_millis(100));
|
sleep(Duration::from_millis(100));
|
||||||
if let Err(err) = recv.next_signal() {
|
if let Err(err) = recv.next_signal() {
|
||||||
@@ -67,23 +73,57 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
if let Ok(data) = signals.charge.try_recv() {
|
if let Ok(data) = signals.charge.try_recv() {
|
||||||
notify!(do_charge_notif, last_notification, &data);
|
notify!(do_charge_notif, last_notification, &data);
|
||||||
}
|
}
|
||||||
if let Ok(data) = signals.gfx_vendor.try_recv() {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn gfx_thread() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut last_notification: Option<NotificationHandle> = 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);
|
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 {
|
match data {
|
||||||
GfxRequiredUserAction::Logout | GfxRequiredUserAction::Reboot => {
|
GfxRequiredUserAction::Logout | GfxRequiredUserAction::Reboot => {
|
||||||
do_gfx_action_notif(&data)?;
|
do_gfx_action_notif(&data)
|
||||||
|
.map_err(|e| {
|
||||||
|
println!("Error: {}", e);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
}
|
}
|
||||||
GfxRequiredUserAction::Integrated => {
|
GfxRequiredUserAction::Integrated => {
|
||||||
base_notification!(
|
base_notification!(
|
||||||
"You must be in integrated mode first to switch to the requested mode"
|
"You must be in integrated mode first to switch to the requested mode"
|
||||||
)?;
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
println!("Error: {}", e);
|
||||||
|
})
|
||||||
|
.ok();
|
||||||
}
|
}
|
||||||
GfxRequiredUserAction::None => {}
|
GfxRequiredUserAction::None => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_thermal_notif(profile: &Profile) -> Result<NotificationHandle, Box<dyn Error>> {
|
fn do_thermal_notif(profile: &Profile) -> Result<NotificationHandle, Box<dyn Error>> {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ edition = "2018"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
zbus = "^1.9.1"
|
||||||
rog_anime = { path = "../rog-anime" }
|
rog_anime = { path = "../rog-anime" }
|
||||||
rog_aura = { path = "../rog-aura" }
|
rog_aura = { path = "../rog-aura" }
|
||||||
rog_dbus = { path = "../rog-dbus" }
|
rog_dbus = { path = "../rog-dbus" }
|
||||||
@@ -14,7 +15,6 @@ rog_profiles = { path = "../rog-profiles" }
|
|||||||
rog_types = { path = "../rog-types" }
|
rog_types = { path = "../rog-types" }
|
||||||
daemon = { path = "../daemon" }
|
daemon = { path = "../daemon" }
|
||||||
gumdrop = "^0.8"
|
gumdrop = "^0.8"
|
||||||
yansi-term = "^0.1"
|
|
||||||
supergfxctl = { path = "../supergfx" }
|
supergfxctl = { path = "../supergfx" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|||||||
@@ -9,16 +9,17 @@ use profiles_cli::ProfileCommand;
|
|||||||
use rog_anime::{AnimeDataBuffer, AnimeImage, Vec2, ANIME_DATA_LEN};
|
use rog_anime::{AnimeDataBuffer, AnimeImage, Vec2, ANIME_DATA_LEN};
|
||||||
use rog_aura::{self, AuraEffect};
|
use rog_aura::{self, AuraEffect};
|
||||||
use rog_dbus::RogDbusClient;
|
use rog_dbus::RogDbusClient;
|
||||||
use rog_types::{
|
use rog_types::supported::{
|
||||||
supported::{
|
AnimeSupportedFunctions, LedSupportedFunctions, PlatformProfileFunctions,
|
||||||
AnimeSupportedFunctions, LedSupportedFunctions, PlatformProfileFunctions,
|
RogBiosSupportedFunctions,
|
||||||
RogBiosSupportedFunctions,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use supergfxctl::gfx_vendors::{GfxPower, GfxRequiredUserAction, GfxVendors};
|
use std::{env::args, path::Path, sync::mpsc::channel};
|
||||||
use std::{env::args, path::Path};
|
use supergfxctl::{
|
||||||
use yansi_term::Colour::Green;
|
gfx_vendors::{GfxRequiredUserAction, GfxVendors},
|
||||||
use yansi_term::Colour::Red;
|
special::{get_asus_gsync_gfx_mode, has_asus_gsync_gfx_mode},
|
||||||
|
zbus_proxy::GfxProxy,
|
||||||
|
};
|
||||||
|
use zbus::Connection;
|
||||||
|
|
||||||
#[derive(Default, Options)]
|
#[derive(Default, Options)]
|
||||||
struct CliStart {
|
struct CliStart {
|
||||||
@@ -152,7 +153,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
match parsed.command {
|
match parsed.command {
|
||||||
Some(CliCommand::LedMode(mode)) => handle_led_mode(&dbus, &supported.keyboard_led, &mode)?,
|
Some(CliCommand::LedMode(mode)) => handle_led_mode(&dbus, &supported.keyboard_led, &mode)?,
|
||||||
Some(CliCommand::Profile(cmd)) => handle_profile(&dbus, &supported.platform_profile, &cmd)?,
|
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::Anime(cmd)) => handle_anime(&dbus, &supported.anime_ctrl, &cmd)?,
|
||||||
Some(CliCommand::Bios(cmd)) => handle_bios_option(&dbus, &supported.rog_bios_ctrl, &cmd)?,
|
Some(CliCommand::Bios(cmd)) => handle_bios_option(&dbus, &supported.rog_bios_ctrl, &cmd)?,
|
||||||
None => {
|
None => {
|
||||||
@@ -190,62 +191,67 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_gfx(
|
fn do_gfx(command: GraphicsCommand) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
dbus: &RogDbusClient,
|
|
||||||
supported: &RogBiosSupportedFunctions,
|
|
||||||
command: GraphicsCommand,
|
|
||||||
) -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
if command.mode.is_none() && !command.get && !command.pow && !command.force || command.help {
|
if command.mode.is_none() && !command.get && !command.pow && !command.force || command.help {
|
||||||
println!("{}", command.self_usage());
|
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 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");
|
println!("You can not change modes until you turn dedicated/G-Sync off and reboot");
|
||||||
std::process::exit(-1);
|
std::process::exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("If anything fails check `journalctl -b -u asusd`\n");
|
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!("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");
|
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
|
err
|
||||||
})?;
|
})?;
|
||||||
let res = dbus.gfx_wait_changed()?;
|
|
||||||
match res {
|
loop {
|
||||||
GfxRequiredUserAction::Integrated => {
|
proxy.next_signal()?;
|
||||||
println!(
|
|
||||||
"You must change to Integrated before you can change to {}",
|
if let Ok(res) = rx.try_recv() {
|
||||||
<&str>::from(mode)
|
match res {
|
||||||
);
|
GfxRequiredUserAction::Integrated => {
|
||||||
}
|
println!(
|
||||||
GfxRequiredUserAction::Logout | GfxRequiredUserAction::Reboot => {
|
"You must change to Integrated before you can change to {}",
|
||||||
println!(
|
<&str>::from(mode)
|
||||||
"Graphics mode changed to {}. User action required is: {}",
|
);
|
||||||
<&str>::from(mode),
|
}
|
||||||
<&str>::from(&res)
|
GfxRequiredUserAction::Logout | GfxRequiredUserAction::Reboot => {
|
||||||
);
|
println!(
|
||||||
}
|
"Graphics mode changed to {}. User action required is: {}",
|
||||||
GfxRequiredUserAction::None => {
|
<&str>::from(mode),
|
||||||
println!("Graphics mode changed to {}", <&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 {
|
if command.get {
|
||||||
let res = dbus.proxies().gfx().gfx_get_mode()?;
|
let res = proxy.gfx_get_mode()?;
|
||||||
println!("Current graphics mode: {}", <&str>::from(res));
|
println!("Current graphics mode: {}", <&str>::from(res));
|
||||||
}
|
}
|
||||||
if command.pow {
|
if command.pow {
|
||||||
let res = dbus.proxies().gfx().gfx_get_pwr()?;
|
let res = proxy.gfx_get_pwr()?;
|
||||||
match res {
|
println!("Current power status: {}", <&str>::from(&res));
|
||||||
GfxPower::Active => {
|
|
||||||
println!("Current power status: {}", Red.paint(<&str>::from(&res)))
|
|
||||||
}
|
|
||||||
_ => println!("Current power status: {}", Green.paint(<&str>::from(&res))),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ rog_aura = { path = "../rog-aura" }
|
|||||||
rog_types = { path = "../rog-types" }
|
rog_types = { path = "../rog-types" }
|
||||||
rog_profiles = { path = "../rog-profiles" }
|
rog_profiles = { path = "../rog-profiles" }
|
||||||
rog_dbus = { path = "../rog-dbus" }
|
rog_dbus = { path = "../rog-dbus" }
|
||||||
supergfxctl = { path = "../supergfx" }
|
|
||||||
rusb = "^0.8"
|
rusb = "^0.8"
|
||||||
udev = "^0.6"
|
udev = "^0.6"
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use serde_derive::{Deserialize, Serialize};
|
|||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
use crate::config_old::*;
|
|
||||||
use crate::VERSION;
|
use crate::VERSION;
|
||||||
|
|
||||||
pub static CONFIG_PATH: &str = "/etc/asusd/asusd.conf";
|
pub static CONFIG_PATH: &str = "/etc/asusd/asusd.conf";
|
||||||
@@ -36,9 +35,6 @@ impl Config {
|
|||||||
config = Self::new();
|
config = Self::new();
|
||||||
} else if let Ok(data) = serde_json::from_str(&buf) {
|
} else if let Ok(data) = serde_json::from_str(&buf) {
|
||||||
config = data;
|
config = data;
|
||||||
} else if let Ok(data) = serde_json::from_str::<ConfigV352>(&buf) {
|
|
||||||
config = data.into_current();
|
|
||||||
info!("Updated config version to: {}", VERSION);
|
|
||||||
} else {
|
} else {
|
||||||
warn!("Could not deserialise {}", CONFIG_PATH);
|
warn!("Could not deserialise {}", CONFIG_PATH);
|
||||||
panic!("Please remove {} then restart asusd", CONFIG_PATH);
|
panic!("Please remove {} then restart asusd", CONFIG_PATH);
|
||||||
|
|||||||
@@ -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<String>,
|
|
||||||
#[serde(skip)]
|
|
||||||
pub curr_fan_mode: u8,
|
|
||||||
pub bat_charge_limit: u8,
|
|
||||||
pub power_profiles: BTreeMap<String, ProfileV317>,
|
|
||||||
}
|
|
||||||
|
|
||||||
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<GfxVendors>,
|
|
||||||
pub gfx_managed: bool,
|
|
||||||
pub gfx_vfio_enable: bool,
|
|
||||||
pub active_profile: String,
|
|
||||||
pub toggle_profiles: Vec<String>,
|
|
||||||
#[serde(skip)]
|
|
||||||
pub curr_fan_mode: u8,
|
|
||||||
pub bat_charge_limit: u8,
|
|
||||||
pub power_profiles: BTreeMap<String, ProfileV317>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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<()>,
|
|
||||||
}
|
|
||||||
@@ -40,19 +40,23 @@ impl GetSupported for CtrlPlatformProfile {
|
|||||||
|
|
||||||
fn get_supported() -> Self::A {
|
fn get_supported() -> Self::A {
|
||||||
if !Profile::is_platform_profile_supported() {
|
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.
|
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:
|
To enable profile support you require a kernel with the following patch applied:
|
||||||
https://lkml.org/lkml/2021/8/18/1022
|
https://lkml.org/lkml/2021/8/18/1022
|
||||||
"#);
|
"#
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if !FanCurves::is_fan_curves_supported() {
|
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.
|
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:
|
To enable fan-curve support you require a kernel with the following patch applied:
|
||||||
https://lkml.org/lkml/2021/8/20/232
|
https://lkml.org/lkml/2021/8/20/232
|
||||||
Please note that as of 24/08/2021 this is not final.
|
Please note that as of 24/08/2021 this is not final.
|
||||||
"#);
|
"#
|
||||||
|
);
|
||||||
}
|
}
|
||||||
PlatformProfileFunctions {
|
PlatformProfileFunctions {
|
||||||
platform_profile: Profile::is_platform_profile_supported(),
|
platform_profile: Profile::is_platform_profile_supported(),
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use daemon::ctrl_anime::config::AnimeConfig;
|
use daemon::ctrl_anime::config::AnimeConfig;
|
||||||
use daemon::ctrl_anime::zbus::CtrlAnimeZbus;
|
use daemon::ctrl_anime::zbus::CtrlAnimeZbus;
|
||||||
|
use daemon::ctrl_anime::*;
|
||||||
use daemon::ctrl_aura::config::AuraConfig;
|
use daemon::ctrl_aura::config::AuraConfig;
|
||||||
use daemon::ctrl_aura::controller::{
|
use daemon::ctrl_aura::controller::{
|
||||||
CtrlKbdLed, CtrlKbdLedReloader, CtrlKbdLedTask, CtrlKbdLedZbus,
|
CtrlKbdLed, CtrlKbdLedReloader, CtrlKbdLedTask, CtrlKbdLedZbus,
|
||||||
@@ -10,15 +11,11 @@ use daemon::ctrl_profiles::controller::CtrlPlatformTask;
|
|||||||
use daemon::{
|
use daemon::{
|
||||||
config::Config, ctrl_supported::SupportedFunctions, laptops::print_board_info, GetSupported,
|
config::Config, ctrl_supported::SupportedFunctions, laptops::print_board_info, GetSupported,
|
||||||
};
|
};
|
||||||
use daemon::{ctrl_anime::*};
|
|
||||||
use daemon::{
|
use daemon::{
|
||||||
ctrl_profiles::{controller::CtrlPlatformProfile, zbus::ProfileZbus},
|
ctrl_profiles::{controller::CtrlPlatformProfile, zbus::ProfileZbus},
|
||||||
laptops::LaptopLedData,
|
laptops::LaptopLedData,
|
||||||
};
|
};
|
||||||
|
|
||||||
use supergfxctl::config::GfxConfig;
|
|
||||||
use supergfxctl::controller::CtrlGraphics;
|
|
||||||
use supergfxctl::gfx_vendors::GfxVendors;
|
|
||||||
use ::zbus::{fdo, Connection, ObjectServer};
|
use ::zbus::{fdo, Connection, ObjectServer};
|
||||||
use daemon::{CtrlTask, Reloadable, ZbusAdd};
|
use daemon::{CtrlTask, Reloadable, ZbusAdd};
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
@@ -34,7 +31,6 @@ use daemon::ctrl_rog_bios::CtrlRogBios;
|
|||||||
use zvariant::ObjectPath;
|
use zvariant::ObjectPath;
|
||||||
|
|
||||||
static PROFILE_CONFIG_PATH: &str = "/etc/asusd/profile.conf";
|
static PROFILE_CONFIG_PATH: &str = "/etc/asusd/profile.conf";
|
||||||
static GFX_CONFIG_PATH: &str = "/etc/asusd/supergfx.conf";
|
|
||||||
|
|
||||||
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
pub fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut logger = env_logger::Builder::new();
|
let mut logger = env_logger::Builder::new();
|
||||||
@@ -86,10 +82,6 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
let config = Config::load();
|
let config = Config::load();
|
||||||
let config = Arc::new(Mutex::new(config));
|
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);
|
supported.add_to_server(&mut object_server);
|
||||||
|
|
||||||
match CtrlRogBios::new(config.clone()) {
|
match CtrlRogBios::new(config.clone()) {
|
||||||
@@ -105,7 +97,7 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match CtrlCharge::new(config.clone()) {
|
match CtrlCharge::new(config) {
|
||||||
Ok(mut ctrl) => {
|
Ok(mut ctrl) => {
|
||||||
// Do a reload of any settings
|
// Do a reload of any settings
|
||||||
ctrl.reload()
|
ctrl.reload()
|
||||||
@@ -173,48 +165,6 @@ fn start_daemon() -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
// TODO: implement messaging between threads to check fails
|
||||||
|
|
||||||
// Run tasks
|
// Run tasks
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
use rog_profiles::error::ProfileError;
|
use rog_profiles::error::ProfileError;
|
||||||
use rog_types::error::GraphicsError;
|
|
||||||
use supergfxctl::error::GfxError;
|
|
||||||
use std::convert::From;
|
use std::convert::From;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
@@ -19,7 +17,6 @@ pub enum RogError {
|
|||||||
MissingFunction(String),
|
MissingFunction(String),
|
||||||
MissingLedBrightNode(String, std::io::Error),
|
MissingLedBrightNode(String, std::io::Error),
|
||||||
ReloadFail(String),
|
ReloadFail(String),
|
||||||
GfxSwitching(GfxError),
|
|
||||||
Profiles(ProfileError),
|
Profiles(ProfileError),
|
||||||
Initramfs(String),
|
Initramfs(String),
|
||||||
Modprobe(String),
|
Modprobe(String),
|
||||||
@@ -44,7 +41,6 @@ impl fmt::Display for RogError {
|
|||||||
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),
|
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::Profiles(deets) => write!(f, "Profile error: {}", deets),
|
||||||
RogError::Initramfs(detail) => write!(f, "Initiramfs error: {}", detail),
|
RogError::Initramfs(detail) => write!(f, "Initiramfs error: {}", detail),
|
||||||
RogError::Modprobe(detail) => write!(f, "Modprobe 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 std::error::Error for RogError {}
|
||||||
|
|
||||||
impl From<GraphicsError> for RogError {
|
|
||||||
fn from(err: GraphicsError) -> Self {
|
|
||||||
match err {
|
|
||||||
GraphicsError::ParseVendor => RogError::GfxSwitching(GfxError::ParseVendor),
|
|
||||||
GraphicsError::ParsePower => RogError::GfxSwitching(GfxError::ParsePower),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<ProfileError> for RogError {
|
impl From<ProfileError> for RogError {
|
||||||
fn from(err: ProfileError) -> Self {
|
fn from(err: ProfileError) -> Self {
|
||||||
RogError::Profiles(err)
|
RogError::Profiles(err)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#![deny(unused_must_use)]
|
#![deny(unused_must_use)]
|
||||||
/// Configuration loading, saving
|
/// Configuration loading, saving
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub(crate) mod config_old;
|
|
||||||
/// Control of AniMe matrix display
|
/// Control of AniMe matrix display
|
||||||
pub mod ctrl_anime;
|
pub mod ctrl_anime;
|
||||||
/// Keyboard LED brightness control, RGB, and LED display modes
|
/// Keyboard LED brightness control, RGB, and LED display modes
|
||||||
|
|||||||
BIN
data/anime/asus/festive/Love u mom.gif
Executable file
BIN
data/anime/asus/festive/Love u mom.gif
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 153 KiB |
BIN
data/anime/asus/festive/Mother's day.gif
Executable file
BIN
data/anime/asus/festive/Mother's day.gif
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
BIN
data/anime/asus/music/Diamond.gif
Executable file
BIN
data/anime/asus/music/Diamond.gif
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 128 KiB |
BIN
data/anime/asus/trend/Hero.gif
Executable file
BIN
data/anime/asus/trend/Hero.gif
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 107 KiB |
@@ -1,10 +1,10 @@
|
|||||||
pub static DBUS_NAME: &str = "org.asuslinux.Daemon";
|
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_PATH: &str = "/org/asuslinux/Daemon";
|
||||||
pub static DBUS_IFACE: &str = "org.asuslinux.Daemon";
|
pub static DBUS_IFACE: &str = "org.asuslinux.Daemon";
|
||||||
|
|
||||||
pub mod zbus_anime;
|
pub mod zbus_anime;
|
||||||
pub mod zbus_charge;
|
pub mod zbus_charge;
|
||||||
pub mod zbus_gfx;
|
|
||||||
pub mod zbus_led;
|
pub mod zbus_led;
|
||||||
pub mod zbus_profile;
|
pub mod zbus_profile;
|
||||||
pub mod zbus_rogbios;
|
pub mod zbus_rogbios;
|
||||||
@@ -13,7 +13,6 @@ pub mod zbus_supported;
|
|||||||
use rog_anime::AnimePowerStates;
|
use rog_anime::AnimePowerStates;
|
||||||
use rog_aura::{AuraEffect, LedPowerStates};
|
use rog_aura::{AuraEffect, LedPowerStates};
|
||||||
use rog_profiles::Profile;
|
use rog_profiles::Profile;
|
||||||
use supergfxctl::gfx_vendors::{GfxRequiredUserAction, GfxVendors};
|
|
||||||
use std::sync::mpsc::{channel, Receiver};
|
use std::sync::mpsc::{channel, Receiver};
|
||||||
use zbus::{Connection, Result, SignalReceiver};
|
use zbus::{Connection, Result, SignalReceiver};
|
||||||
|
|
||||||
@@ -21,7 +20,6 @@ pub static VERSION: &str = env!("CARGO_PKG_VERSION");
|
|||||||
pub struct DbusProxies<'a> {
|
pub struct DbusProxies<'a> {
|
||||||
anime: zbus_anime::AnimeProxy<'a>,
|
anime: zbus_anime::AnimeProxy<'a>,
|
||||||
charge: zbus_charge::ChargeProxy<'a>,
|
charge: zbus_charge::ChargeProxy<'a>,
|
||||||
gfx: zbus_gfx::GfxProxy<'a>,
|
|
||||||
led: zbus_led::LedProxy<'a>,
|
led: zbus_led::LedProxy<'a>,
|
||||||
profile: zbus_profile::ProfileProxy<'a>,
|
profile: zbus_profile::ProfileProxy<'a>,
|
||||||
rog_bios: zbus_rogbios::RogBiosProxy<'a>,
|
rog_bios: zbus_rogbios::RogBiosProxy<'a>,
|
||||||
@@ -38,7 +36,6 @@ impl<'a> DbusProxies<'a> {
|
|||||||
anime: zbus_anime::AnimeProxy::new(&conn)?,
|
anime: zbus_anime::AnimeProxy::new(&conn)?,
|
||||||
led: zbus_led::LedProxy::new(&conn)?,
|
led: zbus_led::LedProxy::new(&conn)?,
|
||||||
charge: zbus_charge::ChargeProxy::new(&conn)?,
|
charge: zbus_charge::ChargeProxy::new(&conn)?,
|
||||||
gfx: zbus_gfx::GfxProxy::new(&conn)?,
|
|
||||||
profile: zbus_profile::ProfileProxy::new(&conn)?,
|
profile: zbus_profile::ProfileProxy::new(&conn)?,
|
||||||
rog_bios: zbus_rogbios::RogBiosProxy::new(&conn)?,
|
rog_bios: zbus_rogbios::RogBiosProxy::new(&conn)?,
|
||||||
supported: zbus_supported::SupportProxy::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.anime.proxy());
|
||||||
recv.receive_for(self.led.proxy());
|
recv.receive_for(self.led.proxy());
|
||||||
recv.receive_for(self.charge.proxy());
|
recv.receive_for(self.charge.proxy());
|
||||||
recv.receive_for(self.gfx.proxy());
|
|
||||||
recv.receive_for(self.profile.proxy());
|
recv.receive_for(self.profile.proxy());
|
||||||
recv.receive_for(self.rog_bios.proxy());
|
recv.receive_for(self.rog_bios.proxy());
|
||||||
recv.receive_for(self.supported.proxy());
|
recv.receive_for(self.supported.proxy());
|
||||||
@@ -67,10 +63,6 @@ impl<'a> DbusProxies<'a> {
|
|||||||
&self.charge
|
&self.charge
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gfx(&self) -> &zbus_gfx::GfxProxy<'a> {
|
|
||||||
&self.gfx
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn led(&self) -> &zbus_led::LedProxy<'a> {
|
pub fn led(&self) -> &zbus_led::LedProxy<'a> {
|
||||||
&self.led
|
&self.led
|
||||||
}
|
}
|
||||||
@@ -90,8 +82,6 @@ impl<'a> DbusProxies<'a> {
|
|||||||
|
|
||||||
// Signals separated out
|
// Signals separated out
|
||||||
pub struct Signals {
|
pub struct Signals {
|
||||||
pub gfx_vendor: Receiver<GfxVendors>,
|
|
||||||
pub gfx_action: Receiver<GfxRequiredUserAction>,
|
|
||||||
pub profile: Receiver<Profile>,
|
pub profile: Receiver<Profile>,
|
||||||
pub led_mode: Receiver<AuraEffect>,
|
pub led_mode: Receiver<AuraEffect>,
|
||||||
pub led_power_state: Receiver<LedPowerStates>,
|
pub led_power_state: Receiver<LedPowerStates>,
|
||||||
@@ -105,16 +95,6 @@ impl Signals {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(proxies: &DbusProxies) -> Result<Self> {
|
pub fn new(proxies: &DbusProxies) -> Result<Self> {
|
||||||
Ok(Signals {
|
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: {
|
profile: {
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
proxies.profile.connect_notify_profile(tx)?;
|
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.anime.proxy());
|
||||||
recv.receive_for(self.proxies.led.proxy());
|
recv.receive_for(self.proxies.led.proxy());
|
||||||
recv.receive_for(self.proxies.charge.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.profile.proxy());
|
||||||
recv.receive_for(self.proxies.rog_bios.proxy());
|
recv.receive_for(self.proxies.rog_bios.proxy());
|
||||||
recv.receive_for(self.proxies.supported.proxy());
|
recv.receive_for(self.proxies.supported.proxy());
|
||||||
recv
|
recv
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* GFX
|
|
||||||
*/
|
|
||||||
pub fn gfx_wait_changed(&self) -> Result<GfxRequiredUserAction> {
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {}
|
|
||||||
@@ -8,6 +8,4 @@ pub static DBUS_IFACE: &str = "org.asuslinux.Daemon";
|
|||||||
|
|
||||||
pub mod supported;
|
pub mod supported;
|
||||||
|
|
||||||
pub mod error;
|
|
||||||
|
|
||||||
pub static VERSION: &str = env!("CARGO_PKG_VERSION");
|
pub static VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||||
|
|||||||
@@ -12,6 +12,26 @@ keywords = ["graphics", "nvidia", "switching"]
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
exclude = ["data"]
|
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]
|
[dependencies]
|
||||||
serde = "^1.0"
|
serde = "^1.0"
|
||||||
serde_derive = "^1.0"
|
serde_derive = "^1.0"
|
||||||
@@ -23,4 +43,7 @@ zvariant = "^2.8"
|
|||||||
zvariant_derive = "^2.8"
|
zvariant_derive = "^2.8"
|
||||||
logind-zbus = "^0.7.1"
|
logind-zbus = "^0.7.1"
|
||||||
|
|
||||||
sysfs-class = "^0.1.2"
|
sysfs-class = "^0.1.2"
|
||||||
|
|
||||||
|
env_logger = { version = "^0.8", optional = true }
|
||||||
|
gumdrop = { version = "^0.8", optional = true }
|
||||||
74
supergfx/Makefile
Normal file
74
supergfx/Makefile
Normal file
@@ -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
|
||||||
26
supergfx/data/org.supergfxctl.Daemon.conf
Normal file
26
supergfx/data/org.supergfxctl.Daemon.conf
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<!DOCTYPE busconfig PUBLIC
|
||||||
|
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||||
|
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||||
|
<busconfig>
|
||||||
|
<policy group="adm">
|
||||||
|
<allow send_destination="org.supergfxctl.Daemon"/>
|
||||||
|
<allow receive_sender="org.supergfxctl.Daemon"/>
|
||||||
|
</policy>
|
||||||
|
<policy group="sudo">
|
||||||
|
<allow send_destination="org.supergfxctl.Daemon"/>
|
||||||
|
<allow receive_sender="org.supergfxctl.Daemon"/>
|
||||||
|
</policy>
|
||||||
|
<policy group="users">
|
||||||
|
<allow send_destination="org.supergfxctl.Daemon"/>
|
||||||
|
<allow receive_sender="org.supergfxctl.Daemon"/>
|
||||||
|
</policy>
|
||||||
|
<policy group="wheel">
|
||||||
|
<allow send_destination="org.supergfxctl.Daemon"/>
|
||||||
|
<allow receive_sender="org.supergfxctl.Daemon"/>
|
||||||
|
</policy>
|
||||||
|
<policy user="root">
|
||||||
|
<allow own="org.supergfxctl.Daemon"/>
|
||||||
|
<allow send_destination="org.supergfxctl.Daemon"/>
|
||||||
|
<allow receive_sender="org.supergfxctl.Daemon"/>
|
||||||
|
</policy>
|
||||||
|
</busconfig>
|
||||||
16
supergfx/data/supergfxd.service
Normal file
16
supergfx/data/supergfxd.service
Normal file
@@ -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
|
||||||
105
supergfx/src/cli.rs
Normal file
105
supergfx/src/cli.rs
Normal file
@@ -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: <nvidia, hybrid, compute, integrated>"
|
||||||
|
)]
|
||||||
|
mode: Option<GfxVendors>,
|
||||||
|
#[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<dyn std::error::Error>> {
|
||||||
|
let args: Vec<String> = 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<dyn std::error::Error>> {
|
||||||
|
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(())
|
||||||
|
}
|
||||||
105
supergfx/src/daemon.rs
Normal file
105
supergfx/src/daemon.rs
Normal file
@@ -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<dyn std::error::Error>> {
|
||||||
|
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<dyn Error>> {
|
||||||
|
// 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<Mutex<GfxConfig>>,
|
||||||
|
) -> 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(())
|
||||||
|
}
|
||||||
@@ -69,4 +69,4 @@ impl From<std::io::Error> for GfxError {
|
|||||||
fn from(err: std::io::Error) -> Self {
|
fn from(err: std::io::Error) -> Self {
|
||||||
GfxError::Io(err)
|
GfxError::Io(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
pub mod error;
|
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod gfx_vendors;
|
|
||||||
pub mod controller;
|
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
|
/// 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
|
/// such as the G-Sync mode available on some ASUS ROG laptops
|
||||||
pub(crate) mod special;
|
pub mod special;
|
||||||
pub mod zbus;
|
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"];
|
const NVIDIA_DRIVERS: [&str; 4] = ["nvidia_drm", "nvidia_modeset", "nvidia_uvm", "nvidia"];
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ use crate::error::GfxError;
|
|||||||
static ASUS_SWITCH_GRAPHIC_MODE: &str =
|
static ASUS_SWITCH_GRAPHIC_MODE: &str =
|
||||||
"/sys/firmware/efi/efivars/AsusSwitchGraphicMode-607005d5-3f75-4b2e-98f0-85ba66797a3e";
|
"/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()
|
Path::new(ASUS_SWITCH_GRAPHIC_MODE).exists()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_asus_gsync_gfx_mode() -> Result<i8, GfxError> {
|
pub fn get_asus_gsync_gfx_mode() -> Result<i8, GfxError> {
|
||||||
let path = ASUS_SWITCH_GRAPHIC_MODE;
|
let path = ASUS_SWITCH_GRAPHIC_MODE;
|
||||||
let mut file = OpenOptions::new()
|
let mut file = OpenOptions::new()
|
||||||
.read(true)
|
.read(true)
|
||||||
@@ -22,4 +22,4 @@ pub(crate) fn get_asus_gsync_gfx_mode() -> Result<i8, GfxError> {
|
|||||||
|
|
||||||
let idx = data.len() - 1;
|
let idx = data.len() - 1;
|
||||||
Ok(data[idx] as i8)
|
Ok(data[idx] as i8)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
|
use ::zbus::dbus_interface;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use zvariant::ObjectPath;
|
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;
|
use super::controller::CtrlGraphics;
|
||||||
|
|
||||||
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
#[dbus_interface(name = "org.supergfxctl.Daemon")]
|
||||||
impl CtrlGraphics {
|
impl CtrlGraphics {
|
||||||
fn vendor(&self) -> zbus::fdo::Result<GfxVendors> {
|
fn vendor(&self) -> zbus::fdo::Result<GfxVendors> {
|
||||||
self.get_gfx_mode().map_err(|err| {
|
self.get_gfx_mode().map_err(|err| {
|
||||||
@@ -28,10 +31,13 @@ impl CtrlGraphics {
|
|||||||
error!("GFX: {}", err);
|
error!("GFX: {}", err);
|
||||||
zbus::fdo::Error::Failed(format!("GFX fail: {}", err))
|
zbus::fdo::Error::Failed(format!("GFX fail: {}", err))
|
||||||
})?;
|
})?;
|
||||||
self.notify_gfx(&vendor)
|
|
||||||
.unwrap_or_else(|err| warn!("GFX: {}", err));
|
|
||||||
self.notify_action(&msg)
|
self.notify_action(&msg)
|
||||||
.unwrap_or_else(|err| warn!("GFX: {}", err));
|
.unwrap_or_else(|err| warn!("GFX: {}", err));
|
||||||
|
|
||||||
|
self.notify_gfx(&vendor)
|
||||||
|
.unwrap_or_else(|err| warn!("GFX: {}", err));
|
||||||
|
|
||||||
Ok(msg)
|
Ok(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +51,7 @@ impl CtrlGraphics {
|
|||||||
impl CtrlGraphics {
|
impl CtrlGraphics {
|
||||||
pub fn add_to_server(self, server: &mut zbus::ObjectServer) {
|
pub fn add_to_server(self, server: &mut zbus::ObjectServer) {
|
||||||
server
|
server
|
||||||
.at(&ObjectPath::from_str_unchecked("/org/asuslinux/Gfx"), self)
|
.at(&ObjectPath::from_str_unchecked(DBUS_IFACE_PATH), self)
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
warn!("GFX: CtrlGraphics: add_to_server {}", err);
|
warn!("GFX: CtrlGraphics: add_to_server {}", err);
|
||||||
err
|
err
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//! # DBus interface proxy for: `org.asuslinux.Gfx`
|
//! # DBus interface proxy for: `org.asuslinux.Gfx`
|
||||||
//!
|
//!
|
||||||
//! This code was generated by `zbus-xmlgen` `1.0.0` from DBus introspection data.
|
//! 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.
|
//! 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.
|
//! …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, Message, Result};
|
||||||
use zbus::{dbus_proxy, Connection, Result};
|
|
||||||
|
|
||||||
#[dbus_proxy(
|
use crate::{
|
||||||
interface = "org.asuslinux.Daemon",
|
gfx_vendors::{GfxPower, GfxRequiredUserAction, GfxVendors},
|
||||||
default_path = "/org/asuslinux/Gfx"
|
DBUS_IFACE_PATH,
|
||||||
)]
|
};
|
||||||
|
|
||||||
|
#[dbus_proxy(interface = "org.supergfxctl.Daemon")]
|
||||||
trait Daemon {
|
trait Daemon {
|
||||||
/// Power method
|
/// Power method
|
||||||
fn power(&self) -> zbus::Result<GfxPower>;
|
fn power(&self) -> zbus::Result<GfxPower>;
|
||||||
@@ -47,12 +48,25 @@ trait Daemon {
|
|||||||
fn notify_gfx(&self, vendor: GfxVendors) -> zbus::Result<()>;
|
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> {
|
impl<'a> GfxProxy<'a> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(conn: &Connection) -> Result<Self> {
|
pub fn new(conn: &Connection) -> Result<Self> {
|
||||||
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<Self> {
|
||||||
|
let proxy = DaemonProxy::new_for(conn, destination, path)?;
|
||||||
|
Ok(GfxProxy(proxy))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn new_for_owned(conn: Connection, destination: String, path: String) -> Result<Self> {
|
||||||
|
let proxy = DaemonProxy::new_for_owned(conn, destination, path)?;
|
||||||
|
Ok(GfxProxy(proxy))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -95,4 +109,9 @@ impl<'a> GfxProxy<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn next_signal(&self) -> Result<Option<Message>> {
|
||||||
|
self.0.next_signal()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user