Begin rog-aura crate

This commit is contained in:
Luke D Jones
2021-04-11 18:50:57 +12:00
parent e9f1fa01fc
commit 6f36d91281
39 changed files with 665 additions and 84 deletions

View File

@@ -1,378 +0,0 @@
// static LED_INIT1: [u8; 2] = [0x5d, 0xb9];
// static LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
// static LED_INIT3: [u8; 6] = [0x5d, 0x05, 0x20, 0x31, 0, 0x08];
// static LED_INIT4: &str = "^ASUS Tech.Inc."; // ^ == 0x5e
// static LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08];
use crate::error::AuraError;
use crate::LED_MSG_LEN;
use serde_derive::{Deserialize, Serialize};
use std::str::FromStr;
use zvariant_derive::Type;
#[derive(Debug, Copy, Clone, PartialEq, Deserialize, Serialize, Type)]
pub enum LedBrightness {
Off,
Low,
Med,
High,
}
impl LedBrightness {
pub fn as_char_code(&self) -> u8 {
std::char::from_digit(*self as u32, 10).unwrap() as u8
}
}
impl From<u32> for LedBrightness {
fn from(bright: u32) -> Self {
match bright {
0 => LedBrightness::Off,
1 => LedBrightness::Low,
2 => LedBrightness::Med,
3 => LedBrightness::High,
_ => LedBrightness::Med,
}
}
}
#[derive(Debug, Clone, PartialEq, Copy, Deserialize, Serialize, Type)]
pub struct Colour(pub u8, pub u8, pub u8);
impl Default for Colour {
fn default() -> Self {
Colour(166, 0, 0)
}
}
impl FromStr for Colour {
type Err = AuraError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.len() < 6 {
return Err(AuraError::ParseColour);
}
let r = u8::from_str_radix(&s[0..2], 16).or(Err(AuraError::ParseColour))?;
let g = u8::from_str_radix(&s[2..4], 16).or(Err(AuraError::ParseColour))?;
let b = u8::from_str_radix(&s[4..6], 16).or(Err(AuraError::ParseColour))?;
Ok(Colour(r, g, b))
}
}
#[derive(Debug, Copy, Clone, PartialEq, Deserialize, Serialize, Type)]
pub enum Speed {
Low = 0xe1,
Med = 0xeb,
High = 0xf5,
}
impl Default for Speed {
fn default() -> Self {
Speed::Med
}
}
impl FromStr for Speed {
type Err = AuraError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let s = s.to_lowercase();
match s.as_str() {
"low" => Ok(Speed::Low),
"med" => Ok(Speed::Med),
"high" => Ok(Speed::High),
_ => Err(AuraError::ParseSpeed),
}
}
}
/// Used for Rainbow mode.
///
/// Enum corresponds to the required integer value
#[derive(Debug, Copy, Clone, PartialEq, Deserialize, Serialize, Type)]
pub enum Direction {
Right,
Left,
Up,
Down,
}
impl Default for Direction {
fn default() -> Self {
Direction::Right
}
}
impl FromStr for Direction {
type Err = AuraError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let s = s.to_lowercase();
match s.as_str() {
"right" => Ok(Direction::Right),
"up" => Ok(Direction::Up),
"down" => Ok(Direction::Down),
"left" => Ok(Direction::Left),
_ => Err(AuraError::ParseDirection),
}
}
}
/// Writes out the correct byte string for brightness
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,
]
}
#[derive(
Debug, Type, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Copy, Deserialize, Serialize,
)]
pub enum AuraModeNum {
Static = 0,
Breathe = 1,
Strobe = 2,
Rainbow = 3,
Star = 4,
Rain = 5,
Highlight = 6,
Laser = 7,
Ripple = 8,
Pulse = 10,
Comet = 11,
Flash = 12,
}
impl From<&AuraModeNum> for &str {
fn from(mode: &AuraModeNum) -> Self {
match mode {
AuraModeNum::Static => "Static",
AuraModeNum::Breathe => "Breathing",
AuraModeNum::Strobe => "Strobing",
AuraModeNum::Rainbow => "Rainbow",
AuraModeNum::Star => "Stars",
AuraModeNum::Rain => "Rain",
AuraModeNum::Highlight => "Keypress Highlight",
AuraModeNum::Laser => "Keypress Laser",
AuraModeNum::Ripple => "Keypress Ripple",
AuraModeNum::Pulse => "Pulse",
AuraModeNum::Comet => "Comet",
AuraModeNum::Flash => "Flash",
}
}
}
impl From<&str> for AuraModeNum {
fn from(mode: &str) -> Self {
match mode {
"Static" => AuraModeNum::Static,
"Breathing" => AuraModeNum::Breathe,
"Strobing" => AuraModeNum::Strobe,
"Rainbow" => AuraModeNum::Rainbow,
"Stars" => AuraModeNum::Star,
"Rain" => AuraModeNum::Rain,
"Keypress Highlight" => AuraModeNum::Highlight,
"Keypress Laser" => AuraModeNum::Laser,
"Keypress Ripple" => AuraModeNum::Ripple,
"Pulse" => AuraModeNum::Pulse,
"Comet" => AuraModeNum::Comet,
"Flash" => AuraModeNum::Flash,
_ => AuraModeNum::Static,
}
}
}
impl From<u8> for AuraModeNum {
fn from(mode: u8) -> Self {
match mode {
0 => AuraModeNum::Static,
1 => AuraModeNum::Breathe,
2 => AuraModeNum::Strobe,
3 => AuraModeNum::Rainbow,
4 => AuraModeNum::Star,
5 => AuraModeNum::Rain,
6 => AuraModeNum::Highlight,
7 => AuraModeNum::Laser,
8 => AuraModeNum::Ripple,
10 => AuraModeNum::Pulse,
11 => AuraModeNum::Comet,
12 => AuraModeNum::Flash,
_ => AuraModeNum::Static,
}
}
}
#[derive(Deserialize, Serialize)]
pub struct AuraMultiZone {
static_: [AuraEffect; 4],
breathe: [AuraEffect; 4],
}
impl AuraMultiZone {
pub fn set(&mut self, effect: AuraEffect) {
if effect.mode == AuraModeNum::Static {
match effect.zone {
AuraZone::None => {}
AuraZone::One => self.static_[0] = effect,
AuraZone::Two => self.static_[1] = effect,
AuraZone::Three => self.static_[2] = effect,
AuraZone::Four => self.static_[3] = effect,
}
} else if effect.mode == AuraModeNum::Breathe {
match effect.zone {
AuraZone::None => {}
AuraZone::One => self.breathe[0] = effect,
AuraZone::Two => self.breathe[1] = effect,
AuraZone::Three => self.breathe[2] = effect,
AuraZone::Four => self.breathe[3] = effect,
}
}
}
pub fn static_(&self) -> &[AuraEffect; 4] {
&self.static_
}
pub fn breathe(&self) -> &[AuraEffect; 4] {
&self.breathe
}
}
impl Default for AuraMultiZone {
fn default() -> Self {
Self {
static_: [
AuraEffect {
mode: AuraModeNum::Static,
zone: AuraZone::One,
..Default::default()
},
AuraEffect {
mode: AuraModeNum::Static,
zone: AuraZone::Two,
..Default::default()
},
AuraEffect {
mode: AuraModeNum::Static,
zone: AuraZone::Three,
..Default::default()
},
AuraEffect {
mode: AuraModeNum::Static,
zone: AuraZone::Four,
..Default::default()
},
],
breathe: [
AuraEffect {
mode: AuraModeNum::Breathe,
zone: AuraZone::One,
..Default::default()
},
AuraEffect {
mode: AuraModeNum::Breathe,
zone: AuraZone::Two,
..Default::default()
},
AuraEffect {
mode: AuraModeNum::Breathe,
zone: AuraZone::Three,
..Default::default()
},
AuraEffect {
mode: AuraModeNum::Breathe,
zone: AuraZone::Four,
..Default::default()
},
],
}
}
}
/// Base effects have no zoning, while multizone is 1-4
#[derive(Debug, Type, Copy, Clone, PartialEq, Deserialize, Serialize)]
pub enum AuraZone {
None,
One,
Two,
Three,
Four,
}
/// Default factory modes structure
#[derive(Debug, Type, Clone, Deserialize, Serialize)]
pub struct AuraEffect {
/// The effect type
pub mode: AuraModeNum,
/// `AuraZone::None` for no zone or zoneless keyboards
pub zone: AuraZone,
/// Primary colour for all modes
pub colour1: Colour,
/// Secondary colour in some modes like Breathing or Stars
pub colour2: Colour,
/// One of three speeds for modes that support speed (most that animate)
pub speed: Speed,
/// Up, down, left, right. Only Rainbow mode seems to use this
pub direction: Direction,
}
impl AuraEffect {
pub fn mode(&self) -> &AuraModeNum {
&self.mode
}
pub fn mode_name(&self) -> String {
(<&str>::from(&self.mode)).to_string()
}
pub fn mode_num(&self) -> u8 {
self.mode as u8
}
pub fn default_with_mode(mode: AuraModeNum) -> Self {
Self {
mode,
..Default::default()
}
}
pub fn zone(&self) -> AuraZone {
self.zone
}
}
impl Default for AuraEffect {
fn default() -> Self {
Self {
mode: AuraModeNum::Static,
zone: AuraZone::None,
colour1: Colour(166, 0, 0),
colour2: Colour(0, 0, 0),
speed: Speed::Med,
direction: Direction::Right,
}
}
}
/// Parses `AuraEffect` in to packet data for writing to the USB interface
///
/// Byte structure:
/// ```ignore
/// | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12|
/// |---|---|---|---|---|---|---|---|---|---|---|---|---|
/// |5d |b3 |00 |03 |ff |00 |00 |00 |00 |00 |00 |ff |00 |
/// ```
impl From<&AuraEffect> for [u8; LED_MSG_LEN] {
fn from(aura: &AuraEffect) -> Self {
let mut msg = [0u8; LED_MSG_LEN];
msg[0] = 0x5d;
msg[1] = 0xb3;
msg[2] = aura.zone as u8;
msg[3] = aura.mode as u8;
msg[4] = aura.colour1.0;
msg[5] = aura.colour1.1;
msg[6] = aura.colour1.2;
msg[7] = aura.speed as u8;
msg[8] = aura.direction as u8;
msg[10] = aura.colour2.0;
msg[11] = aura.colour2.1;
msg[12] = aura.colour2.2;
msg
}
}

View File

@@ -1,456 +0,0 @@
/// A `KeyColourArray` contains all data to change the full set of keyboard
/// key colours individually.
///
/// Each row of the internal array is a full HID packet that can be sent
/// to the keyboard EC. One row controls one group of keys, these keys are not
/// necessarily all on the same row of the keyboard, with some splitting between
/// two rows.
#[derive(Clone)]
pub struct KeyColourArray([[u8; 64]; 11]);
impl Default for KeyColourArray {
fn default() -> Self {
Self::new()
}
}
impl KeyColourArray {
pub fn new() -> Self {
let mut set = [[0u8; 64]; 11];
for (count, row) in set.iter_mut().enumerate() {
row[0] = 0x5d; // Report ID
row[1] = 0xbc; // Mode = custom??, 0xb3 is builtin
row[2] = 0x00;
row[3] = 0x01; // ??
row[4] = 0x01; // ??, 4,5,6 are normally RGB for builtin mode colours
row[5] = 0x01; // ??
row[6] = (count as u8) << 4; // Key group
if count == 10 {
row[7] = 0x08; // 0b00001000
} else {
row[7] = 0x10; // 0b00010000 addressing? flips for group a0
}
row[8] = 0x00;
}
KeyColourArray(set)
}
/// Initialise and clear the keyboard for custom effects
#[inline]
pub const fn get_init_msg() -> [u8; 64] {
let mut init = [0u8; 64];
init[0] = 0x5d; // Report ID
init[1] = 0xbc; // Mode = custom??, 0xb3 is builtin
init
}
#[inline]
pub fn set(&mut self, key: Key, r: u8, g: u8, b: u8) {
if let Some((rr, gg, bb)) = self.key(key) {
*rr = r;
*gg = g;
*bb = b;
}
}
/// Indexes in to `KeyColourArray` at the correct row and column
/// to set a series of three bytes to the chosen R,G,B values
pub fn key(&mut self, key: Key) -> Option<(&mut u8, &mut u8, &mut u8)> {
// Tuples are indexes in to array
let (row, col) = match key {
Key::VolDown => (0, 15),
Key::VolUp => (0, 18),
Key::MicMute => (0, 21),
Key::Rog => (0, 24),
//
Key::Esc => (1, 24),
Key::F1 => (1, 30),
Key::F2 => (1, 33),
Key::F3 => (1, 36),
Key::F4 => (1, 39),
Key::F5 => (1, 45),
Key::F6 => (1, 48),
Key::F7 => (1, 51),
Key::F8 => (1, 54),
//
Key::F9 => (2, 12),
Key::F10 => (2, 15),
Key::F11 => (2, 18),
Key::F12 => (2, 21),
Key::Del => (2, 24),
Key::Tilde => (2, 39),
Key::N1 => (2, 42),
Key::N2 => (2, 45),
Key::N3 => (2, 48),
Key::N4 => (2, 51),
Key::N5 => (2, 54),
//
Key::N6 => (3, 9),
Key::N7 => (3, 12),
Key::N8 => (3, 15),
Key::N9 => (3, 18),
Key::N0 => (3, 21),
Key::Hyphen => (3, 24),
Key::Equals => (3, 27),
Key::BkSpc1 => (3, 30),
Key::BkSpc2 => (3, 33),
Key::BkSpc3 => (3, 36),
Key::Home => (3, 39),
Key::Tab => (3, 54),
//
Key::Q => (4, 9),
Key::W => (4, 12),
Key::E => (4, 15),
Key::R => (4, 18),
Key::T => (4, 21),
Key::Y => (4, 24),
Key::U => (4, 27),
Key::I => (4, 30),
Key::O => (4, 33),
Key::P => (4, 36),
Key::LBracket => (4, 39),
Key::RBracket => (4, 42),
Key::BackSlash => (4, 45),
Key::PgUp => (4, 54),
//
Key::Caps => (5, 21),
Key::A => (5, 24),
Key::S => (5, 27),
Key::D => (5, 30),
Key::F => (5, 33),
Key::G => (5, 36),
Key::H => (5, 39),
Key::J => (5, 42),
Key::K => (5, 45),
Key::L => (5, 48),
Key::SemiColon => (5, 51),
Key::Quote => (5, 54),
//
Key::Ret1 => (6, 12),
Key::Ret2 => (6, 15),
Key::Ret3 => (6, 18),
Key::PgDn => (6, 21),
Key::LShift => (6, 36),
Key::Z => (6, 42),
Key::X => (6, 45),
Key::C => (6, 48),
Key::V => (6, 51),
Key::B => (6, 54),
//
Key::N => (7, 9),
Key::M => (7, 12),
Key::Comma => (7, 15),
Key::Period => (7, 18),
Key::FwdSlash => (7, 21),
Key::Rshift1 => (7, 27),
Key::Rshift2 => (7, 30),
Key::Rshift3 => (7, 33),
Key::End => (7, 36),
Key::LCtrl => (7, 51),
Key::LFn => (7, 54),
//
Key::Meta => (8, 9),
Key::LAlt => (8, 12),
Key::Space1 => (8, 15),
Key::Space2 => (8, 18),
Key::Space3 => (8, 21),
Key::Space4 => (8, 24),
Key::RAlt => (8, 30),
Key::PrtSc => (8, 33),
Key::RCtrl => (8, 36),
Key::Up => (8, 42),
Key::RFn => (8, 51),
//
Key::Left => (9, 54),
//
Key::Down => (10, 9),
Key::Right => (10, 12),
Key::None => return None,
};
// LOLOLOLOLOLOLOL! Look it's safe okay
unsafe {
Some((
&mut *(&mut self.0[row][col] as *mut u8),
&mut *(&mut self.0[row][col + 1] as *mut u8),
&mut *(&mut self.0[row][col + 2] as *mut u8),
))
}
}
#[inline]
pub fn get(&self) -> &[[u8; 64]; 11] {
&self.0
}
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum Key {
VolUp,
VolDown,
MicMute,
Rog,
Esc,
F1,
F2,
F3,
F4,
F5,
F6,
F7,
F8,
F9,
F10,
F11,
F12,
Del,
Tilde,
N1,
N2,
N3,
N4,
N5,
N6,
N7,
N8,
N9,
N0,
Hyphen,
Equals,
BkSpc1,
BkSpc2,
BkSpc3,
Home,
Tab,
Q,
W,
E,
R,
T,
Y,
U,
I,
O,
P,
LBracket,
RBracket,
BackSlash,
PgUp,
Caps,
A,
S,
D,
F,
G,
H,
J,
K,
L,
SemiColon,
Quote,
Ret1,
Ret2,
Ret3,
PgDn,
LShift,
Z,
X,
C,
V,
B,
N,
M,
Comma,
Period,
FwdSlash,
Rshift1,
Rshift2,
Rshift3,
End,
LCtrl,
LFn,
Meta,
LAlt,
Space1,
Space2,
Space3,
Space4,
RAlt,
PrtSc,
RCtrl,
Up,
Down,
Left,
Right,
RFn,
None,
}
pub trait KeyLayout {
fn get_rows(&self) -> &Vec<[Key; 17]>;
}
#[allow(clippy::upper_case_acronyms)]
pub struct GX502Layout(Vec<[Key; 17]>);
impl KeyLayout for GX502Layout {
fn get_rows(&self) -> &Vec<[Key; 17]> {
&self.0
}
}
impl Default for GX502Layout {
fn default() -> Self {
GX502Layout(vec![
[
Key::None,
Key::None,
Key::VolDown,
Key::VolUp,
Key::MicMute,
Key::Rog,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
],
[
Key::Esc,
Key::None,
Key::F1,
Key::F2,
Key::F3,
Key::F4,
Key::None, // not sure which key to put here
Key::F5,
Key::F6,
Key::F7,
Key::F8,
Key::F9,
Key::F9,
Key::F10,
Key::F11,
Key::F12,
Key::Del,
],
[
Key::Tilde,
Key::N1,
Key::N2,
Key::N3,
Key::N4,
Key::N5,
Key::N6,
Key::N7,
Key::N8,
Key::N9,
Key::N0,
Key::Hyphen,
Key::Equals,
Key::BkSpc1,
Key::BkSpc2,
Key::BkSpc3,
Key::Home,
],
[
Key::Tab,
Key::Q,
Key::W,
Key::E,
Key::R,
Key::T,
Key::Y,
Key::U,
Key::I,
Key::O,
Key::P,
Key::LBracket,
Key::RBracket,
Key::BackSlash,
Key::BackSlash,
Key::BackSlash,
Key::PgUp,
],
[
Key::Caps,
Key::A,
Key::S,
Key::D,
Key::F,
Key::G,
Key::H,
Key::J,
Key::K,
Key::L,
Key::SemiColon,
Key::Quote,
Key::Quote,
Key::Ret1,
Key::Ret2,
Key::Ret3,
Key::PgDn,
],
[
Key::LShift,
Key::LShift,
Key::Z,
Key::X,
Key::C,
Key::V,
Key::B,
Key::N,
Key::M,
Key::Comma,
Key::Period,
Key::FwdSlash,
Key::FwdSlash,
Key::Rshift1,
Key::Rshift2,
Key::Rshift3,
Key::End,
],
[
Key::LCtrl,
Key::LFn,
Key::Meta,
Key::LAlt,
Key::Space1,
Key::Space2,
Key::Space3,
Key::Space4,
Key::Space4,
Key::RAlt,
Key::PrtSc,
Key::RCtrl,
Key::RCtrl,
Key::Left,
Key::Up,
Key::Right,
Key::RFn,
],
[
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::None,
Key::Left,
Key::Down,
Key::Right,
Key::None,
],
])
}
}

View File

@@ -1,30 +1,6 @@
use std::error::Error;
use std::fmt;
#[derive(Debug)]
pub enum AuraError {
ParseColour,
ParseSpeed,
ParseDirection,
ParseBrightness,
ParseAnime,
}
impl fmt::Display for AuraError {
// This trait requires `fmt` with this exact signature.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AuraError::ParseColour => write!(f, "Could not parse colour"),
AuraError::ParseSpeed => write!(f, "Could not parse speed"),
AuraError::ParseDirection => write!(f, "Could not parse direction"),
AuraError::ParseBrightness => write!(f, "Could not parse brightness"),
AuraError::ParseAnime => write!(f, "Could not parse anime"),
}
}
}
impl Error for AuraError {}
#[derive(Debug)]
pub enum GraphicsError {
ParseVendor,

View File

@@ -5,15 +5,9 @@
pub static DBUS_NAME: &str = "org.asuslinux.Daemon";
pub static DBUS_PATH: &str = "/org/asuslinux/Daemon";
pub static DBUS_IFACE: &str = "org.asuslinux.Daemon";
pub const LED_MSG_LEN: usize = 17;
pub mod aura_modes;
pub mod profile;
/// Enables you to create fancy RGB effects
pub mod aura_perkey;
pub mod gfx_vendors;
pub mod supported;

View File

@@ -1,7 +1,6 @@
use rog_aura::AuraModeNum;
use serde_derive::{Deserialize, Serialize};
use crate::aura_modes::AuraModeNum;
#[derive(Serialize, Deserialize)]
pub struct SupportedFunctions {
pub anime_ctrl: AnimeSupportedFunctions,