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:
@@ -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"
|
||||
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
|
||||
7
supergfx/data/90-asusd-nvidia-pm.rules
Normal file
7
supergfx/data/90-asusd-nvidia-pm.rules
Normal file
@@ -0,0 +1,7 @@
|
||||
# Enable runtime PM for NVIDIA VGA/3D controller devices on driver bind
|
||||
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="auto"
|
||||
ACTION=="bind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="auto"
|
||||
|
||||
# Disable runtime PM for NVIDIA VGA/3D controller devices on driver unbind
|
||||
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030000", TEST=="power/control", ATTR{power/control}="on"
|
||||
ACTION=="unbind", SUBSYSTEM=="pci", ATTR{vendor}=="0x10de", ATTR{class}=="0x030200", TEST=="power/control", ATTR{power/control}="on"
|
||||
4
supergfx/data/90-nvidia-screen-G05.conf
Normal file
4
supergfx/data/90-nvidia-screen-G05.conf
Normal file
@@ -0,0 +1,4 @@
|
||||
Section "ServerLayout"
|
||||
Identifier "layout"
|
||||
Option "AllowNVIDIAGPUScreens"
|
||||
EndSection
|
||||
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 {
|
||||
GfxError::Io(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"];
|
||||
|
||||
|
||||
@@ -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<i8, GfxError> {
|
||||
pub fn get_asus_gsync_gfx_mode() -> Result<i8, GfxError> {
|
||||
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<i8, GfxError> {
|
||||
|
||||
let idx = data.len() - 1;
|
||||
Ok(data[idx] as i8)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<GfxVendors> {
|
||||
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
|
||||
117
supergfx/src/zbus_proxy.rs
Normal file
117
supergfx/src/zbus_proxy.rs
Normal file
@@ -0,0 +1,117 @@
|
||||
//! # DBus interface proxy for: `org.asuslinux.Gfx`
|
||||
//!
|
||||
//! This code was generated by `zbus-xmlgen` `1.0.0` from DBus introspection data.
|
||||
//! Source: `Interface '/org/supergfxctl/Gfx' from service 'org.asuslinux.Daemon' on system bus`.
|
||||
//!
|
||||
//! You may prefer to adapt it, instead of using it verbatim.
|
||||
//!
|
||||
//! More information can be found in the
|
||||
//! [Writing a client proxy](https://zeenix.pages.freedesktop.org/zbus/client.html)
|
||||
//! section of the zbus documentation.
|
||||
//!
|
||||
//! This DBus object implements
|
||||
//! [standard DBus interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
|
||||
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
|
||||
//!
|
||||
//! * [`zbus::fdo::PropertiesProxy`]
|
||||
//! * [`zbus::fdo::IntrospectableProxy`]
|
||||
//! * [`zbus::fdo::PeerProxy`]
|
||||
//!
|
||||
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
|
||||
|
||||
use std::sync::mpsc::{Receiver, Sender};
|
||||
|
||||
use zbus::{dbus_proxy, Connection, Message, Result};
|
||||
|
||||
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<GfxPower>;
|
||||
|
||||
/// SetVendor method
|
||||
fn set_vendor(&self, vendor: &GfxVendors) -> zbus::Result<GfxRequiredUserAction>;
|
||||
|
||||
/// Vendor method
|
||||
fn vendor(&self) -> zbus::Result<GfxVendors>;
|
||||
|
||||
/// NotifyAction signal
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_action(&self, action: GfxRequiredUserAction) -> zbus::Result<()>;
|
||||
|
||||
/// NotifyGfx signal
|
||||
#[dbus_proxy(signal)]
|
||||
fn notify_gfx(&self, vendor: GfxVendors) -> zbus::Result<()>;
|
||||
}
|
||||
|
||||
pub struct GfxProxy<'a>(pub DaemonProxy<'a>);
|
||||
|
||||
impl<'a> GfxProxy<'a> {
|
||||
#[inline]
|
||||
pub fn new(conn: &Connection) -> Result<Self> {
|
||||
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]
|
||||
pub fn proxy(&self) -> &DaemonProxy<'a> {
|
||||
&self.0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn gfx_get_pwr(&self) -> Result<GfxPower> {
|
||||
self.0.power()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn gfx_get_mode(&self) -> Result<GfxVendors> {
|
||||
self.0.vendor()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn gfx_write_mode(&self, vendor: &GfxVendors) -> Result<GfxRequiredUserAction> {
|
||||
self.0.set_vendor(vendor)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn connect_notify_action(
|
||||
&self,
|
||||
send: Sender<GfxRequiredUserAction>,
|
||||
) -> zbus::fdo::Result<()> {
|
||||
self.0.connect_notify_action(move |data| {
|
||||
send.send(data)
|
||||
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn connect_notify_gfx(&self, send: Sender<GfxVendors>) -> zbus::fdo::Result<()> {
|
||||
self.0.connect_notify_gfx(move |data| {
|
||||
send.send(data)
|
||||
.map_err(|err| zbus::fdo::Error::Failed(err.to_string()))?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn next_signal(&self) -> Result<Option<Message>> {
|
||||
self.0.next_signal()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user