mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
343 lines
11 KiB
Rust
343 lines
11 KiB
Rust
use async_trait::async_trait;
|
|
use log::warn;
|
|
use rog_aura::{AuraEffect, LedBrightness, LedPowerStates};
|
|
use zbus::{dbus_interface, Connection, SignalContext};
|
|
|
|
use super::controller::CtrlKbdLedZbus;
|
|
|
|
#[async_trait]
|
|
impl crate::ZbusAdd for CtrlKbdLedZbus {
|
|
async fn add_to_server(self, server: &mut Connection) {
|
|
Self::add_to_server_helper(self, "/org/asuslinux/Led", server).await;
|
|
}
|
|
}
|
|
|
|
/// The main interface for changing, reading, or notfying signals
|
|
///
|
|
/// LED commands are split between Brightness, Modes, Per-Key
|
|
#[dbus_interface(name = "org.asuslinux.Daemon")]
|
|
impl CtrlKbdLedZbus {
|
|
/// Set the keyboard brightness level (0-3)
|
|
async fn set_brightness(&mut self, brightness: LedBrightness) {
|
|
if let Ok(ctrl) = self.0.try_lock() {
|
|
ctrl.set_brightness(brightness)
|
|
.map_err(|err| warn!("{}", err))
|
|
.ok();
|
|
}
|
|
}
|
|
|
|
/// Set the keyboard LED to enabled while the device is awake
|
|
async fn set_boot_enabled(
|
|
&mut self,
|
|
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
enabled: bool,
|
|
) {
|
|
let mut states = None;
|
|
if let Ok(mut ctrl) = self.0.try_lock() {
|
|
ctrl.config.boot_anim_enabled = enabled;
|
|
ctrl.config.write();
|
|
|
|
ctrl.set_power_states(&ctrl.config)
|
|
.map_err(|err| warn!("{}", err))
|
|
.ok();
|
|
|
|
states = Some(LedPowerStates {
|
|
boot_anim: ctrl.config.boot_anim_enabled,
|
|
sleep_anim: ctrl.config.sleep_anim_enabled,
|
|
all_leds: ctrl.config.all_leds_enabled,
|
|
keys_leds: ctrl.config.keys_leds_enabled,
|
|
side_leds: ctrl.config.side_leds_enabled,
|
|
});
|
|
}
|
|
// Need to pull state out like this due to MutexGuard
|
|
if let Some(states) = states {
|
|
Self::notify_power_states(&ctxt, &states)
|
|
.await
|
|
.unwrap_or_else(|err| warn!("{}", err));
|
|
}
|
|
}
|
|
|
|
/// Set the keyboard LED suspend animation to enabled while the device is suspended
|
|
async fn set_sleep_enabled(
|
|
&mut self,
|
|
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
enabled: bool,
|
|
) {
|
|
let mut states = None;
|
|
if let Ok(mut ctrl) = self.0.try_lock() {
|
|
ctrl.config.sleep_anim_enabled = enabled;
|
|
ctrl.config.write();
|
|
|
|
ctrl.set_power_states(&ctrl.config)
|
|
.map_err(|err| warn!("{}", err))
|
|
.ok();
|
|
|
|
states = Some(LedPowerStates {
|
|
boot_anim: ctrl.config.boot_anim_enabled,
|
|
sleep_anim: ctrl.config.sleep_anim_enabled,
|
|
all_leds: ctrl.config.all_leds_enabled,
|
|
keys_leds: ctrl.config.keys_leds_enabled,
|
|
side_leds: ctrl.config.side_leds_enabled,
|
|
});
|
|
}
|
|
if let Some(states) = states {
|
|
Self::notify_power_states(&ctxt, &states)
|
|
.await
|
|
.unwrap_or_else(|err| warn!("{}", err));
|
|
}
|
|
}
|
|
|
|
/// Set all the keyboard LEDs (keys and side) to enabled
|
|
async fn set_all_leds_enabled(
|
|
&mut self,
|
|
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
enabled: bool,
|
|
) {
|
|
let mut states = None;
|
|
if let Ok(mut ctrl) = self.0.try_lock() {
|
|
ctrl.config.all_leds_enabled = enabled;
|
|
ctrl.config.keys_leds_enabled = enabled;
|
|
ctrl.config.side_leds_enabled = enabled;
|
|
ctrl.config.write();
|
|
|
|
ctrl.set_power_states(&ctrl.config)
|
|
.map_err(|err| warn!("{}", err))
|
|
.ok();
|
|
|
|
states = Some(LedPowerStates {
|
|
boot_anim: ctrl.config.boot_anim_enabled,
|
|
sleep_anim: ctrl.config.sleep_anim_enabled,
|
|
all_leds: ctrl.config.all_leds_enabled,
|
|
keys_leds: ctrl.config.keys_leds_enabled,
|
|
side_leds: ctrl.config.side_leds_enabled,
|
|
});
|
|
}
|
|
// Need to pull state out like this due to MutexGuard
|
|
if let Some(states) = states {
|
|
Self::notify_power_states(&ctxt, &states)
|
|
.await
|
|
.unwrap_or_else(|err| warn!("{}", err));
|
|
}
|
|
}
|
|
|
|
/// Set the keyboard keys LEDs to enabled
|
|
async fn set_keys_leds_enabled(
|
|
&mut self,
|
|
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
enabled: bool,
|
|
) {
|
|
let mut states = None;
|
|
if let Ok(mut ctrl) = self.0.try_lock() {
|
|
ctrl.config.keys_leds_enabled = enabled;
|
|
ctrl.config.write();
|
|
|
|
ctrl.set_power_states(&ctrl.config)
|
|
.map_err(|err| warn!("{}", err))
|
|
.ok();
|
|
|
|
states = Some(LedPowerStates {
|
|
boot_anim: ctrl.config.boot_anim_enabled,
|
|
sleep_anim: ctrl.config.sleep_anim_enabled,
|
|
all_leds: ctrl.config.all_leds_enabled,
|
|
keys_leds: ctrl.config.keys_leds_enabled,
|
|
side_leds: ctrl.config.side_leds_enabled,
|
|
});
|
|
}
|
|
// Need to pull state out like this due to MutexGuard
|
|
if let Some(states) = states {
|
|
Self::notify_power_states(&ctxt, &states)
|
|
.await
|
|
.unwrap_or_else(|err| warn!("{}", err));
|
|
}
|
|
}
|
|
|
|
/// Set the keyboard side LEDs to enabled
|
|
async fn set_side_leds_enabled(
|
|
&mut self,
|
|
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
enabled: bool,
|
|
) {
|
|
let mut states = None;
|
|
if let Ok(mut ctrl) = self.0.try_lock() {
|
|
ctrl.config.side_leds_enabled = enabled;
|
|
ctrl.config.write();
|
|
|
|
ctrl.set_power_states(&ctrl.config)
|
|
.map_err(|err| warn!("{}", err))
|
|
.ok();
|
|
|
|
states = Some(LedPowerStates {
|
|
boot_anim: ctrl.config.boot_anim_enabled,
|
|
sleep_anim: ctrl.config.sleep_anim_enabled,
|
|
all_leds: ctrl.config.all_leds_enabled,
|
|
keys_leds: ctrl.config.keys_leds_enabled,
|
|
side_leds: ctrl.config.side_leds_enabled,
|
|
});
|
|
}
|
|
// Need to pull state out like this due to MutexGuard
|
|
if let Some(states) = states {
|
|
Self::notify_power_states(&ctxt, &states)
|
|
.await
|
|
.unwrap_or_else(|err| warn!("{}", err));
|
|
}
|
|
}
|
|
|
|
async fn set_led_mode(
|
|
&mut self,
|
|
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
|
effect: AuraEffect,
|
|
) {
|
|
let mut led = None;
|
|
if let Ok(mut ctrl) = self.0.try_lock() {
|
|
match ctrl.do_command(effect) {
|
|
Ok(_) => {
|
|
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
|
led = Some(mode.clone());
|
|
}
|
|
}
|
|
Err(err) => {
|
|
warn!("{}", err);
|
|
}
|
|
}
|
|
}
|
|
if let Some(led) = led {
|
|
Self::notify_led(&ctxt, led)
|
|
.await
|
|
.unwrap_or_else(|err| warn!("{}", err));
|
|
}
|
|
}
|
|
|
|
async fn next_led_mode(&self, #[zbus(signal_context)] ctxt: SignalContext<'_>) {
|
|
let mut led = None;
|
|
if let Ok(mut ctrl) = self.0.lock() {
|
|
ctrl.toggle_mode(false)
|
|
.unwrap_or_else(|err| warn!("{}", err));
|
|
|
|
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
|
led = Some(mode.clone());
|
|
}
|
|
}
|
|
if let Some(led) = led {
|
|
Self::notify_led(&ctxt, led)
|
|
.await
|
|
.unwrap_or_else(|err| warn!("{}", err));
|
|
}
|
|
}
|
|
|
|
async fn prev_led_mode(&self, #[zbus(signal_context)] ctxt: SignalContext<'_>) {
|
|
let mut led = None;
|
|
if let Ok(mut ctrl) = self.0.lock() {
|
|
ctrl.toggle_mode(true)
|
|
.unwrap_or_else(|err| warn!("{}", err));
|
|
|
|
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
|
led = Some(mode.clone());
|
|
}
|
|
}
|
|
if let Some(led) = led {
|
|
Self::notify_led(&ctxt, led)
|
|
.await
|
|
.unwrap_or_else(|err| warn!("{}", err));
|
|
}
|
|
}
|
|
|
|
async fn next_led_brightness(&self) {
|
|
if let Ok(mut ctrl) = self.0.try_lock() {
|
|
ctrl.next_brightness()
|
|
.unwrap_or_else(|err| warn!("{}", err));
|
|
}
|
|
}
|
|
|
|
async fn prev_led_brightness(&self) {
|
|
if let Ok(mut ctrl) = self.0.try_lock() {
|
|
ctrl.prev_brightness()
|
|
.unwrap_or_else(|err| warn!("{}", err));
|
|
}
|
|
}
|
|
|
|
#[dbus_interface(property)]
|
|
async fn boot_enabled(&self) -> bool {
|
|
if let Ok(ctrl) = self.0.try_lock() {
|
|
return ctrl.config.boot_anim_enabled;
|
|
}
|
|
true
|
|
}
|
|
|
|
#[dbus_interface(property)]
|
|
async fn sleep_enabled(&self) -> bool {
|
|
if let Ok(ctrl) = self.0.try_lock() {
|
|
return ctrl.config.sleep_anim_enabled;
|
|
}
|
|
true
|
|
}
|
|
|
|
#[dbus_interface(property)]
|
|
async fn all_leds_enabled(&self) -> bool {
|
|
if let Ok(ctrl) = self.0.try_lock() {
|
|
return ctrl.config.all_leds_enabled;
|
|
}
|
|
true
|
|
}
|
|
|
|
#[dbus_interface(property)]
|
|
async fn keys_leds_enabled(&self) -> bool {
|
|
if let Ok(ctrl) = self.0.try_lock() {
|
|
return ctrl.config.keys_leds_enabled;
|
|
}
|
|
true
|
|
}
|
|
|
|
#[dbus_interface(property)]
|
|
fn side_leds_enabled(&self) -> bool {
|
|
if let Ok(ctrl) = self.0.try_lock() {
|
|
return ctrl.config.side_leds_enabled;
|
|
}
|
|
true
|
|
}
|
|
|
|
/// Return the current mode data
|
|
#[dbus_interface(property)]
|
|
async fn led_mode(&self) -> String {
|
|
if let Ok(ctrl) = self.0.try_lock() {
|
|
if let Some(mode) = ctrl.config.builtins.get(&ctrl.config.current_mode) {
|
|
if let Ok(json) = serde_json::to_string(&mode) {
|
|
return json;
|
|
}
|
|
}
|
|
}
|
|
warn!("SetKeyBacklight could not deserialise");
|
|
"SetKeyBacklight could not deserialise".to_string()
|
|
}
|
|
|
|
/// Return a list of available modes
|
|
#[dbus_interface(property)]
|
|
async fn led_modes(&self) -> String {
|
|
if let Ok(ctrl) = self.0.try_lock() {
|
|
if let Ok(json) = serde_json::to_string(&ctrl.config.builtins) {
|
|
return json;
|
|
}
|
|
}
|
|
warn!("SetKeyBacklight could not deserialise");
|
|
"SetKeyBacklight could not serialise".to_string()
|
|
}
|
|
|
|
/// Return the current LED brightness
|
|
#[dbus_interface(property)]
|
|
async fn led_brightness(&self) -> i8 {
|
|
if let Ok(ctrl) = self.0.try_lock() {
|
|
return ctrl.get_brightness().map(|n| n as i8).unwrap_or(-1);
|
|
}
|
|
warn!("SetKeyBacklight could not serialise");
|
|
-1
|
|
}
|
|
|
|
#[dbus_interface(signal)]
|
|
async fn notify_led(signal_ctxt: &SignalContext<'_>, data: AuraEffect) -> zbus::Result<()>;
|
|
|
|
#[dbus_interface(signal)]
|
|
async fn notify_power_states(
|
|
signal_ctxt: &SignalContext<'_>,
|
|
data: &LedPowerStates,
|
|
) -> zbus::Result<()>;
|
|
}
|