Rebuild of LED power control

This commit is contained in:
Luke D. Jones
2022-07-14 21:18:53 +12:00
parent 51656dc13f
commit 535e104ccc
9 changed files with 393 additions and 316 deletions

View File

@@ -2,6 +2,53 @@ use gumdrop::Options;
use rog_aura::{error::Error, AuraEffect, AuraModeNum, AuraZone, Colour, Direction, Speed};
use std::str::FromStr;
#[derive(Options)]
pub struct LedPowerCommand {
#[options(help = "print help message")]
pub help: bool,
#[options(command)]
pub command: Option<SetAuraEnabled>,
}
#[derive(Options)]
pub enum SetAuraEnabled {
#[options(help = "set <keyboard, logo, lightbar> to enabled while the device is booting")]
Boot(AuraEnabled),
#[options(help = "set <keyboard, logo, lightbar> to animate while the device is suspended")]
Sleep(AuraEnabled),
#[options(help = "set <keyboard, logo, lightbar> to enabled while device is awake")]
Awake(AuraEnabled),
#[options(help = "set <keyboard, logo, lightbar> to animate while the device is shutdown")]
Shutdown(AuraEnabled),
}
#[derive(Debug, Clone, Default, Options)]
pub struct AuraEnabled {
#[options(help = "print help message")]
pub help: bool,
#[options(meta = "", help = "<true/false>")]
pub keyboard: Option<bool>,
#[options(meta = "", help = "<true/false>")]
pub logo: Option<bool>,
#[options(meta = "", help = "<true/false>")]
pub lightbar: Option<bool>,
}
// impl FromStr for AuraEnabled {
// type Err = Error;
// fn from_str(s: &str) -> Result<Self, Self::Err> {
// let s = s.to_lowercase();
// dbg!(s);
// Ok(Self {
// help: false,
// keyboard: None,
// logo: None,
// lightbar: None,
// })
// }
// }
#[derive(Options)]
pub struct LedBrightness {
level: Option<u32>,
@@ -57,6 +104,7 @@ pub struct SingleSpeed {
)]
pub zone: AuraZone,
}
#[derive(Debug, Clone, Options, Default)]
pub struct SingleSpeedDirection {
#[options(help = "print help message")]
@@ -306,7 +354,6 @@ impl From<&SetAuraBuiltin> for AuraEffect {
data.mode = AuraModeNum::Flash;
data
}
_ => AuraEffect::default(),
}
}
}

View File

@@ -1,6 +1,6 @@
use crate::{
anime_cli::AnimeCommand,
aura_cli::{LedBrightness, SetAuraBuiltin},
aura_cli::{LedBrightness, LedPowerCommand, SetAuraBuiltin},
profiles_cli::{FanCurveCommand, ProfileCommand},
};
use gumdrop::Options;
@@ -29,6 +29,8 @@ pub struct CliStart {
pub enum CliCommand {
#[options(help = "Set the keyboard lighting from built-in modes")]
LedMode(LedModeCommand),
#[options(help = "Set the keyboard lighting from built-in modes")]
LedPower(LedPowerCommand),
#[options(help = "Set or select platform_profile")]
Profile(ProfileCommand),
#[options(help = "Set, select, or modify fan curves if supported")]
@@ -49,25 +51,6 @@ pub struct LedModeCommand {
pub next_mode: bool,
#[options(help = "switch to previous aura mode")]
pub prev_mode: bool,
#[options(
meta = "",
help = "set the keyboard LED to enabled while the device is awake"
)]
pub boot_enable: Option<bool>,
#[options(
meta = "",
help = "set the keyboard LED suspend animation to enabled while the device is suspended"
)]
pub sleep_enable: Option<bool>,
#[options(
meta = "",
help = "set the full keyboard LEDs (keys and side) to enabled"
)]
pub all_leds_enable: Option<bool>,
#[options(meta = "", help = "set the keyboard keys LEDs to enabled")]
pub keys_leds_enable: Option<bool>,
#[options(meta = "", help = "set the keyboard side LEDs to enabled")]
pub side_leds_enable: Option<bool>,
#[options(command)]
pub command: Option<SetAuraBuiltin>,
}

View File

@@ -2,11 +2,13 @@ use std::process::Command;
use std::thread::sleep;
use std::{env::args, path::Path};
use aura_cli::LedPowerCommand;
use gumdrop::{Opt, Options};
use anime_cli::{AnimeActions, AnimeCommand};
use profiles_cli::{FanCurveCommand, ProfileCommand};
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, Vec2};
use rog_aura::usb::AuraControl;
use rog_aura::{self, AuraEffect};
use rog_dbus::RogDbusClientBlocking;
use rog_profiles::error::ProfileError;
@@ -143,6 +145,7 @@ fn do_parsed(
) -> Result<(), Box<dyn std::error::Error>> {
match &parsed.command {
Some(CliCommand::LedMode(mode)) => handle_led_mode(dbus, &supported.keyboard_led, mode)?,
Some(CliCommand::LedPower(pow)) => handle_led_power(dbus, &supported.keyboard_led, pow)?,
Some(CliCommand::Profile(cmd)) => handle_profile(dbus, &supported.platform_profile, cmd)?,
Some(CliCommand::FanCurve(cmd)) => {
handle_fan_curve(dbus, &supported.platform_profile, cmd)?
@@ -339,15 +342,7 @@ fn handle_led_mode(
supported: &LedSupportedFunctions,
mode: &LedModeCommand,
) -> Result<(), Box<dyn std::error::Error>> {
if mode.command.is_none()
&& !mode.prev_mode
&& !mode.next_mode
&& mode.boot_enable.is_none()
&& mode.sleep_enable.is_none()
&& mode.all_leds_enable.is_none()
&& mode.keys_leds_enable.is_none()
&& mode.side_leds_enable.is_none()
{
if mode.command.is_none() && !mode.prev_mode && !mode.next_mode {
if !mode.help {
println!("Missing arg or command\n");
}
@@ -396,22 +391,165 @@ fn handle_led_mode(
.set_led_mode(&<AuraEffect>::from(mode))?;
}
if let Some(enable) = mode.boot_enable {
dbus.proxies().led().set_boot_enabled(enable)?;
Ok(())
}
if let Some(enable) = mode.sleep_enable {
dbus.proxies().led().set_sleep_enabled(enable)?;
fn handle_led_power(
dbus: &RogDbusClientBlocking,
_supported: &LedSupportedFunctions,
power: &LedPowerCommand,
) -> Result<(), Box<dyn std::error::Error>> {
if power.command().is_none() {
if !power.help {
println!("Missing arg or command\n");
}
println!("{}\n", power.self_usage());
println!("Commands available");
if let Some(cmdlist) = LedPowerCommand::command_list() {
let commands: Vec<String> = cmdlist.lines().map(|s| s.to_string()).collect();
for command in commands.iter() {
println!("{}", command);
}
}
if let Some(enable) = mode.all_leds_enable {
dbus.proxies().led().set_all_leds_enabled(enable)?;
println!("\nHelp can also be requested on commands, e.g: boot --help");
return Ok(());
}
if let Some(pow) = power.command.as_ref() {
if pow.help_requested() {
println!("{}", pow.self_usage());
return Ok(());
}
match pow {
// TODO: make this a macro or something
aura_cli::SetAuraEnabled::Boot(arg) => {
let mut enabled: Vec<AuraControl> = Vec::new();
let mut disabled: Vec<AuraControl> = Vec::new();
arg.keyboard.map(|v| {
if v {
enabled.push(AuraControl::BootKeyb)
} else {
disabled.push(AuraControl::BootKeyb)
}
});
arg.logo.map(|v| {
if v {
enabled.push(AuraControl::BootLogo)
} else {
disabled.push(AuraControl::BootLogo)
}
});
arg.lightbar.map(|v| {
if v {
enabled.push(AuraControl::BootBar)
} else {
disabled.push(AuraControl::BootBar)
}
});
if !enabled.is_empty() {
dbus.proxies().led().set_leds_enabled(enabled)?;
}
if !disabled.is_empty() {
dbus.proxies().led().set_leds_disabled(disabled)?;
}
}
aura_cli::SetAuraEnabled::Sleep(arg) => {
let mut enabled: Vec<AuraControl> = Vec::new();
let mut disabled: Vec<AuraControl> = Vec::new();
arg.keyboard.map(|v| {
if v {
enabled.push(AuraControl::SleepKeyb)
} else {
disabled.push(AuraControl::SleepKeyb)
}
});
arg.logo.map(|v| {
if v {
enabled.push(AuraControl::SleepLogo)
} else {
disabled.push(AuraControl::SleepLogo)
}
});
arg.lightbar.map(|v| {
if v {
enabled.push(AuraControl::SleepBar)
} else {
disabled.push(AuraControl::SleepBar)
}
});
if !enabled.is_empty() {
dbus.proxies().led().set_leds_enabled(enabled)?;
}
if !disabled.is_empty() {
dbus.proxies().led().set_leds_disabled(disabled)?;
}
}
aura_cli::SetAuraEnabled::Awake(arg) => {
let mut enabled: Vec<AuraControl> = Vec::new();
let mut disabled: Vec<AuraControl> = Vec::new();
arg.keyboard.map(|v| {
if v {
enabled.push(AuraControl::AwakeKeyb)
} else {
disabled.push(AuraControl::AwakeKeyb)
}
});
arg.logo.map(|v| {
if v {
enabled.push(AuraControl::AwakeLogo)
} else {
disabled.push(AuraControl::AwakeLogo)
}
});
arg.lightbar.map(|v| {
if v {
enabled.push(AuraControl::AwakeBar)
} else {
disabled.push(AuraControl::AwakeBar)
}
});
if !enabled.is_empty() {
dbus.proxies().led().set_leds_enabled(enabled)?;
}
if !disabled.is_empty() {
dbus.proxies().led().set_leds_disabled(disabled)?;
}
}
aura_cli::SetAuraEnabled::Shutdown(arg) => {
let mut enabled: Vec<AuraControl> = Vec::new();
let mut disabled: Vec<AuraControl> = Vec::new();
arg.keyboard.map(|v| {
if v {
enabled.push(AuraControl::ShutdownKeyb)
} else {
disabled.push(AuraControl::ShutdownKeyb)
}
});
arg.logo.map(|v| {
if v {
enabled.push(AuraControl::ShutdownLogo)
} else {
disabled.push(AuraControl::ShutdownLogo)
}
});
arg.lightbar.map(|v| {
if v {
enabled.push(AuraControl::ShutdownBar)
} else {
disabled.push(AuraControl::ShutdownBar)
}
});
if !enabled.is_empty() {
dbus.proxies().led().set_leds_enabled(enabled)?;
}
if !disabled.is_empty() {
dbus.proxies().led().set_leds_disabled(disabled)?;
}
}
if let Some(enable) = mode.keys_leds_enable {
dbus.proxies().led().set_keys_leds_enabled(enable)?;
}
if let Some(enable) = mode.side_leds_enable {
dbus.proxies().led().set_side_leds_enabled(enable)?;
}
Ok(())

View File

@@ -1,6 +1,7 @@
use crate::laptops::LaptopLedData;
use log::{error, warn};
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, LedBrightness, LedPowerStates};
use rog_aura::usb::AuraControl;
use rog_aura::{AuraEffect, AuraModeNum, AuraZone, LedBrightness};
use serde_derive::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::fs::{File, OpenOptions};
@@ -15,7 +16,7 @@ pub struct AuraConfig {
pub current_mode: AuraModeNum,
pub builtins: BTreeMap<AuraModeNum, AuraEffect>,
pub multizone: Option<BTreeMap<AuraModeNum, Vec<AuraEffect>>>,
pub power_states: LedPowerStates,
pub enabled: Vec<AuraControl>,
}
impl Default for AuraConfig {
@@ -25,13 +26,20 @@ impl Default for AuraConfig {
current_mode: AuraModeNum::Static,
builtins: BTreeMap::new(),
multizone: None,
power_states: LedPowerStates {
boot_anim: true,
sleep_anim: true,
all_leds: true,
keys_leds: true,
side_leds: true,
},
enabled: vec![
AuraControl::BootLogo,
AuraControl::BootKeyb,
AuraControl::SleepLogo,
AuraControl::SleepKeyb,
AuraControl::AwakeLogo,
AuraControl::AwakeKeyb,
AuraControl::ShutdownLogo,
AuraControl::ShutdownKeyb,
AuraControl::AwakeBar,
AuraControl::BootBar,
AuraControl::SleepBar,
AuraControl::ShutdownBar,
],
}
}
}

View File

@@ -9,7 +9,7 @@ use crate::{
use async_trait::async_trait;
use log::{error, info, warn};
use logind_zbus::manager::ManagerProxy;
use rog_aura::usb::leds_message;
use rog_aura::usb::AuraControl;
use rog_aura::{
usb::{LED_APPLY, LED_SET},
AuraEffect, LedBrightness, LED_MSG_LEN,
@@ -298,17 +298,11 @@ impl CtrlKbdLed {
/// Set combination state for boot animation/sleep animation/all leds/keys leds/side leds LED active
pub(super) fn set_power_states(&self, config: &AuraConfig) -> Result<(), RogError> {
let bytes = leds_message(
config.power_states.boot_anim,
config.power_states.sleep_anim,
config.power_states.all_leds,
config.power_states.keys_leds,
config.power_states.side_leds,
);
let bytes = AuraControl::to_bytes(&config.enabled);
// Quite ugly, must be a more idiomatic way to do
let message = [
0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0x5d, 0xbd, 0x01, bytes[0], bytes[1], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
self.write_bytes(&message)?;

View File

@@ -1,6 +1,6 @@
use async_trait::async_trait;
use log::warn;
use rog_aura::{AuraEffect, LedBrightness, LedPowerStates};
use rog_aura::{usb::AuraControl, AuraEffect, LedBrightness};
use zbus::{dbus_interface, Connection, SignalContext};
use super::controller::CtrlKbdLedZbus;
@@ -26,22 +26,26 @@ impl CtrlKbdLedZbus {
}
}
/// Set the keyboard LED to enabled while the device is awake
async fn set_boot_enabled(
/// Set a variety of states
async fn set_leds_enabled(
&mut self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
enabled: bool,
enabled: Vec<AuraControl>,
) {
let mut states = None;
if let Ok(mut ctrl) = self.0.try_lock() {
ctrl.config.power_states.boot_anim = enabled;
for s in enabled {
if !ctrl.config.enabled.contains(&s) {
ctrl.config.enabled.push(s);
}
}
ctrl.config.write();
ctrl.set_power_states(&ctrl.config)
.map_err(|err| warn!("{}", err))
.ok();
states = Some(ctrl.config.power_states);
states = Some(ctrl.config.enabled.clone());
}
// Need to pull state out like this due to MutexGuard
if let Some(states) = states {
@@ -51,98 +55,27 @@ impl CtrlKbdLedZbus {
}
}
/// Set the keyboard LED suspend animation to enabled while the device is suspended
async fn set_sleep_enabled(
async fn set_leds_disabled(
&mut self,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
enabled: bool,
disabled: Vec<AuraControl>,
) {
let mut states = None;
if let Ok(mut ctrl) = self.0.try_lock() {
ctrl.config.power_states.sleep_anim = enabled;
for s in disabled {
if ctrl.config.enabled.contains(&s) {
if let Ok(idx) = ctrl.config.enabled.binary_search(&s) {
ctrl.config.enabled.remove(idx);
}
}
}
ctrl.config.write();
ctrl.set_power_states(&ctrl.config)
.map_err(|err| warn!("{}", err))
.ok();
states = Some(ctrl.config.power_states);
}
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.power_states.all_leds = enabled;
ctrl.config.power_states.keys_leds = enabled;
ctrl.config.power_states.side_leds = enabled;
ctrl.config.write();
ctrl.set_power_states(&ctrl.config)
.map_err(|err| warn!("{}", err))
.ok();
states = Some(ctrl.config.power_states);
}
// 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.power_states.keys_leds = enabled;
ctrl.config.write();
ctrl.set_power_states(&ctrl.config)
.map_err(|err| warn!("{}", err))
.ok();
states = Some(ctrl.config.power_states);
}
// 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.power_states.side_leds = enabled;
ctrl.config.write();
ctrl.set_power_states(&ctrl.config)
.map_err(|err| warn!("{}", err))
.ok();
states = Some(ctrl.config.power_states);
states = Some(ctrl.config.enabled.clone());
}
// Need to pull state out like this due to MutexGuard
if let Some(states) = states {
@@ -226,43 +159,11 @@ impl CtrlKbdLedZbus {
}
#[dbus_interface(property)]
async fn boot_enabled(&self) -> bool {
async fn leds_enabled(&self) -> Vec<u8> {
if let Ok(ctrl) = self.0.try_lock() {
return ctrl.config.power_states.boot_anim;
return AuraControl::to_bytes(&ctrl.config.enabled).to_vec();
}
true
}
#[dbus_interface(property)]
async fn sleep_enabled(&self) -> bool {
if let Ok(ctrl) = self.0.try_lock() {
return ctrl.config.power_states.sleep_anim;
}
true
}
#[dbus_interface(property)]
async fn all_leds_enabled(&self) -> bool {
if let Ok(ctrl) = self.0.try_lock() {
return ctrl.config.power_states.all_leds;
}
true
}
#[dbus_interface(property)]
async fn keys_leds_enabled(&self) -> bool {
if let Ok(ctrl) = self.0.try_lock() {
return ctrl.config.power_states.keys_leds;
}
true
}
#[dbus_interface(property)]
fn side_leds_enabled(&self) -> bool {
if let Ok(ctrl) = self.0.try_lock() {
return ctrl.config.power_states.side_leds;
}
true
vec![0, 0]
}
/// Return the current mode data
@@ -307,6 +208,6 @@ impl CtrlKbdLedZbus {
#[dbus_interface(signal)]
async fn notify_power_states(
signal_ctxt: &SignalContext<'_>,
data: &LedPowerStates,
data: &[AuraControl],
) -> zbus::Result<()>;
}

View File

@@ -11,16 +11,6 @@ use zvariant::Type;
use crate::{error::Error, LED_MSG_LEN};
#[cfg_attr(feature = "dbus", derive(Type))]
#[derive(Debug, PartialEq, Copy, Clone, Deserialize, Serialize)]
pub struct LedPowerStates {
pub boot_anim: bool,
pub sleep_anim: bool,
pub all_leds: bool,
pub keys_leds: bool,
pub side_leds: bool,
}
#[cfg_attr(feature = "dbus", derive(Type))]
#[derive(Debug, Copy, Clone, PartialEq, Deserialize, Serialize)]
pub enum LedBrightness {

View File

@@ -1,6 +1,7 @@
use crate::usb::LedCfgState::{Off, On};
use std::convert::TryFrom;
use serde::{Deserialize, Serialize};
use std::ops::{BitAnd, BitOr};
#[cfg(feature = "dbus")]
use zvariant::Type;
pub const LED_INIT1: [u8; 2] = [0x5d, 0xb9];
pub const LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
@@ -12,13 +13,6 @@ pub const LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08];
pub const LED_APPLY: [u8; 17] = [0x5d, 0xb4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
pub const LED_SET: [u8; 17] = [0x5d, 0xb5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
pub const BOOT_MASK: i32 = 0xc31309;
pub const SLEEP_MASK: i32 = 0x300904;
pub const ALL_LEDS_MASK: i32 = 0x000002;
pub const KBD_LEDS_MASK: i32 = 0x080000;
pub const SIDE_LEDS_MASK: i32 = 0x040500;
pub const LEDS_STATE_MASK: i32 = ALL_LEDS_MASK | KBD_LEDS_MASK | SIDE_LEDS_MASK;
/// Writes out the correct byte string for brightness
pub const fn aura_brightness_bytes(brightness: u8) -> [u8; 17] {
[
@@ -26,113 +20,152 @@ pub const fn aura_brightness_bytes(brightness: u8) -> [u8; 17] {
]
}
#[derive(Clone, Copy)]
pub enum LedCfgState {
On = 0xffffff,
Off = 0x0,
#[cfg_attr(feature = "dbus", derive(Type))]
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)]
#[repr(u16)]
pub enum AuraControl {
BootLogo = 1,
BootKeyb = 1 << 1,
AwakeLogo = 1 << 2,
AwakeKeyb = 1 << 3,
SleepLogo = 1 << 4,
SleepKeyb = 1 << 5,
ShutdownLogo = 1 << 6,
ShutdownKeyb = 1 << 7,
AwakeBar = 1 << 7 + 2,
BootBar = 1 << 7 + 3,
SleepBar = 1 << 7 + 4,
ShutdownBar = 1 << 7 + 5,
}
impl From<i32> for LedCfgState {
fn from(state: i32) -> Self {
match state {
0xffffff => On,
0x0 => Off,
_ => Off,
}
impl From<AuraControl> for u16 {
fn from(a: AuraControl) -> Self {
a as u16
}
}
impl From<bool> for LedCfgState {
fn from(state: bool) -> Self {
match state {
true => On,
false => Off,
}
}
}
impl TryFrom<[u8; 3]> for LedCfgState {
type Error = &'static str;
fn try_from(value: [u8; 3]) -> Result<Self, Self::Error> {
match value {
[0xff, 0xff, 0xff] => Ok(On),
[0, 0, 0] => Ok(Off),
_ => Err("Unconvertible value"),
}
}
}
impl BitAnd<LedCfgState> for i32 {
type Output = i32;
fn bitand(self, rhs: LedCfgState) -> i32 {
return self & rhs as i32;
}
}
impl BitOr<LedCfgState> for i32 {
type Output = i32;
fn bitor(self, rhs: LedCfgState) -> Self::Output {
return self | rhs as i32;
impl AuraControl {
pub fn to_bytes(control: &[Self]) -> [u8; 2] {
let mut a: u16 = 0;
control.iter().for_each(|n| {
a |= *n as u16;
});
[(a & 0xff) as u8, ((a & 0xff00) >> 8) as u8]
}
}
impl BitOr<LedCfgState> for LedCfgState {
type Output = i32;
impl BitOr<AuraControl> for AuraControl {
type Output = u16;
fn bitor(self, rhs: LedCfgState) -> i32 {
return self as i32 | rhs as i32;
fn bitor(self, rhs: AuraControl) -> Self::Output {
return self as u16 | rhs as u16;
}
}
impl BitAnd<LedCfgState> for LedCfgState {
type Output = LedCfgState;
impl BitAnd<AuraControl> for AuraControl {
type Output = u16;
fn bitand(self, rhs: LedCfgState) -> LedCfgState {
return (self as i32 & rhs as i32).into();
fn bitand(self, rhs: AuraControl) -> Self::Output {
return self as u16 & rhs as u16;
}
}
pub fn leds_message(
boot_state: bool,
sleep_state: bool,
all_leds_state: bool,
kbd_leds_state: bool,
side_leds_state: bool,
) -> [u8; 3] {
let raw_message = _leds_message(
boot_state.into(),
sleep_state.into(),
all_leds_state.into(),
kbd_leds_state.into(),
side_leds_state.into(),
);
#[cfg(test)]
mod tests {
use crate::usb::AuraControl;
let [_, lows @ ..] = i32::to_be_bytes(raw_message);
return lows;
#[test]
fn check_led_control_bytes() {
// All on
let byte1 = [
AuraControl::BootLogo,
AuraControl::BootKeyb,
AuraControl::SleepLogo,
AuraControl::SleepKeyb,
AuraControl::AwakeLogo,
AuraControl::AwakeKeyb,
AuraControl::ShutdownLogo,
AuraControl::ShutdownKeyb,
];
let bytes = AuraControl::to_bytes(&byte1);
println!("{:08b}", bytes[0]);
assert_eq!(bytes[0], 0xff);
//
let byte1 = [
// AuraControl::BootLogo,
AuraControl::BootKeyb,
AuraControl::SleepLogo,
AuraControl::SleepKeyb,
AuraControl::AwakeLogo,
AuraControl::AwakeKeyb,
AuraControl::ShutdownLogo,
AuraControl::ShutdownKeyb,
];
let bytes = AuraControl::to_bytes(&byte1);
println!("{:08b}", bytes[0]);
assert_eq!(bytes[0], 0xfe);
let byte1 = [
AuraControl::BootLogo,
// AuraControl::BootKeyb,
AuraControl::SleepLogo,
AuraControl::SleepKeyb,
AuraControl::AwakeLogo,
AuraControl::AwakeKeyb,
AuraControl::ShutdownLogo,
AuraControl::ShutdownKeyb,
];
let bytes = AuraControl::to_bytes(&byte1);
println!("{:08b}", bytes[0]);
assert_eq!(bytes[0], 0xfd);
let byte1 = [
AuraControl::BootLogo,
AuraControl::BootKeyb,
// AuraControl::SleepLogo,
AuraControl::SleepKeyb,
AuraControl::AwakeLogo,
AuraControl::AwakeKeyb,
AuraControl::ShutdownLogo,
AuraControl::ShutdownKeyb,
];
let bytes = AuraControl::to_bytes(&byte1);
println!("{:08b}", bytes[0]);
assert_eq!(bytes[0], 0xef);
let byte1 = [
AuraControl::BootLogo,
AuraControl::BootKeyb,
AuraControl::SleepLogo,
// AuraControl::SleepKeyb,
AuraControl::AwakeLogo,
AuraControl::AwakeKeyb,
AuraControl::ShutdownLogo,
AuraControl::ShutdownKeyb,
];
let bytes = AuraControl::to_bytes(&byte1);
println!("{:08b}", bytes[0]);
assert_eq!(bytes[0], 0xdf);
let byte2 = [
AuraControl::AwakeBar,
AuraControl::BootBar,
AuraControl::SleepBar,
AuraControl::ShutdownBar,
];
let bytes = AuraControl::to_bytes(&byte2);
println!("{:08b}", bytes[1]);
assert_eq!(bytes[1], 0x1e);
let byte2 = [
AuraControl::AwakeBar,
AuraControl::BootBar,
// AuraControl::SleepBar,
AuraControl::ShutdownBar,
];
let bytes = AuraControl::to_bytes(&byte2);
println!("{:08b}", bytes[1]);
assert_eq!(bytes[1], 0x16);
}
fn _leds_message(
boot_state: LedCfgState,
sleep_state: LedCfgState,
all_leds_state: LedCfgState,
kbd_leds_state: LedCfgState,
side_leds_state: LedCfgState,
) -> i32 {
let full_leds_state = match all_leds_state {
On => {
(ALL_LEDS_MASK & all_leds_state)
| (KBD_LEDS_MASK & kbd_leds_state)
| (SIDE_LEDS_MASK & side_leds_state)
}
Off => 0x0100 & side_leds_state,
};
let boot_xor_sleep = (BOOT_MASK & boot_state) ^ (SLEEP_MASK & sleep_state);
return match (all_leds_state | kbd_leds_state | side_leds_state).into() {
On => boot_xor_sleep ^ ((boot_xor_sleep ^ full_leds_state) & LEDS_STATE_MASK),
_ => boot_xor_sleep,
};
}

View File

@@ -22,7 +22,7 @@
use zbus::{blocking::Connection, Result};
use zbus_macros::dbus_proxy;
use rog_aura::{AuraEffect, KeyColourArray, LedBrightness, LedPowerStates};
use rog_aura::{usb::AuraControl, AuraEffect, KeyColourArray, LedBrightness};
const BLOCKING_TIME: u64 = 40; // 100ms = 10 FPS, max 50ms = 20 FPS, 40ms = 25 FPS
@@ -49,27 +49,16 @@ trait Led {
/// SetLedMode method
fn set_led_mode(&self, effect: &AuraEffect) -> zbus::Result<()>;
/// SetAwakeEnabled method
fn set_boot_enabled(&self, enabled: bool) -> zbus::Result<()>;
fn set_leds_enabled(&self, enabled: Vec<AuraControl>) -> zbus::Result<()>;
/// SetSleepEnabled method
fn set_sleep_enabled(&self, enabled: bool) -> zbus::Result<()>;
/// SetSideLedsEnabled method
fn set_all_leds_enabled(&self, enabled: bool) -> Result<()>;
/// SetSideLedsEnabled method
fn set_keys_leds_enabled(&self, enabled: bool) -> Result<()>;
/// SetSideLedsEnabled method
fn set_side_leds_enabled(&self, enabled: bool) -> Result<()>;
fn set_leds_disabled(&self, disabled: Vec<AuraControl>) -> zbus::Result<()>;
/// NotifyLed signal
#[dbus_proxy(signal)]
fn notify_led(&self, data: AuraEffect) -> zbus::Result<()>;
#[dbus_proxy(signal)]
fn notify_power_states(&self, data: LedPowerStates) -> zbus::Result<()>;
fn notify_power_states(&self, data: Vec<AuraControl>) -> zbus::Result<()>;
/// LedBrightness property
#[dbus_proxy(property)]
@@ -84,13 +73,7 @@ trait Led {
fn led_modes(&self) -> zbus::Result<String>;
#[dbus_proxy(property)]
fn awake_enabled(&self) -> zbus::Result<bool>;
#[dbus_proxy(property)]
fn sleep_enabled(&self) -> zbus::Result<bool>;
#[dbus_proxy(property)]
fn side_leds_enabled(&self) -> zbus::Result<bool>;
fn leds_enabled(&self) -> zbus::Result<Vec<u8>>;
}
pub struct LedProxyPerkey<'a>(LedProxyBlocking<'a>);