pub static DBUS_NAME: &str = "org.rogcore.Daemon"; pub static DBUS_PATH: &str = "/org/rogcore/Daemon"; pub static DBUS_IFACE: &str = "org.rogcore.Daemon"; pub const LED_MSG_LEN: usize = 17; pub mod aura_modes; use aura_modes::AuraModes; /// Contains mostly only what is required for parsing CLI options pub mod cli_options; /// Enables you to create fancy RGB effects pub mod fancy; /// The main dbus group for system controls, e.g, fan control, keyboard LED's pub mod core_dbus; /// Specific dbus for writing to the AniMe Matrix display (if supported) pub mod anime_dbus; /// Helper functions for the AniMe display pub mod anime_matrix; pub mod error; /// Writes aout the correct byte string for brightness /// /// The HID descriptor looks like: /// /// ```ignore /// 0x06, 0x31, 0xFF, // Usage Page (Vendor Defined 0xFF31) /// 0x09, 0x76, // Usage (0x76) /// 0xA1, 0x01, // Collection (Application) /// 0x85, 0x5A, // Report ID (90) /// 0x19, 0x00, // Usage Minimum (0x00) /// 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) /// 0x15, 0x00, // Logical Minimum (0) /// 0x26, 0xFF, 0x00, // Logical Maximum (255) /// 0x75, 0x08, // Report Size (8) /// 0x95, 0x05, // Report Count (5) /// 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) /// 0x19, 0x00, // Usage Minimum (0x00) /// 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) /// 0x15, 0x00, // Logical Minimum (0) /// 0x26, 0xFF, 0x00, // Logical Maximum (255) /// 0x75, 0x08, // Report Size (8) /// 0x95, 0x3F, // Report Count (63) /// 0xB1, 0x00, // Feature (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) /// 0xC0, // End Collection /// ``` pub fn aura_brightness_bytes(brightness: u8) -> [u8; 17] { // TODO: check brightness range [ 0x5A, 0xBA, 0xC5, 0xC4, brightness, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] } /// Parses `AuraCommands` in to packet data /// /// 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 | /// ``` /// /// Bytes 0 and 1 should always be 5d, b3 /// /// On multizone laptops byte 2 is the zone number, RGB in usual /// place, byte 3 set to zero /// /// Byte 3 sets the mode type: /// - 00 = static /// - 01 = breathe (can set two colours) /// - 02 = strobe (through all colours) /// - 03 = rainbow /// - 04 = star (byte 9 sets rain colour) /// - 05 = rain keys, red, white, turquoise /// - 06 = pressed keys light up and fade /// - 07 = pressed key emits laser /// - 08 = pressed key emits water ripple /// - 09 = no effect/not used /// - 0a fast pulse (no speed setting) /// - 0b vertical line racing to right (no speed setting) /// - 0c wider vertical line racing to right (no speed setting) /// /// Bytes 4, 5, 6 are Red, Green, Blue /// /// Byte 7 sets speed from /// - 0x00 = Off /// - 0xe1 = Slow /// - 0xeb = Medium /// - 0xf5 = Fast /// /// Byte 8 sets rainbow direction: /// - 0x00 = rightwards /// - 0x01 = leftwards /// - 0x02 = upwards /// - 0x03 = downwards /// /// Bytes 10, 11, 12 are Red, Green, Blue for second colour if mode supports it /// /// The HID descriptor looks like: /// ```ignore /// 0x06, 0x31, 0xFF, // Usage Page (Vendor Defined 0xFF31) /// 0x09, 0x79, // Usage (0x79) /// 0xA1, 0x01, // Collection (Application) /// 0x85, 0x5D, // Report ID (93) /// 0x19, 0x00, // Usage Minimum (0x00) /// 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) /// 0x15, 0x00, // Logical Minimum (0) /// 0x26, 0xFF, 0x00, // Logical Maximum (255) /// 0x75, 0x08, // Report Size (8) /// 0x95, 0x1F, // Report Count (31) /// 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) /// 0x19, 0x00, // Usage Minimum (0x00) /// 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) /// 0x15, 0x00, // Logical Minimum (0) /// 0x26, 0xFF, 0x00, // Logical Maximum (255) /// 0x75, 0x08, // Report Size (8) /// 0x95, 0x3F, // Report Count (63) /// 0x91, 0x00, // Output (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) /// 0x19, 0x00, // Usage Minimum (0x00) /// 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) /// 0x15, 0x00, // Logical Minimum (0) /// 0x26, 0xFF, 0x00, // Logical Maximum (255) /// 0x75, 0x08, // Report Size (8) /// 0x95, 0x3F, // Report Count (63) /// 0xB1, 0x00, // Feature (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) /// 0xC0, // End Collection /// ``` /// /// This descriptor is also used for the per-key LED settings impl From<&AuraModes> for [u8; LED_MSG_LEN] { fn from(mode: &AuraModes) -> Self { let mut msg = [0u8; LED_MSG_LEN]; msg[0] = 0x5d; msg[1] = 0xb3; match mode { AuraModes::LedBrightness(n) => return aura_brightness_bytes(*n), AuraModes::Stable(_) => msg[3] = 0x00, AuraModes::Breathe(_) => msg[3] = 0x01, AuraModes::Strobe(_) => msg[3] = 0x02, AuraModes::Rainbow(_) => msg[3] = 0x03, AuraModes::Star(_) => msg[3] = 0x04, AuraModes::Rain(_) => msg[3] = 0x05, AuraModes::Highlight(_) => msg[3] = 0x06, AuraModes::Laser(_) => msg[3] = 0x07, AuraModes::Ripple(_) => msg[3] = 0x08, AuraModes::Pulse(_) => msg[3] = 0x0a, AuraModes::Comet(_) => msg[3] = 0x0b, AuraModes::Flash(_) => msg[3] = 0x0c, AuraModes::MultiStatic(_) => msg[3] = 0x0d, _ => print!("Mode not convertable to array: {}", <&str>::from(mode)), } match mode { AuraModes::Rainbow(settings) => { msg[7] = settings.speed as u8; msg[8] = settings.direction as u8; } AuraModes::Star(settings) => { msg[4] = settings.colour.0; msg[5] = settings.colour.1; msg[6] = settings.colour.2; msg[7] = settings.speed as u8; msg[9] = settings.colour2.2; } AuraModes::Breathe(settings) => { msg[4] = settings.colour.0; msg[5] = settings.colour.1; msg[6] = settings.colour.2; msg[7] = settings.speed as u8; msg[10] = settings.colour2.0; msg[11] = settings.colour2.1; msg[12] = settings.colour2.2; } AuraModes::Strobe(settings) | AuraModes::Rain(settings) => { msg[7] = settings.speed as u8; } AuraModes::Highlight(settings) | AuraModes::Laser(settings) | AuraModes::Ripple(settings) => { msg[4] = settings.colour.0; msg[5] = settings.colour.1; msg[6] = settings.colour.2; msg[7] = settings.speed as u8; } AuraModes::Stable(settings) | AuraModes::Pulse(settings) | AuraModes::Comet(settings) | AuraModes::Flash(settings) => { msg[4] = settings.colour.0; msg[5] = settings.colour.1; msg[6] = settings.colour.2; } _ => panic!("Mode not convertable to array"), } msg } } impl From for [u8; LED_MSG_LEN] { #[inline] fn from(mode: AuraModes) -> Self { <[u8; LED_MSG_LEN]>::from(&mode) } } impl From for [[u8; LED_MSG_LEN]; 4] { #[inline] fn from(mode: AuraModes) -> Self { <[[u8; LED_MSG_LEN]; 4]>::from(&mode) } } impl From<&AuraModes> for [[u8; LED_MSG_LEN]; 4] { #[inline] fn from(mode: &AuraModes) -> Self { let mut msg = [[0u8; LED_MSG_LEN]; 4]; for (i, row) in msg.iter_mut().enumerate() { row[0] = 0x5d; row[1] = 0xb3; row[2] = i as u8 + 1; } match mode { AuraModes::MultiStatic(settings) => { msg[0][4] = settings.colour1.0; msg[0][5] = settings.colour1.1; msg[0][6] = settings.colour1.2; msg[1][4] = settings.colour2.0; msg[1][5] = settings.colour2.1; msg[1][6] = settings.colour2.2; msg[2][4] = settings.colour3.0; msg[2][5] = settings.colour3.1; msg[2][6] = settings.colour3.2; msg[3][4] = settings.colour4.0; msg[3][5] = settings.colour4.1; msg[3][6] = settings.colour4.2; } _ => panic!("Mode not convertable to array"), } msg } }