Merge branch 'main' into main

This commit is contained in:
Luke Jones
2024-04-10 08:54:54 +12:00
committed by GitHub
61 changed files with 1573 additions and 3009 deletions

View File

@@ -1,149 +0,0 @@
use crate::advanced::LedCode;
impl From<LedCode> for &str {
fn from(k: LedCode) -> Self {
(&k).into()
}
}
impl From<&LedCode> for &str {
fn from(k: &LedCode) -> Self {
#[allow(clippy::match_same_arms)]
match k {
LedCode::VolUp => "Volume Up",
LedCode::VolDown => "Volume Down",
LedCode::MicMute => "Mute Mic",
LedCode::RogApp => "ROG",
LedCode::RogFan => "Fan Control",
LedCode::Esc => "Escape",
LedCode::F1 => "F1",
LedCode::F2 => "F2",
LedCode::F3 => "F3",
LedCode::F4 => "F4",
LedCode::F5 => "F5",
LedCode::F6 => "F6",
LedCode::F7 => "F7",
LedCode::F8 => "F8",
LedCode::F9 => "F9",
LedCode::F10 => "F10",
LedCode::F11 => "F11",
LedCode::F12 => "F12",
LedCode::Del => "Delete",
LedCode::Tilde => "Tilde",
LedCode::N1 => "1",
LedCode::N2 => "2",
LedCode::N3 => "3",
LedCode::N4 => "4",
LedCode::N5 => "5",
LedCode::N6 => "6",
LedCode::N7 => "7",
LedCode::N8 => "8",
LedCode::N9 => "9",
LedCode::N0 => "0",
LedCode::Hyphen => "-",
LedCode::Equals => "=",
LedCode::Backspace => "Backspace",
LedCode::Backspace3_1 => "Backspace LED 1",
LedCode::Backspace3_2 => "Backspace LED 2",
LedCode::Backspace3_3 => "Backspace LED 3",
LedCode::Home => "Home",
LedCode::Tab => "Tab",
LedCode::Q => "Q",
LedCode::W => "W",
LedCode::E => "E",
LedCode::R => "R",
LedCode::T => "T",
LedCode::Y => "Y",
LedCode::U => "U",
LedCode::I => "I",
LedCode::O => "O",
LedCode::P => "P",
LedCode::LBracket => "[",
LedCode::RBracket => "]",
LedCode::BackSlash => "\\",
LedCode::PgUp => "Page Up",
LedCode::Caps => "Caps Lock",
LedCode::A => "A",
LedCode::S => "S",
LedCode::D => "D",
LedCode::F => "F",
LedCode::G => "G",
LedCode::H => "H",
LedCode::J => "J",
LedCode::K => "K",
LedCode::L => "L",
LedCode::SemiColon => ";",
LedCode::Quote => "'",
LedCode::Return => "Return",
LedCode::Return3_1 => "Return LED 1",
LedCode::Return3_2 => "Return LED 2",
LedCode::Return3_3 => "Return LED 3",
LedCode::PgDn => "Page Down",
LedCode::LShift => "Left Shift",
LedCode::LShift3_1 => "Left Shift LED 1",
LedCode::LShift3_2 => "Left Shift LED 2",
LedCode::LShift3_3 => "Left Shift LED 3",
LedCode::Z => "Z",
LedCode::X => "X",
LedCode::C => "C",
LedCode::V => "V",
LedCode::B => "B",
LedCode::N => "N",
LedCode::M => "M",
LedCode::Comma => ",",
LedCode::Period => ".",
LedCode::Star => "*",
LedCode::NumPadDel => "Delete",
LedCode::NumPadPlus => "+",
LedCode::NumPadEnter => "Enter",
LedCode::NumPadPause => "Pause",
LedCode::NumPadPrtSc => "Print Screen",
LedCode::NumPadHome => "Home",
LedCode::NumLock => "Num-Lock",
LedCode::FwdSlash => "/",
LedCode::Rshift => "Right Shift",
LedCode::Rshift3_1 => "Right Shift LED 1",
LedCode::Rshift3_2 => "Right Shift LED 2",
LedCode::Rshift3_3 => "Right Shift LED 3",
LedCode::End => "End",
LedCode::LCtrl => "Left Control",
LedCode::LFn => "Left Fn",
LedCode::Meta => "Meta",
LedCode::LAlt => "Left Alt",
LedCode::Spacebar => "Space",
LedCode::Spacebar5_1 => "Space LED 1",
LedCode::Spacebar5_2 => "Space LED 2",
LedCode::Spacebar5_3 => "Space LED 3",
LedCode::Spacebar5_4 => "Space LED 4",
LedCode::Spacebar5_5 => "Space LED 5",
LedCode::RAlt => "Right Alt",
LedCode::PrtSc => "Print Screen",
LedCode::RCtrl => "Right Control",
LedCode::Pause => "Pause",
LedCode::Up => "Up",
LedCode::Down => "Down",
LedCode::Left => "Left",
LedCode::Right => "Right",
LedCode::RFn => "Right Fn",
LedCode::MediaPlay => "Media Play",
LedCode::MediaStop => "Media Stop",
LedCode::MediaNext => "Media Next",
LedCode::MediaPrev => "Media Previous",
LedCode::LidLogo => "Lid Logo",
LedCode::LidLeft => "Lid Left",
LedCode::LidRight => "Lid Right",
LedCode::LightbarRight => "Lightbar Right",
LedCode::LightbarRightCorner => "Lightbar Right Corner",
LedCode::LightbarRightBottom => "Lightbar Right Bottom",
LedCode::LightbarLeftBottom => "Lightbar Left Bottom",
LedCode::LightbarLeftCorner => "Lightbar Left Corner",
LedCode::LightbarLeft => "Lightbar Left",
LedCode::Spacing | LedCode::Blocking => "",
LedCode::SingleZone => "Single Zoned Keyboard",
LedCode::ZonedKbLeft => "Left Zone (zone 1)",
LedCode::ZonedKbLeftMid => "Center-left Zone (zone 2)",
LedCode::ZonedKbRightMid => "Center-right Zone (zone 3)",
LedCode::ZonedKbRight => "Right Zone (zone 4)",
}
}
}

View File

@@ -4,21 +4,11 @@ use serde_derive::{Deserialize, Serialize};
use typeshare::typeshare;
use zbus::zvariant::{OwnedValue, Type, Value};
use crate::usb::AuraDevice;
use crate::{AdvancedAuraType, AuraModeNum, AuraZone};
use crate::keyboard::AdvancedAuraType;
use crate::{AuraModeNum, AuraZone};
pub const ASUS_LED_MODE_CONF: &str = "/usr/share/asusd/aura_support.ron";
pub const ASUS_LED_MODE_USER_CONF: &str = "/etc/asusd/asusd_user_ledmodes.ron";
pub const ASUS_KEYBOARD_DEVICES: [AuraDevice; 8] = [
AuraDevice::Tuf,
AuraDevice::X1854,
AuraDevice::X1869,
AuraDevice::X1866,
AuraDevice::X18c6,
AuraDevice::X19b6,
AuraDevice::X1a30,
AuraDevice::X1abe,
];
#[derive(Debug, Default, Clone, PartialEq, Eq, Deserialize, Serialize)]
pub struct LedSupportFile(Vec<LaptopLedData>);
@@ -30,7 +20,7 @@ pub struct LedSupportFile(Vec<LaptopLedData>);
derive(Type, Value, OwnedValue),
zvariant(signature = "u")
)]
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Default, Copy, Clone)]
#[derive(Serialize, Deserialize, PartialEq, Eq, Hash, Debug, Default, Copy, Clone)]
pub enum PowerZones {
/// The logo on some laptop lids
#[default]
@@ -43,6 +33,8 @@ pub enum PowerZones {
Lid = 3,
/// The led strip on the rear of some laptops
RearGlow = 4,
/// On pre-2021 laptops there is either 1 or 2 zones used
KeyboardAndLightbar = 5,
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize)]
@@ -153,10 +145,10 @@ mod tests {
use ron::ser::PrettyConfig;
use super::LaptopLedData;
use crate::advanced::LedCode;
use crate::aura_detection::{LedSupportFile, PowerZones};
use crate::keyboard::{AdvancedAuraType, LedCode};
// use crate::zoned::Zone;
use crate::{AdvancedAuraType, AuraModeNum, AuraZone};
use crate::{AuraModeNum, AuraZone};
#[test]
fn check_data_parse() {

View File

@@ -1,9 +1,3 @@
pub const LED_INIT1: [u8; 2] = [0x5d, 0xb9];
pub const LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
pub const LED_INIT3: [u8; 6] = [0x5d, 0x05, 0x20, 0x31, 0, 0x08];
pub const LED_INIT4: &str = "^ASUS Tech.Inc."; // ^ == 0x5e
pub const LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08];
use std::fmt::Display;
use std::str::FromStr;

View File

@@ -1,162 +0,0 @@
//! Older code that is not useful but stillr elevant as a reference
/// # Bits for newer 0x18c6, 0x19B6, 0x1a30, keyboard models
///
/// | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Label |
/// |--------|---------|---------|---------|----------|
/// |00000001| 00000000| 00000000| 00000000|boot_logo_|
/// |00000010| 00000000| 00000000| 00000000|boot_keyb_|
/// |00000100| 00000000| 00000000| 00000000|awake_logo|
/// |00001000| 00000000| 00000000| 00000000|awake_keyb|
/// |00010000| 00000000| 00000000| 00000000|sleep_logo|
/// |00100000| 00000000| 00000000| 00000000|sleep_keyb|
/// |01000000| 00000000| 00000000| 00000000|shut_logo_|
/// |10000000| 00000000| 00000000| 00000000|shut_keyb_|
/// |00000000| 00000010| 00000000| 00000000|boot_bar__|
/// |00000000| 00000100| 00000000| 00000000|awake_bar_|
/// |00000000| 00001000| 00000000| 00000000|sleep_bar_|
/// |00000000| 00010000| 00000000| 00000000|shut_bar__|
/// |00000000| 00000000| 00000001| 00000000|boot_lid__|
/// |00000000| 00000000| 00000010| 00000000|awkae_lid_|
/// |00000000| 00000000| 00000100| 00000000|sleep_lid_|
/// |00000000| 00000000| 00001000| 00000000|shut_lid__|
/// |00000000| 00000000| 00000000| 00000001|boot_rear_|
/// |00000000| 00000000| 00000000| 00000010|awake_rear|
/// |00000000| 00000000| 00000000| 00000100|sleep_rear|
/// |00000000| 00000000| 00000000| 00001000|shut_rear_|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum AuraDevRog2 {
BootLogo = 1,
BootKeyb = 1 << 1,
AwakeLogo = 1 << 2,
AwakeKeyb = 1 << 3,
SleepLogo = 1 << 4,
SleepKeyb = 1 << 5,
ShutdownLogo = 1 << 6,
ShutdownKeyb = 1 << 7,
BootBar = 1 << (7 + 2),
AwakeBar = 1 << (7 + 3),
SleepBar = 1 << (7 + 4),
ShutdownBar = 1 << (7 + 5),
BootLid = 1 << (15 + 1),
AwakeLid = 1 << (15 + 2),
SleepLid = 1 << (15 + 3),
ShutdownLid = 1 << (15 + 4),
BootRearGlow = 1 << (23 + 1),
AwakeRearGlow = 1 << (23 + 2),
SleepRearGlow = 1 << (23 + 3),
ShutdownRearGlow = 1 << (23 + 4),
}
impl From<AuraDevRog2> for u32 {
fn from(a: AuraDevRog2) -> Self {
a as u32
}
}
impl AuraDevRog2 {
pub fn to_bytes(control: &[Self]) -> [u8; 4] {
let mut a: u32 = 0;
for n in control {
a |= *n as u32;
}
[
(a & 0xff) as u8,
((a & 0xff00) >> 8) as u8,
((a & 0xff0000) >> 16) as u8,
((a & 0xff000000) >> 24) as u8,
]
}
pub const fn dev_id() -> &'static str {
"0x196b"
}
}
#[cfg(test)]
mod tests {
use crate::deprecated::AuraDevRog2;
#[test]
fn check_0x19b6_control_bytes_binary_rep() {
fn to_binary_string(bytes: &[AuraDevRog2]) -> String {
let bytes = AuraDevRog2::to_bytes(bytes);
format!(
"{:08b}, {:08b}, {:08b}, {:08b}",
bytes[0], bytes[1], bytes[2], bytes[3]
)
}
let boot_logo_ = to_binary_string(&[AuraDevRog2::BootLogo]);
let boot_keyb_ = to_binary_string(&[AuraDevRog2::BootKeyb]);
let sleep_logo = to_binary_string(&[AuraDevRog2::SleepLogo]);
let sleep_keyb = to_binary_string(&[AuraDevRog2::SleepKeyb]);
let awake_logo = to_binary_string(&[AuraDevRog2::AwakeLogo]);
let awake_keyb = to_binary_string(&[AuraDevRog2::AwakeKeyb]);
let shut_logo_ = to_binary_string(&[AuraDevRog2::ShutdownLogo]);
let shut_keyb_ = to_binary_string(&[AuraDevRog2::ShutdownKeyb]);
let boot_bar__ = to_binary_string(&[AuraDevRog2::BootBar]);
let awake_bar_ = to_binary_string(&[AuraDevRog2::AwakeBar]);
let sleep_bar_ = to_binary_string(&[AuraDevRog2::SleepBar]);
let shut_bar__ = to_binary_string(&[AuraDevRog2::ShutdownBar]);
let boot_lid__ = to_binary_string(&[AuraDevRog2::BootLid]);
let awkae_lid_ = to_binary_string(&[AuraDevRog2::AwakeLid]);
let sleep_lid_ = to_binary_string(&[AuraDevRog2::SleepLid]);
let shut_lid__ = to_binary_string(&[AuraDevRog2::ShutdownLid]);
let boot_rear_ = to_binary_string(&[AuraDevRog2::BootRearGlow]);
let awake_rear = to_binary_string(&[AuraDevRog2::AwakeRearGlow]);
let sleep_rear = to_binary_string(&[AuraDevRog2::SleepRearGlow]);
let shut_rear_ = to_binary_string(&[AuraDevRog2::ShutdownRearGlow]);
assert_eq!(boot_logo_, "00000001, 00000000, 00000000, 00000000");
assert_eq!(boot_keyb_, "00000010, 00000000, 00000000, 00000000");
assert_eq!(awake_logo, "00000100, 00000000, 00000000, 00000000");
assert_eq!(awake_keyb, "00001000, 00000000, 00000000, 00000000");
assert_eq!(sleep_logo, "00010000, 00000000, 00000000, 00000000");
assert_eq!(sleep_keyb, "00100000, 00000000, 00000000, 00000000");
assert_eq!(shut_logo_, "01000000, 00000000, 00000000, 00000000");
assert_eq!(shut_keyb_, "10000000, 00000000, 00000000, 00000000");
//
assert_eq!(boot_bar__, "00000000, 00000010, 00000000, 00000000");
assert_eq!(awake_bar_, "00000000, 00000100, 00000000, 00000000");
assert_eq!(sleep_bar_, "00000000, 00001000, 00000000, 00000000");
assert_eq!(shut_bar__, "00000000, 00010000, 00000000, 00000000");
//
assert_eq!(boot_lid__, "00000000, 00000000, 00000001, 00000000");
assert_eq!(awkae_lid_, "00000000, 00000000, 00000010, 00000000");
assert_eq!(sleep_lid_, "00000000, 00000000, 00000100, 00000000");
assert_eq!(shut_lid__, "00000000, 00000000, 00001000, 00000000");
//
assert_eq!(boot_rear_, "00000000, 00000000, 00000000, 00000001");
assert_eq!(awake_rear, "00000000, 00000000, 00000000, 00000010");
assert_eq!(sleep_rear, "00000000, 00000000, 00000000, 00000100");
assert_eq!(shut_rear_, "00000000, 00000000, 00000000, 00001000");
// All on
let byte1 = [
AuraDevRog2::BootLogo,
AuraDevRog2::BootKeyb,
AuraDevRog2::SleepLogo,
AuraDevRog2::SleepKeyb,
AuraDevRog2::AwakeLogo,
AuraDevRog2::AwakeKeyb,
AuraDevRog2::ShutdownLogo,
AuraDevRog2::ShutdownKeyb,
AuraDevRog2::BootBar,
AuraDevRog2::AwakeBar,
AuraDevRog2::SleepBar,
AuraDevRog2::ShutdownBar,
AuraDevRog2::AwakeLid,
AuraDevRog2::BootLid,
AuraDevRog2::SleepLid,
AuraDevRog2::ShutdownLid,
AuraDevRog2::AwakeRearGlow,
AuraDevRog2::BootRearGlow,
AuraDevRog2::SleepRearGlow,
AuraDevRog2::ShutdownRearGlow,
];
let out = to_binary_string(&byte1);
assert_eq!(out, "11111111, 00011110, 00001111, 00001111");
}
}

View File

@@ -1,5 +1,5 @@
use super::{EffectState, InputForEffect};
use crate::advanced::LedCode;
use crate::keyboard::{KeyLayout, LedCode};
use crate::Colour;
pub struct InputBased {
@@ -14,7 +14,7 @@ pub struct InputBased {
}
impl EffectState for InputBased {
fn next_colour_state(&mut self, _layout: &crate::layouts::KeyLayout) {
fn next_colour_state(&mut self, _layout: &KeyLayout) {
self.input.next_colour_state();
self.colour = self.input.get_colour();
}

View File

@@ -1,8 +1,7 @@
use serde::{Deserialize, Serialize};
use super::EffectState;
use crate::advanced::LedCode;
use crate::layouts::KeyLayout;
use crate::keyboard::{KeyLayout, LedCode};
use crate::{effect_state_impl, Colour, Speed};
#[derive(Debug, Clone, Deserialize, Serialize)]

View File

@@ -1,8 +1,7 @@
use serde::{Deserialize, Serialize};
use crate::advanced::LedCode;
use crate::effects::{p_random, EffectState};
use crate::layouts::KeyLayout;
use crate::keyboard::{KeyLayout, LedCode};
use crate::{effect_state_impl, Colour};
#[derive(Debug, Clone, Deserialize, Serialize)]

View File

@@ -12,8 +12,7 @@ pub use breathe::*;
mod static_;
pub use static_::*;
use crate::advanced::{LedCode, LedUsbPackets, UsbPackets};
use crate::layouts::KeyLayout;
use crate::keyboard::{KeyLayout, LedCode, LedUsbPackets, UsbPackets};
use crate::Colour;
// static mut RNDINDEX: usize = 0;
@@ -132,12 +131,12 @@ macro_rules! effect_state_impl {
self.colour
}
fn get_led(&self) -> $crate::advanced::LedCode {
fn get_led(&self) -> $crate::keyboard::LedCode {
self.led.clone()
}
/// Change the led type
fn set_led(&mut self, address: $crate::advanced::LedCode) {
fn set_led(&mut self, address: $crate::keyboard::LedCode) {
self.led = address;
}
};
@@ -148,14 +147,14 @@ macro_rules! effect_impl {
($($effect:ident),*) => {
impl Effect {
/// Get the type of LED set
pub fn led(&self) -> $crate::advanced::LedCode {
pub fn led(&self) -> $crate::keyboard::LedCode {
match self {
$(Effect::$effect(c) => c.get_led(),)*
}
}
/// Change the led type (can be used to change location of the effect)
pub fn set_led(&mut self, address: $crate::advanced::LedCode) {
pub fn set_led(&mut self, address: $crate::keyboard::LedCode) {
match self {
$(Effect::$effect(c) => c.set_led(address),)*
}
@@ -200,9 +199,8 @@ effect_impl!(Static, Breathe, DoomFlicker, DoomLightFlash);
#[cfg(test)]
mod tests {
use crate::advanced::LedCode;
use crate::effects::{AdvancedEffects, Breathe, DoomFlicker, Effect, Static};
use crate::layouts::KeyLayout;
use crate::keyboard::{KeyLayout, LedCode};
use crate::{Colour, Speed};
#[test]

View File

@@ -1,8 +1,7 @@
use serde::{Deserialize, Serialize};
use super::EffectState;
use crate::advanced::LedCode;
use crate::layouts::KeyLayout;
use crate::keyboard::{KeyLayout, LedCode};
use crate::{effect_state_impl, Colour};
#[derive(Debug, Clone, Deserialize, Serialize)]

View File

@@ -490,9 +490,157 @@ impl From<LedUsbPackets> for UsbPackets {
}
}
impl From<LedCode> for &str {
fn from(k: LedCode) -> Self {
(&k).into()
}
}
impl From<&LedCode> for &str {
fn from(k: &LedCode) -> Self {
#[allow(clippy::match_same_arms)]
match k {
LedCode::VolUp => "Volume Up",
LedCode::VolDown => "Volume Down",
LedCode::MicMute => "Mute Mic",
LedCode::RogApp => "ROG",
LedCode::RogFan => "Fan Control",
LedCode::Esc => "Escape",
LedCode::F1 => "F1",
LedCode::F2 => "F2",
LedCode::F3 => "F3",
LedCode::F4 => "F4",
LedCode::F5 => "F5",
LedCode::F6 => "F6",
LedCode::F7 => "F7",
LedCode::F8 => "F8",
LedCode::F9 => "F9",
LedCode::F10 => "F10",
LedCode::F11 => "F11",
LedCode::F12 => "F12",
LedCode::Del => "Delete",
LedCode::Tilde => "Tilde",
LedCode::N1 => "1",
LedCode::N2 => "2",
LedCode::N3 => "3",
LedCode::N4 => "4",
LedCode::N5 => "5",
LedCode::N6 => "6",
LedCode::N7 => "7",
LedCode::N8 => "8",
LedCode::N9 => "9",
LedCode::N0 => "0",
LedCode::Hyphen => "-",
LedCode::Equals => "=",
LedCode::Backspace => "Backspace",
LedCode::Backspace3_1 => "Backspace LED 1",
LedCode::Backspace3_2 => "Backspace LED 2",
LedCode::Backspace3_3 => "Backspace LED 3",
LedCode::Home => "Home",
LedCode::Tab => "Tab",
LedCode::Q => "Q",
LedCode::W => "W",
LedCode::E => "E",
LedCode::R => "R",
LedCode::T => "T",
LedCode::Y => "Y",
LedCode::U => "U",
LedCode::I => "I",
LedCode::O => "O",
LedCode::P => "P",
LedCode::LBracket => "[",
LedCode::RBracket => "]",
LedCode::BackSlash => "\\",
LedCode::PgUp => "Page Up",
LedCode::Caps => "Caps Lock",
LedCode::A => "A",
LedCode::S => "S",
LedCode::D => "D",
LedCode::F => "F",
LedCode::G => "G",
LedCode::H => "H",
LedCode::J => "J",
LedCode::K => "K",
LedCode::L => "L",
LedCode::SemiColon => ";",
LedCode::Quote => "'",
LedCode::Return => "Return",
LedCode::Return3_1 => "Return LED 1",
LedCode::Return3_2 => "Return LED 2",
LedCode::Return3_3 => "Return LED 3",
LedCode::PgDn => "Page Down",
LedCode::LShift => "Left Shift",
LedCode::LShift3_1 => "Left Shift LED 1",
LedCode::LShift3_2 => "Left Shift LED 2",
LedCode::LShift3_3 => "Left Shift LED 3",
LedCode::Z => "Z",
LedCode::X => "X",
LedCode::C => "C",
LedCode::V => "V",
LedCode::B => "B",
LedCode::N => "N",
LedCode::M => "M",
LedCode::Comma => ",",
LedCode::Period => ".",
LedCode::Star => "*",
LedCode::NumPadDel => "Delete",
LedCode::NumPadPlus => "+",
LedCode::NumPadEnter => "Enter",
LedCode::NumPadPause => "Pause",
LedCode::NumPadPrtSc => "Print Screen",
LedCode::NumPadHome => "Home",
LedCode::NumLock => "Num-Lock",
LedCode::FwdSlash => "/",
LedCode::Rshift => "Right Shift",
LedCode::Rshift3_1 => "Right Shift LED 1",
LedCode::Rshift3_2 => "Right Shift LED 2",
LedCode::Rshift3_3 => "Right Shift LED 3",
LedCode::End => "End",
LedCode::LCtrl => "Left Control",
LedCode::LFn => "Left Fn",
LedCode::Meta => "Meta",
LedCode::LAlt => "Left Alt",
LedCode::Spacebar => "Space",
LedCode::Spacebar5_1 => "Space LED 1",
LedCode::Spacebar5_2 => "Space LED 2",
LedCode::Spacebar5_3 => "Space LED 3",
LedCode::Spacebar5_4 => "Space LED 4",
LedCode::Spacebar5_5 => "Space LED 5",
LedCode::RAlt => "Right Alt",
LedCode::PrtSc => "Print Screen",
LedCode::RCtrl => "Right Control",
LedCode::Pause => "Pause",
LedCode::Up => "Up",
LedCode::Down => "Down",
LedCode::Left => "Left",
LedCode::Right => "Right",
LedCode::RFn => "Right Fn",
LedCode::MediaPlay => "Media Play",
LedCode::MediaStop => "Media Stop",
LedCode::MediaNext => "Media Next",
LedCode::MediaPrev => "Media Previous",
LedCode::LidLogo => "Lid Logo",
LedCode::LidLeft => "Lid Left",
LedCode::LidRight => "Lid Right",
LedCode::LightbarRight => "Lightbar Right",
LedCode::LightbarRightCorner => "Lightbar Right Corner",
LedCode::LightbarRightBottom => "Lightbar Right Bottom",
LedCode::LightbarLeftBottom => "Lightbar Left Bottom",
LedCode::LightbarLeftCorner => "Lightbar Left Corner",
LedCode::LightbarLeft => "Lightbar Left",
LedCode::Spacing | LedCode::Blocking => "",
LedCode::SingleZone => "Single Zoned Keyboard",
LedCode::ZonedKbLeft => "Left Zone (zone 1)",
LedCode::ZonedKbLeftMid => "Center-left Zone (zone 2)",
LedCode::ZonedKbRightMid => "Center-right Zone (zone 3)",
LedCode::ZonedKbRight => "Right Zone (zone 4)",
}
}
}
#[cfg(test)]
mod tests {
use crate::advanced::{LedCode, LedUsbPackets, UsbPackets};
use crate::keyboard::{LedCode, LedUsbPackets, UsbPackets};
macro_rules! colour_check_zoned {
($zone:expr, $pkt_idx_start:expr) => {

View File

@@ -8,10 +8,10 @@ use std::slice::Iter;
use log::warn;
use serde::{Deserialize, Serialize};
use crate::advanced::LedCode;
use crate::aura_detection::LaptopLedData;
use crate::error::Error;
use crate::{AdvancedAuraType, AuraModeNum, AuraZone};
use crate::keyboard::{AdvancedAuraType, LedCode};
use crate::{AuraModeNum, AuraZone};
/// The `key_type` plays a role in effects (eventually). You could for example
/// add a `ShapeType::Spacing` to pad out an effect, such as a laserbeam across
@@ -459,7 +459,7 @@ mod tests {
use std::path::PathBuf;
use crate::aura_detection::LedSupportFile;
use crate::layouts::KeyLayout;
use crate::keyboard::KeyLayout;
#[test]
fn check_parse_all() {

View File

@@ -0,0 +1,20 @@
/// All handling for `RgbAddress`ing.
mod advanced;
pub use advanced::*;
/// Helpers for consructing keyboard layouts for UI use and effects
mod layouts;
pub use layouts::*;
mod power;
pub use power::*;
#[derive(Debug, Clone, PartialEq, Eq, Default, serde::Deserialize, serde::Serialize)]
pub enum AdvancedAuraType {
/// A `None` will apply the effect to the whole keyboard via basic-static
/// mode
#[default]
None,
Zoned(Vec<LedCode>),
PerKey,
}

View File

@@ -0,0 +1,522 @@
//! Power state for Laptop MCU RGB/LED. This is generally for newer
//! 0x18c6, 0x19B6, 0x1a30, keyboard models (2021+)
use std::fmt::Debug;
use std::ops::{BitAnd, BitOr};
use log::warn;
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
#[cfg(feature = "dbus")]
use zbus::zvariant::{OwnedValue, Type, Value};
use crate::aura_detection::{LaptopLedData, PowerZones};
use crate::AuraDeviceType;
/// Meaning of this struct depends on the laptop generation.
/// - 2021+, the struct is a single zone with 4 states
/// - pre-2021, the struct is 1 or 2 zones and 3 states
/// - Tuf, the struct is 1 zone and 3 states
#[typeshare]
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct AuraPowerState {
pub zone: PowerZones,
pub boot: bool,
pub awake: bool,
pub sleep: bool,
/// Ignored for pre-2021 and Tuf
pub shutdown: bool,
}
impl Default for AuraPowerState {
/// Defaults all to off
fn default() -> Self {
Self {
zone: PowerZones::Keyboard,
boot: true,
awake: true,
sleep: true,
shutdown: true,
}
}
}
impl AuraPowerState {
fn default_for(zone: PowerZones) -> Self {
Self {
zone,
boot: true,
awake: true,
sleep: true,
shutdown: true,
}
}
fn tuf_to_bytes(&self) -> Vec<u8> {
todo!("0s and 1s for bool array")
}
/// # Bits for older 0x1866 keyboard model
///
/// Keybord and Lightbar require Awake, Boot and Sleep apply to both
/// Keybord and Lightbar regardless of if either are enabled (or Awake is
/// enabled)
///
/// | Byte 1 | Byte 2 | Byte 3 | function | hex |
/// |------------|------------|------------|----------|----------|
/// | 0000, 0000 | 0000, 0000 | 0000, 0010 | Awake | 00,00,02 |
/// | 0000, 1000 | 0000, 0000 | 0000, 0000 | Keyboard | 08,00,00 |
/// | 0000, 0100 | 0000, 0101 | 0000, 0000 | Lightbar | 04,05,00 |
/// | 1100, 0011 | 0001, 0010 | 0000, 1001 | Boot/Sht | c3,12,09 |
/// | 0011, 0000 | 0000, 1000 | 0000, 0100 | Sleep | 30,08,04 |
/// | 1111, 1111 | 0001, 1111 | 0000, 1111 | all on | |
fn old_to_bytes(&self) -> Vec<u8> {
let mut a: u32 = 0;
if self.awake {
a |= OldAuraPower::Awake as u32;
}
if self.boot {
a |= OldAuraPower::Boot as u32;
}
if self.sleep {
a |= OldAuraPower::Sleep as u32;
}
if matches!(
self.zone,
PowerZones::Keyboard | PowerZones::KeyboardAndLightbar
) {
a |= OldAuraPower::Keyboard as u32;
}
if matches!(
self.zone,
PowerZones::Lightbar | PowerZones::KeyboardAndLightbar
) {
a |= OldAuraPower::Lightbar as u32;
}
vec![
((a & 0xff0000) >> 16) as u8,
((a & 0xff00) >> 8) as u8,
(a & 0xff) as u8,
0x00,
]
}
fn new_to_byte(&self) -> u32 {
match self.zone {
PowerZones::Logo => {
self.boot as u32
| (self.awake as u32) << 2
| (self.sleep as u32) << 4
| (self.shutdown as u32) << 6
}
PowerZones::Keyboard => {
(self.boot as u32) << 1
| (self.awake as u32) << 3
| (self.sleep as u32) << 5
| (self.shutdown as u32) << 7
}
PowerZones::Lightbar => {
(self.boot as u32) << (7 + 2)
| (self.awake as u32) << (7 + 3)
| (self.sleep as u32) << (7 + 4)
| (self.shutdown as u32) << (7 + 5)
}
PowerZones::Lid => {
(self.boot as u32) << (15 + 1)
| (self.awake as u32) << (15 + 2)
| (self.sleep as u32) << (15 + 3)
| (self.shutdown as u32) << (15 + 4)
}
PowerZones::RearGlow => {
(self.boot as u32) << (23 + 1)
| (self.awake as u32) << (23 + 2)
| (self.sleep as u32) << (23 + 3)
| (self.shutdown as u32) << (23 + 4)
}
PowerZones::KeyboardAndLightbar => 0,
}
}
}
#[typeshare]
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct LaptopAuraPower {
pub states: Vec<AuraPowerState>,
}
impl LaptopAuraPower {
/// # Bits for newer 0x18c6, 0x19B6, 0x1a30, keyboard models
///
/// | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Label |
/// |--------|---------|---------|---------|----------|
/// |00000001| 00000000| 00000000| 00000000|boot_logo_|
/// |00000010| 00000000| 00000000| 00000000|boot_keyb_|
/// |00000100| 00000000| 00000000| 00000000|awake_logo|
/// |00001000| 00000000| 00000000| 00000000|awake_keyb|
/// |00010000| 00000000| 00000000| 00000000|sleep_logo|
/// |00100000| 00000000| 00000000| 00000000|sleep_keyb|
/// |01000000| 00000000| 00000000| 00000000|shut_logo_|
/// |10000000| 00000000| 00000000| 00000000|shut_keyb_|
/// |00000000| 00000010| 00000000| 00000000|boot_bar__|
/// |00000000| 00000100| 00000000| 00000000|awake_bar_|
/// |00000000| 00001000| 00000000| 00000000|sleep_bar_|
/// |00000000| 00010000| 00000000| 00000000|shut_bar__|
/// |00000000| 00000000| 00000001| 00000000|boot_lid__|
/// |00000000| 00000000| 00000010| 00000000|awkae_lid_|
/// |00000000| 00000000| 00000100| 00000000|sleep_lid_|
/// |00000000| 00000000| 00001000| 00000000|shut_lid__|
/// |00000000| 00000000| 00000000| 00000001|boot_rear_|
/// |00000000| 00000000| 00000000| 00000010|awake_rear|
/// |00000000| 00000000| 00000000| 00000100|sleep_rear|
/// |00000000| 00000000| 00000000| 00001000|shut_rear_|
fn new_to_bytes(&self) -> Vec<u8> {
let mut a: u32 = 0;
for state in self.states.iter() {
a |= state.new_to_byte();
}
vec![
(a & 0xff) as u8,
((a & 0xff00) >> 8) as u8,
((a & 0xff0000) >> 16) as u8,
((a & 0xff000000) >> 24) as u8,
]
}
// TODO: use support data to setup correct zones
pub fn new(aura_type: AuraDeviceType, support_data: &LaptopLedData) -> Self {
match aura_type {
AuraDeviceType::Unknown | AuraDeviceType::LaptopPost2021 => {
let mut states = Vec::new();
for zone in support_data.power_zones.iter() {
states.push(AuraPowerState::default_for(*zone))
}
Self { states }
}
AuraDeviceType::LaptopPre2021 => {
if support_data.power_zones.contains(&PowerZones::Lightbar) {
Self {
states: vec![AuraPowerState::default_for(PowerZones::KeyboardAndLightbar)],
}
} else {
Self {
states: vec![AuraPowerState::default_for(PowerZones::Keyboard)],
}
}
}
AuraDeviceType::LaptopTuf => Self {
states: vec![AuraPowerState::default_for(PowerZones::Keyboard)],
},
AuraDeviceType::ScsiExtDisk => todo!(),
}
}
pub fn to_bytes(&self, aura_type: AuraDeviceType) -> Vec<u8> {
match aura_type {
AuraDeviceType::LaptopPost2021 => self.new_to_bytes(),
AuraDeviceType::LaptopPre2021 => self
.states
.first()
.cloned()
.unwrap_or_default()
.old_to_bytes(),
AuraDeviceType::LaptopTuf => self
.states
.first()
.cloned()
.unwrap_or_default()
.tuf_to_bytes(),
AuraDeviceType::Unknown => {
warn!("Trying to create bytes for an unknown device");
self.new_to_bytes()
}
AuraDeviceType::ScsiExtDisk => todo!(),
}
}
}
/// | Byte 1 | Byte 2 | Byte 3 | function | hex |
/// |------------|------------|------------|----------|----------|
/// | 0000, 0000 | 0000, 0000 | 0000, 0010 | Awake | 00,00,02 |
/// | 0000, 1000 | 0000, 0000 | 0000, 0000 | Keyboard | 08,00,00 |
/// | 0000, 0100 | 0000, 0101 | 0000, 0000 | Lightbar | 04,05,00 |
/// | 1100, 0011 | 0001, 0010 | 0000, 1001 | Boot/Sht | c3,12,09 |
/// | 0011, 0000 | 0000, 1000 | 0000, 0100 | Sleep | 30,08,04 |
/// | 1111, 1111 | 0001, 1111 | 0000, 1111 | all on | |
#[repr(u32)]
enum OldAuraPower {
Awake = 0x000002,
Boot = 0xc31209,
Sleep = 0x300804,
Keyboard = 0x080000,
Lightbar = 0x040500,
}
impl BitOr<OldAuraPower> for OldAuraPower {
type Output = u32;
fn bitor(self, rhs: OldAuraPower) -> Self::Output {
self as u32 | rhs as u32
}
}
impl BitAnd<OldAuraPower> for OldAuraPower {
type Output = u32;
fn bitand(self, rhs: OldAuraPower) -> Self::Output {
self as u32 & rhs as u32
}
}
impl From<OldAuraPower> for u32 {
fn from(a: OldAuraPower) -> Self {
a as u32
}
}
#[cfg(test)]
mod test {
use crate::aura_detection::{LaptopLedData, PowerZones};
use crate::keyboard::{AuraPowerState, LaptopAuraPower};
use crate::AuraDeviceType;
#[test]
fn check_0x1866_control_bytes() {
let state = AuraPowerState {
zone: PowerZones::Keyboard,
awake: true,
boot: false,
sleep: false,
shutdown: false,
};
let bytes = state.old_to_bytes();
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
assert_eq!(bytes, [0x08, 0x00, 0x02, 0x00]);
let state = AuraPowerState {
zone: PowerZones::Lightbar,
awake: true,
boot: false,
sleep: false,
shutdown: false,
};
let bytes = state.old_to_bytes();
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
assert_eq!(bytes, [0x04, 0x05, 0x02, 0x00]);
let bytes = AuraPowerState {
zone: PowerZones::Keyboard,
awake: false,
boot: false,
sleep: true,
shutdown: false,
};
let bytes = bytes.old_to_bytes();
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
assert_eq!(bytes, [0x30, 0x08, 0x04, 0x00]);
let bytes = AuraPowerState {
zone: PowerZones::Keyboard,
awake: false,
boot: true,
sleep: false,
shutdown: false,
};
let bytes = bytes.old_to_bytes();
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
assert_eq!(bytes, [0xc3, 0x12, 0x09, 0x00]);
let power = AuraPowerState {
zone: PowerZones::KeyboardAndLightbar,
awake: true,
boot: true,
sleep: true,
shutdown: false,
};
let bytes = power.old_to_bytes();
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
assert_eq!(bytes, [0xff, 0x1f, 0x000f, 0x00]);
}
#[test]
fn check_0x19b6_control_bytes_binary_rep() {
fn to_binary_string(power: &LaptopAuraPower) -> String {
let bytes = power.to_bytes(AuraDeviceType::LaptopPost2021);
format!(
"{:08b}, {:08b}, {:08b}, {:08b}",
bytes[0], bytes[1], bytes[2], bytes[3]
)
}
let boot_logo_ = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Logo,
boot: true,
..Default::default()
}],
});
let boot_keyb_ = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Keyboard,
boot: true,
..Default::default()
}],
});
let sleep_logo = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Logo,
sleep: true,
..Default::default()
}],
});
let sleep_keyb = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Keyboard,
sleep: true,
..Default::default()
}],
});
let awake_logo = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Logo,
awake: true,
..Default::default()
}],
});
let awake_keyb = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Keyboard,
awake: true,
..Default::default()
}],
});
let shut_logo_ = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Logo,
shutdown: true,
..Default::default()
}],
});
let shut_keyb_ = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Keyboard,
shutdown: true,
..Default::default()
}],
});
let boot_bar__ = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Lightbar,
boot: true,
..Default::default()
}],
});
let awake_bar_ = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Lightbar,
awake: true,
..Default::default()
}],
});
let sleep_bar_ = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Lightbar,
sleep: true,
..Default::default()
}],
});
let shut_bar__ = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Lightbar,
shutdown: true,
..Default::default()
}],
});
let boot_lid__ = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Lid,
boot: true,
..Default::default()
}],
});
let awake_lid_ = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Lid,
awake: true,
..Default::default()
}],
});
let sleep_lid_ = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Lid,
sleep: true,
..Default::default()
}],
});
let shut_lid__ = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::Lid,
shutdown: true,
..Default::default()
}],
});
let boot_rear_ = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::RearGlow,
boot: true,
..Default::default()
}],
});
let awake_rear = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::RearGlow,
awake: true,
..Default::default()
}],
});
let sleep_rear = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::RearGlow,
sleep: true,
..Default::default()
}],
});
let shut_rear_ = to_binary_string(&LaptopAuraPower {
states: vec![AuraPowerState {
zone: PowerZones::RearGlow,
shutdown: true,
..Default::default()
}],
});
assert_eq!(boot_logo_, "00000001, 00000000, 00000000, 00000000");
assert_eq!(boot_keyb_, "00000010, 00000000, 00000000, 00000000");
assert_eq!(awake_logo, "00000100, 00000000, 00000000, 00000000");
assert_eq!(awake_keyb, "00001000, 00000000, 00000000, 00000000");
assert_eq!(sleep_logo, "00010000, 00000000, 00000000, 00000000");
assert_eq!(sleep_keyb, "00100000, 00000000, 00000000, 00000000");
assert_eq!(shut_logo_, "01000000, 00000000, 00000000, 00000000");
assert_eq!(shut_keyb_, "10000000, 00000000, 00000000, 00000000");
//
assert_eq!(boot_bar__, "00000000, 00000010, 00000000, 00000000");
assert_eq!(awake_bar_, "00000000, 00000100, 00000000, 00000000");
assert_eq!(sleep_bar_, "00000000, 00001000, 00000000, 00000000");
assert_eq!(shut_bar__, "00000000, 00010000, 00000000, 00000000");
//
assert_eq!(boot_lid__, "00000000, 00000000, 00000001, 00000000");
assert_eq!(awake_lid_, "00000000, 00000000, 00000010, 00000000");
assert_eq!(sleep_lid_, "00000000, 00000000, 00000100, 00000000");
assert_eq!(shut_lid__, "00000000, 00000000, 00001000, 00000000");
//
assert_eq!(boot_rear_, "00000000, 00000000, 00000000, 00000001");
assert_eq!(awake_rear, "00000000, 00000000, 00000000, 00000010");
assert_eq!(sleep_rear, "00000000, 00000000, 00000000, 00000100");
assert_eq!(shut_rear_, "00000000, 00000000, 00000000, 00001000");
// All on
let byte1 = LaptopAuraPower::new(AuraDeviceType::LaptopPost2021, &LaptopLedData::default());
let out = to_binary_string(&byte1);
assert_eq!(out, "11111111, 00011110, 00001111, 00001111");
}
}

View File

@@ -1,25 +1,28 @@
mod builtin_modes;
use advanced::LedCode;
pub use builtin_modes::*;
// TODO: Generic builtin modes
// TODO: Traits for finding device + writing generic modes
// TODO: Traits for writing aura_sync
// TODO: separate keyboard and laptop parts?
use std::fmt::Debug;
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
#[cfg(feature = "dbus")]
use zbus::zvariant::{OwnedValue, Type, Value};
/// A container of images/grids/gifs/pauses which can be iterated over to
/// generate cool effects
pub mod effects;
/// All handling for `RgbAddress`ing.
pub mod advanced;
/// Convert the `RgbAddress` to `&str` labels
pub mod advanced_to_str;
mod builtin_modes;
pub use builtin_modes::*;
/// Helper for detecting what is available
pub mod aura_detection;
pub mod error;
/// Helpers for consructing keyboard layouts for UI use and effects
pub mod layouts;
pub mod usb;
pub mod power;
mod deprecated;
pub mod keyboard;
pub const LED_MSG_LEN: usize = 17;
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
@@ -61,12 +64,44 @@ pub const ORANGE: Colour = Colour {
};
pub const GRADIENT: [Colour; 7] = [RED, VIOLET, BLUE, TEAL, GREEN, YELLOW, ORANGE];
#[derive(Debug, Clone, PartialEq, Eq, Default, serde::Deserialize, serde::Serialize)]
pub enum AdvancedAuraType {
/// A `None` will apply the effect to the whole keyboard via basic-static
/// mode
#[typeshare]
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum AuraDeviceType {
/// Most new laptops
#[default]
None,
Zoned(Vec<LedCode>),
PerKey,
LaptopPost2021 = 0,
LaptopPre2021 = 1,
LaptopTuf = 2,
ScsiExtDisk = 3,
Unknown = 255,
}
impl AuraDeviceType {
pub fn is_old_laptop(&self) -> bool {
*self == Self::LaptopPre2021
}
pub fn is_tuf_laptop(&self) -> bool {
*self == Self::LaptopTuf
}
pub fn is_new_laptop(&self) -> bool {
*self == Self::LaptopPost2021
}
pub fn is_scsi(&self) -> bool {
*self == Self::ScsiExtDisk
}
}
impl From<&str> for AuraDeviceType {
fn from(s: &str) -> Self {
match s.to_lowercase().trim_start_matches("0x") {
"tuf" => AuraDeviceType::LaptopTuf,
"1932" => AuraDeviceType::ScsiExtDisk,
"1866" | "18c6" | "1869" | "1854" => Self::LaptopPre2021,
_ => Self::LaptopPost2021,
}
}
}

View File

@@ -1,344 +0,0 @@
use std::fmt::Debug;
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
#[cfg(feature = "dbus")]
use zbus::zvariant::{OwnedValue, Type, Value};
use crate::aura_detection::PowerZones;
#[typeshare]
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct KbAuraPowerState {
pub zone: PowerZones,
pub boot: bool,
pub awake: bool,
pub sleep: bool,
pub shutdown: bool,
}
impl Default for KbAuraPowerState {
/// Defaults all to off
fn default() -> Self {
Self {
zone: PowerZones::Keyboard,
boot: false,
awake: false,
sleep: false,
shutdown: false,
}
}
}
impl KbAuraPowerState {
pub fn to_byte(&self, zone: PowerZones) -> u32 {
match zone {
PowerZones::Logo => {
self.boot as u32
| (self.awake as u32) << 2
| (self.sleep as u32) << 4
| (self.shutdown as u32) << 6
}
PowerZones::Keyboard => {
(self.boot as u32) << 1
| (self.awake as u32) << 3
| (self.sleep as u32) << 5
| (self.shutdown as u32) << 7
}
PowerZones::Lightbar => {
(self.boot as u32) << (7 + 2)
| (self.awake as u32) << (7 + 3)
| (self.sleep as u32) << (7 + 4)
| (self.shutdown as u32) << (7 + 5)
}
PowerZones::Lid => {
(self.boot as u32) << (15 + 1)
| (self.awake as u32) << (15 + 2)
| (self.sleep as u32) << (15 + 3)
| (self.shutdown as u32) << (15 + 4)
}
PowerZones::RearGlow => {
(self.boot as u32) << (23 + 1)
| (self.awake as u32) << (23 + 2)
| (self.sleep as u32) << (23 + 3)
| (self.shutdown as u32) << (23 + 4)
}
}
}
}
/// Track and control the Aura keyboard power state
///
/// # Bits for newer 0x18c6, 0x19B6, 0x1a30, keyboard models
///
/// | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Label |
/// |--------|---------|---------|---------|----------|
/// |00000001| 00000000| 00000000| 00000000|boot_logo_|
/// |00000010| 00000000| 00000000| 00000000|boot_keyb_|
/// |00000100| 00000000| 00000000| 00000000|awake_logo|
/// |00001000| 00000000| 00000000| 00000000|awake_keyb|
/// |00010000| 00000000| 00000000| 00000000|sleep_logo|
/// |00100000| 00000000| 00000000| 00000000|sleep_keyb|
/// |01000000| 00000000| 00000000| 00000000|shut_logo_|
/// |10000000| 00000000| 00000000| 00000000|shut_keyb_|
/// |00000000| 00000010| 00000000| 00000000|boot_bar__|
/// |00000000| 00000100| 00000000| 00000000|awake_bar_|
/// |00000000| 00001000| 00000000| 00000000|sleep_bar_|
/// |00000000| 00010000| 00000000| 00000000|shut_bar__|
/// |00000000| 00000000| 00000001| 00000000|boot_lid__|
/// |00000000| 00000000| 00000010| 00000000|awkae_lid_|
/// |00000000| 00000000| 00000100| 00000000|sleep_lid_|
/// |00000000| 00000000| 00001000| 00000000|shut_lid__|
/// |00000000| 00000000| 00000000| 00000001|boot_rear_|
/// |00000000| 00000000| 00000000| 00000010|awake_rear|
/// |00000000| 00000000| 00000000| 00000100|sleep_rear|
/// |00000000| 00000000| 00000000| 00001000|shut_rear_|
#[typeshare]
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct AuraPower {
pub keyboard: KbAuraPowerState,
pub logo: KbAuraPowerState,
pub lightbar: KbAuraPowerState,
pub lid: KbAuraPowerState,
pub rear_glow: KbAuraPowerState,
}
impl AuraPower {
pub fn new_all_on() -> Self {
Self {
keyboard: KbAuraPowerState {
zone: PowerZones::Keyboard,
boot: true,
awake: true,
sleep: true,
shutdown: true,
},
logo: KbAuraPowerState {
zone: PowerZones::Logo,
boot: true,
awake: true,
sleep: true,
shutdown: true,
},
lightbar: KbAuraPowerState {
zone: PowerZones::Lightbar,
boot: true,
awake: true,
sleep: true,
shutdown: true,
},
lid: KbAuraPowerState {
zone: PowerZones::Lid,
boot: true,
awake: true,
sleep: true,
shutdown: true,
},
rear_glow: KbAuraPowerState {
zone: PowerZones::RearGlow,
boot: true,
awake: true,
sleep: true,
shutdown: true,
},
}
}
pub fn to_bytes(&self) -> [u8; 4] {
let mut a: u32 = 0;
a |= self.keyboard.to_byte(PowerZones::Keyboard);
a |= self.logo.to_byte(PowerZones::Logo);
a |= self.lid.to_byte(PowerZones::Lid);
a |= self.lightbar.to_byte(PowerZones::Lightbar);
a |= self.rear_glow.to_byte(PowerZones::RearGlow);
[
(a & 0xff) as u8,
((a & 0xff00) >> 8) as u8,
((a & 0xff0000) >> 16) as u8,
((a & 0xff000000) >> 24) as u8,
]
}
}
#[test]
fn check_0x19b6_control_bytes_binary_rep() {
fn to_binary_string(power: &AuraPower) -> String {
let bytes = power.to_bytes();
format!(
"{:08b}, {:08b}, {:08b}, {:08b}",
bytes[0], bytes[1], bytes[2], bytes[3]
)
}
let boot_logo_ = to_binary_string(&AuraPower {
logo: KbAuraPowerState {
boot: true,
..Default::default()
},
..Default::default()
});
let boot_keyb_ = to_binary_string(&AuraPower {
keyboard: KbAuraPowerState {
boot: true,
..Default::default()
},
..Default::default()
});
let sleep_logo = to_binary_string(&AuraPower {
logo: KbAuraPowerState {
sleep: true,
..Default::default()
},
..Default::default()
});
let sleep_keyb = to_binary_string(&AuraPower {
keyboard: KbAuraPowerState {
sleep: true,
..Default::default()
},
..Default::default()
});
let awake_logo = to_binary_string(&AuraPower {
logo: KbAuraPowerState {
awake: true,
..Default::default()
},
..Default::default()
});
let awake_keyb = to_binary_string(&AuraPower {
keyboard: KbAuraPowerState {
awake: true,
..Default::default()
},
..Default::default()
});
let shut_logo_ = to_binary_string(&AuraPower {
logo: KbAuraPowerState {
shutdown: true,
..Default::default()
},
..Default::default()
});
let shut_keyb_ = to_binary_string(&AuraPower {
keyboard: KbAuraPowerState {
shutdown: true,
..Default::default()
},
..Default::default()
});
let boot_bar__ = to_binary_string(&AuraPower {
lightbar: KbAuraPowerState {
boot: true,
..Default::default()
},
..Default::default()
});
let awake_bar_ = to_binary_string(&AuraPower {
lightbar: KbAuraPowerState {
awake: true,
..Default::default()
},
..Default::default()
});
let sleep_bar_ = to_binary_string(&AuraPower {
lightbar: KbAuraPowerState {
sleep: true,
..Default::default()
},
..Default::default()
});
let shut_bar__ = to_binary_string(&AuraPower {
lightbar: KbAuraPowerState {
shutdown: true,
..Default::default()
},
..Default::default()
});
let boot_lid__ = to_binary_string(&AuraPower {
lid: KbAuraPowerState {
boot: true,
..Default::default()
},
..Default::default()
});
let awkae_lid_ = to_binary_string(&AuraPower {
lid: KbAuraPowerState {
awake: true,
..Default::default()
},
..Default::default()
});
let sleep_lid_ = to_binary_string(&AuraPower {
lid: KbAuraPowerState {
sleep: true,
..Default::default()
},
..Default::default()
});
let shut_lid__ = to_binary_string(&AuraPower {
lid: KbAuraPowerState {
shutdown: true,
..Default::default()
},
..Default::default()
});
let boot_rear_ = to_binary_string(&AuraPower {
rear_glow: KbAuraPowerState {
boot: true,
..Default::default()
},
..Default::default()
});
let awake_rear = to_binary_string(&AuraPower {
rear_glow: KbAuraPowerState {
awake: true,
..Default::default()
},
..Default::default()
});
let sleep_rear = to_binary_string(&AuraPower {
rear_glow: KbAuraPowerState {
sleep: true,
..Default::default()
},
..Default::default()
});
let shut_rear_ = to_binary_string(&AuraPower {
rear_glow: KbAuraPowerState {
shutdown: true,
..Default::default()
},
..Default::default()
});
assert_eq!(boot_logo_, "00000001, 00000000, 00000000, 00000000");
assert_eq!(boot_keyb_, "00000010, 00000000, 00000000, 00000000");
assert_eq!(awake_logo, "00000100, 00000000, 00000000, 00000000");
assert_eq!(awake_keyb, "00001000, 00000000, 00000000, 00000000");
assert_eq!(sleep_logo, "00010000, 00000000, 00000000, 00000000");
assert_eq!(sleep_keyb, "00100000, 00000000, 00000000, 00000000");
assert_eq!(shut_logo_, "01000000, 00000000, 00000000, 00000000");
assert_eq!(shut_keyb_, "10000000, 00000000, 00000000, 00000000");
//
assert_eq!(boot_bar__, "00000000, 00000010, 00000000, 00000000");
assert_eq!(awake_bar_, "00000000, 00000100, 00000000, 00000000");
assert_eq!(sleep_bar_, "00000000, 00001000, 00000000, 00000000");
assert_eq!(shut_bar__, "00000000, 00010000, 00000000, 00000000");
//
assert_eq!(boot_lid__, "00000000, 00000000, 00000001, 00000000");
assert_eq!(awkae_lid_, "00000000, 00000000, 00000010, 00000000");
assert_eq!(sleep_lid_, "00000000, 00000000, 00000100, 00000000");
assert_eq!(shut_lid__, "00000000, 00000000, 00001000, 00000000");
//
assert_eq!(boot_rear_, "00000000, 00000000, 00000000, 00000001");
assert_eq!(awake_rear, "00000000, 00000000, 00000000, 00000010");
assert_eq!(sleep_rear, "00000000, 00000000, 00000000, 00000100");
assert_eq!(shut_rear_, "00000000, 00000000, 00000000, 00001000");
// All on
let byte1 = AuraPower::new_all_on();
let out = to_binary_string(&byte1);
assert_eq!(out, "11111111, 00011110, 00001111, 00001111");
}

View File

@@ -1,19 +1,3 @@
use std::fmt::Debug;
use std::ops::{BitAnd, BitOr};
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
#[cfg(feature = "dbus")]
use zbus::zvariant::{OwnedValue, Type, Value};
use crate::power::AuraPower;
pub const LED_INIT1: [u8; 2] = [0x5d, 0xb9];
pub const LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
pub const LED_INIT3: [u8; 6] = [0x5d, 0x05, 0x20, 0x31, 0, 0x08];
pub const LED_INIT4: &str = "^ASUS Tech.Inc."; // ^ == 0x5e
pub const LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08];
// Only these two packets must be 17 bytes
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];
@@ -24,243 +8,3 @@ pub const fn aura_brightness_bytes(brightness: u8) -> [u8; 17] {
0x5a, 0xba, 0xc5, 0xc4, brightness, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]
}
#[typeshare]
#[cfg_attr(
feature = "dbus",
derive(Type, Value, OwnedValue),
zvariant(signature = "s")
)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
pub enum AuraDevice {
Tuf = 0,
X1854 = 1,
X1869 = 2,
X1866 = 3,
X18c6 = 4,
#[default]
X19b6 = 5,
X1a30 = 6,
X1abe = 7,
Unknown = 99,
}
impl AuraDevice {
pub fn is_tuf_style(&self) -> bool {
matches!(self, AuraDevice::Tuf)
}
pub fn is_old_style(&self) -> bool {
!matches!(
self,
AuraDevice::Unknown
| AuraDevice::Tuf
| AuraDevice::X19b6
| AuraDevice::X18c6
| AuraDevice::X1a30
| AuraDevice::X1abe
)
}
pub fn is_new_style(&self) -> bool {
matches!(
self,
AuraDevice::X19b6 | AuraDevice::X18c6 | AuraDevice::X1a30 | AuraDevice::X1abe
)
}
}
impl From<AuraDevice> for &str {
fn from(a: AuraDevice) -> Self {
match a {
AuraDevice::Tuf => "tuf",
AuraDevice::X1854 => "1854",
AuraDevice::X1869 => "1869",
AuraDevice::X1866 => "1866",
AuraDevice::X18c6 => "18c6",
AuraDevice::X19b6 => "19b6",
AuraDevice::X1a30 => "1a30",
AuraDevice::X1abe => "1abe",
AuraDevice::Unknown => "unknown",
}
}
}
impl From<&str> for AuraDevice {
fn from(s: &str) -> Self {
match s.to_lowercase().as_str() {
"tuf" => AuraDevice::Tuf,
"1866" | "0x1866" => AuraDevice::X1866,
"18c6" | "0x18c6" => AuraDevice::X18c6,
"1869" | "0x1869" => AuraDevice::X1869,
"1854" | "0x1854" => AuraDevice::X1854,
"19b6" | "0x19b6" => AuraDevice::X19b6,
"1a30" | "0x1a30" => AuraDevice::X1a30,
"1abe" | "0x1abe" => AuraDevice::X1abe,
_ => AuraDevice::Unknown,
}
}
}
impl Debug for AuraDevice {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Tuf => write!(f, "Tuf"),
Self::X1854 => write!(f, "0x1854"),
Self::X1869 => write!(f, "0x1869"),
Self::X1866 => write!(f, "0x1866"),
Self::X18c6 => write!(f, "0x18c6"),
Self::X19b6 => write!(f, "0x19B6"),
Self::X1a30 => write!(f, "0x1A30"),
Self::X1abe => write!(f, "0x1ABE"),
Self::Unknown => write!(f, "Unknown"),
}
}
}
/// This struct is intended as a helper to pass args to generic dbus interface
#[typeshare]
#[cfg_attr(feature = "dbus", derive(Type, Value, OwnedValue))]
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
pub struct AuraPowerDev {
/// TUF laptops use a similar style of control to the older ROG devices but
/// through WMI
pub tuf: Vec<AuraDevTuf>,
/// Pre-0x19b6 devices use a different smaller scheme to the newer ROG
/// devices
pub old_rog: Vec<AuraDevRog1>,
/// ASUS standardised control scheme from 2020 onwards
pub rog: AuraPower,
}
#[typeshare]
#[cfg_attr(
feature = "dbus",
derive(Type, Value, OwnedValue),
zvariant(signature = "u")
)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum AuraDevTuf {
Boot = 0,
Awake = 1,
Sleep = 2,
Keyboard = 3,
}
impl AuraDevTuf {
pub const fn dev_id() -> &'static str {
"tuf"
}
}
/// # Bits for older 0x1866 keyboard model
///
/// Keybord and Lightbar require Awake, Boot and Sleep apply to both
/// Keybord and Lightbar regardless of if either are enabled (or Awake is
/// enabled)
///
/// | Byte 1 | Byte 2 | Byte 3 | function | hex |
/// |------------|------------|------------|----------|----------|
/// | 0000, 0000 | 0000, 0000 | 0000, 0010 | Awake | 00,00,02 |
/// | 0000, 1000 | 0000, 0000 | 0000, 0000 | Keyboard | 08,00,00 |
/// | 0000, 0100 | 0000, 0101 | 0000, 0000 | Lightbar | 04,05,00 |
/// | 1100, 0011 | 0001, 0010 | 0000, 1001 | Boot/Sht | c3,12,09 |
/// | 0011, 0000 | 0000, 1000 | 0000, 0100 | Sleep | 30,08,04 |
/// | 1111, 1111 | 0001, 1111 | 0000, 1111 | all on | |
#[typeshare]
#[cfg_attr(
feature = "dbus",
derive(Type, Value, OwnedValue),
zvariant(signature = "u")
)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[repr(u32)]
pub enum AuraDevRog1 {
Awake = 0x000002,
Keyboard = 0x080000,
Lightbar = 0x040500,
Boot = 0xc31209,
Sleep = 0x300804,
}
impl From<AuraDevRog1> for u32 {
fn from(a: AuraDevRog1) -> Self {
a as u32
}
}
impl AuraDevRog1 {
pub fn to_bytes(control: &[Self]) -> [u8; 4] {
let mut a: u32 = 0;
for n in control {
a |= *n as u32;
}
[
((a & 0xff0000) >> 16) as u8,
((a & 0xff00) >> 8) as u8,
(a & 0xff) as u8,
0x00,
]
}
pub const fn dev_id() -> &'static str {
"0x1866"
}
}
impl BitOr<AuraDevRog1> for AuraDevRog1 {
type Output = u32;
fn bitor(self, rhs: AuraDevRog1) -> Self::Output {
self as u32 | rhs as u32
}
}
impl BitAnd<AuraDevRog1> for AuraDevRog1 {
type Output = u32;
fn bitand(self, rhs: AuraDevRog1) -> Self::Output {
self as u32 & rhs as u32
}
}
#[cfg(test)]
mod tests {
use super::AuraDevRog1;
#[test]
fn check_0x1866_control_bytes() {
let bytes = [AuraDevRog1::Keyboard, AuraDevRog1::Awake];
let bytes = AuraDevRog1::to_bytes(&bytes);
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
assert_eq!(bytes, [0x08, 0x00, 0x02, 0x00]);
let bytes = [AuraDevRog1::Lightbar, AuraDevRog1::Awake];
let bytes = AuraDevRog1::to_bytes(&bytes);
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
assert_eq!(bytes, [0x04, 0x05, 0x02, 0x00]);
let bytes = [AuraDevRog1::Sleep];
let bytes = AuraDevRog1::to_bytes(&bytes);
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
assert_eq!(bytes, [0x30, 0x08, 0x04, 0x00]);
let bytes = [AuraDevRog1::Boot];
let bytes = AuraDevRog1::to_bytes(&bytes);
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
assert_eq!(bytes, [0xc3, 0x12, 0x09, 0x00]);
let bytes = [
AuraDevRog1::Keyboard,
AuraDevRog1::Lightbar,
AuraDevRog1::Awake,
AuraDevRog1::Sleep,
AuraDevRog1::Boot,
];
let bytes = AuraDevRog1::to_bytes(&bytes);
println!("{:08b}, {:08b}, {:08b}", bytes[0], bytes[1], bytes[2]);
assert_eq!(bytes, [0xff, 0x1f, 0x000f, 0x00]);
}
}